pub struct BuilderRegistry<T: ?Sized> { /* private fields */ }Available on crate feature
std only.Expand description
§Registry for type-erased FromXml builders which construct T
For general information on builder registries, see registry.
§Performance trade-offs
The implementation of the BuilderRegistry is optimized toward specific
usages. Other usages may see negative performance impacts. The following
assumptions are made:
- Types are added only once at startup and a matching
reservecall is made beforehands. - There are many different types.
FromXml::xml_name_matcherreturns a different value for most of the types which are added.
The lookup algorithms in particular are geared toward the implications of the last two assumptions and may be rather inefficient otherwise.
§Example
This example illustrates the manual usage of the BuilderRegistry.
#[derive(FromXml, Debug, PartialEq)]
#[xml(namespace = "urn:example", name = "foo")]
struct Foo;
#[derive(FromXml, Debug, PartialEq)]
#[xml(namespace = "urn:example", name = "bar")]
struct Bar;
#[derive(Debug, PartialEq)]
enum Either {
A(Foo),
B(Bar),
}
// BuilderRegistry::add::<U> requires that Either: MayContain<U>, in order
// to be able to wrap the U::Builder such that it outputs a Xso<Either>
// instead.
impl MayContain<Foo> for Either {
fn upcast_into(other: Foo) -> Box<Self> { Box::new(Self::A(other)) }
}
impl MayContain<Bar> for Either {
fn upcast_into(other: Bar) -> Box<Self> { Box::new(Self::B(other)) }
}
let registry = BuilderRegistry::<Either>::new();
registry.add::<Foo>();
registry.add::<Bar>();
let mut builder = registry.make_builder(
(
Namespace::from_str("urn:example"),
xml_ncname!("foo").to_owned(), // <- Selects the Foo variant
),
AttrMap::new(),
&Context::empty(),
).unwrap();
let x = builder.feed(Event::EndElement(EventMetrics::zero()), &Context::empty()).unwrap().unwrap();
assert_eq!(Either::A(Foo), *x);
let mut builder = registry.make_builder(
(
Namespace::from_str("urn:example"),
xml_ncname!("bar").to_owned(), // <- Selects the Bar variant
),
AttrMap::new(),
&Context::empty(),
).unwrap();
let x = builder.feed(Event::EndElement(EventMetrics::zero()), &Context::empty()).unwrap().unwrap();
assert_eq!(Either::B(Bar), *x);Implementing FromXml on the Either type in the above example would
be trivial and look like this:
// ... code from the previous example ...
use xso::dynxso::UnboxBuilder;
// In order to be able to use the registry from the FromXml implementation,
// it must be a static (as opposed to a local variable as in the previous
// example).
static REGISTRY: BuilderRegistry<Either> = BuilderRegistry::new();
REGISTRY.add::<Foo>();
REGISTRY.add::<Bar>();
impl FromXml for Either {
type Builder = UnboxBuilder<Box<dyn FromEventsBuilder<Output = Box<Either>>>>;
fn from_events(name: QName, attrs: AttrMap, ctx: &Context<'_>) -> Result<Self::Builder, FromEventsError> {
REGISTRY.make_builder(name, attrs, ctx).map(UnboxBuilder::wrap)
}
}
assert_eq!(
Either::A(Foo),
from_bytes("<foo xmlns='urn:example'/>".as_bytes()).unwrap(),
);
assert_eq!(
Either::B(Bar),
from_bytes("<bar xmlns='urn:example'/>".as_bytes()).unwrap(),
);Implementations§
Trait Implementations§
Source§impl<T: ?Sized + 'static> Default for BuilderRegistry<T>
impl<T: ?Sized + 'static> Default for BuilderRegistry<T>
Source§impl<T: ?Sized + 'static> DynXsoRegistryAdd<T> for BuilderRegistry<T>
impl<T: ?Sized + 'static> DynXsoRegistryAdd<T> for BuilderRegistry<T>
Source§impl<T: ?Sized + 'static> DynXsoRegistryLookup<T> for BuilderRegistry<T>
impl<T: ?Sized + 'static> DynXsoRegistryLookup<T> for BuilderRegistry<T>
Source§fn make_builder(
&self,
name: QName,
attrs: AttrMap,
ctx: &Context<'_>,
) -> Result<Box<dyn FromEventsBuilder<Output = Box<T>>>, FromEventsError>
fn make_builder( &self, name: QName, attrs: AttrMap, ctx: &Context<'_>, ) -> Result<Box<dyn FromEventsBuilder<Output = Box<T>>>, FromEventsError>
Make a builder for the given element header. Read more
Auto Trait Implementations§
impl<T> !Freeze for BuilderRegistry<T>
impl<T> RefUnwindSafe for BuilderRegistry<T>where
T: ?Sized,
impl<T> Send for BuilderRegistry<T>where
T: ?Sized,
impl<T> Sync for BuilderRegistry<T>where
T: ?Sized,
impl<T> Unpin for BuilderRegistry<T>where
T: ?Sized,
impl<T> UnwindSafe for BuilderRegistry<T>where
T: ?Sized,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more