alloy_sol_type_parser/
stem.rsuse crate::{Error, Input, Result, RootType, TupleSpecifier};
use winnow::{combinator::trace, PResult, Parser};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TypeStem<'a> {
Root(RootType<'a>),
Tuple(TupleSpecifier<'a>),
}
impl<'a> TryFrom<&'a str> for TypeStem<'a> {
type Error = Error;
#[inline]
fn try_from(value: &'a str) -> Result<Self> {
Self::parse(value)
}
}
impl AsRef<str> for TypeStem<'_> {
#[inline]
fn as_ref(&self) -> &str {
self.span()
}
}
impl<'a> TypeStem<'a> {
#[inline]
pub fn parse(input: &'a str) -> Result<Self> {
if input.starts_with('(') || input.starts_with("tuple(") {
input.try_into().map(Self::Tuple)
} else {
input.try_into().map(Self::Root)
}
}
pub(crate) fn parser(input: &mut Input<'a>) -> PResult<Self> {
let name = "TypeStem";
if input.starts_with('(') || input.starts_with("tuple(") {
trace(name, TupleSpecifier::parser).parse_next(input).map(Self::Tuple)
} else {
trace(name, RootType::parser).parse_next(input).map(Self::Root)
}
}
#[inline]
pub const fn as_root(&self) -> Option<&RootType<'a>> {
match self {
Self::Root(root) => Some(root),
Self::Tuple(_) => None,
}
}
#[inline]
pub const fn as_tuple(&self) -> Option<&TupleSpecifier<'a>> {
match self {
Self::Root(_) => None,
Self::Tuple(tuple) => Some(tuple),
}
}
#[inline]
pub const fn span(&self) -> &'a str {
match self {
Self::Root(root) => root.span(),
Self::Tuple(tuple) => tuple.span(),
}
}
#[inline]
pub fn try_basic_solidity(&self) -> Result<()> {
match self {
Self::Root(root) => root.try_basic_solidity(),
Self::Tuple(tuple) => tuple.try_basic_solidity(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tuple() {
assert_eq!(
TypeStem::parse("()"),
Ok(TypeStem::Tuple(TupleSpecifier { span: "()", types: vec![] }))
);
TypeStem::parse("tuple(").unwrap_err();
assert_eq!(
TypeStem::parse("tuple()"),
Ok(TypeStem::Tuple(TupleSpecifier { span: "tuple()", types: vec![] }))
);
assert_eq!(TypeStem::parse("tuple"), Ok(TypeStem::Root(RootType::parse("tuple").unwrap())))
}
}