syn_solidity/type/
mapping.rsuse crate::{kw, SolIdent, Spanned, Type, VariableDeclaration};
use proc_macro2::Span;
use std::{
fmt,
hash::{Hash, Hasher},
};
use syn::{
parenthesized,
parse::{Parse, ParseStream},
token::Paren,
Result, Token,
};
#[derive(Clone)]
pub struct TypeMapping {
pub mapping_token: kw::mapping,
pub paren_token: Paren,
pub key: Box<Type>,
pub key_name: Option<SolIdent>,
pub fat_arrow_token: Token![=>],
pub value: Box<Type>,
pub value_name: Option<SolIdent>,
}
impl PartialEq for TypeMapping {
fn eq(&self, other: &Self) -> bool {
self.key == other.key && self.value == other.value
}
}
impl Eq for TypeMapping {}
impl Hash for TypeMapping {
fn hash<H: Hasher>(&self, state: &mut H) {
self.key.hash(state);
self.value.hash(state);
}
}
impl fmt::Display for TypeMapping {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "mapping({} ", self.key)?;
if let Some(key_name) = &self.key_name {
write!(f, "{key_name} ")?;
}
write!(f, "=> {} ", self.value)?;
if let Some(value_name) = &self.value_name {
write!(f, "{value_name}")?;
}
f.write_str(")")
}
}
impl fmt::Debug for TypeMapping {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TypeMapping")
.field("key", &self.key)
.field("key_name", &self.key_name)
.field("value", &self.value)
.field("value_name", &self.value_name)
.finish()
}
}
impl Parse for TypeMapping {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let content;
Ok(Self {
mapping_token: input.parse()?,
paren_token: parenthesized!(content in input),
key: content.parse()?,
key_name: content.call(SolIdent::parse_opt)?,
fat_arrow_token: content.parse()?,
value: content.parse()?,
value_name: content.call(SolIdent::parse_opt)?,
})
}
}
impl Spanned for TypeMapping {
fn span(&self) -> Span {
let span = self.mapping_token.span;
span.join(self.paren_token.span.join()).unwrap_or(span)
}
fn set_span(&mut self, span: Span) {
self.mapping_token.span = span;
self.paren_token = Paren(span);
self.key.set_span(span);
if let Some(key_name) = &mut self.key_name {
key_name.set_span(span);
}
self.value.set_span(span);
if let Some(value_name) = &mut self.value_name {
value_name.set_span(span);
}
}
}
impl TypeMapping {
pub fn key_var(&self) -> VariableDeclaration {
VariableDeclaration::new_with((*self.key).clone(), None, self.key_name.clone())
}
pub fn value_var(&self) -> VariableDeclaration {
VariableDeclaration::new_with((*self.value).clone(), None, self.value_name.clone())
}
}