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#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub enum CowId<'a> {
13 BlankId(Cow<'a, BlankId>),
15
16 Iri(Cow<'a, Iri>),
18}
19
20impl CowId<'_> {
21 pub fn is_blank_id(&self) -> bool {
23 matches!(self, Self::BlankId(_))
24 }
25
26 pub fn is_iri(&self) -> bool {
28 matches!(self, Self::Iri(_))
29 }
30
31 pub fn as_blank_id(&self) -> Option<&BlankId> {
33 match self {
34 Self::BlankId(b) => Some(b),
35 _ => None,
36 }
37 }
38
39 pub fn as_iri(&self) -> Option<&Iri> {
41 match self {
42 Self::Iri(iri) => Some(iri),
43 _ => None,
44 }
45 }
46
47 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 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}