syn_solidity/type/
mapping.rs

1use crate::{SolIdent, Spanned, Type, VariableDeclaration, kw};
2use proc_macro2::Span;
3use std::{
4    fmt,
5    hash::{Hash, Hasher},
6};
7use syn::{
8    Result, Token, parenthesized,
9    parse::{Parse, ParseStream},
10    token::Paren,
11};
12
13/// A mapping type: `mapping(uint key => string value)`
14#[derive(Clone)]
15pub struct TypeMapping {
16    pub mapping_token: kw::mapping,
17    pub paren_token: Paren,
18    pub key: Box<Type>,
19    pub key_name: Option<SolIdent>,
20    pub fat_arrow_token: Token![=>],
21    pub value: Box<Type>,
22    pub value_name: Option<SolIdent>,
23}
24
25impl PartialEq for TypeMapping {
26    fn eq(&self, other: &Self) -> bool {
27        self.key == other.key && self.value == other.value
28    }
29}
30
31impl Eq for TypeMapping {}
32
33impl Hash for TypeMapping {
34    fn hash<H: Hasher>(&self, state: &mut H) {
35        self.key.hash(state);
36        self.value.hash(state);
37    }
38}
39
40impl fmt::Display for TypeMapping {
41    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42        write!(f, "mapping({} ", self.key)?;
43        if let Some(key_name) = &self.key_name {
44            write!(f, "{key_name} ")?;
45        }
46        write!(f, "=> {} ", self.value)?;
47        if let Some(value_name) = &self.value_name {
48            write!(f, "{value_name}")?;
49        }
50        f.write_str(")")
51    }
52}
53
54impl fmt::Debug for TypeMapping {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        f.debug_struct("TypeMapping")
57            .field("key", &self.key)
58            .field("key_name", &self.key_name)
59            .field("value", &self.value)
60            .field("value_name", &self.value_name)
61            .finish()
62    }
63}
64
65impl Parse for TypeMapping {
66    fn parse(input: ParseStream<'_>) -> Result<Self> {
67        let content;
68        Ok(Self {
69            mapping_token: input.parse()?,
70            paren_token: parenthesized!(content in input),
71            key: content.parse()?,
72            key_name: content.call(SolIdent::parse_opt)?,
73            fat_arrow_token: content.parse()?,
74            value: content.parse()?,
75            value_name: content.call(SolIdent::parse_opt)?,
76        })
77    }
78}
79
80impl Spanned for TypeMapping {
81    fn span(&self) -> Span {
82        let span = self.mapping_token.span;
83        span.join(self.paren_token.span.join()).unwrap_or(span)
84    }
85
86    fn set_span(&mut self, span: Span) {
87        self.mapping_token.span = span;
88        self.paren_token = Paren(span);
89        self.key.set_span(span);
90        if let Some(key_name) = &mut self.key_name {
91            key_name.set_span(span);
92        }
93        self.value.set_span(span);
94        if let Some(value_name) = &mut self.value_name {
95            value_name.set_span(span);
96        }
97    }
98}
99
100impl TypeMapping {
101    /// Returns a `VariableDeclaration` corresponding to this mapping's key.
102    pub fn key_var(&self) -> VariableDeclaration {
103        VariableDeclaration::new_with((*self.key).clone(), None, self.key_name.clone())
104    }
105
106    /// Returns a `VariableDeclaration` corresponding to this mapping's value.
107    pub fn value_var(&self) -> VariableDeclaration {
108        VariableDeclaration::new_with((*self.value).clone(), None, self.value_name.clone())
109    }
110}