Skip to content

Support for zio-prelude Newtype/Subtype schema derivation #923

@elmnic

Description

@elmnic

Deriving a Schema for the following example produces a JSON that, obviously, produces a field for all aspects of the case class, e.g.

case class Age(value: Int):
  given Schema[Age] = Schema.primitive[Int].transform(Age(_), _.value)  

case class Name(value: String):
  given Schema[Name] = Schema.primitive[Int].transform(Name(_), _.value)  

produces

{
  "age": {
    "value": 123
  },
  "name": {
    "value": "John Doe"
  }
}

Combine this with "value classes", like for example zio-prelude's Newtype/Subtype, deriving a schema for those should instead produce something like this:

{
  "age": 123,
  "name": "John Doe"
}

This can be achieved using case classes and Schema.primitive to manually wrap/unwrap the underlying value like so:

import zio.prelude.Subtype

case class Age(value: Int):
  given Schema[Age] = Schema.primitive[Int].transform(Age(_), _.value)  

case class Name(value: String):
  given Schema[Name] = Schema.primitive[String].transform(Name(_), _.value)  

I would instead want the DeriveSchema.gen to support zio-prelude Newtype/Subtype to capture this concept directly, e.g.:

import zio.prelude.Subtype

object Age extends Subtype[Int]:
  given Schema[Age] = Schema.primitive[Int].transform(Age(_), Age.unwrap(_)) // Current necessary solution
  given Schema[Age] = DeriveSchema.gen // vs macro derivation

object Name extends Subtype[String]:
  given Schema[Name] = Schema.primitive[String].transform(Name(_), Name.unwrap(_))  
  given Schema[Name] = DeriveSchema.gen

I did try my hand at this for a little while but I am completely new when it comes to macros and was unable to find a way to find the .unwrap method on the object in question. Hoping some macro-wizard knows if it's possible and what to do.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions