From e657b72bcffd06c83e84397eee69a953177dfab1 Mon Sep 17 00:00:00 2001 From: Avril Date: Mon, 12 Apr 2021 14:24:19 +0100 Subject: [PATCH] added AsRef/Mut impls for 'dyn AsyncWrite + Unpin' when 'S' is 'Unpin' for convenience --- src/dual.rs | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/dual.rs b/src/dual.rs index 7053426..e07d50c 100644 --- a/src/dual.rs +++ b/src/dual.rs @@ -17,17 +17,47 @@ use std::{ bool_type!(pub Encrypted; "Is the value encrypted?"); bool_type!(pub Encryption; "What way are we en/decrypting?" => Encrypt, Decrypt); +/// A wrapper `AsyncWrite` stream that allows switching between encrypted (chacha20stream) and plain stream writing. +/// +/// # Polymorphic dispatching +/// While this type implements `AsyncWrite` itself, it is recommended to use the polymorphic mutable reference returned by `as_dyn_unpin_mut()` (or `as_dyn_mut()` for non-`Unpin` values of `S`) for writing if lots of `AsyncWrite` methods will be dispatched on the instance. +/// This will prevent the need to check the discriminant of the enum each time the `DualStream`'s `AsyncWrite` methods are polled. +/// The type implements `AsRef/Mut` for streams `S` that are both `Unpin` and not `Unpin` for convenience. #[derive(Debug)] -pub enum DualStream +pub enum DualStream { /// If there is a panic while switching modes, the stream is left in this invariant state. + /// + /// Stream `S` is dropped if the instance is in this state. Poisoned, - + + /// Stream `S` is being written to through a chacha20stream `AsyncSink` stream cipher. Encrypted(AsyncSink), + /// Stream `S` is being written to directly. Plain(S), } -// We can use dynamic dispatching to prevent the need to check the enum's discriminant each time. (In theory. It might not be that useful unless we add `Unpin` here too. TODO: Check this later.) +// We can use dynamic dispatching to prevent the need to check the enum's discriminant each time. +// We have `AsRef/Mut`s for normal and `Unpin` polymorphic `AsyncWrite`s +impl<'a, S: AsyncWrite + Unpin> AsRef for DualStream +where S: 'a +{ + fn as_ref(&self) -> &(dyn AsyncWrite + Unpin + 'a) + { + self.as_dyn_unpin() + } +} + +impl<'a, S: AsyncWrite + Unpin> AsMut for DualStream +where S: 'a +{ + fn as_mut(&mut self) -> &mut (dyn AsyncWrite + Unpin + 'a) + { + self.as_dyn_unpin_mut() + } +} + + impl<'a, S: AsyncWrite> AsRef for DualStream where S: 'a {