nimiq-utils 0.2.0

Various utilities (e.g., CRC, Merkle proofs, timers) for Nimiq's Rust implementation
Documentation
use std::sync::{Weak, Arc};

pub trait Listener<E>: Send + Sync {
    fn on_event(&self, event: &E);
}

impl<E, F: Fn(&E)> Listener<E> for F
    where F: Send + Sync {
    fn on_event(&self, event: &E) {
        self(event);
    }
}

pub type ListenerHandle = usize;

#[derive(Default)]
pub struct Notifier<'l, E> {
    listeners: Vec<(ListenerHandle, Box<dyn Listener<E> + 'l>)>,
    next_handle: ListenerHandle
}

impl<'l, E> Notifier<'l, E> {
    pub fn new() -> Self {
        Self {
            listeners: Vec::new(),
            next_handle: 0,
        }
    }

    pub fn register<T: Listener<E> + 'l>(&mut self, listener: T) -> ListenerHandle {
        let handle = self.next_handle;
        self.listeners.push((handle, Box::new(listener)));
        self.next_handle += 1;
        handle
    }

    pub fn deregister(&mut self, handle: ListenerHandle) {
        for (i, (stored_handle, _)) in self.listeners.iter().enumerate() {
            if handle == *stored_handle {
                self.listeners.remove(i);
                return;
            }
        }
    }

    pub fn notify(&self, event: E) {
        for (_, listener) in &self.listeners {
            listener.on_event(&event);
        }
    }
}


pub fn weak_listener<T, E, C>(weak_ref: Weak<T>, closure: C) -> impl Listener<E>
    where C: Fn(Arc<T>, &E) + Send + Sync, T: Send + Sync {
    move |event: &E| {
        if let Some(arc) = weak_ref.upgrade() {
            closure(arc, event);
        }
    }
}

pub fn weak_passthru_listener<T, E, C>(weak_ref: Weak<T>, closure: C) -> impl PassThroughListener<E>
    where C: Fn(Arc<T>, E) + Send + Sync, T: Send + Sync {
    move |event: E| {
        if let Some(arc) = weak_ref.upgrade() {
            closure(arc, event);
        }
    }
}

pub trait PassThroughListener<E>: Send + Sync {
    fn on_event(&self, event: E);
}

impl<E, F: Fn(E)> PassThroughListener<E> for F
    where F: Send + Sync {
    fn on_event(&self, event: E) {
        self(event);
    }
}

#[derive(Default)]
pub struct PassThroughNotifier<'l, E> {
    listener: Option<Box<dyn PassThroughListener<E> + 'l>>,
}

impl<'l, E> PassThroughNotifier<'l, E> {
    pub fn new() -> Self {
        Self {
            listener: None,
        }
    }

    pub fn register<T: PassThroughListener<E> + 'l>(&mut self, listener: T) {
        self.listener = Some(Box::new(listener));
    }

    pub fn deregister(&mut self) {
        self.listener = None;
    }

    pub fn notify(&self, event: E) {
        if let Some(ref listener) = self.listener {
            listener.on_event(event);
        }
    }
}