srdf/
object.rs

1use std::{
2    convert::Infallible,
3    fmt::{Debug, Display},
4};
5
6use crate::literal::Literal;
7use crate::numeric_literal::NumericLiteral;
8use iri_s::IriS;
9use serde::{Deserialize, Serialize};
10
11/// Concrete representation of RDF objects which can be IRIs, Blank nodes or literals
12///
13/// Note: We plan to support triple terms as in RDF-star in the future
14#[derive(Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
15pub enum Object {
16    Iri(IriS),
17    BlankNode(String),
18    Literal(Literal),
19}
20
21impl Object {
22    pub fn iri(iri: IriS) -> Object {
23        Object::Iri(iri)
24    }
25
26    pub fn bnode(str: String) -> Object {
27        Object::BlankNode(str)
28    }
29
30    pub fn literal(lit: Literal) -> Object {
31        Object::Literal(lit)
32    }
33
34    pub fn str(str: &str) -> Object {
35        Object::Literal(Literal::str(str))
36    }
37
38    pub fn length(&self) -> usize {
39        match self {
40            Object::Iri(iri) => iri.as_str().len(),
41            Object::BlankNode(bn) => bn.len(),
42            Object::Literal(lit) => lit.lexical_form().len(),
43        }
44    }
45
46    pub fn numeric_value(&self) -> Option<NumericLiteral> {
47        match self {
48            Object::Iri(_) | Object::BlankNode(_) => None,
49            Object::Literal(lit) => lit.numeric_value(),
50        }
51    }
52
53    pub fn boolean(b: bool) -> Object {
54        Object::Literal(Literal::boolean(b))
55    }
56}
57
58impl From<IriS> for Object {
59    fn from(iri: IriS) -> Self {
60        Object::Iri(iri)
61    }
62}
63
64impl From<Literal> for Object {
65    fn from(lit: Literal) -> Self {
66        Object::Literal(lit)
67    }
68}
69
70impl From<Object> for oxrdf::Term {
71    fn from(value: Object) -> Self {
72        match value {
73            Object::Iri(iri_s) => oxrdf::NamedNode::new_unchecked(iri_s.as_str()).into(),
74            Object::BlankNode(bnode) => oxrdf::BlankNode::new_unchecked(bnode).into(),
75            Object::Literal(literal) => oxrdf::Term::Literal(literal.into()),
76        }
77    }
78}
79
80impl From<oxrdf::Term> for Object {
81    fn from(value: oxrdf::Term) -> Self {
82        match value {
83            oxrdf::Term::NamedNode(named_node) => Object::iri(IriS::from_named_node(&named_node)),
84            oxrdf::Term::BlankNode(blank_node) => Object::bnode(blank_node.into_string()),
85            oxrdf::Term::Literal(literal) => Object::literal(literal.into()),
86            #[cfg(feature = "rdf-star")]
87            oxrdf::Term::Triple(_) => todo!(),
88        }
89    }
90}
91
92impl TryFrom<Object> for oxrdf::Subject {
93    type Error = Infallible;
94
95    fn try_from(value: Object) -> Result<Self, Self::Error> {
96        match value {
97            Object::Iri(iri_s) => Ok(oxrdf::NamedNode::new_unchecked(iri_s.as_str()).into()),
98            Object::BlankNode(bnode) => Ok(oxrdf::BlankNode::new_unchecked(bnode).into()),
99            Object::Literal(_) => todo!(),
100        }
101    }
102}
103
104impl Default for Object {
105    fn default() -> Self {
106        Object::Iri(IriS::default())
107    }
108}
109
110impl Display for Object {
111    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112        match self {
113            Object::Iri(iri) => write!(f, "{iri}"),
114            Object::BlankNode(bnode) => write!(f, "_{bnode}"),
115            Object::Literal(lit) => write!(f, "{lit}"),
116        }
117    }
118}
119
120impl Debug for Object {
121    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122        match self {
123            Object::Iri(iri) => write!(f, "Iri {{{iri:?}}}"),
124            Object::BlankNode(bnode) => write!(f, "Bnode{{{bnode:?}}}"),
125            Object::Literal(lit) => write!(f, "Literal{{{lit:?}}}"),
126        }
127    }
128}