use core::any::TypeId;
pub use paste::paste;
use serde_json::Value;
use std::collections::BTreeMap;
use std::sync::Arc;
use std::sync::Mutex;
#[macro_export]
macro_rules! declare {
{then $(,$a:expr)*} => {
const THEN_FNS: &'static [fn() -> Option<$crate::contract::actions::ThenFuncAsFinishOrFunc<'static, Self, Self::StatefulArguments>>] = &[$($a,)*];
};
[state $i:ty] => {
type StatefulArguments = $i;
};
[state] => {
#[cfg(feature = "nightly")]
type StatefulArguments = ();
#[cfg(not(feature = "nightly"))]
type StatefulArguments;
};
{updatable<$($i:ty)?> $(,$a:expr)*} => {
const FINISH_OR_FUNCS: &'static [fn() -> Option<Box<dyn $crate::contract::actions::CallableAsFoF<Self, Self::StatefulArguments>>>] = &[$($a,)*];
declare![state $($i)?];
};
{non updatable} => {
#[cfg(not(feature = "nightly"))]
declare![state ()];
};
{finish $(,$a:expr)*} => {
const FINISH_FNS: &'static [fn() -> Option<$crate::contract::actions::Guard<Self>>] = &[$($a,)*];
};
}
#[macro_export]
macro_rules! decl_then {
{
$(#[$meta:meta])*
$name:ident
} => {
$crate::contract::macros::paste!{
$(#[$meta])*
fn [<then_ $name>](&self, _ctx:$crate::contract::Context, _:$crate::contract::actions::ThenFuncTypeTag)-> $crate::contract::TxTmplIt
{
unimplemented!();
}
$(#[$meta])*
fn $name<'a>() -> Option<$crate::contract::actions::ThenFuncAsFinishOrFunc<'a, Self, <Self as sapio::contract::Contract>::StatefulArguments>> {None}
}
};
}
lazy_static::lazy_static! {
static ref SCHEMA_MAP: Mutex<BTreeMap<TypeId, Arc<Value>>> =
Mutex::new(BTreeMap::new());
}
pub fn get_schema_for<T: schemars::JsonSchema + 'static + Sized>() -> Arc<Value> {
SCHEMA_MAP
.lock()
.unwrap()
.entry(TypeId::of::<T>())
.or_insert_with(|| {
Arc::new(
serde_json::to_value(schemars::schema_for!(T))
.expect("Schema must be able to convert to JSON"),
)
})
.clone()
}
#[macro_export]
macro_rules! web_api {
{$name:ident,$type:ty,{}} => {
$crate::contract::macros::paste!{
const [<CONTINUE_SCHEMA_FOR_ $name:upper >] : Option<&'static dyn Fn() -> std::sync::Arc<$crate::schemars::schema::RootSchema>> = Some(&|| $crate::contract::macros::get_schema_for::<$type>());
}
};
{$name:ident,$type:ty} => {
$crate::contract::macros::paste!{
const [<CONTINUE_SCHEMA_FOR_ $name:upper >] : Option<&'static dyn Fn() -> std::sync::Arc<$crate::schemars::schema::RootSchema>> = None;
}
}
}
pub use web_api;
#[macro_export]
macro_rules! is_web_api_type {
(
$b:block
) => {
$crate::contract::actions::WebAPIEnabled
};
() => {
$crate::contract::actions::WebAPIDisabled
};
}
#[macro_export]
macro_rules! decl_continuation {
{
$(#[$meta:meta])*
$(<web=$web_enable:block>)?
$name:ident<$arg_type:ty>
} => {
$crate::contract::macros::paste!{
$crate::contract::macros::web_api!($name,$arg_type$(,$web_enable)*);
$(#[$meta])*
fn [<continue_ $name>](&self, _ctx:$crate::contract::Context, _o: $arg_type)-> $crate::contract::TxTmplIt
{
unimplemented!();
}
$(#[$meta])*
fn $name<'a>() ->
Option<Box<dyn
$crate::contract::actions::CallableAsFoF<Self, <Self as $crate::contract::Contract>::StatefulArguments>>>
{
None
}
}
};
}
#[macro_export]
macro_rules! decl_guard {
{
$(#[$meta:meta])*
$name:ident} => {
$crate::contract::macros::paste!{
$(#[$meta])*
fn [<guard_ $name>](&self, _ctx:$crate::contract::Context) -> $crate::sapio_base::Clause {
unimplemented!();
}
$(#[$meta])*
fn $name() -> Option<$crate::contract::actions::Guard<Self>> {
None
}
}
};
}
#[macro_export]
macro_rules! decl_compile_if {
{
$(#[$meta:meta])*
$name:ident
} => {
$crate::contract::macros::paste!{
$(#[$meta])*
fn [<compile_if $name>](&self, _ctx: $crate::contract::Context) -> $crate::contract::actions::ConditionalCompileType {
unimplemented!()
}
$(#[$meta])*
fn $name() -> Option<$crate::contract::actions::ConditionallyCompileIf<Self>> {
None
}
}
};
}