-
Notifications
You must be signed in to change notification settings - Fork 3
Description
A backend wrapper could be created that is parameterized by an allow-list which statically prevents things from being sent/received that shouldn't be.
First, this setup would let you define a new marker type and enumerate a specific set of types which are allowed on the "allow list" denoted by that type.
/// A marker type standing in for allowing every type to be serialized/deserialized.
pub struct AllowAll;
/// A marker trait that indicates whether or not the type `T` belongs to the allow-list `Self`.
pub trait Allow<T> {}
/// The `AllowAll` marker type allows all types.
impl<T> Allow<T> for AllowAll {}You would use it like so:
pub struct OnlyByteAndBool;
impl Allow<u8> for OnlyByteAndBool {}
impl Allow<bool> for OnlyByteAndBool {}Because of trait coherence rules, nobody outside the crate in which OnlyByteAndBool can add another impl for OnlyByteAndBool: Allow<T> for some new T.
Then, this abstraction can be used to implement a general restriction mechanism for backends:
#[repr(transparent)]
struct Restricted<T, List = AllowAll>{
inner: T,
list: PhantomData<fn() -> List>,
}Then, we would implement all the backend traits, forwarding their implementations, for Restricted, except adding the clause where List: Allow<T> to each impl.
Edited from the comment posted by @kwf in #107 (comment)