mirror of
https://codeberg.org/icewind/tf-log-parser.git
synced 2026-06-03 18:24:09 +02:00
derive GameEvent parsing
This commit is contained in:
parent
ab5a061eb0
commit
f5957059d8
10 changed files with 116 additions and 121 deletions
68
derive/src/events.rs
Normal file
68
derive/src/events.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
use crate::{err, Derivable, DeriveParams};
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::quote_spanned;
|
||||
use syn::{Data, DeriveInput, Generics, Result};
|
||||
|
||||
pub struct Events;
|
||||
|
||||
impl Derivable for Events {
|
||||
type Params = EventsParam;
|
||||
|
||||
fn derive(params: EventsParam) -> Result<TokenStream> {
|
||||
let enum_ident = params.name;
|
||||
let span = enum_ident.span();
|
||||
|
||||
let variants = params.variants.iter().map(|(variant_name, empty)| {
|
||||
let span = variant_name.span();
|
||||
if *empty {
|
||||
quote_spanned!(span => RawEventType::#variant_name => Self::#variant_name,)
|
||||
} else {
|
||||
quote_spanned!(span => RawEventType::#variant_name => Self::#variant_name(parse_event(raw.params).with_raw(raw)?),)
|
||||
}
|
||||
});
|
||||
|
||||
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
|
||||
|
||||
Ok(
|
||||
quote_spanned!(span => impl #impl_generics #enum_ident #ty_generics #where_clause {
|
||||
pub fn parse(raw: &RawEvent<'a>) -> Result<Self, GameEventError> {
|
||||
Ok(match raw.ty {
|
||||
#(#variants)*
|
||||
_ => {
|
||||
todo!("{:?} not parsed yet", raw.ty);
|
||||
}
|
||||
})
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EventsParam {
|
||||
name: Ident,
|
||||
generics: Generics,
|
||||
variants: Vec<(Ident, bool)>,
|
||||
}
|
||||
|
||||
impl DeriveParams for EventsParam {
|
||||
fn parse(input: &DeriveInput) -> Result<EventsParam> {
|
||||
let Data::Enum(data) = &input.data else {
|
||||
return err("only supported on enums", input);
|
||||
};
|
||||
let name = input.ident.clone();
|
||||
let generics = input.generics.clone();
|
||||
|
||||
let variants = data
|
||||
.variants
|
||||
.iter()
|
||||
.map(|variant| (variant.ident.clone(), variant.fields.is_empty()))
|
||||
.collect();
|
||||
|
||||
Ok(EventsParam {
|
||||
name,
|
||||
generics,
|
||||
variants,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,10 @@
|
|||
extern crate proc_macro;
|
||||
|
||||
mod event;
|
||||
mod events;
|
||||
|
||||
use crate::event::Event;
|
||||
use crate::events::Events;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::ToTokens;
|
||||
use std::fmt::{Debug, Display};
|
||||
|
|
@ -12,12 +14,20 @@ use syn::{parse_macro_input, DeriveInput, Error, Result};
|
|||
|
||||
/// Derive the `Event` trait for a struct
|
||||
#[proc_macro_derive(Event, attributes(event))]
|
||||
pub fn derive_pod(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
pub fn derive_event(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let expanded = derive_trait::<Event>(parse_macro_input!(input as DeriveInput));
|
||||
|
||||
proc_macro::TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
/// Derive the `Events` trait for a struct
|
||||
#[proc_macro_derive(Events, attributes())]
|
||||
pub fn derive_events(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let expanded = derive_trait::<Events>(parse_macro_input!(input as DeriveInput));
|
||||
|
||||
proc_macro::TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
/// Basic wrapper for error handling
|
||||
fn derive_trait<Trait: Derivable>(input: DeriveInput) -> TokenStream {
|
||||
derive_trait_inner::<Trait>(input).unwrap_or_else(|err| err.into_compile_error())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue