sdml_core/model/definitions/
rdf.rs1use crate::{
2 load::ModuleLoader,
3 model::{
4 annotations::{AnnotationBuilder, AnnotationOnlyBody, AnnotationProperty, HasAnnotations},
5 check::{MaybeIncomplete, Validate},
6 identifiers::{Identifier, IdentifierReference, QualifiedIdentifier},
7 modules::Module,
8 values::Value,
9 HasBody, HasName, HasSourceSpan, References, Span,
10 },
11 stdlib,
12 store::ModuleStore,
13};
14use sdml_errors::diagnostics::functions::IdentifierCaseConvention;
15use std::collections::BTreeSet;
16
17#[cfg(feature = "serde")]
18use serde::{Deserialize, Serialize};
19
20#[derive(Clone, Debug)]
26#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
27pub struct RdfDef {
28 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
29 span: Option<Span>,
30 name: Identifier,
31 body: AnnotationOnlyBody,
32}
33
34impl HasName for RdfDef {
39 fn name(&self) -> &Identifier {
40 &self.name
41 }
42
43 fn set_name(&mut self, name: Identifier) {
44 self.name = name;
45 }
46}
47
48impl HasBody for RdfDef {
49 type Body = AnnotationOnlyBody;
50
51 fn body(&self) -> &Self::Body {
52 &self.body
53 }
54
55 fn body_mut(&mut self) -> &mut Self::Body {
56 &mut self.body
57 }
58
59 fn set_body(&mut self, body: Self::Body) {
60 self.body = body;
61 }
62}
63
64impl HasSourceSpan for RdfDef {
65 fn with_source_span(self, span: Span) -> Self {
66 let mut self_mut = self;
67 self_mut.span = Some(span);
68 self_mut
69 }
70
71 fn source_span(&self) -> Option<&Span> {
72 self.span.as_ref()
73 }
74
75 fn set_source_span(&mut self, span: Span) {
76 self.span = Some(span);
77 }
78
79 fn unset_source_span(&mut self) {
80 self.span = None;
81 }
82}
83
84impl References for RdfDef {
85 fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
86 self.body.referenced_annotations(names);
87 }
88
89 fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
90 self.body.referenced_types(names);
91 }
92}
93
94impl AnnotationBuilder for RdfDef {
95 fn with_predicate<I, V>(self, predicate: I, value: V) -> Self
96 where
97 Self: Sized,
98 I: Into<IdentifierReference>,
99 V: Into<Value>,
100 {
101 let mut self_mut = self;
102 self_mut
103 .body
104 .add_to_annotations(AnnotationProperty::new(predicate.into(), value.into()));
105 self_mut
106 }
107}
108
109impl MaybeIncomplete for RdfDef {
110 fn is_incomplete(&self, _: &Module, _: &impl ModuleStore) -> bool {
111 false
112 }
113}
114
115impl Validate for RdfDef {
116 fn validate(
117 &self,
118 top: &Module,
119 cache: &impl ModuleStore,
120 loader: &impl ModuleLoader,
121 check_constraints: bool,
122 ) {
123 self.name
124 .validate(top, loader, Some(IdentifierCaseConvention::RdfDefinition));
125 self.body.validate(top, cache, loader, check_constraints);
126 }
127}
128
129impl RdfDef {
130 fn new(name: Identifier) -> Self {
135 Self {
136 span: None,
137 name,
138 body: Default::default(),
139 }
140 }
141
142 pub fn class(name: Identifier) -> Self {
143 Self::new(name).with_type(QualifiedIdentifier::new(
144 Identifier::new_unchecked(stdlib::rdfs::MODULE_NAME),
145 Identifier::new_unchecked(stdlib::rdfs::CLASS),
146 ))
147 }
148
149 pub fn is_class(&self) -> bool {
150 self.body.has_rdf_type(
151 &QualifiedIdentifier::new(
152 Identifier::new_unchecked(stdlib::rdfs::MODULE_NAME),
153 Identifier::new_unchecked(stdlib::rdfs::CLASS),
154 )
155 .into(),
156 )
157 }
158
159 pub fn datatype(name: Identifier) -> Self {
160 Self::new(name).with_type(QualifiedIdentifier::new(
161 Identifier::new_unchecked(stdlib::rdfs::MODULE_NAME),
162 Identifier::new_unchecked(stdlib::rdfs::DATATYPE),
163 ))
164 }
165
166 pub fn is_datatype(&self) -> bool {
167 self.body.has_rdf_type(
168 &QualifiedIdentifier::new(
169 Identifier::new_unchecked(stdlib::rdfs::MODULE_NAME),
170 Identifier::new_unchecked(stdlib::rdfs::DATATYPE),
171 )
172 .into(),
173 )
174 }
175
176 pub fn property(name: Identifier) -> Self {
177 Self::new(name).with_type(QualifiedIdentifier::new(
178 Identifier::new_unchecked(stdlib::rdf::MODULE_NAME),
179 Identifier::new_unchecked(stdlib::rdf::PROPERTY),
180 ))
181 }
182
183 pub fn is_property(&self) -> bool {
184 self.body.has_rdf_type(
185 &QualifiedIdentifier::new(
186 Identifier::new_unchecked(stdlib::rdf::MODULE_NAME),
187 Identifier::new_unchecked(stdlib::rdf::PROPERTY),
188 )
189 .into(),
190 )
191 }
192
193 pub fn individual(name: Identifier) -> Self {
194 Self::new(name)
195 }
196}