Skip to content

Commit 5ceece9

Browse files
committed
Handle non-empty schemas
1 parent 61f5fd6 commit 5ceece9

File tree

9 files changed

+43
-28
lines changed

9 files changed

+43
-28
lines changed

build.sbt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ inThisBuild(
3939
ThisBuild / publishTo := sonatypePublishToBundle.value
4040
scalacOptions ++= Seq("-scalajs")
4141

42-
addCommandAlias("prepare", "fix; fmt")
43-
addCommandAlias("fmt", "all scalafmtSbt scalafmtAll")
42+
addCommandAlias("fmt", "all scalafmtSbt scalafmtAll;fix")
4443
addCommandAlias("fmtCheck", "all scalafmtSbtCheck scalafmtCheckAll")
4544
addCommandAlias("fix", "scalafixAll")
4645
addCommandAlias("fixCheck", "scalafixAll --check")

project/BuildHelper.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ object BuildHelper {
188188
baseDirectory.value
189189
)
190190
},
191-
nativeConfig ~= { _.withMultithreading(false) },
191+
nativeConfig ~= { _.withMultithreading(false) }
192192
)
193193

194194
def buildInfoSettings(packageName: String) = Seq(

zio-schema-avro/src/main/scala/zio/schema/codec/AvroSchemaCodec.scala

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,14 @@ object AvroSchemaCodec extends AvroSchemaCodec {
277277

278278
private def toAvroSchema(schema: Schema[_]): scala.util.Either[String, SchemaAvro] = {
279279
schema match {
280-
case e: Enum[_] => toAvroEnum(e)
281-
case record: Record[_] => toAvroRecord(record)
282-
case map: Schema.Map[_, _] => toAvroMap(map)
283-
case seq: Schema.Sequence[_, _, _] => toAvroSchema(seq.elementSchema).map(SchemaAvro.createArray)
284-
case set: Schema.Set[_] => toAvroSchema(set.elementSchema).map(SchemaAvro.createArray)
285-
case Transform(codec, _, _, _, _) => toAvroSchema(codec)
280+
case e: Enum[_] => toAvroEnum(e)
281+
case record: Record[_] => toAvroRecord(record)
282+
case map: Schema.Map[_, _] => toAvroMap(map)
283+
case map: Schema.NonEmptyMap[_, _] => toAvroMap(map)
284+
case seq: Schema.Sequence[_, _, _] => toAvroSchema(seq.elementSchema).map(SchemaAvro.createArray)
285+
case seq: Schema.NonEmptySequence[_, _, _] => toAvroSchema(seq.elementSchema).map(SchemaAvro.createArray)
286+
case set: Schema.Set[_] => toAvroSchema(set.elementSchema).map(SchemaAvro.createArray)
287+
case Transform(codec, _, _, _, _) => toAvroSchema(codec)
286288
case Primitive(standardType, _) =>
287289
standardType match {
288290
case StandardType.UnitType => Right(SchemaAvro.create(SchemaAvro.Type.NULL))
@@ -624,6 +626,18 @@ object AvroSchemaCodec extends AvroSchemaCodec {
624626
toAvroSchema(tupleSchema).map(SchemaAvro.createArray)
625627
}
626628

629+
private[codec] def toAvroMap(map: NonEmptyMap[_, _]): scala.util.Either[String, SchemaAvro] =
630+
map.keySchema match {
631+
case p: Schema.Primitive[_] if p.standardType == StandardType.StringType =>
632+
toAvroSchema(map.valueSchema).map(SchemaAvro.createMap)
633+
case _ =>
634+
val tupleSchema = Schema
635+
.Tuple2(map.keySchema, map.valueSchema)
636+
.annotate(AvroAnnotations.name("Tuple"))
637+
.annotate(AvroAnnotations.namespace("scala"))
638+
toAvroSchema(tupleSchema).map(SchemaAvro.createArray)
639+
}
640+
627641
private[codec] def toAvroDecimal(schema: Schema[_]): scala.util.Either[String, SchemaAvro] = {
628642
val scale = schema.annotations.collectFirst { case AvroAnnotations.scale(s) => s }
629643
.getOrElse(AvroAnnotations.scale().scale)
@@ -820,7 +834,9 @@ object AvroSchemaCodec extends AvroSchemaCodec {
820834
case c: Dynamic => Right(c)
821835
case c: GenericRecord => Right(c)
822836
case c: Map[_, _] => Right(c)
837+
case c: NonEmptyMap[_, _] => Right(c)
823838
case c: Sequence[_, _, _] => Right(c)
839+
case c: NonEmptySequence[_, _, _] => Right(c)
824840
case c: Set[_] => Right(c)
825841
case c: Fail[_] => Right(c)
826842
case c: Lazy[_] => Right(c)

zio-schema-avro/src/test/scala/zio/schema/codec/AvroSchemaCodecSpec.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,10 +1918,7 @@ object AssertionHelper {
19181918
def recordFields(assertion: Assertion[Iterable[Schema.Field[_, _]]]): Assertion[Schema.Record[_]] =
19191919
Assertion.assertionRec[Schema.Record[_], Chunk[Field[_, _]]]("hasRecordField")(
19201920
assertion
1921-
) {
1922-
case r: Schema.Record[_] => Some(r.fields)
1923-
case _ => None
1924-
}
1921+
)((r: Schema.Record[_]) => Some(r.fields))
19251922

19261923
def hasSequenceElementSchema[A](assertion: Assertion[Schema[A]]): Assertion[Schema.Sequence[_, A, _]] =
19271924
Assertion.hasField("schemaA", _.elementSchema, assertion)

zio-schema-bson/src/test/scala/zio/schema/codec/BsonSchemaCodecSpec.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ object BsonSchemaCodecSpec extends ZIOSpecDefault {
4040
implicit lazy val schema: Schema[Tree] = DeriveSchema.gen
4141
implicit lazy val codec: BsonCodec[Tree] = BsonSchemaCodec.bsonCodec(schema)
4242

43-
private val genLeaf = Gen.int.map(Leaf)
43+
private val genLeaf = Gen.int.map(Leaf.apply)
4444

4545
lazy val gen: Gen[Any, Tree] = Gen.sized { i =>
46-
if (i >= 2) Gen.oneOf(genLeaf, Gen.suspend(gen.zipWith(gen)(Branch)).resize(i / 2))
46+
if (i >= 2) Gen.oneOf(genLeaf, Gen.suspend(gen.zipWith(gen)(Branch.apply)).resize(i / 2))
4747
else genLeaf
4848
}
4949
}

zio-schema-derivation/shared/src/main/scala/zio/schema/CachedDeriver.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,18 +126,22 @@ private[schema] object CachedDeriver {
126126
final case class Tuple2[A, B](leftKey: CacheKey[A], rightKey: CacheKey[B]) extends CacheKey[(A, B)]
127127
final case class Set[A](element: CacheKey[A]) extends CacheKey[Set[A]]
128128
final case class Map[K, V](key: CacheKey[K], valuew: CacheKey[V]) extends CacheKey[Map[K, V]]
129+
final case class NonEmptyMap[K, V](key: CacheKey[K], valuew: CacheKey[V]) extends CacheKey[NonEmptyMap[K, V]]
129130
final case class Misc[A](schema: Schema[A]) extends CacheKey[A]
130131

131132
def fromStandardType[A](st: StandardType[A]): CacheKey[A] = Primitive(st)
132133

133134
def fromSchema[A](schema: Schema[A]): CacheKey[A] =
134135
schema match {
135-
case e: Schema.Enum[_] => WithId(e.id)
136-
case record: Schema.Record[_] => WithId(record.id)
137-
case seq: Schema.Sequence[_, _, _] => WithIdentityObject(fromSchema(seq.elementSchema), seq.identity)
138-
case set: Schema.Set[_] => Set(fromSchema(set.elementSchema)).asInstanceOf[CacheKey[A]]
136+
case e: Schema.Enum[_] => WithId(e.id)
137+
case record: Schema.Record[_] => WithId(record.id)
138+
case seq: Schema.Sequence[_, _, _] => WithIdentityObject(fromSchema(seq.elementSchema), seq.identity)
139+
case seq: Schema.NonEmptySequence[_, _, _] => WithIdentityObject(fromSchema(seq.elementSchema), seq.identity)
140+
case set: Schema.Set[_] => Set(fromSchema(set.elementSchema)).asInstanceOf[CacheKey[A]]
139141
case map: Schema.Map[_, _] =>
140142
Map(fromSchema(map.keySchema), fromSchema(map.valueSchema)).asInstanceOf[CacheKey[A]]
143+
case map: Schema.NonEmptyMap[_, _] =>
144+
Map(fromSchema(map.keySchema), fromSchema(map.valueSchema)).asInstanceOf[CacheKey[A]]
141145
case Schema.Transform(inner, _, _, _, identity) => WithIdentityObject(fromSchema(inner), identity)
142146
case Schema.Primitive(standardType, _) => fromStandardType(standardType)
143147
case optional: Schema.Optional[_] => Optional(fromSchema(optional.schema)).asInstanceOf[CacheKey[A]]

zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,11 @@ object JsonCodec {
183183
//scalafmt: { maxColumn = 400, optIn.configStyleArguments = false }
184184
private[codec] def schemaEncoder[A](schema: Schema[A], cfg: Config, discriminatorTuple: DiscriminatorTuple = Chunk.empty): ZJsonEncoder[A] =
185185
schema match {
186-
case Schema.Primitive(standardType, _) => primitiveCodec(standardType).encoder
187-
case Schema.Sequence(schema, _, g, _, _) => ZJsonEncoder.chunk(schemaEncoder(schema, cfg, discriminatorTuple)).contramap(g)
188-
case Schema.NonEmptySequence(schema, _, g, _, _) => ZJsonEncoder.chunk(schemaEncoder(schema, cfg, discriminatorTuple)).contramap(g)
189-
case Schema.Map(ks, vs, _) => mapEncoder(ks, vs, discriminatorTuple, cfg)
190-
case Schema.NonEmptyMap(ks, vs, _) => mapEncoder(ks, vs, discriminatorTuple, cfg).contramap[NonEmptyMap[Any, Any]](_.toMap.asInstanceOf[Map[Any, Any]]).asInstanceOf[ZJsonEncoder[A]]
186+
case Schema.Primitive(standardType, _) => primitiveCodec(standardType).encoder
187+
case Schema.Sequence(schema, _, g, _, _) => ZJsonEncoder.chunk(schemaEncoder(schema, cfg, discriminatorTuple)).contramap(g)
188+
case Schema.NonEmptySequence(schema, _, g, _, _) => ZJsonEncoder.chunk(schemaEncoder(schema, cfg, discriminatorTuple)).contramap(g)
189+
case Schema.Map(ks, vs, _) => mapEncoder(ks, vs, discriminatorTuple, cfg)
190+
case Schema.NonEmptyMap(ks: Schema[kt], vs: Schema[vt], _) => mapEncoder(ks, vs, discriminatorTuple, cfg).contramap[NonEmptyMap[kt, vt]](_.toMap.asInstanceOf[Map[kt, vt]]).asInstanceOf[ZJsonEncoder[A]]
191191
case Schema.Set(s, _) =>
192192
ZJsonEncoder.chunk(schemaEncoder(s, cfg, discriminatorTuple)).contramap(m => Chunk.fromIterable(m))
193193
case Schema.Transform(c, _, g, a, _) => transformEncoder(a.foldLeft(c)((s, a) => s.annotate(a)), g, cfg)

zio-schema-protobuf/shared/src/main/scala/zio/schema/codec/ProtobufCodec.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,6 @@ object ProtobufCodec {
182182
encodeKey(rightWireType, Some(2)) ++
183183
rightDecoder.remainder
184184
encodeKey(WireType.LengthDelimited(data.size), Some(seqIndex)) ++ data
185-
case other =>
186-
throw new IllegalStateException(s"Invalid state in processDictionary: $other")
187185
}
188186
}.flatten
189187
val data = encodeKey(
@@ -371,7 +369,7 @@ object ProtobufCodec {
371369
byteBuffer.order(ByteOrder.LITTLE_ENDIAN)
372370
byteBuffer.putDouble(v)
373371
encodeKey(WireType.Bit64, fieldNumber) ++ Chunk.fromArray(byteBuffer.array)
374-
case (StandardType.BinaryType, bytes: Chunk[Byte]) =>
372+
case (StandardType.BinaryType, bytes: Chunk[Byte] @unchecked) =>
375373
encodeKey(WireType.LengthDelimited(bytes.length), fieldNumber) ++ bytes
376374
case (StandardType.CharType, c: Char) =>
377375
encodePrimitive(fieldNumber, StandardType.StringType, c.toString)

zio-schema/shared/src/main/scala/zio/schema/Differ.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import java.util.{ Currency, UUID }
2525
import scala.annotation.nowarn
2626
import scala.collection.immutable.ListMap
2727

28+
import zio.prelude.NonEmptyMap
2829
import zio.schema.diff.Edit
2930
import zio.{ Chunk, ChunkBuilder }
3031

@@ -269,7 +270,7 @@ object Differ {
269270
case s @ Schema.NonEmptySequence(schema, _, f, _, _) => fromSchema(schema).chunk.transform(f, s.fromChunk)
270271
case Schema.Set(s, _) => set(s)
271272
case Schema.Map(k, v, _) => map(k, v)
272-
case s @ Schema.NonEmptyMap(k, v, _) => map(k, v).transform(_.toMap.asInstanceOf[Map[Any, Any]], s.fromMap)
273+
case s @ Schema.NonEmptyMap(k: Schema[kt], v: Schema[vt], _) => map(k, v).transform[NonEmptyMap[kt, vt]](_.toMap.asInstanceOf[Map[kt, vt]], s.fromMap).asInstanceOf[Differ[A]]
273274
case Schema.Either(leftSchema, rightSchema, _) => either(fromSchema(leftSchema), fromSchema(rightSchema))
274275
case Schema.Fallback(leftSchema, rightSchema, _, _) => fallback(fromSchema(leftSchema), fromSchema(rightSchema))
275276
case s @ Schema.Lazy(_) => fromSchema(s.schema)

0 commit comments

Comments
 (0)