syn_solidity/item/
enum.rs

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