Skip to main content

ModelAdapter

Struct ModelAdapter 

Source
pub struct ModelAdapter<A: AstAdapter> { /* private fields */ }
Expand description

A base arbor enriched with a model’s derived structure.

Implementations§

Source§

impl<A: AstAdapter> ModelAdapter<A>

Source

pub fn new(base: A, model: Model) -> Self

Source

pub fn check(&self) -> Result<(), String>

Everything a model can get wrong that only the source can tell: call after construction, before the first query.

Source

pub fn check_trees(&self) -> Result<(), String>

Refuse a tree whose path names no node.

Source

pub fn check_ref_targets(&self) -> Result<(), String>

Refuse a ref whose target names nothing: neither a container a node statement declares nor a root-level node of the source (a table, a mount, a top-level key). A typo in the target would otherwise resolve nothing, silently. The derived containers are not materialized for the check: their names are in the declarations.

Source

pub fn check_declared_traits(&self) -> Result<(), String>

Refuse a declared trait that redefines one the arbor already has: a trait the adapter puts on any node, or the trait a node constructor gives a derived container’s members. The check walks the base arbor once per declaration; call it after construction, before the first query.

Source

pub fn base(&self) -> &A

Source

pub fn locator( &self, node: NodeId, base_locator: impl Fn(NodeId) -> String, ) -> String

A human-readable locator, composing the base’s own renderer for base nodes: /container/value for derived nodes.

Trait Implementations§

Source§

impl<A: AstAdapter> AstAdapter for ModelAdapter<A>

Source§

fn child_host(&self, node: NodeId) -> NodeId

A base node’s transparent links stay transparent; the model’s own nodes host their own children.

Source§

fn can_refer_to(&self, source: NodeId, target: NodeId) -> Option<bool>

A ref declared over the source whose target is the container the target node stands in (a derived container, or a container of the source it sits under); else the base’s own declarations.

Source§

fn reference_properties(&self, source: NodeId, target: NodeId) -> Vec<String>

The fields of the refs declared over the source into the target’s container; else the base’s own declarations.

Source§

fn reverse_label(&self, target: NodeId) -> Option<String>

A base node’s label is the base’s to give; a derived node needs none (the model’s refs resolve without labels).

Source§

fn tree_identities(&self) -> Vec<(String, NodeId)>

The declared trees first (a declaration names the same node as the mount’s own target would, and wins), then the base’s own identities.

Source§

fn resolve_needs_label(&self, node: NodeId, property: &str) -> bool

A property the model declares a ref for resolves by that declaration; any other asks the base.

Source§

fn aliased_metadata(&self, node: NodeId) -> &'static [&'static str]

Model nodes add their own annotations (n-rows); base nodes keep the mounted adapter’s, aliases included. A model node’s id means nothing to the base, so it is never passed down (a mount would read a mount index out of it).

Source§

fn provenance(&self, node: NodeId) -> Provenance

Data provenance. An aliased node is its base node under a role, so it answers that node’s provenance. An elevated node is a new value the model made: it answers a derivation source only (model:/container), never the components of any row it was computed from — the same no-leak discipline property applies to elevated values.

Source§

fn answers_to(&self, node: NodeId, name: &str) -> bool

A written name reaches a node under its canonical name or any alias the model declares for names.

Source§

fn has_trait(&self, node: NodeId, name: &str) -> bool

A written trait reaches a node under a canonical trait or any alias <...> the model declares.

Source§

fn document_by_ref(&self, id: &str) -> Option<NodeId>

The document the base holds under a URL — base ids pass straight through this layer.

Source§

fn reverse_resolve( &self, node: NodeId, property: Option<&str>, hint: Option<&str>, ) -> Option<Vec<NodeId>>

The base’s reverse index answers only when the model adds no reference fabric of its own; otherwise the walk sees both.

Source§

fn descendants_named( &self, node: NodeId, name: &str, ) -> Option<Vec<(NodeId, usize)>>

The base’s name index answers below any base node but the root (the model’s containers hang there) and only when no name alias could widen the match.

An edge’s own properties are the base’s: a model adds links (refs, relations) that carry none, and a node standing for a base one reads through to it.

Source§

fn unit_scale(&self, expr: &str) -> Option<(f64, String)>

The imported libraries first (units LIBRARY;), then the source’s own.

Source§

fn root(&self) -> NodeId

The root node — the initial navigation context.
Source§

fn children(&self, node: NodeId) -> Vec<NodeId>

The tree children of node, in document order. Read more
Source§

fn non_tree_nodes(&self) -> Vec<NodeId>

The nodes of the arbor that are not in the tree — joined to it by crosslinks alone, with no parent and no path. The universal search *// reaches them after the tree, in this order; :::is-non-tree is true on them. The default is none: every shipped adapter puts every node in the tree.
Source§

fn walks_for_references(&self) -> bool

