Skip to main content

use_graph_store/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use core::fmt;
5
6macro_rules! string_newtype {
7    ($(#[$meta:meta])* $name:ident) => {
8        $(#[$meta])*
9        #[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
10        pub struct $name(String);
11
12        impl $name {
13            /// Creates a new string-backed primitive.
14            pub fn new(value: impl Into<String>) -> Self {
15                Self(value.into())
16            }
17
18            /// Returns the stored string value.
19            pub fn as_str(&self) -> &str {
20                &self.0
21            }
22        }
23
24        impl AsRef<str> for $name {
25            fn as_ref(&self) -> &str {
26                self.as_str()
27            }
28        }
29
30        impl From<String> for $name {
31            fn from(value: String) -> Self {
32                Self::new(value)
33            }
34        }
35
36        impl From<&str> for $name {
37            fn from(value: &str) -> Self {
38                Self::new(value)
39            }
40        }
41
42        impl fmt::Display for $name {
43            fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
44                formatter.write_str(self.as_str())
45            }
46        }
47    };
48}
49
50string_newtype! {
51    /// A property-graph vertex identifier.
52    VertexId
53}
54string_newtype! {
55    /// A property-graph edge identifier.
56    EdgeId
57}
58string_newtype! {
59    /// A property-graph vertex label.
60    VertexLabel
61}
62string_newtype! {
63    /// A property-graph edge label.
64    EdgeLabel
65}
66string_newtype! {
67    /// A property key.
68    PropertyKey
69}
70string_newtype! {
71    /// A property value payload.
72    PropertyValue
73}
74string_newtype! {
75    /// A traversal label used by graph-store queries or projections.
76    TraversalLabel
77}
78
79/// A graph property key/value pair.
80#[derive(Clone, Debug, Eq, Hash, PartialEq)]
81pub struct GraphProperty {
82    key: PropertyKey,
83    value: PropertyValue,
84}
85
86impl GraphProperty {
87    /// Creates a graph property.
88    pub fn new(key: PropertyKey, value: PropertyValue) -> Self {
89        Self { key, value }
90    }
91
92    /// Returns the property key.
93    pub const fn key(&self) -> &PropertyKey {
94        &self.key
95    }
96
97    /// Returns the property value.
98    pub const fn value(&self) -> &PropertyValue {
99        &self.value
100    }
101}
102
103/// A property-graph vertex model.
104#[derive(Clone, Debug, Eq, PartialEq)]
105pub struct GraphVertex {
106    id: VertexId,
107    label: VertexLabel,
108    properties: Vec<GraphProperty>,
109}
110
111impl GraphVertex {
112    /// Creates a graph vertex.
113    pub fn new(id: VertexId, label: VertexLabel) -> Self {
114        Self {
115            id,
116            label,
117            properties: Vec::new(),
118        }
119    }
120
121    /// Adds a property.
122    pub fn with_property(mut self, property: GraphProperty) -> Self {
123        self.properties.push(property);
124        self
125    }
126
127    /// Returns the vertex identifier.
128    pub const fn id(&self) -> &VertexId {
129        &self.id
130    }
131
132    /// Returns the vertex label.
133    pub const fn label(&self) -> &VertexLabel {
134        &self.label
135    }
136
137    /// Returns vertex properties.
138    pub fn properties(&self) -> &[GraphProperty] {
139        &self.properties
140    }
141}
142
143/// A property-graph edge model.
144#[derive(Clone, Debug, Eq, PartialEq)]
145pub struct GraphEdge {
146    id: EdgeId,
147    source: VertexId,
148    target: VertexId,
149    label: EdgeLabel,
150    properties: Vec<GraphProperty>,
151}
152
153impl GraphEdge {
154    /// Creates a graph edge between two vertices.
155    pub fn new(id: EdgeId, source: VertexId, target: VertexId, label: EdgeLabel) -> Self {
156        Self {
157            id,
158            source,
159            target,
160            label,
161            properties: Vec::new(),
162        }
163    }
164
165    /// Adds a property.
166    pub fn with_property(mut self, property: GraphProperty) -> Self {
167        self.properties.push(property);
168        self
169    }
170
171    /// Returns the edge identifier.
172    pub const fn id(&self) -> &EdgeId {
173        &self.id
174    }
175
176    /// Returns the source vertex identifier.
177    pub const fn source(&self) -> &VertexId {
178        &self.source
179    }
180
181    /// Returns the target vertex identifier.
182    pub const fn target(&self) -> &VertexId {
183        &self.target
184    }
185
186    /// Returns the edge label.
187    pub const fn label(&self) -> &EdgeLabel {
188        &self.label
189    }
190
191    /// Returns edge properties.
192    pub fn properties(&self) -> &[GraphProperty] {
193        &self.properties
194    }
195}
196
197#[cfg(test)]
198mod tests {
199    use super::{
200        EdgeId, EdgeLabel, GraphEdge, GraphProperty, GraphVertex, PropertyKey, PropertyValue,
201        TraversalLabel, VertexId, VertexLabel,
202    };
203
204    #[test]
205    fn constructs_graph_store_labels() {
206        assert_eq!(VertexId::new("v1").to_string(), "v1");
207        assert_eq!(TraversalLabel::new("friends").as_ref(), "friends");
208    }
209
210    #[test]
211    fn builds_vertices_and_edges() {
212        let property = GraphProperty::new(PropertyKey::new("name"), PropertyValue::new("Ada"));
213        let vertex = GraphVertex::new(VertexId::new("person_1"), VertexLabel::new("Person"))
214            .with_property(property.clone());
215        let edge = GraphEdge::new(
216            EdgeId::new("edge_1"),
217            VertexId::new("person_1"),
218            VertexId::new("person_2"),
219            EdgeLabel::new("knows"),
220        )
221        .with_property(property);
222
223        assert_eq!(vertex.properties().len(), 1);
224        assert_eq!(edge.source().as_str(), "person_1");
225        assert_eq!(edge.properties().len(), 1);
226    }
227}