Parse and Serialize
Schema.parse(map) receives a #{} map literal and attempts to build a
validated instance. The return is always a Result<Schema, str>: Result::Ok
with the instance on success, or Result::Err with a descriptive message when
a field is missing or has the wrong type. Consume the result with
match, unwrap, unwrap_or, is_ok, or is_err.
Point.parse with a complete map returns Ok; an incomplete map returns Err.
// Feature: schema validation — `Schema.parse(map)` returns Result<Schema, str>
// Syntax: pass a map to `parse`; on success you get `Result::Ok(instance)`,
// on failure `Result::Err(message)`. Use `match`, `unwrap`, or
// `is_ok` / `is_err` to consume the result idiomatically.
// When to use: validating untrusted input — HTTP bodies, CLI args,
// JSON payloads, file deserialization.
schema Point {
x: int,
y: int,
}
// Pattern-match the Result — the most idiomatic shape.
match Point.parse(#{x: 10, y: 20}) {
Result::Ok(p) => {
print(p.x)
print(p.y)
},
Result::Err(e) => print("error: {e}"),
}
// expected:
// 10
// 20
// Missing field → Err. The exact message is implementation-defined,
// but the variant is reliable.
match Point.parse(#{x: 10}) {
Result::Ok(_) => print("?"),
Result::Err(_) => print("validation failed"),
}
// expected: validation failed
The reverse path is instance.to_map(), which serializes all fields back into
a map — ready to send over the network, write to a file, or encode as JSON.
Together with parse, it forms the complete validation-and-serialization cycle:
Rect.to_map() accesses fields via the map; Point.to_map() + json.encode closes the loop.
// Feature: schema serialization — `instance.to_map()` round-trips back to a map
// Syntax: any parsed schema instance has a `.to_map()` method.
// When to use: re-encoding to JSON, sending over the network,
// merging with other maps, structured logging.
use std::json
schema Rect {
width: int,
height: int,
}
match Rect.parse(#{width: 5, height: 3}) {
Result::Ok(r) => {
let m = r.to_map()
print(m["width"])
print(m["height"])
},
Result::Err(e) => print("error: {e}"),
}
// expected:
// 5
// 3
// Round-trip: parse → to_map → encode as JSON.
schema Point {
x: int,
y: int,
}
match Point.parse(#{x: 1, y: 2}) {
Result::Ok(p) => print(json.encode(p.to_map())),
Result::Err(e) => print("error: {e}"),
}
// expected: {"x":1,"y":2} (key order may vary)
Challenge
Create a schema Email { address: str } and try parsing an empty map #{}.
Print the error message received. Then parse a valid map, convert it with
to_map(), and verify that m["address"] returns the original value.