60 lines
1.6 KiB
Plaintext
60 lines
1.6 KiB
Plaintext
///|
|
|
/// Chain two schemas: validate the input against `self`, then validate the
|
|
/// result against `output`. Errors from each stage are reported independently.
|
|
///
|
|
/// Unlike `.transform()`, `.pipe()` creates a clear two-stage pipeline where
|
|
/// the output schema can have its own rules — errors are attributed to the
|
|
/// correct stage.
|
|
///
|
|
/// # Example
|
|
/// ```mbt nocheck
|
|
/// let s = string()
|
|
/// .transform(fn(s) { Ok(Json::string(s.length().to_string())) })
|
|
/// .pipe(number().min(5))
|
|
/// // string check → transform → number check(.min(5))
|
|
/// ```
|
|
pub fn Schema::pipe(self : Schema, output : Schema) -> Schema {
|
|
{
|
|
schema_type: PipeType(
|
|
self,
|
|
TransformClosure::{ f: fn(v) { Ok(v) } },
|
|
output,
|
|
),
|
|
rules: [],
|
|
description: self.description,
|
|
required_error: self.required_error,
|
|
invalid_type_error: self.invalid_type_error,
|
|
name: self.name,
|
|
brand: self.brand,
|
|
}
|
|
}
|
|
|
|
///|
|
|
pub fn Schema::parse_pipe(
|
|
_self : Schema,
|
|
input_schema : Schema,
|
|
bridge : TransformClosure,
|
|
output_schema : Schema,
|
|
json : Json,
|
|
path_stack : Array[String],
|
|
) -> RawSchemaResult {
|
|
match parse_inner(input_schema, json, path_stack) {
|
|
Err(e) => Err(e)
|
|
Ok(parsed) =>
|
|
match (bridge.f)(parsed) {
|
|
Err(msg) => {
|
|
let path = format_path(path_stack)
|
|
Err([
|
|
RawIssue::{
|
|
code: IssueCode::Custom,
|
|
path,
|
|
message: msg,
|
|
input: json,
|
|
},
|
|
])
|
|
}
|
|
Ok(bridged) => parse_inner(output_schema, bridged, path_stack)
|
|
}
|
|
}
|
|
}
|