Skip to main content

compose_lens/model/
network.rs

1//! Service-network attachments and top-level network definitions.
2
3use super::{BooleanValue, FieldReference, KeyValueEntry, Labels, Located};
4use crate::source::SourceSpan;
5
6/// Options for one service attachment to a network.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct ServiceNetwork {
9    name: Located<String>,
10    span: SourceSpan,
11    aliases: Vec<Located<String>>,
12    interface_name: Option<Located<String>>,
13    ipv4_address: Option<Located<String>>,
14    ipv6_address: Option<Located<String>>,
15    link_local_ips: Vec<Located<String>>,
16    mac_address: Option<Located<String>>,
17    driver_opts: Vec<KeyValueEntry>,
18    gw_priority: Option<Located<String>>,
19    priority: Option<Located<String>>,
20    extension_fields: Vec<FieldReference>,
21    unknown_fields: Vec<FieldReference>,
22}
23
24impl ServiceNetwork {
25    pub(crate) fn new(name: Located<String>, span: SourceSpan) -> Self {
26        Self {
27            name,
28            span,
29            aliases: Vec::new(),
30            interface_name: None,
31            ipv4_address: None,
32            ipv6_address: None,
33            link_local_ips: Vec::new(),
34            mac_address: None,
35            driver_opts: Vec::new(),
36            gw_priority: None,
37            priority: None,
38            extension_fields: Vec::new(),
39            unknown_fields: Vec::new(),
40        }
41    }
42
43    pub(crate) fn set_aliases(&mut self, value: Vec<Located<String>>) {
44        self.aliases = value;
45    }
46    pub(crate) fn set_interface_name(&mut self, value: Located<String>) {
47        self.interface_name = Some(value);
48    }
49    pub(crate) fn set_ipv4_address(&mut self, value: Located<String>) {
50        self.ipv4_address = Some(value);
51    }
52    pub(crate) fn set_ipv6_address(&mut self, value: Located<String>) {
53        self.ipv6_address = Some(value);
54    }
55    pub(crate) fn set_link_local_ips(&mut self, value: Vec<Located<String>>) {
56        self.link_local_ips = value;
57    }
58    pub(crate) fn set_mac_address(&mut self, value: Located<String>) {
59        self.mac_address = Some(value);
60    }
61    pub(crate) fn set_driver_opts(&mut self, value: Vec<KeyValueEntry>) {
62        self.driver_opts = value;
63    }
64    pub(crate) fn set_gw_priority(&mut self, value: Located<String>) {
65        self.gw_priority = Some(value);
66    }
67    pub(crate) fn set_priority(&mut self, value: Located<String>) {
68        self.priority = Some(value);
69    }
70    pub(crate) fn push_extension(&mut self, value: FieldReference) {
71        self.extension_fields.push(value);
72    }
73    pub(crate) fn push_unknown(&mut self, value: FieldReference) {
74        self.unknown_fields.push(value);
75    }
76
77    /// Returns the referenced top-level network name.
78    #[must_use]
79    pub const fn name(&self) -> &Located<String> {
80        &self.name
81    }
82    /// Returns the complete attachment span.
83    #[must_use]
84    pub const fn span(&self) -> SourceSpan {
85        self.span
86    }
87    /// Returns network-scoped aliases.
88    #[must_use]
89    pub fn aliases(&self) -> &[Located<String>] {
90        &self.aliases
91    }
92    /// Returns the requested interface name.
93    #[must_use]
94    pub const fn interface_name(&self) -> Option<&Located<String>> {
95        self.interface_name.as_ref()
96    }
97    /// Returns the requested IPv4 address.
98    #[must_use]
99    pub const fn ipv4_address(&self) -> Option<&Located<String>> {
100        self.ipv4_address.as_ref()
101    }
102    /// Returns the requested IPv6 address.
103    #[must_use]
104    pub const fn ipv6_address(&self) -> Option<&Located<String>> {
105        self.ipv6_address.as_ref()
106    }
107    /// Returns link-local addresses.
108    #[must_use]
109    pub fn link_local_ips(&self) -> &[Located<String>] {
110        &self.link_local_ips
111    }
112    /// Returns the network-scoped MAC address.
113    #[must_use]
114    pub const fn mac_address(&self) -> Option<&Located<String>> {
115        self.mac_address.as_ref()
116    }
117    /// Returns driver options in authored order.
118    #[must_use]
119    pub fn driver_opts(&self) -> &[KeyValueEntry] {
120        &self.driver_opts
121    }
122    /// Returns the default-gateway priority without applying interpolation or defaults.
123    #[must_use]
124    pub const fn gw_priority(&self) -> Option<&Located<String>> {
125        self.gw_priority.as_ref()
126    }
127    /// Returns connection priority without applying interpolation or defaults.
128    #[must_use]
129    pub const fn priority(&self) -> Option<&Located<String>> {
130        self.priority.as_ref()
131    }
132    /// Returns retained `x-` fields.
133    #[must_use]
134    pub fn extension_fields(&self) -> &[FieldReference] {
135        &self.extension_fields
136    }
137    /// Returns unrecognized attachment fields.
138    #[must_use]
139    pub fn unknown_fields(&self) -> &[FieldReference] {
140        &self.unknown_fields
141    }
142}
143
144/// Service network syntax, retained as a sequence or mapping.
145#[derive(Debug, Clone, PartialEq, Eq)]
146pub enum ServiceNetworks {
147    /// Sequence syntax containing network names only.
148    Short {
149        /// The complete sequence span.
150        span: SourceSpan,
151        /// Network names in authored order.
152        names: Vec<Located<String>>,
153    },
154    /// Mapping syntax containing per-network options.
155    Long {
156        /// The complete mapping span.
157        span: SourceSpan,
158        /// Attachments in authored order.
159        networks: Vec<ServiceNetwork>,
160    },
161}
162
163impl ServiceNetworks {
164    /// Returns the complete service-networks span.
165    #[must_use]
166    pub const fn span(&self) -> SourceSpan {
167        match self {
168            Self::Short { span, .. } | Self::Long { span, .. } => *span,
169        }
170    }
171}
172
173/// One top-level IPAM subnet configuration.
174#[derive(Debug, Clone, PartialEq, Eq)]
175pub struct IpamConfig {
176    span: SourceSpan,
177    subnet: Option<Located<String>>,
178    ip_range: Option<Located<String>>,
179    gateway: Option<Located<String>>,
180    aux_addresses: Vec<KeyValueEntry>,
181    extension_fields: Vec<FieldReference>,
182    unknown_fields: Vec<FieldReference>,
183}
184
185impl IpamConfig {
186    pub(crate) fn new(span: SourceSpan) -> Self {
187        Self {
188            span,
189            subnet: None,
190            ip_range: None,
191            gateway: None,
192            aux_addresses: Vec::new(),
193            extension_fields: Vec::new(),
194            unknown_fields: Vec::new(),
195        }
196    }
197    pub(crate) fn set_subnet(&mut self, value: Located<String>) {
198        self.subnet = Some(value);
199    }
200    pub(crate) fn set_ip_range(&mut self, value: Located<String>) {
201        self.ip_range = Some(value);
202    }
203    pub(crate) fn set_gateway(&mut self, value: Located<String>) {
204        self.gateway = Some(value);
205    }
206    pub(crate) fn set_aux_addresses(&mut self, value: Vec<KeyValueEntry>) {
207        self.aux_addresses = value;
208    }
209    pub(crate) fn push_extension(&mut self, value: FieldReference) {
210        self.extension_fields.push(value);
211    }
212    pub(crate) fn push_unknown(&mut self, value: FieldReference) {
213        self.unknown_fields.push(value);
214    }
215
216    /// Returns the complete configuration span.
217    #[must_use]
218    pub const fn span(&self) -> SourceSpan {
219        self.span
220    }
221    /// Returns the subnet.
222    #[must_use]
223    pub const fn subnet(&self) -> Option<&Located<String>> {
224        self.subnet.as_ref()
225    }
226    /// Returns the allocation range.
227    #[must_use]
228    pub const fn ip_range(&self) -> Option<&Located<String>> {
229        self.ip_range.as_ref()
230    }
231    /// Returns the gateway.
232    #[must_use]
233    pub const fn gateway(&self) -> Option<&Located<String>> {
234        self.gateway.as_ref()
235    }
236    /// Returns auxiliary addresses.
237    #[must_use]
238    pub fn aux_addresses(&self) -> &[KeyValueEntry] {
239        &self.aux_addresses
240    }
241    /// Returns retained `x-` fields.
242    #[must_use]
243    pub fn extension_fields(&self) -> &[FieldReference] {
244        &self.extension_fields
245    }
246    /// Returns unrecognized fields.
247    #[must_use]
248    pub fn unknown_fields(&self) -> &[FieldReference] {
249        &self.unknown_fields
250    }
251}
252
253/// Top-level network IPAM configuration.
254#[derive(Debug, Clone, PartialEq, Eq)]
255pub struct Ipam {
256    span: SourceSpan,
257    driver: Option<Located<String>>,
258    config: Vec<IpamConfig>,
259    options: Vec<KeyValueEntry>,
260    extension_fields: Vec<FieldReference>,
261    unknown_fields: Vec<FieldReference>,
262}
263
264impl Ipam {
265    pub(crate) fn new(span: SourceSpan) -> Self {
266        Self {
267            span,
268            driver: None,
269            config: Vec::new(),
270            options: Vec::new(),
271            extension_fields: Vec::new(),
272            unknown_fields: Vec::new(),
273        }
274    }
275    pub(crate) fn set_driver(&mut self, value: Located<String>) {
276        self.driver = Some(value);
277    }
278    pub(crate) fn set_config(&mut self, value: Vec<IpamConfig>) {
279        self.config = value;
280    }
281    pub(crate) fn set_options(&mut self, value: Vec<KeyValueEntry>) {
282        self.options = value;
283    }
284    pub(crate) fn push_extension(&mut self, value: FieldReference) {
285        self.extension_fields.push(value);
286    }
287    pub(crate) fn push_unknown(&mut self, value: FieldReference) {
288        self.unknown_fields.push(value);
289    }
290
291    /// Returns the complete IPAM mapping span.
292    #[must_use]
293    pub const fn span(&self) -> SourceSpan {
294        self.span
295    }
296    /// Returns the IPAM driver.
297    #[must_use]
298    pub const fn driver(&self) -> Option<&Located<String>> {
299        self.driver.as_ref()
300    }
301    /// Returns subnet configurations.
302    #[must_use]
303    pub fn config(&self) -> &[IpamConfig] {
304        &self.config
305    }
306    /// Returns driver-specific options.
307    #[must_use]
308    pub fn options(&self) -> &[KeyValueEntry] {
309        &self.options
310    }
311    /// Returns retained `x-` fields.
312    #[must_use]
313    pub fn extension_fields(&self) -> &[FieldReference] {
314        &self.extension_fields
315    }
316    /// Returns unrecognized fields.
317    #[must_use]
318    pub fn unknown_fields(&self) -> &[FieldReference] {
319        &self.unknown_fields
320    }
321}
322
323/// A typed top-level Compose network definition.
324#[derive(Debug, Clone, PartialEq, Eq)]
325pub struct NetworkDefinition {
326    name: Located<String>,
327    span: SourceSpan,
328    driver: Option<Located<String>>,
329    driver_opts: Vec<KeyValueEntry>,
330    attachable: Option<Located<BooleanValue>>,
331    enable_ipv4: Option<Located<BooleanValue>>,
332    enable_ipv6: Option<Located<BooleanValue>>,
333    external: Option<Located<BooleanValue>>,
334    internal: Option<Located<BooleanValue>>,
335    ipam: Option<Ipam>,
336    labels: Option<Labels>,
337    custom_name: Option<Located<String>>,
338    extension_fields: Vec<FieldReference>,
339    unknown_fields: Vec<FieldReference>,
340}
341
342impl NetworkDefinition {
343    pub(crate) fn new(name: Located<String>, span: SourceSpan) -> Self {
344        Self {
345            name,
346            span,
347            driver: None,
348            driver_opts: Vec::new(),
349            attachable: None,
350            enable_ipv4: None,
351            enable_ipv6: None,
352            external: None,
353            internal: None,
354            ipam: None,
355            labels: None,
356            custom_name: None,
357            extension_fields: Vec::new(),
358            unknown_fields: Vec::new(),
359        }
360    }
361    pub(crate) fn set_driver(&mut self, value: Located<String>) {
362        self.driver = Some(value);
363    }
364    pub(crate) fn set_driver_opts(&mut self, value: Vec<KeyValueEntry>) {
365        self.driver_opts = value;
366    }
367    pub(crate) fn set_attachable(&mut self, value: Located<BooleanValue>) {
368        self.attachable = Some(value);
369    }
370    pub(crate) fn set_enable_ipv4(&mut self, value: Located<BooleanValue>) {
371        self.enable_ipv4 = Some(value);
372    }
373    pub(crate) fn set_enable_ipv6(&mut self, value: Located<BooleanValue>) {
374        self.enable_ipv6 = Some(value);
375    }
376    pub(crate) fn set_external(&mut self, value: Located<BooleanValue>) {
377        self.external = Some(value);
378    }
379    pub(crate) fn set_internal(&mut self, value: Located<BooleanValue>) {
380        self.internal = Some(value);
381    }
382    pub(crate) fn set_ipam(&mut self, value: Ipam) {
383        self.ipam = Some(value);
384    }
385    pub(crate) fn set_labels(&mut self, value: Labels) {
386        self.labels = Some(value);
387    }
388    pub(crate) fn set_custom_name(&mut self, value: Located<String>) {
389        self.custom_name = Some(value);
390    }
391    pub(crate) fn push_extension(&mut self, value: FieldReference) {
392        self.extension_fields.push(value);
393    }
394    pub(crate) fn push_unknown(&mut self, value: FieldReference) {
395        self.unknown_fields.push(value);
396    }
397
398    /// Returns the model identifier used by services.
399    #[must_use]
400    pub const fn name(&self) -> &Located<String> {
401        &self.name
402    }
403    /// Returns the complete definition span.
404    #[must_use]
405    pub const fn span(&self) -> SourceSpan {
406        self.span
407    }
408    /// Returns the network driver.
409    #[must_use]
410    pub const fn driver(&self) -> Option<&Located<String>> {
411        self.driver.as_ref()
412    }
413    /// Returns driver options.
414    #[must_use]
415    pub fn driver_opts(&self) -> &[KeyValueEntry] {
416        &self.driver_opts
417    }
418    /// Returns the attachable setting.
419    #[must_use]
420    pub const fn attachable(&self) -> Option<&Located<BooleanValue>> {
421        self.attachable.as_ref()
422    }
423    /// Returns the IPv4 setting.
424    #[must_use]
425    pub const fn enable_ipv4(&self) -> Option<&Located<BooleanValue>> {
426        self.enable_ipv4.as_ref()
427    }
428    /// Returns the IPv6 setting.
429    #[must_use]
430    pub const fn enable_ipv6(&self) -> Option<&Located<BooleanValue>> {
431        self.enable_ipv6.as_ref()
432    }
433    /// Returns the external-lifecycle setting.
434    #[must_use]
435    pub const fn external(&self) -> Option<&Located<BooleanValue>> {
436        self.external.as_ref()
437    }
438    /// Returns the internal-network setting.
439    #[must_use]
440    pub const fn internal(&self) -> Option<&Located<BooleanValue>> {
441        self.internal.as_ref()
442    }
443    /// Returns IPAM configuration.
444    #[must_use]
445    pub const fn ipam(&self) -> Option<&Ipam> {
446        self.ipam.as_ref()
447    }
448    /// Returns labels with their syntax form retained.
449    #[must_use]
450    pub const fn labels(&self) -> Option<&Labels> {
451        self.labels.as_ref()
452    }
453    /// Returns the platform-level custom name.
454    #[must_use]
455    pub const fn custom_name(&self) -> Option<&Located<String>> {
456        self.custom_name.as_ref()
457    }
458    /// Returns retained `x-` fields.
459    #[must_use]
460    pub fn extension_fields(&self) -> &[FieldReference] {
461        &self.extension_fields
462    }
463    /// Returns unrecognized fields.
464    #[must_use]
465    pub fn unknown_fields(&self) -> &[FieldReference] {
466        &self.unknown_fields
467    }
468}