-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
borerSerialization
example showing how to use the iron-borer
…
…module.
- Loading branch information
Showing
4 changed files
with
93 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Small Demo of borer integration | ||
This example shows how to integrate _iron_ with [borer](https://sirthias.github.io/borer/). | ||
|
||
After having added `"io.github.iltotore" %% "iron-borer" % "<version>"` as a dependency you can say this: | ||
|
||
```scala | ||
import io.github.iltotore.iron.borer.given | ||
``` | ||
|
||
With this import in place all refined types `T` automatically have _borer_ `Encoder[T]` and `Decoder[T]` | ||
instances available, as long as the respective Encoders and Decoders for the (unrefined) underlying types are already | ||
`given`. | ||
|
||
If a refinement error is triggered during decoding because the decoded value doesn't match the refinement condition(s) | ||
decoding will fail with a `Borer.Error.ValidationFailure`. | ||
|
||
|
||
## Run the example | ||
|
||
Use the following command (in the Iron project root directory) to run the example: | ||
|
||
```sh | ||
mill examples.borerSerialization.run | ||
``` |
25 changes: 25 additions & 0 deletions
25
examples/borerSerialization/src/io/github/iltotore/iron/formBorer/Account.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package io.github.iltotore.iron.formBorer | ||
|
||
import io.bullet.borer.Codec | ||
import io.bullet.borer.derivation.MapBasedCodecs | ||
import io.github.iltotore.iron.constraint.all.* | ||
import io.github.iltotore.iron.{*, given} | ||
import io.github.iltotore.iron.borer.given // this enables borer <-> iron integration | ||
|
||
type Username = (Alphanumeric & MinLength[3] & MaxLength[10]) DescribedAs | ||
"Username should be alphanumeric and have a length between 3 and 10" | ||
|
||
type Password = (Match["[A-Za-z].*[0-9]|[0-9].*[A-Za-z]"] & MinLength[6] & MaxLength[20]) DescribedAs | ||
"Password must contain at least a letter, a digit and have a length between 6 and 20" | ||
|
||
type Age = Greater[0] DescribedAs | ||
"Age should be strictly positive" | ||
|
||
case class Account( | ||
name: String :| Username, | ||
password: String :| Password, | ||
age: Int :| Age | ||
) | ||
|
||
object Account: | ||
given Codec[Account] = MapBasedCodecs.deriveCodec |
31 changes: 31 additions & 0 deletions
31
examples/borerSerialization/src/io/github/iltotore/iron/formBorer/main.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package io.github.iltotore.iron.formBorer | ||
|
||
import io.bullet.borer.{Borer, Json} | ||
import io.github.iltotore.iron.{*, given} | ||
|
||
@main def main: Unit = | ||
|
||
val account = Account( | ||
name = "matt", | ||
password = "bar123", | ||
age = 42 | ||
) | ||
|
||
val okValidEncoding = """{"name":"matt","password":"bar123","age":42}""" | ||
val invalidEncoding = """{"name":"matt","password":"bar","age":42}""" | ||
|
||
val encoding = Json.encode(account).toUtf8String | ||
println(encoding) | ||
assert(encoding == okValidEncoding) | ||
|
||
val decoding = Json.decode(okValidEncoding.getBytes).to[Account].valueEither | ||
println(decoding) | ||
assert(decoding == Right(account)) | ||
|
||
val decoding2 = Json.decode(invalidEncoding.getBytes).to[Account].valueEither | ||
decoding2 match { | ||
case Left(e: Borer.Error.ValidationFailure[_]) => | ||
// "Password must contain at least a letter, a digit and have a length between 6 and 20 (input position 26)" | ||
println(e.getMessage) | ||
case _ => throw new IllegalStateException | ||
} |