syn_solidity/item/
enum.rs

1use crate::{SolIdent, Spanned, Type, utils::DebugPunctuated};
2use proc_macro2::{Span, TokenStream};
3use quote::ToTokens;
4use std::{fmt, num::NonZeroU16};
5use syn::{
6    Attribute, Result, Token, braced,
7    parse::{Parse, ParseStream},
8    punctuated::Punctuated,
9    token::Brace,
10};
11
12/// An enum definition: `enum Foo { A, B, C }`.
13///
14/// Solidity reference:
15/// <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.enumDefinition>
16#[derive(Clone)]
17pub struct ItemEnum {
18    pub attrs: Vec<Attribute>,
19    pub enum_token: Token![enum],
20    pub name: SolIdent,
21    pub brace_token: Brace,
22    pub variants: Punctuated<Variant, Token![,]>,
23}
24
25impl fmt::Display for ItemEnum {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        write!(f, "enum {} {{ ", self.name)?;
28        for (i, variant) in self.variants.iter().enumerate() {
29            if i > 0 {
30                f.write_str(", ")?;
31            }
32            variant.fmt(f)?;
33        }
34        f.write_str(" }")
35    }
36}
37
38impl fmt::Debug for ItemEnum {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        f.debug_struct("ItemEnum")
41            .field("attrs", &self.attrs)
42            .field("name", &self.name)
43            .field("variants", DebugPunctuated::new(&self.variants))
44            .finish()
45    }
46}
47
48impl Parse for ItemEnum {
49    fn parse(input: ParseStream<'_>) -> Result<Self> {
50        let content;
51        Ok(Self {
52            attrs: input.call(Attribute::parse_outer)?,
53            enum_token: input.parse()?,
54            name: input.parse()?,
55            brace_token: braced!(content in input),
56            variants: content.parse_terminated(Variant::parse, Token![,])?,
57        })
58    }
59}
60
61impl Spanned for ItemEnum {
62    fn span(&self) -> Span {
63        self.name.span()
64    }
65
66    fn set_span(&mut self, span: Span) {
67        self.name.set_span(span);
68    }
69}
70
71impl ItemEnum {
72    pub fn as_type(&self) -> Type {
73        Type::Uint(self.span(), Some(NonZeroU16::new(8).unwrap()))
74    }
75}
76
77/// An enum variant.
78#[derive(Clone, Debug)]
79pub struct Variant {
80    pub attrs: Vec<Attribute>,
81
82    /// Name of the variant.
83    pub ident: SolIdent,
84}
85
86impl fmt::Display for Variant {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        self.ident.fmt(f)
89    }
90}
91
92impl Parse for Variant {
93    fn parse(input: ParseStream<'_>) -> Result<Self> {
94        Ok(Self { attrs: input.call(Attribute::parse_outer)?, ident: input.parse()? })
95    }
96}
97
98impl ToTokens for Variant {
99    fn to_tokens(&self, tokens: &mut TokenStream) {
100        for attr in &self.attrs {
101            attr.to_tokens(tokens);
102        }
103        self.ident.to_tokens(tokens);
104    }
105}
106
107impl Spanned for Variant {
108    fn span(&self) -> Span {
109        self.ident.span()
110    }
111
112    fn set_span(&mut self, span: Span) {
113        self.ident.set_span(span);
114    }
115}