compose_lens/model/
environment.rs1use super::{BooleanValue, ComposeScalar, FieldReference, Located};
4use crate::source::SourceSpan;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct EnvironmentListEntry {
9 raw: Located<String>,
10 name: String,
11 value: Option<String>,
12}
13
14impl EnvironmentListEntry {
15 pub(super) fn parse(raw: Located<String>) -> Self {
16 let (name, value) = raw.value().split_once('=').map_or_else(
17 || (raw.value().clone(), None),
18 |(name, value)| (name.to_owned(), Some(value.to_owned())),
19 );
20 Self { raw, name, value }
21 }
22
23 #[must_use]
25 pub const fn raw(&self) -> &Located<String> {
26 &self.raw
27 }
28
29 #[must_use]
31 pub fn name(&self) -> &str {
32 &self.name
33 }
34
35 #[must_use]
39 pub fn value(&self) -> Option<&str> {
40 self.value.as_deref()
41 }
42}
43
44#[derive(Debug, Clone, PartialEq, Eq)]
46pub struct EnvironmentMapEntry {
47 name: Located<String>,
48 value: Located<ComposeScalar>,
49 span: SourceSpan,
50}
51
52impl EnvironmentMapEntry {
53 pub(super) const fn new(name: Located<String>, value: Located<ComposeScalar>, span: SourceSpan) -> Self {
54 Self { name, value, span }
55 }
56
57 #[must_use]
59 pub const fn name(&self) -> &Located<String> {
60 &self.name
61 }
62
63 #[must_use]
65 pub const fn value(&self) -> &Located<ComposeScalar> {
66 &self.value
67 }
68
69 #[must_use]
71 pub const fn span(&self) -> SourceSpan {
72 self.span
73 }
74}
75
76#[derive(Debug, Clone, PartialEq, Eq)]
78pub enum Environment {
79 List {
81 span: SourceSpan,
83 entries: Vec<EnvironmentListEntry>,
85 },
86 Map {
88 span: SourceSpan,
90 entries: Vec<EnvironmentMapEntry>,
92 },
93}
94
95impl Environment {
96 #[must_use]
98 pub const fn span(&self) -> SourceSpan {
99 match self {
100 Self::List { span, .. } | Self::Map { span, .. } => *span,
101 }
102 }
103}
104
105#[derive(Debug, Clone, PartialEq, Eq)]
107pub enum EnvironmentFile {
108 Short(Located<String>),
110 Long(Box<LongEnvironmentFile>),
112}
113
114impl EnvironmentFile {
115 #[must_use]
117 pub const fn path(&self) -> Option<&Located<String>> {
118 match self {
119 Self::Short(path) => Some(path),
120 Self::Long(value) => value.path(),
121 }
122 }
123}
124
125#[derive(Debug, Clone, PartialEq, Eq)]
127pub struct LongEnvironmentFile {
128 span: SourceSpan,
129 path: Option<Located<String>>,
130 required: Option<Located<BooleanValue>>,
131 format: Option<EnvironmentFileFormat>,
132 extension_fields: Vec<FieldReference>,
133 unknown_fields: Vec<FieldReference>,
134}
135
136impl LongEnvironmentFile {
137 pub(super) const fn new(span: SourceSpan) -> Self {
138 Self {
139 span,
140 path: None,
141 required: None,
142 format: None,
143 extension_fields: Vec::new(),
144 unknown_fields: Vec::new(),
145 }
146 }
147
148 pub(super) fn set_path(&mut self, value: Located<String>) {
149 self.path = Some(value);
150 }
151
152 pub(super) fn set_required(&mut self, value: Located<BooleanValue>) {
153 self.required = Some(value);
154 }
155
156 pub(super) fn set_format(&mut self, value: EnvironmentFileFormat) {
157 self.format = Some(value);
158 }
159
160 pub(super) fn push_extension(&mut self, value: FieldReference) {
161 self.extension_fields.push(value);
162 }
163
164 pub(super) fn push_unknown(&mut self, value: FieldReference) {
165 self.unknown_fields.push(value);
166 }
167
168 #[must_use]
170 pub const fn span(&self) -> SourceSpan {
171 self.span
172 }
173
174 #[must_use]
176 pub const fn path(&self) -> Option<&Located<String>> {
177 self.path.as_ref()
178 }
179
180 #[must_use]
182 pub const fn required(&self) -> Option<&Located<BooleanValue>> {
183 self.required.as_ref()
184 }
185
186 #[must_use]
188 pub const fn format(&self) -> Option<&EnvironmentFileFormat> {
189 self.format.as_ref()
190 }
191
192 #[must_use]
194 pub fn extension_fields(&self) -> &[FieldReference] {
195 &self.extension_fields
196 }
197
198 #[must_use]
200 pub fn unknown_fields(&self) -> &[FieldReference] {
201 &self.unknown_fields
202 }
203}
204
205#[derive(Debug, Clone, PartialEq, Eq)]
207pub struct EnvironmentFileFormat {
208 raw: Located<String>,
209 kind: EnvironmentFileFormatKind,
210}
211
212impl EnvironmentFileFormat {
213 pub(crate) fn parse(raw: Located<String>) -> Self {
214 let kind = EnvironmentFileFormatKind::classify(raw.value());
215 Self { raw, kind }
216 }
217
218 #[must_use]
220 pub const fn raw(&self) -> &Located<String> {
221 &self.raw
222 }
223
224 #[must_use]
226 pub const fn kind(&self) -> EnvironmentFileFormatKind {
227 self.kind
228 }
229
230 #[must_use]
232 pub const fn is_valid(&self) -> bool {
233 !matches!(self.kind, EnvironmentFileFormatKind::Other)
234 }
235}
236
237#[derive(Debug, Clone, Copy, PartialEq, Eq)]
239#[non_exhaustive]
240pub enum EnvironmentFileFormatKind {
241 Raw,
243 Expression,
245 Other,
247}
248
249impl EnvironmentFileFormatKind {
250 pub(crate) fn classify(value: &str) -> Self {
251 match value {
252 "raw" => Self::Raw,
253 value if value.contains('$') => Self::Expression,
254 _ => Self::Other,
255 }
256 }
257}