From 15b18a933591cb00234c6e7cfbc1e918c8135418 Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Tue, 27 Oct 2020 19:43:23 -0500 Subject: [PATCH] :construction: --- Cargo.toml | 7 ++- src/http_serde.rs | 133 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 3 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 src/http_serde.rs diff --git a/Cargo.toml b/Cargo.toml index d809441..99d8f74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,11 @@ edition = "2018" [dependencies] -futures = "0.3.7" -hyper = "0.13.8" +futures = "0.3" +http = "0.2" +hyper = "0.13" reqwest = { version = "0.10.8", features = ["stream"] } +rmp-serde = "0.14.4" +serde = {version = "1.0", features = ["derive"]} tokio = { version = "0.2", features = ["full"] } ulid = "0.4.1" diff --git a/src/http_serde.rs b/src/http_serde.rs new file mode 100644 index 0000000..ebdcc72 --- /dev/null +++ b/src/http_serde.rs @@ -0,0 +1,133 @@ +use std::{ + collections::*, + convert::{TryFrom, TryInto}, + iter::FromIterator, +}; + +use serde::{Deserialize, Serialize}; + +pub enum Error { + Unsupported, + InvalidHeaderName, +} + +impl From for Error { + fn from (x: hyper::header::InvalidHeaderName) -> Self { + Self::InvalidHeaderName + } +} + +#[derive (Deserialize, Serialize)] +pub enum Method { + // Only GET is supported for now + Get, +} + +impl TryFrom for Method { + type Error = Error; + + fn try_from (x: hyper::Method) -> Result { + match x { + hyper::Method::GET => Ok (Self::Get), + _ => Err (Error::Unsupported), + } + } +} + +impl From for hyper::Method { + fn from (x: Method) -> Self { + match x { + Method::Get => Self::GET, + } + } +} + +#[derive (Deserialize, Serialize)] +pub struct RequestParts { + pub method: Method, + + // Technically URIs are subtle and complex but I don't care + pub uri: String, + + // Technically Hyper has headers in a multi-map + // but I don't feel like doing that right now. + + // Headers are _kinda_ ASCII but they can also be binary. + // HTTP is nutty. + pub headers: HashMap >, +} + +impl TryFrom for RequestParts { + type Error = Error; + + fn try_from (x: http::request::Parts) -> Result { + let method = x.method.try_into ()?; + let uri = x.uri.to_string (); + let headers = HashMap::from_iter ( + x.headers.into_iter () + .filter_map (|(k, v)| k.map (|k| (k, v))) + .map (|(k, v)| (String::from (k.as_str ()), v.as_bytes ().to_vec ())) + ); + + Ok (Self { + method, + uri, + headers, + }) + } +} + +impl TryFrom for http::request::Builder { + type Error = Error; + + fn try_from (x: RequestParts) -> Result { + let method = Method::from (x.method); + + let mut result = Self::new () + .method (method) + .uri (x.uri) + ; + + for (k, v) in x.headers.into_iter () { + result = result.header (http::header::HeaderName::try_from (&k)?, v); + } + + Ok (result) + } +} + +#[derive (Deserialize, Serialize)] +pub enum StatusCode { + Ok, + NotFound, +} + +impl TryFrom for StatusCode { + type Error = Error; + + fn try_from (x: hyper::StatusCode) -> Result { + match x { + hyper::StatusCode::OK => Ok (Self::Ok), + hyper::StatusCode::NOT_FOUND => Ok (Self::NotFound), + _ => Err (Error::Unsupported), + } + } +} + +impl From for hyper::StatusCode { + fn from (x: StatusCode) -> Self { + match x { + StatusCode::Ok => Self::OK, + StatusCode::NotFound => Self::NOT_FOUND, + } + } +} + +#[derive (Deserialize, Serialize)] +pub struct Response { + pub status_code: String, + + // Technically Hyper has headers in a multi-map + // but I don't feel like doing that right now. + pub headers: HashMap , +} diff --git a/src/lib.rs b/src/lib.rs index 887d28c..2f2290f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,2 @@ +pub mod http_serde; pub mod watcher;