1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
use crate::{Error, Result, RootType, TupleSpecifier};
/// A stem of a Solidity array type. It is either a root type, or a tuple type.
///
/// # Examples
///
/// ```
/// # use alloy_sol_type_parser::{TypeStem, RootType, TupleSpecifier};
/// let stem = TypeStem::try_from("uint256")?;
/// assert_eq!(stem.span(), "uint256");
/// assert!(matches!(stem, TypeStem::Root(_)));
/// assert_eq!(stem.as_root(), Some(&RootType::try_from("uint256").unwrap()));
///
/// let stem = TypeStem::try_from("(uint256,bool)")?;
/// assert_eq!(stem.span(), "(uint256,bool)");
/// assert!(matches!(stem, TypeStem::Tuple(_)));
/// assert_eq!(
/// stem.as_tuple(),
/// Some(&TupleSpecifier::try_from("(uint256,bool)").unwrap())
/// );
/// # Ok::<_, alloy_sol_type_parser::Error>(())
/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TypeStem<'a> {
/// Root type.
Root(RootType<'a>),
/// Tuple type.
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> {
/// Fallible conversion to a root type
#[inline]
pub const fn as_root(&self) -> Option<&RootType<'a>> {
match self {
Self::Root(root) => Some(root),
Self::Tuple(_) => None,
}
}
/// Fallible conversion to a tuple type
#[inline]
pub const fn as_tuple(&self) -> Option<&TupleSpecifier<'a>> {
match self {
Self::Root(_) => None,
Self::Tuple(tuple) => Some(tuple),
}
}
/// Parse a type stem from a string.
#[inline]
pub fn parse(s: &'a str) -> Result<Self> {
if s.starts_with('(') || s.starts_with("tuple(") {
s.try_into().map(Self::Tuple)
} else {
s.try_into().map(Self::Root)
}
}
/// Returns the type stem as a string.
#[inline]
pub const fn span(&self) -> &'a str {
match self {
Self::Root(root) => root.span(),
Self::Tuple(tuple) => tuple.span(),
}
}
/// Returns true if the type is a basic Solidity type.
#[inline]
pub fn try_basic_solidity(&self) -> Result<()> {
match self {
Self::Root(root) => root.try_basic_solidity(),
Self::Tuple(tuple) => tuple.try_basic_solidity(),
}
}
}