rdftk_core/model/statement/
object.rs

1use crate::model::features::{Featured, FEATURE_RDF_STAR, FEATURE_STMT_OBJECT_COLLECTIONS};
2use crate::model::literal::Literal;
3use crate::model::statement::{
4    BlankNode, Collection, Statement, SubjectNode, BLANK_NODE_NAMESPACE,
5};
6use rdftk_iri::{Iri, Name};
7use std::borrow::Borrow;
8use std::cmp::Ordering;
9use std::fmt::{Debug, Display, Formatter};
10use std::sync::Arc;
11
12// ------------------------------------------------------------------------------------------------
13// Public Types
14// ------------------------------------------------------------------------------------------------
15
16#[derive(Clone, Debug, PartialEq, Eq, Hash)]
17pub enum ObjectNode {
18    Blank(BlankNode),
19    Resource(Iri),
20    Literal(Literal),
21    Collection(Collection),
22    Statement(Arc<Statement>),
23}
24
25// ------------------------------------------------------------------------------------------------
26// Implementations
27// ------------------------------------------------------------------------------------------------
28
29impl From<&ObjectNode> for ObjectNode {
30    fn from(v: &ObjectNode) -> Self {
31        v.clone()
32    }
33}
34
35impl From<BlankNode> for ObjectNode {
36    fn from(v: BlankNode) -> Self {
37        Self::Blank(v)
38    }
39}
40
41impl From<&BlankNode> for ObjectNode {
42    fn from(v: &BlankNode) -> Self {
43        Self::Blank(v.clone())
44    }
45}
46
47impl From<Name> for ObjectNode {
48    fn from(v: Name) -> Self {
49        Self::Blank(v.into())
50    }
51}
52
53impl From<&Name> for ObjectNode {
54    fn from(v: &Name) -> Self {
55        Self::Blank(v.clone().into())
56    }
57}
58
59impl From<Iri> for ObjectNode {
60    fn from(v: Iri) -> Self {
61        Self::Resource(v)
62    }
63}
64
65impl From<&Iri> for ObjectNode {
66    fn from(v: &Iri) -> Self {
67        Self::Resource(v.clone())
68    }
69}
70
71impl From<Literal> for ObjectNode {
72    fn from(v: Literal) -> Self {
73        Self::Literal(v)
74    }
75}
76
77impl From<&Literal> for ObjectNode {
78    fn from(v: &Literal) -> Self {
79        Self::Literal(v.clone())
80    }
81}
82
83impl From<Collection> for ObjectNode {
84    fn from(v: Collection) -> Self {
85        Self::Collection(v)
86    }
87}
88
89impl From<&Collection> for ObjectNode {
90    fn from(v: &Collection) -> Self {
91        Self::Collection(v.clone())
92    }
93}
94
95impl From<Statement> for ObjectNode {
96    fn from(v: Statement) -> Self {
97        Self::Statement(Arc::new(v))
98    }
99}
100
101impl From<&Statement> for ObjectNode {
102    fn from(v: &Statement) -> Self {
103        Self::Statement(Arc::new(v.clone()))
104    }
105}
106
107impl From<Arc<Statement>> for ObjectNode {
108    fn from(v: Arc<Statement>) -> Self {
109        Self::Statement(v)
110    }
111}
112
113impl From<&Arc<Statement>> for ObjectNode {
114    fn from(v: &Arc<Statement>) -> Self {
115        Self::Statement(v.clone())
116    }
117}
118
119// ------------------------------------------------------------------------------------------------
120
121impl Display for ObjectNode {
122    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
123        match self {
124            Self::Blank(node) => write!(f, "{}:{}", BLANK_NODE_NAMESPACE, node),
125            Self::Resource(iri) => write!(f, "<{}>", iri),
126            Self::Literal(lit) => write!(f, "{}", lit),
127            Self::Collection(col) => write!(f, "{}", col),
128            Self::Statement(st) => write!(f, "<< {} >>", st),
129        }
130    }
131}
132
133// ------------------------------------------------------------------------------------------------
134
135impl PartialEq<BlankNode> for ObjectNode {
136    fn eq(&self, other: &BlankNode) -> bool {
137        match self {
138            Self::Blank(value) => value == other,
139            _ => false,
140        }
141    }
142}
143
144impl PartialEq<Iri> for ObjectNode {
145    fn eq(&self, other: &Iri) -> bool {
146        match self {
147            Self::Resource(value) => value == other,
148            _ => false,
149        }
150    }
151}
152
153impl PartialEq<Literal> for ObjectNode {
154    fn eq(&self, other: &Literal) -> bool {
155        match self {
156            Self::Literal(value) => value == other,
157            _ => false,
158        }
159    }
160}
161
162impl PartialEq<Collection> for ObjectNode {
163    fn eq(&self, other: &Collection) -> bool {
164        match self {
165            Self::Collection(value) => value == other,
166            _ => false,
167        }
168    }
169}
170
171impl PartialEq<Statement> for ObjectNode {
172    fn eq(&self, other: &Statement) -> bool {
173        match self {
174            Self::Statement(value) => {
175                <Arc<Statement> as Borrow<Statement>>::borrow(value) == other.borrow()
176            }
177            _ => false,
178        }
179    }
180}
181
182impl PartialEq<Arc<Statement>> for ObjectNode {
183    fn eq(&self, other: &Arc<Statement>) -> bool {
184        match self {
185            Self::Statement(value) => value == other,
186            _ => false,
187        }
188    }
189}
190
191// ------------------------------------------------------------------------------------------------
192
193impl PartialOrd for ObjectNode {
194    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
195        Some(self.cmp(other))
196    }
197}
198
199impl Ord for ObjectNode {
200    fn cmp(&self, other: &Self) -> Ordering {
201        match (self, other) {
202            (Self::Blank(lhs), Self::Blank(rhs)) => lhs.cmp(rhs),
203            (Self::Blank(_), Self::Resource(_)) => Ordering::Less,
204            (Self::Blank(_), Self::Literal(_)) => Ordering::Less,
205            (Self::Blank(_), Self::Collection(_)) => Ordering::Less,
206            (Self::Blank(_), Self::Statement(_)) => Ordering::Less,
207            // --------------------------------------------------------
208            (Self::Resource(_), Self::Blank(_)) => Ordering::Greater,
209            (Self::Resource(lhs), Self::Resource(rhs)) => lhs.cmp(rhs),
210            (Self::Resource(_), Self::Literal(_)) => Ordering::Less,
211            (Self::Resource(_), Self::Collection(_)) => Ordering::Less,
212            (Self::Resource(_), Self::Statement(_)) => Ordering::Less,
213            // --------------------------------------------------------
214            (Self::Literal(_), Self::Blank(_)) => Ordering::Greater,
215            (Self::Literal(_), Self::Resource(_)) => Ordering::Greater,
216            (Self::Literal(lhs), Self::Literal(rhs)) => lhs.cmp(rhs),
217            (Self::Literal(_), Self::Collection(_)) => Ordering::Less,
218            (Self::Literal(_), Self::Statement(_)) => Ordering::Less,
219            // --------------------------------------------------------
220            (Self::Collection(_), Self::Blank(_)) => Ordering::Greater,
221            (Self::Collection(_), Self::Resource(_)) => Ordering::Greater,
222            (Self::Collection(_), Self::Literal(_)) => Ordering::Greater,
223            (Self::Collection(lhs), Self::Collection(rhs)) => lhs.cmp(rhs),
224            (Self::Collection(_), Self::Statement(_)) => Ordering::Less,
225            // --------------------------------------------------------
226            (Self::Statement(_), Self::Blank(_)) => Ordering::Greater,
227            (Self::Statement(_), Self::Resource(_)) => Ordering::Greater,
228            (Self::Statement(_), Self::Literal(_)) => Ordering::Greater,
229            (Self::Statement(_), Self::Collection(_)) => Ordering::Greater,
230            (Self::Statement(lhs), Self::Statement(rhs)) => lhs.cmp(rhs),
231        }
232    }
233}
234
235// ------------------------------------------------------------------------------------------------
236
237impl Featured for ObjectNode {
238    fn supports_feature(&self, feature: &Iri) -> bool {
239        *feature == *FEATURE_RDF_STAR || *feature == *FEATURE_STMT_OBJECT_COLLECTIONS
240    }
241}
242
243// ------------------------------------------------------------------------------------------------
244
245impl ObjectNode {
246    // --------------------------------------------------------------------------------------------
247    // Variants
248    // --------------------------------------------------------------------------------------------
249    pub fn is_blank(&self) -> bool {
250        matches!(self, Self::Blank(_))
251    }
252
253    pub fn as_blank(&self) -> Option<&BlankNode> {
254        match &self {
255            Self::Blank(v) => Some(v),
256            _ => None,
257        }
258    }
259
260    pub fn is_resource(&self) -> bool {
261        matches!(self, Self::Resource(_))
262    }
263
264    pub fn as_resource(&self) -> Option<&Iri> {
265        match &self {
266            Self::Resource(v) => Some(v),
267            _ => None,
268        }
269    }
270
271    pub fn is_literal(&self) -> bool {
272        matches!(self, Self::Literal(_))
273    }
274
275    pub fn as_literal(&self) -> Option<&Literal> {
276        match &self {
277            Self::Literal(v) => Some(v),
278            _ => None,
279        }
280    }
281
282    pub fn is_collection(&self) -> bool {
283        matches!(self, Self::Collection(_))
284    }
285
286    pub fn as_collection(&self) -> Option<&Collection> {
287        match &self {
288            Self::Collection(v) => Some(v),
289            _ => None,
290        }
291    }
292
293    pub fn is_statement(&self) -> bool {
294        matches!(self, Self::Statement(_))
295    }
296
297    pub fn as_statement(&self) -> Option<Arc<Statement>> {
298        match &self {
299            Self::Statement(v) => Some(v.clone()),
300            _ => None,
301        }
302    }
303    // --------------------------------------------------------------------------------------------
304    // Conversions
305    // --------------------------------------------------------------------------------------------
306    pub fn to_subject(&self) -> Option<SubjectNode> {
307        match self {
308            ObjectNode::Blank(v) => Some(v.clone().into()),
309            ObjectNode::Resource(v) => Some(v.clone().into()),
310            ObjectNode::Statement(v) => Some(v.clone().into()),
311            ObjectNode::Literal(_) => None,
312            ObjectNode::Collection(_) => None,
313        }
314    }
315}