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
#[derive(Clone, Copy)]
#[derive(Copy)]
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]
impl<StateInput: ServiceState> StateOperator for NoOperator<StateInput> {
type StateInput = StateInput;
@ -50,9 +57,16 @@ impl<StateInput: ServiceState> StateOperator for NoOperator<StateInput> {
}
/// Empty state
#[derive(Clone, Copy)]
#[derive(Copy)]
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> {
type Settings = Settings;
@ -64,25 +78,53 @@ impl<Settings: Send + Sync + 'static> ServiceState for NoState<Settings> {
/// 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<S: ServiceState, Operator: StateOperator<StateInput = S>> {
watcher: StateWatcher<S>,
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.
/// Update the current state and notifies the [`StateHandle`].
#[derive(Clone)]
pub struct StateUpdater<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`]
#[derive(Clone)]
pub struct StateWatcher<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> {
/// Send a new state and notify the [`StateWatcher`]
pub fn update(&mut self, new_state: S) {