From d73637eccd0191503730055d3cdab67d8c84afeb Mon Sep 17 00:00:00 2001 From: Giacomo Pasini Date: Fri, 4 Nov 2022 13:16:03 +0100 Subject: [PATCH] Manually derive Clone (#6) Current derive(Clone) macro adds bounds on generic parameters which are sometimes unnecessary and overly restrictive. While we wait for perfect derive to be available, let's manually derive Clone. --- overwatch/src/services/state.rs | 52 +++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/overwatch/src/services/state.rs b/overwatch/src/services/state.rs index 3469433..5c9e7ab 100644 --- a/overwatch/src/services/state.rs +++ b/overwatch/src/services/state.rs @@ -35,9 +35,16 @@ pub trait StateOperator: Send { } /// Operator that doesn't perform any operation upon state update -#[derive(Clone, Copy)] +#[derive(Copy)] pub struct NoOperator(PhantomData); +// auto derive introduces unnecessary Clone bound on T +impl Clone for NoOperator { + fn clone(&self) -> Self { + Self(PhantomData) + } +} + #[async_trait] impl StateOperator for NoOperator { type StateInput = StateInput; @@ -50,9 +57,16 @@ impl StateOperator for NoOperator { } /// Empty state -#[derive(Clone, Copy)] +#[derive(Copy)] pub struct NoState(PhantomData); +// auto derive introduces unnecessary Clone bound on T +impl Clone for NoState { + fn clone(&self) -> Self { + Self(PhantomData) + } +} + impl ServiceState for NoState { type Settings = Settings; @@ -64,25 +78,53 @@ impl ServiceState for NoState { /// Receiver part of the state handling mechanism. /// A state handle watches a stream of incoming states and triggers the attached operator handling /// method over it. -#[derive(Clone)] pub struct StateHandle> { watcher: StateWatcher, operator: Operator, } +// auto derive introduces unnecessary Clone bound on T +impl> Clone for StateHandle +where + Operator: Clone, +{ + fn clone(&self) -> Self { + Self { + watcher: self.watcher.clone(), + operator: self.operator.clone(), + } + } +} + /// Sender part of the state handling mechanism. /// Update the current state and notifies the [`StateHandle`]. -#[derive(Clone)] pub struct StateUpdater { sender: Arc>, } +// auto derive introduces unnecessary Clone bound on T +impl Clone for StateUpdater { + fn clone(&self) -> Self { + Self { + sender: self.sender.clone(), + } + } +} + /// Wrapper over [`tokio::sync::watch::Receiver`] -#[derive(Clone)] pub struct StateWatcher { receiver: Receiver, } +// auto derive introduces unnecessary Clone bound on T +impl Clone for StateWatcher { + fn clone(&self) -> Self { + Self { + receiver: self.receiver.clone(), + } + } +} + impl StateUpdater { /// Send a new state and notify the [`StateWatcher`] pub fn update(&mut self, new_state: S) {