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