dev_kit/command/uri/
components.rs1use 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}