ciboulette/body/
resource_type_builder.rs

1use lazy_static::__Deref;
2
3use super::*;
4
5/// ## Describe a `json:api` type attribute schema and list its relationships
6#[derive(Clone, Debug, Getters, MutGetters)]
7#[getset(get = "pub", get_mut = "pub")]
8pub struct CibouletteResourceTypeBuilder {
9    relationships: BTreeMap<ArcStr, petgraph::graph::EdgeIndex<u16>>,
10    relationships_type_to_alias: BTreeMap<ArcStr, ArcStr>,
11    schema: MessyJsonObject,
12    ids: CibouletteIdTypeSelector,
13    name: ArcStr,
14}
15
16impl CibouletteResourceTypeBuilder {
17    /// Create a new type from a schema and a list of relationships
18    pub fn new(name: String, id_type: CibouletteIdTypeSelector, schema: MessyJsonObject) -> Self {
19        CibouletteResourceTypeBuilder {
20            relationships: BTreeMap::new(),
21            relationships_type_to_alias: BTreeMap::new(),
22            schema,
23            ids: id_type,
24            name: ArcStr::from(name),
25        }
26    }
27
28    /// Check the the name of every field in an object.
29    ///
30    /// Return `Some(field)` if a field doesn't respect the member name's checks.
31    fn check_member_name_obj(val: &MessyJsonObject) -> Option<String> {
32        for (k, v) in val.properties().iter() {
33            if !crate::member_name::check_member_name(&*k) {
34                return Some(k.to_string());
35            }
36            if let Some(x) = Self::check_member_name(v) {
37                return Some(x);
38            }
39        }
40        None
41    }
42
43    /// Check the the name of every field in an document.
44    ///
45    /// Return `Some(field)` if a field doesn't respect the member name's checks.
46    fn check_member_name(val: &MessyJson) -> Option<String> {
47        match val.deref() {
48            MessyJsonInner::Obj(map) => Self::check_member_name_obj(map),
49            MessyJsonInner::Array(arr) => Self::check_member_name(arr.items()),
50            _ => None,
51        }
52    }
53
54    /// Build the resource type, checking once the member names
55    pub fn build(self) -> Result<CibouletteResourceType, CibouletteError> {
56        if let Some(x) = Self::check_member_name_obj(self.schema()) {
57            return Err(CibouletteError::InvalidMemberName(x));
58        }
59        Ok(CibouletteResourceType::new(
60            self.name,
61            self.ids,
62            self.schema,
63        ))
64    }
65}
66
67impl Ord for CibouletteResourceTypeBuilder {
68    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
69        self.name.cmp(&other.name)
70    }
71}
72
73impl PartialOrd for CibouletteResourceTypeBuilder {
74    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
75        Some(self.name.cmp(&other.name))
76    }
77}
78
79impl PartialEq for CibouletteResourceTypeBuilder {
80    fn eq(&self, other: &Self) -> bool {
81        self.name == other.name
82    }
83}
84
85impl Eq for CibouletteResourceTypeBuilder {}