Skip to main content

avalanche_types/jsonrpc/client/
url.rs

1//! Url is a helper module for creating avalanche node URLs.
2use hyper::{http::uri::Builder, http::uri::Scheme, Uri};
3use strum::{Display, IntoStaticStr};
4
5use crate::errors::Error;
6
7/// Path represents the various http client paths that can be called.
8/// Each Path has a distinct url.
9#[non_exhaustive]
10#[derive(Debug, Display, IntoStaticStr)]
11pub enum Path {
12    /// The admin url path /ext/admin
13    #[strum(to_string = "/ext/admin")]
14    Admin,
15    /// The info url path /ext/info
16    #[strum(to_string = "/ext/info")]
17    Info,
18    /// The health url path /ext/health
19    #[strum(to_string = "/ext/health")]
20    Health,
21    /// The liveness url path /ext/health/liveness
22    #[strum(to_string = "/ext/health/liveness")]
23    Liveness,
24    /// The P-chain url path /ext/P
25    #[strum(to_string = "/ext/P")]
26    P,
27    /// The X-chain url path /ext/bc/X
28    #[strum(to_string = "/ext/bc/X")]
29    X,
30    /// The C-chain url path /ext/bc/C/rpc
31    #[strum(to_string = "/ext/bc/C/rpc")]
32    C,
33    /// A custom path for a subnet rpc url for example.
34    #[strum(to_string = "{0}")]
35    Custom(String),
36}
37
38/// new returns a Url from path-based components.
39/// By default the scheme is http.
40/// In case of an error marshaling to a Url, a non-retryable error is returned.
41pub fn try_create_url(
42    path: Path,
43    scheme: Option<&str>,
44    host: &str,
45    port: Option<u16>,
46) -> Result<Uri, Error> {
47    Builder::new()
48        .authority(if let Some(port) = port {
49            format!("{host}:{port}")
50        } else {
51            host.to_string()
52        })
53        .scheme(scheme.unwrap_or(Scheme::HTTP.as_str()))
54        .path_and_query(path.to_string())
55        .build()
56        .map_err(|e| Error::Other {
57            message: format!("http://{host}{path} failed url::try_create_url '{}'", e),
58            retryable: false,
59        })
60}
61
62#[cfg(test)]
63mod tests {
64    use super::Path;
65
66    #[test]
67    fn test_try_create_url() {
68        let test_table: Vec<(Option<&str>, &str, Option<u16>)> =
69            vec![(None, "127.0.0.1", Some(9650))];
70
71        assert_eq!(
72            super::try_create_url(
73                Path::Admin,
74                test_table[0].0,
75                test_table[0].1,
76                test_table[0].2
77            )
78            .unwrap()
79            .to_string(),
80            "http://127.0.0.1:9650/ext/admin".to_string()
81        );
82        assert_eq!(
83            super::try_create_url(
84                Path::Liveness,
85                test_table[0].0,
86                test_table[0].1,
87                test_table[0].2
88            )
89            .unwrap()
90            .to_string(),
91            "http://127.0.0.1:9650/ext/health/liveness".to_string()
92        );
93        assert_eq!(
94            super::try_create_url(Path::C, test_table[0].0, test_table[0].1, test_table[0].2)
95                .unwrap()
96                .to_string(),
97            "http://127.0.0.1:9650/ext/bc/C/rpc".to_string()
98        );
99    }
100}