syn_solidity/type/
array.rs1use crate::{Expr, Lit, LitNumber, Spanned, Type};
2use proc_macro2::Span;
3use std::{
4 fmt,
5 hash::{Hash, Hasher},
6};
7use syn::{
8 bracketed,
9 parse::{Parse, ParseStream},
10 token::Bracket,
11 Result,
12};
13
14#[derive(Clone)]
16pub struct TypeArray {
17 pub ty: Box<Type>,
18 pub bracket_token: Bracket,
19 pub size: Option<Box<Expr>>,
20}
21
22impl PartialEq for TypeArray {
23 fn eq(&self, other: &Self) -> bool {
24 self.ty == other.ty && self.size() == other.size()
25 }
26}
27
28impl Eq for TypeArray {}
29
30impl Hash for TypeArray {
31 fn hash<H: Hasher>(&self, state: &mut H) {
32 self.ty.hash(state);
33 self.size().hash(state);
34 }
35}
36
37impl fmt::Display for TypeArray {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 self.ty.fmt(f)?;
40 f.write_str("[")?;
41 if let Some(s) = self.size_lit() {
42 f.write_str(s.base10_digits())?;
43 }
44 f.write_str("]")
45 }
46}
47
48impl fmt::Debug for TypeArray {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 f.debug_tuple("TypeArray").field(&self.ty).field(&self.size()).finish()
51 }
52}
53
54impl Parse for TypeArray {
55 fn parse(input: ParseStream<'_>) -> Result<Self> {
56 let ty = input.parse()?;
57 Self::parse_nested(Box::new(ty), input)
58 }
59}
60
61impl Spanned for TypeArray {
62 fn span(&self) -> Span {
63 let span = self.ty.span();
64 span.join(self.bracket_token.span.join()).unwrap_or(span)
65 }
66
67 fn set_span(&mut self, span: Span) {
68 self.ty.set_span(span);
69 self.bracket_token = Bracket(span);
70 if let Some(size) = &mut self.size {
71 size.set_span(span);
72 }
73 }
74}
75
76impl TypeArray {
77 pub fn size(&self) -> Option<usize> {
79 self.size_lit().and_then(|s| s.base10_parse().ok())
80 }
81
82 pub fn size_lit(&self) -> Option<&LitNumber> {
84 self.size.as_ref().and_then(|s| match &**s {
85 Expr::Lit(Lit::Number(n)) => Some(n),
86 _ => None,
87 })
88 }
89
90 pub fn is_abi_dynamic(&self) -> bool {
92 match self.size {
93 Some(_) => self.ty.is_abi_dynamic(),
94 None => true,
95 }
96 }
97
98 pub fn parse_nested(ty: Box<Type>, input: ParseStream<'_>) -> Result<Self> {
100 let content;
101 Ok(Self {
102 ty,
103 bracket_token: bracketed!(content in input),
104 size: {
105 if content.is_empty() {
106 None
107 } else {
108 Some(content.parse()?)
109 }
110 },
111 })
112 }
113}