cameleon_genapi/
builder.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use super::{
6    parser,
7    store::{
8        CacheSink, DefaultCacheStore, DefaultNodeStore, DefaultValueStore, NodeData, NodeId,
9        ValueData, ValueId,
10    },
11    RegisterDescription, ValueCtxt,
12};
13
14#[derive(Default)]
15pub struct GenApiBuilder<T = DefaultNodeStore, U = DefaultValueStore, S = DefaultCacheStore> {
16    node_store: T,
17    value_store: U,
18    cache_store: S,
19}
20
21pub type BuildResult<T, U, S> = parser::ParseResult<(RegisterDescription, T, ValueCtxt<U, S>)>;
22
23impl<T, U, S> GenApiBuilder<T, U, S> {
24    pub fn build(mut self, xml: &impl AsRef<str>) -> BuildResult<T::Store, U::Store, S::Store>
25    where
26        T: NodeStoreBuilder,
27        U: ValueStoreBuilder,
28        S: CacheStoreBuilder,
29    {
30        let reg_desc = parser::parse(
31            xml,
32            &mut self.node_store,
33            &mut self.value_store,
34            &mut self.cache_store,
35        )?;
36
37        Ok((
38            reg_desc,
39            self.node_store.build(),
40            ValueCtxt::new(self.value_store.build(), self.cache_store.build()),
41        ))
42    }
43
44    pub fn no_cache(self) -> GenApiBuilder<T, U, CacheSink> {
45        GenApiBuilder {
46            node_store: self.node_store,
47            value_store: self.value_store,
48            cache_store: CacheSink::default(),
49        }
50    }
51
52    pub fn with_node_store<T2>(self, node_store: T2) -> GenApiBuilder<T2, U, S> {
53        GenApiBuilder {
54            node_store,
55            value_store: self.value_store,
56            cache_store: self.cache_store,
57        }
58    }
59
60    pub fn with_value_store<U2>(self, value_store: U2) -> GenApiBuilder<T, U2, S> {
61        GenApiBuilder {
62            node_store: self.node_store,
63            value_store,
64            cache_store: self.cache_store,
65        }
66    }
67
68    pub fn with_cache_store<S2>(self, cache_store: S2) -> GenApiBuilder<T, U, S2> {
69        GenApiBuilder {
70            node_store: self.node_store,
71            value_store: self.value_store,
72            cache_store,
73        }
74    }
75}
76
77pub trait NodeStoreBuilder {
78    type Store;
79
80    /// Build `NodeStore`.
81    fn build(self) -> Self::Store;
82
83    /// Store [`NodeData`].
84    fn store_node(&mut self, nid: NodeId, data: NodeData);
85
86    /// Intern the node name and return the corresponding [`NodeId`].
87    fn get_or_intern<T>(&mut self, node_name: T) -> NodeId
88    where
89        T: AsRef<str>;
90
91    /// Returns fresh id for each call.
92    fn fresh_id(&mut self) -> u32;
93}
94
95pub trait ValueStoreBuilder {
96    type Store;
97
98    /// Build `ValueStore`.
99    fn build(self) -> Self::Store;
100
101    /// Store the `ValueData` and return the corresponding [`ValueId`].
102    fn store<T, U>(&mut self, data: T) -> U
103    where
104        T: Into<ValueData>,
105        U: From<ValueId>;
106}
107
108pub trait CacheStoreBuilder {
109    type Store;
110
111    /// Build `CacheStore`.
112    fn build(self) -> Self::Store;
113
114    /// Store invalidator and its target to be invalidated.
115    fn store_invalidator(&mut self, invalidator: NodeId, target: NodeId);
116}