sdml_core/model/definitions/
entities.rs1use 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#[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#[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
51impl 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 pub const fn new(name: Identifier) -> Self {
166 Self {
167 span: None,
168 name,
169 body: None,
170 }
171 }
172}
173
174impl 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 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 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 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}