Skip to main content

rdf_syntax/id/
ref.rs

1use core::fmt;
2use std::borrow::Cow;
3use std::cmp::Ordering;
4
5use iref::{Iri, IriBuf};
6
7use into_owned_trait::IntoOwned;
8
9use crate::{BlankId, BlankIdBuf, RdfDisplay};
10
11use super::{CowId, Id};
12
13/// Resource identifier reference.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub enum IdRef<'a> {
16	/// Blank node identifier.
17	BlankId(&'a BlankId),
18
19	/// IRI.
20	Iri(&'a Iri),
21}
22
23impl<'a> IdRef<'a> {
24	/// Checks if this is a blank node identifier.
25	pub fn is_blank_id(&self) -> bool {
26		matches!(self, Self::BlankId(_))
27	}
28
29	/// Checks if this is an IRI.
30	pub fn is_iri(&self) -> bool {
31		matches!(self, Self::Iri(_))
32	}
33
34	/// Returns this identifier as a blank node identifier, if it is one.
35	pub fn as_blank_id(&self) -> Option<&'a BlankId> {
36		match self {
37			Self::BlankId(b) => Some(b),
38			_ => None,
39		}
40	}
41
42	/// Returns this identifier as an IRI, if it is one.
43	pub fn as_iri(&self) -> Option<&'a Iri> {
44		match self {
45			Self::Iri(iri) => Some(iri),
46			_ => None,
47		}
48	}
49
50	/// Turns this identifier reference into a copy-on-write identifier.
51	pub fn into_cow(self) -> CowId<'a> {
52		match self {
53			Self::BlankId(b) => CowId::BlankId(Cow::Borrowed(b)),
54			Self::Iri(iri) => CowId::Iri(Cow::Borrowed(iri)),
55		}
56	}
57}
58
59impl IdRef<'_> {
60	/// Clones the referenced identifier.
61	pub fn to_owned(&self) -> Id {
62		(*self).into_owned()
63	}
64
65	/// Clones the referenced identifier.
66	pub fn into_owned(self) -> Id {
67		match self {
68			Self::BlankId(blank_id) => Id::BlankId(blank_id.to_owned()),
69			Self::Iri(iri) => Id::Iri(iri.to_owned()),
70		}
71	}
72}
73
74impl fmt::Display for IdRef<'_> {
75	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76		match self {
77			Self::BlankId(b) => b.fmt(f),
78			Self::Iri(i) => i.fmt(f),
79		}
80	}
81}
82
83impl RdfDisplay for IdRef<'_> {
84	fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85		match self {
86			Self::BlankId(b) => b.rdf_fmt(f),
87			Self::Iri(i) => i.rdf_fmt(f),
88		}
89	}
90}
91
92impl PartialEq<Iri> for IdRef<'_> {
93	fn eq(&self, other: &Iri) -> bool {
94		match self {
95			Self::Iri(iri) => *iri == other,
96			_ => false,
97		}
98	}
99}
100
101impl PartialEq<&Iri> for IdRef<'_> {
102	fn eq(&self, other: &&Iri) -> bool {
103		self.eq(*other)
104	}
105}
106
107impl PartialEq<IriBuf> for IdRef<'_> {
108	fn eq(&self, other: &IriBuf) -> bool {
109		match self {
110			Self::Iri(iri) => *iri == other.as_iri(),
111			_ => false,
112		}
113	}
114}
115
116impl PartialEq<&IriBuf> for IdRef<'_> {
117	fn eq(&self, other: &&IriBuf) -> bool {
118		self.eq(*other)
119	}
120}
121
122impl PartialEq<BlankId> for IdRef<'_> {
123	fn eq(&self, other: &BlankId) -> bool {
124		match self {
125			Self::BlankId(b) => *b == other,
126			_ => false,
127		}
128	}
129}
130
131impl PartialEq<BlankIdBuf> for IdRef<'_> {
132	fn eq(&self, other: &BlankIdBuf) -> bool {
133		match self {
134			Self::BlankId(b) => *b == other.as_blank_id(),
135			_ => false,
136		}
137	}
138}
139
140impl PartialEq<&BlankId> for IdRef<'_> {
141	fn eq(&self, other: &&BlankId) -> bool {
142		self.eq(*other)
143	}
144}
145
146impl PartialEq<&BlankIdBuf> for IdRef<'_> {
147	fn eq(&self, other: &&BlankIdBuf) -> bool {
148		self.eq(*other)
149	}
150}
151
152impl PartialEq<Id> for IdRef<'_> {
153	fn eq(&self, other: &Id) -> bool {
154		match (self, other) {
155			(Self::BlankId(a), Id::BlankId(b)) => *a == b,
156			(Self::Iri(a), Id::Iri(b)) => *a == b,
157			_ => false,
158		}
159	}
160}
161
162impl PartialOrd<Id> for IdRef<'_> {
163	fn partial_cmp(&self, other: &Id) -> Option<Ordering> {
164		match (self, other) {
165			(Self::BlankId(a), Id::BlankId(b)) => (*a).partial_cmp(b),
166			(Self::BlankId(_), Id::Iri(_)) => Some(Ordering::Less),
167			(Self::Iri(_), Id::BlankId(_)) => Some(Ordering::Greater),
168			(Self::Iri(a), Id::Iri(b)) => (*a).partial_cmp(b),
169		}
170	}
171}
172
173impl AsRef<str> for IdRef<'_> {
174	fn as_ref(&self) -> &str {
175		match self {
176			Self::BlankId(b) => b.as_ref(),
177			Self::Iri(i) => i.as_str(),
178		}
179	}
180}
181
182impl IntoOwned for IdRef<'_> {
183	type Owned = Id;
184
185	fn into_owned(self) -> Id {
186		match self {
187			Self::BlankId(blank_id) => Id::BlankId(blank_id.to_owned()),
188			Self::Iri(iri) => Id::Iri(iri.to_owned()),
189		}
190	}
191}
192
193impl From<IdRef<'_>> for Id {
194	fn from(value: IdRef<'_>) -> Self {
195		value.into_owned()
196	}
197}
198
199impl equivalent::Equivalent<Id> for IdRef<'_> {
200	fn equivalent(&self, key: &Id) -> bool {
201		self == key
202	}
203}
204
205impl equivalent::Comparable<Id> for IdRef<'_> {
206	fn compare(&self, key: &Id) -> std::cmp::Ordering {
207		self.partial_cmp(key).unwrap()
208	}
209}