sdml_core/model/definitions/
structures.rs1use crate::model::{
2 annotations::{Annotation, HasAnnotations},
3 check::Validate,
4 definitions::HasMembers,
5 identifiers::{Identifier, IdentifierReference},
6 members::Member,
7 References, Span,
8};
9use std::{collections::HashSet, fmt::Debug};
10
11use sdml_errors::diagnostics::functions::IdentifierCaseConvention;
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14
15#[derive(Clone, Debug)]
21#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
22pub struct StructureDef {
23 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
24 span: Option<Box<Span>>,
25 name: Identifier,
26 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
27 body: Option<StructureBody>,
28}
29
30#[derive(Clone, Debug, Default)]
32#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
33pub struct StructureBody {
34 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
35 span: Option<Box<Span>>,
36 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
37 annotations: Vec<Annotation>,
38 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
39 members: Vec<Member>,
40}
41
42impl_has_name_for!(StructureDef);
47
48impl_has_optional_body_for!(StructureDef, StructureBody);
49
50impl_has_source_span_for!(StructureDef);
51
52impl_references_for!(StructureDef => delegate optional body);
53
54impl_annotation_builder!(StructureDef, optional body);
55
56impl_maybe_incomplete_for!(StructureDef);
57
58impl Validate for StructureDef {
59 fn validate(
60 &self,
61 top: &crate::model::modules::Module,
62 cache: &impl crate::store::ModuleStore,
63 loader: &impl crate::load::ModuleLoader,
64 check_constraints: bool,
65 ) {
66 self.name
67 .validate(top, loader, Some(IdentifierCaseConvention::TypeDefinition));
68 if let Some(body) = &self.body {
69 body.validate(top, cache, loader, check_constraints);
70 }
71 }
72}
73
74impl StructureDef {
75 pub fn new(name: Identifier) -> Self {
80 Self {
81 span: None,
82 name,
83 body: None,
84 }
85 }
86}
87
88impl_has_annotations_for!(StructureBody);
91
92impl_has_members_for!(StructureBody);
93
94impl_has_source_span_for!(StructureBody);
95
96impl_maybe_incomplete_for!(StructureBody; over members);
97
98impl_validate_for_annotations_and_members!(StructureBody);
99
100impl References for StructureBody {
101 fn referenced_types<'a>(&'a self, names: &mut HashSet<&'a IdentifierReference>) {
102 self.members().for_each(|m| m.referenced_types(names));
103 }
104
105 fn referenced_annotations<'a>(&'a self, names: &mut HashSet<&'a IdentifierReference>) {
106 self.members().for_each(|m| m.referenced_annotations(names));
107 }
108}