Whether a reverse resolution or a value match with no scope may walk the whole arbor to find its referrers. An adapter over a small, in-memory source opens to the walk; a store or a service does not, and such a query is refused with a message asking for a scope — an empty answer could not be told from an absence of referrers. A declared reference (a foreign key, a model ref) answers through reverse_resolve and needs no walk.
Source§

fn resolves_references(&self) -> bool

Whether this source resolves references at all. An adapter with no notion of a reference (a CSV file, a directory, a log stream) says no, and a reverse arrow over it is refused with the value match as the remedy, rather than answered with an empty set that would read as “nothing points here”.
Source§

fn property_names(&self, node: NodeId) -> Vec<String>

The names of the properties a node has — what “any property” means for <--(SCOPE::*). By default its off-tree properties, its reference property, and its children’s names (a row’s columns, an object’s keys are properties under the same names); an adapter whose properties are not children (an element’s attributes) lists them.
Source§

fn index_lookup( &self, scope: &str, property: &str, value: &Value, ) -> Option<Vec<NodeId>>

index SCOPE::prop; — the nodes of the declared scope whose property holds value, from an index the model keeps; None when no declaration covers the pair (the walk answers). An index changes cost, never the answer: the caller still tests each node it names.
Source§

fn index_referrers( &self, scope: &str, property: &str, label: Option<&str>, target: NodeId, ) -> Option<Vec<NodeId>>

The declared-scope nodes whose property resolves (under the relation label, when given) to target, from the same index; None when no declaration covers the pair.
Source§

fn properties(&self, node: NodeId) -> Vec<(String, Value)>

The node’s own properties, enumerated — name and value, in the source’s order — for readings that keep values off the tree (the JSON property reading, where an object’s scalar fields are no nodes). The serializers (| json, | xml, | kaiv) merge them with the children, a child winning a shared name. The default is none: for a reading whose values are all nodes, the children already say everything.
Source§

fn children_named(&self, node: NodeId, name: &str) -> Vec<NodeId>

The children of node whose edge name is exactly name — the engine’s fast path for name-matcher child hops. The default filters children; an adapter whose containers cannot be enumerated (permission-scoped or unbounded remote trees) overrides this with a direct, name-addressed lookup. Must be observationally identical to the default wherever enumeration works. The adapter owns the name test: it may deliberately alias — resolve a name to a node whose edge name differs (git revision syntax landing on a hash-named commit) — and the engine will not re-filter. Container-scoped resolution like that stays child-axis only; per-node spelling aliases belong in answers_to, which this default consults.
Source§

fn name(&self, node: NodeId) -> Option<String>

The name of node — the label of its incoming tree edge. Read more
Source§

fn parent(&self, node: NodeId) -> Option<NodeId>

The parent of node, or None for the root.
Source§

fn traits(&self, node: NodeId) -> Vec<String>

The traits of node — its adapter-defined classifications, used by <trait> navigation filters (e.g. a filesystem adapter’s <dir>, <code>, <image>).
Source§

fn property(&self, node: NodeId, name: &str) -> Option<Value>

A named property of node — ::prop. None if absent.
Source§

fn default_value(&self, node: NodeId) -> Option<Value>

The default projection of node — bare ::, adapter-specific (a filesystem adapter returns file content).
Source§

fn metadata(&self, node: NodeId, key: &str) -> Option<Value>

Adapter-defined metadata — ::::key (a filesystem adapter’s size, modified, permissions, …). None if absent.
Source§

fn provenance_list(&self, node: NodeId) -> ProvenanceList

The data provenance of node as a list — every source the substrate records for the datum, and how many it elides. The default is the singular answer as a one-entry list; an adapter whose substrate records several (kaiv’s ?a;b;+N) overrides it, and a wrapper layers each entry.
Source§

fn resolve( &self, node: NodeId, property: &str, hint: Option<&str>, ) -> Option<NodeId>

Resolve a cross-reference: ::property-->hint maps node’s property (a value that references another node) to its target, with an optional adapter-specific hint (a relation type such as an html rel, or a target container such as a table). A JSON adapter resolves a $ref JSON Pointer; None if unresolvable.
Source§

fn external_ref( &self, node: NodeId, property: &str, hint: Option<&str>, ) -> Option<ExternalRef>

The external reference node’s property holds, if any: the identity of a document outside this arbor and, where the reference says so, the location within it — both as the adapter reads them out of its own reference syntax (for html, the anchor’s absolute URL and its fragment). The engine does not look inside either string: it asks for the document among the mounts (the host’s registration, then document_by_ref), and hands the location to resolve_fragment on the document it found. Consulted by ::property--> when in-document resolution misses; an unmounted document lands among the run’s unresolved external references for the host’s acquisition loop. The engine itself never fetches.
Source§

fn resolve_fragment(&self, node: NodeId, fragment: &str) -> Option<NodeId>

