Add convertion to/from Request/Response from/to http::Request/Response
This commit is contained in:
parent
74dad12056
commit
c71b60ef70
@ -16,8 +16,9 @@ http = "0.1.0"
|
|||||||
hyper = "0.12"
|
hyper = "0.12"
|
||||||
serde_json = "1.0.3"
|
serde_json = "1.0.3"
|
||||||
serde_urlencoded = "0.5.1"
|
serde_urlencoded = "0.5.1"
|
||||||
|
ruma-identifiers = "0.11"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ruma-identifiers = "0.11"
|
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
url = "1.7"
|
||||||
|
76
src/lib.rs
76
src/lib.rs
@ -15,13 +15,16 @@
|
|||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate http;
|
extern crate http;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
#[cfg(test)]
|
|
||||||
extern crate ruma_identifiers;
|
extern crate ruma_identifiers;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
extern crate serde;
|
||||||
|
#[cfg(test)]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate serde_urlencoded;
|
extern crate serde_urlencoded;
|
||||||
|
#[cfg(test)]
|
||||||
|
extern crate url;
|
||||||
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -33,9 +36,9 @@ use hyper::Body;
|
|||||||
/// A Matrix API endpoint.
|
/// A Matrix API endpoint.
|
||||||
pub trait Endpoint<T = Body, U = Body> {
|
pub trait Endpoint<T = Body, U = Body> {
|
||||||
/// Data needed to make a request to the endpoint.
|
/// Data needed to make a request to the endpoint.
|
||||||
type Request: TryInto<Request<T>, Error = Error>;
|
type Request: TryInto<Request<T>, Error = Error> + FutureFrom<Request<T>, Error = Error>;
|
||||||
/// Data returned from the endpoint.
|
/// Data returned from the endpoint.
|
||||||
type Response: FutureFrom<Response<U>, Error = Error>;
|
type Response: FutureFrom<Response<U>, Error = Error> + TryInto<Response<U>>;
|
||||||
|
|
||||||
/// Metadata about the endpoint.
|
/// Metadata about the endpoint.
|
||||||
const METADATA: Metadata;
|
const METADATA: Metadata;
|
||||||
@ -53,8 +56,12 @@ pub enum Error {
|
|||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
/// A Serde JSON error.
|
/// A Serde JSON error.
|
||||||
SerdeJson(serde_json::Error),
|
SerdeJson(serde_json::Error),
|
||||||
|
/// A Serde URL decoding error.
|
||||||
|
SerdeUrlEncodedDe(serde_urlencoded::de::Error),
|
||||||
/// A Serde URL encoding error.
|
/// A Serde URL encoding error.
|
||||||
SerdeUrlEncoded(serde_urlencoded::ser::Error),
|
SerdeUrlEncodedSer(serde_urlencoded::ser::Error),
|
||||||
|
/// A Ruma Identitifiers error.
|
||||||
|
RumaIdentifiers(ruma_identifiers::Error),
|
||||||
/// An HTTP status code indicating error.
|
/// An HTTP status code indicating error.
|
||||||
StatusCode(StatusCode),
|
StatusCode(StatusCode),
|
||||||
/// Standard hack to prevent exhaustive matching.
|
/// Standard hack to prevent exhaustive matching.
|
||||||
@ -87,9 +94,21 @@ impl From<serde_json::Error> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<serde_urlencoded::de::Error> for Error {
|
||||||
|
fn from(error: serde_urlencoded::de::Error) -> Self {
|
||||||
|
Error::SerdeUrlEncodedDe(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<serde_urlencoded::ser::Error> for Error {
|
impl From<serde_urlencoded::ser::Error> for Error {
|
||||||
fn from(error: serde_urlencoded::ser::Error) -> Self {
|
fn from(error: serde_urlencoded::ser::Error) -> Self {
|
||||||
Error::SerdeUrlEncoded(error)
|
Error::SerdeUrlEncodedSer(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ruma_identifiers::Error> for Error {
|
||||||
|
fn from(error: ruma_identifiers::Error) -> Self {
|
||||||
|
Error::RumaIdentifiers(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,10 +137,13 @@ mod tests {
|
|||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use futures::future::{err, ok, FutureFrom, FutureResult};
|
use futures::future::{err, ok, FutureFrom, FutureResult};
|
||||||
|
use http::header::CONTENT_TYPE;
|
||||||
use http::method::Method;
|
use http::method::Method;
|
||||||
use http::{Request as HttpRequest, Response as HttpResponse};
|
use http::{Request as HttpRequest, Response as HttpResponse};
|
||||||
use ruma_identifiers::{RoomAliasId, RoomId};
|
use ruma_identifiers::{RoomAliasId, RoomId};
|
||||||
|
use serde::de::{Deserialize, IntoDeserializer};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
use url::percent_encoding;
|
||||||
|
|
||||||
use super::super::{Endpoint as ApiEndpoint, Error, Metadata};
|
use super::super::{Endpoint as ApiEndpoint, Error, Metadata};
|
||||||
|
|
||||||
@ -149,7 +171,7 @@ mod tests {
|
|||||||
pub room_alias: RoomAliasId, // path
|
pub room_alias: RoomAliasId, // path
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
struct RequestBody {
|
struct RequestBody {
|
||||||
room_id: RoomId,
|
room_id: RoomId,
|
||||||
}
|
}
|
||||||
@ -178,6 +200,36 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FutureFrom<HttpRequest<Vec<u8>>> for Request {
|
||||||
|
type Future = FutureResult<Self, Self::Error>;
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn future_from(request: HttpRequest<Vec<u8>>) -> Self::Future {
|
||||||
|
FutureResult::from(Self::try_from(request))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<HttpRequest<Vec<u8>>> for Request {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(request: HttpRequest<Vec<u8>>) -> Result<Request, Self::Error> {
|
||||||
|
let request_body: RequestBody =
|
||||||
|
::serde_json::from_slice(request.body().as_slice())?;
|
||||||
|
let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
|
||||||
|
Ok(Request {
|
||||||
|
room_id: request_body.room_id,
|
||||||
|
room_alias: {
|
||||||
|
let segment = path_segments.get(5).unwrap().as_bytes();
|
||||||
|
let decoded =
|
||||||
|
percent_encoding::percent_decode(segment)
|
||||||
|
.decode_utf8_lossy();
|
||||||
|
RoomAliasId::deserialize(decoded.into_deserializer())
|
||||||
|
.map_err(|e: serde_json::error::Error| e)?
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The response to a request to create a new room alias.
|
/// The response to a request to create a new room alias.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Response;
|
pub struct Response;
|
||||||
@ -196,5 +248,17 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Response> for HttpResponse<Vec<u8>> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(_response: Response) -> Result<HttpResponse<Vec<u8>>, Self::Error> {
|
||||||
|
let response = HttpResponse::builder()
|
||||||
|
.header(CONTENT_TYPE, "application/json")
|
||||||
|
.body("{}".as_bytes().to_vec())
|
||||||
|
.unwrap();
|
||||||
|
Ok(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user