oxrdf/
named_node.rs

1use oxiri::{Iri, IriParseError};
2use std::cmp::Ordering;
3use std::fmt;
4
5/// An owned RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
6///
7/// The default string formatter is returning an N-Triples, Turtle, and SPARQL compatible representation:
8/// ```
9/// use oxrdf::NamedNode;
10///
11/// assert_eq!(
12///     "<http://example.com/foo>",
13///     NamedNode::new("http://example.com/foo")?.to_string()
14/// );
15/// # Result::<_,oxrdf::IriParseError>::Ok(())
16/// ```
17#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
18pub struct NamedNode {
19    iri: String,
20}
21
22impl NamedNode {
23    /// Builds and validate an RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
24    pub fn new(iri: impl Into<String>) -> Result<Self, IriParseError> {
25        Ok(Self::new_from_iri(Iri::parse(iri.into())?))
26    }
27
28    #[inline]
29    pub(crate) fn new_from_iri(iri: Iri<String>) -> Self {
30        Self::new_unchecked(iri.into_inner())
31    }
32
33    /// Builds an RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) from a string.
34    ///
35    /// It is the caller's responsibility to ensure that `iri` is a valid IRI.
36    ///
37    /// [`NamedNode::new()`] is a safe version of this constructor and should be used for untrusted data.
38    #[inline]
39    pub fn new_unchecked(iri: impl Into<String>) -> Self {
40        Self { iri: iri.into() }
41    }
42
43    #[inline]
44    pub fn as_str(&self) -> &str {
45        self.iri.as_str()
46    }
47
48    #[inline]
49    pub fn into_string(self) -> String {
50        self.iri
51    }
52
53    #[inline]
54    pub fn as_ref(&self) -> NamedNodeRef<'_> {
55        NamedNodeRef::new_unchecked(&self.iri)
56    }
57}
58
59impl fmt::Display for NamedNode {
60    #[inline]
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        self.as_ref().fmt(f)
63    }
64}
65
66impl PartialEq<str> for NamedNode {
67    #[inline]
68    fn eq(&self, other: &str) -> bool {
69        self.as_str() == other
70    }
71}
72
73impl PartialEq<NamedNode> for str {
74    #[inline]
75    fn eq(&self, other: &NamedNode) -> bool {
76        self == other.as_str()
77    }
78}
79
80impl PartialEq<&str> for NamedNode {
81    #[inline]
82    fn eq(&self, other: &&str) -> bool {
83        self == *other
84    }
85}
86
87impl PartialEq<NamedNode> for &str {
88    #[inline]
89    fn eq(&self, other: &NamedNode) -> bool {
90        *self == other
91    }
92}
93
94/// A borrowed RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
95///
96/// The default string formatter is returning an N-Triples, Turtle, and SPARQL compatible representation:
97/// ```
98/// use oxrdf::NamedNodeRef;
99///
100/// assert_eq!(
101///     "<http://example.com/foo>",
102///     NamedNodeRef::new("http://example.com/foo")?.to_string()
103/// );
104/// # Result::<_,oxrdf::IriParseError>::Ok(())
105/// ```
106#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)]
107pub struct NamedNodeRef<'a> {
108    iri: &'a str,
109}
110
111impl<'a> NamedNodeRef<'a> {
112    /// Builds and validate an RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
113    pub fn new(iri: &'a str) -> Result<Self, IriParseError> {
114        Ok(Self::new_from_iri(Iri::parse(iri)?))
115    }
116
117    #[inline]
118    pub(crate) fn new_from_iri(iri: Iri<&'a str>) -> Self {
119        Self::new_unchecked(iri.into_inner())
120    }
121
122    /// Builds an RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) from a string.
123    ///
124    /// It is the caller's responsibility to ensure that `iri` is a valid IRI.
125    ///
126    /// [`NamedNode::new()`] is a safe version of this constructor and should be used for untrusted data.
127    #[inline]
128    pub const fn new_unchecked(iri: &'a str) -> Self {
129        Self { iri }
130    }
131
132    #[inline]
133    pub const fn as_str(self) -> &'a str {
134        self.iri
135    }
136
137    #[inline]
138    pub fn into_owned(self) -> NamedNode {
139        NamedNode::new_unchecked(self.iri)
140    }
141}
142
143impl fmt::Display for NamedNodeRef<'_> {
144    #[inline]
145    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146        write!(f, "<{}>", self.as_str())
147    }
148}
149
150impl From<NamedNodeRef<'_>> for NamedNode {
151    #[inline]
152    fn from(node: NamedNodeRef<'_>) -> Self {
153        node.into_owned()
154    }
155}
156
157impl<'a> From<&'a NamedNode> for NamedNodeRef<'a> {
158    #[inline]
159    fn from(node: &'a NamedNode) -> Self {
160        node.as_ref()
161    }
162}
163
164impl PartialEq<NamedNode> for NamedNodeRef<'_> {
165    #[inline]
166    fn eq(&self, other: &NamedNode) -> bool {
167        self.as_str() == other.as_str()
168    }
169}
170
171impl PartialEq<NamedNodeRef<'_>> for NamedNode {
172    #[inline]
173    fn eq(&self, other: &NamedNodeRef<'_>) -> bool {
174        self.as_str() == other.as_str()
175    }
176}
177
178impl PartialEq<str> for NamedNodeRef<'_> {
179    #[inline]
180    fn eq(&self, other: &str) -> bool {
181        self.as_str() == other
182    }
183}
184
185impl PartialEq<NamedNodeRef<'_>> for str {
186    #[inline]
187    fn eq(&self, other: &NamedNodeRef<'_>) -> bool {
188        self == other.as_str()
189    }
190}
191
192impl PartialEq<&str> for NamedNodeRef<'_> {
193    #[inline]
194    fn eq(&self, other: &&str) -> bool {
195        self == *other
196    }
197}
198
199impl PartialEq<NamedNodeRef<'_>> for &str {
200    #[inline]
201    fn eq(&self, other: &NamedNodeRef<'_>) -> bool {
202        *self == other
203    }
204}
205
206impl PartialOrd<NamedNode> for NamedNodeRef<'_> {
207    #[inline]
208    fn partial_cmp(&self, other: &NamedNode) -> Option<Ordering> {
209        self.partial_cmp(&other.as_ref())
210    }
211}
212
213impl PartialOrd<NamedNodeRef<'_>> for NamedNode {
214    #[inline]
215    fn partial_cmp(&self, other: &NamedNodeRef<'_>) -> Option<Ordering> {
216        self.as_ref().partial_cmp(other)
217    }
218}
219
220impl From<Iri<String>> for NamedNode {
221    #[inline]
222    fn from(iri: Iri<String>) -> Self {
223        Self {
224            iri: iri.into_inner(),
225        }
226    }
227}
228
229impl<'a> From<Iri<&'a str>> for NamedNodeRef<'a> {
230    #[inline]
231    fn from(iri: Iri<&'a str>) -> Self {
232        Self {
233            iri: iri.into_inner(),
234        }
235    }
236}