From 430e39f9f69e7261bbe70c5c7d14750861248c09 Mon Sep 17 00:00:00 2001 From: Pierangelo Cecchetto Date: Tue, 9 Nov 2021 00:34:33 +0100 Subject: [PATCH] Rebased/reformatted --- .../scala/zio/schema/codec/JsonCodec.scala | 19 ++--- .../zio/schema/optics/ZioOpticsBuilder.scala | 4 +- .../zio/schema/codec/ProtobufCodec.scala | 70 ++++++++++--------- .../main/scala/zio/schema/DynamicValue.scala | 2 +- .../src/main/scala/zio/schema/Schema.scala | 11 +-- .../main/scala/zio/schema/ast/SchemaAst.scala | 6 +- .../scala/zio/schema/DynamicValueGen.scala | 4 +- 7 files changed, 61 insertions(+), 55 deletions(-) diff --git a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala index 8e3ecca5f..f0036d59a 100644 --- a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala +++ b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala @@ -101,9 +101,9 @@ object JsonCodec extends Codec { } private[codec] def schemaEncoder[A](schema: Schema[A]): JsonEncoder[A] = schema match { - case Schema.Primitive(standardType, _) => primitiveCodec(standardType) - case Schema.Sequence(schema, _, g, _) => JsonEncoder.chunk(schemaEncoder(schema)).contramap(g) - case Schema.MapSchema(ks, vs) => + case Schema.Primitive(standardType, _) => primitiveCodec(standardType) + case Schema.Sequence(schema, _, g, _) => JsonEncoder.chunk(schemaEncoder(schema)).contramap(g) + case Schema.MapSchema(ks, vs, _) => JsonEncoder.chunk(schemaEncoder(ks).both(schemaEncoder(vs))).contramap(m => Chunk.fromIterable(m)) case Schema.Transform(c, _, g, _) => transformEncoder(c, g) case Schema.Tuple(l, r, _) => JsonEncoder.tuple2(schemaEncoder(l), schemaEncoder(r)) @@ -190,12 +190,13 @@ object JsonCodec extends Codec { schemaDecoder(schema).decodeJson(json) private[codec] def schemaDecoder[A](schema: Schema[A]): JsonDecoder[A] = schema match { - case Schema.Primitive(standardType, _) => primitiveCodec(standardType) - case Schema.Optional(codec, _) => JsonDecoder.option(schemaDecoder(codec)) - case Schema.Tuple(left, right, _) => JsonDecoder.tuple2(schemaDecoder(left), schemaDecoder(right)) - case Schema.Transform(codec, f, _, _) => schemaDecoder(codec).mapOrFail(f) - case Schema.Sequence(codec, f, _, _) => JsonDecoder.chunk(schemaDecoder(codec)).map(f) - case Schema.MapSchema(ks, vs) => JsonDecoder.chunk(schemaDecoder(ks) <*> schemaDecoder(vs)).map(entries => entries.toList.toMap) + case Schema.Primitive(standardType, _) => primitiveCodec(standardType) + case Schema.Optional(codec, _) => JsonDecoder.option(schemaDecoder(codec)) + case Schema.Tuple(left, right, _) => JsonDecoder.tuple2(schemaDecoder(left), schemaDecoder(right)) + case Schema.Transform(codec, f, _, _) => schemaDecoder(codec).mapOrFail(f) + case Schema.Sequence(codec, f, _, _) => JsonDecoder.chunk(schemaDecoder(codec)).map(f) + case Schema.MapSchema(ks, vs, _) => + JsonDecoder.chunk(schemaDecoder(ks) <*> schemaDecoder(vs)).map(entries => entries.toList.toMap) case Schema.Fail(message, _) => failDecoder(message) case Schema.GenericRecord(structure, _) => recordDecoder(structure.toChunk) case Schema.EitherSchema(left, right, _) => JsonDecoder.either(schemaDecoder(left), schemaDecoder(right)) diff --git a/zio-schema-optics/shared/src/main/scala/zio/schema/optics/ZioOpticsBuilder.scala b/zio-schema-optics/shared/src/main/scala/zio/schema/optics/ZioOpticsBuilder.scala index f43af9bac..1248b1de8 100644 --- a/zio-schema-optics/shared/src/main/scala/zio/schema/optics/ZioOpticsBuilder.scala +++ b/zio-schema-optics/shared/src/main/scala/zio/schema/optics/ZioOpticsBuilder.scala @@ -42,12 +42,12 @@ object ZioOpticsBuilder extends AccessorBuilder { element: Schema[A] ): Optic[S, S, Chunk[A], OpticFailure, OpticFailure, Chunk[A], S] = collection match { - case seq @ Schema.Sequence(_, _, _) => + case seq @ Schema.Sequence(_, _, _, _) => ZTraversal( ZioOpticsBuilder.makeSeqTraversalGet(seq), ZioOpticsBuilder.makeSeqTraversalSet(seq) ) - case Schema.MapSchema(_, _) => + case Schema.MapSchema(_, _, _) => ZTraversal( ZioOpticsBuilder.makeMapTraversalGet, ZioOpticsBuilder.makeMapTraversalSet diff --git a/zio-schema-protobuf/shared/src/main/scala/zio/schema/codec/ProtobufCodec.scala b/zio-schema-protobuf/shared/src/main/scala/zio/schema/codec/ProtobufCodec.scala index b4c61d76e..8585a6009 100644 --- a/zio-schema-protobuf/shared/src/main/scala/zio/schema/codec/ProtobufCodec.scala +++ b/zio-schema-protobuf/shared/src/main/scala/zio/schema/codec/ProtobufCodec.scala @@ -132,22 +132,23 @@ object ProtobufCodec extends Codec { def encode[A](fieldNumber: Option[Int], schema: Schema[A], value: A): Chunk[Byte] = (schema, value) match { - case (Schema.GenericRecord(structure), v: Map[String, _]) => encodeRecord(fieldNumber, structure.toChunk, v) - case (Schema.Sequence(element, _, g), v) => encodeSequence(fieldNumber, element, g(v)) - case (Schema.MapSchema(ks, vs), v: Map[k, v]) => encodeSequence(fieldNumber, ks <*> vs, Chunk.fromIterable(v)) - case (Schema.Transform(codec, _, g), _) => g(value).map(encode(fieldNumber, codec, _)).getOrElse(Chunk.empty) - case (Schema.Primitive(standardType), v) => encodePrimitive(fieldNumber, standardType, v) - case (Schema.Tuple(left, right), v @ (_, _)) => encodeTuple(fieldNumber, left, right, v) - case (Schema.Optional(codec), v: Option[_]) => encodeOptional(fieldNumber, codec, v) - case (Schema.EitherSchema(left, right), v: Either[_, _]) => encodeEither(fieldNumber, left, right, v) - case (lzy @ Schema.Lazy(_), v) => encode(fieldNumber, lzy.schema, v) - case (Schema.Meta(ast), _) => encode(fieldNumber, Schema[SchemaAst], ast) - case ProductEncoder(encode) => encode(fieldNumber) - case (Schema.Enum1(c, _), v) => encodeEnum(fieldNumber, v, c) - case (Schema.Enum2(c1, c2, _), v) => encodeEnum(fieldNumber, v, c1, c2) - case (Schema.Enum3(c1, c2, c3, _), v) => encodeEnum(fieldNumber, v, c1, c2, c3) - case (Schema.EnumN(cs, _), v) => encodeEnum(fieldNumber, v, cs.toSeq: _*) - case (_, _) => Chunk.empty + case (Schema.GenericRecord(structure, _), v: Map[String, _]) => encodeRecord(fieldNumber, structure.toChunk, v) + case (Schema.Sequence(element, _, g, _), v) => encodeSequence(fieldNumber, element, g(v)) + case (Schema.MapSchema(ks, vs, _), v: Map[k, v]) => + encodeSequence(fieldNumber, ks <*> vs, Chunk.fromIterable(v)) + case (Schema.Transform(codec, _, g, _), _) => g(value).map(encode(fieldNumber, codec, _)).getOrElse(Chunk.empty) + case (Schema.Primitive(standardType, _), v) => encodePrimitive(fieldNumber, standardType, v) + case (Schema.Tuple(left, right, _), v @ (_, _)) => encodeTuple(fieldNumber, left, right, v) + case (Schema.Optional(codec, _), v: Option[_]) => encodeOptional(fieldNumber, codec, v) + case (Schema.EitherSchema(left, right, _), v: Either[_, _]) => encodeEither(fieldNumber, left, right, v) + case (lzy @ Schema.Lazy(_), v) => encode(fieldNumber, lzy.schema, v) + case (Schema.Meta(ast, _), _) => encode(fieldNumber, Schema[SchemaAst], ast) + case ProductEncoder(encode) => encode(fieldNumber) + case (Schema.Enum1(c, _), v) => encodeEnum(fieldNumber, v, c) + case (Schema.Enum2(c1, c2, _), v) => encodeEnum(fieldNumber, v, c1, c2) + case (Schema.Enum3(c1, c2, c3, _), v) => encodeEnum(fieldNumber, v, c1, c2, c3) + case (Schema.EnumN(cs, _), v) => encodeEnum(fieldNumber, v, cs.toSeq: _*) + case (_, _) => Chunk.empty } private def encodeEnum[Z](fieldNumber: Option[Int], value: Z, cases: Schema.Case[_, Z]*): Chunk[Byte] = { @@ -200,8 +201,6 @@ object ProtobufCodec extends Codec { encodeKey(WireType.LengthDelimited(chunk.size), fieldNumber) ++ chunk } -// private def encodeMap[K, V] - @scala.annotation.tailrec private def encodePrimitive[A]( fieldNumber: Option[Int], @@ -444,23 +443,28 @@ object ProtobufCodec extends Codec { }, true ) - case Schema.MapSchema(ks: Schema[k], vs: Schema[v]) => + case Schema.MapSchema(ks: Schema[k], vs: Schema[v], _) => decoder( - Schema.Sequence(ks <*> vs, (c: Chunk[(k, v)]) => c.toList.toMap, (m: Map[k, v]) => Chunk.fromIterable(m)) + Schema.Sequence( + ks <*> vs, + (c: Chunk[(k, v)]) => c.toList.toMap, + (m: Map[k, v]) => Chunk.fromIterable(m), + Chunk.empty + ) ) - case Schema.Transform(codec, f, _) => transformDecoder(codec, f) - case Schema.Primitive(standardType) => primitiveDecoder(standardType) - case Schema.Tuple(left, right) => tupleDecoder(left, right) - case Schema.Optional(codec) => optionalDecoder(codec) - case Schema.Fail(message) => fail(message) - case Schema.EitherSchema(left, right) => eitherDecoder(left, right) - case lzy @ Schema.Lazy(_) => decoder(lzy.schema) - case Schema.Meta(_) => astDecoder - case ProductDecoder(decoder) => decoder - case Schema.Enum1(c, _) => enumDecoder(c) - case Schema.Enum2(c1, c2, _) => enumDecoder(c1, c2) - case Schema.Enum3(c1, c2, c3, _) => enumDecoder(c1, c2, c3) - case Schema.EnumN(cs, _) => enumDecoder(cs.toSeq: _*) + case Schema.Transform(codec, f, _, _) => transformDecoder(codec, f) + case Schema.Primitive(standardType, _) => primitiveDecoder(standardType) + case Schema.Tuple(left, right, _) => tupleDecoder(left, right) + case Schema.Optional(codec, _) => optionalDecoder(codec) + case Schema.Fail(message, _) => fail(message) + case Schema.EitherSchema(left, right, _) => eitherDecoder(left, right) + case lzy @ Schema.Lazy(_) => decoder(lzy.schema) + case Schema.Meta(_, _) => astDecoder + case ProductDecoder(decoder) => decoder + case Schema.Enum1(c, _) => enumDecoder(c) + case Schema.Enum2(c1, c2, _) => enumDecoder(c1, c2) + case Schema.Enum3(c1, c2, c3, _) => enumDecoder(c1, c2, c3) + case Schema.EnumN(cs, _) => enumDecoder(cs.toSeq: _*) } private val astDecoder: Decoder[Schema[_]] = diff --git a/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala b/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala index 6a50247a8..ecc7403d6 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala @@ -952,7 +952,7 @@ object DynamicValue { case Schema.Sequence(schema, _, toChunk, _) => DynamicValue.Sequence(toChunk(value).map(fromSchemaAndValue(schema, _))) - case Schema.MapSchema(ks: Schema[k], vs: Schema[v]) => + case Schema.MapSchema(ks: Schema[k], vs: Schema[v], _) => val entries = value.asInstanceOf[Map[k, v]].map { case (key, value) => (fromSchemaAndValue(ks, key), fromSchemaAndValue(vs, value)) } diff --git a/zio-schema/shared/src/main/scala/zio/schema/Schema.scala b/zio-schema/shared/src/main/scala/zio/schema/Schema.scala index bd1acf00d..3bac366ae 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Schema.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Schema.scala @@ -1,9 +1,7 @@ package zio.schema import java.time.temporal.ChronoUnit - import scala.collection.immutable.ListMap - import zio.Chunk import zio.schema.ast._ @@ -207,7 +205,7 @@ object Schema extends TupleSchemas with RecordSchemas with EnumSchemas { Schema.Sequence[Chunk[A], A](schemaA, identity, identity, Chunk.empty) implicit def map[K, V](implicit ks: Schema[K], vs: Schema[V]): Schema[Map[K, V]] = - Schema.MapSchema(ks, vs) + Schema.MapSchema(ks, vs, Chunk.empty) implicit def either[A, B](implicit left: Schema[A], right: Schema[B]): Schema[Either[A, B]] = EitherSchema(left, right) @@ -249,7 +247,7 @@ object Schema extends TupleSchemas with RecordSchemas with EnumSchemas { fromChunk: Chunk[Elem] => Col, toChunk: Col => Chunk[Elem], override val annotations: Chunk[Any] - ) extends Collection[Col, Elem] { self => + ) extends Collection[Col, Elem] { self => override type Accessors[Lens[_, _], Prism[_, _], Traversal[_, _]] = Traversal[Col, Elem] override def annotate(annotation: Any): Sequence[Col, Elem] = copy(annotations = annotations :+ annotation) @@ -382,9 +380,12 @@ object Schema extends TupleSchemas with RecordSchemas with EnumSchemas { } - final case class MapSchema[K, V](ks: Schema[K], vs: Schema[V]) extends Collection[Map[K, V], (K, V)] { self => + final case class MapSchema[K, V](ks: Schema[K], vs: Schema[V], override val annotations: Chunk[Any]) + extends Collection[Map[K, V], (K, V)] { self => override type Accessors[Lens[_, _], Prism[_, _], Traversal[_, _]] = Traversal[Map[K, V], (K, V)] + override def annotate(annotation: Any): MapSchema[K, V] = copy(annotations = annotations :+ annotation) + override def makeAccessors(b: AccessorBuilder): b.Traversal[Map[K, V], (K, V)] = b.makeTraversal(self, ks <*> vs) } diff --git a/zio-schema/shared/src/main/scala/zio/schema/ast/SchemaAst.scala b/zio-schema/shared/src/main/scala/zio/schema/ast/SchemaAst.scala index 5643d85ee..8e1e24757 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/ast/SchemaAst.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/ast/SchemaAst.scala @@ -188,7 +188,7 @@ object SchemaAst { .buildProduct() case Schema.Sequence(schema, _, _, _) => subtree(NodePath.root, Chunk.empty, schema, dimensions = 1) - case Schema.MapSchema(ks, vs) => + case Schema.MapSchema(ks, vs, _) => NodeBuilder(NodePath.root, Chunk.empty, optional = false, dimensions = 1) .addLabelledSubtree("key", ks) .addLabelledSubtree("value", vs) @@ -240,8 +240,8 @@ object SchemaAst { .buildProduct() case Schema.Sequence(schema, _, _, _) => subtree(path, lineage, schema, optional, dimensions + 1) - case Schema.MapSchema(ks, vs) => - subtree(path, lineage, ks <*> vs, optional = false, dimensions + 1) + case Schema.MapSchema(ks, vs, _) => + subtree(path, lineage, ks <*> vs, optional = false, dimensions + 1) case Schema.Transform(schema, _, _, _) => subtree(path, lineage, schema, optional, dimensions) case lzy @ Schema.Lazy(_) => subtree(path, lineage, lzy.schema, optional, dimensions) case s: Schema.Record[_] => diff --git a/zio-schema/shared/src/test/scala/zio/schema/DynamicValueGen.scala b/zio-schema/shared/src/test/scala/zio/schema/DynamicValueGen.scala index 57169d368..6086e4f1b 100644 --- a/zio-schema/shared/src/test/scala/zio/schema/DynamicValueGen.scala +++ b/zio-schema/shared/src/test/scala/zio/schema/DynamicValueGen.scala @@ -47,7 +47,7 @@ object DynamicValueGen { //scalafmt: { maxColumn = 400 } def anyDynamicValueOfSchema[A](schema: Schema[A]): Gen[Random with Sized, DynamicValue] = schema match { - case Schema.Primitive(standardType, _) => anyPrimitiveDynamicValue(standardType) + case Schema.Primitive(standardType, _) => anyPrimitiveDynamicValue(standardType) case s: Schema.Record[A] => anyDynamicValueWithStructure(s.structure) case Schema.Enum1(case1, _) => anyDynamicValueOfEnum(Chunk(case1)) case Schema.Enum2(case1, case2, _) => anyDynamicValueOfEnum(Chunk(case1, case2)) @@ -73,7 +73,7 @@ object DynamicValueGen { case Schema.Enum22(case1, case2, case3, case4, case5, case6, case7, case8, case9, case10, case11, case12, case13, case14, case15, case16, case17, case18, case19, case20, case21, case22, _) => anyDynamicValueOfEnum(Chunk(case1, case2, case3, case4, case5, case6, case7, case8, case9, case10, case11, case12, case13, case14, case15, case16, case17, case18, case19, case20, case21, case22)) case Schema.EnumN(cases, _) => anyDynamicValueOfEnum(Chunk.fromIterable(cases.toSeq)) case Schema.Sequence(schema, _, _, _) => Gen.chunkOfBounded(0, 2)(anyDynamicValueOfSchema(schema)).map(DynamicValue.Sequence(_)) - case Schema.MapSchema(ks, vs) => Gen.chunkOfBounded(0, 2)(anyDynamicValueOfSchema(ks) zip anyDynamicValueOfSchema(vs)).map(DynamicValue.Dictionary(_)) + case Schema.MapSchema(ks, vs, _) => Gen.chunkOfBounded(0, 2)(anyDynamicValueOfSchema(ks).zip(anyDynamicValueOfSchema(vs))).map(DynamicValue.Dictionary(_)) case Schema.Optional(schema, _) => Gen.oneOf(anyDynamicSomeValueOfSchema(schema), Gen.const(DynamicValue.NoneValue)) case Schema.Tuple(left, right, _) => anyDynamicTupleValue(left, right) case Schema.EitherSchema(left, right, _) =>