Skip to main content

compose_lens/model/
provider.rs

1//! Source-aware service provider configuration.
2
3use crate::source::SourceSpan;
4
5use super::{ComposeScalar, FieldReference, Located};
6
7/// One authored scalar or sequence value in a service provider option.
8#[derive(Debug, Clone, PartialEq, Eq)]
9#[non_exhaustive]
10pub enum ProviderOptionValue {
11    /// One YAML string, number, or boolean scalar.
12    Scalar(Located<ComposeScalar>),
13    /// An ordered sequence of provider-option items.
14    Sequence {
15        /// Complete sequence span.
16        span: SourceSpan,
17        /// Valid and malformed items in authored order.
18        items: Vec<ProviderOptionItem>,
19    },
20}
21
22impl ProviderOptionValue {
23    /// Returns the complete value span.
24    #[must_use]
25    pub const fn span(&self) -> SourceSpan {
26        match self {
27            Self::Scalar(value) => value.span(),
28            Self::Sequence { span, .. } => *span,
29        }
30    }
31}
32
33/// One item in an authored provider-option sequence.
34#[derive(Debug, Clone, PartialEq, Eq)]
35#[non_exhaustive]
36pub enum ProviderOptionItem {
37    /// A YAML string, number, or boolean scalar.
38    Scalar(Located<ComposeScalar>),
39    /// A malformed item retained by source span.
40    Unmodeled {
41        /// Complete malformed-item span.
42        span: SourceSpan,
43    },
44}
45
46impl ProviderOptionItem {
47    /// Returns the complete item span.
48    #[must_use]
49    pub const fn span(&self) -> SourceSpan {
50        match self {
51            Self::Scalar(value) => value.span(),
52            Self::Unmodeled { span } => *span,
53        }
54    }
55}
56
57/// One source-aware provider option mapping entry.
58#[derive(Debug, Clone, PartialEq, Eq)]
59pub struct ProviderOption {
60    name: Located<String>,
61    value: ProviderOptionValue,
62    span: SourceSpan,
63}
64
65impl ProviderOption {
66    pub(crate) const fn new(name: Located<String>, value: ProviderOptionValue, span: SourceSpan) -> Self {
67        Self { name, value, span }
68    }
69
70    /// Returns the non-empty option name and source span.
71    #[must_use]
72    pub const fn name(&self) -> &Located<String> {
73        &self.name
74    }
75
76    /// Returns the raw scalar or ordered sequence option value.
77    #[must_use]
78    pub const fn value(&self) -> &ProviderOptionValue {
79        &self.value
80    }
81
82    /// Returns the complete key/value entry span.
83    #[must_use]
84    pub const fn span(&self) -> SourceSpan {
85        self.span
86    }
87}
88
89/// An ordered service provider-options mapping, including an explicitly empty mapping.
90#[derive(Debug, Clone, PartialEq, Eq)]
91pub struct ProviderOptions {
92    span: SourceSpan,
93    entries: Vec<ProviderOption>,
94    unmodeled_entries: Vec<FieldReference>,
95}
96
97impl ProviderOptions {
98    pub(crate) const fn new(
99        span: SourceSpan,
100        entries: Vec<ProviderOption>,
101        unmodeled_entries: Vec<FieldReference>,
102    ) -> Self {
103        Self {
104            span,
105            entries,
106            unmodeled_entries,
107        }
108    }
109
110    /// Returns the complete options mapping span.
111    #[must_use]
112    pub const fn span(&self) -> SourceSpan {
113        self.span
114    }
115
116    /// Returns valid option entries in authored order.
117    #[must_use]
118    pub fn entries(&self) -> &[ProviderOption] {
119        &self.entries
120    }
121
122    /// Returns malformed or duplicate option entries retained as evidence.
123    #[must_use]
124    pub fn unmodeled_entries(&self) -> &[FieldReference] {
125        &self.unmodeled_entries
126    }
127}
128
129/// An authored service `provider` mapping.
130#[derive(Debug, Clone, PartialEq, Eq)]
131pub struct Provider {
132    span: SourceSpan,
133    type_: Option<Located<String>>,
134    options: Option<ProviderOptions>,
135    extension_fields: Vec<FieldReference>,
136    unknown_fields: Vec<FieldReference>,
137}
138
139impl Provider {
140    pub(crate) const fn new(span: SourceSpan) -> Self {
141        Self {
142            span,
143            type_: None,
144            options: None,
145            extension_fields: Vec::new(),
146            unknown_fields: Vec::new(),
147        }
148    }
149
150    pub(crate) fn set_type(&mut self, value: Located<String>) {
151        self.type_ = Some(value);
152    }
153
154    pub(crate) fn set_options(&mut self, value: ProviderOptions) {
155        self.options = Some(value);
156    }
157
158    pub(crate) fn push_extension(&mut self, field: FieldReference) {
159        self.extension_fields.push(field);
160    }
161
162    pub(crate) fn push_unknown(&mut self, field: FieldReference) {
163        self.unknown_fields.push(field);
164    }
165
166    /// Returns the complete provider mapping span.
167    #[must_use]
168    pub const fn span(&self) -> SourceSpan {
169        self.span
170    }
171
172    /// Returns the required strict YAML-string provider type when validly authored.
173    #[must_use]
174    pub const fn type_(&self) -> Option<&Located<String>> {
175        self.type_.as_ref()
176    }
177
178    /// Returns the optional ordered provider options mapping.
179    #[must_use]
180    pub const fn options(&self) -> Option<&ProviderOptions> {
181        self.options.as_ref()
182    }
183
184    /// Returns retained parent `x-*` members.
185    #[must_use]
186    pub fn extension_fields(&self) -> &[FieldReference] {
187        &self.extension_fields
188    }
189
190    /// Returns retained unknown or malformed parent members.
191    #[must_use]
192    pub fn unknown_fields(&self) -> &[FieldReference] {
193        &self.unknown_fields
194    }
195}