Re-export ruma-api-macros from ruma-api.
This commit is contained in:
parent
e291730288
commit
4f03c4dce2
27
Cargo.toml
27
Cargo.toml
@ -18,10 +18,29 @@ serde_json = "1.0.40"
|
||||
serde_urlencoded = "0.6.0"
|
||||
ruma-identifiers = "0.14.0"
|
||||
|
||||
[dev-dependencies]
|
||||
url = "2.0.0"
|
||||
percent-encoding = "2.0.0"
|
||||
[dependencies.percent-encoding]
|
||||
version = "2.0.0"
|
||||
optional = true
|
||||
|
||||
[dev-dependencies.serde]
|
||||
[dependencies.ruma-api-macros]
|
||||
version = "0.6.0"
|
||||
path = "ruma-api-macros"
|
||||
optional = true
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.98"
|
||||
features = ["derive"]
|
||||
optional = true
|
||||
|
||||
[dependencies.url]
|
||||
version = "2.0.0"
|
||||
optional = true
|
||||
|
||||
[features]
|
||||
default = ["with-ruma-api-macros"]
|
||||
with-ruma-api-macros = ["percent-encoding", "ruma-api-macros", "serde", "url"]
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"ruma-api-macros",
|
||||
]
|
||||
|
@ -142,10 +142,10 @@ impl ToTokens for Api {
|
||||
#path_var_ident: {
|
||||
let segment = path_segments.get(#i).unwrap().as_bytes();
|
||||
let decoded =
|
||||
::url::percent_encoding::percent_decode(segment)
|
||||
ruma_api::exports::percent_encoding::percent_decode(segment)
|
||||
.decode_utf8_lossy();
|
||||
#ty::deserialize(decoded.into_deserializer())
|
||||
.map_err(|e: ::serde_json::error::Error| e)?
|
||||
.map_err(|e: ruma_api::exports::serde_json::error::Error| e)?
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -171,7 +171,7 @@ impl ToTokens for Api {
|
||||
#request_query_init_fields
|
||||
};
|
||||
|
||||
url.set_query(Some(&::serde_urlencoded::to_string(request_query)?));
|
||||
url.set_query(Some(&ruma_api::exports::serde_urlencoded::to_string(request_query)?));
|
||||
}
|
||||
} else {
|
||||
TokenStream::new()
|
||||
@ -180,7 +180,7 @@ impl ToTokens for Api {
|
||||
let extract_request_query = if self.request.has_query_fields() {
|
||||
quote! {
|
||||
let request_query: RequestQuery =
|
||||
::serde_urlencoded::from_str(&request.uri().query().unwrap_or(""))?;
|
||||
ruma_api::exports::serde_urlencoded::from_str(&request.uri().query().unwrap_or(""))?;
|
||||
}
|
||||
} else {
|
||||
TokenStream::new()
|
||||
@ -225,7 +225,7 @@ impl ToTokens for Api {
|
||||
quote! {
|
||||
let request_body = RequestBody(request.#field_name);
|
||||
|
||||
let mut http_request = ::http::Request::new(::serde_json::to_vec(&request_body)?);
|
||||
let mut http_request = ruma_api::exports::http::Request::new(ruma_api::exports::serde_json::to_vec(&request_body)?);
|
||||
}
|
||||
} else if self.request.has_body_fields() {
|
||||
let request_body_init_fields = self.request.request_body_init_fields();
|
||||
@ -235,11 +235,11 @@ impl ToTokens for Api {
|
||||
#request_body_init_fields
|
||||
};
|
||||
|
||||
let mut http_request = ::http::Request::new(::serde_json::to_vec(&request_body)?);
|
||||
let mut http_request = ruma_api::exports::http::Request::new(ruma_api::exports::serde_json::to_vec(&request_body)?);
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
let mut http_request = ::http::Request::new(Vec::new());
|
||||
let mut http_request = ruma_api::exports::http::Request::new(Vec::new());
|
||||
}
|
||||
};
|
||||
|
||||
@ -247,12 +247,12 @@ impl ToTokens for Api {
|
||||
let ty = &field.ty;
|
||||
quote! {
|
||||
let request_body: #ty =
|
||||
::serde_json::from_slice(request.body().as_slice())?;
|
||||
ruma_api::exports::serde_json::from_slice(request.body().as_slice())?;
|
||||
}
|
||||
} else if self.request.has_body_fields() {
|
||||
quote! {
|
||||
let request_body: RequestBody =
|
||||
::serde_json::from_slice(request.body().as_slice())?;
|
||||
ruma_api::exports::serde_json::from_slice(request.body().as_slice())?;
|
||||
}
|
||||
} else {
|
||||
TokenStream::new()
|
||||
@ -278,11 +278,11 @@ impl ToTokens for Api {
|
||||
let field_type = &field.ty;
|
||||
|
||||
quote! {
|
||||
::serde_json::from_slice::<#field_type>(http_response.into_body().as_slice())?
|
||||
ruma_api::exports::serde_json::from_slice::<#field_type>(http_response.into_body().as_slice())?
|
||||
}
|
||||
} else if self.response.has_body_fields() {
|
||||
quote! {
|
||||
::serde_json::from_slice::<ResponseBody>(http_response.into_body().as_slice())?
|
||||
ruma_api::exports::serde_json::from_slice::<ResponseBody>(http_response.into_body().as_slice())?
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
@ -309,7 +309,7 @@ impl ToTokens for Api {
|
||||
let try_serialize_response_body = if self.response.has_body() {
|
||||
let body = self.response.to_body();
|
||||
quote! {
|
||||
::serde_json::to_vec(&#body)?
|
||||
ruma_api::exports::serde_json::to_vec(&#body)?
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
@ -317,29 +317,28 @@ impl ToTokens for Api {
|
||||
}
|
||||
};
|
||||
|
||||
let endpoint_doc = format!("The `{}` API endpoint.\n\n{}", name, description.value());
|
||||
let request_doc = format!("Data for a request to the `{}` API endpoint.", name);
|
||||
let request_doc = format!(
|
||||
"Data for a request to the `{}` API endpoint.\n\n{}",
|
||||
name,
|
||||
description.value()
|
||||
);
|
||||
let response_doc = format!("Data in the response from the `{}` API endpoint.", name);
|
||||
|
||||
let api = quote! {
|
||||
use ::ruma_api::Endpoint as _;
|
||||
use ::serde::Deserialize as _;
|
||||
use ::serde::de::{Error as _, IntoDeserializer as _};
|
||||
use ruma_api::Endpoint as _;
|
||||
use ruma_api::exports::serde::Deserialize as _;
|
||||
use ruma_api::exports::serde::de::{Error as _, IntoDeserializer as _};
|
||||
|
||||
use ::std::convert::{TryInto as _};
|
||||
|
||||
#[doc = #endpoint_doc]
|
||||
#[derive(Debug)]
|
||||
pub struct Endpoint;
|
||||
use std::convert::{TryInto as _};
|
||||
|
||||
#[doc = #request_doc]
|
||||
#request_types
|
||||
|
||||
impl ::std::convert::TryFrom<::http::Request<Vec<u8>>> for Request {
|
||||
type Error = ::ruma_api::Error;
|
||||
impl std::convert::TryFrom<ruma_api::exports::http::Request<Vec<u8>>> for Request {
|
||||
type Error = ruma_api::Error;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn try_from(request: ::http::Request<Vec<u8>>) -> Result<Self, Self::Error> {
|
||||
fn try_from(request: ruma_api::exports::http::Request<Vec<u8>>) -> Result<Self, Self::Error> {
|
||||
#extract_request_path
|
||||
#extract_request_query
|
||||
#extract_request_headers
|
||||
@ -354,24 +353,24 @@ impl ToTokens for Api {
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::TryFrom<Request> for ::http::Request<Vec<u8>> {
|
||||
type Error = ::ruma_api::Error;
|
||||
impl std::convert::TryFrom<Request> for ruma_api::exports::http::Request<Vec<u8>> {
|
||||
type Error = ruma_api::Error;
|
||||
|
||||
#[allow(unused_mut, unused_variables)]
|
||||
fn try_from(request: Request) -> Result<Self, Self::Error> {
|
||||
let metadata = Endpoint::METADATA;
|
||||
let metadata = Request::METADATA;
|
||||
|
||||
// Use dummy homeserver url which has to be overwritten in
|
||||
// the calling code. Previously (with http::Uri) this was
|
||||
// not required, but Url::parse only accepts absolute urls.
|
||||
let mut url = ::url::Url::parse("http://invalid-host-please-change/").unwrap();
|
||||
let mut url = ruma_api::exports::url::Url::parse("http://invalid-host-please-change/").unwrap();
|
||||
|
||||
{ #set_request_path }
|
||||
{ #set_request_query }
|
||||
|
||||
#create_http_request
|
||||
|
||||
*http_request.method_mut() = ::http::Method::#method;
|
||||
*http_request.method_mut() = ruma_api::exports::http::Method::#method;
|
||||
*http_request.uri_mut() = url.into_string().parse().unwrap();
|
||||
|
||||
{ #add_headers_to_request }
|
||||
@ -383,13 +382,13 @@ impl ToTokens for Api {
|
||||
#[doc = #response_doc]
|
||||
#response_types
|
||||
|
||||
impl ::std::convert::TryFrom<Response> for ::http::Response<Vec<u8>> {
|
||||
type Error = ::ruma_api::Error;
|
||||
impl std::convert::TryFrom<Response> for ruma_api::exports::http::Response<Vec<u8>> {
|
||||
type Error = ruma_api::Error;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn try_from(response: Response) -> Result<Self, Self::Error> {
|
||||
let response = ::http::Response::builder()
|
||||
.header(::http::header::CONTENT_TYPE, "application/json")
|
||||
let response = ruma_api::exports::http::Response::builder()
|
||||
.header(ruma_api::exports::http::header::CONTENT_TYPE, "application/json")
|
||||
#serialize_response_headers
|
||||
.body(#try_serialize_response_body)
|
||||
.unwrap();
|
||||
@ -397,11 +396,11 @@ impl ToTokens for Api {
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::TryFrom<::http::Response<Vec<u8>>> for Response {
|
||||
type Error = ::ruma_api::Error;
|
||||
impl std::convert::TryFrom<ruma_api::exports::http::Response<Vec<u8>>> for Response {
|
||||
type Error = ruma_api::Error;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn try_from(http_response: ::http::Response<Vec<u8>>) -> Result<Self, Self::Error> {
|
||||
fn try_from(http_response: ruma_api::exports::http::Response<Vec<u8>>) -> Result<Self, Self::Error> {
|
||||
if http_response.status().is_success() {
|
||||
#extract_response_headers
|
||||
|
||||
@ -415,14 +414,13 @@ impl ToTokens for Api {
|
||||
}
|
||||
}
|
||||
|
||||
impl ::ruma_api::Endpoint for Endpoint {
|
||||
type Request = Request;
|
||||
impl ruma_api::Endpoint for Request {
|
||||
type Response = Response;
|
||||
|
||||
/// Metadata for the `#name` endpoint.
|
||||
const METADATA: ::ruma_api::Metadata = ::ruma_api::Metadata {
|
||||
const METADATA: ruma_api::Metadata = ruma_api::Metadata {
|
||||
description: #description,
|
||||
method: ::http::Method::#method,
|
||||
method: ruma_api::exports::http::Method::#method,
|
||||
name: #name,
|
||||
path: #path,
|
||||
rate_limited: #rate_limited,
|
||||
|
@ -28,8 +28,8 @@ impl Request {
|
||||
|
||||
quote! {
|
||||
headers.append(
|
||||
::http::header::#header_name,
|
||||
::http::header::HeaderValue::from_str(request.#field_name.as_ref())
|
||||
ruma_api::exports::http::header::#header_name,
|
||||
ruma_api::exports::http::header::HeaderValue::from_str(request.#field_name.as_ref())
|
||||
.expect("failed to convert value into HeaderValue"),
|
||||
);
|
||||
}
|
||||
@ -52,9 +52,9 @@ impl Request {
|
||||
let header_name_string = header_name.to_string();
|
||||
|
||||
quote! {
|
||||
#field_name: headers.get(::http::header::#header_name)
|
||||
#field_name: headers.get(ruma_api::exports::http::header::#header_name)
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.ok_or(::serde_json::Error::missing_field(#header_name_string))?
|
||||
.ok_or(ruma_api::exports::serde_json::Error::missing_field(#header_name_string))?
|
||||
.to_owned()
|
||||
}
|
||||
});
|
||||
@ -261,7 +261,7 @@ impl ToTokens for Request {
|
||||
|
||||
quote_spanned! {span=>
|
||||
/// Data in the request body.
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, ruma_api::exports::serde::Deserialize, ruma_api::exports::serde::Serialize)]
|
||||
struct RequestBody(#ty);
|
||||
}
|
||||
} else if self.has_body_fields() {
|
||||
@ -278,7 +278,7 @@ impl ToTokens for Request {
|
||||
|
||||
quote! {
|
||||
/// Data in the request body.
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, ruma_api::exports::serde::Deserialize, ruma_api::exports::serde::Serialize)]
|
||||
struct RequestBody {
|
||||
#(#fields),*
|
||||
}
|
||||
@ -302,7 +302,7 @@ impl ToTokens for Request {
|
||||
|
||||
quote! {
|
||||
/// Data in the request path.
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, ruma_api::exports::serde::Deserialize, ruma_api::exports::serde::Serialize)]
|
||||
struct RequestPath {
|
||||
#(#fields),*
|
||||
}
|
||||
@ -325,7 +325,7 @@ impl ToTokens for Request {
|
||||
|
||||
quote! {
|
||||
/// Data in the request's query string.
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, ruma_api::exports::serde::Deserialize, ruma_api::exports::serde::Serialize)]
|
||||
struct RequestQuery {
|
||||
#(#fields),*
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ impl Response {
|
||||
let span = field.span();
|
||||
|
||||
quote_spanned! {span=>
|
||||
#field_name: headers.remove(::http::header::#header_name)
|
||||
#field_name: headers.remove(ruma_api::exports::http::header::#header_name)
|
||||
.expect("response missing expected header")
|
||||
.to_str()
|
||||
.expect("failed to convert HeaderValue to str")
|
||||
@ -97,7 +97,7 @@ impl Response {
|
||||
let span = field.span();
|
||||
|
||||
Some(quote_spanned! {span=>
|
||||
.header(::http::header::#header_name, response.#field_name)
|
||||
.header(ruma_api::exports::http::header::#header_name, response.#field_name)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
@ -247,7 +247,7 @@ impl ToTokens for Response {
|
||||
|
||||
quote_spanned! {span=>
|
||||
/// Data in the response body.
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, ruma_api::exports::serde::Deserialize, ruma_api::exports::serde::Serialize)]
|
||||
struct ResponseBody(#ty);
|
||||
}
|
||||
} else if self.has_body_fields() {
|
||||
@ -264,7 +264,7 @@ impl ToTokens for Response {
|
||||
|
||||
quote! {
|
||||
/// Data in the response body.
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, ruma_api::exports::serde::Deserialize, ruma_api::exports::serde::Serialize)]
|
||||
struct ResponseBody {
|
||||
#(#fields),*
|
||||
}
|
||||
|
@ -139,11 +139,10 @@ mod api;
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// ```rust,ignore
|
||||
/// # fn main() {
|
||||
/// pub mod some_endpoint {
|
||||
/// use ruma_api_macros::ruma_api;
|
||||
/// use serde::{Deserialize, Serialize};
|
||||
///
|
||||
/// ruma_api! {
|
||||
/// metadata {
|
||||
@ -179,7 +178,6 @@ mod api;
|
||||
///
|
||||
/// pub mod newtype_body_endpoint {
|
||||
/// use ruma_api_macros::ruma_api;
|
||||
/// use serde::{Deserialize, Serialize};
|
||||
///
|
||||
/// #[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
/// pub struct MyCustomType {
|
||||
|
16
src/lib.rs
16
src/lib.rs
@ -47,6 +47,22 @@ use ruma_identifiers;
|
||||
use serde_json;
|
||||
use serde_urlencoded;
|
||||
|
||||
#[cfg(feature = "with-ruma-api-macros")]
|
||||
pub use ruma_api_macros::ruma_api;
|
||||
|
||||
#[cfg(feature = "with-ruma-api-macros")]
|
||||
#[doc(hidden)]
|
||||
/// This module is used to support the generated code from ruma-api-macros.
|
||||
/// It is not considered part of ruma-api's public API.
|
||||
pub mod exports {
|
||||
pub use http;
|
||||
pub use percent_encoding;
|
||||
pub use serde;
|
||||
pub use serde_json;
|
||||
pub use serde_urlencoded;
|
||||
pub use url;
|
||||
}
|
||||
|
||||
/// A Matrix API endpoint.
|
||||
///
|
||||
/// The type implementing this trait contains any data needed to make a request to the endpoint.
|
||||
|
@ -1,6 +1,5 @@
|
||||
pub mod some_endpoint {
|
||||
use ruma_api_macros::ruma_api;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ruma_api::ruma_api;
|
||||
|
||||
ruma_api! {
|
||||
metadata {
|
||||
@ -40,3 +39,33 @@ pub mod some_endpoint {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod newtype_body_endpoint {
|
||||
use ruma_api_macros::ruma_api;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct MyCustomType {
|
||||
pub foo: String,
|
||||
}
|
||||
|
||||
ruma_api! {
|
||||
metadata {
|
||||
description: "Does something.",
|
||||
method: GET,
|
||||
name: "newtype_body_endpoint",
|
||||
path: "/_matrix/some/newtype/body/endpoint",
|
||||
rate_limited: false,
|
||||
requires_authentication: false,
|
||||
}
|
||||
|
||||
request {
|
||||
#[ruma_api(body)]
|
||||
pub file: Vec<u8>,
|
||||
}
|
||||
|
||||
response {
|
||||
#[ruma_api(body)]
|
||||
pub my_custom_type: MyCustomType,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user