Skip to content

Commit

Permalink
feat: No more reflection
Browse files Browse the repository at this point in the history
  • Loading branch information
Chuckame committed Jan 22, 2024
1 parent f0cbc8b commit 4871569
Show file tree
Hide file tree
Showing 15 changed files with 225 additions and 253 deletions.
5 changes: 2 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ dependencies {
api(libs.apache.avro)
api(libs.kotlinx.serialization.core)
implementation(libs.kotlinx.serialization.json)
implementation(kotlin("reflect"))
implementation(libs.xerial.snappy)
testImplementation(libs.kotest.junit5)
testImplementation(libs.kotest.core)
Expand All @@ -49,8 +48,8 @@ dependencies {

tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions.apiVersion = "1.5"
kotlinOptions.languageVersion = "1.5"
kotlinOptions.apiVersion = "1.6"
kotlinOptions.languageVersion = "1.6"
kotlinOptions.freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
}
java {
Expand Down
6 changes: 5 additions & 1 deletion src/main/kotlin/com/github/avrokotlin/avro4k/Avro.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import kotlinx.serialization.modules.contextual
import org.apache.avro.Schema
import org.apache.avro.file.CodecFactory
import org.apache.avro.generic.GenericRecord
import java.io.*
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.InputStream
import java.io.OutputStream
import java.nio.ByteBuffer
import java.nio.file.Files
import java.nio.file.Path
Expand Down
62 changes: 60 additions & 2 deletions src/main/kotlin/com/github/avrokotlin/avro4k/annotations.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
@file:OptIn(ExperimentalSerializationApi::class)

package com.github.avrokotlin.avro4k

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo
import kotlinx.serialization.descriptors.PrimitiveKind
import org.apache.avro.LogicalTypes
import org.apache.avro.Schema
import org.apache.avro.SchemaBuilder
import org.intellij.lang.annotations.Language

@SerialInfo
Expand All @@ -23,7 +28,57 @@ annotation class AvroName(val value: String)

@SerialInfo
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
annotation class ScalePrecision(val scale: Int, val precision: Int)
annotation class ScalePrecision(val scale: Int = 2, val precision: Int = 8)

@SerialInfo
@Target(AnnotationTarget.PROPERTY)
annotation class AvroDecimalLogicalType(val schema: LogicalDecimalTypeEnum = LogicalDecimalTypeEnum.BYTES)

enum class LogicalDecimalTypeEnum {
BYTES,
STRING,

/**
* Fixed must be accompanied with [AvroFixed]
*/
FIXED,
}

@SerialInfo
@Target(AnnotationTarget.PROPERTY)
annotation class AvroUuidLogicalType

@SerialInfo
@Target(AnnotationTarget.PROPERTY)
annotation class AvroTimeLogicalType(val type: LogicalTimeTypeEnum)

enum class LogicalTimeTypeEnum(val logicalTypeName: String, val kind: PrimitiveKind, val schemaFor: () -> Schema) {
DATE("date", PrimitiveKind.INT, { LogicalTypes.date().addToSchema(SchemaBuilder.builder().intType()) }),
TIME_MILLIS(
"time-millis",
PrimitiveKind.INT,
{ LogicalTypes.timeMillis().addToSchema(SchemaBuilder.builder().intType()) }),
TIME_MICROS(
"time-micros",
PrimitiveKind.LONG,
{ LogicalTypes.timeMicros().addToSchema(SchemaBuilder.builder().longType()) }),
TIMESTAMP_MILLIS(
"timestamp-millis",
PrimitiveKind.LONG,
{ LogicalTypes.timestampMillis().addToSchema(SchemaBuilder.builder().longType()) }),
TIMESTAMP_MICROS(
"timestamp-micros",
PrimitiveKind.LONG,
{ LogicalTypes.timestampMicros().addToSchema(SchemaBuilder.builder().longType()) }),
LOCAL_TIMESTAMP_MILLIS(
"local-timestamp-millis",
PrimitiveKind.LONG,
{ LogicalTypes.localTimestampMillis().addToSchema(SchemaBuilder.builder().longType()) }),
LOCAL_TIMESTAMP_MICROS(
"local-timestamp-micros",
PrimitiveKind.LONG,
{ LogicalTypes.localTimestampMicros().addToSchema(SchemaBuilder.builder().longType()) }),
}

@SerialInfo
@Target(AnnotationTarget.CLASS)
Expand All @@ -38,7 +93,10 @@ annotation class AvroDoc(val value: String)
annotation class AvroAlias(vararg val value: String)

@SerialInfo
@Deprecated(message = "Will be removed in the next major release", replaceWith = ReplaceWith("@AvroAlias(alias1, alias2)"))
@Deprecated(
message = "Will be removed in the next major release",
replaceWith = ReplaceWith("@AvroAlias(alias1, alias2)")
)
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
annotation class AvroAliases(val value: Array<String>)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ object StringFromAvroValue : FromAvroValue<Any?, String> {
is CharSequence -> value.toString()
is ByteBuffer -> String(value.array())
null -> throw SerializationException("Cannot decode <null> as a string")
else -> throw SerializationException("Unsupported type for String [is ${value.javaClass}]")
else -> throw SerializationException("Unsupported type for String [is ${value::class.qualifiedName}]")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ class MapDecoder(
return when (val v = value()) {
is Float -> v
null -> throw SerializationException("Cannot decode <null> as a Float")
else -> throw SerializationException("Unsupported type for Float ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Float ${v::class.qualifiedName}")
}
}

override fun decodeInt(): Int {
return when (val v = value()) {
is Int -> v
null -> throw SerializationException("Cannot decode <null> as a Int")
else -> throw SerializationException("Unsupported type for Int ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Int ${v::class.qualifiedName}")
}
}

Expand All @@ -63,7 +63,7 @@ class MapDecoder(
is Long -> v
is Int -> v.toLong()
null -> throw SerializationException("Cannot decode <null> as a Long")
else -> throw SerializationException("Unsupported type for Long ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Long ${v::class.qualifiedName}")
}
}

Expand All @@ -72,7 +72,7 @@ class MapDecoder(
is Double -> v
is Float -> v.toDouble()
null -> throw SerializationException("Cannot decode <null> as a Double")
else -> throw SerializationException("Unsupported type for Double ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Double ${v::class.qualifiedName}")
}
}

Expand All @@ -81,15 +81,15 @@ class MapDecoder(
is Byte -> v
is Int -> v.toByte()
null -> throw SerializationException("Cannot decode <null> as a Byte")
else -> throw SerializationException("Unsupported type for Byte ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Byte ${v::class.qualifiedName}")
}
}

