syn_solidity/item/
struct.rs

1use crate::{FieldList, SolIdent, Spanned, Type};
2use proc_macro2::Span;
3use std::{
4    fmt,
5    hash::{Hash, Hasher},
6};
7use syn::{
8    Attribute, Result, Token, braced,
9    parse::{Parse, ParseStream},
10    token::Brace,
11};
12
13/// A struct definition: `struct Foo { uint256 bar; }`.
14///
15/// Solidity reference:
16/// <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.structDefinition>
17#[derive(Clone)]
18pub struct ItemStruct {
19    pub attrs: Vec<Attribute>,
20    pub struct_token: Token![struct],
21    pub name: SolIdent,
22    pub brace_token: Brace,
23    pub fields: FieldList,
24}
25
26impl PartialEq for ItemStruct {
27    fn eq(&self, other: &Self) -> bool {
28        self.name == other.name && self.fields == other.fields
29    }
30}
31
32impl Eq for ItemStruct {}
33
34impl Hash for ItemStruct {
35    fn hash<H: Hasher>(&self, state: &mut H) {
36        self.name.hash(state);
37        self.fields.hash(state);
38    }
39}
40
41impl fmt::Display for ItemStruct {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        write!(f, "struct {} {{ {} }}", self.name, self.fields)
44    }
45}
46
47impl fmt::Debug for ItemStruct {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        f.debug_struct("ItemStruct")
50            .field("attrs", &self.attrs)
51            .field("name", &self.name)
52            .field("fields", &self.fields)
53            .finish()
54    }
55}
56
57impl Parse for ItemStruct {
58    fn parse(input: ParseStream<'_>) -> Result<Self> {
59        let content;
60        Ok(Self {
61            attrs: input.call(Attribute::parse_outer)?,
62            struct_token: input.parse()?,
63            name: input.parse()?,
64            brace_token: braced!(content in input),
65            fields: content.parse()?,
66        })
67    }
68}
69
70impl Spanned for ItemStruct {
71    fn span(&self) -> Span {
72        self.name.span()
73    }
74
75    fn set_span(&mut self, span: Span) {
76        self.struct_token = Token![struct](span);
77        self.name.set_span(span);
78        self.brace_token = Brace(span);
79    }
80}
81
82impl ItemStruct {
83    pub fn as_type(&self) -> Type {
84        let mut ty = Type::Tuple(self.fields.types().cloned().collect());
85        ty.set_span(self.span());
86        ty
87    }
88}