alloy_sol_type_parser/
stem.rs1use crate::{Error, Input, Result, RootType, TupleSpecifier};
2use winnow::{ModalResult, Parser, combinator::trace};
3
4#[derive(Clone, Debug, PartialEq, Eq)]
22pub enum TypeStem<'a> {
23 Root(RootType<'a>),
25 Tuple(TupleSpecifier<'a>),
27}
28
29impl<'a> TryFrom<&'a str> for TypeStem<'a> {
30 type Error = Error;
31
32 #[inline]
33 fn try_from(value: &'a str) -> Result<Self> {
34 Self::parse(value)
35 }
36}
37
38impl AsRef<str> for TypeStem<'_> {
39 #[inline]
40 fn as_ref(&self) -> &str {
41 self.span()
42 }
43}
44
45impl<'a> TypeStem<'a> {
46 #[inline]
48 pub fn parse(input: &'a str) -> Result<Self> {
49 if input.starts_with('(') || input.starts_with("tuple(") {
50 input.try_into().map(Self::Tuple)
51 } else {
52 input.try_into().map(Self::Root)
53 }
54 }
55
56 #[cfg(feature = "eip712")]
58 pub(crate) fn eip712_parser(input: &mut Input<'a>) -> ModalResult<Self> {
59 let name = "TypeStem::eip712";
60 if input.starts_with('(') || input.starts_with("tuple(") {
61 trace(name, TupleSpecifier::eip712_parser).parse_next(input).map(Self::Tuple)
62 } else {
63 trace(name, RootType::eip712_parser).parse_next(input).map(Self::Root)
64 }
65 }
66
67 pub(crate) fn parser(input: &mut Input<'a>) -> ModalResult<Self> {
69 let name = "TypeStem";
70 if input.starts_with('(') || input.starts_with("tuple(") {
71 trace(name, TupleSpecifier::parser).parse_next(input).map(Self::Tuple)
72 } else {
73 trace(name, RootType::parser).parse_next(input).map(Self::Root)
74 }
75 }
76
77 #[inline]
79 pub const fn as_root(&self) -> Option<&RootType<'a>> {
80 match self {
81 Self::Root(root) => Some(root),
82 Self::Tuple(_) => None,
83 }
84 }
85
86 #[inline]
88 pub const fn as_tuple(&self) -> Option<&TupleSpecifier<'a>> {
89 match self {
90 Self::Root(_) => None,
91 Self::Tuple(tuple) => Some(tuple),
92 }
93 }
94
95 #[inline]
97 pub const fn span(&self) -> &'a str {
98 match self {
99 Self::Root(root) => root.span(),
100 Self::Tuple(tuple) => tuple.span(),
101 }
102 }
103
104 #[inline]
106 pub fn try_basic_solidity(&self) -> Result<()> {
107 match self {
108 Self::Root(root) => root.try_basic_solidity(),
109 Self::Tuple(tuple) => tuple.try_basic_solidity(),
110 }
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 #[test]
119 fn tuple() {
120 assert_eq!(
122 TypeStem::parse("()"),
123 Ok(TypeStem::Tuple(TupleSpecifier { span: "()", types: vec![] }))
124 );
125 TypeStem::parse("tuple(").unwrap_err();
126 assert_eq!(
127 TypeStem::parse("tuple()"),
128 Ok(TypeStem::Tuple(TupleSpecifier { span: "tuple()", types: vec![] }))
129 );
130
131 assert_eq!(TypeStem::parse("tuple"), Ok(TypeStem::Root(RootType::parse("tuple").unwrap())))
133 }
134}