Expand description
fig-schema — the schema layer: what a field expects — its type, its
allowed values, and how to present it — layered over fig’s schema-free
value tree.
fig parses bytes → fig::Value and edits losslessly; it has no notion of
“what is valid here”. This crate adds that knowledge as a generic,
embedder-agnostic engine. It never learns the word “prov” or “flower”: a
consumer (prov, for frontmatter fields; flower, for a metadata editor)
defines its own constraint type — an enum covering whatever kinds of
constraint it needs (a controlled vocabulary, a reference into a
workspace, …) — and implements Validate on it. FieldRule/Schema
are generic over that type, so the path-matching and commit-time
validation plumbing is written once, here, and reused by every embedder.
What’s genuinely reusable, and lives here as concrete types rather than being left to the embedder:
PathPat/SegPat— pattern-matching a fig path, including “every item of this list” (SegPat::EachItem) and “this subtree” (SegPat::AnyDepth).FieldType— the expected type, and type-directed coercion of an edit buffer (FieldType::coerce).Term/Cardinality/validate_enum— a controlled vocabulary and the logic to check a value against one (closed-vocabulary rejection, open-vocabulary near-miss warnings). Cardinality (one vs. many) is pure data shape, useful even to a constraint this crate doesn’t otherwise model (a relation/reference field, for instance).Presentation/Icon/Tint— renderer-neutral display hints, carried on every rule but never interpreted here.Issue/IssueKind— why a value failed, as data rather than prose, so the embedder owns the wording.Issue’sDisplayrenders a reasonable English default for embedders that don’t care.
§Example
use fig::Value;
use fig_schema::{
FieldRule, FieldType, PathPat, Presentation, Schema, Seg, Term, Validate,
Validation, validate_enum,
};
// The embedder's own constraint type — the seam this crate is built around.
struct Vocabulary { values: Vec<Term>, closed: bool }
impl Validate for Vocabulary {
fn validate(&self, value: &Value) -> Validation {
validate_enum(&self.values, self.closed, value)
}
}
let schema = Schema::new(vec![FieldRule {
at: PathPat::each_item_of("audience"),
ty: Some(FieldType::Str),
constraint: Some(Vocabulary {
values: vec![Term::value("public"), Term::value("family")],
closed: true,
}),
present: Presentation::default(),
}]);
// Find the rule governing `audience[0]`, then check a candidate against it.
let path = [Seg::Key("audience".into()), Seg::Index(0)];
let rule = schema.rule_for(&path).expect("a rule governs this path");
assert!(rule.validate(&Value::Str("public".into())).is_ok());
let rejected = rule.validate(&Value::Str("familly".into()));
assert!(rejected.is_reject());
assert_eq!(
rejected.issue().unwrap().suggestion.as_deref(),
Some("family"),
);Structs§
- Field
Rule - One field rule: which node(s) it governs, the type it expects, an optional
constraint of the embedder’s own type
C, and how to present it. - Issue
- Why a value failed to validate.
- PathPat
- A path pattern. Unlike a concrete
Segpath it can reach every element of a sequence (SegPat::EachItem), every entry of a mapping (SegPat::AnyKey), or a whole subtree (SegPat::AnyDepth), so a rule can constrain each item of a list field (tags:,audience:) or everything beneath a key. - Presentation
- Presentation hints for one field rule.
- Schema
- A set of field rules. Matched against a row’s fig path to find what governs it.
- Term
- One term of a controlled vocabulary.
Enums§
- Cardinality
- Whether a reference or list-shaped field holds one entry or many. Pure data
shape — reused by an embedder’s own reference/relation constraint (prov’s
spanning/cardinalityconcepts, for instance) without this crate needing to know what a “relation” is. - Field
Type - The type a field expects. Drives type-directed parsing and widget choice.
- Icon
- A semantic icon hint. Frontends map to their own symbol set.
- Issue
Kind - The kind of an
Issue. - Seg
- One step of a fig path: a mapping key or a sequence index. Owned (unlike
fig::Segment<'a>, which borrows), so a path can outlive a single FFI call. - SegPat
- One step of a
PathPat. - Tint
- A semantic tint hint. Frontends map to theme-adaptive colours.
- Validation
- The result of validating a value against a field’s constraint at commit time.
Traits§
- Validate
- A field constraint that knows how to check a candidate value. An embedder
implements this on its own constraint type (an enum with a vocabulary
variant, a reference variant, whatever it needs);
crate::FieldRule::validatedispatches to it generically.
Functions§
- validate_
enum - Validate
valueagainst a controlled vocabulary — the reusable logic behind any embedder’s vocabulary-shaped constraint.