ciboulette/store/
mod.rs

1use super::*;
2use getset::CopyGetters;
3
4mod builder;
5mod many_to_many;
6mod one_to_many;
7mod relationships_options;
8mod relationships_options_builder;
9pub use builder::CibouletteStoreBuilder;
10pub use relationships_options::{
11    CibouletteRelationshipManyToManyOption, CibouletteRelationshipOneToManyOption,
12    CibouletteRelationshipOption,
13};
14pub use relationships_options_builder::{
15    CibouletteRelationshipManyToManyOptionBuilder, CibouletteRelationshipOneToManyOptionBuilder,
16    CibouletteRelationshipOptionBuilder,
17};
18
19#[cfg(test)]
20mod tests;
21
22/// ## Map of accepted resource types
23#[derive(Clone, Debug, Getters, MutGetters)]
24#[getset(get = "pub", get_mut)]
25pub struct CibouletteStore {
26    graph: petgraph::graph::Graph<
27        Arc<CibouletteResourceType>,
28        CibouletteRelationshipOption,
29        petgraph::Directed,
30        u16,
31    >,
32    map: BTreeMap<ArcStr, petgraph::graph::NodeIndex<u16>>,
33    config: CibouletteConfig,
34}
35
36impl CibouletteStore {
37    /// Get a type index from the graph
38    pub fn get_type_index(&self, name: &str) -> Option<&petgraph::graph::NodeIndex<u16>> {
39        self.map.get(name)
40    }
41
42    /// Get a type from the graph
43    pub fn get_type_with_index(
44        &self,
45        name: &str,
46    ) -> Option<(
47        petgraph::graph::NodeIndex<u16>,
48        &Arc<CibouletteResourceType>,
49    )> {
50        self.map
51            .get(name)
52            .and_then(|x| self.graph.node_weight(*x).map(|y| (*x, y)))
53    }
54
55    /// Get a type from the graph, returning an error if not found
56    pub fn get_type_if_exists(&self, name: &str) -> Option<Arc<CibouletteResourceType>> {
57        self.map
58            .get(name)
59            .and_then(|x| self.graph.node_weight(*x))
60            .cloned()
61    }
62
63    /// Get a type from the graph, returning an error if not found
64    pub fn get_type(&self, name: &str) -> Result<&Arc<CibouletteResourceType>, CibouletteError> {
65        self.map
66            .get(name)
67            .and_then(|x| self.graph.node_weight(*x))
68            .ok_or_else(|| CibouletteError::UnknownType(name.to_string()))
69    }
70
71    /// Get a relationship from the graph
72    pub fn get_rel(
73        &self,
74        from: &str,
75        to: &str,
76    ) -> Result<(&CibouletteResourceType, &CibouletteRelationshipOption), CibouletteError> {
77        let from_i = self
78            .map
79            .get(from)
80            .ok_or_else(|| CibouletteError::UnknownType(from.to_string()))?;
81        let from_type = self
82            .graph
83            .node_weight(*from_i)
84            .ok_or_else(|| CibouletteError::TypeNotInGraph(from.to_string()))?;
85        let rel = from_type.relationships().get(to).ok_or_else(|| {
86            CibouletteError::UnknownRelationship(from.to_string(), to.to_string())
87        })?;
88        let (_from_type_i, to_type_i) = self
89            .graph
90            .edge_endpoints(*rel)
91            .ok_or_else(|| CibouletteError::RelNotInGraph(from.to_string(), to.to_string()))?;
92        let to_type = self
93            .graph
94            .node_weight(to_type_i)
95            .ok_or_else(|| CibouletteError::RelNotInGraph(from.to_string(), to.to_string()))?;
96        let opt = self
97            .graph
98            .edge_weight(*rel)
99            .ok_or_else(|| CibouletteError::RelNotInGraph(from.to_string(), to.to_string()))?;
100
101        Ok((to_type, opt))
102    }
103}