teaql_core/
entity_graph.rs1use crate::{Entity, MutationValues, 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 values: MutationValues,
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 values: entity.into_values(),
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 values: MutationValues,
104 }
105
106 impl Entity for DummyEntity {
107 fn into_values(self) -> MutationValues {
108 self.values
109 }
110
111 fn from_compact_row(row: crate::CompactRow) -> Result<Self, EntityError> {
112 Ok(Self {
113 values: row.into_map().into(),
114 })
115 }
116 }
117
118 impl TeaqlEntity for DummyEntity {
119 const ENTITY_NAME: &'static str = "Dummy";
120
121 fn entity_descriptor() -> EntityDescriptor {
122 EntityDescriptor::new("Dummy")
123 .property(PropertyDescriptor::new("id", DataType::I64).id())
124 }
125 }
126
127 #[test]
128 fn test_entity_graph_builder_annotations_and_child_operations() {
129 let mut rec1 = BTreeMap::new();
130 rec1.insert("id".to_string(), Value::I64(1));
131 let entity1 = DummyEntity { values: rec1.into() };
132
133 let mut rec2 = BTreeMap::new();
134 rec2.insert("id".to_string(), Value::I64(2));
135 let entity2 = DummyEntity { values: rec2.into() };
136
137 let graph = EntityGraph::new(entity1)
138 .comment("Parent creation")
139 .child(
140 "dummy_items",
141 EntityGraph::new(entity2).comment("Child deletion").delete(),
142 )
143 .build();
144
145 let root = graph.root;
146 assert_eq!(root.entity_type, "Dummy");
147 assert_eq!(root.comment.as_deref(), Some("Parent creation"));
148 assert_eq!(root.operation, EntityGraphOperation::Save);
149 assert_eq!(root.children.len(), 1);
150
151 let (rel_name, child_node) = &root.children[0];
152 assert_eq!(rel_name, "dummy_items");
153 assert_eq!(child_node.entity_type, "Dummy");
154 assert_eq!(child_node.comment.as_deref(), Some("Child deletion"));
155 assert_eq!(child_node.operation, EntityGraphOperation::Delete);
156 }
157}