-
Notifications
You must be signed in to change notification settings - Fork 149
Add schema-iron module for Iron refinement type support #1097
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # ZIO Blocks Schema Iron | ||
|
|
||
| Integration between ZIO Blocks Schema and [Iron](https://github.com/Iltotore/iron) for type-safe refinement types. | ||
|
|
||
| ## Installation | ||
|
|
||
| ```scala | ||
| libraryDependencies += "dev.zio" %% "zio-blocks-schema-iron" % "0.0.1" | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| ```scala | ||
| import zio.blocks.schema.* | ||
| import zio.blocks.schema.iron.given | ||
| import io.github.iltotore.iron.* | ||
| import io.github.iltotore.iron.constraint.numeric.* | ||
|
|
||
| case class Person(name: String, age: Int :| Positive) | ||
|
|
||
| object Person: | ||
| given Schema[Person] = Schema.derived | ||
|
|
||
| // Now you can use Person with any format | ||
| val jsonCodec = Schema[Person].derive(JsonFormat) | ||
|
|
||
| // Decoding with validation | ||
| val validJson = """{"name":"Alice","age":25}""" | ||
| val invalidJson = """{"name":"Bob","age":-5}""" | ||
|
|
||
| jsonCodec.decode(validJson.getBytes) // Right(Person(Alice,25)) | ||
| jsonCodec.decode(invalidJson.getBytes) // Left(SchemaError: Should be strictly positive at: .age) | ||
| ``` | ||
|
|
||
| The integration automatically derives `Schema[A :| C]` from `Schema[A]` with runtime validation using Iron's constraints. | ||
|
|
||
| ## Known Limitations | ||
|
|
||
| Due to how ZIO Blocks handles opaque types in derived schemas, encoding refined types may not work correctly in all cases. Decoding and validation work as expected. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package zio.blocks.schema | ||
|
|
||
| import io.github.iltotore.iron.* | ||
|
|
||
| package object iron { | ||
|
|
||
| inline given ironSchema[A, C](using baseSchema: Schema[A], constraint: Constraint[A, C]): Schema[A :| C] = | ||
| baseSchema.transformOrFail( | ||
| a => a.refineEither[C].left.map(SchemaError.validationFailed), | ||
| refined => refined.asInstanceOf[A] | ||
| ) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package zio.blocks.schema.iron | ||
|
|
||
| import zio.blocks.schema.* | ||
| import zio.test.* | ||
| import io.github.iltotore.iron.* | ||
| import io.github.iltotore.iron.constraint.numeric.* | ||
|
|
||
| class IronSchemaSpec extends SchemaBaseSpec { | ||
|
|
||
| case class Person(name: String, age: Int :| Positive) | ||
|
|
||
| object Person { | ||
| given Schema[Person] = Schema.derived | ||
| } | ||
|
|
||
| def spec = suite("IronSchemaSpec")( | ||
| test("derive schema for refined types") { | ||
| val schema = summon[Schema[Person]] | ||
| assertTrue(schema != null) | ||
| }, | ||
|
|
||
| test("refined type schema has correct structure") { | ||
| val ageSchema = summon[Schema[Int :| Positive]] | ||
| assertTrue(ageSchema != null) | ||
| } | ||
| ) | ||
|
Comment on lines
+16
to
+26
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This public API declaration is missing required Scaladoc documentation. According to project guidelines, all new public APIs must have comprehensive Scaladoc including:
@tparamtags for type parametersAandCexplaining their purpose@returntag (if applicable for given instances)The Scaladoc should explain that this automatically derives a Schema for Iron-refined types that validates the constraint during decoding and unwraps during encoding.
Example structure: