Fix some bad formatting

This commit is contained in:
Jonas Platte 2020-08-08 21:52:58 +02:00
parent 0366466792
commit 1fbf05d71f
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
35 changed files with 266 additions and 140 deletions

View File

@ -282,7 +282,9 @@ impl ToTokens for Api {
type Error = ::ruma_api::error::IntoHttpError; type Error = ::ruma_api::error::IntoHttpError;
#[allow(unused_variables)] #[allow(unused_variables)]
fn try_from(response: Response #response_lifetimes) -> ::std::result::Result<Self, Self::Error> { fn try_from(
response: Response #response_lifetimes,
) -> ::std::result::Result<Self, Self::Error> {
let response = ::ruma_api::exports::http::Response::builder() let response = ::ruma_api::exports::http::Response::builder()
.header(::ruma_api::exports::http::header::CONTENT_TYPE, "application/json") .header(::ruma_api::exports::http::header::CONTENT_TYPE, "application/json")
#serialize_response_headers #serialize_response_headers
@ -314,7 +316,9 @@ impl ToTokens for Api {
} else { } else {
match <#error as ::ruma_api::EndpointError>::try_from_response(response) { match <#error as ::ruma_api::EndpointError>::try_from_response(response) {
Ok(err) => Err(::ruma_api::error::ServerError::Known(err).into()), Ok(err) => Err(::ruma_api::error::ServerError::Known(err).into()),
Err(response_err) => Err(::ruma_api::error::ServerError::Unknown(response_err).into()) Err(response_err) => {
Err(::ruma_api::error::ServerError::Unknown(response_err).into())
}
} }
} }
} }

View File

