File: collections_overloading.rs

package info (click to toggle)
rust-buildstructor 0.6.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 532 kB
  • sloc: makefile: 2
file content (99 lines) | stat: -rw-r--r-- 2,540 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use buildstructor::buildstructor;
use derive_more::From;
use http::header::{HeaderName, CONTENT_TYPE};
use http::{HeaderMap, HeaderValue};
use multimap::MultiMap;
use std::error::Error;

pub struct Collections {
    headers: HeaderMap,
}

#[buildstructor]
impl Collections {
    #[builder]
    fn new(
        headers: MultiMap<IntoHeaderName, IntoHeaderValue>,
    ) -> Result<Collections, Box<dyn Error>> {
        let mut valid_headers = HeaderMap::new();
        for (key, values) in headers {
            let header_name: HeaderName = key.try_into()?;
            for value in values {
                let header_value: HeaderValue = value.try_into()?;
                valid_headers.insert(header_name.clone(), header_value);
            }
        }

        Ok(Self {
            headers: valid_headers,
        })
    }
}

#[derive(From, Eq, Hash, PartialEq)]
pub enum IntoHeaderName {
    String(String),
    HeaderName(HeaderName),
}

#[derive(From, Eq, Hash, PartialEq)]
pub enum IntoHeaderValue {
    String(String),
    HeaderValue(HeaderValue),
}

impl From<&str> for IntoHeaderName {
    fn from(name: &str) -> Self {
        IntoHeaderName::String(name.to_string())
    }
}

impl From<&str> for IntoHeaderValue {
    fn from(value: &str) -> Self {
        IntoHeaderValue::String(value.to_string())
    }
}

impl TryFrom<IntoHeaderName> for HeaderName {
    type Error = Box<dyn Error>;

    fn try_from(value: IntoHeaderName) -> Result<Self, Self::Error> {
        Ok(match value {
            IntoHeaderName::String(name) => HeaderName::try_from(name)?,
            IntoHeaderName::HeaderName(name) => name,
        })
    }
}

impl TryFrom<IntoHeaderValue> for HeaderValue {
    type Error = Box<dyn Error>;

    fn try_from(value: IntoHeaderValue) -> Result<Self, Self::Error> {
        Ok(match value {
            IntoHeaderValue::String(value) => HeaderValue::try_from(value)?,
            IntoHeaderValue::HeaderValue(value) => value,
        })
    }
}

fn main() {
    let collections = Collections::builder()
        .header("foo", "bar")
        .header(CONTENT_TYPE, "html")
        .header("bif".to_string(), "baz".to_string())
        .build()
        .unwrap();

    assert_eq!(
        collections.headers.get("foo").unwrap(),
        HeaderValue::from_static("bar")
    );
    assert_eq!(
        collections.headers.get(CONTENT_TYPE).unwrap(),
        HeaderValue::from_static("html")
    );
    assert_eq!(
        collections.headers.get("bif").unwrap(),
        HeaderValue::from_static("baz")
    );
}