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.
This commit is contained in:
Giacomo Pasini 2022-11-04 13:16:03 +01:00 committed by GitHub
parent 6362735d44
commit d73637eccd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 47 additions and 5 deletions

View File

@ -35,9 +35,16 @@ pub trait StateOperator: Send {
} }
/// Operator that doesn't perform any operation upon state update /// Operator that doesn't perform any operation upon state update
#[derive(Clone, Copy)] #[derive(Copy)]
pub struct NoOperator<StateInput>(PhantomData<StateInput>); pub struct NoOperator<StateInput>(PhantomData<StateInput>);
// auto derive introduces unnecessary Clone bound on T
impl<T> Clone for NoOperator<T> {
fn clone(&self) -> Self {
Self(PhantomData)
}
}
#[async_trait] #[async_trait]
impl<StateInput: ServiceState> StateOperator for NoOperator<StateInput> { impl<StateInput: ServiceState> StateOperator for NoOperator<StateInput> {
type StateInput = StateInput; type StateInput = StateInput;
@ -50,9 +57,16 @@ impl<StateInput: ServiceState> StateOperator for NoOperator<StateInput> {
} }
/// Empty state /// Empty state
#[derive(Clone, Copy)] #[derive(Copy)]
pub struct NoState<Settings>(PhantomData<Settings>); pub struct NoState<Settings>(PhantomData<Settings>);
// auto derive introduces unnecessary Clone bound on T
impl<T> Clone for NoState<T> {
fn clone(&self) -> Self {
Self(PhantomData)
}
}
impl<Settings: Send + Sync + 'static> ServiceState for NoState<Settings> { impl<Settings: Send + Sync + 'static> ServiceState for NoState<Settings> {
type Settings = Settings; type Settings = Settings;
@ -64,25 +78,53 @@ impl<Settings: Send + Sync + 'static> ServiceState for NoState<Settings> {
/// Receiver part of the state handling mechanism. /// Receiver part of the state handling mechanism.
/// A state handle watches a stream of incoming states and triggers the attached operator handling /// A state handle watches a stream of incoming states and triggers the attached operator handling
/// method over it. /// method over it.
#[derive(Clone)]
pub struct StateHandle<S: ServiceState, Operator: StateOperator<StateInput = S>> { pub struct StateHandle<S: ServiceState, Operator: StateOperator<StateInput = S>> {
watcher: StateWatcher<S>, watcher: StateWatcher<S>,
operator: Operator, operator: Operator,
} }
// auto derive introduces unnecessary Clone bound on T
impl<S: ServiceState, Operator: StateOperator<StateInput = S>> Clone for StateHandle<S, Operator>
where
Operator: Clone,
{
fn clone(&self) -> Self {
Self {
watcher: self.watcher.clone(),
operator: self.operator.clone(),
}
}
}
/// Sender part of the state handling mechanism. /// Sender part of the state handling mechanism.
/// Update the current state and notifies the [`StateHandle`]. /// Update the current state and notifies the [`StateHandle`].
#[derive(Clone)]
pub struct StateUpdater<S> { pub struct StateUpdater<S> {
sender: Arc<Sender<S>>, sender: Arc<Sender<S>>,
} }
// auto derive introduces unnecessary Clone bound on T
impl<T> Clone for StateUpdater<T> {
fn clone(&self) -> Self {
Self {
sender: self.sender.clone(),
}
}
}
/// Wrapper over [`tokio::sync::watch::Receiver`] /// Wrapper over [`tokio::sync::watch::Receiver`]
#[derive(Clone)]
pub struct StateWatcher<S> { pub struct StateWatcher<S> {
receiver: Receiver<S>, receiver: Receiver<S>,
} }
// auto derive introduces unnecessary Clone bound on T
impl<T> Clone for StateWatcher<T> {
fn clone(&self) -> Self {
Self {
receiver: self.receiver.clone(),
}
}
}
impl<S: ServiceState> StateUpdater<S> { impl<S: ServiceState> StateUpdater<S> {
/// Send a new state and notify the [`StateWatcher`] /// Send a new state and notify the [`StateWatcher`]
pub fn update(&mut self, new_state: S) { pub fn update(&mut self, new_state: S) {