sdml_core/model/definitions/
entities.rs1use crate::load::ModuleLoader;
2use crate::model::References;
3use crate::model::{
4 annotations::Annotation,
5 check::Validate,
6 definitions::HasMembers,
7 identifiers::{Identifier, IdentifierReference},
8 members::Member,
9 modules::Module,
10 Span,
11};
12use crate::store::ModuleStore;
13use sdml_errors::diagnostics::functions::IdentifierCaseConvention;
14use std::{collections::HashSet, fmt::Debug};
15
16#[cfg(feature = "serde")]
17use serde::{Deserialize, Serialize};
18
19#[derive(Clone, Debug)]
25#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
26pub struct EntityDef {
27 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
28 span: Option<Box<Span>>,
29 name: Identifier,
30 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
31 body: Option<EntityBody>,
32}
33
34#[derive(Clone, Debug)]
36#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
37pub struct EntityBody {
38 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
39 span: Option<Box<Span>>,
40 identity: Member,
41 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
42 annotations: Vec<Annotation>,
43 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
44 members: Vec<Member>,
45}
46
47impl_has_name_for!(EntityDef);
52
53impl_has_optional_body_for!(EntityDef, EntityBody);
54
55impl_has_source_span_for!(EntityDef);
56
57impl_references_for!(EntityDef => delegate optional body);
58
59impl_annotation_builder!(EntityDef, optional body);
60
61impl_maybe_incomplete_for!(EntityDef);
62
63impl Validate for EntityDef {
64 fn validate(
65 &self,
66 top: &Module,
67 cache: &impl ModuleStore,
68 loader: &impl ModuleLoader,
69 check_constraints: bool,
70 ) {
71 self.name
72 .validate(top, loader, Some(IdentifierCaseConvention::TypeDefinition));
73 if let Some(body) = &self.body {
74 body.validate(top, cache, loader, check_constraints);
75 }
76 }
77}
78
79impl EntityDef {
80 pub const fn new(name: Identifier) -> Self {
85 Self {
86 span: None,
87 name,
88 body: None,
89 }
90 }
91}
92
93impl_has_annotations_for!(EntityBody);
96
97impl_has_members_for!(EntityBody);
98
99impl_has_source_span_for!(EntityBody);
100
101impl_maybe_incomplete_for!(EntityBody; over members);
102
103impl Validate for EntityBody {
104 fn validate(
105 &self,
106 top: &Module,
107 cache: &impl ModuleStore,
108 loader: &impl ModuleLoader,
109 check_constraints: bool,
110 ) {
111 self.identity
112 .validate(top, cache, loader, check_constraints);
113 for annotation in &self.annotations {
114 annotation.validate(top, cache, loader, check_constraints);
115 }
116 for member in &self.members {
117 member.validate(top, cache, loader, check_constraints);
118 }
119 }
120}
121
122impl References for EntityBody {
123 fn referenced_annotations<'a>(&'a self, names: &mut HashSet<&'a IdentifierReference>) {
124 self.members().for_each(|m| m.referenced_annotations(names))
125 }
126
127 fn referenced_types<'a>(&'a self, names: &mut HashSet<&'a IdentifierReference>) {
128 self.members().for_each(|m| m.referenced_types(names))
129 }
130}
131
132impl EntityBody {
133 pub fn new(identity: Member) -> Self {
138 Self {
139 span: None,
140 identity,
141 annotations: Default::default(),
142 members: Default::default(),
143 }
144 }
145
146 get_and_set!(pub identity, set_identity => Member);
151}