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