#![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 notify;
pub mod stream;
pub mod sync;
#[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
}
}
#[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")
}
}
}
}