use crate::{
Result, Word,
abi::{self, Token, TokenSeq},
private::SolTypeValue,
};
use alloc::vec::Vec;
pub trait SolType: Sized {
type RustType: SolTypeValue<Self> + 'static;
type Token<'a>: Token<'a>;
const SOL_NAME: &'static str;
const ENCODED_SIZE: Option<usize>;
const PACKED_ENCODED_SIZE: Option<usize>;
const DYNAMIC: bool = Self::ENCODED_SIZE.is_none();
#[inline]
fn abi_encoded_size<E: ?Sized + SolTypeValue<Self>>(rust: &E) -> usize {
rust.stv_abi_encoded_size()
}
fn valid_token(token: &Self::Token<'_>) -> bool;
#[inline]
fn type_check(token: &Self::Token<'_>) -> Result<()> {
if Self::valid_token(token) {
Ok(())
} else {
Err(crate::Error::type_check_fail_token::<Self>(token))
}
}
fn detokenize(token: Self::Token<'_>) -> Self::RustType;
#[inline]
fn tokenize<E: ?Sized + SolTypeValue<Self>>(rust: &E) -> Self::Token<'_> {
rust.stv_to_tokens()
}
#[inline]
fn eip712_data_word<E: ?Sized + SolTypeValue<Self>>(rust: &E) -> Word {
rust.stv_eip712_data_word()
}
#[inline]
fn abi_packed_encoded_size<E: ?Sized + SolTypeValue<Self>>(rust: &E) -> usize {
rust.stv_abi_packed_encoded_size()
}
#[inline]
fn abi_encode_packed_to<E: ?Sized + SolTypeValue<Self>>(rust: &E, out: &mut Vec<u8>) {
rust.stv_abi_encode_packed_to(out)
}
#[inline]
fn abi_encode_packed<E: ?Sized + SolTypeValue<Self>>(rust: &E) -> Vec<u8> {
let mut out = Vec::with_capacity(Self::abi_packed_encoded_size(rust));
Self::abi_encode_packed_to(rust, &mut out);
out
}
#[inline]
fn abi_encode<E: ?Sized + SolTypeValue<Self>>(rust: &E) -> Vec<u8> {
abi::encode(&rust.stv_to_tokens())
}
#[inline]
fn abi_encode_params<E: ?Sized + SolTypeValue<Self>>(rust: &E) -> Vec<u8>
where
for<'a> Self::Token<'a>: TokenSeq<'a>,
{
abi::encode_params(&rust.stv_to_tokens())
}
#[inline]
fn abi_encode_sequence<E: ?Sized + SolTypeValue<Self>>(rust: &E) -> Vec<u8>
where
for<'a> Self::Token<'a>: TokenSeq<'a>,
{
abi::encode_sequence(&rust.stv_to_tokens())
}
#[inline]
fn abi_decode(data: &[u8]) -> Result<Self::RustType> {
abi::decode::<Self::Token<'_>>(data).map(Self::detokenize)
}
#[inline]
fn abi_decode_validate(data: &[u8]) -> Result<Self::RustType> {
let token = abi::decode::<Self::Token<'_>>(data)?;
Self::type_check(&token)?;
Ok(Self::detokenize(token))
}
#[inline]
fn abi_decode_params<'de>(data: &'de [u8]) -> Result<Self::RustType>
where
Self::Token<'de>: TokenSeq<'de>,
{
abi::decode_params::<Self::Token<'_>>(data).map(Self::detokenize)
}
#[inline]
fn abi_decode_params_validate<'de>(data: &'de [u8]) -> Result<Self::RustType>
where
Self::Token<'de>: TokenSeq<'de>,
{
let token = abi::decode_params::<Self::Token<'_>>(data)?;
Self::type_check(&token)?;
Ok(Self::detokenize(token))
}
#[inline]
fn abi_decode_sequence<'de>(data: &'de [u8]) -> Result<Self::RustType>
where
Self::Token<'de>: TokenSeq<'de>,
{
abi::decode_sequence::<Self::Token<'_>>(data).map(Self::detokenize)
}
#[inline]
fn abi_decode_sequence_validate<'de>(data: &'de [u8]) -> Result<Self::RustType>
where
Self::Token<'de>: TokenSeq<'de>,
{
let token = abi::decode_sequence::<Self::Token<'_>>(data)?;
Self::type_check(&token)?;
Ok(Self::detokenize(token))
}
}