dev_kit/command/uri/
components.rs

1use crate::command::uri::{QueryPartName, QueryPartVal, UriComponent, UriComponentValue};
2use itertools::Itertools;
3use std::fmt::{Display, Formatter};
4use std::str::FromStr;
5
6impl FromStr for UriComponent {
7    type Err = anyhow::Error;
8
9    fn from_str(value: &str) -> Result<Self, Self::Err> {
10        let value = value.to_lowercase();
11        Ok(match value.as_str() {
12            "scheme" => UriComponent::Scheme,
13            "authority" => UriComponent::Authority,
14            "host" => UriComponent::Host,
15            "port" => UriComponent::Port,
16            "path" => UriComponent::Path,
17            value => {
18                match &value[..1] {
19                    "?" => {
20                        UriComponent::Query(Some(QueryPartName::from_str(&value[1..])?))
21                    }
22                    _ => {
23                        UriComponent::Query(Some(QueryPartName::from_str(value)?))
24                    }
25                }
26            }
27        })
28    }
29}
30
31impl UriComponentValue {
32    pub fn name(&self) -> &'static str {
33        match self {
34            UriComponentValue::Scheme(_) => "scheme",
35            UriComponentValue::Authority(_) => "authority",
36            UriComponentValue::Host(_) => "host",
37            UriComponentValue::Port(_) => "port",
38            UriComponentValue::Path(_) => "path",
39            UriComponentValue::Query(_) => "query",
40        }
41    }
42
43    pub fn string_value(&self) -> String {
44        match self {
45            UriComponentValue::Scheme(val) => val.to_string(),
46            UriComponentValue::Authority(val) => val.as_ref().map(|it|it.to_string()).unwrap_or_default(),
47            UriComponentValue::Host(val) => val.to_string(),
48            UriComponentValue::Port(val) => val.to_string(),
49            UriComponentValue::Path(val) => val.to_string(),
50            UriComponentValue::Query(val) => {
51                val.into_iter().map(|(k, v)| format!("{}={}", k, v)).join("&")
52            }
53        }
54    }
55}
56
57impl QueryPartVal {
58    pub fn concat(&self, other: &Self) -> Self {
59        let vec = vec![self.clone(), other.clone()].into_iter().flat_map(|it| {
60            match it {
61                QueryPartVal::Single(Some(val)) => vec![val],
62                QueryPartVal::Multi(vec) => vec,
63                _ => vec![]
64            }
65        }).collect_vec();
66        Self::Multi(vec)
67    }
68}
69
70impl Display for QueryPartVal {
71    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
72        match self {
73            QueryPartVal::Single(string) => serde_json::to_string(string).unwrap_or_default().fmt(f),
74            QueryPartVal::Multi(arr) => serde_json::to_string(arr).unwrap_or_default().fmt(f),
75        }
76    }
77}