use alloc::vec::Vec;
use core::fmt;
use alloy_primitives::U256;
use crate::{abi::AbiType, console, ArbResult};
pub const CONSTRUCTOR_BASE_NAME: &str = "stylus_constructor";
pub const CONSTRUCTOR_EXECUTED_SLOT: U256 = alloy_primitives::U256::from_be_bytes(
keccak_const::Keccak256::new()
.update(CONSTRUCTOR_BASE_NAME.as_bytes())
.finalize(),
);
pub trait EncodableReturnType {
fn encode(self) -> ArbResult;
}
impl<T> EncodableReturnType for T
where
T: AbiType + alloy_sol_types::private::SolTypeValue<<T as AbiType>::SolType>,
{
#[inline(always)]
fn encode(self) -> ArbResult {
Ok(<T as AbiType>::abi_encode_return(&self))
}
}
impl<T, E: Into<Vec<u8>>> EncodableReturnType for Result<T, E>
where
T: AbiType + alloy_sol_types::private::SolTypeValue<<T as AbiType>::SolType>,
{
#[inline(always)]
fn encode(self) -> ArbResult {
match self {
Ok(result) => result.encode(),
Err(err) => Err(err.into()),
}
}
}
#[inline(always)]
pub const fn digest_to_selector(digest: [u8; 32]) -> [u8; 4] {
let mut selector = [0u8; 4];
selector[0] = digest[0];
selector[1] = digest[1];
selector[2] = digest[2];
selector[3] = digest[3];
selector
}
#[allow(unused)]
pub fn failed_to_decode_arguments(err: alloy_sol_types::Error) {
console!("failed to decode arguments: {err}");
}
pub trait AbiResult {
type OkType;
}
impl<O, E> AbiResult for Result<O, E> {
type OkType = O;
}
impl<T: AbiType> AbiResult for T {
type OkType = T;
}
pub fn write_solidity_returns<T: AbiResult>(f: &mut fmt::Formatter) -> fmt::Result
where
T::OkType: AbiType,
{
let abi = T::OkType::EXPORT_ABI_RET.as_str();
if abi == "()" {
Ok(())
} else if abi.starts_with('(') {
write!(f, " returns {abi}")
} else {
write!(f, " returns ({abi})")
}
}