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