override fun decodeBoolean(): Boolean {
return when (val v = value()) {
is Boolean -> v
null -> throw SerializationException("Cannot decode <null> as a Boolean")
else -> throw SerializationException("Unsupported type for Boolean ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Boolean. Actual: ${v::class.qualifiedName}")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class RecordDecoder(
return when (val v = fieldValue()) {
is Boolean -> v
null -> throw SerializationException("Cannot decode <null> as a Boolean")
else -> throw SerializationException("Unsupported type for Boolean ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Boolean ${v::class.qualifiedName}")
}
}

Expand All @@ -119,7 +119,7 @@ class RecordDecoder(
is Byte -> v
is Int -> if (v < 255) v.toByte() else throw SerializationException("Out of bound integer cannot be converted to byte [$v]")
null -> throw SerializationException("Cannot decode <null> as a Byte")
else -> throw SerializationException("Unsupported type for Byte ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Byte ${v::class.qualifiedName}")
}
}

Expand All @@ -141,15 +141,15 @@ class RecordDecoder(
return when (val v = fieldValue()) {
is Float -> v
null -> throw SerializationException("Cannot decode <null> as a Float")
else -> throw SerializationException("Unsupported type for Float ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Float ${v::class.qualifiedName}")
}
}

override fun decodeInt(): Int {
return when (val v = fieldValue()) {
is Int -> v
null -> throw SerializationException("Cannot decode <null> as a Int")
else -> throw SerializationException("Unsupported type for Int ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Int ${v::class.qualifiedName}")
}
}

Expand All @@ -158,7 +158,7 @@ class RecordDecoder(
is Long -> v
is Int -> v.toLong()
null -> throw SerializationException("Cannot decode <null> as a Long")
else -> throw SerializationException("Unsupported type for Long [is ${v.javaClass}]")
else -> throw SerializationException("Unsupported type for Long [is ${v::class.qualifiedName}]")
}
}

Expand All @@ -167,7 +167,7 @@ class RecordDecoder(
is Double -> v
is Float -> v.toDouble()
null -> throw SerializationException("Cannot decode <null> as a Double")
else -> throw SerializationException("Unsupported type for Double ${v.javaClass}")
else -> throw SerializationException("Unsupported type for Double ${v::class.qualifiedName}")
}
}

Expand Down

This file was deleted.

Loading

0 comments on commit 4871569

Please sign in to comment.