Skip to main content

fuchsia_url/
boot.rs

1// Copyright 2026 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
5pub const SCHEME_STR: &str = "fuchsia-boot";
6
7use crate::generic;
8
9/// A component URL for the boot resolver. Either an [`AbsoluteComponentUrl`] or a
10/// [`RelativeComponentUrl`](crate::RelativeComponentUrl).
11pub type ComponentUrl =
12    generic::ComponentUrl<Scheme, generic::NoneHost, Option<crate::Path>, generic::NoneHash>;
13
14/// An absolute component URL for the boot resolver, composed of:
15///   * scheme == "fuchsia-boot"
16///   * no host
17///   * an optional [`Path`](crate::Path). Unpackaged bootfs components, of which there are few
18///     remaining, do not have a `Path`.
19///   * no hash
20///   * a [`Resource`](crate::Resource)
21pub type AbsoluteComponentUrl = generic::AbsoluteComponentUrl<
22    Scheme,
23    generic::NoneHost,
24    Option<crate::Path>,
25    generic::NoneHash,
26>;
27
28impl AbsoluteComponentUrl {
29    pub fn new(path: Option<crate::Path>, resource: crate::Resource) -> Self {
30        Self::from_parts(Scheme, crate::NoneHost, path, crate::NoneHash, resource)
31    }
32}
33
34/// A package URL for the boot resolver. Either an [`AbsolutePackageUrl`] or a
35/// [`RelativePackageUrl`](crate::RelativePackageUrl).
36pub type PackageUrl =
37    generic::PackageUrl<Scheme, generic::NoneHost, Option<crate::Path>, generic::NoneHash>;
38
39/// An absolute package URL for the boot resolver, composed of:
40///   * scheme == "fuchsia-boot"
41///   * no host
42///   * an optional [`Path`](crate::Path). Unpackaged bootfs components, of which there are few
43///     remaining, do not have a `Path` (since they don't have a package), and so their package URL
44///     is the degenerate pathless URL.
45///   * no hash
46pub type AbsolutePackageUrl =
47    generic::AbsolutePackageUrl<Scheme, generic::NoneHost, Option<crate::Path>, generic::NoneHash>;
48
49/// Scheme type for fuchsia-boot URLs.
50#[derive(Debug, Clone)]
51pub struct Scheme;
52impl crate::Sealer for Scheme {}
53impl generic::SchemeTrait for Scheme {
54    fn try_from_part(scheme: crate::Scheme) -> Result<Self, crate::ParseError> {
55        match scheme {
56            crate::Scheme::FuchsiaBoot => Ok(Self),
57            _ => Err(crate::ParseError::InvalidScheme),
58        }
59    }
60}
61impl std::fmt::Display for Scheme {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        f.write_str(SCHEME_STR)
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    #[test]
72    fn component_url_round_trip() {
73        let abs = "fuchsia-boot:///my/path#my-resource";
74        assert_eq!(ComponentUrl::parse(abs).unwrap().to_string(), abs);
75
76        let abs_pathless = "fuchsia-boot://#my-resource";
77        assert_eq!(ComponentUrl::parse(abs_pathless).unwrap().to_string(), abs_pathless);
78
79        let rel = "my-path#my-resource";
80        assert_eq!(ComponentUrl::parse(rel).unwrap().to_string(), rel);
81    }
82
83    #[test]
84    fn package_url_round_trip() {
85        let abs = "fuchsia-boot:///my/path";
86        assert_eq!(PackageUrl::parse(abs).unwrap().to_string(), abs);
87
88        let rel = "my-path";
89        assert_eq!(PackageUrl::parse(rel).unwrap().to_string(), rel);
90    }
91}