@ -194,7 +194,8 @@ impl Request {
self.struct_init_fields(RequestFieldKind::Body, quote!(self)) self.struct_init_fields(RequestFieldKind::Body, quote!(self))
} }
/// Produces code for a struct initializer for query string fields on a variable named `request`. /// Produces code for a struct initializer for query string fields on a variable named
/// `request`.
pub fn request_query_init_fields(&self) -> TokenStream { pub fn request_query_init_fields(&self) -> TokenStream {
self.struct_init_fields(RequestFieldKind::Query, quote!(self)) self.struct_init_fields(RequestFieldKind::Query, quote!(self))
} }
@ -281,41 +282,40 @@ impl TryFrom<RawRequest> for Request {
} }
field_kind = Some(match meta { field_kind = Some(match meta {
Meta::Word(ident) => { Meta::Word(ident) => match &ident.to_string()[..] {
match &ident.to_string()[..] { attr @ "body" | attr @ "raw_body" => util::req_res_meta_word(
attr @ "body" | attr @ "raw_body" => util::req_res_meta_word( attr,
attr, &field,
&field, &mut newtype_body_field,
&mut newtype_body_field, RequestFieldKind::NewtypeBody,
RequestFieldKind::NewtypeBody, RequestFieldKind::NewtypeRawBody,
RequestFieldKind::NewtypeRawBody, )?,
)?, "path" => RequestFieldKind::Path,
"path" => RequestFieldKind::Path, "query" => RequestFieldKind::Query,
"query" => RequestFieldKind::Query, "query_map" => {
"query_map" => { if let Some(f) = &query_map_field {
if let Some(f) = &query_map_field { let mut error = syn::Error::new_spanned(
let mut error = syn::Error::new_spanned( field,
field, "There can only be one query map field",
"There can only be one query map field", );
); error.combine(syn::Error::new_spanned(
error.combine(syn::Error::new_spanned( f,
f, "Previous query map field",
"Previous query map field",
));
return Err(error);
}
query_map_field = Some(field.clone());
RequestFieldKind::QueryMap
},
_ => {
return Err(syn::Error::new_spanned(
ident,
"Invalid #[ruma_api] argument, expected one of `body`, `path`, `query`, `query_map`",
)); ));
return Err(error);
} }
query_map_field = Some(field.clone());
RequestFieldKind::QueryMap
} }
} _ => {
return Err(syn::Error::new_spanned(
ident,
"Invalid #[ruma_api] argument, expected one of \
`body`, `path`, `query`, `query_map`",
));
}
},
Meta::NameValue(MetaNameValue { name, value }) => util::req_res_name_value( Meta::NameValue(MetaNameValue { name, value }) => util::req_res_name_value(
name, name,
value, value,
@ -326,20 +326,30 @@ impl TryFrom<RawRequest> for Request {
} }
match field_kind.unwrap_or(RequestFieldKind::Body) { match field_kind.unwrap_or(RequestFieldKind::Body) {
RequestFieldKind::Header => util::collect_lifetime_ident(&mut lifetimes.header, &field.ty), RequestFieldKind::Header => {
RequestFieldKind::Body => util::collect_lifetime_ident(&mut lifetimes.body, &field.ty), util::collect_lifetime_ident(&mut lifetimes.header, &field.ty)
RequestFieldKind::NewtypeBody => util::collect_lifetime_ident(&mut lifetimes.body, &field.ty), }
RequestFieldKind::NewtypeRawBody => util::collect_lifetime_ident(&mut lifetimes.body, &field.ty), RequestFieldKind::Body => {
RequestFieldKind::Path => util::collect_lifetime_ident(&mut lifetimes.path, &field.ty), util::collect_lifetime_ident(&mut lifetimes.body, &field.ty)
RequestFieldKind::Query => util::collect_lifetime_ident(&mut lifetimes.query, &field.ty), }
RequestFieldKind::QueryMap => util::collect_lifetime_ident(&mut lifetimes.query, &field.ty), RequestFieldKind::NewtypeBody => {
util::collect_lifetime_ident(&mut lifetimes.body, &field.ty)
}
RequestFieldKind::NewtypeRawBody => {
util::collect_lifetime_ident(&mut lifetimes.body, &field.ty)
}
RequestFieldKind::Path => {
util::collect_lifetime_ident(&mut lifetimes.path, &field.ty)
}
RequestFieldKind::Query => {
util::collect_lifetime_ident(&mut lifetimes.query, &field.ty)
}
RequestFieldKind::QueryMap => {
util::collect_lifetime_ident(&mut lifetimes.query, &field.ty)
}
} }
Ok(RequestField::new( Ok(RequestField::new(field_kind.unwrap_or(RequestFieldKind::Body), field, header))
field_kind.unwrap_or(RequestFieldKind::Body),
field,
header,
))
}) })
.collect::<syn::Result<Vec<_>>>()?; .collect::<syn::Result<Vec<_>>>()?;
@ -388,8 +398,8 @@ impl ToTokens for Request {
let field = Field { ident: None, colon_token: None, ..body_field.field().clone() }; let field = Field { ident: None, colon_token: None, ..body_field.field().clone() };
// Though we don't track the difference between new type body and body // Though we don't track the difference between new type body and body
// for lifetimes, the outer check and the macro failing if it encounters // for lifetimes, the outer check and the macro failing if it encounters
// an illegal combination of field attributes, is enough to guarantee `body_lifetimes` // an illegal combination of field attributes, is enough to guarantee
// correctness. // `body_lifetimes` correctness.
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 {

View File

@ -296,8 +296,8 @@ impl ToTokens for Response {
// Though we don't track the difference between new type body and body // Though we don't track the difference between new type body and body
// for lifetimes, the outer check and the macro failing if it encounters // for lifetimes, the outer check and the macro failing if it encounters
// an illegal combination of field attributes, is enough to guarantee `body_lifetimes` // an illegal combination of field attributes, is enough to guarantee
// correctness. // `body_lifetimes` correctness.
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 {

View File

@ -194,7 +194,8 @@ fn strip_lifetimes(field_type: &mut Type) -> bool {
} }
} }
// If a type has a generic lifetime parameter there must be an `Incoming` variant of that type. // If a type has a generic lifetime parameter there must be an `Incoming` variant of
// that type.
if is_lifetime_generic { if is_lifetime_generic {
if let Some(name) = path.segments.last_mut() { if let Some(name) = path.segments.last_mut() {
let incoming_ty_ident = format_ident!("Incoming{}", name.ident); let incoming_ty_ident = format_ident!("Incoming{}", name.ident);

View File

@ -146,7 +146,10 @@ pub(crate) fn request_path_string_and_parse(
.decode_utf8(), .decode_utf8(),
); );
::ruma_api::try_deserialize!(request, ::std::convert::TryFrom::try_from(&*decoded)) ::ruma_api::try_deserialize!(
request,
::std::convert::TryFrom::try_from(&*decoded),
)
} }
} }
}, },
@ -219,12 +222,13 @@ pub(crate) fn extract_request_query(request: &Request) -> TokenStream {
} }
} else if request.has_query_fields() { } else if request.has_query_fields() {
quote! { quote! {
let request_query: <RequestQuery as ::ruma_api::Outgoing>::Incoming = ::ruma_api::try_deserialize!( let request_query: <RequestQuery as ::ruma_api::Outgoing>::Incoming =
request, ::ruma_api::try_deserialize!(
::ruma_api::exports::ruma_serde::urlencoded::from_str( request,
&request.uri().query().unwrap_or("") ::ruma_api::exports::ruma_serde::urlencoded::from_str(
), &request.uri().query().unwrap_or("")
); ),
);
} }
} else { } else {
TokenStream::new() TokenStream::new()

View File

@ -278,7 +278,8 @@ where
/// A Matrix API endpoint that doesn't require authentication. /// A Matrix API endpoint that doesn't require authentication.
/// ///
/// This marker trait is to indicate that a type implementing `Endpoint` doesn't require any authentication. /// This marker trait is to indicate that a type implementing `Endpoint` doesn't require any
/// authentication.
pub trait NonAuthEndpoint: Endpoint pub trait NonAuthEndpoint: Endpoint
where where
<Self as Outgoing>::Incoming: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError>, <Self as Outgoing>::Incoming: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError>,

View File

@ -18,9 +18,13 @@ ruma_api! {
/// The new password for the account. /// The new password for the account.
pub new_password: String, pub new_password: String,
/// True to revoke the user's other access tokens, and their associated devices if the request succeeds. /// True to revoke the user's other access tokens, and their associated devices if the
/// request succeeds.
///
/// Defaults to true. /// Defaults to true.
/// When false, the server can still take advantage of the soft logout method for the user's remaining devices. ///
/// When false, the server can still take advantage of the soft logout method for the user's
/// remaining devices.
#[serde(default = "ruma_serde::default_true", skip_serializing_if = "ruma_serde::is_true")] #[serde(default = "ruma_serde::default_true", skip_serializing_if = "ruma_serde::is_true")]
pub logout_devices: bool, pub logout_devices: bool,

View File

@ -160,7 +160,8 @@ impl<'de> Visitor<'de> for RoomNetworkVisitor {
Ok(RoomNetwork::All) Ok(RoomNetwork::All)
} else { } else {
Err(M::Error::custom( Err(M::Error::custom(
"`include_all_networks = true` and `third_party_instance_id` are mutually exclusive.", "`include_all_networks = true` and `third_party_instance_id` are mutually \
exclusive.",
)) ))
} }
} else { } else {

View File

@ -15,12 +15,15 @@ ruma_api! {
request: { request: {
/// The desired start point of the list. /// The desired start point of the list.
///
/// Should be the next_batch field from a response to an earlier call to /sync. /// Should be the next_batch field from a response to an earlier call to /sync.
#[ruma_api(query)] #[ruma_api(query)]
pub from: &'a str, pub from: &'a str,
/// The desired end point of the list. /// The desired end point of the list.
/// Should be the next_batch field from a recent call to /sync - typically the most recent such call. ///
/// Should be the next_batch field from a recent call to /sync - typically the most recent
/// such call.
#[ruma_api(query)] #[ruma_api(query)]
pub to: &'a str, pub to: &'a str,
} }

View File

@ -145,7 +145,13 @@ mod tests {
let request: http::Request<Vec<u8>> = let request: http::Request<Vec<u8>> =
req.try_into_http_request("https://homeserver.tld", Some("auth_tok")).unwrap(); req.try_into_http_request("https://homeserver.tld", Some("auth_tok")).unwrap();
assert_eq!( assert_eq!(
"from=token&to=token2&dir=b&limit=0&filter=%7B%22not_types%22%3A%5B%22type%22%5D%2C%22not_rooms%22%3A%5B%22room%22%2C%22room2%22%2C%22room3%22%5D%2C%22rooms%22%3A%5B%22%21roomid%3Aexample.org%22%5D%2C%22lazy_load_members%22%3Atrue%2C%22include_redundant_members%22%3Atrue%7D", "from=token\
&to=token2\
&dir=b\
&limit=0\
&filter=%7B%22not_types%22%3A%5B%22type%22%5D%2C%22not_rooms%22%3A%5B%22room%22%2C%22\
room2%22%2C%22room3%22%5D%2C%22rooms%22%3A%5B%22%21roomid%3Aexample.org%22%5D%2C%22\
lazy_load_members%22%3Atrue%2C%22include_redundant_members%22%3Atrue%7D",
request.uri().query().unwrap() request.uri().query().unwrap()
); );
} }

View File

@ -103,7 +103,9 @@ pub struct PusherData {
} }
/// A special format that the homeserver should use when sending notifications to a Push Gateway. /// A special format that the homeserver should use when sending notifications to a Push Gateway.
/// Currently, only "event_id_only" is supported as of [Push Gateway API r0.1.1](https://matrix.org/docs/spec/push_gateway/r0.1.1#homeserver-behaviour) /// Currently, only "event_id_only" is supported as of [Push Gateway API r0.1.1][spec].
///
/// [spec]: https://matrix.org/docs/spec/push_gateway/r0.1.1#homeserver-behaviour
#[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum PushFormat { pub enum PushFormat {

View File

@ -30,8 +30,8 @@ ruma_api! {
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<UInt>, pub limit: Option<UInt>,
/// Allows basic filtering of events returned. Supply "highlight" to return only events where /// Allows basic filtering of events returned. Supply "highlight" to return only events
/// the notification had the 'highlight' tweak set. /// where the notification had the 'highlight' tweak set.
#[ruma_api(query)] #[ruma_api(query)]
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub only: Option<String> pub only: Option<String>
@ -64,7 +64,8 @@ pub struct Notification {
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub profile_tag: Option<String>, pub profile_tag: Option<String>,
/// Indicates whether the user has sent a read receipt indicating that they have read this message. /// Indicates whether the user has sent a read receipt indicating that they have read this
/// message.
pub read: bool, pub read: bool,
/// The ID of the room in which the event was posted. /// The ID of the room in which the event was posted.

View File

@ -28,19 +28,22 @@ ruma_api! {
#[ruma_api(path)] #[ruma_api(path)]
pub rule_id: String, pub rule_id: String,
/// Use 'before' with a rule_id as its value to make the new rule the next-most important rule with respect to the given user defined rule. /// Use 'before' with a rule_id as its value to make the new rule the next-most important
/// rule with respect to the given user defined rule.
#[ruma_api(query)] #[ruma_api(query)]
pub before: Option<String>, pub before: Option<String>,
/// This makes the new rule the next-less important rule relative to the given user defined rule. /// This makes the new rule the next-less important rule relative to the given user defined
/// rule.
#[ruma_api(query)] #[ruma_api(query)]
pub after: Option<String>, pub after: Option<String>,
/// The actions to perform when this rule is matched. /// The actions to perform when this rule is matched.
pub actions: Vec<Action>, pub actions: Vec<Action>,
/// The conditions that must hold true for an event in order for a rule to be applied to an event. A rule with no conditions always matches. /// The conditions that must hold true for an event in order for a rule to be applied to an
/// Only applicable to underride and override rules, empty Vec otherwise. /// event. A rule with no conditions always matches. Only applicable to underride and
/// override rules, empty Vec otherwise.
#[serde(default)] #[serde(default)]
pub conditions: Vec<PushCondition>, pub conditions: Vec<PushCondition>,

View File

@ -24,7 +24,8 @@ ruma_api! {
/// The transaction ID for this event. /// The transaction ID for this event.
/// ///
/// Clients should generate a unique ID; it will be used by the server to ensure idempotency of requests. /// Clients should generate a unique ID; it will be used by the server to ensure idempotency
/// of requests.
#[ruma_api(path)] #[ruma_api(path)]
pub txn_id: String, pub txn_id: String,

View File

@ -116,7 +116,8 @@ pub struct ConditionalPushRule {
/// The ID of this rule. /// The ID of this rule.
pub rule_id: String, pub rule_id: String,
/// The conditions that must hold true for an event in order for a rule to be applied to an event. /// The conditions that must hold true for an event in order for a rule to be applied to an
/// event.
/// ///
/// A rule with no conditions always matches. /// A rule with no conditions always matches.
pub conditions: Vec<PushCondition>, pub conditions: Vec<PushCondition>,
@ -140,7 +141,8 @@ pub struct ConditionalPushRuleInit {
/// The ID of this rule. /// The ID of this rule.
pub rule_id: String, pub rule_id: String,
/// The conditions that must hold true for an event in order for a rule to be applied to an event. /// The conditions that must hold true for an event in order for a rule to be applied to an
/// event.
/// ///
/// A rule with no conditions always matches. /// A rule with no conditions always matches.
pub conditions: Vec<PushCondition>, pub conditions: Vec<PushCondition>,
@ -180,8 +182,8 @@ pub struct PatternedPushRule {
/// Initial set of fields of `PatterenedPushRule`. /// Initial set of fields of `PatterenedPushRule`.
/// ///
/// This struct will not be updated even if additional fields are added to `PatterenedPushRule` in a new /// This struct will not be updated even if additional fields are added to `PatterenedPushRule` in a
/// (non-breaking) release of the Matrix specification. /// new (non-breaking) release of the Matrix specification.
#[derive(Debug)] #[derive(Debug)]
pub struct PatternedPushRuleInit { pub struct PatternedPushRuleInit {
/// Actions to determine if and how a notification is delivered for events matching this rule. /// Actions to determine if and how a notification is delivered for events matching this rule.

View File

@ -30,7 +30,9 @@ pub struct AnyPushRule {
/// The ID of this rule. /// The ID of this rule.
pub rule_id: String, pub rule_id: String,
/// The conditions that must hold true for an event in order for a rule to be applied to an event. A rule with no conditions always matches. /// The conditions that must hold true for an event in order for a rule to be applied to an
/// event. A rule with no conditions always matches.
///
/// Only applicable to underride and override rules. /// Only applicable to underride and override rules.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub conditions: Option<Vec<PushCondition>>, pub conditions: Option<Vec<PushCondition>>,

View File

@ -83,8 +83,9 @@ fn expand_serialize_event(
let time_since_epoch = let time_since_epoch =
self.origin_server_ts.duration_since(::std::time::UNIX_EPOCH).unwrap(); self.origin_server_ts.duration_since(::std::time::UNIX_EPOCH).unwrap();
let timestamp = <::js_int::UInt as ::std::convert::TryFrom<_>>::try_from(time_since_epoch.as_millis()) let timestamp = <::js_int::UInt as ::std::convert::TryFrom<_>>::try_from(
.map_err(S::Error::custom)?; time_since_epoch.as_millis(),
).map_err(S::Error::custom)?;
state.serialize_field("origin_server_ts", &timestamp)?; state.serialize_field("origin_server_ts", &timestamp)?;
} }
@ -178,11 +179,16 @@ fn expand_deserialize_event(
C::empty(&event_type).map_err(A::Error::custom)? C::empty(&event_type).map_err(A::Error::custom)?
}, },
::ruma_events::HasDeserializeFields::True => { ::ruma_events::HasDeserializeFields::True => {
let json = content.ok_or_else(|| ::serde::de::Error::missing_field("content"))?; let json = content.ok_or_else(
|| ::serde::de::Error::missing_field("content"),
)?;
C::from_parts(&event_type, json).map_err(A::Error::custom)? C::from_parts(&event_type, json).map_err(A::Error::custom)?
}, },
::ruma_events::HasDeserializeFields::Optional => { ::ruma_events::HasDeserializeFields::Optional => {
let json = content.unwrap_or(::serde_json::value::RawValue::from_string("{}".to_string()).unwrap()); let json = content.unwrap_or(
::serde_json::value::RawValue::from_string("{}".to_string())
.unwrap()
);
C::from_parts(&event_type, json).map_err(A::Error::custom)? C::from_parts(&event_type, json).map_err(A::Error::custom)?
}, },
}; };
@ -194,7 +200,9 @@ fn expand_deserialize_event(
} }
} else { } else {
quote! { quote! {
let content = content.ok_or_else(|| ::serde::de::Error::missing_field("content"))?; let content = content.ok_or_else(
|| ::serde::de::Error::missing_field("content"),
)?;
} }
} }
} else if name == "prev_content" { } else if name == "prev_content" {
@ -259,7 +267,8 @@ fn expand_deserialize_event(
#[derive(::serde::Deserialize)] #[derive(::serde::Deserialize)]
#[serde(field_identifier, rename_all = "snake_case")] #[serde(field_identifier, rename_all = "snake_case")]
enum Field { enum Field {
// since this is represented as an enum we have to add it so the JSON picks it up // since this is represented as an enum we have to add it so the JSON picks it
// up
Type, Type,
#( #enum_variants, )* #( #enum_variants, )*
#[serde(other)] #[serde(other)]
@ -270,10 +279,15 @@ fn expand_deserialize_event(
/// the `content` and `prev_content` fields. /// the `content` and `prev_content` fields.
struct EventVisitor #impl_generics (#deserialize_phantom_type #ty_gen); struct EventVisitor #impl_generics (#deserialize_phantom_type #ty_gen);
impl #deserialize_impl_gen ::serde::de::Visitor<'de> for EventVisitor #ty_gen #where_clause { impl #deserialize_impl_gen ::serde::de::Visitor<'de>
for EventVisitor #ty_gen #where_clause
{
type Value = #ident #ty_gen; type Value = #ident #ty_gen;
fn expecting(&self, formatter: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { fn expecting(
&self,
formatter: &mut ::std::fmt::Formatter<'_>,
) -> ::std::fmt::Result {
write!(formatter, "struct implementing {}", stringify!(#content_type)) write!(formatter, "struct implementing {}", stringify!(#content_type))
} }
@ -300,7 +314,9 @@ fn expand_deserialize_event(
#( #(
Field::#enum_variants => { Field::#enum_variants => {
if #field_names.is_some() { if #field_names.is_some() {
return Err(::serde::de::Error::duplicate_field(stringify!(#field_names))); return Err(::serde::de::Error::duplicate_field(
stringify!(#field_names),
));
} }
#field_names = Some(map.next_value()?); #field_names = Some(map.next_value()?);
} }
@ -308,7 +324,8 @@ fn expand_deserialize_event(
} }
} }
let event_type = event_type.ok_or_else(|| ::serde::de::Error::missing_field("type"))?; let event_type =
event_type.ok_or_else(|| ::serde::de::Error::missing_field("type"))?;
#( #ok_or_else_fields )* #( #ok_or_else_fields )*
Ok(#ident { Ok(#ident {
@ -360,7 +377,10 @@ fn expand_from_into(
impl #impl_generics #ident #ty_gen #where_clause { impl #impl_generics #ident #ty_gen #where_clause {
/// Convert this sync event into a full event, one with a room_id field. /// Convert this sync event into a full event, one with a room_id field.
pub fn into_full_event(self, room_id: ::ruma_identifiers::RoomId) -> #full_struct #ty_gen { pub fn into_full_event(
self,
room_id: ::ruma_identifiers::RoomId,
) -> #full_struct #ty_gen {
let Self { #( #fields, )* } = self; let Self { #( #fields, )* } = self;
#full_struct { #full_struct {
#( #fields_without_unsigned, )* #( #fields_without_unsigned, )*

View File

@ -108,11 +108,14 @@ fn expand_any_with_deser(
use ::serde::de::Error as _; use ::serde::de::Error as _;
let json = Box::<::serde_json::value::RawValue>::deserialize(deserializer)?; let json = Box::<::serde_json::value::RawValue>::deserialize(deserializer)?;
let ::ruma_events::EventDeHelper { ev_type, .. } = ::ruma_events::from_raw_json_value(&json)?; let ::ruma_events::EventDeHelper { ev_type, .. } =
::ruma_events::from_raw_json_value(&json)?;
match ev_type.as_str() { match ev_type.as_str() {
#( #(
#events => { #events => {
let event = ::serde_json::from_str::<#content>(json.get()).map_err(D::Error::custom)?; let event = ::serde_json::from_str::<#content>(json.get())
.map_err(D::Error::custom)?;
Ok(Self::#variants(event)) Ok(Self::#variants(event))
}, },
)* )*
@ -176,9 +179,9 @@ fn expand_conversion_impl(
let redaction = if let (EventKind::Message, EventKindVariation::Full) = (kind, var) { let redaction = if let (EventKind::Message, EventKindVariation::Full) = (kind, var) {
quote! { quote! {
#ident::RoomRedaction(event) => { #ident::RoomRedaction(event) => Self::RoomRedaction(
Self::RoomRedaction(::ruma_events::room::redaction::SyncRedactionEvent::from(event)) ::ruma_events::room::redaction::SyncRedactionEvent::from(event),
}, ),
} }
} else { } else {
TokenStream::new() TokenStream::new()
@ -319,7 +322,9 @@ fn expand_content_enum(
} }
} }
fn from_parts(event_type: &str, input: Box<::serde_json::value::RawValue>) -> Result<Self, ::serde_json::Error> { fn from_parts(
event_type: &str, input: Box<::serde_json::value::RawValue>,
) -> Result<Self, ::serde_json::Error> {
match event_type { match event_type {
#( #(
#event_type_str => { #event_type_str => {
@ -328,7 +333,8 @@ fn expand_content_enum(
}, },
)* )*
ev_type => { ev_type => {
let content = ::ruma_events::custom::CustomEventContent::from_parts(ev_type, input)?; let content =
::ruma_events::custom::CustomEventContent::from_parts(ev_type, input)?;
Ok(Self::Custom(content)) Ok(Self::Custom(content))
}, },
} }
@ -392,7 +398,11 @@ fn expand_redact(
Some(quote! { Some(quote! {
impl #ident { impl #ident {
/// Redacts `Self` given a valid `Redaction[Sync]Event`. /// Redacts `Self` given a valid `Redaction[Sync]Event`.
pub fn redact(self, redaction: #param, version: ::ruma_identifiers::RoomVersionId) -> #redaction_enum { pub fn redact(
self,
redaction: #param,
version: ::ruma_identifiers::RoomVersionId,
) -> #redaction_enum {
match self { match self {
#( #(
Self::#variants(event) => { Self::#variants(event) => {
@ -441,7 +451,9 @@ fn expand_redacted_enum(kind: &EventKind, var: &EventKindVariation) -> Option<To
D: ::serde::de::Deserializer<'de>, D: ::serde::de::Deserializer<'de>,
{ {
let json = Box::<::serde_json::value::RawValue>::deserialize(deserializer)?; let json = Box::<::serde_json::value::RawValue>::deserialize(deserializer)?;
let ::ruma_events::EventDeHelper { unsigned, .. } = ::ruma_events::from_raw_json_value(&json)?; let ::ruma_events::EventDeHelper { unsigned, .. } =
::ruma_events::from_raw_json_value(&json)?;
Ok(match unsigned { Ok(match unsigned {
Some(unsigned) if unsigned.redacted_because.is_some() => { Some(unsigned) if unsigned.redacted_because.is_some() => {
Self::Redacted(::ruma_events::from_raw_json_value(&json)?) Self::Redacted(::ruma_events::from_raw_json_value(&json)?)
@ -523,8 +535,10 @@ fn generate_custom_variant(
quote! { quote! {
event => { event => {
let event = let event =
::serde_json::from_str::<::ruma_events::#event_struct<::ruma_events::custom::CustomEventContent>>(json.get()) ::serde_json::from_str::<
.map_err(D::Error::custom)?; ::ruma_events::#event_struct<::ruma_events::custom::CustomEventContent>
>(json.get())
.map_err(D::Error::custom)?;
Ok(Self::Custom(event)) Ok(Self::Custom(event))
}, },

View File

@ -135,7 +135,8 @@ impl Parse for EventKind {
return Err(syn::Error::new( return Err(syn::Error::new(
input.span(), input.span(),
format!( format!(
"valid event kinds are Basic, EphemeralRoom, Message, State, ToDevice found `{}`", "valid event kinds are Basic, EphemeralRoom, Message, State, ToDevice \
found `{}`",
id id
), ),
)); ));
@ -181,10 +182,12 @@ pub struct EventEnumInput {
/// The name of the event. /// The name of the event.
pub name: EventKind, pub name: EventKind,
/// An array of valid matrix event types. This will generate the variants of the event type "name". /// An array of valid matrix event types.
/// There needs to be a corresponding variant in `ruma_events::EventType` for ///
/// this event (converted to a valid Rust-style type name by stripping `m.`, replacing the /// This will generate the variants of the event type "name". There needs to be a corresponding
/// remaining dots by underscores and then converting from snake_case to CamelCase). /// variant in `ruma_events::EventType` for this event (converted to a valid Rust-style type
/// name by stripping `m.`, replacing the remaining dots by underscores and then converting from
/// snake_case to CamelCase).
pub events: Vec<LitStr>, pub events: Vec<LitStr>,
} }

View File

@ -65,7 +65,9 @@ mod tests {
.deserialize() .deserialize()
.unwrap(), .unwrap(),
BasicEvent { BasicEvent {
content: AnyBasicEventContent::IgnoredUserList(IgnoredUserListEventContent { ignored_users, }), content: AnyBasicEventContent::IgnoredUserList(IgnoredUserListEventContent {
ignored_users,
}),
} if ignored_users == vec![user_id!("@carl:example.com")] } if ignored_users == vec![user_id!("@carl:example.com")]
); );
} }

View File

@ -1,5 +1,5 @@
//! Crate `ruma_events` contains serializable types for the events in the [Matrix](https://matrix.org) //! Crate `ruma_events` contains serializable types for the events in the
//! specification that can be shared by client and server code. //! [Matrix](https://matrix.org) specification that can be shared by client and server code.
//! //!
//! All data exchanged over Matrix is expressed as an event. //! All data exchanged over Matrix is expressed as an event.
//! Different event types represent different actions, such as joining a room or sending a message. //! Different event types represent different actions, such as joining a room or sending a message.
@ -44,8 +44,8 @@
//! They have at least the following additional keys: //! They have at least the following additional keys:
//! * `state_key`, a string which serves as a sort of "sub-type." //! * `state_key`, a string which serves as a sort of "sub-type."
//! The state key allows a room to persist multiple state events of the same type. //! The state key allows a room to persist multiple state events of the same type.
//! You can think of a room's state events as being a `BTreeMap` where the keys are the tuple //! You can think of a room's state events as being a `BTreeMap` where the keys are the
//! `(event_type, state_key)`. //! tuple `(event_type, state_key)`.
//! * Optionally, `prev_content`, a JSON object containing the `content` object from the //! * Optionally, `prev_content`, a JSON object containing the `content` object from the
//! previous event of the given `(event_type, state_key)` tuple in the given room. //! previous event of the given `(event_type, state_key)` tuple in the given room.
//! //!

View File

@ -163,7 +163,8 @@ pub enum MembershipChange {
NotImplemented, NotImplemented,
} }
/// Internal function so all `MemberEventContent` state event kinds can share the same implementation. /// Internal function so all `MemberEventContent` state event kinds can share the same
/// implementation.
fn membership_change( fn membership_change(
content: &MemberEventContent, content: &MemberEventContent,
prev_content: Option<&MemberEventContent>, prev_content: Option<&MemberEventContent>,

View File

@ -140,10 +140,13 @@ fn redacted_aliases_deserialize() {
.unwrap() .unwrap()
.deserialize() .deserialize()
.unwrap(), .unwrap(),
AnySyncRoomEvent::RedactedState(AnyRedactedSyncStateEvent::RoomAliases(RedactedSyncStateEvent { AnySyncRoomEvent::RedactedState(AnyRedactedSyncStateEvent::RoomAliases(
content: RedactedAliasesEventContent { aliases }, RedactedSyncStateEvent {
event_id, .. content: RedactedAliasesEventContent { aliases },
})) if event_id == event_id!("$h29iv0s8:example.com") event_id,
..
},
)) if event_id == event_id!("$h29iv0s8:example.com")
&& aliases.is_none() && aliases.is_none()
) )
} }
@ -207,10 +210,13 @@ fn redacted_deserialize_any_room_sync() {
.unwrap() .unwrap()
.deserialize() .deserialize()
.unwrap(), .unwrap(),
AnySyncRoomEvent::RedactedMessage(AnyRedactedSyncMessageEvent::RoomMessage(RedactedSyncMessageEvent { AnySyncRoomEvent::RedactedMessage(AnyRedactedSyncMessageEvent::RoomMessage(
content: RedactedMessageEventContent, RedactedSyncMessageEvent {
event_id, .. content: RedactedMessageEventContent,
})) if event_id == event_id!("$h29iv0s8:example.com") event_id,
..
}
)) if event_id == event_id!("$h29iv0s8:example.com")
) )
} }
@ -235,12 +241,17 @@ fn redacted_state_event_deserialize() {
.unwrap() .unwrap()
.deserialize() .deserialize()
.unwrap(), .unwrap(),
AnySyncRoomEvent::RedactedState(AnyRedactedSyncStateEvent::RoomCreate(RedactedSyncStateEvent { AnySyncRoomEvent::RedactedState(AnyRedactedSyncStateEvent::RoomCreate(
content: RedactedCreateEventContent { RedactedSyncStateEvent {
creator, content: RedactedCreateEventContent {
}, creator,
event_id, state_key, unsigned, .. },
})) if event_id == event_id!("$h29iv0s8:example.com") event_id,
state_key,
unsigned,
..
}
)) if event_id == event_id!("$h29iv0s8:example.com")
&& unsigned.redacted_because.is_some() && unsigned.redacted_because.is_some()
&& state_key == "hello there" && state_key == "hello there"
&& creator == user_id!("@carl:example.com") && creator == user_id!("@carl:example.com")

View File

@ -164,7 +164,8 @@ impl<'de> Visitor<'de> for RoomNetworkVisitor {
Ok(RoomNetwork::All) Ok(RoomNetwork::All)
} else { } else {
Err(M::Error::custom( Err(M::Error::custom(
"`include_all_networks = true` and `third_party_instance_id` are mutually exclusive.", "`include_all_networks = true` and `third_party_instance_id` are mutually \
exclusive.",
)) ))
} }
} else { } else {

View File

@ -1,3 +1,4 @@
//! Query for another server's keys. The receiving (notary) server must sign the keys returned by the queried server. //! Query for another server's keys. The receiving (notary) server must sign the keys returned by
//! the queried server.
pub mod v2; pub mod v2;

View File

@ -1,3 +1,4 @@
//! Query for keys from multiple servers in a batch format. The receiving (notary) server must sign the keys returned by the queried servers. //! Query for keys from multiple servers in a batch format. The receiving (notary) server must sign
//! the keys returned by the queried servers.
pub mod v2; pub mod v2;

View File

@ -1,7 +1,9 @@
//! A module to deserialize a RoomState struct from incorrectly specified v1 //! A module to deserialize a RoomState struct from incorrectly specified v1
//! send_join endpoint. //! send_join endpoint.
//! //!
//! For more information, see this [GitHub issue](https://github.com/matrix-org/matrix-doc/issues/2541). //! For more information, see this [GitHub issue][issue].
//!
//! [issue]: https://github.com/matrix-org/matrix-doc/issues/2541
use std::fmt; use std::fmt;

View File

@ -26,7 +26,8 @@ ruma_api! {
/// The server_name of the homeserver sending this transaction. /// The server_name of the homeserver sending this transaction.
pub origin: Box<ServerName>, pub origin: Box<ServerName>,
/// POSIX timestamp in milliseconds on the originating homeserver when this transaction started. /// POSIX timestamp in milliseconds on the originating homeserver when this transaction
/// started.
#[serde(with = "ruma_serde::time::ms_since_unix_epoch")] #[serde(with = "ruma_serde::time::ms_since_unix_epoch")]
pub origin_server_ts: SystemTime, pub origin_server_ts: SystemTime,

View File

@ -100,7 +100,9 @@ pub fn server_name(input: TokenStream) -> TokenStream {
assert!(server_name::validate(&id.value()).is_ok(), "Invalid server_name"); assert!(server_name::validate(&id.value()).is_ok(), "Invalid server_name");
let output = quote! { let output = quote! {
<::std::boxed::Box::<#dollar_crate::ServerName> as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap() <::std::boxed::Box::<#dollar_crate::ServerName> as ::std::convert::TryFrom<&str>>::try_from(
#id,
).unwrap()
}; };
output.into() output.into()

View File

@ -1,4 +1,6 @@
//! De-/serialization functions for `Option<std::time::Duration>` objects represented as milliseconds. //! De-/serialization functions for `Option<std::time::Duration>` objects represented as
//! milliseconds.
//!
//! Delegates to `js_int::UInt` to ensure integer size is within bounds. //! Delegates to `js_int::UInt` to ensure integer size is within bounds.
use std::{convert::TryFrom, time::Duration}; use std::{convert::TryFrom, time::Duration};

View File

@ -1,4 +1,6 @@
//! De-/serialization functions for `Option<std::time::Duration>` objects represented as milliseconds. //! De-/serialization functions for `Option<std::time::Duration>` objects represented as
//! milliseconds.
//!
//! Delegates to `js_int::UInt` to ensure integer size is within bounds. //! Delegates to `js_int::UInt` to ensure integer size is within bounds.
use std::{convert::TryFrom, time::Duration}; use std::{convert::TryFrom, time::Duration};

View File

@ -1,4 +1,5 @@
//! De-/serialization functions to and from json strings, allows the type to be used as a query string. //! De-/serialization functions to and from json strings, allows the type to be used as a query
//! string.
use serde::{ use serde::{
de::{Deserialize, DeserializeOwned, Deserializer, Error as _}, de::{Deserialize, DeserializeOwned, Deserializer, Error as _},

View File

@ -78,7 +78,10 @@ static REFERENCE_HASH_FIELDS_TO_REMOVE: &[&str] = &["age_ts", "signatures", "uns
/// A homeserver signs JSON with a key pair: /// A homeserver signs JSON with a key pair:
/// ///
/// ```rust /// ```rust
/// const PKCS8: &str = "MFMCAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/tA0T+6toSMDIQDdM+tpNzNWQM9NFpfgr4B9S7LHszOrVRp9NfKmeXS3aQ"; /// const PKCS8: &str = "\
/// MFMCAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/\
/// tA0T+6toSMDIQDdM+tpNzNWQM9NFpfgr4B9S7LHszOrVRp9NfKmeXS3aQ\
/// ";
/// ///
/// let document = base64::decode_config(&PKCS8, base64::STANDARD_NO_PAD).unwrap(); /// let document = base64::decode_config(&PKCS8, base64::STANDARD_NO_PAD).unwrap();
/// ///
@ -393,7 +396,10 @@ pub fn reference_hash(value: &Value) -> Result<String, Error> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// const PKCS8: &str = "MFMCAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/tA0T+6toSMDIQDdM+tpNzNWQM9NFpfgr4B9S7LHszOrVRp9NfKmeXS3aQ"; /// const PKCS8: &str = "\
/// MFMCAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/\
/// tA0T+6toSMDIQDdM+tpNzNWQM9NFpfgr4B9S7LHszOrVRp9NfKmeXS3aQ\
/// ";
/// ///
/// let document = base64::decode_config(&PKCS8, base64::STANDARD_NO_PAD).unwrap(); /// let document = base64::decode_config(&PKCS8, base64::STANDARD_NO_PAD).unwrap();
/// ///

View File

@ -182,7 +182,10 @@ mod test {
canonical_json, hash_and_sign_event, sign_json, verify_event, verify_json, Ed25519KeyPair, canonical_json, hash_and_sign_event, sign_json, verify_event, verify_json, Ed25519KeyPair,
}; };
const PKCS8: &str = "MFMCAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/tA0T+6toSMDIQDdM+tpNzNWQM9NFpfgr4B9S7LHszOrVRp9NfKmeXS3aQ"; const PKCS8: &str = "\
MFMCAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/\
tA0T+6toSMDIQDdM+tpNzNWQM9NFpfgr4B9S7LHszOrVRp9NfKmeXS3aQ\
";
/// Convenience method for getting the public key as a string /// Convenience method for getting the public key as a string
fn public_key_string() -> String { fn public_key_string() -> String {

View File

@ -45,8 +45,16 @@ impl Signature {
/// * The key ID contains a version with invalid characters. /// * The key ID contains a version with invalid characters.
pub fn new(id: &str, bytes: &[u8]) -> Result<Self, Error> { pub fn new(id: &str, bytes: &[u8]) -> Result<Self, Error> {
let (algorithm, version) = split_id(id).map_err(|split_error| match split_error { let (algorithm, version) = split_id(id).map_err(|split_error| match split_error {
SplitError::InvalidLength(length) => Error::new(format!("malformed signature ID: expected exactly 2 segment separated by a colon, found {}", length)), SplitError::InvalidLength(length) => Error::new(format!(
SplitError::InvalidVersion(version) => Error::new(format!("malformed signature ID: expected version to contain only characters in the character set `[a-zA-Z0-9_]`, found `{}`", version)), "malformed signature ID: expected exactly \
2 segment separated by a colon, found {}",
length
)),
SplitError::InvalidVersion(version) => Error::new(format!(
"malformed signature ID: expected version to contain only \
characters in the character set `[a-zA-Z0-9_]`, found `{}`",
version
)),
SplitError::UnknownAlgorithm(algorithm) => { SplitError::UnknownAlgorithm(algorithm) => {
Error::new(format!("unknown algorithm: {}", algorithm)) Error::new(format!("unknown algorithm: {}", algorithm))
} }