1use std::collections::HashMap;
2use std::ops::Range;
3use serde::{Serialize, Deserialize};
4
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7pub enum Argument {
8 Positioned { position: usize, value: Value },
10 Named { key: String, value: Value },
12}
13
14#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
16pub enum Value {
17 String(String),
18 Number(f64),
19 Boolean(bool),
20 List(Vec<Value>),
21 Map(HashMap<String, Value>),
22 Reference(String), }
24
25#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
27pub struct ArgumentList {
28 pub arguments: Vec<Argument>,
29}
30
31impl ArgumentList {
32 pub fn new(arguments: Vec<Argument>) -> Self {
33 Self { arguments }
34 }
35
36 pub fn empty() -> Self {
37 Self { arguments: vec![] }
38 }
39
40 pub fn as_map(&self) -> HashMap<String, Value> {
41 self.arguments
42 .iter()
43 .enumerate()
44 .map(|(i, arg)| match arg {
45 Argument::Positioned { value, .. } => (i.to_string(), value.clone()),
46 Argument::Named { key, value } => (key.clone(), value.clone()),
47 })
48 .collect()
49 }
50
51 pub fn get_named(&self, key: &str) -> Option<&Value> {
52 self.arguments.iter().find_map(|arg| match arg {
53 Argument::Named { key: k, value } if k == key => Some(value),
54 _ => None,
55 })
56 }
57
58 pub fn get_positioned(&self, position: usize) -> Option<&Value> {
59 self.arguments.iter().find_map(|arg| match arg {
60 Argument::Positioned { position: p, value } if *p == position => Some(value),
61 _ => None,
62 })
63 }
64}
65
66#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
68pub struct MetaData {
69 pub internal_id: String,
70 pub name_range: Range<usize>,
71 pub block_range: Option<Range<usize>>,
72}
73
74#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
76pub struct ApplicatorSpecification {
77 pub name: String,
78 pub arguments: ArgumentList,
79 pub children: Vec<ComponentSpecification>,
80 pub internal_id: String,
81}
82
83#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
85pub enum DeclarationType {
86 Component,
88 Module,
90 ComponentKeyword,
92}
93
94#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
96pub struct ComponentSpecification {
97 pub id: String,
98 pub name: String,
99 pub declaration_type: DeclarationType,
100 pub arguments: ArgumentList,
101 pub applicators: Vec<ApplicatorSpecification>,
102 pub children: Vec<ComponentSpecification>,
103 pub metadata: MetaData,
104}
105
106impl ComponentSpecification {
107 pub fn new(
108 id: String,
109 name: String,
110 arguments: ArgumentList,
111 applicators: Vec<ApplicatorSpecification>,
112 children: Vec<ComponentSpecification>,
113 metadata: MetaData,
114 ) -> Self {
115 Self {
116 id,
117 name,
118 declaration_type: DeclarationType::Component,
119 arguments,
120 applicators,
121 children,
122 metadata,
123 }
124 }
125
126 pub fn with_declaration_type(mut self, declaration_type: DeclarationType) -> Self {
127 self.declaration_type = declaration_type;
128 self
129 }
130
131 pub fn flatten(&self) -> Vec<ComponentSpecification> {
133 let mut result = vec![self.clone()];
134 for child in &self.children {
135 result.extend(child.flatten());
136 }
137 result
138 }
139
140 pub fn to_applicator(&self) -> ApplicatorSpecification {
142 ApplicatorSpecification {
143 name: self.name.trim_start_matches('.').to_string(),
144 arguments: self.arguments.clone(),
145 children: self.children.clone(),
146 internal_id: self.metadata.internal_id.clone(),
147 }
148 }
149}
150
151#[derive(Debug, Clone)]
153pub struct ComponentOutline {
154 pub constructor_start: usize,
155 pub constructor_end: usize,
156 pub block_range: Option<Range<usize>>,
157 pub children: Vec<ComponentOutline>,
158 pub name_range: Range<usize>,
159}
160
161#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
163pub enum ImportClause {
164 Named(Vec<String>),
166 Default(String),
168}
169
170#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
172pub enum ImportSource {
173 Local(String),
175 Url(String),
177}
178
179#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
181pub struct ImportStatement {
182 pub clause: ImportClause,
184 pub source: ImportSource,
186}
187
188impl ImportStatement {
189 pub fn new(clause: ImportClause, source: ImportSource) -> Self {
190 Self { clause, source }
191 }
192
193 pub fn source_path(&self) -> &str {
195 match &self.source {
196 ImportSource::Local(path) => path,
197 ImportSource::Url(url) => url,
198 }
199 }
200
201 pub fn imported_names(&self) -> Vec<String> {
203 match &self.clause {
204 ImportClause::Named(names) => names.clone(),
205 ImportClause::Default(name) => vec![name.clone()],
206 }
207 }
208}
209
210#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
212pub struct Document {
213 pub imports: Vec<ImportStatement>,
215 pub components: Vec<ComponentSpecification>,
217}
218
219impl Document {
220 pub fn new(imports: Vec<ImportStatement>, components: Vec<ComponentSpecification>) -> Self {
221 Self { imports, components }
222 }
223
224 pub fn empty() -> Self {
225 Self { imports: vec![], components: vec![] }
226 }
227}