#
cargo/util/
into_url_with_base.rs

    1use crate::util::{CargoResult, IntoUrl};
    2
    3use url::Url;
    4
    5/// A type that can be interpreted as a relative Url and converted to
    6/// a Url.
    7pub trait IntoUrlWithBase {
    8    /// Performs the conversion
    9    fn into_url_with_base<U: IntoUrl>(self, base: Option<U>) -> CargoResult<Url>;
    10}
    11
    12impl<'a> IntoUrlWithBase for &'a str {
    13    fn into_url_with_base<U: IntoUrl>(self, base: Option<U>) -> CargoResult<Url> {
    14        let base_url = match base {
    15            Some(base) => Some(
    16                base.into_url()
    17                    .map_err(|s| anyhow::format_err!("invalid url `{}`: {}", self, s))?,
    18            ),
    19            None => None,
    20        };
    21
    22        Url::options()
    23            .base_url(base_url.as_ref())
    24            .parse(self)
    25            .map_err(|s| anyhow::format_err!("invalid url `{}`: {}", self, s))
    26    }
    27}
    28
    29#[cfg(test)]
    30mod tests {
    31    use crate::util::IntoUrlWithBase;
    32
    33    #[test]
    34    fn into_url_with_base() {
    35        assert_eq!(
    36            "rel/path"
    37                .into_url_with_base(Some("file:///abs/path/"))
    38                .unwrap()
    39                .to_string(),
    40            "file:///abs/path/rel/path"
    41        );
    42        assert_eq!(
    43            "rel/path"
    44                .into_url_with_base(Some("file:///abs/path/popped-file"))
    45                .unwrap()
    46                .to_string(),
    47            "file:///abs/path/rel/path"
    48        );
    49    }
    50}