### Automatic Migration Derivation Example Source: https://github.com/zio/zio-schema/blob/main/docs/operations/schema-migration.md This example shows how to automatically derive migration steps between two different `Person` case classes (`Person1` and `Person2`) using `Migration.derive`. ```scala import zio.schema._ import zio.schema.meta._ case class Person1(name: String, age: Int, language: String, height: Int) object Person1 { implicit val schema: Schema[Person1] = DeriveSchema.gen } case class Person2( name: String, role: String, language: Set[String], height: Double ) object Person2 { implicit val schema: Schema[Person2] = DeriveSchema.gen } val migrations = Migration.derive( MetaSchema.fromSchema(Person1.schema), MetaSchema.fromSchema(Person2.schema) ) println(migrations) ``` -------------------------------- ### Manual Schema Migration Example Source: https://github.com/zio/zio-schema/blob/main/docs/operations/schema-migration.md This example demonstrates manually migrating a `Person1` object to a `Person2` object by deleting the 'age' field using a `DeleteNode` migration. ```scala import zio.Chunk import zio.schema.meta.Migration.DeleteNode import zio.schema.meta.{Migration, NodePath} import zio.schema.{DeriveSchema, Schema} case class Person1(name: String, age: Int) object Person1 { implicit val schema: Schema[Person1] = DeriveSchema.gen } case class Person2(name: String) object Person2 { implicit val schema: Schema[Person2] = DeriveSchema.gen } val person1: Person1 = Person1("John Doe", 42) val migrations: Chunk[Migration] = Chunk(DeleteNode(NodePath.root / "age")) val person2 = DeriveSchema .gen[Person1] .toDynamic(person1) .transform(migrations) .flatMap(_.toTypedValue[Person2]) assert(person2 == Right(Person2("John Doe"))) ``` -------------------------------- ### MessagePack Encode and Decode Example Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/messsage-pack.md This example demonstrates encoding a `Person` case class to MessagePack's binary format and then decoding it back. Ensure the `Person` schema and MessagePack codec are implicitly available. ```scala import zio._ import zio.schema.codec._ import zio.schema.{DeriveSchema, Schema} case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen implicit val msgPackCodec: BinaryCodec[Person] = MessagePackCodec.messagePackCodec(schema) } object Main extends ZIOAppDefault { def run = for { _ <- ZIO.debug("MessagePack Codec Example:") person: Person = Person("John", 42) encoded: Chunk[Byte] = Person.msgPackCodec.encode(person) _ <- ZIO.debug(s"person object encoded to MessagePack's binary format: ${toHex(encoded)}") decoded <- ZIO.fromEither(Person.msgPackCodec.decode(encoded)) _ <- ZIO.debug(s"MessagePack object decoded to Person class: $decoded") } yield () def toHex(bytes: Chunk[Byte]): String = bytes.map("%02x".format(_)).mkString(" ") } ``` -------------------------------- ### Example: Diffing and Patching a Person Object Source: https://github.com/zio/zio-schema/blob/main/docs/operations/diffing-and-patching.md Demonstrates how to use `diff` to create a patch for a `Person` object and `patch` to apply that change, verifying the result. ```scala import zio.schema._ case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen[Person] } val oldValue = Person("John", 42) val newValue = Person("John", 43) val patch: Patch[Person] = Person.schema.diff(oldValue, newValue) assert( Person.schema.patch(oldValue, patch) == Right(newValue) ) ``` -------------------------------- ### Protobuf Encoded Data Example Source: https://github.com/zio/zio-schema/blob/main/README.md This is the output of the Protobuf encoding example, showing the hexadecimal representation of the encoded Person data. ```scala Encoded data with protobuf codec: 0A044A6F686E102B ``` -------------------------------- ### Configure and Create XML Codec Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/xml.md Demonstrates how to configure the XML codec with custom writer settings and create an instance based on a ZIO Schema. This setup is useful for producing formatted XML output with declarations. ```scala import zio.schema.codec.xml.XmlCodec import zio.schema.codec.xml.WriterConfig import zio.schema.{DeriveSchema, Schema} case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen val config = XmlCodec.Configuration( writerConfig = WriterConfig.pretty.copy(includeDeclaration = true) ) val xmlCodec = XmlCodec.schemaBasedBinaryCodec(config)(schema) } ``` -------------------------------- ### Example: Derive Person Generator and Use in Test Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/zio-test-gen-derivation.md This example demonstrates deriving a `Gen[Sized, Person]` from a `Schema[Person]` and using it with `zio.test.check` to generate test cases. ```scala import zio.schema.{DeriveGen, DeriveSchema, Schema} import zio.test.{Gen, Sized} case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen val gen: Gen[Sized, Person] = DeriveGen.gen } import zio.test._ object ExampleSpec extends ZIOSpecDefault { def spec = test("example test") { check(Person.gen) { p => assertTrue(???) } } } ``` -------------------------------- ### Using Manual Optics to Update User Data Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/optics-derivation.md Demonstrates how to use manually created lenses to get, set, and update values within a User data structure. ```scala import zio._ object Main extends ZIOAppDefault { def run = for { _ <- ZIO.debug("Pure Optics") user = User("John", 34) updatedUser1 <- ZIO.fromEither(nameLens.setOptic("Jane")(user)) _ <- ZIO.debug(s"Name of user updated: $updatedUser1") updatedUser2 <- ZIO.fromEither(ageLens.setOptic(32)(user)) _ <- ZIO.debug(s"Age of user updated: $updatedUser2") updatedUser3 <- ZIO.fromEither( ageAndNameLens.set(("Jane", 32))(User("John", 34)) ) _ <- ZIO.debug(s"Name and age of the user updated: $updatedUser3") } yield () } ``` -------------------------------- ### Derive and Use Thrift Codec for Person Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/thrift.md Example demonstrating how to derive a Thrift codec for a Person case class and use it to encode and decode data. ```scala import zio._ import zio.schema.codec._ import zio.schema.{DeriveSchema, Schema} case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen implicit val thriftCodec: BinaryCodec[Person] = ThriftCodec.thriftCodec(schema) } object Main extends ZIOAppDefault { def run = for { _ <- ZIO.debug("Apache Thrift Codec Example:") person: Person = Person("John", 42) encoded: Chunk[Byte] = Person.thriftCodec.encode(person) _ <- ZIO.debug(s"person object encoded to Thrift's binary format: ${toHex(encoded)}") decoded <- ZIO.fromEither(Person.thriftCodec.decode(encoded)) _ <- ZIO.debug(s"Thrift object decoded to Person class: $decoded") } yield () def toHex(bytes: Chunk[Byte]): String = bytes.map("%02x".format(_)).mkString(" ") } ``` -------------------------------- ### Create Schema for Set of Persons Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md This example demonstrates how to create an implicit schema for a `Set` of `Person` objects using `Schema.set`. ```scala import zio._ import zio.schema._ import zio.schema.Schema._ case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen[Person] implicit val setSchema: Schema[scala.collection.immutable.Set[Person]] = Schema.set[Person] } ``` -------------------------------- ### Example Usage of DTO to Domain Conversion Source: https://github.com/zio/zio-schema/blob/main/docs/examples/mapping-dto-to-domain-object.md Demonstrates the complete flow of creating a PersonDTO, converting it to a Person domain object using the `fromPersonDTO` function, and printing the result. ```scala def run: zio.ZIO[Any, String, Any] = for { personDTO <- ZIO.succeed(PersonDTO("John", "Doe", (1981, 7, 13))) person <- Person.fromPersonDTO(personDTO) _ <- ZIO.debug(s"person: $person") } yield () ``` -------------------------------- ### Generating Avro Schema with Annotations Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/avro.md This example demonstrates how to generate an Avro schema from a ZIO Schema that includes annotations, and then prints the resulting Avro schema in JSON format. ```scala import zio._ import zio.schema.Schema import zio.schema.DeriveSchema import zio.schema.codec.AvroSchemaCodec object Main extends ZIOAppDefault { def run = for { _ <- ZIO.debug("AvroSchemaCodec Example with annotations:") avroSchema <- ZIO.fromEither(AvroSchemaCodec.encode(Person.schema)) _ <- ZIO.debug(s"The person schema in Avro Schema JSON format: $avroSchema") } yield () } ``` -------------------------------- ### Map Schema for String to Person Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md Example of creating a map schema for String keys and Person values using the Schema.map constructor. ```scala import zio._ import zio.schema._ import zio.schema.Schema._ case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen[Person] implicit val mapSchema: Schema[scala.collection.immutable.Map[String, Person]] = Schema.map[String, Person] } ``` -------------------------------- ### Encode Person Data with Protobuf using ZIO Schema Source: https://github.com/zio/zio-schema/blob/main/docs/index.md This example demonstrates how to define a schema for a case class, create a Protobuf codec, and then encode an instance of the case class to bytes using ZIO Streams. The output is then printed as a hexadecimal string. ```scala import zio._ import zio.stream._ import zio.schema.codec.{BinaryCodec, ProtobufCodec} import zio.schema.{DeriveSchema, Schema} import java.io.IOException final case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen val protobufCodec: BinaryCodec[Person] = ProtobufCodec.protobufCodec } object Main extends ZIOAppDefault { def run: ZIO[Any, IOException, Unit] = ZStream .succeed(Person("John", 43)) .via(Person.protobufCodec.streamEncoder) .runCollect .flatMap(x => Console.printLine(s"Encoded data with protobuf codec: ${toHex(x)}") ) def toHex(chunk: Chunk[Byte]): String = chunk.map("%02X".format(_)).mkString } ``` -------------------------------- ### Round-trip Conversion with JSON and Protobuf Encoders Source: https://github.com/zio/zio-schema/blob/main/docs/examples/combining-different-encoders.md This example demonstrates a full round-trip conversion of a Person object. It first encodes the object to JSON, then decodes it back, and subsequently encodes it to Protobuf and decodes it back. This showcases combining different encoders for sequential data transformation. ```scala object CombiningExample extends zio.App { import zio.schema.codec.JsonCodec import zio.schema.codec.ProtobufCodec import ManualConstruction._ import zio.stream.ZStream override def run(args: List[String]): UIO[ExitCode] = for { _ <- ZIO.unit _ <- ZIO.debug("combining roundtrip") person = Person("Michelle", 32) personToJson = JsonCodec.encoder[Person](schemaPerson) jsonToPerson = JsonCodec.decoder[Person](schemaPerson) personToProto = ProtobufCodec.encoder[Person](schemaPerson) protoToPerson = ProtobufCodec.decoder[Person](schemaPerson) newPerson <- ZStream(person) .tap(v => ZIO.debug("input object is: " + v)) .transduce(personToJson) .transduce(jsonToPerson) .tap(v => ZIO.debug("object after json roundtrip: " + v)) .transduce(personToProto) .transduce(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 } ``` -------------------------------- ### Define Schema for Person Case Class Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md This example shows how to manually define an implicit schema for a `Person` case class using `Schema.CaseClass2`, specifying its fields and constructor. ```scala import zio.schema._ final case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = Schema.CaseClass2[String, Int, Person]( id0 = TypeId.fromTypeName("Person"), field01 = Schema.Field( name0 = "name", schema0 = Schema[String], get0 = _.name, set0 = (p, x) => p.copy(name = x) ), field02 = Schema.Field( name0 = "age", schema0 = Schema[Int], get0 = _.age, set0 = (person, age) => person.copy(age = age) ), construct0 = (name, age) => Person(name, age), ) } ``` -------------------------------- ### Custom List Schema for Person Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md Example of creating a custom Sequence schema for a List of Person objects, defining conversions from and to Chunk. ```scala import zio._ import zio.schema._ import zio.schema.Schema._ case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen[Person] } val personListSchema: Schema[List[Person]] = Sequence[List[Person], Person, String]( elementSchema = Schema[Person], fromChunk = _.toList, toChunk = i => Chunk.fromIterable(i), annotations = Chunk.empty, identity = "List" ) ``` -------------------------------- ### Deriving Schema for Validated Age Type Source: https://github.com/zio/zio-schema/blob/main/docs/operations/transforming-schemas.md An example demonstrating how to derive a `Schema[Age]` from `Schema[Int]` using `transformOrFail`. This includes validation logic to ensure the integer value is within the acceptable age range. ```scala import zio.schema._ case class Age(i: Int) object Age { implicit val schema: Schema[Age] = Schema[Int].transformOrFail( (i: Int) => if (i >= 0 && i <= 120) Right(Age(i)) else Left("Age must be between 1 and 120"), (age: Age) => Right(age.i) ) } ``` -------------------------------- ### Encode and Decode Stream of Persons with ZIO Streams Source: https://github.com/zio/zio-schema/blob/main/docs/integration-with-zio-streams.md Use `streamEncoder` and `streamDecoder` to transform a stream of `Person` objects to and from JSON bytes. This example demonstrates a full roundtrip of encoding, decoding, and re-encoding. ```scala import zio._ import zio.stream._ import zio.schema._ import zio.schema.codec.JsonCodec object Main extends ZIOAppDefault { case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen[Person] } def run: ZIO[Any, Exception, Unit] = ZStream .fromIterable(Seq(Person("John", 42))) .debug("the input object is") .via(JsonCodec.schemaBasedBinaryCodec[Person].streamEncoder) .via(ZPipeline.utfDecode) .debug("json string of person") .via(ZPipeline.utf8Encode) .via(JsonCodec.schemaBasedBinaryCodec[Person].streamDecoder) .debug("person after roundtrip") .runDrain } ``` -------------------------------- ### Prepare and Test Project Source: https://github.com/zio/zio-schema/blob/main/README.md Commands to run before submitting a Pull Request to ensure tests are passing and code is properly formatted. ```bash sbt prepare sbt test ``` -------------------------------- ### Get Schema of a Schema Source: https://github.com/zio/zio-schema/blob/main/docs/operations/serialization-of-the-schema-itself.md Use the `serializable` method on a `Schema[A]` to obtain a `Schema[Schema[A]]`. This allows schemas to be serialized and deserialized. ```scala sealed trait Schema[A] { def serializable: Schema[Schema[A]] } ``` -------------------------------- ### Create Tuple Schemas Directly Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md Shows how to directly create schemas for tuples of different sizes using ZIO Schema's implicit conversions for tuples. ```scala import zio.schema._ val tuple2: Schema[(String, Int)] = Schema[(String, Int)] val tuple3: Schema[(String, Int, Boolean)] = Schema[(String, Int, Boolean)] // ... ``` -------------------------------- ### Use Protobuf Streaming Codecs Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/protobuf.md Demonstrates encoding and decoding streams of data using Protobuf codecs. This is useful for processing sequences of Protobuf messages efficiently. ```scala import zio._ import zio.schema.codec.{BinaryCodec, ProtobufCodec} import zio.schema.{DeriveSchema, Schema} import zio.stream.ZStream case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen implicit val protobufCodec: BinaryCodec[Person] = ProtobufCodec.protobufCodec(schema) } object Main extends ZIOAppDefault { def run = for { _ <- ZIO.debug("Protobuf Stream Codecs Example:") person = Person("John", 42) personToProto = Person.protobufCodec.streamEncoder protoToPerson = Person.protobufCodec.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 () } ``` -------------------------------- ### Add ZIO Optics to build.sbt Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/optics-derivation.md Include the ZIO Optics library in your project dependencies by adding this line to your build.sbt file. ```scala libraryDependencies += "dev.zio" %% "zio-optics" % "" ``` -------------------------------- ### Protobuf Roundtrip Test Source: https://github.com/zio/zio-schema/blob/main/docs/automatic-schema-derivation.md Demonstrates encoding and decoding a Customer object using ProtobufCodec to verify schema derivation and codec functionality. ```scala // Create a customer instance val customer = Customer( person = Person("John Doe", 42), paymentMethod = PaymentMethod.CreditCard("1000100010001000", 6, 2024) ) // Create binary codec from customer val customerCodec: BinaryCodec[Customer] = ProtobufCodec.protobufCodec[Customer] // Encode the customer object val encodedCustomer: Chunk[Byte] = customerCodec.encode(customer) // Decode the byte array back to the person instance val decodedCustomer: Either[DecodeError, Customer] = customerCodec.decode(encodedCustomer) assert(Right(customer) == decodedCustomer) ``` -------------------------------- ### Validate Person Object Against Schema Source: https://github.com/zio/zio-schema/blob/main/docs/operations/validating-types.md Validate a `Person` object against its defined schema. This example demonstrates validating a `Person` with an age outside the allowed range (0-120). A `Chunk[ValidationError]` is returned, listing the failed validation rules. ```scala import zio._ import zio.schema.validation._ val result: Chunk[ValidationError] = Person.schema.validate(Person("John Doe", 130)) println(result) // Output: // Chunk(EqualTo(130,120),LessThan(130,120)) ``` -------------------------------- ### Add ZIO Schema Optics to build.sbt Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/optics-derivation.md Add the ZIO Schema Optics module to your project dependencies to enable automatic derivation of optics from ZIO Schemas. ```scala libraryDependencies += "dev.zio" %% "zio-schema-optics" % @VERSION@ ``` -------------------------------- ### Protobuf Codec Roundtrip Test Source: https://github.com/zio/zio-schema/blob/main/docs/manual-schema-construction.md Demonstrates encoding a Customer object to Protobuf binary format and decoding it back. Ensure the decoded object matches the original. ```scala import zio.schema._ import zio.schema.codec._ import zio.schema.codec.ProtobufCodec._ // Create a customer instance val customer = Customer( person = Person("John Doe", 42), paymentMethod = PaymentMethod.CreditCard("1000100010001000", 6, 2024) ) // Create binary codec from customer val customerCodec: BinaryCodec[Customer] = ProtobufCodec.protobufCodec[Customer] // Encode the customer object val encodedCustomer: Chunk[Byte] = customerCodec.encode(customer) // Decode the byte array back to the person instance val decodedCustomer: Either[DecodeError, Customer] = customerCodec.decode(encodedCustomer) assert(Right(customer) == decodedCustomer) ``` -------------------------------- ### Define CaseClass1 and CaseClass2 Apply Methods Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md These definitions show the `apply` methods for `CaseClass1` and `CaseClass2`, illustrating how ZIO Schema constructs record schemas from fields and a constructor function. ```scala sealed trait CaseClass1[A, Z] extends Record[Z] object CaseClass1 { def apply[A, Z]( id0: TypeId, field0: Field[Z, A], defaultConstruct0: A => Z, annotations0: Chunk[Any] = Chunk.empty ): CaseClass1[A, Z] = ??? } object CaseClass2 { def apply[A1, A2, Z]( id0: TypeId, field01: Field[Z, A1], field02: Field[Z, A2], construct0: (A1, A2) => Z, annotations0: Chunk[Any] = Chunk.empty ): CaseClass2[A1, A2, Z] = ??? } ``` -------------------------------- ### Define Domain Models Source: https://github.com/zio/zio-schema/blob/main/docs/automatic-schema-derivation.md Define your case classes and sealed traits that will be used for schema derivation. ```scala final case class Person(name: String, age: Int) sealed trait 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 } final case class Customer(person: Person, paymentMethod: PaymentMethod) ``` -------------------------------- ### Add Protobuf Dependency to build.sbt Source: https://github.com/zio/zio-schema/blob/main/docs/manual-schema-construction.md Include this line in your build.sbt file to add the ZIO Schema Protobuf module. ```scala libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % @VERSION@ ``` -------------------------------- ### Schema Trait with makeAccessors Method Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/optics-derivation.md Illustrates the Schema trait's makeAccessors method, which is used to derive optics from a ZIO Schema. ```scala trait Schema[A] { def makeAccessors(b: AccessorBuilder): Accessors[b.Lens, b.Prism, b.Traversal] } ``` -------------------------------- ### ZIO Schema Tuple Combination (zip) Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md Demonstrates combining two schemas into a schema for a tuple using the `Schema#zip` operator. This is implemented via the `Schema.Tuple2` type class. ```scala object Schema { def zip[B](that: Schema[B]): Schema[(A, B)] = Schema.Tuple2(self, that) } ``` ```scala object Schema { final case class Tuple2[A, B]( left: Schema[A], right: Schema[B], annotations: Chunk[Any] = Chunk.em pty ) extends Schema[(A, B)] } ``` -------------------------------- ### ZIO Schema enumeration Constructor Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md Provides a simplified constructor `Schema.enumeration` for creating enumeration schemas, especially useful for enumerations with a large number of cases. ```scala object Schema { def enumeration[A, C <: CaseSet.Aux[A]](id: TypeId, caseSet: C): Schema[A] = ??? } ``` -------------------------------- ### ZIO Schema Tuple Constructors Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md Provides implicit constructors for creating schemas for tuples of varying arity (2 to 22). These leverage the `zip` operator for composition. ```scala object Schema { implicit def tuple2[A, B](implicit c1: Schema[A], c2: Schema[B]): Schema[(A, B)] = c1.zip(c2) implicit def tuple3[A, B, C](implicit c1: Schema[A], c2: Schema[B], c3: Schema[C]): Schema[(A, B, C)] = c1.zip(c2).zip(c3).transform({ case ((a, b), c) => (a, b, c) }, { case (a, b, c) => ((a, b), c) }) // tuple3, tuple4, ..., tuple22 } ``` -------------------------------- ### Add ZIO Schema Dependencies to build.sbt Source: https://github.com/zio/zio-schema/blob/main/docs/index.md Include these lines in your build.sbt file to add ZIO Schema and its related modules. Ensure to replace '@VERSION@' with the appropriate version number. ```scala libraryDependencies += "dev.zio" %% "zio-schema" % "@VERSION@" libraryDependencies += "dev.zio" %% "zio-schema-avro" % "@VERSION@" libraryDependencies += "dev.zio" %% "zio-schema-bson" % "@VERSION@" libraryDependencies += "dev.zio" %% "zio-schema-json" % "@VERSION@" libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "@VERSION@" libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % "@VERSION@" libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "@VERSION@" libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % "@VERSION@" // Required for the automatic generic derivation of schemas libraryDependencies += "dev.zio" %% "zio-schema-derivation" % "@VERSION@" libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided" ``` -------------------------------- ### Add ZIO Schema Derivation Dependency Source: https://github.com/zio/zio-schema/blob/main/docs/automatic-schema-derivation.md Add this line to your build.sbt file to enable automatic schema derivation. ```scala libraryDependencies += "dev.zio" %% "zio-schema-derivation" % @VERSION@ ``` -------------------------------- ### XML Writer Configuration Options Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/xml.md Explore different `WriterConfig` options to customize XML output, such as indentation, declaration inclusion, and character encoding. ```scala object WriterConfig { val default: WriterConfig // No indentation, no declaration val pretty: WriterConfig // 2-space indentation val withDeclaration: WriterConfig // Includes XML declaration } ``` -------------------------------- ### Add ZIO Schema Dependencies to build.sbt Source: https://github.com/zio/zio-schema/blob/main/README.md Include these lines in your build.sbt file to add ZIO Schema and its related modules. Ensure the version matches your project's requirements. The scala-reflect library is required for automatic generic derivation. ```scala libraryDependencies += "dev.zio" %% "zio-schema" % "1.8.5" libraryDependencies += "dev.zio" %% "zio-schema-avro" % "1.8.5" libraryDependencies += "dev.zio" %% "zio-schema-bson" % "1.8.5" libraryDependencies += "dev.zio" %% "zio-schema-json" % "1.8.5" libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "1.8.5" libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % "1.8.5" libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "1.8.5" libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % "1.8.5" // Required for the automatic generic derivation of schemas libraryDependencies += "dev.zio" %% "zio-schema-derivation" % "1.8.5" libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided" ``` -------------------------------- ### Add MessagePack Dependency Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/messsage-pack.md Include the `zio-schema-msg-pack` dependency in your `build.sbt` file to enable MessagePack codec generation. ```scala libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "@VERSION@" ``` -------------------------------- ### Accessing Case Class Fields in Scala Source: https://github.com/zio/zio-schema/blob/main/docs/motivation.md Shows the standard Scala syntax for accessing fields of a case class instance. ```scala val person = Person("Michelle", 32) val name = person.name val age = person.age ``` -------------------------------- ### Reifying Side Effects with ZIO Task Source: https://github.com/zio/zio-schema/blob/main/docs/motivation.md Demonstrates how to reify imperative `println` statements into ZIO `Task` values for functional composition and error handling. ```scala println("Hello") println("World") ``` ```scala val effect1 = Task(println("Hello")) val effect2 = Task(println("World")) ``` ```scala (Task(println("Hello")) zipPar Task(println("World"))).retryN(100) ``` -------------------------------- ### Serialize and Deserialize with AvroCodec Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/avro.md Utilize AvroCodec.schemaBasedBinaryCodec to create a BinaryCodec for a given Schema[A]. This allows encoding data into Avro's binary format and decoding it back. Ensure the type has an implicit Schema[A] and BinaryCodec[A] instance. ```scala import zio._ import zio.schema.Schema import zio.schema.DeriveSchema import zio.schema.codec.{AvroCodec, BinaryCodec} case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen implicit val binaryCodec: BinaryCodec[Person] = AvroCodec.schemaBasedBinaryCodec[Person] } object Main extends ZIOAppDefault { def run = for { _ <- ZIO.debug("AvroCodec Example:") encodedPerson = Person.binaryCodec.encode(Person("John", 42)) _ <- ZIO.debug(s"encoded person object: ${toHex(encodedPerson)}") decodedPerson <- ZIO.fromEither( Person.binaryCodec.decode(encodedPerson) ) _ <- ZIO.debug(s"decoded person object: $decodedPerson") } yield () def toHex(bytes: Chunk[Byte]): String = bytes.map("%02x".format(_)).mkString(" ") } ``` -------------------------------- ### Creating Primitive Schemas Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md Schemas for primitive types can be created using Schema.primitive[A] or Schema.apply[A], leveraging implicit conversions from StandardType[A]. ```scala val intSchema1: Schema[Int] = Schema[Int] val intSchema2: Schema[Int] = Schema.primitive[Int] ``` -------------------------------- ### Add zio-schema-zio-test Dependency Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/zio-test-gen-derivation.md Add this dependency to your build.sbt file to enable derivation of ZIO Test generators from ZIO Schemas. ```scala libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % @VERSION@ ``` -------------------------------- ### Output of Automatic Migration Derivation Source: https://github.com/zio/zio-schema/blob/main/docs/operations/schema-migration.md The output displays the automatically generated migration steps as a `Chunk[Migration]`, detailing operations like incrementing dimensions, changing types, adding nodes, and deleting nodes. ```scala Right( Chunk(IncrementDimensions(Chunk(language,item),1), ChangeType(Chunk(height),double), AddNode(Chunk(role),string), DeleteNode(Chunk(age))) ) ``` -------------------------------- ### Add Thrift Dependency Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/thrift.md Add the zio-schema-thrift dependency to your build.sbt file to enable Thrift codec derivation. ```scala libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "@VERSION@" ``` -------------------------------- ### Derive BSON Codec for a Case Class Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/bson.md Define a case class, derive its ZIO Schema, and then use `BsonSchemaCodec.bsonCodec` to create a BSON codec. This allows encoding and decoding instances of the case class to and from BSON values. ```scala import org.bson.BsonValue import zio._ import zio.bson._ import zio.schema.codec._ import zio.schema.{DeriveSchema, Schema} case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen implicit val bsonCodec: BsonCodec[Person] = BsonSchemaCodec.bsonCodec(Person.schema) } object Main extends ZIOAppDefault { def run = for { _ <- ZIO.debug("Bson Example:") person: Person = Person("John", 42) encoded: BsonValue = person.toBsonValue _ <- ZIO.debug(s"person object encoded to BsonValue: $encoded") decoded <- ZIO.fromEither(encoded.as[Person]) _ <- ZIO.debug(s"BsonValue of person object decoded to Person: $decoded") } yield () } ``` -------------------------------- ### Built-in List, Chunk, and Vector Schemas Source: https://github.com/zio/zio-schema/blob/main/docs/basic-building-blocks.md Convenience constructors for creating schemas for List, Chunk, and Vector types. ```scala import zio._ import zio.schema._ import zio.schema.Schema._ case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen[Person] implicit val listSchema: Schema[List[Person]] = Schema.list[Person] implicit val chunkSchema: Schema[Chunk[Person]] = Schema.chunk[Person] implicit val vectorSchema: Schema[Vector[Person]] = Schema.vector[Person] } ``` -------------------------------- ### Add XML Codec Dependency Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/xml.md Add this dependency to your `build.sbt` file to include the XML codec functionality. ```scala libraryDependencies += "dev.zio" %% "zio-schema-xml" % @VERSION@ ``` -------------------------------- ### Derive Protobuf Codec for a Case Class Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/protobuf.md Derives a Protobuf BinaryCodec for a given ZIO Schema. Ensure the schema is implicitly available. This codec can be used for encoding and decoding data to Protobuf's binary format. ```scala import zio._ import zio.schema.codec._ import zio.schema.{DeriveSchema, Schema} case class Person(name: String, age: Int) object Person { implicit val schema : Schema[Person] = DeriveSchema.gen implicit val protobufCodec: BinaryCodec[Person] = ProtobufCodec.protobufCodec(schema) } object Main extends ZIOAppDefault { def run = for { _ <- ZIO.debug("Protobuf Codec Example:") person: Person = Person("John", 42) encoded: Chunk[Byte] = Person.protobufCodec.encode(person) _ <- ZIO.debug( s"person object encoded to Protobuf's binary format: ${toHex(encoded)}" ) decoded <- ZIO.fromEither(Person.protobufCodec.decode(encoded)) _ <- ZIO.debug(s"Protobuf object decoded to Person class: $decoded") } yield () def toHex(bytes: Chunk[Byte]): String = bytes.map("%02x".format(_)).mkString(" ") } ``` -------------------------------- ### Derive Basic XML Codec Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/xml.md Derive an XML codec from a ZIO Schema for a case class. This allows encoding and decoding data to and from XML format. ```scala import zio._ import zio.schema.codec.BinaryCodec import zio.schema.codec.xml.XmlCodec import zio.schema.{DeriveSchema, Schema} case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen implicit val xmlCodec: BinaryCodec[Person] = XmlCodec.schemaBasedBinaryCodec(schema) } object Main extends ZIOAppDefault { def run = for { _ <- ZIO.debug("XML Codec Example:") person: Person = Person("John", 42) encoded: Chunk[Byte] = Person.xmlCodec.encode(person) _ <- ZIO.debug(s"person object encoded to XML: ${new String(encoded.toArray)}") decoded <- ZIO.fromEither(Person.xmlCodec.decode(encoded)) _ <- ZIO.debug(s"XML decoded to Person class: $decoded") } yield () } ``` -------------------------------- ### WriterConfig Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/xml.md Configuration options for customizing XML writing behavior. ```APIDOC ## Configuration ### WriterConfig The `WriterConfig` allows customization of XML output: - `indentStep`: Number of spaces for indentation (0 for compact output) - `includeDeclaration`: Whether to include XML declaration (``) - `encoding`: Character encoding (default: "UTF-8") ```scala object WriterConfig { val default: WriterConfig // No indentation, no declaration val pretty: WriterConfig // 2-space indentation val withDeclaration: WriterConfig // Includes XML declaration } ``` ``` -------------------------------- ### XML Annotations Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/xml.md Annotations to customize XML output, such as marking fields as attributes or adding namespaces. ```APIDOC ## XML Annotations ### @xmlAttribute The `@xmlAttribute` annotation marks a field to be encoded as an XML attribute instead of a child element. ```scala mdoc:compile-only import zio.schema.codec.xml.xmlAttribute import zio.schema.{DeriveSchema, Schema} case class Person(@xmlAttribute id: Int, name: String) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen } // Produces: Alice ``` ### @xmlNamespace The `@xmlNamespace` annotation adds namespace information to a type. ```scala mdoc:compile-only import zio.schema.codec.xml.xmlNamespace import zio.schema.{DeriveSchema, Schema} @xmlNamespace("http://example.com/ns", Some("ex")) case class Item(name: String) object Item { implicit val schema: Schema[Item] = DeriveSchema.gen } // Produces: Alice ``` ``` -------------------------------- ### Encode Person to Protobuf Source: https://github.com/zio/zio-schema/blob/main/README.md Defines a Person case class, its schema, and a Protobuf codec. It then encodes a Person instance to Protobuf format and prints the hexadecimal representation. ```scala import zio._ import zio.stream._ import zio.schema.codec.{BinaryCodec, ProtobufCodec} import zio.schema.{DeriveSchema, Schema} import java.io.IOException final case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen val protobufCodec: BinaryCodec[Person] = ProtobufCodec.protobufCodec } object Main extends ZIOAppDefault { def run: ZIO[Any, IOException, Unit] = ZStream .succeed(Person("John", 43)) .via(Person.protobufCodec.streamEncoder) .runCollect .flatMap(x => Console.printLine(s"Encoded data with protobuf codec: ${toHex(x)}") ) def toHex(chunk: Chunk[Byte]): String = chunk.map("%02X".format(_)).mkString } ``` -------------------------------- ### Update Case Class Fields with Lenses Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/optics-derivation.md Demonstrates using derived lenses to update fields within a case class instance. Requires the `User` schema and lenses to be defined. ```scala object MainApp extends ZIOAppDefault { def run = for { _ <- ZIO.debug("Auto-derivation of Optics") user = User("John", 42) updatedUser1 = User.nameLens.set("Jane")(user) _ <- ZIO.debug(s"Name of user updated: $updatedUser1") updatedUser2 = User.ageLens.set(32)(user) _ <- ZIO.debug(s"Age of user updated: $updatedUser2") nameAndAgeLens = User.nameLens.zip(User.ageLens) updatedUser3 = nameAndAgeLens.set(("Jane", 32))(user) _ <- ZIO.debug(s"Name and age of the user updated: $updatedUser3") } yield () } ``` -------------------------------- ### Create Mapping Schema with Transformation Source: https://github.com/zio/zio-schema/blob/main/docs/examples/mapping-dto-to-domain-object.md Creates a ZIO Schema that transforms a PersonDTO into a Person domain object. It handles combining first and last names and parsing the birthdate. ```scala val personDTOMapperSchema: Schema[Person] = PersonDTO.schema.transform( f = dto => { val (year, month, day) = dto.birthday Person( dto.firstName + " " + dto.lastName, birthdate = LocalDate.of(year, month, day) ) }, g = (person: Person) => { val fullNameArray = person.name.split(" ") PersonDTO( fullNameArray.head, fullNameArray.last, ( person.birthdate.getYear, person.birthdate.getMonthValue, person.birthdate.getDayOfMonth ) ) } ) ``` -------------------------------- ### Derive Ordering for Case Class Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/ordering-derivation.md Use `DeriveSchema.gen` to implicitly derive a schema for a case class, then access its `ordering` method to sort collections. ```scala import zio.schema._ case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen[Person] } val sortedList: Seq[Person] = List( Person("John", 42), Person("Jane", 34) ).sorted(Person.schema.ordering) ``` -------------------------------- ### Define Schema for List of Ints Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/optics-derivation.md Manually defines a schema for `List[Int]` to be used with ZIO Schema optics. This is necessary when the schema is not automatically derivable. ```scala import zio.schema.Schema._ import zio.schema._ object IntList { implicit val listschema: Schema.Sequence[List[Int], Int, String] = Sequence[List[Int], Int, String]( elementSchema = Schema[Int], fromChunk = _.toList, toChunk = i => Chunk.fromIterable(i), annotations = Chunk.empty, identity = "List" ) val traversal: ZTraversal[List[Int], List[Int], Int, Int] = listschema.makeAccessors(ZioOpticsBuilder) } ``` -------------------------------- ### Simplified BinaryCodec Interface Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/index.md A simplified view of the `BinaryCodec` trait, focusing on direct encoding and decoding of values and streams. ```scala import zio.Chunk import zio.stream.ZPipeline trait BinaryCodec[A] { def encode(value: A): Chunk[Byte] def decode(whole: Chunk[Byte]): Either[DecodeError, A] def streamEncoder: ZPipeline[Any, Nothing, A, Byte] def streamDecoder: ZPipeline[Any, DecodeError, Byte, A] } ``` -------------------------------- ### Manual Lens Creation for User Data Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/optics-derivation.md Define lenses manually for accessing and modifying the 'name' and 'age' fields of a User case class using ZIO Optics. ```scala import zio.optics._ case class User(name: String, age: Int) val nameLens = Lens[User, String]( user => Right(user.name), name => user => Right(user.copy(name = name)) ) val ageLens = Lens[User, Int]( user => Right(user.age), age => user => Right(user.copy(age = age)) ) val ageAndNameLens = nameLens.zip(ageLens) ``` -------------------------------- ### Schema Migration Methods Source: https://github.com/zio/zio-schema/blob/main/docs/operations/schema-migration.md The `migrate` method attempts to transform values from an old schema to a new one, returning a function for successful transformations or an error message. The `coerce` method attempts to create a new schema that is compatible with the old one. ```scala sealed trait Schema[A] { def migrate[B](newSchema: Schema[B]): Either[String, A => scala.util.Either[String, B]] def coerce[B](newSchema: Schema[B]): Either[String, Schema[B]] } ``` -------------------------------- ### Use Streaming XML Codecs Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/xml.md Process large XML datasets efficiently using streaming encoders and decoders provided by the XML codec. ```scala import zio._ import zio.schema.codec.BinaryCodec import zio.schema.codec.xml.XmlCodec import zio.schema.{DeriveSchema, Schema} import zio.stream.ZStream case class Person(name: String, age: Int) object Person { implicit val schema: Schema[Person] = DeriveSchema.gen implicit val xmlCodec: BinaryCodec[Person] = XmlCodec.schemaBasedBinaryCodec(schema) } object Main extends ZIOAppDefault { def run = for { _ <- ZIO.debug("XML Stream Codecs Example:") person = Person("John", 42) personToXml = Person.xmlCodec.streamEncoder xmlToPerson = Person.xmlCodec.streamDecoder newPerson <- ZStream(person) .via(personToXml) .via(xmlToPerson) .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 () } ``` -------------------------------- ### XML Output Structure Source: https://github.com/zio/zio-schema/blob/main/docs/derivations/codecs/xml.md This is the resulting XML structure when encoding the `Person` case class. ```xml John42 ```