From 815716b44bfd9fdc41dd30aef9980abb103f89b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=8BAndrzej=20Ressel?= Date: Sun, 30 Apr 2023 16:19:22 +0200 Subject: [PATCH 1/6] Rewrite DynamicValue error handling to Validate --- .../scala-2/zio/schema/DynamicValueSpec.scala | 3 +- .../zio/schema/example/example7/Problem.scala | 3 +- .../main/scala/zio/schema/DynamicValue.scala | 109 +++++++++--------- .../src/main/scala/zio/schema/Patch.scala | 58 +++++----- .../src/main/scala/zio/schema/Schema.scala | 2 +- .../main/scala/zio/schema/StandardType.scala | 4 +- .../scala/zio/schema/codec/DecodeError.scala | 6 - 7 files changed, 88 insertions(+), 97 deletions(-) diff --git a/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala b/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala index 26f91be2d..aad09121b 100644 --- a/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala @@ -1,6 +1,7 @@ package zio.schema import zio._ +import zio.prelude.Validation import zio.schema.Schema.Primitive import zio.schema.SchemaGen._ import zio.test.Assertion._ @@ -97,7 +98,7 @@ object DynamicValueSpec extends ZIOSpecDefault { check(Json.genDeep) { json => val dyn = DynamicValue.fromSchemaAndValue(Json.schema, json) val json2 = dyn.toTypedValue(Json.schema) - assertTrue(json2 == Right(json)) + assertTrue(json2 == Validation.succeed(json)) } } @@ TestAspect.size(250) @@ TestAspect.ignore ) diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala index 9548d3e46..393e9b017 100644 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala +++ b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala @@ -2,7 +2,6 @@ package dev.zio.schema.example.example7 import scala.collection.immutable.ListMap import scala.util.Try - import zio.schema._ import zio.{ Chunk, Unsafe } @@ -44,7 +43,7 @@ private[example7] object Problem { params: Map[String, List[String]] )(implicit schema: Schema[A]): scala.util.Either[String, A] = toDV(params) - .map(_.toTypedValue(schema)) + .map(_.toTypedValue(schema).toEither) .collectFirst { case Right(v) => v 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 eae9bb983..4620ec2f0 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala @@ -1,11 +1,11 @@ package zio.schema +import zio.prelude.Validation + import java.math.{ BigDecimal, BigInteger } import java.time._ import java.util.UUID - import scala.collection.immutable.ListMap - import zio.schema.codec.DecodeError import zio.schema.meta.{ MetaSchema, Migration } import zio.{ Cause, Chunk, Unsafe } @@ -19,33 +19,37 @@ sealed trait DynamicValue { case (_, error @ Left(_)) => error } - def toTypedValue[A](implicit schema: Schema[A]): Either[String, A] = - toTypedValueLazyError.left.map(_.message) + def toTypedValue[A](implicit schema: Schema[A]): Validation[String, A] = + toTypedValueLazyError.mapError(_.toString) - def toValue[A](implicit schema: Schema[A]): Either[DecodeError, A] = toTypedValueLazyError + def toValue[A](implicit schema: Schema[A]): Validation[DecodeError, A] = toTypedValueLazyError def toTypedValueOption[A](implicit schema: Schema[A]): Option[A] = toTypedValueLazyError.toOption - private def toTypedValueLazyError[A](implicit schema: Schema[A]): Either[DecodeError, A] = + private def toTypedValueLazyError[A](implicit schema: Schema[A]): Validation[DecodeError, A] = (self, schema) match { case (DynamicValue.Primitive(value, p), Schema.Primitive(p2, _)) if p == p2 => - Right(value.asInstanceOf[A]) + Validation.succeed(value.asInstanceOf[A]) case (DynamicValue.Record(_, values), Schema.GenericRecord(_, structure, _)) => - DynamicValue.decodeStructure(values, structure.toChunk).asInstanceOf[Either[DecodeError, A]] + DynamicValue.decodeStructure(values, structure.toChunk).asInstanceOf[Validation[DecodeError, A]] case (DynamicValue.Record(_, values), s: Schema.Record[A]) => DynamicValue .decodeStructure(values, s.fields) .map(m => Chunk.fromIterable(m.values)) - .flatMap(values => s.construct(values)(Unsafe.unsafe).left.map(err => DecodeError.MalformedField(s, err))) + .flatMap( + values => + Validation + .fromEither(s.construct(values)(Unsafe.unsafe).left.map(err => DecodeError.MalformedField(s, err))) + ) case (DynamicValue.Enumeration(_, (key, value)), s: Schema.Enum[A]) => s.caseOf(key) match { case Some(caseValue) => - value.toTypedValueLazyError(caseValue.schema).asInstanceOf[Either[DecodeError, A]] - case None => Left(DecodeError.MissingCase(key, s)) + value.toTypedValueLazyError(caseValue.schema).asInstanceOf[Validation[DecodeError, A]] + case None => Validation.fail(DecodeError.MissingCase(key, s)) } case (DynamicValue.LeftValue(value), Schema.Either(schema1, _, _)) => @@ -57,66 +61,59 @@ sealed trait DynamicValue { case (DynamicValue.Tuple(leftValue, rightValue), Schema.Tuple2(leftSchema, rightSchema, _)) => val typedLeft = leftValue.toTypedValueLazyError(leftSchema) val typedRight = rightValue.toTypedValueLazyError(rightSchema) - (typedLeft, typedRight) match { - case (Left(e1), Left(e2)) => - Left(DecodeError.And(e1, e2)) - case (_, Left(e)) => Left(e) - case (Left(e), _) => Left(e) - case (Right(a), Right(b)) => Right(a -> b) - } + Validation + .validate(typedLeft, typedRight) case (DynamicValue.Sequence(values), schema: Schema.Sequence[col, t, _]) => - values - .foldLeft[Either[DecodeError, Chunk[t]]](Right[DecodeError, Chunk[t]](Chunk.empty)) { - case (err @ Left(_), _) => err - case (Right(values), value) => - value.toTypedValueLazyError(schema.elementSchema).map(values :+ _) - } + Validation + .validateAll( + values.map(_.toTypedValueLazyError(schema.elementSchema)) + ) .map(schema.fromChunk) case (DynamicValue.SetValue(values), schema: Schema.Set[t]) => - values.foldLeft[Either[DecodeError, Set[t]]](Right[DecodeError, Set[t]](Set.empty)) { - case (err @ Left(_), _) => err - case (Right(values), value) => - value.toTypedValueLazyError(schema.elementSchema).map(values + _) - } + Validation + .validateAll( + values.map(_.toTypedValueLazyError(schema.elementSchema)) + ) case (DynamicValue.SomeValue(value), Schema.Optional(schema: Schema[_], _)) => value.toTypedValueLazyError(schema).map(Some(_)) case (DynamicValue.NoneValue, Schema.Optional(_, _)) => - Right(None) + Validation.succeed(None) case (value, Schema.Transform(schema, f, _, _, _)) => value .toTypedValueLazyError(schema) - .flatMap(value => f(value).left.map(err => DecodeError.MalformedField(schema, err))) + .flatMap(value => Validation.fromEither(f(value).left.map(err => DecodeError.MalformedField(schema, err)))) case (DynamicValue.Dictionary(entries), schema: Schema.Map[k, v]) => - entries.foldLeft[Either[DecodeError, Map[k, v]]](Right[DecodeError, Map[k, v]](Map.empty)) { - case (err @ Left(_), _) => err - case (Right(map), entry) => { - for { - key <- entry._1.toTypedValueLazyError(schema.keySchema) - value <- entry._2.toTypedValueLazyError(schema.valueSchema) - } yield map ++ Map(key -> value) - } - } + Validation + .validateAll( + entries.map { entry => + for { + key <- entry._1.toTypedValueLazyError(schema.keySchema) + value <- entry._2.toTypedValueLazyError(schema.valueSchema) + } yield key -> value + } + ) + .map(_.toMap) case (_, l @ Schema.Lazy(_)) => toTypedValueLazyError(l.schema) case (DynamicValue.Error(message), _) => - Left(DecodeError.ReadError(Cause.empty, message)) + Validation.fail(DecodeError.ReadError(Cause.empty, message)) case (DynamicValue.Tuple(dyn, DynamicValue.DynamicAst(ast)), _) => val valueSchema = ast.toSchema.asInstanceOf[Schema[Any]] dyn.toTypedValueLazyError(valueSchema).map(a => (a -> valueSchema).asInstanceOf[A]) - case (dyn, Schema.Dynamic(_)) => Right(dyn) + case (dyn, Schema.Dynamic(_)) => Validation.succeed(dyn) case _ => - Left(DecodeError.CastError(self, schema)) + Validation.fail(DecodeError.CastError(self, schema)) } } @@ -183,18 +180,20 @@ object DynamicValue { def decodeStructure( values: ListMap[String, DynamicValue], structure: Chunk[Schema.Field[_, _]] - ): Either[DecodeError, ListMap[String, _]] = { - val keys = values.keySet - keys.foldLeft[Either[DecodeError, ListMap[String, Any]]](Right(ListMap.empty)) { - case (Right(record), key) => - (structure.find(_.name == key), values.get(key)) match { - case (Some(field), Some(value)) => - value.toTypedValueLazyError(field.schema).map(value => (record + (key -> value))) - case _ => - Left(DecodeError.IncompatibleShape(values, structure)) - } - case (Left(err), _) => Left(err) - } + ): Validation[DecodeError, ListMap[String, _]] = { + val keys = values.keys.toSeq + Validation + .validateAll( + keys.map(key => { + (structure.find(_.name == key), values.get(key)) match { + case (Some(field), Some(value)) => + value.toTypedValueLazyError(field.schema).map(value => (key -> value)) + case _ => + Validation.fail(DecodeError.IncompatibleShape(values, structure)) + } + }) + ) + .map(seq => ListMap.from(seq)) } final case class Record(id: TypeId, values: ListMap[String, DynamicValue]) extends DynamicValue diff --git a/zio-schema/shared/src/main/scala/zio/schema/Patch.scala b/zio-schema/shared/src/main/scala/zio/schema/Patch.scala index 5d5e7e70b..63fa573b5 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Patch.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Patch.scala @@ -1,10 +1,14 @@ package zio.schema +import zio.Chunk +import zio.schema.diff.Edit +import zio.schema.meta.Migration +import zio.prelude.Validation + import java.math.{ BigInteger, MathContext } import java.time.temporal.{ ChronoField, ChronoUnit } import java.time.{ DayOfWeek, - Duration => JDuration, Instant, LocalDate, LocalDateTime, @@ -17,16 +21,12 @@ import java.time.{ YearMonth, ZoneId, ZoneOffset, + Duration => JDuration, ZonedDateTime => JZonedDateTime } - import scala.annotation.tailrec import scala.collection.immutable.ListMap -import zio.Chunk -import zio.schema.diff.Edit -import zio.schema.meta.Migration - sealed trait Patch[A] { self => /** @@ -320,34 +320,32 @@ object Patch { val structure = schema.fields val patchedDynamicValue = schema.toDynamic(input) match { - case DynamicValue.Record(name, values) => { - differences - .foldLeft[Either[String, ListMap[String, DynamicValue]]](Right(values)) { - case (Right(record), (key, diff)) => - (structure.find(_.name == key).map(_.schema), values.get(key)) match { - case (Some(schema: Schema[b]), Some(oldValue)) => - val oldVal = oldValue.toTypedValue(schema) - oldVal - .flatMap(v => diff.asInstanceOf[Patch[Any]].patch(v)) - .map(v => schema.asInstanceOf[Schema[Any]].toDynamic(v)) match { - case Left(error) => Left(error) - case Right(newValue) => Right(record + (key -> newValue)) - } - case _ => - Left(s"Values=$values and structure=$structure have incompatible shape.") - } - case (Left(string), _) => Left(string) - } - .map(r => (name, r)) - - } + case DynamicValue.Record(name, values) => + Validation + .validateAll( + differences.map { + case (key, diff) => + (structure.find(_.name == key).map(_.schema), values.get(key)) match { + case (Some(schema: Schema[b]), Some(oldValue)) => + val oldVal = oldValue.toTypedValue(schema) + oldVal + .flatMap(v => Validation.fromEither(diff.asInstanceOf[Patch[Any]].patch(v))) + .map(v => schema.asInstanceOf[Schema[Any]].toDynamic(v)) + .map(newValue => key -> newValue) + case _ => + Validation.fail(s"Values=$values and structure=$structure have incompatible shape.") + } + } + ) + .map(r => (name, ListMap.from(r))) - case dv => Left(s"Failed to apply record diff. Unexpected dynamic value for record: $dv") + case dv => Validation.fail(s"Failed to apply record diff. Unexpected dynamic value for record: $dv") } patchedDynamicValue.flatMap { newValues => - schema.fromDynamic(DynamicValue.Record(newValues._1, newValues._2)) - } + Validation.fromEither(schema.fromDynamic(DynamicValue.Record(newValues._1, newValues._2))) + }.toEither.left + .map(_.toString()) } def orIdentical: Patch[R] = 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 26eb6c168..fd3157ebf 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Schema.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Schema.scala @@ -92,7 +92,7 @@ sealed trait Schema[A] { def patch(oldValue: A, diff: Patch[A]): scala.util.Either[String, A] = diff.patch(oldValue) def fromDynamic(value: DynamicValue): scala.util.Either[String, A] = - value.toTypedValue(self) + value.toTypedValue(self).toEither.left.map(_.toString) def makeAccessors(b: AccessorBuilder): Accessors[b.Lens, b.Prism, b.Traversal] diff --git a/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala b/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala index 8be43c8a4..1a403cd78 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala @@ -3,8 +3,8 @@ package zio.schema import java.math.BigInteger import java.time import java.time._ - import zio.Chunk +import zio.prelude.Validation sealed trait StandardType[A] extends Ordering[A] { self => def tag: String @@ -14,7 +14,7 @@ sealed trait StandardType[A] extends Ordering[A] { self => /** * Converts a DynamicValue into a primitive type. */ - def toTypedPrimitive(value: DynamicValue): Either[String, A] = + def toTypedPrimitive(value: DynamicValue): Validation[String, A] = value.toTypedValue(Schema.primitive[A](self)) } diff --git a/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala b/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala index 2189922ef..520c61f87 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala @@ -13,17 +13,11 @@ sealed trait DecodeError extends Exception with NoStackTrace { self => override def getMessage(): String = message - def and(that: DecodeError): DecodeError = DecodeError.And(self, that) - def or(that: DecodeError): DecodeError = DecodeError.Or(self, that) } object DecodeError { - final case class And(left: DecodeError, right: DecodeError) extends DecodeError { - def message: String = s"${left.message} and ${right.message}" - } - final case class Or(left: DecodeError, right: DecodeError) extends DecodeError { override def message: String = s"${left.message} or ${right.message}" } From 34da1f0f797dbd0a5277d041e5e18f3833b00e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=8BAndrzej=20Ressel?= Date: Sun, 30 Apr 2023 16:46:48 +0200 Subject: [PATCH 2/6] Rewriting codebase to Validation --- .sbtopts | 2 +- .../zio/schema/codec/CodecBenchmarks.scala | 2 +- .../zio/schema/codec/ProtobufBenchmarks.scala | 2 +- .../zio/schema/AccessorBuilderSpec.scala | 4 +- .../scala-2/zio/schema/DynamicValueSpec.scala | 28 +- .../scala-2/zio/schema/OrderingSpec.scala | 20 +- .../test/scala-2/zio/schema/PatchSpec.scala | 8 +- .../test/scala-2/zio/schema/SchemaGen.scala | 12 +- .../zio/schema/SchemaMigrationSpec.scala | 16 +- .../src/test/scala-2/zio/schema/types.scala | 30 +- .../scala/zio/schema/DefaultValueSpec.scala | 84 ++-- .../test/scala/zio/schema/MigrationSpec.scala | 12 +- .../test/scala/zio/schema/SchemaSpec.scala | 8 +- .../scala/zio/schema/ast/NodePathSpec.scala | 2 +- .../scala/zio/schema/codec/AvroCodec.scala | 294 +++++++------- .../zio/schema/codec/AvroPropMarker.scala | 38 +- .../zio/schema/codec/AvroCodecSpec.scala | 360 +++++++++--------- .../src/main/scala-2/zio/schema/Derive.scala | 6 +- .../scala-2/zio/schema/DeriveSchema.scala | 6 +- .../src/main/scala-3/zio/schema/Derive.scala | 10 +- .../scala-3/zio/schema/DeriveSchema.scala | 6 +- .../main/scala/zio/schema/CachedDeriver.scala | 12 +- .../src/main/scala/zio/schema/Deriver.scala | 16 +- .../scala/zio/schema/DeriveSchemaSpec.scala | 4 +- .../test/scala/zio/schema/DeriveSpec.scala | 12 +- .../zio/schema/SchemaValidationSpec.scala | 6 +- .../example4/Example4Transformation.scala | 8 +- .../example6/Example6_ReifiedOptics.scala | 4 +- .../zio/schema/example/example7/Problem.scala | 40 +- .../zio/schema/example/example8/Decoder.scala | 16 +- .../zio/schema/example/example8/Usage.scala | 4 +- .../schema/example/example9/Patching.scala | 6 +- .../scala/zio/schema/codec/JsonCodec.scala | 16 +- .../zio/schema/codec/JsonCodecSpec.scala | 20 +- .../zio/schema/codec/MessagePackCodec.scala | 2 +- .../zio/schema/codec/MessagePackDecoder.scala | 18 +- .../zio/schema/codec/MessagePackEncoder.scala | 6 +- .../schema/codec/MessagePackCodecSpec.scala | 14 +- .../zio/schema/optics/ZioOpticsBuilder.scala | 38 +- .../scala/zio/schema/optics/LensSpec.scala | 4 +- .../zio/schema/codec/ProtobufCodec.scala | 32 +- .../zio/schema/codec/ProtobufCodecSpec.scala | 24 +- .../scala/zio/schema/codec/ThriftCodec.scala | 36 +- .../zio/schema/codec/ThriftCodecSpec.scala | 14 +- .../src/main/scala/zio/schema/DeriveGen.scala | 2 +- .../src/test/scala/zio/schema/TestData.scala | 4 +- .../src/main/scala/zio/schema/Differ.scala | 42 +- .../main/scala/zio/schema/DynamicValue.scala | 16 +- .../MutableSchemaBasedValueBuilder.scala | 28 +- .../MutableSchemaBasedValueProcessor.scala | 28 +- .../src/main/scala/zio/schema/Patch.scala | 151 ++++---- .../src/main/scala/zio/schema/Schema.scala | 304 ++++++++------- .../scala/zio/schema/SchemaEquality.scala | 2 +- .../main/scala/zio/schema/StandardType.scala | 150 ++++---- .../scala/zio/schema/codec/BinaryCodecs.scala | 2 +- .../main/scala/zio/schema/codec/Codecs.scala | 4 +- .../main/scala/zio/schema/codec/Decoder.scala | 2 +- .../schema/meta/ExtensibleMetaSchema.scala | 14 +- .../scala/zio/schema/meta/Migration.scala | 162 ++++---- .../main/scala/zio/schema/meta/NodePath.scala | 2 +- .../src/main/scala/zio/schema/syntax.scala | 4 +- .../zio/schema/validation/Predicate.scala | 16 +- .../zio/schema/validation/Validation.scala | 8 +- .../scala/zio/schema/SchemaAssertions.scala | 2 +- 64 files changed, 1133 insertions(+), 1112 deletions(-) diff --git a/.sbtopts b/.sbtopts index ae2b88708..66610b278 100644 --- a/.sbtopts +++ b/.sbtopts @@ -1,4 +1,4 @@ -J-Xms5120m -J-Xmx5120m --J-XX:MaxMetaspaceSize=1024m +-J-XX:MaxMetaspaceSize=2048m -J-XX:MetaspaceSize=760m \ No newline at end of file diff --git a/benchmarks/src/main/scala/zio/schema/codec/CodecBenchmarks.scala b/benchmarks/src/main/scala/zio/schema/codec/CodecBenchmarks.scala index 334b0da7d..b894b19f3 100644 --- a/benchmarks/src/main/scala/zio/schema/codec/CodecBenchmarks.scala +++ b/benchmarks/src/main/scala/zio/schema/codec/CodecBenchmarks.scala @@ -15,7 +15,7 @@ object CodecBenchmarks { val statusProtobufEncoder: Status => Chunk[Byte] = ProtobufCodec.protobufCodec[Status].encode - val statusProtobufDecoder: Chunk[Byte] => Either[DecodeError, Status] = + val statusProtobufDecoder: Chunk[Byte] => zio.prelude.Validation[DecodeError, Status] = ProtobufCodec.protobufCodec[Status].decode val statuses: Array[Status] = Array( diff --git a/benchmarks/src/main/scala/zio/schema/codec/ProtobufBenchmarks.scala b/benchmarks/src/main/scala/zio/schema/codec/ProtobufBenchmarks.scala index da14574f1..313b370fe 100644 --- a/benchmarks/src/main/scala/zio/schema/codec/ProtobufBenchmarks.scala +++ b/benchmarks/src/main/scala/zio/schema/codec/ProtobufBenchmarks.scala @@ -58,7 +58,7 @@ class ProtobufBenchmarks { byteChunkCodec.encode(bigByteChunk) @Benchmark - def decodeLargeByteChunk(): Either[DecodeError, Chunk[Byte]] = + def decodeLargeByteChunk(): zio.prelude.Validation[DecodeError, Chunk[Byte]] = byteChunkCodec.decode(encodedBigByteChunk) } diff --git a/tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala b/tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala index d2b467cf7..fbfa5797b 100644 --- a/tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala @@ -84,8 +84,8 @@ object AccessorBuilderSpec extends ZIOSpecDefault { test("either") { check(SchemaGen.anyPrimitive <*> SchemaGen.anyPrimitive) { case (leftSchema, rightSchema) => - val eitherSchema: Schema.Either[_, _] = - (rightSchema <+> leftSchema).asInstanceOf[Schema.Either[_, _]] + val eitherSchema: Schema.zio.prelude.Validation[_, _] = + (rightSchema <+> leftSchema).asInstanceOf[Schema.zio.prelude.Validation[_, _]] val accessor = eitherSchema.makeAccessors(builder) assert( diff --git a/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala b/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala index aad09121b..13ec5c647 100644 --- a/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala @@ -15,48 +15,48 @@ object DynamicValueSpec extends ZIOSpecDefault { suite("Primitives")(primitiveTests: _*), test("round-trips Records") { check(SchemaGen.anyRecordOfRecordsAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips Enumerations") { check(SchemaGen.anyEnumerationAndValue) { case (schema, a) => - assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips Eithers") { check(SchemaGen.anyEitherAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips Tuples") { check(SchemaGen.anyTupleAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips Optionals") { check(SchemaGen.anyOptionalAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips Transform") { check(SchemaGen.anyTransformAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips CaseClass") { check(SchemaGen.anyCaseClassAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips Enum") { check(SchemaGen.anyEnumAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips any un-nested schema") { check(SchemaGen.anyLeafAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips any nested schema") { @@ -68,22 +68,22 @@ object DynamicValueSpec extends ZIOSpecDefault { test("round-trips recursive data types") { check(SchemaGen.anyRecursiveTypeAndValue) { case (schema, a) => - assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips sequence") { check(SchemaGen.anySequenceAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips set") { check(SchemaGen.anySetAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } }, test("round-trips map") { check(SchemaGen.anyMapAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } } ), @@ -113,7 +113,7 @@ object DynamicValueSpec extends ZIOSpecDefault { private def dynamicValueLaw[R, A](gen: Gen[R, A], schema: Schema[A]): URIO[R with TestConfig, TestResult] = check(gen) { a => - assert(schema.fromDynamic(schema.toDynamic(a)))(isRight(equalTo(a))) + assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) } } diff --git a/tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala b/tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala index 2e33499d3..5a759c5df 100644 --- a/tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala @@ -88,27 +88,27 @@ object OrderingSpec extends ZIOSpecDefault { } yield (None, Some(a)) ) - def genAnyOrderedPairEither: Gen[Sized, SchemaAndPair[Either[_, _]]] = + def genAnyOrderedPairEither: Gen[Sized, SchemaAndPair[zio.prelude.Validation[_, _]]] = for { leftSchema <- anySchema rightSchema <- anySchema (l, r) <- genOrderedPairEither(leftSchema, rightSchema) - } yield (Schema.Either(leftSchema, rightSchema), l, r).asInstanceOf[SchemaAndPair[Either[_, _]]] + } yield (Schema.Either(leftSchema, rightSchema), l, r).asInstanceOf[SchemaAndPair[zio.prelude.Validation[_, _]]] - def genOrderedPairEither[A, B]( + def genOrderedPairzio.prelude.Validation[A, B]( lSchema: Schema[A], rSchema: Schema[B] - ): Gen[Sized, (Either[A, B], Either[A, B])] = Gen.oneOf( + ): Gen[Sized, (zio.prelude.Validation[A, B], zio.prelude.Validation[A, B])] = Gen.oneOf( for { (small, large) <- genOrderedPair(lSchema) } yield (Left(small), Left(large)), for { (small, large) <- genOrderedPair(rSchema) - } yield (Right(small), Right(large)), + } yield (zio.prelude.Validation.succeed(small), zio.prelude.Validation.succeed(large)), for { l <- genFromSchema(lSchema) r <- genFromSchema(rSchema) - } yield (Left(l), Right(r)) + } yield (Left(l), zio.prelude.Validation.succeed(r)) ) def genAnyOrderedPairTuple: Gen[Sized, SchemaAndPair[_]] = @@ -116,7 +116,7 @@ object OrderingSpec extends ZIOSpecDefault { xSchema <- anySchema ySchema <- anySchema (l, r) <- genOrderedPairTuple(xSchema, ySchema) - } yield (Schema.Tuple2(xSchema, ySchema), l, r).asInstanceOf[SchemaAndPair[Either[_, _]]] + } yield (Schema.Tuple2(xSchema, ySchema), l, r).asInstanceOf[SchemaAndPair[zio.prelude.Validation[_, _]]] def genOrderedPairTuple[A, B]( xSchema: Schema[A], @@ -171,9 +171,9 @@ object OrderingSpec extends ZIOSpecDefault { for { (small, large) <- genOrderedPair(schema) } yield (schema.transformOrFail({ (a: A) => - Right(a) + zio.prelude.Validation.succeed(a) }, { (a: A) => - Right(a) + zio.prelude.Validation.succeed(a) }), small, large) def genOrderedPairDecodeTransform[A]( @@ -182,7 +182,7 @@ object OrderingSpec extends ZIOSpecDefault { for { error <- Gen.boolean (small, large) <- genOrderedPair(schema) - encode = (a: A) => Right(schema.toDynamic(a)) + encode = (a: A) => zio.prelude.Validation.succeed(schema.toDynamic(a)) decode = schema.fromDynamic(_) smallEncoded = encode(small).toOption.get smallEncodedOrError = if (error) DynamicValue.SomeValue(smallEncoded) else smallEncoded diff --git a/tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala b/tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala index f20285052..e6cc2c6c8 100644 --- a/tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala @@ -19,7 +19,7 @@ object PatchSpec extends ZIOSpecDefault { test("Boolean")(patchIdentityLaw[Boolean]), test("Bytes")(patchIdentityLaw[Chunk[Byte]]), suite("Either") { - test("primitive")(patchIdentityLaw[Either[String, String]]) + test("primitive")(patchIdentityLaw[zio.prelude.Validation[String, String]]) }, suite("Option") { test("primitive")(patchIdentityLaw[Option[String]]) @@ -160,7 +160,7 @@ object PatchSpec extends ZIOSpecDefault { ), suite("not comparable")( test("Left <-> Right") { - notComparable[Either[String, String]](_.isLeft, _.isRight)(_.isLeft) + notComparable[zio.prelude.Validation[String, String]](_.isLeft, _.isRight)(_.isLeft) }, test("Separate enum cases") { notComparable[Pet](_.isInstanceOf[Pet.Dog], _.isInstanceOf[Pet.Cat])(_.isLeft) @@ -182,7 +182,7 @@ object PatchSpec extends ZIOSpecDefault { val afterInvert = diff.invert.invert val patched = schema.diff(l, r).patch(l) val patchedAfterInvert = afterInvert.patch(l) - assert(patched)(isRight(equalTo(r))) && assert(patchedAfterInvert)(isRight(equalTo(r))) + assert(patched)(iszio.prelude.Validation.succeed(equalTo(r))) && assert(patchedAfterInvert)(iszio.prelude.Validation.succeed(equalTo(r))) } else { assertTrue(true) } @@ -190,7 +190,7 @@ object PatchSpec extends ZIOSpecDefault { } private def notComparable[A](leftFilter: A => Boolean, rightFilter: A => Boolean)( - assertion: Either[String, A] => Boolean + assertion: zio.prelude.Validation[String, A] => Boolean )(implicit schema: Schema[A]): URIO[Sized with TestConfig, TestResult] = { val gen = DeriveGen.gen[A] diff --git a/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala b/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala index d4519a3e3..3bb653475 100644 --- a/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala +++ b/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala @@ -98,13 +98,13 @@ object SchemaGen { value <- gen } yield schema -> value - val anyEither: Gen[Sized, Schema.Either[_, _]] = + val anyEither: Gen[Sized, Schema.zio.prelude.Validation[_, _]] = for { left <- anyPrimitive right <- anyPrimitive } yield Schema.Either(left, right) - type EitherAndGen[A, B] = (Schema.Either[A, B], Gen[Sized, scala.util.Either[A, B]]) + type EitherAndGen[A, B] = (Schema.zio.prelude.Validation[A, B], Gen[Sized, zio.prelude.Validation[A, B]]) val anyEitherAndGen: Gen[Sized, EitherAndGen[_, _]] = for { @@ -112,7 +112,7 @@ object SchemaGen { (rightSchema, rightGen) <- anyPrimitiveAndGen } yield (Schema.Either(leftSchema, rightSchema), Gen.either(leftGen, rightGen)) - type EitherAndValue[A, B] = (Schema.Either[A, B], scala.util.Either[A, B]) + type EitherAndValue[A, B] = (Schema.zio.prelude.Validation[A, B], zio.prelude.Validation[A, B]) val anyEitherAndValue: Gen[Sized, EitherAndValue[_, _]] = for { @@ -315,8 +315,8 @@ object SchemaGen { private def transformSequence[A](schema: Schema[Chunk[A]]): SequenceTransform[A] = Schema.Transform[Chunk[A], List[A], String]( schema, - chunk => Right(chunk.toList), - list => Right(Chunk.fromIterable(list)), + chunk => zio.prelude.Validation.succeed(chunk.toList), + list => zio.prelude.Validation.succeed(Chunk.fromIterable(list)), Chunk.empty, "transformSequence" ) @@ -594,7 +594,7 @@ object SchemaGen { // anyEnumeration(anyTree(depth - 1)).map(toCaseSet).map(Schema.enumeration[Any, CaseSet.Aux[Any]](_)) ) - type SchemaAndDerivedValue[A, B] = (Schema[A], Schema[B], Chunk[scala.util.Either[A, B]]) + type SchemaAndDerivedValue[A, B] = (Schema[A], Schema[B], Chunk[zio.prelude.Validation[A, B]]) lazy val anyLeafAndValue: Gen[Sized, SchemaAndValue[_]] = for { diff --git a/tests/shared/src/test/scala-2/zio/schema/SchemaMigrationSpec.scala b/tests/shared/src/test/scala-2/zio/schema/SchemaMigrationSpec.scala index 47d5fa66c..82ce8a954 100644 --- a/tests/shared/src/test/scala-2/zio/schema/SchemaMigrationSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/SchemaMigrationSpec.scala @@ -47,7 +47,7 @@ object SchemaMigrationSpec extends ZIOSpecDefault { val actualMigration = original.migrate[Recursive3] - assert(actualMigration)(isRight(equalTo(expectedMigration))) + assert(actualMigration)(iszio.prelude.Validation.succeed(equalTo(expectedMigration))) }, test("require optional field") { assert(PetFood.DogFood(List("i"), Some("brand")))(migratesTo(BrandedPetFood.DogFood(List("i"), "brand"))) @@ -66,7 +66,7 @@ object SchemaMigrationSpec extends ZIOSpecDefault { check(PetFood.gen) { from => PetFood.brandedEquivalent(from) match { case Left(_) => assert(from)(cannotMigrateValue[PetFood, BrandedPetFood]) - case Right(to) => assert(from)(migratesTo(to)) + case zio.prelude.Validation.succeed(to) => assert(from)(migratesTo(to)) } } } @@ -114,7 +114,7 @@ object SchemaMigrationSpec extends ZIOSpecDefault { check(genA) { a => val roundTrip = a.migrate[B].flatMap(_.migrate[A]) - assertTrue(roundTrip == Right(a)) + assertTrue(roundTrip == zio.prelude.Validation.succeed(a)) } case class Recursive1(level: Int, value: String, r: Option[Recursive1]) @@ -170,9 +170,9 @@ object SchemaMigrationSpec extends ZIOSpecDefault { (Gen.listOf(Gen.string) <*> Gen.option(Gen.string)).map((CatFood.apply _).tupled) } - def brandedEquivalent(p: PetFood): Either[String, BrandedPetFood] = p match { - case CatFood(ingredients, Some(brand)) => Right(BrandedPetFood.CatFood(ingredients, brand)) - case DogFood(ingredients, Some(brand)) => Right(BrandedPetFood.DogFood(ingredients, brand)) + def brandedEquivalent(p: PetFood): zio.prelude.Validation[String, BrandedPetFood] = p match { + case CatFood(ingredients, Some(brand)) => zio.prelude.Validation.succeed(BrandedPetFood.CatFood(ingredients, brand)) + case DogFood(ingredients, Some(brand)) => zio.prelude.Validation.succeed(BrandedPetFood.DogFood(ingredients, brand)) case _ => Left("error") } @@ -299,7 +299,7 @@ object SchemaMigrationSpec extends ZIOSpecDefault { implicit lazy val schema: Schema[Version2] = DeriveSchema.gen } - case class NestedEither1(v1: Int, v2: Either[String, PetFood.DogFood]) + case class NestedEither1(v1: Int, v2: zio.prelude.Validation[String, PetFood.DogFood]) object NestedEither1 { implicit lazy val schema: Schema[NestedEither1] = DeriveSchema.gen @@ -311,7 +311,7 @@ object SchemaMigrationSpec extends ZIOSpecDefault { } yield NestedEither1(v1, v2) } - case class NestedEither2(v1: Int, v2: Either[String, PetFood.CatFood]) + case class NestedEither2(v1: Int, v2: zio.prelude.Validation[String, PetFood.CatFood]) object NestedEither2 { implicit lazy val schema: Schema[NestedEither2] = DeriveSchema.gen diff --git a/tests/shared/src/test/scala-2/zio/schema/types.scala b/tests/shared/src/test/scala-2/zio/schema/types.scala index 520410002..0f0865d5b 100644 --- a/tests/shared/src/test/scala-2/zio/schema/types.scala +++ b/tests/shared/src/test/scala-2/zio/schema/types.scala @@ -156,7 +156,7 @@ object types { object RecursiveList { implicit lazy val schema: Schema[RecursiveList] = DeriveSchema.gen } - case class RecursiveEither(level: Long, r: Either[String, Recursive]) extends Recursive + case class RecursiveEither(level: Long, r: zio.prelude.Validation[String, Recursive]) extends Recursive object RecursiveEither { implicit lazy val schema: Schema[RecursiveEither] = DeriveSchema.gen @@ -166,13 +166,13 @@ object types { } case class EitherVariants( - f1: Either[Option[String], Int], - f2: Either[List[String], String], - f3: Either[Option[Int], List[String]], - f4: Either[List[Option[Int]], Option[List[String]]], - f5: Either[Either[Int, String], Option[Int]], - f6: Either[Arities, Arities], - f7: Either[Recursive, Recursive] + f1: zio.prelude.Validation[Option[String], Int], + f2: zio.prelude.Validation[List[String], String], + f3: zio.prelude.Validation[Option[Int], List[String]], + f4: zio.prelude.Validation[List[Option[Int]], Option[List[String]]], + f5: zio.prelude.Validation[zio.prelude.Validation[Int, String], Option[Int]], + f6: zio.prelude.Validation[Arities, Arities], + f7: zio.prelude.Validation[Recursive, Recursive] ) object EitherVariants { @@ -182,7 +182,7 @@ object types { case class OptionVariants( f1: Option[Int], f2: Option[List[String]], - f3: Option[Either[String, Int]], + f3: Option[zio.prelude.Validation[String, Int]], f4: Option[Recursive], f5: Option[Arities] ) @@ -200,12 +200,12 @@ object types { f6: Chunk[Option[String]], f7: List[List[String]], f8: Chunk[Chunk[String]], - f9: List[Either[String, Int]], - f10: Chunk[Either[Option[String], Int]], - f11: List[Either[Option[String], List[Int]]], - f12: Chunk[Either[Option[String], List[Int]]], - f13: List[Option[Either[String, Chunk[Int]]]], - f14: Chunk[Option[Either[String, List[Int]]]], + f9: List[zio.prelude.Validation[String, Int]], + f10: Chunk[zio.prelude.Validation[Option[String], Int]], + f11: List[zio.prelude.Validation[Option[String], List[Int]]], + f12: Chunk[zio.prelude.Validation[Option[String], List[Int]]], + f13: List[Option[zio.prelude.Validation[String, Chunk[Int]]]], + f14: Chunk[Option[zio.prelude.Validation[String, List[Int]]]], f15: List[Arities], f16: Chunk[Arities], f17: List[Recursive], diff --git a/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala b/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala index 1f28f6fb9..3c326d901 100644 --- a/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala @@ -37,109 +37,109 @@ object DefaultValueSpec extends ZIOSpecDefault { def spec: Spec[Environment, Any] = suite("Default Value Spec")( suite("Primitive")( test("UnitType default value") { - assert(Primitive(StandardType.UnitType).defaultValue)(isRight(equalTo(()))) + assert(Primitive(StandardType.UnitType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(()))) }, test("StringType default value") { - assert(Primitive(StandardType.StringType).defaultValue)(isRight(equalTo(""))) + assert(Primitive(StandardType.StringType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(""))) }, test("BoolType default value") { - assert(Primitive(StandardType.BoolType).defaultValue)(isRight(equalTo(false))) + assert(Primitive(StandardType.BoolType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(false))) }, test("ShortType default value") { - assert(Primitive(StandardType.ShortType).defaultValue)(isRight(equalTo(0.asInstanceOf[Short]))) + assert(Primitive(StandardType.ShortType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(0.asInstanceOf[Short]))) }, test("IntType default value") { - assert(Primitive(StandardType.IntType).defaultValue)(isRight(equalTo(0))) + assert(Primitive(StandardType.IntType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(0))) }, test("LongType default value") { - assert(Primitive(StandardType.LongType).defaultValue)(isRight(equalTo(0.asInstanceOf[Long]))) + assert(Primitive(StandardType.LongType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(0.asInstanceOf[Long]))) }, test("FloatType default value") { - assert(Primitive(StandardType.FloatType).defaultValue)(isRight(equalTo(0.0.asInstanceOf[Float]))) + assert(Primitive(StandardType.FloatType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(0.0.asInstanceOf[Float]))) }, test("DoubleType default value") { - assert(Primitive(StandardType.DoubleType).defaultValue)(isRight(equalTo(0.0))) + assert(Primitive(StandardType.DoubleType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(0.0))) }, test("BinaryType default value") { - assert(Primitive(StandardType.BinaryType).defaultValue)(isRight(equalTo(Chunk.empty))) + assert(Primitive(StandardType.BinaryType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(Chunk.empty))) }, test("CharType default value") { - assert(Primitive(StandardType.CharType).defaultValue)(isRight(equalTo('\u0000'))) + assert(Primitive(StandardType.CharType).defaultValue)(iszio.prelude.Validation.succeed(equalTo('\u0000'))) }, test("BigDecimalType default value") { - assert(Primitive(StandardType.BigDecimalType).defaultValue)(isRight(equalTo(java.math.BigDecimal.ZERO))) + assert(Primitive(StandardType.BigDecimalType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.math.BigDecimal.ZERO))) }, test("BigIntegerType default value") { - assert(Primitive(StandardType.BigIntegerType).defaultValue)(isRight(equalTo(java.math.BigInteger.ZERO))) + assert(Primitive(StandardType.BigIntegerType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.math.BigInteger.ZERO))) }, test("DayOfWeekType default value") { assert(Primitive(StandardType.DayOfWeekType).defaultValue)( - isRight(equalTo(java.time.temporal.WeekFields.of(java.util.Locale.getDefault).getFirstDayOfWeek)) + iszio.prelude.Validation.succeed(equalTo(java.time.temporal.WeekFields.of(java.util.Locale.getDefault).getFirstDayOfWeek)) ) }, test("Month default value") { - assert(Primitive(StandardType.MonthType).defaultValue)(isRight(equalTo(java.time.Month.JANUARY))) + assert(Primitive(StandardType.MonthType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.time.Month.JANUARY))) }, test("MonthDay default value") { assert(Primitive(StandardType.MonthDayType).defaultValue)( - isRight(equalTo(java.time.MonthDay.of(java.time.Month.JANUARY, 1))) + iszio.prelude.Validation.succeed(equalTo(java.time.MonthDay.of(java.time.Month.JANUARY, 1))) ) }, test("Period default value") { - assert(Primitive(StandardType.PeriodType).defaultValue)(isRight(equalTo(java.time.Period.ZERO))) + assert(Primitive(StandardType.PeriodType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.time.Period.ZERO))) }, test("Year default value") { assert(Primitive(StandardType.YearType).defaultValue)( - isRight(equalTo(java.time.Year.now)) + iszio.prelude.Validation.succeed(equalTo(java.time.Year.now)) ) }, test("YearMonth default value") { - assert(Primitive(StandardType.YearMonthType).defaultValue)(isRight(equalTo(java.time.YearMonth.now))) + assert(Primitive(StandardType.YearMonthType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.time.YearMonth.now))) }, test("ZoneId default value") { - assert(Primitive(StandardType.ZoneIdType).defaultValue)(isRight(equalTo(java.time.ZoneId.systemDefault))) + assert(Primitive(StandardType.ZoneIdType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.time.ZoneId.systemDefault))) }, test("ZoneOffset default value") { - assert(Primitive(StandardType.ZoneOffsetType).defaultValue)(isRight(equalTo(java.time.ZoneOffset.UTC))) + assert(Primitive(StandardType.ZoneOffsetType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.time.ZoneOffset.UTC))) }, test("Duration default value") { assert(Primitive(StandardType.DurationType).defaultValue)( - isRight(equalTo(java.time.Duration.ZERO)) + iszio.prelude.Validation.succeed(equalTo(java.time.Duration.ZERO)) ) }, test("Instant default value") { assert(Primitive(StandardType.InstantType).defaultValue)( - isRight(equalTo(java.time.Instant.EPOCH)) + iszio.prelude.Validation.succeed(equalTo(java.time.Instant.EPOCH)) ) }, test("LocalDate default value") { assert(Primitive(StandardType.LocalDateType).defaultValue)( - isRight(isSubtype[java.time.LocalDate](anything)) + iszio.prelude.Validation.succeed(isSubtype[java.time.LocalDate](anything)) ) }, test("LocalTime default value") { assert(Primitive(StandardType.LocalTimeType).defaultValue)( - isRight(equalTo(java.time.LocalTime.MIDNIGHT)) + iszio.prelude.Validation.succeed(equalTo(java.time.LocalTime.MIDNIGHT)) ) }, test("LocalDateTime default value") { assert(Primitive(StandardType.LocalDateTimeType).defaultValue)( - isRight(isSubtype[java.time.LocalDateTime](anything)) + iszio.prelude.Validation.succeed(isSubtype[java.time.LocalDateTime](anything)) ) }, test("OffsetTime default value") { assert(Primitive(StandardType.OffsetTimeType).defaultValue)( - isRight(isSubtype[java.time.OffsetTime](anything)) + iszio.prelude.Validation.succeed(isSubtype[java.time.OffsetTime](anything)) ) }, test("OffsetDateTime default value") { assert(Primitive(StandardType.OffsetDateTimeType).defaultValue)( - isRight(isSubtype[java.time.OffsetDateTime](anything)) + iszio.prelude.Validation.succeed(isSubtype[java.time.OffsetDateTime](anything)) ) }, test("ZonedDateTime default value") { assert(Primitive(StandardType.ZonedDateTimeType).defaultValue)( - isRight(isSubtype[java.time.ZonedDateTime](anything)) + iszio.prelude.Validation.succeed(isSubtype[java.time.ZonedDateTime](anything)) ) } ), @@ -156,7 +156,7 @@ object DefaultValueSpec extends ZIOSpecDefault { ), UserId.apply ) - assert(schema.defaultValue)(isRight(equalTo(UserId("")))) + assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo(UserId("")))) }, test("recursive") { val expected: Schema[User] = @@ -191,15 +191,15 @@ object DefaultValueSpec extends ZIOSpecDefault { ), User.apply ) - assert(expected.defaultValue)(isRight(equalTo(User(UserId(""), "", 0)))) + assert(expected.defaultValue)(iszio.prelude.Validation.succeed(equalTo(User(UserId(""), "", 0)))) } ), suite("Sequence")( test("chunk") { - assert(Schema.chunk[Int].defaultValue)(isRight(equalTo(Chunk(0)))) + assert(Schema.chunk[Int].defaultValue)(iszio.prelude.Validation.succeed(equalTo(Chunk(0)))) }, test("list") { - assert(Schema.list[Int].defaultValue)(isRight(equalTo(List(0)))) + assert(Schema.list[Int].defaultValue)(iszio.prelude.Validation.succeed(equalTo(List(0)))) } ), suite("Enumeration")( @@ -211,19 +211,19 @@ object DefaultValueSpec extends ZIOSpecDefault { Any ]("myString")(_.asInstanceOf[String])(_.asInstanceOf[Any])(_.isInstanceOf[String]) ) - assert(schema.defaultValue)(isRight(equalTo(0))) + assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo(0))) } ), suite("Transform")( test("returns transformed default value") { val schema: Schema[String] = Schema.primitive(StandardType.IntType).transform[String](_.toString, _.toInt) - assert(schema.defaultValue)(isRight(equalTo("0"))) + assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo("0"))) } ), suite("Optional")( test("defaults to None") { val schema: Schema[Option[Int]] = Schema.option[Int] - assert(schema.defaultValue)(isRight(isNone)) + assert(schema.defaultValue)(iszio.prelude.Validation.succeed(isNone)) } ), suite("Fail")( @@ -236,13 +236,13 @@ object DefaultValueSpec extends ZIOSpecDefault { test("defaults to default value of tuple members") { val schema: Schema[(Int, String)] = Schema.tuple2(Schema.primitive(StandardType.IntType), Schema.primitive(StandardType.StringType)) - assert(schema.defaultValue)(isRight(equalTo((0, "")))) + assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo((0, "")))) } ), suite("Lazy")( test("calls the schema thunk") { val schema: Lazy[Int] = Schema.Lazy(() => Schema.primitive(StandardType.IntType)) - assert(schema.defaultValue)(isRight(equalTo(0))) + assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo(0))) } ), suite("Enum")( @@ -274,24 +274,24 @@ object DefaultValueSpec extends ZIOSpecDefault { (s: Status) => s.isInstanceOf[Pending.type] ) ) - assert(schema.defaultValue)(isRight(equalTo(Failed(0, "", None, "")))) + assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo(Failed(0, "", None, "")))) } ), suite("EitherSchema")( test("either") { - val eitherSchema: Schema[Either[Int, String]] = Schema.either( + val eitherSchema: Schema[zio.prelude.Validation[Int, String]] = Schema.either( Schema.primitive(StandardType.IntType), Schema.primitive(StandardType.StringType) ) - assert(eitherSchema.defaultValue)(isRight(isLeft(equalTo(0)))) + assert(eitherSchema.defaultValue)(iszio.prelude.Validation.succeed(isLeft(equalTo(0)))) }, test("left") { val leftSchema = Schema.either(Schema.primitive(StandardType.IntType), Schema.fail("Nothing")) - assert(leftSchema.defaultValue)(isRight(isLeft(equalTo(0)))) + assert(leftSchema.defaultValue)(iszio.prelude.Validation.succeed(isLeft(equalTo(0)))) }, test("right") { val rightSchema = Schema.either(Schema.fail("Nothing"), Schema.primitive(StandardType.StringType)) - assert(rightSchema.defaultValue)(isRight(isRight(equalTo("")))) + assert(rightSchema.defaultValue)(iszio.prelude.Validation.succeed(iszio.prelude.Validation.succeed(equalTo("")))) } ) ) diff --git a/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala b/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala index 15576083f..424563324 100644 --- a/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala @@ -19,7 +19,7 @@ object MigrationSpec extends ZIOSpecDefault { assertTrue( Migration - .derive(from, to) == Right(Chunk(Migration.ChangeType(NodePath.root, StandardType.StringType))) + .derive(from, to) == zio.prelude.Validation.succeed(Chunk(Migration.ChangeType(NodePath.root, StandardType.StringType))) ) }, test("optional") { @@ -29,7 +29,7 @@ object MigrationSpec extends ZIOSpecDefault { assertTrue( Migration - .derive(from, to) == Right(Chunk(Migration.Optional(NodePath.root))) + .derive(from, to) == zio.prelude.Validation.succeed(Chunk(Migration.Optional(NodePath.root))) ) }, test("require") { @@ -40,7 +40,7 @@ object MigrationSpec extends ZIOSpecDefault { assertTrue( Migration - .derive(from, to) == Right(Chunk(Migration.Require(NodePath.root))) + .derive(from, to) == zio.prelude.Validation.succeed(Chunk(Migration.Require(NodePath.root))) ) }, test("increment dimensions") { @@ -55,7 +55,7 @@ object MigrationSpec extends ZIOSpecDefault { assertTrue( Migration - .derive(from, to) == Right(Chunk(Migration.IncrementDimensions(NodePath.root, 1))) + .derive(from, to) == zio.prelude.Validation.succeed(Chunk(Migration.IncrementDimensions(NodePath.root, 1))) ) }, test("decrement dimensions") { @@ -69,7 +69,7 @@ object MigrationSpec extends ZIOSpecDefault { assertTrue( Migration - .derive(from, to) == Right(Chunk(Migration.DecrementDimensions(NodePath.root, 1))) + .derive(from, to) == zio.prelude.Validation.succeed(Chunk(Migration.DecrementDimensions(NodePath.root, 1))) ) } ), @@ -286,7 +286,7 @@ object MigrationSpec extends ZIOSpecDefault { def transformsValueTo[A: Schema](value: A, expected: DynamicValue): Assertion[Migration] = Assertion.assertion("transformsValueTo") { transform => val transformed = transform.migrate(value.dynamic) - transformed == Right(expected) + transformed == zio.prelude.Validation.succeed(expected) } def failsToTransform[A: Schema](value: A): Assertion[Migration] = diff --git a/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala b/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala index fbecd6bf6..fb330edc1 100644 --- a/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala @@ -72,12 +72,12 @@ object SchemaSpec extends ZIOSpecDefault { ) ) - val f: Unit => Either[String, Int] = _ => Right(0) - val g: Int => Either[String, Unit] = _ => Right(()) + val f: Unit => zio.prelude.Validation[String, Int] = _ => zio.prelude.Validation.succeed(0) + val g: Int => zio.prelude.Validation[String, Unit] = _ => zio.prelude.Validation.succeed(()) def schemaTransform: Schema[Int] = schemaUnit.transformOrFail[Int](f, g) - def tranformF(u: Unit): Either[String, Int] = Some(u).map(_ => 0).toRight("") - def tranformG(i: Int): Either[String, Unit] = Some(i).map(_ => ()).toRight("") + def tranformF(u: Unit): zio.prelude.Validation[String, Int] = Some(u).map(_ => 0).tozio.prelude.Validation.succeed("") + def tranformG(i: Int): zio.prelude.Validation[String, Unit] = Some(i).map(_ => ()).tozio.prelude.Validation.succeed("") def schemaTransformMethod: Schema[Int] = schemaUnit.transformOrFail(tranformF, tranformG) } diff --git a/tests/shared/src/test/scala/zio/schema/ast/NodePathSpec.scala b/tests/shared/src/test/scala/zio/schema/ast/NodePathSpec.scala index f6cc2439a..4dec61572 100644 --- a/tests/shared/src/test/scala/zio/schema/ast/NodePathSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/ast/NodePathSpec.scala @@ -53,7 +53,7 @@ object NodePathSpec extends ZIOSpecDefault { test("partition path into internal path and leaf label") { check(anyPathOfN(2)) { path => val (internalPath, leaf) = path.partitionLeaf - assert(internalPath)(Assertion.equalTo(NodePath(path.dropRight(1)))) && + assert(internalPath)(Assertion.equalTo(NodePath(path.dropzio.prelude.Validation.succeed(1)))) && assertTrue(leaf == Some(path.last)) } }, diff --git a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala index 3500669b7..4b181bc78 100644 --- a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala +++ b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala @@ -20,33 +20,33 @@ import zio.schema.codec.AvroPropMarker._ import zio.schema.meta.MetaSchema trait AvroCodec { - def encode(schema: Schema[_]): scala.util.Either[String, String] + def encode(schema: Schema[_]): zio.prelude.Validation[String, String] - def decode(bytes: Chunk[Byte]): scala.util.Either[String, Schema[_]] + def decode(bytes: Chunk[Byte]): zio.prelude.Validation[String, Schema[_]] } object AvroCodec extends AvroCodec { - def encode(schema: Schema[_]): scala.util.Either[String, String] = + def encode(schema: Schema[_]): zio.prelude.Validation[String, String] = toAvroSchema(schema).map(_.toString) - def encodeToApacheAvro(schema: Schema[_]): scala.util.Either[String, SchemaAvro] = + def encodeToApacheAvro(schema: Schema[_]): zio.prelude.Validation[String, SchemaAvro] = toAvroSchema(schema) - def decode(bytes: Chunk[Byte]): scala.util.Either[String, Schema[_]] = { + def decode(bytes: Chunk[Byte]): zio.prelude.Validation[String, Schema[_]] = { val avroSchemaParser = new SchemaAvro.Parser() val avroSchema = Try { avroSchemaParser.parse(new String(bytes.toArray, StandardCharsets.UTF_8)) }.fold( e => Left(e.getMessage), - s => Right(s) + s => zio.prelude.Validation.succeed(s) ) avroSchema.flatMap(toZioSchema) } - def decodeFromApacheAvro: SchemaAvro => scala.util.Either[String, Schema[_]] = toZioSchema + def decodeFromApacheAvro: SchemaAvro => zio.prelude.Validation[String, Schema[_]] = toZioSchema - private def toZioSchema(avroSchema: SchemaAvro): scala.util.Either[String, Schema[_]] = + private def toZioSchema(avroSchema: SchemaAvro): zio.prelude.Validation[String, Schema[_]] = for { // make sure to parse logical types with throwing exceptions enabled, // otherwise parsing errors on invalid logical types might be lost @@ -56,11 +56,11 @@ object AvroCodec extends AvroCodec { result <- avroSchema.getType match { case SchemaAvro.Type.RECORD => RecordType.fromAvroRecord(avroSchema) match { - case Some(RecordType.Period) => Right(Schema.primitive(StandardType.PeriodType)) - case Some(RecordType.YearMonth) => Right(Schema.primitive(StandardType.YearMonthType)) + case Some(RecordType.Period) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.PeriodType)) + case Some(RecordType.YearMonth) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.YearMonthType)) case Some(RecordType.Tuple) => toZioTuple(avroSchema) - case Some(RecordType.MonthDay) => Right(Schema.primitive(StandardType.MonthDayType)) - case Some(RecordType.Duration) => Right(Schema.primitive(StandardType.DurationType)) + case Some(RecordType.MonthDay) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.MonthDayType)) + case Some(RecordType.Duration) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.DurationType)) case None => toZioRecord(avroSchema) } case SchemaAvro.Type.ENUM => toZioStringEnum(avroSchema) @@ -77,7 +77,7 @@ object AvroCodec extends AvroCodec { } case SchemaAvro.Type.FIXED => val fixed = if (avroSchema.getLogicalType == null) { - Right(Schema.primitive(StandardType.BinaryType)) + zio.prelude.Validation.succeed(Schema.primitive(StandardType.BinaryType)) } else if (avroSchema.getLogicalType.isInstanceOf[LogicalTypes.Decimal]) { val size = avroSchema.getFixedSize toZioDecimal(avroSchema, DecimalType.Fixed(size)) @@ -95,51 +95,51 @@ object AvroCodec extends AvroCodec { .map(_.dateTimeFormatter) .flatMap(_ => { stringType match { - case StringType.ZoneId => Right(Schema.primitive(StandardType.ZoneIdType)) + case StringType.ZoneId => zio.prelude.Validation.succeed(Schema.primitive(StandardType.ZoneIdType)) case StringType.Instant => - Right( + zio.prelude.Validation.succeed( Schema .primitive(StandardType.InstantType) .annotate(AvroAnnotations.formatToString) ) case StringType.LocalDate => - Right( + zio.prelude.Validation.succeed( Schema .primitive(StandardType.LocalDateType) .annotate(AvroAnnotations.formatToString) ) case StringType.LocalTime => - Right( + zio.prelude.Validation.succeed( Schema .primitive(StandardType.LocalTimeType) .annotate(AvroAnnotations.formatToString) ) case StringType.LocalDateTime => - Right( + zio.prelude.Validation.succeed( Schema .primitive(StandardType.LocalDateTimeType) .annotate(AvroAnnotations.formatToString) ) case StringType.OffsetTime => - Right(Schema.primitive(StandardType.OffsetTimeType)) + zio.prelude.Validation.succeed(Schema.primitive(StandardType.OffsetTimeType)) case StringType.OffsetDateTime => - Right(Schema.primitive(StandardType.OffsetDateTimeType)) + zio.prelude.Validation.succeed(Schema.primitive(StandardType.OffsetDateTimeType)) case StringType.ZoneDateTime => - Right(Schema.primitive(StandardType.ZonedDateTimeType)) + zio.prelude.Validation.succeed(Schema.primitive(StandardType.ZonedDateTimeType)) } }) case None => if (avroSchema.getLogicalType == null) { - Right(Schema.primitive(StandardType.StringType)) + zio.prelude.Validation.succeed(Schema.primitive(StandardType.StringType)) } else if (avroSchema.getLogicalType.getName == LogicalTypes.uuid().getName) { - Right(Schema.primitive(StandardType.UUIDType)) + zio.prelude.Validation.succeed(Schema.primitive(StandardType.UUIDType)) } else { Left(s"Unsupported string logical type: ${avroSchema.getLogicalType.getName}") } } case SchemaAvro.Type.BYTES => if (avroSchema.getLogicalType == null) { - Right(Schema.primitive(StandardType.BinaryType)) + zio.prelude.Validation.succeed(Schema.primitive(StandardType.BinaryType)) } else if (avroSchema.getLogicalType.isInstanceOf[LogicalTypes.Decimal]) { toZioDecimal(avroSchema, DecimalType.Bytes) } else { @@ -147,15 +147,15 @@ object AvroCodec extends AvroCodec { } case SchemaAvro.Type.INT => IntType.fromAvroInt(avroSchema) match { - case Some(IntType.Char) => Right(Schema.primitive(StandardType.CharType)) - case Some(IntType.DayOfWeek) => Right(Schema.primitive(StandardType.DayOfWeekType)) - case Some(IntType.Year) => Right(Schema.primitive(StandardType.YearType)) - case Some(IntType.Short) => Right(Schema.primitive(StandardType.ShortType)) - case Some(IntType.Month) => Right(Schema.primitive(StandardType.MonthType)) - case Some(IntType.ZoneOffset) => Right(Schema.primitive(StandardType.ZoneOffsetType)) + case Some(IntType.Char) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.CharType)) + case Some(IntType.DayOfWeek) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.DayOfWeekType)) + case Some(IntType.Year) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.YearType)) + case Some(IntType.Short) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.ShortType)) + case Some(IntType.Month) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.MonthType)) + case Some(IntType.ZoneOffset) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.ZoneOffsetType)) case None => if (avroSchema.getLogicalType == null) { - Right(Schema.primitive(StandardType.IntType)) + zio.prelude.Validation.succeed(Schema.primitive(StandardType.IntType)) } else avroSchema.getLogicalType match { case _: LogicalTypes.TimeMillis => @@ -173,7 +173,7 @@ object AvroCodec extends AvroCodec { } case SchemaAvro.Type.LONG => if (avroSchema.getLogicalType == null) { - Right(Schema.primitive(StandardType.LongType)) + zio.prelude.Validation.succeed(Schema.primitive(StandardType.LongType)) } else avroSchema.getLogicalType match { case _: LogicalTypes.TimeMicros => @@ -203,10 +203,10 @@ object AvroCodec extends AvroCodec { ) case _ => Left(s"Unsupported long logical type ${avroSchema.getLogicalType.getName}") } - case SchemaAvro.Type.FLOAT => Right(Schema.primitive(StandardType.FloatType)) - case SchemaAvro.Type.DOUBLE => Right(Schema.primitive(StandardType.DoubleType)) - case SchemaAvro.Type.BOOLEAN => Right(Schema.primitive(StandardType.BoolType)) - case SchemaAvro.Type.NULL => Right(Schema.primitive(StandardType.UnitType)) + case SchemaAvro.Type.FLOAT => zio.prelude.Validation.succeed(Schema.primitive(StandardType.FloatType)) + case SchemaAvro.Type.DOUBLE => zio.prelude.Validation.succeed(Schema.primitive(StandardType.DoubleType)) + case SchemaAvro.Type.BOOLEAN => zio.prelude.Validation.succeed(Schema.primitive(StandardType.BoolType)) + case SchemaAvro.Type.NULL => zio.prelude.Validation.succeed(Schema.primitive(StandardType.UnitType)) case null => Left(s"Unsupported type ${avroSchema.getType}") } } yield result @@ -275,7 +275,7 @@ object AvroCodec extends AvroCodec { ) ) - private def toAvroSchema(schema: Schema[_]): scala.util.Either[String, SchemaAvro] = { + private def toAvroSchema(schema: Schema[_]): zio.prelude.Validation[String, SchemaAvro] = { schema match { case e: Enum[_] => toAvroEnum(e) case record: Record[_] => toAvroRecord(record) @@ -285,45 +285,45 @@ object AvroCodec extends AvroCodec { case Transform(codec, _, _, _, _) => toAvroSchema(codec) case Primitive(standardType, _) => standardType match { - case StandardType.UnitType => Right(SchemaAvro.create(SchemaAvro.Type.NULL)) - case StandardType.StringType => Right(SchemaAvro.create(SchemaAvro.Type.STRING)) - case StandardType.BoolType => Right(SchemaAvro.create(SchemaAvro.Type.BOOLEAN)) + case StandardType.UnitType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.NULL)) + case StandardType.StringType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.STRING)) + case StandardType.BoolType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.BOOLEAN)) case StandardType.ShortType => - Right(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Short))) - case StandardType.ByteType => Right(SchemaAvro.create(SchemaAvro.Type.INT)) - case StandardType.IntType => Right(SchemaAvro.create(SchemaAvro.Type.INT)) - case StandardType.LongType => Right(SchemaAvro.create(SchemaAvro.Type.LONG)) - case StandardType.FloatType => Right(SchemaAvro.create(SchemaAvro.Type.FLOAT)) - case StandardType.DoubleType => Right(SchemaAvro.create(SchemaAvro.Type.DOUBLE)) - case StandardType.BinaryType => Right(toAvroBinary(schema)) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Short))) + case StandardType.ByteType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT)) + case StandardType.IntType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT)) + case StandardType.LongType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.LONG)) + case StandardType.FloatType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.FLOAT)) + case StandardType.DoubleType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.DOUBLE)) + case StandardType.BinaryType => zio.prelude.Validation.succeed(toAvroBinary(schema)) case StandardType.CharType => - Right(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Char))) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Char))) case StandardType.UUIDType => - Right(LogicalTypes.uuid().addToSchema(SchemaAvro.create(SchemaAvro.Type.STRING))) + zio.prelude.Validation.succeed(LogicalTypes.uuid().addToSchema(SchemaAvro.create(SchemaAvro.Type.STRING))) case StandardType.BigDecimalType => toAvroDecimal(schema) case StandardType.BigIntegerType => toAvroDecimal(schema) case StandardType.DayOfWeekType => - Right(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.DayOfWeek))) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.DayOfWeek))) case StandardType.MonthType => - Right(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Month))) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Month))) case StandardType.YearType => - Right(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Year))) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Year))) case StandardType.ZoneIdType => - Right(SchemaAvro.create(SchemaAvro.Type.STRING).addMarkerProp(StringDiscriminator(StringType.ZoneId))) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.STRING).addMarkerProp(StringDiscriminator(StringType.ZoneId))) case StandardType.ZoneOffsetType => - Right(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.ZoneOffset))) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.ZoneOffset))) case StandardType.MonthDayType => //TODO 1 - //Right(SchemaAvro.create(monthDayStructure).addMarkerProp(RecordDiscriminator(RecordType.MonthDay))) - Right(SchemaAvro.create(SchemaAvro.Type.RECORD)) + //zio.prelude.Validation.succeed(SchemaAvro.create(monthDayStructure).addMarkerProp(RecordDiscriminator(RecordType.MonthDay))) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) case StandardType.PeriodType => //TODO 2 //toAvroSchema(periodStructure).map(_.addMarkerProp(RecordDiscriminator(RecordType.Period))) - Right(SchemaAvro.create(SchemaAvro.Type.RECORD)) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) case StandardType.YearMonthType => //TODO 3 //toAvroSchema(yearMonthStructure).map(_.addMarkerProp(RecordDiscriminator(RecordType.YearMonth))) - Right(SchemaAvro.create(SchemaAvro.Type.RECORD)) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) case StandardType.DurationType => // TODO: Java implementation of Apache Avro does not support logical type Duration yet: // AVRO-2123 with PR https://github.com/apache/avro/pull/1263 @@ -332,46 +332,46 @@ object AvroCodec extends AvroCodec { //DurationChronoUnit.fromTemporalUnit(temporalUnit).getOrElse(DurationChronoUnit.default) //toAvroSchema(durationStructure).map( // _.addMarkerProp(RecordDiscriminator(RecordType.Duration)).addMarkerProp(chronoUnitMarker)) - Right(SchemaAvro.create(SchemaAvro.Type.RECORD)) + zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) case StandardType.InstantType => - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.Instant)) ) case StandardType.LocalDateType => - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalDate)) ) case StandardType.LocalTimeType => - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalTime)) ) case StandardType.LocalDateTimeType => - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalDateTime)) ) case StandardType.OffsetTimeType => - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.OffsetTime)) ) case StandardType.OffsetDateTimeType => - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.OffsetDateTime)) ) case StandardType.ZonedDateTimeType => - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.ZoneDateTime)) @@ -404,7 +404,7 @@ object AvroCodec extends AvroCodec { rightSchema = if (r.getType == SchemaAvro.Type.UNION) wrapAvro(r, rname, UnionWrapper) else r _ <- if (leftSchema.getFullName == rightSchema.getFullName) Left(s"Left and right schemas of either must have different fullnames: ${leftSchema.getFullName}") - else Right(()) + else zio.prelude.Validation.succeed(()) } yield SchemaAvro.createUnion(leftSchema, rightSchema) // Unions in Avro can not hold additional properties, so we need to wrap the union in a record @@ -430,9 +430,9 @@ object AvroCodec extends AvroCodec { private[codec] def toAvroInstant( formatter: DateTimeFormatter, annotations: Chunk[Any] - ): scala.util.Either[String, SchemaAvro] = + ): zio.prelude.Validation[String, SchemaAvro] = if (hasFormatToStringAnnotation(annotations)) { - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.Instant)) @@ -442,33 +442,33 @@ object AvroCodec extends AvroCodec { val baseSchema = SchemaAvro.create(SchemaAvro.Type.LONG) getTimeprecisionType(annotations).getOrElse(TimePrecisionType.default) match { case TimePrecisionType.Millis => - Right(LogicalTypes.timestampMillis().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) + zio.prelude.Validation.succeed(LogicalTypes.timestampMillis().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) case TimePrecisionType.Micros => - Right(LogicalTypes.timestampMicros().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) + zio.prelude.Validation.succeed(LogicalTypes.timestampMicros().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) } } private[codec] def toAvroLocalDate( formatter: DateTimeFormatter, annotations: Chunk[Any] - ): scala.util.Either[String, SchemaAvro] = + ): zio.prelude.Validation[String, SchemaAvro] = if (hasFormatToStringAnnotation(annotations)) { - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalDate)) .addMarkerProp(Formatter(formatter)) ) } else { - Right(LogicalTypes.date().addToSchema(SchemaAvro.create(SchemaAvro.Type.INT)).addMarkerProp(Formatter(formatter))) + zio.prelude.Validation.succeed(LogicalTypes.date().addToSchema(SchemaAvro.create(SchemaAvro.Type.INT)).addMarkerProp(Formatter(formatter))) } private[codec] def toAvroLocalTime( formatter: DateTimeFormatter, annotations: Chunk[Any] - ): scala.util.Either[String, SchemaAvro] = + ): zio.prelude.Validation[String, SchemaAvro] = if (hasFormatToStringAnnotation(annotations)) { - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalTime)) @@ -477,14 +477,14 @@ object AvroCodec extends AvroCodec { } else { getTimeprecisionType(annotations).getOrElse(TimePrecisionType.default) match { case TimePrecisionType.Millis => - Right( + zio.prelude.Validation.succeed( LogicalTypes .timeMillis() .addToSchema(SchemaAvro.create(SchemaAvro.Type.INT)) .addMarkerProp(Formatter(formatter)) ) case TimePrecisionType.Micros => - Right( + zio.prelude.Validation.succeed( LogicalTypes .timeMicros() .addToSchema(SchemaAvro.create(SchemaAvro.Type.LONG)) @@ -496,9 +496,9 @@ object AvroCodec extends AvroCodec { private[codec] def toAvroLocalDateTime( formatter: DateTimeFormatter, annotations: Chunk[Any] - ): scala.util.Either[String, SchemaAvro] = + ): zio.prelude.Validation[String, SchemaAvro] = if (hasFormatToStringAnnotation(annotations)) { - Right( + zio.prelude.Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalDateTime)) @@ -508,9 +508,9 @@ object AvroCodec extends AvroCodec { val baseSchema = SchemaAvro.create(SchemaAvro.Type.LONG) getTimeprecisionType(annotations).getOrElse(TimePrecisionType.default) match { case TimePrecisionType.Millis => - Right(LogicalTypes.localTimestampMillis().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) + zio.prelude.Validation.succeed(LogicalTypes.localTimestampMillis().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) case TimePrecisionType.Micros => - Right(LogicalTypes.localTimestampMicros().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) + zio.prelude.Validation.succeed(LogicalTypes.localTimestampMicros().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) } } @@ -529,7 +529,7 @@ object AvroCodec extends AvroCodec { .addMarkerProp(marker) } - private[codec] def toAvroEnum(enu: Enum[_]): scala.util.Either[String, SchemaAvro] = { + private[codec] def toAvroEnum(enu: Enum[_]): zio.prelude.Validation[String, SchemaAvro] = { val avroEnumAnnotationExists = hasAvroEnumAnnotation(enu.annotations) val isAvroEnumEquivalent = enu.cases.map(_.schema).forall { case (Transform(Primitive(standardType, _), _, _, _, _)) @@ -554,10 +554,10 @@ object AvroCodec extends AvroCodec { case (symbol, (Transform(Primitive(standardType, _), _, _, _, _), annotations)) if standardType == StandardType.UnitType => val name = getNameOption(annotations).getOrElse(symbol) - Right(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) + zio.prelude.Validation.succeed(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) case (symbol, (CaseClass0(_, _, _), annotations)) => val name = getNameOption(annotations).getOrElse(symbol) - Right(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) + zio.prelude.Validation.succeed(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) case (symbol, (schema, annotations)) => val name = getNameOption(annotations).getOrElse(symbol) val schemaWithName = addNameAnnotationIfMissing(schema, name) @@ -571,7 +571,7 @@ object AvroCodec extends AvroCodec { case _: String => true case _ => false } match { - case (Nil, right: List[org.apache.avro.Schema @unchecked]) => Right(SchemaAvro.createUnion(right.asJava)) + case (Nil, right: List[org.apache.avro.Schema @unchecked]) => zio.prelude.Validation.succeed(SchemaAvro.createUnion(right.asJava)) case (left, _) => Left(left.mkString("\n")) } } @@ -586,11 +586,11 @@ object AvroCodec extends AvroCodec { case _ => null } - private[codec] def toAvroRecord(record: Record[_]): scala.util.Either[String, SchemaAvro] = + private[codec] def toAvroRecord(record: Record[_]): zio.prelude.Validation[String, SchemaAvro] = for { name <- getName(record) namespaceOption <- getNamespace(record.annotations) - result <- Right( + result <- zio.prelude.Validation.succeed( SchemaAvro.createRecord( name, getDoc(record.annotations).orNull, @@ -601,7 +601,7 @@ object AvroCodec extends AvroCodec { ) } yield result - private[codec] def toAvroMap(map: Map[_, _]): scala.util.Either[String, SchemaAvro] = + private[codec] def toAvroMap(map: Map[_, _]): zio.prelude.Validation[String, SchemaAvro] = map.keySchema match { case p: Schema.Primitive[_] if p.standardType == StandardType.StringType => toAvroSchema(map.valueSchema).map(SchemaAvro.createMap) @@ -613,7 +613,7 @@ object AvroCodec extends AvroCodec { toAvroSchema(tupleSchema).map(SchemaAvro.createArray) } - private[codec] def toAvroDecimal(schema: Schema[_]): scala.util.Either[String, SchemaAvro] = { + private[codec] def toAvroDecimal(schema: Schema[_]): zio.prelude.Validation[String, SchemaAvro] = { val scale = schema.annotations.collectFirst { case AvroAnnotations.scale(s) => s } .getOrElse(AvroAnnotations.scale().scale) val precision = schema match { @@ -632,7 +632,7 @@ object AvroCodec extends AvroCodec { doc = getDoc(schema.annotations).orNull result = SchemaAvro.createFixed(name, doc, namespaceOption.orNull, size) } yield result - case DecimalType.Bytes => Right(SchemaAvro.create(SchemaAvro.Type.BYTES)) + case DecimalType.Bytes => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.BYTES)) } baseAvroType.map( LogicalTypes @@ -644,7 +644,7 @@ object AvroCodec extends AvroCodec { private[codec] def toErrorMessage(err: Throwable, at: AnyRef) = s"Error mapping to Apache Avro schema: $err at ${at.toString}" - private[codec] def toAvroRecordField[Z](value: Field[Z, _]): scala.util.Either[String, SchemaAvro.Field] = + private[codec] def toAvroRecordField[Z](value: Field[Z, _]): zio.prelude.Validation[String, SchemaAvro.Field] = toAvroSchema(value.schema).map( schema => new SchemaAvro.Field( @@ -659,21 +659,21 @@ object AvroCodec extends AvroCodec { private[codec] def getFieldOrder(annotations: Chunk[Any]): Option[FieldOrderType] = annotations.collectFirst { case AvroAnnotations.fieldOrder(fieldOrderType) => fieldOrderType } - private[codec] def getName(schema: Schema[_]): scala.util.Either[String, String] = { + private[codec] def getName(schema: Schema[_]): zio.prelude.Validation[String, String] = { val validNameRegex = raw"[A-Za-z_][A-Za-z0-9_]*".r schema.annotations.collectFirst { case AvroAnnotations.name(name) => name } match { case Some(s) => s match { - case validNameRegex() => Right(s) + case validNameRegex() => zio.prelude.Validation.succeed(s) case _ => Left(s"Invalid Avro name: $s") } case None => schema match { - case r: Record[_] => Right(r.id.name) - case e: Enum[_] => Right(e.id.name) - case _ => Right(s"hashed_${schema.ast.toString.hashCode().toString.replaceFirst("-", "n")}") + case r: Record[_] => zio.prelude.Validation.succeed(r.id.name) + case e: Enum[_] => zio.prelude.Validation.succeed(e.id.name) + case _ => zio.prelude.Validation.succeed(s"hashed_${schema.ast.toString.hashCode().toString.replaceFirst("-", "n")}") // TODO: better way to generate a (maybe stable) name? } } @@ -688,16 +688,16 @@ object AvroCodec extends AvroCodec { private[codec] def getDefault(annotations: Chunk[Any]): Option[java.lang.Object] = annotations.collectFirst { case AvroAnnotations.default(javaDefaultObject) => javaDefaultObject } - private[codec] def getNamespace(annotations: Chunk[Any]): scala.util.Either[String, Option[String]] = { + private[codec] def getNamespace(annotations: Chunk[Any]): zio.prelude.Validation[String, Option[String]] = { val validNamespaceRegex = raw"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*".r annotations.collectFirst { case AvroAnnotations.namespace(ns) => ns } match { case Some(s) => s match { - case validNamespaceRegex(_) => Right(Some(s)) + case validNamespaceRegex(_) => zio.prelude.Validation.succeed(Some(s)) case _ => Left(s"Invalid Avro namespace: $s") } - case None => Right(None) + case None => zio.prelude.Validation.succeed(None) } } @@ -711,13 +711,13 @@ object AvroCodec extends AvroCodec { private[codec] def toZioDecimal( avroSchema: SchemaAvro, decimalType: DecimalType - ): scala.util.Either[String, Schema[_]] = { + ): zio.prelude.Validation[String, Schema[_]] = { val decimalTypeAnnotation = AvroAnnotations.decimal(decimalType) val decimalLogicalType = avroSchema.getLogicalType.asInstanceOf[LogicalTypes.Decimal] val precision = decimalLogicalType.getPrecision val scale = decimalLogicalType.getScale if (precision - scale > 0) { - Right( + zio.prelude.Validation.succeed( Schema .primitive(StandardType.BigDecimalType) .annotate(AvroAnnotations.scale(scale)) @@ -725,7 +725,7 @@ object AvroCodec extends AvroCodec { .annotate(decimalTypeAnnotation) ) } else { - Right( + zio.prelude.Validation.succeed( Schema .primitive(StandardType.BigIntegerType) .annotate(AvroAnnotations.scale(scale)) @@ -734,7 +734,7 @@ object AvroCodec extends AvroCodec { } } - private[codec] def toZioEnumeration[A, Z](avroSchema: SchemaAvro): scala.util.Either[String, Schema[Z]] = { + private[codec] def toZioEnumeration[A, Z](avroSchema: SchemaAvro): zio.prelude.Validation[String, Schema[Z]] = { val cases = avroSchema.getTypes.asScala .map(t => { val inner = @@ -766,7 +766,7 @@ object AvroCodec extends AvroCodec { caseSet.map(cs => Schema.enumeration(TypeId.parse(avroSchema.getName), cs)) } - private[codec] def toZioRecord(avroSchema: SchemaAvro): scala.util.Either[String, Schema[_]] = + private[codec] def toZioRecord(avroSchema: SchemaAvro): zio.prelude.Validation[String, Schema[_]] = if (avroSchema.getObjectProp(UnionWrapper.propName) != null) { avroSchema.getFields.asScala.headOption match { case Some(value) => toZioSchema(value.schema()) @@ -778,44 +778,44 @@ object AvroCodec extends AvroCodec { toZioSchema(value.schema()).flatMap { case enu: Enum[_] => enu.cases.toList match { - case first :: second :: Nil => Right(Schema.either(first.schema, second.schema)) + case first :: second :: Nil => zio.prelude.Validation.succeed(Schema.either(first.schema, second.schema)) case _ => Left("ZIO schema wrapped either must have exactly two cases") } - case e: Schema.Either[_, _] => Right(e) - case c: CaseClass0[_] => Right(c) - case c: CaseClass1[_, _] => Right(c) - case c: CaseClass2[_, _, _] => Right(c) - case c: CaseClass3[_, _, _, _] => Right(c) - case c: CaseClass4[_, _, _, _, _] => Right(c) - case c: CaseClass5[_, _, _, _, _, _] => Right(c) - case c: CaseClass6[_, _, _, _, _, _, _] => Right(c) - case c: CaseClass7[_, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass8[_, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass9[_, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass10[_, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass11[_, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass12[_, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass13[_, _, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: CaseClass22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Right(c) - case c: Dynamic => Right(c) - case c: GenericRecord => Right(c) - case c: Map[_, _] => Right(c) - case c: Sequence[_, _, _] => Right(c) - case c: Set[_] => Right(c) - case c: Fail[_] => Right(c) - case c: Lazy[_] => Right(c) - case c: Optional[_] => Right(c) - case c: Primitive[_] => Right(c) - case c: Transform[_, _, _] => Right(c) - case c: Tuple2[_, _] => Right(c) + case e: Schema.zio.prelude.Validation[_, _] => zio.prelude.Validation.succeed(e) + case c: CaseClass0[_] => zio.prelude.Validation.succeed(c) + case c: CaseClass1[_, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass2[_, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass3[_, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass4[_, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass5[_, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass6[_, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass7[_, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass8[_, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass9[_, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass10[_, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass11[_, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass12[_, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass13[_, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: CaseClass22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) + case c: Dynamic => zio.prelude.Validation.succeed(c) + case c: GenericRecord => zio.prelude.Validation.succeed(c) + case c: Map[_, _] => zio.prelude.Validation.succeed(c) + case c: Sequence[_, _, _] => zio.prelude.Validation.succeed(c) + case c: Set[_] => zio.prelude.Validation.succeed(c) + case c: Fail[_] => zio.prelude.Validation.succeed(c) + case c: Lazy[_] => zio.prelude.Validation.succeed(c) + case c: Optional[_] => zio.prelude.Validation.succeed(c) + case c: Primitive[_] => zio.prelude.Validation.succeed(c) + case c: Transform[_, _, _] => zio.prelude.Validation.succeed(c) + case c: Tuple2[_, _] => zio.prelude.Validation.succeed(c) } case None => Left("ZIO schema wrapped record must have a single field") @@ -827,16 +827,16 @@ object AvroCodec extends AvroCodec { } } - private def extractZioFields[Z](avroSchema: SchemaAvro): scala.util.Either[String, List[Field[Z, _]]] = + private def extractZioFields[Z](avroSchema: SchemaAvro): zio.prelude.Validation[String, List[Field[Z, _]]] = avroSchema.getFields.asScala.map(toZioField).toList.map(_.merge).partition { case _: String => true case _ => false } match { - case (Nil, right: List[Field[Z, _] @unchecked]) => Right(right) + case (Nil, right: List[Field[Z, _] @unchecked]) => zio.prelude.Validation.succeed(right) case (left, _) => Left(left.mkString("\n")) } - private[codec] def toZioField(field: SchemaAvro.Field): scala.util.Either[String, Field[ListMap[String, _], _]] = + private[codec] def toZioField(field: SchemaAvro.Field): zio.prelude.Validation[String, Field[ListMap[String, _], _]] = toZioSchema(field.schema()) .map( (s: Schema[_]) => @@ -849,7 +849,7 @@ object AvroCodec extends AvroCodec { ) ) - private[codec] def toZioTuple(schema: SchemaAvro): scala.util.Either[String, Schema[_]] = + private[codec] def toZioTuple(schema: SchemaAvro): zio.prelude.Validation[String, Schema[_]] = for { _ <- scala.util.Either .cond(schema.getFields.size() == 2, (), "Tuple must have exactly 2 fields:" + schema.toString(false)) @@ -891,14 +891,14 @@ object AvroCodec extends AvroCodec { Chunk.fromIterable(annotations) } - private[codec] def toZioStringEnum(avroSchema: SchemaAvro): scala.util.Either[String, Schema[_]] = { + private[codec] def toZioStringEnum(avroSchema: SchemaAvro): zio.prelude.Validation[String, Schema[_]] = { val cases = avroSchema.getEnumSymbols.asScala .map(s => Schema.Case[String, String](s, Schema[String], identity, identity, _.isInstanceOf[String])) .toSeq val caseSet = CaseSet[String](cases: _*).asInstanceOf[Aux[String]] val enumeration: Schema[String] = Schema.enumeration(TypeId.parse("org.apache.avro.Schema"), caseSet) - Right(enumeration.addAllAnnotations(buildZioAnnotations(avroSchema))) + zio.prelude.Validation.succeed(enumeration.addAllAnnotations(buildZioAnnotations(avroSchema))) } private[codec] case object OptionUnion { diff --git a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala index 9217fcced..c3c317bd1 100644 --- a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala +++ b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala @@ -59,13 +59,13 @@ object AvroPropMarker { val propName = "zio.schema.codec.avro.dateTimeFormatter" val default: Formatter = Formatter(DateTimeFormatter.ISO_INSTANT) - def fromAvroStringOrDefault(avroSchema: SchemaAvro, stringType: StringType): Either[String, Formatter] = + def fromAvroStringOrDefault(avroSchema: SchemaAvro, stringType: StringType): zio.prelude.Validation[String, Formatter] = fromAvroString(avroSchema).map { case Some(value) => value case None => getDefaultByStringType(stringType) } - def fromAvroStringOrDefault(avroSchema: SchemaAvro, logicalType: LogicalType): Either[String, Formatter] = + def fromAvroStringOrDefault(avroSchema: SchemaAvro, logicalType: LogicalType): zio.prelude.Validation[String, Formatter] = fromAvroString(avroSchema).map { case Some(value) => value case None => getDefaultByLogicalType(logicalType) @@ -95,30 +95,30 @@ object AvroPropMarker { case StringType.ZoneDateTime => Formatter(DateTimeFormatter.ISO_ZONED_DATE_TIME) } - private def fromAvroString(avroSchema: SchemaAvro): Either[String, Option[Formatter]] = + private def fromAvroString(avroSchema: SchemaAvro): zio.prelude.Validation[String, Option[Formatter]] = avroSchema.getObjectProps.asScala.get(propName).collect { - case "ISO_LOCAL_DATE_TIME" => Right(Formatter(DateTimeFormatter.ISO_LOCAL_DATE_TIME)) - case "ISO_DATE" => Right(Formatter(DateTimeFormatter.ISO_DATE)) - case "ISO_TIME" => Right(Formatter(DateTimeFormatter.ISO_TIME)) - case "ISO_LOCAL_TIME" => Right(Formatter(DateTimeFormatter.ISO_LOCAL_TIME)) - case "ISO_LOCAL_DATE" => Right(Formatter(DateTimeFormatter.ISO_LOCAL_DATE)) - case "ISO_OFFSET_DATE_TIME" => Right(Formatter(DateTimeFormatter.ISO_OFFSET_DATE_TIME)) - case "ISO_OFFSET_DATE" => Right(Formatter(DateTimeFormatter.ISO_OFFSET_DATE)) - case "ISO_OFFSET_TIME" => Right(Formatter(DateTimeFormatter.ISO_OFFSET_TIME)) - case "ISO_ZONED_DATE_TIME" => Right(Formatter(DateTimeFormatter.ISO_ZONED_DATE_TIME)) - case "ISO_ORDINAL_DATE" => Right(Formatter(DateTimeFormatter.ISO_ORDINAL_DATE)) - case "ISO_WEEK_DATE" => Right(Formatter(DateTimeFormatter.ISO_WEEK_DATE)) - case "ISO_INSTANT" => Right(Formatter(DateTimeFormatter.ISO_INSTANT)) - case "ISO_DATE_TIME" => Right(Formatter(DateTimeFormatter.ISO_DATE_TIME)) - case "RFC_1123_DATE_TIME" => Right(Formatter(DateTimeFormatter.RFC_1123_DATE_TIME)) - case "BASIC_ISO_DATE" => Right(Formatter(DateTimeFormatter.BASIC_ISO_DATE)) + case "ISO_LOCAL_DATE_TIME" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_LOCAL_DATE_TIME)) + case "ISO_DATE" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_DATE)) + case "ISO_TIME" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_TIME)) + case "ISO_LOCAL_TIME" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_LOCAL_TIME)) + case "ISO_LOCAL_DATE" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_LOCAL_DATE)) + case "ISO_OFFSET_DATE_TIME" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_OFFSET_DATE_TIME)) + case "ISO_OFFSET_DATE" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_OFFSET_DATE)) + case "ISO_OFFSET_TIME" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_OFFSET_TIME)) + case "ISO_ZONED_DATE_TIME" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_ZONED_DATE_TIME)) + case "ISO_ORDINAL_DATE" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_ORDINAL_DATE)) + case "ISO_WEEK_DATE" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_WEEK_DATE)) + case "ISO_INSTANT" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_INSTANT)) + case "ISO_DATE_TIME" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.ISO_DATE_TIME)) + case "RFC_1123_DATE_TIME" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.RFC_1123_DATE_TIME)) + case "BASIC_ISO_DATE" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.BASIC_ISO_DATE)) case s: String => Try { Formatter(DateTimeFormatter.ofPattern(s)) }.toEither.left.map(_.getMessage) } match { case Some(value) => value.map(Some(_)) - case None => Right(None) + case None => zio.prelude.Validation.succeed(None) } } diff --git a/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala b/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala index 3592028f2..695fb6041 100644 --- a/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala +++ b/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala @@ -47,7 +47,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) val expected = """{"type":"enum","name":"MyEnum","symbols":["A","B","C"]}""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("encodes sealed trait objects only as union of records when no avroEnum annotation is present") { @@ -56,7 +56,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """[{"type":"record","name":"A","fields":[]},{"type":"record","name":"B","fields":[]},{"type":"record","name":"MyC","fields":[]}]""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("encodes sealed trait objects only as enum when avroEnum annotation is present") { @@ -64,7 +64,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) val expected = """{"type":"enum","name":"MyEnum","symbols":["A","B","MyC"]}""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("ignores avroEnum annotation if ADT cannot be reduced to String symbols") { val schema = DeriveSchema.gen[SpecTestData.CaseObjectAndCaseClassAdt] @@ -72,7 +72,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """[{"type":"record","name":"A","fields":[]},{"type":"record","name":"B","fields":[]},{"type":"record","name":"MyC","fields":[]},{"type":"record","name":"D","fields":[{"name":"s","type":"string"}]}]""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("flatten nested unions with initialSchemaDerived derivation") { val schema = DeriveSchema.gen[SpecTestData.UnionWithNesting] @@ -80,7 +80,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """[{"type":"record","name":"A","fields":[]},{"type":"record","name":"B","fields":[]},{"type":"record","name":"MyC","fields":[]},{"type":"record","name":"D","fields":[{"name":"s","type":"string"}]}]""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("wraps nested unions") { val schemaA = DeriveSchema.gen[UnionWithNesting.Nested.A.type] @@ -137,7 +137,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val wrappedString = """[{"type":"record","name":"wrapper_Nested","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"A","namespace":"","fields":[]},{"type":"record","name":"B","namespace":"","fields":[]}]}],"zio.schema.codec.avro.wrapper":true},{"type":"record","name":"C","fields":[]},{"type":"record","name":"D","fields":[{"name":"s","type":"string"}]}]""" - assert(result)(isRight(equalTo(wrappedString))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(wrappedString))) } ), suite("record")( @@ -149,7 +149,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"hashed_1642816955","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" - assert(result1)(isRight(equalTo(expected))) && assert(result2)(isRight(equalTo(expected))) + assert(result1)(iszio.prelude.Validation.succeed(equalTo(expected))) && assert(result2)(iszio.prelude.Validation.succeed(equalTo(expected))) } @@ TestAspect.ignore, // TODO: FIX test("fail with left on invalid name") { val schema = DeriveSchema.gen[SpecTestData.Record].annotate(AvroAnnotations.name("0invalid")) @@ -162,7 +162,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" ) @@ -174,7 +174,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"record","name":"MyNamedFieldRecord","fields":[{"name":"myNamedField","type":"string"},{"name":"b","type":"boolean"}]}""" ) @@ -186,7 +186,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"record","name":"MyNamedRecord","doc":"My doc","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" ) @@ -199,7 +199,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"record","name":"MyNamedRecord","namespace":"test.namespace","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" ) @@ -218,7 +218,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"error","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("includes all fields") { val schema = DeriveSchema.gen[SpecTestData.NamedRecord] @@ -226,7 +226,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("includes nested record fields") { val schema = DeriveSchema.gen[SpecTestData.NestedRecord] @@ -234,7 +234,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"NestedRecord","fields":[{"name":"s","type":"string"},{"name":"nested","type":{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}]}""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) } ), suite("map")( @@ -244,7 +244,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Map(keySchema, valueSchema) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"map","values":"string"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"map","values":"string"}"""))) }, test("string keys and complex values") { val keySchema = Schema.primitive(StandardType.StringType) @@ -253,7 +253,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"map","values":{"type":"record","name":"Simple","fields":[{"name":"s","type":"string"}]}}""" ) @@ -273,7 +273,7 @@ object AvroCodecSpec extends ZIOSpecDefault { ) val hasTupleField_2 = containsString("""{"name":"_2","type":"string"}""") - assert(result)(isRight(isArray && tupleItems && hasTupleField_1 && hasTupleField_2)) + assert(result)(iszio.prelude.Validation.succeed(isArray && tupleItems && hasTupleField_1 && hasTupleField_2)) }, test("complex keys and complex values") { val keySchema = DeriveSchema.gen[SpecTestData.SimpleRecord] @@ -290,7 +290,7 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"name":"_2","type":{"type":"record","name":"MyNamedRecord","namespace":"","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}""" ) - assert(result)(isRight(isArray && tupleItems && hasTupleField_1 && hasTupleField_2)) + assert(result)(iszio.prelude.Validation.succeed(isArray && tupleItems && hasTupleField_1 && hasTupleField_2)) } ), suite("seq")( @@ -304,7 +304,7 @@ object AvroCodecSpec extends ZIOSpecDefault { ) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"array","items":"string"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"array","items":"string"}"""))) }, test("encodes complex types") { val valueSchema = DeriveSchema.gen[SpecTestData.NamedRecord] @@ -313,7 +313,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"array","items":{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}""" ) @@ -332,7 +332,7 @@ object AvroCodecSpec extends ZIOSpecDefault { ) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"array","items":"string"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"array","items":"string"}"""))) }, test("encodes complex types") { val valueSchema = DeriveSchema.gen[SpecTestData.NamedRecord] @@ -341,7 +341,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"array","items":{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}""" ) @@ -354,7 +354,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Optional(Schema.primitive(StandardType.StringType)) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""["null","string"]"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""["null","string"]"""))) }, test("encodes complex types") { val valueSchema = DeriveSchema.gen[SpecTestData.NamedRecord] @@ -362,7 +362,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """["null",{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}]""" ) @@ -374,7 +374,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """["null",{"type":"record","name":"wrapper_hashed_3594628","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":"null"}],"zio.schema.codec.avro.wrapper":true}]""" ) @@ -387,7 +387,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """["null",{"type":"record","name":"wrapper_hashed_n813828848","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":["null","string"]}],"zio.schema.codec.avro.wrapper":true}]""" ) @@ -400,7 +400,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """["null",{"type":"record","name":"wrapper_MyEnum","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"A","namespace":"","fields":[]},{"type":"record","name":"B","namespace":"","fields":[]},{"type":"record","name":"MyC","namespace":"","fields":[]}]}],"zio.schema.codec.avro.wrapper":true}]""" ) @@ -414,7 +414,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """["null",{"type":"record","name":"wrapper_hashed_n630422444","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":["string","int"]}],"zio.schema.codec.avro.either":true}]""" ) @@ -430,7 +430,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"wrapper_hashed_n630422444","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":["string","int"]}],"zio.schema.codec.avro.either":true}""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("create a named union") { val schema = Schema @@ -440,7 +440,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"wrapper_MyEither","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":["string","int"]}],"zio.schema.codec.avro.either":true}""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("encodes complex types") { val left = DeriveSchema.gen[SpecTestData.SimpleRecord] @@ -450,7 +450,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"wrapper_hashed_754352222","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"Simple","namespace":"","fields":[{"name":"s","type":"string"}]},"string"]}],"zio.schema.codec.avro.either":true}""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("fails with duplicate names") { val left = DeriveSchema.gen[SpecTestData.SimpleRecord] @@ -469,7 +469,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"record","name":"wrapper_hashed_n465006219","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"wrapper_hashed_n813828848","fields":[{"name":"value","type":["null","string"]}],"zio.schema.codec.avro.wrapper":true},"string"]}],"zio.schema.codec.avro.either":true}""" ) @@ -485,7 +485,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"wrapper_hashed_2071802344","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"wrapper_hashed_n465006219","fields":[{"name":"value","type":[{"type":"record","name":"wrapper_hashed_n813828848","fields":[{"name":"value","type":["null","string"]}],"zio.schema.codec.avro.wrapper":true},"string"]}],"zio.schema.codec.avro.either":true},"string"]}],"zio.schema.codec.avro.either":true}""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) } ), suite("tuple")( @@ -496,7 +496,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"record","name":"MyTuple","fields":[{"name":"_1","type":"string"},{"name":"_2","type":"string"}],"zio.schema.codec.recordType":"tuple"}""" ) @@ -513,7 +513,7 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"name":"_1","type":{"type":"record","name":"Simple","fields":[{"name":"s","type":"string"}]}}""" val field_2 = """{"name":"_2","type":{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}""" - assert(result)(isRight(containsString(field_1) && containsString(field_2))) + assert(result)(iszio.prelude.Validation.succeed(containsString(field_1) && containsString(field_2))) }, test("encodes duplicate complex types by reference") { val left = DeriveSchema.gen[SpecTestData.SimpleRecord] @@ -524,7 +524,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field_1 = """{"name":"_1","type":{"type":"record","name":"Simple","fields":[{"name":"s","type":"string"}]}}""" val field_2 = """{"name":"_2","type":"Simple"}""" - assert(result)(isRight(containsString(field_1) && containsString(field_2))) + assert(result)(iszio.prelude.Validation.succeed(containsString(field_1) && containsString(field_2))) } ), suite("primitives")( @@ -532,55 +532,55 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.primitive(StandardType.UnitType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("\"null\""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("\"null\""))) }, test("encodes StringType") { val schema = Schema.primitive(StandardType.StringType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("\"string\""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("\"string\""))) }, test("encodes BooleanType") { val schema = Schema.primitive(StandardType.BoolType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("\"boolean\""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("\"boolean\""))) }, test("encodes ShortType") { val schema = Schema.primitive(StandardType.ShortType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"short"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"short"}"""))) }, test("encodes IntType") { val schema = Schema.primitive(StandardType.IntType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("\"int\""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("\"int\""))) }, test("encodes LongType") { val schema = Schema.primitive(StandardType.LongType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("\"long\""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("\"long\""))) }, test("encodes FloatType") { val schema = Schema.primitive(StandardType.FloatType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("\"float\""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("\"float\""))) }, test("encodes DoubleType") { val schema = Schema.primitive(StandardType.DoubleType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("\"double\""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("\"double\""))) }, test("encodes BinaryType as bytes") { val schema = Schema.primitive(StandardType.BinaryType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("\"bytes\""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("\"bytes\""))) }, test("encodes BinaryType as fixed") { val size = 12 @@ -591,26 +591,26 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) val expected = """{"type":"fixed","name":"MyFixed","doc":"","size":12}""" - assert(result)(isRight(equalTo(expected))) + assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) }, test("encodes CharType") { val schema = Schema.primitive(StandardType.CharType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"char"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"char"}"""))) }, test("encodes UUIDType") { val schema = Schema.primitive(StandardType.UUIDType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"string","logicalType":"uuid"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"string","logicalType":"uuid"}"""))) }, test("encodes BigDecimalType as Bytes") { val schema = Schema.primitive(StandardType.BigDecimalType).annotate(AvroAnnotations.decimal(DecimalType.Bytes)) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":48,"scale":24}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"bytes","logicalType":"decimal","precision":48,"scale":24}"""))) }, test("encodes BigDecimalType as Bytes with scala and precision") { val schema = Schema @@ -620,7 +620,7 @@ object AvroCodecSpec extends ZIOSpecDefault { .annotate(AvroAnnotations.precision(20)) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":20,"scale":10}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"bytes","logicalType":"decimal","precision":20,"scale":10}"""))) }, test("encodes BigDecimalType as Fixed") { val schema = @@ -628,7 +628,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"fixed","name":"Decimal_48_24","size":21,"logicalType":"decimal","precision":48,"scale":24}""" ) @@ -644,7 +644,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"fixed","name":"Decimal_20_10","size":9,"logicalType":"decimal","precision":20,"scale":10}""" ) @@ -656,7 +656,7 @@ object AvroCodecSpec extends ZIOSpecDefault { Schema.primitive(StandardType.BigIntegerType).annotate(AvroAnnotations.decimal(DecimalType.Bytes)) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":24,"scale":24}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"bytes","logicalType":"decimal","precision":24,"scale":24}"""))) }, test("encodes BigIntegerType as Bytes with scala and precision") { val schema = Schema @@ -666,7 +666,7 @@ object AvroCodecSpec extends ZIOSpecDefault { .annotate(AvroAnnotations.precision(20)) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":10,"scale":10}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"bytes","logicalType":"decimal","precision":10,"scale":10}"""))) }, test("encodes BigIntegerType as Fixed") { val schema = @@ -674,7 +674,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"fixed","name":"Decimal_24_24","size":11,"logicalType":"decimal","precision":24,"scale":24}""" ) @@ -690,7 +690,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"fixed","name":"Decimal_10_10","size":5,"logicalType":"decimal","precision":10,"scale":10}""" ) @@ -701,31 +701,31 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.primitive(StandardType.DayOfWeekType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"dayOfWeek"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"dayOfWeek"}"""))) }, test("encodes MonthType") { val schema = Schema.primitive(StandardType.MonthType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"month"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"month"}"""))) }, test("encodes YearType") { val schema = Schema.primitive(StandardType.YearType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"year"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"year"}"""))) }, test("encodes ZoneIdType") { val schema = Schema.primitive(StandardType.ZoneIdType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"string","zio.schema.codec.stringType":"zoneId"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"string","zio.schema.codec.stringType":"zoneId"}"""))) }, test("encodes ZoneOffsetType") { val schema = Schema.primitive(StandardType.ZoneOffsetType) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"zoneOffset"}"""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"zoneOffset"}"""))) }, //TODO 1 //test("encodes MonthDayType") { @@ -733,7 +733,7 @@ object AvroCodecSpec extends ZIOSpecDefault { // val result = AvroCodec.encode(schema) // assert(result)( - // isRight( + // iszio.prelude.Validation.succeed( // equalTo( // """{"type":"record","name":"MonthDay","namespace":"zio.schema.codec.avro","fields":[{"name":"month","type":"int"},{"name":"day","type":"int"}],"zio.schema.codec.recordType":"monthDay"}""" // ) @@ -746,7 +746,7 @@ object AvroCodecSpec extends ZIOSpecDefault { // val result = AvroCodec.encode(schema) // // assert(result)( - // isRight( + // iszio.prelude.Validation.succeed( // equalTo( // """{"type":"record","name":"Period","namespace":"zio.schema.codec.avro","fields":[{"name":"years","type":"int"},{"name":"months","type":"int"},{"name":"days","type":"int"}],"zio.schema.codec.recordType":"period"}""" // ) @@ -759,7 +759,7 @@ object AvroCodecSpec extends ZIOSpecDefault { // val result = AvroCodec.encode(schema) // // assert(result)( - // isRight( + // iszio.prelude.Validation.succeed( // equalTo( // """{"type":"record","name":"YearMonth","namespace":"zio.schema.codec.avro","fields":[{"name":"year","type":"int"},{"name":"month","type":"int"}],"zio.schema.codec.recordType":"yearMonth"}""" // ) @@ -772,7 +772,7 @@ object AvroCodecSpec extends ZIOSpecDefault { // val result = AvroCodec.encode(schema) // // assert(result)( - // isRight( + // iszio.prelude.Validation.succeed( // equalTo( // """{"type":"record","name":"Duration","namespace":"zio.schema.codec.avro","fields":[{"name":"seconds","type":"long"},{"name":"nanos","type":"int"}],"zio.schema.codec.recordType":"duration","zio.schema.codec.avro.durationChronoUnit":"DAYS"}""" // ) @@ -784,7 +784,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"string","zio.schema.codec.stringType":"instant"}""" ) @@ -797,7 +797,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"string","zio.schema.codec.stringType":"localDate"}""" ) @@ -810,7 +810,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"string","zio.schema.codec.stringType":"localTime"}""" ) @@ -823,7 +823,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"string","zio.schema.codec.stringType":"localDateTime"}""" ) @@ -835,7 +835,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"string","zio.schema.codec.stringType":"offsetTime"}""" ) @@ -847,7 +847,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"string","zio.schema.codec.stringType":"offsetDateTime"}""" ) @@ -859,7 +859,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) assert(result)( - isRight( + iszio.prelude.Validation.succeed( equalTo( """{"type":"string","zio.schema.codec.stringType":"zoneDateTime"}""" ) @@ -877,7 +877,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Lazy(() => Schema.primitive(StandardType.StringType)) val result = AvroCodec.encode(schema) - assert(result)(isRight(equalTo("\"string\""))) + assert(result)(iszio.prelude.Validation.succeed(equalTo("\"string\""))) } ), /** @@ -891,7 +891,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema.map(_.ast))( - isRight( + iszio.prelude.Validation.succeed( equalTo( Schema .record( @@ -942,7 +942,7 @@ object AvroCodecSpec extends ZIOSpecDefault { ) ) - assert(schema.map(_.ast))(isRight(equalTo(expectedSchema.ast))) + assert(schema.map(_.ast))(iszio.prelude.Validation.succeed(equalTo(expectedSchema.ast))) }, test("unwrap a wrapped initialSchemaDerived") { val s = @@ -950,7 +950,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema.map(_.ast))( - isRight( + iszio.prelude.Validation.succeed( equalTo( Schema .record( @@ -978,14 +978,14 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"record","name":"Period","namespace":"zio.schema.codec.avro","fields":[{"name":"years","type":"int"},{"name":"months","type":"int"},{"name":"days","type":"int"}],"zio.schema.codec.recordType":"period"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.PeriodType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.PeriodType))) }, test("yearMonth record") { val s = """{"type":"record","name":"YearMonth","namespace":"zio.schema.codec.avro","fields":[{"name":"year","type":"int"},{"name":"month","type":"int"}],"zio.schema.codec.recordType":"yearMonth"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.YearMonthType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.YearMonthType))) }, test("tuple record successful") { val s = @@ -993,7 +993,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema)( - isRight(isTuple(isStandardType(StandardType.StringType), isStandardType(StandardType.IntType))) + iszio.prelude.Validation.succeed(isTuple(isStandardType(StandardType.StringType), isStandardType(StandardType.IntType))) ) }, test("tuple record failing") { @@ -1008,56 +1008,56 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"record","name":"MonthDay","namespace":"zio.schema.codec.avro","fields":[{"name":"month","type":"int"},{"name":"day","type":"int"}],"zio.schema.codec.recordType":"monthDay"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.MonthDayType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.MonthDayType))) }, test("duration record without chrono unit annotation") { val s = """{"type":"record","name":"Duration","namespace":"zio.schema.codec.avro","fields":[{"name":"seconds","type":"long"},{"name":"nanos","type":"int"}],"zio.schema.codec.recordType":"duration"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.DurationType))) //(ChronoUnit.MILLIS)))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.DurationType))) //(ChronoUnit.MILLIS)))) }, test("duration record chrono unit annotation") { val s = """{"type":"record","name":"Duration","namespace":"zio.schema.codec.avro","fields":[{"name":"seconds","type":"long"},{"name":"nanos","type":"int"}],"zio.schema.codec.recordType":"duration","zio.schema.codec.avro.durationChronoUnit":"DAYS"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.DurationType))) //(ChronoUnit.DAYS)))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.DurationType))) //(ChronoUnit.DAYS)))) }, test("assign the name annotation") { val s = """{"type":"record","name":"TestRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isRecord(hasNameAnnotation(equalTo("TestRecord"))))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasNameAnnotation(equalTo("TestRecord"))))) }, test("assign the namespace annotation") { val s = """{"type":"record","name":"TestRecord","namespace":"MyTest","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isRecord(hasNamespaceAnnotation(equalTo("MyTest"))))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasNamespaceAnnotation(equalTo("MyTest"))))) }, test("not assign the namespace annotation if missing") { val s = """{"type":"record","name":"TestRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isRecord(hasNamespaceAnnotation(anything).negate))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasNamespaceAnnotation(anything).negate))) }, zio.test.test("assign the doc annotation") { val s = """{"type":"record","name":"TestRecord","doc":"Very helpful documentation!","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isRecord(hasDocAnnotation(equalTo("Very helpful documentation!"))))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasDocAnnotation(equalTo("Very helpful documentation!"))))) }, test("not assign the doc annotation if missing") { val s = """{"type":"record","name":"TestRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isRecord(hasDocAnnotation(anything).negate))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasDocAnnotation(anything).negate))) }, test("assign the aliases annotation") { val s = @@ -1065,7 +1065,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema)( - isRight(isRecord(hasAliasesAnnotation(exists[String](equalTo("wow")) && exists(equalTo("cool"))))) + iszio.prelude.Validation.succeed(isRecord(hasAliasesAnnotation(exists[String](equalTo("wow")) && exists(equalTo("cool"))))) ) }, test("not assign the aliases annotation if missing") { @@ -1073,28 +1073,28 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"record","name":"TestRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isRecord(hasAliasesAnnotation(anything).negate))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasAliasesAnnotation(anything).negate))) }, test("not assign the aliases annotation if empty") { val s = """{"type":"record","name":"TestRecord","aliases":[],"fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isRecord(hasAliasesAnnotation(anything).negate))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasAliasesAnnotation(anything).negate))) }, zio.test.test("assign the error annotation") { val s = """{"type":"error","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isRecord(hasErrorAnnotation))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasErrorAnnotation))) }, test("not assign the error annotation if not an error") { val s = """{"type":"record","name":"TestRecord","aliases":[],"fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isRecord(hasErrorAnnotation.negate))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasErrorAnnotation.negate))) } ), suite("fields")( @@ -1105,7 +1105,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field1 = hasRecordField(hasLabel(equalTo("s")) && hasSchema(isStandardType(StandardType.StringType))) val field2 = hasRecordField(hasLabel(equalTo("b")) && hasSchema(isStandardType(StandardType.BoolType))) - assert(schema)(isRight(isRecord(field1 && field2))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2))) }, test("decodes the fields complex initialSchemaDerived") { val s = @@ -1116,7 +1116,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field2 = hasRecordField(hasLabel(equalTo("b")) && hasSchema(isStandardType(StandardType.BoolType))) val complex = isRecord(field1 && field2) val field = hasRecordField(hasLabel(equalTo("complex")) && hasSchema(complex)) - assert(schema)(isRight(isRecord(field))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(field))) }, zio.test.test("assign the field name annotation") { val s = @@ -1125,7 +1125,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field1 = hasRecordField(hasLabel(equalTo("s")) && hasNameAnnotation(equalTo("s"))) val field2 = hasRecordField(hasLabel(equalTo("b")) && hasNameAnnotation(equalTo("b"))) - assert(schema)(isRight(isRecord(field1 && field2))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2))) }, zio.test.test("assign the field doc annotation iff it exists") { val s = @@ -1134,7 +1134,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field1 = hasRecordField(hasLabel(equalTo("s")) && hasDocAnnotation(equalTo("Very helpful doc!"))) val field2 = hasRecordField(hasLabel(equalTo("b")) && hasDocAnnotation(anything).negate) - assert(schema)(isRight(isRecord(field1 && field2))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2))) }, test("assign the field default annotation") { val s = @@ -1146,7 +1146,7 @@ object AvroCodecSpec extends ZIOSpecDefault { hasLabel(equalTo("complex")) && hasFieldDefaultAnnotation(asString(equalTo("""{s=defaultS, b=true}"""))) ) val field3 = hasRecordField(hasLabel(equalTo("b")) && hasFieldDefaultAnnotation(anything).negate) - assert(schema)(isRight(isRecord(field1 && field2 && field3))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2 && field3))) }, zio.test.test("assign the fieldOrder annotation") { val s = @@ -1159,7 +1159,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field2 = hasRecordField( hasLabel(equalTo("b")) && hasFieldOrderAnnotation(equalTo(AvroAnnotations.FieldOrderType.Ascending)) ) - assert(schema)(isRight(isRecord(field1 && field2))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2))) }, zio.test.test("assign the field aliases annotation") { val s = @@ -1170,7 +1170,7 @@ object AvroCodecSpec extends ZIOSpecDefault { hasLabel(equalTo("s")) && hasAliasesAnnotation(Assertion.hasSameElements(Seq("wow", "cool"))) ) val field2 = hasRecordField(hasLabel(equalTo("b")) && hasAliasesAnnotation(anything).negate) - assert(schema)(isRight(isRecord(field1 && field2))) + assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2))) } ), suite("enum")( @@ -1181,56 +1181,56 @@ object AvroCodecSpec extends ZIOSpecDefault { val symbolKeysAssetion = Assertion.hasKeys(hasSameElements(Seq("a", "b", "c"))) val enumStringTypeAssertion: Assertion[ListMap[String, (Schema[_], Chunk[Any])]] = Assertion.hasValues(forall(tuple2First(isStandardType(StandardType.StringType)))) - assert(schema)(isRight(isEnum(enumStructure(symbolKeysAssetion && enumStringTypeAssertion)))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(enumStructure(symbolKeysAssetion && enumStringTypeAssertion)))) }, test("assign the enum name annotation") { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isEnum(hasNameAnnotation(equalTo("TestEnum"))))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasNameAnnotation(equalTo("TestEnum"))))) }, test("assign the enum namespace annotation") { val s = """{"type":"enum","name":"TestEnum","namespace":"MyTest","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isEnum(hasNamespaceAnnotation(equalTo("MyTest"))))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasNamespaceAnnotation(equalTo("MyTest"))))) }, test("not assign the enum namespace annotation if empty") { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isEnum(hasNamespaceAnnotation(anything).negate))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasNamespaceAnnotation(anything).negate))) }, test("assign the enum aliases annotation") { val s = """{"type":"enum","name":"TestEnum","aliases":["MyAlias", "MyAlias2"],"symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isEnum(hasAliasesAnnotation(hasSameElements(Seq("MyAlias", "MyAlias2")))))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasAliasesAnnotation(hasSameElements(Seq("MyAlias", "MyAlias2")))))) }, test("not assign the enum aliases annotation if empty") { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isEnum(hasAliasesAnnotation(anything).negate))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasAliasesAnnotation(anything).negate))) }, test("assign the enum doc annotation") { val s = """{"type":"enum","name":"TestEnum","doc":"Some very helpful documentation!","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isEnum(hasDocAnnotation(equalTo("Some very helpful documentation!"))))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasDocAnnotation(equalTo("Some very helpful documentation!"))))) }, test("not assign the enum doc annotation if empty") { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isEnum(hasAliasesAnnotation(anything).negate))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasAliasesAnnotation(anything).negate))) }, test("assign the enum default annotation") { val s = """{"type":"enum","name":"TestEnum","default":"a","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isEnum(hasDefaultAnnotation(equalTo("a"))))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasDefaultAnnotation(equalTo("a"))))) }, test("fail if enum default is not a symbol") { val s = """{"type":"enum","name":"TestEnum","default":"d","symbols":["a","b","c"]}""" @@ -1242,28 +1242,28 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isEnum(hasDefaultAnnotation(anything).negate))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasDefaultAnnotation(anything).negate))) } ), test("decodes primitive array") { val s = """{"type":"array","items":{"type":"int"}}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isSequence(hasSequenceElementSchema(isStandardType(StandardType.IntType))))) + assert(schema)(iszio.prelude.Validation.succeed(isSequence(hasSequenceElementSchema(isStandardType(StandardType.IntType))))) }, test("decodes complex array") { val s = """{"type":"array","items":{"type":"record","name":"TestRecord","fields":[{"name":"f1","type":"int"},{"name":"f2","type":"string"}]}}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isSequence(hasSequenceElementSchema(isRecord(anything))))) + assert(schema)(iszio.prelude.Validation.succeed(isSequence(hasSequenceElementSchema(isRecord(anything))))) }, test("decodes map with string keys") { val s = """{"type":"map","values":{"type":"int"}}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema)( - isRight( + iszio.prelude.Validation.succeed( isMap( hasMapKeys(isStandardType(StandardType.StringType)) && hasMapValues( isStandardType(StandardType.IntType) @@ -1277,19 +1277,19 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """[{"type":"null"}, {"type":"int"}]""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isOption(hasOptionElementSchema(isStandardType(StandardType.IntType))))) + assert(schema)(iszio.prelude.Validation.succeed(isOption(hasOptionElementSchema(isStandardType(StandardType.IntType))))) }, test("option union with null on second position") { val s = """[{"type":"int"}, {"type":"null"}]""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isOption(hasOptionElementSchema(isStandardType(StandardType.IntType))))) + assert(schema)(iszio.prelude.Validation.succeed(isOption(hasOptionElementSchema(isStandardType(StandardType.IntType))))) }, test("not an option union with more than one element type") { val s = """[{"type":"null"}, {"type":"int"}, {"type":"string"}]""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isOption(anything).negate)) + assert(schema)(iszio.prelude.Validation.succeed(isOption(anything).negate)) }, test("nested either union") { val s = @@ -1297,7 +1297,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema)( - isRight( + iszio.prelude.Validation.succeed( isEither( isEither(isOption(anything), isStandardType(StandardType.StringType)), isStandardType(StandardType.StringType) @@ -1312,7 +1312,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val assertion1 = hasKey("null", tuple2First(isStandardType(StandardType.UnitType))) val sssertion2 = hasKey("int", tuple2First(isStandardType(StandardType.IntType))) val assertion3 = hasKey("string", tuple2First(isStandardType(StandardType.StringType))) - assert(schema)(isRight(isEnum(enumStructure(assertion1 && sssertion2 && assertion3)))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(enumStructure(assertion1 && sssertion2 && assertion3)))) }, test("correct case codec for case object of ADT") { val s = @@ -1322,7 +1322,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val assertionA = hasKey("A", tuple2First(isEmptyRecord)) val assertionB = hasKey("B", tuple2First(isEmptyRecord)) val assertionMyC = hasKey("MyC", tuple2First(isEmptyRecord)) - assert(schema)(isRight(isEnum(enumStructure(assertionA && assertionB && assertionMyC)))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(enumStructure(assertionA && assertionB && assertionMyC)))) }, test("correct case codec for case class of ADT") { val s = @@ -1335,7 +1335,7 @@ object AvroCodecSpec extends ZIOSpecDefault { ) val assertionB = hasKey("B", tuple2First(isEmptyRecord)) val assertionMyC = hasKey("MyC", tuple2First(isEmptyRecord)) - assert(schema)(isRight(isEnum(enumStructure(assertionA && assertionB && assertionMyC)))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(enumStructure(assertionA && assertionB && assertionMyC)))) }, test("unwrap nested union") { val s = @@ -1354,7 +1354,7 @@ object AvroCodecSpec extends ZIOSpecDefault { hasKey("zio.schema.codec.avro.wrapper_hashed_n465006219", tuple2First(nestedEnumAssertion)) val cEnumKey = hasKey("C", tuple2First(isEmptyRecord)) val dEnumKey = hasKey("D", tuple2First(isRecord(hasRecordField(hasLabel(equalTo("s")))))) - assert(schema)(isRight(isEnum(enumStructure(nestedEnumKey && cEnumKey && dEnumKey)))) + assert(schema)(iszio.prelude.Validation.succeed(isEnum(enumStructure(nestedEnumKey && cEnumKey && dEnumKey)))) } ), suite("fixed")( @@ -1370,7 +1370,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val hasPrecisionAnnotation: Assertion[Iterable[Any]] = exists(equalTo(AvroAnnotations.precision(11))) val hasAnnotationsAssertion = annotations(hasDecimalTypeAnnotation && hasScalaAnnotation && hasPrecisionAnnotation) - assert(schema)(isRight(isDecimalAssertion && hasAnnotationsAssertion)) + assert(schema)(iszio.prelude.Validation.succeed(isDecimalAssertion && hasAnnotationsAssertion)) }, test("logical type decimal as BigInteger") { val s = @@ -1385,7 +1385,7 @@ object AvroCodecSpec extends ZIOSpecDefault { exists(Assertion.isSubtype[AvroAnnotations.precision.type](anything)).negate val hasAnnotationsAssertion = annotations(hasDecimalTypeAnnotation && hasScalaAnnotation && doesNotHavePrecisionAnnotation) - assert(schema)(isRight(isBigIntegerType && hasAnnotationsAssertion)) + assert(schema)(iszio.prelude.Validation.succeed(isBigIntegerType && hasAnnotationsAssertion)) }, test("fail on invalid logical type") { val s = @@ -1399,7 +1399,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) val hasNameAnnotation = annotations(exists(equalTo(AvroAnnotations.name("Something")))) - assert(schema)(isRight(isStandardType(StandardType.BinaryType) && hasNameAnnotation)) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.BinaryType) && hasNameAnnotation)) } ), suite("string")( @@ -1407,20 +1407,20 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """{"type":"string","zio.schema.codec.stringType":"zoneId"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.ZoneIdType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.ZoneIdType))) }, test("decodes instant with formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"instant","zio.schema.codec.avro.dateTimeFormatter":"ISO_INSTANT"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.InstantType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) }, test("decodes instant using default") { val s = """{"type":"string","zio.schema.codec.stringType":"instant"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.InstantType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) }, test("decodes instant with formatter pattern") { val pattern = "yyyy MM dd" @@ -1428,7 +1428,7 @@ object AvroCodecSpec extends ZIOSpecDefault { s"""{"type":"string","zio.schema.codec.stringType":"instant","zio.schema.codec.avro.dateTimeFormatter":"$pattern"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.InstantType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) }, test("decode DateTimeFormatter field fails on invalid formatter") { val pattern = "this is not a valid formatter pattern" @@ -1443,40 +1443,40 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"string","zio.schema.codec.stringType":"localDate","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalDateType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateType))) }, test("decodes localDate with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localDate"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalDateType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateType))) }, test("decodes localTime with formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localTime","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) }, test("decodes localTime with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localTime"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) }, test("decodes localDateTime with formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localDateTime","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalDateTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType))) }, test("decodes localDateTime with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localDateTime"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema)( - isRight(isStandardType(StandardType.LocalDateTimeType)) + iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType)) ) }, test("decodes zonedDateTime with formatter") { @@ -1484,14 +1484,14 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"string","zio.schema.codec.stringType":"zoneDateTime","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.ZonedDateTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.ZonedDateTimeType))) }, test("decodes zonedDateTime with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"zoneDateTime"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema)( - isRight(isStandardType(StandardType.ZonedDateTimeType)) + iszio.prelude.Validation.succeed(isStandardType(StandardType.ZonedDateTimeType)) ) }, test("decodes offsetTime with formatter") { @@ -1499,40 +1499,40 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"string","zio.schema.codec.stringType":"offsetTime","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.OffsetTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.OffsetTimeType))) }, test("decodes offsetTime with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"offsetTime"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.OffsetTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.OffsetTimeType))) }, test("decodes offsetDateTime with formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"offsetDateTime","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.OffsetDateTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.OffsetDateTimeType))) }, test("decodes offsetDateTime with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"offsetDateTime"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema)( - isRight(isStandardType(StandardType.OffsetDateTimeType)) + iszio.prelude.Validation.succeed(isStandardType(StandardType.OffsetDateTimeType)) ) }, test("decodes logical type uuid") { val s = """{"type":"string","logicalType":"uuid"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.UUIDType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.UUIDType))) }, test("decodes primitive type string") { val s = """{"type":"string"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.StringType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.StringType))) } ), suite("bytes")( @@ -1547,7 +1547,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val hasPrecisionAnnotation: Assertion[Iterable[Any]] = exists(equalTo(AvroAnnotations.precision(20))) val hasAnnotationsAssertion = annotations(hasDecimalTypeAnnotation && hasScalaAnnotation && hasPrecisionAnnotation) - assert(schema)(isRight(isDecimalAssertion && hasAnnotationsAssertion)) + assert(schema)(iszio.prelude.Validation.succeed(isDecimalAssertion && hasAnnotationsAssertion)) }, test("logical type decimal as BigInteger") { val s = """{"type":"bytes","logicalType":"decimal","precision":20,"scale":20}""" @@ -1558,13 +1558,13 @@ object AvroCodecSpec extends ZIOSpecDefault { exists(equalTo(AvroAnnotations.decimal(DecimalType.Bytes))) val hasScalaAnnotation: Assertion[Iterable[Any]] = exists(equalTo(AvroAnnotations.scale(20))) val hasAnnotationsAssertion = annotations(hasDecimalTypeAnnotation && hasScalaAnnotation) - assert(schema)(isRight(isBigIntegerAssertion && hasAnnotationsAssertion)) + assert(schema)(iszio.prelude.Validation.succeed(isBigIntegerAssertion && hasAnnotationsAssertion)) }, test("decode as binary") { val s = """{"type":"bytes"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.BinaryType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.BinaryType))) } ), suite("int")( @@ -1572,69 +1572,69 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """{"type":"int","zio.schema.codec.intType":"char"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.CharType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.CharType))) }, test("decodes dayOfWeek") { val s = """{"type":"int","zio.schema.codec.intType":"dayOfWeek"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.DayOfWeekType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.DayOfWeekType))) }, test("decodes Year") { val s = """{"type":"int","zio.schema.codec.intType":"year"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.YearType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.YearType))) }, test("decodes short") { val s = """{"type":"int","zio.schema.codec.intType":"short"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.ShortType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.ShortType))) }, test("decodes month") { val s = """{"type":"int","zio.schema.codec.intType":"month"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.MonthType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.MonthType))) }, test("decodes zoneOffset") { val s = """{"type":"int","zio.schema.codec.intType":"zoneOffset"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.ZoneOffsetType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.ZoneOffsetType))) }, test("decodes int") { val s = """{"type":"int"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.IntType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.IntType))) }, test("decodes logical type timemillis") { val s = """{"type":"int","logicalType":"time-millis","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) }, test("decodes logical type timemillis with default formatter") { val s = """{"type":"int","logicalType":"time-millis"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) }, test("decodes logical type date") { val s = """{"type":"int","logicalType":"date"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalDateType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateType))) }, test("decodes logical type date with default formatter") { val s = """{"type":"int","logicalType":"date"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalDateType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateType))) } ), suite("long")( @@ -1642,60 +1642,60 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """{"type":"long"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LongType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LongType))) }, test("decodes logical type timeMicros") { val s = """{"type":"long","logicalType":"time-micros","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) }, test("decodes logical type timeMicros with default formatter") { val s = """{"type":"long","logicalType":"time-micros"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) }, test("decodes logical type timestampMillis") { val s = """{"type":"long","logicalType":"timestamp-millis","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.InstantType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) }, test("decodes logical type timestampMillis with default formatter") { val s = """{"type":"long","logicalType":"timestamp-millis"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.InstantType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) }, test("decodes logical type timestampMicros") { val s = """{"type":"long","logicalType":"timestamp-micros","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.InstantType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) }, test("decodes logical type timestampMicros with default formatter") { val s = """{"type":"long","logicalType":"timestamp-micros"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.InstantType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) }, test("decodes logical type LocalTimestamp millis") { val s = """{"type":"long","logicalType":"local-timestamp-millis","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalDateTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType))) }, test("decodes logical type LocalTimestamp millis with default formatter") { val s = """{"type":"long","logicalType":"local-timestamp-millis"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema)( - isRight(isStandardType(StandardType.LocalDateTimeType)) + iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType)) ) }, test("decodes logical type LocalTimestamp micros") { @@ -1703,14 +1703,14 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"long","logicalType":"local-timestamp-micros","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.LocalDateTimeType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType))) }, test("decodes logical type LocalTimestamp micros with default formatter") { val s = """{"type":"long","logicalType":"local-timestamp-micros"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) assert(schema)( - isRight(isStandardType(StandardType.LocalDateTimeType)) + iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType)) ) } ), @@ -1718,25 +1718,25 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """{"type":"float"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.FloatType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.FloatType))) }, test("double") { val s = """{"type":"double"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.DoubleType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.DoubleType))) }, test("boolean") { val s = """{"type":"boolean"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.BoolType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.BoolType))) }, test("null") { val s = """{"type":"null"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isRight(isStandardType(StandardType.UnitType))) + assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.UnitType))) } ), test("encode/decode full adt test") { @@ -1748,7 +1748,7 @@ object AvroCodecSpec extends ZIOSpecDefault { //_ <- AvroCodec.encode(decoded) TODO: this fails } yield decoded - assert(decoded)(isRight(hasField("ast", _.ast, equalTo(initialSchemaDerived.ast)))) + assert(decoded)(iszio.prelude.Validation.succeed(hasField("ast", _.ast, equalTo(initialSchemaDerived.ast)))) } @@ TestAspect.ignore // TODO: FIX ) } @@ -1819,19 +1819,19 @@ object AssertionHelper { ) ) - def isEither[A, B](assertion: Assertion[Schema.Either[A, B]]): Assertion[Schema[_]] = - Assertion.isCase[Schema[_], Schema.Either[A, B]]( + def iszio.prelude.Validation[A, B](assertion: Assertion[Schema.zio.prelude.Validation[A, B]]): Assertion[Schema[_]] = + Assertion.isCase[Schema[_], Schema.zio.prelude.Validation[A, B]]( "Either", { - case r: Schema.Either[_, _] => Try { r.asInstanceOf[Schema.Either[A, B]] }.toOption + case r: Schema.zio.prelude.Validation[_, _] => Try { r.asInstanceOf[Schema.zio.prelude.Validation[A, B]] }.toOption case _ => None }, assertion ) - def isEither[A, B](leftAssertion: Assertion[Schema[A]], rightAssertion: Assertion[Schema[B]]): Assertion[Schema[_]] = - isEither[A, B]( - hasField[Schema.Either[A, B], Schema[A]]("left", _.left, leftAssertion) && hasField[ - Schema.Either[A, B], + def iszio.prelude.Validation[A, B](leftAssertion: Assertion[Schema[A]], rightAssertion: Assertion[Schema[B]]): Assertion[Schema[_]] = + iszio.prelude.Validation[A, B]( + hasField[Schema.zio.prelude.Validation[A, B], Schema[A]]("left", _.left, leftAssertion) && hasField[ + Schema.zio.prelude.Validation[A, B], Schema[B] ]("right", _.right, rightAssertion) ) @@ -1859,7 +1859,7 @@ object AssertionHelper { def enumStructure(assertion: Assertion[ListMap[String, (Schema[_], Chunk[Any])]]): Assertion[Schema.Enum[_]] = Assertion.assertionRec("enumStructure")(assertion)( enum => - Some(`enum`.cases.foldRight(ListMap.empty[String, (Schema[_], Chunk[Any])]) { (caseValue, acc) => + Some(`enum`.cases.foldzio.prelude.Validation.succeed(ListMap.empty[String, (Schema[_], Chunk[Any])]) { (caseValue, acc) => (acc + (caseValue.id -> scala.Tuple2(caseValue.schema, caseValue.annotations))) }) ) @@ -2031,7 +2031,7 @@ object SpecTestData { // case class IterablesComplex(list: List[InnerRecord], map: Map[InnerRecord, Enum]) extends TopLevelUnion } - case class InnerRecord(s: String, union: Option[scala.util.Either[String, Int]]) + case class InnerRecord(s: String, union: Option[zio.prelude.Validation[String, Int]]) sealed trait Union case class NestedUnion(inner: InnerUnion) extends Union diff --git a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/Derive.scala b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/Derive.scala index fcdc372e4..e8f4b4e6a 100644 --- a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/Derive.scala +++ b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/Derive.scala @@ -22,7 +22,7 @@ object Derive { val setTpe = c.typeOf[Set[_]] val vectorTpe = c.typeOf[Vector[_]] val chunkTpe = c.typeOf[Chunk[_]] - val eitherTpe = c.typeOf[Either[_, _]] + val eitherTpe = c.typeOf[zio.prelude.Validation[_, _]] val tuple2Tpe = c.typeOf[Tuple2[_, _]] val tuple3Tpe = c.typeOf[Tuple3[_, _, _]] val tuple4Tpe = c.typeOf[Tuple4[_, _, _, _]] @@ -234,8 +234,8 @@ object Derive { val rightInstance = recurse(concreteType(tpe, rightTpe), rightSchema, currentFrame +: stack, top = false) q"""{ - lazy val $schemaRef = $forcedSchema.asInstanceOf[_root_.zio.schema.Schema.Either[$leftTpe, $rightTpe]] - lazy val $selfRefWithType = $deriver.deriveEither[$leftTpe, $rightTpe]($schemaRef, $leftInstance, $rightInstance, $summoned) + lazy val $schemaRef = $forcedSchema.asInstanceOf[_root_.zio.schema.Schema.zio.prelude.Validation[$leftTpe, $rightTpe]] + lazy val $selfRefWithType = $deriver.derivezio.prelude.Validation[$leftTpe, $rightTpe]($schemaRef, $leftInstance, $rightInstance, $summoned) $selfRef }""" } else if (tpe <:< tuple2Tpe) { diff --git a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala index c1ddb7714..a86186201 100644 --- a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala @@ -97,7 +97,7 @@ object DeriveSchema { else recurse(schemaType, stack) case typeArg1 :: typeArg2 :: Nil => - if (schemaType <:< typeOf[Either[_, _]]) + if (schemaType <:< typeOf[zio.prelude.Validation[_, _]]) q"""_root_.zio.schema.Schema.either( _root_.zio.schema.Schema.defer(${directInferSchema( parentType, @@ -299,13 +299,13 @@ object DeriveSchema { } """ } - q"""(m: scala.collection.immutable.ListMap[String, _]) => try { Right($tpeCompanion.apply(..$casts)) } catch { case e: Throwable => Left(e.getMessage) }""" + q"""(m: scala.collection.immutable.ListMap[String, _]) => try { zio.prelude.Validation.succeed($tpeCompanion.apply(..$casts)) } catch { case e: Throwable => Left(e.getMessage) }""" } val toMap = { val tuples = fieldAccessors.map { fieldName => q"(${fieldName.toString},b.$fieldName)" } - q"""(b: $tpe) => Right(scala.collection.immutable.ListMap.apply(..$tuples))""" + q"""(b: $tpe) => zio.prelude.Validation.succeed(scala.collection.immutable.ListMap.apply(..$tuples))""" } val applyArgs = diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala index c33c8cdcf..02250b931 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala @@ -89,15 +89,15 @@ private case class DeriveInstance()(using val ctx: Quotes) extends ReflectionUti seqSchemaRef -> '{Schema.force($schema).asInstanceOf[Schema.Sequence[List[a], a, _]]}, selfRef -> '{$deriver.deriveSequence[List, a]($seqSchemaRefExpr, $elemInstance, ${summoned})} ) - case '[scala.util.Either[a, b]] => - val (schemaRef, schemaRefExpr) = createSchemaRef[scala.util.Either[a, b], Schema.Either[a, b]](stack) - val summoned = summonOptionalIfNotTop[F, scala.util.Either[a, b]](top) + case '[zio.prelude.Validation[a, b]] => + val (schemaRef, schemaRefExpr) = createSchemaRef[zio.prelude.Validation[a, b], Schema.zio.prelude.Validation[a, b]](stack) + val summoned = summonOptionalIfNotTop[F, zio.prelude.Validation[a, b]](top) val instanceA = deriveInstance[F, a](deriver, '{$schemaRefExpr.left}, stack) val instanceB = deriveInstance[F, b](deriver, '{$schemaRefExpr.right}, stack) lazyVals[F[A]](selfRef, - schemaRef -> '{Schema.force($schema).asInstanceOf[Schema.Either[a, b]]}, - selfRef -> '{$deriver.deriveEither[a, b]($schemaRefExpr, $instanceA, $instanceB, $summoned)} + schemaRef -> '{Schema.force($schema).asInstanceOf[Schema.zio.prelude.Validation[a, b]]}, + selfRef -> '{$deriver.derivezio.prelude.Validation[a, b]($schemaRefExpr, $instanceA, $instanceB, $summoned)} ) case '[Option[a]] => val (schemaRef, schemaRefExpr) = createSchemaRef[Option[a], Schema.Optional[a]](stack) diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala index bcc1ee5db..ed97726c1 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala @@ -55,7 +55,7 @@ private case class DeriveSchema()(using val ctx: Quotes) extends ReflectionUtils case '[List[a]] => val schema = deriveSchema[a](stack) '{ Schema.list(Schema.defer(${schema})) }.asExprOf[Schema[T]] - case '[scala.util.Either[a, b]] => + case '[zio.prelude.Validation[a, b]] => val schemaA = deriveSchema[a](stack) val schemaB = deriveSchema[b](stack) '{ Schema.either(Schema.defer(${schemaA}), Schema.defer(${schemaB})) }.asExprOf[Schema[T]] @@ -232,7 +232,7 @@ private case class DeriveSchema()(using val ctx: Quotes) extends ReflectionUtils } val fromMap = '{ (m: ListMap[String, _]) => - try { Right(${appliedConstructor('m)}) } catch { + try { zio.prelude.Validation.succeed(${appliedConstructor('m)}) } catch { case e: Throwable => Left(e.getMessage) }} @@ -250,7 +250,7 @@ private case class DeriveSchema()(using val ctx: Quotes) extends ReflectionUtils '{(${Expr(label)}, ${Select.unique(b.asTerm, label).asExprOf[t]})} } } - val toMap = '{(b: T) => Right(ListMap.apply(${Varargs(tuples('b))} :_*)) } + val toMap = '{(b: T) => zio.prelude.Validation.succeed(ListMap.apply(${Varargs(tuples('b))} :_*)) } '{${genericRecord.asExprOf[GenericRecord]}.transformOrFail[T]($fromMap, $toMap)}.asTerm } 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 5ed934417..09c9112c7 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 @@ -65,12 +65,12 @@ private[schema] class CachedDeriver[F[_]] private (deriver: Deriver[F], val cach deriver.deriveMap(map, key, value, summoned) } - override def deriveEither[A, B]( - either: Schema.Either[A, B], + override def derivezio.prelude.Validation[A, B]( + either: Schema.zio.prelude.Validation[A, B], left: => F[A], right: => F[B], - summoned: => Option[F[Either[A, B]]] - ): F[Either[A, B]] = + summoned: => Option[F[zio.prelude.Validation[A, B]]] + ): F[zio.prelude.Validation[A, B]] = cached(either) { deriver.deriveEither(either, left, right, summoned) } @@ -121,7 +121,7 @@ private[schema] object CachedDeriver { final case class WithId[A](typeId: TypeId) extends CacheKey[A] final case class WithIdentityObject[A](inner: CacheKey[_], id: Any) extends CacheKey[A] final case class Optional[A](key: CacheKey[A]) extends CacheKey[A] - final case class Either[A, B](leftKey: CacheKey[A], rightKey: CacheKey[B]) extends CacheKey[Either[A, B]] + final case class zio.prelude.Validation[A, B](leftKey: CacheKey[A], rightKey: CacheKey[B]) extends CacheKey[zio.prelude.Validation[A, B]] 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]] @@ -142,7 +142,7 @@ private[schema] object CachedDeriver { case optional: Schema.Optional[_] => Optional(fromSchema(optional.schema)).asInstanceOf[CacheKey[A]] case tuple: Schema.Tuple2[_, _] => Tuple2(fromSchema(tuple.left), fromSchema(tuple.right)).asInstanceOf[CacheKey[A]] - case either: Schema.Either[_, _] => + case either: Schema.zio.prelude.Validation[_, _] => Either(fromSchema(either.leftSchema), fromSchema(either.rightSchema)).asInstanceOf[CacheKey[A]] case Schema.Lazy(schema0) => fromSchema(schema0()) case Schema.Dynamic(_) => Misc(schema) diff --git a/zio-schema-derivation/shared/src/main/scala/zio/schema/Deriver.scala b/zio-schema-derivation/shared/src/main/scala/zio/schema/Deriver.scala index da1481116..48afbf6e1 100644 --- a/zio-schema-derivation/shared/src/main/scala/zio/schema/Deriver.scala +++ b/zio-schema-derivation/shared/src/main/scala/zio/schema/Deriver.scala @@ -82,12 +82,12 @@ trait Deriver[F[_]] extends VersionSpecificDeriver[F] { self => summoned: => Option[F[Map[K, V]]] ): F[Map[K, V]] - def deriveEither[A, B]( - either: Schema.Either[A, B], + def derivezio.prelude.Validation[A, B]( + either: Schema.zio.prelude.Validation[A, B], left: => F[A], right: => F[B], - summoned: => Option[F[Either[A, B]]] - ): F[Either[A, B]] = + summoned: => Option[F[zio.prelude.Validation[A, B]]] + ): F[zio.prelude.Validation[A, B]] = deriveEnum( either.toEnum, Chunk(wrap(left), wrap(right)), @@ -179,12 +179,12 @@ trait Deriver[F[_]] extends VersionSpecificDeriver[F] { self => self.deriveMap(map, key, value, summoned) } - final override def deriveEither[A, B]( - either: Schema.Either[A, B], + final override def derivezio.prelude.Validation[A, B]( + either: Schema.zio.prelude.Validation[A, B], left: => F[A], right: => F[B], - summoned: => Option[F[Either[A, B]]] - ): F[Either[A, B]] = + summoned: => Option[F[zio.prelude.Validation[A, B]]] + ): F[zio.prelude.Validation[A, B]] = summoned.getOrElse { self.deriveEither(either, left, right, summoned) } diff --git a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSchemaSpec.scala b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSchemaSpec.scala index dd37ad614..3c3a92516 100644 --- a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSchemaSpec.scala +++ b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSchemaSpec.scala @@ -376,12 +376,12 @@ object DeriveSchemaSpec extends ZIOSpecDefault with VersionSpecificDeriveSchemaS val a = DependsOnA(Some(DependsOnB(None))) val a0 = Schema[DependsOnA].fromDynamic(Schema[DependsOnA].toDynamic(a)) assert(Schema[DependsOnA])(anything) - assert(a0)(isRight(equalTo(a))) + assert(a0)(iszio.prelude.Validation.succeed(equalTo(a))) val b = DependsOnB(Some(DependsOnA(None))) val b0 = Schema[DependsOnB].fromDynamic(Schema[DependsOnB].toDynamic(b)) assert(Schema[DependsOnB])(anything) - assert(b0)(isRight(equalTo(b))) + assert(b0)(iszio.prelude.Validation.succeed(equalTo(b))) }, test("correctly derives recursive Enum with type parameters") { val derived: Schema[Tree[Recursive]] = DeriveSchema.gen[Tree[Recursive]] diff --git a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala index 20b004a44..414932139 100644 --- a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala +++ b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala @@ -223,7 +223,7 @@ object DeriveSpec extends ZIOSpecDefault with VersionSpecificDeriveSpec { implicit val schema: Schema[Record5] = DeriveSchema.gen[Record5] } - case class Record6(map: Map[String, Record1], either: Either[String, Record2]) + case class Record6(map: Map[String, Record1], either: zio.prelude.Validation[String, Record2]) object Record6 { implicit val schema: Schema[Record6] = DeriveSchema.gen[Record6] @@ -426,16 +426,16 @@ object DeriveSpec extends ZIOSpecDefault with VersionSpecificDeriveSpec { } } - override def deriveEither[A, B]( - either: Schema.Either[A, B], + override def derivezio.prelude.Validation[A, B]( + either: Schema.zio.prelude.Validation[A, B], left: => TC[A], right: => TC[B], - summoned: => Option[TC[Either[A, B]]] - ): TC[Either[A, B]] = + summoned: => Option[TC[zio.prelude.Validation[A, B]]] + ): TC[zio.prelude.Validation[A, B]] = summoned.getOrElse { assert(left ne null) assert(right ne null) - new TC[Either[A, B]] { + new TC[zio.prelude.Validation[A, B]] { override def isDerived: Boolean = true override def inner: Option[TC[_]] = Some(right) } diff --git a/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaValidationSpec.scala b/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaValidationSpec.scala index 4173f3de2..4c83e6f78 100644 --- a/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaValidationSpec.scala +++ b/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaValidationSpec.scala @@ -10,7 +10,7 @@ object SchemaValidationSpec extends ZIOSpecDefault { import Assertion._ final case class ExampleData( - either: scala.util.Either[Person, Person] = Right(goodData), + either: zio.prelude.Validation[Person, Person] = zio.prelude.Validation.succeed(goodData), option: Option[Person] = None, list: List[Person] = goodData :: Nil, tuple: scala.Tuple2[Person, Person] = (goodData, goodData), @@ -29,7 +29,7 @@ object SchemaValidationSpec extends ZIOSpecDefault { final case class Wrapper(person: Person) implicit val schema - : CaseClass6[scala.util.Either[Person, Person], Option[Person], List[Person], (Person, Person), Wrapper, EnumData, ExampleData] = + : CaseClass6[zio.prelude.Validation[Person, Person], Option[Person], List[Person], (Person, Person), Wrapper, EnumData, ExampleData] = DeriveSchema.gen[ExampleData] val badData: Person = Person("foo", 123123123) @@ -104,7 +104,7 @@ object SchemaValidationSpec extends ZIOSpecDefault { assert(validated)(Assertion.hasSameElements(expected)) }, test("Example Data, Right ValidationError") { - val exampleData = ExampleData(either = Right(badData)) + val exampleData = ExampleData(either = zio.prelude.Validation.succeed(badData)) val validated: Chunk[ValidationError] = Schema.validate(exampleData) diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example4/Example4Transformation.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example4/Example4Transformation.scala index 60978b234..8ff0ed531 100644 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example4/Example4Transformation.scala +++ b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example4/Example4Transformation.scala @@ -70,7 +70,7 @@ object Example4Transformation extends ZIOAppDefault { (dto: DomainPerson) => WebPerson(dto.firstname + " " + dto.lastname, dto.years) ) - val domainPerson: Either[String, DomainPerson] = + val domainPerson: zio.prelude.Validation[String, DomainPerson] = WebPerson.schema.migrate(personTransformation).flatMap(f => f(webPerson)) override def run: UIO[Unit] = ZIO.debug(domainPerson) @@ -85,7 +85,7 @@ object Example4Ast extends zio.ZIOAppDefault { val webPerson: WebPerson = WebPerson("Mike Moe", 32) - val dyn: Either[String, DynamicValue] = WebPerson.schema + val dyn: zio.prelude.Validation[String, DynamicValue] = WebPerson.schema .toDynamic(webPerson) .transform( Chunk( @@ -114,10 +114,10 @@ object Example4Ast2 extends zio.ZIOAppDefault { val domainPersonAst: MetaSchema = MetaSchema.fromSchema(DomainPerson.schema) val migrationAst: MetaSchema = MetaSchema.fromSchema(personTransformation) - val migrationWebPersonAstToMigrationAst: Either[String, Chunk[Migration]] = + val migrationWebPersonAstToMigrationAst: zio.prelude.Validation[String, Chunk[Migration]] = Migration.derive(webPersonAst, migrationAst) - val migrationWebPersonAstToDomainPersonAst: Either[String, Chunk[Migration]] = + val migrationWebPersonAstToDomainPersonAst: zio.prelude.Validation[String, Chunk[Migration]] = Migration.derive(webPersonAst, domainPersonAst) override def run: ZIO[Environment with ZIOAppArgs, Any, Any] = diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example6/Example6_ReifiedOptics.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example6/Example6_ReifiedOptics.scala index 7d1d0e383..86e440ed8 100644 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example6/Example6_ReifiedOptics.scala +++ b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example6/Example6_ReifiedOptics.scala @@ -117,8 +117,8 @@ object Example6_PureOptics extends scala.App { val employees: Lens[Company, List[Employee]] = Lens( - company => Right(company.employees), - employees => company => Right(company.copy(employees = employees)) + company => zio.prelude.Validation.succeed(company.employees), + employees => company => zio.prelude.Validation.succeed(company.copy(employees = employees)) ) val employee: Employee = Employee("employee2") diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala index 393e9b017..20236991e 100644 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala +++ b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala @@ -22,16 +22,16 @@ private[example7] object Problem { // sample url1: /foo/?name=john&age=42#foo // sample url2: /foo/?name=john&age=42&location=london&address=baker%20street - def decodePersonFromQueryParams(params: Map[String, List[String]]): scala.util.Either[String, Person] = + def decodePersonFromQueryParams(params: Map[String, List[String]]): zio.prelude.Validation[String, Person] = for { - name <- params.get("name").toRight("name parameter is missing") - age <- params.get("age").toRight("age parameter is missing") + name <- params.get("name").tozio.prelude.Validation.succeed("name parameter is missing") + age <- params.get("age").tozio.prelude.Validation.succeed("age parameter is missing") } yield Person(name.head, age.head.toInt) - def decodeProfileFromQueryParams(params: Map[String, List[String]]): scala.util.Either[String, Profile] = + def decodeProfileFromQueryParams(params: Map[String, List[String]]): zio.prelude.Validation[String, Profile] = for { - location <- params.get("location").toRight("location parameter is missing") - address <- params.get("address").toRight("address parameter is missing") + location <- params.get("location").tozio.prelude.Validation.succeed("location parameter is missing") + address <- params.get("address").tozio.prelude.Validation.succeed("address parameter is missing") } yield Profile(location.head, address.head) object Approach1 extends scala.App { @@ -41,14 +41,14 @@ private[example7] object Problem { // probably suitable for the normal business application with medium performance requirements def decode[A]( params: Map[String, List[String]] - )(implicit schema: Schema[A]): scala.util.Either[String, A] = + )(implicit schema: Schema[A]): zio.prelude.Validation[String, A] = toDV(params) .map(_.toTypedValue(schema).toEither) .collectFirst { - case Right(v) => + case zio.prelude.Validation.succeed(v) => v } - .toRight("some error") + .tozio.prelude.Validation.succeed("some error") // parse each element into String and if possible Int representations. We basically create all // possible solutions here. The Set[DynamicValue] removes duplicates. @@ -84,7 +84,7 @@ private[example7] object Problem { .map(v => DynamicValue.Record(TypeId.Structural, v)) } - val p: scala.util.Either[String, Person] = decode[Person](Map("name" -> List("John"), "age" -> List("42"))) + val p: zio.prelude.Validation[String, Person] = decode[Person](Map("name" -> List("John"), "age" -> List("42"))) println(p) } @@ -96,16 +96,16 @@ private[example7] object Problem { // this will be a sophisticated solution for a high performance library like ZIO def decodeFromQueryParams[A]( params: QueryParams - )(implicit schema: Schema[A], decoder: QueryParams => scala.util.Either[String, A]): scala.util.Either[String, A] = + )(implicit schema: Schema[A], decoder: QueryParams => zio.prelude.Validation[String, A]): zio.prelude.Validation[String, A] = decoder(params) - def buildDecoder[A](implicit schemaA: Schema[A]): QueryParams => scala.util.Either[String, A] = { + def buildDecoder[A](implicit schemaA: Schema[A]): QueryParams => zio.prelude.Validation[String, A] = { - def compile[B](key: Option[String], schemaB: Schema[B]): QueryParams => scala.util.Either[String, B] = + def compile[B](key: Option[String], schemaB: Schema[B]): QueryParams => zio.prelude.Validation[String, B] = schemaB match { case transform: Transform[a, B, _] => import transform.{ f, schema } - val func: QueryParams => scala.util.Either[String, Any] = compile(key, schema) + val func: QueryParams => zio.prelude.Validation[String, Any] = compile(key, schema) (params: QueryParams) => func(params).flatMap(v => f(v.asInstanceOf[a])) case Primitive(standardType, _) => key match { @@ -115,17 +115,17 @@ private[example7] object Problem { case Some(key) => standardType match { case StandardType.StringType => - val f: QueryParams => scala.util.Either[String, B] = (qp: QueryParams) => + val f: QueryParams => zio.prelude.Validation[String, B] = (qp: QueryParams) => qp.get(key) match { case Some(value :: _) => Right[String, B](value.asInstanceOf[B]) case _ => Left(s"Cannot extract a primitive string out of nothing") } f case StandardType.IntType => - val f: QueryParams => scala.util.Either[String, B] = (qp: QueryParams) => + val f: QueryParams => zio.prelude.Validation[String, B] = (qp: QueryParams) => qp.get(key) match { case Some(value :: _) => - Try(value.toInt).toOption.toRight(s"cannot create an integer out of $value") + Try(value.toInt).toOption.tozio.prelude.Validation.succeed(s"cannot create an integer out of $value") case _ => Left(s"Cannot extract a primitive string out of nothing") } f @@ -169,8 +169,8 @@ private[example7] object Problem { record.fields.map { case Schema.Field(label, schema, _, _, _, _) => compile(Some(label), schema)(qp) - }.foldRight[scala.util.Either[String, Chunk[Any]]](Right(Chunk.empty)) { - case (Right(nextValue), Right(values)) => Right(values :+ nextValue) + }.foldRight[zio.prelude.Validation[String, Chunk[Any]]](zio.prelude.Validation.succeed(Chunk.empty)) { + case (zio.prelude.Validation.succeed(nextValue), zio.prelude.Validation.succeed(values)) => zio.prelude.Validation.succeed(values :+ nextValue) case (Left(err), _) => Left(err) case (_, Left(err)) => Left(err) } @@ -195,7 +195,7 @@ private[example7] object Problem { compile(None, schemaA) } - implicit val personDecoder: QueryParams => scala.util.Either[String, Person] = buildDecoder[Person] + implicit val personDecoder: QueryParams => zio.prelude.Validation[String, Person] = buildDecoder[Person] println("approach 2") diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Decoder.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Decoder.scala index f5136969b..c19a9859e 100644 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Decoder.scala +++ b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Decoder.scala @@ -7,7 +7,7 @@ import zio.prelude._ import zio.schema._ trait Decoder[+A] { - def decode(in: Json): Either[String, A] + def decode(in: Json): zio.prelude.Validation[String, A] } object Decoder { @@ -19,16 +19,16 @@ object Decoder { a <- schema.fromDynamic(dv) } yield a - private def jsonToDynamicValue(in: Json): Either[String, DynamicValue] = + private def jsonToDynamicValue(in: Json): zio.prelude.Validation[String, DynamicValue] = in match { case Json.JStr(s) => - Right(DynamicValue.Primitive(s, StandardType.StringType)) + zio.prelude.Validation.succeed(DynamicValue.Primitive(s, StandardType.StringType)) case Json.JNum(d) => - Right(DynamicValue.Primitive(d, StandardType.DoubleType)) + zio.prelude.Validation.succeed(DynamicValue.Primitive(d, StandardType.DoubleType)) case Json.JBool(b) => - Right(DynamicValue.Primitive(b, StandardType.BoolType)) + zio.prelude.Validation.succeed(DynamicValue.Primitive(b, StandardType.BoolType)) case Json.JArr(as) => as.forEach(jsonToDynamicValue) @@ -37,9 +37,9 @@ object Decoder { case Json.JObj(map) => map.map { case (k, v) => k -> jsonToDynamicValue(v) - }.foldRight[Either[String, DynamicValue]](Right(DynamicValue.Record(TypeId.Structural, ListMap.empty))) { - case ((key, Right(value)), Right(DynamicValue.Record(_, values))) => - Right(DynamicValue.Record(TypeId.parse(key), values + (key -> value))) + }.foldRight[zio.prelude.Validation[String, DynamicValue]](zio.prelude.Validation.succeed(DynamicValue.Record(TypeId.Structural, ListMap.empty))) { + case ((key, zio.prelude.Validation.succeed(value)), zio.prelude.Validation.succeed(DynamicValue.Record(_, values))) => + zio.prelude.Validation.succeed(DynamicValue.Record(TypeId.parse(key), values + (key -> value))) case ((_, Left(err)), _) => Left(err) case (_, Left(err)) => Left(err) } diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Usage.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Usage.scala index 2f5adb185..5ea2c4efe 100644 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Usage.scala +++ b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Usage.scala @@ -12,8 +12,8 @@ object Usage extends App { val p: Person = Person("cal", 30) val pJson: Json = Encoder.deriveEncoder[Person].encode(p) - val sameP: Either[String, Person] = Decoder.deriveDecoder[Person].decode(pJson) - println(sameP == Right(p)) + val sameP: zio.prelude.Validation[String, Person] = Decoder.deriveDecoder[Person].decode(pJson) + println(sameP == zio.prelude.Validation.succeed(p)) println { Decoder diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example9/Patching.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example9/Patching.scala index daab0b2dc..328f38939 100644 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example9/Patching.scala +++ b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example9/Patching.scala @@ -18,9 +18,9 @@ object Patching extends App { private val patch: Patch[Person] = schema.diff(person1, person2) private val inverted: Patch[Person] = patch.invert - private val result1: Either[String, Person] = patch.patch(person1) - private val result2: Either[String, Person] = result1.flatMap(inverted.patch) + private val result1: zio.prelude.Validation[String, Person] = patch.patch(person1) + private val result2: zio.prelude.Validation[String, Person] = result1.flatMap(inverted.patch) - assert(result2 == Right(person1)) + assert(result2 == zio.prelude.Validation.succeed(person1)) } 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 8c22480fa..8eb88de08 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 @@ -27,7 +27,7 @@ object JsonCodec { implicit def zioJsonBinaryCodec[A](implicit jsonCodec: ZJsonCodec[A]): BinaryCodec[A] = new BinaryCodec[A] { - override def decode(whole: Chunk[Byte]): Either[DecodeError, A] = + override def decode(whole: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = jsonCodec .decodeJson( new String(whole.toArray, JsonEncoder.CHARSET) @@ -60,7 +60,7 @@ object JsonCodec { implicit def schemaBasedBinaryCodec[A](implicit schema: Schema[A]): BinaryCodec[A] = new BinaryCodec[A] { - override def decode(whole: Chunk[Byte]): Either[DecodeError, A] = + override def decode(whole: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = JsonDecoder.decode( schema, new String(whole.toArray, JsonEncoder.CHARSET) @@ -360,20 +360,20 @@ object JsonCodec { } } - private def transformEncoder[A, B](schema: Schema[A], g: B => Either[String, A]): ZJsonEncoder[B] = + private def transformEncoder[A, B](schema: Schema[A], g: B => zio.prelude.Validation[String, A]): ZJsonEncoder[B] = new ZJsonEncoder[B] { private lazy val innerEncoder = schemaEncoder(schema) override def unsafeEncode(b: B, indent: Option[Int], out: Write): Unit = g(b) match { case Left(_) => () - case Right(a) => innerEncoder.unsafeEncode(a, indent, out) + case zio.prelude.Validation.succeed(a) => innerEncoder.unsafeEncode(a, indent, out) } override def isNothing(b: B): Boolean = g(b) match { case Left(_) => false - case Right(a) => innerEncoder.isNothing(a) + case zio.prelude.Validation.succeed(a) => innerEncoder.isNothing(a) } } @@ -474,10 +474,10 @@ object JsonCodec { import Codecs._ import ProductDecoder._ - final def decode[A](schema: Schema[A], json: String): Either[DecodeError, A] = + final def decode[A](schema: Schema[A], json: String): zio.prelude.Validation[DecodeError, A] = schemaDecoder(schema).decodeJson(json) match { case Left(value) => Left(ReadError(Cause.empty, value)) - case Right(value) => Right(value) + case zio.prelude.Validation.succeed(value) => zio.prelude.Validation.succeed(value) } def x[A](dec: ZJsonDecoder[A]): Unit = dec match { @@ -645,7 +645,7 @@ object JsonCodec { ZJsonDecoder.string.mapOrFail( s => caseMap.get(caseNameAliases.get(s).getOrElse(s)) match { - case Some(z) => Right(z) + case Some(z) => zio.prelude.Validation.succeed(z) case None => Left("unrecognized string") } ) diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index d35adb72d..bfccb5f92 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -275,7 +275,7 @@ object JsonCodecSpec extends ZIOSpecDefault { val errorMessage = "I'm sorry Dave, I can't do that" val schema: Schema[Int] = Schema .Primitive(StandardType.StringType) - .transformOrFail[Int](_ => Left(errorMessage), i => Right(i.toString)) + .transformOrFail[Int](_ => Left(errorMessage), i => zio.prelude.Validation.succeed(i.toString)) check(Gen.int(Int.MinValue, Int.MaxValue)) { int => assertDecodesToError( schema, @@ -495,7 +495,7 @@ object JsonCodecSpec extends ZIOSpecDefault { right <- SchemaGen.anyTupleAndValue } yield ( Schema.Either(left._1.asInstanceOf[Schema[(Any, Any)]], right._1.asInstanceOf[Schema[(Any, Any)]]), - Right(right._2) + zio.prelude.Validation.succeed(right._2) ) ) { case (schema, value) => assertEncodesThenDecodes(schema, value) @@ -534,9 +534,9 @@ object JsonCodecSpec extends ZIOSpecDefault { ) ) { case (schema, value) => - assertEncodesThenDecodes[scala.util.Either[Map[Any, Any], Map[Any, Any]]]( - schema.asInstanceOf[Schema[scala.util.Either[Map[Any, Any], Map[Any, Any]]]], - value.asInstanceOf[scala.util.Either[Map[Any, Any], Map[Any, Any]]] + assertEncodesThenDecodes[zio.prelude.Validation[Map[Any, Any], Map[Any, Any]]]( + schema.asInstanceOf[Schema[zio.prelude.Validation[Map[Any, Any], Map[Any, Any]]]], + value.asInstanceOf[zio.prelude.Validation[Map[Any, Any], Map[Any, Any]]] ) } }, @@ -552,9 +552,9 @@ object JsonCodecSpec extends ZIOSpecDefault { ) ) { case (schema, value) => - assertEncodesThenDecodes[scala.util.Either[Set[Any], Set[Any]]]( - schema.asInstanceOf[Schema[scala.util.Either[Set[Any], Set[Any]]]], - value.asInstanceOf[scala.util.Either[Set[Any], Set[Any]]] + assertEncodesThenDecodes[zio.prelude.Validation[Set[Any], Set[Any]]]( + schema.asInstanceOf[Schema[zio.prelude.Validation[Set[Any], Set[Any]]]], + value.asInstanceOf[zio.prelude.Validation[Set[Any], Set[Any]]] ) } }, @@ -588,7 +588,7 @@ object JsonCodecSpec extends ZIOSpecDefault { check(for { (left, _) <- SchemaGen.anyRecordOfRecordsAndValue (right, b) <- SchemaGen.anyRecordOfRecordsAndValue - } yield (Schema.Either(left, right), Right(b))) { + } yield (Schema.Either(left, right), zio.prelude.Validation.succeed(b))) { case (schema, value) => assertEncodesThenDecodes(schema, value) } @@ -597,7 +597,7 @@ object JsonCodecSpec extends ZIOSpecDefault { check(for { (left, _) <- SchemaGen.anyEnumerationAndValue (right, value) <- SchemaGen.anySequenceAndValue - } yield (Schema.Either(left, right), Right(value))) { + } yield (Schema.Either(left, right), zio.prelude.Validation.succeed(value))) { case (schema, value) => assertEncodesThenDecodes(schema, value) } } diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala index ceb7faf68..3c312c117 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala @@ -14,7 +14,7 @@ object MessagePackCodec { override def encode(a: A): Chunk[Byte] = new MessagePackEncoder().encode(schema, a) - override def decode(bytes: Chunk[Byte]): Either[DecodeError, A] = + override def decode(bytes: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = if (bytes.isEmpty) Left(ReadError(Cause.empty, "No bytes to decode")) else diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala index 821baf4b6..699fb4733 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala @@ -105,7 +105,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { case _ => fail(path, s"Unknown schema ${schema.getClass.getName}") } - private def decodeTransform[A, B](path: Path, schema: Schema[B], f: B => scala.util.Either[String, A]): Result[A] = + private def decodeTransform[A, B](path: Path, schema: Schema[B], f: B => zio.prelude.Validation[String, A]): Result[A] = decodeValue(path, schema).flatMap(a => f(a).left.map(msg => MalformedFieldWithPath(path, msg))) private def decodeRecord[Z](path: Path, fields: Seq[Schema.Field[Z, _]]): Result[ListMap[String, _]] = @@ -123,7 +123,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { case Some(fieldSchema) => decodeValue(actualPath, fieldSchema) match { case Left(err) => Left(err) - case Right(value) => + case zio.prelude.Validation.succeed(value) => if (index == fields.size) { succeed(m.updated(fieldName, value)) } else { @@ -151,7 +151,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { def decodeElements(n: Int, m: scala.collection.mutable.Map[K, V]): Result[scala.collection.immutable.Map[K, V]] = if (n > 0) { (decodeValue(path, schema.keySchema), decodeValue(path, schema.valueSchema)) match { - case (Right(key), Right(value)) => decodeElements(n - 1, m += ((key, value))) + case (zio.prelude.Validation.succeed(key), zio.prelude.Validation.succeed(value)) => decodeElements(n - 1, m += ((key, value))) case (l, r) => val key = l.fold(_.message, _.toString) val value = r.fold(_.message, _.toString) @@ -172,7 +172,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { def decodeElements(n: Int, cb: ChunkBuilder[A]): Result[Chunk[A]] = if (n > 0) { decodeValue(path, elementSchema) match { - case Right(elem) => decodeElements(n - 1, cb += elem) + case zio.prelude.Validation.succeed(elem) => decodeElements(n - 1, cb += elem) case Left(err) => Left(err) } } else { @@ -217,7 +217,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { } yield new java.math.BigDecimal(unscaled, scale, ctx) opt match { - case Some(value) => Right(value) + case Some(value) => zio.prelude.Validation.succeed(value) case None => fail(path, s"Invalid big decimal record $data") } } @@ -297,7 +297,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { } ) - private def decodeEither[A, B](path: Path, left: Schema[A], right: Schema[B]): Result[Either[A, B]] = + private def decodezio.prelude.Validation[A, B](path: Path, left: Schema[A], right: Schema[B]): Result[zio.prelude.Validation[A, B]] = Try(unpacker.unpackMapHeader()).fold( err => fail(path, s"Error parsing Either structure: ${err.getMessage}"), size => @@ -306,7 +306,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { } else { decodeString(path :+ "either").flatMap { case "left" => decodeValue(path :+ "either:left", left).map(Left(_)) - case "right" => decodeValue(path :+ "either:right", right).map(Right(_)) + case "right" => decodeValue(path :+ "either:right", right).map(zio.prelude.Validation.succeed(_)) case str => fail(path :+ "either", s"Unexpected field name: $str") } } @@ -614,10 +614,10 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { object MessagePackDecoder { type Path = Chunk[String] - type Result[A] = scala.util.Either[DecodeError, A] + type Result[A] = zio.prelude.Validation[DecodeError, A] private def succeed[A](a: => A): Result[A] = - Right(a) + zio.prelude.Validation.succeed(a) private def fail(path: Path, failure: String): Result[Nothing] = Left(MalformedFieldWithPath(path, failure)) diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala index ca267d2fc..32b6cb46d 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala @@ -31,7 +31,7 @@ private[codec] class MessagePackEncoder { case (Schema.Primitive(standardType, _), v) => encodePrimitive(standardType, v) case (Schema.Tuple2(left, right, _), v @ (_, _)) => encodeTuple(left, right, v) case (optSchema: Schema.Optional[_], v: Option[_]) => encodeOptional(optSchema.asInstanceOf[Schema.Optional[Any]].schema, v.asInstanceOf[Option[Any]]) - case (eitherSchema: Schema.Either[_, _], v: scala.util.Either[_, _]) => encodeEither(eitherSchema.asInstanceOf[Schema.Either[Any, Any]].left, eitherSchema.asInstanceOf[Schema.Either[Any, Any]].right, v.asInstanceOf[scala.util.Either[Any, Any]]) + case (eitherSchema: Schema.zio.prelude.Validation[_, _], v: zio.prelude.Validation[_, _]) => encodeEither(eitherSchema.asInstanceOf[Schema.zio.prelude.Validation[Any, Any]].left, eitherSchema.asInstanceOf[Schema.zio.prelude.Validation[Any, Any]].right, v.asInstanceOf[zio.prelude.Validation[Any, Any]]) case (lzy @ Schema.Lazy(_), v) => encodeValue(lzy.schema, v) // case (Schema.Meta(ast, _), _) => encodeValue(fieldNumber, Schema[MetaSchema], ast) case (Schema.CaseClass0(_, _, _), _) => encodePrimitive(StandardType.UnitType, ()) @@ -128,13 +128,13 @@ private[codec] class MessagePackEncoder { } } - private def encodeEither[A, B](left: Schema[A], right: Schema[B], either: scala.util.Either[A, B]): Unit = { + private def encodezio.prelude.Validation[A, B](left: Schema[A], right: Schema[B], either: zio.prelude.Validation[A, B]): Unit = { packer.packMapHeader(1) either match { case Left(value) => packer.packString("left") encodeValue(left, value) - case Right(value) => + case zio.prelude.Validation.succeed(value) => packer.packString("right") encodeValue(right, value) } diff --git a/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala b/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala index dd3886b42..a1c7dc346 100644 --- a/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala +++ b/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala @@ -413,7 +413,7 @@ object MessagePackCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(either))) && assert(ed2)(equalTo(either)) }, test("either right") { - val either = Right("hello") + val either = zio.prelude.Validation.succeed("hello") for { ed <- encodeAndDecode(eitherSchema, either) ed2 <- encodeAndDecodeNS(eitherSchema, either) @@ -427,8 +427,8 @@ object MessagePackCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(eitherLeft))) && assert(ed2)(equalTo(eitherLeft)) }, test("either with sum type") { - val eitherRight = Right(BooleanValue(true)) - val eitherRight2 = Right(StringValue("hello")) + val eitherRight = zio.prelude.Validation.succeed(BooleanValue(true)) + val eitherRight2 = zio.prelude.Validation.succeed(StringValue("hello")) for { ed <- encodeAndDecode(complexEitherSchema, eitherRight2) ed2 <- encodeAndDecodeNS(complexEitherSchema, eitherRight) @@ -525,7 +525,7 @@ object MessagePackCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(value))) && assert(ed2)(equalTo(value)) }, test("either within either") { - val either = Right(Left(BooleanValue(true))) + val either = zio.prelude.Validation.succeed(Left(BooleanValue(true))) val schema = Schema.either(Schema[Int], Schema.either(schemaOneOf, Schema[String])) for { ed <- encodeAndDecode(schema, either) @@ -894,12 +894,12 @@ object MessagePackCodecSpec extends ZIOSpecDefault { val complexTupleSchema: Schema.Tuple2[Record, OneOf] = Schema.Tuple2(Record.schemaRecord, schemaOneOf) - val eitherSchema: Schema.Either[Int, String] = Schema.Either(Schema[Int], Schema[String]) + val eitherSchema: Schema.zio.prelude.Validation[Int, String] = Schema.Either(Schema[Int], Schema[String]) - val complexEitherSchema: Schema.Either[Record, OneOf] = + val complexEitherSchema: Schema.zio.prelude.Validation[Record, OneOf] = Schema.Either(Record.schemaRecord, schemaOneOf) - val complexEitherSchema2: Schema.Either[MyRecord, MyRecord] = + val complexEitherSchema2: Schema.zio.prelude.Validation[MyRecord, MyRecord] = Schema.Either(myRecord, myRecord) case class RichProduct(stringOneOf: OneOf, basicString: BasicString, record: Record) 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 6da76d0d8..7a10c8b38 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 @@ -34,7 +34,7 @@ object ZioOpticsBuilder extends AccessorBuilder { ): ZPrism[S, S, A, A] = ZPrism( get = ZioOpticsBuilder.makePrismGet(term), - set = (piece: A) => Right(piece.asInstanceOf[S]) + set = (piece: A) => zio.prelude.Validation.succeed(piece.asInstanceOf[S]) ) override def makeTraversal[S, A]( @@ -62,7 +62,7 @@ object ZioOpticsBuilder extends AccessorBuilder { private[optics] def makeLensGet[S, A]( product: Schema.Record[S], term: Schema.Field[S, A] - ): S => Either[(OpticFailure, S), A] = { (whole: S) => + ): S => zio.prelude.Validation[(OpticFailure, S), A] = { (whole: S) => product.toDynamic(whole) match { case DynamicValue.Record(_, values) => values @@ -70,7 +70,7 @@ object ZioOpticsBuilder extends AccessorBuilder { .map { dynamicField => term.schema.fromDynamic(dynamicField) match { case Left(error) => Left(OpticFailure(error) -> whole) - case Right(value) => Right(value) + case zio.prelude.Validation.succeed(value) => zio.prelude.Validation.succeed(value) } } .getOrElse(Left(OpticFailure(s"No term found with label ${term.name}") -> whole)) @@ -81,13 +81,13 @@ object ZioOpticsBuilder extends AccessorBuilder { private[optics] def makeLensSet[S, A]( product: Schema.Record[S], term: Schema.Field[S, A] - ): A => S => Either[(OpticFailure, S), S] = { (piece: A) => (whole: S) => + ): A => S => zio.prelude.Validation[(OpticFailure, S), S] = { (piece: A) => (whole: S) => product.toDynamic(whole) match { case DynamicValue.Record(name, values) => val updated = spliceRecord(values, term.name, term.name -> term.schema.toDynamic(piece)) product.fromDynamic(DynamicValue.Record(name, updated)) match { case Left(error) => Left(OpticFailure(error) -> whole) - case Right(value) => Right(value) + case zio.prelude.Validation.succeed(value) => zio.prelude.Validation.succeed(value) } case _ => Left(OpticFailure(s"Unexpected dynamic value for whole") -> whole) } @@ -95,22 +95,22 @@ object ZioOpticsBuilder extends AccessorBuilder { private[optics] def makePrismGet[S, A]( term: Schema.Case[S, A] - ): S => Either[(OpticFailure, S), A] = { (whole: S) => + ): S => zio.prelude.Validation[(OpticFailure, S), A] = { (whole: S) => term.deconstructOption(whole) match { - case Some(a) => Right(a) + case Some(a) => zio.prelude.Validation.succeed(a) case None => Left(OpticFailure(s"Cannot deconstruct to term ${term.id}") -> whole) } } private[optics] def makeSeqTraversalGet[S, A]( collection: Schema.Sequence[S, A, _] - ): S => Either[(OpticFailure, S), Chunk[A]] = { (whole: S) => - Right(collection.toChunk(whole)) + ): S => zio.prelude.Validation[(OpticFailure, S), Chunk[A]] = { (whole: S) => + zio.prelude.Validation.succeed(collection.toChunk(whole)) } private[optics] def makeSeqTraversalSet[S, A]( collection: Schema.Sequence[S, A, _] - ): Chunk[A] => S => Either[(OpticFailure, S), S] = { (piece: Chunk[A]) => (whole: S) => + ): Chunk[A] => S => zio.prelude.Validation[(OpticFailure, S), S] = { (piece: Chunk[A]) => (whole: S) => val builder = ChunkBuilder.make[A]() val leftIterator = collection.toChunk(whole).iterator val rightIterator = piece.iterator @@ -121,24 +121,24 @@ object ZioOpticsBuilder extends AccessorBuilder { while (leftIterator.hasNext) { builder += leftIterator.next() } - Right(collection.fromChunk(builder.result())) + zio.prelude.Validation.succeed(collection.fromChunk(builder.result())) } - private[optics] def makeMapTraversalGet[K, V](whole: Map[K, V]): Either[(OpticFailure, Map[K, V]), Chunk[(K, V)]] = - Right(Chunk.fromIterable(whole)) + private[optics] def makeMapTraversalGet[K, V](whole: Map[K, V]): zio.prelude.Validation[(OpticFailure, Map[K, V]), Chunk[(K, V)]] = + zio.prelude.Validation.succeed(Chunk.fromIterable(whole)) private[optics] def makeMapTraversalSet[K, V] - : Chunk[(K, V)] => Map[K, V] => Either[(OpticFailure, Map[K, V]), Map[K, V]] = { + : Chunk[(K, V)] => Map[K, V] => zio.prelude.Validation[(OpticFailure, Map[K, V]), Map[K, V]] = { (piece: Chunk[(K, V)]) => (whole: Map[K, V]) => - Right(whole ++ piece.toList) + zio.prelude.Validation.succeed(whole ++ piece.toList) } - private[optics] def makeSetTraversalGet[A](whole: Set[A]): Either[(OpticFailure, Set[A]), Chunk[A]] = - Right(Chunk.fromIterable(whole)) + private[optics] def makeSetTraversalGet[A](whole: Set[A]): zio.prelude.Validation[(OpticFailure, Set[A]), Chunk[A]] = + zio.prelude.Validation.succeed(Chunk.fromIterable(whole)) - private[optics] def makeSetTraversalSet[A]: Chunk[A] => Set[A] => Either[(OpticFailure, Set[A]), Set[A]] = { + private[optics] def makeSetTraversalSet[A]: Chunk[A] => Set[A] => zio.prelude.Validation[(OpticFailure, Set[A]), Set[A]] = { (piece: Chunk[A]) => (whole: Set[A]) => - Right(whole ++ piece.toSet) + zio.prelude.Validation.succeed(whole ++ piece.toSet) } private def spliceRecord( diff --git a/zio-schema-optics/shared/src/test/scala/zio/schema/optics/LensSpec.scala b/zio-schema-optics/shared/src/test/scala/zio/schema/optics/LensSpec.scala index bc1678179..d4f77c703 100644 --- a/zio-schema-optics/shared/src/test/scala/zio/schema/optics/LensSpec.scala +++ b/zio-schema-optics/shared/src/test/scala/zio/schema/optics/LensSpec.scala @@ -32,7 +32,7 @@ object LensSpec extends ZIOSpecDefault { ): URIO[Env, TestResult] = check(genWhole) { wholeBefore => val wholeAfter = lens.get(wholeBefore).flatMap(lens.set(_)(wholeBefore)) - assert(wholeAfter)(isRight(equalTo(wholeBefore))) + assert(wholeAfter)(iszio.prelude.Validation.succeed(equalTo(wholeBefore))) } def setGetIdentity[F, Env <: TestConfig, Whole, Piece](genWhole: Gen[Env, Whole], genPiece: Gen[Env, Piece])( @@ -40,7 +40,7 @@ object LensSpec extends ZIOSpecDefault { ): URIO[Env, TestResult] = check(genWhole, genPiece) { (whole, pieceBefore) => val pieceAfter = lens.set(pieceBefore)(whole).flatMap(lens.get) - assert(pieceAfter)(isRight(equalTo(pieceBefore))) + assert(pieceAfter)(iszio.prelude.Validation.succeed(equalTo(pieceBefore))) } def setSetIdentity[F, Env <: TestConfig, Whole, Piece](genWhole: Gen[Env, Whole], genPiece: Gen[Env, Piece])( 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 01a25f7fd..7ac12dd35 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 @@ -20,7 +20,7 @@ object ProtobufCodec { implicit def protobufCodec[A](implicit schema: Schema[A]): BinaryCodec[A] = new BinaryCodec[A] { - override def decode(whole: Chunk[Byte]): Either[DecodeError, A] = + override def decode(whole: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = new Decoder(whole).decode(schema) override def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] = @@ -59,7 +59,7 @@ object ProtobufCodec { case _: Schema.Tuple2[_, _] => false case _: Schema.Optional[_] => false case _: Schema.Fail[_] => false - case _: Schema.Either[_, _] => false + case _: Schema.zio.prelude.Validation[_, _] => false case lzy @ Schema.Lazy(_) => canBePacked(lzy.schema) case _ => false } @@ -213,8 +213,8 @@ object ProtobufCodec { override protected def processEither( context: EncoderContext, - schema: Schema.Either[_, _], - value: Either[Chunk[Byte], Chunk[Byte]] + schema: Schema.zio.prelude.Validation[_, _], + value: zio.prelude.Validation[Chunk[Byte], Chunk[Byte]] ): Chunk[Byte] = { val encodedEither = value.merge encodeKey(WireType.LengthDelimited(encodedEither.size), context.fieldNumber) ++ encodedEither @@ -269,10 +269,10 @@ object ProtobufCodec { ): EncoderContext = context.copy(fieldNumber = Some(index + 1)) - override protected def contextForEither(context: EncoderContext, e: Either[Unit, Unit]): EncoderContext = + override protected def contextForEither(context: EncoderContext, e: zio.prelude.Validation[Unit, Unit]): EncoderContext = e match { case Left(_) => context.copy(fieldNumber = Some(1)) - case Right(_) => context.copy(fieldNumber = Some(2)) + case zio.prelude.Validation.succeed(_) => context.copy(fieldNumber = Some(2)) } override protected def contextForOption(context: EncoderContext, o: Option[Unit]): EncoderContext = @@ -493,9 +493,9 @@ object ProtobufCodec { private val state: DecoderState = new DecoderState(chunk, 0) - def decode[A](schema: Schema[A]): scala.util.Either[DecodeError, A] = + def decode[A](schema: Schema[A]): zio.prelude.Validation[DecodeError, A] = try { - Right(create(schema).asInstanceOf[A]) + zio.prelude.Validation.succeed(create(schema).asInstanceOf[A]) } catch { case CreateValueFromSchemaError(_, cause) => cause match { @@ -624,7 +624,7 @@ object ProtobufCodec { ): Any = Unsafe.unsafe { implicit u => record.construct(values.map(_._2)) match { - case Right(result) => result + case zio.prelude.Validation.succeed(result) => result case Left(message) => throw DecodeError.ReadError(Cause.empty, message) } } @@ -814,19 +814,19 @@ object ProtobufCodec { override protected def startCreatingEither( context: DecoderContext, - schema: Schema.Either[_, _] - ): Either[DecoderContext, DecoderContext] = + schema: Schema.zio.prelude.Validation[_, _] + ): zio.prelude.Validation[DecoderContext, DecoderContext] = keyDecoder(context) match { case (_, fieldNumber) if fieldNumber == 1 => Left(context) - case (_, fieldNumber) if fieldNumber == 2 => Right(context) + case (_, fieldNumber) if fieldNumber == 2 => zio.prelude.Validation.succeed(context) case (_, fieldNumber) => throw ExtraFields(fieldNumber.toString, s"Invalid field number ($fieldNumber) for either") } override protected def createEither( context: DecoderContext, - schema: Schema.Either[_, _], - value: Either[Any, Any] + schema: Schema.zio.prelude.Validation[_, _], + value: zio.prelude.Validation[Any, Any] ): Any = value @@ -875,12 +875,12 @@ object ProtobufCodec { override protected def transform( context: DecoderContext, value: Any, - f: Any => Either[String, Any], + f: Any => zio.prelude.Validation[String, Any], schema: Schema[_] ): Any = f(value) match { case Left(value) => throw MalformedField(schema, value) - case Right(value) => value + case zio.prelude.Validation.succeed(value) => value } override protected def fail(context: DecoderContext, message: String): Any = diff --git a/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala b/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala index b15dc82ad..3b1430258 100644 --- a/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala +++ b/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala @@ -475,7 +475,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(either))) && assert(ed2)(equalTo(either)) }, test("either right") { - val either = Right("hello") + val either = zio.prelude.Validation.succeed("hello") for { ed <- encodeAndDecode(eitherSchema, either) ed2 <- encodeAndDecodeNS(eitherSchema, either) @@ -489,8 +489,8 @@ object ProtobufCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(eitherLeft))) && assert(ed2)(equalTo(eitherLeft)) }, test("either with sum type") { - val eitherRight = Right(BooleanValue(true)) - val eitherRight2 = Right(StringValue("hello")) + val eitherRight = zio.prelude.Validation.succeed(BooleanValue(true)) + val eitherRight2 = zio.prelude.Validation.succeed(StringValue("hello")) for { ed <- encodeAndDecode(complexEitherSchema, eitherRight2) ed2 <- encodeAndDecodeNS(complexEitherSchema, eitherRight) @@ -575,7 +575,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(value))) && assert(ed2)(equalTo(value)) }, test("either within either") { - val either = Right(Left(BooleanValue(true))) + val either = zio.prelude.Validation.succeed(Left(BooleanValue(true))) val schema = Schema.either(Schema[Int], Schema.either(schemaOneOf, Schema[String])) for { ed <- encodeAndDecode(schema, either) @@ -585,7 +585,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { test("sequence of tuples") { for { ed <- encodeAndDecodeNS2(Schema[List[(String, Int)]], List("foo" -> 1, "bar" -> 2)) - } yield assertTrue(ed == Right(List("foo" -> 1, "bar" -> 2))) + } yield assertTrue(ed == zio.prelude.Validation.succeed(List("foo" -> 1, "bar" -> 2))) }, test("sequence of products") { val richSequence = SequenceOfProduct( @@ -633,7 +633,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { for { ed <- encodeAndDecode2(schema, value) // ed2 <- encodeAndDecodeNS(schema, value) - } yield assertTrue(ed == Right(Chunk(value))) //&& assert(ed2)(equalTo(value)) + } yield assertTrue(ed == zio.prelude.Validation.succeed(Chunk(value))) //&& assert(ed2)(equalTo(value)) } }, test("deep recursive data types") { @@ -642,7 +642,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { for { ed <- encodeAndDecode2(schema, value) // ed2 <- encodeAndDecodeNS(schema, value) - } yield assertTrue(ed == Right(Chunk(value))) //&& assert(ed2)(equalTo(value)) + } yield assertTrue(ed == zio.prelude.Validation.succeed(Chunk(value))) //&& assert(ed2)(equalTo(value)) } } @@ TestAspect.size(200) ), @@ -944,12 +944,12 @@ object ProtobufCodecSpec extends ZIOSpecDefault { val complexTupleSchema: Schema.Tuple2[Record, OneOf] = Schema.Tuple2(Record.schemaRecord, schemaOneOf) - val eitherSchema: Schema.Either[Int, String] = Schema.Either(Schema[Int], Schema[String]) + val eitherSchema: Schema.zio.prelude.Validation[Int, String] = Schema.Either(Schema[Int], Schema[String]) - val complexEitherSchema: Schema.Either[Record, OneOf] = + val complexEitherSchema: Schema.zio.prelude.Validation[Record, OneOf] = Schema.Either(Record.schemaRecord, schemaOneOf) - val complexEitherSchema2: Schema.Either[MyRecord, MyRecord] = + val complexEitherSchema2: Schema.zio.prelude.Validation[MyRecord, MyRecord] = Schema.Either(myRecord, myRecord) case class RichProduct(stringOneOf: OneOf, basicString: BasicString, record: Record) @@ -1054,7 +1054,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { .apply(ZStream.succeed(input)) .run(ZSink.collectAll) - def encodeAndDecode2[A](schema: Schema[A], input: A): ZIO[Any, Any, scala.util.Either[DecodeError, Chunk[A]]] = + def encodeAndDecode2[A](schema: Schema[A], input: A): ZIO[Any, Any, zio.prelude.Validation[DecodeError, Chunk[A]]] = ProtobufCodec .protobufCodec(schema) .streamEncoder @@ -1089,7 +1089,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { schema: Schema[A], input: A, print: Boolean = false - ): ZIO[Any, DecodeError, scala.util.Either[DecodeError, A]] = + ): ZIO[Any, DecodeError, zio.prelude.Validation[DecodeError, A]] = ZIO .succeed(input) .tap(value => printLine(s"Input Value: $value").when(print).ignore) diff --git a/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala b/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala index 411b5c558..3dc39e875 100644 --- a/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala +++ b/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala @@ -21,7 +21,7 @@ object ThriftCodec { implicit def thriftCodec[A](implicit schema: Schema[A]): BinaryCodec[A] = new BinaryCodec[A] { - override def decode(whole: Chunk[Byte]): Either[DecodeError, A] = + override def decode(whole: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = if (whole.isEmpty) Left(EmptyContent("No bytes to decode")) else @@ -44,12 +44,12 @@ object ThriftCodec { } } - private def decodeChunk(chunk: Chunk[Byte]): Either[DecodeError, A] = + private def decodeChunk(chunk: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = if (chunk.isEmpty) Left(EmptyContent("No bytes to decode")) else { try { - Right( + zio.prelude.Validation.succeed( new Decoder(chunk) .create(schema) .asInstanceOf[A] @@ -133,13 +133,13 @@ object ThriftCodec { override protected def processSet(context: Context, schema: Schema.Set[_], value: Set[Unit]): Unit = {} - override protected def startProcessingEither(context: Context, schema: Schema.Either[_, _]): Unit = + override protected def startProcessingEither(context: Context, schema: Schema.zio.prelude.Validation[_, _]): Unit = writeFieldBegin(context.fieldNumber, TType.STRUCT) override protected def processEither( context: Context, - schema: Schema.Either[_, _], - value: Either[Unit, Unit] + schema: Schema.zio.prelude.Validation[_, _], + value: zio.prelude.Validation[Unit, Unit] ): Unit = writeFieldEnd() @@ -184,10 +184,10 @@ object ThriftCodec { override protected def contextForEnumConstructor(context: Context, index: Int, c: Schema.Case[_, _]): Context = context.copy(fieldNumber = Some((index + 1).toShort)) - override protected def contextForEither(context: Context, e: Either[Unit, Unit]): Context = + override protected def contextForEither(context: Context, e: zio.prelude.Validation[Unit, Unit]): Context = e match { case Left(_) => context.copy(fieldNumber = Some(1)) - case Right(_) => context.copy(fieldNumber = Some(2)) + case zio.prelude.Validation.succeed(_) => context.copy(fieldNumber = Some(2)) } override protected def contextForOption(context: Context, o: Option[Unit]): Context = @@ -627,14 +627,14 @@ object ThriftCodec { Unsafe.unsafe { implicit u => record.construct(allValues) match { case Left(message) => fail(context, message) - case Right(value) => value + case zio.prelude.Validation.succeed(value) => value } } } else { Unsafe.unsafe { implicit u => record.construct(Chunk.empty) match { case Left(message) => fail(context, message) - case Right(value) => value + case zio.prelude.Validation.succeed(value) => value } } } @@ -772,20 +772,20 @@ object ThriftCodec { override protected def startCreatingEither( context: DecoderContext, - schema: Schema.Either[_, _] - ): Either[DecoderContext, DecoderContext] = { + schema: Schema.zio.prelude.Validation[_, _] + ): zio.prelude.Validation[DecoderContext, DecoderContext] = { val readField = p.readFieldBegin() readField.id match { case 1 => Left(context.copy(path = context.path :+ "either:left")) - case 2 => Right(context.copy(path = context.path :+ "either:right")) - case _ => fail(context, "Failed to decode either.").asInstanceOf[Either[DecoderContext, DecoderContext]] + case 2 => zio.prelude.Validation.succeed(context.copy(path = context.path :+ "either:right")) + case _ => fail(context, "Failed to decode either.").asInstanceOf[zio.prelude.Validation[DecoderContext, DecoderContext]] } } override protected def createEither( context: DecoderContext, - schema: Schema.Either[_, _], - value: Either[Any, Any] + schema: Schema.zio.prelude.Validation[_, _], + value: zio.prelude.Validation[Any, Any] ): Any = value @@ -818,12 +818,12 @@ object ThriftCodec { override protected def transform( context: DecoderContext, value: Any, - f: Any => Either[String, Any], + f: Any => zio.prelude.Validation[String, Any], schema: Schema[_] ): Any = f(value) match { case Left(value) => fail(context, value) - case Right(value) => value + case zio.prelude.Validation.succeed(value) => value } override protected def fail(context: DecoderContext, message: String): Any = diff --git a/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala b/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala index 67c4cd9f5..0cca11c1e 100644 --- a/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala +++ b/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala @@ -465,7 +465,7 @@ object ThriftCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(either))) && assert(ed2)(equalTo(either)) }, test("either right") { - val either = Right("hello") + val either = zio.prelude.Validation.succeed("hello") for { ed <- encodeAndDecode(eitherSchema, either) ed2 <- encodeAndDecodeNS(eitherSchema, either) @@ -479,8 +479,8 @@ object ThriftCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(eitherLeft))) && assert(ed2)(equalTo(eitherLeft)) }, test("either with sum type") { - val eitherRight = Right(BooleanValue(true)) - val eitherRight2 = Right(StringValue("hello")) + val eitherRight = zio.prelude.Validation.succeed(BooleanValue(true)) + val eitherRight2 = zio.prelude.Validation.succeed(StringValue("hello")) for { ed <- encodeAndDecode(complexEitherSchema, eitherRight2) ed2 <- encodeAndDecodeNS(complexEitherSchema, eitherRight) @@ -597,7 +597,7 @@ object ThriftCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(value))) && assert(ed2)(equalTo(value)) }, test("either within either") { - val either = Right(Left(BooleanValue(true))) + val either = zio.prelude.Validation.succeed(Left(BooleanValue(true))) val schema = Schema.either(Schema[Int], Schema.either(schemaOneOf, Schema[String])) for { ed <- encodeAndDecode(schema, either) @@ -1020,12 +1020,12 @@ object ThriftCodecSpec extends ZIOSpecDefault { val complexTupleSchema: Schema.Tuple2[Record, OneOf] = Schema.Tuple2(Record.schemaRecord, schemaOneOf) - val eitherSchema: Schema.Either[Int, String] = Schema.Either(Schema[Int], Schema[String]) + val eitherSchema: Schema.zio.prelude.Validation[Int, String] = Schema.Either(Schema[Int], Schema[String]) - val complexEitherSchema: Schema.Either[Record, OneOf] = + val complexEitherSchema: Schema.zio.prelude.Validation[Record, OneOf] = Schema.Either(Record.schemaRecord, schemaOneOf) - val complexEitherSchema2: Schema.Either[MyRecord, MyRecord] = + val complexEitherSchema2: Schema.zio.prelude.Validation[MyRecord, MyRecord] = Schema.Either(myRecord, myRecord) case class RichProduct(stringOneOf: OneOf, basicString: BasicString, record: Record) diff --git a/zio-schema-zio-test/shared/src/main/scala/zio/schema/DeriveGen.scala b/zio-schema-zio-test/shared/src/main/scala/zio/schema/DeriveGen.scala index c2cf96731..cc0eaab16 100644 --- a/zio-schema-zio-test/shared/src/main/scala/zio/schema/DeriveGen.scala +++ b/zio-schema-zio-test/shared/src/main/scala/zio/schema/DeriveGen.scala @@ -529,7 +529,7 @@ object DeriveGen { private def genTuple[A, B](tuple: Schema.Tuple2[A, B]): Gen[Sized, (A, B)] = gen(tuple.left).zip(gen(tuple.right)) - private def genEither[A, B](either: Schema.Either[A, B]): Gen[Sized, scala.util.Either[A, B]] = + private def genzio.prelude.Validation[A, B](either: Schema.zio.prelude.Validation[A, B]): Gen[Sized, zio.prelude.Validation[A, B]] = Gen.either(gen(either.left), gen(either.right)) private def genLazy[A](lazySchema: Schema.Lazy[A]): Gen[Sized, A] = diff --git a/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala b/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala index 49de74a50..6b72a610d 100644 --- a/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala +++ b/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala @@ -48,14 +48,14 @@ object TestData { val uuidSchema: Schema[java.util.UUID] = Schema.Primitive(StandardType.UUIDType) - val eitherSchema: Schema[Either[String, Unit]] = Schema.Either(stringSchema, unitSchema) + val eitherSchema: Schema[zio.prelude.Validation[String, Unit]] = Schema.Either(stringSchema, unitSchema) val tupleSchema: Schema[(String, Unit)] = Schema.Tuple2(stringSchema, unitSchema) val listSchema: Schema[List[Int]] = Schema.list(intSchema) val mapSchema: Schema[Map[Int, String]] = Schema.map(intSchema, stringSchema) val optionalSchema: Schema[Option[Int]] = Schema.Optional(intSchema) val transformSchema: Schema[String] = - intSchema.transformOrFail[String]((int: Int) => Right(int.toString), (_: String) => Left("error")) + intSchema.transformOrFail[String]((int: Int) => zio.prelude.Validation.succeed(int.toString), (_: String) => Left("error")) val failSchema: Schema[Unit] = Schema.Fail[Unit]("failed") val lazySchema: Schema[Int] = Schema.Lazy(() => intSchema) diff --git a/zio-schema/shared/src/main/scala/zio/schema/Differ.scala b/zio-schema/shared/src/main/scala/zio/schema/Differ.scala index 4f4dee67f..4c3e4b70d 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Differ.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Differ.scala @@ -1,15 +1,15 @@ package zio.schema +import zio.prelude.Validation + import java.math.{ BigInteger, MathContext } import java.time.temporal.{ ChronoField, ChronoUnit } import java.time.{ DayOfWeek, - Duration => JDuration, Instant, LocalDate, LocalDateTime, LocalTime, - Month => JMonth, MonthDay, OffsetDateTime, OffsetTime, @@ -18,13 +18,13 @@ import java.time.{ YearMonth, ZoneId, ZoneOffset, + Duration => JDuration, + Month => JMonth, ZonedDateTime => JZonedDateTime } import java.util.UUID - import scala.annotation.nowarn import scala.collection.immutable.ListMap - import zio.schema.diff.Edit import zio.{ Chunk, ChunkBuilder } @@ -41,14 +41,15 @@ trait Differ[A] { self => def transform[B](f: B => A, g: A => B): Differ[B] = (thisValue: B, thatValue: B) => - Patch.Transform(self(f(thisValue), f(thatValue)), g.andThen(Right(_)), f.andThen(Right(_))) + Patch.Transform(self(f(thisValue), f(thatValue)), g.andThen(Validation.succeed), f.andThen(Validation.succeed)) - def transformOrFail[B](f: B => Either[String, A], g: A => Either[String, B]): Differ[B] = + def transformOrFail[B](f: B => Validation[String, A], g: A => Validation[String, B]): Differ[B] = (thisValue: B, thatValue: B) => - f(thisValue) -> f(thatValue) match { - case (Right(l), Right(r)) => Patch.Transform(self(l, r), g, f) - case _ => Patch.notComparable - } + (for { + l <- f(thisValue) + r <- f(thatValue) + } yield Patch.Transform(self(l, r), g, f)) + .getOrElse(Patch.notComparable) def chunk: Differ[Chunk[A]] = Differ.LCSDiff[A] @@ -56,8 +57,8 @@ trait Differ[A] { self => case (Some(l), Some(r)) => Patch.Transform[A, Option[A]]( self(l, r), - (a: A) => Right(Some(a)), - (a: Option[A]) => a.map(Right(_)).getOrElse(Left("Patch cannot be applied to None value")) + (a: A) => Validation(Some(a)), + (a: Option[A]) => a.map(zio.prelude.Validation.succeed(_)).getOrElse(Left("Patch cannot be applied to None value")) ) case (Some(_), None) => Patch.Total(None) case (None, Some(r)) => Patch.Total(Some(r)) @@ -225,20 +226,13 @@ object Differ { case Schema.Primitive(StandardType.BigIntegerType, _) => bigInt case Schema.Primitive(StandardType.StringType, _) => string case Schema.Primitive(StandardType.UUIDType, _) => - string.transformOrFail[UUID]( - (uuid: UUID) => Right(uuid.toString), - (s: String) => - try { - Right(UUID.fromString(s)) - } catch { case e: Throwable => Left(s"$s is not a valid UUID: ${e.getMessage}") } - ) + string.transformOrFail[UUID]((uuid: UUID) => Validation.succeed(uuid.toString), (s: String) => Validation(UUID.fromString(s)).mapError(e => s"$s is not a valid UUID: ${e.getMessage}")) case Schema.Primitive(StandardType.ZoneIdType, _) => string.transformOrFail[ZoneId]( - (zoneId: ZoneId) => Right(zoneId.getId), + (zoneId: ZoneId) => Validation.succeed(zoneId.getId), (s: String) => - try { - Right(ZoneId.of(s)) - } catch { case e: Throwable => Left(s"$s is not a valid ZoneId: ${e.getMessage}") } + Validation(ZoneId.of(s)) + .mapError(e => s"$s is not a valid ZoneId: ${e.getMessage}") ) case Schema.Primitive(StandardType.DayOfWeekType, _) => dayOfWeek case Schema.Primitive(StandardType.PeriodType, _) => period @@ -526,7 +520,7 @@ object Differ { (thisValue: (A, B), thatValue: (A, B)) => (thisValue, thatValue) match { case ((thisA, thisB), (thatA, thatB)) => - left(thisA, thatA) <*> right(thisB, thatB) + left(thisA, thatA) <*> zio.prelude.Validation.succeed(thisB, thatB) } def either[A, B](left: Differ[A], right: Differ[B]): Differ[Either[A, B]] = 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 4620ec2f0..5419632ea 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala @@ -13,9 +13,9 @@ import zio.{ Cause, Chunk, Unsafe } sealed trait DynamicValue { self => - def transform(transforms: Chunk[Migration]): Either[String, DynamicValue] = - transforms.foldRight[Either[String, DynamicValue]](Right(self)) { - case (transform, Right(value)) => transform.migrate(value) + def transform(transforms: Chunk[Migration]): zio.prelude.Validation[String, DynamicValue] = + transforms.foldRight[zio.prelude.Validation[String, DynamicValue]](zio.prelude.Validation.succeed(self)) { + case (transform, zio.prelude.Validation.succeed(value)) => transform.migrate(value) case (_, error @ Left(_)) => error } @@ -56,7 +56,7 @@ sealed trait DynamicValue { value.toTypedValueLazyError(schema1).map(Left(_)) case (DynamicValue.RightValue(value), Schema.Either(_, schema1, _)) => - value.toTypedValueLazyError(schema1).map(Right(_)) + value.toTypedValueLazyError(schema1).map(zio.prelude.Validation.succeed(_)) case (DynamicValue.Tuple(leftValue, rightValue), Schema.Tuple2(leftSchema, rightSchema, _)) => val typedLeft = leftValue.toTypedValueLazyError(leftSchema) @@ -143,12 +143,12 @@ object DynamicValue { DynamicValue.SetValue(value) override protected def processEither( - schema: Schema.Either[_, _], - value: Either[DynamicValue, DynamicValue] + schema: Schema.zio.prelude.Validation[_, _], + value: zio.prelude.Validation[DynamicValue, DynamicValue] ): DynamicValue = value match { case Left(value) => DynamicValue.LeftValue(value) - case Right(value) => DynamicValue.RightValue(value) + case zio.prelude.Validation.succeed(value) => DynamicValue.RightValue(value) } override protected def processOption(schema: Schema.Optional[_], value: Option[DynamicValue]): DynamicValue = @@ -491,7 +491,7 @@ object DynamicValue { "values", Schema.defer(Schema.chunk(Schema.tuple2(Schema.primitive[String], DynamicValue.schema))), get0 = record => Chunk.fromIterable(record.values), - set0 = (record, values) => record.copy(values = values.foldRight(ListMap.empty[String, DynamicValue])((a, b) => b + a)) + set0 = (record, values) => record.copy(values = values.foldzio.prelude.Validation.succeed(ListMap.empty[String, DynamicValue])((a, b) => b + a)) ), (id, chunk) => DynamicValue.Record(id, ListMap(chunk.toSeq: _*)) ), diff --git a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala index 4a49f6b1a..54faf1862 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala @@ -123,10 +123,10 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { * this method is responsible for gathering enough information to decide whether the created value will * be a Left or a Right. The result value represents this, and for each case allows specifying a context * that will be used to create the inner value. */ - protected def startCreatingEither(context: Context, schema: Schema.Either[_, _]): Either[Context, Context] + protected def startCreatingEither(context: Context, schema: Schema.zio.prelude.Validation[_, _]): zio.prelude.Validation[Context, Context] /** Create the either value from an inner value */ - protected def createEither(context: Context, schema: Schema.Either[_, _], value: Either[Target, Target]): Target + protected def createEither(context: Context, schema: Schema.zio.prelude.Validation[_, _], value: zio.prelude.Validation[Target, Target]): Target /** The next value to be created is a tuple with the given schema. The returned context is used to * construct the first element of the tuple. */ @@ -147,7 +147,7 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { /** Transforms a value with the given function that can fail. Making this customizable allows encoding the failure * in Target. */ - protected def transform(context: Context, value: Target, f: Any => Either[String, Any], schema: Schema[_]): Target + protected def transform(context: Context, value: Target, f: Any => zio.prelude.Validation[String, Any], schema: Schema[_]): Target /** Fail the builder with the given message */ protected def fail(context: Context, message: String): Target @@ -615,7 +615,7 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { finishWith(createSet(contextStack.head, s, Chunk.empty)) } - case s: Schema.Either[l, r] => + case s: Schema.zio.prelude.Validation[l, r] => startCreatingEither(currentContext, s) match { case Left(newState) => currentSchema = s.left @@ -624,12 +624,12 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { contextStack = contextStack.tail finishWith(createEither(contextStack.head, s, Left(value))) } - case Right(newState) => + case zio.prelude.Validation.succeed(newState) => currentSchema = s.right pushContext(newState) push { value => contextStack = contextStack.tail - finishWith(createEither(contextStack.head, s, Right(value))) + finishWith(createEither(contextStack.head, s, zio.prelude.Validation.succeed(value))) } } @@ -663,7 +663,7 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { case s @ Schema.Transform(schema, f, _, _, _) => currentSchema = schema push { result => - finishWith(transform(currentContext, result, f.asInstanceOf[Any => Either[String, Any]], s)) + finishWith(transform(currentContext, result, f.asInstanceOf[Any => zio.prelude.Validation[String, Any]], s)) } case s @ Schema.CaseClass0(_, _, _) => @@ -1111,18 +1111,18 @@ trait SimpleMutableSchemaBasedValueBuilder[Target] extends MutableSchemaBasedVal protected def createOptional(schema: Schema.Optional[_], value: Option[Target]): Target - override protected def startCreatingEither(context: Unit, schema: Schema.Either[_, _]): Either[Unit, Unit] = + override protected def startCreatingEither(context: Unit, schema: Schema.zio.prelude.Validation[_, _]): zio.prelude.Validation[Unit, Unit] = startCreatingEither(schema) - protected def startCreatingEither(schema: Schema.Either[_, _]): Either[Unit, Unit] + protected def startCreatingEither(schema: Schema.zio.prelude.Validation[_, _]): zio.prelude.Validation[Unit, Unit] override protected def createEither( context: Unit, - schema: Schema.Either[_, _], - value: Either[Target, Target] + schema: Schema.zio.prelude.Validation[_, _], + value: zio.prelude.Validation[Target, Target] ): Target = createEither(schema, value) - protected def createEither(schema: Schema.Either[_, _], value: Either[Target, Target]): Target + protected def createEither(schema: Schema.zio.prelude.Validation[_, _], value: zio.prelude.Validation[Target, Target]): Target override protected def startCreatingTuple(context: Unit, schema: Schema.Tuple2[_, _]): Unit = startCreatingTuple(schema) @@ -1147,12 +1147,12 @@ trait SimpleMutableSchemaBasedValueBuilder[Target] extends MutableSchemaBasedVal override protected def transform( context: Unit, value: Target, - f: Any => Either[String, Any], + f: Any => zio.prelude.Validation[String, Any], schema: Schema[_] ): Target = transform(value, f, schema) - protected def transform(value: Target, f: Any => Either[String, Any], schema: Schema[_]): Target + protected def transform(value: Target, f: Any => zio.prelude.Validation[String, Any], schema: Schema[_]): Target override protected def fail(context: Unit, message: String): Target = fail(message) diff --git a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala index c044608f4..38d3e6a7e 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala @@ -56,10 +56,10 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { protected def processSet(context: Context, schema: Schema.Set[_], value: Set[Target]): Target /** Called before processing and either value */ - @nowarn protected def startProcessingEither(context: Context, schema: Schema.Either[_, _]): Unit = {} + @nowarn protected def startProcessingEither(context: Context, schema: Schema.zio.prelude.Validation[_, _]): Unit = {} /** Process an either value using its already processed left or right value */ - protected def processEither(context: Context, schema: Schema.Either[_, _], value: Either[Target, Target]): Target + protected def processEither(context: Context, schema: Schema.zio.prelude.Validation[_, _], value: zio.prelude.Validation[Target, Target]): Target /** Called before processing an option value */ @nowarn protected def startProcessingOption(context: Context, schema: Schema.Optional[_]): Unit = {} @@ -93,7 +93,7 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { protected def contextForEnumConstructor(context: Context, index: Int, c: Schema.Case[_, _]): Context /** Gets the context for an either's left or right value within the parent context */ - protected def contextForEither(context: Context, e: Either[Unit, Unit]): Context + protected def contextForEither(context: Context, e: zio.prelude.Validation[Unit, Unit]): Context /** Gets the context for an option's inner value within the parent context */ protected def contextForOption(context: Context, o: Option[Unit]): Context @@ -814,9 +814,9 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { pushContext(contextForSet(currentContext, s, 0)) processNext(0) - case s: Schema.Either[l, r] => + case s: Schema.zio.prelude.Validation[l, r] => startProcessingEither(currentContext, s) - currentValue.asInstanceOf[Either[l, r]] match { + currentValue.asInstanceOf[zio.prelude.Validation[l, r]] match { case Left(value: l) => currentValue = value currentSchema = s.left @@ -825,13 +825,13 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { contextStack = contextStack.tail finishWith(processEither(currentContext, s, Left(dyn))) } - case Right(value: r) => + case zio.prelude.Validation.succeed(value: r) => currentValue = value currentSchema = s.right - pushContext(contextForEither(currentContext, Right(()))) + pushContext(contextForEither(currentContext, zio.prelude.Validation.succeed(()))) push { dyn => contextStack = contextStack.tail - finishWith(processEither(currentContext, s, Right(dyn))) + finishWith(processEither(currentContext, s, zio.prelude.Validation.succeed(dyn))) } } @@ -868,10 +868,10 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { } case Schema.Transform(schema, _, g, _, _) => - g.asInstanceOf[Any => Either[String, Any]](currentValue) match { + g.asInstanceOf[Any => zio.prelude.Validation[String, Any]](currentValue) match { case Left(message) => finishWith(fail(currentContext, message)) - case Right(a) => + case zio.prelude.Validation.succeed(a) => currentValue = a currentSchema = schema } @@ -1347,7 +1347,7 @@ trait SimpleMutableSchemaBasedValueProcessor[Target] extends MutableSchemaBasedV protected def processSet(schema: Schema.Set[_], value: Set[Target]): Target - protected def processEither(schema: Schema.Either[_, _], value: Either[Target, Target]): Target + protected def processEither(schema: Schema.zio.prelude.Validation[_, _], value: zio.prelude.Validation[Target, Target]): Target protected def processOption(schema: Schema.Optional[_], value: Option[Target]): Target @@ -1389,8 +1389,8 @@ trait SimpleMutableSchemaBasedValueProcessor[Target] extends MutableSchemaBasedV override protected def processEither( context: Unit, - schema: Schema.Either[_, _], - value: Either[Target, Target] + schema: Schema.zio.prelude.Validation[_, _], + value: zio.prelude.Validation[Target, Target] ): Target = processEither(schema, value) @@ -1414,7 +1414,7 @@ trait SimpleMutableSchemaBasedValueProcessor[Target] extends MutableSchemaBasedV override protected def contextForEnumConstructor(context: Unit, index: Int, c: Schema.Case[_, _]): Unit = () - override protected def contextForEither(context: Unit, e: Either[Unit, Unit]): Unit = + override protected def contextForEither(context: Unit, e: zio.prelude.Validation[Unit, Unit]): Unit = () override protected def contextForOption(context: Unit, o: Option[Unit]): Unit = diff --git a/zio-schema/shared/src/main/scala/zio/schema/Patch.scala b/zio-schema/shared/src/main/scala/zio/schema/Patch.scala index 63fa573b5..8c34b78e7 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Patch.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Patch.scala @@ -36,7 +36,7 @@ sealed trait Patch[A] { self => def zip[B](that: Patch[B]): Patch[(A, B)] = Patch.Tuple(self, that) - def patch(a: A): Either[String, A] + def patch(a: A): Validation[String, A] def invert: Patch[A] @@ -54,48 +54,48 @@ object Patch { def notComparable[A]: NotComparable[A] = NotComparable() final case class Identical[A]() extends Patch[A] { - override def patch(a: A): Either[String, A] = Right(a) - override def isIdentical: Boolean = true + override def patch(a: A): Validation[String, A] = Validation.succeed(a) + override def isIdentical: Boolean = true override def invert: Patch[A] = this } final case class Bool(xor: Boolean) extends Patch[Boolean] { - override def patch(a: Boolean): Either[String, Boolean] = Right(a ^ xor) + override def patch(a: Boolean): Validation[String, Boolean] = Validation.succeed(a ^ xor) override def invert: Patch[Boolean] = this } final case class Number[A](distance: A)(implicit ev: Numeric[A]) extends Patch[A] { - override def patch(input: A): Either[String, A] = - Right(ev.minus(input, distance)) + override def patch(input: A): Validation[String, A] = + Validation.succeed(ev.minus(input, distance)) override def invert: Patch[A] = Number(ev.negate(distance)) } final case class BigInt(distance: BigInteger) extends Patch[BigInteger] { - override def patch(input: BigInteger): Either[String, BigInteger] = - Right(input.subtract(distance)) + override def patch(input: BigInteger): Validation[String, BigInteger] = + Validation.succeed(input.subtract(distance)) override def invert: Patch[BigInteger] = BigInt(distance.negate()) } final case class BigDecimal(distance: java.math.BigDecimal, precision: Int) extends Patch[java.math.BigDecimal] { - override def patch(input: java.math.BigDecimal): Either[String, java.math.BigDecimal] = { + override def patch(input: java.math.BigDecimal): Validation[String, java.math.BigDecimal] = { val mc = new MathContext(precision) - Right(input.round(mc).subtract(distance, mc)) + Validation.succeed(input.round(mc).subtract(distance, mc)) } override def invert: Patch[java.math.BigDecimal] = BigDecimal(distance.negate(), precision) } final case class Temporal[A](distances: List[Long], tpe: StandardType[A]) extends Patch[A] { self => - override def patch(a: A): Either[String, A] = + override def patch(a: A): Validation[String, A] = (tpe, distances) match { case (_: StandardType.YearType.type, distance :: Nil) => - Right(Year.of(a.asInstanceOf[Year].getValue - distance.toInt).asInstanceOf[A]) + Validation.succeed(Year.of(a.asInstanceOf[Year].getValue - distance.toInt).asInstanceOf[A]) case (_: StandardType.YearMonthType.type, distance :: Nil) => - Right( + Validation.succeed( YearMonth .now() .`with`( @@ -105,17 +105,17 @@ object Patch { .asInstanceOf[A] ) case (_: StandardType.ZonedDateTimeType.type, distance :: Nil) => - Right(LocalDate.ofEpochDay(a.asInstanceOf[LocalDate].toEpochDay - distance).asInstanceOf[A]) + Validation.succeed(LocalDate.ofEpochDay(a.asInstanceOf[LocalDate].toEpochDay - distance).asInstanceOf[A]) case (_: StandardType.InstantType.type, dist1 :: dist2 :: Nil) => - Right( + Validation.succeed( Instant .ofEpochSecond(a.asInstanceOf[Instant].getEpochSecond - dist1, a.asInstanceOf[Instant].getNano() - dist2) .asInstanceOf[A] ) case (_: StandardType.LocalTimeType.type, distance :: Nil) => - Right(LocalTime.ofNanoOfDay(a.asInstanceOf[LocalTime].toNanoOfDay - distance).asInstanceOf[A]) + Validation.succeed(LocalTime.ofNanoOfDay(a.asInstanceOf[LocalTime].toNanoOfDay - distance).asInstanceOf[A]) case (_: StandardType.LocalDateTimeType.type, dist1 :: dist2 :: Nil) => - Right { + Validation.succeed { LocalDateTime .of( LocalDate.ofEpochDay(a.asInstanceOf[LocalDateTime].toLocalDate.toEpochDay - dist1), @@ -124,7 +124,7 @@ object Patch { .asInstanceOf[A] } case (_: StandardType.OffsetTimeType.type, dist1 :: dist2 :: Nil) => - Right { + Validation.succeed { OffsetTime .of( LocalTime.ofNanoOfDay(a.asInstanceOf[OffsetTime].toLocalTime.toNanoOfDay - dist1), @@ -133,7 +133,7 @@ object Patch { .asInstanceOf[A] } case (_: StandardType.OffsetDateTimeType.type, dist1 :: dist2 :: dist3 :: Nil) => - Right { + Validation.succeed { OffsetDateTime .of( LocalDate.ofEpochDay(a.asInstanceOf[OffsetDateTime].toLocalDate.toEpochDay - dist1), @@ -143,45 +143,41 @@ object Patch { .asInstanceOf[A] } case (_: StandardType.PeriodType.type, dayAdjustment :: monthAdjustment :: yearAdjustment :: Nil) => - try { - Right( - Period - .of( - a.asInstanceOf[Period].getYears - yearAdjustment.toInt, - a.asInstanceOf[Period].getMonths - monthAdjustment.toInt, - a.asInstanceOf[Period].getDays - dayAdjustment.toInt - ) - .asInstanceOf[A] - ) - } catch { case _: Throwable => Left(s"Invalid java.time.Period diff $self") } + Validation( + Period + .of( + a.asInstanceOf[Period].getYears - yearAdjustment.toInt, + a.asInstanceOf[Period].getMonths - monthAdjustment.toInt, + a.asInstanceOf[Period].getDays - dayAdjustment.toInt + ) + .asInstanceOf[A] + ).mapError(_ => s"Invalid java.time.Period diff $self") case (_: StandardType.ZoneOffsetType.type, distance :: Nil) => - try { - Right( - ZoneOffset.ofTotalSeconds(a.asInstanceOf[ZoneOffset].getTotalSeconds + distance.toInt).asInstanceOf[A] - ) - } catch { case t: Throwable => Left(s"Patched offset is invalid: ${t.getMessage}") } + Validation( + ZoneOffset.ofTotalSeconds(a.asInstanceOf[ZoneOffset].getTotalSeconds + distance.toInt).asInstanceOf[A] + ).mapError(e => s"Patched offset is invalid: ${e.getMessage}") case (_: StandardType.DayOfWeekType.type, distance :: Nil) => - Right(a.asInstanceOf[DayOfWeek].plus(distance).asInstanceOf[A]) + Validation.succeed(a.asInstanceOf[DayOfWeek].plus(distance).asInstanceOf[A]) case (_: StandardType.MonthType.type, distance :: Nil) => - Right(a.asInstanceOf[java.time.Month].plus(distance).asInstanceOf[A]) + Validation.succeed(a.asInstanceOf[java.time.Month].plus(distance).asInstanceOf[A]) case (_: StandardType.DurationType.type, dist1 :: dist2 :: Nil) => - Right( + Validation.succeed( JDuration .ofSeconds(a.asInstanceOf[JDuration].getSeconds - dist1, a.asInstanceOf[JDuration].getNano() - dist2) .asInstanceOf[A] ) // // TODO need to deal with leap year differences case (_: StandardType.MonthDayType.type, regDiff :: _ :: Nil) => - Right( - MonthDay.from(ChronoUnit.DAYS.addTo(a.asInstanceOf[MonthDay].atYear(2001), regDiff.toLong)).asInstanceOf[A] + Validation.succeed( + MonthDay.from(ChronoUnit.DAYS.addTo(a.asInstanceOf[MonthDay].atYear(2001), regDiff)).asInstanceOf[A] ) case (_: StandardType.LocalDateType.type, dist :: Nil) => - Right( + Validation.succeed( LocalDate .ofEpochDay(a.asInstanceOf[LocalDate].toEpochDay - dist) .asInstanceOf[A] ) - case (s, _) => Left(s"Cannot apply temporal diff to value with type $s") + case (s, _) => Validation.fail(s"Cannot apply temporal diff to value with type $s") } override def invert: Patch[A] = Temporal(distances.map(-_), tpe) @@ -189,18 +185,15 @@ object Patch { final case class ZonedDateTime(localDateTimeDiff: Patch[java.time.LocalDateTime], zoneIdDiff: Patch[String]) extends Patch[java.time.ZonedDateTime] { - override def patch(input: JZonedDateTime): scala.Either[String, JZonedDateTime] = + override def patch(input: JZonedDateTime): Validation[String, JZonedDateTime] = for { patchedLocalDateTime <- localDateTimeDiff.patch(input.toLocalDateTime) patchedZoneId <- zoneIdDiff.patch(input.getZone.getId) - patched <- try { - Right(JZonedDateTime.of(patchedLocalDateTime, ZoneId.of(patchedZoneId))) - } catch { - case e: Throwable => - Left( + patched <- Validation(JZonedDateTime.of(patchedLocalDateTime, ZoneId.of(patchedZoneId))) + .mapError( + e => s"Patched ZonedDateTime is not valid. Patched values $patchedLocalDateTime, $patchedZoneId. Error=${e.getMessage}" - ) - } + ) } yield patched override def invert: Patch[JZonedDateTime] = ZonedDateTime(localDateTimeDiff.invert, zoneIdDiff.invert) @@ -209,7 +202,7 @@ object Patch { final case class Tuple[A, B](leftDifference: Patch[A], rightDifference: Patch[B]) extends Patch[(A, B)] { override def isIdentical: Boolean = leftDifference.isIdentical && rightDifference.isIdentical - override def patch(input: (A, B)): Either[String, (A, B)] = + override def patch(input: (A, B)): Validation[String, (A, B)] = for { l <- leftDifference.patch(input._1) r <- rightDifference.patch(input._2) @@ -219,20 +212,20 @@ object Patch { } final case class LCS[A](edits: Chunk[Edit[A]]) extends Patch[Chunk[A]] { - override def patch(as: Chunk[A]): Either[String, Chunk[A]] = { + override def patch(as: Chunk[A]): Validation[String, Chunk[A]] = { import zio.schema.diff.{ Edit => ZEdit } @tailrec - def calc(in: List[A], edits: List[Edit[A]], result: List[A]): Either[String, Chunk[A]] = (in, edits) match { - case (_ :: _, Nil) => Left(s"Incorrect Patch - no instructions for these items: ${in.mkString}.") - case (h :: _, ZEdit.Delete(s) :: _) if s != h => Left(s"Cannot Delete $s - current letter is $h.") - case (Nil, ZEdit.Delete(s) :: _) => Left(s"Cannot Delete $s - no items left to delete.") + def calc(in: List[A], edits: List[Edit[A]], result: List[A]): Validation[String, Chunk[A]] = (in, edits) match { + case (_ :: _, Nil) => Validation.fail(s"Incorrect Patch - no instructions for these items: ${in.mkString}.") + case (h :: _, ZEdit.Delete(s) :: _) if s != h => Validation.fail(s"Cannot Delete $s - current letter is $h.") + case (Nil, ZEdit.Delete(s) :: _) => Validation.fail(s"Cannot Delete $s - no items left to delete.") case (_ :: t, ZEdit.Delete(_) :: tail) => calc(t, tail, result) - case (h :: _, ZEdit.Keep(s) :: _) if s != h => Left(s"Cannot Keep $s - current letter is $h.") - case (Nil, ZEdit.Keep(s) :: _) => Left(s"Cannot Keep $s - no items left to keep.") + case (h :: _, ZEdit.Keep(s) :: _) if s != h => Validation.fail(s"Cannot Keep $s - current letter is $h.") + case (Nil, ZEdit.Keep(s) :: _) => Validation.fail(s"Cannot Keep $s - no items left to keep.") case (h :: t, ZEdit.Keep(_) :: tail) => calc(t, tail, result :+ h) case (in, ZEdit.Insert(s) :: tail) => calc(in, tail, result :+ s) - case (Nil, Nil) => Right(Chunk.fromIterable(result)) + case (Nil, Nil) => Validation.succeed(Chunk.fromIterable(result)) } calc(as.toList, edits.toList, Nil) @@ -242,37 +235,37 @@ object Patch { } final case class Total[A](value: A) extends Patch[A] { - override def patch(input: A): Either[String, A] = Right(value) - override def invert: Patch[A] = Total(value) + override def patch(input: A): Validation[String, A] = Validation.succeed(value) + override def invert: Patch[A] = Total(value) } - final case class EitherDiff[A, B](diff: Either[Patch[A], Patch[B]]) extends Patch[Either[A, B]] { + final case class EitherDiff[A, B](diff: zio.prelude.Validation[Patch[A], Patch[B]]) extends Patch[zio.prelude.Validation[A, B]] { override def isIdentical: Boolean = diff.fold(_.isIdentical, _.isIdentical) override def isComparable: Boolean = diff.fold(_.isComparable, _.isComparable) - override def patch(input: Either[A, B]): Either[String, Either[A, B]] = (input, diff) match { - case (Left(_), Right(_)) => Left(s"Cannot apply a right diff to a left value") - case (Right(_), Left(_)) => Left(s"Cannot apply a left diff to a right value") + override def patch(input: zio.prelude.Validation[A, B]): Validation[String, zio.prelude.Validation[A, B]] = (input, diff) match { + case (Left(_), zio.prelude.Validation.succeed(_)) => Validation.fail(s"Cannot apply a right diff to a left value") + case (zio.prelude.Validation.succeed(_), Left(_)) => Validation.fail(s"Cannot apply a left diff to a right value") case (Left(in), Left(diff)) => diff.patch(in).map(Left(_)) - case (Right(in), Right(diff)) => - diff.patch(in).map(Right(_)) + case (zio.prelude.Validation.succeed(in), zio.prelude.Validation.succeed(diff)) => + diff.patch(in).map(zio.prelude.Validation.succeed(_)) } - override def invert: Patch[Either[A, B]] = diff match { + override def invert: Patch[zio.prelude.Validation[A, B]] = diff match { case Left(value) => EitherDiff(Left(value.invert)) - case Right(value) => EitherDiff(Right(value.invert)) + case zio.prelude.Validation.succeed(value) => EitherDiff(zio.prelude.Validation.succeed(value.invert)) } } - final case class Transform[A, B](patch: Patch[A], f: A => Either[String, B], g: B => Either[String, A]) + final case class Transform[A, B](patch: Patch[A], f: A => Validation[String, B], g: B => Validation[String, A]) extends Patch[B] { override def isIdentical: Boolean = patch.isIdentical override def isComparable: Boolean = patch.isComparable - override def patch(input: B): Either[String, B] = + override def patch(input: B): Validation[String, B] = for { a <- g(input) a1 <- patch.patch(a) @@ -283,11 +276,11 @@ object Patch { } /** - * Represents diff between incomparable values. For instance Left(1) and Right("a") + * Represents diff between incomparable values. For instance Left(1) and zio.prelude.Validation.succeed("a") */ final case class NotComparable[A]() extends Patch[A] { - override def patch(input: A): Either[String, A] = - Left(s"Non-comparable diff cannot be applied") + override def patch(input: A): Validation[String, A] = + Validation.fail(s"Non-comparable diff cannot be applied") override def isComparable: Boolean = false @@ -297,7 +290,8 @@ object Patch { final case class SchemaMigration(migrations: Chunk[Migration]) extends Patch[Schema[_]] { self => //TODO Probably need to implement this - override def patch(input: Schema[_]): Either[String, Schema[_]] = Left(s"Schema migrations cannot be applied") + override def patch(input: Schema[_]): Validation[String, Schema[_]] = + Validation.fail(s"Schema migrations cannot be applied") def orIdentical: Patch[Schema[_]] = if (migrations.isEmpty) Patch.identical @@ -316,7 +310,7 @@ object Patch { override def isComparable: Boolean = differences.forall(_._2.isComparable) - override def patch(input: R): Either[String, R] = { + override def patch(input: R): Validation[String, R] = { val structure = schema.fields val patchedDynamicValue = schema.toDynamic(input) match { @@ -329,7 +323,7 @@ object Patch { case (Some(schema: Schema[b]), Some(oldValue)) => val oldVal = oldValue.toTypedValue(schema) oldVal - .flatMap(v => Validation.fromEither(diff.asInstanceOf[Patch[Any]].patch(v))) + .flatMap(v => diff.asInstanceOf[Patch[Any]].patch(v)) .map(v => schema.asInstanceOf[Schema[Any]].toDynamic(v)) .map(newValue => key -> newValue) case _ => @@ -344,8 +338,7 @@ object Patch { patchedDynamicValue.flatMap { newValues => Validation.fromEither(schema.fromDynamic(DynamicValue.Record(newValues._1, newValues._2))) - }.toEither.left - .map(_.toString()) + } } def orIdentical: Patch[R] = 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 fd3157ebf..422bea2d3 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Schema.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Schema.scala @@ -2,14 +2,12 @@ package zio.schema import java.net.{ URI, URL } import java.time.temporal.ChronoUnit - import scala.annotation.tailrec import scala.collection.immutable.ListMap - import zio.schema.internal.SourceLocation import zio.schema.meta._ import zio.schema.validation._ -import zio.{ Chunk, Unsafe } +import zio.{ Chunk, Unsafe, prelude } /** * A `Schema[A]` describes the structure of some data type `A`, in terms of case classes, @@ -48,12 +46,12 @@ sealed trait Schema[A] { /** * A symbolic operator for [[orElseEither]]. */ - def <+>[B](that: Schema[B]): Schema[scala.util.Either[A, B]] = self.orElseEither(that) + def <+>[B](that: Schema[B]): Schema[zio.prelude.Validation[A, B]] = self.orElseEither(that) /** * The default value for a `Schema` of type `A`. */ - def defaultValue: scala.util.Either[String, A] + def defaultValue: zio.prelude.Validation[String, A] /** * Chunk of annotations for this schema @@ -73,7 +71,7 @@ sealed trait Schema[A] { * This can be used to e.g convert between a case class and it's * "generic" representation as a ListMap[String,_] */ - def coerce[B](newSchema: Schema[B]): Either[String, Schema[B]] = + def coerce[B](newSchema: Schema[B]): zio.prelude.Validation[String, Schema[B]] = for { f <- self.migrate(newSchema) g <- newSchema.migrate(self) @@ -89,17 +87,17 @@ sealed trait Schema[A] { /** * Patch value with a Patch. */ - def patch(oldValue: A, diff: Patch[A]): scala.util.Either[String, A] = diff.patch(oldValue) + def patch(oldValue: A, diff: Patch[A]): prelude.Validation[String, A] = diff.patch(oldValue) - def fromDynamic(value: DynamicValue): scala.util.Either[String, A] = - value.toTypedValue(self).toEither.left.map(_.toString) + def fromDynamic(value: DynamicValue): zio.prelude.Validation[String, A] = + value.toTypedValue(self) def makeAccessors(b: AccessorBuilder): Accessors[b.Lens, b.Prism, b.Traversal] /** * Generate a homomorphism from A to B iff A and B are homomorphic */ - def migrate[B](newSchema: Schema[B]): Either[String, A => scala.util.Either[String, B]] = + def migrate[B](newSchema: Schema[B]): zio.prelude.Validation[String, A => zio.prelude.Validation[String, B]] = Migration.derive(MetaSchema.fromSchema(self), MetaSchema.fromSchema(newSchema)).map { transforms => (a: A) => self.toDynamic(a).transform(transforms).flatMap(newSchema.fromDynamic) } @@ -125,7 +123,7 @@ sealed trait Schema[A] { .asInstanceOf[Schema[Schema[_]]] .transformOrFail( s => s.coerce(self), - s => Right(s.ast.toSchema) + s => zio.prelude.Validation.succeed(s.ast.toSchema) ) def toDynamic(value: A): DynamicValue = @@ -136,13 +134,19 @@ sealed trait Schema[A] { * between `A` and `B`, without possibility of failure. */ def transform[B](f: A => B, g: B => A)(implicit loc: SourceLocation): Schema[B] = - Schema.Transform[A, B, SourceLocation](self, a => Right(f(a)), b => Right(g(b)), annotations, loc) + Schema.Transform[A, B, SourceLocation]( + self, + a => prelude.Validation.succeed(f(a)), + b => prelude.Validation.succeed(g(b)), + annotations, + loc + ) /** * Transforms this `Schema[A]` into a `Schema[B]`, by supplying two functions that can transform * between `A` and `B` (possibly failing in some cases). */ - def transformOrFail[B](f: A => scala.util.Either[String, B], g: B => scala.util.Either[String, A])( + def transformOrFail[B](f: A => prelude.Validation[String, B], g: B => prelude.Validation[String, A])( implicit loc: SourceLocation ): Schema[B] = Schema.Transform[A, B, SourceLocation](self, f, g, annotations, loc) @@ -194,8 +198,8 @@ object Schema extends SchemaEquality { toChunk(value).flatMap(value => loop(value, schema)) case Transform(schema, _, g, _, _) => g(value) match { - case Right(value) => loop(value, schema) - case Left(error) => Chunk(ValidationError.Generic(error)) + case zio.prelude.Validation.succeed(value) => loop(value, schema) + case Left(error) => Chunk(ValidationError.Generic(error)) } case Primitive(_, _) => Chunk.empty case optional @ Optional(schema, _) => @@ -234,9 +238,9 @@ object Schema extends SchemaEquality { } .reverse case either @ Schema.Either(left, right, _) => - value.asInstanceOf[scala.util.Either[either.LeftType, either.RightType]] match { - case Left(value) => loop(value, left) - case Right(value) => loop(value, right) + value.asInstanceOf[zio.prelude.Validation[either.LeftType, either.RightType]] match { + case Left(value) => loop(value, left) + case zio.prelude.Validation.succeed(value) => loop(value, right) } case Dynamic(_) => Chunk.empty case Fail(_, _) => Chunk.empty @@ -250,34 +254,34 @@ object Schema extends SchemaEquality { implicit val chronoUnit: Schema[ChronoUnit] = Schema[String].transformOrFail( { - case "SECONDS" => Right(ChronoUnit.SECONDS) - case "CENTURIES" => Right(ChronoUnit.CENTURIES) - case "DAYS" => Right(ChronoUnit.DAYS) - case "DECADES" => Right(ChronoUnit.DECADES) - case "FOREVER" => Right(ChronoUnit.FOREVER) - case "HOURS" => Right(ChronoUnit.HOURS) - case "MICROS" => Right(ChronoUnit.MICROS) - case "MILLIS" => Right(ChronoUnit.MILLIS) - case "MINUTES" => Right(ChronoUnit.MINUTES) - case "MONTHS" => Right(ChronoUnit.MONTHS) - case "NANOS" => Right(ChronoUnit.NANOS) - case "WEEKS" => Right(ChronoUnit.WEEKS) - case "YEARS" => Right(ChronoUnit.YEARS) + case "SECONDS" => zio.prelude.Validation.succeed(ChronoUnit.SECONDS) + case "CENTURIES" => zio.prelude.Validation.succeed(ChronoUnit.CENTURIES) + case "DAYS" => zio.prelude.Validation.succeed(ChronoUnit.DAYS) + case "DECADES" => zio.prelude.Validation.succeed(ChronoUnit.DECADES) + case "FOREVER" => zio.prelude.Validation.succeed(ChronoUnit.FOREVER) + case "HOURS" => zio.prelude.Validation.succeed(ChronoUnit.HOURS) + case "MICROS" => zio.prelude.Validation.succeed(ChronoUnit.MICROS) + case "MILLIS" => zio.prelude.Validation.succeed(ChronoUnit.MILLIS) + case "MINUTES" => zio.prelude.Validation.succeed(ChronoUnit.MINUTES) + case "MONTHS" => zio.prelude.Validation.succeed(ChronoUnit.MONTHS) + case "NANOS" => zio.prelude.Validation.succeed(ChronoUnit.NANOS) + case "WEEKS" => zio.prelude.Validation.succeed(ChronoUnit.WEEKS) + case "YEARS" => zio.prelude.Validation.succeed(ChronoUnit.YEARS) case _ => Left("Failed") }, { - case ChronoUnit.SECONDS => Right("SECONDS") - case ChronoUnit.CENTURIES => Right("CENTURIES") - case ChronoUnit.DAYS => Right("DAYS") - case ChronoUnit.DECADES => Right("DECADES") - case ChronoUnit.FOREVER => Right("FOREVER") - case ChronoUnit.HOURS => Right("HOURS") - case ChronoUnit.MICROS => Right("MICROS") - case ChronoUnit.MILLIS => Right("MILLIS") - case ChronoUnit.MINUTES => Right("MINUTES") - case ChronoUnit.MONTHS => Right("MONTHS") - case ChronoUnit.NANOS => Right("NANOS") - case ChronoUnit.WEEKS => Right("WEEKS") - case ChronoUnit.YEARS => Right("YEARS") + case ChronoUnit.SECONDS => zio.prelude.Validation.succeed("SECONDS") + case ChronoUnit.CENTURIES => zio.prelude.Validation.succeed("CENTURIES") + case ChronoUnit.DAYS => zio.prelude.Validation.succeed("DAYS") + case ChronoUnit.DECADES => zio.prelude.Validation.succeed("DECADES") + case ChronoUnit.FOREVER => zio.prelude.Validation.succeed("FOREVER") + case ChronoUnit.HOURS => zio.prelude.Validation.succeed("HOURS") + case ChronoUnit.MICROS => zio.prelude.Validation.succeed("MICROS") + case ChronoUnit.MILLIS => zio.prelude.Validation.succeed("MILLIS") + case ChronoUnit.MINUTES => zio.prelude.Validation.succeed("MINUTES") + case ChronoUnit.MONTHS => zio.prelude.Validation.succeed("MONTHS") + case ChronoUnit.NANOS => zio.prelude.Validation.succeed("NANOS") + case ChronoUnit.WEEKS => zio.prelude.Validation.succeed("WEEKS") + case ChronoUnit.YEARS => zio.prelude.Validation.succeed("YEARS") case _ => Left("Failed") } ) @@ -317,9 +321,9 @@ object Schema extends SchemaEquality { Schema[String].transformOrFail( string => try { - Right(new URL(string)) + zio.prelude.Validation.succeed(new URL(string)) } catch { case _: Exception => Left(s"Invalid URL: $string") }, - url => Right(url.toString) + url => zio.prelude.Validation.succeed(url.toString) ) implicit def schemaSchema[A]: Schema[Schema[A]] = Schema[MetaSchema].transform( @@ -331,9 +335,9 @@ object Schema extends SchemaEquality { Schema[String].transformOrFail( string => try { - Right(new URI(string)) + zio.prelude.Validation.succeed(new URI(string)) } catch { case _: Exception => Left(s"Invalid URI: $string") }, - uri => Right(uri.toString) + uri => zio.prelude.Validation.succeed(uri.toString) ) implicit def standardSchema[A]: Schema[StandardType[A]] = Schema[String].transformOrFail[StandardType[A]]( @@ -341,8 +345,11 @@ object Schema extends SchemaEquality { StandardType .fromString(string) .asInstanceOf[Option[StandardType[A]]] - .toRight(s"Invalid StandardType tag ${string}"), - standardType => Right(standardType.tag) + .tozio + .prelude + .Validation + .succeed(s"Invalid StandardType tag ${string}"), + standardType => zio.prelude.Validation.succeed(standardType.tag) ) sealed trait Enum[Z] extends Schema[Z] { @@ -411,20 +418,24 @@ object Schema extends SchemaEquality { def fields: Chunk[Field[R, _]] - def construct(fieldValues: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, R] + def construct(fieldValues: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, R] def deconstruct(value: R)(implicit unsafe: Unsafe): Chunk[Any] def id: TypeId - def defaultValue: scala.util.Either[String, R] = + def defaultValue: zio.prelude.Validation[String, R] = Unsafe.unsafe { implicit unsafe => - self.fields - .map(_.schema.defaultValue) - .foldLeft[scala.util.Either[String, Chunk[R]]](Right(Chunk.empty)) { - case (e @ Left(_), _) => e - case (_, Left(e)) => Left[String, Chunk[R]](e) - case (Right(values), Right(value)) => Right[String, Chunk[R]](values :+ value.asInstanceOf[R]) + zio.prelude.Validation + .validateAll( + self.fields + .map(_.schema.defaultValue) + ) + .foldLeft[zio.prelude.Validation[String, Chunk[R]]](zio.prelude.Validation.succeed(Chunk.empty)) { + case (e @ Left(_), _) => e + case (_, Left(e)) => Left[String, Chunk[R]](e) + case (zio.prelude.Validation.succeed(values), zio.prelude.Validation.succeed(value)) => + Right[String, Chunk[R]](values :+ value.asInstanceOf[R]) } .flatMap(self.construct) } @@ -444,7 +455,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Sequence[Col, Elem, I] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Col] = + override def defaultValue: zio.prelude.Validation[String, Col] = elementSchema.defaultValue.map(fromChunk.compose(Chunk(_))) override def makeAccessors(b: AccessorBuilder): b.Traversal[Col, Elem] = b.makeTraversal(self, elementSchema) @@ -455,14 +466,14 @@ object Schema extends SchemaEquality { final case class Transform[A, B, I]( schema: Schema[A], - f: A => scala.util.Either[String, B], - g: B => scala.util.Either[String, A], + f: A => prelude.Validation[String, B], + g: B => prelude.Validation[String, A], annotations: Chunk[Any], identity: I ) extends Schema[B] { override type Accessors[Lens[_, _, _], Prism[_, _, _], Traversal[_, _]] = schema.Accessors[Lens, Prism, Traversal] - def defaultValue: scala.util.Either[String, B] = schema.defaultValue.flatMap(f) + def defaultValue: zio.prelude.Validation[String, B] = schema.defaultValue.flatMap(f) override def makeAccessors(b: AccessorBuilder): schema.Accessors[b.Lens, b.Prism, b.Traversal] = schema.makeAccessors(b) @@ -474,8 +485,8 @@ object Schema extends SchemaEquality { .fromSchema(schema) .asInstanceOf[Schema[Schema[_]]] .transformOrFail( - s => s.coerce(schema).flatMap(s1 => Right(s1.transformOrFail(f, g))), - s => Right(s.transformOrFail(g, f).ast.toSchema) + s => s.coerce(schema).flatMap(s1 => zio.prelude.Validation.succeed(s1.transformOrFail(f, g))), + s => zio.prelude.Validation.succeed(s.transformOrFail(g, f).ast.toSchema) ) override def toString: String = s"Transform($schema, $identity)" @@ -488,7 +499,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Primitive[A] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, A] = standardType.defaultValue + override def defaultValue: zio.prelude.Validation[String, A] = standardType.defaultValue override def makeAccessors(b: AccessorBuilder): Unit = () } @@ -529,7 +540,7 @@ object Schema extends SchemaEquality { Chunk.empty ) - def defaultValue: scala.util.Either[String, Option[A]] = Right(None) + def defaultValue: zio.prelude.Validation[String, Option[A]] = zio.prelude.Validation.succeed(None) override def makeAccessors( b: AccessorBuilder @@ -543,7 +554,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Fail[A] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, A] = Left(message) + override def defaultValue: zio.prelude.Validation[String, A] = Left(message) override def makeAccessors(b: AccessorBuilder): Unit = () } @@ -567,7 +578,7 @@ object Schema extends SchemaEquality { annotations ) - override def defaultValue: scala.util.Either[String, (A, B)] = + override def defaultValue: zio.prelude.Validation[String, (A, B)] = left.defaultValue.flatMap(a => right.defaultValue.map(b => (a, b))) override def makeAccessors(b: AccessorBuilder): (b.Lens[first.type, (A, B), A], b.Lens[second.type, (A, B), B]) = @@ -644,7 +655,7 @@ object Schema extends SchemaEquality { lazy val schema: Schema[A] = schema0() - def defaultValue: scala.util.Either[String, A] = schema.defaultValue + def defaultValue: zio.prelude.Validation[String, A] = schema.defaultValue override def makeAccessors(b: AccessorBuilder): schema.Accessors[b.Lens, b.Prism, b.Traversal] = schema.makeAccessors(b) @@ -665,7 +676,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Map[K, V] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, scala.collection.immutable.Map[K, V]] = + override def defaultValue: zio.prelude.Validation[String, scala.collection.immutable.Map[K, V]] = keySchema.defaultValue.flatMap( defaultKey => valueSchema.defaultValue.map(defaultValue => scala.collection.immutable.Map(defaultKey -> defaultValue)) @@ -686,7 +697,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Set[A] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, scala.collection.immutable.Set[A]] = + override def defaultValue: zio.prelude.Validation[String, scala.collection.immutable.Set[A]] = elementSchema.defaultValue.map(scala.collection.immutable.Set(_)) override def makeAccessors(b: AccessorBuilder): b.Traversal[scala.collection.immutable.Set[A], A] = @@ -701,8 +712,8 @@ object Schema extends SchemaEquality { /** * The default value for a `Schema` of type `A`. */ - override def defaultValue: scala.util.Either[String, DynamicValue] = - Right(DynamicValue.NoneValue) + override def defaultValue: zio.prelude.Validation[String, DynamicValue] = + zio.prelude.Validation.succeed(DynamicValue.NoneValue) /** * Returns a new schema that with `annotation` @@ -738,7 +749,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum1[A, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): b.Prism[case1.id.type, Z, A] = b.makePrism(self, case1) @@ -758,7 +769,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum2[A1, A2, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): (b.Prism[case1.id.type, Z, A1], b.Prism[case2.id.type, Z, A2]) = (b.makePrism(self, case1), b.makePrism(self, case2)) @@ -779,7 +790,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum3[A1, A2, A3, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors( b: AccessorBuilder @@ -808,7 +819,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum4[A1, A2, A3, A4, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -842,7 +853,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum5[A1, A2, A3, A4, A5, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors( b: AccessorBuilder @@ -888,7 +899,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum6[A1, A2, A3, A4, A5, A6, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors( b: AccessorBuilder @@ -938,7 +949,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum7[A1, A2, A3, A4, A5, A6, A7, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -990,7 +1001,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum8[A1, A2, A3, A4, A5, A6, A7, A8, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1045,7 +1056,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum9[A1, A2, A3, A4, A5, A6, A7, A8, A9, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1104,7 +1115,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1180,7 +1191,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1262,7 +1273,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1361,7 +1372,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum13[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1466,7 +1477,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum14[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1579,7 +1590,7 @@ object Schema extends SchemaEquality { ): Enum15[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1698,7 +1709,7 @@ object Schema extends SchemaEquality { ): Enum16[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1823,7 +1834,7 @@ object Schema extends SchemaEquality { ): Enum17[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1954,7 +1965,7 @@ object Schema extends SchemaEquality { ): Enum18[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -2091,7 +2102,7 @@ object Schema extends SchemaEquality { ): Enum19[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -2234,7 +2245,7 @@ object Schema extends SchemaEquality { ): Enum20[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -2383,7 +2394,7 @@ object Schema extends SchemaEquality { ): Enum21[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors( b: AccessorBuilder @@ -2540,7 +2551,7 @@ object Schema extends SchemaEquality { ): Enum22[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: scala.util.Either[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors( b: AccessorBuilder @@ -2629,11 +2640,11 @@ object Schema extends SchemaEquality { override def cases: Chunk[Case[Z, _]] = Chunk(caseSet.toSeq: _*) - def defaultValue: scala.util.Either[String, Z] = + def defaultValue: zio.prelude.Validation[String, Z] = if (caseSet.toSeq.isEmpty) Left("cannot access default value for enum with no members") else - caseSet.toSeq.head.schema.defaultValue.asInstanceOf[scala.util.Either[String, Z]] + caseSet.toSeq.head.schema.defaultValue.asInstanceOf[zio.prelude.Validation[String, Z]] override def makeAccessors(b: AccessorBuilder): caseSet.Accessors[Z, b.Lens, b.Prism, b.Traversal] = caseSet.makeAccessors(self, b) @@ -3311,9 +3322,11 @@ object Schema extends SchemaEquality { override def fields: Chunk[Schema.Field[ListMap[String, _], _]] = fieldSet.toChunk - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, ListMap[String, _]] = + override def construct( + values: Chunk[Any] + )(implicit unsafe: Unsafe): zio.prelude.Validation[String, ListMap[String, _]] = if (values.size == fields.size) - Right(ListMap(fields.map(_.name).zip(values): _*)) + zio.prelude.Validation.succeed(ListMap(fields.map(_.name).zip(values): _*)) else Left(s"wrong number of values for $fields") @@ -3340,10 +3353,10 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk.empty - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.isEmpty) try { - Right(defaultConstruct()) + zio.prelude.Validation.succeed(defaultConstruct()) } catch { case _: Throwable => Left("invalid type in values") } else @@ -3391,10 +3404,10 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 1) try { - Right(defaultConstruct(values(0).asInstanceOf[A])) + zio.prelude.Validation.succeed(defaultConstruct(values(0).asInstanceOf[A])) } catch { case _: Throwable => Left("invalid type in values") } else @@ -3458,10 +3471,10 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 2) try { - Right(construct(values(0).asInstanceOf[A1], values(1).asInstanceOf[A2])) + zio.prelude.Validation.succeed(construct(values(0).asInstanceOf[A1], values(1).asInstanceOf[A2])) } catch { case _: Throwable => Left("invalid type in values") } else @@ -3538,10 +3551,11 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 3) try { - Right(construct(values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], values(2).asInstanceOf[A3])) + zio.prelude.Validation + .succeed(construct(values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], values(2).asInstanceOf[A3])) } catch { case _: Throwable => Left("invalid type in values") } else @@ -3633,10 +3647,10 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 4) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -3753,10 +3767,10 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4, field5) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 5) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -3906,10 +3920,10 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4, field5, field6) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 6) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -4079,10 +4093,10 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4, field5, field6, field7) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 7) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -4285,10 +4299,10 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4, field5, field6, field7, field8) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 8) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -4508,10 +4522,10 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4, field5, field6, field7, field8, field9) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 9) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -4769,10 +4783,10 @@ object Schema extends SchemaEquality { field10 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 10) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -5052,10 +5066,10 @@ object Schema extends SchemaEquality { field11 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 11) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -5354,10 +5368,10 @@ object Schema extends SchemaEquality { field12 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 12) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -5675,10 +5689,10 @@ object Schema extends SchemaEquality { field13 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 13) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -6015,10 +6029,10 @@ object Schema extends SchemaEquality { field14 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 14) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -6375,10 +6389,10 @@ object Schema extends SchemaEquality { field15 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 15) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -6756,10 +6770,10 @@ object Schema extends SchemaEquality { field16 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 16) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -7156,10 +7170,10 @@ object Schema extends SchemaEquality { field17 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 17) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -7575,10 +7589,10 @@ object Schema extends SchemaEquality { field18 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 18) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -8015,10 +8029,10 @@ object Schema extends SchemaEquality { field19 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 19) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -8474,10 +8488,10 @@ object Schema extends SchemaEquality { field20 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 20) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -8973,10 +8987,10 @@ object Schema extends SchemaEquality { field21 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 21) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], @@ -9538,10 +9552,10 @@ object Schema extends SchemaEquality { field22 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): scala.util.Either[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = if (values.size == 22) try { - Right( + zio.prelude.Validation.succeed( construct( values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], diff --git a/zio-schema/shared/src/main/scala/zio/schema/SchemaEquality.scala b/zio-schema/shared/src/main/scala/zio/schema/SchemaEquality.scala index f30e43402..83b2d61a6 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/SchemaEquality.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/SchemaEquality.scala @@ -66,7 +66,7 @@ trait SchemaEquality { lTuple.annotations == rTuple.annotations && lTuple.left === rTuple.left && rTuple.right === rTuple.right - case (lEither: Schema.Either[_, _], rEither: Schema.Either[_, _]) => + case (lEither: Schema.zio.prelude.Validation[_, _], rEither: Schema.zio.prelude.Validation[_, _]) => lEither.annotations == rEither.annotations && lEither.left === rEither.left && lEither.right === rEither.right diff --git a/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala b/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala index 1a403cd78..54c17c336 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala @@ -8,7 +8,7 @@ import zio.prelude.Validation sealed trait StandardType[A] extends Ordering[A] { self => def tag: String - def defaultValue: Either[String, A] + def defaultValue: zio.prelude.Validation[String, A] override def toString: String = tag /** @@ -90,63 +90,66 @@ object StandardType { def apply[A](implicit standardType: StandardType[A]): StandardType[A] = standardType implicit object UnitType extends StandardType[Unit] { - override def tag: String = Tags.UNIT - override def compare(x: Unit, y: Unit): Int = 0 - override def defaultValue: Either[String, Unit] = Right(()) + override def tag: String = Tags.UNIT + override def compare(x: Unit, y: Unit): Int = 0 + override def defaultValue: zio.prelude.Validation[String, Unit] = zio.prelude.Validation.succeed(()) } implicit object StringType extends StandardType[String] { - override def tag: String = Tags.STRING - override def compare(x: String, y: String): Int = x.compareTo(y) - override def defaultValue: Either[String, String] = Right("") + override def tag: String = Tags.STRING + override def compare(x: String, y: String): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, String] = zio.prelude.Validation.succeed("") } implicit object BoolType extends StandardType[Boolean] { - override def tag: String = Tags.BOOL - override def compare(x: Boolean, y: Boolean): Int = x.compareTo(y) - override def defaultValue: Either[String, Boolean] = Right(false) + override def tag: String = Tags.BOOL + override def compare(x: Boolean, y: Boolean): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, Boolean] = zio.prelude.Validation.succeed(false) } implicit object ByteType extends StandardType[Byte] { - override def tag: String = Tags.BYTE - override def compare(x: Byte, y: Byte): Int = x.compareTo(y) - override def defaultValue: Either[String, Byte] = Right(0.toByte) + override def tag: String = Tags.BYTE + override def compare(x: Byte, y: Byte): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, Byte] = zio.prelude.Validation.succeed(0.toByte) } implicit object ShortType extends StandardType[Short] { - override def tag: String = Tags.SHORT - override def compare(x: Short, y: Short): Int = x.compareTo(y) - override def defaultValue: Either[String, Short] = Right(0.asInstanceOf[Short]) + override def tag: String = Tags.SHORT + override def compare(x: Short, y: Short): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, Short] = + zio.prelude.Validation.succeed(0.asInstanceOf[Short]) } implicit object IntType extends StandardType[Int] { - override def tag: String = Tags.INT - override def compare(x: Int, y: Int): Int = x.compareTo(y) - override def defaultValue: Either[String, Int] = Right(0) + override def tag: String = Tags.INT + override def compare(x: Int, y: Int): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, Int] = zio.prelude.Validation.succeed(0) } implicit object LongType extends StandardType[Long] { - override def tag: String = Tags.LONG - override def compare(x: Long, y: Long): Int = x.compareTo(y) - override def defaultValue: Either[String, Long] = Right(0.asInstanceOf[Long]) + override def tag: String = Tags.LONG + override def compare(x: Long, y: Long): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, Long] = + zio.prelude.Validation.succeed(0.asInstanceOf[Long]) } implicit object FloatType extends StandardType[Float] { - override def tag: String = Tags.FLOAT - override def compare(x: Float, y: Float): Int = x.compareTo(y) - override def defaultValue: Either[String, Float] = Right(0.0.asInstanceOf[Float]) + override def tag: String = Tags.FLOAT + override def compare(x: Float, y: Float): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, Float] = + zio.prelude.Validation.succeed(0.0.asInstanceOf[Float]) } implicit object DoubleType extends StandardType[Double] { - override def tag: String = Tags.DOUBLE - override def compare(x: Double, y: Double): Int = x.compareTo(y) - override def defaultValue: Either[String, Double] = Right(0.0) + override def tag: String = Tags.DOUBLE + override def compare(x: Double, y: Double): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, Double] = zio.prelude.Validation.succeed(0.0) } implicit object BinaryType extends StandardType[Chunk[Byte]] { - override def tag: String = Tags.BINARY - override def compare(x: Chunk[Byte], y: Chunk[Byte]): Int = x.sum.compare(y.sum) - override def defaultValue: Either[String, Chunk[Byte]] = Right(Chunk.empty) + override def tag: String = Tags.BINARY + override def compare(x: Chunk[Byte], y: Chunk[Byte]): Int = x.sum.compare(y.sum) + override def defaultValue: zio.prelude.Validation[String, Chunk[Byte]] = zio.prelude.Validation.succeed(Chunk.empty) } implicit object CharType extends StandardType[Char] { @@ -154,46 +157,50 @@ object StandardType { override def compare(x: Char, y: Char): Int = x.compareTo(y) // The NUL Unicode character is used as the default value for // `StandardType[Char]` because the empty Char '' does not compile - override def defaultValue: Either[String, Char] = Right('\u0000') + override def defaultValue: zio.prelude.Validation[String, Char] = zio.prelude.Validation.succeed('\u0000') } implicit object UUIDType extends StandardType[java.util.UUID] { override def tag: String = Tags.UUID override def compare(x: java.util.UUID, y: java.util.UUID): Int = x.compareTo(y) - override def defaultValue: Either[String, java.util.UUID] = Right(java.util.UUID.randomUUID()) + override def defaultValue: zio.prelude.Validation[String, java.util.UUID] = + zio.prelude.Validation.succeed(java.util.UUID.randomUUID()) } implicit object BigDecimalType extends StandardType[java.math.BigDecimal] { override def tag: String = Tags.BIG_DECIMAL override def compare(x: java.math.BigDecimal, y: java.math.BigDecimal): Int = x.compareTo(y) - override def defaultValue: Either[String, java.math.BigDecimal] = Right(java.math.BigDecimal.ZERO) + override def defaultValue: zio.prelude.Validation[String, java.math.BigDecimal] = + zio.prelude.Validation.succeed(java.math.BigDecimal.ZERO) } implicit object BigIntegerType extends StandardType[java.math.BigInteger] { - override def tag: String = Tags.BIG_INTEGER - override def compare(x: BigInteger, y: BigInteger): Int = x.compareTo(y) - override def defaultValue: Either[String, java.math.BigInteger] = Right(java.math.BigInteger.ZERO) + override def tag: String = Tags.BIG_INTEGER + override def compare(x: BigInteger, y: BigInteger): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, java.math.BigInteger] = + zio.prelude.Validation.succeed(java.math.BigInteger.ZERO) } //java.time specific types implicit object DayOfWeekType extends StandardType[DayOfWeek] { override def tag: String = Tags.DAY_OF_WEEK override def compare(x: DayOfWeek, y: DayOfWeek): Int = x.getValue.compareTo(y.getValue) - override def defaultValue: Either[String, DayOfWeek] = - Right(java.time.temporal.WeekFields.of(java.util.Locale.getDefault).getFirstDayOfWeek) + override def defaultValue: zio.prelude.Validation[String, DayOfWeek] = + zio.prelude.Validation.succeed(java.time.temporal.WeekFields.of(java.util.Locale.getDefault).getFirstDayOfWeek) } implicit object MonthType extends StandardType[java.time.Month] { - override def tag: String = Tags.MONTH - override def compare(x: Month, y: Month): Int = x.getValue.compareTo(y.getValue) - override def defaultValue: Either[String, java.time.Month] = Right(java.time.Month.JANUARY) + override def tag: String = Tags.MONTH + override def compare(x: Month, y: Month): Int = x.getValue.compareTo(y.getValue) + override def defaultValue: zio.prelude.Validation[String, java.time.Month] = + Validation.succeed(java.time.Month.JANUARY) } implicit object MonthDayType extends StandardType[java.time.MonthDay] { override def tag: String = Tags.MONTH_DAY override def compare(x: MonthDay, y: MonthDay): Int = x.compareTo(y) - override def defaultValue: Either[String, java.time.MonthDay] = - Right(java.time.MonthDay.of(java.time.Month.JANUARY, 1)) + override def defaultValue: zio.prelude.Validation[String, java.time.MonthDay] = + zio.prelude.Validation.succeed(java.time.MonthDay.of(java.time.Month.JANUARY, 1)) } implicit object PeriodType extends StandardType[java.time.Period] { @@ -202,43 +209,50 @@ object StandardType { val startDate = time.LocalDate.of(0, 1, 1) startDate.plus(x).compareTo(startDate.plus(y)) } - override def defaultValue: Either[String, java.time.Period] = Right(java.time.Period.ZERO) + override def defaultValue: zio.prelude.Validation[String, java.time.Period] = + zio.prelude.Validation.succeed(java.time.Period.ZERO) } implicit object YearType extends StandardType[java.time.Year] { - override def tag: String = Tags.YEAR - override def compare(x: Year, y: Year): Int = x.getValue.compareTo(y.getValue) - override def defaultValue: Either[String, java.time.Year] = Right(java.time.Year.now) + override def tag: String = Tags.YEAR + override def compare(x: Year, y: Year): Int = x.getValue.compareTo(y.getValue) + override def defaultValue: zio.prelude.Validation[String, java.time.Year] = + zio.prelude.Validation.succeed(java.time.Year.now) } implicit object YearMonthType extends StandardType[java.time.YearMonth] { - override def tag: String = Tags.YEAR_MONTH - override def compare(x: YearMonth, y: YearMonth): Int = x.compareTo(y) - override def defaultValue: Either[String, java.time.YearMonth] = Right(java.time.YearMonth.now) + override def tag: String = Tags.YEAR_MONTH + override def compare(x: YearMonth, y: YearMonth): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, java.time.YearMonth] = + zio.prelude.Validation.succeed(java.time.YearMonth.now) } implicit object ZoneIdType extends StandardType[java.time.ZoneId] { - override def tag: String = Tags.ZONE_ID - override def compare(x: ZoneId, y: ZoneId): Int = x.getId.compareTo(y.getId) // TODO is there a better comparison - override def defaultValue: Either[String, java.time.ZoneId] = Right(java.time.ZoneId.systemDefault) + override def tag: String = Tags.ZONE_ID + override def compare(x: ZoneId, y: ZoneId): Int = x.getId.compareTo(y.getId) // TODO is there a better comparison + override def defaultValue: zio.prelude.Validation[String, java.time.ZoneId] = + zio.prelude.Validation.succeed(java.time.ZoneId.systemDefault) } implicit object ZoneOffsetType extends StandardType[java.time.ZoneOffset] { - override def tag: String = Tags.ZONE_OFFSET - override def compare(x: ZoneOffset, y: ZoneOffset): Int = x.compareTo(y) - override def defaultValue: Either[String, java.time.ZoneOffset] = Right(java.time.ZoneOffset.UTC) + override def tag: String = Tags.ZONE_OFFSET + override def compare(x: ZoneOffset, y: ZoneOffset): Int = x.compareTo(y) + override def defaultValue: zio.prelude.Validation[String, java.time.ZoneOffset] = + zio.prelude.Validation.succeed(java.time.ZoneOffset.UTC) } implicit object DurationType extends StandardType[java.time.Duration] { override def tag: String = Tags.DURATION override def compare(x: time.Duration, y: time.Duration): Int = x.compareTo(y) - override def defaultValue: Either[String, java.time.Duration] = Right(java.time.Duration.ZERO) + override def defaultValue: zio.prelude.Validation[String, java.time.Duration] = + zio.prelude.Validation.succeed(java.time.Duration.ZERO) } implicit object InstantType extends StandardType[java.time.Instant] { override def tag: String = Tags.INSTANT - override def defaultValue: Either[String, Instant] = Right(java.time.Instant.EPOCH) + override def defaultValue: zio.prelude.Validation[String, Instant] = + zio.prelude.Validation.succeed(java.time.Instant.EPOCH) override def compare(x: Instant, y: Instant): Int = x.compareTo(y) } @@ -246,7 +260,8 @@ object StandardType { implicit object LocalDateType extends StandardType[java.time.LocalDate] { override def tag: String = Tags.LOCAL_DATE - override def defaultValue: Either[String, LocalDate] = Right(java.time.LocalDate.now) + override def defaultValue: zio.prelude.Validation[String, LocalDate] = + zio.prelude.Validation.succeed(java.time.LocalDate.now) override def compare(x: LocalDate, y: LocalDate): Int = x.compareTo(y) } @@ -254,7 +269,8 @@ object StandardType { implicit object LocalTimeType extends StandardType[java.time.LocalTime] { override def tag: String = Tags.LOCAL_TIME - override def defaultValue: Either[String, LocalTime] = Right(java.time.LocalTime.MIDNIGHT) + override def defaultValue: zio.prelude.Validation[String, LocalTime] = + zio.prelude.Validation.succeed(java.time.LocalTime.MIDNIGHT) override def compare(x: LocalTime, y: LocalTime): Int = x.compareTo(y) } @@ -262,7 +278,8 @@ object StandardType { implicit object LocalDateTimeType extends StandardType[java.time.LocalDateTime] { override def tag: String = Tags.LOCAL_DATE_TIME - override def defaultValue: Either[String, LocalDateTime] = Right(java.time.LocalDateTime.now) + override def defaultValue: zio.prelude.Validation[String, LocalDateTime] = + zio.prelude.Validation.succeed(java.time.LocalDateTime.now) override def compare(x: LocalDateTime, y: LocalDateTime): Int = x.compareTo(y) } @@ -270,7 +287,8 @@ object StandardType { implicit object OffsetTimeType extends StandardType[java.time.OffsetTime] { override def tag: String = Tags.OFFSET_TIME - override def defaultValue: Either[String, OffsetTime] = Right(java.time.OffsetTime.now) + override def defaultValue: zio.prelude.Validation[String, OffsetTime] = + zio.prelude.Validation.succeed(java.time.OffsetTime.now) override def compare(x: OffsetTime, y: OffsetTime): Int = x.compareTo(y) } @@ -278,7 +296,8 @@ object StandardType { implicit object OffsetDateTimeType extends StandardType[java.time.OffsetDateTime] { override def tag: String = Tags.OFFSET_DATE_TIME - override def defaultValue: Either[String, OffsetDateTime] = Right(java.time.OffsetDateTime.now) + override def defaultValue: zio.prelude.Validation[String, OffsetDateTime] = + zio.prelude.Validation.succeed(java.time.OffsetDateTime.now) override def compare(x: OffsetDateTime, y: OffsetDateTime): Int = x.compareTo(y) } @@ -286,7 +305,8 @@ object StandardType { implicit object ZonedDateTimeType extends StandardType[java.time.ZonedDateTime] { override def tag: String = Tags.ZONED_DATE_TIME - override def defaultValue: Either[String, ZonedDateTime] = Right(java.time.ZonedDateTime.now) + override def defaultValue: zio.prelude.Validation[String, ZonedDateTime] = + zio.prelude.Validation.succeed(java.time.ZonedDateTime.now) override def compare(x: ZonedDateTime, y: ZonedDateTime): Int = x.compareTo(y) } diff --git a/zio-schema/shared/src/main/scala/zio/schema/codec/BinaryCodecs.scala b/zio-schema/shared/src/main/scala/zio/schema/codec/BinaryCodecs.scala index c57ef9c88..89b1c26fe 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/codec/BinaryCodecs.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/codec/BinaryCodecs.scala @@ -32,7 +32,7 @@ object BinaryCodecs { override def streamEncoder[T](implicit ev: IsElementOf[T, Types]): ZPipeline[Any, Nothing, T, Byte] = instances.withInstance((codec: BinaryCodec[T]) => codec.streamEncoder) - override def decode[T](whole: Chunk[Byte])(implicit ev: IsElementOf[T, Types]): Either[DecodeError, T] = + override def decode[T](whole: Chunk[Byte])(implicit ev: IsElementOf[T, Types]): zio.prelude.Validation[DecodeError, T] = instances.withInstance((codec: BinaryCodec[T]) => codec.decode(whole)) override def streamDecoder[T](implicit ev: IsElementOf[T, Types]): ZPipeline[Any, DecodeError, Byte, T] = diff --git a/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala b/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala index db7e3a89b..5b45d7d38 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala @@ -22,7 +22,7 @@ import zio.stream.ZPipeline trait Codecs[Whole, Element, Types <: TypeList] { def encode[T](value: T)(implicit ev: T IsElementOf Types): Whole def streamEncoder[T](implicit ev: T IsElementOf Types): ZPipeline[Any, Nothing, T, Element] - def decode[T](whole: Whole)(implicit ev: T IsElementOf Types): Either[DecodeError, T] + def decode[T](whole: Whole)(implicit ev: T IsElementOf Types): zio.prelude.Validation[DecodeError, T] def streamDecoder[T](implicit ev: T IsElementOf Types): ZPipeline[Any, DecodeError, Element, T] } @@ -37,7 +37,7 @@ object Codecs { final override def streamEncoder[T](implicit ev: IsElementOf[T, Types]): ZPipeline[Any, Nothing, T, Element] = instances.withInstance((codec: Codec[Whole, Element, T]) => codec.streamEncoder) - final override def decode[T](whole: Whole)(implicit ev: IsElementOf[T, Types]): Either[DecodeError, T] = + final override def decode[T](whole: Whole)(implicit ev: IsElementOf[T, Types]): zio.prelude.Validation[DecodeError, T] = instances.withInstance((codec: Codec[Whole, Element, T]) => codec.decode(whole)) final override def streamDecoder[T](implicit ev: IsElementOf[T, Types]): ZPipeline[Any, DecodeError, Element, T] = diff --git a/zio-schema/shared/src/main/scala/zio/schema/codec/Decoder.scala b/zio-schema/shared/src/main/scala/zio/schema/codec/Decoder.scala index 03f13f42e..23edadf99 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/codec/Decoder.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/codec/Decoder.scala @@ -20,7 +20,7 @@ import zio.stream.ZPipeline trait Decoder[Whole, Element, +A] { - def decode(whole: Whole): Either[DecodeError, A] + def decode(whole: Whole): zio.prelude.Validation[DecodeError, A] def streamDecoder: ZPipeline[Any, DecodeError, Element, A] diff --git a/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala b/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala index 8560c79de..f4841df26 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala @@ -388,17 +388,17 @@ object ExtensibleMetaSchema { private def tupled[BuiltIn <: TypeList]( value: Value[BuiltIn] - ): scala.Either[String, (String, Chunk[String], Boolean)] = - Right((value.valueType.tag, value.path, value.optional)) + ): scala.zio.prelude.Validation[String, (String, Chunk[String], Boolean)] = + zio.prelude.Validation.succeed((value.valueType.tag, value.path, value.optional)) private def fromTuple[BuiltIn <: TypeList]( tuple: (String, Chunk[String], Boolean) - )(implicit builtInInstances: SchemaInstances[BuiltIn]): scala.Either[String, Value[BuiltIn]] = tuple match { + )(implicit builtInInstances: SchemaInstances[BuiltIn]): scala.zio.prelude.Validation[String, Value[BuiltIn]] = tuple match { case (s, path, optional) => StandardType .fromString(s) .map(typ => Value(typ, NodePath(path), optional)) - .toRight(s"unkown standard type $s") + .tozio.prelude.Validation.succeed(s"unkown standard type $s") } } final case class Ref[BuiltIn <: TypeList]( @@ -687,12 +687,12 @@ object ExtensibleMetaSchema { caseOf[Sum[BuiltIn], ExtensibleMetaSchema[BuiltIn]]("Sum")(_.asInstanceOf[Sum[BuiltIn]])( _.asInstanceOf[ExtensibleMetaSchema[BuiltIn]] )(_.isInstanceOf[Sum[BuiltIn]]) ++ - caseOf[Either[BuiltIn], ExtensibleMetaSchema[BuiltIn]]("Either")( - _.asInstanceOf[Either[BuiltIn]] + caseOf[zio.prelude.Validation[BuiltIn], ExtensibleMetaSchema[BuiltIn]]("Either")( + _.asInstanceOf[zio.prelude.Validation[BuiltIn]] )( _.asInstanceOf[ExtensibleMetaSchema[BuiltIn]] )( - _.isInstanceOf[Either[BuiltIn]] + _.isInstanceOf[zio.prelude.Validation[BuiltIn]] ) ++ caseOf[Product[BuiltIn], ExtensibleMetaSchema[BuiltIn]]("Product")( _.asInstanceOf[Product[BuiltIn]] diff --git a/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala b/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala index 908baae5a..7f359dc51 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala @@ -10,7 +10,7 @@ sealed trait Migration { self => def path: NodePath - def migrate(value: DynamicValue): Either[String, DynamicValue] = + def migrate(value: DynamicValue): zio.prelude.Validation[String, DynamicValue] = self match { case Migration.Require(path) => Migration.require(value, path.toList) case Migration.Optional(path) => Migration.makeOptional(value, path.toList) @@ -19,7 +19,7 @@ sealed trait Migration { self => s"Cannot change type of node at path ${path.render}: No type conversion is available" ) case Migration.DeleteNode(path) => Migration.deleteNode(value, path.toList) - case Migration.AddCase(_, _) => Right(value) + case Migration.AddCase(_, _) => zio.prelude.Validation.succeed(value) case Migration.AddNode(path, _) => Left(s"Cannot add node at path ${path.render}: No default value is available") case Migration.Relabel(path, transform) => Migration.relabel(value, path.toList, transform) @@ -58,28 +58,28 @@ object Migration { final case class Recursive(override val path: NodePath, relativeNodePath: NodePath, relativeMigration: Migration) extends Migration - def derive(from: MetaSchema, to: MetaSchema): Either[String, Chunk[Migration]] = { + def derive(from: MetaSchema, to: MetaSchema): zio.prelude.Validation[String, Chunk[Migration]] = { def go( acc: Chunk[Migration], path: NodePath, fromSubtree: MetaSchema, toSubtree: MetaSchema, ignoreRefs: Boolean - ): Either[String, Chunk[Migration]] = { + ): zio.prelude.Validation[String, Chunk[Migration]] = { def goProduct( f: MetaSchema, t: MetaSchema, ffields: Chunk[MetaSchema.Labelled], tfields: Chunk[MetaSchema.Labelled] - ): Either[String, Chunk[Migration]] = + ): zio.prelude.Validation[String, Chunk[Migration]] = matchedSubtrees(ffields, tfields).map { case (Labelled(nextPath, fs), Labelled(_, ts)) => go(acc, path / nextPath, fs, ts, ignoreRefs) - }.foldRight[Either[String, Chunk[Migration]]](Right(Chunk.empty)) { - case (err @ Left(_), Right(_)) => err - case (Right(_), err @ Left(_)) => err + }.foldRight[zio.prelude.Validation[String, Chunk[Migration]]](zio.prelude.Validation.succeed(Chunk.empty)) { + case (err @ Left(_), zio.prelude.Validation.succeed(_)) => err + case (zio.prelude.Validation.succeed(_), err @ Left(_)) => err case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Right(t1), Right(t2)) => Right(t1 ++ t2) + case (zio.prelude.Validation.succeed(t1), zio.prelude.Validation.succeed(t2)) => zio.prelude.Validation.succeed(t1 ++ t2) } .map( _ ++ acc ++ transformShape(path, f, t) ++ insertions(path, ffields, tfields) ++ deletions( @@ -94,14 +94,14 @@ object Migration { t: MetaSchema, fcases: Chunk[MetaSchema.Labelled], tcases: Chunk[MetaSchema.Labelled] - ): Either[String, Chunk[Migration]] = + ): zio.prelude.Validation[String, Chunk[Migration]] = matchedSubtrees(fcases, tcases).map { case (Labelled(nextPath, fs), Labelled(_, ts)) => go(acc, path / nextPath, fs, ts, ignoreRefs) - }.foldRight[Either[String, Chunk[Migration]]](Right(Chunk.empty)) { - case (err @ Left(_), Right(_)) => err - case (Right(_), err @ Left(_)) => err + }.foldRight[zio.prelude.Validation[String, Chunk[Migration]]](zio.prelude.Validation.succeed(Chunk.empty)) { + case (err @ Left(_), zio.prelude.Validation.succeed(_)) => err + case (zio.prelude.Validation.succeed(_), err @ Left(_)) => err case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Right(t1), Right(t2)) => Right(t1 ++ t2) + case (zio.prelude.Validation.succeed(t1), zio.prelude.Validation.succeed(t2)) => zio.prelude.Validation.succeed(t1 ++ t2) } .map( _ ++ acc ++ transformShape(path, f, t) ++ caseInsertions(path, fcases, tcases) ++ deletions( @@ -113,7 +113,7 @@ object Migration { (fromSubtree, toSubtree) match { case (f @ ExtensibleMetaSchema.FailNode(_, _, _), t @ ExtensibleMetaSchema.FailNode(_, _, _)) => - Right( + zio.prelude.Validation.succeed( if (f.message == t.message) Chunk.empty else @@ -172,17 +172,17 @@ object Migration { goSum(f, t, fcases, tcases) case (f @ ExtensibleMetaSchema.Value(ftype, _, _), t @ ExtensibleMetaSchema.Value(ttype, _, _)) if ttype != ftype => - Right(transformShape(path, f, t) :+ ChangeType(path, ttype)) + zio.prelude.Validation.succeed(transformShape(path, f, t) :+ ChangeType(path, ttype)) case (f @ ExtensibleMetaSchema.Value(_, _, _), t @ ExtensibleMetaSchema.Value(_, _, _)) => - Right(transformShape(path, f, t)) + zio.prelude.Validation.succeed(transformShape(path, f, t)) case (f @ ExtensibleMetaSchema.Ref(fromRef, nodePath, _), t @ ExtensibleMetaSchema.Ref(toRef, _, _)) if fromRef == toRef => - if (ignoreRefs) Right(Chunk.empty) + if (ignoreRefs) zio.prelude.Validation.succeed(Chunk.empty) else { val recursiveMigrations = acc .filter(_.path.isSubpathOf(fromRef)) .map(relativize(fromRef, nodePath.relativeTo(fromRef))) - Right(recursiveMigrations ++ transformShape(path, f, t)) + zio.prelude.Validation.succeed(recursiveMigrations ++ transformShape(path, f, t)) } case (f, t) => Left(s"Subtrees at path ${renderPath(path)} are not homomorphic: $f cannot be mapped to $t") } @@ -228,7 +228,7 @@ object Migration { * For example, converting from snake to camel case (or vica versa) */ sealed trait LabelTransformation { - def apply(label: String): Either[String, String] + def apply(label: String): zio.prelude.Validation[String, String] } object LabelTransformation {} @@ -289,20 +289,20 @@ object Migration { value: DynamicValue, path: List[String], trace: Chunk[String] = Chunk.empty - )(op: (String, DynamicValue) => Either[String, Option[(String, DynamicValue)]]): Either[String, DynamicValue] = { + )(op: (String, DynamicValue) => zio.prelude.Validation[String, Option[(String, DynamicValue)]]): zio.prelude.Validation[String, DynamicValue] = { (value, path) match { case (DynamicValue.SomeValue(value), _) => updateLeaf(value, path, trace)(op).map(DynamicValue.SomeValue(_)) - case (DynamicValue.NoneValue, _) => Right(DynamicValue.NoneValue) + case (DynamicValue.NoneValue, _) => zio.prelude.Validation.succeed(DynamicValue.NoneValue) case (DynamicValue.Sequence(values), "item" :: remainder) => values.zipWithIndex.map { case (v, idx) => updateLeaf(v, remainder, trace :+ s"item[$idx]")(op) } - .foldRight[Either[String, DynamicValue.Sequence]](Right(DynamicValue.Sequence(Chunk.empty))) { + .foldRight[zio.prelude.Validation[String, DynamicValue.Sequence]](zio.prelude.Validation.succeed(DynamicValue.Sequence(Chunk.empty))) { case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Left(e), Right(_)) => Left(e) - case (Right(_), Left(e)) => Left(e) - case (Right(DynamicValue.Sequence(v1s)), Right(DynamicValue.Sequence(v2s))) => - Right(DynamicValue.Sequence(v1s ++ v2s)) - case (Right(v1), Right(DynamicValue.Sequence(v2s))) => Right(DynamicValue.Sequence(v1 +: v2s)) + case (Left(e), zio.prelude.Validation.succeed(_)) => Left(e) + case (zio.prelude.Validation.succeed(_), Left(e)) => Left(e) + case (zio.prelude.Validation.succeed(DynamicValue.Sequence(v1s)), zio.prelude.Validation.succeed(DynamicValue.Sequence(v2s))) => + zio.prelude.Validation.succeed(DynamicValue.Sequence(v1s ++ v2s)) + case (zio.prelude.Validation.succeed(v1), zio.prelude.Validation.succeed(DynamicValue.Sequence(v2s))) => zio.prelude.Validation.succeed(DynamicValue.Sequence(v1 +: v2s)) } case (DynamicValue.Tuple(l, r), "left" :: remainder) => updateLeaf(l, remainder, trace :+ "left")(op).map(newLeft => DynamicValue.Tuple(newLeft, r)) @@ -311,11 +311,11 @@ object Migration { case (DynamicValue.LeftValue(l), "left" :: remainder) => updateLeaf(l, remainder, trace :+ "left")(op).map(DynamicValue.LeftValue(_)) case (value @ DynamicValue.LeftValue(_), "right" :: _) => - Right(value) + zio.prelude.Validation.succeed(value) case (DynamicValue.RightValue(r), "right" :: remainder) => updateLeaf(r, remainder, trace :+ "right")(op).map(DynamicValue.RightValue(_)) case (value @ DynamicValue.RightValue(_), "left" :: _) => - Right(value) + zio.prelude.Validation.succeed(value) case (DynamicValue.Record(name, values), leafLabel :: Nil) if values.keySet.contains(leafLabel) => op(leafLabel, values(leafLabel)).map { case Some((newLeafLabel, newLeafValue)) => @@ -329,10 +329,10 @@ object Migration { case (DynamicValue.Record(_, _), nextLabel :: _) => Left(s"Expected label $nextLabel not found at path ${renderPath(trace)}") case (v @ DynamicValue.Enumeration(_, (caseLabel, _)), nextLabel :: _) if caseLabel != nextLabel => - Right(v) + zio.prelude.Validation.succeed(v) case (DynamicValue.Enumeration(id, (caseLabel, caseValue)), nextLabel :: Nil) if caseLabel == nextLabel => op(caseLabel, caseValue).flatMap { - case Some(newCase) => Right(DynamicValue.Enumeration(id, newCase)) + case Some(newCase) => zio.prelude.Validation.succeed(DynamicValue.Enumeration(id, newCase)) case None => Left( s"Failed to update leaf node at path ${renderPath(trace :+ nextLabel)}: Cannot remove instantiated case" @@ -349,16 +349,16 @@ object Migration { .map { case (k, idx) => op(s"key[$idx]", k).flatMap { - case Some((_, migrated)) => Right(migrated) + case Some((_, migrated)) => zio.prelude.Validation.succeed(migrated) case None => Left(s"invalid update at $path, cannot remove map key") } } - .foldRight[Either[String, Chunk[DynamicValue]]](Right(Chunk.empty)) { + .foldRight[zio.prelude.Validation[String, Chunk[DynamicValue]]](zio.prelude.Validation.succeed(Chunk.empty)) { case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Left(e), Right(_)) => Left(e) - case (Right(_), Left(e)) => Left(e) - case (Right(value), Right(chunk)) => - Right(value +: chunk) + case (Left(e), zio.prelude.Validation.succeed(_)) => Left(e) + case (zio.prelude.Validation.succeed(_), Left(e)) => Left(e) + case (zio.prelude.Validation.succeed(value), zio.prelude.Validation.succeed(chunk)) => + zio.prelude.Validation.succeed(value +: chunk) } .map { keys => DynamicValue.Dictionary(keys.zip(entries.map(_._2))) @@ -371,12 +371,12 @@ object Migration { case (k, idx) => updateLeaf(k, remainder, trace :+ s"key[$idx]")(op) } - .foldRight[Either[String, Chunk[DynamicValue]]](Right(Chunk.empty)) { + .foldRight[zio.prelude.Validation[String, Chunk[DynamicValue]]](zio.prelude.Validation.succeed(Chunk.empty)) { case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Left(e), Right(_)) => Left(e) - case (Right(_), Left(e)) => Left(e) - case (Right(value), Right(chunk)) => - Right(value +: chunk) + case (Left(e), zio.prelude.Validation.succeed(_)) => Left(e) + case (zio.prelude.Validation.succeed(_), Left(e)) => Left(e) + case (zio.prelude.Validation.succeed(value), zio.prelude.Validation.succeed(chunk)) => + zio.prelude.Validation.succeed(value +: chunk) } .map { keys => DynamicValue.Dictionary(keys.zip(entries.map(_._2))) @@ -388,16 +388,16 @@ object Migration { .map { case (k, idx) => op(s"key[$idx]", k).flatMap { - case Some((_, migrated)) => Right(migrated) + case Some((_, migrated)) => zio.prelude.Validation.succeed(migrated) case None => Left(s"invalid update at $path, cannot remove map value") } } - .foldRight[Either[String, Chunk[DynamicValue]]](Right(Chunk.empty)) { + .foldRight[zio.prelude.Validation[String, Chunk[DynamicValue]]](zio.prelude.Validation.succeed(Chunk.empty)) { case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Left(e), Right(_)) => Left(e) - case (Right(_), Left(e)) => Left(e) - case (Right(value), Right(chunk)) => - Right(value +: chunk) + case (Left(e), zio.prelude.Validation.succeed(_)) => Left(e) + case (zio.prelude.Validation.succeed(_), Left(e)) => Left(e) + case (zio.prelude.Validation.succeed(value), zio.prelude.Validation.succeed(chunk)) => + zio.prelude.Validation.succeed(value +: chunk) } .map { values => DynamicValue.Dictionary(entries.map(_._1).zip(values)) @@ -410,12 +410,12 @@ object Migration { case (k, idx) => updateLeaf(k, remainder, trace :+ s"value[$idx]")(op) } - .foldRight[Either[String, Chunk[DynamicValue]]](Right(Chunk.empty)) { + .foldRight[zio.prelude.Validation[String, Chunk[DynamicValue]]](zio.prelude.Validation.succeed(Chunk.empty)) { case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Left(e), Right(_)) => Left(e) - case (Right(_), Left(e)) => Left(e) - case (Right(value), Right(chunk)) => - Right(value +: chunk) + case (Left(e), zio.prelude.Validation.succeed(_)) => Left(e) + case (zio.prelude.Validation.succeed(_), Left(e)) => Left(e) + case (zio.prelude.Validation.succeed(value), zio.prelude.Validation.succeed(chunk)) => + zio.prelude.Validation.succeed(value +: chunk) } .map { values => DynamicValue.Dictionary(entries.map(_._1).zip(values)) @@ -437,7 +437,7 @@ object Migration { private def materializeRecursive(depth: Int)(migration: Recursive): Migration = { def appendRecursiveN(n: Int)(relativePath: NodePath): NodePath = - (0 until n).foldRight(NodePath.root)((_, path) => path / relativePath) + (0 until n).foldzio.prelude.Validation.succeed(NodePath.root)((_, path) => path / relativePath) migration match { case Recursive(refPath, relativeNodePath, m: UpdateFail) => @@ -465,11 +465,11 @@ object Migration { } } - protected[schema] def migrateRecursive(value: DynamicValue, migration: Recursive): Either[String, DynamicValue] = { - def go(lastValue: DynamicValue, depth: Int): Either[String, DynamicValue] = + protected[schema] def migrateRecursive(value: DynamicValue, migration: Recursive): zio.prelude.Validation[String, DynamicValue] = { + def go(lastValue: DynamicValue, depth: Int): zio.prelude.Validation[String, DynamicValue] = materializeRecursive(depth)(migration).migrate(lastValue).flatMap { thisValue => if (thisValue == lastValue) - Right(thisValue) + zio.prelude.Validation.succeed(thisValue) else go(thisValue, depth + 1) } @@ -480,14 +480,14 @@ object Migration { value: DynamicValue, path: List[String], newMessage: String - ): Either[String, DynamicValue] = + ): zio.prelude.Validation[String, DynamicValue] = (path, value) match { - case (Nil, DynamicValue.Error(_)) => Right(DynamicValue.Error(newMessage)) + case (Nil, DynamicValue.Error(_)) => zio.prelude.Validation.succeed(DynamicValue.Error(newMessage)) case (Nil, _) => Left(s"Failed to update fail message at root. Unexpected type") case _ => updateLeaf(value, path) { (label, value) => value match { - case DynamicValue.Error(_) => Right(Some(label -> DynamicValue.Error(newMessage))) + case DynamicValue.Error(_) => zio.prelude.Validation.succeed(Some(label -> DynamicValue.Error(newMessage))) case _ => Left(s"Failed to update fail message at ${renderPath(path)}. Unexpected type") } } @@ -497,20 +497,20 @@ object Migration { value: DynamicValue, path: List[String], n: Int - ): Either[String, DynamicValue] = + ): zio.prelude.Validation[String, DynamicValue] = path match { case Nil => - Right( - (0 until n).foldRight(value) { + zio.prelude.Validation.succeed( + (0 until n).foldzio.prelude.Validation.succeed(value) { case (_, acc) => DynamicValue.Sequence(Chunk(acc)) } ) case _ => updateLeaf(value, path) { (label, v) => - Right( + zio.prelude.Validation.succeed( Some( - (0 until n).foldRight(label -> v) { + (0 until n).foldzio.prelude.Validation.succeed(label -> v) { case (_, (_, acc)) => label -> DynamicValue.Sequence(Chunk(acc)) } @@ -524,12 +524,12 @@ object Migration { value: DynamicValue, path: List[String], n: Int - ): Either[String, DynamicValue] = + ): zio.prelude.Validation[String, DynamicValue] = path match { case Nil => - (0 until n).foldRight[Either[String, DynamicValue]](Right(value)) { + (0 until n).foldRight[zio.prelude.Validation[String, DynamicValue]](zio.prelude.Validation.succeed(value)) { case (_, error @ Left(_)) => error - case (_, Right(DynamicValue.Sequence(values))) if values.size == 1 => Right(values(0)) + case (_, zio.prelude.Validation.succeed(DynamicValue.Sequence(values))) if values.size == 1 => zio.prelude.Validation.succeed(values(0)) case _ => Left( s"Failed to decrement dimensions for node at path ${renderPath(path)}: Can only decrement dimensions on a sequence with one element" @@ -538,9 +538,9 @@ object Migration { case _ => updateLeaf(value, path) { (label, value) => (0 until n) - .foldRight[Either[String, DynamicValue]](Right(value)) { + .foldRight[zio.prelude.Validation[String, DynamicValue]](zio.prelude.Validation.succeed(value)) { case (_, error @ Left(_)) => error - case (_, Right(DynamicValue.Sequence(values))) if values.size == 1 => Right(values(0)) + case (_, zio.prelude.Validation.succeed(DynamicValue.Sequence(values))) if values.size == 1 => zio.prelude.Validation.succeed(values(0)) case _ => Left( s"Failed to decrement dimensions for node at path ${renderPath(path)}: Can only decrement dimensions on a sequence with one element" @@ -553,9 +553,9 @@ object Migration { protected[schema] def require( value: DynamicValue, path: List[String] - ): Either[String, DynamicValue] = + ): zio.prelude.Validation[String, DynamicValue] = (value, path) match { - case (DynamicValue.SomeValue(v), Nil) => Right(v) + case (DynamicValue.SomeValue(v), Nil) => zio.prelude.Validation.succeed(v) case (DynamicValue.NoneValue, Nil) => Left( s"Failed to require node: Optional value was None" @@ -563,7 +563,7 @@ object Migration { case _ => updateLeaf(value, path) { case (label, DynamicValue.SomeValue(v)) => - Right(Some(label -> v)) + zio.prelude.Validation.succeed(Some(label -> v)) case (_, DynamicValue.NoneValue) => Left(s"Failed to require leaf at path ${renderPath(path)}: Optional value was not available") case _ => @@ -575,7 +575,7 @@ object Migration { value: DynamicValue, path: List[String], transformation: LabelTransformation - ): Either[String, DynamicValue] = + ): zio.prelude.Validation[String, DynamicValue] = path match { case Nil => Left(s"Cannot relabel node: Path was empty") case _ => @@ -583,7 +583,7 @@ object Migration { transformation(label).fold( error => Left(s"Failed to relabel node at path ${renderPath(path)}: Relabel transform failed with error $error"), - newLabel => Right(Some(newLabel -> value)) + newLabel => zio.prelude.Validation.succeed(Some(newLabel -> value)) ) } } @@ -591,24 +591,24 @@ object Migration { protected[schema] def makeOptional( value: DynamicValue, path: List[String] - ): Either[String, DynamicValue] = + ): zio.prelude.Validation[String, DynamicValue] = (value, path) match { - case (value, Nil) => Right(DynamicValue.SomeValue(value)) + case (value, Nil) => zio.prelude.Validation.succeed(DynamicValue.SomeValue(value)) case _ => updateLeaf(value, path) { case (label, value) => - Right(Some(label -> DynamicValue.SomeValue(value))) + zio.prelude.Validation.succeed(Some(label -> DynamicValue.SomeValue(value))) } } protected[schema] def deleteNode( value: DynamicValue, path: List[String] - ): Either[String, DynamicValue] = + ): zio.prelude.Validation[String, DynamicValue] = path match { case Nil => Left(s"Cannot delete node: Path was empty") case _ => - updateLeaf(value, path)((_, _) => Right(None)) + updateLeaf(value, path)((_, _) => zio.prelude.Validation.succeed(None)) } private def renderPath(path: Iterable[String]): String = path.mkString("/") diff --git a/zio-schema/shared/src/main/scala/zio/schema/meta/NodePath.scala b/zio-schema/shared/src/main/scala/zio/schema/meta/NodePath.scala index 388056edc..d657a2368 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/meta/NodePath.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/meta/NodePath.scala @@ -28,7 +28,7 @@ object NodePath extends Subtype[Chunk[String]] { def partitionLeaf: (NodePath, Option[String]) = if (self.isEmpty) (self, None) - else (NodePath(self.dropRight(1)), Some(self.last)) + else (NodePath(self.dropzio.prelude.Validation.succeed(1)), Some(self.last)) def render: String = if (self.isEmpty) diff --git a/zio-schema/shared/src/main/scala/zio/schema/syntax.scala b/zio-schema/shared/src/main/scala/zio/schema/syntax.scala index ddef44490..5eed212a6 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/syntax.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/syntax.scala @@ -11,7 +11,7 @@ trait SchemaSyntax { */ def diffEach(that: A): Patch[A] = Schema[A].diff(a, that) - def runPatch(diff: Patch[A]): Either[String, A] = + def runPatch(diff: Patch[A]): zio.prelude.Validation[String, A] = Schema[A].patch(a, diff) } @@ -21,7 +21,7 @@ trait SchemaSyntax { implicit class MigrationOps[A: Schema](a: A) { - def migrate[B: Schema]: Either[String, B] = + def migrate[B: Schema]: zio.prelude.Validation[String, B] = Schema[A].migrate(Schema[B]).flatMap(f => f(a)) } } diff --git a/zio-schema/shared/src/main/scala/zio/schema/validation/Predicate.scala b/zio-schema/shared/src/main/scala/zio/schema/validation/Predicate.scala index 3f47a297e..e02f72a97 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/validation/Predicate.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/validation/Predicate.scala @@ -4,7 +4,7 @@ import zio.Chunk sealed trait Predicate[A] { type Errors = Chunk[ValidationError] - type Result = Either[Errors, Errors] + type Result = zio.prelude.Validation[Errors, Errors] def validate(value: A): Result } @@ -16,20 +16,20 @@ object Predicate { def validate(value: String): Result = if (value.length() >= n) - Right(Chunk(ValidationError.MaxLength(n, value.length(), value))) + zio.prelude.Validation.succeed(Chunk(ValidationError.MaxLength(n, value.length(), value))) else Left(Chunk(ValidationError.MinLength(n, value.length(), value))) } final case class MaxLength(n: Int) extends Str[String] { def validate(value: String): Result = - if (value.length() <= n) Right(Chunk(ValidationError.MinLength(n, value.length(), value))) + if (value.length() <= n) zio.prelude.Validation.succeed(Chunk(ValidationError.MinLength(n, value.length(), value))) else Left(Chunk(ValidationError.MaxLength(n, value.length(), value))) } final case class Matches(r: Regex) extends Str[String] { def validate(value: String): Result = - if (r.test(value)) Right(Chunk(ValidationError.NotRegexMatch(value, r))) + if (r.test(value)) zio.prelude.Validation.succeed(Chunk(ValidationError.NotRegexMatch(value, r))) else Left(Chunk(ValidationError.RegexMatch(value, r))) } } @@ -44,7 +44,7 @@ object Predicate { def validate(v: A): Result = if (numType.numeric.compare(v, value) > 0) - Right(Chunk(ValidationError.LessThan(v, value))) + zio.prelude.Validation.succeed(Chunk(ValidationError.LessThan(v, value))) else Left(Chunk(ValidationError.GreaterThan(v, value))) } @@ -52,7 +52,7 @@ object Predicate { def validate(v: A): Result = if (numType.numeric.compare(v, value) < 0) - Right(Chunk(ValidationError.GreaterThan(v, value))) + zio.prelude.Validation.succeed(Chunk(ValidationError.GreaterThan(v, value))) else Left(Chunk(ValidationError.LessThan(v, value))) } @@ -60,13 +60,13 @@ object Predicate { def validate(v: A): Result = if (numType.numeric.compare(v, value) == 0) - Right(Chunk(ValidationError.NotEqualTo(v, value))) + zio.prelude.Validation.succeed(Chunk(ValidationError.NotEqualTo(v, value))) else Left(Chunk(ValidationError.EqualTo(v, value))) } } final case class True[A]() extends Predicate[A] { // A => True - def validate(value: A): Result = Right(Chunk.empty) + def validate(value: A): Result = zio.prelude.Validation.succeed(Chunk.empty) } } diff --git a/zio-schema/shared/src/main/scala/zio/schema/validation/Validation.scala b/zio-schema/shared/src/main/scala/zio/schema/validation/Validation.scala index 078795ef1..4b756eac2 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/validation/Validation.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/validation/Validation.scala @@ -7,15 +7,15 @@ final case class Validation[A](bool: Bool[Predicate[A]]) { self => def ||(that: Validation[A]): Validation[A] = Validation(self.bool || that.bool) def unary_! : Validation[A] = Validation(!self.bool) - def validate(value: A): Either[Chunk[ValidationError], Unit] = { + def validate(value: A): zio.prelude.Validation[Chunk[ValidationError], Unit] = { type Errors = Chunk[ValidationError] - type Result = Either[Errors, Errors] + type Result = zio.prelude.Validation[Errors, Errors] def combineAnd(left: Result, right: Result): Result = (left, right) match { case (Left(leftErrors), Left(rightErrors)) => Left(leftErrors ++ rightErrors) case (Left(leftErrors), _) => Left(leftErrors) case (_, Left(rightErrors)) => Left(rightErrors) - case (Right(leftSuccesses), Right(rightSuccesses)) => Right(leftSuccesses ++ rightSuccesses) + case (zio.prelude.Validation.succeed(leftSuccesses), zio.prelude.Validation.succeed(rightSuccesses)) => zio.prelude.Validation.succeed(leftSuccesses ++ rightSuccesses) } def combineOr(left: Result, right: Result): Result = @@ -23,7 +23,7 @@ final case class Validation[A](bool: Bool[Predicate[A]]) { self => case (Left(leftErrors), Left(rightErrors)) => Left(leftErrors ++ rightErrors) case (Left(_), right) => right case (right, Left(_)) => right - case (Right(leftSuccesses), Right(rightSuccesses)) => Right(leftSuccesses ++ rightSuccesses) + case (zio.prelude.Validation.succeed(leftSuccesses), zio.prelude.Validation.succeed(rightSuccesses)) => zio.prelude.Validation.succeed(leftSuccesses ++ rightSuccesses) } def loop(bool: Bool[Predicate[A]]): Result = { diff --git a/zio-schema/shared/src/test/scala/zio/schema/SchemaAssertions.scala b/zio-schema/shared/src/test/scala/zio/schema/SchemaAssertions.scala index 9b0f26b69..2b08c63b5 100644 --- a/zio-schema/shared/src/test/scala/zio/schema/SchemaAssertions.scala +++ b/zio-schema/shared/src/test/scala/zio/schema/SchemaAssertions.scala @@ -9,7 +9,7 @@ object SchemaAssertions { Assertion.assertion("migratesTo") { value => value.migrate[B] match { case Left(_) => false - case Right(m) if m != expected => false + case zio.prelude.Validation.succeed(m) if m != expected => false case _ => true } From 2849c2fd8bb564dc824e6f3125f6bc6d46cc232f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=8BAndrzej=20Ressel?= Date: Fri, 19 May 2023 03:20:20 +0200 Subject: [PATCH 3/6] Save --- .../zio/schema/AccessorBuilderSpec.scala | 7 +- .../scala-2/zio/schema/DynamicValueSpec.scala | 30 +- .../scala-2/zio/schema/OrderingSpec.scala | 8 +- .../test/scala-2/zio/schema/PatchSpec.scala | 8 +- .../test/scala-2/zio/schema/SchemaGen.scala | 22 +- .../zio/schema/SchemaMigrationSpec.scala | 17 +- .../src/test/scala-2/zio/schema/types.scala | 30 +- .../scala/zio/schema/DefaultValueSpec.scala | 114 +- .../test/scala/zio/schema/MigrationSpec.scala | 4 +- .../test/scala/zio/schema/SchemaSpec.scala | 10 +- .../scala/zio/schema/ast/NodePathSpec.scala | 2 +- .../scala/zio/schema/codec/AvroCodec.scala | 401 ++++--- .../zio/schema/codec/AvroPropMarker.scala | 11 +- .../zio/schema/codec/AvroCodecSpec.scala | 448 ++++---- .../src/main/scala-2/zio/schema/Derive.scala | 6 +- .../scala-2/zio/schema/DeriveSchema.scala | 6 +- .../src/main/scala-3/zio/schema/Derive.scala | 6 +- .../scala-3/zio/schema/DeriveSchema.scala | 6 +- .../main/scala/zio/schema/CachedDeriver.scala | 12 +- .../src/main/scala/zio/schema/Deriver.scala | 16 +- .../scala/zio/schema/DeriveSchemaSpec.scala | 4 +- .../test/scala/zio/schema/DeriveSpec.scala | 12 +- ...cala => SchemaSchemaValidationSpec$.scala} | 124 +- .../schema/example/example1/Example1.scala | 244 ---- .../schema/example/example2/Example2.scala | 225 ---- .../schema/example/example3/Example3.scala | 88 -- .../example4/Example4Transformation.scala | 136 --- .../example/example5/Example5_Diffing.scala | 63 - .../example6/Example6_ReifiedOptics.scala | 127 --- .../zio/schema/example/example7/Problem.scala | 212 ---- .../zio/schema/example/example8/Decoder.scala | 47 - .../zio/schema/example/example8/Encoder.scala | 38 - .../zio/schema/example/example8/Json.scala | 11 - .../zio/schema/example/example8/Usage.scala | 30 - .../schema/example/example9/Patching.scala | 26 - .../scala/zio/schema/codec/JsonCodec.scala | 46 +- .../zio/schema/codec/JsonCodecSpec.scala | 31 +- .../zio/schema/codec/MessagePackCodec.scala | 20 +- .../zio/schema/codec/MessagePackDecoder.scala | 55 +- .../zio/schema/codec/MessagePackEncoder.scala | 14 +- .../schema/codec/MessagePackCodecSpec.scala | 39 +- .../zio/schema/optics/ZioOpticsBuilder.scala | 46 +- .../scala/zio/schema/optics/LensSpec.scala | 4 +- .../zio/schema/codec/ProtobufCodec.scala | 70 +- .../zio/schema/codec/ProtobufCodecSpec.scala | 28 +- .../scala/zio/schema/codec/ThriftCodec.scala | 93 +- .../zio/schema/codec/ThriftCodecSpec.scala | 58 +- .../src/main/scala/zio/schema/DeriveGen.scala | 2 +- .../src/test/scala/zio/schema/TestData.scala | 5 +- .../src/main/scala/zio/schema/Differ.scala | 10 +- .../main/scala/zio/schema/DynamicValue.scala | 19 +- .../MutableSchemaBasedValueBuilder.scala | 41 +- .../MutableSchemaBasedValueProcessor.scala | 41 +- .../src/main/scala/zio/schema/Patch.scala | 25 +- .../src/main/scala/zio/schema/Schema.scala | 332 +++--- .../scala/zio/schema/SchemaEquality.scala | 2 +- .../zio/schema/annotation/validate.scala | 4 +- .../scala/zio/schema/codec/DecodeError.scala | 4 +- .../main/scala/zio/schema/codec/Decoder.scala | 3 +- .../schema/meta/ExtensibleMetaSchema.scala | 22 +- .../scala/zio/schema/meta/Migration.scala | 205 ++-- .../main/scala/zio/schema/meta/NodePath.scala | 2 +- .../validation/PhoneNumberValidation.scala | 1012 ++++++++--------- .../zio/schema/validation/Predicate.scala | 31 +- .../scala/zio/schema/validation/Regexs.scala | 20 +- .../schema/validation/SchemaValidation.scala | 83 ++ .../scala/zio/schema/validation/Time.scala | 4 +- .../zio/schema/validation/Validation.scala | 79 -- .../schema/validation/ValidationErrors.scala | 22 +- .../scala/zio/schema/SchemaAssertions.scala | 9 +- ...=> PhoneNumberSchemaValidationSpec$.scala} | 622 +++++----- ...Spec.scala => SchemaValidationSpec$.scala} | 136 ++- .../zio/schema/validation/TimeSpec.scala | 80 +- 73 files changed, 2285 insertions(+), 3585 deletions(-) rename zio-schema-derivation/shared/src/test/scala/zio/schema/{SchemaValidationSpec.scala => SchemaSchemaValidationSpec$.scala} (56%) delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example1/Example1.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example2/Example2.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example3/Example3.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example4/Example4Transformation.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example5/Example5_Diffing.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example6/Example6_ReifiedOptics.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Decoder.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Encoder.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Json.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Usage.scala delete mode 100644 zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example9/Patching.scala create mode 100644 zio-schema/shared/src/main/scala/zio/schema/validation/SchemaValidation.scala delete mode 100644 zio-schema/shared/src/main/scala/zio/schema/validation/Validation.scala rename zio-schema/shared/src/test/scala/zio/schema/validation/{PhoneNumberValidationSpec.scala => PhoneNumberSchemaValidationSpec$.scala} (57%) rename zio-schema/shared/src/test/scala/zio/schema/validation/{ValidationSpec.scala => SchemaValidationSpec$.scala} (77%) diff --git a/tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala b/tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala index fbfa5797b..f8ae98ab7 100644 --- a/tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala @@ -1,5 +1,6 @@ package zio.schema +import zio.prelude.Validation import zio.schema.Schema._ import zio.schema.SchemaGen.Json.schema import zio.test._ @@ -35,7 +36,7 @@ object AccessorBuilderSpec extends ZIOSpecDefault { }, test("transform") { check(SchemaGen.anyPrimitive) { schema => - val transform = schema.transformOrFail[Unit](_ => Left("error"), _ => Left("error")) + val transform = schema.transformOrFail[Unit](_ => Validation.fail("error"), _ => Validation.fail("error")) val transformAccessor: Any = transform.makeAccessors(builder).asInstanceOf[Any] val schemaAccessor: Any = schema.makeAccessors(builder).asInstanceOf[Any] @@ -84,8 +85,8 @@ object AccessorBuilderSpec extends ZIOSpecDefault { test("either") { check(SchemaGen.anyPrimitive <*> SchemaGen.anyPrimitive) { case (leftSchema, rightSchema) => - val eitherSchema: Schema.zio.prelude.Validation[_, _] = - (rightSchema <+> leftSchema).asInstanceOf[Schema.zio.prelude.Validation[_, _]] + val eitherSchema: Schema.Either[_, _] = + (rightSchema <+> leftSchema).asInstanceOf[Schema.Either[_, _]] val accessor = eitherSchema.makeAccessors(builder) assert( diff --git a/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala b/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala index 13ec5c647..22346a0d2 100644 --- a/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala @@ -15,75 +15,75 @@ object DynamicValueSpec extends ZIOSpecDefault { suite("Primitives")(primitiveTests: _*), test("round-trips Records") { check(SchemaGen.anyRecordOfRecordsAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips Enumerations") { check(SchemaGen.anyEnumerationAndValue) { case (schema, a) => - assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips Eithers") { check(SchemaGen.anyEitherAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips Tuples") { check(SchemaGen.anyTupleAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips Optionals") { check(SchemaGen.anyOptionalAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips Transform") { check(SchemaGen.anyTransformAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips CaseClass") { check(SchemaGen.anyCaseClassAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips Enum") { check(SchemaGen.anyEnumAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips any un-nested schema") { check(SchemaGen.anyLeafAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips any nested schema") { check(SchemaGen.anyTree(1).flatMap(s => DynamicValueGen.anyDynamicValueOfSchema(s).map(s -> _))) { case (schema, dynamic) => - assert(schema.fromDynamic(dynamic))(isRight) + assert(schema.fromDynamic(dynamic).toEither)(isRight) } }, test("round-trips recursive data types") { check(SchemaGen.anyRecursiveTypeAndValue) { case (schema, a) => - assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips sequence") { check(SchemaGen.anySequenceAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips set") { check(SchemaGen.anySetAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } }, test("round-trips map") { check(SchemaGen.anyMapAndValue) { - case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + case (schema, a) => assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } } ), @@ -113,7 +113,7 @@ object DynamicValueSpec extends ZIOSpecDefault { private def dynamicValueLaw[R, A](gen: Gen[R, A], schema: Schema[A]): URIO[R with TestConfig, TestResult] = check(gen) { a => - assert(schema.fromDynamic(schema.toDynamic(a)))(iszio.prelude.Validation.succeed(equalTo(a))) + assert(schema.fromDynamic(schema.toDynamic(a)).toEither)(isRight(equalTo(a))) } } diff --git a/tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala b/tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala index 5a759c5df..c4d798238 100644 --- a/tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala @@ -95,20 +95,20 @@ object OrderingSpec extends ZIOSpecDefault { (l, r) <- genOrderedPairEither(leftSchema, rightSchema) } yield (Schema.Either(leftSchema, rightSchema), l, r).asInstanceOf[SchemaAndPair[zio.prelude.Validation[_, _]]] - def genOrderedPairzio.prelude.Validation[A, B]( + def genOrderedPairEither[A, B]( lSchema: Schema[A], rSchema: Schema[B] - ): Gen[Sized, (zio.prelude.Validation[A, B], zio.prelude.Validation[A, B])] = Gen.oneOf( + ): Gen[Sized, (Either[A, B], Either[A, B])] = Gen.oneOf( for { (small, large) <- genOrderedPair(lSchema) } yield (Left(small), Left(large)), for { (small, large) <- genOrderedPair(rSchema) - } yield (zio.prelude.Validation.succeed(small), zio.prelude.Validation.succeed(large)), + } yield (Right(small), Right(large)), for { l <- genFromSchema(lSchema) r <- genFromSchema(rSchema) - } yield (Left(l), zio.prelude.Validation.succeed(r)) + } yield (Left(l), Right(r)) ) def genAnyOrderedPairTuple: Gen[Sized, SchemaAndPair[_]] = diff --git a/tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala b/tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala index e6cc2c6c8..fdfff446b 100644 --- a/tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala @@ -19,7 +19,7 @@ object PatchSpec extends ZIOSpecDefault { test("Boolean")(patchIdentityLaw[Boolean]), test("Bytes")(patchIdentityLaw[Chunk[Byte]]), suite("Either") { - test("primitive")(patchIdentityLaw[zio.prelude.Validation[String, String]]) + test("primitive")(patchIdentityLaw[Either[String, String]]) }, suite("Option") { test("primitive")(patchIdentityLaw[Option[String]]) @@ -160,10 +160,10 @@ object PatchSpec extends ZIOSpecDefault { ), suite("not comparable")( test("Left <-> Right") { - notComparable[zio.prelude.Validation[String, String]](_.isLeft, _.isRight)(_.isLeft) + notComparable[Either[String, String]](_.isLeft, _.isRight)(_.toEither.isLeft) }, test("Separate enum cases") { - notComparable[Pet](_.isInstanceOf[Pet.Dog], _.isInstanceOf[Pet.Cat])(_.isLeft) + notComparable[Pet](_.isInstanceOf[Pet.Dog], _.isInstanceOf[Pet.Cat])(_.toEither.isLeft) } ) ) @@ -182,7 +182,7 @@ object PatchSpec extends ZIOSpecDefault { val afterInvert = diff.invert.invert val patched = schema.diff(l, r).patch(l) val patchedAfterInvert = afterInvert.patch(l) - assert(patched)(iszio.prelude.Validation.succeed(equalTo(r))) && assert(patchedAfterInvert)(iszio.prelude.Validation.succeed(equalTo(r))) + assert(patched.toEither)(isRight(equalTo(r))) && assert(patchedAfterInvert.toEither)(isRight(equalTo(r))) } else { assertTrue(true) } diff --git a/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala b/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala index 3bb653475..39cf32798 100644 --- a/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala +++ b/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala @@ -1,9 +1,9 @@ package zio.schema import scala.collection.immutable.ListMap - import zio.Chunk -import zio.test.{ Gen, Sized } +import zio.prelude.Validation +import zio.test.{Gen, Sized} object SchemaGen { @@ -98,13 +98,13 @@ object SchemaGen { value <- gen } yield schema -> value - val anyEither: Gen[Sized, Schema.zio.prelude.Validation[_, _]] = + val anyEither: Gen[Sized, Schema.Either[_, _]] = for { left <- anyPrimitive right <- anyPrimitive } yield Schema.Either(left, right) - type EitherAndGen[A, B] = (Schema.zio.prelude.Validation[A, B], Gen[Sized, zio.prelude.Validation[A, B]]) + type EitherAndGen[A, B] = (Schema.Either[A, B], Gen[Sized, Either[A, B]]) val anyEitherAndGen: Gen[Sized, EitherAndGen[_, _]] = for { @@ -112,7 +112,7 @@ object SchemaGen { (rightSchema, rightGen) <- anyPrimitiveAndGen } yield (Schema.Either(leftSchema, rightSchema), Gen.either(leftGen, rightGen)) - type EitherAndValue[A, B] = (Schema.zio.prelude.Validation[A, B], zio.prelude.Validation[A, B]) + type EitherAndValue[A, B] = (Schema.Either[A, B], Either[A, B]) val anyEitherAndValue: Gen[Sized, EitherAndValue[_, _]] = for { @@ -315,8 +315,8 @@ object SchemaGen { private def transformSequence[A](schema: Schema[Chunk[A]]): SequenceTransform[A] = Schema.Transform[Chunk[A], List[A], String]( schema, - chunk => zio.prelude.Validation.succeed(chunk.toList), - list => zio.prelude.Validation.succeed(Chunk.fromIterable(list)), + chunk => Validation.succeed(chunk.toList), + list => Validation.succeed(Chunk.fromIterable(list)), Chunk.empty, "transformSequence" ) @@ -348,8 +348,8 @@ object SchemaGen { def transformRecord[A](schema: Schema[ListMap[String, _]]): RecordTransform[A] = Schema.Transform[ListMap[String, _], A, String]( schema, - _ => Left("Not implemented."), - _ => Left("Not implemented."), + _ => Validation.fail("Not implemented."), + _ => Validation.fail("Not implemented."), Chunk.empty, "transformRecord" ) @@ -381,8 +381,8 @@ object SchemaGen { def transformEnumeration[A](schema: Schema[Any]): EnumerationTransform[_] = Schema.Transform[Any, A, String]( schema, - _ => Left("Not implemented."), - _ => Left("Not implemented."), + _ => Validation.fail("Not implemented."), + _ => Validation.fail("Not implemented."), Chunk.empty, "transformEnumeration" ) diff --git a/tests/shared/src/test/scala-2/zio/schema/SchemaMigrationSpec.scala b/tests/shared/src/test/scala-2/zio/schema/SchemaMigrationSpec.scala index 82ce8a954..d6e70e33c 100644 --- a/tests/shared/src/test/scala-2/zio/schema/SchemaMigrationSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/SchemaMigrationSpec.scala @@ -1,6 +1,7 @@ package zio.schema import zio._ +import zio.prelude.Validation import zio.schema.syntax._ import zio.test.Assertion._ import zio.test._ @@ -47,7 +48,7 @@ object SchemaMigrationSpec extends ZIOSpecDefault { val actualMigration = original.migrate[Recursive3] - assert(actualMigration)(iszio.prelude.Validation.succeed(equalTo(expectedMigration))) + assert(actualMigration.toEither)(isRight(equalTo(expectedMigration))) }, test("require optional field") { assert(PetFood.DogFood(List("i"), Some("brand")))(migratesTo(BrandedPetFood.DogFood(List("i"), "brand"))) @@ -64,9 +65,9 @@ object SchemaMigrationSpec extends ZIOSpecDefault { }, test("migrates to equivalent type") { check(PetFood.gen) { from => - PetFood.brandedEquivalent(from) match { + PetFood.brandedEquivalent(from).toEither match { case Left(_) => assert(from)(cannotMigrateValue[PetFood, BrandedPetFood]) - case zio.prelude.Validation.succeed(to) => assert(from)(migratesTo(to)) + case Right(to) => assert(from)(migratesTo(to)) } } } @@ -171,9 +172,9 @@ object SchemaMigrationSpec extends ZIOSpecDefault { } def brandedEquivalent(p: PetFood): zio.prelude.Validation[String, BrandedPetFood] = p match { - case CatFood(ingredients, Some(brand)) => zio.prelude.Validation.succeed(BrandedPetFood.CatFood(ingredients, brand)) - case DogFood(ingredients, Some(brand)) => zio.prelude.Validation.succeed(BrandedPetFood.DogFood(ingredients, brand)) - case _ => Left("error") + case CatFood(ingredients, Some(brand)) => Validation.succeed(BrandedPetFood.CatFood(ingredients, brand)) + case DogFood(ingredients, Some(brand)) => Validation.succeed(BrandedPetFood.DogFood(ingredients, brand)) + case _ => Validation.fail("error") } implicit lazy val schema: Schema[PetFood] = DeriveSchema.gen @@ -299,7 +300,7 @@ object SchemaMigrationSpec extends ZIOSpecDefault { implicit lazy val schema: Schema[Version2] = DeriveSchema.gen } - case class NestedEither1(v1: Int, v2: zio.prelude.Validation[String, PetFood.DogFood]) + case class NestedEither1(v1: Int, v2: Either[String, PetFood.DogFood]) object NestedEither1 { implicit lazy val schema: Schema[NestedEither1] = DeriveSchema.gen @@ -311,7 +312,7 @@ object SchemaMigrationSpec extends ZIOSpecDefault { } yield NestedEither1(v1, v2) } - case class NestedEither2(v1: Int, v2: zio.prelude.Validation[String, PetFood.CatFood]) + case class NestedEither2(v1: Int, v2: Either[String, PetFood.CatFood]) object NestedEither2 { implicit lazy val schema: Schema[NestedEither2] = DeriveSchema.gen diff --git a/tests/shared/src/test/scala-2/zio/schema/types.scala b/tests/shared/src/test/scala-2/zio/schema/types.scala index 0f0865d5b..520410002 100644 --- a/tests/shared/src/test/scala-2/zio/schema/types.scala +++ b/tests/shared/src/test/scala-2/zio/schema/types.scala @@ -156,7 +156,7 @@ object types { object RecursiveList { implicit lazy val schema: Schema[RecursiveList] = DeriveSchema.gen } - case class RecursiveEither(level: Long, r: zio.prelude.Validation[String, Recursive]) extends Recursive + case class RecursiveEither(level: Long, r: Either[String, Recursive]) extends Recursive object RecursiveEither { implicit lazy val schema: Schema[RecursiveEither] = DeriveSchema.gen @@ -166,13 +166,13 @@ object types { } case class EitherVariants( - f1: zio.prelude.Validation[Option[String], Int], - f2: zio.prelude.Validation[List[String], String], - f3: zio.prelude.Validation[Option[Int], List[String]], - f4: zio.prelude.Validation[List[Option[Int]], Option[List[String]]], - f5: zio.prelude.Validation[zio.prelude.Validation[Int, String], Option[Int]], - f6: zio.prelude.Validation[Arities, Arities], - f7: zio.prelude.Validation[Recursive, Recursive] + f1: Either[Option[String], Int], + f2: Either[List[String], String], + f3: Either[Option[Int], List[String]], + f4: Either[List[Option[Int]], Option[List[String]]], + f5: Either[Either[Int, String], Option[Int]], + f6: Either[Arities, Arities], + f7: Either[Recursive, Recursive] ) object EitherVariants { @@ -182,7 +182,7 @@ object types { case class OptionVariants( f1: Option[Int], f2: Option[List[String]], - f3: Option[zio.prelude.Validation[String, Int]], + f3: Option[Either[String, Int]], f4: Option[Recursive], f5: Option[Arities] ) @@ -200,12 +200,12 @@ object types { f6: Chunk[Option[String]], f7: List[List[String]], f8: Chunk[Chunk[String]], - f9: List[zio.prelude.Validation[String, Int]], - f10: Chunk[zio.prelude.Validation[Option[String], Int]], - f11: List[zio.prelude.Validation[Option[String], List[Int]]], - f12: Chunk[zio.prelude.Validation[Option[String], List[Int]]], - f13: List[Option[zio.prelude.Validation[String, Chunk[Int]]]], - f14: Chunk[Option[zio.prelude.Validation[String, List[Int]]]], + f9: List[Either[String, Int]], + f10: Chunk[Either[Option[String], Int]], + f11: List[Either[Option[String], List[Int]]], + f12: Chunk[Either[Option[String], List[Int]]], + f13: List[Option[Either[String, Chunk[Int]]]], + f14: Chunk[Option[Either[String, List[Int]]]], f15: List[Arities], f16: Chunk[Arities], f17: List[Recursive], diff --git a/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala b/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala index 3c326d901..55d47c7e2 100644 --- a/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala @@ -1,10 +1,10 @@ package zio.schema -import zio.Chunk +import zio.{Chunk, NonEmptyChunk} import zio.schema.CaseSet.caseOf -import zio.schema.Schema.{ Lazy, Primitive } +import zio.schema.Schema.{Lazy, Primitive} import zio.test.Assertion._ -import zio.test.{ Spec, ZIOSpecDefault, assert } +import zio.test.{Spec, ZIOSpecDefault, assert} object DefaultValueSpec extends ZIOSpecDefault { // Record Tests @@ -37,109 +37,109 @@ object DefaultValueSpec extends ZIOSpecDefault { def spec: Spec[Environment, Any] = suite("Default Value Spec")( suite("Primitive")( test("UnitType default value") { - assert(Primitive(StandardType.UnitType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(()))) + assert(Primitive(StandardType.UnitType).defaultValue.toEither)(isRight(equalTo(()))) }, test("StringType default value") { - assert(Primitive(StandardType.StringType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(""))) + assert(Primitive(StandardType.StringType).defaultValue.toEither)(isRight(equalTo(""))) }, test("BoolType default value") { - assert(Primitive(StandardType.BoolType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(false))) + assert(Primitive(StandardType.BoolType).defaultValue.toEither)(isRight(equalTo(false))) }, test("ShortType default value") { - assert(Primitive(StandardType.ShortType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(0.asInstanceOf[Short]))) + assert(Primitive(StandardType.ShortType).defaultValue.toEither)(isRight(equalTo(0.asInstanceOf[Short]))) }, test("IntType default value") { - assert(Primitive(StandardType.IntType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(0))) + assert(Primitive(StandardType.IntType).defaultValue.toEither)(isRight(equalTo(0))) }, test("LongType default value") { - assert(Primitive(StandardType.LongType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(0.asInstanceOf[Long]))) + assert(Primitive(StandardType.LongType).defaultValue.toEither)(isRight(equalTo(0.asInstanceOf[Long]))) }, test("FloatType default value") { - assert(Primitive(StandardType.FloatType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(0.0.asInstanceOf[Float]))) + assert(Primitive(StandardType.FloatType).defaultValue.toEither)(isRight(equalTo(0.0.asInstanceOf[Float]))) }, test("DoubleType default value") { - assert(Primitive(StandardType.DoubleType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(0.0))) + assert(Primitive(StandardType.DoubleType).defaultValue.toEither)(isRight(equalTo(0.0))) }, test("BinaryType default value") { - assert(Primitive(StandardType.BinaryType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(Chunk.empty))) + assert(Primitive(StandardType.BinaryType).defaultValue.toEither)(isRight(equalTo(Chunk.empty))) }, test("CharType default value") { - assert(Primitive(StandardType.CharType).defaultValue)(iszio.prelude.Validation.succeed(equalTo('\u0000'))) + assert(Primitive(StandardType.CharType).defaultValue.toEither)(isRight(equalTo('\u0000'))) }, test("BigDecimalType default value") { - assert(Primitive(StandardType.BigDecimalType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.math.BigDecimal.ZERO))) + assert(Primitive(StandardType.BigDecimalType).defaultValue.toEither)(isRight(equalTo(java.math.BigDecimal.ZERO))) }, test("BigIntegerType default value") { - assert(Primitive(StandardType.BigIntegerType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.math.BigInteger.ZERO))) + assert(Primitive(StandardType.BigIntegerType).defaultValue.toEither)(isRight(equalTo(java.math.BigInteger.ZERO))) }, test("DayOfWeekType default value") { - assert(Primitive(StandardType.DayOfWeekType).defaultValue)( - iszio.prelude.Validation.succeed(equalTo(java.time.temporal.WeekFields.of(java.util.Locale.getDefault).getFirstDayOfWeek)) + assert(Primitive(StandardType.DayOfWeekType).defaultValue.toEither)( + isRight(equalTo(java.time.temporal.WeekFields.of(java.util.Locale.getDefault).getFirstDayOfWeek)) ) }, test("Month default value") { - assert(Primitive(StandardType.MonthType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.time.Month.JANUARY))) + assert(Primitive(StandardType.MonthType).defaultValue.toEither)(isRight(equalTo(java.time.Month.JANUARY))) }, test("MonthDay default value") { - assert(Primitive(StandardType.MonthDayType).defaultValue)( - iszio.prelude.Validation.succeed(equalTo(java.time.MonthDay.of(java.time.Month.JANUARY, 1))) + assert(Primitive(StandardType.MonthDayType).defaultValue.toEither)( + isRight(equalTo(java.time.MonthDay.of(java.time.Month.JANUARY, 1))) ) }, test("Period default value") { - assert(Primitive(StandardType.PeriodType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.time.Period.ZERO))) + assert(Primitive(StandardType.PeriodType).defaultValue.toEither)(isRight(equalTo(java.time.Period.ZERO))) }, test("Year default value") { - assert(Primitive(StandardType.YearType).defaultValue)( - iszio.prelude.Validation.succeed(equalTo(java.time.Year.now)) + assert(Primitive(StandardType.YearType).defaultValue.toEither)( + isRight(equalTo(java.time.Year.now)) ) }, test("YearMonth default value") { - assert(Primitive(StandardType.YearMonthType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.time.YearMonth.now))) + assert(Primitive(StandardType.YearMonthType).defaultValue.toEither)(isRight(equalTo(java.time.YearMonth.now))) }, test("ZoneId default value") { - assert(Primitive(StandardType.ZoneIdType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.time.ZoneId.systemDefault))) + assert(Primitive(StandardType.ZoneIdType).defaultValue.toEither)(isRight(equalTo(java.time.ZoneId.systemDefault))) }, test("ZoneOffset default value") { - assert(Primitive(StandardType.ZoneOffsetType).defaultValue)(iszio.prelude.Validation.succeed(equalTo(java.time.ZoneOffset.UTC))) + assert(Primitive(StandardType.ZoneOffsetType).defaultValue.toEither)(isRight(equalTo(java.time.ZoneOffset.UTC))) }, test("Duration default value") { - assert(Primitive(StandardType.DurationType).defaultValue)( - iszio.prelude.Validation.succeed(equalTo(java.time.Duration.ZERO)) + assert(Primitive(StandardType.DurationType).defaultValue.toEither)( + isRight(equalTo(java.time.Duration.ZERO)) ) }, test("Instant default value") { - assert(Primitive(StandardType.InstantType).defaultValue)( - iszio.prelude.Validation.succeed(equalTo(java.time.Instant.EPOCH)) + assert(Primitive(StandardType.InstantType).defaultValue.toEither)( + isRight(equalTo(java.time.Instant.EPOCH)) ) }, test("LocalDate default value") { - assert(Primitive(StandardType.LocalDateType).defaultValue)( - iszio.prelude.Validation.succeed(isSubtype[java.time.LocalDate](anything)) + assert(Primitive(StandardType.LocalDateType).defaultValue.toEither)( + isRight(isSubtype[java.time.LocalDate](anything)) ) }, test("LocalTime default value") { - assert(Primitive(StandardType.LocalTimeType).defaultValue)( - iszio.prelude.Validation.succeed(equalTo(java.time.LocalTime.MIDNIGHT)) + assert(Primitive(StandardType.LocalTimeType).defaultValue.toEither)( + isRight(equalTo(java.time.LocalTime.MIDNIGHT)) ) }, test("LocalDateTime default value") { - assert(Primitive(StandardType.LocalDateTimeType).defaultValue)( - iszio.prelude.Validation.succeed(isSubtype[java.time.LocalDateTime](anything)) + assert(Primitive(StandardType.LocalDateTimeType).defaultValue.toEither)( + isRight(isSubtype[java.time.LocalDateTime](anything)) ) }, test("OffsetTime default value") { - assert(Primitive(StandardType.OffsetTimeType).defaultValue)( - iszio.prelude.Validation.succeed(isSubtype[java.time.OffsetTime](anything)) + assert(Primitive(StandardType.OffsetTimeType).defaultValue.toEither)( + isRight(isSubtype[java.time.OffsetTime](anything)) ) }, test("OffsetDateTime default value") { - assert(Primitive(StandardType.OffsetDateTimeType).defaultValue)( - iszio.prelude.Validation.succeed(isSubtype[java.time.OffsetDateTime](anything)) + assert(Primitive(StandardType.OffsetDateTimeType).defaultValue.toEither)( + isRight(isSubtype[java.time.OffsetDateTime](anything)) ) }, test("ZonedDateTime default value") { - assert(Primitive(StandardType.ZonedDateTimeType).defaultValue)( - iszio.prelude.Validation.succeed(isSubtype[java.time.ZonedDateTime](anything)) + assert(Primitive(StandardType.ZonedDateTimeType).defaultValue.toEither)( + isRight(isSubtype[java.time.ZonedDateTime](anything)) ) } ), @@ -156,7 +156,7 @@ object DefaultValueSpec extends ZIOSpecDefault { ), UserId.apply ) - assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo(UserId("")))) + assert(schema.defaultValue.toEither)(isRight(equalTo(UserId("")))) }, test("recursive") { val expected: Schema[User] = @@ -191,15 +191,15 @@ object DefaultValueSpec extends ZIOSpecDefault { ), User.apply ) - assert(expected.defaultValue)(iszio.prelude.Validation.succeed(equalTo(User(UserId(""), "", 0)))) + assert(expected.defaultValue.toEither)(isRight(equalTo(User(UserId(""), "", 0)))) } ), suite("Sequence")( test("chunk") { - assert(Schema.chunk[Int].defaultValue)(iszio.prelude.Validation.succeed(equalTo(Chunk(0)))) + assert(Schema.chunk[Int].defaultValue.toEither)(isRight(equalTo(Chunk(0)))) }, test("list") { - assert(Schema.list[Int].defaultValue)(iszio.prelude.Validation.succeed(equalTo(List(0)))) + assert(Schema.list[Int].defaultValue.toEither)(isRight(equalTo(List(0)))) } ), suite("Enumeration")( @@ -211,38 +211,38 @@ object DefaultValueSpec extends ZIOSpecDefault { Any ]("myString")(_.asInstanceOf[String])(_.asInstanceOf[Any])(_.isInstanceOf[String]) ) - assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo(0))) + assert(schema.defaultValue.toEither)(isRight(equalTo(0))) } ), suite("Transform")( test("returns transformed default value") { val schema: Schema[String] = Schema.primitive(StandardType.IntType).transform[String](_.toString, _.toInt) - assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo("0"))) + assert(schema.defaultValue.toEither)(isRight(equalTo("0"))) } ), suite("Optional")( test("defaults to None") { val schema: Schema[Option[Int]] = Schema.option[Int] - assert(schema.defaultValue)(iszio.prelude.Validation.succeed(isNone)) + assert(schema.defaultValue.toEither)(isRight(isNone)) } ), suite("Fail")( test("defaults to the error message") { val schema: Schema[Nothing] = Schema.fail("failing") - assert(schema.defaultValue)(isLeft(equalTo("failing"))) + assert(schema.defaultValue.toEither)(isLeft(equalTo(NonEmptyChunk("failing")))) } ), suite("Tuple")( test("defaults to default value of tuple members") { val schema: Schema[(Int, String)] = Schema.tuple2(Schema.primitive(StandardType.IntType), Schema.primitive(StandardType.StringType)) - assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo((0, "")))) + assert(schema.defaultValue.toEither)(isRight(equalTo((0, "")))) } ), suite("Lazy")( test("calls the schema thunk") { val schema: Lazy[Int] = Schema.Lazy(() => Schema.primitive(StandardType.IntType)) - assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo(0))) + assert(schema.defaultValue.toEither)(isRight(equalTo(0))) } ), suite("Enum")( @@ -274,24 +274,24 @@ object DefaultValueSpec extends ZIOSpecDefault { (s: Status) => s.isInstanceOf[Pending.type] ) ) - assert(schema.defaultValue)(iszio.prelude.Validation.succeed(equalTo(Failed(0, "", None, "")))) + assert(schema.defaultValue.toEither)(isRight(equalTo(Failed(0, "", None, "")))) } ), suite("EitherSchema")( test("either") { - val eitherSchema: Schema[zio.prelude.Validation[Int, String]] = Schema.either( + val eitherSchema: Schema[Either[Int, String]] = Schema.either( Schema.primitive(StandardType.IntType), Schema.primitive(StandardType.StringType) ) - assert(eitherSchema.defaultValue)(iszio.prelude.Validation.succeed(isLeft(equalTo(0)))) + assert(eitherSchema.defaultValue.toEither)(isRight(isLeft(equalTo(0)))) }, test("left") { val leftSchema = Schema.either(Schema.primitive(StandardType.IntType), Schema.fail("Nothing")) - assert(leftSchema.defaultValue)(iszio.prelude.Validation.succeed(isLeft(equalTo(0)))) + assert(leftSchema.defaultValue.toEither)(isRight(isLeft(equalTo(0)))) }, test("right") { val rightSchema = Schema.either(Schema.fail("Nothing"), Schema.primitive(StandardType.StringType)) - assert(rightSchema.defaultValue)(iszio.prelude.Validation.succeed(iszio.prelude.Validation.succeed(equalTo("")))) + assert(rightSchema.defaultValue.toEither)(isRight(isRight(equalTo("")))) } ) ) diff --git a/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala b/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala index 424563324..bc6bfaf81 100644 --- a/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala @@ -231,7 +231,7 @@ object MigrationSpec extends ZIOSpecDefault { val value: Pet2 = Pet2.Hamster("name") val dynamicValue = value.dynamic - assertTrue(Migration.DeleteNode(NodePath.root / "Hamster").migrate(dynamicValue).isLeft) + assertTrue(Migration.DeleteNode(NodePath.root / "Hamster").migrate(dynamicValue).toEither.isLeft) } ) ) @@ -291,7 +291,7 @@ object MigrationSpec extends ZIOSpecDefault { def failsToTransform[A: Schema](value: A): Assertion[Migration] = Assertion.assertion("failsToTransform") { transform => - transform.migrate(value.dynamic).isLeft + transform.migrate(value.dynamic).toEither.isLeft } case class Recursive1(v1: Int, v2: String, r: Option[Recursive1]) diff --git a/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala b/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala index fb330edc1..a36d80ada 100644 --- a/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala @@ -1,8 +1,8 @@ package zio.schema import scala.collection.immutable.ListMap - import zio.Chunk +import zio.prelude.Validation import zio.schema.CaseSet._ import zio.test.Assertion._ import zio.test._ @@ -72,12 +72,12 @@ object SchemaSpec extends ZIOSpecDefault { ) ) - val f: Unit => zio.prelude.Validation[String, Int] = _ => zio.prelude.Validation.succeed(0) - val g: Int => zio.prelude.Validation[String, Unit] = _ => zio.prelude.Validation.succeed(()) + val f: Unit => Validation[String, Int] = _ => zio.prelude.Validation.succeed(0) + val g: Int => Validation[String, Unit] = _ => zio.prelude.Validation.succeed(()) def schemaTransform: Schema[Int] = schemaUnit.transformOrFail[Int](f, g) - def tranformF(u: Unit): zio.prelude.Validation[String, Int] = Some(u).map(_ => 0).tozio.prelude.Validation.succeed("") - def tranformG(i: Int): zio.prelude.Validation[String, Unit] = Some(i).map(_ => ()).tozio.prelude.Validation.succeed("") + def tranformF(u: Unit): Validation[String, Int] = Validation.fromEither(Some(u).map(_ => 0).toRight("")) + def tranformG(i: Int): Validation[String, Unit] = Validation.fromEither(Some(i).map(_ => ()).toRight("")) def schemaTransformMethod: Schema[Int] = schemaUnit.transformOrFail(tranformF, tranformG) } diff --git a/tests/shared/src/test/scala/zio/schema/ast/NodePathSpec.scala b/tests/shared/src/test/scala/zio/schema/ast/NodePathSpec.scala index 4dec61572..f6cc2439a 100644 --- a/tests/shared/src/test/scala/zio/schema/ast/NodePathSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/ast/NodePathSpec.scala @@ -53,7 +53,7 @@ object NodePathSpec extends ZIOSpecDefault { test("partition path into internal path and leaf label") { check(anyPathOfN(2)) { path => val (internalPath, leaf) = path.partitionLeaf - assert(internalPath)(Assertion.equalTo(NodePath(path.dropzio.prelude.Validation.succeed(1)))) && + assert(internalPath)(Assertion.equalTo(NodePath(path.dropRight(1)))) && assertTrue(leaf == Some(path.last)) } }, diff --git a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala index 4b181bc78..1f8d7eb3e 100644 --- a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala +++ b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala @@ -2,65 +2,60 @@ package zio.schema.codec import java.nio.charset.StandardCharsets import java.time.format.DateTimeFormatter -import java.time.{ Duration, Month, MonthDay, Period, Year, YearMonth } - +import java.time.{Duration, Month, MonthDay, Period, Year, YearMonth} import scala.annotation.StaticAnnotation import scala.collection.immutable.ListMap import scala.jdk.CollectionConverters._ -import scala.util.{ Right, Try } - -import org.apache.avro.{ LogicalTypes, Schema => SchemaAvro } - +import scala.util.{Right, Try} +import org.apache.avro.{LogicalTypes, Schema => SchemaAvro} import zio.Chunk +import zio.prelude.Validation import zio.schema.CaseSet.Aux -import zio.schema.Schema.{ Record, _ } +import zio.schema.Schema.{Record, _} import zio.schema._ import zio.schema.codec.AvroAnnotations._ import zio.schema.codec.AvroPropMarker._ import zio.schema.meta.MetaSchema trait AvroCodec { - def encode(schema: Schema[_]): zio.prelude.Validation[String, String] + def encode(schema: Schema[_]): Validation[String, String] - def decode(bytes: Chunk[Byte]): zio.prelude.Validation[String, Schema[_]] + def decode(bytes: Chunk[Byte]): Validation[String, Schema[_]] } object AvroCodec extends AvroCodec { - def encode(schema: Schema[_]): zio.prelude.Validation[String, String] = + def encode(schema: Schema[_]): Validation[String, String] = toAvroSchema(schema).map(_.toString) - def encodeToApacheAvro(schema: Schema[_]): zio.prelude.Validation[String, SchemaAvro] = + def encodeToApacheAvro(schema: Schema[_]): Validation[String, SchemaAvro] = toAvroSchema(schema) - def decode(bytes: Chunk[Byte]): zio.prelude.Validation[String, Schema[_]] = { + def decode(bytes: Chunk[Byte]): Validation[String, Schema[_]] = { val avroSchemaParser = new SchemaAvro.Parser() - val avroSchema = Try { + val avroSchema = Validation( avroSchemaParser.parse(new String(bytes.toArray, StandardCharsets.UTF_8)) - }.fold( - e => Left(e.getMessage), - s => zio.prelude.Validation.succeed(s) - ) + ).mapError(_.getMessage) avroSchema.flatMap(toZioSchema) } - def decodeFromApacheAvro: SchemaAvro => zio.prelude.Validation[String, Schema[_]] = toZioSchema + def decodeFromApacheAvro: SchemaAvro => Validation[String, Schema[_]] = toZioSchema - private def toZioSchema(avroSchema: SchemaAvro): zio.prelude.Validation[String, Schema[_]] = + private def toZioSchema(avroSchema: SchemaAvro): Validation[String, Schema[_]] = for { // make sure to parse logical types with throwing exceptions enabled, // otherwise parsing errors on invalid logical types might be lost - _ <- Try { + _ <- Validation { LogicalTypes.fromSchema(avroSchema) - }.toEither.left.map(e => e.getMessage) + }.mapError(e => e.getMessage) result <- avroSchema.getType match { case SchemaAvro.Type.RECORD => RecordType.fromAvroRecord(avroSchema) match { - case Some(RecordType.Period) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.PeriodType)) - case Some(RecordType.YearMonth) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.YearMonthType)) + case Some(RecordType.Period) => Validation.succeed(Schema.primitive(StandardType.PeriodType)) + case Some(RecordType.YearMonth) => Validation.succeed(Schema.primitive(StandardType.YearMonthType)) case Some(RecordType.Tuple) => toZioTuple(avroSchema) - case Some(RecordType.MonthDay) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.MonthDayType)) - case Some(RecordType.Duration) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.DurationType)) + case Some(RecordType.MonthDay) => Validation.succeed(Schema.primitive(StandardType.MonthDayType)) + case Some(RecordType.Duration) => Validation.succeed(Schema.primitive(StandardType.DurationType)) case None => toZioRecord(avroSchema) } case SchemaAvro.Type.ENUM => toZioStringEnum(avroSchema) @@ -77,14 +72,14 @@ object AvroCodec extends AvroCodec { } case SchemaAvro.Type.FIXED => val fixed = if (avroSchema.getLogicalType == null) { - zio.prelude.Validation.succeed(Schema.primitive(StandardType.BinaryType)) + Validation.succeed(Schema.primitive(StandardType.BinaryType)) } else if (avroSchema.getLogicalType.isInstanceOf[LogicalTypes.Decimal]) { val size = avroSchema.getFixedSize toZioDecimal(avroSchema, DecimalType.Fixed(size)) } else { // TODO: Java implementation of Apache Avro does not support logical type Duration yet: // AVRO-2123 with PR https://github.com/apache/avro/pull/1263 - Left(s"Unsupported fixed logical type ${avroSchema.getLogicalType}") + Validation.fail(s"Unsupported fixed logical type ${avroSchema.getLogicalType}") } fixed.map(_.addAllAnnotations(buildZioAnnotations(avroSchema))) case SchemaAvro.Type.STRING => @@ -95,67 +90,67 @@ object AvroCodec extends AvroCodec { .map(_.dateTimeFormatter) .flatMap(_ => { stringType match { - case StringType.ZoneId => zio.prelude.Validation.succeed(Schema.primitive(StandardType.ZoneIdType)) + case StringType.ZoneId => Validation.succeed(Schema.primitive(StandardType.ZoneIdType)) case StringType.Instant => - zio.prelude.Validation.succeed( + Validation.succeed( Schema .primitive(StandardType.InstantType) .annotate(AvroAnnotations.formatToString) ) case StringType.LocalDate => - zio.prelude.Validation.succeed( + Validation.succeed( Schema .primitive(StandardType.LocalDateType) .annotate(AvroAnnotations.formatToString) ) case StringType.LocalTime => - zio.prelude.Validation.succeed( + Validation.succeed( Schema .primitive(StandardType.LocalTimeType) .annotate(AvroAnnotations.formatToString) ) case StringType.LocalDateTime => - zio.prelude.Validation.succeed( + Validation.succeed( Schema .primitive(StandardType.LocalDateTimeType) .annotate(AvroAnnotations.formatToString) ) case StringType.OffsetTime => - zio.prelude.Validation.succeed(Schema.primitive(StandardType.OffsetTimeType)) + Validation.succeed(Schema.primitive(StandardType.OffsetTimeType)) case StringType.OffsetDateTime => - zio.prelude.Validation.succeed(Schema.primitive(StandardType.OffsetDateTimeType)) + Validation.succeed(Schema.primitive(StandardType.OffsetDateTimeType)) case StringType.ZoneDateTime => - zio.prelude.Validation.succeed(Schema.primitive(StandardType.ZonedDateTimeType)) + Validation.succeed(Schema.primitive(StandardType.ZonedDateTimeType)) } }) case None => if (avroSchema.getLogicalType == null) { - zio.prelude.Validation.succeed(Schema.primitive(StandardType.StringType)) + Validation.succeed(Schema.primitive(StandardType.StringType)) } else if (avroSchema.getLogicalType.getName == LogicalTypes.uuid().getName) { - zio.prelude.Validation.succeed(Schema.primitive(StandardType.UUIDType)) + Validation.succeed(Schema.primitive(StandardType.UUIDType)) } else { - Left(s"Unsupported string logical type: ${avroSchema.getLogicalType.getName}") + Validation.fail(s"Unsupported string logical type: ${avroSchema.getLogicalType.getName}") } } case SchemaAvro.Type.BYTES => if (avroSchema.getLogicalType == null) { - zio.prelude.Validation.succeed(Schema.primitive(StandardType.BinaryType)) + Validation.succeed(Schema.primitive(StandardType.BinaryType)) } else if (avroSchema.getLogicalType.isInstanceOf[LogicalTypes.Decimal]) { toZioDecimal(avroSchema, DecimalType.Bytes) } else { - Left(s"Unsupported bytes logical type ${avroSchema.getLogicalType.getName}") + Validation.fail(s"Unsupported bytes logical type ${avroSchema.getLogicalType.getName}") } case SchemaAvro.Type.INT => IntType.fromAvroInt(avroSchema) match { - case Some(IntType.Char) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.CharType)) - case Some(IntType.DayOfWeek) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.DayOfWeekType)) - case Some(IntType.Year) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.YearType)) - case Some(IntType.Short) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.ShortType)) - case Some(IntType.Month) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.MonthType)) - case Some(IntType.ZoneOffset) => zio.prelude.Validation.succeed(Schema.primitive(StandardType.ZoneOffsetType)) + case Some(IntType.Char) => Validation.succeed(Schema.primitive(StandardType.CharType)) + case Some(IntType.DayOfWeek) => Validation.succeed(Schema.primitive(StandardType.DayOfWeekType)) + case Some(IntType.Year) => Validation.succeed(Schema.primitive(StandardType.YearType)) + case Some(IntType.Short) => Validation.succeed(Schema.primitive(StandardType.ShortType)) + case Some(IntType.Month) => Validation.succeed(Schema.primitive(StandardType.MonthType)) + case Some(IntType.ZoneOffset) => Validation.succeed(Schema.primitive(StandardType.ZoneOffsetType)) case None => if (avroSchema.getLogicalType == null) { - zio.prelude.Validation.succeed(Schema.primitive(StandardType.IntType)) + Validation.succeed(Schema.primitive(StandardType.IntType)) } else avroSchema.getLogicalType match { case _: LogicalTypes.TimeMillis => @@ -168,12 +163,12 @@ object AvroCodec extends AvroCodec { formatter.map( _ => Schema.primitive(StandardType.LocalDateType) ) - case _ => Left(s"Unsupported int logical type ${avroSchema.getLogicalType.getName}") + case _ => Validation.fail(s"Unsupported int logical type ${avroSchema.getLogicalType.getName}") } } case SchemaAvro.Type.LONG => if (avroSchema.getLogicalType == null) { - zio.prelude.Validation.succeed(Schema.primitive(StandardType.LongType)) + Validation.succeed(Schema.primitive(StandardType.LongType)) } else avroSchema.getLogicalType match { case _: LogicalTypes.TimeMicros => @@ -201,13 +196,13 @@ object AvroCodec extends AvroCodec { formatter.map( _ => Schema.primitive(StandardType.LocalDateTimeType) ) - case _ => Left(s"Unsupported long logical type ${avroSchema.getLogicalType.getName}") + case _ => Validation.fail(s"Unsupported long logical type ${avroSchema.getLogicalType.getName}") } - case SchemaAvro.Type.FLOAT => zio.prelude.Validation.succeed(Schema.primitive(StandardType.FloatType)) - case SchemaAvro.Type.DOUBLE => zio.prelude.Validation.succeed(Schema.primitive(StandardType.DoubleType)) - case SchemaAvro.Type.BOOLEAN => zio.prelude.Validation.succeed(Schema.primitive(StandardType.BoolType)) - case SchemaAvro.Type.NULL => zio.prelude.Validation.succeed(Schema.primitive(StandardType.UnitType)) - case null => Left(s"Unsupported type ${avroSchema.getType}") + case SchemaAvro.Type.FLOAT => Validation.succeed(Schema.primitive(StandardType.FloatType)) + case SchemaAvro.Type.DOUBLE => Validation.succeed(Schema.primitive(StandardType.DoubleType)) + case SchemaAvro.Type.BOOLEAN => Validation.succeed(Schema.primitive(StandardType.BoolType)) + case SchemaAvro.Type.NULL => Validation.succeed(Schema.primitive(StandardType.UnitType)) + case null => Validation.fail(s"Unsupported type ${avroSchema.getType}") } } yield result @@ -275,7 +270,7 @@ object AvroCodec extends AvroCodec { ) ) - private def toAvroSchema(schema: Schema[_]): zio.prelude.Validation[String, SchemaAvro] = { + private def toAvroSchema(schema: Schema[_]): Validation[String, SchemaAvro] = { schema match { case e: Enum[_] => toAvroEnum(e) case record: Record[_] => toAvroRecord(record) @@ -285,45 +280,45 @@ object AvroCodec extends AvroCodec { case Transform(codec, _, _, _, _) => toAvroSchema(codec) case Primitive(standardType, _) => standardType match { - case StandardType.UnitType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.NULL)) - case StandardType.StringType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.STRING)) - case StandardType.BoolType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.BOOLEAN)) + case StandardType.UnitType => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.NULL)) + case StandardType.StringType => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.STRING)) + case StandardType.BoolType => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.BOOLEAN)) case StandardType.ShortType => - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Short))) - case StandardType.ByteType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT)) - case StandardType.IntType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT)) - case StandardType.LongType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.LONG)) - case StandardType.FloatType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.FLOAT)) - case StandardType.DoubleType => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.DOUBLE)) - case StandardType.BinaryType => zio.prelude.Validation.succeed(toAvroBinary(schema)) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Short))) + case StandardType.ByteType => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT)) + case StandardType.IntType => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT)) + case StandardType.LongType => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.LONG)) + case StandardType.FloatType => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.FLOAT)) + case StandardType.DoubleType => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.DOUBLE)) + case StandardType.BinaryType => Validation.succeed(toAvroBinary(schema)) case StandardType.CharType => - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Char))) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Char))) case StandardType.UUIDType => - zio.prelude.Validation.succeed(LogicalTypes.uuid().addToSchema(SchemaAvro.create(SchemaAvro.Type.STRING))) + Validation.succeed(LogicalTypes.uuid().addToSchema(SchemaAvro.create(SchemaAvro.Type.STRING))) case StandardType.BigDecimalType => toAvroDecimal(schema) case StandardType.BigIntegerType => toAvroDecimal(schema) case StandardType.DayOfWeekType => - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.DayOfWeek))) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.DayOfWeek))) case StandardType.MonthType => - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Month))) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Month))) case StandardType.YearType => - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Year))) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Year))) case StandardType.ZoneIdType => - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.STRING).addMarkerProp(StringDiscriminator(StringType.ZoneId))) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.STRING).addMarkerProp(StringDiscriminator(StringType.ZoneId))) case StandardType.ZoneOffsetType => - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.ZoneOffset))) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.ZoneOffset))) case StandardType.MonthDayType => //TODO 1 //zio.prelude.Validation.succeed(SchemaAvro.create(monthDayStructure).addMarkerProp(RecordDiscriminator(RecordType.MonthDay))) - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) case StandardType.PeriodType => //TODO 2 //toAvroSchema(periodStructure).map(_.addMarkerProp(RecordDiscriminator(RecordType.Period))) - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) case StandardType.YearMonthType => //TODO 3 //toAvroSchema(yearMonthStructure).map(_.addMarkerProp(RecordDiscriminator(RecordType.YearMonth))) - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) case StandardType.DurationType => // TODO: Java implementation of Apache Avro does not support logical type Duration yet: // AVRO-2123 with PR https://github.com/apache/avro/pull/1263 @@ -332,46 +327,46 @@ object AvroCodec extends AvroCodec { //DurationChronoUnit.fromTemporalUnit(temporalUnit).getOrElse(DurationChronoUnit.default) //toAvroSchema(durationStructure).map( // _.addMarkerProp(RecordDiscriminator(RecordType.Duration)).addMarkerProp(chronoUnitMarker)) - zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) + Validation.succeed(SchemaAvro.create(SchemaAvro.Type.RECORD)) case StandardType.InstantType => - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.Instant)) ) case StandardType.LocalDateType => - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalDate)) ) case StandardType.LocalTimeType => - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalTime)) ) case StandardType.LocalDateTimeType => - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalDateTime)) ) case StandardType.OffsetTimeType => - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.OffsetTime)) ) case StandardType.OffsetDateTimeType => - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.OffsetDateTime)) ) case StandardType.ZonedDateTimeType => - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.ZoneDateTime)) @@ -389,7 +384,7 @@ object AvroCodec extends AvroCodec { case schema => schema } } yield SchemaAvro.createUnion(SchemaAvro.create(SchemaAvro.Type.NULL), wrappedAvroSchema) - case Fail(message, _) => Left(message) + case Fail(message, _) => Validation.fail(message) case tuple: Tuple2[_, _] => toAvroSchema(tuple.toRecord).map( _.addMarkerProp(RecordDiscriminator(RecordType.Tuple)) @@ -403,8 +398,8 @@ object AvroCodec extends AvroCodec { leftSchema = if (l.getType == SchemaAvro.Type.UNION) wrapAvro(l, lname, UnionWrapper) else l rightSchema = if (r.getType == SchemaAvro.Type.UNION) wrapAvro(r, rname, UnionWrapper) else r _ <- if (leftSchema.getFullName == rightSchema.getFullName) - Left(s"Left and right schemas of either must have different fullnames: ${leftSchema.getFullName}") - else zio.prelude.Validation.succeed(()) + Validation.fail(s"Left and right schemas of either must have different fullnames: ${leftSchema.getFullName}") + else Validation.succeed(()) } yield SchemaAvro.createUnion(leftSchema, rightSchema) // Unions in Avro can not hold additional properties, so we need to wrap the union in a record @@ -430,9 +425,9 @@ object AvroCodec extends AvroCodec { private[codec] def toAvroInstant( formatter: DateTimeFormatter, annotations: Chunk[Any] - ): zio.prelude.Validation[String, SchemaAvro] = + ): Validation[String, SchemaAvro] = if (hasFormatToStringAnnotation(annotations)) { - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.Instant)) @@ -442,33 +437,33 @@ object AvroCodec extends AvroCodec { val baseSchema = SchemaAvro.create(SchemaAvro.Type.LONG) getTimeprecisionType(annotations).getOrElse(TimePrecisionType.default) match { case TimePrecisionType.Millis => - zio.prelude.Validation.succeed(LogicalTypes.timestampMillis().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) + Validation.succeed(LogicalTypes.timestampMillis().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) case TimePrecisionType.Micros => - zio.prelude.Validation.succeed(LogicalTypes.timestampMicros().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) + Validation.succeed(LogicalTypes.timestampMicros().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) } } private[codec] def toAvroLocalDate( formatter: DateTimeFormatter, annotations: Chunk[Any] - ): zio.prelude.Validation[String, SchemaAvro] = + ): Validation[String, SchemaAvro] = if (hasFormatToStringAnnotation(annotations)) { - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalDate)) .addMarkerProp(Formatter(formatter)) ) } else { - zio.prelude.Validation.succeed(LogicalTypes.date().addToSchema(SchemaAvro.create(SchemaAvro.Type.INT)).addMarkerProp(Formatter(formatter))) + Validation.succeed(LogicalTypes.date().addToSchema(SchemaAvro.create(SchemaAvro.Type.INT)).addMarkerProp(Formatter(formatter))) } private[codec] def toAvroLocalTime( formatter: DateTimeFormatter, annotations: Chunk[Any] - ): zio.prelude.Validation[String, SchemaAvro] = + ): Validation[String, SchemaAvro] = if (hasFormatToStringAnnotation(annotations)) { - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalTime)) @@ -477,14 +472,14 @@ object AvroCodec extends AvroCodec { } else { getTimeprecisionType(annotations).getOrElse(TimePrecisionType.default) match { case TimePrecisionType.Millis => - zio.prelude.Validation.succeed( + Validation.succeed( LogicalTypes .timeMillis() .addToSchema(SchemaAvro.create(SchemaAvro.Type.INT)) .addMarkerProp(Formatter(formatter)) ) case TimePrecisionType.Micros => - zio.prelude.Validation.succeed( + Validation.succeed( LogicalTypes .timeMicros() .addToSchema(SchemaAvro.create(SchemaAvro.Type.LONG)) @@ -496,9 +491,9 @@ object AvroCodec extends AvroCodec { private[codec] def toAvroLocalDateTime( formatter: DateTimeFormatter, annotations: Chunk[Any] - ): zio.prelude.Validation[String, SchemaAvro] = + ): Validation[String, SchemaAvro] = if (hasFormatToStringAnnotation(annotations)) { - zio.prelude.Validation.succeed( + Validation.succeed( SchemaAvro .create(SchemaAvro.Type.STRING) .addMarkerProp(StringDiscriminator(StringType.LocalDateTime)) @@ -508,9 +503,9 @@ object AvroCodec extends AvroCodec { val baseSchema = SchemaAvro.create(SchemaAvro.Type.LONG) getTimeprecisionType(annotations).getOrElse(TimePrecisionType.default) match { case TimePrecisionType.Millis => - zio.prelude.Validation.succeed(LogicalTypes.localTimestampMillis().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) + Validation.succeed(LogicalTypes.localTimestampMillis().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) case TimePrecisionType.Micros => - zio.prelude.Validation.succeed(LogicalTypes.localTimestampMicros().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) + Validation.succeed(LogicalTypes.localTimestampMicros().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) } } @@ -529,20 +524,20 @@ object AvroCodec extends AvroCodec { .addMarkerProp(marker) } - private[codec] def toAvroEnum(enu: Enum[_]): zio.prelude.Validation[String, SchemaAvro] = { + private[codec] def toAvroEnum(enu: Enum[_]): Validation[String, SchemaAvro] = { val avroEnumAnnotationExists = hasAvroEnumAnnotation(enu.annotations) val isAvroEnumEquivalent = enu.cases.map(_.schema).forall { case (Transform(Primitive(standardType, _), _, _, _, _)) - if standardType == StandardType.UnitType && avroEnumAnnotationExists => + if standardType == StandardType.UnitType && avroEnumAnnotationExists => true case (Primitive(standardType, _)) if standardType == StandardType.StringType => true - case (CaseClass0(_, _, _)) if avroEnumAnnotationExists => true - case _ => false + case (CaseClass0(_, _, _)) if avroEnumAnnotationExists => true + case _ => false } if (isAvroEnumEquivalent) { for { - name <- getName(enu) - doc = getDoc(enu.annotations).orNull + name <- getName(enu) + doc = getDoc(enu.annotations).orNull namespaceOption <- getNamespace(enu.annotations) symbols = enu.cases.map { case caseValue => getNameOption(caseValue.annotations).getOrElse(caseValue.id) @@ -552,14 +547,14 @@ object AvroCodec extends AvroCodec { } else { val cases = enu.cases.map(c => (c.id, (c.schema, c.annotations))).map { case (symbol, (Transform(Primitive(standardType, _), _, _, _, _), annotations)) - if standardType == StandardType.UnitType => + if standardType == StandardType.UnitType => val name = getNameOption(annotations).getOrElse(symbol) - zio.prelude.Validation.succeed(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) + Validation.succeed(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) case (symbol, (CaseClass0(_, _, _), annotations)) => val name = getNameOption(annotations).getOrElse(symbol) - zio.prelude.Validation.succeed(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) + Validation.succeed(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) case (symbol, (schema, annotations)) => - val name = getNameOption(annotations).getOrElse(symbol) + val name = getNameOption(annotations).getOrElse(symbol) val schemaWithName = addNameAnnotationIfMissing(schema, name) toAvroSchema(schemaWithName).map { case schema: SchemaAvro if schema.getType == SchemaAvro.Type.UNION => @@ -567,30 +562,21 @@ object AvroCodec extends AvroCodec { case schema => schema } } - cases.toList.map(_.merge).partition { - case _: String => true - case _ => false - } match { - case (Nil, right: List[org.apache.avro.Schema @unchecked]) => zio.prelude.Validation.succeed(SchemaAvro.createUnion(right.asJava)) - case (left, _) => Left(left.mkString("\n")) - } + Validation.validateAll(cases.toList) + .map(c => SchemaAvro.createUnion(c.asJava)) } } - private def extractAvroFields(record: Record[_]): List[org.apache.avro.Schema.Field] = - record.fields.map(toAvroRecordField).toList.map(_.merge).partition { - case _: String => true - case _ => false - } match { - case (Nil, right: List[org.apache.avro.Schema.Field @unchecked]) => right - case _ => null - } + private def extractAvroFields(record: Record[_]): List[org.apache.avro.Schema.Field] = { + Validation.validateAll(record.fields.map(toAvroRecordField(_)).toList) + .getOrElse(null) + } - private[codec] def toAvroRecord(record: Record[_]): zio.prelude.Validation[String, SchemaAvro] = + private[codec] def toAvroRecord(record: Record[_]): Validation[String, SchemaAvro] = for { name <- getName(record) namespaceOption <- getNamespace(record.annotations) - result <- zio.prelude.Validation.succeed( + result <- Validation.succeed( SchemaAvro.createRecord( name, getDoc(record.annotations).orNull, @@ -601,7 +587,7 @@ object AvroCodec extends AvroCodec { ) } yield result - private[codec] def toAvroMap(map: Map[_, _]): zio.prelude.Validation[String, SchemaAvro] = + private[codec] def toAvroMap(map: Map[_, _]): Validation[String, SchemaAvro] = map.keySchema match { case p: Schema.Primitive[_] if p.standardType == StandardType.StringType => toAvroSchema(map.valueSchema).map(SchemaAvro.createMap) @@ -613,7 +599,7 @@ object AvroCodec extends AvroCodec { toAvroSchema(tupleSchema).map(SchemaAvro.createArray) } - private[codec] def toAvroDecimal(schema: Schema[_]): zio.prelude.Validation[String, SchemaAvro] = { + private[codec] def toAvroDecimal(schema: Schema[_]): Validation[String, SchemaAvro] = { val scale = schema.annotations.collectFirst { case AvroAnnotations.scale(s) => s } .getOrElse(AvroAnnotations.scale().scale) val precision = schema match { @@ -632,7 +618,7 @@ object AvroCodec extends AvroCodec { doc = getDoc(schema.annotations).orNull result = SchemaAvro.createFixed(name, doc, namespaceOption.orNull, size) } yield result - case DecimalType.Bytes => zio.prelude.Validation.succeed(SchemaAvro.create(SchemaAvro.Type.BYTES)) + case DecimalType.Bytes => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.BYTES)) } baseAvroType.map( LogicalTypes @@ -644,7 +630,7 @@ object AvroCodec extends AvroCodec { private[codec] def toErrorMessage(err: Throwable, at: AnyRef) = s"Error mapping to Apache Avro schema: $err at ${at.toString}" - private[codec] def toAvroRecordField[Z](value: Field[Z, _]): zio.prelude.Validation[String, SchemaAvro.Field] = + private[codec] def toAvroRecordField[Z](value: Field[Z, _]): Validation[String, SchemaAvro.Field] = toAvroSchema(value.schema).map( schema => new SchemaAvro.Field( @@ -659,21 +645,21 @@ object AvroCodec extends AvroCodec { private[codec] def getFieldOrder(annotations: Chunk[Any]): Option[FieldOrderType] = annotations.collectFirst { case AvroAnnotations.fieldOrder(fieldOrderType) => fieldOrderType } - private[codec] def getName(schema: Schema[_]): zio.prelude.Validation[String, String] = { + private[codec] def getName(schema: Schema[_]): Validation[String, String] = { val validNameRegex = raw"[A-Za-z_][A-Za-z0-9_]*".r schema.annotations.collectFirst { case AvroAnnotations.name(name) => name } match { case Some(s) => s match { - case validNameRegex() => zio.prelude.Validation.succeed(s) + case validNameRegex() => Validation.succeed(s) case _ => - Left(s"Invalid Avro name: $s") + Validation.fail(s"Invalid Avro name: $s") } case None => schema match { - case r: Record[_] => zio.prelude.Validation.succeed(r.id.name) - case e: Enum[_] => zio.prelude.Validation.succeed(e.id.name) - case _ => zio.prelude.Validation.succeed(s"hashed_${schema.ast.toString.hashCode().toString.replaceFirst("-", "n")}") + case r: Record[_] => Validation.succeed(r.id.name) + case e: Enum[_] => Validation.succeed(e.id.name) + case _ => Validation.succeed(s"hashed_${schema.ast.toString.hashCode().toString.replaceFirst("-", "n")}") // TODO: better way to generate a (maybe stable) name? } } @@ -688,16 +674,16 @@ object AvroCodec extends AvroCodec { private[codec] def getDefault(annotations: Chunk[Any]): Option[java.lang.Object] = annotations.collectFirst { case AvroAnnotations.default(javaDefaultObject) => javaDefaultObject } - private[codec] def getNamespace(annotations: Chunk[Any]): zio.prelude.Validation[String, Option[String]] = { + private[codec] def getNamespace(annotations: Chunk[Any]): Validation[String, Option[String]] = { val validNamespaceRegex = raw"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*".r annotations.collectFirst { case AvroAnnotations.namespace(ns) => ns } match { case Some(s) => s match { - case validNamespaceRegex(_) => zio.prelude.Validation.succeed(Some(s)) - case _ => Left(s"Invalid Avro namespace: $s") + case validNamespaceRegex(_) => Validation.succeed(Some(s)) + case _ => Validation.fail(s"Invalid Avro namespace: $s") } - case None => zio.prelude.Validation.succeed(None) + case None => Validation.succeed(None) } } @@ -711,13 +697,13 @@ object AvroCodec extends AvroCodec { private[codec] def toZioDecimal( avroSchema: SchemaAvro, decimalType: DecimalType - ): zio.prelude.Validation[String, Schema[_]] = { + ): Validation[String, Schema[_]] = { val decimalTypeAnnotation = AvroAnnotations.decimal(decimalType) val decimalLogicalType = avroSchema.getLogicalType.asInstanceOf[LogicalTypes.Decimal] val precision = decimalLogicalType.getPrecision val scale = decimalLogicalType.getScale if (precision - scale > 0) { - zio.prelude.Validation.succeed( + Validation.succeed( Schema .primitive(StandardType.BigDecimalType) .annotate(AvroAnnotations.scale(scale)) @@ -725,7 +711,7 @@ object AvroCodec extends AvroCodec { .annotate(decimalTypeAnnotation) ) } else { - zio.prelude.Validation.succeed( + Validation.succeed( Schema .primitive(StandardType.BigIntegerType) .annotate(AvroAnnotations.scale(scale)) @@ -734,7 +720,7 @@ object AvroCodec extends AvroCodec { } } - private[codec] def toZioEnumeration[A, Z](avroSchema: SchemaAvro): zio.prelude.Validation[String, Schema[Z]] = { + private[codec] def toZioEnumeration[A, Z](avroSchema: SchemaAvro): Validation[String, Schema[Z]] = { val cases = avroSchema.getTypes.asScala .map(t => { val inner = @@ -753,24 +739,23 @@ object AvroCodec extends AvroCodec { ) ) }) - val caseSet = cases.toList.map(_.merge).partition { - case _: String => true - case _ => false - } match { - case (Nil, right: Seq[Case[_, _] @unchecked]) => - Try { - CaseSet(right: _*).asInstanceOf[CaseSet { type EnumType = Z }] - }.toEither.left.map(_.getMessage) - case (left, _) => Left(left.mkString("\n")) - } + + + val caseSet = Validation.validateAll(cases.toList) + .flatMap(cases => { + Validation( + CaseSet(cases: _*).asInstanceOf[CaseSet { type EnumType = Z }] + ).mapError(_.getMessage) + }) + caseSet.map(cs => Schema.enumeration(TypeId.parse(avroSchema.getName), cs)) } - private[codec] def toZioRecord(avroSchema: SchemaAvro): zio.prelude.Validation[String, Schema[_]] = + private[codec] def toZioRecord(avroSchema: SchemaAvro): Validation[String, Schema[_]] = if (avroSchema.getObjectProp(UnionWrapper.propName) != null) { avroSchema.getFields.asScala.headOption match { case Some(value) => toZioSchema(value.schema()) - case None => Left("ZIO schema wrapped record must have a single field") + case None => Validation.fail("ZIO schema wrapped record must have a single field") } } else if (avroSchema.getObjectProp(EitherWrapper.propName) != null) { avroSchema.getFields.asScala.headOption match { @@ -778,47 +763,47 @@ object AvroCodec extends AvroCodec { toZioSchema(value.schema()).flatMap { case enu: Enum[_] => enu.cases.toList match { - case first :: second :: Nil => zio.prelude.Validation.succeed(Schema.either(first.schema, second.schema)) - case _ => Left("ZIO schema wrapped either must have exactly two cases") + case first :: second :: Nil => Validation.succeed(Schema.either(first.schema, second.schema)) + case _ => Validation.fail("ZIO schema wrapped either must have exactly two cases") } - case e: Schema.zio.prelude.Validation[_, _] => zio.prelude.Validation.succeed(e) - case c: CaseClass0[_] => zio.prelude.Validation.succeed(c) - case c: CaseClass1[_, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass2[_, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass3[_, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass4[_, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass5[_, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass6[_, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass7[_, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass8[_, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass9[_, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass10[_, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass11[_, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass12[_, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass13[_, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: CaseClass22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => zio.prelude.Validation.succeed(c) - case c: Dynamic => zio.prelude.Validation.succeed(c) - case c: GenericRecord => zio.prelude.Validation.succeed(c) - case c: Map[_, _] => zio.prelude.Validation.succeed(c) - case c: Sequence[_, _, _] => zio.prelude.Validation.succeed(c) - case c: Set[_] => zio.prelude.Validation.succeed(c) - case c: Fail[_] => zio.prelude.Validation.succeed(c) - case c: Lazy[_] => zio.prelude.Validation.succeed(c) - case c: Optional[_] => zio.prelude.Validation.succeed(c) - case c: Primitive[_] => zio.prelude.Validation.succeed(c) - case c: Transform[_, _, _] => zio.prelude.Validation.succeed(c) - case c: Tuple2[_, _] => zio.prelude.Validation.succeed(c) + case e: Schema.Either[_, _] => Validation.succeed(e) + case c: CaseClass0[_] => Validation.succeed(c) + case c: CaseClass1[_, _] => Validation.succeed(c) + case c: CaseClass2[_, _, _] => Validation.succeed(c) + case c: CaseClass3[_, _, _, _] => Validation.succeed(c) + case c: CaseClass4[_, _, _, _, _] => Validation.succeed(c) + case c: CaseClass5[_, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass6[_, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass7[_, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass8[_, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass9[_, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass10[_, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass11[_, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass12[_, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass13[_, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: Dynamic => Validation.succeed(c) + case c: GenericRecord => Validation.succeed(c) + case c: Map[_, _] => Validation.succeed(c) + case c: Sequence[_, _, _] => Validation.succeed(c) + case c: Set[_] => Validation.succeed(c) + case c: Fail[_] => Validation.succeed(c) + case c: Lazy[_] => Validation.succeed(c) + case c: Optional[_] => Validation.succeed(c) + case c: Primitive[_] => Validation.succeed(c) + case c: Transform[_, _, _] => Validation.succeed(c) + case c: Tuple2[_, _] => Validation.succeed(c) } - case None => Left("ZIO schema wrapped record must have a single field") + case None => Validation.fail("ZIO schema wrapped record must have a single field") } } else { val annotations = buildZioAnnotations(avroSchema) @@ -827,16 +812,10 @@ object AvroCodec extends AvroCodec { } } - private def extractZioFields[Z](avroSchema: SchemaAvro): zio.prelude.Validation[String, List[Field[Z, _]]] = - avroSchema.getFields.asScala.map(toZioField).toList.map(_.merge).partition { - case _: String => true - case _ => false - } match { - case (Nil, right: List[Field[Z, _] @unchecked]) => zio.prelude.Validation.succeed(right) - case (left, _) => Left(left.mkString("\n")) - } + private def extractZioFields[Z](avroSchema: SchemaAvro): Validation[String, List[Field[Z, _]]] = + Validation.validateAll(avroSchema.getFields.asScala.map(toZioField).map(_.map(_.asInstanceOf[Field[Z, _]])).toList) - private[codec] def toZioField(field: SchemaAvro.Field): zio.prelude.Validation[String, Field[ListMap[String, _], _]] = + private[codec] def toZioField(field: SchemaAvro.Field): Validation[String, Field[ListMap[String, _], _]] = toZioSchema(field.schema()) .map( (s: Schema[_]) => @@ -849,10 +828,10 @@ object AvroCodec extends AvroCodec { ) ) - private[codec] def toZioTuple(schema: SchemaAvro): zio.prelude.Validation[String, Schema[_]] = + private[codec] def toZioTuple(schema: SchemaAvro): Validation[String, Schema[_]] = for { - _ <- scala.util.Either - .cond(schema.getFields.size() == 2, (), "Tuple must have exactly 2 fields:" + schema.toString(false)) + _ <- Validation.fromEither(scala.Either + .cond(schema.getFields.size() == 2, (), "Tuple must have exactly 2 fields:" + schema.toString(false))) _1 <- toZioSchema(schema.getFields.get(0).schema()) _2 <- toZioSchema(schema.getFields.get(1).schema()) } yield Schema.Tuple2(_1, _2, buildZioAnnotations(schema)) @@ -891,14 +870,14 @@ object AvroCodec extends AvroCodec { Chunk.fromIterable(annotations) } - private[codec] def toZioStringEnum(avroSchema: SchemaAvro): zio.prelude.Validation[String, Schema[_]] = { + private[codec] def toZioStringEnum(avroSchema: SchemaAvro): Validation[String, Schema[_]] = { val cases = avroSchema.getEnumSymbols.asScala .map(s => Schema.Case[String, String](s, Schema[String], identity, identity, _.isInstanceOf[String])) .toSeq val caseSet = CaseSet[String](cases: _*).asInstanceOf[Aux[String]] val enumeration: Schema[String] = Schema.enumeration(TypeId.parse("org.apache.avro.Schema"), caseSet) - zio.prelude.Validation.succeed(enumeration.addAllAnnotations(buildZioAnnotations(avroSchema))) + Validation.succeed(enumeration.addAllAnnotations(buildZioAnnotations(avroSchema))) } private[codec] case object OptionUnion { diff --git a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala index c3c317bd1..9ec0d6add 100644 --- a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala +++ b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala @@ -1,12 +1,11 @@ package zio.schema.codec import java.time.format.DateTimeFormatter -import java.time.temporal.{ ChronoUnit, TemporalUnit } - +import java.time.temporal.{ChronoUnit, TemporalUnit} import scala.jdk.CollectionConverters._ import scala.util.Try - -import org.apache.avro.{ LogicalType, LogicalTypes, Schema => SchemaAvro } +import org.apache.avro.{LogicalType, LogicalTypes, Schema => SchemaAvro} +import zio.prelude.Validation sealed trait AvroPropMarker { def propName: String @@ -113,9 +112,9 @@ object AvroPropMarker { case "RFC_1123_DATE_TIME" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.RFC_1123_DATE_TIME)) case "BASIC_ISO_DATE" => zio.prelude.Validation.succeed(Formatter(DateTimeFormatter.BASIC_ISO_DATE)) case s: String => - Try { + Validation { Formatter(DateTimeFormatter.ofPattern(s)) - }.toEither.left.map(_.getMessage) + }.mapError(_.getMessage) } match { case Some(value) => value.map(Some(_)) case None => zio.prelude.Validation.succeed(None) diff --git a/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala b/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala index 695fb6041..7ec123e55 100644 --- a/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala +++ b/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala @@ -47,7 +47,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) val expected = """{"type":"enum","name":"MyEnum","symbols":["A","B","C"]}""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("encodes sealed trait objects only as union of records when no avroEnum annotation is present") { @@ -56,7 +56,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """[{"type":"record","name":"A","fields":[]},{"type":"record","name":"B","fields":[]},{"type":"record","name":"MyC","fields":[]}]""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("encodes sealed trait objects only as enum when avroEnum annotation is present") { @@ -64,7 +64,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) val expected = """{"type":"enum","name":"MyEnum","symbols":["A","B","MyC"]}""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("ignores avroEnum annotation if ADT cannot be reduced to String symbols") { val schema = DeriveSchema.gen[SpecTestData.CaseObjectAndCaseClassAdt] @@ -72,7 +72,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """[{"type":"record","name":"A","fields":[]},{"type":"record","name":"B","fields":[]},{"type":"record","name":"MyC","fields":[]},{"type":"record","name":"D","fields":[{"name":"s","type":"string"}]}]""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("flatten nested unions with initialSchemaDerived derivation") { val schema = DeriveSchema.gen[SpecTestData.UnionWithNesting] @@ -80,7 +80,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """[{"type":"record","name":"A","fields":[]},{"type":"record","name":"B","fields":[]},{"type":"record","name":"MyC","fields":[]},{"type":"record","name":"D","fields":[{"name":"s","type":"string"}]}]""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("wraps nested unions") { val schemaA = DeriveSchema.gen[UnionWithNesting.Nested.A.type] @@ -137,7 +137,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val wrappedString = """[{"type":"record","name":"wrapper_Nested","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"A","namespace":"","fields":[]},{"type":"record","name":"B","namespace":"","fields":[]}]}],"zio.schema.codec.avro.wrapper":true},{"type":"record","name":"C","fields":[]},{"type":"record","name":"D","fields":[{"name":"s","type":"string"}]}]""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(wrappedString))) + assert(result.toEither)(isRight(equalTo(wrappedString))) } ), suite("record")( @@ -149,20 +149,20 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"hashed_1642816955","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" - assert(result1)(iszio.prelude.Validation.succeed(equalTo(expected))) && assert(result2)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result1.toEither)(isRight(equalTo(expected))) && assert(result2.toEither)(isRight(equalTo(expected))) } @@ TestAspect.ignore, // TODO: FIX test("fail with left on invalid name") { val schema = DeriveSchema.gen[SpecTestData.Record].annotate(AvroAnnotations.name("0invalid")) val result = AvroCodec.encode(schema) - assert(result)(isLeft(containsString("""0invalid"""))) + assert(result.toEither.left.map(_.head))(isLeft(containsString("""0invalid"""))) }, test("pick up name from annotation") { val schema = DeriveSchema.gen[SpecTestData.NamedRecord] val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" ) @@ -173,8 +173,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = DeriveSchema.gen[SpecTestData.NamedFieldRecord] val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"record","name":"MyNamedFieldRecord","fields":[{"name":"myNamedField","type":"string"},{"name":"b","type":"boolean"}]}""" ) @@ -185,8 +185,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = DeriveSchema.gen[SpecTestData.NamedRecord].annotate(AvroAnnotations.doc("My doc")) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"record","name":"MyNamedRecord","doc":"My doc","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" ) @@ -198,8 +198,8 @@ object AvroCodecSpec extends ZIOSpecDefault { DeriveSchema.gen[SpecTestData.NamedRecord].annotate(AvroAnnotations.namespace("test.namespace")) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"record","name":"MyNamedRecord","namespace":"test.namespace","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" ) @@ -210,7 +210,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = DeriveSchema.gen[SpecTestData.NamedRecord].annotate(AvroAnnotations.namespace("0@-.invalid")) val result = AvroCodec.encode(schema) - assert(result)(isLeft(containsString("""0@-.invalid"""))) + assert(result.toEither.left.map(_.head))(isLeft(containsString("""0@-.invalid"""))) }, test("pick up error annotation") { val schema = DeriveSchema.gen[SpecTestData.NamedRecord].annotate(AvroAnnotations.error) @@ -218,7 +218,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"error","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("includes all fields") { val schema = DeriveSchema.gen[SpecTestData.NamedRecord] @@ -226,7 +226,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("includes nested record fields") { val schema = DeriveSchema.gen[SpecTestData.NestedRecord] @@ -234,7 +234,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"NestedRecord","fields":[{"name":"s","type":"string"},{"name":"nested","type":{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}]}""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) } ), suite("map")( @@ -244,7 +244,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Map(keySchema, valueSchema) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"map","values":"string"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"map","values":"string"}"""))) }, test("string keys and complex values") { val keySchema = Schema.primitive(StandardType.StringType) @@ -252,8 +252,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Map(keySchema, valueSchema) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"map","values":{"type":"record","name":"Simple","fields":[{"name":"s","type":"string"}]}}""" ) @@ -273,7 +273,7 @@ object AvroCodecSpec extends ZIOSpecDefault { ) val hasTupleField_2 = containsString("""{"name":"_2","type":"string"}""") - assert(result)(iszio.prelude.Validation.succeed(isArray && tupleItems && hasTupleField_1 && hasTupleField_2)) + assert(result.toEither)(isRight(isArray && tupleItems && hasTupleField_1 && hasTupleField_2)) }, test("complex keys and complex values") { val keySchema = DeriveSchema.gen[SpecTestData.SimpleRecord] @@ -290,7 +290,7 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"name":"_2","type":{"type":"record","name":"MyNamedRecord","namespace":"","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}""" ) - assert(result)(iszio.prelude.Validation.succeed(isArray && tupleItems && hasTupleField_1 && hasTupleField_2)) + assert(result.toEither)(isRight(isArray && tupleItems && hasTupleField_1 && hasTupleField_2)) } ), suite("seq")( @@ -304,7 +304,7 @@ object AvroCodecSpec extends ZIOSpecDefault { ) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"array","items":"string"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"array","items":"string"}"""))) }, test("encodes complex types") { val valueSchema = DeriveSchema.gen[SpecTestData.NamedRecord] @@ -312,8 +312,8 @@ object AvroCodecSpec extends ZIOSpecDefault { .Sequence[Chunk[NamedRecord], NamedRecord, String](valueSchema, identity, identity, Chunk.empty, "Seq") val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"array","items":{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}""" ) @@ -332,7 +332,7 @@ object AvroCodecSpec extends ZIOSpecDefault { ) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"array","items":"string"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"array","items":"string"}"""))) }, test("encodes complex types") { val valueSchema = DeriveSchema.gen[SpecTestData.NamedRecord] @@ -340,8 +340,8 @@ object AvroCodecSpec extends ZIOSpecDefault { .Sequence[Chunk[NamedRecord], NamedRecord, String](valueSchema, identity, identity, Chunk.empty, "Seq") val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"array","items":{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}""" ) @@ -354,15 +354,15 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Optional(Schema.primitive(StandardType.StringType)) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""["null","string"]"""))) + assert(result.toEither)(isRight(equalTo("""["null","string"]"""))) }, test("encodes complex types") { val valueSchema = DeriveSchema.gen[SpecTestData.NamedRecord] val schema = Schema.Optional(valueSchema) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """["null",{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}]""" ) @@ -373,8 +373,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Optional(Schema.primitive(StandardType.UnitType)) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """["null",{"type":"record","name":"wrapper_hashed_3594628","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":"null"}],"zio.schema.codec.avro.wrapper":true}]""" ) @@ -386,8 +386,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Optional(nested) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """["null",{"type":"record","name":"wrapper_hashed_n813828848","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":["null","string"]}],"zio.schema.codec.avro.wrapper":true}]""" ) @@ -399,8 +399,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Optional(union) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """["null",{"type":"record","name":"wrapper_MyEnum","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"A","namespace":"","fields":[]},{"type":"record","name":"B","namespace":"","fields":[]},{"type":"record","name":"MyC","namespace":"","fields":[]}]}],"zio.schema.codec.avro.wrapper":true}]""" ) @@ -413,8 +413,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Optional(either) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """["null",{"type":"record","name":"wrapper_hashed_n630422444","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":["string","int"]}],"zio.schema.codec.avro.either":true}]""" ) @@ -430,7 +430,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"wrapper_hashed_n630422444","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":["string","int"]}],"zio.schema.codec.avro.either":true}""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("create a named union") { val schema = Schema @@ -440,7 +440,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"wrapper_MyEither","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":["string","int"]}],"zio.schema.codec.avro.either":true}""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("encodes complex types") { val left = DeriveSchema.gen[SpecTestData.SimpleRecord] @@ -450,7 +450,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"wrapper_hashed_754352222","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"Simple","namespace":"","fields":[{"name":"s","type":"string"}]},"string"]}],"zio.schema.codec.avro.either":true}""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("fails with duplicate names") { val left = DeriveSchema.gen[SpecTestData.SimpleRecord] @@ -458,7 +458,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Either(left, right) val result = AvroCodec.encode(schema) - assert(result)( + assert(result.toEither.left.map(_.head))( isLeft(equalTo("""Left and right schemas of either must have different fullnames: Simple""")) ) }, @@ -468,8 +468,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Either(left, right) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"record","name":"wrapper_hashed_n465006219","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"wrapper_hashed_n813828848","fields":[{"name":"value","type":["null","string"]}],"zio.schema.codec.avro.wrapper":true},"string"]}],"zio.schema.codec.avro.either":true}""" ) @@ -485,7 +485,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val expected = """{"type":"record","name":"wrapper_hashed_2071802344","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"wrapper_hashed_n465006219","fields":[{"name":"value","type":[{"type":"record","name":"wrapper_hashed_n813828848","fields":[{"name":"value","type":["null","string"]}],"zio.schema.codec.avro.wrapper":true},"string"]}],"zio.schema.codec.avro.either":true},"string"]}],"zio.schema.codec.avro.either":true}""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) } ), suite("tuple")( @@ -495,8 +495,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.Tuple2(left, right).annotate(AvroAnnotations.name("MyTuple")) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"record","name":"MyTuple","fields":[{"name":"_1","type":"string"},{"name":"_2","type":"string"}],"zio.schema.codec.recordType":"tuple"}""" ) @@ -513,7 +513,7 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"name":"_1","type":{"type":"record","name":"Simple","fields":[{"name":"s","type":"string"}]}}""" val field_2 = """{"name":"_2","type":{"type":"record","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}""" - assert(result)(iszio.prelude.Validation.succeed(containsString(field_1) && containsString(field_2))) + assert(result.toEither)(isRight(containsString(field_1) && containsString(field_2))) }, test("encodes duplicate complex types by reference") { val left = DeriveSchema.gen[SpecTestData.SimpleRecord] @@ -524,7 +524,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field_1 = """{"name":"_1","type":{"type":"record","name":"Simple","fields":[{"name":"s","type":"string"}]}}""" val field_2 = """{"name":"_2","type":"Simple"}""" - assert(result)(iszio.prelude.Validation.succeed(containsString(field_1) && containsString(field_2))) + assert(result.toEither)(isRight(containsString(field_1) && containsString(field_2))) } ), suite("primitives")( @@ -532,55 +532,55 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.primitive(StandardType.UnitType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("\"null\""))) + assert(result.toEither)(isRight(equalTo("\"null\""))) }, test("encodes StringType") { val schema = Schema.primitive(StandardType.StringType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("\"string\""))) + assert(result.toEither)(isRight(equalTo("\"string\""))) }, test("encodes BooleanType") { val schema = Schema.primitive(StandardType.BoolType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("\"boolean\""))) + assert(result.toEither)(isRight(equalTo("\"boolean\""))) }, test("encodes ShortType") { val schema = Schema.primitive(StandardType.ShortType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"short"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"short"}"""))) }, test("encodes IntType") { val schema = Schema.primitive(StandardType.IntType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("\"int\""))) + assert(result.toEither)(isRight(equalTo("\"int\""))) }, test("encodes LongType") { val schema = Schema.primitive(StandardType.LongType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("\"long\""))) + assert(result.toEither)(isRight(equalTo("\"long\""))) }, test("encodes FloatType") { val schema = Schema.primitive(StandardType.FloatType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("\"float\""))) + assert(result.toEither)(isRight(equalTo("\"float\""))) }, test("encodes DoubleType") { val schema = Schema.primitive(StandardType.DoubleType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("\"double\""))) + assert(result.toEither)(isRight(equalTo("\"double\""))) }, test("encodes BinaryType as bytes") { val schema = Schema.primitive(StandardType.BinaryType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("\"bytes\""))) + assert(result.toEither)(isRight(equalTo("\"bytes\""))) }, test("encodes BinaryType as fixed") { val size = 12 @@ -591,26 +591,26 @@ object AvroCodecSpec extends ZIOSpecDefault { val result = AvroCodec.encode(schema) val expected = """{"type":"fixed","name":"MyFixed","doc":"","size":12}""" - assert(result)(iszio.prelude.Validation.succeed(equalTo(expected))) + assert(result.toEither)(isRight(equalTo(expected))) }, test("encodes CharType") { val schema = Schema.primitive(StandardType.CharType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"char"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"char"}"""))) }, test("encodes UUIDType") { val schema = Schema.primitive(StandardType.UUIDType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"string","logicalType":"uuid"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"string","logicalType":"uuid"}"""))) }, test("encodes BigDecimalType as Bytes") { val schema = Schema.primitive(StandardType.BigDecimalType).annotate(AvroAnnotations.decimal(DecimalType.Bytes)) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"bytes","logicalType":"decimal","precision":48,"scale":24}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":48,"scale":24}"""))) }, test("encodes BigDecimalType as Bytes with scala and precision") { val schema = Schema @@ -620,15 +620,15 @@ object AvroCodecSpec extends ZIOSpecDefault { .annotate(AvroAnnotations.precision(20)) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"bytes","logicalType":"decimal","precision":20,"scale":10}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":20,"scale":10}"""))) }, test("encodes BigDecimalType as Fixed") { val schema = Schema.primitive(StandardType.BigDecimalType).annotate(AvroAnnotations.decimal(DecimalType.Fixed(21))) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"fixed","name":"Decimal_48_24","size":21,"logicalType":"decimal","precision":48,"scale":24}""" ) @@ -643,8 +643,8 @@ object AvroCodecSpec extends ZIOSpecDefault { .annotate(AvroAnnotations.precision(20)) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"fixed","name":"Decimal_20_10","size":9,"logicalType":"decimal","precision":20,"scale":10}""" ) @@ -656,7 +656,7 @@ object AvroCodecSpec extends ZIOSpecDefault { Schema.primitive(StandardType.BigIntegerType).annotate(AvroAnnotations.decimal(DecimalType.Bytes)) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"bytes","logicalType":"decimal","precision":24,"scale":24}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":24,"scale":24}"""))) }, test("encodes BigIntegerType as Bytes with scala and precision") { val schema = Schema @@ -666,15 +666,15 @@ object AvroCodecSpec extends ZIOSpecDefault { .annotate(AvroAnnotations.precision(20)) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"bytes","logicalType":"decimal","precision":10,"scale":10}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":10,"scale":10}"""))) }, test("encodes BigIntegerType as Fixed") { val schema = Schema.primitive(StandardType.BigIntegerType).annotate(AvroAnnotations.decimal(DecimalType.Fixed(11))) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"fixed","name":"Decimal_24_24","size":11,"logicalType":"decimal","precision":24,"scale":24}""" ) @@ -689,8 +689,8 @@ object AvroCodecSpec extends ZIOSpecDefault { .annotate(AvroAnnotations.precision(20)) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"fixed","name":"Decimal_10_10","size":5,"logicalType":"decimal","precision":10,"scale":10}""" ) @@ -701,31 +701,31 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.primitive(StandardType.DayOfWeekType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"dayOfWeek"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"dayOfWeek"}"""))) }, test("encodes MonthType") { val schema = Schema.primitive(StandardType.MonthType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"month"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"month"}"""))) }, test("encodes YearType") { val schema = Schema.primitive(StandardType.YearType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"year"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"year"}"""))) }, test("encodes ZoneIdType") { val schema = Schema.primitive(StandardType.ZoneIdType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"string","zio.schema.codec.stringType":"zoneId"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"string","zio.schema.codec.stringType":"zoneId"}"""))) }, test("encodes ZoneOffsetType") { val schema = Schema.primitive(StandardType.ZoneOffsetType) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("""{"type":"int","zio.schema.codec.intType":"zoneOffset"}"""))) + assert(result.toEither)(isRight(equalTo("""{"type":"int","zio.schema.codec.intType":"zoneOffset"}"""))) }, //TODO 1 //test("encodes MonthDayType") { @@ -733,7 +733,7 @@ object AvroCodecSpec extends ZIOSpecDefault { // val result = AvroCodec.encode(schema) // assert(result)( - // iszio.prelude.Validation.succeed( + // isRight( // equalTo( // """{"type":"record","name":"MonthDay","namespace":"zio.schema.codec.avro","fields":[{"name":"month","type":"int"},{"name":"day","type":"int"}],"zio.schema.codec.recordType":"monthDay"}""" // ) @@ -746,7 +746,7 @@ object AvroCodecSpec extends ZIOSpecDefault { // val result = AvroCodec.encode(schema) // // assert(result)( - // iszio.prelude.Validation.succeed( + // isRight( // equalTo( // """{"type":"record","name":"Period","namespace":"zio.schema.codec.avro","fields":[{"name":"years","type":"int"},{"name":"months","type":"int"},{"name":"days","type":"int"}],"zio.schema.codec.recordType":"period"}""" // ) @@ -759,7 +759,7 @@ object AvroCodecSpec extends ZIOSpecDefault { // val result = AvroCodec.encode(schema) // // assert(result)( - // iszio.prelude.Validation.succeed( + // isRight( // equalTo( // """{"type":"record","name":"YearMonth","namespace":"zio.schema.codec.avro","fields":[{"name":"year","type":"int"},{"name":"month","type":"int"}],"zio.schema.codec.recordType":"yearMonth"}""" // ) @@ -772,7 +772,7 @@ object AvroCodecSpec extends ZIOSpecDefault { // val result = AvroCodec.encode(schema) // // assert(result)( - // iszio.prelude.Validation.succeed( + // isRight( // equalTo( // """{"type":"record","name":"Duration","namespace":"zio.schema.codec.avro","fields":[{"name":"seconds","type":"long"},{"name":"nanos","type":"int"}],"zio.schema.codec.recordType":"duration","zio.schema.codec.avro.durationChronoUnit":"DAYS"}""" // ) @@ -783,8 +783,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.primitive(StandardType.InstantType).annotate(AvroAnnotations.formatToString) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"string","zio.schema.codec.stringType":"instant"}""" ) @@ -796,8 +796,8 @@ object AvroCodecSpec extends ZIOSpecDefault { Schema.primitive(StandardType.LocalDateType).annotate(AvroAnnotations.formatToString) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"string","zio.schema.codec.stringType":"localDate"}""" ) @@ -809,8 +809,8 @@ object AvroCodecSpec extends ZIOSpecDefault { Schema.primitive(StandardType.LocalTimeType).annotate(AvroAnnotations.formatToString) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"string","zio.schema.codec.stringType":"localTime"}""" ) @@ -822,8 +822,8 @@ object AvroCodecSpec extends ZIOSpecDefault { Schema.primitive(StandardType.LocalDateTimeType).annotate(AvroAnnotations.formatToString) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"string","zio.schema.codec.stringType":"localDateTime"}""" ) @@ -834,8 +834,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.primitive(StandardType.OffsetTimeType) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"string","zio.schema.codec.stringType":"offsetTime"}""" ) @@ -846,8 +846,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.primitive(StandardType.OffsetDateTimeType) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"string","zio.schema.codec.stringType":"offsetDateTime"}""" ) @@ -858,8 +858,8 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.primitive(StandardType.ZonedDateTimeType) val result = AvroCodec.encode(schema) - assert(result)( - iszio.prelude.Validation.succeed( + assert(result.toEither)( + isRight( equalTo( """{"type":"string","zio.schema.codec.stringType":"zoneDateTime"}""" ) @@ -871,13 +871,13 @@ object AvroCodecSpec extends ZIOSpecDefault { val schema = Schema.fail("I'm failing") val result = AvroCodec.encode(schema) - assert(result)(isLeft(equalTo("""I'm failing"""))) + assert(result.toEither.left.map(_.head))(isLeft(equalTo("""I'm failing"""))) }, test("lazy is handled properly") { val schema = Schema.Lazy(() => Schema.primitive(StandardType.StringType)) val result = AvroCodec.encode(schema) - assert(result)(iszio.prelude.Validation.succeed(equalTo("\"string\""))) + assert(result.toEither)(isRight(equalTo("\"string\""))) } ), /** @@ -890,8 +890,8 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"record","name":"TestRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema.map(_.ast))( - iszio.prelude.Validation.succeed( + assert(schema.map(_.ast).toEither)( + isRight( equalTo( Schema .record( @@ -942,15 +942,15 @@ object AvroCodecSpec extends ZIOSpecDefault { ) ) - assert(schema.map(_.ast))(iszio.prelude.Validation.succeed(equalTo(expectedSchema.ast))) + assert(schema.map(_.ast).toEither)(isRight(equalTo(expectedSchema.ast))) }, test("unwrap a wrapped initialSchemaDerived") { val s = """{"type":"record","zio.schema.codec.avro.wrapper":true,"name":"wrapper_xyz","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":{"type":"record","name":"TestRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema.map(_.ast))( - iszio.prelude.Validation.succeed( + assert(schema.map(_.ast).toEither)( + isRight( equalTo( Schema .record( @@ -978,22 +978,22 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"record","name":"Period","namespace":"zio.schema.codec.avro","fields":[{"name":"years","type":"int"},{"name":"months","type":"int"},{"name":"days","type":"int"}],"zio.schema.codec.recordType":"period"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.PeriodType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.PeriodType))) }, test("yearMonth record") { val s = """{"type":"record","name":"YearMonth","namespace":"zio.schema.codec.avro","fields":[{"name":"year","type":"int"},{"name":"month","type":"int"}],"zio.schema.codec.recordType":"yearMonth"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.YearMonthType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.YearMonthType))) }, test("tuple record successful") { val s = """{"type":"record","name":"Tuple","namespace":"zio.schema.codec.avro","fields":[{"name":"_1","type":"string"},{"name":"_2","type":"int"}],"zio.schema.codec.recordType":"tuple"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)( - iszio.prelude.Validation.succeed(isTuple(isStandardType(StandardType.StringType), isStandardType(StandardType.IntType))) + assert(schema.toEither)( + isRight(isTuple(isStandardType(StandardType.StringType), isStandardType(StandardType.IntType))) ) }, test("tuple record failing") { @@ -1001,71 +1001,71 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"record","name":"Tuple","namespace":"zio.schema.codec.avro","fields":[{"name":"_1","type":"string"},{"name":"_2","type":"int"},{"name":"_3","type":"int"}],"zio.schema.codec.recordType":"tuple"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isLeft) + assert(schema.toEither)(isLeft) }, test("monthDay record") { val s = """{"type":"record","name":"MonthDay","namespace":"zio.schema.codec.avro","fields":[{"name":"month","type":"int"},{"name":"day","type":"int"}],"zio.schema.codec.recordType":"monthDay"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.MonthDayType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.MonthDayType))) }, test("duration record without chrono unit annotation") { val s = """{"type":"record","name":"Duration","namespace":"zio.schema.codec.avro","fields":[{"name":"seconds","type":"long"},{"name":"nanos","type":"int"}],"zio.schema.codec.recordType":"duration"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.DurationType))) //(ChronoUnit.MILLIS)))) + assert(schema.toEither)(isRight(isStandardType(StandardType.DurationType))) //(ChronoUnit.MILLIS)))) }, test("duration record chrono unit annotation") { val s = """{"type":"record","name":"Duration","namespace":"zio.schema.codec.avro","fields":[{"name":"seconds","type":"long"},{"name":"nanos","type":"int"}],"zio.schema.codec.recordType":"duration","zio.schema.codec.avro.durationChronoUnit":"DAYS"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.DurationType))) //(ChronoUnit.DAYS)))) + assert(schema.toEither)(isRight(isStandardType(StandardType.DurationType))) //(ChronoUnit.DAYS)))) }, test("assign the name annotation") { val s = """{"type":"record","name":"TestRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasNameAnnotation(equalTo("TestRecord"))))) + assert(schema.toEither)(isRight(isRecord(hasNameAnnotation(equalTo("TestRecord"))))) }, test("assign the namespace annotation") { val s = """{"type":"record","name":"TestRecord","namespace":"MyTest","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasNamespaceAnnotation(equalTo("MyTest"))))) + assert(schema.toEither)(isRight(isRecord(hasNamespaceAnnotation(equalTo("MyTest"))))) }, test("not assign the namespace annotation if missing") { val s = """{"type":"record","name":"TestRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasNamespaceAnnotation(anything).negate))) + assert(schema.toEither)(isRight(isRecord(hasNamespaceAnnotation(anything).negate))) }, zio.test.test("assign the doc annotation") { val s = """{"type":"record","name":"TestRecord","doc":"Very helpful documentation!","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasDocAnnotation(equalTo("Very helpful documentation!"))))) + assert(schema.toEither)(isRight(isRecord(hasDocAnnotation(equalTo("Very helpful documentation!"))))) }, test("not assign the doc annotation if missing") { val s = """{"type":"record","name":"TestRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasDocAnnotation(anything).negate))) + assert(schema.toEither)(isRight(isRecord(hasDocAnnotation(anything).negate))) }, test("assign the aliases annotation") { val s = """{"type":"record","name":"TestRecord","aliases":["wow", "cool"],"fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)( - iszio.prelude.Validation.succeed(isRecord(hasAliasesAnnotation(exists[String](equalTo("wow")) && exists(equalTo("cool"))))) + assert(schema.toEither)( + isRight(isRecord(hasAliasesAnnotation(exists[String](equalTo("wow")) && exists(equalTo("cool"))))) ) }, test("not assign the aliases annotation if missing") { @@ -1073,28 +1073,28 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"record","name":"TestRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasAliasesAnnotation(anything).negate))) + assert(schema.toEither)(isRight(isRecord(hasAliasesAnnotation(anything).negate))) }, test("not assign the aliases annotation if empty") { val s = """{"type":"record","name":"TestRecord","aliases":[],"fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasAliasesAnnotation(anything).negate))) + assert(schema.toEither)(isRight(isRecord(hasAliasesAnnotation(anything).negate))) }, zio.test.test("assign the error annotation") { val s = """{"type":"error","name":"MyNamedRecord","fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasErrorAnnotation))) + assert(schema.toEither)(isRight(isRecord(hasErrorAnnotation))) }, test("not assign the error annotation if not an error") { val s = """{"type":"record","name":"TestRecord","aliases":[],"fields":[{"name":"s","type":"string"},{"name":"b","type":"boolean"}]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(hasErrorAnnotation.negate))) + assert(schema.toEither)(isRight(isRecord(hasErrorAnnotation.negate))) } ), suite("fields")( @@ -1105,7 +1105,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field1 = hasRecordField(hasLabel(equalTo("s")) && hasSchema(isStandardType(StandardType.StringType))) val field2 = hasRecordField(hasLabel(equalTo("b")) && hasSchema(isStandardType(StandardType.BoolType))) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2))) + assert(schema.toEither)(isRight(isRecord(field1 && field2))) }, test("decodes the fields complex initialSchemaDerived") { val s = @@ -1116,7 +1116,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field2 = hasRecordField(hasLabel(equalTo("b")) && hasSchema(isStandardType(StandardType.BoolType))) val complex = isRecord(field1 && field2) val field = hasRecordField(hasLabel(equalTo("complex")) && hasSchema(complex)) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(field))) + assert(schema.toEither)(isRight(isRecord(field))) }, zio.test.test("assign the field name annotation") { val s = @@ -1125,7 +1125,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field1 = hasRecordField(hasLabel(equalTo("s")) && hasNameAnnotation(equalTo("s"))) val field2 = hasRecordField(hasLabel(equalTo("b")) && hasNameAnnotation(equalTo("b"))) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2))) + assert(schema.toEither)(isRight(isRecord(field1 && field2))) }, zio.test.test("assign the field doc annotation iff it exists") { val s = @@ -1134,7 +1134,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field1 = hasRecordField(hasLabel(equalTo("s")) && hasDocAnnotation(equalTo("Very helpful doc!"))) val field2 = hasRecordField(hasLabel(equalTo("b")) && hasDocAnnotation(anything).negate) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2))) + assert(schema.toEither)(isRight(isRecord(field1 && field2))) }, test("assign the field default annotation") { val s = @@ -1146,7 +1146,7 @@ object AvroCodecSpec extends ZIOSpecDefault { hasLabel(equalTo("complex")) && hasFieldDefaultAnnotation(asString(equalTo("""{s=defaultS, b=true}"""))) ) val field3 = hasRecordField(hasLabel(equalTo("b")) && hasFieldDefaultAnnotation(anything).negate) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2 && field3))) + assert(schema.toEither)(isRight(isRecord(field1 && field2 && field3))) }, zio.test.test("assign the fieldOrder annotation") { val s = @@ -1159,7 +1159,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val field2 = hasRecordField( hasLabel(equalTo("b")) && hasFieldOrderAnnotation(equalTo(AvroAnnotations.FieldOrderType.Ascending)) ) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2))) + assert(schema.toEither)(isRight(isRecord(field1 && field2))) }, zio.test.test("assign the field aliases annotation") { val s = @@ -1170,7 +1170,7 @@ object AvroCodecSpec extends ZIOSpecDefault { hasLabel(equalTo("s")) && hasAliasesAnnotation(Assertion.hasSameElements(Seq("wow", "cool"))) ) val field2 = hasRecordField(hasLabel(equalTo("b")) && hasAliasesAnnotation(anything).negate) - assert(schema)(iszio.prelude.Validation.succeed(isRecord(field1 && field2))) + assert(schema.toEither)(isRight(isRecord(field1 && field2))) } ), suite("enum")( @@ -1181,89 +1181,89 @@ object AvroCodecSpec extends ZIOSpecDefault { val symbolKeysAssetion = Assertion.hasKeys(hasSameElements(Seq("a", "b", "c"))) val enumStringTypeAssertion: Assertion[ListMap[String, (Schema[_], Chunk[Any])]] = Assertion.hasValues(forall(tuple2First(isStandardType(StandardType.StringType)))) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(enumStructure(symbolKeysAssetion && enumStringTypeAssertion)))) + assert(schema.toEither)(isRight(isEnum(enumStructure(symbolKeysAssetion && enumStringTypeAssertion)))) }, test("assign the enum name annotation") { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasNameAnnotation(equalTo("TestEnum"))))) + assert(schema.toEither)(isRight(isEnum(hasNameAnnotation(equalTo("TestEnum"))))) }, test("assign the enum namespace annotation") { val s = """{"type":"enum","name":"TestEnum","namespace":"MyTest","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasNamespaceAnnotation(equalTo("MyTest"))))) + assert(schema.toEither)(isRight(isEnum(hasNamespaceAnnotation(equalTo("MyTest"))))) }, test("not assign the enum namespace annotation if empty") { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasNamespaceAnnotation(anything).negate))) + assert(schema.toEither)(isRight(isEnum(hasNamespaceAnnotation(anything).negate))) }, test("assign the enum aliases annotation") { val s = """{"type":"enum","name":"TestEnum","aliases":["MyAlias", "MyAlias2"],"symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasAliasesAnnotation(hasSameElements(Seq("MyAlias", "MyAlias2")))))) + assert(schema.toEither)(isRight(isEnum(hasAliasesAnnotation(hasSameElements(Seq("MyAlias", "MyAlias2")))))) }, test("not assign the enum aliases annotation if empty") { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasAliasesAnnotation(anything).negate))) + assert(schema.toEither)(isRight(isEnum(hasAliasesAnnotation(anything).negate))) }, test("assign the enum doc annotation") { val s = """{"type":"enum","name":"TestEnum","doc":"Some very helpful documentation!","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasDocAnnotation(equalTo("Some very helpful documentation!"))))) + assert(schema.toEither)(isRight(isEnum(hasDocAnnotation(equalTo("Some very helpful documentation!"))))) }, test("not assign the enum doc annotation if empty") { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasAliasesAnnotation(anything).negate))) + assert(schema.toEither)(isRight(isEnum(hasAliasesAnnotation(anything).negate))) }, test("assign the enum default annotation") { val s = """{"type":"enum","name":"TestEnum","default":"a","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasDefaultAnnotation(equalTo("a"))))) + assert(schema.toEither)(isRight(isEnum(hasDefaultAnnotation(equalTo("a"))))) }, test("fail if enum default is not a symbol") { val s = """{"type":"enum","name":"TestEnum","default":"d","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isLeft(equalTo("The Enum Default: d is not in the enum symbol set: [a, b, c]"))) + assert(schema.toEither.left.map(_.head))(isLeft(equalTo("The Enum Default: d is not in the enum symbol set: [a, b, c]"))) }, test("not assign the enum default annotation if empty") { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(hasDefaultAnnotation(anything).negate))) + assert(schema.toEither)(isRight(isEnum(hasDefaultAnnotation(anything).negate))) } ), test("decodes primitive array") { val s = """{"type":"array","items":{"type":"int"}}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isSequence(hasSequenceElementSchema(isStandardType(StandardType.IntType))))) + assert(schema.toEither)(isRight(isSequence(hasSequenceElementSchema(isStandardType(StandardType.IntType))))) }, test("decodes complex array") { val s = """{"type":"array","items":{"type":"record","name":"TestRecord","fields":[{"name":"f1","type":"int"},{"name":"f2","type":"string"}]}}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isSequence(hasSequenceElementSchema(isRecord(anything))))) + assert(schema.toEither)(isRight(isSequence(hasSequenceElementSchema(isRecord(anything))))) }, test("decodes map with string keys") { val s = """{"type":"map","values":{"type":"int"}}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)( - iszio.prelude.Validation.succeed( + assert(schema.toEither)( + isRight( isMap( hasMapKeys(isStandardType(StandardType.StringType)) && hasMapValues( isStandardType(StandardType.IntType) @@ -1277,27 +1277,27 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """[{"type":"null"}, {"type":"int"}]""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isOption(hasOptionElementSchema(isStandardType(StandardType.IntType))))) + assert(schema.toEither)(isRight(isOption(hasOptionElementSchema(isStandardType(StandardType.IntType))))) }, test("option union with null on second position") { val s = """[{"type":"int"}, {"type":"null"}]""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isOption(hasOptionElementSchema(isStandardType(StandardType.IntType))))) + assert(schema.toEither)(isRight(isOption(hasOptionElementSchema(isStandardType(StandardType.IntType))))) }, test("not an option union with more than one element type") { val s = """[{"type":"null"}, {"type":"int"}, {"type":"string"}]""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isOption(anything).negate)) + assert(schema.toEither)(isRight(isOption(anything).negate)) }, test("nested either union") { val s = """{"type":"record","name":"wrapper_hashed_2071802344","namespace":"zio.schema.codec.avro","fields":[{"name":"value","type":[{"type":"record","name":"wrapper_hashed_n465006219","fields":[{"name":"value","type":[{"type":"record","name":"wrapper_hashed_n813828848","fields":[{"name":"value","type":["null","string"]}],"zio.schema.codec.avro.wrapper":true},"string"]}],"zio.schema.codec.avro.either":true},"string"]}],"zio.schema.codec.avro.either":true}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)( - iszio.prelude.Validation.succeed( + assert(schema.toEither)( + isRight( isEither( isEither(isOption(anything), isStandardType(StandardType.StringType)), isStandardType(StandardType.StringType) @@ -1312,7 +1312,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val assertion1 = hasKey("null", tuple2First(isStandardType(StandardType.UnitType))) val sssertion2 = hasKey("int", tuple2First(isStandardType(StandardType.IntType))) val assertion3 = hasKey("string", tuple2First(isStandardType(StandardType.StringType))) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(enumStructure(assertion1 && sssertion2 && assertion3)))) + assert(schema.toEither)(isRight(isEnum(enumStructure(assertion1 && sssertion2 && assertion3)))) }, test("correct case codec for case object of ADT") { val s = @@ -1322,7 +1322,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val assertionA = hasKey("A", tuple2First(isEmptyRecord)) val assertionB = hasKey("B", tuple2First(isEmptyRecord)) val assertionMyC = hasKey("MyC", tuple2First(isEmptyRecord)) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(enumStructure(assertionA && assertionB && assertionMyC)))) + assert(schema.toEither)(isRight(isEnum(enumStructure(assertionA && assertionB && assertionMyC)))) }, test("correct case codec for case class of ADT") { val s = @@ -1335,7 +1335,7 @@ object AvroCodecSpec extends ZIOSpecDefault { ) val assertionB = hasKey("B", tuple2First(isEmptyRecord)) val assertionMyC = hasKey("MyC", tuple2First(isEmptyRecord)) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(enumStructure(assertionA && assertionB && assertionMyC)))) + assert(schema.toEither)(isRight(isEnum(enumStructure(assertionA && assertionB && assertionMyC)))) }, test("unwrap nested union") { val s = @@ -1354,7 +1354,7 @@ object AvroCodecSpec extends ZIOSpecDefault { hasKey("zio.schema.codec.avro.wrapper_hashed_n465006219", tuple2First(nestedEnumAssertion)) val cEnumKey = hasKey("C", tuple2First(isEmptyRecord)) val dEnumKey = hasKey("D", tuple2First(isRecord(hasRecordField(hasLabel(equalTo("s")))))) - assert(schema)(iszio.prelude.Validation.succeed(isEnum(enumStructure(nestedEnumKey && cEnumKey && dEnumKey)))) + assert(schema.toEither)(isRight(isEnum(enumStructure(nestedEnumKey && cEnumKey && dEnumKey)))) } ), suite("fixed")( @@ -1370,7 +1370,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val hasPrecisionAnnotation: Assertion[Iterable[Any]] = exists(equalTo(AvroAnnotations.precision(11))) val hasAnnotationsAssertion = annotations(hasDecimalTypeAnnotation && hasScalaAnnotation && hasPrecisionAnnotation) - assert(schema)(iszio.prelude.Validation.succeed(isDecimalAssertion && hasAnnotationsAssertion)) + assert(schema.toEither)(isRight(isDecimalAssertion && hasAnnotationsAssertion)) }, test("logical type decimal as BigInteger") { val s = @@ -1385,21 +1385,21 @@ object AvroCodecSpec extends ZIOSpecDefault { exists(Assertion.isSubtype[AvroAnnotations.precision.type](anything)).negate val hasAnnotationsAssertion = annotations(hasDecimalTypeAnnotation && hasScalaAnnotation && doesNotHavePrecisionAnnotation) - assert(schema)(iszio.prelude.Validation.succeed(isBigIntegerType && hasAnnotationsAssertion)) + assert(schema.toEither)(isRight(isBigIntegerType && hasAnnotationsAssertion)) }, test("fail on invalid logical type") { val s = """{"type":"fixed","name":"Decimal_10_10","size":5,"logicalType":"decimal","precision":9,"scale":10}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isLeft(equalTo("Invalid decimal scale: 10 (greater than precision: 9)"))) + assert(schema.toEither.left.map(_.head))(isLeft(equalTo("Invalid decimal scale: 10 (greater than precision: 9)"))) }, test("decode as binary") { val s = """{"type":"fixed","name":"Something","size":5}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) val hasNameAnnotation = annotations(exists(equalTo(AvroAnnotations.name("Something")))) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.BinaryType) && hasNameAnnotation)) + assert(schema.toEither)(isRight(isStandardType(StandardType.BinaryType) && hasNameAnnotation)) } ), suite("string")( @@ -1407,20 +1407,20 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """{"type":"string","zio.schema.codec.stringType":"zoneId"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.ZoneIdType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.ZoneIdType))) }, test("decodes instant with formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"instant","zio.schema.codec.avro.dateTimeFormatter":"ISO_INSTANT"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.InstantType))) }, test("decodes instant using default") { val s = """{"type":"string","zio.schema.codec.stringType":"instant"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.InstantType))) }, test("decodes instant with formatter pattern") { val pattern = "yyyy MM dd" @@ -1428,7 +1428,7 @@ object AvroCodecSpec extends ZIOSpecDefault { s"""{"type":"string","zio.schema.codec.stringType":"instant","zio.schema.codec.avro.dateTimeFormatter":"$pattern"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.InstantType))) }, test("decode DateTimeFormatter field fails on invalid formatter") { val pattern = "this is not a valid formatter pattern" @@ -1436,47 +1436,47 @@ object AvroCodecSpec extends ZIOSpecDefault { s"""{"type":"string","zio.schema.codec.stringType":"instant","zio.schema.codec.avro.dateTimeFormatter":"$pattern"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(isLeft(equalTo("Unknown pattern letter: t"))) + assert(schema.toEither.left.map(_.head))(isLeft(equalTo("Unknown pattern letter: t"))) }, test("decodes localDate with formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localDate","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalDateType))) }, test("decodes localDate with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localDate"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalDateType))) }, test("decodes localTime with formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localTime","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalTimeType))) }, test("decodes localTime with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localTime"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalTimeType))) }, test("decodes localDateTime with formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localDateTime","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalDateTimeType))) }, test("decodes localDateTime with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"localDateTime"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)( - iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType)) + assert(schema.toEither)( + isRight(isStandardType(StandardType.LocalDateTimeType)) ) }, test("decodes zonedDateTime with formatter") { @@ -1484,14 +1484,14 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"string","zio.schema.codec.stringType":"zoneDateTime","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.ZonedDateTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.ZonedDateTimeType))) }, test("decodes zonedDateTime with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"zoneDateTime"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)( - iszio.prelude.Validation.succeed(isStandardType(StandardType.ZonedDateTimeType)) + assert(schema.toEither)( + isRight(isStandardType(StandardType.ZonedDateTimeType)) ) }, test("decodes offsetTime with formatter") { @@ -1499,40 +1499,40 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"string","zio.schema.codec.stringType":"offsetTime","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.OffsetTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.OffsetTimeType))) }, test("decodes offsetTime with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"offsetTime"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.OffsetTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.OffsetTimeType))) }, test("decodes offsetDateTime with formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"offsetDateTime","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.OffsetDateTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.OffsetDateTimeType))) }, test("decodes offsetDateTime with default formatter") { val s = """{"type":"string","zio.schema.codec.stringType":"offsetDateTime"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)( - iszio.prelude.Validation.succeed(isStandardType(StandardType.OffsetDateTimeType)) + assert(schema.toEither)( + isRight(isStandardType(StandardType.OffsetDateTimeType)) ) }, test("decodes logical type uuid") { val s = """{"type":"string","logicalType":"uuid"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.UUIDType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.UUIDType))) }, test("decodes primitive type string") { val s = """{"type":"string"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.StringType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.StringType))) } ), suite("bytes")( @@ -1547,7 +1547,7 @@ object AvroCodecSpec extends ZIOSpecDefault { val hasPrecisionAnnotation: Assertion[Iterable[Any]] = exists(equalTo(AvroAnnotations.precision(20))) val hasAnnotationsAssertion = annotations(hasDecimalTypeAnnotation && hasScalaAnnotation && hasPrecisionAnnotation) - assert(schema)(iszio.prelude.Validation.succeed(isDecimalAssertion && hasAnnotationsAssertion)) + assert(schema.toEither)(isRight(isDecimalAssertion && hasAnnotationsAssertion)) }, test("logical type decimal as BigInteger") { val s = """{"type":"bytes","logicalType":"decimal","precision":20,"scale":20}""" @@ -1558,13 +1558,13 @@ object AvroCodecSpec extends ZIOSpecDefault { exists(equalTo(AvroAnnotations.decimal(DecimalType.Bytes))) val hasScalaAnnotation: Assertion[Iterable[Any]] = exists(equalTo(AvroAnnotations.scale(20))) val hasAnnotationsAssertion = annotations(hasDecimalTypeAnnotation && hasScalaAnnotation) - assert(schema)(iszio.prelude.Validation.succeed(isBigIntegerAssertion && hasAnnotationsAssertion)) + assert(schema.toEither)(isRight(isBigIntegerAssertion && hasAnnotationsAssertion)) }, test("decode as binary") { val s = """{"type":"bytes"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.BinaryType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.BinaryType))) } ), suite("int")( @@ -1572,69 +1572,69 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """{"type":"int","zio.schema.codec.intType":"char"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.CharType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.CharType))) }, test("decodes dayOfWeek") { val s = """{"type":"int","zio.schema.codec.intType":"dayOfWeek"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.DayOfWeekType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.DayOfWeekType))) }, test("decodes Year") { val s = """{"type":"int","zio.schema.codec.intType":"year"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.YearType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.YearType))) }, test("decodes short") { val s = """{"type":"int","zio.schema.codec.intType":"short"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.ShortType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.ShortType))) }, test("decodes month") { val s = """{"type":"int","zio.schema.codec.intType":"month"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.MonthType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.MonthType))) }, test("decodes zoneOffset") { val s = """{"type":"int","zio.schema.codec.intType":"zoneOffset"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.ZoneOffsetType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.ZoneOffsetType))) }, test("decodes int") { val s = """{"type":"int"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.IntType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.IntType))) }, test("decodes logical type timemillis") { val s = """{"type":"int","logicalType":"time-millis","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalTimeType))) }, test("decodes logical type timemillis with default formatter") { val s = """{"type":"int","logicalType":"time-millis"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalTimeType))) }, test("decodes logical type date") { val s = """{"type":"int","logicalType":"date"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalDateType))) }, test("decodes logical type date with default formatter") { val s = """{"type":"int","logicalType":"date"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalDateType))) } ), suite("long")( @@ -1642,60 +1642,60 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """{"type":"long"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LongType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LongType))) }, test("decodes logical type timeMicros") { val s = """{"type":"long","logicalType":"time-micros","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalTimeType))) }, test("decodes logical type timeMicros with default formatter") { val s = """{"type":"long","logicalType":"time-micros"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalTimeType))) }, test("decodes logical type timestampMillis") { val s = """{"type":"long","logicalType":"timestamp-millis","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.InstantType))) }, test("decodes logical type timestampMillis with default formatter") { val s = """{"type":"long","logicalType":"timestamp-millis"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.InstantType))) }, test("decodes logical type timestampMicros") { val s = """{"type":"long","logicalType":"timestamp-micros","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.InstantType))) }, test("decodes logical type timestampMicros with default formatter") { val s = """{"type":"long","logicalType":"timestamp-micros"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.InstantType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.InstantType))) }, test("decodes logical type LocalTimestamp millis") { val s = """{"type":"long","logicalType":"local-timestamp-millis","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalDateTimeType))) }, test("decodes logical type LocalTimestamp millis with default formatter") { val s = """{"type":"long","logicalType":"local-timestamp-millis"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)( - iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType)) + assert(schema.toEither)( + isRight(isStandardType(StandardType.LocalDateTimeType)) ) }, test("decodes logical type LocalTimestamp micros") { @@ -1703,14 +1703,14 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"long","logicalType":"local-timestamp-micros","zio.schema.codec.avro.dateTimeFormatter":"ISO_ORDINAL_DATE"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.LocalDateTimeType))) }, test("decodes logical type LocalTimestamp micros with default formatter") { val s = """{"type":"long","logicalType":"local-timestamp-micros"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)( - iszio.prelude.Validation.succeed(isStandardType(StandardType.LocalDateTimeType)) + assert(schema.toEither)( + isRight(isStandardType(StandardType.LocalDateTimeType)) ) } ), @@ -1718,25 +1718,25 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """{"type":"float"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.FloatType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.FloatType))) }, test("double") { val s = """{"type":"double"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.DoubleType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.DoubleType))) }, test("boolean") { val s = """{"type":"boolean"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.BoolType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.BoolType))) }, test("null") { val s = """{"type":"null"}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema)(iszio.prelude.Validation.succeed(isStandardType(StandardType.UnitType))) + assert(schema.toEither)(isRight(isStandardType(StandardType.UnitType))) } ), test("encode/decode full adt test") { @@ -1748,7 +1748,7 @@ object AvroCodecSpec extends ZIOSpecDefault { //_ <- AvroCodec.encode(decoded) TODO: this fails } yield decoded - assert(decoded)(iszio.prelude.Validation.succeed(hasField("ast", _.ast, equalTo(initialSchemaDerived.ast)))) + assert(decoded.toEither)(isRight(hasField("ast", _.ast, equalTo(initialSchemaDerived.ast)))) } @@ TestAspect.ignore // TODO: FIX ) } @@ -1819,19 +1819,19 @@ object AssertionHelper { ) ) - def iszio.prelude.Validation[A, B](assertion: Assertion[Schema.zio.prelude.Validation[A, B]]): Assertion[Schema[_]] = - Assertion.isCase[Schema[_], Schema.zio.prelude.Validation[A, B]]( + def isEither[A, B](assertion: Assertion[Schema.Either[A, B]]): Assertion[Schema[_]] = + Assertion.isCase[Schema[_], Schema.Either[A, B]]( "Either", { - case r: Schema.zio.prelude.Validation[_, _] => Try { r.asInstanceOf[Schema.zio.prelude.Validation[A, B]] }.toOption + case r: Schema.Either[_, _] => Try { r.asInstanceOf[Schema.Either[A, B]] }.toOption case _ => None }, assertion ) - def iszio.prelude.Validation[A, B](leftAssertion: Assertion[Schema[A]], rightAssertion: Assertion[Schema[B]]): Assertion[Schema[_]] = - iszio.prelude.Validation[A, B]( - hasField[Schema.zio.prelude.Validation[A, B], Schema[A]]("left", _.left, leftAssertion) && hasField[ - Schema.zio.prelude.Validation[A, B], + def isEither[A, B](leftAssertion: Assertion[Schema[A]], rightAssertion: Assertion[Schema[B]]): Assertion[Schema[_]] = + isEither[A, B]( + hasField[Schema.Either[A, B], Schema[A]]("left", _.left, leftAssertion) && hasField[ + Schema.Either[A, B], Schema[B] ]("right", _.right, rightAssertion) ) @@ -1859,7 +1859,7 @@ object AssertionHelper { def enumStructure(assertion: Assertion[ListMap[String, (Schema[_], Chunk[Any])]]): Assertion[Schema.Enum[_]] = Assertion.assertionRec("enumStructure")(assertion)( enum => - Some(`enum`.cases.foldzio.prelude.Validation.succeed(ListMap.empty[String, (Schema[_], Chunk[Any])]) { (caseValue, acc) => + Some(`enum`.cases.foldRight(ListMap.empty[String, (Schema[_], Chunk[Any])]) { (caseValue, acc) => (acc + (caseValue.id -> scala.Tuple2(caseValue.schema, caseValue.annotations))) }) ) @@ -2031,7 +2031,7 @@ object SpecTestData { // case class IterablesComplex(list: List[InnerRecord], map: Map[InnerRecord, Enum]) extends TopLevelUnion } - case class InnerRecord(s: String, union: Option[zio.prelude.Validation[String, Int]]) + case class InnerRecord(s: String, union: Option[scala.Either[String, Int]]) sealed trait Union case class NestedUnion(inner: InnerUnion) extends Union diff --git a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/Derive.scala b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/Derive.scala index e8f4b4e6a..a165db514 100644 --- a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/Derive.scala +++ b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/Derive.scala @@ -22,7 +22,7 @@ object Derive { val setTpe = c.typeOf[Set[_]] val vectorTpe = c.typeOf[Vector[_]] val chunkTpe = c.typeOf[Chunk[_]] - val eitherTpe = c.typeOf[zio.prelude.Validation[_, _]] + val eitherTpe = c.typeOf[scala.Either[_, _]] val tuple2Tpe = c.typeOf[Tuple2[_, _]] val tuple3Tpe = c.typeOf[Tuple3[_, _, _]] val tuple4Tpe = c.typeOf[Tuple4[_, _, _, _]] @@ -234,8 +234,8 @@ object Derive { val rightInstance = recurse(concreteType(tpe, rightTpe), rightSchema, currentFrame +: stack, top = false) q"""{ - lazy val $schemaRef = $forcedSchema.asInstanceOf[_root_.zio.schema.Schema.zio.prelude.Validation[$leftTpe, $rightTpe]] - lazy val $selfRefWithType = $deriver.derivezio.prelude.Validation[$leftTpe, $rightTpe]($schemaRef, $leftInstance, $rightInstance, $summoned) + lazy val $schemaRef = $forcedSchema.asInstanceOf[_root_.zio.schema.Schema.Either[$leftTpe, $rightTpe]] + lazy val $selfRefWithType = $deriver.deriveEither[$leftTpe, $rightTpe]($schemaRef, $leftInstance, $rightInstance, $summoned) $selfRef }""" } else if (tpe <:< tuple2Tpe) { diff --git a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala index a86186201..4b32b3333 100644 --- a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala @@ -97,7 +97,7 @@ object DeriveSchema { else recurse(schemaType, stack) case typeArg1 :: typeArg2 :: Nil => - if (schemaType <:< typeOf[zio.prelude.Validation[_, _]]) + if (schemaType <:< typeOf[Either[_, _]]) q"""_root_.zio.schema.Schema.either( _root_.zio.schema.Schema.defer(${directInferSchema( parentType, @@ -259,7 +259,7 @@ object DeriveSchema { } } }.filter(_ != EmptyTree) - .map(_.foldLeft[c.universe.Tree](q"_root_.zio.schema.validation.Validation.succeed") { + .map(_.foldLeft[c.universe.Tree](q"_root_.zio.schema.validation.SchemaValidation.succeed") { case (acc, t) => q"$acc && $t" }) }.getOrElse(Nil) @@ -299,7 +299,7 @@ object DeriveSchema { } """ } - q"""(m: scala.collection.immutable.ListMap[String, _]) => try { zio.prelude.Validation.succeed($tpeCompanion.apply(..$casts)) } catch { case e: Throwable => Left(e.getMessage) }""" + q"""(m: scala.collection.immutable.ListMap[String, _]) => try { zio.prelude.Validation.succeed($tpeCompanion.apply(..$casts)) } catch { case e: Throwable => zio.prelude.Validation.fail(e.getMessage) }""" } val toMap = { val tuples = fieldAccessors.map { fieldName => diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala index 02250b931..0d6b00d79 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala @@ -90,14 +90,14 @@ private case class DeriveInstance()(using val ctx: Quotes) extends ReflectionUti selfRef -> '{$deriver.deriveSequence[List, a]($seqSchemaRefExpr, $elemInstance, ${summoned})} ) case '[zio.prelude.Validation[a, b]] => - val (schemaRef, schemaRefExpr) = createSchemaRef[zio.prelude.Validation[a, b], Schema.zio.prelude.Validation[a, b]](stack) + val (schemaRef, schemaRefExpr) = createSchemaRef[zio.prelude.Validation[a, b], Schema.Either[a, b]](stack) val summoned = summonOptionalIfNotTop[F, zio.prelude.Validation[a, b]](top) val instanceA = deriveInstance[F, a](deriver, '{$schemaRefExpr.left}, stack) val instanceB = deriveInstance[F, b](deriver, '{$schemaRefExpr.right}, stack) lazyVals[F[A]](selfRef, - schemaRef -> '{Schema.force($schema).asInstanceOf[Schema.zio.prelude.Validation[a, b]]}, - selfRef -> '{$deriver.derivezio.prelude.Validation[a, b]($schemaRefExpr, $instanceA, $instanceB, $summoned)} + schemaRef -> '{Schema.force($schema).asInstanceOf[Schema.Either[a, b]]}, + selfRef -> '{$deriver.deriveEither[A, B]($schemaRefExpr, $instanceA, $instanceB, $summoned)} ) case '[Option[a]] => val (schemaRef, schemaRefExpr) = createSchemaRef[Option[a], Schema.Optional[a]](stack) diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala index ed97726c1..73b070878 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala @@ -233,7 +233,7 @@ private case class DeriveSchema()(using val ctx: Quotes) extends ReflectionUtils val fromMap = '{ (m: ListMap[String, _]) => try { zio.prelude.Validation.succeed(${appliedConstructor('m)}) } catch { - case e: Throwable => Left(e.getMessage) + case e: Throwable => zio.prelude.Validation.fail(e.getMessage) }} def tuples(b: Expr[T])(using Quotes) = @@ -338,7 +338,7 @@ private case class DeriveSchema()(using val ctx: Quotes) extends ReflectionUtils // Derive Field for a CaseClass def deriveField[T: Type](repr: TypeRepr, name: String, anns: List[Expr[Any]], stack: Stack)(using Quotes) = { - import zio.schema.validation.Validation + import zio.schema.validation.SchemaValidation import zio.schema.annotation.validate val tpe = TypeRepr.of[T] @@ -389,7 +389,7 @@ private case class DeriveSchema()(using val ctx: Quotes) extends ReflectionUtils // Derive Field for a GenericRecord def deriveGenericField[T: Type](repr: TypeRepr, name: String, anns: List[Expr[Any]], stack: Stack)(using Quotes) = { - import zio.schema.validation.Validation + import zio.schema.validation.SchemaValidation import zio.schema.annotation.validate val tpe = TypeRepr.of[T] 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 09c9112c7..5ed934417 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 @@ -65,12 +65,12 @@ private[schema] class CachedDeriver[F[_]] private (deriver: Deriver[F], val cach deriver.deriveMap(map, key, value, summoned) } - override def derivezio.prelude.Validation[A, B]( - either: Schema.zio.prelude.Validation[A, B], + override def deriveEither[A, B]( + either: Schema.Either[A, B], left: => F[A], right: => F[B], - summoned: => Option[F[zio.prelude.Validation[A, B]]] - ): F[zio.prelude.Validation[A, B]] = + summoned: => Option[F[Either[A, B]]] + ): F[Either[A, B]] = cached(either) { deriver.deriveEither(either, left, right, summoned) } @@ -121,7 +121,7 @@ private[schema] object CachedDeriver { final case class WithId[A](typeId: TypeId) extends CacheKey[A] final case class WithIdentityObject[A](inner: CacheKey[_], id: Any) extends CacheKey[A] final case class Optional[A](key: CacheKey[A]) extends CacheKey[A] - final case class zio.prelude.Validation[A, B](leftKey: CacheKey[A], rightKey: CacheKey[B]) extends CacheKey[zio.prelude.Validation[A, B]] + final case class Either[A, B](leftKey: CacheKey[A], rightKey: CacheKey[B]) extends CacheKey[Either[A, B]] 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]] @@ -142,7 +142,7 @@ private[schema] object CachedDeriver { case optional: Schema.Optional[_] => Optional(fromSchema(optional.schema)).asInstanceOf[CacheKey[A]] case tuple: Schema.Tuple2[_, _] => Tuple2(fromSchema(tuple.left), fromSchema(tuple.right)).asInstanceOf[CacheKey[A]] - case either: Schema.zio.prelude.Validation[_, _] => + case either: Schema.Either[_, _] => Either(fromSchema(either.leftSchema), fromSchema(either.rightSchema)).asInstanceOf[CacheKey[A]] case Schema.Lazy(schema0) => fromSchema(schema0()) case Schema.Dynamic(_) => Misc(schema) diff --git a/zio-schema-derivation/shared/src/main/scala/zio/schema/Deriver.scala b/zio-schema-derivation/shared/src/main/scala/zio/schema/Deriver.scala index 48afbf6e1..da1481116 100644 --- a/zio-schema-derivation/shared/src/main/scala/zio/schema/Deriver.scala +++ b/zio-schema-derivation/shared/src/main/scala/zio/schema/Deriver.scala @@ -82,12 +82,12 @@ trait Deriver[F[_]] extends VersionSpecificDeriver[F] { self => summoned: => Option[F[Map[K, V]]] ): F[Map[K, V]] - def derivezio.prelude.Validation[A, B]( - either: Schema.zio.prelude.Validation[A, B], + def deriveEither[A, B]( + either: Schema.Either[A, B], left: => F[A], right: => F[B], - summoned: => Option[F[zio.prelude.Validation[A, B]]] - ): F[zio.prelude.Validation[A, B]] = + summoned: => Option[F[Either[A, B]]] + ): F[Either[A, B]] = deriveEnum( either.toEnum, Chunk(wrap(left), wrap(right)), @@ -179,12 +179,12 @@ trait Deriver[F[_]] extends VersionSpecificDeriver[F] { self => self.deriveMap(map, key, value, summoned) } - final override def derivezio.prelude.Validation[A, B]( - either: Schema.zio.prelude.Validation[A, B], + final override def deriveEither[A, B]( + either: Schema.Either[A, B], left: => F[A], right: => F[B], - summoned: => Option[F[zio.prelude.Validation[A, B]]] - ): F[zio.prelude.Validation[A, B]] = + summoned: => Option[F[Either[A, B]]] + ): F[Either[A, B]] = summoned.getOrElse { self.deriveEither(either, left, right, summoned) } diff --git a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSchemaSpec.scala b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSchemaSpec.scala index 3c3a92516..0421fc248 100644 --- a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSchemaSpec.scala +++ b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSchemaSpec.scala @@ -376,12 +376,12 @@ object DeriveSchemaSpec extends ZIOSpecDefault with VersionSpecificDeriveSchemaS val a = DependsOnA(Some(DependsOnB(None))) val a0 = Schema[DependsOnA].fromDynamic(Schema[DependsOnA].toDynamic(a)) assert(Schema[DependsOnA])(anything) - assert(a0)(iszio.prelude.Validation.succeed(equalTo(a))) + assert(a0.toEither)(isRight(equalTo(a))) val b = DependsOnB(Some(DependsOnA(None))) val b0 = Schema[DependsOnB].fromDynamic(Schema[DependsOnB].toDynamic(b)) assert(Schema[DependsOnB])(anything) - assert(b0)(iszio.prelude.Validation.succeed(equalTo(b))) + assert(b0.toEither)(isRight(equalTo(b))) }, test("correctly derives recursive Enum with type parameters") { val derived: Schema[Tree[Recursive]] = DeriveSchema.gen[Tree[Recursive]] diff --git a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala index 414932139..352062601 100644 --- a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala +++ b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala @@ -223,7 +223,7 @@ object DeriveSpec extends ZIOSpecDefault with VersionSpecificDeriveSpec { implicit val schema: Schema[Record5] = DeriveSchema.gen[Record5] } - case class Record6(map: Map[String, Record1], either: zio.prelude.Validation[String, Record2]) + case class Record6(map: Map[String, Record1], either: scala.Either[String, Record2]) object Record6 { implicit val schema: Schema[Record6] = DeriveSchema.gen[Record6] @@ -426,16 +426,16 @@ object DeriveSpec extends ZIOSpecDefault with VersionSpecificDeriveSpec { } } - override def derivezio.prelude.Validation[A, B]( - either: Schema.zio.prelude.Validation[A, B], + override def deriveEither[A, B]( + either: Schema.Either[A, B], left: => TC[A], right: => TC[B], - summoned: => Option[TC[zio.prelude.Validation[A, B]]] - ): TC[zio.prelude.Validation[A, B]] = + summoned: => Option[TC[Either[A, B]]] + ): TC[Either[A, B]] = summoned.getOrElse { assert(left ne null) assert(right ne null) - new TC[zio.prelude.Validation[A, B]] { + new TC[Either[A, B]] { override def isDerived: Boolean = true override def inner: Option[TC[_]] = Some(right) } diff --git a/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaValidationSpec.scala b/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec$.scala similarity index 56% rename from zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaValidationSpec.scala rename to zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec$.scala index 4c83e6f78..1a31a0ec2 100644 --- a/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaValidationSpec.scala +++ b/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec$.scala @@ -3,14 +3,14 @@ package zio.schema import zio._ import zio.schema.Schema._ import zio.schema.annotation.validate -import zio.schema.validation.{ Validation, ValidationError } +import zio.schema.validation.{ SchemaValidation, SchemaValidationError } import zio.test._ -object SchemaValidationSpec extends ZIOSpecDefault { +object SchemaSchemaValidationSpec$ extends ZIOSpecDefault { import Assertion._ final case class ExampleData( - either: zio.prelude.Validation[Person, Person] = zio.prelude.Validation.succeed(goodData), + either: scala.Either[Person, Person] = Right(goodData), option: Option[Person] = None, list: List[Person] = goodData :: Nil, tuple: scala.Tuple2[Person, Person] = (goodData, goodData), @@ -29,17 +29,17 @@ object SchemaValidationSpec extends ZIOSpecDefault { final case class Wrapper(person: Person) implicit val schema - : CaseClass6[zio.prelude.Validation[Person, Person], Option[Person], List[Person], (Person, Person), Wrapper, EnumData, ExampleData] = + : CaseClass6[scala.Either[Person, Person], Option[Person], List[Person], (Person, Person), Wrapper, EnumData, ExampleData] = DeriveSchema.gen[ExampleData] val badData: Person = Person("foo", 123123123) val goodData: Person = Person("foo", 100) - final case class Person(name: String, @validate(Validation.between(0, 120)) age: Int) + final case class Person(name: String, @validate(SchemaValidation.between(0, 120)) age: Int) // val schemaCaseClass2: Schema.CaseClass2[String, Int, Person] = DeriveSchema.gen[Person] val schemaPerson: CaseClass2[String, Int, Person] = DeriveSchema.gen[Person] - final case class Grade(@validate(Validation.greaterThan(0)) value: Int) + final case class Grade(@validate(SchemaValidation.greaterThan(0)) value: Int) // val schemaCaseClass1: Schema.CaseClass1[Int, Grade] = DeriveSchema.gen[Grade] val schemaGrade: CaseClass1[Int, Grade] = DeriveSchema.gen[Grade] @@ -47,70 +47,70 @@ object SchemaValidationSpec extends ZIOSpecDefault { test("Invalid CaseClass1 creation") { val grade = Grade(-50) implicit val gradeSchema: Schema[Grade] = schemaGrade - val validated: Chunk[ValidationError] = Schema.validate(grade) + val validated: Chunk[SchemaValidationError] = Schema.validate(grade) - val expected: Chunk[ValidationError] = - Chunk(ValidationError.GreaterThan(-50, 0)) + val expected: Chunk[SchemaValidationError] = + Chunk(SchemaValidationError.GreaterThan(-50, 0)) assert(validated)(Assertion.hasSameElements(expected)) }, test("Valid CaseClass1 creation") { val grade = Grade(97) implicit val gradeSchema: Schema[Grade] = schemaGrade - val validated: Chunk[ValidationError] = Schema.validate(grade) + val validated: Chunk[SchemaValidationError] = Schema.validate(grade) - val expected: Chunk[ValidationError] = Chunk.empty + val expected: Chunk[SchemaValidationError] = Chunk.empty assert(validated)(equalTo(expected)) }, test("Invalid CaseClass2 creation") { val person = Person("Michelle", 200) implicit val personSchema: Schema[Person] = schemaPerson - val validated: Chunk[ValidationError] = Schema.validate(person) + val validated: Chunk[SchemaValidationError] = Schema.validate(person) - val expected: Chunk[ValidationError] = - Chunk(ValidationError.LessThan(200, 120), ValidationError.EqualTo(200, 120)) + val expected: Chunk[SchemaValidationError] = + Chunk(SchemaValidationError.LessThan(200, 120), SchemaValidationError.EqualTo(200, 120)) assert(validated)(Assertion.hasSameElements(expected)) }, test("Valid CaseClass2 creation") { val person = Person("Michelle", 20) implicit val personSchema: Schema[Person] = schemaPerson - val validated: Chunk[ValidationError] = Schema.validate(person) + val validated: Chunk[SchemaValidationError] = Schema.validate(person) - val expected: Chunk[ValidationError] = Chunk.empty + val expected: Chunk[SchemaValidationError] = Chunk.empty assert(validated)(Assertion.hasSameElements(expected)) }, test("Example Data, no ValidationErrors") { val exampleData = ExampleData() - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk.empty + val expected: Chunk[SchemaValidationError] = Chunk.empty assert(validated)(hasSameElements(expected)) }, test("Example Data, Left ValidationError") { val exampleData = ExampleData(either = Left(badData)) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk( - ValidationError.LessThan(123123123, 120), - ValidationError.EqualTo(123123123, 120) + val expected: Chunk[SchemaValidationError] = Chunk( + SchemaValidationError.LessThan(123123123, 120), + SchemaValidationError.EqualTo(123123123, 120) ) assert(validated)(Assertion.hasSameElements(expected)) }, test("Example Data, Right ValidationError") { - val exampleData = ExampleData(either = zio.prelude.Validation.succeed(badData)) + val exampleData = ExampleData(either = Right(badData)) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk( - ValidationError.LessThan(123123123, 120), - ValidationError.EqualTo(123123123, 120) + val expected: Chunk[SchemaValidationError] = Chunk( + SchemaValidationError.LessThan(123123123, 120), + SchemaValidationError.EqualTo(123123123, 120) ) assert(validated)(Assertion.hasSameElements(expected)) @@ -118,20 +118,20 @@ object SchemaValidationSpec extends ZIOSpecDefault { test("Example Data, Option value without ValidationError") { val exampleData = ExampleData(option = Some(goodData)) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk.empty + val expected: Chunk[SchemaValidationError] = Chunk.empty assert(validated)(Assertion.hasSameElements(expected)) }, test("Example Data, Option value with ValidationError") { val exampleData = ExampleData(option = Some(badData)) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk( - ValidationError.LessThan(123123123, 120), - ValidationError.EqualTo(123123123, 120) + val expected: Chunk[SchemaValidationError] = Chunk( + SchemaValidationError.LessThan(123123123, 120), + SchemaValidationError.EqualTo(123123123, 120) ) assert(validated)(Assertion.hasSameElements(expected)) @@ -139,11 +139,11 @@ object SchemaValidationSpec extends ZIOSpecDefault { test("Example Data, single element List with ValidationError") { val exampleData = ExampleData(list = badData :: Nil) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk( - ValidationError.LessThan(123123123, 120), - ValidationError.EqualTo(123123123, 120) + val expected: Chunk[SchemaValidationError] = Chunk( + SchemaValidationError.LessThan(123123123, 120), + SchemaValidationError.EqualTo(123123123, 120) ) assert(validated)(Assertion.hasSameElements(expected)) @@ -151,11 +151,11 @@ object SchemaValidationSpec extends ZIOSpecDefault { test("Example Data, multi element List with ValidationError") { val exampleData = ExampleData(list = goodData :: goodData :: badData :: Nil) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk( - ValidationError.LessThan(123123123, 120), - ValidationError.EqualTo(123123123, 120) + val expected: Chunk[SchemaValidationError] = Chunk( + SchemaValidationError.LessThan(123123123, 120), + SchemaValidationError.EqualTo(123123123, 120) ) assert(validated)(Assertion.hasSameElements(expected)) @@ -163,11 +163,11 @@ object SchemaValidationSpec extends ZIOSpecDefault { test("Example Data, Tuple with ValidationError on first element") { val exampleData = ExampleData(tuple = (badData, goodData)) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk( - ValidationError.LessThan(123123123, 120), - ValidationError.EqualTo(123123123, 120) + val expected: Chunk[SchemaValidationError] = Chunk( + SchemaValidationError.LessThan(123123123, 120), + SchemaValidationError.EqualTo(123123123, 120) ) assert(validated)(Assertion.hasSameElements(expected)) @@ -175,11 +175,11 @@ object SchemaValidationSpec extends ZIOSpecDefault { test("Example Data, Tuple with ValidationError on second element") { val exampleData = ExampleData(tuple = (goodData, badData)) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk( - ValidationError.LessThan(123123123, 120), - ValidationError.EqualTo(123123123, 120) + val expected: Chunk[SchemaValidationError] = Chunk( + SchemaValidationError.LessThan(123123123, 120), + SchemaValidationError.EqualTo(123123123, 120) ) assert(validated)(Assertion.hasSameElements(expected)) @@ -187,11 +187,11 @@ object SchemaValidationSpec extends ZIOSpecDefault { test("Example Data, Wrapper class wrapping class with ValidationError") { val exampleData = ExampleData(wrapper = Wrapper(badData)) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk( - ValidationError.LessThan(123123123, 120), - ValidationError.EqualTo(123123123, 120) + val expected: Chunk[SchemaValidationError] = Chunk( + SchemaValidationError.LessThan(123123123, 120), + SchemaValidationError.EqualTo(123123123, 120) ) assert(validated)(Assertion.hasSameElements(expected)) @@ -199,11 +199,11 @@ object SchemaValidationSpec extends ZIOSpecDefault { test("Example Data, first Enum with ValidationError") { val exampleData = ExampleData(enumData = EnumData.Case1(badData)) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk( - ValidationError.LessThan(123123123, 120), - ValidationError.EqualTo(123123123, 120) + val expected: Chunk[SchemaValidationError] = Chunk( + SchemaValidationError.LessThan(123123123, 120), + SchemaValidationError.EqualTo(123123123, 120) ) assert(validated)(Assertion.hasSameElements(expected)) @@ -211,11 +211,11 @@ object SchemaValidationSpec extends ZIOSpecDefault { test("Example Data, second Enum with ValidationError") { val exampleData = ExampleData(enumData = EnumData.Case2(badData)) - val validated: Chunk[ValidationError] = Schema.validate(exampleData) + val validated: Chunk[SchemaValidationError] = Schema.validate(exampleData) - val expected: Chunk[ValidationError] = Chunk( - ValidationError.LessThan(123123123, 120), - ValidationError.EqualTo(123123123, 120) + val expected: Chunk[SchemaValidationError] = Chunk( + SchemaValidationError.LessThan(123123123, 120), + SchemaValidationError.EqualTo(123123123, 120) ) assert(validated)(Assertion.hasSameElements(expected)) @@ -240,7 +240,7 @@ object SchemaValidationSpec extends ZIOSpecDefault { test("Validator successfully extracts from validation annotation") { val validation = schemaPerson.field2.validation - assertTrue(validation.validate(45).isRight) && assertTrue(validation.validate(-20).isLeft) + assertTrue(validation.validate(45).toEither.isRight) && assertTrue(validation.validate(-20).toEither.isLeft) } ) } diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example1/Example1.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example1/Example1.scala deleted file mode 100644 index 7a9b2188a..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example1/Example1.scala +++ /dev/null @@ -1,244 +0,0 @@ -package dev.zio.schema.example.example1 - -import zio._ -import zio.schema.{ DeriveSchema, Schema, TypeId } -import zio.stream.ZPipeline - -/** - * Example 1 of ZIO-Schema: - * - * In this example we define our basic Domain Model. - * Then we'll show how to manually construct a Schema for the given domain model - * and how to derive one using macros. - * - * We'll then use the Schema to transform instances of our classes (Person) to/from JSON and Protobuf. - */ - -object Domain { - sealed trait PaymentMethod - - final case class Person(name: String, age: Int) - - final case class Customer(person: Person, paymentMethod: PaymentMethod) - - object PaymentMethod { - final case class CreditCard(number: String, expirationMonth: Int, expirationYear: Int) extends PaymentMethod - final case class WireTransfer(accountNumber: String, bankCode: String) extends PaymentMethod - } -} - -import dev.zio.schema.example.example1.Domain._ - -object ManualConstruction { - import Domain.PaymentMethod._ - import zio.schema.Schema._ - - val schemaPerson: Schema[Person] = Schema.CaseClass2[String, Int, Person]( - TypeId.parse("dev.zio.schema.example.example1.Domain.Person"), - field01 = - Schema.Field[Person, String]("name", Schema.primitive[String], get0 = _.name, set0 = (p, v) => p.copy(name = v)), - field02 = Schema.Field[Person, Int]("age", Schema.primitive[Int], get0 = _.age, set0 = (p, v) => p.copy(age = v)), - construct0 = (name, age) => Person(name, age) - ) - - val schemaPaymentMethodWireTransfer: Schema[WireTransfer] = Schema.CaseClass2[String, String, WireTransfer]( - TypeId.parse("dev.zio.schema.example.example1.Domain.PaymentMethod.WireTransfer"), - field01 = Schema.Field[WireTransfer, String]( - "accountNumber", - Schema.primitive[String], - get0 = _.accountNumber, - set0 = (p, v) => p.copy(accountNumber = v) - ), - field02 = Schema.Field[WireTransfer, String]( - "bankCode", - Schema.primitive[String], - get0 = _.bankCode, - set0 = (p, v) => p.copy(bankCode = v) - ), - construct0 = (number, bankCode) => PaymentMethod.WireTransfer(number, bankCode) - ) - - val schemaPaymentMethodCreditCard: Schema[CreditCard] = Schema.CaseClass3[String, Int, Int, CreditCard]( - TypeId.parse("dev.zio.schema.example.example1.Domain.PaymentMethod.CreditCard"), - field01 = Schema.Field[CreditCard, String]( - "number", - Schema.primitive[String], - get0 = _.number, - set0 = (p, v) => p.copy(number = v) - ), - field02 = Schema.Field[CreditCard, Int]( - "expirationMonth", - Schema.primitive[Int], - get0 = _.expirationMonth, - set0 = (p, v) => p.copy(expirationMonth = v) - ), - field03 = Schema.Field[CreditCard, Int]( - "expirationYear", - Schema.primitive[Int], - get0 = _.expirationYear, - set0 = (p, v) => p.copy(expirationYear = v) - ), - construct0 = - (number, expirationMonth, expirationYear) => PaymentMethod.CreditCard(number, expirationMonth, expirationYear) - ) - - val schemaPaymentMethod: Schema[PaymentMethod] = - Schema.Enum2[PaymentMethod.CreditCard, PaymentMethod.WireTransfer, PaymentMethod]( - id = TypeId.parse("dev.zio.schema.example.example1.Domain.PaymentMethod"), - case1 = Case[PaymentMethod, PaymentMethod.CreditCard]( - id = "CreditCard", - schema = schemaPaymentMethodCreditCard, - unsafeDeconstruct = pm => pm.asInstanceOf[PaymentMethod.CreditCard], - construct = pc => pc.asInstanceOf[PaymentMethod], - isCase = _.isInstanceOf[PaymentMethod.CreditCard], - annotations = Chunk.empty - ), - case2 = Case[PaymentMethod, PaymentMethod.WireTransfer]( - id = "WireTransfer", - schema = schemaPaymentMethodWireTransfer, - unsafeDeconstruct = pm => pm.asInstanceOf[PaymentMethod.WireTransfer], - construct = pc => pc.asInstanceOf[PaymentMethod], - isCase = _.isInstanceOf[PaymentMethod.WireTransfer], - annotations = Chunk.empty - ), - annotations = Chunk.empty - ) - - val schemaCustomer: Schema[Customer] = Schema.CaseClass2[Person, PaymentMethod, Customer]( - TypeId.parse("dev.zio.schema.example.example1.Domain.Customer"), - field01 = - Schema.Field[Customer, Person]("person", schemaPerson, get0 = _.person, set0 = (p, v) => p.copy(person = v)), - field02 = Schema.Field[Customer, PaymentMethod]( - "paymentMethod", - schemaPaymentMethod, - get0 = _.paymentMethod, - set0 = (p, v) => p.copy(paymentMethod = v) - ), - construct0 = (person, paymentMethod) => Customer(person, paymentMethod) - ) - - val schemaPersonDictionary: Schema[scala.collection.immutable.Map[String, Person]] = - Schema.map( - Schema.primitive[String], - Schema[Person](schemaPerson) - ) - -} - -object MacroConstruction { - - implicit val schemaPerson: Schema[Person] = DeriveSchema.gen[Person] - - val schemaPaymentMethod: Schema[PaymentMethod] = DeriveSchema.gen[PaymentMethod] - - val schemaCustomer: Schema[Customer] = DeriveSchema.gen[Customer] - - val schemaPersonDictionaryFromMacro: Schema[scala.collection.immutable.Map[String, Person]] = - DeriveSchema.gen[Map[String, Person]] - -} - -object JsonSample extends zio.ZIOAppDefault { - import ManualConstruction._ - import zio.schema.codec.JsonCodec - import zio.stream.ZStream - - override def run: ZIO[Environment with ZIOAppArgs, Any, Any] = - for { - _ <- ZIO.unit - person = Person("Michelle", 32) - personToJsonTransducer = JsonCodec.schemaBasedBinaryCodec[Person](schemaPerson).streamEncoder - _ <- ZStream(person) - .via(personToJsonTransducer) - .via(ZPipeline.utf8Decode) - .foreach(ZIO.debug(_)) - } yield ExitCode.success -} - -object ProtobufExample extends ZIOAppDefault { - import ManualConstruction._ - import zio.schema.codec.ProtobufCodec - import zio.stream.ZStream - - override def run: ZIO[Environment with ZIOAppArgs, Any, Any] = - for { - _ <- ZIO.unit - _ <- ZIO.debug("protobuf roundtrip") - person = Person("Michelle", 32) - - personToProto = ProtobufCodec.protobufCodec[Person](schemaPerson).streamEncoder - protoToPerson = ProtobufCodec.protobufCodec[Person](schemaPerson).streamDecoder - - newPerson <- ZStream(person) - .via(personToProto) - .via(protoToPerson) - .runHead - .some - .catchAll(error => ZIO.debug(error)) - _ <- ZIO.debug("is old person the new person? " + (person == newPerson).toString) - _ <- ZIO.debug("old person: " + person) - _ <- ZIO.debug("new person: " + newPerson) - } yield ExitCode.success -} - -object CombiningExample extends ZIOAppDefault { - import ManualConstruction._ - import zio.schema.codec.{ JsonCodec, ProtobufCodec } - import zio.stream.ZStream - - override def run: ZIO[Environment with ZIOAppArgs, Any, Any] = - for { - _ <- ZIO.unit - _ <- ZIO.debug("combining roundtrip") - person = Person("Michelle", 32) - - personToJson = JsonCodec.schemaBasedBinaryCodec[Person](schemaPerson).streamEncoder - jsonToPerson = JsonCodec.schemaBasedBinaryCodec[Person](schemaPerson).streamDecoder - - personToProto = ProtobufCodec.protobufCodec[Person](schemaPerson).streamEncoder - protoToPerson = ProtobufCodec.protobufCodec[Person](schemaPerson).streamDecoder - - newPerson <- ZStream(person) - .tap(v => ZIO.debug("input object is: " + v)) - .via(personToJson) - .via(jsonToPerson) - .tap(v => ZIO.debug("object after json roundtrip: " + v)) - .via(personToProto) - .via(protoToPerson) - .tap(v => ZIO.debug("person after protobuf roundtrip: " + v)) - .runHead - .some - .catchAll(error => ZIO.debug(error)) - _ <- ZIO.debug("is old person the new person? " + (person == newPerson).toString) - _ <- ZIO.debug("old person: " + person) - _ <- ZIO.debug("new person: " + newPerson) - } yield ExitCode.success -} - -object DictionaryExample extends ZIOAppDefault { - - import MacroConstruction._ - import zio.schema.codec.JsonCodec - import zio.stream.ZStream - override def run: ZIO[Environment with ZIOAppArgs, Any, Any] = - for { - _ <- ZIO.unit - person = Person("Mike", 32) - dictionary = Map("m" -> person) - dictionaryToJson = JsonCodec - .schemaBasedBinaryCodec[scala.collection.immutable.Map[String, Person]](schemaPersonDictionaryFromMacro) - .streamEncoder - jsonToDictionary = JsonCodec - .schemaBasedBinaryCodec[scala.collection.immutable.Map[String, Person]](schemaPersonDictionaryFromMacro) - .streamDecoder - newPersonDictionary <- ZStream(dictionary) - .via(dictionaryToJson) - .via(jsonToDictionary) - .runHead - .some - .catchAll(error => ZIO.debug(error)) - _ <- ZIO.debug("is old dictionary the new dictionary? " + (dictionary == newPersonDictionary).toString) - _ <- ZIO.debug("old dictionary: " + dictionary) - _ <- ZIO.debug("new dictionary: " + newPersonDictionary) - } yield ExitCode.success -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example2/Example2.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example2/Example2.scala deleted file mode 100644 index 3bc56004e..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example2/Example2.scala +++ /dev/null @@ -1,225 +0,0 @@ -package dev.zio.schema.example.example2 - -import zio._ -import zio.schema.Schema._ -import zio.schema.{ Schema, TypeId } -import zio.stream.ZPipeline - -/** - * Example 2 of ZIO-Schema - * - * In this example, we pull the definition of our schema into the companion objects of our types. - * This will help us in the future to avoid having to write the same code over and over again. - * - * Again we'll also show that the moved schema can still be used to transform an object from/to JSON and Protobuf. - */ - -object Domain { - sealed trait PaymentMethod - - final case class Person(name: String, age: Int) - - object Person { - - val name: Field[Person, String] = - Schema.Field[Person, String]("name", Schema.primitive[String], get0 = _.name, set0 = (p, v) => p.copy(name = v)) - - val age: Field[Person, Int] = - Schema.Field[Person, Int]("age", Schema.primitive[Int], get0 = _.age, set0 = (p, v) => p.copy(age = v)) - - val schema: Schema[Person] = Schema.CaseClass2[String, Int, Person]( - TypeId.parse("dev.zio.schema.example.example2.Domain.Person"), - field01 = name, - field02 = age, - construct0 = (name, age) => Person(name, age) - ) - } - - object PaymentMethod { - final case class CreditCard(number: String, expirationMonth: Int, expirationYear: Int) extends PaymentMethod - - object CreditCard { - - val number: Field[CreditCard, String] = - Schema.Field[CreditCard, String]( - "number", - Schema.primitive[String], - get0 = _.number, - set0 = (p, v) => p.copy(number = v) - ) - - val expirationMonth: Field[CreditCard, Int] = - Schema.Field[CreditCard, Int]( - "expirationMonth", - Schema.primitive[Int], - get0 = _.expirationMonth, - set0 = (p, v) => p.copy(expirationMonth = v) - ) - - val expirationYear: Field[CreditCard, Int] = - Schema.Field[CreditCard, Int]( - "expirationYear", - Schema.primitive[Int], - get0 = _.expirationYear, - set0 = (p, v) => p.copy(expirationYear = v) - ) - implicit val schema: Schema[CreditCard] = Schema.CaseClass3[String, Int, Int, CreditCard]( - TypeId.parse("dev.zio.schema.example.example2.Domain.PaymentMethod.CreditCard"), - field01 = number, - field02 = expirationMonth, - field03 = expirationYear, - construct0 = - (number, expirationMonth, expirationYear) => PaymentMethod.CreditCard(number, expirationMonth, expirationYear) - ) - } - - final case class WireTransfer(accountNumber: String, bankCode: String) extends PaymentMethod - - object WireTransfer { - - val accountNumber: Field[WireTransfer, String] = - Schema.Field[WireTransfer, String]( - "accountNumber", - Schema.primitive[String], - get0 = _.accountNumber, - set0 = (p, v) => p.copy(accountNumber = v) - ) - - val bankCode: Field[WireTransfer, String] = - Schema.Field[WireTransfer, String]( - "bankCode", - Schema.primitive[String], - get0 = _.bankCode, - set0 = (p, v) => p.copy(bankCode = v) - ) - - implicit val schema: Schema[WireTransfer] = Schema.CaseClass2[String, String, WireTransfer]( - TypeId.parse("dev.zio.schema.example.example2.Domain.PaymentMethod.WireTransfer"), - field01 = accountNumber, - field02 = bankCode, - construct0 = (number, bankCode) => PaymentMethod.WireTransfer(number, bankCode) - ) - } - - val schemaPaymentMethod: Schema[PaymentMethod] = Schema.Enum2[CreditCard, WireTransfer, PaymentMethod]( - id = TypeId.parse("dev.zio.schema.example.example2.Domain.PaymentMethod"), - case1 = Case[PaymentMethod, CreditCard]( - id = "CreditCard", - schema = CreditCard.schema, - unsafeDeconstruct = pm => pm.asInstanceOf[PaymentMethod.CreditCard], - construct = pc => pc.asInstanceOf[PaymentMethod], - isCase = _.isInstanceOf[PaymentMethod.CreditCard], - annotations = Chunk.empty - ), - case2 = Case[PaymentMethod, WireTransfer]( - id = "WireTransfer", - schema = WireTransfer.schema, - unsafeDeconstruct = pm => pm.asInstanceOf[PaymentMethod.WireTransfer], - construct = pc => pc.asInstanceOf[PaymentMethod], - isCase = _.isInstanceOf[PaymentMethod.WireTransfer], - annotations = Chunk.empty - ), - annotations = Chunk.empty - ) - - } - - final case class Customer(person: Person, paymentMethod: PaymentMethod) - - object Customer { - - val person: Field[Customer, Person] = - Schema.Field[Customer, Person]("person", Person.schema, get0 = _.person, set0 = (p, v) => p.copy(person = v)) - - val paymentMethod: Field[Customer, PaymentMethod] = - Schema.Field[Customer, PaymentMethod]( - "paymentMethod", - PaymentMethod.schemaPaymentMethod, - get0 = _.paymentMethod, - set0 = (p, v) => p.copy(paymentMethod = v) - ) - - implicit val schema: Schema[Customer] = Schema.CaseClass2[Person, PaymentMethod, Customer]( - TypeId.parse("dev.zio.schema.example.example2.Domain.Customer"), - field01 = Customer.person, - field02 = Customer.paymentMethod, - construct0 = (person, paymentMethod) => Customer(person, paymentMethod) - ) - } -} - -import dev.zio.schema.example.example2.Domain._ - -object JsonSample extends zio.ZIOAppDefault { - import zio.schema.codec.JsonCodec - import zio.stream.ZStream - - override def run: ZIO[Environment with ZIOAppArgs, Any, Any] = - for { - _ <- ZIO.unit - person = Person("Michelle", 32) - personToJsonPipeline = JsonCodec.schemaBasedBinaryCodec[Person](Person.schema).streamEncoder - _ <- ZStream(person) - .via(personToJsonPipeline) - .via(ZPipeline.utf8Decode) - .foreach(f => ZIO.debug(f)) - } yield ExitCode.success -} - -object ProtobufExample extends ZIOAppDefault { - import zio.schema.codec.ProtobufCodec - import zio.stream.ZStream - - override def run: ZIO[Environment with ZIOAppArgs, Any, Any] = - for { - _ <- ZIO.unit - _ <- ZIO.debug("protobuf roundtrip") - person = Person("Michelle", 32) - - personToProto = ProtobufCodec.protobufCodec[Person](Person.schema).streamEncoder - protoToPerson = ProtobufCodec.protobufCodec[Person](Person.schema).streamDecoder - - newPerson <- ZStream(person) - .via(personToProto) - .via(protoToPerson) - .runHead - .some - .catchAll(error => ZIO.debug(error)) - _ <- ZIO.debug("is old person the new person? " + (person == newPerson).toString) - _ <- ZIO.debug("old person: " + person) - _ <- ZIO.debug("new person: " + newPerson) - } yield ExitCode.success -} - -object CombiningExample extends zio.ZIOAppDefault { - import zio.schema.codec.{ JsonCodec, ProtobufCodec } - import zio.stream.ZStream - - override def run: ZIO[Environment with ZIOAppArgs, Any, Any] = - for { - _ <- ZIO.unit - _ <- ZIO.debug("combining roundtrip") - person = Person("Michelle", 32) - - personToJson = JsonCodec.schemaBasedBinaryCodec[Person](Person.schema).streamEncoder - jsonToPerson = JsonCodec.schemaBasedBinaryCodec[Person](Person.schema).streamDecoder - - personToProto = ProtobufCodec.protobufCodec[Person](Person.schema).streamEncoder - protoToPerson = ProtobufCodec.protobufCodec[Person](Person.schema).streamDecoder - - newPerson <- ZStream(person) - .tap(v => ZIO.debug("input object is: " + v)) - .via(personToJson) - .via(jsonToPerson) - .tap(v => ZIO.debug("object after json roundtrip: " + v)) - .via(personToProto) - .via(protoToPerson) - .tap(v => ZIO.debug("person after protobuf roundtrip: " + v)) - .runHead - .some - .catchAll(error => ZIO.debug(error)) - _ <- ZIO.debug("is old person the new person? " + (person == newPerson).toString) - _ <- ZIO.debug("old person: " + person) - _ <- ZIO.debug("new person: " + newPerson) - } yield ExitCode.success -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example3/Example3.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example3/Example3.scala deleted file mode 100644 index 127fb89ce..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example3/Example3.scala +++ /dev/null @@ -1,88 +0,0 @@ -package dev.zio.schema.example.example3 - -import zio._ -import zio.schema.Schema._ -import zio.schema._ - -/** - * Example3: - * In this example we'll take a look on how to use ZIO-Schema to - * transform a PersonDTO (e.g. from a REST API) into a Person (e.g. for a database) in a single step. - * - * To do this, we'll transform the Schema of the PersonDTO into a Schema of the Person. - **/ -private[example3] object Domain { - final case class Person(name: String, age: Int) - - object Person { - - val name: Field[Person, String] = - Field[Person, String]("name", primitive[String], get0 = _.name, set0 = (p, v) => p.copy(name = v)) - - val age: Field[Person, Int] = - Field[Person, Int]("age", primitive[Int], get0 = _.age, set0 = (p, v) => p.copy(age = v)) - - val schema: Schema[Person] = CaseClass2[String, Int, Person]( - TypeId.parse("dev.zio.example.example3.Domain.Person"), - field01 = name, - field02 = age, - construct0 = (name, age) => Person(name, age) - ) - } - - final case class PersonDTO(firstname: String, lastname: String, years: Int) - - object PersonDTO { - - val firstname: Field[PersonDTO, String] = - Field("firstname", primitive[String], get0 = _.firstname, set0 = (p, v) => p.copy(firstname = v)) - - val lastname: Field[PersonDTO, String] = - Field("lastname", primitive[String], get0 = _.lastname, set0 = (p, v) => p.copy(lastname = v)) - - val years: Field[PersonDTO, Int] = - Field("years", primitive[Int], get0 = _.years, set0 = (p, v) => p.copy(years = v)) - - val schema: Schema[PersonDTO] = CaseClass3[String, String, Int, PersonDTO]( - TypeId.parse("dev.zio.example.example3.Domain.PersonDTO"), - field01 = firstname, - field02 = lastname, - field03 = years, - construct0 = (fn, ln, y) => PersonDTO(fn, ln, y) - ) - } - -} - -object Example3 extends ZIOAppDefault { - import dev.zio.schema.example.example3.Domain._ - import zio.schema.codec.JsonCodec - - val personTransformation: Schema[Person] = PersonDTO.schema.transform[Person]( - (dto: PersonDTO) => Person(dto.firstname + " " + dto.lastname, dto.years), - (person: Person) => { - val name = person.name.split(" ").toSeq - PersonDTO(name.head, name.tail.mkString(" "), person.age) - } - ) - - override val run: ZIO[Environment with ZIOAppArgs, Any, Any] = for { - _ <- ZIO.unit - json = """{"firstname":"John","lastname":"Doe","years":42}""" - chunks = Chunk.fromArray(json.getBytes) - _ <- ZIO.debug("input JSON : " + json) - - // get objects from JSON - personDTO <- ZIO.fromEither(JsonCodec.schemaBasedBinaryCodec[PersonDTO](PersonDTO.schema).decode(chunks)) - person <- ZIO.fromEither(JsonCodec.schemaBasedBinaryCodec[Person](personTransformation).decode(chunks)) - _ <- ZIO.debug("PersonDTO : " + personDTO) - _ <- ZIO.debug("Person : " + person) - - // get JSON from Objects - personJson = new String(JsonCodec.schemaBasedBinaryCodec[Person](Person.schema).encode(person).toArray) - personDTOJson = new String(JsonCodec.schemaBasedBinaryCodec[Person](personTransformation).encode(person).toArray) - _ <- ZIO.debug("Person JSON: " + personJson) - _ <- ZIO.debug("PersonDTO JSON: " + personDTOJson) - - } yield () -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example4/Example4Transformation.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example4/Example4Transformation.scala deleted file mode 100644 index 8ff0ed531..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example4/Example4Transformation.scala +++ /dev/null @@ -1,136 +0,0 @@ -package dev.zio.schema.example.example4 - -import zio._ -import zio.schema._ -import zio.schema.meta._ - -/** - * Example 4: In this Example, we use ZIO-Schema to migrate objects from one representation to another. - * This is a very common use case in proper designed applications where we have to migrate between - * different representations depending on the layer, e.g. - * transforming a Request-DTO to a Domain-DTO to a Database-DTO. - **/ -private[example4] object Domain { - final case class WebPerson(name: String, age: Int) - - object WebPerson { - - val name: Schema.Field[WebPerson, String] = - Schema - .Field[WebPerson, String]("name", Schema.primitive[String], get0 = _.name, set0 = (p, v) => p.copy(name = v)) - - val age: Schema.Field[WebPerson, Int] = - Schema.Field[WebPerson, Int]("age", Schema.primitive[Int], get0 = _.age, set0 = (p, v) => p.copy(age = v)) - - val schema: Schema[WebPerson] = Schema.CaseClass2[String, Int, WebPerson]( - TypeId.parse("dev.zio.schema.example.example4.Domain.WebPerson"), - field01 = name, - field02 = age, - construct0 = (name, age) => WebPerson(name, age) - ) - } - - final case class DomainPerson(firstname: String, lastname: String, years: Int) - - object DomainPerson { - - val firstname: Schema.Field[DomainPerson, String] = - Schema.Field("firstname", Schema.primitive[String], get0 = _.firstname, set0 = (p, v) => p.copy(firstname = v)) - - val lastname: Schema.Field[DomainPerson, String] = - Schema.Field("lastname", Schema.primitive[String], get0 = _.lastname, set0 = (p, v) => p.copy(lastname = v)) - - val years: Schema.Field[DomainPerson, Int] = - Schema.Field("years", Schema.primitive[Int], get0 = _.years, set0 = (p, v) => p.copy(years = v)) - - val schema: Schema[DomainPerson] = Schema.CaseClass3[String, String, Int, DomainPerson]( - TypeId.parse("dev.zio.schema.example.example4.Domain.DomainPerson"), - field01 = firstname, - field02 = lastname, - field03 = years, - construct0 = (fn, ln, y) => DomainPerson(fn, ln, y) - ) - } - -} - -// TODO - not working: -// Here I try to convert between WebPerson and DomainPerson using the `transform` method on `Schema` -object Example4Transformation extends ZIOAppDefault { - - import Domain._ - - val webPerson: WebPerson = WebPerson("Mike Moe", 32) - - val personTransformation: Schema[DomainPerson] = WebPerson.schema.transform[DomainPerson]( - (person: WebPerson) => { - val name = person.name.split(" ").toSeq - DomainPerson(name.head, name.tail.mkString(" "), person.age) - }, - (dto: DomainPerson) => WebPerson(dto.firstname + " " + dto.lastname, dto.years) - ) - - val domainPerson: zio.prelude.Validation[String, DomainPerson] = - WebPerson.schema.migrate(personTransformation).flatMap(f => f(webPerson)) - - override def run: UIO[Unit] = ZIO.debug(domainPerson) -} - -// TODO - not working!: -// Here I try to convert between WebPerson and DomainPerson -// using the roundtrip with dynamic and SchemaAst migrations. -object Example4Ast extends zio.ZIOAppDefault { - - import Domain._ - - val webPerson: WebPerson = WebPerson("Mike Moe", 32) - - val dyn: zio.prelude.Validation[String, DynamicValue] = WebPerson.schema - .toDynamic(webPerson) - .transform( - Chunk( - Migration.AddNode(NodePath.root / "lastname", MetaSchema.fromSchema(DomainPerson.lastname.schema)) -// Migration.Relabel(NodePath.root / "years", Migration.LabelTransformation("age")) // does not compile, LabelTransformation - ) - ) - //.flatMap(dv => DomainPerson.schema.fromDynamic(dv)) - - override def run: UIO[Unit] = ZIO.debug(dyn) -} - -object Example4Ast2 extends zio.ZIOAppDefault { - import Domain._ - - val webPerson: WebPerson = WebPerson("Mike Moe", 32) - - val personTransformation: Schema[DomainPerson] = WebPerson.schema.transform[DomainPerson]( - (person: WebPerson) => { - val name = person.name.split(" ").toSeq - DomainPerson(name.head, name.tail.mkString(" "), person.age) - }, - (dto: DomainPerson) => WebPerson(dto.firstname + " " + dto.lastname, dto.years) - ) - val webPersonAst: MetaSchema = MetaSchema.fromSchema(WebPerson.schema) - val domainPersonAst: MetaSchema = MetaSchema.fromSchema(DomainPerson.schema) - val migrationAst: MetaSchema = MetaSchema.fromSchema(personTransformation) - - val migrationWebPersonAstToMigrationAst: zio.prelude.Validation[String, Chunk[Migration]] = - Migration.derive(webPersonAst, migrationAst) - - val migrationWebPersonAstToDomainPersonAst: zio.prelude.Validation[String, Chunk[Migration]] = - Migration.derive(webPersonAst, domainPersonAst) - - override def run: ZIO[Environment with ZIOAppArgs, Any, Any] = - for { - _ <- ZIO.debug(webPersonAst) - _ <- ZIO.debug(domainPersonAst) - _ <- ZIO.debug(migrationAst) - _ <- ZIO.debug("migrationWebPersonAstToMigrationAst" + migrationWebPersonAstToMigrationAst) - _ <- ZIO.debug("migrationWebPersonAstToDomainPersonAst" + migrationWebPersonAstToDomainPersonAst) - x = WebPerson.schema.migrate(personTransformation).flatMap(f => f(webPerson)) - _ <- ZIO.debug(x) // Left(Failed to cast Record(ListMap(name -> Primitive(Mike Moe,string), age -> Primitive(32,int))) to schema Transform(CaseClass2(Field(name,Primitive(string)),Field(age,Primitive(int))))) - - domainPerson = WebPerson.schema.migrate(DomainPerson.schema).flatMap(f => f(webPerson)) - _ <- ZIO.debug(domainPerson) // Left(Cannot add node at path firstname: No default value is available) - } yield () -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example5/Example5_Diffing.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example5/Example5_Diffing.scala deleted file mode 100644 index 05c1839cd..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example5/Example5_Diffing.scala +++ /dev/null @@ -1,63 +0,0 @@ -package dev.zio.schema.example.example5 - -import zio._ -import zio.schema.Schema._ -import zio.schema._ - -/** - * Example 5: In this example, we use ZIO-Schema to detect changes in our objects. - * - */ -private[example5] object Domain { - final case class Person(name: String, age: Int) - - object Person { - - val name: Field[Person, String] = - Field[Person, String]("name", primitive[String], get0 = _.name, set0 = (p, v) => p.copy(name = v)) - - val age: Field[Person, Int] = - Field[Person, Int]("age", primitive[Int], get0 = _.age, set0 = (p, v) => p.copy(age = v)) - - val schema: Schema[Person] = CaseClass2[String, Int, Person]( - TypeId.parse("dev.zio.schema.example.example5.Domain.Person"), - field01 = name, - field02 = age, - construct0 = (name, age) => Person(name, age) - ) - } - - final case class PersonDTO(firstname: String, lastname: String, years: Int) - - object PersonDTO { - - val firstname: Field[PersonDTO, String] = - Field("firstname", primitive[String], get0 = _.firstname, set0 = (p, v) => p.copy(firstname = v)) - - val lastname: Field[PersonDTO, String] = - Field("lastname", primitive[String], get0 = _.lastname, set0 = (p, v) => p.copy(lastname = v)) - - val years: Field[PersonDTO, Int] = - Field("years", primitive[Int], get0 = _.years, set0 = (p, v) => p.copy(years = v)) - - val schema: Schema[PersonDTO] = CaseClass3[String, String, Int, PersonDTO]( - TypeId.parse("dev.zio.schema.example.example5.Domain.PersonDTO"), - field01 = firstname, - field02 = lastname, - field03 = years, - construct0 = (fn, ln, y) => PersonDTO(fn, ln, y) - ) - } - -} - -object Example5_Diffing extends ZIOAppDefault { - - import Domain._ - - val personDTO: PersonDTO = PersonDTO("Mike", "Moe", 32) - - val diff: Patch[PersonDTO] = PersonDTO.schema.diff(personDTO, personDTO.copy(lastname = "Max")) - - override val run: UIO[Unit] = ZIO.debug(diff) -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example6/Example6_ReifiedOptics.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example6/Example6_ReifiedOptics.scala deleted file mode 100644 index 86e440ed8..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example6/Example6_ReifiedOptics.scala +++ /dev/null @@ -1,127 +0,0 @@ -package dev.zio.schema.example.example6 - -import zio._ -import zio.schema.Schema._ -import zio.schema._ -import zio.schema.optics.ZioOpticsBuilder - -private[example6] object Domain { - final case class User(name: String, age: Int) - final case class Address(street: String, city: String, state: String) - final case class UserAddress(user: User, address: Address) - final case class Company(boss: User, employees: List[UserAddress]) - - implicit val userSchema: Schema.CaseClass2[String, Int, User] = Schema.CaseClass2[String, Int, User]( - TypeId.parse("dev.zio.schema.example.example6.Domain.User"), - field01 = Field("name", Schema.primitive[String], get0 = _.name, set0 = (p, v) => p.copy(name = v)), - field02 = Field("age", Schema.primitive[Int], get0 = _.age, set0 = (p, v) => p.copy(age = v)), - construct0 = (name, years) => User(name, years) - ) - - implicit val addressSchema: CaseClass3[String, String, String, Address] = - Schema.CaseClass3[String, String, String, Address]( - TypeId.parse("dev.zio.schema.example.example6.Domain.Address"), - field01 = Field("street", Schema.primitive[String], get0 = _.street, set0 = (p, v) => p.copy(street = v)), - field02 = Field("city", Schema.primitive[String], get0 = _.city, set0 = (p, v) => p.copy(city = v)), - field03 = Field("state", Schema.primitive[String], get0 = _.state, set0 = (p, v) => p.copy(state = v)), - construct0 = (street, city, state) => Address(street, city, state) - ) - - implicit val userAddressSchema: CaseClass2[User, Address, UserAddress] = - Schema.CaseClass2[User, Address, UserAddress]( - TypeId.parse("dev.zio.schema.example.example6.Domain.UserAddress"), - field01 = Field("user", userSchema, get0 = _.user, set0 = (p, v) => p.copy(user = v)), - field02 = Field("address", addressSchema, get0 = _.address, set0 = (p, v) => p.copy(address = v)), - construct0 = (user, address) => UserAddress(user, address) - ) - - implicit val companySchema: CaseClass2[User, List[UserAddress], Company] = - Schema.CaseClass2[User, List[UserAddress], Company]( - TypeId.parse("dev.zio.schema.example.example6.Domain.Company"), - field01 = Field("boss", userSchema, get0 = _.boss, set0 = (p, v) => p.copy(boss = v)), - field02 = - Field("employees", Schema.list(userAddressSchema), get0 = _.employees, set0 = (p, v) => p.copy(employees = v)), - construct0 = (boss, employees) => Company(boss, employees) - ) - -} - -object Example6_ReifiedOptics extends ZIOAppDefault { - import Domain._ - - val lensTest1: ZIO[Any, Nothing, Unit] = for { - _ <- ZIO.debug("lens test 1") - user = User("Dominik", 35) - userAccessors = userSchema.makeAccessors(ZioOpticsBuilder) - lensName = userAccessors._1 - lensAge = userAccessors._2 - changedUser = lensName.zip(lensAge).setOptic(("Mike", 32))(user) - _ <- ZIO.debug(user) - _ <- ZIO.debug(changedUser) - } yield () - - val lensTest2: ZIO[Any, Nothing, Unit] = for { - _ <- ZIO.debug("lens test 2") - user = User("Dominik", 35) - address = Address("Street", "City", "State") - userAddress = UserAddress(user, address) - userAddressAccessors = userAddressSchema.makeAccessors(ZioOpticsBuilder) - //userAccessors = userSchema.makeAccessors(ZioOpticsBuilder) - addressAccessors = addressSchema.makeAccessors(ZioOpticsBuilder) - - changedUserAddress = (userAddressAccessors._2 >>> addressAccessors._3).setOptic("New State")(userAddress) - _ <- ZIO.debug(userAddress) - _ <- ZIO.debug(changedUserAddress) - } yield () - - val traversalTest1: ZIO[Any, Nothing, Unit] = for { - _ <- ZIO.debug("\n\n\n\n") - _ <- ZIO.debug("traversal test 1.. trying to add a employee to a company") - company = Company(boss = User("Dominik", 36), List.empty[UserAddress]) - _ <- ZIO.debug("old company : " + company) - (_, employeesLens) = companySchema.makeAccessors(ZioOpticsBuilder) - - employeeSchema = companySchema.field2.schema.asInstanceOf[Sequence[List[UserAddress], UserAddress, _]] - employeesTraversal = ZioOpticsBuilder - .makeTraversal[List[UserAddress], UserAddress](employeeSchema, userAddressSchema) - - // not working approach - updatedCompany = (employeesLens >>> employeesTraversal).update(company)( - emps => emps ++ Chunk(UserAddress(User("joe", 22), Address("s1", "s2", "s3"))) - ) - _ <- ZIO.debug("updated company : " + updatedCompany) - - // working approach - updatedCompany2 = employeesLens.update(company)( - emps => emps ++ List(UserAddress(User("joe", 22), Address("s1", "s2", "s3"))) - ) - _ <- ZIO.debug("updated company2: " + updatedCompany2) - } yield () - - override def run: ZIO[Environment with ZIOAppArgs, Any, Any] = (lensTest1 *> lensTest2 *> traversalTest1) -} - -/** - * Example by adam that shows pure usage of optics without any schema or derivation - */ -object Example6_PureOptics extends scala.App { - import zio.optics._ - - final case class User(name: String) - final case class Employee(name: String) - - final case class Company(boss: User, employees: List[Employee]) - - val company: Company = Company(User("boss"), List(Employee("employee1"))) - println("company with 1 employee : " + company) - - val employees: Lens[Company, List[Employee]] = - Lens( - company => zio.prelude.Validation.succeed(company.employees), - employees => company => zio.prelude.Validation.succeed(company.copy(employees = employees)) - ) - - val employee: Employee = Employee("employee2") - - println("company with 2 employees: " + employees.update(company)(employees => employee :: employees)) -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala deleted file mode 100644 index 20236991e..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example7/Problem.scala +++ /dev/null @@ -1,212 +0,0 @@ -package dev.zio.schema.example.example7 - -import scala.collection.immutable.ListMap -import scala.util.Try -import zio.schema._ -import zio.{ Chunk, Unsafe } - -/** This exercise is based on John DeGoes' Spartan training on ZIO-Schema from 2021-11-04 - */ -private[example7] object Problem { - - final case class Person(name: String, age: Int) - - object Person { - implicit val schema: Schema[Person] = DeriveSchema.gen[Person] - } - final case class Profile(location: String, address: String) - - object Profile { - implicit val schema: Schema[Profile] = DeriveSchema.gen[Profile] - } - // sample url1: /foo/?name=john&age=42#foo - // sample url2: /foo/?name=john&age=42&location=london&address=baker%20street - - def decodePersonFromQueryParams(params: Map[String, List[String]]): zio.prelude.Validation[String, Person] = - for { - name <- params.get("name").tozio.prelude.Validation.succeed("name parameter is missing") - age <- params.get("age").tozio.prelude.Validation.succeed("age parameter is missing") - } yield Person(name.head, age.head.toInt) - - def decodeProfileFromQueryParams(params: Map[String, List[String]]): zio.prelude.Validation[String, Profile] = - for { - location <- params.get("location").tozio.prelude.Validation.succeed("location parameter is missing") - address <- params.get("address").tozio.prelude.Validation.succeed("address parameter is missing") - } yield Profile(location.head, address.head) - - object Approach1 extends scala.App { - - // this will be a "quick and dirty" solution, that can be accomplished in a few minutes. - // not suitable for _extremely high performance_ applications - // probably suitable for the normal business application with medium performance requirements - def decode[A]( - params: Map[String, List[String]] - )(implicit schema: Schema[A]): zio.prelude.Validation[String, A] = - toDV(params) - .map(_.toTypedValue(schema).toEither) - .collectFirst { - case zio.prelude.Validation.succeed(v) => - v - } - .tozio.prelude.Validation.succeed("some error") - - // parse each element into String and if possible Int representations. We basically create all - // possible solutions here. The Set[DynamicValue] removes duplicates. - def toDV(params: Map[String, List[String]]): Set[DynamicValue] = { - import DynamicValue._ - params - .foldLeft[Set[ListMap[String, DynamicValue]]](Set(ListMap())) { - case (set, (key, values)) => - set.flatMap { acc => - values match { - case Nil => Set(acc.updated(key, Singleton(()))) - case x :: Nil => - val strInterpretation = - Set(acc.updated(key, Primitive[String](x, StandardType.StringType))) - val intInterpretation = Try(x.toInt).toOption match { - case Some(value) => - Set(acc.updated(key, Primitive[Int](value, StandardType.IntType))) - case None => Set() - } - strInterpretation ++ intInterpretation - case xs => - Set( - acc.updated( - key, - DynamicValue.Sequence( - Chunk.fromIterable(xs).map(Primitive[String](_, StandardType.StringType)) - ) - ) - ) - } - } - } - .map(v => DynamicValue.Record(TypeId.Structural, v)) - } - - val p: zio.prelude.Validation[String, Person] = decode[Person](Map("name" -> List("John"), "age" -> List("42"))) - - println(p) - } - - object Approach2 extends scala.App { - import Schema._ - type QueryParams = scala.collection.immutable.Map[String, List[String]] - - // this will be a sophisticated solution for a high performance library like ZIO - def decodeFromQueryParams[A]( - params: QueryParams - )(implicit schema: Schema[A], decoder: QueryParams => zio.prelude.Validation[String, A]): zio.prelude.Validation[String, A] = - decoder(params) - - def buildDecoder[A](implicit schemaA: Schema[A]): QueryParams => zio.prelude.Validation[String, A] = { - - def compile[B](key: Option[String], schemaB: Schema[B]): QueryParams => zio.prelude.Validation[String, B] = - schemaB match { - case transform: Transform[a, B, _] => - import transform.{ f, schema } - val func: QueryParams => zio.prelude.Validation[String, Any] = compile(key, schema) - (params: QueryParams) => func(params).flatMap(v => f(v.asInstanceOf[a])) - case Primitive(standardType, _) => - key match { - case None => - val error = Left(s"Cannot extract a primitive out of a query string") - Function.const(error) - case Some(key) => - standardType match { - case StandardType.StringType => - val f: QueryParams => zio.prelude.Validation[String, B] = (qp: QueryParams) => - qp.get(key) match { - case Some(value :: _) => Right[String, B](value.asInstanceOf[B]) - case _ => Left(s"Cannot extract a primitive string out of nothing") - } - f - case StandardType.IntType => - val f: QueryParams => zio.prelude.Validation[String, B] = (qp: QueryParams) => - qp.get(key) match { - case Some(value :: _) => - Try(value.toInt).toOption.tozio.prelude.Validation.succeed(s"cannot create an integer out of $value") - case _ => Left(s"Cannot extract a primitive string out of nothing") - } - f - case _ => - val error = Left(s"Expected String or Int but found $standardType") - Function.const(error) - } - } - - case cc: CaseClass1[a, B] => - val f = compile[a](Some(cc.field.name), cc.field.schema) - (qp: QueryParams) => f(qp).map(v => cc.defaultConstruct(v)) - - case cc: CaseClass2[a, b, B] => - val f1 = compile[a](Some(cc.field1.name), cc.field1.schema) - val f2 = compile[b](Some(cc.field2.name), cc.field2.schema) - - (qp: QueryParams) => - for { - v1 <- f1(qp) - v2 <- f2(qp) - } yield cc.construct(v1, v2) - - case cc: CaseClass3[a, b, c, B] => - val f1 = compile[a](Some(cc.field1.name), cc.field1.schema) - val f2 = compile[b](Some(cc.field2.name), cc.field2.schema) - val f3 = compile[c](Some(cc.field3.name), cc.field3.schema) - - (qp: QueryParams) => - for { - v1 <- f1(qp) - v2 <- f2(qp) - v3 <- f3(qp) - } yield cc.construct(v1, v2, v3) - - // And so on to arity 23.. - - case record: Record[B] => - Unsafe.unsafe { implicit unsafe => (qp: QueryParams) => - { - record.fields.map { - case Schema.Field(label, schema, _, _, _, _) => - compile(Some(label), schema)(qp) - }.foldRight[zio.prelude.Validation[String, Chunk[Any]]](zio.prelude.Validation.succeed(Chunk.empty)) { - case (zio.prelude.Validation.succeed(nextValue), zio.prelude.Validation.succeed(values)) => zio.prelude.Validation.succeed(values :+ nextValue) - case (Left(err), _) => Left(err) - case (_, Left(err)) => Left(err) - } - .flatMap(record.construct) - } - } - - case Fail(message, _) => Function.const(Left(message)) - //case enumer: Enum[_] => ??? - //case Optional(codec) => ??? - //case Tuple(left, right) => ??? - //case EitherSchema(left, right) => ??? - case lzy @ Lazy(_) => - // lazy val to make sure its only compiled on first usage and not instantly recursing - lazy val compiled = compile(key, lzy.schema) - (qp: QueryParams) => compiled(qp) - case _ => - val err = Left(s"Decoding from query parameters is not supported for $schemaB") - Function.const(err) - } - - compile(None, schemaA) - } - - implicit val personDecoder: QueryParams => zio.prelude.Validation[String, Person] = buildDecoder[Person] - - println("approach 2") - - private val data = scala.collection.immutable.Map("name" -> List("John"), "age" -> List("42")) - - println(decodeFromQueryParams[Person](data)) - } -} - -object Runner extends scala.App { - - Problem.Approach1.main(Array.empty) - Problem.Approach2.main(Array.empty) -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Decoder.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Decoder.scala deleted file mode 100644 index c19a9859e..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Decoder.scala +++ /dev/null @@ -1,47 +0,0 @@ -package dev.zio.schema.example.example8 - -import scala.collection.immutable.ListMap - -import zio.Chunk -import zio.prelude._ -import zio.schema._ - -trait Decoder[+A] { - def decode(in: Json): zio.prelude.Validation[String, A] -} - -object Decoder { - - def deriveDecoder[A](implicit schema: Schema[A]): Decoder[A] = - in => - for { - dv <- jsonToDynamicValue(in) - a <- schema.fromDynamic(dv) - } yield a - - private def jsonToDynamicValue(in: Json): zio.prelude.Validation[String, DynamicValue] = - in match { - case Json.JStr(s) => - zio.prelude.Validation.succeed(DynamicValue.Primitive(s, StandardType.StringType)) - - case Json.JNum(d) => - zio.prelude.Validation.succeed(DynamicValue.Primitive(d, StandardType.DoubleType)) - - case Json.JBool(b) => - zio.prelude.Validation.succeed(DynamicValue.Primitive(b, StandardType.BoolType)) - - case Json.JArr(as) => - as.forEach(jsonToDynamicValue) - .map(list => DynamicValue.Sequence(Chunk.fromIterable(list))) - - case Json.JObj(map) => - map.map { - case (k, v) => k -> jsonToDynamicValue(v) - }.foldRight[zio.prelude.Validation[String, DynamicValue]](zio.prelude.Validation.succeed(DynamicValue.Record(TypeId.Structural, ListMap.empty))) { - case ((key, zio.prelude.Validation.succeed(value)), zio.prelude.Validation.succeed(DynamicValue.Record(_, values))) => - zio.prelude.Validation.succeed(DynamicValue.Record(TypeId.parse(key), values + (key -> value))) - case ((_, Left(err)), _) => Left(err) - case (_, Left(err)) => Left(err) - } - } -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Encoder.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Encoder.scala deleted file mode 100644 index 3ab79f3c7..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Encoder.scala +++ /dev/null @@ -1,38 +0,0 @@ -package dev.zio.schema.example.example8 - -import zio.schema.{ DynamicValue, Schema, StandardType } - -trait Encoder[A] { - def encode(in: A): Json -} - -object Encoder { - - def deriveEncoder[A](implicit schema: Schema[A]): Encoder[A] = { (in: A) => - toJson(schema.toDynamic(in)) - } - - private def toJson(in: DynamicValue): Json = - in match { - case p: DynamicValue.Primitive[a] => - p.standardType match { - case StandardType.StringType => - Json.JStr(p.value) - - case StandardType.DoubleType | StandardType.IntType | StandardType.LongType => - Json.JNum(p.value) - - case StandardType.BoolType => - Json.JBool(p.value) - - case _ => - Json.JStr(p.value.toString) - } - - case DynamicValue.Sequence(chunk) => - Json.JArr(chunk.map(toJson).toList) - - case DynamicValue.Record(_, values) => - Json.JObj(values.map { case (k, v) => (k, toJson(v)) }) - } -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Json.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Json.scala deleted file mode 100644 index 89c3d86fd..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Json.scala +++ /dev/null @@ -1,11 +0,0 @@ -package dev.zio.schema.example.example8 - -sealed trait Json - -object Json { - final case class JStr(s: String) extends Json - final case class JNum(d: Double) extends Json - final case class JBool(b: Boolean) extends Json - final case class JArr(as: List[Json]) extends Json - final case class JObj(map: Map[String, Json]) extends Json -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Usage.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Usage.scala deleted file mode 100644 index 5ea2c4efe..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example8/Usage.scala +++ /dev/null @@ -1,30 +0,0 @@ -package dev.zio.schema.example.example8 - -import zio.schema.{ DeriveSchema, Schema } - -final case class Person(name: String, age: Double) - -object Person { - implicit val schemaPerson: Schema[Person] = DeriveSchema.gen[Person] -} - -object Usage extends App { - val p: Person = Person("cal", 30) - - val pJson: Json = Encoder.deriveEncoder[Person].encode(p) - val sameP: zio.prelude.Validation[String, Person] = Decoder.deriveDecoder[Person].decode(pJson) - println(sameP == zio.prelude.Validation.succeed(p)) - - println { - Decoder - .deriveDecoder[Person] - .decode( - Json.JObj( - Map( - "name" -> Json.JStr("cal"), - "age" -> Json.JNum(30) - ) - ) - ) - } -} diff --git a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example9/Patching.scala b/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example9/Patching.scala deleted file mode 100644 index 328f38939..000000000 --- a/zio-schema-examples/shared/src/main/scala/dev/zio/schema/example/example9/Patching.scala +++ /dev/null @@ -1,26 +0,0 @@ -package dev.zio.schema.example.example9 - -import zio.schema.{ DeriveSchema, Patch, Schema } - -object Patching extends App { - - final case class Person(name: String, age: Int) - - object Person { - implicit lazy val schema: Schema[Person] = DeriveSchema.gen - } - - private val person1 = Person("Gabriel", 45) - private val person2 = Person("Gabi", 54) - - import Person._ - - private val patch: Patch[Person] = schema.diff(person1, person2) - private val inverted: Patch[Person] = patch.invert - - private val result1: zio.prelude.Validation[String, Person] = patch.patch(person1) - private val result2: zio.prelude.Validation[String, Person] = result1.flatMap(inverted.patch) - - assert(result2 == zio.prelude.Validation.succeed(person1)) - -} 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 8eb88de08..4fd3db45a 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 @@ -2,38 +2,33 @@ package zio.schema.codec import java.nio.CharBuffer import java.nio.charset.StandardCharsets - import scala.collection.immutable.ListMap - import zio.json.JsonCodec._ -import zio.json.JsonDecoder.{ JsonError, UnsafeJson } +import zio.json.JsonDecoder.{JsonError, UnsafeJson} import zio.json.ast.Json -import zio.json.internal.{ Lexer, RecordingReader, RetractReader, StringMatrix, Write } -import zio.json.{ - JsonCodec => ZJsonCodec, - JsonDecoder => ZJsonDecoder, - JsonEncoder => ZJsonEncoder, - JsonFieldDecoder, - JsonFieldEncoder -} +import zio.json.internal.{Lexer, RecordingReader, RetractReader, StringMatrix, Write} +import zio.json.{JsonFieldDecoder, JsonFieldEncoder, JsonCodec => ZJsonCodec, JsonDecoder => ZJsonDecoder, JsonEncoder => ZJsonEncoder} +import zio.prelude.{Validation, ZValidation} import zio.schema._ import zio.schema.annotation._ import zio.schema.codec.DecodeError.ReadError import zio.stream.ZPipeline -import zio.{ Cause, Chunk, ChunkBuilder, NonEmptyChunk, ZIO } +import zio.{Cause, Chunk, ChunkBuilder, NonEmptyChunk, ZIO, prelude} object JsonCodec { type DiscriminatorTuple = Chunk[(discriminatorName, String)] implicit def zioJsonBinaryCodec[A](implicit jsonCodec: ZJsonCodec[A]): BinaryCodec[A] = new BinaryCodec[A] { - override def decode(whole: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = + override def decode(whole: Chunk[Byte]): Validation[DecodeError, A] = { + Validation.fromEither( jsonCodec .decodeJson( new String(whole.toArray, JsonEncoder.CHARSET) ) - .left - .map(failure => DecodeError.ReadError(Cause.empty, failure)) + ) + .mapError(failure => DecodeError.ReadError(Cause.empty, failure)) + } override def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] = ZPipeline.fromChannel( @@ -75,7 +70,7 @@ object JsonCodec { case (_, fragments) => fragments.mkString } >>> ZPipeline.mapZIO { (s: String) => - ZIO.fromEither(JsonDecoder.decode(schema, s)) + ZIO.fromEither(JsonDecoder.decode(schema, s).toEither.left.map(_.head)) } override def encode(value: A): Chunk[Byte] = @@ -366,15 +361,16 @@ object JsonCodec { override def unsafeEncode(b: B, indent: Option[Int], out: Write): Unit = g(b) match { - case Left(_) => () - case zio.prelude.Validation.succeed(a) => innerEncoder.unsafeEncode(a, indent, out) + case Validation.Failure(_, _) => () + case Validation.Success(_, a) => innerEncoder.unsafeEncode(a, indent, out) } - override def isNothing(b: B): Boolean = + override def isNothing(b: B): Boolean = { g(b) match { - case Left(_) => false - case zio.prelude.Validation.succeed(a) => innerEncoder.isNothing(a) + case Validation.Failure(_, _) => false + case Validation.Success(_, a) => innerEncoder.isNothing(a) } + } } private def enumEncoder[Z](parentSchema: Schema.Enum[Z], cases: Schema.Case[Z, _]*): ZJsonEncoder[Z] = @@ -476,8 +472,8 @@ object JsonCodec { final def decode[A](schema: Schema[A], json: String): zio.prelude.Validation[DecodeError, A] = schemaDecoder(schema).decodeJson(json) match { - case Left(value) => Left(ReadError(Cause.empty, value)) - case zio.prelude.Validation.succeed(value) => zio.prelude.Validation.succeed(value) + case Left(value) => Validation.fail(ReadError(Cause.empty, value)) + case Right(value) => Validation.succeed(value) } def x[A](dec: ZJsonDecoder[A]): Unit = dec match { @@ -489,7 +485,7 @@ object JsonCodec { case Schema.Primitive(standardType, _) => primitiveCodec(standardType).decoder case Schema.Optional(codec, _) => ZJsonDecoder.option(schemaDecoder(codec, hasDiscriminator)) case Schema.Tuple2(left, right, _) => ZJsonDecoder.tuple2(schemaDecoder(left, hasDiscriminator), schemaDecoder(right, hasDiscriminator)) - case Schema.Transform(codec, f, _, _, _) => schemaDecoder(codec, hasDiscriminator).mapOrFail(f) + case Schema.Transform(codec, f, _, _, _) => schemaDecoder(codec, hasDiscriminator).mapOrFail(g => f(g).toEither.left.map(_.head)) case Schema.Sequence(codec, f, _, _, _) => ZJsonDecoder.chunk(schemaDecoder(codec, hasDiscriminator)).map(f) case Schema.Map(ks, vs, _) => mapDecoder(ks, vs, hasDiscriminator) case Schema.Set(s, _) => ZJsonDecoder.chunk(schemaDecoder(s, hasDiscriminator)).map(entries => entries.toSet) @@ -645,7 +641,7 @@ object JsonCodec { ZJsonDecoder.string.mapOrFail( s => caseMap.get(caseNameAliases.get(s).getOrElse(s)) match { - case Some(z) => zio.prelude.Validation.succeed(z) + case Some(z) => Right(z) case None => Left("unrecognized string") } ) diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index bfccb5f92..5495ade59 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -1,20 +1,19 @@ package zio.schema.codec -import java.time.{ ZoneId, ZoneOffset } - +import java.time.{ZoneId, ZoneOffset} import scala.collection.immutable.ListMap - import zio.Console._ import zio._ import zio.json.JsonDecoder.JsonError -import zio.json.{ DeriveJsonEncoder, JsonEncoder } +import zio.json.{DeriveJsonEncoder, JsonEncoder} +import zio.prelude.Validation import zio.schema.CaseSet._ import zio.schema._ import zio.schema.annotation._ import zio.schema.codec.DecodeError.ReadError import zio.schema.codec.JsonCodec.JsonEncoder.charSequenceToByteChunk -import zio.schema.codec.JsonCodecSpec.PaymentMethod.{ CreditCard, PayPal, WireTransfer } -import zio.schema.codec.JsonCodecSpec.Subscription.{ OneTime, Recurring } +import zio.schema.codec.JsonCodecSpec.PaymentMethod.{CreditCard, PayPal, WireTransfer} +import zio.schema.codec.JsonCodecSpec.Subscription.{OneTime, Recurring} import zio.schema.meta.MetaSchema import zio.stream.ZStream import zio.test.Assertion._ @@ -275,7 +274,7 @@ object JsonCodecSpec extends ZIOSpecDefault { val errorMessage = "I'm sorry Dave, I can't do that" val schema: Schema[Int] = Schema .Primitive(StandardType.StringType) - .transformOrFail[Int](_ => Left(errorMessage), i => zio.prelude.Validation.succeed(i.toString)) + .transformOrFail[Int](_ => Validation.fail(errorMessage), i => Validation.succeed(i.toString)) check(Gen.int(Int.MinValue, Int.MaxValue)) { int => assertDecodesToError( schema, @@ -495,7 +494,7 @@ object JsonCodecSpec extends ZIOSpecDefault { right <- SchemaGen.anyTupleAndValue } yield ( Schema.Either(left._1.asInstanceOf[Schema[(Any, Any)]], right._1.asInstanceOf[Schema[(Any, Any)]]), - zio.prelude.Validation.succeed(right._2) + Right(right._2) ) ) { case (schema, value) => assertEncodesThenDecodes(schema, value) @@ -534,9 +533,9 @@ object JsonCodecSpec extends ZIOSpecDefault { ) ) { case (schema, value) => - assertEncodesThenDecodes[zio.prelude.Validation[Map[Any, Any], Map[Any, Any]]]( - schema.asInstanceOf[Schema[zio.prelude.Validation[Map[Any, Any], Map[Any, Any]]]], - value.asInstanceOf[zio.prelude.Validation[Map[Any, Any], Map[Any, Any]]] + assertEncodesThenDecodes[Either[Map[Any, Any], Map[Any, Any]]]( + schema.asInstanceOf[Schema[Either[Map[Any, Any], Map[Any, Any]]]], + value.asInstanceOf[Either[Map[Any, Any], Map[Any, Any]]] ) } }, @@ -552,9 +551,9 @@ object JsonCodecSpec extends ZIOSpecDefault { ) ) { case (schema, value) => - assertEncodesThenDecodes[zio.prelude.Validation[Set[Any], Set[Any]]]( - schema.asInstanceOf[Schema[zio.prelude.Validation[Set[Any], Set[Any]]]], - value.asInstanceOf[zio.prelude.Validation[Set[Any], Set[Any]]] + assertEncodesThenDecodes[Either[Set[Any], Set[Any]]]( + schema.asInstanceOf[Schema[Either[Set[Any], Set[Any]]]], + value.asInstanceOf[Either[Set[Any], Set[Any]]] ) } }, @@ -588,7 +587,7 @@ object JsonCodecSpec extends ZIOSpecDefault { check(for { (left, _) <- SchemaGen.anyRecordOfRecordsAndValue (right, b) <- SchemaGen.anyRecordOfRecordsAndValue - } yield (Schema.Either(left, right), zio.prelude.Validation.succeed(b))) { + } yield (Schema.Either(left, right), Right(b))) { case (schema, value) => assertEncodesThenDecodes(schema, value) } @@ -597,7 +596,7 @@ object JsonCodecSpec extends ZIOSpecDefault { check(for { (left, _) <- SchemaGen.anyEnumerationAndValue (right, value) <- SchemaGen.anySequenceAndValue - } yield (Schema.Either(left, right), zio.prelude.Validation.succeed(value))) { + } yield (Schema.Either(left, right), Right(value))) { case (schema, value) => assertEncodesThenDecodes(schema, value) } } diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala index 3c312c117..18495c94c 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala @@ -1,12 +1,13 @@ package zio.schema.codec -import java.math.{ BigInteger, MathContext } -import java.time._ +import zio.prelude.Validation +import java.math.{BigInteger, MathContext} +import java.time._ import zio.schema.codec.DecodeError.ReadError -import zio.schema.{ Schema, StandardType } +import zio.schema.{Schema, StandardType} import zio.stream.ZPipeline -import zio.{ Cause, Chunk, ZIO } +import zio.{Cause, Chunk, ZIO} object MessagePackCodec { implicit def messagePackCodec[A](implicit schema: Schema[A]): BinaryCodec[A] = @@ -14,9 +15,9 @@ object MessagePackCodec { override def encode(a: A): Chunk[Byte] = new MessagePackEncoder().encode(schema, a) - override def decode(bytes: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = + override def decode(bytes: Chunk[Byte]): Validation[DecodeError, A] = if (bytes.isEmpty) - Left(ReadError(Cause.empty, "No bytes to decode")) + Validation.fail(ReadError(Cause.empty, "No bytes to decode")) else decodeChunk(bytes) @@ -30,15 +31,16 @@ object MessagePackCodec { override def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] = ZPipeline.mapChunksZIO { chunk => ZIO.fromEither( - decodeChunk(chunk).map(Chunk(_)) + //FIXME?? + decodeChunk(chunk).map(Chunk(_)).toEither.left.map(_.head) ) } private def decodeChunk(chunk: Chunk[Byte]) = new MessagePackDecoder(chunk) .decode(schema) - .left - .map(identity) +// .left +// .map(identity) } //TODO those are duplicates from ThriftCodec diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala index 699fb4733..218dde1b5 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala @@ -2,18 +2,16 @@ package zio.schema.codec import java.time._ import java.util.UUID - import scala.annotation.tailrec import scala.collection.immutable.ListMap import scala.util.control.NonFatal -import scala.util.{ Failure, Success, Try } - -import org.msgpack.core.{ MessagePack, MessageUnpacker } - +import scala.util.{Failure, Success, Try} +import org.msgpack.core.{MessagePack, MessageUnpacker} +import zio.prelude.{Validation, ZValidation} import zio.schema.codec.DecodeError.MalformedFieldWithPath import zio.schema.codec.MessagePackDecoder._ -import zio.schema.{ DynamicValue, Schema, StandardType } -import zio.{ Chunk, ChunkBuilder } +import zio.schema.{DynamicValue, Schema, StandardType} +import zio.{Chunk, ChunkBuilder} private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { private val unpacker = MessagePack.newDefaultUnpacker(bytes.toArray) @@ -105,8 +103,8 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { case _ => fail(path, s"Unknown schema ${schema.getClass.getName}") } - private def decodeTransform[A, B](path: Path, schema: Schema[B], f: B => zio.prelude.Validation[String, A]): Result[A] = - decodeValue(path, schema).flatMap(a => f(a).left.map(msg => MalformedFieldWithPath(path, msg))) + private def decodeTransform[A, B](path: Path, schema: Schema[B], f: B => Validation[String, A]): Result[A] = + decodeValue(path, schema).flatMap(a => f(a).mapError(msg => MalformedFieldWithPath(path, msg))) private def decodeRecord[Z](path: Path, fields: Seq[Schema.Field[Z, _]]): Result[ListMap[String, _]] = decodeStructure(path, fields.map(f => f.name -> f.schema).toMap) @@ -122,14 +120,21 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { fields.get(fieldName) match { case Some(fieldSchema) => decodeValue(actualPath, fieldSchema) match { - case Left(err) => Left(err) - case zio.prelude.Validation.succeed(value) => + case f@ Validation.Failure(_, _) => f + case Validation.Success(_, value) => if (index == fields.size) { - succeed(m.updated(fieldName, value)) - } else { - readFields(m.updated(fieldName, value), index + 1) - } + succeed(m.updated(fieldName, value)) + } else { + readFields(m.updated(fieldName, value), index + 1) + } } +// .flatMap(value => { +// if (index == fields.size) { +// succeed(m.updated(fieldName, value)) +// } else { +// readFields(m.updated(fieldName, value), index + 1) +// } +// }) case None => fail(path, s"Could not find schema for field: [$fieldName] on index: $index") } @@ -151,10 +156,10 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { def decodeElements(n: Int, m: scala.collection.mutable.Map[K, V]): Result[scala.collection.immutable.Map[K, V]] = if (n > 0) { (decodeValue(path, schema.keySchema), decodeValue(path, schema.valueSchema)) match { - case (zio.prelude.Validation.succeed(key), zio.prelude.Validation.succeed(value)) => decodeElements(n - 1, m += ((key, value))) + case (zio.prelude.Validation.Success(_, key), zio.prelude.Validation.Success(_, value)) => decodeElements(n - 1, m += ((key, value))) case (l, r) => - val key = l.fold(_.message, _.toString) - val value = r.fold(_.message, _.toString) + val key = l.fold(_.map(_.message).toString(), _.toString) + val value = r.fold(_.map(_.message).toString(), _.toString) fail(path, s"Error decoding Map element (key: $key; value: $value)") } } else { @@ -172,8 +177,8 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { def decodeElements(n: Int, cb: ChunkBuilder[A]): Result[Chunk[A]] = if (n > 0) { decodeValue(path, elementSchema) match { - case zio.prelude.Validation.succeed(elem) => decodeElements(n - 1, cb += elem) - case Left(err) => Left(err) + case zio.prelude.Validation.Success(_, elem) => decodeElements(n - 1, cb += elem) + case failure@ zio.prelude.Validation.Failure(_, _) => failure } } else { succeed(cb.result()) @@ -297,7 +302,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { } ) - private def decodezio.prelude.Validation[A, B](path: Path, left: Schema[A], right: Schema[B]): Result[zio.prelude.Validation[A, B]] = + private def decodeEither[A, B](path: Path, left: Schema[A], right: Schema[B]): Result[Either[A, B]] = Try(unpacker.unpackMapHeader()).fold( err => fail(path, s"Error parsing Either structure: ${err.getMessage}"), size => @@ -306,7 +311,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { } else { decodeString(path :+ "either").flatMap { case "left" => decodeValue(path :+ "either:left", left).map(Left(_)) - case "right" => decodeValue(path :+ "either:right", right).map(zio.prelude.Validation.succeed(_)) + case "right" => decodeValue(path :+ "either:right", right).map(Right(_)) case str => fail(path :+ "either", s"Unexpected field name: $str") } } @@ -614,11 +619,11 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { object MessagePackDecoder { type Path = Chunk[String] - type Result[A] = zio.prelude.Validation[DecodeError, A] + type Result[A] = Validation[DecodeError, A] private def succeed[A](a: => A): Result[A] = - zio.prelude.Validation.succeed(a) + Validation.succeed(a) private def fail(path: Path, failure: String): Result[Nothing] = - Left(MalformedFieldWithPath(path, failure)) + Validation.fail(MalformedFieldWithPath(path, failure)) } diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala index 32b6cb46d..1108c54d3 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala @@ -2,13 +2,11 @@ package zio.schema.codec import java.time._ import java.util.UUID - import scala.collection.immutable.ListMap - import org.msgpack.core.MessagePack - import zio.Chunk -import zio.schema.{ DynamicValue, Schema, StandardType } +import zio.prelude.data.Optional.AllValuesAreNullable +import zio.schema.{DynamicValue, Schema, StandardType} private[codec] class MessagePackEncoder { private val packer = MessagePack.newDefaultBufferPacker() @@ -27,11 +25,11 @@ private[codec] class MessagePackEncoder { case (Schema.Sequence(element, _, g, _, _), v) => encodeSequence(element, g(v)) case (mapSchema: Schema.Map[_, _], map: Map[_, _]) => encodeMap(mapSchema.asInstanceOf[Schema.Map[Any, Any]], map.asInstanceOf[scala.collection.immutable.Map[Any, Any]]) case (setSchema: Schema.Set[_], set: Set[_]) => encodeSet(setSchema.asInstanceOf[Schema.Set[Any]].elementSchema, set.asInstanceOf[scala.collection.immutable.Set[Any]]) - case (Schema.Transform(schema, _, g, _, _), _) => g(value).foreach(encodeValue(schema, _)) + case (Schema.Transform(schema, _, g, _, _), _) => g(value).map(v => encodeValue(schema, v)): Unit case (Schema.Primitive(standardType, _), v) => encodePrimitive(standardType, v) case (Schema.Tuple2(left, right, _), v @ (_, _)) => encodeTuple(left, right, v) case (optSchema: Schema.Optional[_], v: Option[_]) => encodeOptional(optSchema.asInstanceOf[Schema.Optional[Any]].schema, v.asInstanceOf[Option[Any]]) - case (eitherSchema: Schema.zio.prelude.Validation[_, _], v: zio.prelude.Validation[_, _]) => encodeEither(eitherSchema.asInstanceOf[Schema.zio.prelude.Validation[Any, Any]].left, eitherSchema.asInstanceOf[Schema.zio.prelude.Validation[Any, Any]].right, v.asInstanceOf[zio.prelude.Validation[Any, Any]]) + case (eitherSchema: Schema.Either[_, _], v: Either[_, _]) => encodeEither(eitherSchema.asInstanceOf[Schema.Either[Any, Any]].left, eitherSchema.asInstanceOf[Schema.Either[Any, Any]].right, v.asInstanceOf[scala.Either[Any, Any]]) case (lzy @ Schema.Lazy(_), v) => encodeValue(lzy.schema, v) // case (Schema.Meta(ast, _), _) => encodeValue(fieldNumber, Schema[MetaSchema], ast) case (Schema.CaseClass0(_, _, _), _) => encodePrimitive(StandardType.UnitType, ()) @@ -128,13 +126,13 @@ private[codec] class MessagePackEncoder { } } - private def encodezio.prelude.Validation[A, B](left: Schema[A], right: Schema[B], either: zio.prelude.Validation[A, B]): Unit = { + private def encodeEither[A, B](left: Schema[A], right: Schema[B], either: Either[A, B]): Unit = { packer.packMapHeader(1) either match { case Left(value) => packer.packString("left") encodeValue(left, value) - case zio.prelude.Validation.succeed(value) => + case Right(value) => packer.packString("right") encodeValue(right, value) } diff --git a/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala b/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala index a1c7dc346..505f50492 100644 --- a/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala +++ b/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala @@ -2,21 +2,18 @@ package zio.schema.codec import java.time._ import java.util.UUID - import scala.collection.immutable.ListMap import scala.util.Try - import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.scala.DefaultScalaModule -import org.msgpack.core.{ MessagePack, MessagePacker } +import org.msgpack.core.{MessagePack, MessagePacker} import org.msgpack.jackson.dataformat.MessagePackFactory - import zio.schema.CaseSet.caseOf import zio.schema._ -import zio.stream.{ ZSink, ZStream } +import zio.stream.{ZSink, ZStream} import zio.test.Assertion._ import zio.test._ -import zio.{ Chunk, Console, Scope, Task, ZIO } +import zio.{Chunk, Console, NonEmptyChunk, Scope, Task, ZIO} object MessagePackCodecSpec extends ZIOSpecDefault { @@ -413,7 +410,7 @@ object MessagePackCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(either))) && assert(ed2)(equalTo(either)) }, test("either right") { - val either = zio.prelude.Validation.succeed("hello") + val either = Right("hello") for { ed <- encodeAndDecode(eitherSchema, either) ed2 <- encodeAndDecodeNS(eitherSchema, either) @@ -427,8 +424,8 @@ object MessagePackCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(eitherLeft))) && assert(ed2)(equalTo(eitherLeft)) }, test("either with sum type") { - val eitherRight = zio.prelude.Validation.succeed(BooleanValue(true)) - val eitherRight2 = zio.prelude.Validation.succeed(StringValue("hello")) + val eitherRight = Right(BooleanValue(true)) + val eitherRight2 = Right(StringValue("hello")) for { ed <- encodeAndDecode(complexEitherSchema, eitherRight2) ed2 <- encodeAndDecodeNS(complexEitherSchema, eitherRight) @@ -525,7 +522,7 @@ object MessagePackCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(value))) && assert(ed2)(equalTo(value)) }, test("either within either") { - val either = zio.prelude.Validation.succeed(Left(BooleanValue(true))) + val either = Right(Left(BooleanValue(true))) val schema = Schema.either(Schema[Int], Schema.either(schemaOneOf, Schema[String])) for { ed <- encodeAndDecode(schema, either) @@ -696,7 +693,7 @@ object MessagePackCodecSpec extends ZIOSpecDefault { }, test("empty input by non streaming variant") { assertZIO(decodeNS(Schema[Int], "").exit)( - failsWithA[DecodeError] + failsWithA[NonEmptyChunk[DecodeError]] ) } ), @@ -709,7 +706,7 @@ object MessagePackCodecSpec extends ZIOSpecDefault { failsWithA[DecodeError] ) && assert(d2)( - failsWithA[DecodeError] + failsWithA[NonEmptyChunk[DecodeError]] ) }, test("missing value") { @@ -894,12 +891,12 @@ object MessagePackCodecSpec extends ZIOSpecDefault { val complexTupleSchema: Schema.Tuple2[Record, OneOf] = Schema.Tuple2(Record.schemaRecord, schemaOneOf) - val eitherSchema: Schema.zio.prelude.Validation[Int, String] = Schema.Either(Schema[Int], Schema[String]) + val eitherSchema: Schema.Either[Int, String] = Schema.Either(Schema[Int], Schema[String]) - val complexEitherSchema: Schema.zio.prelude.Validation[Record, OneOf] = + val complexEitherSchema: Schema.Either[Record, OneOf] = Schema.Either(Record.schemaRecord, schemaOneOf) - val complexEitherSchema2: Schema.zio.prelude.Validation[MyRecord, MyRecord] = + val complexEitherSchema2: Schema.Either[MyRecord, MyRecord] = Schema.Either(myRecord, myRecord) case class RichProduct(stringOneOf: OneOf, basicString: BasicString, record: Record) @@ -988,8 +985,8 @@ object MessagePackCodecSpec extends ZIOSpecDefault { .run(ZSink.collectAll) //NS == non streaming variant of decode - def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, DecodeError, A] = - ZIO.succeed(MessagePackCodec.messagePackCodec(schema).decode(fromHex(hex))).absolve[DecodeError, A] + def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, NonEmptyChunk[DecodeError], A] = + ZIO.succeed(MessagePackCodec.messagePackCodec(schema).decode(fromHex(hex)).toEither).absolve def encodeAndDecode[A](schema: Schema[A], input: A): ZIO[Any, DecodeError, Chunk[A]] = ZStream @@ -1006,20 +1003,20 @@ object MessagePackCodecSpec extends ZIOSpecDefault { .run(ZSink.collectAll) //NS == non streaming variant of encodeAndDecode - def encodeAndDecodeNS[A](schema: Schema[A], input: A, print: Boolean = false): ZIO[Any, DecodeError, A] = + def encodeAndDecodeNS[A](schema: Schema[A], input: A, print: Boolean = false): ZIO[Any, NonEmptyChunk[DecodeError], A] = ZIO .succeed(input) .tap(value => Console.printLine(s"Input Value: $value").when(print).ignore) .map(a => MessagePackCodec.messagePackCodec(schema).encode(a)) .tap(encoded => Console.printLine(s"\nEncoded Bytes:\n${toHex(encoded)}").when(print).ignore) - .map(ch => MessagePackCodec.messagePackCodec(schema).decode(ch)) + .map(ch => MessagePackCodec.messagePackCodec(schema).decode(ch).toEither) .absolve - def encodeAndDecodeNS[A](encodeSchema: Schema[A], decodeSchema: Schema[A], input: A): ZIO[Any, DecodeError, A] = + def encodeAndDecodeNS[A](encodeSchema: Schema[A], decodeSchema: Schema[A], input: A): ZIO[Any, NonEmptyChunk[DecodeError], A] = ZIO .succeed(input) .map(a => MessagePackCodec.messagePackCodec(encodeSchema).encode(a)) - .map(ch => MessagePackCodec.messagePackCodec(decodeSchema).decode(ch)) + .map(ch => MessagePackCodec.messagePackCodec(decodeSchema).decode(ch).toEither) .absolve } 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 7a10c8b38..03bb3fcfa 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 @@ -34,7 +34,7 @@ object ZioOpticsBuilder extends AccessorBuilder { ): ZPrism[S, S, A, A] = ZPrism( get = ZioOpticsBuilder.makePrismGet(term), - set = (piece: A) => zio.prelude.Validation.succeed(piece.asInstanceOf[S]) + set = (piece: A) => Right(piece.asInstanceOf[S]) ) override def makeTraversal[S, A]( @@ -62,15 +62,15 @@ object ZioOpticsBuilder extends AccessorBuilder { private[optics] def makeLensGet[S, A]( product: Schema.Record[S], term: Schema.Field[S, A] - ): S => zio.prelude.Validation[(OpticFailure, S), A] = { (whole: S) => + ): S => Either[(OpticFailure, S), A] = { (whole: S) => product.toDynamic(whole) match { case DynamicValue.Record(_, values) => values .get(term.name) .map { dynamicField => - term.schema.fromDynamic(dynamicField) match { - case Left(error) => Left(OpticFailure(error) -> whole) - case zio.prelude.Validation.succeed(value) => zio.prelude.Validation.succeed(value) + term.schema.fromDynamic(dynamicField).toEither match { + case Left(error) => Left(OpticFailure(error.toString()) -> whole) + case Right(value) => Right(value) } } .getOrElse(Left(OpticFailure(s"No term found with label ${term.name}") -> whole)) @@ -81,13 +81,13 @@ object ZioOpticsBuilder extends AccessorBuilder { private[optics] def makeLensSet[S, A]( product: Schema.Record[S], term: Schema.Field[S, A] - ): A => S => zio.prelude.Validation[(OpticFailure, S), S] = { (piece: A) => (whole: S) => + ): A => S => Either[(OpticFailure, S), S] = { (piece: A) => (whole: S) => product.toDynamic(whole) match { case DynamicValue.Record(name, values) => val updated = spliceRecord(values, term.name, term.name -> term.schema.toDynamic(piece)) - product.fromDynamic(DynamicValue.Record(name, updated)) match { - case Left(error) => Left(OpticFailure(error) -> whole) - case zio.prelude.Validation.succeed(value) => zio.prelude.Validation.succeed(value) + product.fromDynamic(DynamicValue.Record(name, updated)).toEither match { + case Left(error) => Left(OpticFailure(error.toString()) -> whole) + case Right(value) => Right(value) } case _ => Left(OpticFailure(s"Unexpected dynamic value for whole") -> whole) } @@ -95,22 +95,22 @@ object ZioOpticsBuilder extends AccessorBuilder { private[optics] def makePrismGet[S, A]( term: Schema.Case[S, A] - ): S => zio.prelude.Validation[(OpticFailure, S), A] = { (whole: S) => + ): S => Either[(OpticFailure, S), A] = { (whole: S) => term.deconstructOption(whole) match { - case Some(a) => zio.prelude.Validation.succeed(a) + case Some(a) => Right(a) case None => Left(OpticFailure(s"Cannot deconstruct to term ${term.id}") -> whole) } } private[optics] def makeSeqTraversalGet[S, A]( collection: Schema.Sequence[S, A, _] - ): S => zio.prelude.Validation[(OpticFailure, S), Chunk[A]] = { (whole: S) => - zio.prelude.Validation.succeed(collection.toChunk(whole)) + ): S => Either[(OpticFailure, S), Chunk[A]] = { (whole: S) => + Right(collection.toChunk(whole)) } private[optics] def makeSeqTraversalSet[S, A]( collection: Schema.Sequence[S, A, _] - ): Chunk[A] => S => zio.prelude.Validation[(OpticFailure, S), S] = { (piece: Chunk[A]) => (whole: S) => + ): Chunk[A] => S => Either[(OpticFailure, S), S] = { (piece: Chunk[A]) => (whole: S) => val builder = ChunkBuilder.make[A]() val leftIterator = collection.toChunk(whole).iterator val rightIterator = piece.iterator @@ -121,24 +121,24 @@ object ZioOpticsBuilder extends AccessorBuilder { while (leftIterator.hasNext) { builder += leftIterator.next() } - zio.prelude.Validation.succeed(collection.fromChunk(builder.result())) + Right(collection.fromChunk(builder.result())) } - private[optics] def makeMapTraversalGet[K, V](whole: Map[K, V]): zio.prelude.Validation[(OpticFailure, Map[K, V]), Chunk[(K, V)]] = - zio.prelude.Validation.succeed(Chunk.fromIterable(whole)) + private[optics] def makeMapTraversalGet[K, V](whole: Map[K, V]): Either[(OpticFailure, Map[K, V]), Chunk[(K, V)]] = + Right(Chunk.fromIterable(whole)) private[optics] def makeMapTraversalSet[K, V] - : Chunk[(K, V)] => Map[K, V] => zio.prelude.Validation[(OpticFailure, Map[K, V]), Map[K, V]] = { + : Chunk[(K, V)] => Map[K, V] => Either[(OpticFailure, Map[K, V]), Map[K, V]] = { (piece: Chunk[(K, V)]) => (whole: Map[K, V]) => - zio.prelude.Validation.succeed(whole ++ piece.toList) + Right(whole ++ piece.toList) } - private[optics] def makeSetTraversalGet[A](whole: Set[A]): zio.prelude.Validation[(OpticFailure, Set[A]), Chunk[A]] = - zio.prelude.Validation.succeed(Chunk.fromIterable(whole)) + private[optics] def makeSetTraversalGet[A](whole: Set[A]): Either[(OpticFailure, Set[A]), Chunk[A]] = + Right(Chunk.fromIterable(whole)) - private[optics] def makeSetTraversalSet[A]: Chunk[A] => Set[A] => zio.prelude.Validation[(OpticFailure, Set[A]), Set[A]] = { + private[optics] def makeSetTraversalSet[A]: Chunk[A] => Set[A] => Either[(OpticFailure, Set[A]), Set[A]] = { (piece: Chunk[A]) => (whole: Set[A]) => - zio.prelude.Validation.succeed(whole ++ piece.toSet) + Right(whole ++ piece.toSet) } private def spliceRecord( diff --git a/zio-schema-optics/shared/src/test/scala/zio/schema/optics/LensSpec.scala b/zio-schema-optics/shared/src/test/scala/zio/schema/optics/LensSpec.scala index d4f77c703..bc1678179 100644 --- a/zio-schema-optics/shared/src/test/scala/zio/schema/optics/LensSpec.scala +++ b/zio-schema-optics/shared/src/test/scala/zio/schema/optics/LensSpec.scala @@ -32,7 +32,7 @@ object LensSpec extends ZIOSpecDefault { ): URIO[Env, TestResult] = check(genWhole) { wholeBefore => val wholeAfter = lens.get(wholeBefore).flatMap(lens.set(_)(wholeBefore)) - assert(wholeAfter)(iszio.prelude.Validation.succeed(equalTo(wholeBefore))) + assert(wholeAfter)(isRight(equalTo(wholeBefore))) } def setGetIdentity[F, Env <: TestConfig, Whole, Piece](genWhole: Gen[Env, Whole], genPiece: Gen[Env, Piece])( @@ -40,7 +40,7 @@ object LensSpec extends ZIOSpecDefault { ): URIO[Env, TestResult] = check(genWhole, genPiece) { (whole, pieceBefore) => val pieceAfter = lens.set(pieceBefore)(whole).flatMap(lens.get) - assert(pieceAfter)(iszio.prelude.Validation.succeed(equalTo(pieceBefore))) + assert(pieceAfter)(isRight(equalTo(pieceBefore))) } def setSetIdentity[F, Env <: TestConfig, Whole, Piece](genWhole: Gen[Env, Whole], genPiece: Gen[Env, Piece])( 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 7ac12dd35..b2066376c 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 @@ -1,20 +1,20 @@ package zio.schema.codec +import zio.prelude.Validation + import java.nio.charset.StandardCharsets -import java.nio.{ ByteBuffer, ByteOrder } +import java.nio.{ByteBuffer, ByteOrder} import java.time._ import java.time.format.DateTimeFormatter import java.util.UUID - import scala.collection.immutable.ListMap import scala.util.control.NonFatal - import zio.schema.MutableSchemaBasedValueBuilder.CreateValueFromSchemaError import zio.schema._ -import zio.schema.codec.DecodeError.{ ExtraFields, MalformedField, MissingField } +import zio.schema.codec.DecodeError.{ExtraFields, MalformedField, MissingField} import zio.schema.codec.ProtobufCodec.Protobuf.WireType.LengthDelimited import zio.stream.ZPipeline -import zio.{ Cause, Chunk, ChunkBuilder, Unsafe, ZIO } +import zio.{Cause, Chunk, ChunkBuilder, Unsafe, ZIO} object ProtobufCodec { @@ -24,7 +24,7 @@ object ProtobufCodec { new Decoder(whole).decode(schema) override def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] = - ZPipeline.mapChunksZIO(chunk => ZIO.fromEither(new Decoder(chunk).decode(schema).map(Chunk(_)))) + ZPipeline.mapChunksZIO(chunk => ZIO.fromEither(new Decoder(chunk).decode(schema).map(Chunk(_)).toEither.left.map(_.head))) override def encode(value: A): Chunk[Byte] = Encoder.process(schema, value) @@ -59,7 +59,7 @@ object ProtobufCodec { case _: Schema.Tuple2[_, _] => false case _: Schema.Optional[_] => false case _: Schema.Fail[_] => false - case _: Schema.zio.prelude.Validation[_, _] => false + case _: Schema.Either[_, _] => false case lzy @ Schema.Lazy(_) => canBePacked(lzy.schema) case _ => false } @@ -213,8 +213,8 @@ object ProtobufCodec { override protected def processEither( context: EncoderContext, - schema: Schema.zio.prelude.Validation[_, _], - value: zio.prelude.Validation[Chunk[Byte], Chunk[Byte]] + schema: Schema.Either[_, _], + value: Either[Chunk[Byte], Chunk[Byte]] ): Chunk[Byte] = { val encodedEither = value.merge encodeKey(WireType.LengthDelimited(encodedEither.size), context.fieldNumber) ++ encodedEither @@ -269,10 +269,10 @@ object ProtobufCodec { ): EncoderContext = context.copy(fieldNumber = Some(index + 1)) - override protected def contextForEither(context: EncoderContext, e: zio.prelude.Validation[Unit, Unit]): EncoderContext = + override protected def contextForEither(context: EncoderContext, e: Either[Unit, Unit]): EncoderContext = e match { case Left(_) => context.copy(fieldNumber = Some(1)) - case zio.prelude.Validation.succeed(_) => context.copy(fieldNumber = Some(2)) + case Right(_) => context.copy(fieldNumber = Some(2)) } override protected def contextForOption(context: EncoderContext, o: Option[Unit]): EncoderContext = @@ -494,18 +494,17 @@ object ProtobufCodec { private val state: DecoderState = new DecoderState(chunk, 0) def decode[A](schema: Schema[A]): zio.prelude.Validation[DecodeError, A] = - try { - zio.prelude.Validation.succeed(create(schema).asInstanceOf[A]) - } catch { - case CreateValueFromSchemaError(_, cause) => - cause match { - case error: DecodeError => Left(error) - case _ => - Left(DecodeError.ReadError(Cause.fail(cause), cause.getMessage)) - } - case NonFatal(err) => - Left(DecodeError.ReadError(Cause.fail(err), err.getMessage)) - } + Validation(create(schema).asInstanceOf[A]) + .mapError { + case CreateValueFromSchemaError(_, cause) => + cause match { + case error: DecodeError => error + case _ => + DecodeError.ReadError(Cause.fail(cause), cause.getMessage) + } + case NonFatal(err) => + DecodeError.ReadError(Cause.fail(err), err.getMessage) + } private def createTypedPrimitive[A](context: DecoderContext, standardType: StandardType[A]): A = createPrimitive(context, standardType).asInstanceOf[A] @@ -623,10 +622,8 @@ object ProtobufCodec { values: Chunk[(Int, Any)] ): Any = Unsafe.unsafe { implicit u => - record.construct(values.map(_._2)) match { - case zio.prelude.Validation.succeed(result) => result - case Left(message) => throw DecodeError.ReadError(Cause.empty, message) - } + //TODO: Maybe combine exceptions? + record.construct(values.map(_._2)).fold(message => throw DecodeError.ReadError(Cause.empty, message.toString()), a => a) } override protected def startCreatingEnum( @@ -814,19 +811,19 @@ object ProtobufCodec { override protected def startCreatingEither( context: DecoderContext, - schema: Schema.zio.prelude.Validation[_, _] - ): zio.prelude.Validation[DecoderContext, DecoderContext] = + schema: Schema.Either[_, _] + ): Either[DecoderContext, DecoderContext] = keyDecoder(context) match { case (_, fieldNumber) if fieldNumber == 1 => Left(context) - case (_, fieldNumber) if fieldNumber == 2 => zio.prelude.Validation.succeed(context) + case (_, fieldNumber) if fieldNumber == 2 => Right(context) case (_, fieldNumber) => throw ExtraFields(fieldNumber.toString, s"Invalid field number ($fieldNumber) for either") } override protected def createEither( context: DecoderContext, - schema: Schema.zio.prelude.Validation[_, _], - value: zio.prelude.Validation[Any, Any] + schema: Schema.Either[_, _], + value: Either[Any, Any] ): Any = value @@ -877,11 +874,10 @@ object ProtobufCodec { value: Any, f: Any => zio.prelude.Validation[String, Any], schema: Schema[_] - ): Any = - f(value) match { - case Left(value) => throw MalformedField(schema, value) - case zio.prelude.Validation.succeed(value) => value - } + ): Any = { + //TODO: Maybe combine exceptions? + f(value).fold(v => throw MalformedField(schema, v.toString()) , a => a) + } override protected def fail(context: DecoderContext, message: String): Any = throw DecodeError.ReadError(Cause.empty, message) diff --git a/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala b/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala index 3b1430258..4f7f7d376 100644 --- a/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala +++ b/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala @@ -475,7 +475,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(either))) && assert(ed2)(equalTo(either)) }, test("either right") { - val either = zio.prelude.Validation.succeed("hello") + val either = Right("hello") for { ed <- encodeAndDecode(eitherSchema, either) ed2 <- encodeAndDecodeNS(eitherSchema, either) @@ -489,8 +489,8 @@ object ProtobufCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(eitherLeft))) && assert(ed2)(equalTo(eitherLeft)) }, test("either with sum type") { - val eitherRight = zio.prelude.Validation.succeed(BooleanValue(true)) - val eitherRight2 = zio.prelude.Validation.succeed(StringValue("hello")) + val eitherRight = Right(BooleanValue(true)) + val eitherRight2 = Right(StringValue("hello")) for { ed <- encodeAndDecode(complexEitherSchema, eitherRight2) ed2 <- encodeAndDecodeNS(complexEitherSchema, eitherRight) @@ -575,7 +575,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(value))) && assert(ed2)(equalTo(value)) }, test("either within either") { - val either = zio.prelude.Validation.succeed(Left(BooleanValue(true))) + val either = Right(Left(BooleanValue(true))) val schema = Schema.either(Schema[Int], Schema.either(schemaOneOf, Schema[String])) for { ed <- encodeAndDecode(schema, either) @@ -633,7 +633,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { for { ed <- encodeAndDecode2(schema, value) // ed2 <- encodeAndDecodeNS(schema, value) - } yield assertTrue(ed == zio.prelude.Validation.succeed(Chunk(value))) //&& assert(ed2)(equalTo(value)) + } yield assertTrue(ed == Right(Chunk(value))) //&& assert(ed2)(equalTo(value)) } }, test("deep recursive data types") { @@ -642,7 +642,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { for { ed <- encodeAndDecode2(schema, value) // ed2 <- encodeAndDecodeNS(schema, value) - } yield assertTrue(ed == zio.prelude.Validation.succeed(Chunk(value))) //&& assert(ed2)(equalTo(value)) + } yield assertTrue(ed == Right(Chunk(value))) //&& assert(ed2)(equalTo(value)) } } @@ TestAspect.size(200) ), @@ -944,12 +944,12 @@ object ProtobufCodecSpec extends ZIOSpecDefault { val complexTupleSchema: Schema.Tuple2[Record, OneOf] = Schema.Tuple2(Record.schemaRecord, schemaOneOf) - val eitherSchema: Schema.zio.prelude.Validation[Int, String] = Schema.Either(Schema[Int], Schema[String]) + val eitherSchema: Schema.Either[Int, String] = Schema.Either(Schema[Int], Schema[String]) - val complexEitherSchema: Schema.zio.prelude.Validation[Record, OneOf] = + val complexEitherSchema: Schema.Either[Record, OneOf] = Schema.Either(Record.schemaRecord, schemaOneOf) - val complexEitherSchema2: Schema.zio.prelude.Validation[MyRecord, MyRecord] = + val complexEitherSchema2: Schema.Either[MyRecord, MyRecord] = Schema.Either(myRecord, myRecord) case class RichProduct(stringOneOf: OneOf, basicString: BasicString, record: Record) @@ -1044,7 +1044,9 @@ object ProtobufCodecSpec extends ZIOSpecDefault { //NS == non streaming variant of decode def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, DecodeError, A] = - ZIO.succeed(ProtobufCodec.protobufCodec(schema).decode(fromHex(hex))).absolve[DecodeError, A] + ZIO.succeed(ProtobufCodec.protobufCodec(schema).decode(fromHex(hex))) + .map(_.toEither.left.map(_.head)) + .absolve[DecodeError, A] def encodeAndDecode[A](schema: Schema[A], input: A): ZIO[Any, DecodeError, Chunk[A]] = ProtobufCodec @@ -1054,7 +1056,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { .apply(ZStream.succeed(input)) .run(ZSink.collectAll) - def encodeAndDecode2[A](schema: Schema[A], input: A): ZIO[Any, Any, zio.prelude.Validation[DecodeError, Chunk[A]]] = + def encodeAndDecode2[A](schema: Schema[A], input: A): ZIO[Any, Any, scala.Either[DecodeError, Chunk[A]]] = ProtobufCodec .protobufCodec(schema) .streamEncoder @@ -1083,6 +1085,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { .map(a => ProtobufCodec.protobufCodec(schema).encode(a)) .tap(encoded => printLine(s"\nEncoded Bytes (${encoded.size}):\n${toHex(encoded)}").when(print).ignore) .map(ch => ProtobufCodec.protobufCodec(schema).decode(ch)) + .map(_.toEither.left.map(_.head)) .absolve def encodeAndDecodeNS2[A]( @@ -1097,7 +1100,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { .tap(encoded => printLine(s"\nEncoded Bytes:\n${toHex(encoded)}").when(print).ignore) .map(ch => ProtobufCodec.protobufCodec(schema).decode(ch)) .tapSome { - case Left(err) => printLine(s"Failed to encode and decode value $input\nError = $err").orDie + case prelude.Validation.Failure(_, err) => printLine(s"Failed to encode and decode value $input\nError = $err").orDie } def encodeAndDecodeNS[A](encodeSchema: Schema[A], decodeSchema: Schema[A], input: A): ZIO[Any, DecodeError, A] = @@ -1105,6 +1108,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { .succeed(input) .map(a => ProtobufCodec.protobufCodec(encodeSchema).encode(a)) .map(ch => ProtobufCodec.protobufCodec(decodeSchema).decode(ch)) + .map(_.toEither.left.map(_.head)) .absolve } diff --git a/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala b/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala index 3dc39e875..51a520585 100644 --- a/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala +++ b/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala @@ -3,19 +3,17 @@ package zio.schema.codec import java.nio.ByteBuffer import java.time._ import java.util.UUID - -import scala.annotation.{ nowarn, tailrec } +import scala.annotation.{nowarn, tailrec} import scala.collection.immutable.ListMap import scala.util.control.NonFatal - import org.apache.thrift.protocol._ - +import zio.prelude.Validation import zio.schema.MutableSchemaBasedValueBuilder.CreateValueFromSchemaError import zio.schema._ -import zio.schema.annotation.{ fieldDefaultValue, optionalField, transientField } -import zio.schema.codec.DecodeError.{ EmptyContent, MalformedFieldWithPath, ReadError, ReadErrorWithPath } +import zio.schema.annotation.{fieldDefaultValue, optionalField, transientField} +import zio.schema.codec.DecodeError.{EmptyContent, MalformedField, MalformedFieldWithPath, ReadError, ReadErrorWithPath} import zio.stream.ZPipeline -import zio.{ Cause, Chunk, Unsafe, ZIO } +import zio.{Cause, Chunk, NonEmptyChunk, Unsafe, ZIO} object ThriftCodec { @@ -23,14 +21,14 @@ object ThriftCodec { new BinaryCodec[A] { override def decode(whole: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = if (whole.isEmpty) - Left(EmptyContent("No bytes to decode")) + Validation.fail(EmptyContent("No bytes to decode")) else decodeChunk(whole) override def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] = ZPipeline.mapChunksZIO { chunk => ZIO.fromEither( - decodeChunk(chunk).map(Chunk(_)) + decodeChunk(chunk).map(Chunk(_)).toEither.left.map(_.head) ) } @@ -46,27 +44,24 @@ object ThriftCodec { private def decodeChunk(chunk: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = if (chunk.isEmpty) - Left(EmptyContent("No bytes to decode")) + Validation.fail(EmptyContent("No bytes to decode")) else { - try { - zio.prelude.Validation.succeed( - new Decoder(chunk) - .create(schema) - .asInstanceOf[A] - ) - } catch { - case error: CreateValueFromSchemaError[DecoderContext] => - error.cause match { - case error: DecodeError => Left(error) - case _ => - Left( + zio.prelude.Validation( + new Decoder(chunk) + .create(schema) + .asInstanceOf[A] + ) + .mapError { + case error: CreateValueFromSchemaError[DecoderContext] => + error.cause match { + case error: DecodeError => error + case _ => ReadErrorWithPath(error.context.path, Cause.fail(error.cause), error.cause.getMessage) - ) - } - case NonFatal(err) => - Left(ReadError(Cause.fail(err), err.getMessage)) - } - }: @nowarn + } + case NonFatal(err) => + ReadError(Cause.fail(err), err.getMessage) + } + } } class Encoder extends MutableSchemaBasedValueProcessor[Unit, Encoder.Context] { @@ -133,13 +128,13 @@ object ThriftCodec { override protected def processSet(context: Context, schema: Schema.Set[_], value: Set[Unit]): Unit = {} - override protected def startProcessingEither(context: Context, schema: Schema.zio.prelude.Validation[_, _]): Unit = + override protected def startProcessingEither(context: Context, schema: Schema.Either[_, _]): Unit = writeFieldBegin(context.fieldNumber, TType.STRUCT) override protected def processEither( context: Context, - schema: Schema.zio.prelude.Validation[_, _], - value: zio.prelude.Validation[Unit, Unit] + schema: Schema.Either[_, _], + value: Either[Unit, Unit] ): Unit = writeFieldEnd() @@ -184,10 +179,10 @@ object ThriftCodec { override protected def contextForEnumConstructor(context: Context, index: Int, c: Schema.Case[_, _]): Context = context.copy(fieldNumber = Some((index + 1).toShort)) - override protected def contextForEither(context: Context, e: zio.prelude.Validation[Unit, Unit]): Context = + override protected def contextForEither(context: Context, e: Either[Unit, Unit]): Context = e match { case Left(_) => context.copy(fieldNumber = Some(1)) - case zio.prelude.Validation.succeed(_) => context.copy(fieldNumber = Some(2)) + case Right(_) => context.copy(fieldNumber = Some(2)) } override protected def contextForOption(context: Context, o: Option[Unit]): Context = @@ -625,17 +620,11 @@ object ThriftCodec { } } Unsafe.unsafe { implicit u => - record.construct(allValues) match { - case Left(message) => fail(context, message) - case zio.prelude.Validation.succeed(value) => value - } + record.construct(allValues).mapError(message => fail(context, message)) } } else { Unsafe.unsafe { implicit u => - record.construct(Chunk.empty) match { - case Left(message) => fail(context, message) - case zio.prelude.Validation.succeed(value) => value - } + record.construct(Chunk.empty).mapError(message => fail(context, message)) } } @@ -772,20 +761,20 @@ object ThriftCodec { override protected def startCreatingEither( context: DecoderContext, - schema: Schema.zio.prelude.Validation[_, _] - ): zio.prelude.Validation[DecoderContext, DecoderContext] = { + schema: Schema.Either[_, _] + ): Either[DecoderContext, DecoderContext] = { val readField = p.readFieldBegin() readField.id match { case 1 => Left(context.copy(path = context.path :+ "either:left")) - case 2 => zio.prelude.Validation.succeed(context.copy(path = context.path :+ "either:right")) - case _ => fail(context, "Failed to decode either.").asInstanceOf[zio.prelude.Validation[DecoderContext, DecoderContext]] + case 2 => Right(context.copy(path = context.path :+ "either:right")) + case _ => fail(context, "Failed to decode either.").asInstanceOf[Nothing] } } override protected def createEither( context: DecoderContext, - schema: Schema.zio.prelude.Validation[_, _], - value: zio.prelude.Validation[Any, Any] + schema: Schema.Either[_, _], + value: Either[Any, Any] ): Any = value @@ -821,14 +810,14 @@ object ThriftCodec { f: Any => zio.prelude.Validation[String, Any], schema: Schema[_] ): Any = - f(value) match { - case Left(value) => fail(context, value) - case zio.prelude.Validation.succeed(value) => value - } + f(value).fold(v => fail(context, v), a => a) - override protected def fail(context: DecoderContext, message: String): Any = + override protected def fail(context: DecoderContext, message: String): Nothing = throw MalformedFieldWithPath(context.path, message) + protected def fail(context: DecoderContext, message: NonEmptyChunk[String]): Nothing = + throw MalformedFieldWithPath(context.path, message.mkString) + override protected val initialContext: DecoderContext = DecoderContext(Chunk.empty, None) private def emptyValue[A](schema: Schema[A]): Option[A] = schema match { diff --git a/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala b/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala index 0cca11c1e..09263c0b2 100644 --- a/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala +++ b/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala @@ -1,40 +1,20 @@ package zio.schema.codec -import java.time.{ - DayOfWeek, - Duration, - Instant, - LocalDate, - LocalDateTime, - LocalTime, - Month, - MonthDay, - OffsetDateTime, - OffsetTime, - Period, - Year, - YearMonth, - ZoneId, - ZoneOffset, - ZonedDateTime -} +import java.time.{DayOfWeek, Duration, Instant, LocalDate, LocalDateTime, LocalTime, Month, MonthDay, OffsetDateTime, OffsetTime, Period, Year, YearMonth, ZoneId, ZoneOffset, ZonedDateTime} import java.util import java.util.UUID - import scala.collection.immutable.ListMap import scala.util.Try - import org.apache.thrift.TSerializable -import org.apache.thrift.protocol.{ TBinaryProtocol, TField, TType } - +import org.apache.thrift.protocol.{TBinaryProtocol, TField, TType} import zio.schema.CaseSet.caseOf -import zio.schema.annotation.{ fieldDefaultValue, optionalField, transientField } -import zio.schema.codec.{ generated => g } -import zio.schema.{ CaseSet, DeriveSchema, DynamicValue, DynamicValueGen, Schema, SchemaGen, StandardType, TypeId } -import zio.stream.{ ZSink, ZStream } +import zio.schema.annotation.{fieldDefaultValue, optionalField, transientField} +import zio.schema.codec.{generated => g} +import zio.schema.{CaseSet, DeriveSchema, DynamicValue, DynamicValueGen, Schema, SchemaGen, StandardType, TypeId} +import zio.stream.{ZSink, ZStream} import zio.test.Assertion._ import zio.test._ -import zio.{ Chunk, Console, Scope, Task, ZIO } +import zio.{Chunk, Console, NonEmptyChunk, Scope, Task, ZIO} // TODO: use generators instead of manual encode/decode @@ -465,7 +445,7 @@ object ThriftCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(either))) && assert(ed2)(equalTo(either)) }, test("either right") { - val either = zio.prelude.Validation.succeed("hello") + val either = Right("hello") for { ed <- encodeAndDecode(eitherSchema, either) ed2 <- encodeAndDecodeNS(eitherSchema, either) @@ -479,8 +459,8 @@ object ThriftCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(eitherLeft))) && assert(ed2)(equalTo(eitherLeft)) }, test("either with sum type") { - val eitherRight = zio.prelude.Validation.succeed(BooleanValue(true)) - val eitherRight2 = zio.prelude.Validation.succeed(StringValue("hello")) + val eitherRight = Right(BooleanValue(true)) + val eitherRight2 = Right(StringValue("hello")) for { ed <- encodeAndDecode(complexEitherSchema, eitherRight2) ed2 <- encodeAndDecodeNS(complexEitherSchema, eitherRight) @@ -597,7 +577,7 @@ object ThriftCodecSpec extends ZIOSpecDefault { } yield assert(ed)(equalTo(Chunk(value))) && assert(ed2)(equalTo(value)) }, test("either within either") { - val either = zio.prelude.Validation.succeed(Left(BooleanValue(true))) + val either = Right(Left(BooleanValue(true))) val schema = Schema.either(Schema[Int], Schema.either(schemaOneOf, Schema[String])) for { ed <- encodeAndDecode(schema, either) @@ -1020,12 +1000,12 @@ object ThriftCodecSpec extends ZIOSpecDefault { val complexTupleSchema: Schema.Tuple2[Record, OneOf] = Schema.Tuple2(Record.schemaRecord, schemaOneOf) - val eitherSchema: Schema.zio.prelude.Validation[Int, String] = Schema.Either(Schema[Int], Schema[String]) + val eitherSchema: Schema.Either[Int, String] = Schema.Either(Schema[Int], Schema[String]) - val complexEitherSchema: Schema.zio.prelude.Validation[Record, OneOf] = + val complexEitherSchema: Schema.Either[Record, OneOf] = Schema.Either(Record.schemaRecord, schemaOneOf) - val complexEitherSchema2: Schema.zio.prelude.Validation[MyRecord, MyRecord] = + val complexEitherSchema2: Schema.Either[MyRecord, MyRecord] = Schema.Either(myRecord, myRecord) case class RichProduct(stringOneOf: OneOf, basicString: BasicString, record: Record) @@ -1131,8 +1111,8 @@ object ThriftCodecSpec extends ZIOSpecDefault { .run(ZSink.collectAll) //NS == non streaming variant of decode - def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, DecodeError, A] = - ZIO.succeed(ThriftCodec.thriftCodec(schema).decode(fromHex(hex))).absolve[DecodeError, A] + def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, NonEmptyChunk[DecodeError], A] = + ZIO.succeed(ThriftCodec.thriftCodec(schema).decode(fromHex(hex)).toEither).absolve[NonEmptyChunk[DecodeError], A] def encodeAndDecode[A](schema: Schema[A], input: A): ZIO[Any, DecodeError, Chunk[A]] = ZStream @@ -1149,20 +1129,22 @@ object ThriftCodecSpec extends ZIOSpecDefault { .run(ZSink.collectAll) //NS == non streaming variant of encodeAndDecode - def encodeAndDecodeNS[A](schema: Schema[A], input: A, print: Boolean = false): ZIO[Any, DecodeError, A] = + def encodeAndDecodeNS[A](schema: Schema[A], input: A, print: Boolean = false): ZIO[Any, NonEmptyChunk[DecodeError], A] = ZIO .succeed(input) .tap(value => Console.printLine(s"Input Value: $value").when(print).ignore) .map(a => ThriftCodec.thriftCodec(schema).encode(a)) .tap(encoded => Console.printLine(s"\nEncoded Bytes:\n${toHex(encoded)}").when(print).ignore) .map(ch => ThriftCodec.thriftCodec(schema).decode(ch)) + .map(_.toEither) .absolve - def encodeAndDecodeNS[A](encodeSchema: Schema[A], decodeSchema: Schema[A], input: A): ZIO[Any, DecodeError, A] = + def encodeAndDecodeNS[A](encodeSchema: Schema[A], decodeSchema: Schema[A], input: A): ZIO[Any, NonEmptyChunk[DecodeError], A] = ZIO .succeed(input) .map(a => ThriftCodec.thriftCodec(encodeSchema).encode(a)) .map(ch => ThriftCodec.thriftCodec(decodeSchema).decode(ch)) + .map(_.toEither) .absolve } diff --git a/zio-schema-zio-test/shared/src/main/scala/zio/schema/DeriveGen.scala b/zio-schema-zio-test/shared/src/main/scala/zio/schema/DeriveGen.scala index cc0eaab16..b4c5cc03e 100644 --- a/zio-schema-zio-test/shared/src/main/scala/zio/schema/DeriveGen.scala +++ b/zio-schema-zio-test/shared/src/main/scala/zio/schema/DeriveGen.scala @@ -529,7 +529,7 @@ object DeriveGen { private def genTuple[A, B](tuple: Schema.Tuple2[A, B]): Gen[Sized, (A, B)] = gen(tuple.left).zip(gen(tuple.right)) - private def genzio.prelude.Validation[A, B](either: Schema.zio.prelude.Validation[A, B]): Gen[Sized, zio.prelude.Validation[A, B]] = + private def genEither[A, B](either: Schema.Either[A, B]): Gen[Sized, scala.Either[A, B]] = Gen.either(gen(either.left), gen(either.right)) private def genLazy[A](lazySchema: Schema.Lazy[A]): Gen[Sized, A] = diff --git a/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala b/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala index 6b72a610d..0ff84b645 100644 --- a/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala +++ b/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala @@ -1,6 +1,7 @@ package zio.schema import zio.Chunk +import zio.prelude.Validation object TestData { @@ -48,14 +49,14 @@ object TestData { val uuidSchema: Schema[java.util.UUID] = Schema.Primitive(StandardType.UUIDType) - val eitherSchema: Schema[zio.prelude.Validation[String, Unit]] = Schema.Either(stringSchema, unitSchema) + val eitherSchema: Schema[Either[String, Unit]] = Schema.Either(stringSchema, unitSchema) val tupleSchema: Schema[(String, Unit)] = Schema.Tuple2(stringSchema, unitSchema) val listSchema: Schema[List[Int]] = Schema.list(intSchema) val mapSchema: Schema[Map[Int, String]] = Schema.map(intSchema, stringSchema) val optionalSchema: Schema[Option[Int]] = Schema.Optional(intSchema) val transformSchema: Schema[String] = - intSchema.transformOrFail[String]((int: Int) => zio.prelude.Validation.succeed(int.toString), (_: String) => Left("error")) + intSchema.transformOrFail[String]((int: Int) => Validation.succeed(int.toString), (_: String) => Validation.fail("error")) val failSchema: Schema[Unit] = Schema.Fail[Unit]("failed") val lazySchema: Schema[Int] = Schema.Lazy(() => intSchema) diff --git a/zio-schema/shared/src/main/scala/zio/schema/Differ.scala b/zio-schema/shared/src/main/scala/zio/schema/Differ.scala index 4c3e4b70d..bef3b1592 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Differ.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Differ.scala @@ -57,8 +57,8 @@ trait Differ[A] { self => case (Some(l), Some(r)) => Patch.Transform[A, Option[A]]( self(l, r), - (a: A) => Validation(Some(a)), - (a: Option[A]) => a.map(zio.prelude.Validation.succeed(_)).getOrElse(Left("Patch cannot be applied to None value")) + (a: A) => Validation.succeed(Some(a)), + (a: Option[A]) => Validation.fromOptionWith("Patch cannot be applied to None value")(a) ) case (Some(_), None) => Patch.Total(None) case (None, Some(r)) => Patch.Total(Some(r)) @@ -520,11 +520,11 @@ object Differ { (thisValue: (A, B), thatValue: (A, B)) => (thisValue, thatValue) match { case ((thisA, thisB), (thatA, thatB)) => - left(thisA, thatA) <*> zio.prelude.Validation.succeed(thisB, thatB) + left(thisA, thatA) <*> right(thisB, thatB) } - def either[A, B](left: Differ[A], right: Differ[B]): Differ[Either[A, B]] = - instancePartial[Either[A, B]] { + def either[A, B](left: Differ[A], right: Differ[B]): Differ[scala.Either[A, B]] = + instancePartial[scala.Either[A, B]] { case (Left(l), Left(r)) => Patch.EitherDiff(Left(left(l, r))) case (Right(l), Right(r)) => Patch.EitherDiff(Right(right(l, r))) } 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 5419632ea..c6c50191d 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala @@ -15,8 +15,7 @@ sealed trait DynamicValue { def transform(transforms: Chunk[Migration]): zio.prelude.Validation[String, DynamicValue] = transforms.foldRight[zio.prelude.Validation[String, DynamicValue]](zio.prelude.Validation.succeed(self)) { - case (transform, zio.prelude.Validation.succeed(value)) => transform.migrate(value) - case (_, error @ Left(_)) => error + case (transform, result) => result.flatMap(transform.migrate) } def toTypedValue[A](implicit schema: Schema[A]): Validation[String, A] = @@ -41,8 +40,8 @@ sealed trait DynamicValue { .map(m => Chunk.fromIterable(m.values)) .flatMap( values => - Validation - .fromEither(s.construct(values)(Unsafe.unsafe).left.map(err => DecodeError.MalformedField(s, err))) + s.construct(values)(Unsafe.unsafe) + .mapError(err => DecodeError.MalformedField(s, err)) ) case (DynamicValue.Enumeration(_, (key, value)), s: Schema.Enum[A]) => @@ -56,7 +55,7 @@ sealed trait DynamicValue { value.toTypedValueLazyError(schema1).map(Left(_)) case (DynamicValue.RightValue(value), Schema.Either(_, schema1, _)) => - value.toTypedValueLazyError(schema1).map(zio.prelude.Validation.succeed(_)) + value.toTypedValueLazyError(schema1).map(Right(_)) case (DynamicValue.Tuple(leftValue, rightValue), Schema.Tuple2(leftSchema, rightSchema, _)) => val typedLeft = leftValue.toTypedValueLazyError(leftSchema) @@ -86,7 +85,7 @@ sealed trait DynamicValue { case (value, Schema.Transform(schema, f, _, _, _)) => value .toTypedValueLazyError(schema) - .flatMap(value => Validation.fromEither(f(value).left.map(err => DecodeError.MalformedField(schema, err)))) + .flatMap(value => f(value).mapError(err => DecodeError.MalformedField(schema, err))) case (DynamicValue.Dictionary(entries), schema: Schema.Map[k, v]) => Validation @@ -143,12 +142,12 @@ object DynamicValue { DynamicValue.SetValue(value) override protected def processEither( - schema: Schema.zio.prelude.Validation[_, _], - value: zio.prelude.Validation[DynamicValue, DynamicValue] + schema: Schema.Either[_, _], + value: Either[DynamicValue, DynamicValue] ): DynamicValue = value match { case Left(value) => DynamicValue.LeftValue(value) - case zio.prelude.Validation.succeed(value) => DynamicValue.RightValue(value) + case Right(value) => DynamicValue.RightValue(value) } override protected def processOption(schema: Schema.Optional[_], value: Option[DynamicValue]): DynamicValue = @@ -491,7 +490,7 @@ object DynamicValue { "values", Schema.defer(Schema.chunk(Schema.tuple2(Schema.primitive[String], DynamicValue.schema))), get0 = record => Chunk.fromIterable(record.values), - set0 = (record, values) => record.copy(values = values.foldzio.prelude.Validation.succeed(ListMap.empty[String, DynamicValue])((a, b) => b + a)) + set0 = (record, values) => record.copy(values = values.foldRight(ListMap.empty[String, DynamicValue])((a, b) => b + a)) ), (id, chunk) => DynamicValue.Record(id, ListMap(chunk.toSeq: _*)) ), diff --git a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala index 54faf1862..d1462c629 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala @@ -123,10 +123,17 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { * this method is responsible for gathering enough information to decide whether the created value will * be a Left or a Right. The result value represents this, and for each case allows specifying a context * that will be used to create the inner value. */ - protected def startCreatingEither(context: Context, schema: Schema.zio.prelude.Validation[_, _]): zio.prelude.Validation[Context, Context] + protected def startCreatingEither( + context: Context, + schema: Schema.Either[_, _] + ): Either[Context, Context] /** Create the either value from an inner value */ - protected def createEither(context: Context, schema: Schema.zio.prelude.Validation[_, _], value: zio.prelude.Validation[Target, Target]): Target + protected def createEither( + context: Context, + schema: Schema.Either[_, _], + value: Either[Target, Target] + ): Target /** The next value to be created is a tuple with the given schema. The returned context is used to * construct the first element of the tuple. */ @@ -147,7 +154,12 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { /** Transforms a value with the given function that can fail. Making this customizable allows encoding the failure * in Target. */ - protected def transform(context: Context, value: Target, f: Any => zio.prelude.Validation[String, Any], schema: Schema[_]): Target + protected def transform( + context: Context, + value: Target, + f: Any => zio.prelude.Validation[String, Any], + schema: Schema[_] + ): Target /** Fail the builder with the given message */ protected def fail(context: Context, message: String): Target @@ -615,7 +627,7 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { finishWith(createSet(contextStack.head, s, Chunk.empty)) } - case s: Schema.zio.prelude.Validation[l, r] => + case s: Schema.Either[l, r] => startCreatingEither(currentContext, s) match { case Left(newState) => currentSchema = s.left @@ -624,12 +636,12 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { contextStack = contextStack.tail finishWith(createEither(contextStack.head, s, Left(value))) } - case zio.prelude.Validation.succeed(newState) => + case Right(newState) => currentSchema = s.right pushContext(newState) push { value => contextStack = contextStack.tail - finishWith(createEither(contextStack.head, s, zio.prelude.Validation.succeed(value))) + finishWith(createEither(contextStack.head, s, Right(value))) } } @@ -663,7 +675,9 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { case s @ Schema.Transform(schema, f, _, _, _) => currentSchema = schema push { result => - finishWith(transform(currentContext, result, f.asInstanceOf[Any => zio.prelude.Validation[String, Any]], s)) + finishWith( + transform(currentContext, result, f.asInstanceOf[Any => zio.prelude.Validation[String, Any]], s) + ) } case s @ Schema.CaseClass0(_, _, _) => @@ -1111,18 +1125,21 @@ trait SimpleMutableSchemaBasedValueBuilder[Target] extends MutableSchemaBasedVal protected def createOptional(schema: Schema.Optional[_], value: Option[Target]): Target - override protected def startCreatingEither(context: Unit, schema: Schema.zio.prelude.Validation[_, _]): zio.prelude.Validation[Unit, Unit] = + override protected def startCreatingEither( + context: Unit, + schema: Schema.Either[_, _] + ): Either[Unit, Unit] = startCreatingEither(schema) - protected def startCreatingEither(schema: Schema.zio.prelude.Validation[_, _]): zio.prelude.Validation[Unit, Unit] + protected def startCreatingEither(schema: Schema.Either[_, _]): Either[Unit, Unit] override protected def createEither( context: Unit, - schema: Schema.zio.prelude.Validation[_, _], - value: zio.prelude.Validation[Target, Target] + schema: Schema.Either[_, _], + value: Either[Target, Target] ): Target = createEither(schema, value) - protected def createEither(schema: Schema.zio.prelude.Validation[_, _], value: zio.prelude.Validation[Target, Target]): Target + protected def createEither(schema: Schema.Either[_, _], value: Either[Target, Target]): Target override protected def startCreatingTuple(context: Unit, schema: Schema.Tuple2[_, _]): Unit = startCreatingTuple(schema) diff --git a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala index 38d3e6a7e..d68667556 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala @@ -56,10 +56,14 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { protected def processSet(context: Context, schema: Schema.Set[_], value: Set[Target]): Target /** Called before processing and either value */ - @nowarn protected def startProcessingEither(context: Context, schema: Schema.zio.prelude.Validation[_, _]): Unit = {} + @nowarn protected def startProcessingEither(context: Context, schema: Schema.Either[_, _]): Unit = {} /** Process an either value using its already processed left or right value */ - protected def processEither(context: Context, schema: Schema.zio.prelude.Validation[_, _], value: zio.prelude.Validation[Target, Target]): Target + protected def processEither( + context: Context, + schema: Schema.Either[_, _], + value: Either[Target, Target] + ): Target /** Called before processing an option value */ @nowarn protected def startProcessingOption(context: Context, schema: Schema.Optional[_]): Unit = {} @@ -93,7 +97,7 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { protected def contextForEnumConstructor(context: Context, index: Int, c: Schema.Case[_, _]): Context /** Gets the context for an either's left or right value within the parent context */ - protected def contextForEither(context: Context, e: zio.prelude.Validation[Unit, Unit]): Context + protected def contextForEither(context: Context, e: Either[Unit, Unit]): Context /** Gets the context for an option's inner value within the parent context */ protected def contextForOption(context: Context, o: Option[Unit]): Context @@ -814,9 +818,9 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { pushContext(contextForSet(currentContext, s, 0)) processNext(0) - case s: Schema.zio.prelude.Validation[l, r] => + case s: Schema.Either[l, r] => startProcessingEither(currentContext, s) - currentValue.asInstanceOf[zio.prelude.Validation[l, r]] match { + currentValue.asInstanceOf[Either[l, r]] match { case Left(value: l) => currentValue = value currentSchema = s.left @@ -825,13 +829,13 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { contextStack = contextStack.tail finishWith(processEither(currentContext, s, Left(dyn))) } - case zio.prelude.Validation.succeed(value: r) => + case Right(value: r) => currentValue = value currentSchema = s.right - pushContext(contextForEither(currentContext, zio.prelude.Validation.succeed(()))) + pushContext(contextForEither(currentContext, Right(()))) push { dyn => contextStack = contextStack.tail - finishWith(processEither(currentContext, s, zio.prelude.Validation.succeed(dyn))) + finishWith(processEither(currentContext, s, Right(dyn))) } } @@ -868,13 +872,13 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { } case Schema.Transform(schema, _, g, _, _) => - g.asInstanceOf[Any => zio.prelude.Validation[String, Any]](currentValue) match { - case Left(message) => - finishWith(fail(currentContext, message)) - case zio.prelude.Validation.succeed(a) => + g.asInstanceOf[Any => zio.prelude.Validation[String, Any]](currentValue) + .fold({ errors => + finishWith(fail(currentContext, errors.toString())) + }, { a => currentValue = a currentSchema = schema - } + }) case s @ Schema.CaseClass0(_, _, _) => fields(s, currentValue) @@ -1347,7 +1351,10 @@ trait SimpleMutableSchemaBasedValueProcessor[Target] extends MutableSchemaBasedV protected def processSet(schema: Schema.Set[_], value: Set[Target]): Target - protected def processEither(schema: Schema.zio.prelude.Validation[_, _], value: zio.prelude.Validation[Target, Target]): Target + protected def processEither( + schema: Schema.Either[_, _], + value: Either[Target, Target] + ): Target protected def processOption(schema: Schema.Optional[_], value: Option[Target]): Target @@ -1389,8 +1396,8 @@ trait SimpleMutableSchemaBasedValueProcessor[Target] extends MutableSchemaBasedV override protected def processEither( context: Unit, - schema: Schema.zio.prelude.Validation[_, _], - value: zio.prelude.Validation[Target, Target] + schema: Schema.Either[_, _], + value: Either[Target, Target] ): Target = processEither(schema, value) @@ -1414,7 +1421,7 @@ trait SimpleMutableSchemaBasedValueProcessor[Target] extends MutableSchemaBasedV override protected def contextForEnumConstructor(context: Unit, index: Int, c: Schema.Case[_, _]): Unit = () - override protected def contextForEither(context: Unit, e: zio.prelude.Validation[Unit, Unit]): Unit = + override protected def contextForEither(context: Unit, e: Either[Unit, Unit]): Unit = () override protected def contextForOption(context: Unit, o: Option[Unit]): Unit = diff --git a/zio-schema/shared/src/main/scala/zio/schema/Patch.scala b/zio-schema/shared/src/main/scala/zio/schema/Patch.scala index 8c34b78e7..fff3a243f 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Patch.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Patch.scala @@ -239,23 +239,24 @@ object Patch { override def invert: Patch[A] = Total(value) } - final case class EitherDiff[A, B](diff: zio.prelude.Validation[Patch[A], Patch[B]]) extends Patch[zio.prelude.Validation[A, B]] { + final case class EitherDiff[A, B](diff: Either[Patch[A], Patch[B]]) extends Patch[Either[A, B]] { override def isIdentical: Boolean = diff.fold(_.isIdentical, _.isIdentical) override def isComparable: Boolean = diff.fold(_.isComparable, _.isComparable) - override def patch(input: zio.prelude.Validation[A, B]): Validation[String, zio.prelude.Validation[A, B]] = (input, diff) match { - case (Left(_), zio.prelude.Validation.succeed(_)) => Validation.fail(s"Cannot apply a right diff to a left value") - case (zio.prelude.Validation.succeed(_), Left(_)) => Validation.fail(s"Cannot apply a left diff to a right value") - case (Left(in), Left(diff)) => - diff.patch(in).map(Left(_)) - case (zio.prelude.Validation.succeed(in), zio.prelude.Validation.succeed(diff)) => - diff.patch(in).map(zio.prelude.Validation.succeed(_)) - } + override def patch(input: Either[A, B]): Validation[String, Either[A, B]] = + (input, diff) match { + case (Left(_), Right(_)) => Validation.fail(s"Cannot apply a right diff to a left value") + case (Right(_), Left(_)) => Validation.fail(s"Cannot apply a left diff to a right value") + case (Left(in), Left(diff)) => + diff.patch(in).map(e => Left(e)) + case (Right(in), Right(diff)) => + diff.patch(in).map(e => Right(e)) + } - override def invert: Patch[zio.prelude.Validation[A, B]] = diff match { + override def invert: Patch[Either[A, B]] = diff match { case Left(value) => EitherDiff(Left(value.invert)) - case zio.prelude.Validation.succeed(value) => EitherDiff(zio.prelude.Validation.succeed(value.invert)) + case Right(value) => EitherDiff(Right(value.invert)) } } @@ -337,7 +338,7 @@ object Patch { } patchedDynamicValue.flatMap { newValues => - Validation.fromEither(schema.fromDynamic(DynamicValue.Record(newValues._1, newValues._2))) + schema.fromDynamic(DynamicValue.Record(newValues._1, newValues._2)) } } 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 422bea2d3..6e952e841 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Schema.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Schema.scala @@ -1,5 +1,7 @@ package zio.schema +import zio.prelude.Validation + import java.net.{ URI, URL } import java.time.temporal.ChronoUnit import scala.annotation.tailrec @@ -46,12 +48,12 @@ sealed trait Schema[A] { /** * A symbolic operator for [[orElseEither]]. */ - def <+>[B](that: Schema[B]): Schema[zio.prelude.Validation[A, B]] = self.orElseEither(that) + def <+>[B](that: Schema[B]): Schema[Either[A, B]] = self.orElseEither(that) /** * The default value for a `Schema` of type `A`. */ - def defaultValue: zio.prelude.Validation[String, A] + def defaultValue: Validation[String, A] /** * Chunk of annotations for this schema @@ -71,7 +73,7 @@ sealed trait Schema[A] { * This can be used to e.g convert between a case class and it's * "generic" representation as a ListMap[String,_] */ - def coerce[B](newSchema: Schema[B]): zio.prelude.Validation[String, Schema[B]] = + def coerce[B](newSchema: Schema[B]): Validation[String, Schema[B]] = for { f <- self.migrate(newSchema) g <- newSchema.migrate(self) @@ -87,9 +89,9 @@ sealed trait Schema[A] { /** * Patch value with a Patch. */ - def patch(oldValue: A, diff: Patch[A]): prelude.Validation[String, A] = diff.patch(oldValue) + def patch(oldValue: A, diff: Patch[A]): Validation[String, A] = diff.patch(oldValue) - def fromDynamic(value: DynamicValue): zio.prelude.Validation[String, A] = + def fromDynamic(value: DynamicValue): Validation[String, A] = value.toTypedValue(self) def makeAccessors(b: AccessorBuilder): Accessors[b.Lens, b.Prism, b.Traversal] @@ -97,7 +99,7 @@ sealed trait Schema[A] { /** * Generate a homomorphism from A to B iff A and B are homomorphic */ - def migrate[B](newSchema: Schema[B]): zio.prelude.Validation[String, A => zio.prelude.Validation[String, B]] = + def migrate[B](newSchema: Schema[B]): Validation[String, A => Validation[String, B]] = Migration.derive(MetaSchema.fromSchema(self), MetaSchema.fromSchema(newSchema)).map { transforms => (a: A) => self.toDynamic(a).transform(transforms).flatMap(newSchema.fromDynamic) } @@ -136,8 +138,8 @@ sealed trait Schema[A] { def transform[B](f: A => B, g: B => A)(implicit loc: SourceLocation): Schema[B] = Schema.Transform[A, B, SourceLocation]( self, - a => prelude.Validation.succeed(f(a)), - b => prelude.Validation.succeed(g(b)), + a => Validation.succeed(f(a)), + b => Validation.succeed(g(b)), annotations, loc ) @@ -146,12 +148,12 @@ sealed trait Schema[A] { * Transforms this `Schema[A]` into a `Schema[B]`, by supplying two functions that can transform * between `A` and `B` (possibly failing in some cases). */ - def transformOrFail[B](f: A => prelude.Validation[String, B], g: B => prelude.Validation[String, A])( + def transformOrFail[B](f: A => Validation[String, B], g: B => Validation[String, A])( implicit loc: SourceLocation ): Schema[B] = Schema.Transform[A, B, SourceLocation](self, f, g, annotations, loc) - def validate(value: A)(implicit schema: Schema[A]): Chunk[ValidationError] = Schema.validate[A](value) + def validate(value: A)(implicit schema: Schema[A]): Chunk[SchemaValidationError] = Schema.validate[A](value) /** * Returns a new schema that combines this schema and the specified schema together, modeling @@ -191,16 +193,17 @@ object Schema extends SchemaEquality { def singleton[A](instance: A): Schema[A] = Schema[Unit].transform(_ => instance, _ => ()) - def validate[A](value: A)(implicit schema: Schema[A]): Chunk[ValidationError] = { - def loop[A](value: A, schema: Schema[A]): Chunk[ValidationError] = + def validate[A](value: A)(implicit schema: Schema[A]): Chunk[SchemaValidationError] = { + def loop[A](value: A, schema: Schema[A]): Chunk[SchemaValidationError] = schema match { case Sequence(schema, _, toChunk, _, _) => toChunk(value).flatMap(value => loop(value, schema)) case Transform(schema, _, g, _, _) => - g(value) match { - case zio.prelude.Validation.succeed(value) => loop(value, schema) - case Left(error) => Chunk(ValidationError.Generic(error)) - } + g(value) + .mapError(SchemaValidationError.Generic) + .map(value => loop(value, schema)) + .fold(a => a.toChunk, a => a) + case Primitive(_, _) => Chunk.empty case optional @ Optional(schema, _) => value.asInstanceOf[Option[optional.OptionalType]] match { @@ -228,19 +231,19 @@ object Schema extends SchemaEquality { } record.fields .zip(fieldValues) - .foldLeft[Chunk[ValidationError]](Chunk.empty) { + .foldLeft[Chunk[SchemaValidationError]](Chunk.empty) { case (acc, (field, fieldValue)) => - val validation = field.validation.asInstanceOf[Validation[Any]] - validation.validate(fieldValue).swap.getOrElse(Chunk.empty) ++ acc ++ loop( + val validation = field.validation.asInstanceOf[SchemaValidation[Any]] + validation.validate(fieldValue).toEither.swap.map(_.toChunk).getOrElse(Chunk.empty) ++ acc ++ loop( fieldValue, field.schema.asInstanceOf[Schema[Any]] ) } .reverse case either @ Schema.Either(left, right, _) => - value.asInstanceOf[zio.prelude.Validation[either.LeftType, either.RightType]] match { - case Left(value) => loop(value, left) - case zio.prelude.Validation.succeed(value) => loop(value, right) + value.asInstanceOf[scala.Either[either.LeftType, either.RightType]] match { + case Left(value) => loop(value, left) + case Right(value) => loop(value, right) } case Dynamic(_) => Chunk.empty case Fail(_, _) => Chunk.empty @@ -267,7 +270,7 @@ object Schema extends SchemaEquality { case "NANOS" => zio.prelude.Validation.succeed(ChronoUnit.NANOS) case "WEEKS" => zio.prelude.Validation.succeed(ChronoUnit.WEEKS) case "YEARS" => zio.prelude.Validation.succeed(ChronoUnit.YEARS) - case _ => Left("Failed") + case _ => Validation.fail("Failed") }, { case ChronoUnit.SECONDS => zio.prelude.Validation.succeed("SECONDS") case ChronoUnit.CENTURIES => zio.prelude.Validation.succeed("CENTURIES") @@ -282,7 +285,7 @@ object Schema extends SchemaEquality { case ChronoUnit.NANOS => zio.prelude.Validation.succeed("NANOS") case ChronoUnit.WEEKS => zio.prelude.Validation.succeed("WEEKS") case ChronoUnit.YEARS => zio.prelude.Validation.succeed("YEARS") - case _ => Left("Failed") + case _ => Validation.fail("Failed") } ) @@ -322,7 +325,7 @@ object Schema extends SchemaEquality { string => try { zio.prelude.Validation.succeed(new URL(string)) - } catch { case _: Exception => Left(s"Invalid URL: $string") }, + } catch { case _: Exception => Validation.fail(s"Invalid URL: $string") }, url => zio.prelude.Validation.succeed(url.toString) ) @@ -336,20 +339,19 @@ object Schema extends SchemaEquality { string => try { zio.prelude.Validation.succeed(new URI(string)) - } catch { case _: Exception => Left(s"Invalid URI: $string") }, + } catch { case _: Exception => Validation.fail(s"Invalid URI: $string") }, uri => zio.prelude.Validation.succeed(uri.toString) ) implicit def standardSchema[A]: Schema[StandardType[A]] = Schema[String].transformOrFail[StandardType[A]]( string => - StandardType - .fromString(string) - .asInstanceOf[Option[StandardType[A]]] - .tozio - .prelude - .Validation - .succeed(s"Invalid StandardType tag ${string}"), - standardType => zio.prelude.Validation.succeed(standardType.tag) + Validation.fromEither( + StandardType + .fromString(string) + .asInstanceOf[Option[StandardType[A]]] + .toRight(s"Invalid StandardType tag ${string}") + ), + standardType => Validation.succeed(standardType.tag) ) sealed trait Enum[Z] extends Schema[Z] { @@ -372,7 +374,7 @@ object Schema extends SchemaEquality { def name: Field def schema: Schema[A] def annotations: Chunk[Any] - def validation: Validation[A] + def validation: SchemaValidation[A] def get: R => A def set: (R, A) => R @@ -389,23 +391,25 @@ object Schema extends SchemaEquality { name0: String, schema0: Schema[A], annotations0: Chunk[Any] = Chunk.empty, - validation0: Validation[A] = Validation.succeed[A], + validation0: SchemaValidation[A] = SchemaValidation.succeed[A], get0: R => A, set0: (R, A) => R ): Field[R, A] = new Field[R, A] { override type Field = name0.type - def name: Field = name0.asInstanceOf[Field] - def schema: Schema[A] = schema0 - def annotations: Chunk[Any] = annotations0 - def validation: Validation[A] = validation0 - def get: R => A = get0 - def set: (R, A) => R = set0 + def name: Field = name0.asInstanceOf[Field] + def schema: Schema[A] = schema0 + def annotations: Chunk[Any] = annotations0 + def validation: SchemaValidation[A] = validation0 + def get: R => A = get0 + def set: (R, A) => R = set0 } - def unapply[R, A](field: Field[R, A]): Some[(String, Schema[A], Chunk[Any], Validation[A], R => A, (R, A) => R)] = - Some[(String, Schema[A], Chunk[Any], Validation[A], R => A, (R, A) => R)]( + def unapply[R, A]( + field: Field[R, A] + ): Some[(String, Schema[A], Chunk[Any], SchemaValidation[A], R => A, (R, A) => R)] = + Some[(String, Schema[A], Chunk[Any], SchemaValidation[A], R => A, (R, A) => R)]( (field.name, field.schema, field.annotations, field.validation, field.get, field.set) ) } @@ -418,25 +422,19 @@ object Schema extends SchemaEquality { def fields: Chunk[Field[R, _]] - def construct(fieldValues: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, R] + def construct(fieldValues: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, R] def deconstruct(value: R)(implicit unsafe: Unsafe): Chunk[Any] def id: TypeId - def defaultValue: zio.prelude.Validation[String, R] = + def defaultValue: Validation[String, R] = Unsafe.unsafe { implicit unsafe => zio.prelude.Validation .validateAll( self.fields .map(_.schema.defaultValue) ) - .foldLeft[zio.prelude.Validation[String, Chunk[R]]](zio.prelude.Validation.succeed(Chunk.empty)) { - case (e @ Left(_), _) => e - case (_, Left(e)) => Left[String, Chunk[R]](e) - case (zio.prelude.Validation.succeed(values), zio.prelude.Validation.succeed(value)) => - Right[String, Chunk[R]](values :+ value.asInstanceOf[R]) - } .flatMap(self.construct) } } @@ -455,7 +453,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Sequence[Col, Elem, I] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Col] = + override def defaultValue: Validation[String, Col] = elementSchema.defaultValue.map(fromChunk.compose(Chunk(_))) override def makeAccessors(b: AccessorBuilder): b.Traversal[Col, Elem] = b.makeTraversal(self, elementSchema) @@ -466,14 +464,14 @@ object Schema extends SchemaEquality { final case class Transform[A, B, I]( schema: Schema[A], - f: A => prelude.Validation[String, B], - g: B => prelude.Validation[String, A], + f: A => Validation[String, B], + g: B => Validation[String, A], annotations: Chunk[Any], identity: I ) extends Schema[B] { override type Accessors[Lens[_, _, _], Prism[_, _, _], Traversal[_, _]] = schema.Accessors[Lens, Prism, Traversal] - def defaultValue: zio.prelude.Validation[String, B] = schema.defaultValue.flatMap(f) + def defaultValue: Validation[String, B] = schema.defaultValue.flatMap(f) override def makeAccessors(b: AccessorBuilder): schema.Accessors[b.Lens, b.Prism, b.Traversal] = schema.makeAccessors(b) @@ -499,7 +497,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Primitive[A] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, A] = standardType.defaultValue + override def defaultValue: Validation[String, A] = standardType.defaultValue override def makeAccessors(b: AccessorBuilder): Unit = () } @@ -540,7 +538,7 @@ object Schema extends SchemaEquality { Chunk.empty ) - def defaultValue: zio.prelude.Validation[String, Option[A]] = zio.prelude.Validation.succeed(None) + def defaultValue: Validation[String, Option[A]] = zio.prelude.Validation.succeed(None) override def makeAccessors( b: AccessorBuilder @@ -554,7 +552,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Fail[A] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, A] = Left(message) + override def defaultValue: Validation[String, A] = Validation.fail(message) override def makeAccessors(b: AccessorBuilder): Unit = () } @@ -578,7 +576,7 @@ object Schema extends SchemaEquality { annotations ) - override def defaultValue: zio.prelude.Validation[String, (A, B)] = + override def defaultValue: Validation[String, (A, B)] = left.defaultValue.flatMap(a => right.defaultValue.map(b => (a, b))) override def makeAccessors(b: AccessorBuilder): (b.Lens[first.type, (A, B), A], b.Lens[second.type, (A, B), B]) = @@ -628,15 +626,11 @@ object Schema extends SchemaEquality { Chunk.empty ) - override def defaultValue: scala.util.Either[String, scala.util.Either[A, B]] = - left.defaultValue match { - case Right(a) => Right(Left(a)) - case _ => - right.defaultValue match { - case Right(b) => Right(Right(b)) - case _ => Left("unable to extract default value for Either") - } - } + override def defaultValue: Validation[String, scala.util.Either[A, B]] = + left.defaultValue + .map(Left(_)) + .orElse(right.defaultValue.map(Right(_))) + .mapError(e => s"unable to extract default value for Either: ${e}") override def makeAccessors( b: AccessorBuilder @@ -655,7 +649,7 @@ object Schema extends SchemaEquality { lazy val schema: Schema[A] = schema0() - def defaultValue: zio.prelude.Validation[String, A] = schema.defaultValue + def defaultValue: Validation[String, A] = schema.defaultValue override def makeAccessors(b: AccessorBuilder): schema.Accessors[b.Lens, b.Prism, b.Traversal] = schema.makeAccessors(b) @@ -676,7 +670,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Map[K, V] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, scala.collection.immutable.Map[K, V]] = + override def defaultValue: Validation[String, scala.collection.immutable.Map[K, V]] = keySchema.defaultValue.flatMap( defaultKey => valueSchema.defaultValue.map(defaultValue => scala.collection.immutable.Map(defaultKey -> defaultValue)) @@ -697,7 +691,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Set[A] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, scala.collection.immutable.Set[A]] = + override def defaultValue: Validation[String, scala.collection.immutable.Set[A]] = elementSchema.defaultValue.map(scala.collection.immutable.Set(_)) override def makeAccessors(b: AccessorBuilder): b.Traversal[scala.collection.immutable.Set[A], A] = @@ -712,7 +706,7 @@ object Schema extends SchemaEquality { /** * The default value for a `Schema` of type `A`. */ - override def defaultValue: zio.prelude.Validation[String, DynamicValue] = + override def defaultValue: Validation[String, DynamicValue] = zio.prelude.Validation.succeed(DynamicValue.NoneValue) /** @@ -749,7 +743,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum1[A, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): b.Prism[case1.id.type, Z, A] = b.makePrism(self, case1) @@ -769,7 +763,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum2[A1, A2, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): (b.Prism[case1.id.type, Z, A1], b.Prism[case2.id.type, Z, A2]) = (b.makePrism(self, case1), b.makePrism(self, case2)) @@ -790,7 +784,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum3[A1, A2, A3, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors( b: AccessorBuilder @@ -819,7 +813,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum4[A1, A2, A3, A4, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -853,7 +847,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum5[A1, A2, A3, A4, A5, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors( b: AccessorBuilder @@ -899,7 +893,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum6[A1, A2, A3, A4, A5, A6, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors( b: AccessorBuilder @@ -949,7 +943,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum7[A1, A2, A3, A4, A5, A6, A7, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1001,7 +995,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum8[A1, A2, A3, A4, A5, A6, A7, A8, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1056,7 +1050,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum9[A1, A2, A3, A4, A5, A6, A7, A8, A9, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1115,7 +1109,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1191,7 +1185,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1273,7 +1267,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1372,7 +1366,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum13[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1477,7 +1471,7 @@ object Schema extends SchemaEquality { override def annotate(annotation: Any): Enum14[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1590,7 +1584,7 @@ object Schema extends SchemaEquality { ): Enum15[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1709,7 +1703,7 @@ object Schema extends SchemaEquality { ): Enum16[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1834,7 +1828,7 @@ object Schema extends SchemaEquality { ): Enum17[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -1965,7 +1959,7 @@ object Schema extends SchemaEquality { ): Enum18[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -2102,7 +2096,7 @@ object Schema extends SchemaEquality { ): Enum19[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -2245,7 +2239,7 @@ object Schema extends SchemaEquality { ): Enum20[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors(b: AccessorBuilder): ( b.Prism[case1.id.type, Z, A1], @@ -2394,7 +2388,7 @@ object Schema extends SchemaEquality { ): Enum21[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors( b: AccessorBuilder @@ -2551,7 +2545,7 @@ object Schema extends SchemaEquality { ): Enum22[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, Z] = copy(annotations = annotations :+ annotation) - override def defaultValue: zio.prelude.Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) + override def defaultValue: Validation[String, Z] = case1.schema.defaultValue.map(case1.construct) override def makeAccessors( b: AccessorBuilder @@ -2640,11 +2634,11 @@ object Schema extends SchemaEquality { override def cases: Chunk[Case[Z, _]] = Chunk(caseSet.toSeq: _*) - def defaultValue: zio.prelude.Validation[String, Z] = + def defaultValue: Validation[String, Z] = if (caseSet.toSeq.isEmpty) - Left("cannot access default value for enum with no members") + Validation.fail("cannot access default value for enum with no members") else - caseSet.toSeq.head.schema.defaultValue.asInstanceOf[zio.prelude.Validation[String, Z]] + caseSet.toSeq.head.schema.defaultValue.asInstanceOf[Validation[String, Z]] override def makeAccessors(b: AccessorBuilder): caseSet.Accessors[Z, b.Lens, b.Prism, b.Traversal] = caseSet.makeAccessors(self, b) @@ -3324,11 +3318,11 @@ object Schema extends SchemaEquality { override def construct( values: Chunk[Any] - )(implicit unsafe: Unsafe): zio.prelude.Validation[String, ListMap[String, _]] = + )(implicit unsafe: Unsafe): Validation[String, ListMap[String, _]] = if (values.size == fields.size) zio.prelude.Validation.succeed(ListMap(fields.map(_.name).zip(values): _*)) else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(values: ListMap[String, _])(implicit unsafe: Unsafe): Chunk[Any] = Chunk.fromIterable(fields.map(f => values(f.name))) @@ -3353,14 +3347,14 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk.empty - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.isEmpty) try { zio.prelude.Validation.succeed(defaultConstruct()) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk(value) @@ -3404,14 +3398,14 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 1) try { zio.prelude.Validation.succeed(defaultConstruct(values(0).asInstanceOf[A])) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk(field.get(value)) override def toString: String = s"CaseClass1(${fields.mkString(",")})" @@ -3471,14 +3465,14 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 2) try { zio.prelude.Validation.succeed(construct(values(0).asInstanceOf[A1], values(1).asInstanceOf[A2])) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk(field1.get(value), field2.get(value)) @@ -3551,15 +3545,15 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 3) try { zio.prelude.Validation .succeed(construct(values(0).asInstanceOf[A1], values(1).asInstanceOf[A2], values(2).asInstanceOf[A3])) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk(field1.get(value), field2.get(value), field3.get(value)) @@ -3647,7 +3641,7 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 4) try { zio.prelude.Validation.succeed( @@ -3659,9 +3653,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk(field1.get(value), field2.get(value), field3.get(value), field4.get(value)) @@ -3767,7 +3761,7 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4, field5) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 5) try { zio.prelude.Validation.succeed( @@ -3780,9 +3774,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -3920,7 +3914,7 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4, field5, field6) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 6) try { zio.prelude.Validation.succeed( @@ -3934,9 +3928,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -4093,7 +4087,7 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4, field5, field6, field7) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 7) try { zio.prelude.Validation.succeed( @@ -4108,9 +4102,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -4299,7 +4293,7 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4, field5, field6, field7, field8) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 8) try { zio.prelude.Validation.succeed( @@ -4315,9 +4309,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -4522,7 +4516,7 @@ object Schema extends SchemaEquality { override def fields: Chunk[Field[Z, _]] = Chunk(field1, field2, field3, field4, field5, field6, field7, field8, field9) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 9) try { zio.prelude.Validation.succeed( @@ -4539,9 +4533,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -4783,7 +4777,7 @@ object Schema extends SchemaEquality { field10 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 10) try { zio.prelude.Validation.succeed( @@ -4801,9 +4795,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -5066,7 +5060,7 @@ object Schema extends SchemaEquality { field11 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 11) try { zio.prelude.Validation.succeed( @@ -5085,9 +5079,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -5368,7 +5362,7 @@ object Schema extends SchemaEquality { field12 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 12) try { zio.prelude.Validation.succeed( @@ -5388,9 +5382,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -5689,7 +5683,7 @@ object Schema extends SchemaEquality { field13 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 13) try { zio.prelude.Validation.succeed( @@ -5710,9 +5704,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -6029,7 +6023,7 @@ object Schema extends SchemaEquality { field14 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 14) try { zio.prelude.Validation.succeed( @@ -6051,9 +6045,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -6389,7 +6383,7 @@ object Schema extends SchemaEquality { field15 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 15) try { zio.prelude.Validation.succeed( @@ -6412,9 +6406,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -6770,7 +6764,7 @@ object Schema extends SchemaEquality { field16 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 16) try { zio.prelude.Validation.succeed( @@ -6794,9 +6788,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -7170,7 +7164,7 @@ object Schema extends SchemaEquality { field17 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 17) try { zio.prelude.Validation.succeed( @@ -7195,9 +7189,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -7589,7 +7583,7 @@ object Schema extends SchemaEquality { field18 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 18) try { zio.prelude.Validation.succeed( @@ -7615,9 +7609,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -8029,7 +8023,7 @@ object Schema extends SchemaEquality { field19 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 19) try { zio.prelude.Validation.succeed( @@ -8056,9 +8050,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -8488,7 +8482,7 @@ object Schema extends SchemaEquality { field20 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 20) try { zio.prelude.Validation.succeed( @@ -8516,9 +8510,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -8987,7 +8981,7 @@ object Schema extends SchemaEquality { field21 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 21) try { zio.prelude.Validation.succeed( @@ -9016,9 +9010,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), @@ -9552,7 +9546,7 @@ object Schema extends SchemaEquality { field22 ) - override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): zio.prelude.Validation[String, Z] = + override def construct(values: Chunk[Any])(implicit unsafe: Unsafe): Validation[String, Z] = if (values.size == 22) try { zio.prelude.Validation.succeed( @@ -9582,9 +9576,9 @@ object Schema extends SchemaEquality { ) ) } catch { - case _: Throwable => Left("invalid type in values") + case e: Throwable => Validation.fail(s"invalid type in values: [$e]") } else - Left(s"wrong number of values for $fields") + Validation.fail(s"wrong number of values for $fields") override def deconstruct(value: Z)(implicit unsafe: Unsafe): Chunk[Any] = Chunk( field1.get(value), diff --git a/zio-schema/shared/src/main/scala/zio/schema/SchemaEquality.scala b/zio-schema/shared/src/main/scala/zio/schema/SchemaEquality.scala index 83b2d61a6..f30e43402 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/SchemaEquality.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/SchemaEquality.scala @@ -66,7 +66,7 @@ trait SchemaEquality { lTuple.annotations == rTuple.annotations && lTuple.left === rTuple.left && rTuple.right === rTuple.right - case (lEither: Schema.zio.prelude.Validation[_, _], rEither: Schema.zio.prelude.Validation[_, _]) => + case (lEither: Schema.Either[_, _], rEither: Schema.Either[_, _]) => lEither.annotations == rEither.annotations && lEither.left === rEither.left && lEither.right === rEither.right diff --git a/zio-schema/shared/src/main/scala/zio/schema/annotation/validate.scala b/zio-schema/shared/src/main/scala/zio/schema/annotation/validate.scala index cef26e27f..5e675753b 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/annotation/validate.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/annotation/validate.scala @@ -1,5 +1,5 @@ package zio.schema.annotation -import zio.schema.validation.Validation +import zio.schema.validation.SchemaValidation -final case class validate[A](validation: Validation[A]) extends scala.annotation.StaticAnnotation +final case class validate[A](validation: SchemaValidation[A]) extends scala.annotation.StaticAnnotation diff --git a/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala b/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala index 520c61f87..a75f88efd 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala @@ -4,7 +4,7 @@ import scala.collection.immutable.ListMap import scala.util.control.NoStackTrace import zio.schema.Schema.{ Field, Record } -import zio.schema.validation.Validation +import zio.schema.validation.SchemaValidation import zio.schema.{ DynamicValue, Schema } import zio.{ Cause, Chunk } @@ -34,7 +34,7 @@ object DecodeError { final case class ReadErrorWithPath(path: Chunk[String], cause: Cause[Any], message: String) extends DecodeError - final case class ValidationError(validation: Validation[_], field: Field[_, _], message: String) extends DecodeError + final case class ValidationError(validation: SchemaValidation[_], field: Field[_, _], message: String) extends DecodeError final case class ExtraFields(fieldName: String, message: String) extends DecodeError diff --git a/zio-schema/shared/src/main/scala/zio/schema/codec/Decoder.scala b/zio-schema/shared/src/main/scala/zio/schema/codec/Decoder.scala index 23edadf99..217be2a94 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/codec/Decoder.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/codec/Decoder.scala @@ -16,11 +16,12 @@ package zio.schema.codec +import zio.prelude.Validation import zio.stream.ZPipeline trait Decoder[Whole, Element, +A] { - def decode(whole: Whole): zio.prelude.Validation[DecodeError, A] + def decode(whole: Whole): Validation[DecodeError, A] def streamDecoder: ZPipeline[Any, DecodeError, Element, A] diff --git a/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala b/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala index f4841df26..30505c34e 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala @@ -388,17 +388,19 @@ object ExtensibleMetaSchema { private def tupled[BuiltIn <: TypeList]( value: Value[BuiltIn] - ): scala.zio.prelude.Validation[String, (String, Chunk[String], Boolean)] = - zio.prelude.Validation.succeed((value.valueType.tag, value.path, value.optional)) + ): Validation[String, (String, Chunk[String], Boolean)] = + Validation.succeed((value.valueType.tag, value.path, value.optional)) private def fromTuple[BuiltIn <: TypeList]( tuple: (String, Chunk[String], Boolean) - )(implicit builtInInstances: SchemaInstances[BuiltIn]): scala.zio.prelude.Validation[String, Value[BuiltIn]] = tuple match { + )(implicit builtInInstances: SchemaInstances[BuiltIn]): Validation[String, Value[BuiltIn]] = tuple match { case (s, path, optional) => - StandardType - .fromString(s) - .map(typ => Value(typ, NodePath(path), optional)) - .tozio.prelude.Validation.succeed(s"unkown standard type $s") + Validation.fromEither( + StandardType + .fromString(s) + .map(typ => Value(typ, NodePath(path), optional)) + .toRight(s"unkown standard type $s") + ) } } final case class Ref[BuiltIn <: TypeList]( @@ -687,12 +689,12 @@ object ExtensibleMetaSchema { caseOf[Sum[BuiltIn], ExtensibleMetaSchema[BuiltIn]]("Sum")(_.asInstanceOf[Sum[BuiltIn]])( _.asInstanceOf[ExtensibleMetaSchema[BuiltIn]] )(_.isInstanceOf[Sum[BuiltIn]]) ++ - caseOf[zio.prelude.Validation[BuiltIn], ExtensibleMetaSchema[BuiltIn]]("Either")( - _.asInstanceOf[zio.prelude.Validation[BuiltIn]] + caseOf[Either[BuiltIn], ExtensibleMetaSchema[BuiltIn]]("Either")( + _.asInstanceOf[Either[BuiltIn]] )( _.asInstanceOf[ExtensibleMetaSchema[BuiltIn]] )( - _.isInstanceOf[zio.prelude.Validation[BuiltIn]] + _.isInstanceOf[Either[BuiltIn]] ) ++ caseOf[Product[BuiltIn], ExtensibleMetaSchema[BuiltIn]]("Product")( _.asInstanceOf[Product[BuiltIn]] diff --git a/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala b/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala index 7f359dc51..61210eda2 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala @@ -1,7 +1,8 @@ package zio.schema.meta -import scala.collection.immutable.ListMap +import zio.prelude.{ Validation, ZValidation } +import scala.collection.immutable.ListMap import zio.schema.meta.ExtensibleMetaSchema.Labelled import zio.schema.{ DynamicValue, StandardType } import zio.{ Chunk, ChunkBuilder } @@ -10,18 +11,18 @@ sealed trait Migration { self => def path: NodePath - def migrate(value: DynamicValue): zio.prelude.Validation[String, DynamicValue] = + def migrate(value: DynamicValue): Validation[String, DynamicValue] = self match { case Migration.Require(path) => Migration.require(value, path.toList) case Migration.Optional(path) => Migration.makeOptional(value, path.toList) case Migration.ChangeType(path, _) => - Left( + Validation.fail( s"Cannot change type of node at path ${path.render}: No type conversion is available" ) case Migration.DeleteNode(path) => Migration.deleteNode(value, path.toList) - case Migration.AddCase(_, _) => zio.prelude.Validation.succeed(value) + case Migration.AddCase(_, _) => Validation.succeed(value) case Migration.AddNode(path, _) => - Left(s"Cannot add node at path ${path.render}: No default value is available") + Validation.fail(s"Cannot add node at path ${path.render}: No default value is available") case Migration.Relabel(path, transform) => Migration.relabel(value, path.toList, transform) case Migration.IncrementDimensions(path, n) => Migration.incrementDimension(value, path.toList, n) @@ -75,12 +76,8 @@ object Migration { ): zio.prelude.Validation[String, Chunk[Migration]] = matchedSubtrees(ffields, tfields).map { case (Labelled(nextPath, fs), Labelled(_, ts)) => go(acc, path / nextPath, fs, ts, ignoreRefs) - }.foldRight[zio.prelude.Validation[String, Chunk[Migration]]](zio.prelude.Validation.succeed(Chunk.empty)) { - case (err @ Left(_), zio.prelude.Validation.succeed(_)) => err - case (zio.prelude.Validation.succeed(_), err @ Left(_)) => err - case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (zio.prelude.Validation.succeed(t1), zio.prelude.Validation.succeed(t2)) => zio.prelude.Validation.succeed(t1 ++ t2) - } + }.validateAll() + .map(_.flatten) .map( _ ++ acc ++ transformShape(path, f, t) ++ insertions(path, ffields, tfields) ++ deletions( path, @@ -97,12 +94,8 @@ object Migration { ): zio.prelude.Validation[String, Chunk[Migration]] = matchedSubtrees(fcases, tcases).map { case (Labelled(nextPath, fs), Labelled(_, ts)) => go(acc, path / nextPath, fs, ts, ignoreRefs) - }.foldRight[zio.prelude.Validation[String, Chunk[Migration]]](zio.prelude.Validation.succeed(Chunk.empty)) { - case (err @ Left(_), zio.prelude.Validation.succeed(_)) => err - case (zio.prelude.Validation.succeed(_), err @ Left(_)) => err - case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (zio.prelude.Validation.succeed(t1), zio.prelude.Validation.succeed(t2)) => zio.prelude.Validation.succeed(t1 ++ t2) - } + }.validateAll() + .map(_.flatten) .map( _ ++ acc ++ transformShape(path, f, t) ++ caseInsertions(path, fcases, tcases) ++ deletions( path, @@ -113,7 +106,7 @@ object Migration { (fromSubtree, toSubtree) match { case (f @ ExtensibleMetaSchema.FailNode(_, _, _), t @ ExtensibleMetaSchema.FailNode(_, _, _)) => - zio.prelude.Validation.succeed( + Validation.succeed( if (f.message == t.message) Chunk.empty else @@ -172,19 +165,20 @@ object Migration { goSum(f, t, fcases, tcases) case (f @ ExtensibleMetaSchema.Value(ftype, _, _), t @ ExtensibleMetaSchema.Value(ttype, _, _)) if ttype != ftype => - zio.prelude.Validation.succeed(transformShape(path, f, t) :+ ChangeType(path, ttype)) + Validation.succeed(transformShape(path, f, t) :+ ChangeType(path, ttype)) case (f @ ExtensibleMetaSchema.Value(_, _, _), t @ ExtensibleMetaSchema.Value(_, _, _)) => - zio.prelude.Validation.succeed(transformShape(path, f, t)) + Validation.succeed(transformShape(path, f, t)) case (f @ ExtensibleMetaSchema.Ref(fromRef, nodePath, _), t @ ExtensibleMetaSchema.Ref(toRef, _, _)) if fromRef == toRef => - if (ignoreRefs) zio.prelude.Validation.succeed(Chunk.empty) + if (ignoreRefs) Validation.succeed(Chunk.empty) else { val recursiveMigrations = acc .filter(_.path.isSubpathOf(fromRef)) .map(relativize(fromRef, nodePath.relativeTo(fromRef))) - zio.prelude.Validation.succeed(recursiveMigrations ++ transformShape(path, f, t)) + Validation.succeed(recursiveMigrations ++ transformShape(path, f, t)) } - case (f, t) => Left(s"Subtrees at path ${renderPath(path)} are not homomorphic: $f cannot be mapped to $t") + case (f, t) => + Validation.fail(s"Subtrees at path ${renderPath(path)} are not homomorphic: $f cannot be mapped to $t") } } @@ -289,33 +283,29 @@ object Migration { value: DynamicValue, path: List[String], trace: Chunk[String] = Chunk.empty - )(op: (String, DynamicValue) => zio.prelude.Validation[String, Option[(String, DynamicValue)]]): zio.prelude.Validation[String, DynamicValue] = { + )( + op: (String, DynamicValue) => zio.prelude.Validation[String, Option[(String, DynamicValue)]] + ): zio.prelude.Validation[String, DynamicValue] = { (value, path) match { case (DynamicValue.SomeValue(value), _) => - updateLeaf(value, path, trace)(op).map(DynamicValue.SomeValue(_)) - case (DynamicValue.NoneValue, _) => zio.prelude.Validation.succeed(DynamicValue.NoneValue) + updateLeaf(value, path, trace)(op).map(DynamicValue.SomeValue) + case (DynamicValue.NoneValue, _) => Validation.succeed(DynamicValue.NoneValue) case (DynamicValue.Sequence(values), "item" :: remainder) => values.zipWithIndex.map { case (v, idx) => updateLeaf(v, remainder, trace :+ s"item[$idx]")(op) } - .foldRight[zio.prelude.Validation[String, DynamicValue.Sequence]](zio.prelude.Validation.succeed(DynamicValue.Sequence(Chunk.empty))) { - case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Left(e), zio.prelude.Validation.succeed(_)) => Left(e) - case (zio.prelude.Validation.succeed(_), Left(e)) => Left(e) - case (zio.prelude.Validation.succeed(DynamicValue.Sequence(v1s)), zio.prelude.Validation.succeed(DynamicValue.Sequence(v2s))) => - zio.prelude.Validation.succeed(DynamicValue.Sequence(v1s ++ v2s)) - case (zio.prelude.Validation.succeed(v1), zio.prelude.Validation.succeed(DynamicValue.Sequence(v2s))) => zio.prelude.Validation.succeed(DynamicValue.Sequence(v1 +: v2s)) - } + .validateAll() + .map(DynamicValue.Sequence) case (DynamicValue.Tuple(l, r), "left" :: remainder) => updateLeaf(l, remainder, trace :+ "left")(op).map(newLeft => DynamicValue.Tuple(newLeft, r)) case (DynamicValue.Tuple(l, r), "right" :: remainder) => updateLeaf(r, remainder, trace :+ "right")(op).map(newRight => DynamicValue.Tuple(l, newRight)) case (DynamicValue.LeftValue(l), "left" :: remainder) => - updateLeaf(l, remainder, trace :+ "left")(op).map(DynamicValue.LeftValue(_)) + updateLeaf(l, remainder, trace :+ "left")(op).map(DynamicValue.LeftValue) case (value @ DynamicValue.LeftValue(_), "right" :: _) => - zio.prelude.Validation.succeed(value) + Validation.succeed(value) case (DynamicValue.RightValue(r), "right" :: remainder) => - updateLeaf(r, remainder, trace :+ "right")(op).map(DynamicValue.RightValue(_)) + updateLeaf(r, remainder, trace :+ "right")(op).map(DynamicValue.RightValue) case (value @ DynamicValue.RightValue(_), "left" :: _) => - zio.prelude.Validation.succeed(value) + Validation.succeed(value) case (DynamicValue.Record(name, values), leafLabel :: Nil) if values.keySet.contains(leafLabel) => op(leafLabel, values(leafLabel)).map { case Some((newLeafLabel, newLeafValue)) => @@ -327,14 +317,14 @@ object Migration { DynamicValue.Record(name, spliceRecord(values, nextLabel, nextLabel -> updatedValue)) } case (DynamicValue.Record(_, _), nextLabel :: _) => - Left(s"Expected label $nextLabel not found at path ${renderPath(trace)}") + Validation.fail(s"Expected label $nextLabel not found at path ${renderPath(trace)}") case (v @ DynamicValue.Enumeration(_, (caseLabel, _)), nextLabel :: _) if caseLabel != nextLabel => - zio.prelude.Validation.succeed(v) + Validation.succeed(v) case (DynamicValue.Enumeration(id, (caseLabel, caseValue)), nextLabel :: Nil) if caseLabel == nextLabel => op(caseLabel, caseValue).flatMap { - case Some(newCase) => zio.prelude.Validation.succeed(DynamicValue.Enumeration(id, newCase)) + case Some(newCase) => Validation.succeed(DynamicValue.Enumeration(id, newCase)) case None => - Left( + Validation.fail( s"Failed to update leaf node at path ${renderPath(trace :+ nextLabel)}: Cannot remove instantiated case" ) } @@ -349,17 +339,11 @@ object Migration { .map { case (k, idx) => op(s"key[$idx]", k).flatMap { - case Some((_, migrated)) => zio.prelude.Validation.succeed(migrated) - case None => Left(s"invalid update at $path, cannot remove map key") + case Some((_, migrated)) => Validation.succeed(migrated) + case None => Validation.fail(s"invalid update at $path, cannot remove map key") } } - .foldRight[zio.prelude.Validation[String, Chunk[DynamicValue]]](zio.prelude.Validation.succeed(Chunk.empty)) { - case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Left(e), zio.prelude.Validation.succeed(_)) => Left(e) - case (zio.prelude.Validation.succeed(_), Left(e)) => Left(e) - case (zio.prelude.Validation.succeed(value), zio.prelude.Validation.succeed(chunk)) => - zio.prelude.Validation.succeed(value +: chunk) - } + .validateAll() .map { keys => DynamicValue.Dictionary(keys.zip(entries.map(_._2))) } @@ -371,13 +355,7 @@ object Migration { case (k, idx) => updateLeaf(k, remainder, trace :+ s"key[$idx]")(op) } - .foldRight[zio.prelude.Validation[String, Chunk[DynamicValue]]](zio.prelude.Validation.succeed(Chunk.empty)) { - case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Left(e), zio.prelude.Validation.succeed(_)) => Left(e) - case (zio.prelude.Validation.succeed(_), Left(e)) => Left(e) - case (zio.prelude.Validation.succeed(value), zio.prelude.Validation.succeed(chunk)) => - zio.prelude.Validation.succeed(value +: chunk) - } + .validateAll() .map { keys => DynamicValue.Dictionary(keys.zip(entries.map(_._2))) } @@ -388,17 +366,11 @@ object Migration { .map { case (k, idx) => op(s"key[$idx]", k).flatMap { - case Some((_, migrated)) => zio.prelude.Validation.succeed(migrated) - case None => Left(s"invalid update at $path, cannot remove map value") + case Some((_, migrated)) => Validation.succeed(migrated) + case None => Validation.fail(s"invalid update at $path, cannot remove map value") } } - .foldRight[zio.prelude.Validation[String, Chunk[DynamicValue]]](zio.prelude.Validation.succeed(Chunk.empty)) { - case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Left(e), zio.prelude.Validation.succeed(_)) => Left(e) - case (zio.prelude.Validation.succeed(_), Left(e)) => Left(e) - case (zio.prelude.Validation.succeed(value), zio.prelude.Validation.succeed(chunk)) => - zio.prelude.Validation.succeed(value +: chunk) - } + .validateAll() .map { values => DynamicValue.Dictionary(entries.map(_._1).zip(values)) } @@ -410,18 +382,14 @@ object Migration { case (k, idx) => updateLeaf(k, remainder, trace :+ s"value[$idx]")(op) } - .foldRight[zio.prelude.Validation[String, Chunk[DynamicValue]]](zio.prelude.Validation.succeed(Chunk.empty)) { - case (Left(e1), Left(e2)) => Left(s"$e1;\n$e2") - case (Left(e), zio.prelude.Validation.succeed(_)) => Left(e) - case (zio.prelude.Validation.succeed(_), Left(e)) => Left(e) - case (zio.prelude.Validation.succeed(value), zio.prelude.Validation.succeed(chunk)) => - zio.prelude.Validation.succeed(value +: chunk) - } + .validateAll() .map { values => DynamicValue.Dictionary(entries.map(_._1).zip(values)) } case _ => - Left(s"Failed to update leaf at path ${renderPath(trace ++ path)}: Unexpected node at ${renderPath(trace)}") + Validation.fail( + s"Failed to update leaf at path ${renderPath(trace ++ path)}: Unexpected node at ${renderPath(trace)}" + ) } } @@ -437,7 +405,7 @@ object Migration { private def materializeRecursive(depth: Int)(migration: Recursive): Migration = { def appendRecursiveN(n: Int)(relativePath: NodePath): NodePath = - (0 until n).foldzio.prelude.Validation.succeed(NodePath.root)((_, path) => path / relativePath) + (0 until n).foldRight(NodePath.root)((_, path) => path / relativePath) migration match { case Recursive(refPath, relativeNodePath, m: UpdateFail) => @@ -465,11 +433,14 @@ object Migration { } } - protected[schema] def migrateRecursive(value: DynamicValue, migration: Recursive): zio.prelude.Validation[String, DynamicValue] = { + protected[schema] def migrateRecursive( + value: DynamicValue, + migration: Recursive + ): zio.prelude.Validation[String, DynamicValue] = { def go(lastValue: DynamicValue, depth: Int): zio.prelude.Validation[String, DynamicValue] = materializeRecursive(depth)(migration).migrate(lastValue).flatMap { thisValue => if (thisValue == lastValue) - zio.prelude.Validation.succeed(thisValue) + Validation.succeed(thisValue) else go(thisValue, depth + 1) } @@ -482,13 +453,13 @@ object Migration { newMessage: String ): zio.prelude.Validation[String, DynamicValue] = (path, value) match { - case (Nil, DynamicValue.Error(_)) => zio.prelude.Validation.succeed(DynamicValue.Error(newMessage)) - case (Nil, _) => Left(s"Failed to update fail message at root. Unexpected type") + case (Nil, DynamicValue.Error(_)) => Validation.succeed(DynamicValue.Error(newMessage)) + case (Nil, _) => Validation.fail(s"Failed to update fail message at root. Unexpected type") case _ => updateLeaf(value, path) { (label, value) => value match { - case DynamicValue.Error(_) => zio.prelude.Validation.succeed(Some(label -> DynamicValue.Error(newMessage))) - case _ => Left(s"Failed to update fail message at ${renderPath(path)}. Unexpected type") + case DynamicValue.Error(_) => Validation.succeed(Some(label -> DynamicValue.Error(newMessage))) + case _ => Validation.fail(s"Failed to update fail message at ${renderPath(path)}. Unexpected type") } } } @@ -500,17 +471,17 @@ object Migration { ): zio.prelude.Validation[String, DynamicValue] = path match { case Nil => - zio.prelude.Validation.succeed( - (0 until n).foldzio.prelude.Validation.succeed(value) { + Validation.succeed( + (0 until n).foldRight(value) { case (_, acc) => DynamicValue.Sequence(Chunk(acc)) } ) case _ => updateLeaf(value, path) { (label, v) => - zio.prelude.Validation.succeed( + Validation.succeed( Some( - (0 until n).foldzio.prelude.Validation.succeed(label -> v) { + (0 until n).foldRight(label -> v) { case (_, (_, acc)) => label -> DynamicValue.Sequence(Chunk(acc)) } @@ -524,50 +495,52 @@ object Migration { value: DynamicValue, path: List[String], n: Int - ): zio.prelude.Validation[String, DynamicValue] = + ): Validation[String, DynamicValue] = path match { case Nil => - (0 until n).foldRight[zio.prelude.Validation[String, DynamicValue]](zio.prelude.Validation.succeed(value)) { + Validation.fromEither((0 until n).foldRight[Either[String, DynamicValue]](Right(value)) { case (_, error @ Left(_)) => error - case (_, zio.prelude.Validation.succeed(DynamicValue.Sequence(values))) if values.size == 1 => zio.prelude.Validation.succeed(values(0)) + case (_, Right(DynamicValue.Sequence(values))) if values.size == 1 => Right(values(0)) case _ => Left( s"Failed to decrement dimensions for node at path ${renderPath(path)}: Can only decrement dimensions on a sequence with one element" ) - } + }) case _ => updateLeaf(value, path) { (label, value) => - (0 until n) - .foldRight[zio.prelude.Validation[String, DynamicValue]](zio.prelude.Validation.succeed(value)) { - case (_, error @ Left(_)) => error - case (_, zio.prelude.Validation.succeed(DynamicValue.Sequence(values))) if values.size == 1 => zio.prelude.Validation.succeed(values(0)) - case _ => - Left( - s"Failed to decrement dimensions for node at path ${renderPath(path)}: Can only decrement dimensions on a sequence with one element" - ) - } - .map(updatedValue => Some(label -> updatedValue)) + Validation.fromEither( + (0 until n) + .foldRight[Either[String, DynamicValue]](Right(value)) { + case (_, error @ Left(_)) => error + case (_, Right(DynamicValue.Sequence(values))) if values.size == 1 => Right(values(0)) + case _ => + Left( + s"Failed to decrement dimensions for node at path ${renderPath(path)}: Can only decrement dimensions on a sequence with one element" + ) + } + .map(updatedValue => Some(label -> updatedValue)) + ) } } protected[schema] def require( value: DynamicValue, path: List[String] - ): zio.prelude.Validation[String, DynamicValue] = + ): Validation[String, DynamicValue] = (value, path) match { - case (DynamicValue.SomeValue(v), Nil) => zio.prelude.Validation.succeed(v) + case (DynamicValue.SomeValue(v), Nil) => Validation.succeed(v) case (DynamicValue.NoneValue, Nil) => - Left( + Validation.fail( s"Failed to require node: Optional value was None" ) case _ => updateLeaf(value, path) { case (label, DynamicValue.SomeValue(v)) => - zio.prelude.Validation.succeed(Some(label -> v)) + Validation.succeed(Some(label -> v)) case (_, DynamicValue.NoneValue) => - Left(s"Failed to require leaf at path ${renderPath(path)}: Optional value was not available") + Validation.fail(s"Failed to require leaf at path ${renderPath(path)}: Optional value was not available") case _ => - Left(s"Failed to require leaf at path ${renderPath(path)}: Expected optional value at lead") + Validation.fail(s"Failed to require leaf at path ${renderPath(path)}: Expected optional value at lead") } } @@ -577,13 +550,15 @@ object Migration { transformation: LabelTransformation ): zio.prelude.Validation[String, DynamicValue] = path match { - case Nil => Left(s"Cannot relabel node: Path was empty") + case Nil => Validation.fail(s"Cannot relabel node: Path was empty") case _ => updateLeaf(value, path) { (label, value) => transformation(label).fold( error => - Left(s"Failed to relabel node at path ${renderPath(path)}: Relabel transform failed with error $error"), - newLabel => zio.prelude.Validation.succeed(Some(newLabel -> value)) + Validation.fail( + s"Failed to relabel node at path ${renderPath(path)}: Relabel transform failed with error $error" + ), + newLabel => Validation.succeed(Some(newLabel -> value)) ) } } @@ -593,11 +568,11 @@ object Migration { path: List[String] ): zio.prelude.Validation[String, DynamicValue] = (value, path) match { - case (value, Nil) => zio.prelude.Validation.succeed(DynamicValue.SomeValue(value)) + case (value, Nil) => Validation.succeed(DynamicValue.SomeValue(value)) case _ => updateLeaf(value, path) { case (label, value) => - zio.prelude.Validation.succeed(Some(label -> DynamicValue.SomeValue(value))) + Validation.succeed(Some(label -> DynamicValue.SomeValue(value))) } } @@ -606,11 +581,15 @@ object Migration { path: List[String] ): zio.prelude.Validation[String, DynamicValue] = path match { - case Nil => Left(s"Cannot delete node: Path was empty") + case Nil => Validation.fail(s"Cannot delete node: Path was empty") case _ => - updateLeaf(value, path)((_, _) => zio.prelude.Validation.succeed(None)) + updateLeaf(value, path)((_, _) => Validation.succeed(None)) } private def renderPath(path: Iterable[String]): String = path.mkString("/") + implicit private class ChunkExt[+W, +E, +A](c: Chunk[ZValidation[W, E, A]]) { + def validateAll(): ZValidation[W, E, Chunk[A]] = Validation.validateAll(c) + } + } diff --git a/zio-schema/shared/src/main/scala/zio/schema/meta/NodePath.scala b/zio-schema/shared/src/main/scala/zio/schema/meta/NodePath.scala index d657a2368..388056edc 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/meta/NodePath.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/meta/NodePath.scala @@ -28,7 +28,7 @@ object NodePath extends Subtype[Chunk[String]] { def partitionLeaf: (NodePath, Option[String]) = if (self.isEmpty) (self, None) - else (NodePath(self.dropzio.prelude.Validation.succeed(1)), Some(self.last)) + else (NodePath(self.dropRight(1)), Some(self.last)) def render: String = if (self.isEmpty) diff --git a/zio-schema/shared/src/main/scala/zio/schema/validation/PhoneNumberValidation.scala b/zio-schema/shared/src/main/scala/zio/schema/validation/PhoneNumberValidation.scala index 92da0dd73..a0c6f6d25 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/validation/PhoneNumberValidation.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/validation/PhoneNumberValidation.scala @@ -17,2367 +17,2367 @@ trait PhoneNumberValidation { val digitsWithSeparator: Regex = Regex.digit.exactly(1) ~ optionalSeparator /** Phone number validation for Ascension Island */ - lazy val phoneNumberAC: Validation[String] = { + lazy val phoneNumberAC: SchemaValidation[String] = { val countryCode = Regex.literal("247") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Andorra */ - lazy val phoneNumberAD: Validation[String] = { + lazy val phoneNumberAD: SchemaValidation[String] = { val countryCode = Regex.literal("376") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for United Arab Emirates */ - lazy val phoneNumberAE: Validation[String] = { + lazy val phoneNumberAE: SchemaValidation[String] = { val countryCode = Regex.literal("971") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Afghanistan */ - lazy val phoneNumberAF: Validation[String] = { + lazy val phoneNumberAF: SchemaValidation[String] = { val countryCode = Regex.literal("93") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Antigua and Barbuda */ - lazy val phoneNumberAG: Validation[String] = { + lazy val phoneNumberAG: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("268") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Anguilla */ - lazy val phoneNumberAI: Validation[String] = { + lazy val phoneNumberAI: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("264") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Albania */ - lazy val phoneNumberAL: Validation[String] = { + lazy val phoneNumberAL: SchemaValidation[String] = { val countryCode = Regex.literal("355") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Armenia */ - lazy val phoneNumberAM: Validation[String] = { + lazy val phoneNumberAM: SchemaValidation[String] = { val countryCode = Regex.literal("374") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Netherlands Antilles */ - lazy val phoneNumberAN: Validation[String] = { + lazy val phoneNumberAN: SchemaValidation[String] = { val countryCode = Regex.literal("599") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Angola */ - lazy val phoneNumberAO: Validation[String] = { + lazy val phoneNumberAO: SchemaValidation[String] = { val countryCode = Regex.literal("244") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Antarctica */ - lazy val phoneNumberAQ: Validation[String] = { + lazy val phoneNumberAQ: SchemaValidation[String] = { val countryCode = Regex.literal("672") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Argentina */ - lazy val phoneNumberAR: Validation[String] = { + lazy val phoneNumberAR: SchemaValidation[String] = { val countryCode = Regex.literal("54") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for American Samoa */ - lazy val phoneNumberAS: Validation[String] = { + lazy val phoneNumberAS: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("684") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Austria */ - lazy val phoneNumberAT: Validation[String] = { + lazy val phoneNumberAT: SchemaValidation[String] = { val countryCode = Regex.literal("43") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Australia */ - lazy val phoneNumberAU: Validation[String] = { + lazy val phoneNumberAU: SchemaValidation[String] = { val countryCode = Regex.literal("61") val internationalPrefix = plus | Regex.literal("0011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Aruba */ - lazy val phoneNumberAW: Validation[String] = { + lazy val phoneNumberAW: SchemaValidation[String] = { val countryCode = Regex.literal("297") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Aland Islands */ - lazy val phoneNumberAX: Validation[String] = { + lazy val phoneNumberAX: SchemaValidation[String] = { val countryCode = Regex.literal("358") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val leadingDigits = Regex.literal("18") val phoneNumber = digitsWithSeparator.between(6, 8) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Azerbaijan */ - lazy val phoneNumberAZ: Validation[String] = { + lazy val phoneNumberAZ: SchemaValidation[String] = { val countryCode = Regex.literal("994") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Bosnia and Herzegovina */ - lazy val phoneNumberBA: Validation[String] = { + lazy val phoneNumberBA: SchemaValidation[String] = { val countryCode = Regex.literal("387") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Barbados */ - lazy val phoneNumberBB: Validation[String] = { + lazy val phoneNumberBB: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("246") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Bangladesh */ - lazy val phoneNumberBD: Validation[String] = { + lazy val phoneNumberBD: SchemaValidation[String] = { val countryCode = Regex.literal("880") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Belgium */ - lazy val phoneNumberBE: Validation[String] = { + lazy val phoneNumberBE: SchemaValidation[String] = { val countryCode = Regex.literal("32") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Burkina Faso */ - lazy val phoneNumberBF: Validation[String] = { + lazy val phoneNumberBF: SchemaValidation[String] = { val countryCode = Regex.literal("226") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Bulgaria */ - lazy val phoneNumberBG: Validation[String] = { + lazy val phoneNumberBG: SchemaValidation[String] = { val countryCode = Regex.literal("359") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Bahrain */ - lazy val phoneNumberBH: Validation[String] = { + lazy val phoneNumberBH: SchemaValidation[String] = { val countryCode = Regex.literal("973") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Burundi */ - lazy val phoneNumberBI: Validation[String] = { + lazy val phoneNumberBI: SchemaValidation[String] = { val countryCode = Regex.literal("257") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Benin */ - lazy val phoneNumberBJ: Validation[String] = { + lazy val phoneNumberBJ: SchemaValidation[String] = { val countryCode = Regex.literal("229") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Saint-Barthelemy */ - lazy val phoneNumberBL: Validation[String] = { + lazy val phoneNumberBL: SchemaValidation[String] = { val countryCode = Regex.literal("590") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Bermuda */ - lazy val phoneNumberBM: Validation[String] = { + lazy val phoneNumberBM: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("441") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Brunei Darussalam */ - lazy val phoneNumberBN: Validation[String] = { + lazy val phoneNumberBN: SchemaValidation[String] = { val countryCode = Regex.literal("673") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Bolivia */ - lazy val phoneNumberBO: Validation[String] = { + lazy val phoneNumberBO: SchemaValidation[String] = { val countryCode = Regex.literal("591") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Caribbean Netherlands */ - lazy val phoneNumberBQ: Validation[String] = { + lazy val phoneNumberBQ: SchemaValidation[String] = { val countryCode = Regex.literal("599") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val leadingDigits = Regex.literal("347") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Brazil */ - lazy val phoneNumberBR: Validation[String] = { + lazy val phoneNumberBR: SchemaValidation[String] = { val countryCode = Regex.literal("55") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Bahamas */ - lazy val phoneNumberBS: Validation[String] = { + lazy val phoneNumberBS: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("242") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Bhutan */ - lazy val phoneNumberBT: Validation[String] = { + lazy val phoneNumberBT: SchemaValidation[String] = { val countryCode = Regex.literal("975") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Bouvet Island */ - lazy val phoneNumberBV: Validation[String] = { + lazy val phoneNumberBV: SchemaValidation[String] = { val countryCode = Regex.literal("47") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Botswana */ - lazy val phoneNumberBW: Validation[String] = { + lazy val phoneNumberBW: SchemaValidation[String] = { val countryCode = Regex.literal("267") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Belarus */ - lazy val phoneNumberBY: Validation[String] = { + lazy val phoneNumberBY: SchemaValidation[String] = { val countryCode = Regex.literal("375") val internationalPrefix = plus | Regex.literal("00810") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixEight val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Belize */ - lazy val phoneNumberBZ: Validation[String] = { + lazy val phoneNumberBZ: SchemaValidation[String] = { val countryCode = Regex.literal("501") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Canada */ - lazy val phoneNumberCA: Validation[String] = { + lazy val phoneNumberCA: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Cocos (Keeling) Islands */ - lazy val phoneNumberCC: Validation[String] = { + lazy val phoneNumberCC: SchemaValidation[String] = { val countryCode = Regex.literal("61") val internationalPrefix = plus | Regex.literal("0011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Central African Republic */ - lazy val phoneNumberCF: Validation[String] = { + lazy val phoneNumberCF: SchemaValidation[String] = { val countryCode = Regex.literal("236") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Congo (Brazzaville) */ - lazy val phoneNumberCG: Validation[String] = { + lazy val phoneNumberCG: SchemaValidation[String] = { val countryCode = Regex.literal("242") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Congo, (Kinshasa) */ - lazy val phoneNumberCD: Validation[String] = { + lazy val phoneNumberCD: SchemaValidation[String] = { val countryCode = Regex.literal("243") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Switzerland */ - lazy val phoneNumberCH: Validation[String] = { + lazy val phoneNumberCH: SchemaValidation[String] = { val countryCode = Regex.literal("41") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(8, 9) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Cote d'Ivoire */ - lazy val phoneNumberCI: Validation[String] = { + lazy val phoneNumberCI: SchemaValidation[String] = { val countryCode = Regex.literal("225") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Cook Islands */ - lazy val phoneNumberCK: Validation[String] = { + lazy val phoneNumberCK: SchemaValidation[String] = { val countryCode = Regex.literal("682") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Chile */ - lazy val phoneNumberCL: Validation[String] = { + lazy val phoneNumberCL: SchemaValidation[String] = { val countryCode = Regex.literal("56") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Cameroon */ - lazy val phoneNumberCM: Validation[String] = { + lazy val phoneNumberCM: SchemaValidation[String] = { val countryCode = Regex.literal("237") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for China */ - lazy val phoneNumberCN: Validation[String] = { + lazy val phoneNumberCN: SchemaValidation[String] = { val countryCode = Regex.literal("86") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Colombia */ - lazy val phoneNumberCO: Validation[String] = { + lazy val phoneNumberCO: SchemaValidation[String] = { val countryCode = Regex.literal("57") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Costa Rica */ - lazy val phoneNumberCR: Validation[String] = { + lazy val phoneNumberCR: SchemaValidation[String] = { val countryCode = Regex.literal("506") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Cuba */ - lazy val phoneNumberCU: Validation[String] = { + lazy val phoneNumberCU: SchemaValidation[String] = { val countryCode = Regex.literal("53") val internationalPrefix = plus | Regex.literal("119") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Cape Verde */ - lazy val phoneNumberCV: Validation[String] = { + lazy val phoneNumberCV: SchemaValidation[String] = { val countryCode = Regex.literal("238") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Curacao */ - lazy val phoneNumberCW: Validation[String] = { + lazy val phoneNumberCW: SchemaValidation[String] = { val countryCode = Regex.literal("599") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val leadingDigits = Regex.literal("69") val phoneNumber = digitsWithSeparator.between(6, 8) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Christmas Island */ - lazy val phoneNumberCX: Validation[String] = { + lazy val phoneNumberCX: SchemaValidation[String] = { val countryCode = Regex.literal("61") val internationalPrefix = plus | Regex.literal("0011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Cyprus */ - lazy val phoneNumberCY: Validation[String] = { + lazy val phoneNumberCY: SchemaValidation[String] = { val countryCode = Regex.literal("357") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Czech Republic */ - lazy val phoneNumberCZ: Validation[String] = { + lazy val phoneNumberCZ: SchemaValidation[String] = { val countryCode = Regex.literal("420") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Germany */ - lazy val phoneNumberDE: Validation[String] = { + lazy val phoneNumberDE: SchemaValidation[String] = { val countryCode = Regex.literal("49") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(8, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Djibouti */ - lazy val phoneNumberDJ: Validation[String] = { + lazy val phoneNumberDJ: SchemaValidation[String] = { val countryCode = Regex.literal("253") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Denmark */ - lazy val phoneNumberDK: Validation[String] = { + lazy val phoneNumberDK: SchemaValidation[String] = { val countryCode = Regex.literal("45") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Dominica */ - lazy val phoneNumberDM: Validation[String] = { + lazy val phoneNumberDM: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("767") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Dominican Republic */ - lazy val phoneNumberDO: Validation[String] = { + lazy val phoneNumberDO: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("8001") val phoneNumber = digitsWithSeparator.exactly(6) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Algeria */ - lazy val phoneNumberDZ: Validation[String] = { + lazy val phoneNumberDZ: SchemaValidation[String] = { val countryCode = Regex.literal("213") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Ecuador */ - lazy val phoneNumberEC: Validation[String] = { + lazy val phoneNumberEC: SchemaValidation[String] = { val countryCode = Regex.literal("593") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Estonia */ - lazy val phoneNumberEE: Validation[String] = { + lazy val phoneNumberEE: SchemaValidation[String] = { val countryCode = Regex.literal("372") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Egypt */ - lazy val phoneNumberEG: Validation[String] = { + lazy val phoneNumberEG: SchemaValidation[String] = { val countryCode = Regex.literal("20") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Western Sahara */ - lazy val phoneNumberEH: Validation[String] = { + lazy val phoneNumberEH: SchemaValidation[String] = { val countryCode = Regex.literal("212") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val leadingDigits = Regex.literal("528") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Eritrea */ - lazy val phoneNumberER: Validation[String] = { + lazy val phoneNumberER: SchemaValidation[String] = { val countryCode = Regex.literal("291") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Spain */ - lazy val phoneNumberES: Validation[String] = { + lazy val phoneNumberES: SchemaValidation[String] = { val countryCode = Regex.literal("34") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Ethiopia */ - lazy val phoneNumberET: Validation[String] = { + lazy val phoneNumberET: SchemaValidation[String] = { val countryCode = Regex.literal("251") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Finland */ - lazy val phoneNumberFI: Validation[String] = { + lazy val phoneNumberFI: SchemaValidation[String] = { val countryCode = Regex.literal("358") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val leadingDigits = Regex.literal("1") val phoneNumber = digitsWithSeparator.between(6, 9) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Fiji */ - lazy val phoneNumberFJ: Validation[String] = { + lazy val phoneNumberFJ: SchemaValidation[String] = { val countryCode = Regex.literal("679") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Falkland Islands (Malvinas) */ - lazy val phoneNumberFK: Validation[String] = { + lazy val phoneNumberFK: SchemaValidation[String] = { val countryCode = Regex.literal("500") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Micronesia */ - lazy val phoneNumberFM: Validation[String] = { + lazy val phoneNumberFM: SchemaValidation[String] = { val countryCode = Regex.literal("691") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Faroe Islands */ - lazy val phoneNumberFO: Validation[String] = { + lazy val phoneNumberFO: SchemaValidation[String] = { val countryCode = Regex.literal("298") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for France */ - lazy val phoneNumberFR: Validation[String] = { + lazy val phoneNumberFR: SchemaValidation[String] = { val countryCode = Regex.literal("33") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Gabon */ - lazy val phoneNumberGA: Validation[String] = { + lazy val phoneNumberGA: SchemaValidation[String] = { val countryCode = Regex.literal("241") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for United Kingdom */ - lazy val phoneNumberGB: Validation[String] = { + lazy val phoneNumberGB: SchemaValidation[String] = { val countryCode = Regex.literal("44") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Grenada */ - lazy val phoneNumberGD: Validation[String] = { + lazy val phoneNumberGD: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("473") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Georgia */ - lazy val phoneNumberGE: Validation[String] = { + lazy val phoneNumberGE: SchemaValidation[String] = { val countryCode = Regex.literal("995") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for French Guiana */ - lazy val phoneNumberGF: Validation[String] = { + lazy val phoneNumberGF: SchemaValidation[String] = { val countryCode = Regex.literal("594") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Guernsey */ - lazy val phoneNumberGG: Validation[String] = { + lazy val phoneNumberGG: SchemaValidation[String] = { val countryCode = Regex.literal("44") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Ghana */ - lazy val phoneNumberGH: Validation[String] = { + lazy val phoneNumberGH: SchemaValidation[String] = { val countryCode = Regex.literal("233") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Gibraltar */ - lazy val phoneNumberGI: Validation[String] = { + lazy val phoneNumberGI: SchemaValidation[String] = { val countryCode = Regex.literal("350") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Greenland */ - lazy val phoneNumberGL: Validation[String] = { + lazy val phoneNumberGL: SchemaValidation[String] = { val countryCode = Regex.literal("299") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Gambia */ - lazy val phoneNumberGM: Validation[String] = { + lazy val phoneNumberGM: SchemaValidation[String] = { val countryCode = Regex.literal("220") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Guinea */ - lazy val phoneNumberGN: Validation[String] = { + lazy val phoneNumberGN: SchemaValidation[String] = { val countryCode = Regex.literal("224") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Guadeloupe */ - lazy val phoneNumberGP: Validation[String] = { + lazy val phoneNumberGP: SchemaValidation[String] = { val countryCode = Regex.literal("590") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Equatorial Guinea */ - lazy val phoneNumberGQ: Validation[String] = { + lazy val phoneNumberGQ: SchemaValidation[String] = { val countryCode = Regex.literal("240") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Greece */ - lazy val phoneNumberGR: Validation[String] = { + lazy val phoneNumberGR: SchemaValidation[String] = { val countryCode = Regex.literal("30") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for South Sandwich Islands */ - lazy val phoneNumberGS: Validation[String] = { + lazy val phoneNumberGS: SchemaValidation[String] = { val countryCode = Regex.literal("500") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Guatemala */ - lazy val phoneNumberGT: Validation[String] = { + lazy val phoneNumberGT: SchemaValidation[String] = { val countryCode = Regex.literal("502") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Guam */ - lazy val phoneNumberGU: Validation[String] = { + lazy val phoneNumberGU: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("671") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Guinea-Bissau */ - lazy val phoneNumberGW: Validation[String] = { + lazy val phoneNumberGW: SchemaValidation[String] = { val countryCode = Regex.literal("245") val internationalPrefix = plus | Regex.literal("00001") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Guyana */ - lazy val phoneNumberGY: Validation[String] = { + lazy val phoneNumberGY: SchemaValidation[String] = { val countryCode = Regex.literal("592") val internationalPrefix = plus | Regex.literal("001") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Hong Kong */ - lazy val phoneNumberHK: Validation[String] = { + lazy val phoneNumberHK: SchemaValidation[String] = { val countryCode = Regex.literal("852") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Heard and Mcdonald Islands */ - lazy val phoneNumberHM: Validation[String] = { + lazy val phoneNumberHM: SchemaValidation[String] = { val countryCode = Regex.literal("672") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Honduras */ - lazy val phoneNumberHN: Validation[String] = { + lazy val phoneNumberHN: SchemaValidation[String] = { val countryCode = Regex.literal("504") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Croatia */ - lazy val phoneNumberHR: Validation[String] = { + lazy val phoneNumberHR: SchemaValidation[String] = { val countryCode = Regex.literal("385") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Haiti */ - lazy val phoneNumberHT: Validation[String] = { + lazy val phoneNumberHT: SchemaValidation[String] = { val countryCode = Regex.literal("509") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Hungary */ - lazy val phoneNumberHU: Validation[String] = { + lazy val phoneNumberHU: SchemaValidation[String] = { val countryCode = Regex.literal("36") val nationalPrefix = Regex.literal("06") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefix val phoneNumber = digitsWithSeparator.between(8, 9) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Indonesia */ - lazy val phoneNumberID: Validation[String] = { + lazy val phoneNumberID: SchemaValidation[String] = { val countryCode = Regex.literal("62") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Ireland */ - lazy val phoneNumberIE: Validation[String] = { + lazy val phoneNumberIE: SchemaValidation[String] = { val countryCode = Regex.literal("353") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Israel */ - lazy val phoneNumberIL: Validation[String] = { + lazy val phoneNumberIL: SchemaValidation[String] = { val countryCode = Regex.literal("972") val internationalPrefix = plus | Regex.literal("00") | Regex.literal("01") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Isle of Man */ - lazy val phoneNumberIM: Validation[String] = { + lazy val phoneNumberIM: SchemaValidation[String] = { val countryCode = Regex.literal("44") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val leadingDigits = Regex.literal("74576") val phoneNumber = digitsWithSeparator.between(4, 5) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for India */ - lazy val phoneNumberIN: Validation[String] = { + lazy val phoneNumberIN: SchemaValidation[String] = { val countryCode = Regex.literal("91") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for British Indian Ocean Territory */ - lazy val phoneNumberIO: Validation[String] = { + lazy val phoneNumberIO: SchemaValidation[String] = { val countryCode = Regex.literal("246") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Iraq */ - lazy val phoneNumberIQ: Validation[String] = { + lazy val phoneNumberIQ: SchemaValidation[String] = { val countryCode = Regex.literal("964") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Iran */ - lazy val phoneNumberIR: Validation[String] = { + lazy val phoneNumberIR: SchemaValidation[String] = { val countryCode = Regex.literal("98") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Iceland */ - lazy val phoneNumberIS: Validation[String] = { + lazy val phoneNumberIS: SchemaValidation[String] = { val countryCode = Regex.literal("354") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Italy */ - lazy val phoneNumberIT: Validation[String] = { + lazy val phoneNumberIT: SchemaValidation[String] = { val countryCode = Regex.literal("39") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Jersey */ - lazy val phoneNumberJE: Validation[String] = { + lazy val phoneNumberJE: SchemaValidation[String] = { val countryCode = Regex.literal("44") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Jamaica */ - lazy val phoneNumberJM: Validation[String] = { + lazy val phoneNumberJM: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("658") | Regex.literal("876") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Jordan */ - lazy val phoneNumberJO: Validation[String] = { + lazy val phoneNumberJO: SchemaValidation[String] = { val countryCode = Regex.literal("962") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Japan */ - lazy val phoneNumberJP: Validation[String] = { + lazy val phoneNumberJP: SchemaValidation[String] = { val countryCode = Regex.literal("81") val internationalPrefix = plus | Regex.literal("010") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Kenya */ - lazy val phoneNumberKE: Validation[String] = { + lazy val phoneNumberKE: SchemaValidation[String] = { val countryCode = Regex.literal("254") val internationalPrefix = plus | Regex.literal("000") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Kyrgyzstan */ - lazy val phoneNumberKG: Validation[String] = { + lazy val phoneNumberKG: SchemaValidation[String] = { val countryCode = Regex.literal("996") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Cambodia */ - lazy val phoneNumberKH: Validation[String] = { + lazy val phoneNumberKH: SchemaValidation[String] = { val countryCode = Regex.literal("855") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Kiribati */ - lazy val phoneNumberKI: Validation[String] = { + lazy val phoneNumberKI: SchemaValidation[String] = { val countryCode = Regex.literal("686") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Comoros */ - lazy val phoneNumberKM: Validation[String] = { + lazy val phoneNumberKM: SchemaValidation[String] = { val countryCode = Regex.literal("269") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Saint Kitts and Nevis */ - lazy val phoneNumberKN: Validation[String] = { + lazy val phoneNumberKN: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("869") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for North Korea */ - lazy val phoneNumberKP: Validation[String] = { + lazy val phoneNumberKP: SchemaValidation[String] = { val countryCode = Regex.literal("850") val internationalPrefix = plus | Regex.literal("00") | Regex.literal("99") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for South Korea */ - lazy val phoneNumberKR: Validation[String] = { + lazy val phoneNumberKR: SchemaValidation[String] = { val countryCode = Regex.literal("82") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Kuwait */ - lazy val phoneNumberKW: Validation[String] = { + lazy val phoneNumberKW: SchemaValidation[String] = { val countryCode = Regex.literal("965") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Cayman Islands */ - lazy val phoneNumberKY: Validation[String] = { + lazy val phoneNumberKY: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("345") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Kazakhstan */ - lazy val phoneNumberKZ: Validation[String] = { + lazy val phoneNumberKZ: SchemaValidation[String] = { val countryCode = Regex.literal("7") val internationalPrefix = plus | Regex.literal("00810") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val leadingDigits = Regex.literal("33") | Regex.literal("7") val phoneNumber = digitsWithSeparator.between(6, 8) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Lao PDR */ - lazy val phoneNumberLA: Validation[String] = { + lazy val phoneNumberLA: SchemaValidation[String] = { val countryCode = Regex.literal("856") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Lebanon */ - lazy val phoneNumberLB: Validation[String] = { + lazy val phoneNumberLB: SchemaValidation[String] = { val countryCode = Regex.literal("961") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Saint Lucia */ - lazy val phoneNumberLC: Validation[String] = { + lazy val phoneNumberLC: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("758") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Liechtenstein */ - lazy val phoneNumberLI: Validation[String] = { + lazy val phoneNumberLI: SchemaValidation[String] = { val countryCode = Regex.literal("423") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Sri Lanka */ - lazy val phoneNumberLK: Validation[String] = { + lazy val phoneNumberLK: SchemaValidation[String] = { val countryCode = Regex.literal("94") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Liberia */ - lazy val phoneNumberLR: Validation[String] = { + lazy val phoneNumberLR: SchemaValidation[String] = { val countryCode = Regex.literal("231") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Lesotho */ - lazy val phoneNumberLS: Validation[String] = { + lazy val phoneNumberLS: SchemaValidation[String] = { val countryCode = Regex.literal("266") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Lithuania */ - lazy val phoneNumberLT: Validation[String] = { + lazy val phoneNumberLT: SchemaValidation[String] = { val countryCode = Regex.literal("370") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixEight val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Luxembourg */ - lazy val phoneNumberLU: Validation[String] = { + lazy val phoneNumberLU: SchemaValidation[String] = { val countryCode = Regex.literal("352") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Latvia */ - lazy val phoneNumberLV: Validation[String] = { + lazy val phoneNumberLV: SchemaValidation[String] = { val countryCode = Regex.literal("371") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Libya */ - lazy val phoneNumberLY: Validation[String] = { + lazy val phoneNumberLY: SchemaValidation[String] = { val countryCode = Regex.literal("218") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Morocco */ - lazy val phoneNumberMA: Validation[String] = { + lazy val phoneNumberMA: SchemaValidation[String] = { val countryCode = Regex.literal("212") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Monaco */ - lazy val phoneNumberMC: Validation[String] = { + lazy val phoneNumberMC: SchemaValidation[String] = { val countryCode = Regex.literal("377") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Moldova */ - lazy val phoneNumberMD: Validation[String] = { + lazy val phoneNumberMD: SchemaValidation[String] = { val countryCode = Regex.literal("373") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Montenegro */ - lazy val phoneNumberME: Validation[String] = { + lazy val phoneNumberME: SchemaValidation[String] = { val countryCode = Regex.literal("382") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Saint-Martin (French) */ - lazy val phoneNumberMF: Validation[String] = { + lazy val phoneNumberMF: SchemaValidation[String] = { val countryCode = Regex.literal("590") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Madagascar */ - lazy val phoneNumberMG: Validation[String] = { + lazy val phoneNumberMG: SchemaValidation[String] = { val countryCode = Regex.literal("261") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Marshall Islands */ - lazy val phoneNumberMH: Validation[String] = { + lazy val phoneNumberMH: SchemaValidation[String] = { val countryCode = Regex.literal("692") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Macedonia, Republic of */ - lazy val phoneNumberMK: Validation[String] = { + lazy val phoneNumberMK: SchemaValidation[String] = { val countryCode = Regex.literal("389") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Mali */ - lazy val phoneNumberML: Validation[String] = { + lazy val phoneNumberML: SchemaValidation[String] = { val countryCode = Regex.literal("223") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Myanmar */ - lazy val phoneNumberMM: Validation[String] = { + lazy val phoneNumberMM: SchemaValidation[String] = { val countryCode = Regex.literal("95") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Mongolia */ - lazy val phoneNumberMN: Validation[String] = { + lazy val phoneNumberMN: SchemaValidation[String] = { val countryCode = Regex.literal("976") val internationalPrefix = plus | Regex.literal("001") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Macao, SAR China */ - lazy val phoneNumberMO: Validation[String] = { + lazy val phoneNumberMO: SchemaValidation[String] = { val countryCode = Regex.literal("853") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Northern Mariana Islands */ - lazy val phoneNumberMP: Validation[String] = { + lazy val phoneNumberMP: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val leadingDigits = Regex.literal("670") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Martinique */ - lazy val phoneNumberMQ: Validation[String] = { + lazy val phoneNumberMQ: SchemaValidation[String] = { val countryCode = Regex.literal("596") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Mauritania */ - lazy val phoneNumberMR: Validation[String] = { + lazy val phoneNumberMR: SchemaValidation[String] = { val countryCode = Regex.literal("222") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Montserrat */ - lazy val phoneNumberMS: Validation[String] = { + lazy val phoneNumberMS: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("664") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Malta */ - lazy val phoneNumberMT: Validation[String] = { + lazy val phoneNumberMT: SchemaValidation[String] = { val countryCode = Regex.literal("356") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Mauritius */ - lazy val phoneNumberMU: Validation[String] = { + lazy val phoneNumberMU: SchemaValidation[String] = { val countryCode = Regex.literal("230") val internationalPrefix = plus | Regex.literal("0020") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Maldives */ - lazy val phoneNumberMV: Validation[String] = { + lazy val phoneNumberMV: SchemaValidation[String] = { val countryCode = Regex.literal("960") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Malawi */ - lazy val phoneNumberMW: Validation[String] = { + lazy val phoneNumberMW: SchemaValidation[String] = { val countryCode = Regex.literal("265") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Mexico */ - lazy val phoneNumberMX: Validation[String] = { + lazy val phoneNumberMX: SchemaValidation[String] = { val countryCode = Regex.literal("52") val nationalPrefix = Regex.literal("01") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefix val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Malaysia */ - lazy val phoneNumberMY: Validation[String] = { + lazy val phoneNumberMY: SchemaValidation[String] = { val countryCode = Regex.literal("60") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Mozambique */ - lazy val phoneNumberMZ: Validation[String] = { + lazy val phoneNumberMZ: SchemaValidation[String] = { val countryCode = Regex.literal("258") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Namibia */ - lazy val phoneNumberNA: Validation[String] = { + lazy val phoneNumberNA: SchemaValidation[String] = { val countryCode = Regex.literal("264") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for New Caledonia */ - lazy val phoneNumberNC: Validation[String] = { + lazy val phoneNumberNC: SchemaValidation[String] = { val countryCode = Regex.literal("687") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Niger */ - lazy val phoneNumberNE: Validation[String] = { + lazy val phoneNumberNE: SchemaValidation[String] = { val countryCode = Regex.literal("227") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Norfolk Island */ - lazy val phoneNumberNF: Validation[String] = { + lazy val phoneNumberNF: SchemaValidation[String] = { val countryCode = Regex.literal("672") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Nigeria */ - lazy val phoneNumberNG: Validation[String] = { + lazy val phoneNumberNG: SchemaValidation[String] = { val countryCode = Regex.literal("234") val internationalPrefix = plus | Regex.literal("009") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Nicaragua */ - lazy val phoneNumberNI: Validation[String] = { + lazy val phoneNumberNI: SchemaValidation[String] = { val countryCode = Regex.literal("505") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Netherlands */ - lazy val phoneNumberNL: Validation[String] = { + lazy val phoneNumberNL: SchemaValidation[String] = { val countryCode = Regex.literal("31") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Norway */ - lazy val phoneNumberNO: Validation[String] = { + lazy val phoneNumberNO: SchemaValidation[String] = { val countryCode = Regex.literal("47") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val leadingDigits = Regex.literal("02") val phoneNumber = digitsWithSeparator.between(6, 8) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Nepal */ - lazy val phoneNumberNP: Validation[String] = { + lazy val phoneNumberNP: SchemaValidation[String] = { val countryCode = Regex.literal("977") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Nauru */ - lazy val phoneNumberNR: Validation[String] = { + lazy val phoneNumberNR: SchemaValidation[String] = { val countryCode = Regex.literal("674") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Niue */ - lazy val phoneNumberNU: Validation[String] = { + lazy val phoneNumberNU: SchemaValidation[String] = { val countryCode = Regex.literal("683") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for New Zealand */ - lazy val phoneNumberNZ: Validation[String] = { + lazy val phoneNumberNZ: SchemaValidation[String] = { val countryCode = Regex.literal("64") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Oman */ - lazy val phoneNumberOM: Validation[String] = { + lazy val phoneNumberOM: SchemaValidation[String] = { val countryCode = Regex.literal("968") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Panama */ - lazy val phoneNumberPA: Validation[String] = { + lazy val phoneNumberPA: SchemaValidation[String] = { val countryCode = Regex.literal("507") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Peru */ - lazy val phoneNumberPE: Validation[String] = { + lazy val phoneNumberPE: SchemaValidation[String] = { val countryCode = Regex.literal("51") val internationalPrefix = plus | Regex.literal("0019") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for French Polynesia */ - lazy val phoneNumberPF: Validation[String] = { + lazy val phoneNumberPF: SchemaValidation[String] = { val countryCode = Regex.literal("689") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Papua New Guinea */ - lazy val phoneNumberPG: Validation[String] = { + lazy val phoneNumberPG: SchemaValidation[String] = { val countryCode = Regex.literal("675") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Philippines */ - lazy val phoneNumberPH: Validation[String] = { + lazy val phoneNumberPH: SchemaValidation[String] = { val countryCode = Regex.literal("63") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Pakistan */ - lazy val phoneNumberPK: Validation[String] = { + lazy val phoneNumberPK: SchemaValidation[String] = { val countryCode = Regex.literal("92") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Poland */ - lazy val phoneNumberPL: Validation[String] = { + lazy val phoneNumberPL: SchemaValidation[String] = { val countryCode = Regex.literal("48") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Saint Pierre and Miquelon */ - lazy val phoneNumberPM: Validation[String] = { + lazy val phoneNumberPM: SchemaValidation[String] = { val countryCode = Regex.literal("508") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Pitcairn Islands */ - lazy val phoneNumberPN: Validation[String] = { + lazy val phoneNumberPN: SchemaValidation[String] = { val countryCode = Regex.literal("870") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Puerto Rico */ - lazy val phoneNumberPR: Validation[String] = { + lazy val phoneNumberPR: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("787") | Regex.literal("939") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Palestinian Territory */ - lazy val phoneNumberPS: Validation[String] = { + lazy val phoneNumberPS: SchemaValidation[String] = { val countryCode = Regex.literal("970") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Portugal */ - lazy val phoneNumberPT: Validation[String] = { + lazy val phoneNumberPT: SchemaValidation[String] = { val countryCode = Regex.literal("351") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(8, 9) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Palau */ - lazy val phoneNumberPW: Validation[String] = { + lazy val phoneNumberPW: SchemaValidation[String] = { val countryCode = Regex.literal("680") val internationalPrefix = plus | Regex.literal("01") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Paraguay */ - lazy val phoneNumberPY: Validation[String] = { + lazy val phoneNumberPY: SchemaValidation[String] = { val countryCode = Regex.literal("595") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Qatar */ - lazy val phoneNumberQA: Validation[String] = { + lazy val phoneNumberQA: SchemaValidation[String] = { val countryCode = Regex.literal("974") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Reunion */ - lazy val phoneNumberRE: Validation[String] = { + lazy val phoneNumberRE: SchemaValidation[String] = { val countryCode = Regex.literal("262") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Romania */ - lazy val phoneNumberRO: Validation[String] = { + lazy val phoneNumberRO: SchemaValidation[String] = { val countryCode = Regex.literal("40") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Serbia */ - lazy val phoneNumberRS: Validation[String] = { + lazy val phoneNumberRS: SchemaValidation[String] = { val countryCode = Regex.literal("381") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Russia */ - lazy val phoneNumberRU: Validation[String] = { + lazy val phoneNumberRU: SchemaValidation[String] = { val countryCode = Regex.literal("7") val internationalPrefix = plus | Regex.literal("810") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixEight val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Rwanda */ - lazy val phoneNumberRW: Validation[String] = { + lazy val phoneNumberRW: SchemaValidation[String] = { val countryCode = Regex.literal("250") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Saudi Arabia */ - lazy val phoneNumberSA: Validation[String] = { + lazy val phoneNumberSA: SchemaValidation[String] = { val countryCode = Regex.literal("966") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Solomon Islands */ - lazy val phoneNumberSB: Validation[String] = { + lazy val phoneNumberSB: SchemaValidation[String] = { val countryCode = Regex.literal("677") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Seychelles */ - lazy val phoneNumberSC: Validation[String] = { + lazy val phoneNumberSC: SchemaValidation[String] = { val countryCode = Regex.literal("248") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Sudan */ - lazy val phoneNumberSD: Validation[String] = { + lazy val phoneNumberSD: SchemaValidation[String] = { val countryCode = Regex.literal("249") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Sweden */ - lazy val phoneNumberSE: Validation[String] = { + lazy val phoneNumberSE: SchemaValidation[String] = { val countryCode = Regex.literal("46") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Singapore */ - lazy val phoneNumberSG: Validation[String] = { + lazy val phoneNumberSG: SchemaValidation[String] = { val countryCode = Regex.literal("65") val internationalPrefix = plus | Regex.literal("0") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Saint Helena */ - lazy val phoneNumberSH: Validation[String] = { + lazy val phoneNumberSH: SchemaValidation[String] = { val countryCode = Regex.literal("290") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val leadingDigits = Regex.literal("256") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Slovenia */ - lazy val phoneNumberSI: Validation[String] = { + lazy val phoneNumberSI: SchemaValidation[String] = { val countryCode = Regex.literal("386") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Svalbard and Jan Mayen Islands */ - lazy val phoneNumberSJ: Validation[String] = { + lazy val phoneNumberSJ: SchemaValidation[String] = { val countryCode = Regex.literal("47") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val leadingDigits = Regex.literal("79") val phoneNumber = digitsWithSeparator.between(6, 8) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Slovakia */ - lazy val phoneNumberSK: Validation[String] = { + lazy val phoneNumberSK: SchemaValidation[String] = { val countryCode = Regex.literal("421") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Sierra Leone */ - lazy val phoneNumberSL: Validation[String] = { + lazy val phoneNumberSL: SchemaValidation[String] = { val countryCode = Regex.literal("232") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for San Marino */ - lazy val phoneNumberSM: Validation[String] = { + lazy val phoneNumberSM: SchemaValidation[String] = { val countryCode = Regex.literal("378") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Senegal */ - lazy val phoneNumberSN: Validation[String] = { + lazy val phoneNumberSN: SchemaValidation[String] = { val countryCode = Regex.literal("221") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Somalia */ - lazy val phoneNumberSO: Validation[String] = { + lazy val phoneNumberSO: SchemaValidation[String] = { val countryCode = Regex.literal("252") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Suriname */ - lazy val phoneNumberSR: Validation[String] = { + lazy val phoneNumberSR: SchemaValidation[String] = { val countryCode = Regex.literal("597") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for South Sudan */ - lazy val phoneNumberSS: Validation[String] = { + lazy val phoneNumberSS: SchemaValidation[String] = { val countryCode = Regex.literal("211") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Sao Tome and Principe */ - lazy val phoneNumberST: Validation[String] = { + lazy val phoneNumberST: SchemaValidation[String] = { val countryCode = Regex.literal("239") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for El Salvador */ - lazy val phoneNumberSV: Validation[String] = { + lazy val phoneNumberSV: SchemaValidation[String] = { val countryCode = Regex.literal("503") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Saint Marten */ - lazy val phoneNumberSX: Validation[String] = { + lazy val phoneNumberSX: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("721") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Syria */ - lazy val phoneNumberSY: Validation[String] = { + lazy val phoneNumberSY: SchemaValidation[String] = { val countryCode = Regex.literal("963") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Swaziland */ - lazy val phoneNumberSZ: Validation[String] = { + lazy val phoneNumberSZ: SchemaValidation[String] = { val countryCode = Regex.literal("268") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Tristan da Cunha */ - lazy val phoneNumberTA: Validation[String] = { + lazy val phoneNumberTA: SchemaValidation[String] = { val countryCode = Regex.literal("290") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val leadingDigits = Regex.literal("8") val phoneNumber = digitsWithSeparator.between(6, 9) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Turks and Caicos Islands */ - lazy val phoneNumberTC: Validation[String] = { + lazy val phoneNumberTC: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("649") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Chad */ - lazy val phoneNumberTD: Validation[String] = { + lazy val phoneNumberTD: SchemaValidation[String] = { val countryCode = Regex.literal("235") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for French Southern Territories */ - lazy val phoneNumberTF: Validation[String] = { + lazy val phoneNumberTF: SchemaValidation[String] = { val countryCode = Regex.literal("262") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Togo */ - lazy val phoneNumberTG: Validation[String] = { + lazy val phoneNumberTG: SchemaValidation[String] = { val countryCode = Regex.literal("228") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Thailand */ - lazy val phoneNumberTH: Validation[String] = { + lazy val phoneNumberTH: SchemaValidation[String] = { val countryCode = Regex.literal("66") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Tajikistan */ - lazy val phoneNumberTJ: Validation[String] = { + lazy val phoneNumberTJ: SchemaValidation[String] = { val countryCode = Regex.literal("992") val internationalPrefix = plus | Regex.literal("00810") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Tokelau */ - lazy val phoneNumberTK: Validation[String] = { + lazy val phoneNumberTK: SchemaValidation[String] = { val countryCode = Regex.literal("690") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Timor-Leste */ - lazy val phoneNumberTL: Validation[String] = { + lazy val phoneNumberTL: SchemaValidation[String] = { val countryCode = Regex.literal("670") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Turkmenistan */ - lazy val phoneNumberTM: Validation[String] = { + lazy val phoneNumberTM: SchemaValidation[String] = { val countryCode = Regex.literal("993") val internationalPrefix = plus | Regex.literal("00810") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixEight val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Tunisia */ - lazy val phoneNumberTN: Validation[String] = { + lazy val phoneNumberTN: SchemaValidation[String] = { val countryCode = Regex.literal("216") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Tonga */ - lazy val phoneNumberTO: Validation[String] = { + lazy val phoneNumberTO: SchemaValidation[String] = { val countryCode = Regex.literal("676") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Turkey */ - lazy val phoneNumberTR: Validation[String] = { + lazy val phoneNumberTR: SchemaValidation[String] = { val countryCode = Regex.literal("90") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Trinidad and Tobago */ - lazy val phoneNumberTT: Validation[String] = { + lazy val phoneNumberTT: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("868") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Tuvalu */ - lazy val phoneNumberTV: Validation[String] = { + lazy val phoneNumberTV: SchemaValidation[String] = { val countryCode = Regex.literal("688") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Taiwan */ - lazy val phoneNumberTW: Validation[String] = { + lazy val phoneNumberTW: SchemaValidation[String] = { val countryCode = Regex.literal("886") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Tanzania */ - lazy val phoneNumberTZ: Validation[String] = { + lazy val phoneNumberTZ: SchemaValidation[String] = { val countryCode = Regex.literal("255") val internationalPrefix = plus | Regex.literal("00[056]") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Ukraine */ - lazy val phoneNumberUA: Validation[String] = { + lazy val phoneNumberUA: SchemaValidation[String] = { val countryCode = Regex.literal("380") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Uganda */ - lazy val phoneNumberUG: Validation[String] = { + lazy val phoneNumberUG: SchemaValidation[String] = { val countryCode = Regex.literal("256") val internationalPrefix = plus | Regex.literal("00[057]") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for US Minor Outlying Islands */ - lazy val phoneNumberUM: Validation[String] = { + lazy val phoneNumberUM: SchemaValidation[String] = { val countryCode = Regex.literal("1") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for United States of America */ - lazy val phoneNumberUS: Validation[String] = { + lazy val phoneNumberUS: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Uruguay */ - lazy val phoneNumberUY: Validation[String] = { + lazy val phoneNumberUY: SchemaValidation[String] = { val countryCode = Regex.literal("598") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Uzbekistan */ - lazy val phoneNumberUZ: Validation[String] = { + lazy val phoneNumberUZ: SchemaValidation[String] = { val countryCode = Regex.literal("998") val internationalPrefix = plus | Regex.literal("00810") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixEight val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Holy See (Vatican City State) */ - lazy val phoneNumberVA: Validation[String] = { + lazy val phoneNumberVA: SchemaValidation[String] = { val countryCode = Regex.literal("39") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val leadingDigits = Regex.literal("06698") val phoneNumber = digitsWithSeparator.between(4, 6) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Saint Vincent and Grenadines */ - lazy val phoneNumberVC: Validation[String] = { + lazy val phoneNumberVC: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("784") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Venezuela */ - lazy val phoneNumberVE: Validation[String] = { + lazy val phoneNumberVE: SchemaValidation[String] = { val countryCode = Regex.literal("58") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for British Virgin Islands */ - lazy val phoneNumberVG: Validation[String] = { + lazy val phoneNumberVG: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("284") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Virgin Islands, US */ - lazy val phoneNumberVI: Validation[String] = { + lazy val phoneNumberVI: SchemaValidation[String] = { val countryCode = Regex.literal("1") val internationalPrefix = plus | Regex.literal("011") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixOne val leadingDigits = Regex.literal("340") val phoneNumber = digitsWithSeparator.between(6, 7) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Vietnam */ - lazy val phoneNumberVN: Validation[String] = { + lazy val phoneNumberVN: SchemaValidation[String] = { val countryCode = Regex.literal("84") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Vanuatu */ - lazy val phoneNumberVU: Validation[String] = { + lazy val phoneNumberVU: SchemaValidation[String] = { val countryCode = Regex.literal("678") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Wallis and Futuna Islands */ - lazy val phoneNumberWF: Validation[String] = { + lazy val phoneNumberWF: SchemaValidation[String] = { val countryCode = Regex.literal("681") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Samoa */ - lazy val phoneNumberWS: Validation[String] = { + lazy val phoneNumberWS: SchemaValidation[String] = { val countryCode = Regex.literal("685") val internationalPrefix = plus | Regex.literal("0") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Kosovo */ - lazy val phoneNumberXK: Validation[String] = { + lazy val phoneNumberXK: SchemaValidation[String] = { val countryCode = Regex.literal("383") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Yemen */ - lazy val phoneNumberYE: Validation[String] = { + lazy val phoneNumberYE: SchemaValidation[String] = { val countryCode = Regex.literal("967") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Mayotte */ - lazy val phoneNumberYT: Validation[String] = { + lazy val phoneNumberYT: SchemaValidation[String] = { val countryCode = Regex.literal("262") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val leadingDigits = Regex.literal("269") | Regex.literal("63") val phoneNumber = digitsWithSeparator.between(6, 8) - Validation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ leadingDigits ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for South Africa */ - lazy val phoneNumberZA: Validation[String] = { + lazy val phoneNumberZA: SchemaValidation[String] = { val countryCode = Regex.literal("27") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Zambia */ - lazy val phoneNumberZM: Validation[String] = { + lazy val phoneNumberZM: SchemaValidation[String] = { val countryCode = Regex.literal("260") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } /** Phone number validation for Zimbabwe */ - lazy val phoneNumberZW: Validation[String] = { + lazy val phoneNumberZW: SchemaValidation[String] = { val countryCode = Regex.literal("263") val prefix = internationalPrefix ~ optionalSeparator ~ countryCode | nationalPrefixZero val phoneNumber = digitsWithSeparator.between(9, 10) - Validation.regex(prefix ~ optionalSeparator ~ phoneNumber) + SchemaValidation.regex(prefix ~ optionalSeparator ~ phoneNumber) } } diff --git a/zio-schema/shared/src/main/scala/zio/schema/validation/Predicate.scala b/zio-schema/shared/src/main/scala/zio/schema/validation/Predicate.scala index e02f72a97..0c6415a80 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/validation/Predicate.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/validation/Predicate.scala @@ -3,8 +3,8 @@ package zio.schema.validation import zio.Chunk sealed trait Predicate[A] { - type Errors = Chunk[ValidationError] - type Result = zio.prelude.Validation[Errors, Errors] + type Errors = Chunk[SchemaValidationError] + type Result = Either[Errors, Errors] def validate(value: A): Result } @@ -16,21 +16,22 @@ object Predicate { def validate(value: String): Result = if (value.length() >= n) - zio.prelude.Validation.succeed(Chunk(ValidationError.MaxLength(n, value.length(), value))) + Right(Chunk(SchemaValidationError.MaxLength(n, value.length(), value))) else - Left(Chunk(ValidationError.MinLength(n, value.length(), value))) + Left(Chunk(SchemaValidationError.MinLength(n, value.length(), value))) } final case class MaxLength(n: Int) extends Str[String] { def validate(value: String): Result = - if (value.length() <= n) zio.prelude.Validation.succeed(Chunk(ValidationError.MinLength(n, value.length(), value))) - else Left(Chunk(ValidationError.MaxLength(n, value.length(), value))) + if (value.length() <= n) + Right(Chunk(SchemaValidationError.MinLength(n, value.length(), value))) + else Left(Chunk(SchemaValidationError.MaxLength(n, value.length(), value))) } final case class Matches(r: Regex) extends Str[String] { def validate(value: String): Result = - if (r.test(value)) zio.prelude.Validation.succeed(Chunk(ValidationError.NotRegexMatch(value, r))) - else Left(Chunk(ValidationError.RegexMatch(value, r))) + if (r.test(value)) Right(Chunk(SchemaValidationError.NotRegexMatch(value, r))) + else Left(Chunk(SchemaValidationError.RegexMatch(value, r))) } } @@ -44,29 +45,29 @@ object Predicate { def validate(v: A): Result = if (numType.numeric.compare(v, value) > 0) - zio.prelude.Validation.succeed(Chunk(ValidationError.LessThan(v, value))) + Right(Chunk(SchemaValidationError.LessThan(v, value))) else - Left(Chunk(ValidationError.GreaterThan(v, value))) + Left(Chunk(SchemaValidationError.GreaterThan(v, value))) } final case class LessThan[A](numType: NumType[A], value: A) extends Num[A] { def validate(v: A): Result = if (numType.numeric.compare(v, value) < 0) - zio.prelude.Validation.succeed(Chunk(ValidationError.GreaterThan(v, value))) + Right(Chunk(SchemaValidationError.GreaterThan(v, value))) else - Left(Chunk(ValidationError.LessThan(v, value))) + Left(Chunk(SchemaValidationError.LessThan(v, value))) } final case class EqualTo[A](numType: NumType[A], value: A) extends Num[A] { def validate(v: A): Result = if (numType.numeric.compare(v, value) == 0) - zio.prelude.Validation.succeed(Chunk(ValidationError.NotEqualTo(v, value))) + Right(Chunk(SchemaValidationError.NotEqualTo(v, value))) else - Left(Chunk(ValidationError.EqualTo(v, value))) + Left(Chunk(SchemaValidationError.EqualTo(v, value))) } } final case class True[A]() extends Predicate[A] { // A => True - def validate(value: A): Result = zio.prelude.Validation.succeed(Chunk.empty) + def validate(value: A): Result = Right(Chunk.empty) } } diff --git a/zio-schema/shared/src/main/scala/zio/schema/validation/Regexs.scala b/zio-schema/shared/src/main/scala/zio/schema/validation/Regexs.scala index d3ecd9b44..5d147e735 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/validation/Regexs.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/validation/Regexs.scala @@ -2,13 +2,13 @@ package zio.schema.validation trait Regexs { - val identifier: Validation[String] = - Validation.regex((Regex.digitOrLetter | Regex.oneOf('_')).atLeast(1)) + val identifier: SchemaValidation[String] = + SchemaValidation.regex((Regex.digitOrLetter | Regex.oneOf('_')).atLeast(1)) /** * Checks whether a certain string represents a valid email address. */ - lazy val email: Validation[String] = { + lazy val email: SchemaValidation[String] = { val localPart = Regex.letter ~ (Regex.digitOrLetter | Regex.oneOf('_', '.', '+', '-')).atMost(63) val domainSegment = Regex.digitOrLetter | Regex.oneOf('-') val topLevelDomain = domainSegment.between(2, 4) @@ -20,10 +20,10 @@ trait Regexs { val emailWithIpv6Domain = emailBeginning ~ ipBlock(Regex.literal("IPv6:") ~ ipV6Regex) val completeEmail = emailWithNormalDomain | emailWithIpv4Domain | emailWithIpv6Domain - Validation.regex(completeEmail) && Validation.maxLength(254) + SchemaValidation.regex(completeEmail) && SchemaValidation.maxLength(254) } - lazy val duration: Validation[String] = { + lazy val duration: SchemaValidation[String] = { val posDigit = Regex.between('1', '9') val integer = Regex.digit.+ @@ -41,7 +41,7 @@ trait Regexs { val date = (day | month | year) ~ time.? val duration = Regex.oneOf('P') ~ (date | time | week) - Validation.regex(duration) + SchemaValidation.regex(duration) } private lazy val ipV4Regex: Regex = { @@ -61,7 +61,7 @@ trait Regexs { /** * Checks whether a certain string represents a valid IPv4 address. */ - lazy val ipV4: Validation[String] = Validation.regex(ipV4Regex) + lazy val ipV4: SchemaValidation[String] = SchemaValidation.regex(ipV4Regex) private lazy val ipV6Regex: Regex = { val oneDigitHex = Regex.hexDigit.exactly(1) @@ -86,9 +86,9 @@ trait Regexs { /** * Checks whether a certain string represents a valid IPv6 address. */ - lazy val ipV6: Validation[String] = Validation.regex(ipV6Regex) + lazy val ipV6: SchemaValidation[String] = SchemaValidation.regex(ipV6Regex) - lazy val uuidV4: Validation[String] = { + lazy val uuidV4: SchemaValidation[String] = { val hexOctect = Regex.hexDigit ~ Regex.hexDigit val sep = Regex.oneOf('-') @@ -98,7 +98,7 @@ trait Regexs { val clockSeq = Regex.CharacterSet(Set('8', '9', 'a', 'A', 'b', 'B')) ~ Regex.hexDigit ~ hexOctect val node = hexOctect.exactly(6) - Validation.regex( + SchemaValidation.regex( timeLow ~ sep ~ timeMid ~ sep ~ timeHighAndVersion ~ sep ~ diff --git a/zio-schema/shared/src/main/scala/zio/schema/validation/SchemaValidation.scala b/zio-schema/shared/src/main/scala/zio/schema/validation/SchemaValidation.scala new file mode 100644 index 000000000..0719ebd1e --- /dev/null +++ b/zio-schema/shared/src/main/scala/zio/schema/validation/SchemaValidation.scala @@ -0,0 +1,83 @@ +package zio.schema.validation + +import zio.Chunk +import zio.prelude.Validation + +final case class SchemaValidation[A](bool: Bool[Predicate[A]]) { self => + def &&(that: SchemaValidation[A]): SchemaValidation[A] = SchemaValidation(self.bool && that.bool) + def ||(that: SchemaValidation[A]): SchemaValidation[A] = SchemaValidation(self.bool || that.bool) + def unary_! : SchemaValidation[A] = SchemaValidation(!self.bool) + + def validate(value: A): Validation[SchemaValidationError, Unit] = { + type Errors = Chunk[SchemaValidationError] + type Result = Either[Errors, Errors] + def combineAnd(left: Result, right: Result): Result = + (left, right) match { + case (Left(leftErrors), Left(rightErrors)) => Left(leftErrors ++ rightErrors) + case (Left(leftErrors), _) => Left(leftErrors) + case (_, Left(rightErrors)) => Left(rightErrors) + case (Right(leftSuccesses), Right(rightSuccesses)) => Right(leftSuccesses ++ rightSuccesses) + } + + def combineOr(left: Result, right: Result): Result = + (left, right) match { + case (Left(leftErrors), Left(rightErrors)) => Left(leftErrors ++ rightErrors) + case (Left(_), right) => right + case (right, Left(_)) => right + case (Right(leftSuccesses), Right(rightSuccesses)) => Right(leftSuccesses ++ rightSuccesses) + } + + def loop(bool: Bool[Predicate[A]]): Result = { + import Bool._ + bool match { + case And(left, right) => + val leftValidation = loop(left) + val rightValidation = loop(right) + combineAnd(leftValidation, rightValidation) + case Or(left, right) => + val leftValidation = loop(left) + val rightValidation = loop(right) + combineOr(leftValidation, rightValidation) + case Leaf(predicate) => predicate.validate(value) + case Not(value) => loop(value).swap + } + } + + val errors = loop(self.bool).left.getOrElse(Chunk.empty) + errors.nonEmptyOrElse[Validation[SchemaValidationError, Unit]](Validation.succeed(()))( + errors => Validation.failNonEmptyChunk(errors) + ) + } +} + +object SchemaValidation extends Regexs with Time { + import Predicate._ + + // String operations + def minLength(n: Int): SchemaValidation[String] = SchemaValidation(Bool.Leaf(Str.MinLength(n))) + def maxLength(n: Int): SchemaValidation[String] = SchemaValidation(Bool.Leaf(Str.MaxLength(n))) + //Regex + def regex(r: Regex): SchemaValidation[String] = SchemaValidation(Bool.Leaf(Str.Matches(r))) + + // Numerical operations + def greaterThan[A](value: A)(implicit numType: NumType[A]): SchemaValidation[A] = + SchemaValidation(Bool.Leaf(Num.GreaterThan(numType, value))) + + def lessThan[A](value: A)(implicit numType: NumType[A]): SchemaValidation[A] = + SchemaValidation(Bool.Leaf(Num.LessThan(numType, value))) + + def between[A](lower: A, upper: A)(implicit numType: NumType[A]): SchemaValidation[A] = + (greaterThan(lower) || equalTo(lower)) && (lessThan(upper) || equalTo(upper)) + + def equalTo[A](value: A)(implicit numType: NumType[A]): SchemaValidation[A] = + SchemaValidation(Bool.Leaf(Num.EqualTo(numType, value))) + + def succeed[A]: SchemaValidation[A] = SchemaValidation(Bool.Leaf(Predicate.True[A]())) + def fail[A]: SchemaValidation[A] = !succeed[A] + + def allOf[A](vs: SchemaValidation[A]*): SchemaValidation[A] = vs.foldLeft(succeed[A])(_ && _) + def allOf[A](vl: Iterable[SchemaValidation[A]]): SchemaValidation[A] = allOf(vl.toSeq: _*) + + def anyOf[A](vs: SchemaValidation[A]*): SchemaValidation[A] = vs.foldLeft(fail[A])(_ || _) + def anyOf[A](vl: Iterable[SchemaValidation[A]]): SchemaValidation[A] = anyOf(vl.toSeq: _*) +} diff --git a/zio-schema/shared/src/main/scala/zio/schema/validation/Time.scala b/zio-schema/shared/src/main/scala/zio/schema/validation/Time.scala index 3436dd143..ddc99be96 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/validation/Time.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/validation/Time.scala @@ -37,9 +37,9 @@ trait Time { * 1:10:30 * */ - def time(format: String): Validation[String] = { + def time(format: String): SchemaValidation[String] = { val regex = parseFormat(format) - Validation.regex(regex) + SchemaValidation.regex(regex) } sealed private trait Field diff --git a/zio-schema/shared/src/main/scala/zio/schema/validation/Validation.scala b/zio-schema/shared/src/main/scala/zio/schema/validation/Validation.scala deleted file mode 100644 index 4b756eac2..000000000 --- a/zio-schema/shared/src/main/scala/zio/schema/validation/Validation.scala +++ /dev/null @@ -1,79 +0,0 @@ -package zio.schema.validation - -import zio.Chunk - -final case class Validation[A](bool: Bool[Predicate[A]]) { self => - def &&(that: Validation[A]): Validation[A] = Validation(self.bool && that.bool) - def ||(that: Validation[A]): Validation[A] = Validation(self.bool || that.bool) - def unary_! : Validation[A] = Validation(!self.bool) - - def validate(value: A): zio.prelude.Validation[Chunk[ValidationError], Unit] = { - type Errors = Chunk[ValidationError] - type Result = zio.prelude.Validation[Errors, Errors] - def combineAnd(left: Result, right: Result): Result = - (left, right) match { - case (Left(leftErrors), Left(rightErrors)) => Left(leftErrors ++ rightErrors) - case (Left(leftErrors), _) => Left(leftErrors) - case (_, Left(rightErrors)) => Left(rightErrors) - case (zio.prelude.Validation.succeed(leftSuccesses), zio.prelude.Validation.succeed(rightSuccesses)) => zio.prelude.Validation.succeed(leftSuccesses ++ rightSuccesses) - } - - def combineOr(left: Result, right: Result): Result = - (left, right) match { - case (Left(leftErrors), Left(rightErrors)) => Left(leftErrors ++ rightErrors) - case (Left(_), right) => right - case (right, Left(_)) => right - case (zio.prelude.Validation.succeed(leftSuccesses), zio.prelude.Validation.succeed(rightSuccesses)) => zio.prelude.Validation.succeed(leftSuccesses ++ rightSuccesses) - } - - def loop(bool: Bool[Predicate[A]]): Result = { - import Bool._ - bool match { - case And(left, right) => - val leftValidation = loop(left) - val rightValidation = loop(right) - combineAnd(leftValidation, rightValidation) - case Or(left, right) => - val leftValidation = loop(left) - val rightValidation = loop(right) - combineOr(leftValidation, rightValidation) - case Leaf(predicate) => predicate.validate(value) - case Not(value) => loop(value).swap - } - } - - loop(self.bool).map(_ => ()) - } -} - -object Validation extends Regexs with Time { - import Predicate._ - - // String operations - def minLength(n: Int): Validation[String] = Validation(Bool.Leaf(Str.MinLength(n))) - def maxLength(n: Int): Validation[String] = Validation(Bool.Leaf(Str.MaxLength(n))) - //Regex - def regex(r: Regex): Validation[String] = Validation(Bool.Leaf(Str.Matches(r))) - - // Numerical operations - def greaterThan[A](value: A)(implicit numType: NumType[A]): Validation[A] = - Validation(Bool.Leaf(Num.GreaterThan(numType, value))) - - def lessThan[A](value: A)(implicit numType: NumType[A]): Validation[A] = - Validation(Bool.Leaf(Num.LessThan(numType, value))) - - def between[A](lower: A, upper: A)(implicit numType: NumType[A]): Validation[A] = - (greaterThan(lower) || equalTo(lower)) && (lessThan(upper) || equalTo(upper)) - - def equalTo[A](value: A)(implicit numType: NumType[A]): Validation[A] = - Validation(Bool.Leaf(Num.EqualTo(numType, value))) - - def succeed[A]: Validation[A] = Validation(Bool.Leaf(Predicate.True[A]())) - def fail[A]: Validation[A] = !succeed[A] - - def allOf[A](vs: Validation[A]*): Validation[A] = vs.foldLeft(succeed[A])(_ && _) - def allOf[A](vl: Iterable[Validation[A]]): Validation[A] = allOf(vl.toSeq: _*) - - def anyOf[A](vs: Validation[A]*): Validation[A] = vs.foldLeft(fail[A])(_ || _) - def anyOf[A](vl: Iterable[Validation[A]]): Validation[A] = anyOf(vl.toSeq: _*) -} diff --git a/zio-schema/shared/src/main/scala/zio/schema/validation/ValidationErrors.scala b/zio-schema/shared/src/main/scala/zio/schema/validation/ValidationErrors.scala index 8deded772..cea9e1cf3 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/validation/ValidationErrors.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/validation/ValidationErrors.scala @@ -1,46 +1,46 @@ package zio.schema.validation -sealed trait ValidationError { +sealed trait SchemaValidationError { def message: String } -object ValidationError { - final case class MinLength(minLength: Int, actualLength: Int, string: String) extends ValidationError { +object SchemaValidationError { + final case class MinLength(minLength: Int, actualLength: Int, string: String) extends SchemaValidationError { override def message: String = s"Expected the length of $string to be at least $minLength characters but was $actualLength characters." } - final case class MaxLength(maxLength: Int, actualLength: Int, string: String) extends ValidationError { + final case class MaxLength(maxLength: Int, actualLength: Int, string: String) extends SchemaValidationError { override def message: String = s"Expected the length of $string to be at most $maxLength characters but was $actualLength characters." } - final case class GreaterThan[A](value: A, expected: A) extends ValidationError { + final case class GreaterThan[A](value: A, expected: A) extends SchemaValidationError { override def message: String = s"$value should be greater than $expected" } - final case class LessThan[A](value: A, expected: A) extends ValidationError { + final case class LessThan[A](value: A, expected: A) extends SchemaValidationError { override def message: String = s"$value should be less than $expected" } - final case class EqualTo[A](value: A, expected: A) extends ValidationError { + final case class EqualTo[A](value: A, expected: A) extends SchemaValidationError { override def message: String = s"$value should be equal to $expected" } - final case class NotEqualTo[A](value: A, expected: A) extends ValidationError { + final case class NotEqualTo[A](value: A, expected: A) extends SchemaValidationError { override def message: String = s"$value should not be equal to $expected" } - final case class RegexMatch(str: String, expected: Regex) extends ValidationError { + final case class RegexMatch(str: String, expected: Regex) extends SchemaValidationError { override def message: String = s"$str does not match $expected" } - final case class NotRegexMatch(str: String, expected: Regex) extends ValidationError { + final case class NotRegexMatch(str: String, expected: Regex) extends SchemaValidationError { override def message: String = s"$str matches a regex other than $expected" } - final case class Generic(message: String) extends ValidationError + final case class Generic(message: String) extends SchemaValidationError } diff --git a/zio-schema/shared/src/test/scala/zio/schema/SchemaAssertions.scala b/zio-schema/shared/src/test/scala/zio/schema/SchemaAssertions.scala index 2b08c63b5..ff91088a7 100644 --- a/zio-schema/shared/src/test/scala/zio/schema/SchemaAssertions.scala +++ b/zio-schema/shared/src/test/scala/zio/schema/SchemaAssertions.scala @@ -7,17 +7,12 @@ object SchemaAssertions { def migratesTo[A: Schema, B: Schema](expected: B): Assertion[A] = Assertion.assertion("migratesTo") { value => - value.migrate[B] match { - case Left(_) => false - case zio.prelude.Validation.succeed(m) if m != expected => false - case _ => - true - } + value.migrate[B].fold(_ => false, _ == expected) } def cannotMigrateValue[A: Schema, B: Schema]: Assertion[A] = Assertion.assertion("cannotMigrateTo") { value => - value.migrate[B].isLeft + value.migrate[B].toEither.isLeft } def hasSameSchema(expected: Schema[_]): Assertion[Schema[_]] = diff --git a/zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberValidationSpec.scala b/zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberSchemaValidationSpec$.scala similarity index 57% rename from zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberValidationSpec.scala rename to zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberSchemaValidationSpec$.scala index eed95ec3e..927090ef2 100644 --- a/zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberValidationSpec.scala +++ b/zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberSchemaValidationSpec$.scala @@ -2,1330 +2,1330 @@ package zio.schema.validation import zio.Scope import zio.test._ -object PhoneNumberValidationSpec extends ZIOSpecDefault { +object PhoneNumberSchemaValidationSpec$ extends ZIOSpecDefault { def spec: Spec[Environment with TestEnvironment with Scope, Any] = suite("PhoneNumberValidationSpec")( test("Regex phone number validation for Ascension Island") { val validation = PhoneNumberValidation.phoneNumberAC - assertTrue(validation.validate("+247 007 897 156").isRight) + assertTrue(validation.validate("+247 007 897 156").toEither.isRight) }, test("Regex phone number validation for Andorra") { val validation = PhoneNumberValidation.phoneNumberAD - assertTrue(validation.validate("+376 9587541843").isRight) + assertTrue(validation.validate("+376 9587541843").toEither.isRight) }, test("Regex phone number validation for United Arab Emirates") { val validation = PhoneNumberValidation.phoneNumberAE - assertTrue(validation.validate("00 971 0 362744241").isRight) + assertTrue(validation.validate("00 971 0 362744241").toEither.isRight) }, test("Regex phone number validation for Afghanistan") { val validation = PhoneNumberValidation.phoneNumberAF - assertTrue(validation.validate("00 93 0 157218486").isRight) + assertTrue(validation.validate("00 93 0 157218486").toEither.isRight) }, test("Regex phone number validation for Antigua and Barbuda") { val validation = PhoneNumberValidation.phoneNumberAG - assertTrue(validation.validate("011 1 268 612 6402").isRight) + assertTrue(validation.validate("011 1 268 612 6402").toEither.isRight) }, test("Regex phone number validation for Anguilla") { val validation = PhoneNumberValidation.phoneNumberAI - assertTrue(validation.validate("011 1 264 957 0153").isRight) + assertTrue(validation.validate("011 1 264 957 0153").toEither.isRight) }, test("Regex phone number validation for Albania") { val validation = PhoneNumberValidation.phoneNumberAL - assertTrue(validation.validate("+ 355 0747518589").isRight) + assertTrue(validation.validate("+ 355 0747518589").toEither.isRight) }, test("Regex phone number validation for Armenia") { val validation = PhoneNumberValidation.phoneNumberAM - assertTrue(validation.validate("00 374 0756680505").isRight) + assertTrue(validation.validate("00 374 0756680505").toEither.isRight) }, test("Regex phone number validation for Netherlands Antilles") { val validation = PhoneNumberValidation.phoneNumberAN - assertTrue(validation.validate("00 5996053610108").isRight) + assertTrue(validation.validate("00 5996053610108").toEither.isRight) }, test("Regex phone number validation for Angola") { val validation = PhoneNumberValidation.phoneNumberAO - assertTrue(validation.validate("00 2442385294120").isRight) + assertTrue(validation.validate("00 2442385294120").toEither.isRight) }, test("Regex phone number validation for Antarctica") { val validation = PhoneNumberValidation.phoneNumberAQ - assertTrue(validation.validate("00 6720645145061").isRight) + assertTrue(validation.validate("00 6720645145061").toEither.isRight) }, test("Regex phone number validation for Argentina") { val validation = PhoneNumberValidation.phoneNumberAR - assertTrue(validation.validate("+54 90 2883 6466").isRight) + assertTrue(validation.validate("+54 90 2883 6466").toEither.isRight) }, test("Regex phone number validation for American Samoa") { val validation = PhoneNumberValidation.phoneNumberAS - assertTrue(validation.validate("011 1 684 262 8882").isRight) + assertTrue(validation.validate("011 1 684 262 8882").toEither.isRight) }, test("Regex phone number validation for Austria") { val validation = PhoneNumberValidation.phoneNumberAT - assertTrue(validation.validate("+43 75 7429 2998").isRight) + assertTrue(validation.validate("+43 75 7429 2998").toEither.isRight) }, test("Regex phone number validation for Australia") { val validation = PhoneNumberValidation.phoneNumberAU - assertTrue(validation.validate("0011 61 2 8238 5964").isRight) + assertTrue(validation.validate("0011 61 2 8238 5964").toEither.isRight) }, test("Regex phone number validation for Aruba") { val validation = PhoneNumberValidation.phoneNumberAW - assertTrue(validation.validate("00 2979763865107").isRight) + assertTrue(validation.validate("00 2979763865107").toEither.isRight) }, test("Regex phone number validation for Aland Islands") { val validation = PhoneNumberValidation.phoneNumberAX - assertTrue(validation.validate("+358 18 6919660").isRight) + assertTrue(validation.validate("+358 18 6919660").toEither.isRight) }, test("Regex phone number validation for Azerbaijan") { val validation = PhoneNumberValidation.phoneNumberAZ - assertTrue(validation.validate("+994 6152139308").isRight) + assertTrue(validation.validate("+994 6152139308").toEither.isRight) }, test("Regex phone number validation for Bosnia and Herzegovina") { val validation = PhoneNumberValidation.phoneNumberBA - assertTrue(validation.validate("+387 4089348656").isRight) + assertTrue(validation.validate("+387 4089348656").toEither.isRight) }, test("Regex phone number validation for Barbados") { val validation = PhoneNumberValidation.phoneNumberBB - assertTrue(validation.validate("011 1 246 990 0727").isRight) + assertTrue(validation.validate("011 1 246 990 0727").toEither.isRight) }, test("Regex phone number validation for Bangladesh") { val validation = PhoneNumberValidation.phoneNumberBD - assertTrue(validation.validate("+880 7320198614").isRight) + assertTrue(validation.validate("+880 7320198614").toEither.isRight) }, test("Regex phone number validation for Belgium") { val validation = PhoneNumberValidation.phoneNumberBE - assertTrue(validation.validate("+32 8965598550").isRight) + assertTrue(validation.validate("+32 8965598550").toEither.isRight) }, test("Regex phone number validation for Burkina Faso") { val validation = PhoneNumberValidation.phoneNumberBF - assertTrue(validation.validate("00 2267355948208").isRight) + assertTrue(validation.validate("00 2267355948208").toEither.isRight) }, test("Regex phone number validation for Bulgaria") { val validation = PhoneNumberValidation.phoneNumberBG - assertTrue(validation.validate("+359 3442692667").isRight) + assertTrue(validation.validate("+359 3442692667").toEither.isRight) }, test("Regex phone number validation for Bahrain") { val validation = PhoneNumberValidation.phoneNumberBH - assertTrue(validation.validate("00 9739488339568").isRight) + assertTrue(validation.validate("00 9739488339568").toEither.isRight) }, test("Regex phone number validation for Burundi") { val validation = PhoneNumberValidation.phoneNumberBI - assertTrue(validation.validate("00 2574280643674").isRight) + assertTrue(validation.validate("00 2574280643674").toEither.isRight) }, test("Regex phone number validation for Benin") { val validation = PhoneNumberValidation.phoneNumberBJ - assertTrue(validation.validate("00 2298643095311").isRight) + assertTrue(validation.validate("00 2298643095311").toEither.isRight) }, test("Regex phone number validation for Saint-Barthelemy") { val validation = PhoneNumberValidation.phoneNumberBL - assertTrue(validation.validate("+590 6941370797").isRight) + assertTrue(validation.validate("+590 6941370797").toEither.isRight) }, test("Regex phone number validation for Bermuda") { val validation = PhoneNumberValidation.phoneNumberBM - assertTrue(validation.validate("011 1 441 5849940").isRight) + assertTrue(validation.validate("011 1 441 5849940").toEither.isRight) }, test("Regex phone number validation for Brunei Darussalam") { val validation = PhoneNumberValidation.phoneNumberBN - assertTrue(validation.validate("00 6736806811588").isRight) + assertTrue(validation.validate("00 6736806811588").toEither.isRight) }, test("Regex phone number validation for Bolivia") { val validation = PhoneNumberValidation.phoneNumberBO - assertTrue(validation.validate("+591 7962476910").isRight) + assertTrue(validation.validate("+591 7962476910").toEither.isRight) }, test("Regex phone number validation for Caribbean Netherlands") { val validation = PhoneNumberValidation.phoneNumberBQ - assertTrue(validation.validate("00 599 347 0831770").isRight) + assertTrue(validation.validate("00 599 347 0831770").toEither.isRight) }, test("Regex phone number validation for Brazil") { val validation = PhoneNumberValidation.phoneNumberBR - assertTrue(validation.validate("+55 2309750213").isRight) + assertTrue(validation.validate("+55 2309750213").toEither.isRight) }, test("Regex phone number validation for Bahamas") { val validation = PhoneNumberValidation.phoneNumberBS - assertTrue(validation.validate("011 1 242 6083082").isRight) + assertTrue(validation.validate("011 1 242 6083082").toEither.isRight) }, test("Regex phone number validation for Bhutan") { val validation = PhoneNumberValidation.phoneNumberBT - assertTrue(validation.validate("00 9756295499608").isRight) + assertTrue(validation.validate("00 9756295499608").toEither.isRight) }, test("Regex phone number validation for Bouvet Island") { val validation = PhoneNumberValidation.phoneNumberBV - assertTrue(validation.validate("00 474251138559").isRight) + assertTrue(validation.validate("00 474251138559").toEither.isRight) }, test("Regex phone number validation for Botswana") { val validation = PhoneNumberValidation.phoneNumberBW - assertTrue(validation.validate("00 2671639040488").isRight) + assertTrue(validation.validate("00 2671639040488").toEither.isRight) }, test("Regex phone number validation for Belarus") { val validation = PhoneNumberValidation.phoneNumberBY - assertTrue(validation.validate("00810 375 376602746").isRight) + assertTrue(validation.validate("00810 375 376602746").toEither.isRight) }, test("Regex phone number validation for Belize") { val validation = PhoneNumberValidation.phoneNumberBZ - assertTrue(validation.validate("00 5010929861925").isRight) + assertTrue(validation.validate("00 5010929861925").toEither.isRight) }, test("Regex phone number validation for Canada") { val validation = PhoneNumberValidation.phoneNumberCA - assertTrue(validation.validate("011 1 3665464257").isRight) + assertTrue(validation.validate("011 1 3665464257").toEither.isRight) }, test("Regex phone number validation for Cocos (Keeling) Islands") { val validation = PhoneNumberValidation.phoneNumberCC - assertTrue(validation.validate("0011 61 963775620").isRight) + assertTrue(validation.validate("0011 61 963775620").toEither.isRight) }, test("Regex phone number validation for Congo, (Kinshasa)") { val validation = PhoneNumberValidation.phoneNumberCD - assertTrue(validation.validate("00 243 9494344055").isRight) + assertTrue(validation.validate("00 243 9494344055").toEither.isRight) }, test("Regex phone number validation for Central African Republic") { val validation = PhoneNumberValidation.phoneNumberCF - assertTrue(validation.validate("+236 59 6075 5901").isRight) + assertTrue(validation.validate("+236 59 6075 5901").toEither.isRight) }, test("Regex phone number validation for Congo (Brazzaville)") { val validation = PhoneNumberValidation.phoneNumberCG - assertTrue(validation.validate("00 24283 8219 9231").isRight) + assertTrue(validation.validate("00 24283 8219 9231").toEither.isRight) }, test("Regex phone number validation for Switzerland") { val validation = PhoneNumberValidation.phoneNumberCH - assertTrue(validation.validate("+41 62 9504 5752").isRight) - assertTrue(validation.validate("0041791234567").isRight) && - assertTrue(validation.validate("0041 79 123 45 67").isRight) && - assertTrue(validation.validate("+41791234567").isRight) && - assertTrue(validation.validate("+41 79 123 45 67").isRight) && - assertTrue(validation.validate("0791234567").isRight) && - assertTrue(validation.validate("-41 79 123 45 67").isLeft) && - assertTrue(validation.validate("+41 79 123 45 678").isLeft) && - assertTrue(validation.validate("79 123 45 678").isLeft) + assertTrue(validation.validate("+41 62 9504 5752").toEither.isRight) + assertTrue(validation.validate("0041791234567").toEither.isRight) && + assertTrue(validation.validate("0041 79 123 45 67").toEither.isRight) && + assertTrue(validation.validate("+41791234567").toEither.isRight) && + assertTrue(validation.validate("+41 79 123 45 67").toEither.isRight) && + assertTrue(validation.validate("0791234567").toEither.isRight) && + assertTrue(validation.validate("-41 79 123 45 67").toEither.isLeft) && + assertTrue(validation.validate("+41 79 123 45 678").toEither.isLeft) && + assertTrue(validation.validate("79 123 45 678").toEither.isLeft) }, test("Regex phone number validation for Côte d'Ivoire") { val validation = PhoneNumberValidation.phoneNumberCI - assertTrue(validation.validate("00 2256102971096").isRight) + assertTrue(validation.validate("00 2256102971096").toEither.isRight) }, test("Regex phone number validation for Cook Islands") { val validation = PhoneNumberValidation.phoneNumberCK - assertTrue(validation.validate("00 6829326903969").isRight) + assertTrue(validation.validate("00 6829326903969").toEither.isRight) }, test("Regex phone number validation for Chile") { val validation = PhoneNumberValidation.phoneNumberCL - assertTrue(validation.validate("00 565768733529").isRight) + assertTrue(validation.validate("00 565768733529").toEither.isRight) }, test("Regex phone number validation for Cameroon") { val validation = PhoneNumberValidation.phoneNumberCM - assertTrue(validation.validate("00 2379601725044").isRight) + assertTrue(validation.validate("00 2379601725044").toEither.isRight) }, test("Regex phone number validation for China") { val validation = PhoneNumberValidation.phoneNumberCN - assertTrue(validation.validate("00 86 6313884064").isRight) + assertTrue(validation.validate("00 86 6313884064").toEither.isRight) }, test("Regex phone number validation for Colombia") { val validation = PhoneNumberValidation.phoneNumberCO - assertTrue(validation.validate("00 57 5035525009").isRight) + assertTrue(validation.validate("00 57 5035525009").toEither.isRight) }, test("Regex phone number validation for Costa Rica") { val validation = PhoneNumberValidation.phoneNumberCR - assertTrue(validation.validate("+506 2608425852").isRight) + assertTrue(validation.validate("+506 2608425852").toEither.isRight) }, test("Regex phone number validation for Cuba") { val validation = PhoneNumberValidation.phoneNumberCU - assertTrue(validation.validate("119 53 8684721023").isRight) + assertTrue(validation.validate("119 53 8684721023").toEither.isRight) }, test("Regex phone number validation for Cape Verde") { val validation = PhoneNumberValidation.phoneNumberCV - assertTrue(validation.validate("+238 54 1914 6255").isRight) + assertTrue(validation.validate("+238 54 1914 6255").toEither.isRight) }, test("Regex phone number validation for Curacao") { val validation = PhoneNumberValidation.phoneNumberCW - assertTrue(validation.validate("+599 69 9206 6789").isRight) + assertTrue(validation.validate("+599 69 9206 6789").toEither.isRight) }, test("Regex phone number validation for Christmas Island") { val validation = PhoneNumberValidation.phoneNumberCX - assertTrue(validation.validate("0011 61 8606709622").isRight) + assertTrue(validation.validate("0011 61 8606709622").toEither.isRight) }, test("Regex phone number validation for Cyprus") { val validation = PhoneNumberValidation.phoneNumberCY - assertTrue(validation.validate("00 3570126511197").isRight) + assertTrue(validation.validate("00 3570126511197").toEither.isRight) }, test("Regex phone number validation for Czech Republic") { val validation = PhoneNumberValidation.phoneNumberCZ - assertTrue(validation.validate("00 4209207508015").isRight) + assertTrue(validation.validate("00 4209207508015").toEither.isRight) }, test("Regex phone number validation for Germany") { val validation = PhoneNumberValidation.phoneNumberDE - assertTrue(validation.validate("00 49 8591548021").isRight) - assertTrue(validation.validate("+49 30 901820").isRight) && - assertTrue(validation.validate("004930901820").isRight) && - assertTrue(validation.validate("030901820").isRight) && - assertTrue(validation.validate("030 901820").isRight) && - assertTrue(validation.validate("+49 1522 343333").isRight) && - assertTrue(validation.validate("+49 152 901820").isRight) && - assertTrue(validation.validate("0049 152 901820").isRight) && - assertTrue(validation.validate("0041 30 901820").isLeft) && - assertTrue(validation.validate("49 152 901820").isLeft) && - assertTrue(validation.validate("049 152 901820").isLeft) + assertTrue(validation.validate("00 49 8591548021").toEither.isRight) + assertTrue(validation.validate("+49 30 901820").toEither.isRight) && + assertTrue(validation.validate("004930901820").toEither.isRight) && + assertTrue(validation.validate("030901820").toEither.isRight) && + assertTrue(validation.validate("030 901820").toEither.isRight) && + assertTrue(validation.validate("+49 1522 343333").toEither.isRight) && + assertTrue(validation.validate("+49 152 901820").toEither.isRight) && + assertTrue(validation.validate("0049 152 901820").toEither.isRight) && + assertTrue(validation.validate("0041 30 901820").toEither.isLeft) && + assertTrue(validation.validate("49 152 901820").toEither.isLeft) && + assertTrue(validation.validate("049 152 901820").toEither.isLeft) }, test("Regex phone number validation for Djibouti") { val validation = PhoneNumberValidation.phoneNumberDJ - assertTrue(validation.validate("00 2539228818387").isRight) + assertTrue(validation.validate("00 2539228818387").toEither.isRight) }, test("Regex phone number validation for Denmark") { val validation = PhoneNumberValidation.phoneNumberDK - assertTrue(validation.validate("00 450829342925").isRight) + assertTrue(validation.validate("00 450829342925").toEither.isRight) }, test("Regex phone number validation for Dominica") { val validation = PhoneNumberValidation.phoneNumberDM - assertTrue(validation.validate("011 1 767 117 934").isRight) + assertTrue(validation.validate("011 1 767 117 934").toEither.isRight) }, test("Regex phone number validation for Dominican Republic") { val validation = PhoneNumberValidation.phoneNumberDO - assertTrue(validation.validate("011 1 8001 026250").isRight) + assertTrue(validation.validate("011 1 8001 026250").toEither.isRight) }, test("Regex phone number validation for Algeria") { val validation = PhoneNumberValidation.phoneNumberDZ - assertTrue(validation.validate("00 213 1519404947").isRight) + assertTrue(validation.validate("00 213 1519404947").toEither.isRight) }, test("Regex phone number validation for Ecuador") { val validation = PhoneNumberValidation.phoneNumberEC - assertTrue(validation.validate("00 593 7661327173").isRight) + assertTrue(validation.validate("00 593 7661327173").toEither.isRight) }, test("Regex phone number validation for Estonia") { val validation = PhoneNumberValidation.phoneNumberEE - assertTrue(validation.validate("00 3727289832181").isRight) + assertTrue(validation.validate("00 3727289832181").toEither.isRight) }, test("Regex phone number validation for Egypt") { val validation = PhoneNumberValidation.phoneNumberEG - assertTrue(validation.validate("00 20 3371313171").isRight) + assertTrue(validation.validate("00 20 3371313171").toEither.isRight) }, test("Regex phone number validation for Western Sahara") { val validation = PhoneNumberValidation.phoneNumberEH - assertTrue(validation.validate("00 212 528 7355097").isRight) + assertTrue(validation.validate("00 212 528 7355097").toEither.isRight) }, test("Regex phone number validation for Eritrea") { val validation = PhoneNumberValidation.phoneNumberER - assertTrue(validation.validate("00 291 1389368590").isRight) + assertTrue(validation.validate("00 291 1389368590").toEither.isRight) }, test("Regex phone number validation for Spain") { val validation = PhoneNumberValidation.phoneNumberES - assertTrue(validation.validate("00 345499372300").isRight) + assertTrue(validation.validate("00 345499372300").toEither.isRight) }, test("Regex phone number validation for Ethiopia") { val validation = PhoneNumberValidation.phoneNumberET - assertTrue(validation.validate("00 251 9034175157").isRight) + assertTrue(validation.validate("00 251 9034175157").toEither.isRight) }, test("Regex phone number validation for Finland") { val validation = PhoneNumberValidation.phoneNumberFI - assertTrue(validation.validate("+358 1 20 504 1325").isRight) + assertTrue(validation.validate("+358 1 20 504 1325").toEither.isRight) }, test("Regex phone number validation for Fiji") { val validation = PhoneNumberValidation.phoneNumberFJ - assertTrue(validation.validate("00 6792349653587").isRight) + assertTrue(validation.validate("00 6792349653587").toEither.isRight) }, test("Regex phone number validation for Falkland Islands (Malvinas)") { val validation = PhoneNumberValidation.phoneNumberFK - assertTrue(validation.validate("00 5004003005535").isRight) + assertTrue(validation.validate("00 5004003005535").toEither.isRight) }, test("Regex phone number validation for Micronesia, Federated States of") { val validation = PhoneNumberValidation.phoneNumberFM - assertTrue(validation.validate("00 6918410093532").isRight) + assertTrue(validation.validate("00 6918410093532").toEither.isRight) }, test("Regex phone number validation for Faroe Islands") { val validation = PhoneNumberValidation.phoneNumberFO - assertTrue(validation.validate("00 298 5560667813").isRight) + assertTrue(validation.validate("00 298 5560667813").toEither.isRight) }, test("Regex phone number validation for France") { val validation = PhoneNumberValidation.phoneNumberFR - assertTrue(validation.validate("00 33 13 3901 4277").isRight) + assertTrue(validation.validate("00 33 13 3901 4277").toEither.isRight) }, test("Regex phone number validation for Gabon") { val validation = PhoneNumberValidation.phoneNumberGA - assertTrue(validation.validate("00 241 97 2596 5544").isRight) + assertTrue(validation.validate("00 241 97 2596 5544").toEither.isRight) }, test("Regex phone number validation for United Kingdom") { val validation = PhoneNumberValidation.phoneNumberGB - assertTrue(validation.validate("+44 94 2730 0927").isRight) + assertTrue(validation.validate("+44 94 2730 0927").toEither.isRight) }, test("Regex phone number validation for Grenada") { val validation = PhoneNumberValidation.phoneNumberGD - assertTrue(validation.validate("011 1 473 0027293").isRight) + assertTrue(validation.validate("011 1 473 0027293").toEither.isRight) }, test("Regex phone number validation for Georgia") { val validation = PhoneNumberValidation.phoneNumberGE - assertTrue(validation.validate("+995 40 9347 1630").isRight) + assertTrue(validation.validate("+995 40 9347 1630").toEither.isRight) }, test("Regex phone number validation for French Guiana") { val validation = PhoneNumberValidation.phoneNumberGF - assertTrue(validation.validate("+594 18 821 2131").isRight) + assertTrue(validation.validate("+594 18 821 2131").toEither.isRight) }, test("Regex phone number validation for Guernsey") { val validation = PhoneNumberValidation.phoneNumberGG - assertTrue(validation.validate("00 44 37 9295 8099").isRight) + assertTrue(validation.validate("00 44 37 9295 8099").toEither.isRight) }, test("Regex phone number validation for Ghana") { val validation = PhoneNumberValidation.phoneNumberGH - assertTrue(validation.validate("+233 18 4682 1216").isRight) + assertTrue(validation.validate("+233 18 4682 1216").toEither.isRight) }, test("Regex phone number validation for Gibraltar") { val validation = PhoneNumberValidation.phoneNumberGI - assertTrue(validation.validate("00 3508527907652").isRight) + assertTrue(validation.validate("00 3508527907652").toEither.isRight) }, test("Regex phone number validation for Greenland") { val validation = PhoneNumberValidation.phoneNumberGL - assertTrue(validation.validate("00 2996975320055").isRight) + assertTrue(validation.validate("00 2996975320055").toEither.isRight) }, test("Regex phone number validation for Gambia") { val validation = PhoneNumberValidation.phoneNumberGM - assertTrue(validation.validate("00 2208600678245").isRight) + assertTrue(validation.validate("00 2208600678245").toEither.isRight) }, test("Regex phone number validation for Guinea") { val validation = PhoneNumberValidation.phoneNumberGN - assertTrue(validation.validate("00 2246345663760").isRight) + assertTrue(validation.validate("00 2246345663760").toEither.isRight) }, test("Regex phone number validation for Guadeloupe") { val validation = PhoneNumberValidation.phoneNumberGP - assertTrue(validation.validate("00 590 15 1203 0997").isRight) + assertTrue(validation.validate("00 590 15 1203 0997").toEither.isRight) }, test("Regex phone number validation for Equatorial Guinea") { val validation = PhoneNumberValidation.phoneNumberGQ - assertTrue(validation.validate("00 2408656400449").isRight) + assertTrue(validation.validate("00 2408656400449").toEither.isRight) }, test("Regex phone number validation for Greece") { val validation = PhoneNumberValidation.phoneNumberGR - assertTrue(validation.validate("00 305729313542").isRight) + assertTrue(validation.validate("00 305729313542").toEither.isRight) }, test("Regex phone number validation for South Sandwich Islands") { val validation = PhoneNumberValidation.phoneNumberGS - assertTrue(validation.validate("00 5003096544376").isRight) + assertTrue(validation.validate("00 5003096544376").toEither.isRight) }, test("Regex phone number validation for Guatemala") { val validation = PhoneNumberValidation.phoneNumberGT - assertTrue(validation.validate("00 5029817333325").isRight) + assertTrue(validation.validate("00 5029817333325").toEither.isRight) }, test("Regex phone number validation for Guam") { val validation = PhoneNumberValidation.phoneNumberGU - assertTrue(validation.validate("011 1 671 5507500").isRight) + assertTrue(validation.validate("011 1 671 5507500").toEither.isRight) }, test("Regex phone number validation for Guinea-Bissau") { val validation = PhoneNumberValidation.phoneNumberGW - assertTrue(validation.validate("00001 245 72 3061 6510").isRight) + assertTrue(validation.validate("00001 245 72 3061 6510").toEither.isRight) }, test("Regex phone number validation for Guyana") { val validation = PhoneNumberValidation.phoneNumberGY - assertTrue(validation.validate("001 5923161184154").isRight) + assertTrue(validation.validate("001 5923161184154").toEither.isRight) }, test("Regex phone number validation for Hong Kong") { val validation = PhoneNumberValidation.phoneNumberHK - assertTrue(validation.validate("00 8521317558295").isRight) + assertTrue(validation.validate("00 8521317558295").toEither.isRight) }, test("Regex phone number validation for Heard and Mcdonald Islands") { val validation = PhoneNumberValidation.phoneNumberHM - assertTrue(validation.validate("00 6723191710825").isRight) + assertTrue(validation.validate("00 6723191710825").toEither.isRight) }, test("Regex phone number validation for Honduras") { val validation = PhoneNumberValidation.phoneNumberHN - assertTrue(validation.validate("00 5047371910554").isRight) + assertTrue(validation.validate("00 5047371910554").toEither.isRight) }, test("Regex phone number validation for Croatia") { val validation = PhoneNumberValidation.phoneNumberHR - assertTrue(validation.validate("00 385 52 1194 4850").isRight) + assertTrue(validation.validate("00 385 52 1194 4850").toEither.isRight) }, test("Regex phone number validation for Haiti") { val validation = PhoneNumberValidation.phoneNumberHT - assertTrue(validation.validate("00 5092551395589").isRight) + assertTrue(validation.validate("00 5092551395589").toEither.isRight) }, test("Regex phone number validation for Hungary") { val validation = PhoneNumberValidation.phoneNumberHU - assertTrue(validation.validate("+36 18 925 2015").isRight) - assertTrue(validation.validate("003612318855").isRight) && - assertTrue(validation.validate("0036 1 231 88 55").isRight) && - assertTrue(validation.validate("0036 1 231 8855").isRight) && - assertTrue(validation.validate("+3611234567").isRight) && - assertTrue(validation.validate("+36 1 123 45 67").isRight) && - assertTrue(validation.validate("+36 1 123 4567").isRight) && - assertTrue(validation.validate("0611234567").isRight) && - assertTrue(validation.validate("0036-30-231-88-55").isRight) && - assertTrue(validation.validate("0036-30-231-8855").isRight) && - assertTrue(validation.validate("+36301234567").isRight) && - assertTrue(validation.validate("+36-30-123-45-67").isRight) && - assertTrue(validation.validate("+36-30-123-4567").isRight) && - assertTrue(validation.validate("06301234567").isRight) && - assertTrue(validation.validate("+36 11 123 45 67").isRight) && - assertTrue(validation.validate("+36 5 123 45 67").isRight) && - assertTrue(validation.validate("+36 1 123 45 678").isRight) && - assertTrue(validation.validate("-36 1 123 45 67").isLeft) && - assertTrue(validation.validate("1 123 45 678").isLeft) && - assertTrue(validation.validate("-36-30-123-45-67").isLeft) && - assertTrue(validation.validate("+36-30-123-45-678").isLeft) && - assertTrue(validation.validate("30-123-45-678").isLeft) + assertTrue(validation.validate("+36 18 925 2015").toEither.isRight) + assertTrue(validation.validate("003612318855").toEither.isRight) && + assertTrue(validation.validate("0036 1 231 88 55").toEither.isRight) && + assertTrue(validation.validate("0036 1 231 8855").toEither.isRight) && + assertTrue(validation.validate("+3611234567").toEither.isRight) && + assertTrue(validation.validate("+36 1 123 45 67").toEither.isRight) && + assertTrue(validation.validate("+36 1 123 4567").toEither.isRight) && + assertTrue(validation.validate("0611234567").toEither.isRight) && + assertTrue(validation.validate("0036-30-231-88-55").toEither.isRight) && + assertTrue(validation.validate("0036-30-231-8855").toEither.isRight) && + assertTrue(validation.validate("+36301234567").toEither.isRight) && + assertTrue(validation.validate("+36-30-123-45-67").toEither.isRight) && + assertTrue(validation.validate("+36-30-123-4567").toEither.isRight) && + assertTrue(validation.validate("06301234567").toEither.isRight) && + assertTrue(validation.validate("+36 11 123 45 67").toEither.isRight) && + assertTrue(validation.validate("+36 5 123 45 67").toEither.isRight) && + assertTrue(validation.validate("+36 1 123 45 678").toEither.isRight) && + assertTrue(validation.validate("-36 1 123 45 67").toEither.isLeft) && + assertTrue(validation.validate("1 123 45 678").toEither.isLeft) && + assertTrue(validation.validate("-36-30-123-45-67").toEither.isLeft) && + assertTrue(validation.validate("+36-30-123-45-678").toEither.isLeft) && + assertTrue(validation.validate("30-123-45-678").toEither.isLeft) }, test("Regex phone number validation for Indonesia") { val validation = PhoneNumberValidation.phoneNumberID - assertTrue(validation.validate("+62 69 5257 3582").isRight) + assertTrue(validation.validate("+62 69 5257 3582").toEither.isRight) }, test("Regex phone number validation for Ireland") { val validation = PhoneNumberValidation.phoneNumberIE - assertTrue(validation.validate("+353 82 9286 4067").isRight) + assertTrue(validation.validate("+353 82 9286 4067").toEither.isRight) }, test("Regex phone number validation for Israel") { val validation = PhoneNumberValidation.phoneNumberIL - assertTrue(validation.validate("01 972 60 8248 1948").isRight) + assertTrue(validation.validate("01 972 60 8248 1948").toEither.isRight) }, test("Regex phone number validation for Isle of Man") { val validation = PhoneNumberValidation.phoneNumberIM - assertTrue(validation.validate("+44 74576 49 709").isRight) + assertTrue(validation.validate("+44 74576 49 709").toEither.isRight) }, test("Regex phone number validation for India") { val validation = PhoneNumberValidation.phoneNumberIN - assertTrue(validation.validate("00 91 90 3412 7804").isRight) + assertTrue(validation.validate("00 91 90 3412 7804").toEither.isRight) }, test("Regex phone number validation for British Indian Ocean Territory") { val validation = PhoneNumberValidation.phoneNumberIO - assertTrue(validation.validate("00 2462992060814").isRight) + assertTrue(validation.validate("00 2462992060814").toEither.isRight) }, test("Regex phone number validation for Iraq") { val validation = PhoneNumberValidation.phoneNumberIQ - assertTrue(validation.validate("+964 257 4565 059").isRight) + assertTrue(validation.validate("+964 257 4565 059").toEither.isRight) }, test("Regex phone number validation for Iran") { val validation = PhoneNumberValidation.phoneNumberIR - assertTrue(validation.validate("00 98 19 3019 1031").isRight) + assertTrue(validation.validate("00 98 19 3019 1031").toEither.isRight) }, test("Regex phone number validation for Iceland") { val validation = PhoneNumberValidation.phoneNumberIS - assertTrue(validation.validate("00 3541289658929").isRight) + assertTrue(validation.validate("00 3541289658929").toEither.isRight) }, test("Regex phone number validation for Italy") { val validation = PhoneNumberValidation.phoneNumberIT - assertTrue(validation.validate("00 393878141457").isRight) + assertTrue(validation.validate("00 393878141457").toEither.isRight) }, test("Regex phone number validation for Jersey") { val validation = PhoneNumberValidation.phoneNumberJE - assertTrue(validation.validate("+44 57 9972 9605").isRight) + assertTrue(validation.validate("+44 57 9972 9605").toEither.isRight) }, test("Regex phone number validation for Jamaica") { val validation = PhoneNumberValidation.phoneNumberJM - assertTrue(validation.validate("011 1 658 1150558").isRight) + assertTrue(validation.validate("011 1 658 1150558").toEither.isRight) }, test("Regex phone number validation for Jordan") { val validation = PhoneNumberValidation.phoneNumberJO - assertTrue(validation.validate("00 962 84 4532 6108").isRight) + assertTrue(validation.validate("00 962 84 4532 6108").toEither.isRight) }, test("Regex phone number validation for Japan") { val validation = PhoneNumberValidation.phoneNumberJP - assertTrue(validation.validate("010 81 20 4493 0924").isRight) + assertTrue(validation.validate("010 81 20 4493 0924").toEither.isRight) }, test("Regex phone number validation for Kenya") { val validation = PhoneNumberValidation.phoneNumberKE - assertTrue(validation.validate("000 254 48 5947 4534").isRight) + assertTrue(validation.validate("000 254 48 5947 4534").toEither.isRight) }, test("Regex phone number validation for Kyrgyzstan") { val validation = PhoneNumberValidation.phoneNumberKG - assertTrue(validation.validate("+996 16 6735 9115").isRight) + assertTrue(validation.validate("+996 16 6735 9115").toEither.isRight) }, test("Regex phone number validation for Cambodia") { val validation = PhoneNumberValidation.phoneNumberKH - assertTrue(validation.validate("+855 43 4519 9326").isRight) + assertTrue(validation.validate("+855 43 4519 9326").toEither.isRight) }, test("Regex phone number validation for Kiribati") { val validation = PhoneNumberValidation.phoneNumberKI - assertTrue(validation.validate("+686 77 5928 5264").isRight) + assertTrue(validation.validate("+686 77 5928 5264").toEither.isRight) }, test("Regex phone number validation for Comoros") { val validation = PhoneNumberValidation.phoneNumberKM - assertTrue(validation.validate("00 2698571387031").isRight) + assertTrue(validation.validate("00 2698571387031").toEither.isRight) }, test("Regex phone number validation for Saint Kitts and Nevis") { val validation = PhoneNumberValidation.phoneNumberKN - assertTrue(validation.validate("011 1 869 6539479").isRight) + assertTrue(validation.validate("011 1 869 6539479").toEither.isRight) }, test("Regex phone number validation for North Korea") { val validation = PhoneNumberValidation.phoneNumberKP - assertTrue(validation.validate("99 850 17 0277 0657").isRight) + assertTrue(validation.validate("99 850 17 0277 0657").toEither.isRight) }, test("Regex phone number validation for South Korea") { val validation = PhoneNumberValidation.phoneNumberKR - assertTrue(validation.validate("+82 9649592789").isRight) + assertTrue(validation.validate("+82 9649592789").toEither.isRight) }, test("Regex phone number validation for Kuwait") { val validation = PhoneNumberValidation.phoneNumberKW - assertTrue(validation.validate("+965 28 5107 9046").isRight) + assertTrue(validation.validate("+965 28 5107 9046").toEither.isRight) }, test("Regex phone number validation for Cayman Islands") { val validation = PhoneNumberValidation.phoneNumberKY - assertTrue(validation.validate("011 1 345 0106523").isRight) + assertTrue(validation.validate("011 1 345 0106523").toEither.isRight) }, test("Regex phone number validation for Kazakhstan") { val validation = PhoneNumberValidation.phoneNumberKZ - assertTrue(validation.validate("00810 7 33 1450 8219").isRight) + assertTrue(validation.validate("00810 7 33 1450 8219").toEither.isRight) }, test("Regex phone number validation for Lao PDR") { val validation = PhoneNumberValidation.phoneNumberLA - assertTrue(validation.validate("00 856 5368127779").isRight) + assertTrue(validation.validate("00 856 5368127779").toEither.isRight) }, test("Regex phone number validation for Lebanon") { val validation = PhoneNumberValidation.phoneNumberLB - assertTrue(validation.validate("+961 3652044279").isRight) + assertTrue(validation.validate("+961 3652044279").toEither.isRight) }, test("Regex phone number validation for Saint Lucia") { val validation = PhoneNumberValidation.phoneNumberLC - assertTrue(validation.validate("011 1 758 0471732").isRight) + assertTrue(validation.validate("011 1 758 0471732").toEither.isRight) }, test("Regex phone number validation for Liechtenstein") { val validation = PhoneNumberValidation.phoneNumberLI - assertTrue(validation.validate("00 423 6420715797").isRight) + assertTrue(validation.validate("00 423 6420715797").toEither.isRight) }, test("Regex phone number validation for Sri Lanka") { val validation = PhoneNumberValidation.phoneNumberLK - assertTrue(validation.validate("00 94 1935386465").isRight) + assertTrue(validation.validate("00 94 1935386465").toEither.isRight) }, test("Regex phone number validation for Liberia") { val validation = PhoneNumberValidation.phoneNumberLR - assertTrue(validation.validate("00 231 6596099981").isRight) + assertTrue(validation.validate("00 231 6596099981").toEither.isRight) }, test("Regex phone number validation for Lesotho") { val validation = PhoneNumberValidation.phoneNumberLS - assertTrue(validation.validate("00 2662854967720").isRight) + assertTrue(validation.validate("00 2662854967720").toEither.isRight) }, test("Regex phone number validation for Lithuania") { val validation = PhoneNumberValidation.phoneNumberLT - assertTrue(validation.validate("00 370 1974024335").isRight) + assertTrue(validation.validate("00 370 1974024335").toEither.isRight) }, test("Regex phone number validation for Luxembourg") { val validation = PhoneNumberValidation.phoneNumberLU - assertTrue(validation.validate("00 3523 505709778").isRight) + assertTrue(validation.validate("00 3523 505709778").toEither.isRight) }, test("Regex phone number validation for Latvia") { val validation = PhoneNumberValidation.phoneNumberLV - assertTrue(validation.validate("00 3712161145531").isRight) + assertTrue(validation.validate("00 3712161145531").toEither.isRight) }, test("Regex phone number validation for Libya") { val validation = PhoneNumberValidation.phoneNumberLY - assertTrue(validation.validate("00 218 8264419925").isRight) + assertTrue(validation.validate("00 218 8264419925").toEither.isRight) }, test("Regex phone number validation for Morocco") { val validation = PhoneNumberValidation.phoneNumberMA - assertTrue(validation.validate("00 212 3517364769").isRight) + assertTrue(validation.validate("00 212 3517364769").toEither.isRight) }, test("Regex phone number validation for Monaco") { val validation = PhoneNumberValidation.phoneNumberMC - assertTrue(validation.validate("00 377 2021117087").isRight) + assertTrue(validation.validate("00 377 2021117087").toEither.isRight) }, test("Regex phone number validation for Moldova") { val validation = PhoneNumberValidation.phoneNumberMD - assertTrue(validation.validate("00 373 4446201390").isRight) + assertTrue(validation.validate("00 373 4446201390").toEither.isRight) }, test("Regex phone number validation for Montenegro") { val validation = PhoneNumberValidation.phoneNumberME - assertTrue(validation.validate("+382 19 7927 6970").isRight) + assertTrue(validation.validate("+382 19 7927 6970").toEither.isRight) }, test("Regex phone number validation for Saint-Martin (French)") { val validation = PhoneNumberValidation.phoneNumberMF - assertTrue(validation.validate("+590 01 0516 3845").isRight) + assertTrue(validation.validate("+590 01 0516 3845").toEither.isRight) }, test("Regex phone number validation for Madagascar") { val validation = PhoneNumberValidation.phoneNumberMG - assertTrue(validation.validate("+261 353 5945 041").isRight) + assertTrue(validation.validate("+261 353 5945 041").toEither.isRight) }, test("Regex phone number validation for Marshall Islands") { val validation = PhoneNumberValidation.phoneNumberMH - assertTrue(validation.validate("011 692 5127396972").isRight) + assertTrue(validation.validate("011 692 5127396972").toEither.isRight) }, test("Regex phone number validation for Macedonia") { val validation = PhoneNumberValidation.phoneNumberMK - assertTrue(validation.validate("+389 408 929 2478").isRight) + assertTrue(validation.validate("+389 408 929 2478").toEither.isRight) }, test("Regex phone number validation for Mali") { val validation = PhoneNumberValidation.phoneNumberML - assertTrue(validation.validate("00 2233170146268").isRight) + assertTrue(validation.validate("00 2233170146268").toEither.isRight) }, test("Regex phone number validation for Myanmar") { val validation = PhoneNumberValidation.phoneNumberMM - assertTrue(validation.validate("+95 05 8180 4483").isRight) + assertTrue(validation.validate("+95 05 8180 4483").toEither.isRight) }, test("Regex phone number validation for Mongolia") { val validation = PhoneNumberValidation.phoneNumberMN - assertTrue(validation.validate("001 976 15 3640 9604").isRight) + assertTrue(validation.validate("001 976 15 3640 9604").toEither.isRight) }, test("Regex phone number validation for Macao") { val validation = PhoneNumberValidation.phoneNumberMO - assertTrue(validation.validate("00 8531510792742").isRight) + assertTrue(validation.validate("00 8531510792742").toEither.isRight) }, test("Regex phone number validation for Northern Mariana Islands") { val validation = PhoneNumberValidation.phoneNumberMP - assertTrue(validation.validate("011 1 670 893 643").isRight) + assertTrue(validation.validate("011 1 670 893 643").toEither.isRight) }, test("Regex phone number validation for Martinique") { val validation = PhoneNumberValidation.phoneNumberMQ - assertTrue(validation.validate("+596 1932085020").isRight) + assertTrue(validation.validate("+596 1932085020").toEither.isRight) }, test("Regex phone number validation for Mauritania") { val validation = PhoneNumberValidation.phoneNumberMR - assertTrue(validation.validate("+222 54 6048 0691").isRight) + assertTrue(validation.validate("+222 54 6048 0691").toEither.isRight) }, test("Regex phone number validation for Montserrat") { val validation = PhoneNumberValidation.phoneNumberMS - assertTrue(validation.validate("011 1 664 393 4545").isRight) + assertTrue(validation.validate("011 1 664 393 4545").toEither.isRight) }, test("Regex phone number validation for Malta") { val validation = PhoneNumberValidation.phoneNumberMT - assertTrue(validation.validate("00 3565701318096").isRight) + assertTrue(validation.validate("00 3565701318096").toEither.isRight) }, test("Regex phone number validation for Mauritius") { val validation = PhoneNumberValidation.phoneNumberMU - assertTrue(validation.validate("0020 230 12 9500 3440").isRight) + assertTrue(validation.validate("0020 230 12 9500 3440").toEither.isRight) }, test("Regex phone number validation for Maldives") { val validation = PhoneNumberValidation.phoneNumberMV - assertTrue(validation.validate("00 9601707178237").isRight) + assertTrue(validation.validate("00 9601707178237").toEither.isRight) }, test("Regex phone number validation for Malawi") { val validation = PhoneNumberValidation.phoneNumberMW - assertTrue(validation.validate("00 265 4648760757").isRight) + assertTrue(validation.validate("00 265 4648760757").toEither.isRight) }, test("Regex phone number validation for Mexico") { val validation = PhoneNumberValidation.phoneNumberMX - assertTrue(validation.validate("+52 55 1831 3440").isRight) + assertTrue(validation.validate("+52 55 1831 3440").toEither.isRight) }, test("Regex phone number validation for Malaysia") { val validation = PhoneNumberValidation.phoneNumberMY - assertTrue(validation.validate("+60 8189523546").isRight) + assertTrue(validation.validate("+60 8189523546").toEither.isRight) }, test("Regex phone number validation for Mozambique") { val validation = PhoneNumberValidation.phoneNumberMZ - assertTrue(validation.validate("+2589622830508").isRight) + assertTrue(validation.validate("+2589622830508").toEither.isRight) }, test("Regex phone number validation for Namibia") { val validation = PhoneNumberValidation.phoneNumberNA - assertTrue(validation.validate("+264 4876840196").isRight) + assertTrue(validation.validate("+264 4876840196").toEither.isRight) }, test("Regex phone number validation for New Caledonia") { val validation = PhoneNumberValidation.phoneNumberNC - assertTrue(validation.validate("+6872884247049").isRight) + assertTrue(validation.validate("+6872884247049").toEither.isRight) }, test("Regex phone number validation for Niger") { val validation = PhoneNumberValidation.phoneNumberNE - assertTrue(validation.validate("+2271480678971").isRight) + assertTrue(validation.validate("+2271480678971").toEither.isRight) }, test("Regex phone number validation for Norfolk Island") { val validation = PhoneNumberValidation.phoneNumberNF - assertTrue(validation.validate("+6725311013853").isRight) + assertTrue(validation.validate("+6725311013853").toEither.isRight) }, test("Regex phone number validation for Nigeria") { val validation = PhoneNumberValidation.phoneNumberNG - assertTrue(validation.validate("009 234 78 6668 2580").isRight) + assertTrue(validation.validate("009 234 78 6668 2580").toEither.isRight) }, test("Regex phone number validation for Nicaragua") { val validation = PhoneNumberValidation.phoneNumberNI - assertTrue(validation.validate("+5057480416270").isRight) + assertTrue(validation.validate("+5057480416270").toEither.isRight) }, test("Regex phone number validation for Netherlands") { val validation = PhoneNumberValidation.phoneNumberNL - assertTrue(validation.validate("+31 3437953416").isRight) + assertTrue(validation.validate("+31 3437953416").toEither.isRight) }, test("Regex phone number validation for Norway") { val validation = PhoneNumberValidation.phoneNumberNO - assertTrue(validation.validate("+47 02 6239 2816").isRight) + assertTrue(validation.validate("+47 02 6239 2816").toEither.isRight) }, test("Regex phone number validation for Nepal") { val validation = PhoneNumberValidation.phoneNumberNP - assertTrue(validation.validate("00 977 8947592034").isRight) + assertTrue(validation.validate("00 977 8947592034").toEither.isRight) }, test("Regex phone number validation for Nauru") { val validation = PhoneNumberValidation.phoneNumberNR - assertTrue(validation.validate("+674 14 0184 1819").isRight) + assertTrue(validation.validate("+674 14 0184 1819").toEither.isRight) }, test("Regex phone number validation for Niue") { val validation = PhoneNumberValidation.phoneNumberNU - assertTrue(validation.validate("00 683 81 5796 1422").isRight) + assertTrue(validation.validate("00 683 81 5796 1422").toEither.isRight) }, test("Regex phone number validation for New Zealand") { val validation = PhoneNumberValidation.phoneNumberNZ - assertTrue(validation.validate("00 64 4309656720").isRight) + assertTrue(validation.validate("00 64 4309656720").toEither.isRight) }, test("Regex phone number validation for Oman") { val validation = PhoneNumberValidation.phoneNumberOM - assertTrue(validation.validate("+968 17 4687 2788").isRight) + assertTrue(validation.validate("+968 17 4687 2788").toEither.isRight) }, test("Regex phone number validation for Panama") { val validation = PhoneNumberValidation.phoneNumberPA - assertTrue(validation.validate("+507 10 8679 9468").isRight) + assertTrue(validation.validate("+507 10 8679 9468").toEither.isRight) }, test("Regex phone number validation for Peru") { val validation = PhoneNumberValidation.phoneNumberPE - assertTrue(validation.validate("0019 51 51 6407 3711").isRight) + assertTrue(validation.validate("0019 51 51 6407 3711").toEither.isRight) }, test("Regex phone number validation for French Polynesia") { val validation = PhoneNumberValidation.phoneNumberPF - assertTrue(validation.validate("00 689 31 4664 6885").isRight) + assertTrue(validation.validate("00 689 31 4664 6885").toEither.isRight) }, test("Regex phone number validation for Papua New Guinea") { val validation = PhoneNumberValidation.phoneNumberPG - assertTrue(validation.validate("+675 10 2567 0318").isRight) + assertTrue(validation.validate("+675 10 2567 0318").toEither.isRight) }, test("Regex phone number validation for Philippines") { val validation = PhoneNumberValidation.phoneNumberPH - assertTrue(validation.validate("00 63 2851764972").isRight) + assertTrue(validation.validate("00 63 2851764972").toEither.isRight) }, test("Regex phone number validation for Pakistan") { val validation = PhoneNumberValidation.phoneNumberPK - assertTrue(validation.validate("+92 7553664097").isRight) + assertTrue(validation.validate("+92 7553664097").toEither.isRight) }, test("Regex phone number validation for Poland") { val validation = PhoneNumberValidation.phoneNumberPL - assertTrue(validation.validate("00 48168250790").isRight) + assertTrue(validation.validate("00 48168250790").toEither.isRight) }, test("Regex phone number validation for Saint Pierre and Miquelon") { val validation = PhoneNumberValidation.phoneNumberPM - assertTrue(validation.validate("00 508 3214890710").isRight) + assertTrue(validation.validate("00 508 3214890710").toEither.isRight) }, test("Regex phone number validation for Pitcairn Islands") { val validation = PhoneNumberValidation.phoneNumberPN - assertTrue(validation.validate("+870 92 6226 9171").isRight) + assertTrue(validation.validate("+870 92 6226 9171").toEither.isRight) }, test("Regex phone number validation for Puerto Rico") { val validation = PhoneNumberValidation.phoneNumberPR - assertTrue(validation.validate("011 1 787 475 939").isRight) + assertTrue(validation.validate("011 1 787 475 939").toEither.isRight) }, test("Regex phone number validation for Palestinian Territory") { val validation = PhoneNumberValidation.phoneNumberPS - assertTrue(validation.validate("00 970 5758777122").isRight) + assertTrue(validation.validate("00 970 5758777122").toEither.isRight) }, test("Regex phone number validation for Portugal") { val validation = PhoneNumberValidation.phoneNumberPT - assertTrue(validation.validate("+3516910095620").isRight) - assertTrue(validation.validate("00351211140200").isRight) && - assertTrue(validation.validate("00351 211 140 200").isRight) && - assertTrue(validation.validate("00351 21 114 02 00").isRight) && - assertTrue(validation.validate("+351211140200").isRight) && - assertTrue(validation.validate("+351 21 114 02 00").isRight) && - assertTrue(validation.validate("+351 21 114 0200").isRight) && - assertTrue(validation.validate("-351 21 114 02 00").isLeft) && - assertTrue(validation.validate("+351 21 114 02 006").isLeft) && - assertTrue(validation.validate("21 114 02 006").isLeft) + assertTrue(validation.validate("+3516910095620").toEither.isRight) + assertTrue(validation.validate("00351211140200").toEither.isRight) && + assertTrue(validation.validate("00351 211 140 200").toEither.isRight) && + assertTrue(validation.validate("00351 21 114 02 00").toEither.isRight) && + assertTrue(validation.validate("+351211140200").toEither.isRight) && + assertTrue(validation.validate("+351 21 114 02 00").toEither.isRight) && + assertTrue(validation.validate("+351 21 114 0200").toEither.isRight) && + assertTrue(validation.validate("-351 21 114 02 00").toEither.isLeft) && + assertTrue(validation.validate("+351 21 114 02 006").toEither.isLeft) && + assertTrue(validation.validate("21 114 02 006").toEither.isLeft) }, test("Regex phone number validation for Palau") { val validation = PhoneNumberValidation.phoneNumberPW - assertTrue(validation.validate("01 680 54 5298 6941").isRight) + assertTrue(validation.validate("01 680 54 5298 6941").toEither.isRight) }, test("Regex phone number validation for Paraguay") { val validation = PhoneNumberValidation.phoneNumberPY - assertTrue(validation.validate("+595 7488642578").isRight) + assertTrue(validation.validate("+595 7488642578").toEither.isRight) }, test("Regex phone number validation for Qatar") { val validation = PhoneNumberValidation.phoneNumberQA - assertTrue(validation.validate("00 974094360402").isRight) + assertTrue(validation.validate("00 974094360402").toEither.isRight) }, test("Regex phone number validation for Réunion") { val validation = PhoneNumberValidation.phoneNumberRE - assertTrue(validation.validate("00 262 8485511353").isRight) + assertTrue(validation.validate("00 262 8485511353").toEither.isRight) }, test("Regex phone number validation for Romania") { val validation = PhoneNumberValidation.phoneNumberRO - assertTrue(validation.validate("+40 4126654789").isRight) + assertTrue(validation.validate("+40 4126654789").toEither.isRight) }, test("Regex phone number validation for Serbia") { val validation = PhoneNumberValidation.phoneNumberRS - assertTrue(validation.validate("00 381 5718415376").isRight) - assertTrue(validation.validate("+381111234567").isRight) && - assertTrue(validation.validate("+381 11 123 45 67").isRight) && - assertTrue(validation.validate("00381111234567").isRight) && - assertTrue(validation.validate("00381 11 123 45 67").isRight) && - assertTrue(validation.validate("00381 230 123 45 67").isRight) && - assertTrue(validation.validate("0111234567").isRight) && - assertTrue(validation.validate("-381 11 123 45 67").isLeft) && - assertTrue(validation.validate("+381 11 123 45 6789").isLeft) && - assertTrue(validation.validate("11 123 45 678").isLeft) + assertTrue(validation.validate("00 381 5718415376").toEither.isRight) + assertTrue(validation.validate("+381111234567").toEither.isRight) && + assertTrue(validation.validate("+381 11 123 45 67").toEither.isRight) && + assertTrue(validation.validate("00381111234567").toEither.isRight) && + assertTrue(validation.validate("00381 11 123 45 67").toEither.isRight) && + assertTrue(validation.validate("00381 230 123 45 67").toEither.isRight) && + assertTrue(validation.validate("0111234567").toEither.isRight) && + assertTrue(validation.validate("-381 11 123 45 67").toEither.isLeft) && + assertTrue(validation.validate("+381 11 123 45 6789").toEither.isLeft) && + assertTrue(validation.validate("11 123 45 678").toEither.isLeft) }, test("Regex phone number validation for Russian Federation") { val validation = PhoneNumberValidation.phoneNumberRU - assertTrue(validation.validate("810 7 8023940837").isRight) + assertTrue(validation.validate("810 7 8023940837").toEither.isRight) }, test("Regex phone number validation for Rwanda") { val validation = PhoneNumberValidation.phoneNumberRW - assertTrue(validation.validate("00 250 1071423830").isRight) + assertTrue(validation.validate("00 250 1071423830").toEither.isRight) }, test("Regex phone number validation for Saudi Arabia") { val validation = PhoneNumberValidation.phoneNumberSA - assertTrue(validation.validate("+966 2314438338").isRight) + assertTrue(validation.validate("+966 2314438338").toEither.isRight) }, test("Regex phone number validation for Solomon Islands") { val validation = PhoneNumberValidation.phoneNumberSB - assertTrue(validation.validate("+677 68 0771 5592").isRight) + assertTrue(validation.validate("+677 68 0771 5592").toEither.isRight) }, test("Regex phone number validation for Seychelles") { val validation = PhoneNumberValidation.phoneNumberSC - assertTrue(validation.validate("+2483511003232").isRight) + assertTrue(validation.validate("+2483511003232").toEither.isRight) }, test("Regex phone number validation for Sudan") { val validation = PhoneNumberValidation.phoneNumberSD - assertTrue(validation.validate("+249 8299453804").isRight) + assertTrue(validation.validate("+249 8299453804").toEither.isRight) }, test("Regex phone number validation for Sweden") { val validation = PhoneNumberValidation.phoneNumberSE - assertTrue(validation.validate("+46 3782292031").isRight) + assertTrue(validation.validate("+46 3782292031").toEither.isRight) }, test("Regex phone number validation for Singapore") { val validation = PhoneNumberValidation.phoneNumberSG - assertTrue(validation.validate("0 65 894769144").isRight) + assertTrue(validation.validate("0 65 894769144").toEither.isRight) }, test("Regex phone number validation for Saint Helena") { val validation = PhoneNumberValidation.phoneNumberSH - assertTrue(validation.validate("+290 256 649 891").isRight) + assertTrue(validation.validate("+290 256 649 891").toEither.isRight) }, test("Regex phone number validation for Slovenia") { val validation = PhoneNumberValidation.phoneNumberSI - assertTrue(validation.validate("+386 9216604503").isRight) + assertTrue(validation.validate("+386 9216604503").toEither.isRight) }, test("Regex phone number validation for Svalbard and Jan Mayen Islands") { val validation = PhoneNumberValidation.phoneNumberSJ - assertTrue(validation.validate("+47 79 13828050").isRight) + assertTrue(validation.validate("+47 79 13828050").toEither.isRight) }, test("Regex phone number validation for Slovakia") { val validation = PhoneNumberValidation.phoneNumberSK - assertTrue(validation.validate("00 421 9837820736").isRight) + assertTrue(validation.validate("00 421 9837820736").toEither.isRight) }, test("Regex phone number validation for Sierra Leone") { val validation = PhoneNumberValidation.phoneNumberSL - assertTrue(validation.validate("00 232 4479684349").isRight) + assertTrue(validation.validate("00 232 4479684349").toEither.isRight) }, test("Regex phone number validation for San Marino") { val validation = PhoneNumberValidation.phoneNumberSM - assertTrue(validation.validate("00 378038935173").isRight) + assertTrue(validation.validate("00 378038935173").toEither.isRight) }, test("Regex phone number validation for Senegal") { val validation = PhoneNumberValidation.phoneNumberSN - assertTrue(validation.validate("00 2218570840759").isRight) + assertTrue(validation.validate("00 2218570840759").toEither.isRight) }, test("Regex phone number validation for Somalia") { val validation = PhoneNumberValidation.phoneNumberSO - assertTrue(validation.validate("00 252 2908185816").isRight) + assertTrue(validation.validate("00 252 2908185816").toEither.isRight) }, test("Regex phone number validation for Suriname") { val validation = PhoneNumberValidation.phoneNumberSR - assertTrue(validation.validate("00 5975953326179").isRight) + assertTrue(validation.validate("00 5975953326179").toEither.isRight) }, test("Regex phone number validation for South Sudan") { val validation = PhoneNumberValidation.phoneNumberSS - assertTrue(validation.validate("00 211 6613246029").isRight) + assertTrue(validation.validate("00 211 6613246029").toEither.isRight) }, test("Regex phone number validation for Sao Tome and Principe") { val validation = PhoneNumberValidation.phoneNumberST - assertTrue(validation.validate("00 239431200296").isRight) + assertTrue(validation.validate("00 239431200296").toEither.isRight) }, test("Regex phone number validation for El Salvador") { val validation = PhoneNumberValidation.phoneNumberSV - assertTrue(validation.validate("00 503389285910").isRight) + assertTrue(validation.validate("00 503389285910").toEither.isRight) }, test("Regex phone number validation for Saint Marten") { val validation = PhoneNumberValidation.phoneNumberSX - assertTrue(validation.validate("011 1 721 528183").isRight) + assertTrue(validation.validate("011 1 721 528183").toEither.isRight) }, test("Regex phone number validation for Syria") { val validation = PhoneNumberValidation.phoneNumberSY - assertTrue(validation.validate("00 963 3253918464").isRight) + assertTrue(validation.validate("00 963 3253918464").toEither.isRight) }, test("Regex phone number validation for Swaziland") { val validation = PhoneNumberValidation.phoneNumberSZ - assertTrue(validation.validate("00 268184154720").isRight) + assertTrue(validation.validate("00 268184154720").toEither.isRight) }, test("Regex phone number validation for Tristan da Cunha") { val validation = PhoneNumberValidation.phoneNumberTA - assertTrue(validation.validate("+290 8 63587169").isRight) + assertTrue(validation.validate("+290 8 63587169").toEither.isRight) }, test("Regex phone number validation for Turks and Caicos Islands") { val validation = PhoneNumberValidation.phoneNumberTC - assertTrue(validation.validate("011 1 649 102537").isRight) + assertTrue(validation.validate("011 1 649 102537").toEither.isRight) }, test("Regex phone number validation for Chad") { val validation = PhoneNumberValidation.phoneNumberTD - assertTrue(validation.validate("00 2359209745639").isRight) + assertTrue(validation.validate("00 2359209745639").toEither.isRight) }, test("Regex phone number validation for French Southern Territories") { val validation = PhoneNumberValidation.phoneNumberTF - assertTrue(validation.validate("00 262 4215656462").isRight) + assertTrue(validation.validate("00 262 4215656462").toEither.isRight) }, test("Regex phone number validation for Togo") { val validation = PhoneNumberValidation.phoneNumberTG - assertTrue(validation.validate("00 2281952004914").isRight) + assertTrue(validation.validate("00 2281952004914").toEither.isRight) }, test("Regex phone number validation for Thailand") { val validation = PhoneNumberValidation.phoneNumberTH - assertTrue(validation.validate("00 66 7946617112").isRight) + assertTrue(validation.validate("00 66 7946617112").toEither.isRight) }, test("Regex phone number validation for Tajikistan") { val validation = PhoneNumberValidation.phoneNumberTJ - assertTrue(validation.validate("00810 992 57 5953 7962").isRight) + assertTrue(validation.validate("00810 992 57 5953 7962").toEither.isRight) }, test("Regex phone number validation for Tokelau") { val validation = PhoneNumberValidation.phoneNumberTK - assertTrue(validation.validate("00 6908354403605").isRight) + assertTrue(validation.validate("00 6908354403605").toEither.isRight) }, test("Regex phone number validation for Timor-Leste") { val validation = PhoneNumberValidation.phoneNumberTL - assertTrue(validation.validate("00 6704835783535").isRight) + assertTrue(validation.validate("00 6704835783535").toEither.isRight) }, test("Regex phone number validation for Turkmenistan") { val validation = PhoneNumberValidation.phoneNumberTM - assertTrue(validation.validate("00810 993 299 05 5741").isRight) + assertTrue(validation.validate("00810 993 299 05 5741").toEither.isRight) }, test("Regex phone number validation for Tunisia") { val validation = PhoneNumberValidation.phoneNumberTN - assertTrue(validation.validate("00 2162273895609").isRight) + assertTrue(validation.validate("00 2162273895609").toEither.isRight) }, test("Regex phone number validation for Tonga") { val validation = PhoneNumberValidation.phoneNumberTO - assertTrue(validation.validate("00 6769802885047").isRight) + assertTrue(validation.validate("00 6769802885047").toEither.isRight) }, test("Regex phone number validation for Turkey") { val validation = PhoneNumberValidation.phoneNumberTR - assertTrue(validation.validate("00 90 8195268757").isRight) + assertTrue(validation.validate("00 90 8195268757").toEither.isRight) }, test("Regex phone number validation for Trinidad and Tobago") { val validation = PhoneNumberValidation.phoneNumberTT - assertTrue(validation.validate("011 1 868 432 464").isRight) + assertTrue(validation.validate("011 1 868 432 464").toEither.isRight) }, test("Regex phone number validation for Tuvalu") { val validation = PhoneNumberValidation.phoneNumberTV - assertTrue(validation.validate("+688 75 8858 5314").isRight) + assertTrue(validation.validate("+688 75 8858 5314").toEither.isRight) }, test("Regex phone number validation for Taiwan") { val validation = PhoneNumberValidation.phoneNumberTW - assertTrue(validation.validate("+886 35 6499 1065").isRight) + assertTrue(validation.validate("+886 35 6499 1065").toEither.isRight) }, test("Regex phone number validation for Tanzania") { val validation = PhoneNumberValidation.phoneNumberTZ - assertTrue(validation.validate("+255 0143374246").isRight) + assertTrue(validation.validate("+255 0143374246").toEither.isRight) }, test("Regex phone number validation for Ukraine") { val validation = PhoneNumberValidation.phoneNumberUA - assertTrue(validation.validate("00 380 8406262037").isRight) + assertTrue(validation.validate("00 380 8406262037").toEither.isRight) }, test("Regex phone number validation for Uganda") { val validation = PhoneNumberValidation.phoneNumberUG - assertTrue(validation.validate("+256 3856449691").isRight) + assertTrue(validation.validate("+256 3856449691").toEither.isRight) }, test("Regex phone number validation for US Minor Outlying Islands") { val validation = PhoneNumberValidation.phoneNumberUM - assertTrue(validation.validate("+1 929 131 901").isRight) + assertTrue(validation.validate("+1 929 131 901").toEither.isRight) }, test("Regex phone number validation for United States of America") { val validation = PhoneNumberValidation.phoneNumberUS - assertTrue(validation.validate("011 1 447142964").isRight) + assertTrue(validation.validate("011 1 447142964").toEither.isRight) }, test("Regex phone number validation for Uruguay") { val validation = PhoneNumberValidation.phoneNumberUY - assertTrue(validation.validate("00 598 0928779109").isRight) + assertTrue(validation.validate("00 598 0928779109").toEither.isRight) }, test("Regex phone number validation for Uzbekistan") { val validation = PhoneNumberValidation.phoneNumberUZ - assertTrue(validation.validate("00810 998 251 702 0097").isRight) + assertTrue(validation.validate("00810 998 251 702 0097").toEither.isRight) }, test("Regex phone number validation for Holy See (Vatican City State)") { val validation = PhoneNumberValidation.phoneNumberVA - assertTrue(validation.validate("+39 06698 10418").isRight) + assertTrue(validation.validate("+39 06698 10418").toEither.isRight) }, test("Regex phone number validation for Saint Vincent and Grenadines") { val validation = PhoneNumberValidation.phoneNumberVC - assertTrue(validation.validate("011 1 784 3314547").isRight) + assertTrue(validation.validate("011 1 784 3314547").toEither.isRight) }, test("Regex phone number validation for Venezuela") { val validation = PhoneNumberValidation.phoneNumberVE - assertTrue(validation.validate("+58 0161257166").isRight) + assertTrue(validation.validate("+58 0161257166").toEither.isRight) }, test("Regex phone number validation for British Virgin Islands") { val validation = PhoneNumberValidation.phoneNumberVG - assertTrue(validation.validate("011 1 284 966822").isRight) + assertTrue(validation.validate("011 1 284 966822").toEither.isRight) }, test("Regex phone number validation for Virgin Islands, US") { val validation = PhoneNumberValidation.phoneNumberVI - assertTrue(validation.validate("011 1 340 249394").isRight) + assertTrue(validation.validate("011 1 340 249394").toEither.isRight) }, test("Regex phone number validation for Viet Nam") { val validation = PhoneNumberValidation.phoneNumberVN - assertTrue(validation.validate("00 84 5582883606").isRight) + assertTrue(validation.validate("00 84 5582883606").toEither.isRight) }, test("Regex phone number validation for Vanuatu") { val validation = PhoneNumberValidation.phoneNumberVU - assertTrue(validation.validate("00 6786895604772").isRight) + assertTrue(validation.validate("00 6786895604772").toEither.isRight) }, test("Regex phone number validation for Wallis and Futuna Islands") { val validation = PhoneNumberValidation.phoneNumberWF - assertTrue(validation.validate("00 6816712124320").isRight) + assertTrue(validation.validate("00 6816712124320").toEither.isRight) }, test("Regex phone number validation for Samoa") { val validation = PhoneNumberValidation.phoneNumberWS - assertTrue(validation.validate("0 6856225946106").isRight) + assertTrue(validation.validate("0 6856225946106").toEither.isRight) }, test("Regex phone number validation for Kosovo") { val validation = PhoneNumberValidation.phoneNumberXK - assertTrue(validation.validate("00 383 4979043799").isRight) + assertTrue(validation.validate("00 383 4979043799").toEither.isRight) }, test("Regex phone number validation for Yemen") { val validation = PhoneNumberValidation.phoneNumberYE - assertTrue(validation.validate("00 967 8589630609").isRight) + assertTrue(validation.validate("00 967 8589630609").toEither.isRight) }, test("Regex phone number validation for Mayotte") { val validation = PhoneNumberValidation.phoneNumberYT - assertTrue(validation.validate("00 262 269 44 43 21").isRight) + assertTrue(validation.validate("00 262 269 44 43 21").toEither.isRight) }, test("Regex phone number validation for South Africa") { val validation = PhoneNumberValidation.phoneNumberZA - assertTrue(validation.validate("00 27 0081060414").isRight) + assertTrue(validation.validate("00 27 0081060414").toEither.isRight) }, test("Regex phone number validation for Zambia") { val validation = PhoneNumberValidation.phoneNumberZM - assertTrue(validation.validate("00 260 3563071452").isRight) + assertTrue(validation.validate("00 260 3563071452").toEither.isRight) }, test("Regex phone number validation for Zimbabwe") { val validation = PhoneNumberValidation.phoneNumberZW - assertTrue(validation.validate("+263 1141482994").isRight) + assertTrue(validation.validate("+263 1141482994").toEither.isRight) } ) } diff --git a/zio-schema/shared/src/test/scala/zio/schema/validation/ValidationSpec.scala b/zio-schema/shared/src/test/scala/zio/schema/validation/SchemaValidationSpec$.scala similarity index 77% rename from zio-schema/shared/src/test/scala/zio/schema/validation/ValidationSpec.scala rename to zio-schema/shared/src/test/scala/zio/schema/validation/SchemaValidationSpec$.scala index 22f0176bc..1f5edaf5b 100644 --- a/zio-schema/shared/src/test/scala/zio/schema/validation/ValidationSpec.scala +++ b/zio-schema/shared/src/test/scala/zio/schema/validation/SchemaValidationSpec$.scala @@ -2,78 +2,76 @@ package zio.schema.validation import java.time.format.DateTimeFormatter import java.util.Locale - import scala.util.Try - import zio.Scope import zio.test._ -object ValidationSpec extends ZIOSpecDefault { - import zio.schema.validation.ValidationSpec.Hour._ - import zio.schema.validation.ValidationSpec.Minute._ - import zio.schema.validation.ValidationSpec.Second._ - import zio.schema.validation.ValidationSpec.Fraction._ - import zio.schema.validation.ValidationSpec.AmPm._ +object SchemaValidationSpec extends ZIOSpecDefault { + import zio.schema.validation.SchemaValidationSpec.Hour._ + import zio.schema.validation.SchemaValidationSpec.Minute._ + import zio.schema.validation.SchemaValidationSpec.Second._ + import zio.schema.validation.SchemaValidationSpec.Fraction._ + import zio.schema.validation.SchemaValidationSpec.AmPm._ def spec: Spec[Environment with TestEnvironment with Scope, Any] = suite("ValidationSpec")( test("Greater than") { - val validation = Validation.greaterThan(4) + val validation = SchemaValidation.greaterThan(4) - assertTrue(validation.validate(4).isLeft) && - assertTrue(validation.validate(5).isRight) && - assertTrue(validation.validate(6).isRight) && - assertTrue(validation.validate(3).isLeft) + assertTrue(validation.validate(4).toEither.isLeft) && + assertTrue(validation.validate(5).toEither.isRight) && + assertTrue(validation.validate(6).toEither.isRight) && + assertTrue(validation.validate(3).toEither.isLeft) }, test("Less than") { - val validation = Validation.lessThan(4) + val validation = SchemaValidation.lessThan(4) - assertTrue(validation.validate(3).isRight) && - assertTrue(validation.validate(2).isRight) && - assertTrue(validation.validate(5).isLeft) && - assertTrue(validation.validate(4).isLeft) + assertTrue(validation.validate(3).toEither.isRight) && + assertTrue(validation.validate(2).toEither.isRight) && + assertTrue(validation.validate(5).toEither.isLeft) && + assertTrue(validation.validate(4).toEither.isLeft) }, test("Equal to") { - val validation = Validation.equalTo(3) + val validation = SchemaValidation.equalTo(3) - assertTrue(validation.validate(3).isRight) && - assertTrue(validation.validate(5).isLeft) && - assertTrue(validation.validate(2).isLeft) + assertTrue(validation.validate(3).toEither.isRight) && + assertTrue(validation.validate(5).toEither.isLeft) && + assertTrue(validation.validate(2).toEither.isLeft) }, test("MinLength") { - val validation = Validation.minLength(4) + val validation = SchemaValidation.minLength(4) - assertTrue(validation.validate("hello").isRight) && - assertTrue(validation.validate("Todd").isRight) && - assertTrue(validation.validate("how").isLeft) && - assertTrue(validation.validate("hi").isLeft) + assertTrue(validation.validate("hello").toEither.isRight) && + assertTrue(validation.validate("Todd").toEither.isRight) && + assertTrue(validation.validate("how").toEither.isLeft) && + assertTrue(validation.validate("hi").toEither.isLeft) }, test("MaxLength") { - val validation = Validation.maxLength(4) + val validation = SchemaValidation.maxLength(4) - assertTrue(validation.validate("Todd").isRight) && - assertTrue(validation.validate("how").isRight) && - assertTrue(validation.validate("hello").isLeft) && - assertTrue(validation.validate("Automobile").isLeft) + assertTrue(validation.validate("Todd").toEither.isRight) && + assertTrue(validation.validate("how").toEither.isRight) && + assertTrue(validation.validate("hello").toEither.isLeft) && + assertTrue(validation.validate("Automobile").toEither.isLeft) }, test("Regex digit or letter Validation") { - val validation = Validation.regex(Regex.digitOrLetter) - - assertTrue(validation.validate("a").isRight) && - assertTrue(validation.validate("1").isRight) && - assertTrue(validation.validate("12").isLeft) && - assertTrue(validation.validate("*").isLeft) && - assertTrue(validation.validate("ab").isLeft) && - assertTrue(validation.validate("").isLeft) && - assertTrue(validation.validate("&").isLeft) + val validation = SchemaValidation.regex(Regex.digitOrLetter) + + assertTrue(validation.validate("a").toEither.isRight) && + assertTrue(validation.validate("1").toEither.isRight) && + assertTrue(validation.validate("12").toEither.isLeft) && + assertTrue(validation.validate("*").toEither.isLeft) && + assertTrue(validation.validate("ab").toEither.isLeft) && + assertTrue(validation.validate("").toEither.isLeft) && + assertTrue(validation.validate("&").toEither.isLeft) }, test("Regex identifier Validation") { - val validation = Validation.identifier + val validation = SchemaValidation.identifier - assertTrue(validation.validate("_").isRight) && - assertTrue(validation.validate("a").isRight) && - assertTrue(validation.validate("ab").isRight) && - assertTrue(validation.validate("").isLeft) && - assertTrue(validation.validate("*").isLeft) + assertTrue(validation.validate("_").toEither.isRight) && + assertTrue(validation.validate("a").toEither.isRight) && + assertTrue(validation.validate("ab").toEither.isRight) && + assertTrue(validation.validate("").toEither.isLeft) && + assertTrue(validation.validate("*").toEither.isLeft) }, suite("Regex email Validation")( test("should reject an invalid email") { @@ -101,10 +99,10 @@ object ValidationSpec extends ZIOSpecDefault { "postmaster@[2001:cdba:0:0:0:0:3257:9652]" ) } - val validationResult = (value: String) => Validation.email.validate(value) + val validationResult = (value: String) => SchemaValidation.email.validate(value) checkAll(examples) { email => - assertTrue(validationResult(email).isLeft) + assertTrue(validationResult(email).toEither.isLeft) } }, test("should accept a correct email") { @@ -124,10 +122,10 @@ object ValidationSpec extends ZIOSpecDefault { "postmaster@[IPv6:2001:cdba:0:0:0:0:3257:9652]" ) } - val validationResult = (value: String) => Validation.email.validate(value) + val validationResult = (value: String) => SchemaValidation.email.validate(value) checkAll(examples) { email => - assertTrue(validationResult(email).isRight) + assertTrue(validationResult(email).toEither.isRight) } } ), @@ -149,10 +147,10 @@ object ValidationSpec extends ZIOSpecDefault { ) } - val validationResult = (value: String) => Validation.ipV4.validate(value) + val validationResult = (value: String) => SchemaValidation.ipV4.validate(value) checkAll(examples) { ip => - assertTrue(validationResult(ip).isRight) + assertTrue(validationResult(ip).toEither.isRight) } }, test("should reject an invalid IPv4 address") { @@ -166,10 +164,10 @@ object ValidationSpec extends ZIOSpecDefault { ) } - val validationResult = (value: String) => Validation.ipV4.validate(value) + val validationResult = (value: String) => SchemaValidation.ipV4.validate(value) checkAll(examples) { ip => - assertTrue(validationResult(ip).isLeft) + assertTrue(validationResult(ip).toEither.isLeft) } } ), @@ -194,10 +192,10 @@ object ValidationSpec extends ZIOSpecDefault { ) } - val validationResult = (value: String) => Validation.ipV6.validate(value) + val validationResult = (value: String) => SchemaValidation.ipV6.validate(value) checkAll(examples) { ip => - assertTrue(validationResult(ip).isRight) + assertTrue(validationResult(ip).toEither.isRight) } }, test("should reject an invalid IPv6 address") { @@ -209,26 +207,26 @@ object ValidationSpec extends ZIOSpecDefault { ) } - val validationResult = (value: String) => Validation.ipV6.validate(value) + val validationResult = (value: String) => SchemaValidation.ipV6.validate(value) checkAll(examples) { ip => - assertTrue(validationResult(ip).isLeft) + assertTrue(validationResult(ip).toEither.isLeft) } } ), suite("Regex uuid Validations")( test("valid UUID") { - val validation = Validation.uuidV4 + val validation = SchemaValidation.uuidV4 check(Gen.uuid) { uuid => - assertTrue(validation.validate(uuid.toString).isRight) + assertTrue(validation.validate(uuid.toString).toEither.isRight) } }, test("invalid UUID") { - val validation = Validation.uuidV4 - assertTrue(validation.validate("1e3118de-ddb6-11ec-8653-93e6961d46be").isLeft) && - assertTrue(validation.validate("487f5075-fa89-4723-a26d-2e7a13245").isLeft) && - assertTrue(validation.validate("487f5075fa894723a26d2e7a13245135").isLeft) && - assertTrue(validation.validate("").isLeft) + val validation = SchemaValidation.uuidV4 + assertTrue(validation.validate("1e3118de-ddb6-11ec-8653-93e6961d46be").toEither.isLeft) && + assertTrue(validation.validate("487f5075-fa89-4723-a26d-2e7a13245").toEither.isLeft) && + assertTrue(validation.validate("487f5075fa894723a26d2e7a13245135").toEither.isLeft) && + assertTrue(validation.validate("").toEither.isLeft) } ), test("Time Validation HH") { @@ -328,7 +326,7 @@ object ValidationSpec extends ZIOSpecDefault { }, test("Regex duration Validation") { check(Gen.finiteDuration) { duration => - assertTrue(Validation.duration.validate(duration.toString).isRight) + assertTrue(SchemaValidation.duration.validate(duration.toString).toEither.isRight) } } ) @@ -354,12 +352,12 @@ object ValidationSpec extends ZIOSpecDefault { private def parseTimes(createTimesConfig: CreateTimesConfig, format: String): ParsedTimes = { val times = createTimes(exampleTimes, createTimesConfig) val wrongTimes = createTimes(wrongExampleTimes, createTimesConfig) - val validation = Validation.time(format) + val validation = SchemaValidation.time(format) val formatter = DateTimeFormatter.ofPattern(format, Locale.US) def innerParse(times: Seq[String]) = times.map { time => - val valid = validation.validate(time).isRight + val valid = validation.validate(time).toEither.isRight val parsed = Try(formatter.parse(time)).isSuccess ParsedTime(time, valid, parsed) } diff --git a/zio-schema/shared/src/test/scala/zio/schema/validation/TimeSpec.scala b/zio-schema/shared/src/test/scala/zio/schema/validation/TimeSpec.scala index cac22bc68..0eaba92ed 100644 --- a/zio-schema/shared/src/test/scala/zio/schema/validation/TimeSpec.scala +++ b/zio-schema/shared/src/test/scala/zio/schema/validation/TimeSpec.scala @@ -8,48 +8,48 @@ object TimeSpec extends ZIOSpecDefault { def spec: Spec[Environment with TestEnvironment with Scope, Any] = suite("TimeSpec")( test("Valid formats") { - assert(Validation.time("H"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("HH"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("h"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("hh"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("m"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("mm"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("s"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("ss"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("S"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("SS"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("SSS"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("SSSSSSSSS"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("HHmm"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("H:m"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("H:m a"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("HH:mm"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("HH:mm a"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("HHmmss"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("HH:mm:ss"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("HH:mm:ssa"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("HH:mm:ss a"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("a HH:mm:ss"))(isSubtype[Validation[String]](anything)) && - assert(Validation.time("H:m:s a"))(isSubtype[Validation[String]](anything)) + assert(SchemaValidation.time("H"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("HH"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("h"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("hh"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("m"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("mm"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("s"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("ss"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("S"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("SS"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("SSS"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("SSSSSSSSS"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("HHmm"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("H:m"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("H:m a"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("HH:mm"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("HH:mm a"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("HHmmss"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("HH:mm:ss"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("HH:mm:ssa"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("HH:mm:ss a"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("a HH:mm:ss"))(isSubtype[SchemaValidation[String]](anything)) && + assert(SchemaValidation.time("H:m:s a"))(isSubtype[SchemaValidation[String]](anything)) }, test("Invalid formats") { - assert(Validation.time("HHH"))(throws(hasMessage(containsString("max length for")))) && - assert(Validation.time("hhh"))(throws(hasMessage(containsString("max length for")))) && - assert(Validation.time("mmm"))(throws(hasMessage(containsString("max length for")))) && - assert(Validation.time("sss"))(throws(hasMessage(containsString("max length for")))) && - assert(Validation.time("SSSSSSSSSS"))(throws(hasMessage(containsString("max length for")))) && - assert(Validation.time("aa"))(throws(hasMessage(containsString("max length for")))) && - assert(Validation.time("HHmmH"))(throws(hasMessage(containsString("already used in format")))) && - assert(Validation.time("HHmmsm"))(throws(hasMessage(containsString("already used in format")))) && - assert(Validation.time("hhmmhh"))(throws(hasMessage(containsString("already used in format")))) && - assert(Validation.time("a HH:mm:s a"))(throws(hasMessage(containsString("already used in format")))) && - assert(Validation.time("HH:mm:ss.SS S"))(throws(hasMessage(containsString("already used in format")))) && - assert(Validation.time(":"))(throws(hasMessage(containsString("There is no time field")))) && - assert(Validation.time("b"))(throws(hasMessage(containsString("All letters are reserved")))) && - assert(Validation.time("j"))(throws(hasMessage(containsString("All letters are reserved")))) && - assert(Validation.time("B"))(throws(hasMessage(containsString("All letters are reserved")))) && - assert(Validation.time("J"))(throws(hasMessage(containsString("All letters are reserved")))) && - assert(Validation.time(""))(throws(hasMessage(containsString("There is no time field")))) + assert(SchemaValidation.time("HHH"))(throws(hasMessage(containsString("max length for")))) && + assert(SchemaValidation.time("hhh"))(throws(hasMessage(containsString("max length for")))) && + assert(SchemaValidation.time("mmm"))(throws(hasMessage(containsString("max length for")))) && + assert(SchemaValidation.time("sss"))(throws(hasMessage(containsString("max length for")))) && + assert(SchemaValidation.time("SSSSSSSSSS"))(throws(hasMessage(containsString("max length for")))) && + assert(SchemaValidation.time("aa"))(throws(hasMessage(containsString("max length for")))) && + assert(SchemaValidation.time("HHmmH"))(throws(hasMessage(containsString("already used in format")))) && + assert(SchemaValidation.time("HHmmsm"))(throws(hasMessage(containsString("already used in format")))) && + assert(SchemaValidation.time("hhmmhh"))(throws(hasMessage(containsString("already used in format")))) && + assert(SchemaValidation.time("a HH:mm:s a"))(throws(hasMessage(containsString("already used in format")))) && + assert(SchemaValidation.time("HH:mm:ss.SS S"))(throws(hasMessage(containsString("already used in format")))) && + assert(SchemaValidation.time(":"))(throws(hasMessage(containsString("There is no time field")))) && + assert(SchemaValidation.time("b"))(throws(hasMessage(containsString("All letters are reserved")))) && + assert(SchemaValidation.time("j"))(throws(hasMessage(containsString("All letters are reserved")))) && + assert(SchemaValidation.time("B"))(throws(hasMessage(containsString("All letters are reserved")))) && + assert(SchemaValidation.time("J"))(throws(hasMessage(containsString("All letters are reserved")))) && + assert(SchemaValidation.time(""))(throws(hasMessage(containsString("There is no time field")))) } ) } From e3abf72d1cac8f837f2b7a974d8d35dfde8013b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=8BAndrzej=20Ressel?= Date: Fri, 19 May 2023 03:21:22 +0200 Subject: [PATCH 4/6] fmt --- .../test/scala-2/zio/schema/SchemaGen.scala | 2 +- .../scala/zio/schema/DefaultValueSpec.scala | 18 ++- .../test/scala/zio/schema/MigrationSpec.scala | 9 +- .../test/scala/zio/schema/SchemaSpec.scala | 4 +- .../scala/zio/schema/codec/AvroCodec.scala | 150 ++++++++++-------- .../zio/schema/codec/AvroPropMarker.scala | 14 +- .../zio/schema/codec/AvroCodecSpec.scala | 24 ++- .../schema/SchemaSchemaValidationSpec$.scala | 24 +-- .../scala/zio/schema/codec/JsonCodec.scala | 33 ++-- .../zio/schema/codec/JsonCodecSpec.scala | 8 +- .../zio/schema/codec/MessagePackCodec.scala | 6 +- .../zio/schema/codec/MessagePackDecoder.scala | 24 +-- .../zio/schema/codec/MessagePackEncoder.scala | 22 +-- .../schema/codec/MessagePackCodecSpec.scala | 18 ++- .../zio/schema/codec/ProtobufCodec.scala | 40 ++--- .../zio/schema/codec/ProtobufCodecSpec.scala | 6 +- .../scala/zio/schema/codec/ThriftCodec.scala | 25 +-- .../zio/schema/codec/ThriftCodecSpec.scala | 43 +++-- .../src/test/scala/zio/schema/TestData.scala | 3 +- .../scala/zio/schema/codec/BinaryCodecs.scala | 4 +- .../main/scala/zio/schema/codec/Codecs.scala | 4 +- .../scala/zio/schema/codec/DecodeError.scala | 3 +- 22 files changed, 294 insertions(+), 190 deletions(-) diff --git a/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala b/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala index 39cf32798..9b3bcf563 100644 --- a/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala +++ b/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala @@ -3,7 +3,7 @@ package zio.schema import scala.collection.immutable.ListMap import zio.Chunk import zio.prelude.Validation -import zio.test.{Gen, Sized} +import zio.test.{ Gen, Sized } object SchemaGen { diff --git a/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala b/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala index 55d47c7e2..d04213060 100644 --- a/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala @@ -1,10 +1,10 @@ package zio.schema -import zio.{Chunk, NonEmptyChunk} +import zio.{ Chunk, NonEmptyChunk } import zio.schema.CaseSet.caseOf -import zio.schema.Schema.{Lazy, Primitive} +import zio.schema.Schema.{ Lazy, Primitive } import zio.test.Assertion._ -import zio.test.{Spec, ZIOSpecDefault, assert} +import zio.test.{ Spec, ZIOSpecDefault, assert } object DefaultValueSpec extends ZIOSpecDefault { // Record Tests @@ -67,10 +67,14 @@ object DefaultValueSpec extends ZIOSpecDefault { assert(Primitive(StandardType.CharType).defaultValue.toEither)(isRight(equalTo('\u0000'))) }, test("BigDecimalType default value") { - assert(Primitive(StandardType.BigDecimalType).defaultValue.toEither)(isRight(equalTo(java.math.BigDecimal.ZERO))) + assert(Primitive(StandardType.BigDecimalType).defaultValue.toEither)( + isRight(equalTo(java.math.BigDecimal.ZERO)) + ) }, test("BigIntegerType default value") { - assert(Primitive(StandardType.BigIntegerType).defaultValue.toEither)(isRight(equalTo(java.math.BigInteger.ZERO))) + assert(Primitive(StandardType.BigIntegerType).defaultValue.toEither)( + isRight(equalTo(java.math.BigInteger.ZERO)) + ) }, test("DayOfWeekType default value") { assert(Primitive(StandardType.DayOfWeekType).defaultValue.toEither)( @@ -97,7 +101,9 @@ object DefaultValueSpec extends ZIOSpecDefault { assert(Primitive(StandardType.YearMonthType).defaultValue.toEither)(isRight(equalTo(java.time.YearMonth.now))) }, test("ZoneId default value") { - assert(Primitive(StandardType.ZoneIdType).defaultValue.toEither)(isRight(equalTo(java.time.ZoneId.systemDefault))) + assert(Primitive(StandardType.ZoneIdType).defaultValue.toEither)( + isRight(equalTo(java.time.ZoneId.systemDefault)) + ) }, test("ZoneOffset default value") { assert(Primitive(StandardType.ZoneOffsetType).defaultValue.toEither)(isRight(equalTo(java.time.ZoneOffset.UTC))) diff --git a/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala b/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala index bc6bfaf81..014c3f3fd 100644 --- a/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/MigrationSpec.scala @@ -19,7 +19,8 @@ object MigrationSpec extends ZIOSpecDefault { assertTrue( Migration - .derive(from, to) == zio.prelude.Validation.succeed(Chunk(Migration.ChangeType(NodePath.root, StandardType.StringType))) + .derive(from, to) == zio.prelude.Validation + .succeed(Chunk(Migration.ChangeType(NodePath.root, StandardType.StringType))) ) }, test("optional") { @@ -55,7 +56,8 @@ object MigrationSpec extends ZIOSpecDefault { assertTrue( Migration - .derive(from, to) == zio.prelude.Validation.succeed(Chunk(Migration.IncrementDimensions(NodePath.root, 1))) + .derive(from, to) == zio.prelude.Validation + .succeed(Chunk(Migration.IncrementDimensions(NodePath.root, 1))) ) }, test("decrement dimensions") { @@ -69,7 +71,8 @@ object MigrationSpec extends ZIOSpecDefault { assertTrue( Migration - .derive(from, to) == zio.prelude.Validation.succeed(Chunk(Migration.DecrementDimensions(NodePath.root, 1))) + .derive(from, to) == zio.prelude.Validation + .succeed(Chunk(Migration.DecrementDimensions(NodePath.root, 1))) ) } ), diff --git a/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala b/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala index a36d80ada..604cb359e 100644 --- a/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala @@ -74,10 +74,10 @@ object SchemaSpec extends ZIOSpecDefault { val f: Unit => Validation[String, Int] = _ => zio.prelude.Validation.succeed(0) val g: Int => Validation[String, Unit] = _ => zio.prelude.Validation.succeed(()) - def schemaTransform: Schema[Int] = schemaUnit.transformOrFail[Int](f, g) + def schemaTransform: Schema[Int] = schemaUnit.transformOrFail[Int](f, g) def tranformF(u: Unit): Validation[String, Int] = Validation.fromEither(Some(u).map(_ => 0).toRight("")) def tranformG(i: Int): Validation[String, Unit] = Validation.fromEither(Some(i).map(_ => ()).toRight("")) - def schemaTransformMethod: Schema[Int] = schemaUnit.transformOrFail(tranformF, tranformG) + def schemaTransformMethod: Schema[Int] = schemaUnit.transformOrFail(tranformF, tranformG) } diff --git a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala index 1f8d7eb3e..4bc1549af 100644 --- a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala +++ b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala @@ -2,16 +2,16 @@ package zio.schema.codec import java.nio.charset.StandardCharsets import java.time.format.DateTimeFormatter -import java.time.{Duration, Month, MonthDay, Period, Year, YearMonth} +import java.time.{ Duration, Month, MonthDay, Period, Year, YearMonth } import scala.annotation.StaticAnnotation import scala.collection.immutable.ListMap import scala.jdk.CollectionConverters._ -import scala.util.{Right, Try} -import org.apache.avro.{LogicalTypes, Schema => SchemaAvro} +import scala.util.{ Right, Try } +import org.apache.avro.{ LogicalTypes, Schema => SchemaAvro } import zio.Chunk import zio.prelude.Validation import zio.schema.CaseSet.Aux -import zio.schema.Schema.{Record, _} +import zio.schema.Schema.{ Record, _ } import zio.schema._ import zio.schema.codec.AvroAnnotations._ import zio.schema.codec.AvroPropMarker._ @@ -163,7 +163,8 @@ object AvroCodec extends AvroCodec { formatter.map( _ => Schema.primitive(StandardType.LocalDateType) ) - case _ => Validation.fail(s"Unsupported int logical type ${avroSchema.getLogicalType.getName}") + case _ => + Validation.fail(s"Unsupported int logical type ${avroSchema.getLogicalType.getName}") } } case SchemaAvro.Type.LONG => @@ -298,15 +299,21 @@ object AvroCodec extends AvroCodec { case StandardType.BigDecimalType => toAvroDecimal(schema) case StandardType.BigIntegerType => toAvroDecimal(schema) case StandardType.DayOfWeekType => - Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.DayOfWeek))) + Validation.succeed( + SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.DayOfWeek)) + ) case StandardType.MonthType => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Month))) case StandardType.YearType => Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.Year))) case StandardType.ZoneIdType => - Validation.succeed(SchemaAvro.create(SchemaAvro.Type.STRING).addMarkerProp(StringDiscriminator(StringType.ZoneId))) + Validation.succeed( + SchemaAvro.create(SchemaAvro.Type.STRING).addMarkerProp(StringDiscriminator(StringType.ZoneId)) + ) case StandardType.ZoneOffsetType => - Validation.succeed(SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.ZoneOffset))) + Validation.succeed( + SchemaAvro.create(SchemaAvro.Type.INT).addMarkerProp(IntDiscriminator(IntType.ZoneOffset)) + ) case StandardType.MonthDayType => //TODO 1 //zio.prelude.Validation.succeed(SchemaAvro.create(monthDayStructure).addMarkerProp(RecordDiscriminator(RecordType.MonthDay))) @@ -398,7 +405,9 @@ object AvroCodec extends AvroCodec { leftSchema = if (l.getType == SchemaAvro.Type.UNION) wrapAvro(l, lname, UnionWrapper) else l rightSchema = if (r.getType == SchemaAvro.Type.UNION) wrapAvro(r, rname, UnionWrapper) else r _ <- if (leftSchema.getFullName == rightSchema.getFullName) - Validation.fail(s"Left and right schemas of either must have different fullnames: ${leftSchema.getFullName}") + Validation.fail( + s"Left and right schemas of either must have different fullnames: ${leftSchema.getFullName}" + ) else Validation.succeed(()) } yield SchemaAvro.createUnion(leftSchema, rightSchema) @@ -455,7 +464,9 @@ object AvroCodec extends AvroCodec { .addMarkerProp(Formatter(formatter)) ) } else { - Validation.succeed(LogicalTypes.date().addToSchema(SchemaAvro.create(SchemaAvro.Type.INT)).addMarkerProp(Formatter(formatter))) + Validation.succeed( + LogicalTypes.date().addToSchema(SchemaAvro.create(SchemaAvro.Type.INT)).addMarkerProp(Formatter(formatter)) + ) } private[codec] def toAvroLocalTime( @@ -503,9 +514,13 @@ object AvroCodec extends AvroCodec { val baseSchema = SchemaAvro.create(SchemaAvro.Type.LONG) getTimeprecisionType(annotations).getOrElse(TimePrecisionType.default) match { case TimePrecisionType.Millis => - Validation.succeed(LogicalTypes.localTimestampMillis().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) + Validation.succeed( + LogicalTypes.localTimestampMillis().addToSchema(baseSchema).addMarkerProp(Formatter(formatter)) + ) case TimePrecisionType.Micros => - Validation.succeed(LogicalTypes.localTimestampMicros().addToSchema(baseSchema).addMarkerProp(Formatter(formatter))) + Validation.succeed( + LogicalTypes.localTimestampMicros().addToSchema(baseSchema).addMarkerProp(Formatter(formatter)) + ) } } @@ -528,16 +543,16 @@ object AvroCodec extends AvroCodec { val avroEnumAnnotationExists = hasAvroEnumAnnotation(enu.annotations) val isAvroEnumEquivalent = enu.cases.map(_.schema).forall { case (Transform(Primitive(standardType, _), _, _, _, _)) - if standardType == StandardType.UnitType && avroEnumAnnotationExists => + if standardType == StandardType.UnitType && avroEnumAnnotationExists => true case (Primitive(standardType, _)) if standardType == StandardType.StringType => true - case (CaseClass0(_, _, _)) if avroEnumAnnotationExists => true - case _ => false + case (CaseClass0(_, _, _)) if avroEnumAnnotationExists => true + case _ => false } if (isAvroEnumEquivalent) { for { - name <- getName(enu) - doc = getDoc(enu.annotations).orNull + name <- getName(enu) + doc = getDoc(enu.annotations).orNull namespaceOption <- getNamespace(enu.annotations) symbols = enu.cases.map { case caseValue => getNameOption(caseValue.annotations).getOrElse(caseValue.id) @@ -547,14 +562,16 @@ object AvroCodec extends AvroCodec { } else { val cases = enu.cases.map(c => (c.id, (c.schema, c.annotations))).map { case (symbol, (Transform(Primitive(standardType, _), _, _, _, _), annotations)) - if standardType == StandardType.UnitType => + if standardType == StandardType.UnitType => val name = getNameOption(annotations).getOrElse(symbol) - Validation.succeed(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) + Validation + .succeed(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) case (symbol, (CaseClass0(_, _, _), annotations)) => val name = getNameOption(annotations).getOrElse(symbol) - Validation.succeed(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) + Validation + .succeed(SchemaAvro.createRecord(name, null, null, false, new java.util.ArrayList[SchemaAvro.Field])) case (symbol, (schema, annotations)) => - val name = getNameOption(annotations).getOrElse(symbol) + val name = getNameOption(annotations).getOrElse(symbol) val schemaWithName = addNameAnnotationIfMissing(schema, name) toAvroSchema(schemaWithName).map { case schema: SchemaAvro if schema.getType == SchemaAvro.Type.UNION => @@ -562,15 +579,16 @@ object AvroCodec extends AvroCodec { case schema => schema } } - Validation.validateAll(cases.toList) + Validation + .validateAll(cases.toList) .map(c => SchemaAvro.createUnion(c.asJava)) } } - private def extractAvroFields(record: Record[_]): List[org.apache.avro.Schema.Field] = { - Validation.validateAll(record.fields.map(toAvroRecordField(_)).toList) + private def extractAvroFields(record: Record[_]): List[org.apache.avro.Schema.Field] = + Validation + .validateAll(record.fields.map(toAvroRecordField(_)).toList) .getOrElse(null) - } private[codec] def toAvroRecord(record: Record[_]): Validation[String, SchemaAvro] = for { @@ -740,8 +758,8 @@ object AvroCodec extends AvroCodec { ) }) - - val caseSet = Validation.validateAll(cases.toList) + val caseSet = Validation + .validateAll(cases.toList) .flatMap(cases => { Validation( CaseSet(cases: _*).asInstanceOf[CaseSet { type EnumType = Z }] @@ -766,41 +784,43 @@ object AvroCodec extends AvroCodec { case first :: second :: Nil => Validation.succeed(Schema.either(first.schema, second.schema)) case _ => Validation.fail("ZIO schema wrapped either must have exactly two cases") } - case e: Schema.Either[_, _] => Validation.succeed(e) - case c: CaseClass0[_] => Validation.succeed(c) - case c: CaseClass1[_, _] => Validation.succeed(c) - case c: CaseClass2[_, _, _] => Validation.succeed(c) - case c: CaseClass3[_, _, _, _] => Validation.succeed(c) - case c: CaseClass4[_, _, _, _, _] => Validation.succeed(c) - case c: CaseClass5[_, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass6[_, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass7[_, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass8[_, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass9[_, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass10[_, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass11[_, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass12[_, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass13[_, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: CaseClass22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) - case c: Dynamic => Validation.succeed(c) - case c: GenericRecord => Validation.succeed(c) - case c: Map[_, _] => Validation.succeed(c) - case c: Sequence[_, _, _] => Validation.succeed(c) - case c: Set[_] => Validation.succeed(c) - case c: Fail[_] => Validation.succeed(c) - case c: Lazy[_] => Validation.succeed(c) - case c: Optional[_] => Validation.succeed(c) - case c: Primitive[_] => Validation.succeed(c) - case c: Transform[_, _, _] => Validation.succeed(c) - case c: Tuple2[_, _] => Validation.succeed(c) + case e: Schema.Either[_, _] => Validation.succeed(e) + case c: CaseClass0[_] => Validation.succeed(c) + case c: CaseClass1[_, _] => Validation.succeed(c) + case c: CaseClass2[_, _, _] => Validation.succeed(c) + case c: CaseClass3[_, _, _, _] => Validation.succeed(c) + case c: CaseClass4[_, _, _, _, _] => Validation.succeed(c) + case c: CaseClass5[_, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass6[_, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass7[_, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass8[_, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass9[_, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass10[_, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass11[_, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass12[_, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass13[_, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Validation.succeed(c) + case c: CaseClass21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Validation.succeed(c) + case c: CaseClass22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Validation.succeed(c) + case c: Dynamic => Validation.succeed(c) + case c: GenericRecord => Validation.succeed(c) + case c: Map[_, _] => Validation.succeed(c) + case c: Sequence[_, _, _] => Validation.succeed(c) + case c: Set[_] => Validation.succeed(c) + case c: Fail[_] => Validation.succeed(c) + case c: Lazy[_] => Validation.succeed(c) + case c: Optional[_] => Validation.succeed(c) + case c: Primitive[_] => Validation.succeed(c) + case c: Transform[_, _, _] => Validation.succeed(c) + case c: Tuple2[_, _] => Validation.succeed(c) } case None => Validation.fail("ZIO schema wrapped record must have a single field") @@ -830,8 +850,10 @@ object AvroCodec extends AvroCodec { private[codec] def toZioTuple(schema: SchemaAvro): Validation[String, Schema[_]] = for { - _ <- Validation.fromEither(scala.Either - .cond(schema.getFields.size() == 2, (), "Tuple must have exactly 2 fields:" + schema.toString(false))) + _ <- Validation.fromEither( + scala.Either + .cond(schema.getFields.size() == 2, (), "Tuple must have exactly 2 fields:" + schema.toString(false)) + ) _1 <- toZioSchema(schema.getFields.get(0).schema()) _2 <- toZioSchema(schema.getFields.get(1).schema()) } yield Schema.Tuple2(_1, _2, buildZioAnnotations(schema)) diff --git a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala index 9ec0d6add..d5e69673d 100644 --- a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala +++ b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala @@ -1,10 +1,10 @@ package zio.schema.codec import java.time.format.DateTimeFormatter -import java.time.temporal.{ChronoUnit, TemporalUnit} +import java.time.temporal.{ ChronoUnit, TemporalUnit } import scala.jdk.CollectionConverters._ import scala.util.Try -import org.apache.avro.{LogicalType, LogicalTypes, Schema => SchemaAvro} +import org.apache.avro.{ LogicalType, LogicalTypes, Schema => SchemaAvro } import zio.prelude.Validation sealed trait AvroPropMarker { @@ -58,13 +58,19 @@ object AvroPropMarker { val propName = "zio.schema.codec.avro.dateTimeFormatter" val default: Formatter = Formatter(DateTimeFormatter.ISO_INSTANT) - def fromAvroStringOrDefault(avroSchema: SchemaAvro, stringType: StringType): zio.prelude.Validation[String, Formatter] = + def fromAvroStringOrDefault( + avroSchema: SchemaAvro, + stringType: StringType + ): zio.prelude.Validation[String, Formatter] = fromAvroString(avroSchema).map { case Some(value) => value case None => getDefaultByStringType(stringType) } - def fromAvroStringOrDefault(avroSchema: SchemaAvro, logicalType: LogicalType): zio.prelude.Validation[String, Formatter] = + def fromAvroStringOrDefault( + avroSchema: SchemaAvro, + logicalType: LogicalType + ): zio.prelude.Validation[String, Formatter] = fromAvroString(avroSchema).map { case Some(value) => value case None => getDefaultByLogicalType(logicalType) diff --git a/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala b/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala index 7ec123e55..a857f259d 100644 --- a/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala +++ b/zio-schema-avro/shared/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala @@ -610,7 +610,9 @@ object AvroCodecSpec extends ZIOSpecDefault { Schema.primitive(StandardType.BigDecimalType).annotate(AvroAnnotations.decimal(DecimalType.Bytes)) val result = AvroCodec.encode(schema) - assert(result.toEither)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":48,"scale":24}"""))) + assert(result.toEither)( + isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":48,"scale":24}""")) + ) }, test("encodes BigDecimalType as Bytes with scala and precision") { val schema = Schema @@ -620,7 +622,9 @@ object AvroCodecSpec extends ZIOSpecDefault { .annotate(AvroAnnotations.precision(20)) val result = AvroCodec.encode(schema) - assert(result.toEither)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":20,"scale":10}"""))) + assert(result.toEither)( + isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":20,"scale":10}""")) + ) }, test("encodes BigDecimalType as Fixed") { val schema = @@ -656,7 +660,9 @@ object AvroCodecSpec extends ZIOSpecDefault { Schema.primitive(StandardType.BigIntegerType).annotate(AvroAnnotations.decimal(DecimalType.Bytes)) val result = AvroCodec.encode(schema) - assert(result.toEither)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":24,"scale":24}"""))) + assert(result.toEither)( + isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":24,"scale":24}""")) + ) }, test("encodes BigIntegerType as Bytes with scala and precision") { val schema = Schema @@ -666,7 +672,9 @@ object AvroCodecSpec extends ZIOSpecDefault { .annotate(AvroAnnotations.precision(20)) val result = AvroCodec.encode(schema) - assert(result.toEither)(isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":10,"scale":10}"""))) + assert(result.toEither)( + isRight(equalTo("""{"type":"bytes","logicalType":"decimal","precision":10,"scale":10}""")) + ) }, test("encodes BigIntegerType as Fixed") { val schema = @@ -1236,7 +1244,9 @@ object AvroCodecSpec extends ZIOSpecDefault { val s = """{"type":"enum","name":"TestEnum","default":"d","symbols":["a","b","c"]}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema.toEither.left.map(_.head))(isLeft(equalTo("The Enum Default: d is not in the enum symbol set: [a, b, c]"))) + assert(schema.toEither.left.map(_.head))( + isLeft(equalTo("The Enum Default: d is not in the enum symbol set: [a, b, c]")) + ) }, test("not assign the enum default annotation if empty") { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" @@ -1392,7 +1402,9 @@ object AvroCodecSpec extends ZIOSpecDefault { """{"type":"fixed","name":"Decimal_10_10","size":5,"logicalType":"decimal","precision":9,"scale":10}""" val schema = AvroCodec.decode(Chunk.fromArray(s.getBytes())) - assert(schema.toEither.left.map(_.head))(isLeft(equalTo("Invalid decimal scale: 10 (greater than precision: 9)"))) + assert(schema.toEither.left.map(_.head))( + isLeft(equalTo("Invalid decimal scale: 10 (greater than precision: 9)")) + ) }, test("decode as binary") { val s = """{"type":"fixed","name":"Something","size":5}""" diff --git a/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec$.scala b/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec$.scala index 1a31a0ec2..45ba1375c 100644 --- a/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec$.scala +++ b/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec$.scala @@ -45,9 +45,9 @@ object SchemaSchemaValidationSpec$ extends ZIOSpecDefault { override def spec: Spec[Environment, Any] = suite("Schema Validation Spec")( test("Invalid CaseClass1 creation") { - val grade = Grade(-50) - implicit val gradeSchema: Schema[Grade] = schemaGrade - val validated: Chunk[SchemaValidationError] = Schema.validate(grade) + val grade = Grade(-50) + implicit val gradeSchema: Schema[Grade] = schemaGrade + val validated: Chunk[SchemaValidationError] = Schema.validate(grade) val expected: Chunk[SchemaValidationError] = Chunk(SchemaValidationError.GreaterThan(-50, 0)) @@ -55,18 +55,18 @@ object SchemaSchemaValidationSpec$ extends ZIOSpecDefault { assert(validated)(Assertion.hasSameElements(expected)) }, test("Valid CaseClass1 creation") { - val grade = Grade(97) - implicit val gradeSchema: Schema[Grade] = schemaGrade - val validated: Chunk[SchemaValidationError] = Schema.validate(grade) + val grade = Grade(97) + implicit val gradeSchema: Schema[Grade] = schemaGrade + val validated: Chunk[SchemaValidationError] = Schema.validate(grade) val expected: Chunk[SchemaValidationError] = Chunk.empty assert(validated)(equalTo(expected)) }, test("Invalid CaseClass2 creation") { - val person = Person("Michelle", 200) - implicit val personSchema: Schema[Person] = schemaPerson - val validated: Chunk[SchemaValidationError] = Schema.validate(person) + val person = Person("Michelle", 200) + implicit val personSchema: Schema[Person] = schemaPerson + val validated: Chunk[SchemaValidationError] = Schema.validate(person) val expected: Chunk[SchemaValidationError] = Chunk(SchemaValidationError.LessThan(200, 120), SchemaValidationError.EqualTo(200, 120)) @@ -74,9 +74,9 @@ object SchemaSchemaValidationSpec$ extends ZIOSpecDefault { assert(validated)(Assertion.hasSameElements(expected)) }, test("Valid CaseClass2 creation") { - val person = Person("Michelle", 20) - implicit val personSchema: Schema[Person] = schemaPerson - val validated: Chunk[SchemaValidationError] = Schema.validate(person) + val person = Person("Michelle", 20) + implicit val personSchema: Schema[Person] = schemaPerson + val validated: Chunk[SchemaValidationError] = Schema.validate(person) val expected: Chunk[SchemaValidationError] = Chunk.empty 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 4fd3db45a..1a5826525 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 @@ -4,31 +4,37 @@ import java.nio.CharBuffer import java.nio.charset.StandardCharsets import scala.collection.immutable.ListMap import zio.json.JsonCodec._ -import zio.json.JsonDecoder.{JsonError, UnsafeJson} +import zio.json.JsonDecoder.{ JsonError, UnsafeJson } import zio.json.ast.Json -import zio.json.internal.{Lexer, RecordingReader, RetractReader, StringMatrix, Write} -import zio.json.{JsonFieldDecoder, JsonFieldEncoder, JsonCodec => ZJsonCodec, JsonDecoder => ZJsonDecoder, JsonEncoder => ZJsonEncoder} -import zio.prelude.{Validation, ZValidation} +import zio.json.internal.{ Lexer, RecordingReader, RetractReader, StringMatrix, Write } +import zio.json.{ + JsonFieldDecoder, + JsonFieldEncoder, + JsonCodec => ZJsonCodec, + JsonDecoder => ZJsonDecoder, + JsonEncoder => ZJsonEncoder +} +import zio.prelude.{ Validation, ZValidation } import zio.schema._ import zio.schema.annotation._ import zio.schema.codec.DecodeError.ReadError import zio.stream.ZPipeline -import zio.{Cause, Chunk, ChunkBuilder, NonEmptyChunk, ZIO, prelude} +import zio.{ Cause, Chunk, ChunkBuilder, NonEmptyChunk, ZIO, prelude } object JsonCodec { type DiscriminatorTuple = Chunk[(discriminatorName, String)] implicit def zioJsonBinaryCodec[A](implicit jsonCodec: ZJsonCodec[A]): BinaryCodec[A] = new BinaryCodec[A] { - override def decode(whole: Chunk[Byte]): Validation[DecodeError, A] = { - Validation.fromEither( - jsonCodec - .decodeJson( - new String(whole.toArray, JsonEncoder.CHARSET) + override def decode(whole: Chunk[Byte]): Validation[DecodeError, A] = + Validation + .fromEither( + jsonCodec + .decodeJson( + new String(whole.toArray, JsonEncoder.CHARSET) + ) ) - ) .mapError(failure => DecodeError.ReadError(Cause.empty, failure)) - } override def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] = ZPipeline.fromChannel( @@ -365,12 +371,11 @@ object JsonCodec { case Validation.Success(_, a) => innerEncoder.unsafeEncode(a, indent, out) } - override def isNothing(b: B): Boolean = { + override def isNothing(b: B): Boolean = g(b) match { case Validation.Failure(_, _) => false case Validation.Success(_, a) => innerEncoder.isNothing(a) } - } } private def enumEncoder[Z](parentSchema: Schema.Enum[Z], cases: Schema.Case[Z, _]*): ZJsonEncoder[Z] = diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index 5495ade59..ad562577a 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -1,19 +1,19 @@ package zio.schema.codec -import java.time.{ZoneId, ZoneOffset} +import java.time.{ ZoneId, ZoneOffset } import scala.collection.immutable.ListMap import zio.Console._ import zio._ import zio.json.JsonDecoder.JsonError -import zio.json.{DeriveJsonEncoder, JsonEncoder} +import zio.json.{ DeriveJsonEncoder, JsonEncoder } import zio.prelude.Validation import zio.schema.CaseSet._ import zio.schema._ import zio.schema.annotation._ import zio.schema.codec.DecodeError.ReadError import zio.schema.codec.JsonCodec.JsonEncoder.charSequenceToByteChunk -import zio.schema.codec.JsonCodecSpec.PaymentMethod.{CreditCard, PayPal, WireTransfer} -import zio.schema.codec.JsonCodecSpec.Subscription.{OneTime, Recurring} +import zio.schema.codec.JsonCodecSpec.PaymentMethod.{ CreditCard, PayPal, WireTransfer } +import zio.schema.codec.JsonCodecSpec.Subscription.{ OneTime, Recurring } import zio.schema.meta.MetaSchema import zio.stream.ZStream import zio.test.Assertion._ diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala index 18495c94c..3e176d109 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala @@ -2,12 +2,12 @@ package zio.schema.codec import zio.prelude.Validation -import java.math.{BigInteger, MathContext} +import java.math.{ BigInteger, MathContext } import java.time._ import zio.schema.codec.DecodeError.ReadError -import zio.schema.{Schema, StandardType} +import zio.schema.{ Schema, StandardType } import zio.stream.ZPipeline -import zio.{Cause, Chunk, ZIO} +import zio.{ Cause, Chunk, ZIO } object MessagePackCodec { implicit def messagePackCodec[A](implicit schema: Schema[A]): BinaryCodec[A] = diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala index 218dde1b5..76e0dcd5f 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala @@ -5,13 +5,13 @@ import java.util.UUID import scala.annotation.tailrec import scala.collection.immutable.ListMap import scala.util.control.NonFatal -import scala.util.{Failure, Success, Try} -import org.msgpack.core.{MessagePack, MessageUnpacker} -import zio.prelude.{Validation, ZValidation} +import scala.util.{ Failure, Success, Try } +import org.msgpack.core.{ MessagePack, MessageUnpacker } +import zio.prelude.{ Validation, ZValidation } import zio.schema.codec.DecodeError.MalformedFieldWithPath import zio.schema.codec.MessagePackDecoder._ -import zio.schema.{DynamicValue, Schema, StandardType} -import zio.{Chunk, ChunkBuilder} +import zio.schema.{ DynamicValue, Schema, StandardType } +import zio.{ Chunk, ChunkBuilder } private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { private val unpacker = MessagePack.newDefaultUnpacker(bytes.toArray) @@ -120,13 +120,13 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { fields.get(fieldName) match { case Some(fieldSchema) => decodeValue(actualPath, fieldSchema) match { - case f@ Validation.Failure(_, _) => f + case f @ Validation.Failure(_, _) => f case Validation.Success(_, value) => if (index == fields.size) { - succeed(m.updated(fieldName, value)) - } else { - readFields(m.updated(fieldName, value), index + 1) - } + succeed(m.updated(fieldName, value)) + } else { + readFields(m.updated(fieldName, value), index + 1) + } } // .flatMap(value => { // if (index == fields.size) { @@ -177,8 +177,8 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { def decodeElements(n: Int, cb: ChunkBuilder[A]): Result[Chunk[A]] = if (n > 0) { decodeValue(path, elementSchema) match { - case zio.prelude.Validation.Success(_, elem) => decodeElements(n - 1, cb += elem) - case failure@ zio.prelude.Validation.Failure(_, _) => failure + case zio.prelude.Validation.Success(_, elem) => decodeElements(n - 1, cb += elem) + case failure @ zio.prelude.Validation.Failure(_, _) => failure } } else { succeed(cb.result()) diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala index 1108c54d3..6b57294df 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala @@ -6,7 +6,7 @@ import scala.collection.immutable.ListMap import org.msgpack.core.MessagePack import zio.Chunk import zio.prelude.data.Optional.AllValuesAreNullable -import zio.schema.{DynamicValue, Schema, StandardType} +import zio.schema.{ DynamicValue, Schema, StandardType } private[codec] class MessagePackEncoder { private val packer = MessagePack.newDefaultBufferPacker() @@ -21,16 +21,16 @@ private[codec] class MessagePackEncoder { //scalafmt: { maxColumn = 400, optIn.configStyleArguments = false } private def encodeValue[A](schema: Schema[A], value: A): Unit = (schema, value) match { - case (Schema.GenericRecord(_, structure, _), v: Map[String, _]) => encodeRecord(structure.toChunk, v) - case (Schema.Sequence(element, _, g, _, _), v) => encodeSequence(element, g(v)) - case (mapSchema: Schema.Map[_, _], map: Map[_, _]) => encodeMap(mapSchema.asInstanceOf[Schema.Map[Any, Any]], map.asInstanceOf[scala.collection.immutable.Map[Any, Any]]) - case (setSchema: Schema.Set[_], set: Set[_]) => encodeSet(setSchema.asInstanceOf[Schema.Set[Any]].elementSchema, set.asInstanceOf[scala.collection.immutable.Set[Any]]) - case (Schema.Transform(schema, _, g, _, _), _) => g(value).map(v => encodeValue(schema, v)): Unit - case (Schema.Primitive(standardType, _), v) => encodePrimitive(standardType, v) - case (Schema.Tuple2(left, right, _), v @ (_, _)) => encodeTuple(left, right, v) - case (optSchema: Schema.Optional[_], v: Option[_]) => encodeOptional(optSchema.asInstanceOf[Schema.Optional[Any]].schema, v.asInstanceOf[Option[Any]]) - case (eitherSchema: Schema.Either[_, _], v: Either[_, _]) => encodeEither(eitherSchema.asInstanceOf[Schema.Either[Any, Any]].left, eitherSchema.asInstanceOf[Schema.Either[Any, Any]].right, v.asInstanceOf[scala.Either[Any, Any]]) - case (lzy @ Schema.Lazy(_), v) => encodeValue(lzy.schema, v) + case (Schema.GenericRecord(_, structure, _), v: Map[String, _]) => encodeRecord(structure.toChunk, v) + case (Schema.Sequence(element, _, g, _, _), v) => encodeSequence(element, g(v)) + case (mapSchema: Schema.Map[_, _], map: Map[_, _]) => encodeMap(mapSchema.asInstanceOf[Schema.Map[Any, Any]], map.asInstanceOf[scala.collection.immutable.Map[Any, Any]]) + case (setSchema: Schema.Set[_], set: Set[_]) => encodeSet(setSchema.asInstanceOf[Schema.Set[Any]].elementSchema, set.asInstanceOf[scala.collection.immutable.Set[Any]]) + case (Schema.Transform(schema, _, g, _, _), _) => g(value).map(v => encodeValue(schema, v)): Unit + case (Schema.Primitive(standardType, _), v) => encodePrimitive(standardType, v) + case (Schema.Tuple2(left, right, _), v @ (_, _)) => encodeTuple(left, right, v) + case (optSchema: Schema.Optional[_], v: Option[_]) => encodeOptional(optSchema.asInstanceOf[Schema.Optional[Any]].schema, v.asInstanceOf[Option[Any]]) + case (eitherSchema: Schema.Either[_, _], v: Either[_, _]) => encodeEither(eitherSchema.asInstanceOf[Schema.Either[Any, Any]].left, eitherSchema.asInstanceOf[Schema.Either[Any, Any]].right, v.asInstanceOf[scala.Either[Any, Any]]) + case (lzy @ Schema.Lazy(_), v) => encodeValue(lzy.schema, v) // case (Schema.Meta(ast, _), _) => encodeValue(fieldNumber, Schema[MetaSchema], ast) case (Schema.CaseClass0(_, _, _), _) => encodePrimitive(StandardType.UnitType, ()) case (Schema.CaseClass1(_, f, _, _), v) => encodeCaseClass(v, f) diff --git a/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala b/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala index 505f50492..1d8de67db 100644 --- a/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala +++ b/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala @@ -6,14 +6,14 @@ import scala.collection.immutable.ListMap import scala.util.Try import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.scala.DefaultScalaModule -import org.msgpack.core.{MessagePack, MessagePacker} +import org.msgpack.core.{ MessagePack, MessagePacker } import org.msgpack.jackson.dataformat.MessagePackFactory import zio.schema.CaseSet.caseOf import zio.schema._ -import zio.stream.{ZSink, ZStream} +import zio.stream.{ ZSink, ZStream } import zio.test.Assertion._ import zio.test._ -import zio.{Chunk, Console, NonEmptyChunk, Scope, Task, ZIO} +import zio.{ Chunk, Console, NonEmptyChunk, Scope, Task, ZIO } object MessagePackCodecSpec extends ZIOSpecDefault { @@ -1003,7 +1003,11 @@ object MessagePackCodecSpec extends ZIOSpecDefault { .run(ZSink.collectAll) //NS == non streaming variant of encodeAndDecode - def encodeAndDecodeNS[A](schema: Schema[A], input: A, print: Boolean = false): ZIO[Any, NonEmptyChunk[DecodeError], A] = + def encodeAndDecodeNS[A]( + schema: Schema[A], + input: A, + print: Boolean = false + ): ZIO[Any, NonEmptyChunk[DecodeError], A] = ZIO .succeed(input) .tap(value => Console.printLine(s"Input Value: $value").when(print).ignore) @@ -1012,7 +1016,11 @@ object MessagePackCodecSpec extends ZIOSpecDefault { .map(ch => MessagePackCodec.messagePackCodec(schema).decode(ch).toEither) .absolve - def encodeAndDecodeNS[A](encodeSchema: Schema[A], decodeSchema: Schema[A], input: A): ZIO[Any, NonEmptyChunk[DecodeError], A] = + def encodeAndDecodeNS[A]( + encodeSchema: Schema[A], + decodeSchema: Schema[A], + input: A + ): ZIO[Any, NonEmptyChunk[DecodeError], A] = ZIO .succeed(input) .map(a => MessagePackCodec.messagePackCodec(encodeSchema).encode(a)) 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 b2066376c..e22247da6 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 @@ -3,7 +3,7 @@ package zio.schema.codec import zio.prelude.Validation import java.nio.charset.StandardCharsets -import java.nio.{ByteBuffer, ByteOrder} +import java.nio.{ ByteBuffer, ByteOrder } import java.time._ import java.time.format.DateTimeFormatter import java.util.UUID @@ -11,10 +11,10 @@ import scala.collection.immutable.ListMap import scala.util.control.NonFatal import zio.schema.MutableSchemaBasedValueBuilder.CreateValueFromSchemaError import zio.schema._ -import zio.schema.codec.DecodeError.{ExtraFields, MalformedField, MissingField} +import zio.schema.codec.DecodeError.{ ExtraFields, MalformedField, MissingField } import zio.schema.codec.ProtobufCodec.Protobuf.WireType.LengthDelimited import zio.stream.ZPipeline -import zio.{Cause, Chunk, ChunkBuilder, Unsafe, ZIO} +import zio.{ Cause, Chunk, ChunkBuilder, Unsafe, ZIO } object ProtobufCodec { @@ -24,7 +24,9 @@ object ProtobufCodec { new Decoder(whole).decode(schema) override def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] = - ZPipeline.mapChunksZIO(chunk => ZIO.fromEither(new Decoder(chunk).decode(schema).map(Chunk(_)).toEither.left.map(_.head))) + ZPipeline.mapChunksZIO( + chunk => ZIO.fromEither(new Decoder(chunk).decode(schema).map(Chunk(_)).toEither.left.map(_.head)) + ) override def encode(value: A): Chunk[Byte] = Encoder.process(schema, value) @@ -494,17 +496,16 @@ object ProtobufCodec { private val state: DecoderState = new DecoderState(chunk, 0) def decode[A](schema: Schema[A]): zio.prelude.Validation[DecodeError, A] = - Validation(create(schema).asInstanceOf[A]) - .mapError { - case CreateValueFromSchemaError(_, cause) => - cause match { - case error: DecodeError => error - case _ => - DecodeError.ReadError(Cause.fail(cause), cause.getMessage) - } - case NonFatal(err) => - DecodeError.ReadError(Cause.fail(err), err.getMessage) - } + Validation(create(schema).asInstanceOf[A]).mapError { + case CreateValueFromSchemaError(_, cause) => + cause match { + case error: DecodeError => error + case _ => + DecodeError.ReadError(Cause.fail(cause), cause.getMessage) + } + case NonFatal(err) => + DecodeError.ReadError(Cause.fail(err), err.getMessage) + } private def createTypedPrimitive[A](context: DecoderContext, standardType: StandardType[A]): A = createPrimitive(context, standardType).asInstanceOf[A] @@ -623,7 +624,9 @@ object ProtobufCodec { ): Any = Unsafe.unsafe { implicit u => //TODO: Maybe combine exceptions? - record.construct(values.map(_._2)).fold(message => throw DecodeError.ReadError(Cause.empty, message.toString()), a => a) + record + .construct(values.map(_._2)) + .fold(message => throw DecodeError.ReadError(Cause.empty, message.toString()), a => a) } override protected def startCreatingEnum( @@ -874,10 +877,9 @@ object ProtobufCodec { value: Any, f: Any => zio.prelude.Validation[String, Any], schema: Schema[_] - ): Any = { + ): Any = //TODO: Maybe combine exceptions? - f(value).fold(v => throw MalformedField(schema, v.toString()) , a => a) - } + f(value).fold(v => throw MalformedField(schema, v.toString()), a => a) override protected def fail(context: DecoderContext, message: String): Any = throw DecodeError.ReadError(Cause.empty, message) diff --git a/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala b/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala index 4f7f7d376..7adc61075 100644 --- a/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala +++ b/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala @@ -1044,7 +1044,8 @@ object ProtobufCodecSpec extends ZIOSpecDefault { //NS == non streaming variant of decode def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, DecodeError, A] = - ZIO.succeed(ProtobufCodec.protobufCodec(schema).decode(fromHex(hex))) + ZIO + .succeed(ProtobufCodec.protobufCodec(schema).decode(fromHex(hex))) .map(_.toEither.left.map(_.head)) .absolve[DecodeError, A] @@ -1100,7 +1101,8 @@ object ProtobufCodecSpec extends ZIOSpecDefault { .tap(encoded => printLine(s"\nEncoded Bytes:\n${toHex(encoded)}").when(print).ignore) .map(ch => ProtobufCodec.protobufCodec(schema).decode(ch)) .tapSome { - case prelude.Validation.Failure(_, err) => printLine(s"Failed to encode and decode value $input\nError = $err").orDie + case prelude.Validation.Failure(_, err) => + printLine(s"Failed to encode and decode value $input\nError = $err").orDie } def encodeAndDecodeNS[A](encodeSchema: Schema[A], decodeSchema: Schema[A], input: A): ZIO[Any, DecodeError, A] = diff --git a/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala b/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala index 51a520585..b8e73df44 100644 --- a/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala +++ b/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala @@ -3,17 +3,23 @@ package zio.schema.codec import java.nio.ByteBuffer import java.time._ import java.util.UUID -import scala.annotation.{nowarn, tailrec} +import scala.annotation.{ nowarn, tailrec } import scala.collection.immutable.ListMap import scala.util.control.NonFatal import org.apache.thrift.protocol._ import zio.prelude.Validation import zio.schema.MutableSchemaBasedValueBuilder.CreateValueFromSchemaError import zio.schema._ -import zio.schema.annotation.{fieldDefaultValue, optionalField, transientField} -import zio.schema.codec.DecodeError.{EmptyContent, MalformedField, MalformedFieldWithPath, ReadError, ReadErrorWithPath} +import zio.schema.annotation.{ fieldDefaultValue, optionalField, transientField } +import zio.schema.codec.DecodeError.{ + EmptyContent, + MalformedField, + MalformedFieldWithPath, + ReadError, + ReadErrorWithPath +} import zio.stream.ZPipeline -import zio.{Cause, Chunk, NonEmptyChunk, Unsafe, ZIO} +import zio.{ Cause, Chunk, NonEmptyChunk, Unsafe, ZIO } object ThriftCodec { @@ -46,11 +52,12 @@ object ThriftCodec { if (chunk.isEmpty) Validation.fail(EmptyContent("No bytes to decode")) else { - zio.prelude.Validation( - new Decoder(chunk) - .create(schema) - .asInstanceOf[A] - ) + zio.prelude + .Validation( + new Decoder(chunk) + .create(schema) + .asInstanceOf[A] + ) .mapError { case error: CreateValueFromSchemaError[DecoderContext] => error.cause match { diff --git a/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala b/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala index 09263c0b2..8b97aca53 100644 --- a/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala +++ b/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala @@ -1,20 +1,37 @@ package zio.schema.codec -import java.time.{DayOfWeek, Duration, Instant, LocalDate, LocalDateTime, LocalTime, Month, MonthDay, OffsetDateTime, OffsetTime, Period, Year, YearMonth, ZoneId, ZoneOffset, ZonedDateTime} +import java.time.{ + DayOfWeek, + Duration, + Instant, + LocalDate, + LocalDateTime, + LocalTime, + Month, + MonthDay, + OffsetDateTime, + OffsetTime, + Period, + Year, + YearMonth, + ZoneId, + ZoneOffset, + ZonedDateTime +} import java.util import java.util.UUID import scala.collection.immutable.ListMap import scala.util.Try import org.apache.thrift.TSerializable -import org.apache.thrift.protocol.{TBinaryProtocol, TField, TType} +import org.apache.thrift.protocol.{ TBinaryProtocol, TField, TType } import zio.schema.CaseSet.caseOf -import zio.schema.annotation.{fieldDefaultValue, optionalField, transientField} -import zio.schema.codec.{generated => g} -import zio.schema.{CaseSet, DeriveSchema, DynamicValue, DynamicValueGen, Schema, SchemaGen, StandardType, TypeId} -import zio.stream.{ZSink, ZStream} +import zio.schema.annotation.{ fieldDefaultValue, optionalField, transientField } +import zio.schema.codec.{ generated => g } +import zio.schema.{ CaseSet, DeriveSchema, DynamicValue, DynamicValueGen, Schema, SchemaGen, StandardType, TypeId } +import zio.stream.{ ZSink, ZStream } import zio.test.Assertion._ import zio.test._ -import zio.{Chunk, Console, NonEmptyChunk, Scope, Task, ZIO} +import zio.{ Chunk, Console, NonEmptyChunk, Scope, Task, ZIO } // TODO: use generators instead of manual encode/decode @@ -1129,7 +1146,11 @@ object ThriftCodecSpec extends ZIOSpecDefault { .run(ZSink.collectAll) //NS == non streaming variant of encodeAndDecode - def encodeAndDecodeNS[A](schema: Schema[A], input: A, print: Boolean = false): ZIO[Any, NonEmptyChunk[DecodeError], A] = + def encodeAndDecodeNS[A]( + schema: Schema[A], + input: A, + print: Boolean = false + ): ZIO[Any, NonEmptyChunk[DecodeError], A] = ZIO .succeed(input) .tap(value => Console.printLine(s"Input Value: $value").when(print).ignore) @@ -1139,7 +1160,11 @@ object ThriftCodecSpec extends ZIOSpecDefault { .map(_.toEither) .absolve - def encodeAndDecodeNS[A](encodeSchema: Schema[A], decodeSchema: Schema[A], input: A): ZIO[Any, NonEmptyChunk[DecodeError], A] = + def encodeAndDecodeNS[A]( + encodeSchema: Schema[A], + decodeSchema: Schema[A], + input: A + ): ZIO[Any, NonEmptyChunk[DecodeError], A] = ZIO .succeed(input) .map(a => ThriftCodec.thriftCodec(encodeSchema).encode(a)) diff --git a/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala b/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala index 0ff84b645..2f62202c0 100644 --- a/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala +++ b/zio-schema-zio-test/shared/src/test/scala/zio/schema/TestData.scala @@ -56,7 +56,8 @@ object TestData { val optionalSchema: Schema[Option[Int]] = Schema.Optional(intSchema) val transformSchema: Schema[String] = - intSchema.transformOrFail[String]((int: Int) => Validation.succeed(int.toString), (_: String) => Validation.fail("error")) + intSchema + .transformOrFail[String]((int: Int) => Validation.succeed(int.toString), (_: String) => Validation.fail("error")) val failSchema: Schema[Unit] = Schema.Fail[Unit]("failed") val lazySchema: Schema[Int] = Schema.Lazy(() => intSchema) diff --git a/zio-schema/shared/src/main/scala/zio/schema/codec/BinaryCodecs.scala b/zio-schema/shared/src/main/scala/zio/schema/codec/BinaryCodecs.scala index 89b1c26fe..12e1c785b 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/codec/BinaryCodecs.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/codec/BinaryCodecs.scala @@ -32,7 +32,9 @@ object BinaryCodecs { override def streamEncoder[T](implicit ev: IsElementOf[T, Types]): ZPipeline[Any, Nothing, T, Byte] = instances.withInstance((codec: BinaryCodec[T]) => codec.streamEncoder) - override def decode[T](whole: Chunk[Byte])(implicit ev: IsElementOf[T, Types]): zio.prelude.Validation[DecodeError, T] = + override def decode[T]( + whole: Chunk[Byte] + )(implicit ev: IsElementOf[T, Types]): zio.prelude.Validation[DecodeError, T] = instances.withInstance((codec: BinaryCodec[T]) => codec.decode(whole)) override def streamDecoder[T](implicit ev: IsElementOf[T, Types]): ZPipeline[Any, DecodeError, Byte, T] = diff --git a/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala b/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala index 5b45d7d38..3760b19b9 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala @@ -37,7 +37,9 @@ object Codecs { final override def streamEncoder[T](implicit ev: IsElementOf[T, Types]): ZPipeline[Any, Nothing, T, Element] = instances.withInstance((codec: Codec[Whole, Element, T]) => codec.streamEncoder) - final override def decode[T](whole: Whole)(implicit ev: IsElementOf[T, Types]): zio.prelude.Validation[DecodeError, T] = + final override def decode[T]( + whole: Whole + )(implicit ev: IsElementOf[T, Types]): zio.prelude.Validation[DecodeError, T] = instances.withInstance((codec: Codec[Whole, Element, T]) => codec.decode(whole)) final override def streamDecoder[T](implicit ev: IsElementOf[T, Types]): ZPipeline[Any, DecodeError, Element, T] = diff --git a/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala b/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala index a75f88efd..2d284485c 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/codec/DecodeError.scala @@ -34,7 +34,8 @@ object DecodeError { final case class ReadErrorWithPath(path: Chunk[String], cause: Cause[Any], message: String) extends DecodeError - final case class ValidationError(validation: SchemaValidation[_], field: Field[_, _], message: String) extends DecodeError + final case class ValidationError(validation: SchemaValidation[_], field: Field[_, _], message: String) + extends DecodeError final case class ExtraFields(fieldName: String, message: String) extends DecodeError From ae4539c6c25e4616bb2c860711f9786281d0a3bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=8BAndrzej=20Ressel?= Date: Fri, 19 May 2023 03:37:33 +0200 Subject: [PATCH 5/6] Merge master --- .../test/scala-2/zio/schema/SchemaGen.scala | 1 + .../scala/zio/schema/DefaultValueSpec.scala | 2 +- .../test/scala/zio/schema/SchemaSpec.scala | 1 + .../scala/zio/schema/codec/AvroCodec.scala | 5 ++++- .../zio/schema/codec/AvroPropMarker.scala | 4 +++- .../zio/schema/codec/BsonSchemaCodec.scala | 22 ++++++++++--------- .../scala/zio/schema/codec/JsonCodec.scala | 12 +++++----- .../zio/schema/codec/JsonCodecSpec.scala | 2 ++ .../zio/schema/codec/MessagePackCodec.scala | 4 ++-- .../zio/schema/codec/MessagePackDecoder.scala | 5 ++++- .../zio/schema/codec/MessagePackEncoder.scala | 4 +++- .../schema/codec/MessagePackCodecSpec.scala | 3 +++ .../zio/schema/codec/ProtobufCodec.scala | 5 +++-- .../scala/zio/schema/codec/ThriftCodec.scala | 13 +++++------ .../zio/schema/codec/ThriftCodecSpec.scala | 3 +++ .../src/main/scala/zio/schema/Differ.scala | 9 ++++---- .../main/scala/zio/schema/DynamicValue.scala | 5 +++-- .../src/main/scala/zio/schema/Patch.scala | 13 ++++++----- .../src/main/scala/zio/schema/Schema.scala | 7 +++--- .../main/scala/zio/schema/StandardType.scala | 1 + .../scala/zio/schema/meta/Migration.scala | 4 ++-- .../validation/SchemaValidationSpec$.scala | 2 ++ 22 files changed, 78 insertions(+), 49 deletions(-) diff --git a/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala b/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala index 9b3bcf563..139f8aba9 100644 --- a/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala +++ b/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala @@ -1,6 +1,7 @@ package zio.schema import scala.collection.immutable.ListMap + import zio.Chunk import zio.prelude.Validation import zio.test.{ Gen, Sized } diff --git a/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala b/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala index d04213060..25783d033 100644 --- a/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/DefaultValueSpec.scala @@ -1,10 +1,10 @@ package zio.schema -import zio.{ Chunk, NonEmptyChunk } import zio.schema.CaseSet.caseOf import zio.schema.Schema.{ Lazy, Primitive } import zio.test.Assertion._ import zio.test.{ Spec, ZIOSpecDefault, assert } +import zio.{ Chunk, NonEmptyChunk } object DefaultValueSpec extends ZIOSpecDefault { // Record Tests diff --git a/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala b/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala index 604cb359e..b1208011d 100644 --- a/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/SchemaSpec.scala @@ -1,6 +1,7 @@ package zio.schema import scala.collection.immutable.ListMap + import zio.Chunk import zio.prelude.Validation import zio.schema.CaseSet._ diff --git a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala index 4bc1549af..c3e9c8d92 100644 --- a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala +++ b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroCodec.scala @@ -3,11 +3,14 @@ package zio.schema.codec import java.nio.charset.StandardCharsets import java.time.format.DateTimeFormatter import java.time.{ Duration, Month, MonthDay, Period, Year, YearMonth } + import scala.annotation.StaticAnnotation import scala.collection.immutable.ListMap import scala.jdk.CollectionConverters._ -import scala.util.{ Right, Try } +import scala.util.Try + import org.apache.avro.{ LogicalTypes, Schema => SchemaAvro } + import zio.Chunk import zio.prelude.Validation import zio.schema.CaseSet.Aux diff --git a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala index d5e69673d..b23a83910 100644 --- a/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala +++ b/zio-schema-avro/shared/src/main/scala/zio/schema/codec/AvroPropMarker.scala @@ -2,9 +2,11 @@ package zio.schema.codec import java.time.format.DateTimeFormatter import java.time.temporal.{ ChronoUnit, TemporalUnit } + import scala.jdk.CollectionConverters._ -import scala.util.Try + import org.apache.avro.{ LogicalType, LogicalTypes, Schema => SchemaAvro } + import zio.prelude.Validation sealed trait AvroPropMarker { diff --git a/zio-schema-bson/shared/src/main/scala/zio/schema/codec/BsonSchemaCodec.scala b/zio-schema-bson/shared/src/main/scala/zio/schema/codec/BsonSchemaCodec.scala index 4e57c31fe..32e8d7e37 100644 --- a/zio-schema-bson/shared/src/main/scala/zio/schema/codec/BsonSchemaCodec.scala +++ b/zio-schema-bson/shared/src/main/scala/zio/schema/codec/BsonSchemaCodec.scala @@ -25,6 +25,7 @@ import zio.bson.{ bsonHint, bsonNoExtraFields } +import zio.prelude.{ Validation, ZValidation } import zio.schema.annotation.{ caseName, caseNameAliases, @@ -507,20 +508,21 @@ object BsonSchemaCodec { } } - private def transformEncoder[A, B](schema: Schema[A], g: B => Either[String, A]): BsonEncoder[B] = + private def transformEncoder[A, B](schema: Schema[A], g: B => Validation[String, A]): BsonEncoder[B] = new BsonEncoder[B] { private lazy val innerEncoder = schemaEncoder(schema) override def encode(writer: BsonWriter, b: B, ctx: BsonEncoder.EncoderContext): Unit = g(b) match { - case Left(_) => () - case Right(a) => innerEncoder.encode(writer, a, ctx) + case ZValidation.Failure(_, _) => () + case ZValidation.Success(_, value) => innerEncoder.encode(writer, value, ctx) } override def toBsonValue(b: B): BsonValue = g(b) match { - case Left(_) => BsonNull.VALUE - case Right(a) => innerEncoder.toBsonValue(a) + case ZValidation.Failure(_, _) => BsonNull.VALUE + case ZValidation.Success(_, value) => innerEncoder.toBsonValue(value) + } } @@ -689,7 +691,7 @@ object BsonSchemaCodec { case Schema.Primitive(standardType, _) => primitiveCodec(standardType).decoder case Schema.Optional(codec, _) => BsonDecoder.option(schemaDecoder(codec)) case Schema.Tuple2(left, right, _) => tuple2Decoder(schemaDecoder(left), schemaDecoder(right)) - case Schema.Transform(codec, f, _, _, _) => schemaDecoder(codec).mapOrFail(f) + case Schema.Transform(codec, f, _, _, _) => schemaDecoder(codec).mapOrFail(g => f(g).toEither.left.map(_.head)) case Schema.Sequence(codec, f, _, _, _) => chunkDecoder(schemaDecoder(codec)).map(f) case Schema.Map(ks, vs, _) => mapDecoder(ks, vs) case Schema.Set(s, _) => chunkDecoder(schemaDecoder(s)).map(entries => entries.toSet) @@ -1174,8 +1176,8 @@ object BsonSchemaCodec { Unsafe.unsafe { implicit u => caseClassSchema.construct(Chunk.fromArray(ps)) match { - case Left(err) => throw BsonDecoder.Error(trace, s"Failed to construct case class: $err") - case Right(value) => value + case ZValidation.Failure(_, err) => throw BsonDecoder.Error(trace, s"Failed to construct case class: $err") + case ZValidation.Success(_, value) => value } } } @@ -1216,8 +1218,8 @@ object BsonSchemaCodec { Unsafe.unsafe { implicit u => caseClassSchema.construct(Chunk.fromArray(ps)) match { - case Left(err) => throw BsonDecoder.Error(trace, s"Failed to construct case class: $err") - case Right(value) => value + case ZValidation.Failure(_, errors) => throw BsonDecoder.Error(trace, s"Failed to construct case class: $errors") + case ZValidation.Success(_, value) => value } } } 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 1a5826525..2fe05b040 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 @@ -2,24 +2,26 @@ package zio.schema.codec import java.nio.CharBuffer import java.nio.charset.StandardCharsets + import scala.collection.immutable.ListMap + import zio.json.JsonCodec._ import zio.json.JsonDecoder.{ JsonError, UnsafeJson } import zio.json.ast.Json import zio.json.internal.{ Lexer, RecordingReader, RetractReader, StringMatrix, Write } import zio.json.{ - JsonFieldDecoder, - JsonFieldEncoder, JsonCodec => ZJsonCodec, JsonDecoder => ZJsonDecoder, - JsonEncoder => ZJsonEncoder + JsonEncoder => ZJsonEncoder, + JsonFieldDecoder, + JsonFieldEncoder } -import zio.prelude.{ Validation, ZValidation } +import zio.prelude.Validation import zio.schema._ import zio.schema.annotation._ import zio.schema.codec.DecodeError.ReadError import zio.stream.ZPipeline -import zio.{ Cause, Chunk, ChunkBuilder, NonEmptyChunk, ZIO, prelude } +import zio.{ Cause, Chunk, ChunkBuilder, NonEmptyChunk, ZIO } object JsonCodec { type DiscriminatorTuple = Chunk[(discriminatorName, String)] diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index ad562577a..aa611f613 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -1,7 +1,9 @@ package zio.schema.codec import java.time.{ ZoneId, ZoneOffset } + import scala.collection.immutable.ListMap + import zio.Console._ import zio._ import zio.json.JsonDecoder.JsonError diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala index 3e176d109..767046590 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala @@ -1,9 +1,9 @@ package zio.schema.codec -import zio.prelude.Validation - import java.math.{ BigInteger, MathContext } import java.time._ + +import zio.prelude.Validation import zio.schema.codec.DecodeError.ReadError import zio.schema.{ Schema, StandardType } import zio.stream.ZPipeline diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala index 76e0dcd5f..3765227db 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala @@ -2,12 +2,15 @@ package zio.schema.codec import java.time._ import java.util.UUID + import scala.annotation.tailrec import scala.collection.immutable.ListMap import scala.util.control.NonFatal import scala.util.{ Failure, Success, Try } + import org.msgpack.core.{ MessagePack, MessageUnpacker } -import zio.prelude.{ Validation, ZValidation } + +import zio.prelude.Validation import zio.schema.codec.DecodeError.MalformedFieldWithPath import zio.schema.codec.MessagePackDecoder._ import zio.schema.{ DynamicValue, Schema, StandardType } diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala index 6b57294df..a14713d59 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackEncoder.scala @@ -2,10 +2,12 @@ package zio.schema.codec import java.time._ import java.util.UUID + import scala.collection.immutable.ListMap + import org.msgpack.core.MessagePack + import zio.Chunk -import zio.prelude.data.Optional.AllValuesAreNullable import zio.schema.{ DynamicValue, Schema, StandardType } private[codec] class MessagePackEncoder { diff --git a/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala b/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala index 1d8de67db..5d2d9f275 100644 --- a/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala +++ b/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala @@ -2,12 +2,15 @@ package zio.schema.codec import java.time._ import java.util.UUID + import scala.collection.immutable.ListMap import scala.util.Try + import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.scala.DefaultScalaModule import org.msgpack.core.{ MessagePack, MessagePacker } import org.msgpack.jackson.dataformat.MessagePackFactory + import zio.schema.CaseSet.caseOf import zio.schema._ import zio.stream.{ ZSink, ZStream } 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 e22247da6..d25c8e87f 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 @@ -1,14 +1,15 @@ package zio.schema.codec -import zio.prelude.Validation - import java.nio.charset.StandardCharsets import java.nio.{ ByteBuffer, ByteOrder } import java.time._ import java.time.format.DateTimeFormatter import java.util.UUID + import scala.collection.immutable.ListMap import scala.util.control.NonFatal + +import zio.prelude.Validation import zio.schema.MutableSchemaBasedValueBuilder.CreateValueFromSchemaError import zio.schema._ import zio.schema.codec.DecodeError.{ ExtraFields, MalformedField, MissingField } diff --git a/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala b/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala index b8e73df44..acc2cd00f 100644 --- a/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala +++ b/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala @@ -3,21 +3,18 @@ package zio.schema.codec import java.nio.ByteBuffer import java.time._ import java.util.UUID -import scala.annotation.{ nowarn, tailrec } + +import scala.annotation.tailrec import scala.collection.immutable.ListMap import scala.util.control.NonFatal + import org.apache.thrift.protocol._ + import zio.prelude.Validation import zio.schema.MutableSchemaBasedValueBuilder.CreateValueFromSchemaError import zio.schema._ import zio.schema.annotation.{ fieldDefaultValue, optionalField, transientField } -import zio.schema.codec.DecodeError.{ - EmptyContent, - MalformedField, - MalformedFieldWithPath, - ReadError, - ReadErrorWithPath -} +import zio.schema.codec.DecodeError.{ EmptyContent, MalformedFieldWithPath, ReadError, ReadErrorWithPath } import zio.stream.ZPipeline import zio.{ Cause, Chunk, NonEmptyChunk, Unsafe, ZIO } diff --git a/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala b/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala index 8b97aca53..3fe6166ce 100644 --- a/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala +++ b/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala @@ -20,10 +20,13 @@ import java.time.{ } import java.util import java.util.UUID + import scala.collection.immutable.ListMap import scala.util.Try + import org.apache.thrift.TSerializable import org.apache.thrift.protocol.{ TBinaryProtocol, TField, TType } + import zio.schema.CaseSet.caseOf import zio.schema.annotation.{ fieldDefaultValue, optionalField, transientField } import zio.schema.codec.{ generated => g } diff --git a/zio-schema/shared/src/main/scala/zio/schema/Differ.scala b/zio-schema/shared/src/main/scala/zio/schema/Differ.scala index bef3b1592..bfc389903 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Differ.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Differ.scala @@ -1,15 +1,15 @@ package zio.schema -import zio.prelude.Validation - import java.math.{ BigInteger, MathContext } import java.time.temporal.{ ChronoField, ChronoUnit } import java.time.{ DayOfWeek, + Duration => JDuration, Instant, LocalDate, LocalDateTime, LocalTime, + Month => JMonth, MonthDay, OffsetDateTime, OffsetTime, @@ -18,13 +18,14 @@ import java.time.{ YearMonth, ZoneId, ZoneOffset, - Duration => JDuration, - Month => JMonth, ZonedDateTime => JZonedDateTime } import java.util.UUID + import scala.annotation.nowarn import scala.collection.immutable.ListMap + +import zio.prelude.Validation import zio.schema.diff.Edit import zio.{ Chunk, ChunkBuilder } 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 c6c50191d..ad45a0525 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala @@ -1,11 +1,12 @@ package zio.schema -import zio.prelude.Validation - import java.math.{ BigDecimal, BigInteger } import java.time._ import java.util.UUID + import scala.collection.immutable.ListMap + +import zio.prelude.Validation import zio.schema.codec.DecodeError import zio.schema.meta.{ MetaSchema, Migration } import zio.{ Cause, Chunk, Unsafe } diff --git a/zio-schema/shared/src/main/scala/zio/schema/Patch.scala b/zio-schema/shared/src/main/scala/zio/schema/Patch.scala index fff3a243f..2ace2593a 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Patch.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Patch.scala @@ -1,14 +1,10 @@ package zio.schema -import zio.Chunk -import zio.schema.diff.Edit -import zio.schema.meta.Migration -import zio.prelude.Validation - import java.math.{ BigInteger, MathContext } import java.time.temporal.{ ChronoField, ChronoUnit } import java.time.{ DayOfWeek, + Duration => JDuration, Instant, LocalDate, LocalDateTime, @@ -21,12 +17,17 @@ import java.time.{ YearMonth, ZoneId, ZoneOffset, - Duration => JDuration, ZonedDateTime => JZonedDateTime } + import scala.annotation.tailrec import scala.collection.immutable.ListMap +import zio.Chunk +import zio.prelude.Validation +import zio.schema.diff.Edit +import zio.schema.meta.Migration + sealed trait Patch[A] { self => /** 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 6e952e841..7bf5f05d6 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Schema.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Schema.scala @@ -1,15 +1,16 @@ package zio.schema -import zio.prelude.Validation - import java.net.{ URI, URL } import java.time.temporal.ChronoUnit + import scala.annotation.tailrec import scala.collection.immutable.ListMap + +import zio.prelude.Validation import zio.schema.internal.SourceLocation import zio.schema.meta._ import zio.schema.validation._ -import zio.{ Chunk, Unsafe, prelude } +import zio.{ Chunk, Unsafe } /** * A `Schema[A]` describes the structure of some data type `A`, in terms of case classes, diff --git a/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala b/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala index 54c17c336..10e7b06f9 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/StandardType.scala @@ -3,6 +3,7 @@ package zio.schema import java.math.BigInteger import java.time import java.time._ + import zio.Chunk import zio.prelude.Validation diff --git a/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala b/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala index 61210eda2..336a57277 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/meta/Migration.scala @@ -1,8 +1,8 @@ package zio.schema.meta -import zio.prelude.{ Validation, ZValidation } - import scala.collection.immutable.ListMap + +import zio.prelude.{ Validation, ZValidation } import zio.schema.meta.ExtensibleMetaSchema.Labelled import zio.schema.{ DynamicValue, StandardType } import zio.{ Chunk, ChunkBuilder } diff --git a/zio-schema/shared/src/test/scala/zio/schema/validation/SchemaValidationSpec$.scala b/zio-schema/shared/src/test/scala/zio/schema/validation/SchemaValidationSpec$.scala index 1f5edaf5b..25a690e37 100644 --- a/zio-schema/shared/src/test/scala/zio/schema/validation/SchemaValidationSpec$.scala +++ b/zio-schema/shared/src/test/scala/zio/schema/validation/SchemaValidationSpec$.scala @@ -2,7 +2,9 @@ package zio.schema.validation import java.time.format.DateTimeFormatter import java.util.Locale + import scala.util.Try + import zio.Scope import zio.test._ From ad5a273c84c6d72a176e1965ec2b5ea009f2b9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=8BAndrzej=20Ressel?= Date: Fri, 19 May 2023 22:15:56 +0200 Subject: [PATCH 6/6] Finish implementation --- build.sbt | 18 +- .../src/main/scala-3/zio/schema/Derive.scala | 10 +- .../scala-3/zio/schema/DeriveSchema.scala | 1200 ++++++++--------- ...scala => SchemaSchemaValidationSpec.scala} | 2 +- .../scala/zio/schema/codec/JsonCodec.scala | 8 +- .../zio/schema/codec/JsonCodecSpec.scala | 12 +- .../zio/schema/codec/MessagePackCodec.scala | 9 +- .../zio/schema/codec/MessagePackDecoder.scala | 15 +- .../schema/codec/MessagePackCodecSpec.scala | 20 +- .../zio/schema/codec/ProtobufCodec.scala | 4 +- .../zio/schema/codec/ProtobufCodecSpec.scala | 14 +- .../scala/zio/schema/codec/ThriftCodec.scala | 16 +- .../zio/schema/codec/ThriftCodecSpec.scala | 16 +- .../MutableSchemaBasedValueBuilder.scala | 9 +- .../main/scala/zio/schema/codec/Codecs.scala | 5 +- ... => PhoneNumberSchemaValidationSpec.scala} | 2 +- 16 files changed, 670 insertions(+), 690 deletions(-) rename zio-schema-derivation/shared/src/test/scala/zio/schema/{SchemaSchemaValidationSpec$.scala => SchemaSchemaValidationSpec.scala} (99%) rename zio-schema/shared/src/test/scala/zio/schema/validation/{PhoneNumberSchemaValidationSpec$.scala => PhoneNumberSchemaValidationSpec.scala} (99%) diff --git a/build.sbt b/build.sbt index cb1db388f..49d790faa 100644 --- a/build.sbt +++ b/build.sbt @@ -108,10 +108,11 @@ lazy val zioSchema = crossProject(JSPlatform, JVMPlatform) .settings(buildInfoSettings("zio.schema")) .settings( libraryDependencies ++= Seq( - "dev.zio" %% "zio" % zioVersion, - "dev.zio" %% "zio-streams" % zioVersion, - "dev.zio" %% "zio-prelude" % zioPreludeVersion, - "dev.zio" %% "zio-constraintless" % zioConstraintlessVersion + "dev.zio" %% "zio" % zioVersion, + "dev.zio" %% "zio-streams" % zioVersion, + "dev.zio" %% "zio-prelude" % zioPreludeVersion, + "dev.zio" %% "zio-constraintless" % zioConstraintlessVersion, + "org.scala-lang.modules" %% "scala-collection-compat" % scalaCollectionCompatVersion ) ) .dependsOn(zioSchemaMacros) @@ -245,11 +246,10 @@ lazy val zioSchemaBson = crossProject(JVMPlatform) .settings(buildInfoSettings("zio.schema.bson")) .settings( libraryDependencies ++= Seq( - "org.mongodb" % "bson" % bsonVersion, - "dev.zio" %% "zio-bson" % zioBsonVersion, - "dev.zio" %% "zio" % zioVersion, // zio.Chunk - "dev.zio" %% "zio-test-magnolia" % zioVersion % Test, // TODO: implement DeriveDiff in zioSchemaZioTest - "org.scala-lang.modules" %% "scala-collection-compat" % scalaCollectionCompatVersion + "org.mongodb" % "bson" % bsonVersion, + "dev.zio" %% "zio-bson" % zioBsonVersion, + "dev.zio" %% "zio" % zioVersion, // zio.Chunk + "dev.zio" %% "zio-test-magnolia" % zioVersion % Test // TODO: implement DeriveDiff in zioSchemaZioTest ), scalacOptions -= "-Xfatal-warnings" // cross-version imports ) diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala index 0d6b00d79..f84cfc5e0 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/Derive.scala @@ -88,16 +88,16 @@ private case class DeriveInstance()(using val ctx: Quotes) extends ReflectionUti lazyVals[F[A]](selfRef, seqSchemaRef -> '{Schema.force($schema).asInstanceOf[Schema.Sequence[List[a], a, _]]}, selfRef -> '{$deriver.deriveSequence[List, a]($seqSchemaRefExpr, $elemInstance, ${summoned})} - ) - case '[zio.prelude.Validation[a, b]] => - val (schemaRef, schemaRefExpr) = createSchemaRef[zio.prelude.Validation[a, b], Schema.Either[a, b]](stack) - val summoned = summonOptionalIfNotTop[F, zio.prelude.Validation[a, b]](top) + ) + case '[scala.util.Either[a, b]] => + val (schemaRef, schemaRefExpr) = createSchemaRef[scala.util.Either[a, b], Schema.Either[a, b]](stack) + val summoned = summonOptionalIfNotTop[F, scala.util.Either[a, b]](top) val instanceA = deriveInstance[F, a](deriver, '{$schemaRefExpr.left}, stack) val instanceB = deriveInstance[F, b](deriver, '{$schemaRefExpr.right}, stack) lazyVals[F[A]](selfRef, schemaRef -> '{Schema.force($schema).asInstanceOf[Schema.Either[a, b]]}, - selfRef -> '{$deriver.deriveEither[A, B]($schemaRefExpr, $instanceA, $instanceB, $summoned)} + selfRef -> '{$deriver.deriveEither[a, b]($schemaRefExpr, $instanceA, $instanceB, $summoned)} ) case '[Option[a]] => val (schemaRef, schemaRefExpr) = createSchemaRef[Option[a], Schema.Optional[a]](stack) diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala index aa44ca0d9..ce0adc59b 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala @@ -1,600 +1,600 @@ -package zio.schema - -import scala.quoted._ -import scala.deriving.Mirror -import scala.compiletime.{erasedValue, summonInline, constValueTuple} -import scala.collection.immutable.ListMap -import Schema._ - -import zio.schema.annotation.fieldName - -extension (s: Schema.type) transparent inline def derived[A] = DeriveSchema.gen[A] - -object DeriveSchema { - - transparent inline def gen[T]: Schema[T] = ${ deriveSchema[T] } - - private def deriveSchema[T: Type](using Quotes): Expr[Schema[T]] = - DeriveSchema().deriveSchema[T](top = true) -} - -private case class DeriveSchema()(using val ctx: Quotes) extends ReflectionUtils(ctx) { - import ctx.reflect._ - - case class Frame(ref: Term, tpe: TypeRepr) - case class Stack(frames: List[Frame]) { - def find(tpe: TypeRepr): Option[Term] = frames.find(_.tpe =:= tpe).map(_.ref) - - def push(ref: Term, tpe: TypeRepr): Stack = Stack(Frame(ref, tpe) :: frames) - - def pop: Stack = Stack(frames.tail) - - def size = frames.size - - override def toString = - frames.map(f => s"${f.ref.show} : ${f.tpe.show}").mkString("Stack(", ", ", ")") - } - - object Stack { - val empty: Stack = Stack(Nil) - } - - var depth = 0 - - def deriveSchema[T: Type](stack: Stack = Stack.empty, top: Boolean = false)(using Quotes): Expr[Schema[T]] = { - depth += 1 - if (depth > 1024) - throw new Exception("Schema derivation exceeded") - - val typeRepr = TypeRepr.of[T] - val result = stack.find(typeRepr) match { - case Some(ref) => - '{ Schema.defer(${ref.asExprOf[Schema[T]]}) } - case None => - typeRepr.asType match { - case '[List[a]] => - val schema = deriveSchema[a](stack) - '{ Schema.list(Schema.defer(${schema})) }.asExprOf[Schema[T]] - case '[zio.prelude.Validation[a, b]] => - val schemaA = deriveSchema[a](stack) - val schemaB = deriveSchema[b](stack) - '{ Schema.either(Schema.defer(${schemaA}), Schema.defer(${schemaB})) }.asExprOf[Schema[T]] - case '[Option[a]] => - val schema = deriveSchema[a](stack) - // throw new Error(s"OPITOS ${schema.show}") - '{ Schema.option(Schema.defer($schema)) }.asExprOf[Schema[T]] - case '[scala.collection.Set[a]] => - val schema = deriveSchema[a](stack) - '{ Schema.set(Schema.defer(${schema})) }.asExprOf[Schema[T]] - case '[Vector[a]] => - val schema = deriveSchema[a](stack) - '{ Schema.vector(Schema.defer(${schema})) }.asExprOf[Schema[T]] - case '[scala.collection.Map[a, b]] => - val schemaA = deriveSchema[a](stack) - val schemaB = deriveSchema[b](stack) - '{ Schema.map(Schema.defer(${schemaA}), Schema.defer(${schemaB})) }.asExprOf[Schema[T]] - case '[zio.Chunk[a]] => - val schema = deriveSchema[a](stack) - '{ Schema.chunk(Schema.defer(${schema})) }.asExprOf[Schema[T]] - case _ => - val summoned = if (!top) Expr.summon[Schema[T]] else None - summoned match { - case Some(schema) => - // println(s"FOR TYPE ${typeRepr.show}") - // println(s"STACK ${stack.find(typeRepr)}") - // println(s"Found schema ${schema.show}") - schema - case _ => - Mirror(typeRepr) match { - case Some(mirror) => - mirror.mirrorType match { - case MirrorType.Sum => - deriveEnum[T](mirror, stack) - case MirrorType.Product => - deriveCaseClass[T](mirror, stack, top) - } - case None => - val sym = typeRepr.typeSymbol - if (sym.isClassDef && sym.flags.is(Flags.Module)) { - deriveCaseObject[T](stack, top) - } - else { - report.errorAndAbort(s"Deriving schema for ${typeRepr.show} is not supported") - } - } - } - } - } - - //println() - //println() - //println(s"RESULT ${typeRepr.show}") - //println(s"------") - //println(s"RESULT ${result.show}") - - result - } - - def deriveCaseObject[T: Type](stack: Stack, top: Boolean)(using Quotes) = { - val selfRefSymbol = Symbol.newVal(Symbol.spliceOwner, s"derivedSchema${stack.size}", TypeRepr.of[Schema[T]], Flags.Lazy, Symbol.noSymbol) - val selfRef = Ref(selfRefSymbol) - - val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} - val annotationExprs = TypeRepr.of[T].typeSymbol.annotations.filter (filterAnnotation).map (_.asExpr) - val annotations = '{zio.Chunk.fromIterable (${Expr.ofSeq (annotationExprs)})} - - val constructor = '{() => ${Ref(TypeRepr.of[T].typeSymbol.companionModule).asExprOf[T]}} - val ctor = typeRprOf[T](0).typeSymbol.companionModule - val args = List(typeInfo, constructor, annotations) - - val applied = Apply( - TypeApply( - Select.unique(Ref(ctor), "apply"), - List(TypeRepr.of[T].asType match { - case '[tt] => TypeTree.of[tt] - })), - args.map(_.asTerm) - ) - - val lazyValDef = ValDef(selfRefSymbol, Some(applied.changeOwner(selfRefSymbol))) - - applied.asExpr match { - case '{ type tt <: Schema[T]; $ex : `tt` } => - '{ - ${Block( - List(lazyValDef), - selfRef - ).asExpr}.asInstanceOf[tt] - } - } - } - - def deriveCaseClass[T: Type](mirror: Mirror, stack: Stack, top: Boolean)(using Quotes) = { - val selfRefSymbol = Symbol.newVal(Symbol.spliceOwner, s"derivedSchema${stack.size}", TypeRepr.of[Schema[T]], Flags.Lazy, Symbol.noSymbol) - val selfRef = Ref(selfRefSymbol) - val newStack = stack.push(selfRef, TypeRepr.of[T]) - - val labels = mirror.labels.toList - val types = mirror.types.toList - val typesAndLabels = types.zip(labels) - - val paramAnns = fromConstructor(TypeRepr.of[T].typeSymbol) - val constructor = caseClassConstructor[T](mirror).asExpr - - val annotationExprs = TypeRepr.of[T].typeSymbol.annotations.filter(filterAnnotation).map(_.asExpr) - val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) } - val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} - - val applied = if (labels.length <= 22) { - - val typeArgs = - (types.appended(TypeRepr.of[T])).map { tpe => - tpe.asType match - case '[tt] => TypeTree.of[tt] - } - - val ctor = typeRprOf[T](labels.length).typeSymbol.companionModule - val typeAppliedCtor = TypeApply( - Select.unique(Ref(ctor), "apply"), - typeArgs - ) - - val fieldsAndFieldTypes = typesAndLabels.map { case (tpe, label) => deriveField[T](tpe, label, paramAnns.getOrElse(label, List.empty), newStack) } - val (fields, fieldTypes) = fieldsAndFieldTypes.unzip - val args = List(typeInfo) ++ fields ++ Seq(constructor) ++ Seq(annotations) - val terms = Expr.ofTupleFromSeq(args) - - if (labels.length > 0) { - val caseClassWithFieldsTpe = caseClassWithFieldsType(labels.length) - val appliedCaseClassWithFieldsTpe = caseClassWithFieldsTpe.appliedTo( - fieldTypes ++ types ++ List(TypeRepr.of[T]) - ) - - Select.unique(Apply( - typeAppliedCtor, - args.map(_.asTerm) - ), "asInstanceOf").appliedToType(appliedCaseClassWithFieldsTpe) - } else { - Apply( - typeAppliedCtor, - args.map(_.asTerm) - ) - } - } else { - val fieldsAndFieldTypes = typesAndLabels.map { case (tpe, label) => deriveGenericField[T](tpe, label, paramAnns.getOrElse(label, List.empty), newStack) } - val fields = fieldsAndFieldTypes.map(_._1) - val genericRecord = '{GenericRecord($typeInfo, FieldSet.fromFields(${Varargs(fields)} : _*), $annotations)} - - val s = TypeRepr.of[T].typeSymbol.declaredFields - - def casts(m: Expr[ListMap[String, _]])(using Quotes) = - typesAndLabels.map { case (tpe, label) => - val interestingField = s.find (_.name == label) - val fieldType = interestingField match { - case Some(interestingField) => - val ct = tpe.memberType (interestingField) - ct.asType - case None => - tpe.asType - } - fieldType match { case '[t] => - '{ try ${m}.apply(${Expr(label)}).asInstanceOf[t] - catch { - case _: ClassCastException => throw new RuntimeException("Field " + ${Expr(label)} + " has invalid type") - case _: Throwable => throw new RuntimeException("Field " + ${Expr(label)} + " is missing") - } - }.asTerm - } - } - - def appliedConstructor(m: Expr[ListMap[String, _]])(using Quotes) = { - Apply(Select.unique(Ref(TypeRepr.of[T].typeSymbol.companionModule), "apply"), casts(m)).asExprOf[T] - } - - val fromMap = '{ (m: ListMap[String, _]) => - try { zio.prelude.Validation.succeed(${appliedConstructor('m)}) } catch { - case e: Throwable => zio.prelude.Validation.fail(e.getMessage) - }} - - def tuples(b: Expr[T])(using Quotes) = - typesAndLabels.map { case (tpe, label) => - val interestingField = s.find (_.name == label) - val fieldType = interestingField match { - case Some(interestingField) => - val ct = tpe.memberType (interestingField) - ct.asType - case None => - tpe.asType - } - fieldType match { case '[t] => - '{(${Expr(label)}, ${Select.unique(b.asTerm, label).asExprOf[t]})} - } - } - val toMap = '{(b: T) => zio.prelude.Validation.succeed(ListMap.apply(${Varargs(tuples('b))} :_*)) } - - '{${genericRecord.asExprOf[GenericRecord]}.transformOrFail[T]($fromMap, $toMap)}.asTerm - } - - val lazyValDef = ValDef(selfRefSymbol, Some(applied.changeOwner(selfRefSymbol))) - - applied.asExpr match { - case '{ type tt <: Schema[T]; $ex : `tt` } => - '{ - ${Block( - List(lazyValDef), - selfRef - ).asExpr}.asInstanceOf[tt] - } - } - } - - - private def fromDeclarations(from: Symbol): List[(String, List[Expr[Any]])] = - from.declaredFields.map { - field => - field.name -> field.annotations.filter(filterAnnotation).map(_.asExpr) - } - - private def fromConstructor(from: Symbol): scala.collection.Map[String, List[Expr[Any]]] = - from.primaryConstructor.paramSymss.flatten.map { field => - field.name -> field.annotations - .filter(filterAnnotation) - .map(_.asExpr.asInstanceOf[Expr[Any]]) - }.toMap - - def deriveEnum[T: Type](mirror: Mirror, stack: Stack)(using Quotes) = { - val selfRefSymbol = Symbol.newVal(Symbol.spliceOwner, s"derivedSchema${stack.size}", TypeRepr.of[Schema[T]], Flags.Lazy, Symbol.noSymbol) - val selfRef = Ref(selfRefSymbol) - val newStack = stack.push(selfRef, TypeRepr.of[T]) - - val labels = mirror.labels.toList - val types = mirror.types.toList - val typesAndLabels = types.zip(labels) - - val cases = typesAndLabels.map { case (tpe, label) => deriveCase[T](tpe, label, newStack) } - - val annotationExprs = TypeRepr.of[T].typeSymbol.annotations.filter(filterAnnotation).map(_.asExpr) - val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) } - - val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} - - val applied = if (cases.length <= 22) { - val args = List(typeInfo) ++ cases :+ annotations - val terms = Expr.ofTupleFromSeq(args) - val ctor = TypeRepr.of[Enum2[_, _, _]].typeSymbol.primaryConstructor - - val typeArgs = - (types.appended(TypeRepr.of[T])).map { tpe => - tpe.asType match - case '[tt] => TypeTree.of[tt] - } - - val typeTree = enumTypeTree[T](labels.length) - - Apply( - TypeApply( - Select(New(typeTree), ctor), - typeArgs - ), - args.map(_.asTerm) - ) - } else { - '{EnumN($typeInfo, CaseSet(${Varargs(cases)}: _*).asInstanceOf[CaseSet.Aux[T]], $annotations) }.asTerm - } - - val lazyValDef = ValDef(selfRefSymbol, Some(applied.changeOwner(selfRefSymbol))) - - applied.asExpr match { - case '{ type tt <: Schema[T]; $ex : `tt` } => - '{ - ${Block( - List(lazyValDef), - selfRef - ).asExpr}.asInstanceOf[tt] - } - } - } - - - // Derive Field for a CaseClass - def deriveField[T: Type](repr: TypeRepr, name: String, anns: List[Expr[Any]], stack: Stack)(using Quotes) = { - import zio.schema.validation.SchemaValidation - import zio.schema.annotation.validate - - val tpe = TypeRepr.of[T] - val s = tpe.typeSymbol.declaredFields - val interestingField = s.find (_.name == name) - - val fieldType = interestingField match { - case Some(interestingField) => - val ct = tpe.memberType (interestingField) - ct.asType - case None => - repr.asType - } - fieldType match { case '[t] => - val schema = deriveSchema[t](stack) - val validations = anns.collect { - case ann if ann.isExprOf[validate[t]] => ann.asExprOf[validate[t]] - } - val validator: Expr[Validation[t]] = validations.foldLeft[Expr[Validation[t]]]('{Validation.succeed}){ - case (acc, expr) => '{ - $acc && ${expr}.validation - } - } - - val typeParams = TypeRepr.of[T].dealias match - case AppliedType (t, params) => params - case _ => Nil - - val get = '{ (t: T) => ${Select.unique('t.asTerm, name).asExprOf[t]} } - val set = '{ (ts: T, v: t) => ${Select.overloaded('ts.asTerm, "copy", typeParams, List(NamedArg(name, 'v.asTerm))).asExprOf[T]} } - val chunk = '{ zio.Chunk.fromIterable(${ Expr.ofSeq(anns.reverse) }) } - - if (anns.nonEmpty) { - val (newName, newNameValue) = anns.collectFirst { - case ann if ann.isExprOf[fieldName] => - val fieldNameAnn = ann.asExprOf[fieldName] - ('{${fieldNameAnn}.name}, extractFieldNameValue(fieldNameAnn)) - }.getOrElse((Expr(name), name)) - - val f = '{ Field($newName, $schema, $chunk, $validator, $get, $set)} - addFieldName(newNameValue)(f) // TODO: we need to pass the evaluated annotation value instead of name - } else { - val f = '{ Field(${Expr(name)}, $schema, $chunk, $validator, $get, $set) } - addFieldName(name)(f) - } - } - } - -// Derive Field for a GenericRecord - def deriveGenericField[T: Type](repr: TypeRepr, name: String, anns: List[Expr[Any]], stack: Stack)(using Quotes) = { - import zio.schema.validation.SchemaValidation - import zio.schema.annotation.validate - - val tpe = TypeRepr.of[T] - val s = tpe.typeSymbol.declaredFields - val interestingField = s.find (_.name == name) - - val fieldType = interestingField match { - case Some(interestingField) => - val ct = tpe.memberType (interestingField) - ct.asType - case None => - repr.asType - } - fieldType match { case '[t] => - val schema = deriveSchema[t](stack) - val validations = anns.collect { - case ann if ann.isExprOf[validate[t]] => ann.asExprOf[validate[t]] - } - val validator: Expr[Validation[t]] = validations.foldLeft[Expr[Validation[t]]]('{Validation.succeed}){ - case (acc, expr) => '{ - $acc && ${expr}.validation - } - } - - val typeParams = TypeRepr.of[T].dealias match - case AppliedType (t, params) => params - case _ => Nil - - val get = '{ (t: ListMap[String, _]) => t.apply(${Expr(name)}).asInstanceOf[t] } - val set = '{ (ts: ListMap[String, _], v: t) => ts.updated(${Expr(name)}, v) } - val chunk = '{ zio.Chunk.fromIterable(${ Expr.ofSeq(anns.reverse) }) } - - if (anns.nonEmpty) { - val newName = anns.collectFirst { - case ann if ann.isExprOf[fieldName] => '{${ann.asExprOf[fieldName]}.name} - }.getOrElse(Expr(name)) - - val f = '{ Field($newName, $schema, $chunk, $validator, $get, $set) } - addFieldName(name)(f) // TODO: we need to pass the evaluated annotation value instead of name - } else { - val f = '{ Field(${Expr(name)}, $schema, $chunk, $validator, $get, $set) } - addFieldName(name)(f) - } - } - } - - def addFieldName[R: Type, T: Type, F <: Field[R, T]: Type](name: String)(f: Expr[F])(using Quotes) = { - val withFieldName = TypeRepr.of[Field.WithFieldName] - val r = TypeRepr.of[R] - val t = TypeRepr.of[T] - val nameT = ConstantType(StringConstant(name)) - val fieldWithName = withFieldName.appliedTo(List(r, nameT, t)) - (Select.unique(f.asTerm, "asInstanceOf").appliedToType(fieldWithName).asExprOf[F], nameT) - } - - - // sealed case class Case[A, Z](id: String, codec: Schema[A], unsafeDeconstruct: Z => A, annotations: Chunk[Any] = Chunk.empty) { - def deriveCase[T: Type](repr: TypeRepr, label: String, stack: Stack)(using Quotes) = { - repr.asType match { case '[t] => - val schema = deriveSchema[t](stack) - val stringExpr = Expr(label) - - val annotationExprs = TypeRepr.of[t].typeSymbol.annotations.filter(filterAnnotation).map(_.asExpr) - val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) } - - val unsafeDeconstruct = '{ - (z: T) => z.asInstanceOf[t] - } - val construct = '{ - (a: t) => a.asInstanceOf[T] - } - - val isCase = '{ (z: T) => z.isInstanceOf[t @unchecked] } - - '{ Case(${Expr(label)}, $schema, $unsafeDeconstruct, $construct, $isCase, $annotations) } - } - } - - - def caseClassConstructor[T: Type](mirror: Mirror) = { - val product = Expr.summon[scala.deriving.Mirror.ProductOf[T]].get - val methodType = MethodType(mirror.labels.toList)(_ => mirror.types.toList, _ => TypeRepr.of[T]) - Lambda(Symbol.spliceOwner, methodType, { (sym, reprs) => - val tupled = Expr.ofTupleFromSeq(reprs.map(_.asExpr)) - Select.overloaded(product.asTerm, "fromProduct", List.empty, List(tupled.asTerm)) - }) - } - - private def filterAnnotation(a: Term): Boolean = - a.tpe.typeSymbol.maybeOwner.isNoSymbol || - a.tpe.typeSymbol.owner.fullName != "scala.annotation.internal" - - def extractFieldNameValue(attribute: Expr[fieldName]): String = - attribute.asTerm match { - // Apply(Select(New(Ident(fieldName)),),List(Literal(Constant(renamed)))) - case Apply(_, List(Literal(StringConstant(name)))) => - name - } - - def caseClassTypeTree[T: Type](arity: Int): TypeTree = - arity match { - case 0 => TypeTree.of[CaseClass0[T]] - case 1 => TypeTree.of[CaseClass1[_, T]] - case 2 => TypeTree.of[CaseClass2[_, _, T]] - case 3 => TypeTree.of[CaseClass3[_, _, _, T]] - case 4 => TypeTree.of[CaseClass4[_, _, _, _, T]] - case 5 => TypeTree.of[CaseClass5[_, _, _, _, _, T]] - case 6 => TypeTree.of[CaseClass6[_, _, _, _, _, _, T]] - case 7 => TypeTree.of[CaseClass7[_, _, _, _, _, _, _, T]] - case 8 => TypeTree.of[CaseClass8[_, _, _, _, _, _, _, _, T]] - case 9 => TypeTree.of[CaseClass9[_, _, _, _, _, _, _, _, _, T]] - case 10 => TypeTree.of[CaseClass10[_, _, _, _, _, _, _, _, _, _, T]] - case 11 => TypeTree.of[CaseClass11[_, _, _, _, _, _, _, _, _, _, _, T]] - case 12 => TypeTree.of[CaseClass12[_, _, _, _, _, _, _, _, _, _, _, _, T]] - case 13 => TypeTree.of[CaseClass13[_, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 14 => TypeTree.of[CaseClass14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 15 => TypeTree.of[CaseClass15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 16 => TypeTree.of[CaseClass16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 17 => TypeTree.of[CaseClass17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 18 => TypeTree.of[CaseClass18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 19 => TypeTree.of[CaseClass19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 20 => TypeTree.of[CaseClass20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 21 => TypeTree.of[CaseClass21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 22 => TypeTree.of[CaseClass22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - } - - def typeRprOf[T: Type](arity: Int): TypeRepr = - arity match { - case 0 => TypeRepr.of[CaseClass0[T]] - case 1 => TypeRepr.of[CaseClass1[_, T]] - case 2 => TypeRepr.of[CaseClass2[_, _, T]] - case 3 => TypeRepr.of[CaseClass3[_, _, _, T]] - case 4 => TypeRepr.of[CaseClass4[_, _, _, _, T]] - case 5 => TypeRepr.of[CaseClass5[_, _, _, _, _, T]] - case 6 => TypeRepr.of[CaseClass6[_, _, _, _, _, _, T]] - case 7 => TypeRepr.of[CaseClass7[_, _, _, _, _, _, _, T]] - case 8 => TypeRepr.of[CaseClass8[_, _, _, _, _, _, _, _, T]] - case 9 => TypeRepr.of[CaseClass9[_, _, _, _, _, _, _, _, _, T]] - case 10 => TypeRepr.of[CaseClass10[_, _, _, _, _, _, _, _, _, _, T]] - case 11 => TypeRepr.of[CaseClass11[_, _, _, _, _, _, _, _, _, _, _, T]] - case 12 => TypeRepr.of[CaseClass12[_, _, _, _, _, _, _, _, _, _, _, _, T]] - case 13 => TypeRepr.of[CaseClass13[_, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 14 => TypeRepr.of[CaseClass14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 15 => TypeRepr.of[CaseClass15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 16 => TypeRepr.of[CaseClass16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 17 => TypeRepr.of[CaseClass17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 18 => TypeRepr.of[CaseClass18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 19 => TypeRepr.of[CaseClass19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 20 => TypeRepr.of[CaseClass20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 21 => TypeRepr.of[CaseClass21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 22 => TypeRepr.of[CaseClass22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - } - - def caseClassWithFieldsType(arity: Int): TypeRepr = - arity match { - case 1 => TypeRepr.of[CaseClass1.WithFields] - case 2 => TypeRepr.of[CaseClass2.WithFields] - case 3 => TypeRepr.of[CaseClass3.WithFields] - case 4 => TypeRepr.of[CaseClass4.WithFields] - case 5 => TypeRepr.of[CaseClass5.WithFields] - case 6 => TypeRepr.of[CaseClass6.WithFields] - case 7 => TypeRepr.of[CaseClass7.WithFields] - case 8 => TypeRepr.of[CaseClass8.WithFields] - case 9 => TypeRepr.of[CaseClass9.WithFields] - case 10 => TypeRepr.of[CaseClass10.WithFields] - case 11 => TypeRepr.of[CaseClass11.WithFields] - case 12 => TypeRepr.of[CaseClass12.WithFields] - case 13 => TypeRepr.of[CaseClass13.WithFields] - case 14 => TypeRepr.of[CaseClass14.WithFields] - case 15 => TypeRepr.of[CaseClass15.WithFields] - case 16 => TypeRepr.of[CaseClass16.WithFields] - case 17 => TypeRepr.of[CaseClass17.WithFields] - case 18 => TypeRepr.of[CaseClass18.WithFields] - case 19 => TypeRepr.of[CaseClass19.WithFields] - case 20 => TypeRepr.of[CaseClass20.WithFields] - case 21 => TypeRepr.of[CaseClass21.WithFields] - case 22 => TypeRepr.of[CaseClass22.WithFields] - } - - def enumTypeTree[T: Type](arity: Int): TypeTree = - arity match { - case 0 => TypeTree.of[CaseClass0[T]] - case 1 => TypeTree.of[Enum1[_, T]] - case 2 => TypeTree.of[Enum2[_, _, T]] - case 3 => TypeTree.of[Enum3[_, _, _, T]] - case 4 => TypeTree.of[Enum4[_, _, _, _, T]] - case 5 => TypeTree.of[Enum5[_, _, _, _, _, T]] - case 6 => TypeTree.of[Enum6[_, _, _, _, _, _, T]] - case 7 => TypeTree.of[Enum7[_, _, _, _, _, _, _, T]] - case 8 => TypeTree.of[Enum8[_, _, _, _, _, _, _, _, T]] - case 9 => TypeTree.of[Enum9[_, _, _, _, _, _, _, _, _, T]] - case 10 => TypeTree.of[Enum10[_, _, _, _, _, _, _, _, _, _, T]] - case 11 => TypeTree.of[Enum11[_, _, _, _, _, _, _, _, _, _, _, T]] - case 12 => TypeTree.of[Enum12[_, _, _, _, _, _, _, _, _, _, _, _, T]] - case 13 => TypeTree.of[Enum13[_, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 14 => TypeTree.of[Enum14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 15 => TypeTree.of[Enum15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 16 => TypeTree.of[Enum16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 17 => TypeTree.of[Enum17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 18 => TypeTree.of[Enum18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 19 => TypeTree.of[Enum19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 20 => TypeTree.of[Enum20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 21 => TypeTree.of[Enum21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - case 22 => TypeTree.of[Enum22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] - } - -} - +package zio.schema + +import scala.quoted._ +import scala.deriving.Mirror +import scala.compiletime.{erasedValue, summonInline, constValueTuple} +import scala.collection.immutable.ListMap +import Schema._ + +import zio.schema.annotation.fieldName + +extension (s: Schema.type) transparent inline def derived[A] = DeriveSchema.gen[A] + +object DeriveSchema { + + transparent inline def gen[T]: Schema[T] = ${ deriveSchema[T] } + + private def deriveSchema[T: Type](using Quotes): Expr[Schema[T]] = + DeriveSchema().deriveSchema[T](top = true) +} + +private case class DeriveSchema()(using val ctx: Quotes) extends ReflectionUtils(ctx) { + import ctx.reflect._ + + case class Frame(ref: Term, tpe: TypeRepr) + case class Stack(frames: List[Frame]) { + def find(tpe: TypeRepr): Option[Term] = frames.find(_.tpe =:= tpe).map(_.ref) + + def push(ref: Term, tpe: TypeRepr): Stack = Stack(Frame(ref, tpe) :: frames) + + def pop: Stack = Stack(frames.tail) + + def size = frames.size + + override def toString = + frames.map(f => s"${f.ref.show} : ${f.tpe.show}").mkString("Stack(", ", ", ")") + } + + object Stack { + val empty: Stack = Stack(Nil) + } + + var depth = 0 + + def deriveSchema[T: Type](stack: Stack = Stack.empty, top: Boolean = false)(using Quotes): Expr[Schema[T]] = { + depth += 1 + if (depth > 1024) + throw new Exception("Schema derivation exceeded") + + val typeRepr = TypeRepr.of[T] + val result = stack.find(typeRepr) match { + case Some(ref) => + '{ Schema.defer(${ref.asExprOf[Schema[T]]}) } + case None => + typeRepr.asType match { + case '[List[a]] => + val schema = deriveSchema[a](stack) + '{ Schema.list(Schema.defer(${schema})) }.asExprOf[Schema[T]] + case '[zio.prelude.Validation[a, b]] => + val schemaA = deriveSchema[a](stack) + val schemaB = deriveSchema[b](stack) + '{ Schema.either(Schema.defer(${schemaA}), Schema.defer(${schemaB})) }.asExprOf[Schema[T]] + case '[Option[a]] => + val schema = deriveSchema[a](stack) + // throw new Error(s"OPITOS ${schema.show}") + '{ Schema.option(Schema.defer($schema)) }.asExprOf[Schema[T]] + case '[scala.collection.Set[a]] => + val schema = deriveSchema[a](stack) + '{ Schema.set(Schema.defer(${schema})) }.asExprOf[Schema[T]] + case '[Vector[a]] => + val schema = deriveSchema[a](stack) + '{ Schema.vector(Schema.defer(${schema})) }.asExprOf[Schema[T]] + case '[scala.collection.Map[a, b]] => + val schemaA = deriveSchema[a](stack) + val schemaB = deriveSchema[b](stack) + '{ Schema.map(Schema.defer(${schemaA}), Schema.defer(${schemaB})) }.asExprOf[Schema[T]] + case '[zio.Chunk[a]] => + val schema = deriveSchema[a](stack) + '{ Schema.chunk(Schema.defer(${schema})) }.asExprOf[Schema[T]] + case _ => + val summoned = if (!top) Expr.summon[Schema[T]] else None + summoned match { + case Some(schema) => + // println(s"FOR TYPE ${typeRepr.show}") + // println(s"STACK ${stack.find(typeRepr)}") + // println(s"Found schema ${schema.show}") + schema + case _ => + Mirror(typeRepr) match { + case Some(mirror) => + mirror.mirrorType match { + case MirrorType.Sum => + deriveEnum[T](mirror, stack) + case MirrorType.Product => + deriveCaseClass[T](mirror, stack, top) + } + case None => + val sym = typeRepr.typeSymbol + if (sym.isClassDef && sym.flags.is(Flags.Module)) { + deriveCaseObject[T](stack, top) + } + else { + report.errorAndAbort(s"Deriving schema for ${typeRepr.show} is not supported") + } + } + } + } + } + + //println() + //println() + //println(s"RESULT ${typeRepr.show}") + //println(s"------") + //println(s"RESULT ${result.show}") + + result + } + + def deriveCaseObject[T: Type](stack: Stack, top: Boolean)(using Quotes) = { + val selfRefSymbol = Symbol.newVal(Symbol.spliceOwner, s"derivedSchema${stack.size}", TypeRepr.of[Schema[T]], Flags.Lazy, Symbol.noSymbol) + val selfRef = Ref(selfRefSymbol) + + val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} + val annotationExprs = TypeRepr.of[T].typeSymbol.annotations.filter (filterAnnotation).map (_.asExpr) + val annotations = '{zio.Chunk.fromIterable (${Expr.ofSeq (annotationExprs)})} + + val constructor = '{() => ${Ref(TypeRepr.of[T].typeSymbol.companionModule).asExprOf[T]}} + val ctor = typeRprOf[T](0).typeSymbol.companionModule + val args = List(typeInfo, constructor, annotations) + + val applied = Apply( + TypeApply( + Select.unique(Ref(ctor), "apply"), + List(TypeRepr.of[T].asType match { + case '[tt] => TypeTree.of[tt] + })), + args.map(_.asTerm) + ) + + val lazyValDef = ValDef(selfRefSymbol, Some(applied.changeOwner(selfRefSymbol))) + + applied.asExpr match { + case '{ type tt <: Schema[T]; $ex : `tt` } => + '{ + ${Block( + List(lazyValDef), + selfRef + ).asExpr}.asInstanceOf[tt] + } + } + } + + def deriveCaseClass[T: Type](mirror: Mirror, stack: Stack, top: Boolean)(using Quotes) = { + val selfRefSymbol = Symbol.newVal(Symbol.spliceOwner, s"derivedSchema${stack.size}", TypeRepr.of[Schema[T]], Flags.Lazy, Symbol.noSymbol) + val selfRef = Ref(selfRefSymbol) + val newStack = stack.push(selfRef, TypeRepr.of[T]) + + val labels = mirror.labels.toList + val types = mirror.types.toList + val typesAndLabels = types.zip(labels) + + val paramAnns = fromConstructor(TypeRepr.of[T].typeSymbol) + val constructor = caseClassConstructor[T](mirror).asExpr + + val annotationExprs = TypeRepr.of[T].typeSymbol.annotations.filter(filterAnnotation).map(_.asExpr) + val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) } + val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} + + val applied = if (labels.length <= 22) { + + val typeArgs = + (types.appended(TypeRepr.of[T])).map { tpe => + tpe.asType match + case '[tt] => TypeTree.of[tt] + } + + val ctor = typeRprOf[T](labels.length).typeSymbol.companionModule + val typeAppliedCtor = TypeApply( + Select.unique(Ref(ctor), "apply"), + typeArgs + ) + + val fieldsAndFieldTypes = typesAndLabels.map { case (tpe, label) => deriveField[T](tpe, label, paramAnns.getOrElse(label, List.empty), newStack) } + val (fields, fieldTypes) = fieldsAndFieldTypes.unzip + val args = List(typeInfo) ++ fields ++ Seq(constructor) ++ Seq(annotations) + val terms = Expr.ofTupleFromSeq(args) + + if (labels.length > 0) { + val caseClassWithFieldsTpe = caseClassWithFieldsType(labels.length) + val appliedCaseClassWithFieldsTpe = caseClassWithFieldsTpe.appliedTo( + fieldTypes ++ types ++ List(TypeRepr.of[T]) + ) + + Select.unique(Apply( + typeAppliedCtor, + args.map(_.asTerm) + ), "asInstanceOf").appliedToType(appliedCaseClassWithFieldsTpe) + } else { + Apply( + typeAppliedCtor, + args.map(_.asTerm) + ) + } + } else { + val fieldsAndFieldTypes = typesAndLabels.map { case (tpe, label) => deriveGenericField[T](tpe, label, paramAnns.getOrElse(label, List.empty), newStack) } + val fields = fieldsAndFieldTypes.map(_._1) + val genericRecord = '{GenericRecord($typeInfo, FieldSet.fromFields(${Varargs(fields)} : _*), $annotations)} + + val s = TypeRepr.of[T].typeSymbol.declaredFields + + def casts(m: Expr[ListMap[String, _]])(using Quotes) = + typesAndLabels.map { case (tpe, label) => + val interestingField = s.find (_.name == label) + val fieldType = interestingField match { + case Some(interestingField) => + val ct = tpe.memberType (interestingField) + ct.asType + case None => + tpe.asType + } + fieldType match { case '[t] => + '{ try ${m}.apply(${Expr(label)}).asInstanceOf[t] + catch { + case _: ClassCastException => throw new RuntimeException("Field " + ${Expr(label)} + " has invalid type") + case _: Throwable => throw new RuntimeException("Field " + ${Expr(label)} + " is missing") + } + }.asTerm + } + } + + def appliedConstructor(m: Expr[ListMap[String, _]])(using Quotes) = { + Apply(Select.unique(Ref(TypeRepr.of[T].typeSymbol.companionModule), "apply"), casts(m)).asExprOf[T] + } + + val fromMap = '{ (m: ListMap[String, _]) => + try { zio.prelude.Validation.succeed(${appliedConstructor('m)}) } catch { + case e: Throwable => zio.prelude.Validation.fail(e.getMessage) + }} + + def tuples(b: Expr[T])(using Quotes) = + typesAndLabels.map { case (tpe, label) => + val interestingField = s.find (_.name == label) + val fieldType = interestingField match { + case Some(interestingField) => + val ct = tpe.memberType (interestingField) + ct.asType + case None => + tpe.asType + } + fieldType match { case '[t] => + '{(${Expr(label)}, ${Select.unique(b.asTerm, label).asExprOf[t]})} + } + } + val toMap = '{(b: T) => zio.prelude.Validation.succeed(ListMap.apply(${Varargs(tuples('b))} :_*)) } + + '{${genericRecord.asExprOf[GenericRecord]}.transformOrFail[T]($fromMap, $toMap)}.asTerm + } + + val lazyValDef = ValDef(selfRefSymbol, Some(applied.changeOwner(selfRefSymbol))) + + applied.asExpr match { + case '{ type tt <: Schema[T]; $ex : `tt` } => + '{ + ${Block( + List(lazyValDef), + selfRef + ).asExpr}.asInstanceOf[tt] + } + } + } + + + private def fromDeclarations(from: Symbol): List[(String, List[Expr[Any]])] = + from.declaredFields.map { + field => + field.name -> field.annotations.filter(filterAnnotation).map(_.asExpr) + } + + private def fromConstructor(from: Symbol): scala.collection.Map[String, List[Expr[Any]]] = + from.primaryConstructor.paramSymss.flatten.map { field => + field.name -> field.annotations + .filter(filterAnnotation) + .map(_.asExpr.asInstanceOf[Expr[Any]]) + }.toMap + + def deriveEnum[T: Type](mirror: Mirror, stack: Stack)(using Quotes) = { + val selfRefSymbol = Symbol.newVal(Symbol.spliceOwner, s"derivedSchema${stack.size}", TypeRepr.of[Schema[T]], Flags.Lazy, Symbol.noSymbol) + val selfRef = Ref(selfRefSymbol) + val newStack = stack.push(selfRef, TypeRepr.of[T]) + + val labels = mirror.labels.toList + val types = mirror.types.toList + val typesAndLabels = types.zip(labels) + + val cases = typesAndLabels.map { case (tpe, label) => deriveCase[T](tpe, label, newStack) } + + val annotationExprs = TypeRepr.of[T].typeSymbol.annotations.filter(filterAnnotation).map(_.asExpr) + val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) } + + val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} + + val applied = if (cases.length <= 22) { + val args = List(typeInfo) ++ cases :+ annotations + val terms = Expr.ofTupleFromSeq(args) + val ctor = TypeRepr.of[Enum2[_, _, _]].typeSymbol.primaryConstructor + + val typeArgs = + (types.appended(TypeRepr.of[T])).map { tpe => + tpe.asType match + case '[tt] => TypeTree.of[tt] + } + + val typeTree = enumTypeTree[T](labels.length) + + Apply( + TypeApply( + Select(New(typeTree), ctor), + typeArgs + ), + args.map(_.asTerm) + ) + } else { + '{EnumN($typeInfo, CaseSet(${Varargs(cases)}: _*).asInstanceOf[CaseSet.Aux[T]], $annotations) }.asTerm + } + + val lazyValDef = ValDef(selfRefSymbol, Some(applied.changeOwner(selfRefSymbol))) + + applied.asExpr match { + case '{ type tt <: Schema[T]; $ex : `tt` } => + '{ + ${Block( + List(lazyValDef), + selfRef + ).asExpr}.asInstanceOf[tt] + } + } + } + + + // Derive Field for a CaseClass + def deriveField[T: Type](repr: TypeRepr, name: String, anns: List[Expr[Any]], stack: Stack)(using Quotes) = { + import zio.schema.validation.SchemaValidation + import zio.schema.annotation.validate + + val tpe = TypeRepr.of[T] + val s = tpe.typeSymbol.declaredFields + val interestingField = s.find (_.name == name) + + val fieldType = interestingField match { + case Some(interestingField) => + val ct = tpe.memberType (interestingField) + ct.asType + case None => + repr.asType + } + fieldType match { case '[t] => + val schema = deriveSchema[t](stack) + val validations = anns.collect { + case ann if ann.isExprOf[validate[t]] => ann.asExprOf[validate[t]] + } + val validator: Expr[SchemaValidation[t]] = validations.foldLeft[Expr[SchemaValidation[t]]]('{SchemaValidation.succeed}){ + case (acc, expr) => '{ + $acc && ${expr}.validation + } + } + + val typeParams = TypeRepr.of[T].dealias match + case AppliedType (t, params) => params + case _ => Nil + + val get = '{ (t: T) => ${Select.unique('t.asTerm, name).asExprOf[t]} } + val set = '{ (ts: T, v: t) => ${Select.overloaded('ts.asTerm, "copy", typeParams, List(NamedArg(name, 'v.asTerm))).asExprOf[T]} } + val chunk = '{ zio.Chunk.fromIterable(${ Expr.ofSeq(anns.reverse) }) } + + if (anns.nonEmpty) { + val (newName, newNameValue) = anns.collectFirst { + case ann if ann.isExprOf[fieldName] => + val fieldNameAnn = ann.asExprOf[fieldName] + ('{${fieldNameAnn}.name}, extractFieldNameValue(fieldNameAnn)) + }.getOrElse((Expr(name), name)) + + val f = '{ Field($newName, $schema, $chunk, $validator, $get, $set)} + addFieldName(newNameValue)(f) // TODO: we need to pass the evaluated annotation value instead of name + } else { + val f = '{ Field(${Expr(name)}, $schema, $chunk, $validator, $get, $set) } + addFieldName(name)(f) + } + } + } + +// Derive Field for a GenericRecord + def deriveGenericField[T: Type](repr: TypeRepr, name: String, anns: List[Expr[Any]], stack: Stack)(using Quotes) = { + import zio.schema.validation.SchemaValidation + import zio.schema.annotation.validate + + val tpe = TypeRepr.of[T] + val s = tpe.typeSymbol.declaredFields + val interestingField = s.find (_.name == name) + + val fieldType = interestingField match { + case Some(interestingField) => + val ct = tpe.memberType (interestingField) + ct.asType + case None => + repr.asType + } + fieldType match { case '[t] => + val schema = deriveSchema[t](stack) + val validations = anns.collect { + case ann if ann.isExprOf[validate[t]] => ann.asExprOf[validate[t]] + } + val validator: Expr[SchemaValidation[t]] = validations.foldLeft[Expr[SchemaValidation[t]]]('{SchemaValidation.succeed}){ + case (acc, expr) => '{ + $acc && ${expr}.validation + } + } + + val typeParams = TypeRepr.of[T].dealias match + case AppliedType (t, params) => params + case _ => Nil + + val get = '{ (t: ListMap[String, _]) => t.apply(${Expr(name)}).asInstanceOf[t] } + val set = '{ (ts: ListMap[String, _], v: t) => ts.updated(${Expr(name)}, v) } + val chunk = '{ zio.Chunk.fromIterable(${ Expr.ofSeq(anns.reverse) }) } + + if (anns.nonEmpty) { + val newName = anns.collectFirst { + case ann if ann.isExprOf[fieldName] => '{${ann.asExprOf[fieldName]}.name} + }.getOrElse(Expr(name)) + + val f = '{ Field($newName, $schema, $chunk, $validator, $get, $set) } + addFieldName(name)(f) // TODO: we need to pass the evaluated annotation value instead of name + } else { + val f = '{ Field(${Expr(name)}, $schema, $chunk, $validator, $get, $set) } + addFieldName(name)(f) + } + } + } + + def addFieldName[R: Type, T: Type, F <: Field[R, T]: Type](name: String)(f: Expr[F])(using Quotes) = { + val withFieldName = TypeRepr.of[Field.WithFieldName] + val r = TypeRepr.of[R] + val t = TypeRepr.of[T] + val nameT = ConstantType(StringConstant(name)) + val fieldWithName = withFieldName.appliedTo(List(r, nameT, t)) + (Select.unique(f.asTerm, "asInstanceOf").appliedToType(fieldWithName).asExprOf[F], nameT) + } + + + // sealed case class Case[A, Z](id: String, codec: Schema[A], unsafeDeconstruct: Z => A, annotations: Chunk[Any] = Chunk.empty) { + def deriveCase[T: Type](repr: TypeRepr, label: String, stack: Stack)(using Quotes) = { + repr.asType match { case '[t] => + val schema = deriveSchema[t](stack) + val stringExpr = Expr(label) + + val annotationExprs = TypeRepr.of[t].typeSymbol.annotations.filter(filterAnnotation).map(_.asExpr) + val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) } + + val unsafeDeconstruct = '{ + (z: T) => z.asInstanceOf[t] + } + val construct = '{ + (a: t) => a.asInstanceOf[T] + } + + val isCase = '{ (z: T) => z.isInstanceOf[t @unchecked] } + + '{ Case(${Expr(label)}, $schema, $unsafeDeconstruct, $construct, $isCase, $annotations) } + } + } + + + def caseClassConstructor[T: Type](mirror: Mirror) = { + val product = Expr.summon[scala.deriving.Mirror.ProductOf[T]].get + val methodType = MethodType(mirror.labels.toList)(_ => mirror.types.toList, _ => TypeRepr.of[T]) + Lambda(Symbol.spliceOwner, methodType, { (sym, reprs) => + val tupled = Expr.ofTupleFromSeq(reprs.map(_.asExpr)) + Select.overloaded(product.asTerm, "fromProduct", List.empty, List(tupled.asTerm)) + }) + } + + private def filterAnnotation(a: Term): Boolean = + a.tpe.typeSymbol.maybeOwner.isNoSymbol || + a.tpe.typeSymbol.owner.fullName != "scala.annotation.internal" + + def extractFieldNameValue(attribute: Expr[fieldName]): String = + attribute.asTerm match { + // Apply(Select(New(Ident(fieldName)),),List(Literal(Constant(renamed)))) + case Apply(_, List(Literal(StringConstant(name)))) => + name + } + + def caseClassTypeTree[T: Type](arity: Int): TypeTree = + arity match { + case 0 => TypeTree.of[CaseClass0[T]] + case 1 => TypeTree.of[CaseClass1[_, T]] + case 2 => TypeTree.of[CaseClass2[_, _, T]] + case 3 => TypeTree.of[CaseClass3[_, _, _, T]] + case 4 => TypeTree.of[CaseClass4[_, _, _, _, T]] + case 5 => TypeTree.of[CaseClass5[_, _, _, _, _, T]] + case 6 => TypeTree.of[CaseClass6[_, _, _, _, _, _, T]] + case 7 => TypeTree.of[CaseClass7[_, _, _, _, _, _, _, T]] + case 8 => TypeTree.of[CaseClass8[_, _, _, _, _, _, _, _, T]] + case 9 => TypeTree.of[CaseClass9[_, _, _, _, _, _, _, _, _, T]] + case 10 => TypeTree.of[CaseClass10[_, _, _, _, _, _, _, _, _, _, T]] + case 11 => TypeTree.of[CaseClass11[_, _, _, _, _, _, _, _, _, _, _, T]] + case 12 => TypeTree.of[CaseClass12[_, _, _, _, _, _, _, _, _, _, _, _, T]] + case 13 => TypeTree.of[CaseClass13[_, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 14 => TypeTree.of[CaseClass14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 15 => TypeTree.of[CaseClass15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 16 => TypeTree.of[CaseClass16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 17 => TypeTree.of[CaseClass17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 18 => TypeTree.of[CaseClass18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 19 => TypeTree.of[CaseClass19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 20 => TypeTree.of[CaseClass20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 21 => TypeTree.of[CaseClass21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 22 => TypeTree.of[CaseClass22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + } + + def typeRprOf[T: Type](arity: Int): TypeRepr = + arity match { + case 0 => TypeRepr.of[CaseClass0[T]] + case 1 => TypeRepr.of[CaseClass1[_, T]] + case 2 => TypeRepr.of[CaseClass2[_, _, T]] + case 3 => TypeRepr.of[CaseClass3[_, _, _, T]] + case 4 => TypeRepr.of[CaseClass4[_, _, _, _, T]] + case 5 => TypeRepr.of[CaseClass5[_, _, _, _, _, T]] + case 6 => TypeRepr.of[CaseClass6[_, _, _, _, _, _, T]] + case 7 => TypeRepr.of[CaseClass7[_, _, _, _, _, _, _, T]] + case 8 => TypeRepr.of[CaseClass8[_, _, _, _, _, _, _, _, T]] + case 9 => TypeRepr.of[CaseClass9[_, _, _, _, _, _, _, _, _, T]] + case 10 => TypeRepr.of[CaseClass10[_, _, _, _, _, _, _, _, _, _, T]] + case 11 => TypeRepr.of[CaseClass11[_, _, _, _, _, _, _, _, _, _, _, T]] + case 12 => TypeRepr.of[CaseClass12[_, _, _, _, _, _, _, _, _, _, _, _, T]] + case 13 => TypeRepr.of[CaseClass13[_, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 14 => TypeRepr.of[CaseClass14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 15 => TypeRepr.of[CaseClass15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 16 => TypeRepr.of[CaseClass16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 17 => TypeRepr.of[CaseClass17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 18 => TypeRepr.of[CaseClass18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 19 => TypeRepr.of[CaseClass19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 20 => TypeRepr.of[CaseClass20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 21 => TypeRepr.of[CaseClass21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 22 => TypeRepr.of[CaseClass22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + } + + def caseClassWithFieldsType(arity: Int): TypeRepr = + arity match { + case 1 => TypeRepr.of[CaseClass1.WithFields] + case 2 => TypeRepr.of[CaseClass2.WithFields] + case 3 => TypeRepr.of[CaseClass3.WithFields] + case 4 => TypeRepr.of[CaseClass4.WithFields] + case 5 => TypeRepr.of[CaseClass5.WithFields] + case 6 => TypeRepr.of[CaseClass6.WithFields] + case 7 => TypeRepr.of[CaseClass7.WithFields] + case 8 => TypeRepr.of[CaseClass8.WithFields] + case 9 => TypeRepr.of[CaseClass9.WithFields] + case 10 => TypeRepr.of[CaseClass10.WithFields] + case 11 => TypeRepr.of[CaseClass11.WithFields] + case 12 => TypeRepr.of[CaseClass12.WithFields] + case 13 => TypeRepr.of[CaseClass13.WithFields] + case 14 => TypeRepr.of[CaseClass14.WithFields] + case 15 => TypeRepr.of[CaseClass15.WithFields] + case 16 => TypeRepr.of[CaseClass16.WithFields] + case 17 => TypeRepr.of[CaseClass17.WithFields] + case 18 => TypeRepr.of[CaseClass18.WithFields] + case 19 => TypeRepr.of[CaseClass19.WithFields] + case 20 => TypeRepr.of[CaseClass20.WithFields] + case 21 => TypeRepr.of[CaseClass21.WithFields] + case 22 => TypeRepr.of[CaseClass22.WithFields] + } + + def enumTypeTree[T: Type](arity: Int): TypeTree = + arity match { + case 0 => TypeTree.of[CaseClass0[T]] + case 1 => TypeTree.of[Enum1[_, T]] + case 2 => TypeTree.of[Enum2[_, _, T]] + case 3 => TypeTree.of[Enum3[_, _, _, T]] + case 4 => TypeTree.of[Enum4[_, _, _, _, T]] + case 5 => TypeTree.of[Enum5[_, _, _, _, _, T]] + case 6 => TypeTree.of[Enum6[_, _, _, _, _, _, T]] + case 7 => TypeTree.of[Enum7[_, _, _, _, _, _, _, T]] + case 8 => TypeTree.of[Enum8[_, _, _, _, _, _, _, _, T]] + case 9 => TypeTree.of[Enum9[_, _, _, _, _, _, _, _, _, T]] + case 10 => TypeTree.of[Enum10[_, _, _, _, _, _, _, _, _, _, T]] + case 11 => TypeTree.of[Enum11[_, _, _, _, _, _, _, _, _, _, _, T]] + case 12 => TypeTree.of[Enum12[_, _, _, _, _, _, _, _, _, _, _, _, T]] + case 13 => TypeTree.of[Enum13[_, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 14 => TypeTree.of[Enum14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 15 => TypeTree.of[Enum15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 16 => TypeTree.of[Enum16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 17 => TypeTree.of[Enum17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 18 => TypeTree.of[Enum18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 19 => TypeTree.of[Enum19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 20 => TypeTree.of[Enum20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 21 => TypeTree.of[Enum21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + case 22 => TypeTree.of[Enum22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, T]] + } + +} + diff --git a/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec$.scala b/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec.scala similarity index 99% rename from zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec$.scala rename to zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec.scala index 45ba1375c..6b880aaf6 100644 --- a/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec$.scala +++ b/zio-schema-derivation/shared/src/test/scala/zio/schema/SchemaSchemaValidationSpec.scala @@ -6,7 +6,7 @@ import zio.schema.annotation.validate import zio.schema.validation.{ SchemaValidation, SchemaValidationError } import zio.test._ -object SchemaSchemaValidationSpec$ extends ZIOSpecDefault { +object SchemaSchemaValidationSpec extends ZIOSpecDefault { import Assertion._ final case class ExampleData( 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 2fe05b040..51c274865 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 @@ -63,7 +63,7 @@ object JsonCodec { implicit def schemaBasedBinaryCodec[A](implicit schema: Schema[A]): BinaryCodec[A] = new BinaryCodec[A] { - override def decode(whole: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = + override def decode(whole: Chunk[Byte]): Validation[DecodeError, A] = JsonDecoder.decode( schema, new String(whole.toArray, JsonEncoder.CHARSET) @@ -78,7 +78,7 @@ object JsonCodec { case (_, fragments) => fragments.mkString } >>> ZPipeline.mapZIO { (s: String) => - ZIO.fromEither(JsonDecoder.decode(schema, s).toEither.left.map(_.head)) + JsonDecoder.decode(schema, s).toZIO } override def encode(value: A): Chunk[Byte] = @@ -363,7 +363,7 @@ object JsonCodec { } } - private def transformEncoder[A, B](schema: Schema[A], g: B => zio.prelude.Validation[String, A]): ZJsonEncoder[B] = + private def transformEncoder[A, B](schema: Schema[A], g: B => Validation[String, A]): ZJsonEncoder[B] = new ZJsonEncoder[B] { private lazy val innerEncoder = schemaEncoder(schema) @@ -477,7 +477,7 @@ object JsonCodec { import Codecs._ import ProductDecoder._ - final def decode[A](schema: Schema[A], json: String): zio.prelude.Validation[DecodeError, A] = + final def decode[A](schema: Schema[A], json: String): Validation[DecodeError, A] = schemaDecoder(schema).decodeJson(json) match { case Left(value) => Validation.fail(ReadError(Cause.empty, value)) case Right(value) => Validation.succeed(value) diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index aa611f613..4f8730053 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -535,9 +535,9 @@ object JsonCodecSpec extends ZIOSpecDefault { ) ) { case (schema, value) => - assertEncodesThenDecodes[Either[Map[Any, Any], Map[Any, Any]]]( - schema.asInstanceOf[Schema[Either[Map[Any, Any], Map[Any, Any]]]], - value.asInstanceOf[Either[Map[Any, Any], Map[Any, Any]]] + assertEncodesThenDecodes[scala.Either[Map[Any, Any], Map[Any, Any]]]( + schema.asInstanceOf[Schema[scala.Either[Map[Any, Any], Map[Any, Any]]]], + value.asInstanceOf[scala.Either[Map[Any, Any], Map[Any, Any]]] ) } }, @@ -553,9 +553,9 @@ object JsonCodecSpec extends ZIOSpecDefault { ) ) { case (schema, value) => - assertEncodesThenDecodes[Either[Set[Any], Set[Any]]]( - schema.asInstanceOf[Schema[Either[Set[Any], Set[Any]]]], - value.asInstanceOf[Either[Set[Any], Set[Any]]] + assertEncodesThenDecodes[scala.Either[Set[Any], Set[Any]]]( + schema.asInstanceOf[Schema[scala.Either[Set[Any], Set[Any]]]], + value.asInstanceOf[scala.Either[Set[Any], Set[Any]]] ) } }, diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala index 767046590..3290317da 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackCodec.scala @@ -7,7 +7,7 @@ import zio.prelude.Validation import zio.schema.codec.DecodeError.ReadError import zio.schema.{ Schema, StandardType } import zio.stream.ZPipeline -import zio.{ Cause, Chunk, ZIO } +import zio.{ Cause, Chunk } object MessagePackCodec { implicit def messagePackCodec[A](implicit schema: Schema[A]): BinaryCodec[A] = @@ -30,17 +30,12 @@ object MessagePackCodec { override def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] = ZPipeline.mapChunksZIO { chunk => - ZIO.fromEither( - //FIXME?? - decodeChunk(chunk).map(Chunk(_)).toEither.left.map(_.head) - ) + decodeChunk(chunk).map(Chunk(_)).toZIO } private def decodeChunk(chunk: Chunk[Byte]) = new MessagePackDecoder(chunk) .decode(schema) -// .left -// .map(identity) } //TODO those are duplicates from ThriftCodec diff --git a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala index 3765227db..6cb6447c1 100644 --- a/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala +++ b/zio-schema-msg-pack/shared/src/main/scala/zio/schema/codec/MessagePackDecoder.scala @@ -131,13 +131,6 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { readFields(m.updated(fieldName, value), index + 1) } } -// .flatMap(value => { -// if (index == fields.size) { -// succeed(m.updated(fieldName, value)) -// } else { -// readFields(m.updated(fieldName, value), index + 1) -// } -// }) case None => fail(path, s"Could not find schema for field: [$fieldName] on index: $index") } @@ -159,7 +152,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { def decodeElements(n: Int, m: scala.collection.mutable.Map[K, V]): Result[scala.collection.immutable.Map[K, V]] = if (n > 0) { (decodeValue(path, schema.keySchema), decodeValue(path, schema.valueSchema)) match { - case (zio.prelude.Validation.Success(_, key), zio.prelude.Validation.Success(_, value)) => decodeElements(n - 1, m += ((key, value))) + case (Validation.Success(_, key), Validation.Success(_, value)) => decodeElements(n - 1, m += ((key, value))) case (l, r) => val key = l.fold(_.map(_.message).toString(), _.toString) val value = r.fold(_.map(_.message).toString(), _.toString) @@ -180,8 +173,8 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { def decodeElements(n: Int, cb: ChunkBuilder[A]): Result[Chunk[A]] = if (n > 0) { decodeValue(path, elementSchema) match { - case zio.prelude.Validation.Success(_, elem) => decodeElements(n - 1, cb += elem) - case failure @ zio.prelude.Validation.Failure(_, _) => failure + case Validation.Success(_, elem) => decodeElements(n - 1, cb += elem) + case failure @ Validation.Failure(_, _) => failure } } else { succeed(cb.result()) @@ -225,7 +218,7 @@ private[codec] class MessagePackDecoder(bytes: Chunk[Byte]) { } yield new java.math.BigDecimal(unscaled, scale, ctx) opt match { - case Some(value) => zio.prelude.Validation.succeed(value) + case Some(value) => Validation.succeed(value) case None => fail(path, s"Invalid big decimal record $data") } } diff --git a/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala b/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala index 5d2d9f275..7263e8945 100644 --- a/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala +++ b/zio-schema-msg-pack/shared/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala @@ -16,7 +16,7 @@ import zio.schema._ import zio.stream.{ ZSink, ZStream } import zio.test.Assertion._ import zio.test._ -import zio.{ Chunk, Console, NonEmptyChunk, Scope, Task, ZIO } +import zio.{ Chunk, Console, Scope, Task, ZIO } object MessagePackCodecSpec extends ZIOSpecDefault { @@ -696,7 +696,7 @@ object MessagePackCodecSpec extends ZIOSpecDefault { }, test("empty input by non streaming variant") { assertZIO(decodeNS(Schema[Int], "").exit)( - failsWithA[NonEmptyChunk[DecodeError]] + failsWithA[DecodeError] ) } ), @@ -709,7 +709,7 @@ object MessagePackCodecSpec extends ZIOSpecDefault { failsWithA[DecodeError] ) && assert(d2)( - failsWithA[NonEmptyChunk[DecodeError]] + failsWithA[DecodeError] ) }, test("missing value") { @@ -988,8 +988,8 @@ object MessagePackCodecSpec extends ZIOSpecDefault { .run(ZSink.collectAll) //NS == non streaming variant of decode - def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, NonEmptyChunk[DecodeError], A] = - ZIO.succeed(MessagePackCodec.messagePackCodec(schema).decode(fromHex(hex)).toEither).absolve + def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, DecodeError, A] = + MessagePackCodec.messagePackCodec(schema).decode(fromHex(hex)).toZIO def encodeAndDecode[A](schema: Schema[A], input: A): ZIO[Any, DecodeError, Chunk[A]] = ZStream @@ -1010,24 +1010,22 @@ object MessagePackCodecSpec extends ZIOSpecDefault { schema: Schema[A], input: A, print: Boolean = false - ): ZIO[Any, NonEmptyChunk[DecodeError], A] = + ): ZIO[Any, DecodeError, A] = ZIO .succeed(input) .tap(value => Console.printLine(s"Input Value: $value").when(print).ignore) .map(a => MessagePackCodec.messagePackCodec(schema).encode(a)) .tap(encoded => Console.printLine(s"\nEncoded Bytes:\n${toHex(encoded)}").when(print).ignore) - .map(ch => MessagePackCodec.messagePackCodec(schema).decode(ch).toEither) - .absolve + .flatMap(ch => MessagePackCodec.messagePackCodec(schema).decode(ch).toZIO) def encodeAndDecodeNS[A]( encodeSchema: Schema[A], decodeSchema: Schema[A], input: A - ): ZIO[Any, NonEmptyChunk[DecodeError], A] = + ): ZIO[Any, DecodeError, A] = ZIO .succeed(input) .map(a => MessagePackCodec.messagePackCodec(encodeSchema).encode(a)) - .map(ch => MessagePackCodec.messagePackCodec(decodeSchema).decode(ch).toEither) - .absolve + .flatMap(ch => MessagePackCodec.messagePackCodec(decodeSchema).decode(ch).toZIO) } 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 d25c8e87f..b1decd2ee 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 @@ -15,7 +15,7 @@ import zio.schema._ import zio.schema.codec.DecodeError.{ ExtraFields, MalformedField, MissingField } import zio.schema.codec.ProtobufCodec.Protobuf.WireType.LengthDelimited import zio.stream.ZPipeline -import zio.{ Cause, Chunk, ChunkBuilder, Unsafe, ZIO } +import zio.{ Cause, Chunk, ChunkBuilder, Unsafe } object ProtobufCodec { @@ -26,7 +26,7 @@ object ProtobufCodec { override def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] = ZPipeline.mapChunksZIO( - chunk => ZIO.fromEither(new Decoder(chunk).decode(schema).map(Chunk(_)).toEither.left.map(_.head)) + chunk => new Decoder(chunk).decode(schema).map(Chunk(_)).toZIO ) override def encode(value: A): Chunk[Byte] = diff --git a/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala b/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala index 7adc61075..e5d6e294c 100644 --- a/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala +++ b/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala @@ -8,6 +8,7 @@ import scala.util.Try import zio.Console._ import zio._ +import zio.prelude.Validation import zio.schema.CaseSet._ import zio.schema.meta.MetaSchema import zio.schema.{ CaseSet, DeriveSchema, DynamicValue, DynamicValueGen, Schema, SchemaGen, StandardType, TypeId } @@ -1044,10 +1045,7 @@ object ProtobufCodecSpec extends ZIOSpecDefault { //NS == non streaming variant of decode def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, DecodeError, A] = - ZIO - .succeed(ProtobufCodec.protobufCodec(schema).decode(fromHex(hex))) - .map(_.toEither.left.map(_.head)) - .absolve[DecodeError, A] + ProtobufCodec.protobufCodec(schema).decode(fromHex(hex)).toZIO def encodeAndDecode[A](schema: Schema[A], input: A): ZIO[Any, DecodeError, Chunk[A]] = ProtobufCodec @@ -1086,14 +1084,13 @@ object ProtobufCodecSpec extends ZIOSpecDefault { .map(a => ProtobufCodec.protobufCodec(schema).encode(a)) .tap(encoded => printLine(s"\nEncoded Bytes (${encoded.size}):\n${toHex(encoded)}").when(print).ignore) .map(ch => ProtobufCodec.protobufCodec(schema).decode(ch)) - .map(_.toEither.left.map(_.head)) - .absolve + .flatMap(_.toZIO) def encodeAndDecodeNS2[A]( schema: Schema[A], input: A, print: Boolean = false - ): ZIO[Any, DecodeError, zio.prelude.Validation[DecodeError, A]] = + ): ZIO[Any, DecodeError, Validation[DecodeError, A]] = ZIO .succeed(input) .tap(value => printLine(s"Input Value: $value").when(print).ignore) @@ -1110,7 +1107,6 @@ object ProtobufCodecSpec extends ZIOSpecDefault { .succeed(input) .map(a => ProtobufCodec.protobufCodec(encodeSchema).encode(a)) .map(ch => ProtobufCodec.protobufCodec(decodeSchema).decode(ch)) - .map(_.toEither.left.map(_.head)) - .absolve + .flatMap(_.toZIO) } diff --git a/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala b/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala index acc2cd00f..43d0d9f07 100644 --- a/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala +++ b/zio-schema-thrift/shared/src/main/scala/zio/schema/codec/ThriftCodec.scala @@ -16,13 +16,13 @@ import zio.schema._ import zio.schema.annotation.{ fieldDefaultValue, optionalField, transientField } import zio.schema.codec.DecodeError.{ EmptyContent, MalformedFieldWithPath, ReadError, ReadErrorWithPath } import zio.stream.ZPipeline -import zio.{ Cause, Chunk, NonEmptyChunk, Unsafe, ZIO } +import zio.{ Cause, Chunk, NonEmptyChunk, Unsafe } object ThriftCodec { implicit def thriftCodec[A](implicit schema: Schema[A]): BinaryCodec[A] = new BinaryCodec[A] { - override def decode(whole: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = + override def decode(whole: Chunk[Byte]): Validation[DecodeError, A] = if (whole.isEmpty) Validation.fail(EmptyContent("No bytes to decode")) else @@ -30,9 +30,7 @@ object ThriftCodec { override def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] = ZPipeline.mapChunksZIO { chunk => - ZIO.fromEither( - decodeChunk(chunk).map(Chunk(_)).toEither.left.map(_.head) - ) + decodeChunk(chunk).map(Chunk(_)).toZIO } override def encode(value: A): Chunk[Byte] = @@ -45,7 +43,7 @@ object ThriftCodec { } } - private def decodeChunk(chunk: Chunk[Byte]): zio.prelude.Validation[DecodeError, A] = + private def decodeChunk(chunk: Chunk[Byte]): Validation[DecodeError, A] = if (chunk.isEmpty) Validation.fail(EmptyContent("No bytes to decode")) else { @@ -624,11 +622,11 @@ object ThriftCodec { } } Unsafe.unsafe { implicit u => - record.construct(allValues).mapError(message => fail(context, message)) + record.construct(allValues).fold(message => fail(context, message), a => a) } } else { Unsafe.unsafe { implicit u => - record.construct(Chunk.empty).mapError(message => fail(context, message)) + record.construct(Chunk.empty).fold(message => fail(context, message), a => a) } } @@ -811,7 +809,7 @@ object ThriftCodec { override protected def transform( context: DecoderContext, value: Any, - f: Any => zio.prelude.Validation[String, Any], + f: Any => Validation[String, Any], schema: Schema[_] ): Any = f(value).fold(v => fail(context, v), a => a) diff --git a/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala b/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala index 3fe6166ce..b2aed6222 100644 --- a/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala +++ b/zio-schema-thrift/shared/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala @@ -34,7 +34,7 @@ import zio.schema.{ CaseSet, DeriveSchema, DynamicValue, DynamicValueGen, Schema import zio.stream.{ ZSink, ZStream } import zio.test.Assertion._ import zio.test._ -import zio.{ Chunk, Console, NonEmptyChunk, Scope, Task, ZIO } +import zio.{ Chunk, Console, Scope, Task, ZIO } // TODO: use generators instead of manual encode/decode @@ -1131,8 +1131,8 @@ object ThriftCodecSpec extends ZIOSpecDefault { .run(ZSink.collectAll) //NS == non streaming variant of decode - def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, NonEmptyChunk[DecodeError], A] = - ZIO.succeed(ThriftCodec.thriftCodec(schema).decode(fromHex(hex)).toEither).absolve[NonEmptyChunk[DecodeError], A] + def decodeNS[A](schema: Schema[A], hex: String): ZIO[Any, DecodeError, A] = + ThriftCodec.thriftCodec(schema).decode(fromHex(hex)).toZIO def encodeAndDecode[A](schema: Schema[A], input: A): ZIO[Any, DecodeError, Chunk[A]] = ZStream @@ -1153,26 +1153,24 @@ object ThriftCodecSpec extends ZIOSpecDefault { schema: Schema[A], input: A, print: Boolean = false - ): ZIO[Any, NonEmptyChunk[DecodeError], A] = + ): ZIO[Any, DecodeError, A] = ZIO .succeed(input) .tap(value => Console.printLine(s"Input Value: $value").when(print).ignore) .map(a => ThriftCodec.thriftCodec(schema).encode(a)) .tap(encoded => Console.printLine(s"\nEncoded Bytes:\n${toHex(encoded)}").when(print).ignore) .map(ch => ThriftCodec.thriftCodec(schema).decode(ch)) - .map(_.toEither) - .absolve + .flatMap(_.toZIO) def encodeAndDecodeNS[A]( encodeSchema: Schema[A], decodeSchema: Schema[A], input: A - ): ZIO[Any, NonEmptyChunk[DecodeError], A] = + ): ZIO[Any, DecodeError, A] = ZIO .succeed(input) .map(a => ThriftCodec.thriftCodec(encodeSchema).encode(a)) .map(ch => ThriftCodec.thriftCodec(decodeSchema).decode(ch)) - .map(_.toEither) - .absolve + .flatMap(_.toZIO) } diff --git a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala index d1462c629..b8b3ac7bb 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala @@ -2,6 +2,7 @@ package zio.schema import scala.util.control.NonFatal +import zio.prelude.Validation import zio.schema.MutableSchemaBasedValueBuilder.CreateValueFromSchemaError import zio.{ Chunk, ChunkBuilder } @@ -157,7 +158,7 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { protected def transform( context: Context, value: Target, - f: Any => zio.prelude.Validation[String, Any], + f: Any => Validation[String, Any], schema: Schema[_] ): Target @@ -676,7 +677,7 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { currentSchema = schema push { result => finishWith( - transform(currentContext, result, f.asInstanceOf[Any => zio.prelude.Validation[String, Any]], s) + transform(currentContext, result, f.asInstanceOf[Any => Validation[String, Any]], s) ) } @@ -1164,12 +1165,12 @@ trait SimpleMutableSchemaBasedValueBuilder[Target] extends MutableSchemaBasedVal override protected def transform( context: Unit, value: Target, - f: Any => zio.prelude.Validation[String, Any], + f: Any => Validation[String, Any], schema: Schema[_] ): Target = transform(value, f, schema) - protected def transform(value: Target, f: Any => zio.prelude.Validation[String, Any], schema: Schema[_]): Target + protected def transform(value: Target, f: Any => Validation[String, Any], schema: Schema[_]): Target override protected def fail(context: Unit, message: String): Target = fail(message) diff --git a/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala b/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala index 3760b19b9..dcb4e9952 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/codec/Codecs.scala @@ -17,12 +17,13 @@ package zio.schema.codec import zio.constraintless._ +import zio.prelude.Validation import zio.stream.ZPipeline trait Codecs[Whole, Element, Types <: TypeList] { def encode[T](value: T)(implicit ev: T IsElementOf Types): Whole def streamEncoder[T](implicit ev: T IsElementOf Types): ZPipeline[Any, Nothing, T, Element] - def decode[T](whole: Whole)(implicit ev: T IsElementOf Types): zio.prelude.Validation[DecodeError, T] + def decode[T](whole: Whole)(implicit ev: T IsElementOf Types): Validation[DecodeError, T] def streamDecoder[T](implicit ev: T IsElementOf Types): ZPipeline[Any, DecodeError, Element, T] } @@ -39,7 +40,7 @@ object Codecs { final override def decode[T]( whole: Whole - )(implicit ev: IsElementOf[T, Types]): zio.prelude.Validation[DecodeError, T] = + )(implicit ev: IsElementOf[T, Types]): Validation[DecodeError, T] = instances.withInstance((codec: Codec[Whole, Element, T]) => codec.decode(whole)) final override def streamDecoder[T](implicit ev: IsElementOf[T, Types]): ZPipeline[Any, DecodeError, Element, T] = diff --git a/zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberSchemaValidationSpec$.scala b/zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberSchemaValidationSpec.scala similarity index 99% rename from zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberSchemaValidationSpec$.scala rename to zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberSchemaValidationSpec.scala index 927090ef2..c8d935828 100644 --- a/zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberSchemaValidationSpec$.scala +++ b/zio-schema/shared/src/test/scala/zio/schema/validation/PhoneNumberSchemaValidationSpec.scala @@ -2,7 +2,7 @@ package zio.schema.validation import zio.Scope import zio.test._ -object PhoneNumberSchemaValidationSpec$ extends ZIOSpecDefault { +object PhoneNumberSchemaValidationSpec extends ZIOSpecDefault { def spec: Spec[Environment with TestEnvironment with Scope, Any] = suite("PhoneNumberValidationSpec")( test("Regex phone number validation for Ascension Island") {