Derive Serialize in ruma_events!
, use json EventType string for event_type
field
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
This commit is contained in:
parent
14df832005
commit
8ea971b082
@ -1,5 +1,4 @@
|
||||
//! Details of generating code for the `ruma_event` procedural macro.
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{format_ident, quote, quote_spanned, ToTokens};
|
||||
use syn::{
|
||||
@ -7,7 +6,7 @@ use syn::{
|
||||
parse_quote,
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
Attribute, Field, Ident, Path, Token, Type,
|
||||
Attribute, Field, Ident, LitStr, Token, Type,
|
||||
};
|
||||
|
||||
use crate::parse::{Content, EventKind, RumaEventInput};
|
||||
@ -25,7 +24,7 @@ pub struct RumaEvent {
|
||||
|
||||
/// The variant of `ruma_events::EventType` for this event, determined by the `event_type`
|
||||
/// field.
|
||||
event_type: Path,
|
||||
event_type: LitStr,
|
||||
|
||||
/// Struct fields of the event.
|
||||
fields: Vec<Field>,
|
||||
@ -80,10 +79,12 @@ impl ToTokens for RumaEvent {
|
||||
let content_name = &self.content_name;
|
||||
let event_fields = &self.fields;
|
||||
|
||||
let event_type = {
|
||||
let event_type = &self.event_type;
|
||||
let event_type_variant = {
|
||||
let event_type = to_camel_case(self.event_type.value());
|
||||
let variant = Ident::new(&event_type, event_type.span());
|
||||
|
||||
quote! {
|
||||
#event_type
|
||||
::ruma_events::EventType::#variant
|
||||
}
|
||||
};
|
||||
|
||||
@ -315,7 +316,7 @@ impl ToTokens for RumaEvent {
|
||||
|
||||
/// The type of the event.
|
||||
fn event_type(&self) -> ::ruma_events::EventType {
|
||||
#event_type
|
||||
#event_type_variant
|
||||
}
|
||||
}
|
||||
|
||||
@ -406,6 +407,16 @@ fn is_option(ty: &Type) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
/// Splits the given `event_type` string on `.` and `_` removing the `m.` then
|
||||
/// camel casing to give the `EventType` variant.
|
||||
fn to_camel_case(name: String) -> String {
|
||||
assert_eq!(&name[..2], "m.");
|
||||
name[2..]
|
||||
.split(&['.', '_'] as &[char])
|
||||
.map(|s| s.chars().next().unwrap().to_uppercase().to_string() + &s[1..])
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// A wrapper around `syn::Field` that makes it possible to parse `Punctuated<Field, Token![,]>`
|
||||
/// from a `TokenStream`.
|
||||
///
|
||||
|
@ -1,14 +1,10 @@
|
||||
//! Details of parsing input for the `ruma_event` procedural macro.
|
||||
|
||||
use proc_macro2::Span;
|
||||
|
||||
use syn::{
|
||||
braced,
|
||||
parse::{self, Parse, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
token::Colon,
|
||||
Attribute, Expr, Field, FieldValue, Ident, Member, Path, PathArguments, PathSegment, Token,
|
||||
TypePath,
|
||||
Attribute, Expr, ExprLit, Field, FieldValue, Ident, Lit, LitStr, Member, Token, TypePath,
|
||||
};
|
||||
|
||||
/// The entire `ruma_event!` macro structure directly as it appears in the source code..
|
||||
@ -22,9 +18,11 @@ pub struct RumaEventInput {
|
||||
/// The kind of event, determiend by the `kind` field.
|
||||
pub kind: EventKind,
|
||||
|
||||
/// The variant of `ruma_events::EventType` for this event, determined by the `event_type`
|
||||
/// field.
|
||||
pub event_type: Path,
|
||||
/// The value for the `type` field in the JSON representation of this event. 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 remaining dots by underscores and then
|
||||
/// converting from snake_case to CamelCase).
|
||||
pub event_type: LitStr,
|
||||
|
||||
/// Additional named struct fields in the top level event struct.
|
||||
pub fields: Option<Vec<Field>>,
|
||||
@ -98,35 +96,13 @@ impl Parse for RumaEventInput {
|
||||
|
||||
kind = Some(event_kind);
|
||||
} else if ident == "event_type" {
|
||||
match field_value.expr {
|
||||
Expr::Path(expr_path) => {
|
||||
if expr_path.path.segments.len() != 1 {
|
||||
panic!("value of field `event_type` is required to be an ident by `ruma_event!`");
|
||||
}
|
||||
|
||||
let path = expr_path.path;
|
||||
let variant = path.segments.first().unwrap();
|
||||
|
||||
let mut punctuated = Punctuated::new();
|
||||
punctuated.push(PathSegment {
|
||||
ident: Ident::new("ruma_events", Span::call_site()),
|
||||
arguments: PathArguments::None,
|
||||
});
|
||||
punctuated.push(PathSegment {
|
||||
ident: Ident::new("EventType", Span::call_site()),
|
||||
arguments: PathArguments::None,
|
||||
});
|
||||
punctuated.push(variant.clone());
|
||||
|
||||
event_type = Some(Path {
|
||||
leading_colon: Some(Default::default()),
|
||||
segments: punctuated,
|
||||
});
|
||||
}
|
||||
event_type = Some(match field_value.expr {
|
||||
Expr::Lit(ExprLit { lit: Lit::Str(s), .. }) => s,
|
||||
// TODO: Span info
|
||||
_ => panic!(
|
||||
"value of field `event_type` is required to be an ident by `ruma_event!`"
|
||||
"value of field `event_type` is required to be a string literal by `ruma_event!`"
|
||||
),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
panic!("unexpected field-value pair with field name `{}`", ident);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ ruma_event! {
|
||||
/// This event is sent by the callee when they wish to answer the call.
|
||||
AnswerEvent {
|
||||
kind: RoomEvent,
|
||||
event_type: CallAnswer,
|
||||
event_type: "m.call.answer",
|
||||
content: {
|
||||
/// The VoIP session description object. The session description type must be *answer*.
|
||||
pub answer: SessionDescription,
|
||||
|
@ -10,7 +10,7 @@ ruma_event! {
|
||||
/// communicate.
|
||||
CandidatesEvent {
|
||||
kind: RoomEvent,
|
||||
event_type: CallCandidates,
|
||||
event_type: "m.call.candidates",
|
||||
content: {
|
||||
/// The ID of the call this event relates to.
|
||||
pub call_id: String,
|
||||
|
@ -9,7 +9,7 @@ ruma_event! {
|
||||
/// the call has has been established or before to abort the call.
|
||||
HangupEvent {
|
||||
kind: RoomEvent,
|
||||
event_type: CallHangup,
|
||||
event_type: "m.call.hangup",
|
||||
content: {
|
||||
/// The ID of the call this event relates to.
|
||||
pub call_id: String,
|
||||
|
@ -9,7 +9,7 @@ ruma_event! {
|
||||
/// This event is sent by the caller when they wish to establish a call.
|
||||
InviteEvent {
|
||||
kind: RoomEvent,
|
||||
event_type: CallInvite,
|
||||
event_type: "m.call.invite",
|
||||
content: {
|
||||
/// A unique identifer for the call.
|
||||
pub call_id: String,
|
||||
|
@ -9,7 +9,7 @@ ruma_event! {
|
||||
/// Informs the client about the rooms that are considered direct by a user.
|
||||
DirectEvent {
|
||||
kind: Event,
|
||||
event_type: Direct,
|
||||
event_type: "m.direct",
|
||||
content_type_alias: {
|
||||
/// The payload for `DirectEvent`.
|
||||
///
|
||||
|
@ -16,7 +16,7 @@ ruma_event! {
|
||||
/// sending client receiving keys over the newly established session.
|
||||
DummyEvent {
|
||||
kind: Event,
|
||||
event_type: Dummy,
|
||||
event_type: "m.dummy",
|
||||
content_type_alias: {
|
||||
/// The payload for `DummyEvent`.
|
||||
Empty
|
||||
|
@ -11,7 +11,7 @@ ruma_event! {
|
||||
/// Typically it is encrypted as an *m.room.encrypted* event, then sent as a to-device event.
|
||||
ForwardedRoomKeyEvent {
|
||||
kind: Event,
|
||||
event_type: ForwardedRoomKey,
|
||||
event_type: "m.forwarded_room_key",
|
||||
content: {
|
||||
/// The encryption algorithm the key in this event is to be used with.
|
||||
pub algorithm: Algorithm,
|
||||
|
@ -10,7 +10,7 @@ ruma_event! {
|
||||
/// for.
|
||||
FullyReadEvent {
|
||||
kind: Event,
|
||||
event_type: FullyRead,
|
||||
event_type: "m.fully_read",
|
||||
fields: {
|
||||
/// The unique identifier for the room associated with this event.
|
||||
///
|
||||
|
@ -13,7 +13,7 @@ ruma_event! {
|
||||
/// Typically sent as a to-device event.
|
||||
AcceptEvent {
|
||||
kind: Event,
|
||||
event_type: KeyVerificationAccept,
|
||||
event_type: "m.key.verification.accept",
|
||||
content: {
|
||||
/// An opaque identifier for the verification process.
|
||||
///
|
||||
|
@ -14,7 +14,7 @@ ruma_event! {
|
||||
/// Typically sent as a to-device event.
|
||||
CancelEvent {
|
||||
kind: Event,
|
||||
event_type: KeyVerificationCancel,
|
||||
event_type: "m.key.verification.cancel",
|
||||
content: {
|
||||
/// The opaque identifier for the verification process/request.
|
||||
pub transaction_id: String,
|
||||
|
@ -8,7 +8,7 @@ ruma_event! {
|
||||
/// Typically sent as a to-device event.
|
||||
KeyEvent {
|
||||
kind: Event,
|
||||
event_type: KeyVerificationKey,
|
||||
event_type: "m.key.verification.key",
|
||||
content: {
|
||||
/// An opaque identifier for the verification process.
|
||||
///
|
||||
|
@ -10,7 +10,7 @@ ruma_event! {
|
||||
/// Typically sent as a to-device event.
|
||||
MacEvent {
|
||||
kind: Event,
|
||||
event_type: KeyVerificationMac,
|
||||
event_type: "m.key.verification.mac",
|
||||
content: {
|
||||
/// An opaque identifier for the verification process.
|
||||
///
|
||||
|
@ -12,7 +12,7 @@ ruma_event! {
|
||||
/// Typically sent as a to-device event.
|
||||
RequestEvent {
|
||||
kind: Event,
|
||||
event_type: KeyVerificationRequest,
|
||||
event_type: "m.key.verification.request",
|
||||
content: {
|
||||
/// The device ID which is initiating the request.
|
||||
pub from_device: DeviceId,
|
||||
|
@ -9,7 +9,7 @@ ruma_event! {
|
||||
/// Informs the client of a user's presence state change.
|
||||
PresenceEvent {
|
||||
kind: Event,
|
||||
event_type: Presence,
|
||||
event_type: "m.presence",
|
||||
fields: {
|
||||
/// The unique identifier for the user associated with this event.
|
||||
pub sender: UserId,
|
||||
|
@ -19,7 +19,7 @@ ruma_event! {
|
||||
/// Describes all push rules for a user.
|
||||
PushRulesEvent {
|
||||
kind: Event,
|
||||
event_type: PushRules,
|
||||
event_type: "m.push_rules",
|
||||
content: {
|
||||
/// The global ruleset.
|
||||
pub global: Ruleset,
|
||||
|
@ -11,7 +11,7 @@ ruma_event! {
|
||||
/// Informs the client of new receipts.
|
||||
ReceiptEvent {
|
||||
kind: Event,
|
||||
event_type: Receipt,
|
||||
event_type: "m.receipt",
|
||||
fields: {
|
||||
/// The unique identifier for the room associated with this event.
|
||||
///
|
||||
|
@ -7,7 +7,7 @@ ruma_event! {
|
||||
/// Informs the room about what room aliases it has been given.
|
||||
AliasesEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomAliases,
|
||||
event_type: "m.room.aliases",
|
||||
content: {
|
||||
/// A list of room aliases.
|
||||
pub aliases: Vec<RoomAliasId>,
|
||||
|
@ -10,7 +10,7 @@ ruma_event! {
|
||||
/// This can be displayed alongside the room information.
|
||||
AvatarEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomAvatar,
|
||||
event_type: "m.room.avatar",
|
||||
content: {
|
||||
/// Information about the avatar image.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
@ -13,7 +13,7 @@ ruma_event! {
|
||||
/// events.
|
||||
CreateEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomCreate,
|
||||
event_type: "m.room.create",
|
||||
content: {
|
||||
/// The `user_id` of the room creator. This is set by the homeserver.
|
||||
pub creator: UserId,
|
||||
|
@ -9,7 +9,7 @@ ruma_event! {
|
||||
/// Defines how messages sent in this room should be encrypted.
|
||||
EncryptionEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomEncryption,
|
||||
event_type: "m.room.encryption",
|
||||
content: {
|
||||
/// The encryption algorithm to be used to encrypt messages sent in this room.
|
||||
///
|
||||
|
@ -10,7 +10,7 @@ ruma_event! {
|
||||
/// servers should act as if it is present and has the value `GuestAccess::Forbidden`.
|
||||
GuestAccessEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomGuestAccess,
|
||||
event_type: "m.room.guest_access",
|
||||
content: {
|
||||
/// A policy for guest user access to a room.
|
||||
pub guest_access: GuestAccess,
|
||||
|
@ -8,7 +8,7 @@ ruma_event! {
|
||||
/// from before they joined.
|
||||
HistoryVisibilityEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomHistoryVisibility,
|
||||
event_type: "m.room.history_visibility",
|
||||
content: {
|
||||
/// Who can see the room history.
|
||||
pub history_visibility: HistoryVisibility,
|
||||
|
@ -7,7 +7,7 @@ ruma_event! {
|
||||
/// Describes how users are allowed to join the room.
|
||||
JoinRulesEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomJoinRules,
|
||||
event_type: "m.room.join_rules",
|
||||
content: {
|
||||
/// The type of rules used for users wishing to join this room.
|
||||
pub join_rule: JoinRule,
|
||||
|
@ -34,7 +34,7 @@ ruma_event! {
|
||||
/// must be assumed as leave.
|
||||
MemberEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomMember,
|
||||
event_type: "m.room.member",
|
||||
content: {
|
||||
/// The avatar URL for this user, if any. This is added by the homeserver.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
@ -11,7 +11,7 @@ ruma_event! {
|
||||
/// not recognize this event.
|
||||
FeedbackEvent {
|
||||
kind: RoomEvent,
|
||||
event_type: RoomMessageFeedback,
|
||||
event_type: "m.room.message.feedback",
|
||||
content: {
|
||||
/// The event that this feedback is related to.
|
||||
pub target_event_id: EventId,
|
||||
|
@ -7,7 +7,7 @@ ruma_event! {
|
||||
/// Used to "pin" particular events in a room for other participants to review later.
|
||||
PinnedEventsEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomPinnedEvents,
|
||||
event_type: "m.room.pinned_events",
|
||||
content: {
|
||||
/// An ordered list of event IDs to pin.
|
||||
pub pinned: Vec<EventId>,
|
||||
|
@ -7,7 +7,7 @@ ruma_event! {
|
||||
/// A redaction of an event.
|
||||
RedactionEvent {
|
||||
kind: RoomEvent,
|
||||
event_type: RoomRedaction,
|
||||
event_type: "m.room.redaction",
|
||||
fields: {
|
||||
/// The ID of the event that was redacted.
|
||||
pub redacts: EventId,
|
||||
|
@ -11,7 +11,7 @@ ruma_event! {
|
||||
/// Any user who can present that signature may use this invitation to join the target room.
|
||||
ThirdPartyInviteEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomThirdPartyInvite,
|
||||
event_type: "m.room.third_party_invite",
|
||||
content: {
|
||||
/// A user-readable string which represents the user who has been invited.
|
||||
pub display_name: String,
|
||||
|
@ -8,7 +8,7 @@ ruma_event! {
|
||||
/// clients should go there.
|
||||
TombstoneEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomTombstone,
|
||||
event_type: "m.room.tombstone",
|
||||
content: {
|
||||
/// A server-defined message.
|
||||
pub body: String,
|
||||
|
@ -6,7 +6,7 @@ ruma_event! {
|
||||
/// A topic is a short message detailing what is currently being discussed in the room.
|
||||
TopicEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomTopic,
|
||||
event_type: "m.room.topic",
|
||||
content: {
|
||||
/// The topic text.
|
||||
pub topic: String,
|
||||
|
@ -11,7 +11,7 @@ ruma_event! {
|
||||
/// Typically it is encrypted as an *m.room.encrypted* event, then sent as a to-device event.
|
||||
RoomKeyEvent {
|
||||
kind: Event,
|
||||
event_type: RoomKey,
|
||||
event_type: "m.room_key",
|
||||
content: {
|
||||
/// The encryption algorithm the key in this event is to be used with.
|
||||
///
|
||||
|
@ -12,7 +12,7 @@ ruma_event! {
|
||||
/// It is sent as an unencrypted to-device event.
|
||||
RoomKeyRequestEvent {
|
||||
kind: Event,
|
||||
event_type: RoomKeyRequest,
|
||||
event_type: "m.room_key_request",
|
||||
content: {
|
||||
/// Whether this is a new key request or a cancellation of a previous request.
|
||||
pub action: Action,
|
||||
|
@ -8,7 +8,7 @@ ruma_event! {
|
||||
/// A sticker message.
|
||||
StickerEvent {
|
||||
kind: RoomEvent,
|
||||
event_type: Sticker,
|
||||
event_type: "m.sticker",
|
||||
content: {
|
||||
/// A textual representation or associated description of the sticker image. This could
|
||||
/// be the alt text of the original image, or a message to accompany and further
|
||||
|
@ -9,7 +9,7 @@ ruma_event! {
|
||||
/// Informs the client of tags on a room.
|
||||
TagEvent {
|
||||
kind: Event,
|
||||
event_type: Tag,
|
||||
event_type: "m.tag",
|
||||
content: {
|
||||
/// A map of tag names to tag info.
|
||||
pub tags: HashMap<String, TagInfo>,
|
||||
|
@ -7,7 +7,7 @@ ruma_event! {
|
||||
/// Informs the client of the list of users currently typing.
|
||||
TypingEvent {
|
||||
kind: Event,
|
||||
event_type: Typing,
|
||||
event_type: "m.typing",
|
||||
fields: {
|
||||
/// The unique identifier for the room associated with this event.
|
||||
///
|
||||
|
@ -14,7 +14,7 @@ mod common_case {
|
||||
/// Informs the room about what room aliases it has been given.
|
||||
AliasesEvent {
|
||||
kind: StateEvent,
|
||||
event_type: RoomAliases,
|
||||
event_type: "m.room.aliases",
|
||||
content: {
|
||||
/// A list of room aliases.
|
||||
pub aliases: Vec<ruma_identifiers::RoomAliasId>,
|
||||
@ -126,7 +126,7 @@ mod extra_fields {
|
||||
/// A redaction of an event.
|
||||
RedactionEvent {
|
||||
kind: RoomEvent,
|
||||
event_type: RoomRedaction,
|
||||
event_type: "m.room.redaction",
|
||||
fields: {
|
||||
/// The ID of the event that was redacted.
|
||||
pub redacts: ruma_identifiers::EventId
|
||||
@ -174,7 +174,7 @@ mod type_alias {
|
||||
/// Informs the client about the rooms that are considered direct by a user.
|
||||
DirectEvent {
|
||||
kind: Event,
|
||||
event_type: Direct,
|
||||
event_type: "m.direct",
|
||||
content_type_alias: {
|
||||
/// The payload of a `DirectEvent`.
|
||||
///
|
||||
|
Loading…
x
Reference in New Issue
Block a user