v6.1.0
New S.schema helper
(schemaCtx => 'value) => S.t<'value>
It's a helper built on S.literal, S.object, and S.tuple to create schemas for runtime representation of ReScript types conveniently.
@unboxed
type answer =
| Text(string)
| MultiSelect(array<string>)
| Other({value: string, @as("description") maybeDescription: option<string>})
let textSchema = S.schema(s => Text(s.matches(S.string)))
// It'll create the following schema:
// S.string->S.variant(string => Text(string))
let multySelectSchema = S.schema(s => MultiSelect(s.matches(S.array(S.string))))
// The same as:
// S.array(S.string)->S.variant(array => MultiSelect(array))
let otherSchema = S.schema(s => Other({
value: s.matches(S.string),
maybeDescription: s.matches(S.option(S.string)),
}))
// Creates the schema under the hood:
// S.object(s => Other({
// value: s.field("value", S.string),
// maybeDescription: s.field("description", S.option(S.string)),
// }))
// Notice how the field name /|\ is taken from the type's @as attribute
let tupleExampleSchema = S.schema(s => (#id, s.matches(S.string)))
// The same as:
// S.tuple(s => (s.item(0, S.literal(#id)), s.item(1, S.string)))Also, it works fantastic with discriminated unions:
@tag("kind")
type shape =
| @as("circle") Circle({radius: float})
| @as("square") Square({x: float})
| @as("triangle") Triangle({x: float, y: float})
// With S.schema
let circleSchema = S.schema(s => Circle({
radius: s.matches(S.float),
}))
// With S.object
let circleSchema = S.object(s => {
s.tag("kind", "circle")
Circle({
radius: s.field("radius", S.float),
})
})🧠 Note that
S.schemarelies on the runtime representation of your type, whileS.object/S.tupleare more flexible and require you to describe the schema explicitly.
Full Changelog: v6.0.0...v6.1.0