webframework_core/
request.rs

1use hyper::{self, Body, Uri};
2use http::method::Method;
3use http::request::Parts;
4use http::header::{HeaderMap, HeaderValue};
5use slog::Logger;
6use uuid::Uuid;
7use futures::{Future, Stream};
8use bytes::Bytes;
9use failure::{Fail, Context, Error};
10
11#[derive(Debug)]
12pub struct Request {
13    id: Uuid,
14    log: Logger,
15    body: Bytes,
16    parts: Parts,
17}
18
19impl Request {
20    pub fn from_req(id: Uuid, log: Logger, req: hyper::Request<Body>)
21        -> impl Future<Item = Request, Error = Error> + Send + Sized
22    {
23        let (parts, body) = req.into_parts();
24
25        body.concat2().and_then(move |body| {
26            let body = body.into_bytes();
27
28            futures::future::ok(Request {
29                id, log, body, parts
30            })
31        }).map_err(|e| e.context(RequestErrorKind::BodyParseError).into())
32    }
33
34    pub fn uri(&self) -> &Uri {
35        &self.parts.uri
36    }
37
38    pub fn path(&self) -> &str {
39        self.parts.uri.path()
40    }
41
42    pub fn method(&self) -> &Method {
43        &self.parts.method
44    }
45
46    pub fn headers(&self) -> &HeaderMap<HeaderValue> {
47        &self.parts.headers
48    }
49
50    pub fn log(&self) -> &Logger {
51        &self.log
52    }
53
54    pub fn id(&self) -> &Uuid {
55        &self.id
56    }
57
58    pub fn body(&self) -> &[u8] {
59        &self.body
60    }
61}
62
63pub trait FromParameter: Sized {
64    fn from_parameter(param: &str) -> crate::WebResult<Self>;
65}
66
67impl FromParameter for String {
68    fn from_parameter(param: &str) -> crate::WebResult<Self> {
69        Ok(param.to_string())
70    }
71}
72
73pub trait FromRequest<'a>: Sized {
74    fn from_request(req: &'a Request) -> crate::WebResult<Self>;
75}
76
77impl<'a> FromRequest<'a> for &'a Request {
78    fn from_request(req: &Request) -> crate::WebResult<&Request> {
79        Ok(req)
80    }
81}
82
83#[derive(Clone, Eq, PartialEq, Debug, Fail)]
84pub enum RequestErrorKind {
85    #[fail(display = "Could not find required param: _1")]
86    ParamNotFound(String),
87    #[fail(display="could not parse the body")]
88    BodyParseError
89}
90
91#[derive(Debug)]
92pub struct RequestError {
93    inner: Context<RequestErrorKind>,
94}
95
96impl_fail_boilerplate!(RequestErrorKind, RequestError);