Skip to main content

compose_lens/model/
value.rs

1//! Shared scalar and collection values used by the typed Compose model.
2
3use super::Located;
4use crate::source::SourceSpan;
5
6/// A Compose boolean before optional interpolation is evaluated.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum BooleanValue {
9    /// A YAML boolean literal.
10    Literal(bool),
11    /// A scalar expression whose result must later be validated as a boolean.
12    Expression(String),
13}
14
15/// A Compose Build `no_cache` value with its YAML scalar category retained.
16///
17/// Compose accepts either a YAML boolean or a string for this field. Strings, including empty
18/// and interpolation-shaped values, remain strings and are never coerced to booleans.
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub enum BuildNoCache {
21    /// A YAML boolean scalar.
22    Boolean(bool),
23    /// A YAML string scalar without boolean coercion.
24    String(String),
25}
26
27/// A Compose Build `sbom` value with its YAML scalar category retained.
28///
29/// Compose accepts either a YAML boolean or a string for this field. Strings, including empty,
30/// generator-shaped, and interpolation-shaped values, remain strings and are never coerced to
31/// booleans or interpreted as generated SBOM data.
32#[derive(Debug, Clone, PartialEq, Eq)]
33pub enum BuildSbom {
34    /// A YAML boolean scalar.
35    Boolean(bool),
36    /// A YAML string scalar without boolean coercion or generator parsing.
37    String(String),
38}
39
40/// A Compose Build `provenance` value with its YAML scalar category retained.
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub enum BuildProvenance {
43    /// A YAML boolean scalar.
44    Boolean(bool),
45    /// A YAML string scalar without attestation parsing or generation.
46    String(String),
47}
48
49/// A YAML scalar retained without applying Compose interpolation or coercion.
50#[derive(Debug, Clone, PartialEq, Eq)]
51pub enum ComposeScalar {
52    /// An explicit YAML null.
53    Null,
54    /// A YAML boolean.
55    Boolean(bool),
56    /// A numeric scalar with its authored semantic spelling retained.
57    Number(String),
58    /// A string scalar, which may still contain interpolation expressions.
59    String(String),
60}
61
62/// One source-aware key/value entry from a Compose mapping.
63#[derive(Debug, Clone, PartialEq, Eq)]
64pub struct KeyValueEntry {
65    key: Located<String>,
66    value: Located<ComposeScalar>,
67    span: SourceSpan,
68}
69
70impl KeyValueEntry {
71    pub(crate) const fn new(key: Located<String>, value: Located<ComposeScalar>, span: SourceSpan) -> Self {
72        Self { key, value, span }
73    }
74
75    /// Returns the entry key.
76    #[must_use]
77    pub const fn key(&self) -> &Located<String> {
78        &self.key
79    }
80
81    /// Returns the scalar entry value.
82    #[must_use]
83    pub const fn value(&self) -> &Located<ComposeScalar> {
84        &self.value
85    }
86
87    /// Returns the complete key/value span.
88    #[must_use]
89    pub const fn span(&self) -> SourceSpan {
90        self.span
91    }
92}
93
94/// A Compose labels value with its list or mapping form retained.
95#[derive(Debug, Clone, PartialEq, Eq)]
96pub enum Labels {
97    /// List syntax such as `com.example.role=database`.
98    List {
99        /// The complete sequence span.
100        span: SourceSpan,
101        /// Label strings in authored order.
102        values: Vec<Located<String>>,
103    },
104    /// Mapping syntax with scalar values.
105    Map {
106        /// The complete mapping span.
107        span: SourceSpan,
108        /// Label entries in authored order.
109        entries: Vec<KeyValueEntry>,
110    },
111}
112
113impl Labels {
114    /// Returns the authored collection span.
115    #[must_use]
116    pub const fn span(&self) -> SourceSpan {
117        match self {
118            Self::List { span, .. } | Self::Map { span, .. } => *span,
119        }
120    }
121}