1pub mod capabilities;
2pub mod cast;
3#[cfg(feature = "dynamic")]
4pub mod dynamic;
5pub mod element;
6pub mod error;
7pub mod execution;
8pub mod explain;
9pub mod index;
10pub mod operands;
11pub mod operations;
12pub mod optimizer;
13pub mod prelude;
14pub mod registry;
15pub mod selection;
16pub mod traits;
17pub mod value;
18
19pub use element::{
20 Arity, Bare, BoxedIterator, Definite, ElementShape, Indexed, Multiple, OrderState, Ordered,
21 Return, ReturnShape, Single, Unordered,
22};
23pub use error::{Diagnostic, ErrorGroup, External, Failure, FailureKind, QueryResult};
24pub use explain::{Explain, ExplainFormatter, Explanation, Labeled};
25pub use index::{
26 EdgeEndpointRole, EntityDomain, ExpandedChild, ExpandedIndex, ExpandedIndexOwned,
27 ExpandedIndexReference, GroupKey, IndexDomain, OwnedIndex, Position, Positional,
28};
29pub use operands::{
30 Bucket, BucketOwned, CheckedIndexedLaneBuilder, DefiniteEdgeOperand, DefiniteNodeOperand,
31 DefiniteReferenceOperand, EdgeOperand, EdgesOperand, EvaluateContext, EvaluateOperand,
32 GroupOperand, KeyFailure, KeyFailureOwned, NodeOperand, NodesOperand, Operand, OperandContext,
33 Partition, PartitionBucketParts, PartitionKeyFailureParts, PartitionOwned, PartitionOwnedParts,
34 PartitionParts, ReferenceOperand, ReferencesOperand, ReturnBucket, ReturnKeyFailure,
35 ReturnPartition, ReturnPartitionParts,
36};
37pub use operations::{EdgeDirection, MaybeAbsent, PreparedIndexedMultiple};
38pub use selection::{QueryEdges, QueryNodes};
39pub use traits::*;
40pub use value::{
41 AttributeName, BareValueDomain, EntityReference, FailureKindValue, FailureValue, IndexValue,
42 Mask, ReturnValueDomain, Scalar, Unit, ValueDomain,
43};
44
45mod sealed {
46 pub trait Sealed {}
47}
48
49#[cfg(test)]
50mod test {
51 use crate::{Attribute, Filter, HasAttribute, InGroup, QueryEdges, QueryNodes};
52 use graphrecords_core::{
53 GraphRecord,
54 errors::GraphRecordError,
55 graphrecord::{AttributeMap, GraphRecordValue, NodeIndex},
56 };
57 use std::collections::HashMap;
58
59 fn create_nodes() -> Vec<(NodeIndex, AttributeMap)> {
60 vec![
61 (
62 "0".into(),
63 HashMap::from([("lorem".into(), "ipsum".into())]),
64 ),
65 (
66 "1".into(),
67 HashMap::from([("amet".into(), "consectetur".into())]),
68 ),
69 (
70 "2".into(),
71 HashMap::from([("adipiscing".into(), "elit".into())]),
72 ),
73 ("3".into(), HashMap::new()),
74 ]
75 }
76
77 fn create_edges() -> Vec<(NodeIndex, NodeIndex, AttributeMap)> {
78 vec![
79 (
80 "0".into(),
81 "1".into(),
82 HashMap::from([
83 ("sed".into(), "do".into()),
84 ("eiusmod".into(), "tempor".into()),
85 ]),
86 ),
87 (
88 "1".into(),
89 "0".into(),
90 HashMap::from([
91 ("sed".into(), "do".into()),
92 ("eiusmod".into(), "tempor".into()),
93 ]),
94 ),
95 (
96 "1".into(),
97 "2".into(),
98 HashMap::from([("incididunt".into(), "ut".into())]),
99 ),
100 ("0".into(), "2".into(), HashMap::new()),
101 ]
102 }
103
104 fn create_graphrecord() -> GraphRecord {
105 let nodes = create_nodes();
106 let edges = create_edges();
107
108 let mut graphrecord = GraphRecord::from_tuples(nodes, Some(edges), None).unwrap();
109
110 graphrecord
111 .add_group("lorem".into(), Some(vec!["0".into(), "1".into()]), None)
112 .unwrap();
113 graphrecord
114 .add_group("ipsum".into(), Some(vec!["0".into()]), None)
115 .unwrap();
116
117 graphrecord
118 }
119
120 #[test]
121 fn test_query_nodes_attribute() {
122 let graphrecord = create_graphrecord();
123
124 let selection = graphrecord.query_nodes(|node| {
125 let nodes = node.filter(node.has_attribute("lorem".into()));
126
127 nodes.attribute("lorem".into())
128 });
129
130 let elements: Vec<_> = selection.evaluate().unwrap().collect();
131
132 assert_eq!(1, elements.len());
133 assert_eq!(&NodeIndex::from("0"), elements[0].0);
134 assert_eq!(
135 &GraphRecordValue::from("ipsum"),
136 elements[0].1.as_ref().unwrap()
137 );
138 }
139
140 #[test]
141 fn test_query_nodes_in_group() {
142 let graphrecord = create_graphrecord();
143
144 let selection = graphrecord.query_nodes(|node| {
145 let nodes = node.filter(node.in_group("lorem".into()) & !node.in_group("ipsum".into()));
146
147 nodes.attribute("amet".into())
148 });
149
150 let elements: Vec<_> = selection.evaluate().unwrap().collect();
151
152 assert_eq!(1, elements.len());
153 assert_eq!(&NodeIndex::from("1"), elements[0].0);
154 assert_eq!(
155 &GraphRecordValue::from("consectetur"),
156 elements[0].1.as_ref().unwrap()
157 );
158 }
159
160 #[test]
161 fn test_invalid_query_nodes_in_group() {
162 let graphrecord = create_graphrecord();
163
164 let selection =
165 graphrecord.query_nodes(|node| node.filter(node.in_group("consectetur".into())));
166
167 assert!(selection.evaluate().is_err_and(|failure| matches!(
169 failure.downcast_cause::<GraphRecordError>(),
170 Some(GraphRecordError::GroupNotFound { .. })
171 )));
172 }
173
174 #[test]
175 fn test_query_edges_attribute() {
176 let graphrecord = create_graphrecord();
177
178 let selection = graphrecord.query_edges(|edge| {
179 let edges = edge.filter(edge.has_attribute("incididunt".into()));
180
181 edges.attribute("incididunt".into())
182 });
183
184 let elements: Vec<_> = selection.evaluate().unwrap().collect();
185
186 assert_eq!(1, elements.len());
187 assert_eq!(&2, elements[0].0);
188 assert_eq!(
189 &GraphRecordValue::from("ut"),
190 elements[0].1.as_ref().unwrap()
191 );
192 }
193}