Skip to main content

rdf_syntax/id/
cow.rs

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