1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use std::ops::Range;
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), DataSourceReference(String), }
25
26#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
28pub struct ArgumentList {
29 pub arguments: Vec<Argument>,
30}
31
32impl ArgumentList {
33 pub fn new(arguments: Vec<Argument>) -> Self {
34 Self { arguments }
35 }
36
37 pub fn empty() -> Self {
38 Self { arguments: vec![] }
39 }
40
41 pub fn as_map(&self) -> HashMap<String, Value> {
42 self.arguments
43 .iter()
44 .enumerate()
45 .map(|(i, arg)| match arg {
46 Argument::Positioned { value, .. } => (i.to_string(), value.clone()),
47 Argument::Named { key, value } => (key.clone(), value.clone()),
48 })
49 .collect()
50 }
51
52 pub fn get_named(&self, key: &str) -> Option<&Value> {
53 self.arguments.iter().find_map(|arg| match arg {
54 Argument::Named { key: k, value } if k == key => Some(value),
55 _ => None,
56 })
57 }
58
59 pub fn get_positioned(&self, position: usize) -> Option<&Value> {
60 self.arguments.iter().find_map(|arg| match arg {
61 Argument::Positioned { position: p, value } if *p == position => Some(value),
62 _ => None,
63 })
64 }
65}
66
67#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
69pub struct MetaData {
70 pub internal_id: String,
71 pub name_range: Range<usize>,
72 pub block_range: Option<Range<usize>>,
73}
74
75#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
77pub struct ApplicatorSpecification {
78 pub name: String,
79 pub arguments: ArgumentList,
80 pub children: Vec<ComponentSpecification>,
81 pub internal_id: String,
82}
83
84#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
86pub enum DeclarationType {
87 Component,
89 Module,
91 ComponentKeyword,
93}
94
95#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
97pub struct ComponentSpecification {
98 pub id: String,
99 pub name: String,
100 pub declaration_type: DeclarationType,
101 pub arguments: ArgumentList,
102 pub applicators: Vec<ApplicatorSpecification>,
103 pub children: Vec<ComponentSpecification>,
104 pub metadata: MetaData,
105}
106
107impl ComponentSpecification {
108 pub fn new(
109 id: String,
110 name: String,
111 arguments: ArgumentList,
112 applicators: Vec<ApplicatorSpecification>,
113 children: Vec<ComponentSpecification>,
114 metadata: MetaData,
115 ) -> Self {
116 Self {
117 id,
118 name,
119 declaration_type: DeclarationType::Component,
120 arguments,
121 applicators,
122 children,
123 metadata,
124 }
125 }
126
127 pub fn with_declaration_type(mut self, declaration_type: DeclarationType) -> Self {
128 self.declaration_type = declaration_type;
129 self
130 }
131
132 pub fn flatten(&self) -> Vec<ComponentSpecification> {
134 let mut result = vec![self.clone()];
135 for child in &self.children {
136 result.extend(child.flatten());
137 }
138 result
139 }
140
141 pub fn to_applicator(&self) -> ApplicatorSpecification {
143 ApplicatorSpecification {
144 name: self.name.trim_start_matches('.').to_string(),
145 arguments: self.arguments.clone(),
146 children: self.children.clone(),
147 internal_id: self.metadata.internal_id.clone(),
148 }
149 }
150}
151
152#[derive(Debug, Clone)]
154pub struct ComponentOutline {
155 pub constructor_start: usize,
156 pub constructor_end: usize,
157 pub block_range: Option<Range<usize>>,
158 pub children: Vec<ComponentOutline>,
159 pub name_range: Range<usize>,
160}
161
162#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
164pub enum ImportClause {
165 Named(Vec<String>),
167 Default(String),
169}
170
171#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
173pub enum ImportSource {
174 Local(String),
176 Url(String),
178}
179
180#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
182pub struct ImportStatement {
183 pub clause: ImportClause,
185 pub source: ImportSource,
187}
188
189impl ImportStatement {
190 pub fn new(clause: ImportClause, source: ImportSource) -> Self {
191 Self { clause, source }
192 }
193
194 pub fn source_path(&self) -> &str {
196 match &self.source {
197 ImportSource::Local(path) => path,
198 ImportSource::Url(url) => url,
199 }
200 }
201
202 pub fn imported_names(&self) -> Vec<String> {
204 match &self.clause {
205 ImportClause::Named(names) => names.clone(),
206 ImportClause::Default(name) => vec![name.clone()],
207 }
208 }
209}
210
211#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
213pub struct Document {
214 pub imports: Vec<ImportStatement>,
216 pub components: Vec<ComponentSpecification>,
218}
219
220impl Document {
221 pub fn new(imports: Vec<ImportStatement>, components: Vec<ComponentSpecification>) -> Self {
222 Self {
223 imports,
224 components,
225 }
226 }
227
228 pub fn empty() -> Self {
229 Self {
230 imports: vec![],
231 components: vec![],
232 }
233 }
234}