1use crate::model::{
4 BlankNode, NamedNode, Object, ObjectRef, Predicate, PredicateRef, Subject, SubjectRef, Triple,
5 TripleRef, Variable,
6};
7use std::fmt;
8use std::hash::Hash;
9
10#[derive(
12 Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
13)]
14pub enum GraphName {
15 NamedNode(NamedNode),
16 BlankNode(BlankNode),
17 Variable(Variable),
18 DefaultGraph,
19}
20
21impl GraphName {
22 pub fn is_default_graph(&self) -> bool {
24 matches!(self, GraphName::DefaultGraph)
25 }
26}
27
28impl fmt::Display for GraphName {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 GraphName::NamedNode(n) => write!(f, "{n}"),
32 GraphName::BlankNode(b) => write!(f, "{b}"),
33 GraphName::Variable(v) => write!(f, "{v}"),
34 GraphName::DefaultGraph => write!(f, "DEFAULT"),
35 }
36 }
37}
38
39impl AsRef<str> for GraphName {
40 fn as_ref(&self) -> &str {
41 match self {
42 GraphName::NamedNode(n) => n.as_str(),
43 GraphName::BlankNode(b) => b.as_str(),
44 GraphName::Variable(v) => v.name(),
45 GraphName::DefaultGraph => "DEFAULT",
46 }
47 }
48}
49
50impl From<NamedNode> for GraphName {
51 fn from(node: NamedNode) -> Self {
52 GraphName::NamedNode(node)
53 }
54}
55
56impl From<BlankNode> for GraphName {
57 fn from(node: BlankNode) -> Self {
58 GraphName::BlankNode(node)
59 }
60}
61
62impl From<Variable> for GraphName {
63 fn from(variable: Variable) -> Self {
64 GraphName::Variable(variable)
65 }
66}
67
68impl From<crate::model::node::NamedOrBlankNode> for GraphName {
69 fn from(node: crate::model::node::NamedOrBlankNode) -> Self {
70 match node {
71 crate::model::node::NamedOrBlankNode::NamedNode(n) => GraphName::NamedNode(n),
72 crate::model::node::NamedOrBlankNode::BlankNode(b) => GraphName::BlankNode(b),
73 }
74 }
75}
76
77#[derive(
82 Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
83)]
84pub struct Quad {
85 subject: Subject,
86 predicate: Predicate,
87 object: Object,
88 graph_name: GraphName,
89}
90
91impl Quad {
92 pub fn new(
94 subject: impl Into<Subject>,
95 predicate: impl Into<Predicate>,
96 object: impl Into<Object>,
97 graph_name: impl Into<GraphName>,
98 ) -> Self {
99 Quad {
100 subject: subject.into(),
101 predicate: predicate.into(),
102 object: object.into(),
103 graph_name: graph_name.into(),
104 }
105 }
106
107 pub fn new_default_graph(
109 subject: impl Into<Subject>,
110 predicate: impl Into<Predicate>,
111 object: impl Into<Object>,
112 ) -> Self {
113 Quad {
114 subject: subject.into(),
115 predicate: predicate.into(),
116 object: object.into(),
117 graph_name: GraphName::DefaultGraph,
118 }
119 }
120
121 pub fn from_triple(triple: Triple) -> Self {
123 let (subject, predicate, object) = triple.into_parts();
124 Quad::new_default_graph(subject, predicate, object)
125 }
126
127 pub fn from_triple_in_graph(triple: Triple, graph_name: impl Into<GraphName>) -> Self {
129 let (subject, predicate, object) = triple.into_parts();
130 Quad::new(subject, predicate, object, graph_name)
131 }
132
133 pub fn subject(&self) -> &Subject {
135 &self.subject
136 }
137
138 pub fn predicate(&self) -> &Predicate {
140 &self.predicate
141 }
142
143 pub fn object(&self) -> &Object {
145 &self.object
146 }
147
148 pub fn graph_name(&self) -> &GraphName {
150 &self.graph_name
151 }
152
153 pub fn into_parts(self) -> (Subject, Predicate, Object, GraphName) {
155 (self.subject, self.predicate, self.object, self.graph_name)
156 }
157
158 pub fn to_triple(&self) -> Triple {
160 Triple::new(
161 self.subject.clone(),
162 self.predicate.clone(),
163 self.object.clone(),
164 )
165 }
166
167 pub fn as_ref(&self) -> QuadRef<'_> {
169 QuadRef::from(self)
170 }
171
172 pub fn is_default_graph(&self) -> bool {
174 matches!(self.graph_name, GraphName::DefaultGraph)
175 }
176
177 pub fn triple_in_default_graph(&self) -> Option<Triple> {
179 if self.is_default_graph() {
180 Some(self.to_triple())
181 } else {
182 None
183 }
184 }
185
186 pub fn has_variables(&self) -> bool {
188 matches!(self.subject, Subject::Variable(_))
189 || matches!(self.predicate, Predicate::Variable(_))
190 || matches!(self.object, Object::Variable(_))
191 || matches!(self.graph_name, GraphName::Variable(_))
192 }
193
194 pub fn is_ground(&self) -> bool {
196 !self.has_variables()
197 }
198}
199
200impl fmt::Display for Quad {
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 match &self.graph_name {
203 GraphName::DefaultGraph => {
204 write!(f, "{} {} {} .", self.subject, self.predicate, self.object)
205 }
206 graph => write!(
207 f,
208 "{} {} {} {} .",
209 self.subject, self.predicate, self.object, graph
210 ),
211 }
212 }
213}
214
215#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
217pub struct QuadRef<'a> {
218 subject: SubjectRef<'a>,
219 predicate: PredicateRef<'a>,
220 object: ObjectRef<'a>,
221 graph_name: GraphNameRef<'a>,
222}
223
224impl<'a> QuadRef<'a> {
225 pub fn new(
227 subject: SubjectRef<'a>,
228 predicate: PredicateRef<'a>,
229 object: ObjectRef<'a>,
230 graph_name: GraphNameRef<'a>,
231 ) -> Self {
232 QuadRef {
233 subject,
234 predicate,
235 object,
236 graph_name,
237 }
238 }
239
240 pub fn subject(&self) -> SubjectRef<'a> {
242 self.subject
243 }
244
245 pub fn predicate(&self) -> PredicateRef<'a> {
247 self.predicate
248 }
249
250 pub fn object(&self) -> ObjectRef<'a> {
252 self.object
253 }
254
255 pub fn graph_name(&self) -> GraphNameRef<'a> {
257 self.graph_name
258 }
259
260 pub fn to_owned(&self) -> Quad {
262 Quad {
263 subject: self.subject.to_owned(),
264 predicate: self.predicate.to_owned(),
265 object: self.object.to_owned(),
266 graph_name: self.graph_name.to_owned(),
267 }
268 }
269
270 pub fn to_triple_ref(&self) -> TripleRef<'a> {
272 TripleRef::new(self.subject, self.predicate, self.object)
273 }
274
275 pub fn triple(&self) -> TripleRef<'a> {
277 self.to_triple_ref()
278 }
279
280 pub fn into_owned(self) -> Quad {
282 self.to_owned()
283 }
284}
285
286impl<'a> fmt::Display for QuadRef<'a> {
287 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
288 match self.graph_name {
289 GraphNameRef::DefaultGraph => {
290 write!(f, "{} {} {} .", self.subject, self.predicate, self.object)
291 }
292 graph => write!(
293 f,
294 "{} {} {} {} .",
295 self.subject, self.predicate, self.object, graph
296 ),
297 }
298 }
299}
300
301#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
303pub enum GraphNameRef<'a> {
304 NamedNode(&'a NamedNode),
305 BlankNode(&'a BlankNode),
306 Variable(&'a Variable),
307 DefaultGraph,
308}
309
310impl<'a> GraphNameRef<'a> {
311 pub fn is_default_graph(&self) -> bool {
313 matches!(self, GraphNameRef::DefaultGraph)
314 }
315
316 pub fn to_owned(&self) -> GraphName {
318 match self {
319 GraphNameRef::NamedNode(n) => GraphName::NamedNode((*n).clone()),
320 GraphNameRef::BlankNode(b) => GraphName::BlankNode((*b).clone()),
321 GraphNameRef::Variable(v) => GraphName::Variable((*v).clone()),
322 GraphNameRef::DefaultGraph => GraphName::DefaultGraph,
323 }
324 }
325}
326
327impl<'a> fmt::Display for GraphNameRef<'a> {
328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329 match self {
330 GraphNameRef::NamedNode(n) => write!(f, "{n}"),
331 GraphNameRef::BlankNode(b) => write!(f, "{b}"),
332 GraphNameRef::Variable(v) => write!(f, "{v}"),
333 GraphNameRef::DefaultGraph => write!(f, "DEFAULT"),
334 }
335 }
336}
337
338impl<'a> From<&'a GraphName> for GraphNameRef<'a> {
340 fn from(graph_name: &'a GraphName) -> Self {
341 match graph_name {
342 GraphName::NamedNode(n) => GraphNameRef::NamedNode(n),
343 GraphName::BlankNode(b) => GraphNameRef::BlankNode(b),
344 GraphName::Variable(v) => GraphNameRef::Variable(v),
345 GraphName::DefaultGraph => GraphNameRef::DefaultGraph,
346 }
347 }
348}
349
350impl<'a> From<&'a Quad> for QuadRef<'a> {
351 fn from(quad: &'a Quad) -> Self {
352 QuadRef {
353 subject: quad.subject().into(),
354 predicate: quad.predicate().into(),
355 object: quad.object().into(),
356 graph_name: quad.graph_name().into(),
357 }
358 }
359}
360
361impl<'a> From<QuadRef<'a>> for Quad {
362 fn from(quad_ref: QuadRef<'a>) -> Self {
363 quad_ref.to_owned()
364 }
365}
366
367impl From<Triple> for Quad {
368 fn from(triple: Triple) -> Self {
369 Quad::from_triple(triple)
370 }
371}
372
373#[cfg(test)]
374mod tests {
375 use super::*;
376 use crate::model::{Literal, NamedNode};
377
378 #[test]
379 fn test_quad_creation() {
380 let subject = NamedNode::new("http://example.org/subject").unwrap();
381 let predicate = NamedNode::new("http://example.org/predicate").unwrap();
382 let object = Literal::new("object");
383 let graph = NamedNode::new("http://example.org/graph").unwrap();
384
385 let quad = Quad::new(
386 subject.clone(),
387 predicate.clone(),
388 object.clone(),
389 graph.clone(),
390 );
391
392 assert!(quad.is_ground());
393 assert!(!quad.has_variables());
394 assert!(!quad.is_default_graph());
395 }
396
397 #[test]
398 fn test_quad_default_graph() {
399 let subject = NamedNode::new("http://example.org/subject").unwrap();
400 let predicate = NamedNode::new("http://example.org/predicate").unwrap();
401 let object = Literal::new("object");
402
403 let quad = Quad::new_default_graph(subject, predicate, object);
404
405 assert!(quad.is_default_graph());
406 assert!(quad.graph_name().is_default_graph());
407 }
408
409 #[test]
410 fn test_quad_from_triple() {
411 let subject = NamedNode::new("http://example.org/subject").unwrap();
412 let predicate = NamedNode::new("http://example.org/predicate").unwrap();
413 let object = Literal::new("object");
414
415 let triple = Triple::new(subject.clone(), predicate.clone(), object.clone());
416 let quad = Quad::from_triple(triple.clone());
417
418 assert!(quad.is_default_graph());
419 assert_eq!(quad.to_triple().subject(), triple.subject());
420 assert_eq!(quad.to_triple().predicate(), triple.predicate());
421 assert_eq!(quad.to_triple().object(), triple.object());
422 }
423
424 #[test]
425 fn test_quad_with_variable() {
426 let subject = Variable::new("x").unwrap();
427 let predicate = NamedNode::new("http://example.org/predicate").unwrap();
428 let object = Literal::new("object");
429 let graph = Variable::new("g").unwrap();
430
431 let quad = Quad::new(subject, predicate, object, graph);
432
433 assert!(!quad.is_ground());
434 assert!(quad.has_variables());
435 }
436
437 #[test]
438 fn test_quad_ref() {
439 let subject = NamedNode::new("http://example.org/s").unwrap();
440 let predicate = NamedNode::new("http://example.org/p").unwrap();
441 let object = Literal::new("o");
442 let graph = NamedNode::new("http://example.org/g").unwrap();
443
444 let quad = Quad::new(subject, predicate, object, graph);
445 let quad_ref = QuadRef::from(&quad);
446 let quad_owned = quad_ref.to_owned();
447
448 assert_eq!(quad, quad_owned);
449 }
450}