[][src]Struct jsl::registry::Registry

pub struct Registry { /* fields omitted */ }

Holds a collection of schemas, ensuring their mutual references are valid.

Methods

impl Registry[src]

pub fn new() -> Self[src]

Construct a new, empty registry.

pub fn register(&mut self, schema: Schema) -> Result<&[Url], Error>[src]

Add a schema to the registry, and return the IDs of the schemas still missing.

Returns an error if the given schema is non-root, if there already exists a schema with the given ID in the registry, or if the given schema refers to a definition which is known not to exist.

Because this method returns IDs that are still missing, you can call this function over multiple passes until all schemas are fetched. This crate does not presume how or whether you want to fetch schemas over the network.

use serde_json::json;
use jsl::{Registry, Schema, SerdeSchema, Validator, ValidationError};
use failure::{Error, format_err};
use url::Url;

fn main() -> Result<(), Error> {
    let initial_schema: SerdeSchema = serde_json::from_value(json!({
        "properties": {
            "users": {
                "elements": {
                    "ref": "http://schemas.example.com/user.json"
                },
            },
            "next_page_token": { "type": "string" },
        },
    }))?;

    let initial_schema = Schema::from_serde(initial_schema)?;

    let mut registry = Registry::new();
    let mut missing = registry.register(initial_schema)?;

    // When this loop completes, all cross-references will be satisfied.
    while !missing.is_empty() {
        // Your fetch function could decide that an ID is untrusted, and
        // refuse to fetch it.
        let schema = fetch(&missing[0])?;
        missing = registry.register(schema)?;
    }

    Ok(())
}

// This is just a demo implementation. It's up to you how this would
// really work, but it's strongly recommended that you never simply
// execute arbitrary schemas from the network.
fn fetch(url: &Url) -> Result<Schema, Error> {
    if url.as_str() != "http://schemas.example.com/user.json" {
        return Err(format_err!("unexpected url"));
    }

    return Ok(Schema::from_serde(serde_json::from_value(json!({
        "properties": {
            "name": { "type": "string" },
            "display_name": { "type": "string" },
            "created_at": { "type": "string" },
        }
    }))?)?);
}

pub fn get(&self, id: &Option<Url>) -> Option<&Schema>[src]

Gets the schema in this registry with the given ID.

If no such schema exists in this registry, returns None.

pub fn is_sealed(&self) -> bool[src]

Is this registry sealed?

A registry being sealed doesn't mean that it's immutable. Rather, it means that there are no missing IDs in the registry. In other words, the registry is self-sufficient and consistent. Adding schemas to a sealed registry may or may not unseal it.

This is just a convenience shorthand for missing_ids().is_empty().

pub fn missing_ids(&self) -> &[Url][src]

Get the IDs missing from this registry.

This is the same value as what register returns.

Trait Implementations

impl Default for Registry[src]

Auto Trait Implementations

impl Send for Registry

impl Sync for Registry

Blanket Implementations

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T> From for T[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.