Skip to main content

cml/types/
use.rs

1// Copyright 2025 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::types::common::*;
6use crate::{
7    AnyRef, Canonicalize, CanonicalizeContext, CapabilityClause, ConfigNestedValueType, ConfigType,
8    DictionaryRef, Error, EventScope, FilterClause, FromClause, FromClauseContext, PathClause,
9};
10
11use crate::one_or_many::{OneOrMany, always_one, always_one_context, option_one_or_many_as_ref};
12use crate::types::right::{Rights, RightsClause};
13pub use cm_types::{
14    Availability, BorrowedName, DependencyType, HandleType, Name, OnTerminate, ParseError, Path,
15    RelativePath, StartupMode, Url,
16};
17use cml_macro::Reference;
18use reference_doc::ReferenceDoc;
19use serde::{Deserialize, Serialize};
20use serde_json::{Map, Value};
21use std::num::NonZeroU32;
22
23use std::fmt;
24use std::path::PathBuf;
25use std::sync::Arc;
26
27/// A reference in a `use from`.
28#[derive(Debug, PartialEq, Eq, Hash, Clone, Reference)]
29#[reference(
30    expected = "\"parent\", \"framework\", \"debug\", \"self\", \"#<capability-name>\", \"#<child-name>\", \"#<collection-name>\", dictionary path, or none"
31)]
32pub enum UseFromRef {
33    /// A reference to the parent.
34    Parent,
35    /// A reference to the framework.
36    Framework,
37    /// A reference to debug.
38    Debug,
39    /// A reference to a child, collection, or a capability declared on self.
40    ///
41    /// A reference to a capability must be one of the following:
42    /// - A dictionary capability.
43    /// - A protocol that references a storage capability declared in the same component,
44    ///   which will cause the framework to host a fuchsia.sys2.StorageAdmin protocol for the
45    ///   component.
46    ///
47    /// A reference to a collection must be a service capability.
48    ///
49    /// This cannot be used to directly access capabilities that a component itself declares.
50    Named(Name),
51    /// A reference to this component.
52    Self_,
53    /// A reference to a dictionary.
54    Dictionary(DictionaryRef),
55}
56
57/// Example:
58///
59/// ```json5
60/// use: [
61///     {
62///         protocol: [
63///             "fuchsia.ui.scenic.Scenic",
64///             "fuchsia.accessibility.Manager",
65///         ]
66///     },
67///     {
68///         directory: "themes",
69///         path: "/data/themes",
70///         rights: [ "r*" ],
71///     },
72///     {
73///         storage: "persistent",
74///         path: "/data",
75///     },
76///     {
77///         event_stream: [
78///             "started",
79///             "stopped",
80///         ],
81///         from: "framework",
82///     },
83///     {
84///         runner: "own_test_runner".
85///         from: "#test_runner",
86///     },
87/// ],
88/// ```
89#[derive(Deserialize, Debug, Default, PartialEq, Clone, ReferenceDoc, Serialize)]
90#[serde(deny_unknown_fields)]
91#[reference_doc(fields_as = "list", top_level_doc_after_fields)]
92pub struct Use {
93    /// When using a service capability, the [name](#name) of a [service capability][doc-service].
94    #[serde(skip_serializing_if = "Option::is_none")]
95    #[reference_doc(skip = true)]
96    pub service: Option<OneOrMany<Name>>,
97
98    /// When using a protocol capability, the [name](#name) of a [protocol capability][doc-protocol].
99    #[serde(skip_serializing_if = "Option::is_none")]
100    #[reference_doc(skip = true)]
101    pub protocol: Option<OneOrMany<Name>>,
102
103    /// When using a directory capability, the [name](#name) of a [directory capability][doc-directory].
104    #[serde(skip_serializing_if = "Option::is_none")]
105    #[reference_doc(skip = true)]
106    pub directory: Option<Name>,
107
108    /// When using a storage capability, the [name](#name) of a [storage capability][doc-storage].
109    #[serde(skip_serializing_if = "Option::is_none")]
110    #[reference_doc(skip = true)]
111    pub storage: Option<Name>,
112
113    /// When using an event stream capability, the [name](#name) of an [event stream capability][doc-event].
114    #[serde(skip_serializing_if = "Option::is_none")]
115    #[reference_doc(skip = true)]
116    pub event_stream: Option<OneOrMany<Name>>,
117
118    /// When using a runner capability, the [name](#name) of a [runner capability][doc-runners].
119    #[serde(skip_serializing_if = "Option::is_none")]
120    #[reference_doc(skip = true)]
121    pub runner: Option<Name>,
122
123    /// When using a configuration capability, the [name](#name) of a [configuration capability][doc-configuration].
124    #[serde(skip_serializing_if = "Option::is_none")]
125    #[reference_doc(skip = true)]
126    pub config: Option<Name>,
127
128    /// When using a dictionary capability, the [name](#name) of a [dictionary capability][doc-dictionary].
129    #[serde(skip_serializing_if = "Option::is_none")]
130    #[reference_doc(skip = true)]
131    pub dictionary: Option<OneOrMany<Name>>,
132
133    /// The source of the capability. Defaults to `parent`.  One of:
134    /// - `parent`: The component's parent.
135    /// - `debug`: One of [`debug_capabilities`][fidl-environment-decl] in the
136    ///     environment assigned to this component.
137    /// - `framework`: The Component Framework runtime.
138    /// - `self`: This component.
139    /// - `#<capability-name>`: The name of another capability from which the
140    ///     requested capability is derived.
141    /// - `#<child-name>`: A [reference](#references) to a child component
142    ///     instance.
143    ///
144    /// [fidl-environment-decl]: /reference/fidl/fuchsia.component.decl#Environment
145    #[serde(skip_serializing_if = "Option::is_none")]
146    pub from: Option<UseFromRef>,
147
148    /// The path at which to install the capability in the component's namespace. For protocols,
149    /// defaults to `/svc/${protocol}`.  Required for `directory` and `storage`. This property is
150    /// disallowed for declarations with arrays of capability names and for runner capabilities.
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub path: Option<Path>,
153
154    /// A processargs ordinal (aka. "numbered handle") over which a channel to this protocol will
155    /// be delivered to the component's processargs.
156    ///
157    // TODO: We could support strings like "PA_*", but it's not clear that's necessary since usage
158    // of this feature is expected to be limited.
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub numbered_handle: Option<HandleType>,
161
162    /// (`directory` only) the maximum [directory rights][doc-directory-rights] to apply to
163    /// the directory in the component's namespace.
164    #[serde(skip_serializing_if = "Option::is_none")]
165    #[reference_doc(json_type = "array of string")]
166    pub rights: Option<Rights>,
167
168    /// (`directory` only) A subdirectory within the directory capability to provide in the
169    /// component's namespace.
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub subdir: Option<RelativePath>,
172
173    /// (`event_stream` only) When defined the event stream will contain events about only the
174    /// components defined in the scope.
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub scope: Option<OneOrMany<EventScope>>,
177
178    /// (`event_stream` only) Capability requested event streams require specifying a filter
179    /// referring to the protocol to which the events in the event stream apply. The content of the
180    /// filter will be an object mapping from "name" to the "protocol name".
181    #[serde(skip_serializing_if = "Option::is_none")]
182    pub filter: Option<Map<String, Value>>,
183
184    /// The type of dependency between the source and
185    /// this component, one of:
186    /// - `strong`: a strong dependency, which is used to determine shutdown
187    ///     ordering. Component manager is guaranteed to stop the target before the
188    ///     source. This is the default.
189    /// - `weak`: a weak dependency, which is ignored during shutdown. When component manager
190    ///     stops the parent realm, the source may stop before the clients. Clients of weak
191    ///     dependencies must be able to handle these dependencies becoming unavailable.
192    /// This property is disallowed for runner capabilities, which are always a `strong` dependency.
193    #[serde(skip_serializing_if = "Option::is_none")]
194    pub dependency: Option<DependencyType>,
195
196    /// The expectations around this capability's availability. One
197    /// of:
198    /// - `required` (default): a required dependency, the component is unable to perform its
199    ///     work without this capability.
200    /// - `optional`: an optional dependency, the component will be able to function without this
201    ///     capability (although if the capability is unavailable some functionality may be
202    ///     disabled).
203    /// - `transitional`: the source may omit the route completely without even having to route
204    ///     from `void`. Used for soft transitions that introduce new capabilities.
205    /// This property is disallowed for runner capabilities, which are always `required`.
206    ///
207    /// For more information, see the
208    /// [availability](/docs/concepts/components/v2/capabilities/availability.md) documentation.
209    #[serde(skip_serializing_if = "Option::is_none")]
210    pub availability: Option<Availability>,
211
212    /// (`config` only) The configuration key in the component's `config` block that this capability
213    /// will set.
214    #[serde(skip_serializing_if = "Option::is_none")]
215    pub key: Option<Name>,
216
217    /// (`config` only) The type of configuration, one of:
218    /// - `bool`: Boolean type.
219    /// - `uint8`: Unsigned 8 bit type.
220    /// - `uint16`: Unsigned 16 bit type.
221    /// - `uint32`: Unsigned 32 bit type.
222    /// - `uint64`: Unsigned 64 bit type.
223    /// - `int8`: Signed 8 bit type.
224    /// - `int16`: Signed 16 bit type.
225    /// - `int32`: Signed 32 bit type.
226    /// - `int64`: Signed 64 bit type.
227    /// - `string`: ASCII string type.
228    /// - `vector`: Vector type. See `element` for the type of the element within the vector
229    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
230    #[reference_doc(rename = "type")]
231    pub config_type: Option<ConfigType>,
232
233    /// (`configuration` only) Only supported if this configuration `type` is 'string'.
234    /// This is the max size of the string.
235    #[serde(rename = "max_size", skip_serializing_if = "Option::is_none")]
236    #[reference_doc(rename = "max_size")]
237    pub config_max_size: Option<NonZeroU32>,
238
239    /// (`configuration` only) Only supported if this configuration `type` is 'vector'.
240    /// This is the max number of elements in the vector.
241    #[serde(rename = "max_count", skip_serializing_if = "Option::is_none")]
242    #[reference_doc(rename = "max_count")]
243    pub config_max_count: Option<NonZeroU32>,
244
245    /// (`configuration` only) Only supported if this configuration `type` is 'vector'.
246    /// This is the type of the elements in the configuration vector.
247    ///
248    /// Example (simple type):
249    ///
250    /// ```json5
251    /// { type: "uint8" }
252    /// ```
253    ///
254    /// Example (string type):
255    ///
256    /// ```json5
257    /// {
258    ///   type: "string",
259    ///   max_size: 100,
260    /// }
261    /// ```
262    #[serde(rename = "element", skip_serializing_if = "Option::is_none")]
263    #[reference_doc(rename = "element", json_type = "object")]
264    pub config_element_type: Option<ConfigNestedValueType>,
265
266    /// (`configuration` only) The default value of this configuration.
267    /// Default values are used if the capability is optional and routed from `void`.
268    /// This is only supported if `availability` is not `required``.
269    #[serde(rename = "default", skip_serializing_if = "Option::is_none")]
270    #[reference_doc(rename = "default")]
271    pub config_default: Option<serde_json::Value>,
272}
273
274impl Canonicalize for Use {
275    fn canonicalize(&mut self) {
276        // Sort the names of the capabilities. Only capabilities with OneOrMany values are included here.
277        if let Some(service) = &mut self.service {
278            service.canonicalize();
279        } else if let Some(protocol) = &mut self.protocol {
280            protocol.canonicalize();
281        } else if let Some(event_stream) = &mut self.event_stream {
282            event_stream.canonicalize();
283            if let Some(scope) = &mut self.scope {
284                scope.canonicalize();
285            }
286        }
287    }
288}
289
290impl RightsClause for Use {
291    fn rights(&self) -> Option<&Rights> {
292        self.rights.as_ref()
293    }
294}
295
296impl CapabilityClause for Use {
297    fn service(&self) -> Option<OneOrMany<&BorrowedName>> {
298        option_one_or_many_as_ref(&self.service)
299    }
300    fn protocol(&self) -> Option<OneOrMany<&BorrowedName>> {
301        option_one_or_many_as_ref(&self.protocol)
302    }
303    fn directory(&self) -> Option<OneOrMany<&BorrowedName>> {
304        self.directory.as_ref().map(|n| OneOrMany::One(n.as_ref()))
305    }
306    fn storage(&self) -> Option<OneOrMany<&BorrowedName>> {
307        self.storage.as_ref().map(|n| OneOrMany::One(n.as_ref()))
308    }
309    fn runner(&self) -> Option<OneOrMany<&BorrowedName>> {
310        self.runner.as_ref().map(|n| OneOrMany::One(n.as_ref()))
311    }
312    fn resolver(&self) -> Option<OneOrMany<&BorrowedName>> {
313        None
314    }
315    fn event_stream(&self) -> Option<OneOrMany<&BorrowedName>> {
316        option_one_or_many_as_ref(&self.event_stream)
317    }
318    fn dictionary(&self) -> Option<OneOrMany<&BorrowedName>> {
319        option_one_or_many_as_ref(&self.dictionary)
320    }
321    fn config(&self) -> Option<OneOrMany<&BorrowedName>> {
322        self.config.as_ref().map(|n| OneOrMany::One(n.as_ref()))
323    }
324
325    fn set_service(&mut self, o: Option<OneOrMany<Name>>) {
326        self.service = o;
327    }
328    fn set_protocol(&mut self, o: Option<OneOrMany<Name>>) {
329        self.protocol = o;
330    }
331    fn set_directory(&mut self, o: Option<OneOrMany<Name>>) {
332        self.directory = always_one(o);
333    }
334    fn set_storage(&mut self, o: Option<OneOrMany<Name>>) {
335        self.storage = always_one(o);
336    }
337    fn set_runner(&mut self, _o: Option<OneOrMany<Name>>) {}
338    fn set_resolver(&mut self, _o: Option<OneOrMany<Name>>) {}
339    fn set_event_stream(&mut self, o: Option<OneOrMany<Name>>) {
340        self.event_stream = o;
341    }
342    fn set_dictionary(&mut self, _o: Option<OneOrMany<Name>>) {}
343    fn set_config(&mut self, o: Option<OneOrMany<Name>>) {
344        self.config = always_one(o);
345    }
346
347    fn availability(&self) -> Option<Availability> {
348        self.availability
349    }
350    fn set_availability(&mut self, a: Option<Availability>) {
351        self.availability = a;
352    }
353
354    fn decl_type(&self) -> &'static str {
355        "use"
356    }
357    fn supported(&self) -> &[&'static str] {
358        &[
359            "service",
360            "protocol",
361            "directory",
362            "storage",
363            "event_stream",
364            "runner",
365            "config",
366            "dictionary",
367        ]
368    }
369    fn are_many_names_allowed(&self) -> bool {
370        ["service", "protocol", "event_stream"].contains(&self.capability_type().unwrap())
371    }
372}
373
374impl FilterClause for Use {
375    fn filter(&self) -> Option<&Map<String, Value>> {
376        self.filter.as_ref()
377    }
378}
379
380impl PathClause for Use {
381    fn path(&self) -> Option<&Path> {
382        self.path.as_ref()
383    }
384}
385
386impl FromClause for Use {
387    fn from_(&self) -> OneOrMany<AnyRef<'_>> {
388        let one = match &self.from {
389            Some(from) => AnyRef::from(from),
390            // Default for `use`.
391            None => AnyRef::Parent,
392        };
393        OneOrMany::One(one)
394    }
395}
396
397#[derive(Debug, Clone, Default, Serialize)]
398pub struct ContextUse {
399    #[serde(skip)]
400    pub origin: Arc<PathBuf>,
401    #[serde(skip_serializing_if = "Option::is_none")]
402    pub service: Option<ContextSpanned<OneOrMany<Name>>>,
403    #[serde(skip_serializing_if = "Option::is_none")]
404    pub protocol: Option<ContextSpanned<OneOrMany<Name>>>,
405    #[serde(skip_serializing_if = "Option::is_none")]
406    pub directory: Option<ContextSpanned<Name>>,
407    #[serde(skip_serializing_if = "Option::is_none")]
408    pub storage: Option<ContextSpanned<Name>>,
409    #[serde(skip_serializing_if = "Option::is_none")]
410    pub event_stream: Option<ContextSpanned<OneOrMany<Name>>>,
411    #[serde(skip_serializing_if = "Option::is_none")]
412    pub runner: Option<ContextSpanned<Name>>,
413    #[serde(skip_serializing_if = "Option::is_none")]
414    pub config: Option<ContextSpanned<Name>>,
415    #[serde(skip_serializing_if = "Option::is_none")]
416    pub dictionary: Option<ContextSpanned<OneOrMany<Name>>>,
417    #[serde(skip_serializing_if = "Option::is_none")]
418    pub from: Option<ContextSpanned<UseFromRef>>,
419    #[serde(skip_serializing_if = "Option::is_none")]
420    pub path: Option<ContextSpanned<Path>>,
421    #[serde(skip_serializing_if = "Option::is_none")]
422    pub numbered_handle: Option<ContextSpanned<HandleType>>,
423    #[serde(skip_serializing_if = "Option::is_none")]
424    pub rights: Option<ContextSpanned<Rights>>,
425    #[serde(skip_serializing_if = "Option::is_none")]
426    pub subdir: Option<ContextSpanned<RelativePath>>,
427    #[serde(skip_serializing_if = "Option::is_none")]
428    pub scope: Option<ContextSpanned<OneOrMany<EventScope>>>,
429    #[serde(skip_serializing_if = "Option::is_none")]
430    pub filter: Option<ContextSpanned<Map<String, Value>>>,
431    #[serde(skip_serializing_if = "Option::is_none")]
432    pub dependency: Option<ContextSpanned<DependencyType>>,
433    #[serde(skip_serializing_if = "Option::is_none")]
434    pub availability: Option<ContextSpanned<Availability>>,
435    #[serde(skip_serializing_if = "Option::is_none")]
436    pub key: Option<ContextSpanned<Name>>,
437    #[serde(skip_serializing_if = "Option::is_none")]
438    pub config_type: Option<ContextSpanned<ConfigType>>, // todo rename?
439    #[serde(skip_serializing_if = "Option::is_none")]
440    pub config_max_size: Option<ContextSpanned<NonZeroU32>>,
441    #[serde(skip_serializing_if = "Option::is_none")]
442    pub config_max_count: Option<ContextSpanned<NonZeroU32>>,
443    #[serde(skip_serializing_if = "Option::is_none")]
444    pub config_element_type: Option<ContextSpanned<ConfigNestedValueType>>,
445    #[serde(skip_serializing_if = "Option::is_none")]
446    pub config_default: Option<ContextSpanned<serde_json::Value>>,
447}
448
449impl ContextCapabilityClause for ContextUse {
450    fn service(&self) -> Option<ContextSpanned<OneOrMany<&BorrowedName>>> {
451        option_one_or_many_as_ref_context(&self.service)
452    }
453    fn protocol(&self) -> Option<ContextSpanned<OneOrMany<&BorrowedName>>> {
454        option_one_or_many_as_ref_context(&self.protocol)
455    }
456    fn directory(&self) -> Option<ContextSpanned<OneOrMany<&BorrowedName>>> {
457        self.directory.as_ref().map(|s| ContextSpanned {
458            value: OneOrMany::One((s.value).as_ref()),
459            origin: s.origin.clone(),
460        })
461    }
462    fn storage(&self) -> Option<ContextSpanned<OneOrMany<&BorrowedName>>> {
463        self.storage.as_ref().map(|s| ContextSpanned {
464            value: OneOrMany::One((s.value).as_ref()),
465            origin: s.origin.clone(),
466        })
467    }
468    fn runner(&self) -> Option<ContextSpanned<OneOrMany<&BorrowedName>>> {
469        self.runner.as_ref().map(|s| ContextSpanned {
470            value: OneOrMany::One((s.value).as_ref()),
471            origin: s.origin.clone(),
472        })
473    }
474    fn resolver(&self) -> Option<ContextSpanned<OneOrMany<&BorrowedName>>> {
475        None
476    }
477    fn event_stream(&self) -> Option<ContextSpanned<OneOrMany<&BorrowedName>>> {
478        option_one_or_many_as_ref_context(&self.event_stream)
479    }
480    fn dictionary(&self) -> Option<ContextSpanned<OneOrMany<&BorrowedName>>> {
481        option_one_or_many_as_ref_context(&self.dictionary)
482    }
483    fn config(&self) -> Option<ContextSpanned<OneOrMany<&BorrowedName>>> {
484        self.config.as_ref().map(|s| ContextSpanned {
485            value: OneOrMany::One((s.value).as_ref()),
486            origin: s.origin.clone(),
487        })
488    }
489
490    fn decl_type(&self) -> &'static str {
491        "use"
492    }
493    fn supported(&self) -> &[&'static str] {
494        &[
495            "service",
496            "protocol",
497            "directory",
498            "storage",
499            "event_stream",
500            "runner",
501            "config",
502            "dictionary",
503        ]
504    }
505
506    fn are_many_names_allowed(&self) -> bool {
507        ["service", "protocol", "event_stream"].contains(&self.capability_type(None).unwrap())
508    }
509
510    fn set_service(&mut self, o: Option<ContextSpanned<OneOrMany<Name>>>) {
511        self.service = o;
512    }
513    fn set_protocol(&mut self, o: Option<ContextSpanned<OneOrMany<Name>>>) {
514        self.protocol = o;
515    }
516    fn set_directory(&mut self, o: Option<ContextSpanned<OneOrMany<Name>>>) {
517        self.directory = always_one_context(o);
518    }
519    fn set_storage(&mut self, o: Option<ContextSpanned<OneOrMany<Name>>>) {
520        self.storage = always_one_context(o);
521    }
522    fn set_runner(&mut self, _o: Option<ContextSpanned<OneOrMany<Name>>>) {}
523    fn set_resolver(&mut self, _o: Option<ContextSpanned<OneOrMany<Name>>>) {}
524    fn set_event_stream(&mut self, o: Option<ContextSpanned<OneOrMany<Name>>>) {
525        self.event_stream = o;
526    }
527    fn set_dictionary(&mut self, _o: Option<ContextSpanned<OneOrMany<Name>>>) {}
528    fn set_config(&mut self, o: Option<ContextSpanned<OneOrMany<Name>>>) {
529        self.config = always_one_context(o);
530    }
531
532    fn origin(&self) -> &Arc<PathBuf> {
533        &self.origin
534    }
535
536    fn availability(&self) -> Option<ContextSpanned<Availability>> {
537        self.availability.clone()
538    }
539    fn set_availability(&mut self, a: Option<ContextSpanned<Availability>>) {
540        self.availability = a;
541    }
542}
543
544impl CanonicalizeContext for ContextUse {
545    fn canonicalize_context(&mut self) {
546        // Sort the names of the capabilities. Only capabilities with OneOrMany values are included here.
547        if let Some(service) = &mut self.service {
548            service.value.canonicalize_context();
549        } else if let Some(protocol) = &mut self.protocol {
550            protocol.value.canonicalize_context();
551        } else if let Some(event_stream) = &mut self.event_stream {
552            event_stream.value.canonicalize_context();
553            if let Some(scope) = &mut self.scope {
554                scope.value.canonicalize_context();
555            }
556        }
557    }
558}
559
560impl FromClauseContext for ContextUse {
561    fn from_(&self) -> ContextSpanned<OneOrMany<AnyRef<'_>>> {
562        match &self.from {
563            Some(from) => {
564                return ContextSpanned {
565                    value: OneOrMany::One(AnyRef::from(&from.value)),
566                    origin: from.origin.clone(),
567                };
568            }
569            // Default for `use`.
570            None => {
571                return ContextSpanned {
572                    value: OneOrMany::One(AnyRef::Parent),
573                    origin: self.origin.clone(),
574                };
575            }
576        }
577    }
578}
579
580impl RightsClause for ContextUse {
581    fn rights(&self) -> Option<&Rights> {
582        self.rights.as_ref().map(|r| &r.value)
583    }
584}
585
586impl PartialEq for ContextUse {
587    fn eq(&self, other: &Self) -> bool {
588        macro_rules! cmp {
589            ($field:ident) => {
590                match (&self.$field, &other.$field) {
591                    (Some(a), Some(b)) => a.value == b.value,
592                    (None, None) => true,
593                    _ => false,
594                }
595            };
596        }
597
598        cmp!(service)
599            && cmp!(protocol)
600            && cmp!(directory)
601            && cmp!(storage)
602            && cmp!(event_stream)
603            && cmp!(runner)
604            && cmp!(config)
605            && cmp!(dictionary)
606            && cmp!(from)
607            && cmp!(path)
608            && cmp!(numbered_handle)
609            && cmp!(rights)
610            && cmp!(subdir)
611            && cmp!(scope)
612            && cmp!(filter)
613            && cmp!(dependency)
614            && cmp!(availability)
615            && cmp!(key)
616            && cmp!(config_type)
617            && cmp!(config_max_size)
618            && cmp!(config_max_count)
619            && cmp!(config_element_type)
620            && cmp!(config_default)
621    }
622}
623
624impl Eq for ContextUse {}
625
626impl ContextPathClause for ContextUse {
627    fn path(&self) -> Option<&ContextSpanned<Path>> {
628        self.path.as_ref()
629    }
630}
631
632impl Hydrate for Use {
633    type Output = ContextUse;
634
635    fn hydrate(self, file: &Arc<PathBuf>) -> Result<Self::Output, Error> {
636        Ok(ContextUse {
637            origin: file.clone(),
638            service: hydrate_opt_simple(self.service, file),
639            protocol: hydrate_opt_simple(self.protocol, file),
640            directory: hydrate_opt_simple(self.directory, file),
641            storage: hydrate_opt_simple(self.storage, file),
642            event_stream: hydrate_opt_simple(self.event_stream, file),
643            runner: hydrate_opt_simple(self.runner, file),
644            config: hydrate_opt_simple(self.config, file),
645            dictionary: hydrate_opt_simple(self.dictionary, file),
646            from: hydrate_opt_simple(self.from, file),
647            path: hydrate_opt_simple(self.path, file),
648            numbered_handle: hydrate_opt_simple(self.numbered_handle, file),
649            rights: hydrate_opt_simple(self.rights, file),
650            subdir: hydrate_opt_simple(self.subdir, file),
651            scope: hydrate_opt_simple(self.scope, file),
652            filter: hydrate_opt_simple(self.filter, file),
653            dependency: hydrate_opt_simple(self.dependency, file),
654            availability: hydrate_opt_simple(self.availability, file),
655            key: hydrate_opt_simple(self.key, file),
656            config_type: hydrate_opt_simple(self.config_type, file),
657            config_max_size: hydrate_opt_simple(self.config_max_size, file),
658            config_max_count: hydrate_opt_simple(self.config_max_count, file),
659            config_element_type: hydrate_opt_simple(self.config_element_type, file),
660            config_default: hydrate_opt_simple(self.config_default, file),
661        })
662    }
663}