Struct LayerStackBuilder

Source
pub struct LayerStackBuilder<R> { /* private fields */ }
Expand description

Builds a LayerStack from a main layer through a LayerResolver.

Implementations§

Source§

impl<R: LayerResolver> LayerStackBuilder<R>

Source

pub fn new(resolver: R) -> Self

Source

pub fn allow_cycles(self, allow: bool) -> Self

Accept import cycles and skip the import that closes one, as upstream does. Off by default, so cycles are a LayerError::Cycle.

The skipped import names a layer that is still being loaded, so that layer is already placed: it comes after the importer that closes the cycle and overrides it, and the main layer stays last. For main → a → main the stack is a, main.

Source

pub fn resolver(&self) -> &R

Source

pub fn resolver_mut(&mut self) -> &mut R

Source

pub fn into_resolver(self) -> R

Source

pub fn build(&mut self, main: &str) -> Result<LayerStack, LayerError<R::Error>>

Loads the layer main names and, recursively, its imports, in the order described in the module docs: the main layer last.

Source

pub fn build_all<I>( &mut self, uris: I, ) -> Result<LayerStack, LayerError<R::Error>>
where I: IntoIterator, I::Item: AsRef<str>,

Loads several layers given weakest first, and recursively their imports, as if they were the imports of a main layer without data. This is how upstream’s ifcx compose and viewer stack the files a user names, so the last one wins.

The stack holds only the named layers and their imports, in the order build would give them below that main layer: each named layer after its own imports, which it overrides, and the named layers in the order given, so a later one overrides an earlier one and everything that one imports. A layer named twice, or also imported, loads once, where it is first reached. The last layer of the stack is its main layer and gives the federated header. uris resolve with no importer, as build’s main does. At least one is needed; with none, the result is LayerError::Missing for an empty URI.

use openbim_ifcx::layers::{LayerStackBuilder, MemoryResolver};

let layer = |id: &str| format!(r#"{{
    "header": {{"id": "{id}", "ifcxVersion": "ifcx_alpha", "dataVersion": "1.0.0",
               "author": "someone", "timestamp": "2026-10-03"}},
    "imports": [], "schemas": {{}},
    "data": [{{"path": "p1", "attributes": {{"demo::value": "{id}"}}}}]
}}"#);
let mut resolver = MemoryResolver::new();
resolver.insert("base", layer("base"));
resolver.insert("overlay", layer("overlay"));

let stack = LayerStackBuilder::new(resolver).build_all(["base", "overlay"])?;
assert_eq!(stack.keys().collect::<Vec<_>>(), ["base", "overlay"]);
assert_eq!(stack.main().key(), "overlay");
assert_eq!(stack.federate().header.id, "overlay");

Trait Implementations§

Source§

impl<R: Debug> Debug for LayerStackBuilder<R>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<R> Freeze for LayerStackBuilder<R>
where R: Freeze,

§

impl<R> RefUnwindSafe for LayerStackBuilder<R>
where R: RefUnwindSafe,

§

impl<R> Send for LayerStackBuilder<R>
where R: Send,

§

impl<R> Sync for LayerStackBuilder<R>
where R: Sync,

§

impl<R> Unpin for LayerStackBuilder<R>
where R: Unpin,

§

impl<R> UnwindSafe for LayerStackBuilder<R>
where R: 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> Same for T

Source§

type Output = T

Should always be Self
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.