Use ruma_api crate from ruma or if renamed or not in crate prelude
This commit is contained in:
parent
45aad4d10c
commit
6877c2f38d
@ -19,6 +19,7 @@ edition = "2018"
|
|||||||
proc-macro2 = "1.0.19"
|
proc-macro2 = "1.0.19"
|
||||||
quote = "1.0.7"
|
quote = "1.0.7"
|
||||||
syn = { version = "1.0.38", features = ["full", "extra-traits"] }
|
syn = { version = "1.0.38", features = ["full", "extra-traits"] }
|
||||||
|
proc-macro-crate = "0.1.5"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
use std::convert::{TryFrom, TryInto as _};
|
use std::convert::{TryFrom, TryInto as _};
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::{Span, TokenStream};
|
||||||
|
use proc_macro_crate::crate_name;
|
||||||
use quote::{quote, ToTokens};
|
use quote::{quote, ToTokens};
|
||||||
use syn::{
|
use syn::{
|
||||||
braced,
|
braced,
|
||||||
parse::{Parse, ParseStream},
|
parse::{Parse, ParseStream},
|
||||||
spanned::Spanned,
|
spanned::Spanned,
|
||||||
Field, FieldValue, Token, Type,
|
Field, FieldValue, Ident, Token, Type,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) mod attribute;
|
pub(crate) mod attribute;
|
||||||
@ -26,6 +27,15 @@ pub fn strip_serde_attrs(field: &Field) -> Field {
|
|||||||
field
|
field
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn import_ruma_api() -> TokenStream {
|
||||||
|
if let Ok(name) = crate_name("ruma-api") {
|
||||||
|
let import = Ident::new(&name, Span::call_site());
|
||||||
|
quote! { ::#import }
|
||||||
|
} else {
|
||||||
|
quote! { ::ruma_api }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The result of processing the `ruma_api` macro, ready for output back to source code.
|
/// The result of processing the `ruma_api` macro, ready for output back to source code.
|
||||||
pub struct Api {
|
pub struct Api {
|
||||||
/// The `metadata` section of the macro.
|
/// The `metadata` section of the macro.
|
||||||
@ -82,6 +92,9 @@ impl TryFrom<RawApi> for Api {
|
|||||||
|
|
||||||
impl ToTokens for Api {
|
impl ToTokens for Api {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
|
// Guarantee `ruma_api` is available and named something we can refer to.
|
||||||
|
let ruma_api_import = import_ruma_api();
|
||||||
|
|
||||||
let description = &self.metadata.description;
|
let description = &self.metadata.description;
|
||||||
let method = &self.metadata.method;
|
let method = &self.metadata.method;
|
||||||
// We don't (currently) use this literal as a literal in the generated code. Instead we just
|
// We don't (currently) use this literal as a literal in the generated code. Instead we just
|
||||||
@ -130,12 +143,12 @@ impl ToTokens for Api {
|
|||||||
let mut header_kvs = self.request.append_header_kvs();
|
let mut header_kvs = self.request.append_header_kvs();
|
||||||
if requires_authentication.value {
|
if requires_authentication.value {
|
||||||
header_kvs.push(quote! {
|
header_kvs.push(quote! {
|
||||||
::ruma_api::exports::http::header::AUTHORIZATION,
|
#ruma_api_import::exports::http::header::AUTHORIZATION,
|
||||||
::ruma_api::exports::http::header::HeaderValue::from_str(
|
#ruma_api_import::exports::http::header::HeaderValue::from_str(
|
||||||
&::std::format!(
|
&::std::format!(
|
||||||
"Bearer {}",
|
"Bearer {}",
|
||||||
access_token.ok_or_else(
|
access_token.ok_or_else(
|
||||||
::ruma_api::error::IntoHttpError::needs_authentication
|
#ruma_api_import::error::IntoHttpError::needs_authentication
|
||||||
)?
|
)?
|
||||||
)
|
)
|
||||||
)?
|
)?
|
||||||
@ -162,10 +175,10 @@ impl ToTokens for Api {
|
|||||||
TokenStream::new()
|
TokenStream::new()
|
||||||
};
|
};
|
||||||
quote! {
|
quote! {
|
||||||
let request_body: <RequestBody #body_lifetimes as ::ruma_api::Outgoing>::Incoming =
|
let request_body: <RequestBody #body_lifetimes as #ruma_api_import::Outgoing>::Incoming =
|
||||||
::ruma_api::try_deserialize!(
|
#ruma_api_import::try_deserialize!(
|
||||||
request,
|
request,
|
||||||
::ruma_api::exports::serde_json::from_slice(request.body().as_slice())
|
#ruma_api_import::exports::serde_json::from_slice(request.body().as_slice())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -190,18 +203,19 @@ impl ToTokens for Api {
|
|||||||
TokenStream::new()
|
TokenStream::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let typed_response_body_decl =
|
let typed_response_body_decl = if self.response.has_body_fields()
|
||||||
if self.response.has_body_fields() || self.response.newtype_body_field().is_some() {
|
|| self.response.newtype_body_field().is_some()
|
||||||
quote! {
|
{
|
||||||
let response_body: <ResponseBody as ::ruma_api::Outgoing>::Incoming =
|
quote! {
|
||||||
::ruma_api::try_deserialize!(
|
let response_body: <ResponseBody as #ruma_api_import::Outgoing>::Incoming =
|
||||||
response,
|
#ruma_api_import::try_deserialize!(
|
||||||
::ruma_api::exports::serde_json::from_slice(response.body().as_slice()),
|
response,
|
||||||
);
|
#ruma_api_import::exports::serde_json::from_slice(response.body().as_slice()),
|
||||||
}
|
);
|
||||||
} else {
|
}
|
||||||
TokenStream::new()
|
} else {
|
||||||
};
|
TokenStream::new()
|
||||||
|
};
|
||||||
|
|
||||||
let response_init_fields = self.response.init_fields();
|
let response_init_fields = self.response.init_fields();
|
||||||
|
|
||||||
@ -224,22 +238,23 @@ impl ToTokens for Api {
|
|||||||
TokenStream::new()
|
TokenStream::new()
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
impl #request_lifetimes ::ruma_api::NonAuthEndpoint
|
impl #request_lifetimes #ruma_api_import::NonAuthEndpoint
|
||||||
for Request #request_lifetimes
|
for Request #request_lifetimes
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let api = quote! {
|
let api = quote! {
|
||||||
|
|
||||||
#[doc = #request_doc]
|
#[doc = #request_doc]
|
||||||
#request_type
|
#request_type
|
||||||
|
|
||||||
impl ::std::convert::TryFrom<::ruma_api::exports::http::Request<Vec<u8>>> for #request_try_from_type {
|
impl ::std::convert::TryFrom<#ruma_api_import::exports::http::Request<Vec<u8>>> for #request_try_from_type {
|
||||||
type Error = ::ruma_api::error::FromHttpRequestError;
|
type Error = #ruma_api_import::error::FromHttpRequestError;
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn try_from(
|
fn try_from(
|
||||||
request: ::ruma_api::exports::http::Request<Vec<u8>>
|
request: #ruma_api_import::exports::http::Request<Vec<u8>>
|
||||||
) -> ::std::result::Result<Self, Self::Error> {
|
) -> ::std::result::Result<Self, Self::Error> {
|
||||||
#extract_request_path
|
#extract_request_path
|
||||||
#extract_request_query
|
#extract_request_query
|
||||||
@ -258,13 +273,13 @@ impl ToTokens for Api {
|
|||||||
#[doc = #response_doc]
|
#[doc = #response_doc]
|
||||||
#response_type
|
#response_type
|
||||||
|
|
||||||
impl ::std::convert::TryFrom<Response> for ::ruma_api::exports::http::Response<Vec<u8>> {
|
impl ::std::convert::TryFrom<Response> for #ruma_api_import::exports::http::Response<Vec<u8>> {
|
||||||
type Error = ::ruma_api::error::IntoHttpError;
|
type Error = #ruma_api_import::error::IntoHttpError;
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn try_from(response: Response) -> ::std::result::Result<Self, Self::Error> {
|
fn try_from(response: Response) -> ::std::result::Result<Self, Self::Error> {
|
||||||
let response = ::ruma_api::exports::http::Response::builder()
|
let response = #ruma_api_import::exports::http::Response::builder()
|
||||||
.header(::ruma_api::exports::http::header::CONTENT_TYPE, "application/json")
|
.header(#ruma_api_import::exports::http::header::CONTENT_TYPE, "application/json")
|
||||||
#serialize_response_headers
|
#serialize_response_headers
|
||||||
.body(#body)
|
.body(#body)
|
||||||
// Since we require header names to come from the `http::header` module,
|
// Since we require header names to come from the `http::header` module,
|
||||||
@ -274,12 +289,12 @@ impl ToTokens for Api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::convert::TryFrom<::ruma_api::exports::http::Response<Vec<u8>>> for Response {
|
impl ::std::convert::TryFrom<#ruma_api_import::exports::http::Response<Vec<u8>>> for Response {
|
||||||
type Error = ::ruma_api::error::FromHttpResponseError<#error>;
|
type Error = #ruma_api_import::error::FromHttpResponseError<#error>;
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn try_from(
|
fn try_from(
|
||||||
response: ::ruma_api::exports::http::Response<Vec<u8>>,
|
response: #ruma_api_import::exports::http::Response<Vec<u8>>,
|
||||||
) -> ::std::result::Result<Self, Self::Error> {
|
) -> ::std::result::Result<Self, Self::Error> {
|
||||||
if response.status().as_u16() < 400 {
|
if response.status().as_u16() < 400 {
|
||||||
#extract_response_headers
|
#extract_response_headers
|
||||||
@ -290,26 +305,26 @@ impl ToTokens for Api {
|
|||||||
#response_init_fields
|
#response_init_fields
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
match <#error as ::ruma_api::EndpointError>::try_from_response(response) {
|
match <#error as #ruma_api_import::EndpointError>::try_from_response(response) {
|
||||||
Ok(err) => Err(::ruma_api::error::ServerError::Known(err).into()),
|
Ok(err) => Err(#ruma_api_import::error::ServerError::Known(err).into()),
|
||||||
Err(response_err) => {
|
Err(response_err) => {
|
||||||
Err(::ruma_api::error::ServerError::Unknown(response_err).into())
|
Err(#ruma_api_import::error::ServerError::Unknown(response_err).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #request_lifetimes ::ruma_api::Endpoint for Request #request_lifetimes {
|
impl #request_lifetimes #ruma_api_import::Endpoint for Request #request_lifetimes {
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
type ResponseError = #error;
|
type ResponseError = #error;
|
||||||
type IncomingRequest = <Self as ::ruma_api::Outgoing>::Incoming;
|
type IncomingRequest = <Self as #ruma_api_import::Outgoing>::Incoming;
|
||||||
type IncomingResponse = <Response as ::ruma_api::Outgoing>::Incoming;
|
type IncomingResponse = <Response as #ruma_api_import::Outgoing>::Incoming;
|
||||||
|
|
||||||
/// Metadata for the `#name` endpoint.
|
/// Metadata for the `#name` endpoint.
|
||||||
const METADATA: ::ruma_api::Metadata = ::ruma_api::Metadata {
|
const METADATA: #ruma_api_import::Metadata = #ruma_api_import::Metadata {
|
||||||
description: #description,
|
description: #description,
|
||||||
method: ::ruma_api::exports::http::Method::#method,
|
method: #ruma_api_import::exports::http::Method::#method,
|
||||||
name: #name,
|
name: #name,
|
||||||
path: #path,
|
path: #path,
|
||||||
rate_limited: #rate_limited,
|
rate_limited: #rate_limited,
|
||||||
@ -322,13 +337,13 @@ impl ToTokens for Api {
|
|||||||
base_url: &::std::primitive::str,
|
base_url: &::std::primitive::str,
|
||||||
access_token: ::std::option::Option<&str>,
|
access_token: ::std::option::Option<&str>,
|
||||||
) -> ::std::result::Result<
|
) -> ::std::result::Result<
|
||||||
::ruma_api::exports::http::Request<Vec<u8>>,
|
#ruma_api_import::exports::http::Request<Vec<u8>>,
|
||||||
::ruma_api::error::IntoHttpError,
|
#ruma_api_import::error::IntoHttpError,
|
||||||
> {
|
> {
|
||||||
let metadata = Request::METADATA;
|
let metadata = Request::METADATA;
|
||||||
|
|
||||||
let http_request = ::ruma_api::exports::http::Request::builder()
|
let http_request = #ruma_api_import::exports::http::Request::builder()
|
||||||
.method(::ruma_api::exports::http::Method::#method)
|
.method(#ruma_api_import::exports::http::Method::#method)
|
||||||
.uri(::std::format!(
|
.uri(::std::format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
base_url.strip_suffix("/").unwrap_or(base_url),
|
base_url.strip_suffix("/").unwrap_or(base_url),
|
||||||
|
@ -9,7 +9,7 @@ use syn::{spanned::Spanned, Field, Ident, Lifetime};
|
|||||||
use crate::{
|
use crate::{
|
||||||
api::{
|
api::{
|
||||||
attribute::{Meta, MetaNameValue},
|
attribute::{Meta, MetaNameValue},
|
||||||
strip_serde_attrs, RawRequest,
|
import_ruma_api, strip_serde_attrs, RawRequest,
|
||||||
},
|
},
|
||||||
util,
|
util,
|
||||||
};
|
};
|
||||||
@ -29,11 +29,15 @@ pub struct Request {
|
|||||||
|
|
||||||
/// The collected lifetime identifiers from the declared fields.
|
/// The collected lifetime identifiers from the declared fields.
|
||||||
lifetimes: RequestLifetimes,
|
lifetimes: RequestLifetimes,
|
||||||
|
|
||||||
|
// Guarantee `ruma_api` is available and named something we can refer to.
|
||||||
|
ruma_api_import: TokenStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Request {
|
impl Request {
|
||||||
/// Produces code to add necessary HTTP headers to an `http::Request`.
|
/// Produces code to add necessary HTTP headers to an `http::Request`.
|
||||||
pub fn append_header_kvs(&self) -> Vec<TokenStream> {
|
pub fn append_header_kvs(&self) -> Vec<TokenStream> {
|
||||||
|
let ruma_api = &self.ruma_api_import;
|
||||||
self.header_fields().map(|request_field| {
|
self.header_fields().map(|request_field| {
|
||||||
let (field, header_name) = match request_field {
|
let (field, header_name) = match request_field {
|
||||||
RequestField::Header(field, header_name) => (field, header_name),
|
RequestField::Header(field, header_name) => (field, header_name),
|
||||||
@ -43,14 +47,15 @@ impl Request {
|
|||||||
let field_name = &field.ident;
|
let field_name = &field.ident;
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
::ruma_api::exports::http::header::#header_name,
|
#ruma_api::exports::http::header::#header_name,
|
||||||
::ruma_api::exports::http::header::HeaderValue::from_str(self.#field_name.as_ref())?
|
#ruma_api::exports::http::header::HeaderValue::from_str(self.#field_name.as_ref())?
|
||||||
}
|
}
|
||||||
}).collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Produces code to extract fields from the HTTP headers in an `http::Request`.
|
/// Produces code to extract fields from the HTTP headers in an `http::Request`.
|
||||||
pub fn parse_headers_from_request(&self) -> TokenStream {
|
pub fn parse_headers_from_request(&self) -> TokenStream {
|
||||||
|
let ruma_api = &self.ruma_api_import;
|
||||||
let fields = self.header_fields().map(|request_field| {
|
let fields = self.header_fields().map(|request_field| {
|
||||||
let (field, header_name) = match request_field {
|
let (field, header_name) = match request_field {
|
||||||
RequestField::Header(field, header_name) => (field, header_name),
|
RequestField::Header(field, header_name) => (field, header_name),
|
||||||
@ -62,16 +67,16 @@ impl Request {
|
|||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#field_name: match headers
|
#field_name: match headers
|
||||||
.get(::ruma_api::exports::http::header::#header_name)
|
.get(#ruma_api::exports::http::header::#header_name)
|
||||||
.and_then(|v| v.to_str().ok()) // FIXME: Should have a distinct error message
|
.and_then(|v| v.to_str().ok()) // FIXME: Should have a distinct error message
|
||||||
{
|
{
|
||||||
Some(header) => header.to_owned(),
|
Some(header) => header.to_owned(),
|
||||||
None => {
|
None => {
|
||||||
use ::ruma_api::exports::serde::de::Error as _;
|
use #ruma_api::exports::serde::de::Error as _;
|
||||||
|
|
||||||
// FIXME: Not a missing json field, a missing header!
|
// FIXME: Not a missing json field, a missing header!
|
||||||
return Err(::ruma_api::error::RequestDeserializationError::new(
|
return Err(#ruma_api::error::RequestDeserializationError::new(
|
||||||
::ruma_api::exports::serde_json::Error::missing_field(
|
#ruma_api::exports::serde_json::Error::missing_field(
|
||||||
#header_name_string
|
#header_name_string
|
||||||
),
|
),
|
||||||
request,
|
request,
|
||||||
@ -377,12 +382,13 @@ impl TryFrom<RawRequest> for Request {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self { fields, lifetimes })
|
Ok(Self { fields, lifetimes, ruma_api_import: import_ruma_api() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToTokens for Request {
|
impl ToTokens for Request {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
|
let ruma_api = &self.ruma_api_import;
|
||||||
let request_def = if self.fields.is_empty() {
|
let request_def = if self.fields.is_empty() {
|
||||||
quote!(;)
|
quote!(;)
|
||||||
} else {
|
} else {
|
||||||
@ -403,7 +409,7 @@ impl ToTokens for Request {
|
|||||||
let (derive_deserialize, lifetimes) = if self.has_body_lifetimes() {
|
let (derive_deserialize, lifetimes) = if self.has_body_lifetimes() {
|
||||||
(TokenStream::new(), self.body_lifetimes())
|
(TokenStream::new(), self.body_lifetimes())
|
||||||
} else {
|
} else {
|
||||||
(quote!(::ruma_api::exports::serde::Deserialize), TokenStream::new())
|
(quote!(#ruma_api::exports::serde::Deserialize), TokenStream::new())
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((derive_deserialize, quote! { #lifetimes (#field); }))
|
Some((derive_deserialize, quote! { #lifetimes (#field); }))
|
||||||
@ -412,7 +418,7 @@ impl ToTokens for Request {
|
|||||||
let (derive_deserialize, lifetimes) = if self.has_body_lifetimes() {
|
let (derive_deserialize, lifetimes) = if self.has_body_lifetimes() {
|
||||||
(TokenStream::new(), self.body_lifetimes())
|
(TokenStream::new(), self.body_lifetimes())
|
||||||
} else {
|
} else {
|
||||||
(quote!(::ruma_api::exports::serde::Deserialize), TokenStream::new())
|
(quote!(#ruma_api::exports::serde::Deserialize), TokenStream::new())
|
||||||
};
|
};
|
||||||
let fields = fields.map(RequestField::field);
|
let fields = fields.map(RequestField::field);
|
||||||
|
|
||||||
@ -425,8 +431,8 @@ impl ToTokens for Request {
|
|||||||
/// Data in the request body.
|
/// Data in the request body.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
::ruma_api::Outgoing,
|
#ruma_api::Outgoing,
|
||||||
::ruma_api::exports::serde::Serialize,
|
#ruma_api::exports::serde::Serialize,
|
||||||
#derive_deserialize
|
#derive_deserialize
|
||||||
)]
|
)]
|
||||||
struct RequestBody #def
|
struct RequestBody #def
|
||||||
@ -438,15 +444,15 @@ impl ToTokens for Request {
|
|||||||
let (derive_deserialize, lifetime) = if self.has_query_lifetimes() {
|
let (derive_deserialize, lifetime) = if self.has_query_lifetimes() {
|
||||||
(TokenStream::new(), self.query_lifetimes())
|
(TokenStream::new(), self.query_lifetimes())
|
||||||
} else {
|
} else {
|
||||||
(quote!(::ruma_api::exports::serde::Deserialize), TokenStream::new())
|
(quote!(#ruma_api::exports::serde::Deserialize), TokenStream::new())
|
||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
/// Data in the request's query string.
|
/// Data in the request's query string.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
::ruma_api::Outgoing,
|
#ruma_api::Outgoing,
|
||||||
::ruma_api::exports::serde::Serialize,
|
#ruma_api::exports::serde::Serialize,
|
||||||
#derive_deserialize
|
#derive_deserialize
|
||||||
)]
|
)]
|
||||||
struct RequestQuery #lifetime (#field);
|
struct RequestQuery #lifetime (#field);
|
||||||
@ -456,15 +462,15 @@ impl ToTokens for Request {
|
|||||||
let (derive_deserialize, lifetime) = if self.has_query_lifetimes() {
|
let (derive_deserialize, lifetime) = if self.has_query_lifetimes() {
|
||||||
(TokenStream::new(), self.query_lifetimes())
|
(TokenStream::new(), self.query_lifetimes())
|
||||||
} else {
|
} else {
|
||||||
(quote!(::ruma_api::exports::serde::Deserialize), TokenStream::new())
|
(quote!(#ruma_api::exports::serde::Deserialize), TokenStream::new())
|
||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
/// Data in the request's query string.
|
/// Data in the request's query string.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
::ruma_api::Outgoing,
|
#ruma_api::Outgoing,
|
||||||
::ruma_api::exports::serde::Serialize,
|
#ruma_api::exports::serde::Serialize,
|
||||||
#derive_deserialize
|
#derive_deserialize
|
||||||
)]
|
)]
|
||||||
struct RequestQuery #lifetime {
|
struct RequestQuery #lifetime {
|
||||||
@ -476,7 +482,7 @@ impl ToTokens for Request {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let request = quote! {
|
let request = quote! {
|
||||||
#[derive(Debug, Clone, ::ruma_api::Outgoing)]
|
#[derive(Debug, Clone, #ruma_api::Outgoing)]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_no_deserialize]
|
||||||
pub struct Request #request_generics #request_def
|
pub struct Request #request_generics #request_def
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use syn::{spanned::Spanned, Field, Ident};
|
|||||||
use crate::{
|
use crate::{
|
||||||
api::{
|
api::{
|
||||||
attribute::{Meta, MetaNameValue},
|
attribute::{Meta, MetaNameValue},
|
||||||
strip_serde_attrs, RawResponse,
|
import_ruma_api, strip_serde_attrs, RawResponse,
|
||||||
},
|
},
|
||||||
util,
|
util,
|
||||||
};
|
};
|
||||||
@ -18,6 +18,9 @@ use crate::{
|
|||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// The fields of the response.
|
/// The fields of the response.
|
||||||
fields: Vec<ResponseField>,
|
fields: Vec<ResponseField>,
|
||||||
|
|
||||||
|
// Guarantee `ruma_api` is available and named something we can refer to.
|
||||||
|
ruma_api_import: TokenStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Response {
|
impl Response {
|
||||||
@ -33,6 +36,8 @@ impl Response {
|
|||||||
|
|
||||||
/// Produces code for a response struct initializer.
|
/// Produces code for a response struct initializer.
|
||||||
pub fn init_fields(&self) -> TokenStream {
|
pub fn init_fields(&self) -> TokenStream {
|
||||||
|
let ruma_api = &self.ruma_api_import;
|
||||||
|
|
||||||
let mut fields = vec![];
|
let mut fields = vec![];
|
||||||
let mut new_type_raw_body = None;
|
let mut new_type_raw_body = None;
|
||||||
for response_field in &self.fields {
|
for response_field in &self.fields {
|
||||||
@ -51,9 +56,9 @@ impl Response {
|
|||||||
}
|
}
|
||||||
ResponseField::Header(_, header_name) => {
|
ResponseField::Header(_, header_name) => {
|
||||||
quote_spanned! {span=>
|
quote_spanned! {span=>
|
||||||
#field_name: ::ruma_api::try_deserialize!(
|
#field_name: #ruma_api::try_deserialize!(
|
||||||
response,
|
response,
|
||||||
headers.remove(::ruma_api::exports::http::header::#header_name)
|
headers.remove(#ruma_api::exports::http::header::#header_name)
|
||||||
.expect("response missing expected header")
|
.expect("response missing expected header")
|
||||||
.to_str()
|
.to_str()
|
||||||
)
|
)
|
||||||
@ -86,6 +91,8 @@ impl Response {
|
|||||||
|
|
||||||
/// Produces code to add necessary HTTP headers to an `http::Response`.
|
/// Produces code to add necessary HTTP headers to an `http::Response`.
|
||||||
pub fn apply_header_fields(&self) -> TokenStream {
|
pub fn apply_header_fields(&self) -> TokenStream {
|
||||||
|
let ruma_api = &self.ruma_api_import;
|
||||||
|
|
||||||
let header_calls = self.fields.iter().filter_map(|response_field| {
|
let header_calls = self.fields.iter().filter_map(|response_field| {
|
||||||
if let ResponseField::Header(ref field, ref header_name) = *response_field {
|
if let ResponseField::Header(ref field, ref header_name) = *response_field {
|
||||||
let field_name =
|
let field_name =
|
||||||
@ -93,7 +100,7 @@ impl Response {
|
|||||||
let span = field.span();
|
let span = field.span();
|
||||||
|
|
||||||
Some(quote_spanned! {span=>
|
Some(quote_spanned! {span=>
|
||||||
.header(::ruma_api::exports::http::header::#header_name, response.#field_name)
|
.header(#ruma_api::exports::http::header::#header_name, response.#field_name)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -105,6 +112,8 @@ impl Response {
|
|||||||
|
|
||||||
/// Produces code to initialize the struct that will be used to create the response body.
|
/// Produces code to initialize the struct that will be used to create the response body.
|
||||||
pub fn to_body(&self) -> TokenStream {
|
pub fn to_body(&self) -> TokenStream {
|
||||||
|
let ruma_api = &self.ruma_api_import;
|
||||||
|
|
||||||
if let Some(field) = self.newtype_raw_body_field() {
|
if let Some(field) = self.newtype_raw_body_field() {
|
||||||
let field_name = field.ident.as_ref().expect("expected field to have an identifier");
|
let field_name = field.ident.as_ref().expect("expected field to have an identifier");
|
||||||
let span = field.span();
|
let span = field.span();
|
||||||
@ -138,7 +147,7 @@ impl Response {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
quote!(::ruma_api::exports::serde_json::to_vec(&#body)?)
|
quote!(#ruma_api::exports::serde_json::to_vec(&#body)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the newtype body field, if this response has one.
|
/// Gets the newtype body field, if this response has one.
|
||||||
@ -225,12 +234,14 @@ impl TryFrom<RawResponse> for Response {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self { fields })
|
Ok(Self { fields, ruma_api_import: import_ruma_api() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToTokens for Response {
|
impl ToTokens for Response {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
|
let ruma_api = &self.ruma_api_import;
|
||||||
|
|
||||||
let response_def = if self.fields.is_empty() {
|
let response_def = if self.fields.is_empty() {
|
||||||
quote!(;)
|
quote!(;)
|
||||||
} else {
|
} else {
|
||||||
@ -258,15 +269,15 @@ impl ToTokens for Response {
|
|||||||
/// Data in the response body.
|
/// Data in the response body.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
::ruma_api::Outgoing,
|
#ruma_api::Outgoing,
|
||||||
::ruma_api::exports::serde::Deserialize,
|
#ruma_api::exports::serde::Deserialize,
|
||||||
::ruma_api::exports::serde::Serialize,
|
#ruma_api::exports::serde::Serialize,
|
||||||
)]
|
)]
|
||||||
struct ResponseBody #def
|
struct ResponseBody #def
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = quote! {
|
let response = quote! {
|
||||||
#[derive(Debug, Clone, ::ruma_api::Outgoing)]
|
#[derive(Debug, Clone, #ruma_api::Outgoing)]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_no_deserialize]
|
||||||
pub struct Response #response_def
|
pub struct Response #response_def
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user