Skip to main content

linked_data_schema/
linked_data_schema_field_visitor.rs

1mod uuid;
2
3use prefixmap::IriRef;
4use shacl::ast::ASTComponent;
5use std::collections::HashSet;
6
7pub trait LinkedDataSchemaFieldVisitor {
8  fn field_components() -> Vec<ASTComponent> {
9    vec![]
10  }
11
12  fn type_iri_ref() -> Option<IriRef>;
13}
14
15macro_rules! field_visitor_impl {
16  ($for_type:ty, $uri_datatype:literal) => {
17    impl LinkedDataSchemaFieldVisitor for $for_type {
18      fn field_components() -> Vec<ASTComponent> {
19        use std::str::FromStr;
20
21        vec![
22          ASTComponent::MinCount(1),
23          ASTComponent::MaxCount(1),
24          ASTComponent::Datatype(IriRef::from_str($uri_datatype).unwrap()),
25        ]
26      }
27
28      fn type_iri_ref() -> Option<IriRef> {
29        use std::str::FromStr;
30
31        IriRef::from_str($uri_datatype).ok()
32      }
33    }
34  };
35}
36
37field_visitor_impl!(String, "http://www.w3.org/2001/XMLSchema#string");
38field_visitor_impl!(bool, "http://www.w3.org/2001/XMLSchema#boolean");
39field_visitor_impl!(u8, "http://www.w3.org/2001/XMLSchema#unsignedByte");
40field_visitor_impl!(i8, "http://www.w3.org/2001/XMLSchema#byte");
41field_visitor_impl!(u16, "http://www.w3.org/2001/XMLSchema#unsignedShort");
42field_visitor_impl!(i16, "http://www.w3.org/2001/XMLSchema#short");
43field_visitor_impl!(u32, "http://www.w3.org/2001/XMLSchema#unsignedInt");
44field_visitor_impl!(i32, "http://www.w3.org/2001/XMLSchema#int");
45field_visitor_impl!(u64, "http://www.w3.org/2001/XMLSchema#unsignedLong");
46field_visitor_impl!(i64, "http://www.w3.org/2001/XMLSchema#long");
47field_visitor_impl!(usize, "http://www.w3.org/2001/XMLSchema#nonNegativeInteger");
48field_visitor_impl!(isize, "http://www.w3.org/2001/XMLSchema#integer");
49field_visitor_impl!(f32, "http://www.w3.org/2001/XMLSchema#float");
50field_visitor_impl!(f64, "http://www.w3.org/2001/XMLSchema#double");
51
52impl<S: LinkedDataSchemaFieldVisitor> LinkedDataSchemaFieldVisitor for Option<S> {
53  fn field_components() -> Vec<ASTComponent> {
54    if let Some(datatype) = S::type_iri_ref() {
55      [
56        S::field_components(),
57        vec![ASTComponent::MaxCount(1), ASTComponent::Datatype(datatype)],
58      ]
59      .concat()
60    } else {
61      vec![]
62    }
63  }
64
65  fn type_iri_ref() -> Option<IriRef> {
66    None
67  }
68}
69
70impl<S: LinkedDataSchemaFieldVisitor> LinkedDataSchemaFieldVisitor for Vec<S> {
71  fn field_components() -> Vec<ASTComponent> {
72    if let Some(datatype) = S::type_iri_ref() {
73      [
74        S::field_components(),
75        vec![ASTComponent::Datatype(datatype)],
76      ]
77      .concat()
78    } else {
79      vec![]
80    }
81  }
82
83  fn type_iri_ref() -> Option<IriRef> {
84    None
85  }
86}
87
88impl<S: LinkedDataSchemaFieldVisitor> LinkedDataSchemaFieldVisitor for HashSet<S> {
89  fn field_components() -> Vec<ASTComponent> {
90    if let Some(datatype) = S::type_iri_ref() {
91      [
92        S::field_components(),
93        vec![ASTComponent::Datatype(datatype)],
94      ]
95      .concat()
96    } else {
97      vec![]
98    }
99  }
100
101  fn type_iri_ref() -> Option<IriRef> {
102    None
103  }
104}