Skip to main content

Catalog

Struct Catalog 

Source
pub struct Catalog { /* private fields */ }
Expand description

Pre-computed, immutable registry of all JSON-UI components and their schemas.

Constructed once via Catalog::build and accessed globally through global_catalog. All fields are pub(crate) — external callers use the accessor methods added in Plans 02–05.

Implementations§

Source§

impl Catalog

Source

pub fn build() -> Result<Self, CatalogError>

Build the catalog from the static built-in specs and the current plugin registry.

Called once by global_catalog. Returns Err if a plugin’s props_schema() is not a valid JSON Schema or if the assembled full schema fails to compile.

§Errors
Source

pub fn json_schema(&self) -> &Value

Return the fully-assembled spec JSON Schema document.

Shape: root with $schema, root, elements, plus $defs containing Element (with a discriminated oneOf over all component Props) and Action / Visibility references. Zero-copy — the returned &Value lives as long as the Catalog.

Source

pub fn validate(&self, spec: &Spec) -> Result<(), Vec<CatalogError>>

Validate a crate::spec::Spec against the catalog.

Three-stage pipeline (CONTEXT D-10):

  1. Type-name whitelist — every element.type_name must resolve to a built-in or plugin component. Unknown names return CatalogError::UnknownType and short-circuit the rest of the pipeline. This avoids noisy oneOf errors from Stage 3 when a component name is simply wrong (RESEARCH §5).

  2. Per-element Props validation — for each element, look up per_component_schemas[type_name] and validate element.props against it using on-demand jsonschema::validator_for. Errors accumulate as CatalogError::PropsInvalid. Plugin schemas are accepted per CONTEXT D-20.

  3. Envelope check — serialize the full Spec and run it through the cached self.validator (compiled once in Catalog::build, SCHEMA-03). Errors become CatalogError::SpecInvalid.

Errors accumulate across Stages 2 and 3 so a caller sees every issue at once.

Source

pub fn component_schema(&self, type_name: &str) -> Option<&Value>

Return the per-component Props JSON Schema for type_name, or None if the name is not registered as a built-in or plugin component.

The returned schema is Props-only (NOT wrapped in the Element envelope used by Self::json_schema). This is the schema shape Phase 120 AI structured-output generation consumes, and what ferro json-ui:schema --component <name> prints.

The reference has the same lifetime as &self — zero-copy (CONTEXT D-15).

Lookup is unified across built-ins and plugins via the per_component_schemas map populated in Self::build (CONTEXT D-20 — plugin schemas are stored identically after meta-validation).

Source

pub fn components_sorted(&self) -> impl Iterator<Item = &ComponentSpec>

Iterate built-in ComponentSpec entries sorted by name (ascending).

Deterministic ordering is required by CONTEXT D-18 so that Self::json_schema, prompt() (Plan 06), and ferro-mcp json_ui_catalog output (Plan 06 migration) produce byte-stable results for snapshot tests.

Source

pub fn plugin_components_sorted(&self) -> impl Iterator<Item = &ComponentSpec>

Iterate plugin ComponentSpec entries sorted by name (ascending).

Separate from built-ins so consumers can format them in a distinct section (ferro-mcp json_ui_catalog.CatalogResponse preserves the components / plugin_components split per CONTEXT D-24).

Source

pub fn prompt(&self) -> String

Generate a concise text system prompt summarizing every component.

Format: ## Component Catalog header, a one-line note explaining the slot convention, then one ### <Name> section per component (built-ins then plugins, both sorted by name). Each section contains the description, a single Props: line with name (Type) tuples, and (when non-empty) a Slots: line listing slot field names only.

The prompt is intentionally CONCISE (≤ 10 KB, CONTEXT D-17) — the full JSON Schema is NOT embedded. Consumers wanting machine-readable schemas use Self::json_schema or Self::component_schema (Plan 07 CLI).

Deterministic (CONTEXT D-18): two builds of the same catalog yield byte-identical output; order within sections follows alphabetical order via Self::components_sorted and Self::plugin_components_sorted.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more