git.delta.rocks / unique-network / refs/commits / e69af78ae3cb

difftreelog

source

crates/evm-coder/src/solidity.rs4.2 KiBsourcehistory
1#[cfg(not(feature = "std"))]2use alloc::{string::String};3use core::{fmt, marker::PhantomData};4use impl_trait_for_tuples::impl_for_tuples;5use crate::types::*;67pub trait SolidityTypeName: 'static {8	fn solidity_name(writer: &mut impl fmt::Write) -> fmt::Result;9	fn is_void() -> bool {10		false11	}12}1314macro_rules! solidity_type_name {15    ($($ty:ident => $name:expr),* $(,)?) => {16        $(17            impl SolidityTypeName for $ty {18                fn solidity_name(writer: &mut impl core::fmt::Write) -> core::fmt::Result {19                    write!(writer, $name)20                }21            }22        )*23    };24}2526solidity_type_name! {27	uint8 => "uint8",28	uint32 => "uint32",29	uint128 => "uint128",30	uint256 => "uint256",31	address => "address",32	string => "memory string",33	bytes => "memory bytes",34	bool => "bool",35}36impl SolidityTypeName for void {37	fn solidity_name(_writer: &mut impl fmt::Write) -> fmt::Result {38		Ok(())39	}40	fn is_void() -> bool {41		true42	}43}4445pub trait SolidityArguments {46	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result;47	fn is_empty(&self) -> bool {48		self.len() == 049	}50	fn len(&self) -> usize;51}5253#[derive(Default)]54pub struct UnnamedArgument<T>(PhantomData<*const T>);5556impl<T: SolidityTypeName> SolidityArguments for UnnamedArgument<T> {57	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {58		if !T::is_void() {59			T::solidity_name(writer)60		} else {61			Ok(())62		}63	}64	fn len(&self) -> usize {65		if T::is_void() {66			067		} else {68			169		}70	}71}7273pub struct NamedArgument<T>(&'static str, PhantomData<*const T>);7475impl<T> NamedArgument<T> {76	pub fn new(name: &'static str) -> Self {77		Self(name, Default::default())78	}79}8081impl<T: SolidityTypeName> SolidityArguments for NamedArgument<T> {82	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {83		if !T::is_void() {84			T::solidity_name(writer)?;85			write!(writer, " {}", self.0)86		} else {87			Ok(())88		}89	}90	fn len(&self) -> usize {91		if T::is_void() {92			093		} else {94			195		}96	}97}9899impl SolidityArguments for () {100	fn solidity_name(&self, _writer: &mut impl fmt::Write) -> fmt::Result {101		Ok(())102	}103	fn len(&self) -> usize {104		0105	}106}107108#[impl_for_tuples(1, 5)]109impl SolidityArguments for Tuple {110	for_tuples!( where #( Tuple: SolidityArguments ),* );111112	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {113		let mut first = true;114		for_tuples!( #(115            if !Tuple.is_empty() {116                if !first {117                    write!(writer, ", ")?;118                }119                first = false;120                Tuple.solidity_name(writer)?;121            }122        )* );123		Ok(())124	}125	fn len(&self) -> usize {126		for_tuples!( #( Tuple.len() )+* )127	}128}129130pub trait SolidityFunctions {131	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result;132}133134pub enum SolidityMutability {135	Pure,136	View,137	Mutable,138}139pub struct SolidityFunction<A, R> {140	pub name: &'static str,141	pub args: A,142	pub result: R,143	pub mutability: SolidityMutability,144}145impl<A: SolidityArguments, R: SolidityArguments> SolidityFunctions for SolidityFunction<A, R> {146	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {147		write!(writer, "function {}(", self.name)?;148		self.args.solidity_name(writer)?;149		write!(writer, ") external")?;150		match &self.mutability {151			SolidityMutability::Pure => write!(writer, " pure")?,152			SolidityMutability::View => write!(writer, " view")?,153			SolidityMutability::Mutable => {}154		}155		if !self.result.is_empty() {156			write!(writer, " returns (")?;157			self.result.solidity_name(writer)?;158			write!(writer, ")")?;159		}160		writeln!(writer, ";")161	}162}163164#[impl_for_tuples(0, 12)]165impl SolidityFunctions for Tuple {166	for_tuples!( where #( Tuple: SolidityFunctions ),* );167168	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {169		let mut first = false;170		for_tuples!( #(171            Tuple.solidity_name(writer)?;172        )* );173		Ok(())174	}175}176177pub struct SolidityInterface<F: SolidityFunctions> {178	pub name: &'static str,179	pub functions: F,180}181182impl<F: SolidityFunctions> SolidityInterface<F> {183	pub fn format(&self, out: &mut impl fmt::Write) -> fmt::Result {184		writeln!(out, "interface {} {{", self.name)?;185		self.functions.solidity_name(out)?;186		writeln!(out, "}}")?;187		Ok(())188	}189}