sdml_core/model/definitions/
rdf.rs

1use 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// ------------------------------------------------------------------------------------------------
21// Public Types ❱ Definitions ❱ RDF
22// ------------------------------------------------------------------------------------------------
23
24/// Corresponds to the grammar rule `rdf_class_def` and `rdf_property_def`.
25#[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
34// ------------------------------------------------------------------------------------------------
35// Implementations ❱ Definitions ❱ RDF
36// ------------------------------------------------------------------------------------------------
37
38impl 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    // --------------------------------------------------------------------------------------------
131    // Constructors
132    // --------------------------------------------------------------------------------------------
133
134    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}