#[macro_export]
macro_rules! clarity {
(@box $e:expr) => (Box::new($e) as Box<dyn $crate::clarity::Clarity>);
(@empty, $i:ident) => ($crate::clarity::$i::new(vec![]));
(Int, $x:expr) => ($crate::clarity::Int::new($x));
(UInt, $x:expr) => ($crate::clarity::UInt::new($x));
(Buffer, $x:expr) => ($crate::clarity::Buffer::new($x.to_vec()));
(Buffer) => (@empty, Buffer);
(True) => ($crate::clarity::True::new());
(False) => ($crate::clarity::False::new());
(PrincipalStandard, $x:expr) => ($crate::clarity::PrincipalStandard::new($x.to_string()));
(PrincipalContract, $x:expr, $y:expr) => ($crate::clarity::PrincipalContract::new(($x.to_string(), $y.to_string())));
(ResponseOk, $x:expr) => ($crate::clarity::ResponseOk::new(clarity!(@box $x)));
(ResponseErr, $x:expr) => ($crate::clarity::ResponseErr::new(clarity!(@box $x)));
(OptionalSome, $x:expr) => ($crate::clarity::OptionalSome::new(clarity!(@box $x)));
(OptionalNone) => ($crate::clarity::OptionalNone::new());
(List) => (clarity!(@empty, List));
(Tuple) => (clarity!(@empty, Tuple));
(StringAscii, $x:expr) => ($crate::clarity::StringAscii::new($x.to_string()));
(StringUtf8, $x:expr) => ($crate::clarity::StringUtf8::new($x.to_string()));
(FnArguments) => (clarity!(@empty, FnArguments));
(LengthPrefixedStr, $x:expr) => ($crate::clarity::LengthPrefixedStr::new($x.to_string()));
(List $(, $args:expr)*) => {{
let tmp = vec![$(clarity!(@box $args)),*];
$crate::clarity::List::new(tmp)
}};
(Tuple $(, ($key:expr, $value:expr))*) => {{
let tmp = vec![$(($key.to_string(), clarity!(@box $value))),*];
$crate::clarity::Tuple::new(tmp)
}};
(FnArguments $(, $args:expr)*) => {{
let tmp = vec![$(clarity!(@box $args)),*];
$crate::clarity::FnArguments::new(tmp)
}};
}
macro_rules! impl_clarity_primitive {
($name:ident, $type_id:ident) => {
pub struct $name;
impl $name {
pub fn new() -> Self {
$name
}
}
impl ::std::default::Default for $name {
fn default() -> Self {
$name
}
}
impl ::std::cmp::PartialEq for $name {
fn eq(&self, other: &Self) -> bool {
self.to_string() == other.to_string()
}
}
impl ::std::cmp::Eq for $name {}
impl $crate::clarity::Ident for $name {
fn id() -> u8 {
$type_id
}
}
impl $crate::clarity::Any for $name {
fn as_any(&self) -> &dyn ::std::any::Any {
self
}
fn into_any(self: Box<Self>) -> Box<dyn ::std::any::Any> {
self
}
}
impl $crate::clarity::Clarity for $name {}
};
($name:ident, $value:ty, $type_id:ident) => {
pub struct $name {
__value: $value,
}
impl $name {
pub fn new(__value: $value) -> Self {
$name { __value }
}
pub fn value(&self) -> &$value {
&self.__value
}
pub fn into_value(self) -> $value {
self.__value
}
}
impl ::std::cmp::PartialEq for $name {
fn eq(&self, other: &Self) -> bool {
self.to_string() == other.to_string()
}
}
impl ::std::cmp::Eq for $name {}
impl $crate::clarity::Ident for $name {
fn id() -> u8 {
$type_id
}
}
impl $crate::clarity::Any for $name {
fn as_any(&self) -> &dyn ::std::any::Any {
self
}
fn into_any(self: Box<Self>) -> Box<dyn ::std::any::Any> {
self
}
}
impl $crate::clarity::Clarity for $name {}
};
}
macro_rules! impl_clarity_primitive_cast {
($value:ty) => {
impl $crate::clarity::Cast for $value {
fn cast<T: $crate::clarity::Clarity>(self) -> Result<T, Error> {
if let Ok(value) = self.into_any().downcast::<T>() {
Ok(*value)
} else {
Err(Error::BadDowncast)
}
}
fn cast_as<T: $crate::clarity::Clarity>(&self) -> Result<&T, Error> {
if let Some(value) = self.as_any().downcast_ref::<T>() {
Ok(value)
} else {
Err(Error::BadDowncast)
}
}
}
};
($name:ident, $value:ty, $type_id:ident) => {
impl_clarity_primitive!($name, $value, $type_id);
impl $crate::clarity::Cast for $name {
fn cast<T: $crate::clarity::Clarity>(self) -> Result<T, Error> {
if let Ok(value) = self.into_value().into_any().downcast::<T>() {
Ok(*value)
} else {
Err(Error::BadDowncast)
}
}
fn cast_as<T: $crate::clarity::Clarity>(&self) -> Result<&T, Error> {
if let Some(value) = self.value().as_any().downcast_ref::<T>() {
Ok(value)
} else {
Err(Error::BadDowncast)
}
}
}
};
}
pub(crate) use impl_clarity_primitive;
pub(crate) use impl_clarity_primitive_cast;