1use crate::blank_node::BlankNode;
2use crate::literal::Literal;
3use crate::named_node::NamedNode;
4use crate::{BlankNodeRef, LiteralRef, NamedNodeRef};
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize, Serializer};
7use std::fmt;
8
9#[derive(Eq, PartialEq, Debug, Clone, Hash)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12#[cfg_attr(feature = "serde", serde(tag = "type", rename_all = "lowercase"))]
13pub enum NamedOrBlankNode {
14 #[cfg_attr(feature = "serde", serde(rename = "uri"))]
15 NamedNode(NamedNode),
16 #[cfg_attr(feature = "serde", serde(rename = "bnode"))]
17 BlankNode(BlankNode),
18}
19
20impl NamedOrBlankNode {
21 #[inline]
22 pub fn is_named_node(&self) -> bool {
23 self.as_ref().is_named_node()
24 }
25
26 #[inline]
27 pub fn is_blank_node(&self) -> bool {
28 self.as_ref().is_blank_node()
29 }
30
31 #[inline]
32 pub fn as_ref(&self) -> NamedOrBlankNodeRef<'_> {
33 match self {
34 Self::NamedNode(node) => NamedOrBlankNodeRef::NamedNode(node.as_ref()),
35 Self::BlankNode(node) => NamedOrBlankNodeRef::BlankNode(node.as_ref()),
36 }
37 }
38}
39
40impl fmt::Display for NamedOrBlankNode {
41 #[inline]
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 self.as_ref().fmt(f)
44 }
45}
46
47impl From<NamedNode> for NamedOrBlankNode {
48 #[inline]
49 fn from(node: NamedNode) -> Self {
50 Self::NamedNode(node)
51 }
52}
53
54impl From<NamedNodeRef<'_>> for NamedOrBlankNode {
55 #[inline]
56 fn from(node: NamedNodeRef<'_>) -> Self {
57 node.into_owned().into()
58 }
59}
60
61impl From<BlankNode> for NamedOrBlankNode {
62 #[inline]
63 fn from(node: BlankNode) -> Self {
64 Self::BlankNode(node)
65 }
66}
67
68impl From<BlankNodeRef<'_>> for NamedOrBlankNode {
69 #[inline]
70 fn from(node: BlankNodeRef<'_>) -> Self {
71 node.into_owned().into()
72 }
73}
74
75#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
77#[cfg_attr(feature = "serde", derive(Serialize))]
78#[cfg_attr(feature = "serde", serde(tag = "type", rename_all = "lowercase"))]
79pub enum NamedOrBlankNodeRef<'a> {
80 #[cfg_attr(feature = "serde", serde(rename = "uri"))]
81 NamedNode(NamedNodeRef<'a>),
82 #[cfg_attr(feature = "serde", serde(rename = "bnode"))]
83 BlankNode(BlankNodeRef<'a>),
84}
85
86impl NamedOrBlankNodeRef<'_> {
87 #[inline]
88 pub fn is_named_node(&self) -> bool {
89 match self {
90 Self::NamedNode(_) => true,
91 Self::BlankNode(_) => false,
92 }
93 }
94
95 #[inline]
96 pub fn is_blank_node(&self) -> bool {
97 match self {
98 Self::NamedNode(_) => false,
99 Self::BlankNode(_) => true,
100 }
101 }
102
103 #[inline]
104 pub fn into_owned(self) -> NamedOrBlankNode {
105 match self {
106 Self::NamedNode(node) => NamedOrBlankNode::NamedNode(node.into_owned()),
107 Self::BlankNode(node) => NamedOrBlankNode::BlankNode(node.into_owned()),
108 }
109 }
110}
111
112impl fmt::Display for NamedOrBlankNodeRef<'_> {
113 #[inline]
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 match self {
116 Self::NamedNode(node) => node.fmt(f),
117 Self::BlankNode(node) => node.fmt(f),
118 }
119 }
120}
121
122impl<'a> From<NamedNodeRef<'a>> for NamedOrBlankNodeRef<'a> {
123 #[inline]
124 fn from(node: NamedNodeRef<'a>) -> Self {
125 Self::NamedNode(node)
126 }
127}
128
129impl<'a> From<&'a NamedNode> for NamedOrBlankNodeRef<'a> {
130 #[inline]
131 fn from(node: &'a NamedNode) -> Self {
132 node.as_ref().into()
133 }
134}
135
136impl<'a> From<BlankNodeRef<'a>> for NamedOrBlankNodeRef<'a> {
137 #[inline]
138 fn from(node: BlankNodeRef<'a>) -> Self {
139 Self::BlankNode(node)
140 }
141}
142
143impl<'a> From<&'a BlankNode> for NamedOrBlankNodeRef<'a> {
144 #[inline]
145 fn from(node: &'a BlankNode) -> Self {
146 node.as_ref().into()
147 }
148}
149
150impl<'a> From<&'a NamedOrBlankNode> for NamedOrBlankNodeRef<'a> {
151 #[inline]
152 fn from(node: &'a NamedOrBlankNode) -> Self {
153 node.as_ref()
154 }
155}
156
157impl<'a> From<NamedOrBlankNodeRef<'a>> for NamedOrBlankNode {
158 #[inline]
159 fn from(node: NamedOrBlankNodeRef<'a>) -> Self {
160 node.into_owned()
161 }
162}
163
164#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
168#[cfg_attr(feature = "serde", serde(tag = "type", rename_all = "lowercase"))]
169#[derive(Eq, PartialEq, Debug, Clone, Hash)]
170pub enum Term {
171 #[cfg_attr(feature = "serde", serde(rename = "uri"))]
172 NamedNode(NamedNode),
173 #[cfg_attr(feature = "serde", serde(rename = "bnode"))]
174 BlankNode(BlankNode),
175 Literal(Literal),
176 #[cfg(feature = "rdf-12")]
177 Triple(Box<Triple>),
178}
179
180impl Term {
181 #[inline]
182 pub fn is_named_node(&self) -> bool {
183 self.as_ref().is_named_node()
184 }
185
186 #[inline]
187 pub fn is_blank_node(&self) -> bool {
188 self.as_ref().is_blank_node()
189 }
190
191 #[inline]
192 pub fn is_literal(&self) -> bool {
193 self.as_ref().is_literal()
194 }
195
196 #[cfg(feature = "rdf-12")]
197 #[inline]
198 pub fn is_triple(&self) -> bool {
199 self.as_ref().is_triple()
200 }
201
202 #[inline]
203 pub fn as_ref(&self) -> TermRef<'_> {
204 match self {
205 Self::NamedNode(node) => TermRef::NamedNode(node.as_ref()),
206 Self::BlankNode(node) => TermRef::BlankNode(node.as_ref()),
207 Self::Literal(literal) => TermRef::Literal(literal.as_ref()),
208 #[cfg(feature = "rdf-12")]
209 Self::Triple(triple) => TermRef::Triple(triple),
210 }
211 }
212}
213
214impl fmt::Display for Term {
215 #[inline]
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 self.as_ref().fmt(f)
218 }
219}
220
221impl From<NamedNode> for Term {
222 #[inline]
223 fn from(node: NamedNode) -> Self {
224 Self::NamedNode(node)
225 }
226}
227
228impl From<NamedNodeRef<'_>> for Term {
229 #[inline]
230 fn from(node: NamedNodeRef<'_>) -> Self {
231 node.into_owned().into()
232 }
233}
234
235impl From<BlankNode> for Term {
236 #[inline]
237 fn from(node: BlankNode) -> Self {
238 Self::BlankNode(node)
239 }
240}
241
242impl From<BlankNodeRef<'_>> for Term {
243 #[inline]
244 fn from(node: BlankNodeRef<'_>) -> Self {
245 node.into_owned().into()
246 }
247}
248
249impl From<Literal> for Term {
250 #[inline]
251 fn from(literal: Literal) -> Self {
252 Self::Literal(literal)
253 }
254}
255
256impl From<LiteralRef<'_>> for Term {
257 #[inline]
258 fn from(literal: LiteralRef<'_>) -> Self {
259 literal.into_owned().into()
260 }
261}
262
263#[cfg(feature = "rdf-12")]
264impl From<Triple> for Term {
265 #[inline]
266 fn from(triple: Triple) -> Self {
267 Self::Triple(Box::new(triple))
268 }
269}
270
271#[cfg(feature = "rdf-12")]
272impl From<Box<Triple>> for Term {
273 #[inline]
274 fn from(node: Box<Triple>) -> Self {
275 Self::Triple(node)
276 }
277}
278
279#[cfg(feature = "rdf-12")]
280impl From<TripleRef<'_>> for Term {
281 #[inline]
282 fn from(triple: TripleRef<'_>) -> Self {
283 triple.into_owned().into()
284 }
285}
286
287impl From<NamedOrBlankNode> for Term {
288 #[inline]
289 fn from(node: NamedOrBlankNode) -> Self {
290 match node {
291 NamedOrBlankNode::NamedNode(node) => node.into(),
292 NamedOrBlankNode::BlankNode(node) => node.into(),
293 }
294 }
295}
296
297impl From<NamedOrBlankNodeRef<'_>> for Term {
298 #[inline]
299 fn from(node: NamedOrBlankNodeRef<'_>) -> Self {
300 node.into_owned().into()
301 }
302}
303
304impl TryFrom<Term> for NamedNode {
305 type Error = TryFromTermError;
306
307 #[inline]
308 fn try_from(term: Term) -> Result<Self, Self::Error> {
309 if let Term::NamedNode(node) = term {
310 Ok(node)
311 } else {
312 Err(TryFromTermError {
313 term,
314 target: "NamedNode",
315 })
316 }
317 }
318}
319
320impl TryFrom<Term> for BlankNode {
321 type Error = TryFromTermError;
322
323 #[inline]
324 fn try_from(term: Term) -> Result<Self, Self::Error> {
325 if let Term::BlankNode(node) = term {
326 Ok(node)
327 } else {
328 Err(TryFromTermError {
329 term,
330 target: "BlankNode",
331 })
332 }
333 }
334}
335
336impl TryFrom<Term> for Literal {
337 type Error = TryFromTermError;
338
339 #[inline]
340 fn try_from(term: Term) -> Result<Self, Self::Error> {
341 if let Term::Literal(node) = term {
342 Ok(node)
343 } else {
344 Err(TryFromTermError {
345 term,
346 target: "Literal",
347 })
348 }
349 }
350}
351
352impl TryFrom<Term> for NamedOrBlankNode {
353 type Error = TryFromTermError;
354
355 #[inline]
356 fn try_from(term: Term) -> Result<Self, Self::Error> {
357 match term {
358 Term::NamedNode(term) => Ok(Self::NamedNode(term)),
359 Term::BlankNode(term) => Ok(Self::BlankNode(term)),
360 Term::Literal(_) => Err(TryFromTermError {
361 term,
362 target: "NamedOrBlankNode",
363 }),
364 #[cfg(feature = "rdf-12")]
365 Term::Triple(_) => Err(TryFromTermError {
366 term,
367 target: "Triple",
368 }),
369 }
370 }
371}
372
373#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
377#[cfg_attr(feature = "serde", derive(Serialize))]
378#[cfg_attr(feature = "serde", serde(tag = "type", rename_all = "lowercase"))]
379pub enum TermRef<'a> {
380 #[cfg_attr(feature = "serde", serde(rename = "uri"))]
381 NamedNode(NamedNodeRef<'a>),
382 #[cfg_attr(feature = "serde", serde(rename = "bnode"))]
383 BlankNode(BlankNodeRef<'a>),
384 Literal(LiteralRef<'a>),
385 #[cfg(feature = "rdf-12")]
386 Triple(&'a Triple),
387}
388
389impl TermRef<'_> {
390 #[inline]
391 pub fn is_named_node(&self) -> bool {
392 matches!(self, Self::NamedNode(_))
393 }
394
395 #[inline]
396 pub fn is_blank_node(&self) -> bool {
397 matches!(self, Self::BlankNode(_))
398 }
399
400 #[inline]
401 pub fn is_literal(&self) -> bool {
402 matches!(self, Self::Literal(_))
403 }
404
405 #[cfg(feature = "rdf-12")]
406 #[inline]
407 pub fn is_triple(&self) -> bool {
408 matches!(self, Self::Triple(_))
409 }
410
411 #[inline]
412 pub fn into_owned(self) -> Term {
413 match self {
414 Self::NamedNode(node) => Term::NamedNode(node.into_owned()),
415 Self::BlankNode(node) => Term::BlankNode(node.into_owned()),
416 Self::Literal(literal) => Term::Literal(literal.into_owned()),
417 #[cfg(feature = "rdf-12")]
418 Self::Triple(triple) => Term::Triple(Box::new(triple.clone())),
419 }
420 }
421}
422
423impl fmt::Display for TermRef<'_> {
424 #[inline]
425 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
426 match self {
427 Self::NamedNode(node) => node.fmt(f),
428 Self::BlankNode(node) => node.fmt(f),
429 Self::Literal(literal) => literal.fmt(f),
430 #[cfg(feature = "rdf-12")]
431 Self::Triple(triple) => {
432 write!(f, "<<( {triple} )>>")
433 }
434 }
435 }
436}
437
438impl<'a> From<NamedNodeRef<'a>> for TermRef<'a> {
439 #[inline]
440 fn from(node: NamedNodeRef<'a>) -> Self {
441 Self::NamedNode(node)
442 }
443}
444
445impl<'a> From<&'a NamedNode> for TermRef<'a> {
446 #[inline]
447 fn from(node: &'a NamedNode) -> Self {
448 node.as_ref().into()
449 }
450}
451
452impl<'a> From<BlankNodeRef<'a>> for TermRef<'a> {
453 #[inline]
454 fn from(node: BlankNodeRef<'a>) -> Self {
455 Self::BlankNode(node)
456 }
457}
458
459impl<'a> From<&'a BlankNode> for TermRef<'a> {
460 #[inline]
461 fn from(node: &'a BlankNode) -> Self {
462 node.as_ref().into()
463 }
464}
465
466impl<'a> From<LiteralRef<'a>> for TermRef<'a> {
467 #[inline]
468 fn from(literal: LiteralRef<'a>) -> Self {
469 Self::Literal(literal)
470 }
471}
472
473impl<'a> From<&'a Literal> for TermRef<'a> {
474 #[inline]
475 fn from(literal: &'a Literal) -> Self {
476 literal.as_ref().into()
477 }
478}
479
480#[cfg(feature = "rdf-12")]
481impl<'a> From<&'a Triple> for TermRef<'a> {
482 #[inline]
483 fn from(node: &'a Triple) -> Self {
484 Self::Triple(node)
485 }
486}
487
488impl<'a> From<NamedOrBlankNodeRef<'a>> for TermRef<'a> {
489 #[inline]
490 fn from(node: NamedOrBlankNodeRef<'a>) -> Self {
491 match node {
492 NamedOrBlankNodeRef::NamedNode(node) => node.into(),
493 NamedOrBlankNodeRef::BlankNode(node) => node.into(),
494 }
495 }
496}
497
498impl<'a> From<&'a NamedOrBlankNode> for TermRef<'a> {
499 #[inline]
500 fn from(node: &'a NamedOrBlankNode) -> Self {
501 node.as_ref().into()
502 }
503}
504
505impl<'a> From<&'a Term> for TermRef<'a> {
506 #[inline]
507 fn from(node: &'a Term) -> Self {
508 node.as_ref()
509 }
510}
511
512impl<'a> From<TermRef<'a>> for Term {
513 #[inline]
514 fn from(node: TermRef<'a>) -> Self {
515 node.into_owned()
516 }
517}
518
519#[derive(Eq, PartialEq, Debug, Clone, Hash)]
537#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
538pub struct Triple {
539 pub subject: NamedOrBlankNode,
541
542 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_predicate"))]
544 pub predicate: NamedNode,
545
546 pub object: Term,
548}
549
550impl Triple {
551 #[inline]
553 pub fn new(
554 subject: impl Into<NamedOrBlankNode>,
555 predicate: impl Into<NamedNode>,
556 object: impl Into<Term>,
557 ) -> Self {
558 Self {
559 subject: subject.into(),
560 predicate: predicate.into(),
561 object: object.into(),
562 }
563 }
564
565 #[inline]
569 pub fn from_terms(
570 subject: impl Into<Term>,
571 predicate: impl Into<Term>,
572 object: impl Into<Term>,
573 ) -> Result<Self, TryFromTermError> {
574 Ok(Self {
575 subject: subject.into().try_into()?,
576 predicate: predicate.into().try_into()?,
577 object: object.into(),
578 })
579 }
580
581 #[inline]
583 pub fn in_graph(self, graph_name: impl Into<GraphName>) -> Quad {
584 Quad {
585 subject: self.subject,
586 predicate: self.predicate,
587 object: self.object,
588 graph_name: graph_name.into(),
589 }
590 }
591
592 #[inline]
593 pub fn as_ref(&self) -> TripleRef<'_> {
594 TripleRef {
595 subject: self.subject.as_ref(),
596 predicate: self.predicate.as_ref(),
597 object: self.object.as_ref(),
598 }
599 }
600}
601
602impl fmt::Display for Triple {
603 #[inline]
604 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
605 self.as_ref().fmt(f)
606 }
607}
608
609#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
628pub struct TripleRef<'a> {
629 pub subject: NamedOrBlankNodeRef<'a>,
631
632 pub predicate: NamedNodeRef<'a>,
634
635 pub object: TermRef<'a>,
637}
638
639impl<'a> TripleRef<'a> {
640 #[inline]
642 pub fn new(
643 subject: impl Into<NamedOrBlankNodeRef<'a>>,
644 predicate: impl Into<NamedNodeRef<'a>>,
645 object: impl Into<TermRef<'a>>,
646 ) -> Self {
647 Self {
648 subject: subject.into(),
649 predicate: predicate.into(),
650 object: object.into(),
651 }
652 }
653
654 #[inline]
656 pub fn in_graph(self, graph_name: impl Into<GraphNameRef<'a>>) -> QuadRef<'a> {
657 QuadRef {
658 subject: self.subject,
659 predicate: self.predicate,
660 object: self.object,
661 graph_name: graph_name.into(),
662 }
663 }
664
665 #[inline]
666 pub fn into_owned(self) -> Triple {
667 Triple {
668 subject: self.subject.into_owned(),
669 predicate: self.predicate.into_owned(),
670 object: self.object.into_owned(),
671 }
672 }
673}
674
675impl fmt::Display for TripleRef<'_> {
676 #[inline]
677 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
678 write!(f, "{} {} {}", self.subject, self.predicate, self.object)
679 }
680}
681
682impl<'a> From<&'a Triple> for TripleRef<'a> {
683 #[inline]
684 fn from(triple: &'a Triple) -> Self {
685 triple.as_ref()
686 }
687}
688
689impl<'a> From<TripleRef<'a>> for Triple {
690 #[inline]
691 fn from(triple: TripleRef<'a>) -> Self {
692 triple.into_owned()
693 }
694}
695
696#[derive(Eq, PartialEq, Debug, Clone, Hash, Default)]
700#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
701#[cfg_attr(feature = "serde", serde(tag = "type", rename_all = "lowercase"))]
702pub enum GraphName {
703 #[cfg_attr(feature = "serde", serde(rename = "uri"))]
704 NamedNode(NamedNode),
705 #[cfg_attr(feature = "serde", serde(rename = "bnode"))]
706 BlankNode(BlankNode),
707 #[default]
708 #[cfg_attr(feature = "serde", serde(rename = "default"))]
709 DefaultGraph,
710}
711
712impl GraphName {
713 #[inline]
714 pub fn is_named_node(&self) -> bool {
715 self.as_ref().is_named_node()
716 }
717
718 #[inline]
719 pub fn is_blank_node(&self) -> bool {
720 self.as_ref().is_blank_node()
721 }
722
723 #[inline]
724 pub fn is_default_graph(&self) -> bool {
725 self.as_ref().is_default_graph()
726 }
727
728 #[inline]
729 pub fn as_ref(&self) -> GraphNameRef<'_> {
730 match self {
731 Self::NamedNode(node) => GraphNameRef::NamedNode(node.as_ref()),
732 Self::BlankNode(node) => GraphNameRef::BlankNode(node.as_ref()),
733 Self::DefaultGraph => GraphNameRef::DefaultGraph,
734 }
735 }
736}
737
738impl fmt::Display for GraphName {
739 #[inline]
740 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
741 self.as_ref().fmt(f)
742 }
743}
744
745impl From<NamedNode> for GraphName {
746 #[inline]
747 fn from(node: NamedNode) -> Self {
748 Self::NamedNode(node)
749 }
750}
751
752impl From<NamedNodeRef<'_>> for GraphName {
753 #[inline]
754 fn from(node: NamedNodeRef<'_>) -> Self {
755 node.into_owned().into()
756 }
757}
758
759impl From<BlankNode> for GraphName {
760 #[inline]
761 fn from(node: BlankNode) -> Self {
762 Self::BlankNode(node)
763 }
764}
765
766impl From<BlankNodeRef<'_>> for GraphName {
767 #[inline]
768 fn from(node: BlankNodeRef<'_>) -> Self {
769 node.into_owned().into()
770 }
771}
772
773impl From<NamedOrBlankNode> for GraphName {
774 #[inline]
775 fn from(node: NamedOrBlankNode) -> Self {
776 match node {
777 NamedOrBlankNode::NamedNode(node) => node.into(),
778 NamedOrBlankNode::BlankNode(node) => node.into(),
779 }
780 }
781}
782
783impl From<NamedOrBlankNodeRef<'_>> for GraphName {
784 #[inline]
785 fn from(node: NamedOrBlankNodeRef<'_>) -> Self {
786 node.into_owned().into()
787 }
788}
789
790#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash, Default)]
794#[cfg_attr(feature = "serde", derive(Serialize))]
795#[cfg_attr(feature = "serde", serde(tag = "type"))]
796pub enum GraphNameRef<'a> {
797 #[cfg_attr(feature = "serde", serde(rename = "uri"))]
798 NamedNode(NamedNodeRef<'a>),
799 #[cfg_attr(feature = "serde", serde(rename = "bnode"))]
800 BlankNode(BlankNodeRef<'a>),
801 #[default]
802 #[cfg_attr(feature = "serde", serde(rename = "default"))]
803 DefaultGraph,
804}
805
806impl GraphNameRef<'_> {
807 #[inline]
808 pub fn is_named_node(&self) -> bool {
809 matches!(self, Self::NamedNode(_))
810 }
811
812 #[inline]
813 pub fn is_blank_node(&self) -> bool {
814 matches!(self, Self::BlankNode(_))
815 }
816
817 #[inline]
818 pub fn is_default_graph(&self) -> bool {
819 matches!(self, Self::DefaultGraph)
820 }
821
822 #[inline]
823 pub fn into_owned(self) -> GraphName {
824 match self {
825 Self::NamedNode(node) => GraphName::NamedNode(node.into_owned()),
826 Self::BlankNode(node) => GraphName::BlankNode(node.into_owned()),
827 Self::DefaultGraph => GraphName::DefaultGraph,
828 }
829 }
830}
831
832impl fmt::Display for GraphNameRef<'_> {
833 #[inline]
834 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
835 match self {
836 Self::NamedNode(node) => node.fmt(f),
837 Self::BlankNode(node) => node.fmt(f),
838 Self::DefaultGraph => f.write_str("DEFAULT"),
839 }
840 }
841}
842
843impl<'a> From<NamedNodeRef<'a>> for GraphNameRef<'a> {
844 #[inline]
845 fn from(node: NamedNodeRef<'a>) -> Self {
846 Self::NamedNode(node)
847 }
848}
849
850impl<'a> From<&'a NamedNode> for GraphNameRef<'a> {
851 #[inline]
852 fn from(node: &'a NamedNode) -> Self {
853 node.as_ref().into()
854 }
855}
856
857impl<'a> From<BlankNodeRef<'a>> for GraphNameRef<'a> {
858 #[inline]
859 fn from(node: BlankNodeRef<'a>) -> Self {
860 Self::BlankNode(node)
861 }
862}
863
864impl<'a> From<&'a BlankNode> for GraphNameRef<'a> {
865 #[inline]
866 fn from(node: &'a BlankNode) -> Self {
867 node.as_ref().into()
868 }
869}
870
871impl<'a> From<NamedOrBlankNodeRef<'a>> for GraphNameRef<'a> {
872 #[inline]
873 fn from(node: NamedOrBlankNodeRef<'a>) -> Self {
874 match node {
875 NamedOrBlankNodeRef::NamedNode(node) => node.into(),
876 NamedOrBlankNodeRef::BlankNode(node) => node.into(),
877 }
878 }
879}
880
881impl<'a> From<&'a NamedOrBlankNode> for GraphNameRef<'a> {
882 #[inline]
883 fn from(node: &'a NamedOrBlankNode) -> Self {
884 node.as_ref().into()
885 }
886}
887
888impl<'a> From<&'a GraphName> for GraphNameRef<'a> {
889 #[inline]
890 fn from(node: &'a GraphName) -> Self {
891 node.as_ref()
892 }
893}
894
895impl<'a> From<GraphNameRef<'a>> for GraphName {
896 #[inline]
897 fn from(node: GraphNameRef<'a>) -> Self {
898 node.into_owned()
899 }
900}
901
902#[derive(Eq, PartialEq, Debug, Clone, Hash)]
920#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
921pub struct Quad {
922 pub subject: NamedOrBlankNode,
924
925 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_predicate"))]
927 pub predicate: NamedNode,
928
929 pub object: Term,
931
932 #[cfg_attr(feature = "serde", serde(rename = "graph"))]
934 pub graph_name: GraphName,
935}
936
937impl Quad {
938 #[inline]
940 pub fn new(
941 subject: impl Into<NamedOrBlankNode>,
942 predicate: impl Into<NamedNode>,
943 object: impl Into<Term>,
944 graph_name: impl Into<GraphName>,
945 ) -> Self {
946 Self {
947 subject: subject.into(),
948 predicate: predicate.into(),
949 object: object.into(),
950 graph_name: graph_name.into(),
951 }
952 }
953
954 #[inline]
955 pub fn as_ref(&self) -> QuadRef<'_> {
956 QuadRef {
957 subject: self.subject.as_ref(),
958 predicate: self.predicate.as_ref(),
959 object: self.object.as_ref(),
960 graph_name: self.graph_name.as_ref(),
961 }
962 }
963}
964
965impl fmt::Display for Quad {
966 #[inline]
967 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
968 self.as_ref().fmt(f)
969 }
970}
971
972impl From<Quad> for Triple {
973 #[inline]
974 fn from(quad: Quad) -> Self {
975 Self {
976 subject: quad.subject,
977 predicate: quad.predicate,
978 object: quad.object,
979 }
980 }
981}
982
983#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
1001pub struct QuadRef<'a> {
1002 pub subject: NamedOrBlankNodeRef<'a>,
1004
1005 pub predicate: NamedNodeRef<'a>,
1007
1008 pub object: TermRef<'a>,
1010
1011 pub graph_name: GraphNameRef<'a>,
1013}
1014
1015impl<'a> QuadRef<'a> {
1016 #[inline]
1018 pub fn new(
1019 subject: impl Into<NamedOrBlankNodeRef<'a>>,
1020 predicate: impl Into<NamedNodeRef<'a>>,
1021 object: impl Into<TermRef<'a>>,
1022 graph_name: impl Into<GraphNameRef<'a>>,
1023 ) -> Self {
1024 Self {
1025 subject: subject.into(),
1026 predicate: predicate.into(),
1027 object: object.into(),
1028 graph_name: graph_name.into(),
1029 }
1030 }
1031
1032 #[inline]
1033 pub fn into_owned(self) -> Quad {
1034 Quad {
1035 subject: self.subject.into_owned(),
1036 predicate: self.predicate.into_owned(),
1037 object: self.object.into_owned(),
1038 graph_name: self.graph_name.into_owned(),
1039 }
1040 }
1041}
1042
1043impl fmt::Display for QuadRef<'_> {
1044 #[inline]
1045 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1046 if self.graph_name.is_default_graph() {
1047 write!(f, "{} {} {}", self.subject, self.predicate, self.object)
1048 } else {
1049 write!(
1050 f,
1051 "{} {} {} {}",
1052 self.subject, self.predicate, self.object, self.graph_name
1053 )
1054 }
1055 }
1056}
1057
1058impl<'a> From<QuadRef<'a>> for TripleRef<'a> {
1059 #[inline]
1060 fn from(quad: QuadRef<'a>) -> Self {
1061 Self {
1062 subject: quad.subject,
1063 predicate: quad.predicate,
1064 object: quad.object,
1065 }
1066 }
1067}
1068
1069impl<'a> From<&'a Quad> for QuadRef<'a> {
1070 #[inline]
1071 fn from(quad: &'a Quad) -> Self {
1072 quad.as_ref()
1073 }
1074}
1075
1076impl<'a> From<QuadRef<'a>> for Quad {
1077 #[inline]
1078 fn from(quad: QuadRef<'a>) -> Self {
1079 quad.into_owned()
1080 }
1081}
1082
1083#[derive(Debug, Clone, thiserror::Error)]
1085#[error("{term} can not be converted to a {target}")]
1086pub struct TryFromTermError {
1087 term: Term,
1088 target: &'static str,
1089}
1090
1091impl TryFromTermError {
1092 #[inline]
1094 pub fn into_term(self) -> Term {
1095 self.term
1096 }
1097}
1098#[cfg(feature = "serde")]
1099fn serialize_predicate<S>(node: &NamedNode, serializer: S) -> Result<S::Ok, S::Error>
1100where
1101 S: Serializer,
1102{
1103 #[derive(Serialize)]
1104 #[serde(rename = "uri", tag = "type")]
1105 struct Value<'a> {
1106 value: &'a str,
1107 }
1108 Value {
1109 value: node.as_str(),
1110 }
1111 .serialize(serializer)
1112}
1113
1114#[cfg(test)]
1115#[expect(clippy::panic_in_result_fn)]
1116mod tests {
1117 use super::*;
1118 #[cfg(feature = "serde")]
1119 use serde::de::DeserializeOwned;
1120
1121 #[test]
1122 fn triple_from_terms() -> Result<(), TryFromTermError> {
1123 assert_eq!(
1124 Triple::from_terms(
1125 NamedNode::new_unchecked("http://example.com/s"),
1126 NamedNode::new_unchecked("http://example.com/p"),
1127 NamedNode::new_unchecked("http://example.com/o"),
1128 )?,
1129 Triple::new(
1130 NamedNode::new_unchecked("http://example.com/s"),
1131 NamedNode::new_unchecked("http://example.com/p"),
1132 NamedNode::new_unchecked("http://example.com/o"),
1133 )
1134 );
1135 assert_eq!(
1136 Triple::from_terms(
1137 Literal::new_simple_literal("foo"),
1138 NamedNode::new_unchecked("http://example.com/p"),
1139 NamedNode::new_unchecked("http://example.com/o"),
1140 )
1141 .unwrap_err()
1142 .into_term(),
1143 Term::from(Literal::new_simple_literal("foo"))
1144 );
1145 assert_eq!(
1146 Triple::from_terms(
1147 NamedNode::new_unchecked("http://example.com/s"),
1148 Literal::new_simple_literal("foo"),
1149 NamedNode::new_unchecked("http://example.com/o"),
1150 )
1151 .unwrap_err()
1152 .into_term(),
1153 Term::from(Literal::new_simple_literal("foo"))
1154 );
1155 Ok(())
1156 }
1157
1158 #[test]
1159 #[cfg(feature = "serde")]
1160 fn serde() -> Result<(), serde_json::Error> {
1161 let triple = Triple::new(
1162 NamedNode::new_unchecked("http://example.com/s"),
1163 NamedNode::new_unchecked("http://example.com/p"),
1164 NamedNode::new_unchecked("http://example.com/o"),
1165 );
1166 let jsn = serde_json::to_string(&triple)?;
1167 assert_eq!(
1168 jsn,
1169 r#"{"subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"uri","value":"http://example.com/o"}}"#
1170 );
1171 let deserialized: Triple = serde_json::from_str(&jsn)?;
1172 assert_eq!(deserialized, triple);
1173
1174 let triple = Triple::new(
1176 BlankNode::new_unchecked("s"),
1177 NamedNode::new_unchecked("http://example.com/p"),
1178 Literal::new_simple_literal("foo"),
1179 );
1180 let jsn = serde_json::to_string(&triple)?;
1181 assert_eq!(
1182 jsn,
1183 r#"{"subject":{"type":"bnode","value":"s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"literal","value":"foo"}}"#
1184 );
1185 let deserialized: Triple = serde_json::from_str(&jsn)?;
1186 assert_eq!(deserialized, triple);
1187
1188 let triple = Triple::new(
1189 NamedNode::new_unchecked("http://example.com/s"),
1190 NamedNode::new_unchecked("http://example.com/p"),
1191 BlankNode::new_unchecked("foo"),
1192 );
1193
1194 let jsn = serde_json::to_string(&triple)?;
1195 assert_eq!(
1196 jsn,
1197 r#"{"subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"bnode","value":"foo"}}"#
1198 );
1199 let deserialized: Triple = serde_json::from_str(&jsn)?;
1200 assert_eq!(deserialized, triple);
1201
1202 Ok(())
1203 }
1204
1205 #[test]
1206 #[cfg(feature = "serde")]
1207 fn serde_from_reader() -> Result<(), serde_json::Error> {
1208 let triple = Triple::new(
1209 NamedNode::new_unchecked("http://example.com/s"),
1210 NamedNode::new_unchecked("http://example.com/p"),
1211 NamedNode::new_unchecked("http://example.com/o"),
1212 );
1213 let jsn = serde_json::to_string(&triple)?;
1214 let deserialized: Triple = serde_json::from_reader(jsn.as_bytes())?;
1215 assert_eq!(deserialized, triple);
1216
1217 let triple = Triple::new(
1219 NamedNode::new_unchecked("http://example.com/s"),
1220 NamedNode::new_unchecked("http://example.com/p"),
1221 Literal::new_simple_literal("foo"),
1222 );
1223 let jsn = serde_json::to_string(&triple)?;
1224 let deserialized: Triple = serde_json::from_reader(jsn.as_bytes())?;
1225 assert_eq!(deserialized, triple);
1226
1227 let triple = Triple::new(
1228 NamedNode::new_unchecked("http://example.com/s"),
1229 NamedNode::new_unchecked("http://example.com/p"),
1230 BlankNode::new_unchecked("foo"),
1231 );
1232
1233 let jsn = serde_json::to_string(&triple)?;
1234 let deserialized: Triple = serde_json::from_reader(jsn.as_bytes())?;
1235 assert_eq!(deserialized, triple);
1236
1237 Ok(())
1238 }
1239
1240 #[test]
1241 #[cfg(feature = "serde")]
1242 #[cfg(feature = "rdf-12")]
1243 fn serde_star() -> Result<(), serde_json::Error> {
1244 let triple = Triple::new(
1245 NamedNode::new_unchecked("http://example.com/s"),
1246 NamedNode::new_unchecked("http://example.com/p"),
1247 Term::Triple(Box::new(Triple::new(
1248 NamedNode::new_unchecked("http://example.com/s"),
1249 NamedNode::new_unchecked("http://example.com/p"),
1250 NamedNode::new_unchecked("http://example.com/o"),
1251 ))),
1252 );
1253
1254 let jsn = serde_json::to_string(&triple)?;
1255 assert_eq!(
1256 jsn,
1257 r#"{"subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"triple","subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"uri","value":"http://example.com/o"}}}"#
1258 );
1259 let deserialized: Triple = serde_json::from_str(&jsn)?;
1260 assert_eq!(deserialized, triple);
1261
1262 Ok(())
1263 }
1264
1265 #[test]
1266 #[cfg(feature = "serde")]
1267 fn serde_quad() -> Result<(), serde_json::Error> {
1268 let quad = Quad::new(
1269 NamedNode::new_unchecked("http://example.com/s"),
1270 NamedNode::new_unchecked("http://example.com/p"),
1271 NamedNode::new_unchecked("http://example.com/o"),
1272 NamedNode::new_unchecked("http://example.com/g"),
1273 );
1274 let jsn = serde_json::to_string(&quad)?;
1275 assert_eq!(
1276 jsn,
1277 r#"{"subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"uri","value":"http://example.com/o"},"graph":{"type":"uri","value":"http://example.com/g"}}"#
1278 );
1279 let deserialized: Quad = serde_json::from_str(&jsn)?;
1280 assert_eq!(deserialized, quad);
1281
1282 let quad = Quad::new(
1284 NamedNode::new_unchecked("http://example.com/s"),
1285 NamedNode::new_unchecked("http://example.com/p"),
1286 Literal::new_simple_literal("foo"),
1287 NamedNode::new_unchecked("http://example.com/g"),
1288 );
1289 let jsn = serde_json::to_string(&quad)?;
1290 assert_eq!(
1291 jsn,
1292 r#"{"subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"literal","value":"foo"},"graph":{"type":"uri","value":"http://example.com/g"}}"#
1293 );
1294 let deserialized: Quad = serde_json::from_str(&jsn)?;
1295 assert_eq!(deserialized, quad);
1296
1297 let quad = Quad::new(
1298 NamedNode::new_unchecked("http://example.com/s"),
1299 NamedNode::new_unchecked("http://example.com/p"),
1300 BlankNode::new_unchecked("foo"),
1301 NamedNode::new_unchecked("http://example.com/g"),
1302 );
1303
1304 let jsn = serde_json::to_string(&quad)?;
1305 assert_eq!(
1306 jsn,
1307 r#"{"subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"bnode","value":"foo"},"graph":{"type":"uri","value":"http://example.com/g"}}"#
1308 );
1309 let deserialized: Quad = serde_json::from_str(&jsn)?;
1310 assert_eq!(deserialized, quad);
1311
1312 let quad = Quad::new(
1314 NamedNode::new_unchecked("http://example.com/s"),
1315 NamedNode::new_unchecked("http://example.com/p"),
1316 NamedNode::new_unchecked("http://example.com/o"),
1317 BlankNode::new_unchecked("foo"),
1318 );
1319 let jsn = serde_json::to_string(&quad)?;
1320 assert_eq!(
1321 jsn,
1322 r#"{"subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"uri","value":"http://example.com/o"},"graph":{"type":"bnode","value":"foo"}}"#
1323 );
1324 let deserialized: Quad = serde_json::from_str(&jsn)?;
1325 assert_eq!(deserialized, quad);
1326
1327 let quad = Quad::new(
1329 NamedNode::new_unchecked("http://example.com/s"),
1330 NamedNode::new_unchecked("http://example.com/p"),
1331 NamedNode::new_unchecked("http://example.com/o"),
1332 GraphName::DefaultGraph,
1333 );
1334 let jsn = serde_json::to_string(&quad)?;
1335 assert_eq!(
1336 jsn,
1337 r#"{"subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"uri","value":"http://example.com/o"},"graph":{"type":"default"}}"#
1338 );
1339 let deserialized: Quad = serde_json::from_str(&jsn)?;
1340 assert_eq!(deserialized, quad);
1341
1342 Ok(())
1343 }
1344
1345 #[test]
1346 #[cfg(feature = "serde")]
1347 fn serde_quad_from_reader() -> Result<(), serde_json::Error> {
1348 let quad = Quad::new(
1349 NamedNode::new_unchecked("http://example.com/s"),
1350 NamedNode::new_unchecked("http://example.com/p"),
1351 NamedNode::new_unchecked("http://example.com/o"),
1352 NamedNode::new_unchecked("http://example.com/g"),
1353 );
1354 let jsn = serde_json::to_string(&quad)?;
1355 let deserialized: Quad = serde_json::from_reader(jsn.as_bytes())?;
1356 assert_eq!(deserialized, quad);
1357
1358 let quad = Quad::new(
1360 NamedNode::new_unchecked("http://example.com/s"),
1361 NamedNode::new_unchecked("http://example.com/p"),
1362 Literal::new_simple_literal("foo"),
1363 NamedNode::new_unchecked("http://example.com/g"),
1364 );
1365 let jsn = serde_json::to_string(&quad)?;
1366 let deserialized: Quad = serde_json::from_reader(jsn.as_bytes())?;
1367 assert_eq!(deserialized, quad);
1368
1369 let quad = Quad::new(
1370 NamedNode::new_unchecked("http://example.com/s"),
1371 NamedNode::new_unchecked("http://example.com/p"),
1372 BlankNode::new_unchecked("foo"),
1373 NamedNode::new_unchecked("http://example.com/g"),
1374 );
1375
1376 let jsn = serde_json::to_string(&quad)?;
1377 let deserialized: Quad = serde_json::from_reader(jsn.as_bytes())?;
1378 assert_eq!(deserialized, quad);
1379
1380 let quad = Quad::new(
1382 NamedNode::new_unchecked("http://example.com/s"),
1383 NamedNode::new_unchecked("http://example.com/p"),
1384 NamedNode::new_unchecked("http://example.com/o"),
1385 BlankNode::new_unchecked("foo"),
1386 );
1387 let jsn = serde_json::to_string(&quad)?;
1388 let deserialized: Quad = serde_json::from_reader(jsn.as_bytes())?;
1389 assert_eq!(deserialized, quad);
1390
1391 let quad = Quad::new(
1393 NamedNode::new_unchecked("http://example.com/s"),
1394 NamedNode::new_unchecked("http://example.com/p"),
1395 NamedNode::new_unchecked("http://example.com/o"),
1396 GraphName::DefaultGraph,
1397 );
1398 let jsn = serde_json::to_string(&quad)?;
1399 let deserialized: Quad = serde_json::from_reader(jsn.as_bytes())?;
1400 assert_eq!(deserialized, quad);
1401
1402 Ok(())
1403 }
1404
1405 #[test]
1406 #[cfg(feature = "serde")]
1407 #[cfg(feature = "rdf-12")]
1408 fn serde_quad_star() -> Result<(), serde_json::Error> {
1409 let quad = Quad::new(
1410 NamedNode::new_unchecked("http://example.com/s"),
1411 NamedNode::new_unchecked("http://example.com/p"),
1412 Term::Triple(Box::new(Triple::new(
1413 NamedNode::new_unchecked("http://example.com/s"),
1414 NamedNode::new_unchecked("http://example.com/p"),
1415 NamedNode::new_unchecked("http://example.com/o"),
1416 ))),
1417 NamedNode::new_unchecked("http://example.com/g"),
1418 );
1419
1420 let jsn = serde_json::to_string(&quad)?;
1421 assert_eq!(
1422 jsn,
1423 r#"{"subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"triple","subject":{"type":"uri","value":"http://example.com/s"},"predicate":{"type":"uri","value":"http://example.com/p"},"object":{"type":"uri","value":"http://example.com/o"}},"graph":{"type":"uri","value":"http://example.com/g"}}"#
1424 );
1425 let deserialized: Quad = serde_json::from_str(&jsn)?;
1426 assert_eq!(deserialized, quad);
1427
1428 Ok(())
1429 }
1430
1431 #[test]
1432 #[cfg(feature = "serde")]
1433 fn test_deserialize_owned() {
1434 fn assert_deserialize_owned<T: DeserializeOwned>() {}
1435
1436 assert_deserialize_owned::<Term>();
1438 assert_deserialize_owned::<Triple>();
1439 assert_deserialize_owned::<Quad>();
1440 }
1441}