walker_common/utils/
url.rs

1//! URLs
2use url::Url;
3
4/// Get a URL from something
5///
6/// ## Relative URLs
7///
8/// A entity can provide a relative URL. This is an optional operation, and is not implemented by default.
9///
10/// Implementors of this feature should have a clear definition what the meaning of the base is. For example:
11/// the advisory's base is the distribution URL.
12///
13/// The combination of the provided actual base and relative URL must result in the same value as the actual URL.
14pub trait Urlify {
15    /// The URL
16    fn url(&self) -> &Url;
17
18    fn relative_base_and_url(&self) -> Option<(&Url, String)> {
19        None
20    }
21
22    fn relative_url(&self) -> Option<String> {
23        self.relative_base_and_url().map(|(_, url)| url)
24    }
25
26    fn relative_base(&self) -> Option<&Url> {
27        self.relative_base_and_url().map(|(url, _)| url)
28    }
29
30    fn possibly_relative_url(&self) -> String {
31        self.relative_url()
32            .unwrap_or_else(|| self.url().to_string())
33    }
34}
35
36impl<T, E> Urlify for Result<T, E>
37where
38    T: Urlify,
39    E: Urlify,
40{
41    fn url(&self) -> &Url {
42        match self {
43            Ok(something) => something.url(),
44            Err(something) => something.url(),
45        }
46    }
47}
48
49/// Ensure that the path has a trailing slash
50pub fn ensure_slash(mut url: Url) -> Url {
51    if !url.path().ends_with("/") {
52        let new_path = format!("{}/", url.path());
53        url.set_path(&new_path);
54    }
55
56    url
57}