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

use crate::{Request, Error, HeaderName, HeaderValue};
use std::convert::TryInto;
use std::collections::HashMap;

/// A helper to perform multiple associated requests.
/// (Session-)Cookies will be handled
#[derive(Debug)]
pub struct Session {
    headers: HashMap<HeaderName, HeaderValue>,
    #[cfg(feature = "cookies")]
    cookies: CookieStore
}
impl Session {
    #[cfg(feature = "cookies")]
    pub fn cookies(&self) {
        /*CookieStore::parse(
            &mut self,
            cookie_str: &str,
            request_url: &Url*/
    }
    pub fn new() -> Session {
        Session{
            headers: HashMap::new()
        }
    }
    /// Add a single header to all request done with this session
    pub fn set_header(mut self,
        name: impl TryInto<HeaderName, Error = Error>,
        value: impl TryInto<HeaderValue, Error = Error>) -> Result<Self, Error> {

        let val :HeaderValue = value.try_into()?;
        let name :HeaderName = name.try_into()?;
        self.headers.insert(name, val);
        
        Ok(self)
    }
    fn add_session_data(&self, mut req: Request) -> Request {
        for (n, v) in self.headers.iter() {
            req = req.set_header(n.clone(), v.clone()).unwrap();//already converted
        }
        #[cfg(feature = "cookies")]
        {
            let c = self.cookies.get_request_values(url)
            .map(|(n,v)| format!("{}={}", n, v))
            .collect::<Vec<_>>()
            .join("; ");
            if c.len() > 0 {
                req.set_header("Cookie", c);
            }
        }
        req
    }

    pub fn get(&mut self, uri: &str) -> Request {
        self.add_session_data(Request::get(uri))
    }
    pub fn post(&mut self, uri: &str) -> Request {
        self.add_session_data(Request::post(uri))
    }
    pub fn put(&mut self, uri: &str) -> Request {
        self.add_session_data(Request::put(uri))
    }
    pub fn delete(&mut self, uri: &str) -> Request {
        self.add_session_data(Request::delete(uri))
    }
    pub fn head(&mut self, uri: &str) -> Request {
        self.add_session_data(Request::head(uri))
    }
    pub fn options(&mut self, uri: &str) -> Request {
        self.add_session_data(Request::options(uri))
    }
    pub fn request(&mut self, meth: &str, uri: &str) -> Result<Request, Error> {
        Request::new(meth, uri).map(|r|self.add_session_data(r))
    }

    pub fn request_from<R>(&mut self, request : R) -> Result<Request, R::Error>
        where R: TryInto<Request>
     {
        request.try_into().map(|r|self.add_session_data(r))
    }

}