sdml_core/model/definitions/
entities.rs

1use super::HasMultiMembers;
2use crate::load::ModuleLoader;
3use crate::model::annotations::{AnnotationBuilder, AnnotationProperty, HasAnnotations};
4use crate::model::check::{validate_multiple_method_duplicates, MaybeIncomplete};
5use crate::model::values::Value;
6use crate::model::{
7    annotations::Annotation,
8    check::Validate,
9    identifiers::{Identifier, IdentifierReference},
10    members::Member,
11    modules::Module,
12    Span,
13};
14use crate::model::{HasName, HasOptionalBody, HasSourceSpan, References};
15use crate::store::ModuleStore;
16use sdml_errors::diagnostics::functions::IdentifierCaseConvention;
17use std::collections::BTreeMap;
18use std::{collections::BTreeSet, fmt::Debug};
19
20#[cfg(feature = "serde")]
21use serde::{Deserialize, Serialize};
22
23// ------------------------------------------------------------------------------------------------
24// Public Types ❱ Definitions ❱ Entities
25// ------------------------------------------------------------------------------------------------
26
27/// Corresponds to the grammar rule `entity_def`.
28#[derive(Clone, Debug)]
29#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
30pub struct EntityDef {
31    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
32    span: Option<Span>,
33    name: Identifier,
34    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
35    body: Option<EntityBody>,
36}
37
38/// Corresponds to the grammar rule `entity_body`.
39#[derive(Clone, Debug)]
40#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
41pub struct EntityBody {
42    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
43    span: Option<Span>,
44    identity: Member,
45    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
46    annotations: Vec<Annotation>,
47    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "BTreeMap::is_empty"))]
48    members: BTreeMap<Identifier, Member>,
49}
50
51// ------------------------------------------------------------------------------------------------
52// Implementations ❱ Definitions ❱ EntityDef
53// ------------------------------------------------------------------------------------------------
54
55impl HasName for EntityDef {
56    fn name(&self) -> &Identifier {
57        &self.name
58    }
59
60    fn set_name(&mut self, name: Identifier) {
61        self.name = name;
62    }
63}
64
65impl HasOptionalBody for EntityDef {
66    type Body = EntityBody;
67
68    fn body(&self) -> Option<&Self::Body> {
69        self.body.as_ref()
70    }
71
72    fn body_mut(&mut self) -> Option<&mut Self::Body> {
73        self.body.as_mut()
74    }
75
76    fn set_body(&mut self, body: Self::Body) {
77        self.body = Some(body);
78    }
79
80    fn unset_body(&mut self) {
81        self.body = None;
82    }
83}
84
85impl HasSourceSpan for EntityDef {
86    fn with_source_span(self, span: Span) -> Self {
87        let mut self_mut = self;
88        self_mut.span = Some(span);
89        self_mut
90    }
91
92    fn source_span(&self) -> Option<&Span> {
93        self.span.as_ref()
94    }
95
96    fn set_source_span(&mut self, span: Span) {
97        self.span = Some(span);
98    }
99
100    fn unset_source_span(&mut self) {
101        self.span = None;
102    }
103}
104
105impl References for EntityDef {
106    fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
107        if let Some(inner) = &self.body {
108            inner.referenced_annotations(names);
109        }
110    }
111
112    fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
113        if let Some(inner) = &self.body {
114            inner.referenced_types(names);
115        }
116    }
117}
118
119impl AnnotationBuilder for EntityDef {
120    fn with_predicate<I, V>(self, predicate: I, value: V) -> Self
121    where
122        Self: Sized,
123        I: Into<IdentifierReference>,
124        V: Into<Value>,
125    {
126        let mut self_mut = self;
127        if let Some(ref mut inner) = self_mut.body {
128            inner.add_to_annotations(AnnotationProperty::new(predicate.into(), value.into()));
129        }
130        self_mut
131    }
132}
133
134impl MaybeIncomplete for EntityDef {
135    fn is_incomplete(&self, top: &Module, cache: &impl ModuleStore) -> bool {
136        if let Some(body) = &self.body {
137            body.is_incomplete(top, cache)
138        } else {
139            true
140        }
141    }
142}
143
144impl Validate for EntityDef {
145    fn validate(
146        &self,
147        top: &Module,
148        cache: &impl ModuleStore,
149        loader: &impl ModuleLoader,
150        check_constraints: bool,
151    ) {
152        self.name
153            .validate(top, loader, Some(IdentifierCaseConvention::TypeDefinition));
154        if let Some(body) = &self.body {
155            body.validate(top, cache, loader, check_constraints);
156        }
157    }
158}
159
160impl EntityDef {
161    // --------------------------------------------------------------------------------------------
162    // Constructors
163    // --------------------------------------------------------------------------------------------
164
165    pub const fn new(name: Identifier) -> Self {
166        Self {
167            span: None,
168            name,
169            body: None,
170        }
171    }
172}
173
174// ------------------------------------------------------------------------------------------------
175// Implementations ❱ Definitions ❱ EntityBody
176// ------------------------------------------------------------------------------------------------
177
178impl HasAnnotations for EntityBody {
179    fn has_annotations(&self) -> bool {
180        !self.annotations.is_empty()
181    }
182    fn annotation_count(&self) -> usize {
183        self.annotations.len()
184    }
185    fn annotations(&self) -> impl Iterator<Item = &Annotation> {
186        self.annotations.iter()
187    }
188    fn annotations_mut(&mut self) -> impl Iterator<Item = &mut Annotation> {
189        self.annotations.iter_mut()
190    }
191    fn add_to_annotations<I>(&mut self, value: I)
192    where
193        I: Into<Annotation>,
194    {
195        self.annotations.push(value.into())
196    }
197    fn extend_annotations<I>(&mut self, extension: I)
198    where
199        I: IntoIterator<Item = Annotation>,
200    {
201        self.annotations.extend(extension.into_iter())
202    }
203}
204
205impl HasSourceSpan for EntityBody {
206    fn with_source_span(self, span: Span) -> Self {
207        let mut self_mut = self;
208        self_mut.span = Some(span);
209        self_mut
210    }
211
212    fn source_span(&self) -> Option<&Span> {
213        self.span.as_ref()
214    }
215
216    fn set_source_span(&mut self, span: Span) {
217        self.span = Some(span);
218    }
219
220    fn unset_source_span(&mut self) {
221        self.span = None;
222    }
223}
224
225impl MaybeIncomplete for EntityBody {
226    fn is_incomplete(&self, top: &Module, cache: &impl ModuleStore) -> bool {
227        self.members().any(|elem| elem.is_incomplete(top, cache))
228    }
229}
230
231impl Validate for EntityBody {
232    fn validate(
233        &self,
234        top: &Module,
235        cache: &impl ModuleStore,
236        loader: &impl ModuleLoader,
237        check_constraints: bool,
238    ) {
239        validate_multiple_method_duplicates(self, top, cache, loader);
240
241        self.identity
242            .validate(top, cache, loader, check_constraints);
243        for annotation in &self.annotations {
244            annotation.validate(top, cache, loader, check_constraints);
245        }
246        for member in self.members() {
247            member.validate(top, cache, loader, check_constraints);
248        }
249    }
250}
251
252impl References for EntityBody {
253    fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
254        self.identity().referenced_annotations(names);
255        self.members().for_each(|m| m.referenced_annotations(names));
256    }
257
258    fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
259        self.identity().referenced_types(names);
260        self.members().for_each(|m| m.referenced_types(names));
261    }
262}
263
264impl HasMultiMembers for EntityBody {
265    fn has_any_members(&self) -> bool {
266        !(self.has_identity() || self.has_members())
267    }
268
269    fn contains_any_member(&self, name: &Identifier) -> bool {
270        self.contains_identity(name) || self.contains_member(name)
271    }
272
273    fn all_member_count(&self) -> usize {
274        self.identity_count() + self.members.len()
275    }
276
277    fn all_member_names(&self) -> impl Iterator<Item = &Identifier> {
278        self.identity_names().chain(self.member_names())
279    }
280}
281
282impl EntityBody {
283    // --------------------------------------------------------------------------------------------
284    // Constructors
285    // --------------------------------------------------------------------------------------------
286
287    pub fn new(identity: Member) -> Self {
288        Self {
289            span: None,
290            identity,
291            annotations: Default::default(),
292            members: Default::default(),
293        }
294    }
295
296    pub fn with_members<I>(self, members: I) -> Self
297    where
298        I: IntoIterator<Item = Member>,
299    {
300        let mut self_mut = self;
301        self_mut.extend_members(members);
302        self_mut
303    }
304
305    // --------------------------------------------------------------------------------------------
306    // Fields
307    // --------------------------------------------------------------------------------------------
308
309    pub const fn identity(&self) -> &Member {
310        &self.identity
311    }
312
313    pub fn set_identity(&mut self, identity: Member) {
314        self.identity = identity;
315    }
316
317    #[inline(always)]
318    const fn has_identity(&self) -> bool {
319        true
320    }
321
322    #[inline(always)]
323    const fn identity_count(&self) -> usize {
324        1
325    }
326
327    #[inline(always)]
328    fn identity_names(&self) -> impl Iterator<Item = &Identifier> {
329        std::iter::once(self.identity.name())
330    }
331
332    #[inline(always)]
333    fn contains_identity(&self, name: &Identifier) -> bool {
334        self.identity.name() == name
335    }
336
337    // --------------------------------------------------------------------------------------------
338    // Members
339    // --------------------------------------------------------------------------------------------
340
341    pub fn has_members(&self) -> bool {
342        !self.members.is_empty()
343    }
344
345    pub fn member_count(&self) -> usize {
346        self.members.len()
347    }
348
349    pub fn contains_member(&self, name: &Identifier) -> bool {
350        self.members.contains_key(name)
351    }
352
353    pub fn member(&self, name: &Identifier) -> Option<&Member> {
354        self.members.get(name)
355    }
356
357    pub fn member_mut(&mut self, name: &Identifier) -> Option<&mut Member> {
358        self.members.get_mut(name)
359    }
360
361    pub fn members(&self) -> impl Iterator<Item = &Member> {
362        self.members.values()
363    }
364
365    pub fn members_mut(&mut self) -> impl Iterator<Item = &mut Member> {
366        self.members.values_mut()
367    }
368
369    pub fn member_names(&self) -> impl Iterator<Item = &Identifier> {
370        self.members.keys()
371    }
372
373    pub fn add_to_members(&mut self, value: Member) -> Option<Member> {
374        self.members.insert(value.name().clone(), value)
375    }
376
377    pub fn extend_members<I>(&mut self, extension: I)
378    where
379        I: IntoIterator<Item = Member>,
380    {
381        self.members.extend(
382            extension
383                .into_iter()
384                .map(|elem| (elem.name().clone(), elem)),
385        )
386    }
387}