potential 3.0.1

PubSub lib with sync and async API
Documentation
#![doc = include_str!("../README.md")]
#![deny(unsafe_code)]

use crate::sync::{Pub as Sender, Sub as Receiver};
use notify::Notify;
use std::fmt::Debug;

pub mod future;
//mod lock;
mod notify;
pub mod stream;
pub mod sync;

/// The publishing part of the pipework
#[derive(Debug)]
pub struct Pub<T> {
    inner: Sender<T>,
    wakers: Receiver<Notify>,
}
impl<T> Clone for Pub<T> {
    fn clone(&self) -> Self {
        Self {
            inner: self.inner.clone(),
            wakers: self.wakers.clone(),
        }
    }
}
impl<T> Default for Pub<T> {
    fn default() -> Self {
        Self {
            inner: Sender::default(),
            wakers: Receiver::default(),
        }
    }
}
impl<T> Drop for Pub<T> {
    fn drop(&mut self) {
        self.notify();
    }
}
impl<T: Clone> Pub<T> {
    pub fn subscribe(&self) -> Sub<T> {
        Sub {
            inner: self.inner.subscribe(),
            wakers: self.wakers.publish(),
        }
    }

    pub fn push(&mut self, value: T) -> bool {
        let pushed = self.inner.push(value);
        self.notify();
        pushed
    }
}

/// The consuming part of the pipework
#[derive(Debug)]
pub struct Sub<T> {
    inner: Receiver<T>,
    wakers: Sender<Notify>,
}
impl<T> Clone for Sub<T> {
    fn clone(&self) -> Self {
        Self {
            inner: self.inner.clone(),
            wakers: self.wakers.clone(),
        }
    }
}
impl<T> Default for Sub<T> {
    fn default() -> Self {
        Self {
            inner: Default::default(),
            wakers: Default::default(),
        }
    }
}
impl<T: Clone> Sub<T> {
    pub fn publish(&self) -> Pub<T> {
        Pub {
            inner: self.inner.publish(),
            wakers: self.wakers.subscribe(),
        }
    }
    pub fn try_pop(&mut self) -> Result<T, TryPopError> {
        self.inner.try_pop()
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TryPopError {
    Empty,
    Finished,
}
impl std::error::Error for TryPopError {}
impl std::fmt::Display for TryPopError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            TryPopError::Empty => {
                f.write_str("The subscription reached the end, but there still some publishers")
            }
            TryPopError::Finished => {
                f.write_str("The subscription reached the end and there are no publishers left")
            }
        }
    }
}