Diffstat (limited to 'tests/common/builder.rs')
| -rw-r--r-- | tests/common/builder.rs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/tests/common/builder.rs b/tests/common/builder.rs new file mode 100644 index 0000000..d2b182f --- /dev/null +++ b/tests/common/builder.rs @@ -0,0 +1,85 @@ +use mockall::mock; +use treaty::{any::{indirect, AnyTrait, AnyTraitObject, TypeNameId}, effect::{Effect, Future}, protocol::Visitor, Builder, BuilderTypes}; + +use crate::common::{ContextLock, StaticTypeMap}; + +use self::__mock_MockBuilder::__from_seed::Context; + +use super::ContextGuard; + +mock! { + pub Builder<Seed: 'static, Value: 'static, Error: 'static> { + pub fn from_seed(seed: Seed) -> Self; + pub fn build(self) -> Result<Value, Error>; + + pub fn traits(&self, id: TypeNameId) -> &Option<Box<dyn for<'ctx> AnyTrait<'ctx> + Send>>; + pub fn traits_mut(&mut self, id: TypeNameId) -> &mut Option<Box<dyn for<'ctx> AnyTrait<'ctx> + Send>>; + } +} + +impl<Seed: Send, Value: Send, Error: Send> BuilderTypes for MockBuilder<Seed, Value, Error> { + type Seed = Seed; + + type Error = Error; + + type Value = Value; +} + +impl<Seed: 'static, Value: 'static, Error: 'static> MockBuilder<Seed, Value, Error> { + pub fn lock_from_seed_context<'a>() -> ContextGuard<'a, Context<Seed, Value, Error>> { + static LOCKS: StaticTypeMap = StaticTypeMap::new(); + + LOCKS + .get_or_init(|| { + ContextLock::new(MockBuilder::from_seed_context(), |context| { + context.checkpoint() + }) + }) + .lock() + } +} + +impl<'ctx, Seed: Send, Value: Send, Error: Send, E: Effect> Builder<'ctx, E> + for MockBuilder<Seed, Value, Error> +{ + fn from_seed<'a>(seed: Self::Seed) -> Future<'a, Self, E> + where + Self: 'a, + { + E::ready(Self::from_seed(seed)) + } + + fn build<'a>(self) -> Future<'a, Result<Self::Value, Self::Error>, E> + where + Self: 'a, + { + E::ready(self.build()) + } + + fn as_visitor(&mut self) -> Visitor<'_, 'ctx> { + self + } +} + +impl<'ctx, Seed, Value, Error> AnyTrait<'ctx> for MockBuilder<Seed, Value, Error> { + fn upcast_to_id<'a>(&'a self, id: TypeNameId) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref>> + where + 'ctx: 'a, + { + // Find the first trait handler that wants to upcast. + self.traits(id).as_ref().and_then(|t| t.upcast_to_id(id)) + } + + fn upcast_to_id_mut<'a>( + &'a mut self, + id: TypeNameId, + ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Mut>> + where + 'ctx: 'a, + { + // Find the first trait handler that wants to upcast. + self.traits_mut(id) + .as_mut() + .and_then(|t| t.upcast_to_id_mut(id)) + } +} |