Diffstat (limited to 'src/mock/builder.rs')
| -rw-r--r-- | src/mock/builder.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/mock/builder.rs b/src/mock/builder.rs new file mode 100644 index 0000000..31c1623 --- /dev/null +++ b/src/mock/builder.rs @@ -0,0 +1,99 @@ +use mockall::mock; + +use crate::{ + any::{AnyTrait, IndirectLtAny, LtTypeId, Mut, Ref}, + effect::{Effect, Future}, + mock::{ContextLock, StaticTypeMap}, + protocol::Visitor, + Builder, BuilderTypes, +}; + +use self::__mock_MockBuilder::__from_seed::Context; + +use super::ContextGuard; + +use crate::any::ForAnyTypeId; + +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: ForAnyTypeId) -> &Option<Box<dyn for<'ctx> AnyTrait<'ctx> + Send>>; + pub fn traits_mut(&mut self, id: ForAnyTypeId) -> &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<'ctx>> Builder<'ctx, E> + for MockBuilder<Seed, Value, Error> +{ + #[track_caller] + fn from_seed<'a>(seed: Self::Seed) -> Future<'a, 'ctx, Self, E> + where + Self: 'a, + { + E::ready(Self::from_seed(seed)) + } + + #[track_caller] + fn build<'a>(self) -> Future<'a, 'ctx, Result<Self::Value, Self::Error>, E> + where + Self: 'a, + { + E::ready(self.build()) + } + + #[track_caller] + fn as_visitor(&mut self) -> Visitor<'_, 'ctx> { + self + } +} + +impl<'ctx, Seed, Value, Error> AnyTrait<'ctx> for MockBuilder<Seed, Value, Error> { + #[track_caller] + fn upcast_to_id<'a>(&'a self, id: LtTypeId<'ctx>) -> Option<IndirectLtAny<'a, 'ctx, Ref>> + where + 'ctx: 'a, + { + // Find the first trait handler that wants to upcast. + self.traits(id.as_type_id()) + .as_ref() + .and_then(|t| t.upcast_to_id(id)) + } + + #[track_caller] + fn upcast_to_id_mut<'a: 'b, 'b>( + &'a mut self, + id: LtTypeId<'ctx>, + ) -> Option<IndirectLtAny<'b, 'ctx, Mut>> + where + 'ctx: 'a, + { + // Find the first trait handler that wants to upcast. + self.traits_mut(id.as_type_id()) + .as_mut() + .and_then(|t| t.upcast_to_id_mut(id)) + } +} |