| // Copyright 2022 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use crate::errors::ParseError; |
| |
| // The host of a fuchsia-pkg:// URL. |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| pub(crate) struct Host(String); |
| |
| impl Host { |
| /// Returns an error if the provided hostname does not comply to the package URL spec: |
| /// https://fuchsia.dev/fuchsia-src/concepts/packages/package_url#repository |
| /// Contains only lowercase ascii letters, digits, a hyphen or the dot delimiter. |
| pub fn parse(host: String) -> Result<Self, ParseError> { |
| url::Host::parse(&host)?; |
| |
| if host.is_empty() { |
| return Err(ParseError::EmptyHost); |
| } |
| |
| if !host |
| .chars() |
| .all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-' || c == '.') |
| { |
| return Err(ParseError::InvalidHost); |
| } |
| Ok(Self(host)) |
| } |
| } |
| |
| impl AsRef<str> for Host { |
| fn as_ref(&self) -> &str { |
| &self.0 |
| } |
| } |
| |
| impl From<Host> for String { |
| fn from(host: Host) -> Self { |
| host.0 |
| } |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use super::*; |
| |
| #[test] |
| fn parse_err() { |
| for host in [ |
| "FuChSiA.CoM", |
| "FUCHSIA_1.com", |
| "FUCHSIA-1.COM", |
| "fuchsia-①.com", |
| "RISCV.fuchsia.com", |
| "RV64.fuchsia.com", |
| "fu_chsia.com", |
| ] { |
| assert_eq!( |
| Host::parse(host.to_string()), |
| Err(ParseError::InvalidHost), |
| "the host string {:?}", |
| host |
| ); |
| } |
| |
| for host in ["fu:chsia.com", "fu#chsia.com", "fu?chsia.com", "fu/chsia.com"] { |
| assert_eq!( |
| Host::parse(host.to_string()), |
| Err(ParseError::UrlParseError(url::ParseError::InvalidDomainCharacter)), |
| "the host string {:?}", |
| host |
| ); |
| } |
| |
| assert_eq!( |
| Host::parse("".into()), |
| Err(ParseError::UrlParseError(url::ParseError::EmptyHost)) |
| ); |
| } |
| |
| #[test] |
| fn parse_ok() { |
| for host in ["example.org", "ex.am.ple.org", "example0.org", "ex-ample.org", "a", "1", "."] |
| { |
| assert_eq!(Host::parse(host.to_string()).unwrap().as_ref(), host); |
| } |
| } |
| } |