syn_solidity/type/
function.rs

1use crate::{kw, FunctionAttributes, ParameterList, Returns, Spanned};
2use proc_macro2::Span;
3use std::{
4    fmt,
5    hash::{Hash, Hasher},
6};
7use syn::{
8    parenthesized,
9    parse::{Parse, ParseStream},
10    token::Paren,
11    Result,
12};
13
14/// A function type: `function() returns (string memory)`.
15///
16/// Solidity reference:
17/// <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.functionTypeName>
18#[derive(Clone)]
19pub struct TypeFunction {
20    pub function_token: kw::function,
21    pub paren_token: Paren,
22    pub arguments: ParameterList,
23    /// The Solidity attributes of the function.
24    pub attributes: FunctionAttributes,
25    /// The optional return types of the function.
26    pub returns: Option<Returns>,
27}
28
29impl PartialEq for TypeFunction {
30    fn eq(&self, other: &Self) -> bool {
31        self.arguments == other.arguments && self.returns == other.returns
32    }
33}
34
35impl Eq for TypeFunction {}
36
37impl Hash for TypeFunction {
38    fn hash<H: Hasher>(&self, state: &mut H) {
39        self.arguments.hash(state);
40        self.returns.hash(state);
41    }
42}
43
44impl fmt::Display for TypeFunction {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        f.write_str("function (")?;
47        self.arguments.fmt(f)?;
48        f.write_str(")")?;
49
50        for attr in &self.attributes.0 {
51            write!(f, " {attr}")?;
52        }
53
54        if let Some(returns) = &self.returns {
55            write!(f, " {returns}")?;
56        }
57
58        Ok(())
59    }
60}
61
62impl fmt::Debug for TypeFunction {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        f.debug_struct("TypeFunction")
65            .field("arguments", &self.arguments)
66            .field("attributes", &self.attributes)
67            .field("returns", &self.returns)
68            .finish()
69    }
70}
71
72impl Parse for TypeFunction {
73    fn parse(input: ParseStream<'_>) -> Result<Self> {
74        let content;
75        Ok(Self {
76            function_token: input.parse()?,
77            paren_token: parenthesized!(content in input),
78            arguments: content.parse()?,
79            attributes: input.parse()?,
80            returns: input.call(Returns::parse_opt)?,
81        })
82    }
83}
84
85impl Spanned for TypeFunction {
86    fn span(&self) -> Span {
87        self.function_token.span
88    }
89
90    fn set_span(&mut self, span: Span) {
91        self.function_token.span = span;
92    }
93}