Skip to content

Commit

Permalink
Merge pull request #202 from Chuckame/anything-root
Browse files Browse the repository at this point in the history
feat: Support everything at root level
  • Loading branch information
Chuckame authored May 3, 2024
2 parents 85dc5c5 + a4223ac commit a6b4817
Show file tree
Hide file tree
Showing 80 changed files with 2,411 additions and 1,714 deletions.

This file was deleted.

30 changes: 12 additions & 18 deletions src/main/kotlin/com/github/avrokotlin/avro4k/Avro.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.github.avrokotlin.avro4k

import com.github.avrokotlin.avro4k.decoder.RootRecordDecoder
import com.github.avrokotlin.avro4k.encoder.RootRecordEncoder
import com.github.avrokotlin.avro4k.decoder.AvroValueDecoder
import com.github.avrokotlin.avro4k.encoder.AvroValueEncoder
import com.github.avrokotlin.avro4k.internal.RecordResolver
import com.github.avrokotlin.avro4k.internal.UnionResolver
import com.github.avrokotlin.avro4k.schema.FieldNamingStrategy
import com.github.avrokotlin.avro4k.schema.TypeNamingStrategy
import com.github.avrokotlin.avro4k.schema.ValueVisitor
import com.github.avrokotlin.avro4k.serializer.BigDecimalSerializer
import com.github.avrokotlin.avro4k.serializer.BigIntegerSerializer
Expand All @@ -16,7 +17,6 @@ import com.github.avrokotlin.avro4k.serializer.URLSerializer
import com.github.avrokotlin.avro4k.serializer.UUIDSerializer
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerializationException
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.modules.EmptySerializersModule
Expand All @@ -27,7 +27,6 @@ import kotlinx.serialization.serializer
import org.apache.avro.Schema
import org.apache.avro.generic.GenericContainer
import org.apache.avro.generic.GenericDatumReader
import org.apache.avro.generic.GenericRecord
import org.apache.avro.io.DecoderFactory
import org.apache.avro.io.EncoderFactory
import org.apache.avro.reflect.ReflectDatumWriter
Expand All @@ -45,6 +44,8 @@ sealed class Avro(
val serializersModule: SerializersModule,
) {
private val schemaCache: MutableMap<SerialDescriptor, Schema> = ConcurrentHashMap()
internal val recordResolver = RecordResolver(this)
internal val unionResolver = UnionResolver()

companion object Default : Avro(
AvroConfiguration(),
Expand Down Expand Up @@ -102,7 +103,7 @@ sealed class Avro(
value: T,
): Any? {
var result: Any? = null
RootRecordEncoder(writerSchema, serializersModule, configuration) {
AvroValueEncoder(this, writerSchema) {
result = it
}.encodeSerializableValue(serializer, value)
return result
Expand All @@ -118,8 +119,7 @@ sealed class Avro(
EncodedAs.BINARY -> DecoderFactory.get().binaryDecoder(inputStream, null)
EncodedAs.JSON_COMPACT, EncodedAs.JSON_PRETTY -> DecoderFactory.get().jsonDecoder(writerSchema, inputStream)
}
val readerSchema = schema(deserializer.descriptor)
val genericData = GenericDatumReader<Any?>(writerSchema, readerSchema).read(null, avroDecoder)
val genericData = GenericDatumReader<Any?>(writerSchema).read(null, avroDecoder)
return decodeFromGenericData(writerSchema, deserializer, genericData)
}

Expand All @@ -136,11 +136,7 @@ sealed class Avro(
deserializer: DeserializationStrategy<T>,
value: Any?,
): T {
return RootRecordDecoder(
(value as? GenericRecord?) ?: throw SerializationException("Expected a GenericRecord, actual: ${value?.let { it::class.qualifiedName }}"),
serializersModule,
configuration
)
return AvroValueDecoder(this, value, writerSchema)
.decodeSerializableValue(deserializer)
}
}
Expand All @@ -155,18 +151,16 @@ fun Avro(
}

class AvroBuilder internal constructor(avro: Avro) {
var typeNamingStrategy: TypeNamingStrategy = avro.configuration.typeNamingStrategy
var fieldNamingStrategy: FieldNamingStrategy = avro.configuration.fieldNamingStrategy
var implicitNulls: Boolean = avro.configuration.implicitNulls
var encodedAs: EncodedAs = avro.configuration.encodedAs
var serializersModule: SerializersModule = EmptySerializersModule()

fun build() =
AvroConfiguration(
typeNamingStrategy = this.typeNamingStrategy,
fieldNamingStrategy = this.fieldNamingStrategy,
implicitNulls = this.implicitNulls,
encodedAs = this.encodedAs
fieldNamingStrategy = fieldNamingStrategy,
implicitNulls = implicitNulls,
encodedAs = encodedAs
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
package com.github.avrokotlin.avro4k

import com.github.avrokotlin.avro4k.schema.FieldNamingStrategy
import com.github.avrokotlin.avro4k.schema.TypeNamingStrategy
import kotlinx.serialization.ExperimentalSerializationApi

data class AvroConfiguration(
/**
* The naming strategy to use for complex types (record, enum and fixed types).
*
* Default: [TypeNamingStrategy.Builtins.FullyQualified]
*/
val typeNamingStrategy: TypeNamingStrategy = TypeNamingStrategy.Builtins.FullyQualified,
/**
* The naming strategy to use for records' fields name.
*
Expand All @@ -26,9 +20,11 @@ data class AvroConfiguration(
*
* @see EncodedAs
*/
@ExperimentalSerializationApi
val encodedAs: EncodedAs = EncodedAs.BINARY,
)

@ExperimentalSerializationApi
enum class EncodedAs {
BINARY,
JSON_COMPACT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private class KotlinxSerializationDatumWriter<T>(
}
}

internal class KotlinxSerializationDatumReader<T>(
private class KotlinxSerializationDatumReader<T>(
private val deserializer: DeserializationStrategy<T>,
private val avro: Avro,
) : DatumReader<T> {
Expand Down
25 changes: 0 additions & 25 deletions src/main/kotlin/com/github/avrokotlin/avro4k/SerialDescriptor.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.github.avrokotlin.avro4k.decoder

import com.github.avrokotlin.avro4k.Avro
import com.github.avrokotlin.avro4k.internal.DecodedNullError
import com.github.avrokotlin.avro4k.internal.IllegalIndexedAccessError
import kotlinx.serialization.descriptors.SerialDescriptor
import org.apache.avro.Schema

internal class ArrayDecoder(
private val collection: Collection<Any?>,
private val writerSchema: Schema,
override val avro: Avro,
) : AvroTaggedDecoder<Schema>() {
private val iterator = collection.iterator()
private val elementType = if (writerSchema.type == Schema.Type.BYTES) writerSchema else writerSchema.elementType

private var currentItem: Any? = null
private var decodedNullMark = false

override val Schema.writerSchema: Schema
get() = this@ArrayDecoder.elementType

override fun SerialDescriptor.getTag(index: Int): Schema {
return elementType
}

override fun decodeTaggedNotNullMark(tag: Schema): Boolean {
decodedNullMark = true
currentItem = iterator.next()
return currentItem != null
}

override fun decodeTaggedValue(tag: Schema): Any {
val value = if (decodedNullMark) currentItem else iterator.next()
decodedNullMark = false
return value ?: throw DecodedNullError()
}

override fun decodeElementIndex(descriptor: SerialDescriptor): Int {
throw IllegalIndexedAccessError()
}

override fun decodeCollectionSize(descriptor: SerialDescriptor) = collection.size

override fun decodeSequentially() = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.github.avrokotlin.avro4k.decoder

import kotlinx.serialization.encoding.Decoder
import org.apache.avro.Schema
import org.apache.avro.generic.GenericFixed

interface AvroDecoder : Decoder {
val currentWriterSchema: Schema

fun decodeBytes(): ByteArray

fun decodeFixed(): GenericFixed

fun decodeValue(): Any
}
Loading

0 comments on commit a6b4817

Please sign in to comment.