Move Outgoing from ruma-api to ruma-common
The derive macro moves from ruma-api-macros to a new ruma-common-macros crate likewise.
This commit is contained in:
parent
7b08dceb30
commit
fdd326edf7
@ -170,7 +170,10 @@ impl ToTokens for Api {
|
|||||||
TokenStream::new()
|
TokenStream::new()
|
||||||
};
|
};
|
||||||
quote! {
|
quote! {
|
||||||
let request_body: <RequestBody #body_lifetimes as #ruma_api_import::Outgoing>::Incoming =
|
let request_body: <
|
||||||
|
RequestBody #body_lifetimes
|
||||||
|
as #ruma_api_import::exports::ruma_common::Outgoing
|
||||||
|
>::Incoming =
|
||||||
#ruma_api_import::try_deserialize!(
|
#ruma_api_import::try_deserialize!(
|
||||||
request,
|
request,
|
||||||
#ruma_api_import::exports::serde_json::from_slice(request.body().as_slice())
|
#ruma_api_import::exports::serde_json::from_slice(request.body().as_slice())
|
||||||
@ -202,7 +205,10 @@ impl ToTokens for Api {
|
|||||||
|| self.response.newtype_body_field().is_some()
|
|| self.response.newtype_body_field().is_some()
|
||||||
{
|
{
|
||||||
quote! {
|
quote! {
|
||||||
let response_body: <ResponseBody as #ruma_api_import::Outgoing>::Incoming =
|
let response_body: <
|
||||||
|
ResponseBody
|
||||||
|
as #ruma_api_import::exports::ruma_common::Outgoing
|
||||||
|
>::Incoming =
|
||||||
#ruma_api_import::try_deserialize!(
|
#ruma_api_import::try_deserialize!(
|
||||||
response,
|
response,
|
||||||
#ruma_api_import::exports::serde_json::from_slice(response.body().as_slice()),
|
#ruma_api_import::exports::serde_json::from_slice(response.body().as_slice()),
|
||||||
@ -328,7 +334,8 @@ impl ToTokens for Api {
|
|||||||
for Request #request_lifetimes
|
for Request #request_lifetimes
|
||||||
{
|
{
|
||||||
type EndpointError = #error;
|
type EndpointError = #error;
|
||||||
type IncomingResponse = <Response as #ruma_api_import::Outgoing>::Incoming;
|
type IncomingResponse =
|
||||||
|
<Response as #ruma_api_import::exports::ruma_common::Outgoing>::Incoming;
|
||||||
|
|
||||||
#[doc = #metadata_doc]
|
#[doc = #metadata_doc]
|
||||||
const METADATA: #ruma_api_import::Metadata = __METADATA;
|
const METADATA: #ruma_api_import::Metadata = __METADATA;
|
||||||
|
@ -470,7 +470,7 @@ impl ToTokens for Request {
|
|||||||
/// Data in the request body.
|
/// Data in the request body.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
#import_path::Outgoing,
|
#import_path::exports::ruma_common::Outgoing,
|
||||||
#import_path::exports::serde::Serialize,
|
#import_path::exports::serde::Serialize,
|
||||||
#derive_deserialize
|
#derive_deserialize
|
||||||
)]
|
)]
|
||||||
@ -490,7 +490,7 @@ impl ToTokens for Request {
|
|||||||
/// Data in the request's query string.
|
/// Data in the request's query string.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
#import_path::Outgoing,
|
#import_path::exports::ruma_common::Outgoing,
|
||||||
#import_path::exports::serde::Serialize,
|
#import_path::exports::serde::Serialize,
|
||||||
#derive_deserialize
|
#derive_deserialize
|
||||||
)]
|
)]
|
||||||
@ -508,7 +508,7 @@ impl ToTokens for Request {
|
|||||||
/// Data in the request's query string.
|
/// Data in the request's query string.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
#import_path::Outgoing,
|
#import_path::exports::ruma_common::Outgoing,
|
||||||
#import_path::exports::serde::Serialize,
|
#import_path::exports::serde::Serialize,
|
||||||
#derive_deserialize
|
#derive_deserialize
|
||||||
)]
|
)]
|
||||||
@ -521,7 +521,7 @@ impl ToTokens for Request {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let request = quote! {
|
let request = quote! {
|
||||||
#[derive(Debug, Clone, #import_path::Outgoing)]
|
#[derive(Debug, Clone, #import_path::exports::ruma_common::Outgoing)]
|
||||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
#[incoming_derive(!Deserialize)]
|
#[incoming_derive(!Deserialize)]
|
||||||
#( #struct_attributes )*
|
#( #struct_attributes )*
|
||||||
|
@ -310,7 +310,7 @@ impl ToTokens for Response {
|
|||||||
/// Data in the response body.
|
/// Data in the response body.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
#import_path::Outgoing,
|
#import_path::exports::ruma_common::Outgoing,
|
||||||
#import_path::exports::serde::Deserialize,
|
#import_path::exports::serde::Deserialize,
|
||||||
#import_path::exports::serde::Serialize,
|
#import_path::exports::serde::Serialize,
|
||||||
)]
|
)]
|
||||||
@ -318,7 +318,7 @@ impl ToTokens for Response {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let response = quote! {
|
let response = quote! {
|
||||||
#[derive(Debug, Clone, #import_path::Outgoing)]
|
#[derive(Debug, Clone, #import_path::exports::ruma_common::Outgoing)]
|
||||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
#[incoming_derive(!Deserialize)]
|
#[incoming_derive(!Deserialize)]
|
||||||
#( #struct_attributes )*
|
#( #struct_attributes )*
|
||||||
|
@ -15,15 +15,11 @@ use std::convert::TryFrom as _;
|
|||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use syn::{parse_macro_input, DeriveInput};
|
use syn::parse_macro_input;
|
||||||
|
|
||||||
use self::{
|
use self::api::{Api, RawApi};
|
||||||
api::{Api, RawApi},
|
|
||||||
derive_outgoing::expand_derive_outgoing,
|
|
||||||
};
|
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
mod derive_outgoing;
|
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
@ -34,50 +30,3 @@ pub fn ruma_api(input: TokenStream) -> TokenStream {
|
|||||||
Err(err) => err.to_compile_error().into(),
|
Err(err) => err.to_compile_error().into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Derive the `Outgoing` trait, possibly generating an 'Incoming' version of the struct this
|
|
||||||
/// derive macro is used on. Specifically, if no lifetime variables are used on any of the fields
|
|
||||||
/// of the struct, this simple implementation will be generated:
|
|
||||||
///
|
|
||||||
/// ```ignore
|
|
||||||
/// impl Outgoing for MyType {
|
|
||||||
/// type Incoming = Self;
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
|
|
||||||
/* TODO: Extend docs. Previously:
|
|
||||||
|
|
||||||
If, however, `#[wrap_incoming]` is used (which is the only reason you should ever use this
|
|
||||||
derive macro manually), a new struct `IncomingT` (where `T` is the type this derive is used on)
|
|
||||||
is generated, with all of the fields with `#[wrap_incoming]` replaced:
|
|
||||||
|
|
||||||
```ignore
|
|
||||||
#[derive(Outgoing)]
|
|
||||||
struct MyType {
|
|
||||||
pub foo: Foo,
|
|
||||||
#[wrap_incoming]
|
|
||||||
pub bar: Bar,
|
|
||||||
#[wrap_incoming(Baz)]
|
|
||||||
pub baz: Option<Baz>,
|
|
||||||
#[wrap_incoming(with EventResult)]
|
|
||||||
pub x: XEvent,
|
|
||||||
#[wrap_incoming(YEvent with EventResult)]
|
|
||||||
pub ys: Vec<YEvent>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// generated
|
|
||||||
struct IncomingMyType {
|
|
||||||
pub foo: Foo,
|
|
||||||
pub bar: IncomingBar,
|
|
||||||
pub baz: Option<IncomingBaz>,
|
|
||||||
pub x: EventResult<XEvent>,
|
|
||||||
pub ys: Vec<EventResult<YEvent>>,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
*/
|
|
||||||
#[proc_macro_derive(Outgoing, attributes(incoming_derive))]
|
|
||||||
pub fn derive_outgoing(input: TokenStream) -> TokenStream {
|
|
||||||
let input = parse_macro_input!(input as DeriveInput);
|
|
||||||
expand_derive_outgoing(input).unwrap_or_else(|err| err.to_compile_error()).into()
|
|
||||||
}
|
|
||||||
|
@ -285,7 +285,10 @@ pub(crate) fn extract_request_query(request: &Request, import_path: &TokenStream
|
|||||||
}
|
}
|
||||||
} else if request.has_query_fields() {
|
} else if request.has_query_fields() {
|
||||||
quote! {
|
quote! {
|
||||||
let request_query: <RequestQuery as #import_path::Outgoing>::Incoming =
|
let request_query: <
|
||||||
|
RequestQuery
|
||||||
|
as #import_path::exports::ruma_common::Outgoing
|
||||||
|
>::Incoming =
|
||||||
#import_path::try_deserialize!(
|
#import_path::try_deserialize!(
|
||||||
request,
|
request,
|
||||||
#import_path::exports::ruma_serde::urlencoded::from_str(
|
#import_path::exports::ruma_serde::urlencoded::from_str(
|
||||||
|
@ -19,6 +19,7 @@ edition = "2018"
|
|||||||
http = "0.2.1"
|
http = "0.2.1"
|
||||||
percent-encoding = "2.1.0"
|
percent-encoding = "2.1.0"
|
||||||
ruma-api-macros = { version = "=0.17.0-alpha.1", path = "../ruma-api-macros" }
|
ruma-api-macros = { version = "=0.17.0-alpha.1", path = "../ruma-api-macros" }
|
||||||
|
ruma-common = { version = "0.2.0", path = "../ruma-common" }
|
||||||
ruma-identifiers = { version = "0.17.4", path = "../ruma-identifiers" }
|
ruma-identifiers = { version = "0.17.4", path = "../ruma-identifiers" }
|
||||||
ruma-serde = { version = "0.2.3", path = "../ruma-serde" }
|
ruma-serde = { version = "0.2.3", path = "../ruma-serde" }
|
||||||
serde = { version = "1.0.114", features = ["derive"] }
|
serde = { version = "1.0.114", features = ["derive"] }
|
||||||
|
@ -204,11 +204,9 @@ use http::Method;
|
|||||||
/// All request and response types also derive [`Outgoing`][Outgoing]. As such, to allow fallible
|
/// All request and response types also derive [`Outgoing`][Outgoing]. As such, to allow fallible
|
||||||
/// deserialization, you can use the `#[wrap_incoming]` attribute. For details, see the
|
/// deserialization, you can use the `#[wrap_incoming]` attribute. For details, see the
|
||||||
/// documentation for [the derive macro](derive.Outgoing.html).
|
/// documentation for [the derive macro](derive.Outgoing.html).
|
||||||
// TODO: Explain the concept of fallible deserialization before jumping to `ruma_api::Outgoing`
|
// TODO: Explain the concept of fallible deserialization before jumping to `ruma_common::Outgoing`
|
||||||
pub use ruma_api_macros::ruma_api;
|
pub use ruma_api_macros::ruma_api;
|
||||||
|
|
||||||
pub use ruma_api_macros::Outgoing;
|
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
/// This module is used to support the generated code from ruma-api-macros.
|
/// This module is used to support the generated code from ruma-api-macros.
|
||||||
/// It is not considered part of ruma-api's public API.
|
/// It is not considered part of ruma-api's public API.
|
||||||
@ -216,6 +214,7 @@ pub mod error;
|
|||||||
pub mod exports {
|
pub mod exports {
|
||||||
pub use http;
|
pub use http;
|
||||||
pub use percent_encoding;
|
pub use percent_encoding;
|
||||||
|
pub use ruma_common;
|
||||||
pub use ruma_serde;
|
pub use ruma_serde;
|
||||||
pub use serde;
|
pub use serde;
|
||||||
pub use serde_json;
|
pub use serde_json;
|
||||||
@ -223,18 +222,6 @@ pub mod exports {
|
|||||||
|
|
||||||
use error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError};
|
use error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError};
|
||||||
|
|
||||||
/// A type that can be sent to another party that understands the matrix protocol. If any of the
|
|
||||||
/// fields of `Self` don't implement serde's `Deserialize`, you can derive this trait to generate a
|
|
||||||
/// corresponding 'Incoming' type that supports deserialization. This is useful for things like
|
|
||||||
/// ruma_events' `EventResult` type. For more details, see the [derive macro's documentation][doc].
|
|
||||||
///
|
|
||||||
/// [doc]: derive.Outgoing.html
|
|
||||||
// TODO: Better explain how this trait relates to serde's traits
|
|
||||||
pub trait Outgoing {
|
|
||||||
/// The 'Incoming' variant of `Self`.
|
|
||||||
type Incoming;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gives users the ability to define their own serializable / deserializable errors.
|
/// Gives users the ability to define their own serializable / deserializable errors.
|
||||||
pub trait EndpointError: StdError + Sized + 'static {
|
pub trait EndpointError: StdError + Sized + 'static {
|
||||||
/// Tries to construct `Self` from an `http::Response`.
|
/// Tries to construct `Self` from an `http::Response`.
|
||||||
|
@ -3,16 +3,16 @@
|
|||||||
use std::{convert::TryFrom, ops::Deref};
|
use std::{convert::TryFrom, ops::Deref};
|
||||||
|
|
||||||
use http::{header::CONTENT_TYPE, method::Method};
|
use http::{header::CONTENT_TYPE, method::Method};
|
||||||
use ruma_identifiers::{RoomAliasId, RoomId};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use ruma_api::{
|
use ruma_api::{
|
||||||
error::{
|
error::{
|
||||||
FromHttpRequestError, FromHttpResponseError, IntoHttpError, RequestDeserializationError,
|
FromHttpRequestError, FromHttpResponseError, IntoHttpError, RequestDeserializationError,
|
||||||
ResponseDeserializationError, ServerError, Void,
|
ResponseDeserializationError, ServerError, Void,
|
||||||
},
|
},
|
||||||
AuthScheme, IncomingRequest, Metadata, Outgoing, OutgoingRequest,
|
AuthScheme, IncomingRequest, Metadata, OutgoingRequest,
|
||||||
};
|
};
|
||||||
|
use ruma_common::Outgoing;
|
||||||
|
use ruma_identifiers::{RoomAliasId, RoomId};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A request to create a new room alias.
|
/// A request to create a new room alias.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[derive(Copy, Clone, Debug, ruma_api::Outgoing, serde::Serialize)]
|
#[derive(Copy, Clone, Debug, ruma_common::Outgoing, serde::Serialize)]
|
||||||
pub struct OtherThing<'t> {
|
pub struct OtherThing<'t> {
|
||||||
some: &'t str,
|
some: &'t str,
|
||||||
t: &'t [u8],
|
t: &'t [u8],
|
||||||
|
@ -18,7 +18,7 @@ pub mod unbind_3pid;
|
|||||||
|
|
||||||
pub mod whoami;
|
pub mod whoami;
|
||||||
|
|
||||||
use ruma_api::Outgoing;
|
use ruma_common::Outgoing;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Additional authentication information for requestToken endpoints.
|
/// Additional authentication information for requestToken endpoints.
|
||||||
|
@ -6,7 +6,7 @@ pub mod get_filter;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use js_int::UInt;
|
use js_int::UInt;
|
||||||
use ruma_api::Outgoing;
|
use ruma_common::Outgoing;
|
||||||
use ruma_identifiers::{RoomId, UserId};
|
use ruma_identifiers::{RoomId, UserId};
|
||||||
use serde::{
|
use serde::{
|
||||||
de::{MapAccess, Visitor},
|
de::{MapAccess, Visitor},
|
||||||
|
@ -14,8 +14,8 @@ pub mod unban_user;
|
|||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use ruma_api::Outgoing;
|
|
||||||
use ruma_common::thirdparty::Medium;
|
use ruma_common::thirdparty::Medium;
|
||||||
|
use ruma_common::Outgoing;
|
||||||
use ruma_identifiers::{ServerKeyId, ServerNameBox};
|
use ruma_identifiers::{ServerKeyId, ServerNameBox};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
//! [invite-by-user-id]: https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-invite
|
//! [invite-by-user-id]: https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-invite
|
||||||
//! [invite-by-3pid]: https://matrix.org/docs/spec/client_server/r0.6.0#id101
|
//! [invite-by-3pid]: https://matrix.org/docs/spec/client_server/r0.6.0#id101
|
||||||
|
|
||||||
use ruma_api::{ruma_api, Outgoing};
|
use ruma_api::ruma_api;
|
||||||
|
use ruma_common::Outgoing;
|
||||||
use ruma_identifiers::{RoomId, UserId};
|
use ruma_identifiers::{RoomId, UserId};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -7,8 +7,9 @@ use ruma_api::{
|
|||||||
FromHttpRequestError, FromHttpResponseError, IntoHttpError, RequestDeserializationError,
|
FromHttpRequestError, FromHttpResponseError, IntoHttpError, RequestDeserializationError,
|
||||||
ResponseDeserializationError, ServerError,
|
ResponseDeserializationError, ServerError,
|
||||||
},
|
},
|
||||||
AuthScheme, EndpointError, Metadata, Outgoing,
|
AuthScheme, EndpointError, Metadata,
|
||||||
};
|
};
|
||||||
|
use ruma_common::Outgoing;
|
||||||
use ruma_events::{AnyMessageEventContent, EventContent as _};
|
use ruma_events::{AnyMessageEventContent, EventContent as _};
|
||||||
use ruma_identifiers::{EventId, RoomId};
|
use ruma_identifiers::{EventId, RoomId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use js_int::{uint, UInt};
|
use js_int::{uint, UInt};
|
||||||
use ruma_api::{ruma_api, Outgoing};
|
use ruma_api::ruma_api;
|
||||||
use ruma_common::Raw;
|
use ruma_common::{Outgoing, Raw};
|
||||||
use ruma_events::{AnyRoomEvent, AnyStateEvent};
|
use ruma_events::{AnyRoomEvent, AnyStateEvent};
|
||||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! [POST /_matrix/client/r0/login](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-login)
|
//! [POST /_matrix/client/r0/login](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-login)
|
||||||
|
|
||||||
use ruma_api::{ruma_api, Outgoing};
|
use ruma_api::ruma_api;
|
||||||
use ruma_common::thirdparty::Medium;
|
use ruma_common::{thirdparty::Medium, Outgoing};
|
||||||
use ruma_identifiers::{DeviceId, DeviceIdBox, ServerNameBox, UserId};
|
use ruma_identifiers::{DeviceId, DeviceIdBox, ServerNameBox, UserId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
//! Helper module for the Serialize / Deserialize impl's for the User struct
|
//! Helper module for the Serialize / Deserialize impl's for the User struct
|
||||||
//! in the parent module.
|
//! in the parent module.
|
||||||
|
|
||||||
use ruma_api::Outgoing;
|
|
||||||
use ruma_common::thirdparty::Medium;
|
use ruma_common::thirdparty::Medium;
|
||||||
|
use ruma_common::Outgoing;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
// The following three structs could just be used in place of the one in the parent module, but
|
// The following three structs could just be used in place of the one in the parent module, but
|
||||||
|
@ -7,8 +7,9 @@ use ruma_api::{
|
|||||||
FromHttpRequestError, FromHttpResponseError, IntoHttpError, RequestDeserializationError,
|
FromHttpRequestError, FromHttpResponseError, IntoHttpError, RequestDeserializationError,
|
||||||
ResponseDeserializationError, ServerError,
|
ResponseDeserializationError, ServerError,
|
||||||
},
|
},
|
||||||
AuthScheme, EndpointError, Metadata, Outgoing,
|
AuthScheme, EndpointError, Metadata,
|
||||||
};
|
};
|
||||||
|
use ruma_common::Outgoing;
|
||||||
use ruma_events::{AnyStateEventContent, EventContent as _};
|
use ruma_events::{AnyStateEventContent, EventContent as _};
|
||||||
use ruma_identifiers::{EventId, RoomId};
|
use ruma_identifiers::{EventId, RoomId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -7,8 +7,9 @@ use ruma_api::{
|
|||||||
FromHttpRequestError, FromHttpResponseError, IntoHttpError, RequestDeserializationError,
|
FromHttpRequestError, FromHttpResponseError, IntoHttpError, RequestDeserializationError,
|
||||||
ResponseDeserializationError, ServerError,
|
ResponseDeserializationError, ServerError,
|
||||||
},
|
},
|
||||||
AuthScheme, EndpointError, Metadata, Outgoing,
|
AuthScheme, EndpointError, Metadata,
|
||||||
};
|
};
|
||||||
|
use ruma_common::Outgoing;
|
||||||
use ruma_events::{AnyStateEventContent, EventContent as _};
|
use ruma_events::{AnyStateEventContent, EventContent as _};
|
||||||
use ruma_identifiers::{EventId, RoomId};
|
use ruma_identifiers::{EventId, RoomId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
use std::{collections::BTreeMap, time::Duration};
|
use std::{collections::BTreeMap, time::Duration};
|
||||||
|
|
||||||
use js_int::UInt;
|
use js_int::UInt;
|
||||||
use ruma_api::{ruma_api, Outgoing};
|
use ruma_api::ruma_api;
|
||||||
use ruma_common::{presence::PresenceState, Raw};
|
use ruma_common::{presence::PresenceState, Outgoing, Raw};
|
||||||
use ruma_events::{
|
use ruma_events::{
|
||||||
presence::PresenceEvent, AnyBasicEvent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent,
|
presence::PresenceEvent, AnyBasicEvent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent,
|
||||||
AnySyncRoomEvent, AnySyncStateEvent, AnyToDeviceEvent,
|
AnySyncRoomEvent, AnySyncStateEvent, AnyToDeviceEvent,
|
||||||
|
@ -5,7 +5,8 @@ use std::{
|
|||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
};
|
};
|
||||||
|
|
||||||
use ruma_api::{error::ResponseDeserializationError, EndpointError, Outgoing};
|
use ruma_api::{error::ResponseDeserializationError, EndpointError};
|
||||||
|
use ruma_common::Outgoing;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{
|
use serde_json::{
|
||||||
from_slice as from_json_slice, to_vec as to_json_vec, value::RawValue as RawJsonValue,
|
from_slice as from_json_slice, to_vec as to_json_vec, value::RawValue as RawJsonValue,
|
||||||
|
21
ruma-common-macros/Cargo.toml
Normal file
21
ruma-common-macros/Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
[package]
|
||||||
|
authors = ["Jonas Platte <jplatte@posteo.de>",]
|
||||||
|
categories = ["api-bindings", "web-programming"]
|
||||||
|
description = "Procedural macros for ruma-common."
|
||||||
|
homepage = "https://www.ruma.io/"
|
||||||
|
keywords = ["matrix", "chat", "messaging", "ruma"]
|
||||||
|
license = "MIT"
|
||||||
|
name = "ruma-common-macros"
|
||||||
|
readme = "README.md"
|
||||||
|
repository = "https://github.com/ruma/ruma"
|
||||||
|
version = "0.2.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
proc-macro2 = "1.0.19"
|
||||||
|
quote = "1.0.7"
|
||||||
|
syn = { version = "1.0.38", features = ["full", "extra-traits"] }
|
||||||
|
proc-macro-crate = "0.1.5"
|
19
ruma-common-macros/LICENSE
Normal file
19
ruma-common-macros/LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2020 Jonas Platte
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
55
ruma-common-macros/src/lib.rs
Normal file
55
ruma-common-macros/src/lib.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
use proc_macro::TokenStream;
|
||||||
|
use syn::{parse_macro_input, DeriveInput};
|
||||||
|
|
||||||
|
use outgoing::expand_derive_outgoing;
|
||||||
|
|
||||||
|
mod outgoing;
|
||||||
|
mod util;
|
||||||
|
|
||||||
|
/// Derive the `Outgoing` trait, possibly generating an 'Incoming' version of the struct this
|
||||||
|
/// derive macro is used on. Specifically, if no lifetime variables are used on any of the fields
|
||||||
|
/// of the struct, this simple implementation will be generated:
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// impl Outgoing for MyType {
|
||||||
|
/// type Incoming = Self;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/*
|
||||||
|
|
||||||
|
TODO: Extend docs. Previously:
|
||||||
|
|
||||||
|
If, however, `#[wrap_incoming]` is used (which is the only reason you should ever use this
|
||||||
|
derive macro manually), a new struct `IncomingT` (where `T` is the type this derive is used on)
|
||||||
|
is generated, with all of the fields with `#[wrap_incoming]` replaced:
|
||||||
|
|
||||||
|
```ignore
|
||||||
|
#[derive(Outgoing)]
|
||||||
|
struct MyType {
|
||||||
|
pub foo: Foo,
|
||||||
|
#[wrap_incoming]
|
||||||
|
pub bar: Bar,
|
||||||
|
#[wrap_incoming(Baz)]
|
||||||
|
pub baz: Option<Baz>,
|
||||||
|
#[wrap_incoming(with EventResult)]
|
||||||
|
pub x: XEvent,
|
||||||
|
#[wrap_incoming(YEvent with EventResult)]
|
||||||
|
pub ys: Vec<YEvent>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// generated
|
||||||
|
struct IncomingMyType {
|
||||||
|
pub foo: Foo,
|
||||||
|
pub bar: IncomingBar,
|
||||||
|
pub baz: Option<IncomingBaz>,
|
||||||
|
pub x: EventResult<XEvent>,
|
||||||
|
pub ys: Vec<EventResult<YEvent>>,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
*/
|
||||||
|
#[proc_macro_derive(Outgoing, attributes(incoming_derive))]
|
||||||
|
pub fn derive_outgoing(input: TokenStream) -> TokenStream {
|
||||||
|
let input = parse_macro_input!(input as DeriveInput);
|
||||||
|
expand_derive_outgoing(input).unwrap_or_else(|err| err.to_compile_error()).into()
|
||||||
|
}
|
@ -9,7 +9,7 @@ use syn::{
|
|||||||
Token, Type, TypeGenerics, TypePath, TypeReference, TypeSlice, Variant,
|
Token, Type, TypeGenerics, TypePath, TypeReference, TypeSlice, Variant,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::util::import_ruma_api;
|
use crate::util::import_ruma_common;
|
||||||
|
|
||||||
enum StructKind {
|
enum StructKind {
|
||||||
Struct,
|
Struct,
|
||||||
@ -23,7 +23,7 @@ enum DataKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
|
pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||||
let import_path = import_ruma_api();
|
let ruma_common = import_ruma_common();
|
||||||
|
|
||||||
let mut derives = vec![quote! { Debug }];
|
let mut derives = vec![quote! { Debug }];
|
||||||
let mut derive_deserialize = true;
|
let mut derive_deserialize = true;
|
||||||
@ -46,7 +46,7 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
if derive_deserialize {
|
if derive_deserialize {
|
||||||
derives.push(quote! { #import_path::exports::serde::Deserialize });
|
derives.push(quote! { #ruma_common::exports::serde::Deserialize });
|
||||||
}
|
}
|
||||||
|
|
||||||
let input_attrs =
|
let input_attrs =
|
||||||
@ -67,7 +67,7 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match data {
|
match data {
|
||||||
DataKind::Unit => Ok(impl_outgoing_with_incoming_self(&input, &import_path)),
|
DataKind::Unit => Ok(impl_outgoing_with_incoming_self(&input, &ruma_common)),
|
||||||
DataKind::Enum(mut vars) => {
|
DataKind::Enum(mut vars) => {
|
||||||
let mut found_lifetime = false;
|
let mut found_lifetime = false;
|
||||||
for var in &mut vars {
|
for var in &mut vars {
|
||||||
@ -82,7 +82,7 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
let (original_impl_gen, original_ty_gen, _) = input.generics.split_for_impl();
|
let (original_impl_gen, original_ty_gen, _) = input.generics.split_for_impl();
|
||||||
|
|
||||||
if !found_lifetime {
|
if !found_lifetime {
|
||||||
return Ok(impl_outgoing_with_incoming_self(&input, &import_path));
|
return Ok(impl_outgoing_with_incoming_self(&input, &ruma_common));
|
||||||
}
|
}
|
||||||
|
|
||||||
let vis = input.vis;
|
let vis = input.vis;
|
||||||
@ -98,7 +98,7 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
#( #input_attrs )*
|
#( #input_attrs )*
|
||||||
#vis enum #incoming_ident #ty_gen { #( #vars, )* }
|
#vis enum #incoming_ident #ty_gen { #( #vars, )* }
|
||||||
|
|
||||||
impl #original_impl_gen #import_path::Outgoing for #original_ident #original_ty_gen {
|
impl #original_impl_gen #ruma_common::Outgoing for #original_ident #original_ty_gen {
|
||||||
type Incoming = #incoming_ident #impl_gen;
|
type Incoming = #incoming_ident #impl_gen;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -115,7 +115,7 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
let (original_impl_gen, original_ty_gen, _) = input.generics.split_for_impl();
|
let (original_impl_gen, original_ty_gen, _) = input.generics.split_for_impl();
|
||||||
|
|
||||||
if !found_lifetime {
|
if !found_lifetime {
|
||||||
return Ok(impl_outgoing_with_incoming_self(&input, &import_path));
|
return Ok(impl_outgoing_with_incoming_self(&input, &ruma_common));
|
||||||
}
|
}
|
||||||
|
|
||||||
let vis = input.vis;
|
let vis = input.vis;
|
||||||
@ -136,7 +136,7 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
#( #input_attrs )*
|
#( #input_attrs )*
|
||||||
#vis struct #incoming_ident #ty_gen #struct_def
|
#vis struct #incoming_ident #ty_gen #struct_def
|
||||||
|
|
||||||
impl #original_impl_gen #import_path::Outgoing for #original_ident #original_ty_gen {
|
impl #original_impl_gen #ruma_common::Outgoing for #original_ident #original_ty_gen {
|
||||||
type Incoming = #incoming_ident #impl_gen;
|
type Incoming = #incoming_ident #impl_gen;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -150,12 +150,12 @@ fn filter_input_attrs(attr: &Attribute) -> bool {
|
|||||||
attr.path.is_ident("serde") || attr.path.is_ident("non_exhaustive")
|
attr.path.is_ident("serde") || attr.path.is_ident("non_exhaustive")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn impl_outgoing_with_incoming_self(input: &DeriveInput, import_path: &TokenStream) -> TokenStream {
|
fn impl_outgoing_with_incoming_self(input: &DeriveInput, ruma_common: &TokenStream) -> TokenStream {
|
||||||
let ident = &input.ident;
|
let ident = &input.ident;
|
||||||
let (impl_gen, ty_gen, _) = input.generics.split_for_impl();
|
let (impl_gen, ty_gen, _) = input.generics.split_for_impl();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
impl #impl_gen #import_path::Outgoing for #ident #ty_gen {
|
impl #impl_gen #ruma_common::Outgoing for #ident #ty_gen {
|
||||||
type Incoming = Self;
|
type Incoming = Self;
|
||||||
}
|
}
|
||||||
}
|
}
|
15
ruma-common-macros/src/util.rs
Normal file
15
ruma-common-macros/src/util.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
use proc_macro2::{Ident, Span, TokenStream};
|
||||||
|
use proc_macro_crate::crate_name;
|
||||||
|
use quote::quote;
|
||||||
|
|
||||||
|
pub fn import_ruma_common() -> TokenStream {
|
||||||
|
if let Ok(possibly_renamed) = crate_name("ruma-common") {
|
||||||
|
let import = Ident::new(&possibly_renamed, Span::call_site());
|
||||||
|
quote! { ::#import }
|
||||||
|
} else if let Ok(possibly_renamed) = crate_name("ruma") {
|
||||||
|
let import = Ident::new(&possibly_renamed, Span::call_site());
|
||||||
|
quote! { ::#import }
|
||||||
|
} else {
|
||||||
|
quote! { ::ruma_common }
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
js_int = { version = "0.1.9", features = ["serde"] }
|
js_int = { version = "0.1.9", features = ["serde"] }
|
||||||
ruma-api = { version = "=0.17.0-alpha.1", path = "../ruma-api" }
|
ruma-common-macros = { version = "=0.2.0", path = "../ruma-common-macros" }
|
||||||
ruma-identifiers = { version = "0.17.4", path = "../ruma-identifiers" }
|
ruma-identifiers = { version = "0.17.4", path = "../ruma-identifiers" }
|
||||||
ruma-serde = { version = "0.2.3", path = "../ruma-serde" }
|
ruma-serde = { version = "0.2.3", path = "../ruma-serde" }
|
||||||
serde = { version = "1.0.114", features = ["derive"] }
|
serde = { version = "1.0.114", features = ["derive"] }
|
||||||
|
@ -3,16 +3,16 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use js_int::UInt;
|
use js_int::UInt;
|
||||||
use ruma_api::Outgoing;
|
|
||||||
use ruma_identifiers::{RoomAliasId, RoomId};
|
use ruma_identifiers::{RoomAliasId, RoomId};
|
||||||
use serde::{
|
use serde::{
|
||||||
de::{Error, MapAccess, Visitor},
|
de::{Error, MapAccess, Visitor},
|
||||||
ser::SerializeStruct,
|
ser::SerializeStruct,
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
Deserialize, Deserializer, Serialize, Serializer,
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::Value as JsonValue;
|
||||||
|
|
||||||
|
use crate::Outgoing;
|
||||||
|
|
||||||
/// A chunk of a room list response, describing one room.
|
/// A chunk of a room list response, describing one room.
|
||||||
///
|
///
|
||||||
/// To create an instance of this type, first create a `PublicRoomsChunkInit` and convert it via
|
/// To create an instance of this type, first create a `PublicRoomsChunkInit` and convert it via
|
||||||
|
@ -9,4 +9,29 @@ pub mod push;
|
|||||||
mod raw;
|
mod raw;
|
||||||
pub mod thirdparty;
|
pub mod thirdparty;
|
||||||
|
|
||||||
|
pub use ruma_common_macros::Outgoing;
|
||||||
|
|
||||||
pub use self::raw::Raw;
|
pub use self::raw::Raw;
|
||||||
|
|
||||||
|
/// A type that can be sent to another party that understands the matrix protocol. If any of the
|
||||||
|
/// fields of `Self` don't implement serde's `Deserialize`, you can derive this trait to generate a
|
||||||
|
/// corresponding 'Incoming' type that supports deserialization. This is useful for things like
|
||||||
|
/// ruma_events' `EventResult` type. For more details, see the [derive macro's documentation][doc].
|
||||||
|
///
|
||||||
|
/// [doc]: derive.Outgoing.html
|
||||||
|
// TODO: Better explain how this trait relates to serde's traits
|
||||||
|
pub trait Outgoing {
|
||||||
|
/// The 'Incoming' variant of `Self`.
|
||||||
|
type Incoming;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hack to allow both ruma-common itself and external crates (or tests) to use procedural macros
|
||||||
|
// that expect `ruma_common` to exist in the prelude.
|
||||||
|
extern crate self as ruma_common;
|
||||||
|
|
||||||
|
/// This module is used to support the generated code from ruma-api-macros.
|
||||||
|
/// It is not considered part of ruma-common's public API.
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub mod exports {
|
||||||
|
pub use serde;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use ruma_api::Outgoing;
|
use ruma_common::Outgoing;
|
||||||
use ruma_identifiers::UserId;
|
use ruma_identifiers::UserId;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
@ -1,8 +1,11 @@
|
|||||||
//! [POST /_matrix/push/v1/notify](https://matrix.org/docs/spec/push_gateway/r0.1.1#post-matrix-push-v1-notify)
|
//! [POST /_matrix/push/v1/notify](https://matrix.org/docs/spec/push_gateway/r0.1.1#post-matrix-push-v1-notify)
|
||||||
|
|
||||||
use js_int::UInt;
|
use js_int::UInt;
|
||||||
use ruma_api::{ruma_api, Outgoing};
|
use ruma_api::ruma_api;
|
||||||
use ruma_common::push::{PusherData, Tweak};
|
use ruma_common::{
|
||||||
|
push::{PusherData, Tweak},
|
||||||
|
Outgoing,
|
||||||
|
};
|
||||||
use ruma_events::EventType;
|
use ruma_events::EventType;
|
||||||
use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId};
|
use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user