Skip to main content

rust_toolkit_effects/
lib.rs

1//! Generic support traits for effect vocabularies and concrete handlers.
2//!
3//! This crate contains the portable backing traits used by the toolkit's
4//! `#[effect_trait]` and `#[effect_handler]` proc macros.
5
6#![forbid(unsafe_code)]
7
8mod sealed {
9    pub trait EffectSealed {}
10
11    impl<T> EffectSealed for T where
12        T: ?Sized + crate::__private::EffectDefinition + Send + Sync + 'static
13    {
14    }
15}
16
17/// Marker trait for abstract effect vocabularies.
18///
19/// A trait satisfies `Effect` when an `#[effect_trait]`-style proc macro emits
20/// the hidden `EffectDefinition` witness for its trait object.
21pub trait Effect: sealed::EffectSealed + Send + Sync + 'static {}
22
23impl<T> Effect for T where
24    T: ?Sized + crate::__private::EffectDefinition + Send + Sync + 'static
25{
26}
27
28/// Marker trait for concrete handlers of one effect vocabulary.
29pub trait EffectHandler<E>: Send + Sync + 'static
30where
31    E: ?Sized + Effect,
32    Self: crate::__private::HandlerDefinition<E>,
33{
34}
35
36impl<T, E> EffectHandler<E> for T
37where
38    T: ?Sized + Send + Sync + 'static,
39    E: ?Sized + Effect,
40    T: crate::__private::HandlerDefinition<E>,
41{
42}
43
44/// Hidden support items used by the proc macros.
45#[doc(hidden)]
46pub mod __private {
47    use core::marker::PhantomData;
48
49    pub trait EffectDefinition {}
50
51    pub trait HandlerDefinition<E: ?Sized> {}
52
53    // fn() -> (*const T, *const E) makes both T and E invariant without
54    // introducing the Send/Sync implications of raw pointers.
55    pub struct HandlerToken<T: ?Sized, E: ?Sized>(
56        pub PhantomData<fn() -> (*const T, *const E)>,
57    );
58}