1use super::resolve::{BaseIri, BaseIriRef};
4use super::{InvalidIri, IsIri, IsIriRef, *};
5use std::borrow::Borrow;
6use std::fmt::Display;
7
8wrap! { Iri borrowing str :
9 pub fn new(iri: T) -> Result<Self, InvalidIri> {
13 if is_absolute_iri_ref(iri.borrow()) {
14 Ok(Iri(iri))
15 } else {
16 Err(InvalidIri(iri.borrow().to_string()))
17 }
18 }
19
20 pub fn as_str(&self) -> &str {
22 self.0.borrow()
23 }
24
25 pub fn resolve<U: IsIriRef>(&self, rel: U) -> Iri<String> {
31 self.as_base().resolve(rel)
32 }
33
34 pub fn as_base(&self) -> BaseIri<&str> {
37 BaseIri::new(self.0.borrow()).unwrap()
38 }
39
40 pub fn to_base(self) -> BaseIri<T>
43 where
44 T: std::ops::Deref<Target = str>,
45 {
46 BaseIri::new(self.0).unwrap()
47 }
48}
49
50impl<T: Borrow<str>> IsIriRef for Iri<T> {}
51impl<T: Borrow<str>> IsIri for Iri<T> {}
52
53impl<T: Borrow<str>> Display for Iri<T> {
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 write!(f, "{}", self.0.borrow())
56 }
57}
58
59wrap! { IriRef borrowing str :
62 pub fn new(iri: T) -> Result<Self, InvalidIri> {
66 if is_valid_iri_ref(iri.borrow()) {
67 Ok(IriRef(iri))
68 } else {
69 Err(InvalidIri(iri.borrow().to_string()))
70 }
71 }
72
73 pub fn as_str(&self) -> &str {
75 self.0.borrow()
76 }
77
78 pub fn resolve<U: IsIriRef>(&self, rel: U) -> IriRef<String> {
84 self.as_base().resolve(rel)
85 }
86
87 pub fn as_base(&self) -> BaseIriRef<&str> {
90 BaseIriRef::new(self.0.borrow()).unwrap()
91 }
92
93 pub fn to_base(self) -> BaseIriRef<T>
96 where
97 T: std::ops::Deref<Target = str>,
98 {
99 BaseIriRef::new(self.0).unwrap()
100 }
101}
102
103impl<T: Borrow<str>> IsIriRef for IriRef<T> {}
104
105impl<T: Borrow<str>> Display for IriRef<T> {
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 write!(f, "{}", self.0.borrow())
108 }
109}
110
111#[cfg(test)]
114mod test {
115 use super::*;
116 use crate::test::*;
117
118 #[test]
119 fn iri() {
120 for (txt, (abs, ..)) in POSITIVE_IRIS {
121 assert!(Iri::new(*txt).is_ok() == *abs)
122 }
123 for txt in NEGATIVE_IRIS {
124 assert!(Iri::new(*txt).is_err())
125 }
126 }
127
128 #[test]
129 fn iri_box() {
130 for (txt, (abs, ..)) in POSITIVE_IRIS {
131 assert!(Iri::new(Box::from(txt as &str)).is_ok() == *abs)
132 }
133 for txt in NEGATIVE_IRIS {
134 assert!(Iri::new(Box::from(txt as &str)).is_err())
135 }
136 }
137
138 #[test]
139 fn iri_ref() {
140 for (txt, _) in POSITIVE_IRIS {
141 assert!(IriRef::new(*txt).is_ok())
142 }
143 for txt in NEGATIVE_IRIS {
144 assert!(IriRef::new(*txt).is_err())
145 }
146 for (txt, _) in RELATIVE_IRIS {
147 assert!(IriRef::new(*txt).is_ok())
148 }
149 }
150
151 #[test]
152 fn iri_ref_box() {
153 for (txt, _) in POSITIVE_IRIS {
154 assert!(IriRef::new(Box::from(txt as &str)).is_ok())
155 }
156 for txt in NEGATIVE_IRIS {
157 assert!(IriRef::new(Box::from(txt as &str)).is_err())
158 }
159 for (txt, _) in RELATIVE_IRIS {
160 assert!(IriRef::new(Box::from(txt as &str)).is_ok())
161 }
162 }
163
164 #[test]
165 fn heterogeneous_comparison() {
166 let iri1 = Iri::new(String::from("http://example.com/")).unwrap();
167 let iri2 = Iri::new_unchecked(iri1.as_str());
168 assert_eq!(iri1, iri2);
169 }
170}