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#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub enum IdRef<'a> {
16 BlankId(&'a BlankId),
18
19 Iri(&'a Iri),
21}
22
23impl<'a> IdRef<'a> {
24 pub fn is_blank_id(&self) -> bool {
26 matches!(self, Self::BlankId(_))
27 }
28
29 pub fn is_iri(&self) -> bool {
31 matches!(self, Self::Iri(_))
32 }
33
34 pub fn as_blank_id(&self) -> Option<&'a BlankId> {
36 match self {
37 Self::BlankId(b) => Some(b),
38 _ => None,
39 }
40 }
41
42 pub fn as_iri(&self) -> Option<&'a Iri> {
44 match self {
45 Self::Iri(iri) => Some(iri),
46 _ => None,
47 }
48 }
49
50 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 pub fn to_owned(&self) -> Id {
62 (*self).into_owned()
63 }
64
65 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}