use hyper;
use serde_json;
use errors::FunctionError;
use hyper_utils::{no_content, success, body_as_bytes};
pub trait InputCoercible: Sized {
fn try_decode(req: hyper::Request) -> Result<Self, FunctionError>;
}
pub trait OutputCoercible {
fn try_encode(self) -> Result<hyper::Response, FunctionError>;
}
impl InputCoercible for hyper::Request {
fn try_decode(req: hyper::Request) -> Result<hyper::Request, FunctionError> {
Ok(req)
}
}
impl OutputCoercible for hyper::Response {
fn try_encode(self) -> Result<hyper::Response, FunctionError> {
Ok(self)
}
}
impl InputCoercible for () {
fn try_decode(_: hyper::Request) -> Result<(), FunctionError> {
Ok(())
}
}
impl OutputCoercible for () {
fn try_encode(self) -> Result<hyper::Response, FunctionError> {
Ok(no_content())
}
}
impl InputCoercible for Vec<u8> {
fn try_decode(req: hyper::Request) -> Result<Vec<u8>, FunctionError> {
body_as_bytes(req.body())
}
}
impl OutputCoercible for Vec<u8> {
fn try_encode(self) -> Result<hyper::Response, FunctionError> {
Ok(success(self))
}
}
impl InputCoercible for String {
fn try_decode(req: hyper::Request) -> Result<String, FunctionError> {
match body_as_bytes(req.body()) {
Ok(v) => {
match String::from_utf8(v) {
Ok(s) => Ok(s),
Err(e) => Err(FunctionError::invalid_input(e)),
}
}
Err(e) => Err(e),
}
}
}
impl OutputCoercible for String {
fn try_encode(self) -> Result<hyper::Response, FunctionError> {
Ok(success(self))
}
}
impl InputCoercible for serde_json::Value {
fn try_decode(req: hyper::Request) -> Result<serde_json::Value, FunctionError> {
match body_as_bytes(req.body()) {
Ok(v) => {
match serde_json::from_slice(&v) {
Ok(obj) => Ok(obj),
Err(e) => Err(FunctionError::invalid_input(e)),
}
}
Err(e) => Err(e),
}
}
}
impl OutputCoercible for serde_json::Value {
fn try_encode(self) -> Result<hyper::Response, FunctionError> {
match serde_json::to_vec(&self) {
Ok(v) => Ok(success(v)),
Err(e) => Err(FunctionError::io(e)),
}
}
}