syn_solidity/type/
function.rs

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