1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use rdf_types::{
	interpretation::{ReverseIriInterpretation, ReverseLiteralInterpretation},
	vocabulary::LiteralVocabulary,
	Interpretation, Vocabulary, RDF_LANG_STRING,
};

use crate::{
	Context, FromLinkedDataError, LinkedDataDeserializePredicateObjects,
	LinkedDataDeserializeSubject,
};

macro_rules! deserialize_datatype {
	($($ty:ty : $iri:ident),*) => {
		$(
			impl<V: Vocabulary, I: Interpretation> LinkedDataDeserializeSubject<I, V> for $ty
			where
				V: LiteralVocabulary,
				I: ReverseIriInterpretation<Iri = V::Iri> + ReverseLiteralInterpretation<Literal = V::Literal>
			{
				fn deserialize_subject_in<D>(
					vocabulary: &V,
					interpretation: &I,
					_dataset: &D,
					_graph: Option<&I::Resource>,
					resource: &I::Resource,
					context: Context<I>
				) -> Result<Self, FromLinkedDataError>
				where
					D: rdf_types::dataset::PatternMatchingDataset<Resource = I::Resource>
				{
					let mut literal_ty = None;
					for l in interpretation.literals_of(resource) {
						let l = vocabulary.literal(l).unwrap();
						match l.type_ {
							rdf_types::LiteralTypeRef::Any(ty_iri) => {
								let ty_iri = vocabulary.iri(ty_iri).unwrap();
								if ty_iri == xsd_types::$iri {
									return match l.value.parse() {
										Ok(value) => Ok(value),
										Err(_) => Err(FromLinkedDataError::InvalidLiteral(
											context.into_iris(
												vocabulary,
												interpretation
											)
										))
									}
								}

								literal_ty = Some(ty_iri)
							}
							rdf_types::LiteralTypeRef::LangString(_) => {
								literal_ty = Some(RDF_LANG_STRING)
							}
						}
					}

					match literal_ty {
						Some(ty) => {
							Err(FromLinkedDataError::LiteralTypeMismatch {
								context: context.into_iris(vocabulary, interpretation),
								expected: Some(xsd_types::$iri.to_owned()),
								found: ty.to_owned()
							})
						}
						None => {
							Err(FromLinkedDataError::ExpectedLiteral(
								context.into_iris(vocabulary, interpretation)
							))
						}
					}
				}
			}

			impl<V: Vocabulary, I: Interpretation> LinkedDataDeserializePredicateObjects<I, V> for $ty
			where
				V: LiteralVocabulary,
				I: ReverseIriInterpretation<Iri = V::Iri> + ReverseLiteralInterpretation<Literal = V::Literal>
			{
				fn deserialize_objects_in<'a, D>(
					vocabulary: &V,
					interpretation: &I,
					dataset: &D,
					graph: Option<&I::Resource>,
					objects: impl IntoIterator<Item = &'a <I as Interpretation>::Resource>,
					context: Context<I>
				) -> Result<Self, FromLinkedDataError>
				where
					<I as Interpretation>::Resource: 'a,
					D: rdf_types::dataset::PatternMatchingDataset<Resource = I::Resource>
				{
					let mut error = None;

					for o in objects {
						match Self::deserialize_subject_in(vocabulary, interpretation, dataset, graph, o, context) {
							Ok(value) => return Ok(value),
							Err(e) => error = Some(e)
						}
					}

					Err(error.unwrap_or_else(|| {
						FromLinkedDataError::MissingRequiredValue(
							context.into_iris(vocabulary, interpretation)
						)
					}))
				}
			}
		)*
	};
}

deserialize_datatype!(
	u8: XSD_UNSIGNED_BYTE,
	u16: XSD_UNSIGNED_SHORT,
	u32: XSD_UNSIGNED_INT,
	u64: XSD_UNSIGNED_LONG,
	i8: XSD_BYTE,
	i16: XSD_SHORT,
	i32: XSD_INT,
	i64: XSD_LONG,
	String: XSD_STRING,
	xsd_types::DateTime: XSD_DATE_TIME
);