macros: Simplify *EventType generation
This commit is contained in:
parent
1b24a76967
commit
6f6e7ca68e
@ -1,5 +1,5 @@
|
|||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::{Span, TokenStream};
|
||||||
use quote::{format_ident, quote};
|
use quote::quote;
|
||||||
use syn::{Ident, LitStr};
|
use syn::{Ident, LitStr};
|
||||||
|
|
||||||
use super::event_parse::{EventEnumEntry, EventEnumInput, EventKind};
|
use super::event_parse::{EventEnumEntry, EventEnumInput, EventKind};
|
||||||
@ -41,89 +41,49 @@ pub fn expand_event_type_enum(
|
|||||||
}];
|
}];
|
||||||
let mut all = input.enums.iter().map(|e| &e.events).collect::<Vec<_>>();
|
let mut all = input.enums.iter().map(|e| &e.events).collect::<Vec<_>>();
|
||||||
all.push(&presence);
|
all.push(&presence);
|
||||||
let (all_event_types, all_str_ev_types) = generate_variants(&all)?;
|
|
||||||
let all =
|
|
||||||
generate_enum(format_ident!("EventType"), all_str_ev_types, all_event_types, &ruma_common);
|
|
||||||
|
|
||||||
let (room_event_types, room_str_ev_types) = generate_variants(&room)?;
|
let mut res = TokenStream::new();
|
||||||
let room = generate_enum(
|
|
||||||
format_ident!("RoomEventType"),
|
|
||||||
room_str_ev_types,
|
|
||||||
room_event_types,
|
|
||||||
&ruma_common,
|
|
||||||
);
|
|
||||||
|
|
||||||
let (state_event_types, state_str_ev_types) = generate_variants(&state)?;
|
res.extend(generate_enum("EventType", &all, &ruma_common)?);
|
||||||
let state = generate_enum(
|
res.extend(generate_enum("RoomEventType", &room, &ruma_common)?);
|
||||||
format_ident!("StateEventType"),
|
res.extend(generate_enum("StateEventType", &state, &ruma_common)?);
|
||||||
state_str_ev_types,
|
res.extend(generate_enum("MessageLikeEventType", &message, &ruma_common)?);
|
||||||
state_event_types,
|
res.extend(generate_enum("EphemeralRoomEventType", &ephemeral, &ruma_common)?);
|
||||||
&ruma_common,
|
res.extend(generate_enum("RoomAccountDataEventType", &room_account, &ruma_common)?);
|
||||||
);
|
res.extend(generate_enum("GlobalAccountDataEventType", &global_account, &ruma_common)?);
|
||||||
|
res.extend(generate_enum("ToDeviceEventType", &to_device, &ruma_common)?);
|
||||||
|
|
||||||
let (message_event_types, message_str_ev_types) = generate_variants(&message)?;
|
Ok(res)
|
||||||
let message = generate_enum(
|
|
||||||
format_ident!("MessageLikeEventType"),
|
|
||||||
message_str_ev_types,
|
|
||||||
message_event_types,
|
|
||||||
&ruma_common,
|
|
||||||
);
|
|
||||||
|
|
||||||
let (ephemeral_event_types, ephemeral_str_ev_types) = generate_variants(&ephemeral)?;
|
|
||||||
let ephemeral = generate_enum(
|
|
||||||
format_ident!("EphemeralRoomEventType"),
|
|
||||||
ephemeral_str_ev_types,
|
|
||||||
ephemeral_event_types,
|
|
||||||
&ruma_common,
|
|
||||||
);
|
|
||||||
|
|
||||||
let (room_account_event_types, room_account_str_ev_types) = generate_variants(&room_account)?;
|
|
||||||
let room_account = generate_enum(
|
|
||||||
format_ident!("RoomAccountDataEventType"),
|
|
||||||
room_account_str_ev_types,
|
|
||||||
room_account_event_types,
|
|
||||||
&ruma_common,
|
|
||||||
);
|
|
||||||
|
|
||||||
let (global_account_event_types, global_account_str_ev_types) =
|
|
||||||
generate_variants(&global_account)?;
|
|
||||||
let global_account = generate_enum(
|
|
||||||
format_ident!("GlobalAccountDataEventType"),
|
|
||||||
global_account_str_ev_types,
|
|
||||||
global_account_event_types,
|
|
||||||
&ruma_common,
|
|
||||||
);
|
|
||||||
|
|
||||||
let (to_device_event_types, to_device_str_ev_types) = generate_variants(&to_device)?;
|
|
||||||
let to_device = generate_enum(
|
|
||||||
format_ident!("ToDeviceEventType"),
|
|
||||||
to_device_str_ev_types,
|
|
||||||
to_device_event_types,
|
|
||||||
&ruma_common,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(quote! {
|
|
||||||
#all
|
|
||||||
#room
|
|
||||||
#state
|
|
||||||
#message
|
|
||||||
#ephemeral
|
|
||||||
#room_account
|
|
||||||
#global_account
|
|
||||||
#to_device
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_enum(
|
fn generate_enum(
|
||||||
ident: Ident,
|
ident: &str,
|
||||||
ev_type_strings: Vec<&LitStr>,
|
input: &[&Vec<EventEnumEntry>],
|
||||||
variants: Vec<TokenStream>,
|
|
||||||
ruma_common: &TokenStream,
|
ruma_common: &TokenStream,
|
||||||
) -> TokenStream {
|
) -> syn::Result<TokenStream> {
|
||||||
let str_doc = format!("Creates a string slice from this `{}`.", ident);
|
let str_doc = format!("Creates a string slice from this `{}`.", ident);
|
||||||
let byte_doc = format!("Creates a byte slice from this `{}`.", ident);
|
let byte_doc = format!("Creates a byte slice from this `{}`.", ident);
|
||||||
let enum_doc = format!("The type of `{}` this is.", ident);
|
let enum_doc = format!("The type of `{}` this is.", ident.strip_suffix("Type").unwrap());
|
||||||
quote! {
|
|
||||||
|
let ident = Ident::new(ident, Span::call_site());
|
||||||
|
|
||||||
|
let mut deduped: Vec<&EventEnumEntry> = vec![];
|
||||||
|
for item in input.iter().copied().flatten() {
|
||||||
|
if let Some(idx) = deduped.iter().position(|e| e.ev_type == item.ev_type) {
|
||||||
|
// If there is a variant without config attributes use that
|
||||||
|
if deduped[idx].attrs != item.attrs && item.attrs.is_empty() {
|
||||||
|
deduped[idx] = item;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
deduped.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let event_types = deduped.iter().map(|e| &e.ev_type);
|
||||||
|
let variants =
|
||||||
|
deduped.iter().map(|e| Ok(e.to_variant()?.decl())).collect::<syn::Result<Vec<_>>>()?;
|
||||||
|
|
||||||
|
Ok(quote! {
|
||||||
#[doc = #enum_doc]
|
#[doc = #enum_doc]
|
||||||
///
|
///
|
||||||
/// This type can hold an arbitrary string. To check for events that are not available as a
|
/// This type can hold an arbitrary string. To check for events that are not available as a
|
||||||
@ -132,8 +92,8 @@ fn generate_enum(
|
|||||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
pub enum #ident {
|
pub enum #ident {
|
||||||
#(
|
#(
|
||||||
#[doc = #ev_type_strings]
|
#[doc = #event_types]
|
||||||
#[ruma_enum(rename = #ev_type_strings)]
|
#[ruma_enum(rename = #event_types)]
|
||||||
#variants,
|
#variants,
|
||||||
)*
|
)*
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@ -151,27 +111,5 @@ fn generate_enum(
|
|||||||
self.as_str().as_bytes()
|
self.as_str().as_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_variants<'a>(
|
|
||||||
input: &'a [&Vec<EventEnumEntry>],
|
|
||||||
) -> syn::Result<(Vec<TokenStream>, Vec<&'a LitStr>)> {
|
|
||||||
let mut deduped: Vec<&EventEnumEntry> = vec![];
|
|
||||||
for item in input.iter().copied().flatten() {
|
|
||||||
if let Some(idx) = deduped.iter().position(|e| e.ev_type == item.ev_type) {
|
|
||||||
// If there is a variant without config attributes use that
|
|
||||||
if deduped[idx].attrs != item.attrs && item.attrs.is_empty() {
|
|
||||||
deduped[idx] = item;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
deduped.push(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let event_types = deduped.iter().map(|e| &e.ev_type).collect();
|
|
||||||
|
|
||||||
let event_types_variants =
|
|
||||||
deduped.iter().map(|e| Ok(e.to_variant()?.decl())).collect::<syn::Result<Vec<_>>>()?;
|
|
||||||
|
|
||||||
Ok((event_types_variants, event_types))
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user