Finite state machines in rust; bendns fork to add types.
Diffstat (limited to 'rust-fsm-dsl/src/variant.rs')
| -rw-r--r-- | rust-fsm-dsl/src/variant.rs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/rust-fsm-dsl/src/variant.rs b/rust-fsm-dsl/src/variant.rs new file mode 100644 index 0000000..417476b --- /dev/null +++ b/rust-fsm-dsl/src/variant.rs @@ -0,0 +1,73 @@ +use std::fmt::Display; + +use quote::ToTokens; +use syn::{parse::Parse, *}; +/// Variant with no discriminator +#[derive(Hash, Debug, PartialEq, Eq)] +pub struct Variant { + // attrs: Vec<Attribute>, + ident: Ident, + field: Option<(Type, Expr)>, +} + +impl Parse for Variant { + fn parse(input: parse::ParseStream) -> Result<Self> { + // let attrs = input.call(Attribute::parse_outer)?; + // let _visibility: Visibility = input.parse()?; + let ident: Ident = input.parse()?; + let field = if input.peek(token::Paren) { + let inp; + parenthesized!(inp in input); + let t = inp.parse()?; + inp.parse::<Token![=>]>()?; + Some((t, inp.parse()?)) + } else { + None + }; + Ok(Variant { + // attrs, + ident, + field, + }) + } +} + +impl PartialOrd for Variant { + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + self.ident.partial_cmp(&other.ident) + } +} +impl Ord for Variant { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.ident.cmp(&other.ident) + } +} + +impl ToTokens for Variant { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + self.ident.to_tokens(tokens); + if let Some((t, _)) = &self.field { + tokens.extend(quote::quote! { (#t) }) + } + } +} + +impl Variant { + pub fn match_on(&self) -> proc_macro2::TokenStream { + if let Self { + ident, + field: Some((_, p)), + } = self + { + quote::quote! { #ident(#p) } + } else { + self.ident.to_token_stream() + } + } +} + +impl Display for Variant { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.match_on()) + } +} |