Skip to main content

rdf_syntax/term/ground/
ref.rs

1use core::fmt;
2use std::borrow::Cow;
3use std::cmp::Ordering;
4
5use into_owned_trait::IntoOwned;
6use iref::Iri;
7
8use crate::{LiteralRef, RdfDisplay};
9
10use super::{CowGroundTerm, GroundTerm};
11
12/// Ground term reference.
13#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub enum GroundTermRef<'a> {
15	/// IRI.
16	Iri(&'a Iri),
17
18	/// Lexical value.
19	Literal(LiteralRef<'a>),
20}
21
22impl<'a> GroundTermRef<'a> {
23	/// Checks if this is an IRI.
24	pub fn is_iri(&self) -> bool {
25		matches!(self, Self::Iri(_))
26	}
27
28	/// Checks if this is a literal.
29	pub fn is_literal(&self) -> bool {
30		matches!(self, Self::Literal(_))
31	}
32
33	/// Returns this ground term as an IRI, if it is one.
34	pub fn as_iri(&self) -> Option<&'a Iri> {
35		match self {
36			Self::Iri(iri) => Some(iri),
37			_ => None,
38		}
39	}
40
41	/// Returns this ground term as a literal, if it is one.
42	pub fn as_literal(&self) -> Option<LiteralRef<'a>> {
43		match self {
44			Self::Literal(l) => Some(*l),
45			_ => None,
46		}
47	}
48
49	/// Turns this ground term reference into a copy-on-write ground term.
50	pub fn into_cow(self) -> CowGroundTerm<'a> {
51		match self {
52			Self::Iri(iri) => CowGroundTerm::Iri(Cow::Borrowed(iri)),
53			Self::Literal(l) => CowGroundTerm::Literal(l.into()),
54		}
55	}
56}
57
58impl GroundTermRef<'_> {
59	/// Clones the referenced ground term.
60	pub fn to_owned(&self) -> GroundTerm {
61		(*self).into_owned()
62	}
63}
64
65impl IntoOwned for GroundTermRef<'_> {
66	type Owned = GroundTerm;
67
68	fn into_owned(self) -> GroundTerm {
69		match self {
70			Self::Iri(iri) => GroundTerm::Iri(iri.to_owned()),
71			Self::Literal(l) => GroundTerm::Literal(l.into_owned()),
72		}
73	}
74}
75
76impl equivalent::Equivalent<GroundTerm> for GroundTermRef<'_> {
77	fn equivalent(&self, key: &GroundTerm) -> bool {
78		self == key
79	}
80}
81
82impl equivalent::Comparable<GroundTerm> for GroundTermRef<'_> {
83	fn compare(&self, key: &GroundTerm) -> std::cmp::Ordering {
84		self.partial_cmp(key).unwrap()
85	}
86}
87
88impl PartialEq<GroundTerm> for GroundTermRef<'_> {
89	fn eq(&self, other: &GroundTerm) -> bool {
90		match (self, other) {
91			(Self::Iri(a), GroundTerm::Iri(b)) => *a == b,
92			(Self::Literal(a), GroundTerm::Literal(b)) => a == b,
93			_ => false,
94		}
95	}
96}
97
98impl PartialOrd<GroundTerm> for GroundTermRef<'_> {
99	fn partial_cmp(&self, other: &GroundTerm) -> Option<Ordering> {
100		match (self, other) {
101			(Self::Iri(a), GroundTerm::Iri(b)) => (*a).partial_cmp(b),
102			(Self::Iri(_), GroundTerm::Literal(_)) => Some(Ordering::Less),
103			(Self::Literal(_), GroundTerm::Iri(_)) => Some(Ordering::Greater),
104			(Self::Literal(a), GroundTerm::Literal(b)) => (*a).partial_cmp(b),
105		}
106	}
107}
108
109impl fmt::Display for GroundTermRef<'_> {
110	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111		match self {
112			Self::Iri(iri) => iri.fmt(f),
113			Self::Literal(lit) => lit.fmt(f),
114		}
115	}
116}
117
118impl RdfDisplay for GroundTermRef<'_> {
119	fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
120		match self {
121			Self::Iri(iri) => iri.rdf_fmt(f),
122			Self::Literal(lit) => lit.rdf_fmt(f),
123		}
124	}
125}