graphrecords_core/graphrecord/
attributes.rs1use crate::{
2 GraphRecord,
3 errors::{GraphRecordError, GraphRecordResult},
4 prelude::{
5 Attributes, EdgeIndex, GraphRecordAttribute, GraphRecordValue, Group, NodeIndex, SchemaType,
6 },
7};
8
9macro_rules! impl_attributes_mut {
10 (
11 $struct_name:ident,
12 $index_type:ty,
13 $index_field:ident,
14 $entity:literal,
15 $contains_fn:ident,
16 $groups_of_fn:ident,
17 $get_attributes_fn:ident,
18 $get_attributes_mut_fn:ident,
19 $schema_update_fn:ident,
20 $schema_validate_fn:ident
21 ) => {
22 pub struct $struct_name<'a> {
23 $index_field: &'a $index_type,
24 graphrecord: &'a mut GraphRecord,
25 }
26
27 impl<'a> $struct_name<'a> {
28 pub(crate) fn new(
29 $index_field: &'a $index_type,
30 graphrecord: &'a mut GraphRecord,
31 ) -> GraphRecordResult<Self> {
32 if !graphrecord.$contains_fn($index_field) {
33 return Err(GraphRecordError::IndexError(format!(
34 concat!("Cannot find ", $entity, " with index {}"),
35 $index_field
36 )));
37 }
38
39 Ok(Self {
40 $index_field,
41 graphrecord,
42 })
43 }
44
45 fn get_groups(&self) -> Vec<Group> {
46 self.graphrecord
47 .$groups_of_fn(self.$index_field)
48 .expect(concat!($entity, " must exist."))
49 .cloned()
50 .collect()
51 }
52
53 fn handle_schema(
54 &mut self,
55 attributes: &Attributes,
56 groups: &[Group],
57 ) -> GraphRecordResult<()> {
58 let schema = &mut self.graphrecord.schema;
59
60 match schema.schema_type() {
61 SchemaType::Inferred => {
62 if groups.is_empty() {
63 schema.$schema_update_fn(attributes, None, false);
64 } else {
65 for group in groups {
66 schema.$schema_update_fn(attributes, Some(group), false);
67 }
68 }
69 }
70 SchemaType::Provided => {
71 if groups.is_empty() {
72 schema.$schema_validate_fn(self.$index_field, attributes, None)?;
73 } else {
74 for group in groups {
75 schema.$schema_validate_fn(
76 self.$index_field,
77 attributes,
78 Some(group),
79 )?;
80 }
81 }
82 }
83 }
84
85 Ok(())
86 }
87
88 fn set_attributes(&mut self, attributes: Attributes) {
89 *self
90 .graphrecord
91 .graph
92 .$get_attributes_mut_fn(self.$index_field)
93 .expect(concat!($entity, " must exist.")) = attributes;
94 }
95
96 pub fn replace_attributes(&mut self, attributes: Attributes) -> GraphRecordResult<()> {
97 let groups = self.get_groups();
98 self.handle_schema(&attributes, &groups)?;
99 self.set_attributes(attributes);
100 Ok(())
101 }
102
103 pub fn update_attribute(
104 &mut self,
105 attribute: &GraphRecordAttribute,
106 value: GraphRecordValue,
107 ) -> GraphRecordResult<()> {
108 let groups = self.get_groups();
109
110 let mut attributes = self
111 .graphrecord
112 .$get_attributes_fn(self.$index_field)
113 .expect(concat!($entity, " must exist."))
114 .clone();
115 attributes
116 .entry(attribute.clone())
117 .and_modify(|v| *v = value.clone())
118 .or_insert(value);
119
120 self.handle_schema(&attributes, &groups)?;
121 self.set_attributes(attributes);
122 Ok(())
123 }
124
125 pub fn remove_attribute(
126 &mut self,
127 attribute: &GraphRecordAttribute,
128 ) -> GraphRecordResult<GraphRecordValue> {
129 let groups = self.get_groups();
130
131 let mut attributes = self
132 .graphrecord
133 .$get_attributes_fn(self.$index_field)
134 .expect(concat!($entity, " must exist."))
135 .clone();
136 let removed_value = attributes.remove(attribute);
137
138 let Some(removed_value) = removed_value else {
139 return Err(GraphRecordError::KeyError(format!(
140 concat!("Attribute {} does not exist on ", $entity, " {}"),
141 attribute, self.$index_field
142 )));
143 };
144
145 self.handle_schema(&attributes, &groups)?;
146 self.set_attributes(attributes);
147 Ok(removed_value)
148 }
149 }
150 };
151}
152
153impl_attributes_mut!(
154 NodeAttributesMut,
155 NodeIndex,
156 node_index,
157 "node",
158 contains_node,
159 groups_of_node,
160 node_attributes,
161 node_attributes_mut,
162 update_node,
163 validate_node
164);
165
166impl_attributes_mut!(
167 EdgeAttributesMut,
168 EdgeIndex,
169 edge_index,
170 "edge",
171 contains_edge,
172 groups_of_edge,
173 edge_attributes,
174 edge_attributes_mut,
175 update_edge,
176 validate_edge
177);