The element fragment names inside the document node belongs to — html’s id lookup. The landing rung of a fragment-carrying external reference, once its document is mounted.
Source§

fn ref_property(&self, node: NodeId) -> Option<String>

The property carrying node’s own reference, for the bare arrow (//a-->): an html anchor’s href, an iframe’s src. None for a node that references nothing.
Source§

fn ref_label(&self, node: NodeId, property: &str) -> Option<String>

The relation name a resolution edge from node via property carries — html’s rel attribute. None falls back to the property name as the edge label.
Outgoing crosslinks from node, as (label, target) pairs, for -> navigation (a filesystem adapter’s symlinks).
Incoming crosslinks to node, as (label, source) pairs, for <- navigation. May be expensive (an adapter that does not precompute edges must search for referrers).
Source§

fn descendants_where( &self, node: NodeId, name: &str, property: &str, value: &Value, ) -> Option<Vec<(NodeId, usize)>>

The descendants of node named name whose property property equals value, each with its depth, in document order — the fast path behind //name[::property = "value"] for an adapter that indexes a property (the corpus reading’s positional index answers //token[::lower = "tom"] from it). None keeps the engine’s walk and its comparison; Some must be exactly what the walk would find under the standard equality, so an adapter answers only the values it can compare as the engine does (text against text).
Source§

fn select_plan(&self, scope: &[&str], plan: &StepPlan<'_>) -> Option<Vec<bool>>

The dry-run form of select: which of the plan’s conjuncts the adapter would apply, decided from its catalog alone (a column’s existence and type, an index’s presence), with no node in hand. scope is the literal path from the root to the step’s base (["invoices"] for /invoices/*[...]), empty at the root. None when the adapter cannot say — the static plan then counts every conjunct as the engine’s.
Source§

fn estimate(&self, scope: &[&str], plan: &StepPlan<'_>) -> Option<Estimate>

What reaching one step’s nodes would cost, said from the catalog with no node in hand (scope as for select_plan): a warehouse’s dry run, a table’s statistics, a file’s size, an arena’s count. None where the adapter has no estimator — the plan then reads “unknown” for the step.
Source§

fn select(&self, from: NodeId, plan: &StepPlan<'_>) -> Option<Selection>

The search fast path: the nodes one step reaches from from under plan, answered from an index — None keeps the engine’s walk (the default folds children_named, descendants_named and descendants_where: select_by_hooks). Some must be exactly what the walk would find for the conjuncts it marks applied, under the engine’s standard equality; the engine tests the remaining conjuncts and every other predicate on the nodes returned. A child plan’s answer is never re-filtered by name (the adapter owns the name test, as children_named does); a descendant plan’s nodes still pass the nameless tests.
Source§

fn has_node(&self, node: NodeId) -> bool

Whether node is an id this adapter minted — the guard behind the node-id anchor ((!N)), which may name an id from an earlier run (ids are minted deterministically: the same source, the same ids). The default probes the id through parent and name and treats a panic as absence, so an adapter that indexes by id needs no override; one that can answer cheaply should.
A batching hint: the engine is about to follow dir crosslinks from every node in nodes. An adapter backed by a store may fetch them in one statement; semantics are unchanged either way.
Source§

fn quantifier_bound(&self) -> usize

The quantifier bound N_max: the depth to which open-ended path quantifiers (+, *, {m,}) expand, and the ceiling of any explicit {m,n} (the effective upper bound is min(n, N_max)). An adapter whose natural structures run deep may raise it; a run may override it (Run::quantifier_bound, the CLI’s --quantifier-bound). The shell gate and the invocation instant are the run’s alone (Run::allow_shell, Run::now).
Source§

fn count(&self, _from: NodeId, _plan: &StepPlan<'_>) -> Option<usize>

How many nodes one step reaches from from under plan, without materializing them — @| count right after the step asks before walking. None walks; Some must be exactly the walk’s count for the conjuncts the plan carries (every one of them, or none: a count cannot be partially applied). SQL: SELECT COUNT(*); a document index: the bucket’s length.
Source§

fn prefetch_properties(&self, _nodes: &[NodeId], _names: &[&str])

A batching hint, the projection twin of prefetch_links: the engine is about to read the properties names of every node in nodes (the next command projects them). A remote adapter fetches the columns for the frontier in one round trip; semantics are unchanged either way.

Auto Trait Implementations§

§

impl<A> !Freeze for ModelAdapter<A>

§

impl<A> !RefUnwindSafe for ModelAdapter<A>

§

impl<A> !Sync for ModelAdapter<A>

§

impl<A> Send for ModelAdapter<A>
where A: Send,

§

impl<A> Unpin for ModelAdapter<A>
where A: Unpin,

§

impl<A> UnsafeUnpin for ModelAdapter<A>
where A: UnsafeUnpin,

§

impl<A> UnwindSafe for ModelAdapter<A>
where A: UnwindSafe,

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, 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 = !

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.