teaql_core/
entity_graph.rs1use crate::{Entity, Record, TeaqlEntity};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum EntityGraphOperation {
6 Save,
8 Delete,
10}
11
12#[derive(Debug, Clone)]
17pub struct EntityGraphNode {
18 pub entity_type: String,
19 pub record: Record,
20 pub comment: Option<String>,
21 pub operation: EntityGraphOperation,
22 pub children: Vec<(String, EntityGraphNode)>,
23}
24
25pub struct EntityGraphBuilder {
39 node: EntityGraphNode,
40}
41
42impl EntityGraphBuilder {
43 pub fn comment(mut self, comment: impl Into<String>) -> Self {
47 self.node.comment = Some(comment.into());
48 self
49 }
50
51 pub fn delete(mut self) -> Self {
53 self.node.operation = EntityGraphOperation::Delete;
54 self
55 }
56
57 pub fn child(mut self, relation: impl Into<String>, child: EntityGraphBuilder) -> Self {
59 self.node.children.push((relation.into(), child.node));
60 self
61 }
62
63 pub fn build(self) -> EntityGraph {
65 EntityGraph { root: self.node }
66 }
67}
68
69pub struct EntityGraph {
75 pub root: EntityGraphNode,
76}
77
78impl EntityGraph {
79 #[allow(clippy::new_ret_no_self)]
81 pub fn new<T: Entity + TeaqlEntity>(entity: T) -> EntityGraphBuilder {
82 EntityGraphBuilder {
83 node: EntityGraphNode {
84 entity_type: T::entity_descriptor().name.clone(),
85 record: entity.into_record(),
86 comment: None,
87 operation: EntityGraphOperation::Save,
88 children: Vec::new(),
89 },
90 }
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97 use crate::{DataType, EntityDescriptor, EntityError, PropertyDescriptor, Value};
98 use std::collections::BTreeMap;
99
100 #[derive(Debug, Clone)]
102 struct DummyEntity {
103 record: Record,
104 }
105
106 impl Entity for DummyEntity {
107 fn into_record(self) -> Record {
108 self.record
109 }
110
111 fn from_record(record: Record) -> Result<Self, EntityError> {
112 Ok(Self { record })
113 }
114 }
115
116 impl TeaqlEntity for DummyEntity {
117 fn entity_descriptor() -> EntityDescriptor {
118 EntityDescriptor::new("Dummy")
119 .property(PropertyDescriptor::new("id", DataType::I64).id())
120 }
121 }
122
123 #[test]
124 fn test_entity_graph_builder_annotations_and_child_operations() {
125 let mut rec1 = BTreeMap::new();
126 rec1.insert("id".to_string(), Value::I64(1));
127 let entity1 = DummyEntity { record: rec1 };
128
129 let mut rec2 = BTreeMap::new();
130 rec2.insert("id".to_string(), Value::I64(2));
131 let entity2 = DummyEntity { record: rec2 };
132
133 let graph = EntityGraph::new(entity1)
134 .comment("Parent creation")
135 .child(
136 "dummy_items",
137 EntityGraph::new(entity2).comment("Child deletion").delete(),
138 )
139 .build();
140
141 let root = graph.root;
142 assert_eq!(root.entity_type, "Dummy");
143 assert_eq!(root.comment.as_deref(), Some("Parent creation"));
144 assert_eq!(root.operation, EntityGraphOperation::Save);
145 assert_eq!(root.children.len(), 1);
146
147 let (rel_name, child_node) = &root.children[0];
148 assert_eq!(rel_name, "dummy_items");
149 assert_eq!(child_node.entity_type, "Dummy");
150 assert_eq!(child_node.comment.as_deref(), Some("Child deletion"));
151 assert_eq!(child_node.operation, EntityGraphOperation::Delete);
152 }
153}