Summary
As a package developer, in order to model JSON Schema oneOf, I would like to require that a value validates against exactly one of a set of specifications.
Details
This is a new function, distinct from the unreleased stabilize_one_of() that is being renamed to stabilize_any_of() (see the rename Task). Where any_of returns the first spec that succeeds, one_of must evaluate all specs and require that exactly one succeeds. It is therefore order-independent, unlike any_of.
The coercion wrinkle
Because stbl coerces liberally (Postel's law), overlapping specs will frequently both succeed — e.g. "1" is both int-ish and dbl-ish, so stabilize_one_of("1", stabilize_int, stabilize_dbl) would error as ambiguous. This mirrors JSON Schema's own oneOf behavior, where oneOf: [integer, number] fails to validate 1 because it matches both. stabilize_one_of() is therefore intended for mutually exclusive branches; this should be stated prominently in its documentation.
Proposed signature
stabilize_one_of(
x,
...,
x_arg = caller_arg(x),
call = caller_env(),
x_class = object_type(x)
)
Arguments
x, x_arg, call, x_class: As in the other composition stabilizers.
...: Stabilizer functions (stabilize_*, to_*, or specify_*() results), unnamed.
Returns x coerced by the single matching spec.
Behavior
- Evaluate every spec in
... (catching errors) and count successes.
- Exactly one success → return that spec's coerced result.
- Zero successes → error combining the individual failure messages ("matched none of the specifications").
- Two or more successes → error naming the specs that matched ("matched more than one specification: ...").
- Provide a
stabilise_one_of() synonym; consider a to_one_of() counterpart (the name is freed up by the rename).
- Use the error subclass
cant_stabilize_one_of (also freed up by the rename).
References
Summary
Details
This is a new function, distinct from the unreleased
stabilize_one_of()that is being renamed tostabilize_any_of()(see the rename Task). Whereany_ofreturns the first spec that succeeds,one_ofmust evaluate all specs and require that exactly one succeeds. It is therefore order-independent, unlikeany_of.The coercion wrinkle
Because stbl coerces liberally (Postel's law), overlapping specs will frequently both succeed — e.g.
"1"is both int-ish and dbl-ish, sostabilize_one_of("1", stabilize_int, stabilize_dbl)would error as ambiguous. This mirrors JSON Schema's ownoneOfbehavior, whereoneOf: [integer, number]fails to validate1because it matches both.stabilize_one_of()is therefore intended for mutually exclusive branches; this should be stated prominently in its documentation.Proposed signature
Arguments
x,x_arg,call,x_class: As in the other composition stabilizers....: Stabilizer functions (stabilize_*,to_*, orspecify_*()results), unnamed.Returns
xcoerced by the single matching spec.Behavior
...(catching errors) and count successes.stabilise_one_of()synonym; consider ato_one_of()counterpart (the name is freed up by the rename).cant_stabilize_one_of(also freed up by the rename).References
*_one_of()→*_any_of()rename Task;stabilize_all_of()(feat: stabilize_all_of() family #278).