1use core::fmt;
2use std::borrow::Cow;
3use std::cmp::Ordering;
4use std::str::FromStr;
5
6use crate::{BlankId, BlankIdBuf, RdfDisplay};
7use iref::{InvalidIri, Iri, IriBuf};
8
9mod r#ref;
10pub use r#ref::*;
11
12mod cow;
13pub use cow::*;
14
15#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21#[cfg_attr(feature = "serde", serde(untagged))]
22pub enum Id {
23 BlankId(BlankIdBuf),
25
26 Iri(IriBuf),
28}
29
30impl Id {
31 pub fn is_blank_id(&self) -> bool {
33 matches!(self, Self::BlankId(_))
34 }
35
36 pub fn as_blank_id(&self) -> Option<&BlankId> {
38 match self {
39 Self::BlankId(b) => Some(b),
40 _ => None,
41 }
42 }
43
44 pub fn is_iri(&self) -> bool {
46 matches!(self, Self::Iri(_))
47 }
48
49 pub fn as_iri(&self) -> Option<&Iri> {
51 match self {
52 Self::Iri(iri) => Some(iri),
53 _ => None,
54 }
55 }
56
57 pub fn as_ref(&self) -> IdRef<'_> {
59 match self {
60 Self::BlankId(blank_id) => IdRef::BlankId(blank_id),
61 Self::Iri(iri) => IdRef::Iri(iri),
62 }
63 }
64
65 pub fn into_blank_id(self) -> Option<BlankIdBuf> {
67 match self {
68 Self::BlankId(b) => Some(b),
69 _ => None,
70 }
71 }
72
73 pub fn into_iri(self) -> Option<IriBuf> {
75 match self {
76 Self::Iri(iri) => Some(iri),
77 _ => None,
78 }
79 }
80
81 pub fn as_cow(&self) -> CowId<'_> {
83 match self {
84 Self::BlankId(blank_id) => CowId::BlankId(Cow::Borrowed(blank_id)),
85 Self::Iri(iri) => CowId::Iri(Cow::Borrowed(iri)),
86 }
87 }
88
89 pub fn into_cow(self) -> CowId<'static> {
91 match self {
92 Self::BlankId(blank_id) => CowId::BlankId(Cow::Owned(blank_id)),
93 Self::Iri(iri) => CowId::Iri(Cow::Owned(iri)),
94 }
95 }
96}
97
98impl FromStr for Id {
99 type Err = InvalidIri<String>;
100
101 fn from_str(s: &str) -> Result<Self, Self::Err> {
102 match BlankIdBuf::from_str(s) {
103 Ok(b) => Ok(Self::BlankId(b)),
104 Err(_) => IriBuf::from_str(s).map(Self::Iri),
105 }
106 }
107}
108
109impl AsRef<str> for Id {
110 fn as_ref(&self) -> &str {
111 match self {
112 Self::BlankId(b) => b.as_ref(),
113 Self::Iri(i) => i.as_ref(),
114 }
115 }
116}
117
118impl fmt::Display for Id {
119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120 match self {
121 Self::BlankId(b) => b.fmt(f),
122 Self::Iri(i) => i.fmt(f),
123 }
124 }
125}
126
127impl RdfDisplay for Id {
128 fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
129 match self {
130 Self::BlankId(b) => b.rdf_fmt(f),
131 Self::Iri(i) => i.rdf_fmt(f),
132 }
133 }
134}
135
136impl PartialEq<Iri> for Id {
137 fn eq(&self, other: &Iri) -> bool {
138 match self {
139 Self::Iri(iri) => iri.as_iri() == other,
140 _ => false,
141 }
142 }
143}
144
145impl PartialEq<&Iri> for Id {
146 fn eq(&self, other: &&Iri) -> bool {
147 self.eq(*other)
148 }
149}
150
151impl PartialEq<IriBuf> for Id {
152 fn eq(&self, other: &IriBuf) -> bool {
153 match self {
154 Self::Iri(iri) => iri == other,
155 _ => false,
156 }
157 }
158}
159
160impl PartialEq<&IriBuf> for Id {
161 fn eq(&self, other: &&IriBuf) -> bool {
162 self.eq(*other)
163 }
164}
165
166impl PartialEq<BlankId> for Id {
167 fn eq(&self, other: &BlankId) -> bool {
168 match self {
169 Self::BlankId(b) => b.as_blank_id() == other,
170 _ => false,
171 }
172 }
173}
174
175impl PartialEq<BlankIdBuf> for Id {
176 fn eq(&self, other: &BlankIdBuf) -> bool {
177 match self {
178 Self::BlankId(b) => b == other,
179 _ => false,
180 }
181 }
182}
183
184impl PartialEq<&BlankId> for Id {
185 fn eq(&self, other: &&BlankId) -> bool {
186 self.eq(*other)
187 }
188}
189
190impl PartialEq<&BlankIdBuf> for Id {
191 fn eq(&self, other: &&BlankIdBuf) -> bool {
192 self.eq(*other)
193 }
194}
195
196impl<'a> PartialEq<IdRef<'a>> for Id {
197 fn eq(&self, other: &IdRef<'a>) -> bool {
198 match (self, other) {
199 (Self::BlankId(a), IdRef::BlankId(b)) => a == *b,
200 (Self::Iri(a), IdRef::Iri(b)) => a == *b,
201 _ => false,
202 }
203 }
204}
205
206impl<'a> PartialOrd<IdRef<'a>> for Id {
207 fn partial_cmp(&self, other: &IdRef<'a>) -> Option<Ordering> {
208 match (self, other) {
209 (Self::BlankId(a), IdRef::BlankId(b)) => a.as_blank_id().partial_cmp(*b),
210 (Self::BlankId(_), IdRef::Iri(_)) => Some(Ordering::Less),
211 (Self::Iri(_), IdRef::BlankId(_)) => Some(Ordering::Greater),
212 (Self::Iri(a), IdRef::Iri(b)) => a.as_iri().partial_cmp(b),
213 }
214 }
215}