util.rs
1 use std::sync::Arc; 2 3 use fedimint_core::task::{MaybeSend, MaybeSync}; 4 5 use crate::sm::StateTransition; 6 7 pub trait MapStateTransitions { 8 type State: MaybeSend + MaybeSync + 'static; 9 10 fn map<D, W, U>(self, wrap: W, unwrap: U) -> Vec<StateTransition<D>> 11 where 12 D: MaybeSend + MaybeSync + 'static, 13 W: Fn(Self::State) -> D + Clone + MaybeSend + MaybeSync + 'static, 14 U: Fn(D) -> Self::State + Clone + MaybeSend + MaybeSync + 'static; 15 } 16 17 impl<S> MapStateTransitions for Vec<StateTransition<S>> 18 where 19 S: MaybeSend + MaybeSync + 'static, 20 { 21 type State = S; 22 23 fn map<D, W, U>(self, wrap: W, unwrap: U) -> Vec<StateTransition<D>> 24 where 25 D: MaybeSend + MaybeSync + 'static, 26 W: Fn(Self::State) -> D + Clone + MaybeSend + MaybeSync + 'static, 27 U: Fn(D) -> Self::State + Clone + MaybeSend + MaybeSync + 'static, 28 { 29 self.into_iter() 30 .map( 31 |StateTransition { 32 trigger, 33 transition, 34 }| { 35 let wrap = wrap.clone(); 36 let unwrap = unwrap.clone(); 37 StateTransition { 38 trigger, 39 transition: Arc::new(move |dbtx, value, state| { 40 let wrap = wrap.clone(); 41 let unwrap = unwrap.clone(); 42 let transition = transition.clone(); 43 Box::pin( 44 async move { wrap(transition(dbtx, value, unwrap(state)).await) }, 45 ) 46 }), 47 } 48 }, 49 ) 50 .collect() 51 } 52 } 53 54 #[macro_export] 55 macro_rules! sm_enum_variant_translation { 56 ($sm:expr, $enum_variant:path) => { 57 $sm.map( 58 |sm| $enum_variant(sm), 59 |sm| match sm { 60 $enum_variant(sm) => sm, 61 _ => panic!("Incorrectly dispatched state"), 62 }, 63 ) 64 }; 65 }