diff --git a/project/BuildHelper.scala b/project/BuildHelper.scala index d7ff860ab..eda8731f6 100644 --- a/project/BuildHelper.scala +++ b/project/BuildHelper.scala @@ -188,7 +188,7 @@ object BuildHelper { baseDirectory.value ) }, - nativeConfig ~= { _.withMultithreading(false) }, + nativeConfig ~= { _.withMultithreading(false) } ) def buildInfoSettings(packageName: String) = Seq( diff --git a/zio-schema-avro/src/main/scala/zio/schema/codec/AvroSchemaCodec.scala b/zio-schema-avro/src/main/scala/zio/schema/codec/AvroSchemaCodec.scala index 95cf24b4c..7652f9d33 100644 --- a/zio-schema-avro/src/main/scala/zio/schema/codec/AvroSchemaCodec.scala +++ b/zio-schema-avro/src/main/scala/zio/schema/codec/AvroSchemaCodec.scala @@ -277,12 +277,14 @@ object AvroSchemaCodec extends AvroSchemaCodec { private def toAvroSchema(schema: Schema[_]): scala.util.Either[String, SchemaAvro] = { schema match { - case e: Enum[_] => toAvroEnum(e) - case record: Record[_] => toAvroRecord(record) - case map: Schema.Map[_, _] => toAvroMap(map) - case seq: Schema.Sequence[_, _, _] => toAvroSchema(seq.elementSchema).map(SchemaAvro.createArray) - case set: Schema.Set[_] => toAvroSchema(set.elementSchema).map(SchemaAvro.createArray) - case Transform(codec, _, _, _, _) => toAvroSchema(codec) + case e: Enum[_] => toAvroEnum(e) + case record: Record[_] => toAvroRecord(record) + case map: Schema.Map[_, _] => toAvroMap(map) + case map: Schema.NonEmptyMap[_, _] => toAvroMap(map) + case seq: Schema.Sequence[_, _, _] => toAvroSchema(seq.elementSchema).map(SchemaAvro.createArray) + case seq: Schema.NonEmptySequence[_, _, _] => toAvroSchema(seq.elementSchema).map(SchemaAvro.createArray) + case set: Schema.Set[_] => toAvroSchema(set.elementSchema).map(SchemaAvro.createArray) + case Transform(codec, _, _, _, _) => toAvroSchema(codec) case Primitive(standardType, _) => standardType match { case StandardType.UnitType => Right(SchemaAvro.create(SchemaAvro.Type.NULL)) @@ -624,6 +626,18 @@ object AvroSchemaCodec extends AvroSchemaCodec { toAvroSchema(tupleSchema).map(SchemaAvro.createArray) } + private[codec] def toAvroMap(map: NonEmptyMap[_, _]): scala.util.Either[String, SchemaAvro] = + map.keySchema match { + case p: Schema.Primitive[_] if p.standardType == StandardType.StringType => + toAvroSchema(map.valueSchema).map(SchemaAvro.createMap) + case _ => + val tupleSchema = Schema + .Tuple2(map.keySchema, map.valueSchema) + .annotate(AvroAnnotations.name("Tuple")) + .annotate(AvroAnnotations.namespace("scala")) + toAvroSchema(tupleSchema).map(SchemaAvro.createArray) + } + private[codec] def toAvroDecimal(schema: Schema[_]): scala.util.Either[String, SchemaAvro] = { val scale = schema.annotations.collectFirst { case AvroAnnotations.scale(s) => s } .getOrElse(AvroAnnotations.scale().scale) @@ -820,7 +834,9 @@ object AvroSchemaCodec extends AvroSchemaCodec { case c: Dynamic => Right(c) case c: GenericRecord => Right(c) case c: Map[_, _] => Right(c) + case c: NonEmptyMap[_, _] => Right(c) case c: Sequence[_, _, _] => Right(c) + case c: NonEmptySequence[_, _, _] => Right(c) case c: Set[_] => Right(c) case c: Fail[_] => Right(c) case c: Lazy[_] => Right(c) diff --git a/zio-schema-derivation/shared/src/main/scala/zio/schema/CachedDeriver.scala b/zio-schema-derivation/shared/src/main/scala/zio/schema/CachedDeriver.scala index 53d516a65..3dd37ac99 100644 --- a/zio-schema-derivation/shared/src/main/scala/zio/schema/CachedDeriver.scala +++ b/zio-schema-derivation/shared/src/main/scala/zio/schema/CachedDeriver.scala @@ -126,18 +126,22 @@ private[schema] object CachedDeriver { final case class Tuple2[A, B](leftKey: CacheKey[A], rightKey: CacheKey[B]) extends CacheKey[(A, B)] final case class Set[A](element: CacheKey[A]) extends CacheKey[Set[A]] final case class Map[K, V](key: CacheKey[K], valuew: CacheKey[V]) extends CacheKey[Map[K, V]] + final case class NonEmptyMap[K, V](key: CacheKey[K], valuew: CacheKey[V]) extends CacheKey[NonEmptyMap[K, V]] final case class Misc[A](schema: Schema[A]) extends CacheKey[A] def fromStandardType[A](st: StandardType[A]): CacheKey[A] = Primitive(st) def fromSchema[A](schema: Schema[A]): CacheKey[A] = schema match { - case e: Schema.Enum[_] => WithId(e.id) - case record: Schema.Record[_] => WithId(record.id) - case seq: Schema.Sequence[_, _, _] => WithIdentityObject(fromSchema(seq.elementSchema), seq.identity) - case set: Schema.Set[_] => Set(fromSchema(set.elementSchema)).asInstanceOf[CacheKey[A]] + case e: Schema.Enum[_] => WithId(e.id) + case record: Schema.Record[_] => WithId(record.id) + case seq: Schema.Sequence[_, _, _] => WithIdentityObject(fromSchema(seq.elementSchema), seq.identity) + case seq: Schema.NonEmptySequence[_, _, _] => WithIdentityObject(fromSchema(seq.elementSchema), seq.identity) + case set: Schema.Set[_] => Set(fromSchema(set.elementSchema)).asInstanceOf[CacheKey[A]] case map: Schema.Map[_, _] => Map(fromSchema(map.keySchema), fromSchema(map.valueSchema)).asInstanceOf[CacheKey[A]] + case map: Schema.NonEmptyMap[_, _] => + Map(fromSchema(map.keySchema), fromSchema(map.valueSchema)).asInstanceOf[CacheKey[A]] case Schema.Transform(inner, _, _, _, identity) => WithIdentityObject(fromSchema(inner), identity) case Schema.Primitive(standardType, _) => fromStandardType(standardType) case optional: Schema.Optional[_] => Optional(fromSchema(optional.schema)).asInstanceOf[CacheKey[A]]