Skip to main content

Config

Struct Config 

Source
pub struct Config<'a> {
    pub schemas: Arc<dyn SchemaSource + Send + Sync>,
    pub variables: Option<Variables>,
    pub functions: Arc<IndexMap<String, ConfigFunction>>,
    pub partials: Arc<IndexMap<String, Node<'a>>>,
    pub validation: ValidationOptions<'a>,
}
Expand description

Everything the validator and the transformer read.

The lifetime is the source text that partials and ValidationOptions::parents borrow. A config holding neither – the ordinary case for a host that registers schemas once and reuses them – is a Config<'static>, and Rust’s variance lets that be passed wherever a Config<'a> is wanted. That is deliberate: a schema registry that could only validate documents of its own lifetime would have to be rebuilt per page.

§Why three fields are behind an Arc

A config is cloned on a hot path and only one field differs between the original and the copy: {% partial %} scopes a partial’s body by cloning the whole config to replace variables. Everything else – the schemas, the functions, the parsed partials – is registered once and read many times, so copying it per expansion charges the caller for the site’s whole partial corpus on every partial in every page, which compounds exactly where partials earn their keep.

So those three are shared rather than copied. Reads are unchanged (Arc derefs). The two maps have copy-on-write mutators (functions_mut and partials_mut) for assembly; the schema source does not, because a trait object cannot be copied on write. A host fills a MapSchemaSource and shares it with with_schemas, so the sharing is explicit rather than clever.

Fields§

§schemas: Arc<dyn SchemaSource + Send + Sync>

Where a schema comes from.

The only mechanism: there is no map beside it and so no precedence rule to remember. Config::new starts it empty and builtins::config at Markdoc’s own.

§variables: Option<Variables>

Variables a $name reference resolves against.

None switches variable checking off; Some of an empty map switches it on with nothing defined.

§functions: Arc<IndexMap<String, ConfigFunction>>

Functions a f() call resolves against.

Shared: see the note on Config. Use functions_mut to edit one in place.

§partials: Arc<IndexMap<String, Node<'a>>>

Parsed partial documents, keyed by the name {% partial file=... %} uses.

Parsed, not raw: this crate performs no I/O, so a host reads the file and parses it. That is why the config carries a lifetime.

Shared: see the note on Config, where this field is the one that made the sharing worth doing. Use partials_mut to edit the map in place.

§validation: ValidationOptions<'a>

Switches and context for the validation pass.

Implementations§

Source§

impl<'a> Config<'a>

Source

pub fn new() -> Config<'a>

An empty config: no schemas, no variables, no functions, no partials.

Every node then reports node-undefined or tag-undefined, which is the correct answer rather than a degenerate one – upstream’s own validate merges its built-in schemas in before it gets here, and a host that skips that step has genuinely defined nothing.

Source

pub fn with_schemas( self, schemas: Arc<dyn SchemaSource + Send + Sync>, ) -> Config<'a>

Replace the schema source.

Chainable, for the registering case: fill a MapSchemaSource and hand it over in one expression. The source is shared, not copied, so a host with one registry and many configs pays for it once.

Source

pub fn functions_mut(&mut self) -> &mut IndexMap<String, ConfigFunction>

The functions, for in-place edit.

Copy-on-write: the map is copied only if another Config is sharing it, which is what makes registering once and scoping many times cheap.

Source

pub fn partials_mut(&mut self) -> &mut IndexMap<String, Node<'a>>

The parsed partials, for in-place edit. Copy-on-write, as functions_mut is.

Source

pub fn find_schema(&self, node: &Node<'_>) -> Option<&Schema>

The schema for a node: its tag’s if it has a tag, its type’s otherwise.

Upstream’s transformer.findSchema. It lives on the config rather than on Node because the node is the leaf type and the config is the stage above it; upstream’s node.findSchema(config) is the same call with the arrow pointing the other way. The work is SchemaSource::find’s; this only chooses the key.

Trait Implementations§

Source§

impl<'a> Clone for Config<'a>

Source§

fn clone(&self) -> Config<'a>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Config<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Hooks are function pointers with no useful rendering, so the derived Debug is unavailable and this one reports what is there instead: the names registered, which is what you want when a tag-undefined error disagrees with what you thought you registered.

The schema names come through the source’s provided tag_names and node_types, and print as None for a source that cannot enumerate – which is the truth, and different from an empty list.

Source§

impl Default for Config<'_>

Source§

fn default() -> Self

Config::new: an empty schema source, no variables, no functions, no partials. Written out because a trait object has no default.

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for Config<'a>

§

impl<'a> !UnwindSafe for Config<'a>

§

impl<'a> Freeze for Config<'a>

§

impl<'a> Send for Config<'a>

§

impl<'a> Sync for Config<'a>

§

impl<'a> Unpin for Config<'a>

§

impl<'a> UnsafeUnpin for Config<'a>

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.