ethers_core/abi/human_readable/
lexer.rs

1use ethabi::{
2    AbiError, Constructor, Event, EventParam, Function, Param, ParamType, StateMutability,
3};
4use std::{fmt, iter::Peekable, str::CharIndices};
5use unicode_xid::UnicodeXID;
6
7pub type Spanned<Token, Loc, Error> = Result<(Loc, Token, Loc), Error>;
8
9macro_rules! unrecognised {
10    ($l:ident,$r:ident,$t:expr) => {
11        return Err(LexerError::UnrecognisedToken($l, $r, $t))
12    };
13}
14
15#[derive(Copy, Clone, PartialEq, Eq, Debug)]
16pub enum Token<'input> {
17    Identifier(&'input str),
18    Number(&'input str),
19    HexNumber(&'input str),
20    // Punctuation
21    OpenParenthesis,
22    CloseParenthesis,
23    Comma,
24    OpenBracket,
25    CloseBracket,
26    Semicolon,
27    Point,
28
29    Struct,
30    Event,
31    Error,
32    Enum,
33    Function,
34    Tuple,
35
36    Memory,
37    Storage,
38    Calldata,
39
40    Public,
41    Private,
42    Internal,
43    External,
44
45    Constant,
46
47    Type,
48    Pure,
49    View,
50    Payable,
51    Returns,
52    Anonymous,
53    Receive,
54    Fallback,
55    Abstract,
56    Virtual,
57    Override,
58
59    Constructor,
60    Indexed,
61
62    Uint(usize),
63    Int(usize),
64    Bytes(usize),
65    // prior to 0.8.0 `byte` used to be an alias for `bytes1`
66    Byte,
67    DynamicBytes,
68    Bool,
69    Address,
70    String,
71}
72
73// === impl Token ===
74
75impl<'input> Token<'input> {
76    fn into_param_type(self) -> Option<ParamType> {
77        let param = match self {
78            Token::Uint(size) => ParamType::Uint(size),
79            Token::Int(size) => ParamType::Int(size),
80            Token::Bytes(size) => ParamType::FixedBytes(size),
81            Token::Byte => ParamType::FixedBytes(1),
82            Token::DynamicBytes => ParamType::Bytes,
83            Token::Bool => ParamType::Bool,
84            Token::Address => ParamType::Address,
85            Token::String => ParamType::String,
86            Token::Tuple => ParamType::Tuple(vec![]),
87            _ => return None,
88        };
89
90        Some(param)
91    }
92}
93
94impl<'input> fmt::Display for Token<'input> {
95    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96        match self {
97            Token::Identifier(id) => write!(f, "{id}"),
98            Token::Number(num) => write!(f, "{num}"),
99            Token::HexNumber(num) => write!(f, "0x{num}"),
100            Token::Uint(w) => write!(f, "uint{w}"),
101            Token::Int(w) => write!(f, "int{w}"),
102            Token::Bytes(w) => write!(f, "bytes{w}"),
103            Token::Byte => write!(f, "byte"),
104            Token::DynamicBytes => write!(f, "bytes"),
105            Token::Semicolon => write!(f, ";"),
106            Token::Comma => write!(f, ","),
107            Token::OpenParenthesis => write!(f, "("),
108            Token::CloseParenthesis => write!(f, ")"),
109            Token::OpenBracket => write!(f, "["),
110            Token::CloseBracket => write!(f, "]"),
111            Token::Point => write!(f, "."),
112            Token::Tuple => write!(f, "tuple"),
113            Token::Bool => write!(f, "bool"),
114            Token::Address => write!(f, "address"),
115            Token::String => write!(f, "string"),
116            Token::Function => write!(f, "function"),
117            Token::Struct => write!(f, "struct"),
118            Token::Event => write!(f, "event"),
119            Token::Error => write!(f, "error"),
120            Token::Enum => write!(f, "enum"),
121            Token::Type => write!(f, "type"),
122            Token::Memory => write!(f, "memory"),
123            Token::Storage => write!(f, "storage"),
124            Token::Calldata => write!(f, "calldata"),
125            Token::Public => write!(f, "public"),
126            Token::Private => write!(f, "private"),
127            Token::Internal => write!(f, "internal"),
128            Token::External => write!(f, "external"),
129            Token::Constant => write!(f, "constant"),
130            Token::Pure => write!(f, "pure"),
131            Token::View => write!(f, "view"),
132            Token::Payable => write!(f, "payable"),
133            Token::Returns => write!(f, "returns"),
134            Token::Anonymous => write!(f, "anonymous"),
135            Token::Constructor => write!(f, "constructor"),
136            Token::Indexed => write!(f, "indexed"),
137            Token::Receive => write!(f, "receive"),
138            Token::Fallback => write!(f, "fallback"),
139            Token::Abstract => write!(f, "abstract"),
140            Token::Virtual => write!(f, "virtual"),
141            Token::Override => write!(f, "override"),
142        }
143    }
144}
145
146#[derive(Debug, PartialEq, Eq, Clone, thiserror::Error)]
147pub enum LexerError {
148    #[error("UnrecognisedToken {0}:{1} `{2}`")]
149    UnrecognisedToken(usize, usize, String),
150    #[error("Expected token `{2}` at {0}:{1} ")]
151    ExpectedToken(usize, usize, String),
152    #[error("EndofFileInHex {0}:{1}")]
153    EndofFileInHex(usize, usize),
154    #[error("MissingNumber {0}:{1}")]
155    MissingNumber(usize, usize),
156    #[error("end of file but expected `{0}`")]
157    EndOfFileExpectedToken(String),
158    #[error("end of file")]
159    EndOfFile,
160}
161
162#[derive(Clone, Debug)]
163pub(crate) struct HumanReadableLexer<'input> {
164    input: &'input str,
165    chars: Peekable<CharIndices<'input>>,
166}
167
168// === impl HumanReadableLexer ===
169
170impl<'input> HumanReadableLexer<'input> {
171    /// Creates a new instance of the lexer
172    pub fn new(input: &'input str) -> Self {
173        Self { chars: input.char_indices().peekable(), input }
174    }
175
176    fn next_token(&mut self) -> Option<Spanned<Token<'input>, usize, LexerError>> {
177        loop {
178            match self.chars.next() {
179                Some((start, ch)) if UnicodeXID::is_xid_start(ch) || ch == '_' => {
180                    let end;
181                    loop {
182                        if let Some((i, ch)) = self.chars.peek() {
183                            if !UnicodeXID::is_xid_continue(*ch) && *ch != '$' {
184                                end = *i;
185                                break
186                            }
187                            self.chars.next();
188                        } else {
189                            end = self.input.len();
190                            break
191                        }
192                    }
193                    let id = &self.input[start..end];
194
195                    return if let Some(w) = keyword(id) {
196                        Some(Ok((start, w, end)))
197                    } else {
198                        Some(Ok((start, Token::Identifier(id), end)))
199                    }
200                }
201                Some((start, ch)) if ch.is_ascii_digit() => {
202                    let mut end = start + 1;
203                    if ch == '0' {
204                        if let Some((_, 'x')) = self.chars.peek() {
205                            // hex number
206                            self.chars.next();
207
208                            let mut end = match self.chars.next() {
209                                Some((end, ch)) if ch.is_ascii_hexdigit() => end,
210                                Some((_, _)) => {
211                                    return Some(Err(LexerError::MissingNumber(start, start + 1)))
212                                }
213                                None => {
214                                    return Some(Err(LexerError::EndofFileInHex(
215                                        start,
216                                        self.input.len(),
217                                    )))
218                                }
219                            };
220
221                            while let Some((i, ch)) = self.chars.peek() {
222                                if !ch.is_ascii_hexdigit() && *ch != '_' {
223                                    break
224                                }
225                                end = *i;
226                                self.chars.next();
227                            }
228
229                            return Some(Ok((
230                                start,
231                                Token::HexNumber(&self.input[start..=end]),
232                                end + 1,
233                            )))
234                        }
235                    }
236
237                    loop {
238                        if let Some((i, ch)) = self.chars.peek().cloned() {
239                            if !ch.is_ascii_digit() {
240                                break
241                            }
242                            self.chars.next();
243                            end = i + 1;
244                        } else {
245                            end = self.input.len();
246                            break
247                        }
248                    }
249                    return Some(Ok((start, Token::Number(&self.input[start..end]), end + 1)))
250                }
251                Some((i, '(')) => return Some(Ok((i, Token::OpenParenthesis, i + 1))),
252                Some((i, ')')) => return Some(Ok((i, Token::CloseParenthesis, i + 1))),
253                Some((i, ';')) => return Some(Ok((i, Token::Semicolon, i + 1))),
254                Some((i, ',')) => return Some(Ok((i, Token::Comma, i + 1))),
255                Some((i, '.')) => return Some(Ok((i, Token::Point, i + 1))),
256                Some((i, '[')) => return Some(Ok((i, Token::OpenBracket, i + 1))),
257                Some((i, ']')) => return Some(Ok((i, Token::CloseBracket, i + 1))),
258                Some((_, ch)) if ch.is_whitespace() => (),
259                Some((start, _)) => {
260                    let mut end;
261                    loop {
262                        if let Some((i, ch)) = self.chars.next() {
263                            end = i;
264                            if ch.is_whitespace() {
265                                break
266                            }
267                        } else {
268                            end = self.input.len();
269                            break
270                        }
271                    }
272
273                    return Some(Err(LexerError::UnrecognisedToken(
274                        start,
275                        end,
276                        self.input[start..end].to_owned(),
277                    )))
278                }
279                None => return None,
280            }
281        }
282    }
283}
284
285impl<'input> Iterator for HumanReadableLexer<'input> {
286    type Item = Spanned<Token<'input>, usize, LexerError>;
287
288    /// Return the next token
289    fn next(&mut self) -> Option<Self::Item> {
290        self.next_token()
291    }
292}
293
294#[derive(Clone, Debug)]
295pub struct HumanReadableParser<'input> {
296    lexer: Peekable<HumanReadableLexer<'input>>,
297}
298
299// === impl HumanReadableParser ===
300
301impl<'input> HumanReadableParser<'input> {
302    /// Creates a new instance of the lexer
303    pub fn new(input: &'input str) -> Self {
304        let lexer = HumanReadableLexer::new(input);
305        Self { lexer: lexer.peekable() }
306    }
307
308    /// Parses the input into a [ParamType]
309    pub fn parse_type(input: &'input str) -> Result<ParamType, LexerError> {
310        Self::new(input).take_param()
311    }
312
313    /// Parses a [Function] from a human readable form
314    ///
315    /// # Example
316    ///
317    /// ```
318    /// use ethers_core::abi::HumanReadableParser;
319    /// let mut fun = HumanReadableParser::parse_function("function get(address author, string oldValue, string newValue)").unwrap();
320    /// ```
321    pub fn parse_function(input: &'input str) -> Result<Function, LexerError> {
322        Self::new(input).take_function()
323    }
324
325    /// Parses a [Function] from a human readable form
326    ///
327    /// # Example
328    ///
329    /// ```
330    /// use ethers_core::abi::HumanReadableParser;
331    /// let err = HumanReadableParser::parse_error("error MyError(address author, string oldValue, string newValue)").unwrap();
332    /// ```
333    pub fn parse_error(input: &'input str) -> Result<AbiError, LexerError> {
334        Self::new(input).take_error()
335    }
336
337    /// Parses a [Constructor] from a human readable form
338    ///
339    /// # Example
340    ///
341    /// ```
342    /// use ethers_core::abi::HumanReadableParser;
343    /// let mut constructor = HumanReadableParser::parse_constructor("constructor(address author, string oldValue, string newValue)").unwrap();
344    /// ```
345    pub fn parse_constructor(input: &'input str) -> Result<Constructor, LexerError> {
346        Self::new(input).take_constructor()
347    }
348
349    /// Parses an [Event] from a human readable form
350    ///
351    /// # Example
352    ///
353    /// ```
354    /// use ethers_core::abi::HumanReadableParser;
355    /// let mut event = HumanReadableParser::parse_event("event ValueChanged(address indexed author, string oldValue, string newValue)").unwrap();
356    /// ```
357    pub fn parse_event(input: &'input str) -> Result<Event, LexerError> {
358        Self::new(input).take_event()
359    }
360
361    /// Returns the next `Error` and consumes the underlying tokens
362    pub fn take_error(&mut self) -> Result<AbiError, LexerError> {
363        let name = self.take_identifier(Token::Error)?;
364        self.take_open_parenthesis()?;
365        let inputs = self.take_function_params()?;
366        self.take_close_parenthesis()?;
367        Ok(AbiError { name: name.to_string(), inputs })
368    }
369
370    /// Returns the next `Constructor` and consumes the underlying tokens
371    pub fn take_constructor(&mut self) -> Result<Constructor, LexerError> {
372        self.take_next_exact(Token::Constructor)?;
373        self.take_open_parenthesis()?;
374        let inputs = self.take_function_params()?;
375        self.take_close_parenthesis()?;
376        Ok(Constructor { inputs })
377    }
378
379    /// Returns the next `Function` and consumes the underlying tokens
380    pub fn take_function(&mut self) -> Result<Function, LexerError> {
381        let name = self.take_identifier(Token::Function)?;
382
383        self.take_open_parenthesis()?;
384        let inputs = self.take_function_params()?;
385        self.take_close_parenthesis()?;
386
387        let mut state_mutability = Default::default();
388        let mut outputs = vec![];
389        if self.peek().is_some() {
390            let _visibility = self.take_visibility();
391            if let Some(mutability) = self.take_state_mutability() {
392                state_mutability = mutability;
393            }
394            if self.peek_next(Token::Virtual) {
395                self.next();
396            }
397            if self.peek_next(Token::Override) {
398                self.next();
399            }
400            if self.peek_next(Token::Returns) {
401                self.next();
402            }
403
404            if self.peek_next(Token::OpenParenthesis) {
405                self.take_open_parenthesis()?;
406                outputs = self.take_function_params()?;
407                self.take_close_parenthesis()?;
408            }
409        }
410
411        Ok(
412            #[allow(deprecated)]
413            Function { name: name.to_string(), inputs, outputs, constant: None, state_mutability },
414        )
415    }
416
417    pub fn take_event(&mut self) -> Result<Event, LexerError> {
418        let name = self.take_identifier(Token::Event)?;
419        self.take_open_parenthesis()?;
420        let inputs = self.take_event_params()?;
421        self.take_close_parenthesis()?;
422        let event = Event { name: name.to_string(), inputs, anonymous: self.take_anonymous() };
423
424        Ok(event)
425    }
426
427    /// Returns an identifier, optionally prefixed with a token like `function? <name>`
428    fn take_identifier(&mut self, prefixed: Token) -> Result<&'input str, LexerError> {
429        let (l, token, r) = self.next_spanned()?;
430        let name = match token {
431            i if i == prefixed => {
432                let (_, next, _) = self.lexer.peek().cloned().ok_or(LexerError::EndOfFile)??;
433                if let Token::Identifier(name) = next {
434                    self.next();
435                    name
436                } else {
437                    ""
438                }
439            }
440            Token::Identifier(name) => name,
441            t => unrecognised!(l, r, t.to_string()),
442        };
443        Ok(name)
444    }
445
446    fn take_name_opt(&mut self) -> Result<Option<&'input str>, LexerError> {
447        if let (_, Token::Identifier(name), _) = self.peek_some()? {
448            self.next();
449            Ok(Some(name))
450        } else {
451            Ok(None)
452        }
453    }
454
455    fn take_visibility(&mut self) -> Option<Visibility> {
456        match self.lexer.peek() {
457            Some(Ok((_, Token::Internal, _))) => {
458                self.next();
459                Some(Visibility::Internal)
460            }
461            Some(Ok((_, Token::External, _))) => {
462                self.next();
463                Some(Visibility::External)
464            }
465            Some(Ok((_, Token::Private, _))) => {
466                self.next();
467                Some(Visibility::Private)
468            }
469            Some(Ok((_, Token::Public, _))) => {
470                self.next();
471                Some(Visibility::Public)
472            }
473            _ => None,
474        }
475    }
476
477    fn take_state_mutability(&mut self) -> Option<StateMutability> {
478        match self.lexer.peek() {
479            Some(Ok((_, Token::View, _))) => {
480                self.next();
481                Some(StateMutability::View)
482            }
483            Some(Ok((_, Token::Pure, _))) => {
484                self.next();
485                Some(StateMutability::Pure)
486            }
487            Some(Ok((_, Token::Payable, _))) => {
488                self.next();
489                Some(StateMutability::Payable)
490            }
491            _ => None,
492        }
493    }
494
495    fn take_data_location(&mut self) -> Option<DataLocation> {
496        match self.lexer.peek() {
497            Some(Ok((_, Token::Memory, _))) => {
498                self.next();
499                Some(DataLocation::Memory)
500            }
501            Some(Ok((_, Token::Storage, _))) => {
502                self.next();
503                Some(DataLocation::Storage)
504            }
505            Some(Ok((_, Token::Calldata, _))) => {
506                self.next();
507                Some(DataLocation::Calldata)
508            }
509            _ => None,
510        }
511    }
512
513    fn take_anonymous(&mut self) -> bool {
514        if self.peek_next(Token::Anonymous) {
515            self.next();
516            true
517        } else {
518            false
519        }
520    }
521
522    /// Takes comma separated values via `f` until the `token` is parsed
523    fn take_csv_until<T, F>(&mut self, token: Token, f: F) -> Result<Vec<T>, LexerError>
524    where
525        F: Fn(&mut Self) -> Result<T, LexerError>,
526    {
527        let mut params = Vec::new();
528
529        if self.peek_next(token) {
530            return Ok(params)
531        }
532
533        loop {
534            params.push(f(self)?);
535
536            let (l, next, r) = match self.peek() {
537                Some(next) => next?,
538                _ => break,
539            };
540
541            match next {
542                i if i == token => break,
543                Token::Comma => {
544                    self.next_spanned()?;
545                }
546                t => unrecognised!(l, r, t.to_string()),
547            }
548        }
549        Ok(params)
550    }
551
552    /// Parses all function input params
553    fn take_function_params(&mut self) -> Result<Vec<Param>, LexerError> {
554        self.take_csv_until(Token::CloseParenthesis, |s| s.take_input_param())
555    }
556
557    fn take_input_param(&mut self) -> Result<Param, LexerError> {
558        let kind = self.take_param()?;
559        let _location = self.take_data_location();
560        let name = self.take_name_opt()?.unwrap_or("");
561        Ok(Param { name: name.to_string(), kind, internal_type: None })
562    }
563
564    /// Parses all event params
565    fn take_event_params(&mut self) -> Result<Vec<EventParam>, LexerError> {
566        self.take_csv_until(Token::CloseParenthesis, |s| s.take_event_param())
567    }
568
569    fn take_event_param(&mut self) -> Result<EventParam, LexerError> {
570        let kind = self.take_param()?;
571        let mut name = "";
572        let mut indexed = false;
573
574        loop {
575            let (_, token, _) = self.peek_some()?;
576            match token {
577                Token::Indexed => {
578                    indexed = true;
579                    self.next();
580                }
581                Token::Identifier(id) => {
582                    name = id;
583                    self.next();
584                    break
585                }
586                _ => break,
587            };
588        }
589        Ok(EventParam { name: name.to_string(), kind, indexed })
590    }
591
592    /// Parses a list of parameter types
593    fn take_params(&mut self) -> Result<Vec<ParamType>, LexerError> {
594        let mut params = Vec::new();
595
596        if self.peek_next(Token::CloseParenthesis) {
597            return Ok(params)
598        }
599        loop {
600            params.push(self.take_param()?);
601
602            let (l, next, r) = match self.peek() {
603                Some(next) => next?,
604                _ => break,
605            };
606            match next {
607                Token::Comma => {
608                    self.next_spanned()?;
609                }
610                Token::CloseParenthesis => break,
611                t => unrecognised!(l, r, t.to_string()),
612            }
613        }
614
615        Ok(params)
616    }
617
618    fn take_param(&mut self) -> Result<ParamType, LexerError> {
619        let (l, token, r) = self.next_spanned()?;
620        let kind = match token {
621            Token::OpenParenthesis => {
622                let ty = self.take_params()?;
623                self.take_next_exact(Token::CloseParenthesis)?;
624                ParamType::Tuple(ty)
625            }
626            t => t
627                .into_param_type()
628                .ok_or_else(|| LexerError::UnrecognisedToken(l, r, t.to_string()))?,
629        };
630        self.take_array_tail(kind)
631    }
632
633    fn take_array_tail(&mut self, kind: ParamType) -> Result<ParamType, LexerError> {
634        let (_, token, _) = match self.peek() {
635            Some(next) => next?,
636            _ => return Ok(kind),
637        };
638
639        match token {
640            Token::OpenBracket => {
641                self.next_spanned()?;
642                let (_, token, _) = self.peek_some()?;
643                let kind = if let Token::Number(size) = token {
644                    self.next_spanned()?;
645                    ParamType::FixedArray(Box::new(kind), size.parse().unwrap())
646                } else {
647                    ParamType::Array(Box::new(kind))
648                };
649                self.take_next_exact(Token::CloseBracket)?;
650                self.take_array_tail(kind)
651            }
652            _ => Ok(kind),
653        }
654    }
655
656    fn take_open_parenthesis(&mut self) -> Result<(), LexerError> {
657        self.take_next_exact(Token::OpenParenthesis)
658    }
659
660    fn take_close_parenthesis(&mut self) -> Result<(), LexerError> {
661        self.take_next_exact(Token::CloseParenthesis)
662    }
663
664    fn take_next_exact(&mut self, token: Token) -> Result<(), LexerError> {
665        let (l, next, r) = self.next_spanned().map_err(|err| match err {
666            LexerError::UnrecognisedToken(l, r, _) => {
667                LexerError::ExpectedToken(l, r, token.to_string())
668            }
669            LexerError::EndOfFile => LexerError::EndOfFileExpectedToken(token.to_string()),
670            err => err,
671        })?;
672        if next != token {
673            unrecognised!(l, r, next.to_string())
674        }
675        Ok(())
676    }
677
678    /// Returns true if the next token is the given `token`
679    fn peek_next(&mut self, token: Token) -> bool {
680        if let Some(Ok(next)) = self.lexer.peek() {
681            next.1 == token
682        } else {
683            false
684        }
685    }
686
687    fn next_spanned(&mut self) -> Spanned<Token<'input>, usize, LexerError> {
688        self.next().ok_or(LexerError::EndOfFile)?
689    }
690
691    fn next(&mut self) -> Option<Spanned<Token<'input>, usize, LexerError>> {
692        self.lexer.next()
693    }
694
695    fn peek(&mut self) -> Option<Spanned<Token<'input>, usize, LexerError>> {
696        self.lexer.peek().cloned()
697    }
698
699    fn peek_some(&mut self) -> Spanned<Token<'input>, usize, LexerError> {
700        self.lexer.peek().cloned().ok_or(LexerError::EndOfFile)?
701    }
702}
703
704fn keyword(id: &str) -> Option<Token> {
705    let token = match id {
706        "address" => Token::Address,
707        "anonymous" => Token::Anonymous,
708        "bool" => Token::Bool,
709        "bytes1" => Token::Bytes(1),
710        "bytes2" => Token::Bytes(2),
711        "bytes3" => Token::Bytes(3),
712        "bytes4" => Token::Bytes(4),
713        "bytes5" => Token::Bytes(5),
714        "bytes6" => Token::Bytes(6),
715        "bytes7" => Token::Bytes(7),
716        "bytes8" => Token::Bytes(8),
717        "bytes9" => Token::Bytes(9),
718        "bytes10" => Token::Bytes(10),
719        "bytes11" => Token::Bytes(11),
720        "bytes12" => Token::Bytes(12),
721        "bytes13" => Token::Bytes(13),
722        "bytes14" => Token::Bytes(14),
723        "bytes15" => Token::Bytes(15),
724        "bytes16" => Token::Bytes(16),
725        "bytes17" => Token::Bytes(17),
726        "bytes18" => Token::Bytes(18),
727        "bytes19" => Token::Bytes(19),
728        "bytes20" => Token::Bytes(20),
729        "bytes21" => Token::Bytes(21),
730        "bytes22" => Token::Bytes(22),
731        "bytes23" => Token::Bytes(23),
732        "bytes24" => Token::Bytes(24),
733        "bytes25" => Token::Bytes(25),
734        "bytes26" => Token::Bytes(26),
735        "bytes27" => Token::Bytes(27),
736        "bytes28" => Token::Bytes(28),
737        "bytes29" => Token::Bytes(29),
738        "bytes30" => Token::Bytes(30),
739        "bytes31" => Token::Bytes(31),
740        "bytes32" => Token::Bytes(32),
741        "bytes" => Token::DynamicBytes,
742        "byte" => Token::Byte,
743        "calldata" => Token::Calldata,
744        "constant" => Token::Constant,
745        "constructor" => Token::Constructor,
746        "enum" => Token::Enum,
747        "event" => Token::Event,
748        "error" => Token::Error,
749        "external" => Token::External,
750        "function" => Token::Function,
751        "indexed" => Token::Indexed,
752        "tuple" => Token::Tuple,
753        "int8" => Token::Int(8),
754        "int16" => Token::Int(16),
755        "int24" => Token::Int(24),
756        "int32" => Token::Int(32),
757        "int40" => Token::Int(40),
758        "int48" => Token::Int(48),
759        "int56" => Token::Int(56),
760        "int64" => Token::Int(64),
761        "int72" => Token::Int(72),
762        "int80" => Token::Int(80),
763        "int88" => Token::Int(88),
764        "int96" => Token::Int(96),
765        "int104" => Token::Int(104),
766        "int112" => Token::Int(112),
767        "int120" => Token::Int(120),
768        "int128" => Token::Int(128),
769        "int136" => Token::Int(136),
770        "int144" => Token::Int(144),
771        "int152" => Token::Int(152),
772        "int160" => Token::Int(160),
773        "int168" => Token::Int(168),
774        "int176" => Token::Int(176),
775        "int184" => Token::Int(184),
776        "int192" => Token::Int(192),
777        "int200" => Token::Int(200),
778        "int208" => Token::Int(208),
779        "int216" => Token::Int(216),
780        "int224" => Token::Int(224),
781        "int232" => Token::Int(232),
782        "int240" => Token::Int(240),
783        "int248" => Token::Int(248),
784        "int256" => Token::Int(256),
785        "internal" => Token::Internal,
786        "int" => Token::Int(256),
787        "memory" => Token::Memory,
788        "payable" => Token::Payable,
789        "private" => Token::Private,
790        "public" => Token::Public,
791        "pure" => Token::Pure,
792        "returns" => Token::Returns,
793        "storage" => Token::Storage,
794        "string" => Token::String,
795        "struct" => Token::Struct,
796        "type" => Token::Type,
797        "uint8" => Token::Uint(8),
798        "uint16" => Token::Uint(16),
799        "uint24" => Token::Uint(24),
800        "uint32" => Token::Uint(32),
801        "uint40" => Token::Uint(40),
802        "uint48" => Token::Uint(48),
803        "uint56" => Token::Uint(56),
804        "uint64" => Token::Uint(64),
805        "uint72" => Token::Uint(72),
806        "uint80" => Token::Uint(80),
807        "uint88" => Token::Uint(88),
808        "uint96" => Token::Uint(96),
809        "uint104" => Token::Uint(104),
810        "uint112" => Token::Uint(112),
811        "uint120" => Token::Uint(120),
812        "uint128" => Token::Uint(128),
813        "uint136" => Token::Uint(136),
814        "uint144" => Token::Uint(144),
815        "uint152" => Token::Uint(152),
816        "uint160" => Token::Uint(160),
817        "uint168" => Token::Uint(168),
818        "uint176" => Token::Uint(176),
819        "uint184" => Token::Uint(184),
820        "uint192" => Token::Uint(192),
821        "uint200" => Token::Uint(200),
822        "uint208" => Token::Uint(208),
823        "uint216" => Token::Uint(216),
824        "uint224" => Token::Uint(224),
825        "uint232" => Token::Uint(232),
826        "uint240" => Token::Uint(240),
827        "uint248" => Token::Uint(248),
828        "uint256" => Token::Uint(256),
829        "uint" => Token::Uint(256),
830        "view" => Token::View,
831        "receive" => Token::Receive,
832        "fallback" => Token::Fallback,
833        "abstract" => Token::Abstract,
834        "virtual" => Token::Virtual,
835        "override" => Token::Override,
836        _ => return None,
837    };
838    Some(token)
839}
840
841#[derive(Debug, Clone, Eq, PartialEq)]
842pub enum Visibility {
843    Internal,
844    External,
845    Private,
846    Public,
847}
848
849#[derive(Debug, Clone, Eq, PartialEq)]
850pub enum DataLocation {
851    Memory,
852    Storage,
853    Calldata,
854}
855
856#[cfg(test)]
857mod tests {
858    use super::*;
859
860    #[test]
861    fn parse_error() {
862        let f = AbiError {
863            name: "MyError".to_string(),
864            inputs: vec![
865                Param { name: "author".to_string(), kind: ParamType::Address, internal_type: None },
866                Param {
867                    name: "oldValue".to_string(),
868                    kind: ParamType::String,
869                    internal_type: None,
870                },
871                Param {
872                    name: "newValue".to_string(),
873                    kind: ParamType::String,
874                    internal_type: None,
875                },
876            ],
877        };
878        let parsed = HumanReadableParser::parse_error(
879            "error MyError(address author, string oldValue, string newValue)",
880        )
881        .unwrap();
882        assert_eq!(f, parsed);
883    }
884
885    #[test]
886    fn parse_constructor() {
887        let f = Constructor {
888            inputs: vec![
889                Param { name: "author".to_string(), kind: ParamType::Address, internal_type: None },
890                Param {
891                    name: "oldValue".to_string(),
892                    kind: ParamType::String,
893                    internal_type: None,
894                },
895                Param {
896                    name: "newValue".to_string(),
897                    kind: ParamType::String,
898                    internal_type: None,
899                },
900            ],
901        };
902        let parsed = HumanReadableParser::parse_constructor(
903            "constructor(address author, string oldValue, string newValue)",
904        )
905        .unwrap();
906        assert_eq!(f, parsed);
907    }
908
909    #[test]
910    fn test_parse_function() {
911        #[allow(deprecated)]
912        let f = Function {
913            name: "get".to_string(),
914            inputs: vec![
915                Param { name: "author".to_string(), kind: ParamType::Address, internal_type: None },
916                Param {
917                    name: "oldValue".to_string(),
918                    kind: ParamType::String,
919                    internal_type: None,
920                },
921                Param {
922                    name: "newValue".to_string(),
923                    kind: ParamType::String,
924                    internal_type: None,
925                },
926            ],
927            outputs: vec![],
928            constant: None,
929            state_mutability: Default::default(),
930        };
931        let parsed = HumanReadableParser::parse_function(
932            "function get(address author, string oldValue, string newValue)",
933        )
934        .unwrap();
935        assert_eq!(f, parsed);
936
937        let parsed = HumanReadableParser::parse_function(
938            "get(address author, string oldValue, string newValue)",
939        )
940        .unwrap();
941        assert_eq!(f, parsed);
942
943        #[allow(deprecated)]
944        let f = Function {
945            name: "get".to_string(),
946            inputs: vec![
947                Param { name: "".to_string(), kind: ParamType::Address, internal_type: None },
948                Param { name: "".to_string(), kind: ParamType::String, internal_type: None },
949                Param { name: "".to_string(), kind: ParamType::String, internal_type: None },
950            ],
951            outputs: vec![],
952            constant: None,
953            state_mutability: Default::default(),
954        };
955
956        let parsed =
957            HumanReadableParser::parse_function("get(address , string , string )").unwrap();
958        assert_eq!(f, parsed);
959    }
960
961    #[test]
962    fn test_parse_function_output() {
963        #[allow(deprecated)]
964        let f = Function {
965            name: "get".to_string(),
966            inputs: vec![
967                Param { name: "author".to_string(), kind: ParamType::Address, internal_type: None },
968                Param {
969                    name: "oldValue".to_string(),
970                    kind: ParamType::String,
971                    internal_type: None,
972                },
973                Param {
974                    name: "newValue".to_string(),
975                    kind: ParamType::String,
976                    internal_type: None,
977                },
978            ],
979            outputs: vec![
980                Param {
981                    name: "result".to_string(),
982                    kind: ParamType::Uint(256),
983                    internal_type: None,
984                },
985                Param { name: "output".to_string(), kind: ParamType::Address, internal_type: None },
986            ],
987            constant: None,
988            state_mutability: Default::default(),
989        };
990        let parsed = HumanReadableParser::parse_function(
991            "function get(address author, string oldValue, string newValue) returns (uint256 result, address output)",
992        )
993        .unwrap();
994        assert_eq!(f, parsed);
995
996        let parsed = HumanReadableParser::parse_function(
997            " get(address author, string oldValue, string newValue) returns (uint256 result, address output)",
998        )
999        .unwrap();
1000        assert_eq!(f, parsed);
1001        #[allow(deprecated)]
1002        let mut f = Function {
1003            name: "get".to_string(),
1004            inputs: vec![
1005                Param { name: "".to_string(), kind: ParamType::Address, internal_type: None },
1006                Param { name: "".to_string(), kind: ParamType::String, internal_type: None },
1007                Param { name: "".to_string(), kind: ParamType::String, internal_type: None },
1008            ],
1009            outputs: vec![
1010                Param { name: "".to_string(), kind: ParamType::Uint(256), internal_type: None },
1011                Param { name: "".to_string(), kind: ParamType::Address, internal_type: None },
1012            ],
1013            constant: None,
1014            state_mutability: Default::default(),
1015        };
1016        let parsed = HumanReadableParser::parse_function(
1017            "function get(address, string, string) (uint256, address)",
1018        )
1019        .unwrap();
1020        assert_eq!(f, parsed);
1021
1022        f.state_mutability = StateMutability::View;
1023        let parsed = HumanReadableParser::parse_function(
1024            "function get(address, string memory, string calldata) public view (uint256, address)",
1025        )
1026        .unwrap();
1027        assert_eq!(f, parsed);
1028    }
1029
1030    #[test]
1031    fn test_parse_param() {
1032        assert_eq!(HumanReadableParser::parse_type("address").unwrap(), ParamType::Address);
1033        assert_eq!(HumanReadableParser::parse_type("bytes").unwrap(), ParamType::Bytes);
1034        assert_eq!(HumanReadableParser::parse_type("bytes32").unwrap(), ParamType::FixedBytes(32));
1035        assert_eq!(HumanReadableParser::parse_type("bool").unwrap(), ParamType::Bool);
1036        assert_eq!(HumanReadableParser::parse_type("string").unwrap(), ParamType::String);
1037        assert_eq!(HumanReadableParser::parse_type("int").unwrap(), ParamType::Int(256));
1038        assert_eq!(HumanReadableParser::parse_type("uint").unwrap(), ParamType::Uint(256));
1039        assert_eq!(
1040            HumanReadableParser::parse_type(
1041                "
1042        int32"
1043            )
1044            .unwrap(),
1045            ParamType::Int(32)
1046        );
1047        assert_eq!(HumanReadableParser::parse_type("uint32").unwrap(), ParamType::Uint(32));
1048    }
1049
1050    #[test]
1051    fn test_parse_array_param() {
1052        assert_eq!(
1053            HumanReadableParser::parse_type("address[]").unwrap(),
1054            ParamType::Array(Box::new(ParamType::Address))
1055        );
1056        assert_eq!(
1057            HumanReadableParser::parse_type("uint[]").unwrap(),
1058            ParamType::Array(Box::new(ParamType::Uint(256)))
1059        );
1060        assert_eq!(
1061            HumanReadableParser::parse_type("bytes[]").unwrap(),
1062            ParamType::Array(Box::new(ParamType::Bytes))
1063        );
1064        assert_eq!(
1065            HumanReadableParser::parse_type("bool[][]").unwrap(),
1066            ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Bool))))
1067        );
1068    }
1069
1070    #[test]
1071    fn test_parse_fixed_array_param() {
1072        assert_eq!(
1073            HumanReadableParser::parse_type("address[2]").unwrap(),
1074            ParamType::FixedArray(Box::new(ParamType::Address), 2)
1075        );
1076        assert_eq!(
1077            HumanReadableParser::parse_type("bool[17]").unwrap(),
1078            ParamType::FixedArray(Box::new(ParamType::Bool), 17)
1079        );
1080        assert_eq!(
1081            HumanReadableParser::parse_type("bytes[45][3]").unwrap(),
1082            ParamType::FixedArray(
1083                Box::new(ParamType::FixedArray(Box::new(ParamType::Bytes), 45)),
1084                3
1085            )
1086        );
1087    }
1088
1089    #[test]
1090    fn test_parse_mixed_arrays() {
1091        assert_eq!(
1092            HumanReadableParser::parse_type("bool[][3]").unwrap(),
1093            ParamType::FixedArray(Box::new(ParamType::Array(Box::new(ParamType::Bool))), 3)
1094        );
1095        assert_eq!(
1096            HumanReadableParser::parse_type("bool[3][]").unwrap(),
1097            ParamType::Array(Box::new(ParamType::FixedArray(Box::new(ParamType::Bool), 3)))
1098        );
1099    }
1100
1101    #[test]
1102    fn test_parse_struct_param() {
1103        assert_eq!(
1104            HumanReadableParser::parse_type("(address,bool)").unwrap(),
1105            ParamType::Tuple(vec![ParamType::Address, ParamType::Bool])
1106        );
1107        assert_eq!(
1108            HumanReadableParser::parse_type("(bool[3],uint256)").unwrap(),
1109            ParamType::Tuple(vec![
1110                ParamType::FixedArray(Box::new(ParamType::Bool), 3),
1111                ParamType::Uint(256)
1112            ])
1113        );
1114    }
1115
1116    #[test]
1117    fn test_parse_nested_struct_param() {
1118        assert_eq!(
1119            HumanReadableParser::parse_type("(address,bool,(bool,uint256))").unwrap(),
1120            ParamType::Tuple(vec![
1121                ParamType::Address,
1122                ParamType::Bool,
1123                ParamType::Tuple(vec![ParamType::Bool, ParamType::Uint(256)])
1124            ])
1125        );
1126    }
1127
1128    #[test]
1129    fn test_parse_complex_nested_struct_param() {
1130        assert_eq!(
1131            HumanReadableParser::parse_type(
1132                "(address,bool,(bool,uint256,(bool,uint256)),(bool,uint256))"
1133            )
1134            .unwrap(),
1135            ParamType::Tuple(vec![
1136                ParamType::Address,
1137                ParamType::Bool,
1138                ParamType::Tuple(vec![
1139                    ParamType::Bool,
1140                    ParamType::Uint(256),
1141                    ParamType::Tuple(vec![ParamType::Bool, ParamType::Uint(256)])
1142                ]),
1143                ParamType::Tuple(vec![ParamType::Bool, ParamType::Uint(256)])
1144            ])
1145        );
1146    }
1147
1148    #[test]
1149    fn test_parse_nested_tuple_array_param() {
1150        assert_eq!(
1151            HumanReadableParser::parse_type("(uint256,bytes32)[]").unwrap(),
1152            ParamType::Array(Box::new(ParamType::Tuple(vec![
1153                ParamType::Uint(256),
1154                ParamType::FixedBytes(32)
1155            ])))
1156        )
1157    }
1158
1159    #[test]
1160    fn test_parse_inner_tuple_array_param() {
1161        let abi = "((uint256,bytes32)[],address)";
1162        let read = HumanReadableParser::parse_type(abi).unwrap();
1163
1164        let param = ParamType::Tuple(vec![
1165            ParamType::Array(Box::new(ParamType::Tuple(vec![
1166                ParamType::Uint(256),
1167                ParamType::FixedBytes(32),
1168            ]))),
1169            ParamType::Address,
1170        ]);
1171        assert_eq!(read, param);
1172    }
1173
1174    #[test]
1175    fn test_parse_complex_tuple_array_param() {
1176        let abi = "((uint256,uint256)[],(uint256,(uint256,uint256))[])";
1177        let read = HumanReadableParser::parse_type(abi).unwrap();
1178        let param = ParamType::Tuple(vec![
1179            ParamType::Array(Box::new(ParamType::Tuple(vec![
1180                ParamType::Uint(256),
1181                ParamType::Uint(256),
1182            ]))),
1183            ParamType::Array(Box::new(ParamType::Tuple(vec![
1184                ParamType::Uint(256),
1185                ParamType::Tuple(vec![ParamType::Uint(256), ParamType::Uint(256)]),
1186            ]))),
1187        ]);
1188        assert_eq!(read, param);
1189    }
1190
1191    #[test]
1192    fn test_parse_event() {
1193        let abi = "event ValueChanged(address indexed author, string oldValue, string newValue)";
1194        let event = HumanReadableParser::parse_event(abi).unwrap();
1195
1196        assert_eq!(
1197            Event {
1198                name: "ValueChanged".to_string(),
1199                inputs: vec![
1200                    EventParam {
1201                        name: "author".to_string(),
1202                        kind: ParamType::Address,
1203                        indexed: true
1204                    },
1205                    EventParam {
1206                        name: "oldValue".to_string(),
1207                        kind: ParamType::String,
1208                        indexed: false
1209                    },
1210                    EventParam {
1211                        name: "newValue".to_string(),
1212                        kind: ParamType::String,
1213                        indexed: false
1214                    }
1215                ],
1216                anonymous: false
1217            },
1218            event
1219        );
1220    }
1221
1222    #[test]
1223    fn parse_large_function() {
1224        let f = "function atomicMatch_(address[14] addrs, uint[18] uints, uint8[8] feeMethodsSidesKindsHowToCalls, bytes calldataBuy, bytes calldataSell, bytes replacementPatternBuy, bytes replacementPatternSell, bytes staticExtradataBuy, bytes staticExtradataSell, uint8[2] vs, bytes32[5] rssMetadata) public payable";
1225
1226        let _fun = HumanReadableParser::parse_function(f).unwrap();
1227    }
1228}