jsonld_core/deserialization/object/
value.rs1use ld_core::{
2 BorrowedRdfTerm,
3 CowRdfTerm,
4 LinkedData,
5 LinkedDataGraph,
6 LinkedDataPredicateObjects,
7 LinkedDataResource,
8 LinkedDataSubject,
9 OwnedRdfTerm,
10 RdfLiteral,
11 ResourceInterpretation,
12};
13use rdfx::Interpretation;
14
15use crate::{
16 Value,
17 object::value::Literal,
18 rdf::{XSD_BOOLEAN, XSD_CANONICAL_FLOAT, XSD_DOUBLE, XSD_INTEGER, XSD_STRING},
19};
20
21fn owned_literal(value: String, ty: iri_rs::Iri<&str>) -> CowRdfTerm<'static> {
26 let ty = rdfx::Datatype::new(ty.into()).unwrap_or_else(|_| rdfx::Datatype::xsd_string());
27 CowRdfTerm::Owned(OwnedRdfTerm::Literal(RdfLiteral::Any(value, rdfx::LiteralType::Any(ty))))
28}
29
30impl<T, I: Interpretation> LinkedDataResource<I> for Value<T>
31where
32 T: LinkedDataResource<I>,
33{
34 fn interpretation(&self, interpretation: &mut I) -> ResourceInterpretation<'_, I> {
35 let term = match self {
36 Self::Json(json) => Some(CowRdfTerm::Owned(OwnedRdfTerm::Literal(RdfLiteral::Json(json.clone())))),
37 Self::LangString(lang_string) => {
38 let (value, language, _direction) = lang_string.parts();
39 match language {
40 Some(language) => language.as_well_formed().map(|tag| {
45 CowRdfTerm::Owned(OwnedRdfTerm::Literal(RdfLiteral::Any(
46 value.to_owned(),
47 rdfx::LiteralType::LangString(tag.to_owned()),
48 )))
49 }),
50 None => Some(CowRdfTerm::from_str(value, XSD_STRING)),
51 }
52 }
53 Self::Literal(literal, ty) => {
54 let ty_iri = ty.as_ref().and_then(|t| match t.interpretation(interpretation) {
57 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(BorrowedRdfTerm::Iri(iri)))) => Some(iri),
58 _ => None,
59 });
60
61 match literal {
62 Literal::Null => Some(owned_literal("null".to_owned(), ty_iri.unwrap_or(XSD_STRING))),
63 Literal::Boolean(b) => {
64 let value = if *b { "true" } else { "false" };
65 Some(CowRdfTerm::from_str(value, ty_iri.unwrap_or(XSD_BOOLEAN)))
66 }
67 Literal::Number(n) => {
68 let (value, default_ty) = if n.is_i64() && (ty_iri != Some(XSD_DOUBLE)) {
69 (n.to_string(), XSD_INTEGER)
70 } else {
71 (pretty_dtoa::dtoa(n.as_f64_lossy(), XSD_CANONICAL_FLOAT), XSD_DOUBLE)
72 };
73 Some(owned_literal(value, ty_iri.unwrap_or(default_ty)))
74 }
75 Literal::String(s) => Some(CowRdfTerm::from_str(s, ty_iri.unwrap_or(XSD_STRING))),
76 }
77 }
78 };
79
80 ResourceInterpretation::Uninterpreted(term)
81 }
82}
83
84impl<T, I: Interpretation> LinkedDataSubject<I> for Value<T>
85where
86 T: LinkedDataResource<I>,
87{
88 fn visit_subject<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
89 where
90 S: ld_core::SubjectVisitor<I>,
91 {
92 visitor.end()
93 }
94}
95
96impl<T, I: Interpretation> LinkedDataPredicateObjects<I> for Value<T>
97where
98 T: LinkedDataResource<I>,
99{
100 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
101 where
102 S: ld_core::PredicateObjectsVisitor<I>,
103 {
104 visitor.object(self)?;
105 visitor.end()
106 }
107}
108
109impl<T, I: Interpretation> LinkedDataGraph<I> for Value<T>
110where
111 T: LinkedDataResource<I>,
112{
113 fn visit_graph<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
114 where
115 S: ld_core::GraphVisitor<I>,
116 {
117 visitor.subject(self)?;
118 visitor.end()
119 }
120}
121
122impl<T, I: Interpretation> LinkedData<I> for Value<T>
123where
124 T: LinkedDataResource<I>,
125{
126 fn visit<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
127 where
128 S: ld_core::Visitor<I>,
129 {
130 visitor.default_graph(self)?;
131 visitor.end()
132 }
133}