json_ld/syntax/
compact_iri.rs1use std::borrow::Cow;
2
3use rdf_syntax::{InvalidIri, Iri, IriBuf, IriRef, IriRefBuf};
4
5#[derive(Debug, thiserror::Error)]
6#[error("invalid compact IRI")]
7pub struct InvalidJsonLdCompactIri<T>(pub T);
8
9#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
10pub struct JsonLdCompactIri(str);
11
12impl JsonLdCompactIri {
13 pub fn new(s: &str) -> Result<&Self, InvalidJsonLdCompactIri<&str>> {
27 match s.split_once(':') {
28 Some((prefix, suffix)) if prefix != "_" && !suffix.starts_with("//") => {
29 match IriRef::new(s) {
30 Ok(_) => Ok(unsafe { Self::new_unchecked(s) }),
31 Err(_) => Err(InvalidJsonLdCompactIri(s)),
32 }
33 }
34 _ => Err(InvalidJsonLdCompactIri(s)),
35 }
36 }
37
38 pub unsafe fn new_unchecked(s: &str) -> &Self {
44 unsafe { std::mem::transmute(s) }
45 }
46
47 pub fn as_str(&self) -> &str {
48 &self.0
49 }
50
51 pub fn to_owned(&self) -> JsonLdCompactIriBuf {
52 JsonLdCompactIriBuf(self.0.to_owned())
53 }
54
55 pub fn prefix(&self) -> &str {
56 let i = self.find(':').unwrap();
57 &self[0..i]
58 }
59
60 pub fn suffix(&self) -> &str {
61 let i = self.find(':').unwrap();
62 &self[i + 1..]
63 }
64
65 pub fn as_iri(&self) -> Option<&Iri> {
73 Iri::new(self.as_str()).ok()
74 }
75
76 pub fn as_iri_ref(&self) -> Option<&IriRef> {
80 IriRef::new(self.as_str()).ok()
81 }
82
83 pub fn resolve<'a>(
84 &self,
85 resolver: impl FnOnce(&str) -> Option<Cow<'a, Iri>>,
86 ) -> Result<IriBuf, InvalidIri<String>> {
87 match resolver(self.prefix()) {
88 Some(prefix) => IriBuf::from_string(format!("{}{}", prefix, self.suffix())),
89 None => IriBuf::from_string(self.as_str().to_owned()),
90 }
91 }
92}
93
94impl std::ops::Deref for JsonLdCompactIri {
95 type Target = str;
96
97 fn deref(&self) -> &str {
98 &self.0
99 }
100}
101
102impl std::borrow::Borrow<str> for JsonLdCompactIri {
103 fn borrow(&self) -> &str {
104 &self.0
105 }
106}
107
108impl AsRef<str> for JsonLdCompactIri {
109 fn as_ref(&self) -> &str {
110 &self.0
111 }
112}
113
114#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
115pub struct JsonLdCompactIriBuf(String);
116
117impl JsonLdCompactIriBuf {
118 pub fn from_string(s: String) -> Result<Self, InvalidJsonLdCompactIri<String>> {
119 match JsonLdCompactIri::new(&s) {
120 Ok(_) => Ok(unsafe { Self::new_unchecked(s) }),
121 Err(_) => Err(InvalidJsonLdCompactIri(s)),
122 }
123 }
124
125 pub unsafe fn new_unchecked(s: String) -> Self {
131 Self(s)
132 }
133
134 pub fn as_compact_iri(&self) -> &JsonLdCompactIri {
135 unsafe { JsonLdCompactIri::new_unchecked(&self.0) }
136 }
137
138 pub fn into_iri_ref(self) -> IriRefBuf {
139 IriRefBuf::new(self.0).unwrap()
140 }
141
142 pub fn into_string(self) -> String {
143 self.0
144 }
145}
146
147impl std::borrow::Borrow<JsonLdCompactIri> for JsonLdCompactIriBuf {
148 fn borrow(&self) -> &JsonLdCompactIri {
149 self.as_compact_iri()
150 }
151}
152
153impl std::ops::Deref for JsonLdCompactIriBuf {
154 type Target = JsonLdCompactIri;
155
156 fn deref(&self) -> &JsonLdCompactIri {
157 self.as_compact_iri()
158 }
159}