Skip to content

Commit

Permalink
Merge pull request #152 from potfur/properties-with-list-of-values
Browse files Browse the repository at this point in the history
properties with list of values
  • Loading branch information
thake committed Aug 25, 2023
2 parents 3d64d54 + def06bf commit 18dd189
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class AnnotationExtractor(private val annotations: List<Annotation>) {
annotations.filterIsInstance<AvroAliases>().flatMap { it.value.toList() }
}
fun props(): List<Pair<String, String>> = annotations.filterIsInstance<AvroProp>().map { it.key to it.value }
fun jsonProps(): List<Pair<String, String>> = annotations.filterIsInstance<AvroJsonProp>().map { it.key to it.jsonValue }
fun default(): String? = annotations.filterIsInstance<AvroDefault>().firstOrNull()?.value
fun enumDefault(): String? = annotations.filterIsInstance<AvroEnumDefault>().firstOrNull()?.value
}

7 changes: 6 additions & 1 deletion src/main/kotlin/com/github/avrokotlin/avro4k/annotations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ package com.github.avrokotlin.avro4k

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo
import org.intellij.lang.annotations.Language

@SerialInfo
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
annotation class AvroProp(val key: String, val value: String)

@SerialInfo
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
annotation class AvroJsonProp(val key: String, @Language("json") val jsonValue: String)

@SerialInfo
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
annotation class AvroNamespace(val value: String)
Expand Down Expand Up @@ -57,7 +62,7 @@ annotation class AvroFixed(val size: Int)

@SerialInfo
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
annotation class AvroDefault(val value: String)
annotation class AvroDefault(@Language("json") val value: String)

@SerialInfo
@Target(AnnotationTarget.CLASS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.github.avrokotlin.avro4k.schema
import com.github.avrokotlin.avro4k.AnnotationExtractor
import com.github.avrokotlin.avro4k.Avro
import com.github.avrokotlin.avro4k.AvroConfiguration
import com.github.avrokotlin.avro4k.AvroJsonProp
import com.github.avrokotlin.avro4k.AvroProp
import com.github.avrokotlin.avro4k.RecordNaming
import kotlinx.serialization.ExperimentalSerializationApi
Expand Down Expand Up @@ -66,6 +67,7 @@ class ClassSchemaFor(
record.fields = fields
entityAnnotations.aliases().forEach { record.addAlias(it) }
entityAnnotations.props().forEach { (k, v) -> record.addProp(k, v) }
entityAnnotations.jsonProps().forEach { (k, v) -> record.addProp(k, json.parseToJsonElement(v).convertToAvroDefault()) }

return record
}
Expand Down Expand Up @@ -122,6 +124,9 @@ class ClassSchemaFor(
this.descriptor.getElementAnnotations(index)
.filterIsInstance<AvroProp>()
.forEach { field.addProp(it.key, it.value) }
this.descriptor.getElementAnnotations(index)
.filterIsInstance<AvroJsonProp>()
.forEach { field.addProp(it.key, json.parseToJsonElement(it.jsonValue).convertToAvroDefault()) }
annos.aliases().forEach { field.addAlias(it) }

return field
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.github.avrokotlin.avro4k.schema

import com.github.avrokotlin.avro4k.Avro
import com.github.avrokotlin.avro4k.AvroJsonProp
import io.kotest.core.spec.style.WordSpec
import io.kotest.matchers.shouldBe
import kotlinx.serialization.Serializable

class AvroJsonPropSchemaTest : WordSpec() {

enum class Colours {
Red, Green, Blue
}

init {
"@AvroJsonProp" should {
"support props annotation on class" {

val expected = org.apache.avro.Schema.Parser()
.parse(javaClass.getResourceAsStream("/props_json_annotation_class.json"))
val schema = Avro.default.schema(TypeAnnotated.serializer())
schema.toString(true) shouldBe expected.toString(true)
}
"support props annotation on field" {

val expected = org.apache.avro.Schema.Parser()
.parse(javaClass.getResourceAsStream("/props_json_annotation_field.json"))
val schema = Avro.default.schema(AnnotatedProperties.serializer())
schema.toString(true) shouldBe expected.toString(true)
}
"support props annotations on enums" {

val expected = org.apache.avro.Schema.Parser()
.parse(javaClass.getResourceAsStream("/props_json_annotation_scala_enum.json"))
val schema = Avro.default.schema(EnumAnnotated.serializer())
schema.toString(true) shouldBe expected.toString(true)
}
}
}

@Serializable
@AvroJsonProp("guns", """["and", "roses"]""")
data class TypeAnnotated(val str: String)

@Serializable
data class AnnotatedProperties(
@AvroJsonProp("guns", """["and", "roses"]""") val str: String,
@AvroJsonProp("jean", """["michel", "jarre"]""") val long: Long,
@AvroJsonProp(
key = "object",
jsonValue = """{
"a": "foo",
"b": 200,
"c": true,
"d": null,
"e": { "e1": null, "e2": 429 },
"f": ["bar", 404, false, null, {}]
}"""
)
val int: Int
)

@Serializable
data class EnumAnnotated(@AvroJsonProp("guns", """["and", "roses"]""") val colours: Colours)
}
12 changes: 12 additions & 0 deletions src/test/resources/props_json_annotation_class.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"type": "record",
"name": "TypeAnnotated",
"namespace": "com.github.avrokotlin.avro4k.schema.AvroJsonPropSchemaTest",
"fields": [
{
"name": "str",
"type": "string"
}
],
"guns": ["and", "roses"]
}
29 changes: 29 additions & 0 deletions src/test/resources/props_json_annotation_field.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"type": "record",
"name": "AnnotatedProperties",
"namespace": "com.github.avrokotlin.avro4k.schema.AvroJsonPropSchemaTest",
"fields": [
{
"name": "str",
"type": "string",
"guns": ["and", "roses"]
},
{
"name": "long",
"type": "long",
"jean": ["michel", "jarre"]
},
{
"name": "int",
"type": "int",
"object": {
"a": "foo",
"b": 200,
"c": true,
"d": null,
"e": { "e1": null, "e2": 429 },
"f": [ "bar", 404, false, null, {} ]
}
}
]
}
20 changes: 20 additions & 0 deletions src/test/resources/props_json_annotation_scala_enum.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"type": "record",
"name": "EnumAnnotated",
"namespace": "com.github.avrokotlin.avro4k.schema.AvroJsonPropSchemaTest",
"fields": [
{
"name": "colours",
"type": {
"type": "enum",
"name": "Colours",
"symbols": [
"Red",
"Green",
"Blue"
]
},
"guns": ["and", "roses"]
}
]
}

0 comments on commit 18dd189

Please sign in to comment.