diff --git a/ruma-events-macros/src/gen.rs b/ruma-events-macros/src/gen.rs index e88b54fb..6e892fb9 100644 --- a/ruma-events-macros/src/gen.rs +++ b/ruma-events-macros/src/gen.rs @@ -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, @@ -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` /// from a `TokenStream`. /// diff --git a/ruma-events-macros/src/parse.rs b/ruma-events-macros/src/parse.rs index 868955bc..86929000 100644 --- a/ruma-events-macros/src/parse.rs +++ b/ruma-events-macros/src/parse.rs @@ -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>, @@ -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); } diff --git a/src/call/answer.rs b/src/call/answer.rs index c70c945a..48b5faea 100644 --- a/src/call/answer.rs +++ b/src/call/answer.rs @@ -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, diff --git a/src/call/candidates.rs b/src/call/candidates.rs index 70546395..be8655cc 100644 --- a/src/call/candidates.rs +++ b/src/call/candidates.rs @@ -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, diff --git a/src/call/hangup.rs b/src/call/hangup.rs index 78087656..9c8b3993 100644 --- a/src/call/hangup.rs +++ b/src/call/hangup.rs @@ -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, diff --git a/src/call/invite.rs b/src/call/invite.rs index 98b93fd9..16b21ea7 100644 --- a/src/call/invite.rs +++ b/src/call/invite.rs @@ -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, diff --git a/src/direct.rs b/src/direct.rs index bda9446a..ee9f9eff 100644 --- a/src/direct.rs +++ b/src/direct.rs @@ -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`. /// diff --git a/src/dummy.rs b/src/dummy.rs index b0e78f6f..45239c69 100644 --- a/src/dummy.rs +++ b/src/dummy.rs @@ -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 diff --git a/src/forwarded_room_key.rs b/src/forwarded_room_key.rs index e0ee7d47..bcb20340 100644 --- a/src/forwarded_room_key.rs +++ b/src/forwarded_room_key.rs @@ -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, diff --git a/src/fully_read.rs b/src/fully_read.rs index cd2e0458..69e10c16 100644 --- a/src/fully_read.rs +++ b/src/fully_read.rs @@ -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. /// diff --git a/src/key/verification/accept.rs b/src/key/verification/accept.rs index 140a42b9..e2e5aa4a 100644 --- a/src/key/verification/accept.rs +++ b/src/key/verification/accept.rs @@ -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. /// diff --git a/src/key/verification/cancel.rs b/src/key/verification/cancel.rs index 41d88553..ad7a0ffb 100644 --- a/src/key/verification/cancel.rs +++ b/src/key/verification/cancel.rs @@ -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, diff --git a/src/key/verification/key.rs b/src/key/verification/key.rs index 9c27e133..807bf9ed 100644 --- a/src/key/verification/key.rs +++ b/src/key/verification/key.rs @@ -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. /// diff --git a/src/key/verification/mac.rs b/src/key/verification/mac.rs index d59e7ba2..1aad1d9a 100644 --- a/src/key/verification/mac.rs +++ b/src/key/verification/mac.rs @@ -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. /// diff --git a/src/key/verification/request.rs b/src/key/verification/request.rs index 778154ad..77e9dcfb 100644 --- a/src/key/verification/request.rs +++ b/src/key/verification/request.rs @@ -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, diff --git a/src/presence.rs b/src/presence.rs index 785f3ec5..b75b8a34 100644 --- a/src/presence.rs +++ b/src/presence.rs @@ -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, diff --git a/src/push_rules.rs b/src/push_rules.rs index 10388662..c35b1df1 100644 --- a/src/push_rules.rs +++ b/src/push_rules.rs @@ -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, diff --git a/src/receipt.rs b/src/receipt.rs index 773b485b..afd69c5e 100644 --- a/src/receipt.rs +++ b/src/receipt.rs @@ -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. /// diff --git a/src/room/aliases.rs b/src/room/aliases.rs index 203cf642..2c1cab8b 100644 --- a/src/room/aliases.rs +++ b/src/room/aliases.rs @@ -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, diff --git a/src/room/avatar.rs b/src/room/avatar.rs index c45738f9..f0590ae9 100644 --- a/src/room/avatar.rs +++ b/src/room/avatar.rs @@ -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")] diff --git a/src/room/create.rs b/src/room/create.rs index 6ec2f3ce..070a3c5c 100644 --- a/src/room/create.rs +++ b/src/room/create.rs @@ -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, diff --git a/src/room/encryption.rs b/src/room/encryption.rs index 4d4102b8..a2f63014 100644 --- a/src/room/encryption.rs +++ b/src/room/encryption.rs @@ -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. /// diff --git a/src/room/guest_access.rs b/src/room/guest_access.rs index 394c4a68..f659394f 100644 --- a/src/room/guest_access.rs +++ b/src/room/guest_access.rs @@ -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, diff --git a/src/room/history_visibility.rs b/src/room/history_visibility.rs index f37d0ae0..f1ad183b 100644 --- a/src/room/history_visibility.rs +++ b/src/room/history_visibility.rs @@ -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, diff --git a/src/room/join_rules.rs b/src/room/join_rules.rs index 4cd6764c..2ce7ce2f 100644 --- a/src/room/join_rules.rs +++ b/src/room/join_rules.rs @@ -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, diff --git a/src/room/member.rs b/src/room/member.rs index 2eff2568..69b8148f 100644 --- a/src/room/member.rs +++ b/src/room/member.rs @@ -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")] diff --git a/src/room/message/feedback.rs b/src/room/message/feedback.rs index ac7a01c3..5fd708d2 100644 --- a/src/room/message/feedback.rs +++ b/src/room/message/feedback.rs @@ -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, diff --git a/src/room/pinned_events.rs b/src/room/pinned_events.rs index 2fa88758..0812e133 100644 --- a/src/room/pinned_events.rs +++ b/src/room/pinned_events.rs @@ -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, diff --git a/src/room/redaction.rs b/src/room/redaction.rs index b69268cc..2952335a 100644 --- a/src/room/redaction.rs +++ b/src/room/redaction.rs @@ -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, diff --git a/src/room/third_party_invite.rs b/src/room/third_party_invite.rs index 8e107689..bcc76b6e 100644 --- a/src/room/third_party_invite.rs +++ b/src/room/third_party_invite.rs @@ -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, diff --git a/src/room/tombstone.rs b/src/room/tombstone.rs index ce323877..e384ed09 100644 --- a/src/room/tombstone.rs +++ b/src/room/tombstone.rs @@ -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, diff --git a/src/room/topic.rs b/src/room/topic.rs index 02ffc3a2..a327a94d 100644 --- a/src/room/topic.rs +++ b/src/room/topic.rs @@ -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, diff --git a/src/room_key.rs b/src/room_key.rs index c876c704..763b1e30 100644 --- a/src/room_key.rs +++ b/src/room_key.rs @@ -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. /// diff --git a/src/room_key_request.rs b/src/room_key_request.rs index f22ffe4c..cbe33d45 100644 --- a/src/room_key_request.rs +++ b/src/room_key_request.rs @@ -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, diff --git a/src/sticker.rs b/src/sticker.rs index c90c4c2c..78959ef2 100644 --- a/src/sticker.rs +++ b/src/sticker.rs @@ -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 diff --git a/src/tag.rs b/src/tag.rs index 3ed95d00..6c59d994 100644 --- a/src/tag.rs +++ b/src/tag.rs @@ -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, diff --git a/src/typing.rs b/src/typing.rs index 77ca4957..7cd627d8 100644 --- a/src/typing.rs +++ b/src/typing.rs @@ -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. /// diff --git a/tests/ruma_events_macros.rs b/tests/ruma_events_macros.rs index 7bc2fc84..0cb96a9a 100644 --- a/tests/ruma_events_macros.rs +++ b/tests/ruma_events_macros.rs @@ -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, @@ -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`. ///