syn_solidity/type/
mapping.rs

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