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 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 Byte,
67 DynamicBytes,
68 Bool,
69 Address,
70 String,
71}
72
73impl<'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
168impl<'input> HumanReadableLexer<'input> {
171 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 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 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
299impl<'input> HumanReadableParser<'input> {
302 pub fn new(input: &'input str) -> Self {
304 let lexer = HumanReadableLexer::new(input);
305 Self { lexer: lexer.peekable() }
306 }
307
308 pub fn parse_type(input: &'input str) -> Result<ParamType, LexerError> {
310 Self::new(input).take_param()
311 }
312
313 pub fn parse_function(input: &'input str) -> Result<Function, LexerError> {
322 Self::new(input).take_function()
323 }
324
325 pub fn parse_error(input: &'input str) -> Result<AbiError, LexerError> {
334 Self::new(input).take_error()
335 }
336
337 pub fn parse_constructor(input: &'input str) -> Result<Constructor, LexerError> {
346 Self::new(input).take_constructor()
347 }
348
349 pub fn parse_event(input: &'input str) -> Result<Event, LexerError> {
358 Self::new(input).take_event()
359 }
360
361 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 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 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 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 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 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 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 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 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}