use std::marker::PhantomData;
use tracing::{instrument, Span};
use super::sandbox::Sandbox;
use crate::func::call_ctx::MultiUseGuestCallContext;
use crate::Result;
pub trait TransitionMetadata<Cur: Sandbox, Next: Sandbox> {}
pub struct Noop<Cur: Sandbox, Next: Sandbox> {
cur_ph: PhantomData<Cur>,
next_ph: PhantomData<Next>,
}
impl<Cur: Sandbox, Next: Sandbox> Default for Noop<Cur, Next> {
fn default() -> Self {
Self {
cur_ph: PhantomData,
next_ph: PhantomData,
}
}
}
impl<Cur: Sandbox, Next: Sandbox> TransitionMetadata<Cur, Next> for Noop<Cur, Next> {}
pub struct MultiUseContextCallback<'func, Cur: Sandbox, F>
where
F: FnOnce(&mut MultiUseGuestCallContext) -> Result<()> + 'func,
{
cur_ph: PhantomData<Cur>,
fn_life_ph: PhantomData<&'func ()>,
cb: F,
}
impl<'a, Cur: Sandbox, Next: Sandbox, F> TransitionMetadata<Cur, Next>
for MultiUseContextCallback<'a, Cur, F>
where
F: FnOnce(&mut MultiUseGuestCallContext) -> Result<()>,
{
}
impl<'a, Cur: Sandbox, F> MultiUseContextCallback<'a, Cur, F>
where
F: FnOnce(&mut MultiUseGuestCallContext) -> Result<()>,
{
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
pub fn call(self, cur: &mut MultiUseGuestCallContext) -> Result<()> {
(self.cb)(cur)
}
}
impl<'a, Cur: Sandbox, F> From<F> for MultiUseContextCallback<'a, Cur, F>
where
F: FnOnce(&mut MultiUseGuestCallContext) -> Result<()> + 'a,
{
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
fn from(val: F) -> Self {
MultiUseContextCallback {
cur_ph: PhantomData,
fn_life_ph: PhantomData,
cb: val,
}
}
}
#[cfg(test)]
mod tests {
use super::Noop;
use crate::sandbox_state::sandbox::{DevolvableSandbox, EvolvableSandbox, Sandbox};
use crate::Result;
#[derive(Debug, Eq, PartialEq, Clone)]
struct MySandbox1 {}
#[derive(Debug, Eq, PartialEq, Clone)]
struct MySandbox2 {}
impl Sandbox for MySandbox1 {}
impl Sandbox for MySandbox2 {}
impl EvolvableSandbox<MySandbox1, MySandbox2, Noop<MySandbox1, MySandbox2>> for MySandbox1 {
fn evolve(self, _: Noop<MySandbox1, MySandbox2>) -> Result<MySandbox2> {
Ok(MySandbox2 {})
}
}
impl DevolvableSandbox<MySandbox2, MySandbox1, Noop<MySandbox2, MySandbox1>> for MySandbox2 {
fn devolve(self, _: Noop<MySandbox2, MySandbox1>) -> Result<MySandbox1> {
Ok(MySandbox1 {})
}
}
#[test]
fn test_evolve_devolve() {
let sbox_1_1 = MySandbox1 {};
let sbox_2_1 = sbox_1_1.clone().evolve(Noop::default()).unwrap();
let sbox_1_2 = sbox_2_1.clone().devolve(Noop::default()).unwrap();
let sbox_2_2 = sbox_1_2.clone().evolve(Noop::default()).unwrap();
assert_eq!(sbox_1_1, sbox_1_2);
assert_eq!(sbox_2_1, sbox_2_2);
}
}