koibumi 0.0.9

An experimental Bitmessage client
use futures::channel::mpsc::Receiver;
use iced::futures;

use koibumi_node::Event;

pub fn bridge(receiver: Receiver<Event>, id: usize) -> iced::Subscription<Event> {
    iced::Subscription::from_recipe(Bridge { receiver, id })
}

struct Bridge {
    receiver: Receiver<Event>,
    id: usize,
}

impl<H, I> iced_native::subscription::Recipe<H, I> for Bridge
where
    H: std::hash::Hasher,
{
    type Output = Event;

    fn hash(&self, state: &mut H) {
        use std::hash::Hash;

        std::any::TypeId::of::<Self>().hash(state);
        self.id.hash(state);
    }

    fn stream(
        self: Box<Self>,
        _input: futures::stream::BoxStream<'static, I>,
    ) -> futures::stream::BoxStream<'static, Self::Output> {
        use futures::stream::StreamExt;

        self.receiver.boxed()
    }
}

pub fn keep_alive(id: usize) -> iced::Subscription<Event> {
    iced::Subscription::from_recipe(KeepAlive { id })
}

struct KeepAlive {
    id: usize,
}

impl<H, I> iced_native::subscription::Recipe<H, I> for KeepAlive
where
    H: std::hash::Hasher,
{
    type Output = Event;

    fn hash(&self, state: &mut H) {
        use std::hash::Hash;

        // generate hash identical to Bridge's
        std::any::TypeId::of::<Bridge>().hash(state);
        self.id.hash(state);
    }

    fn stream(
        self: Box<Self>,
        _input: futures::stream::BoxStream<'static, I>,
    ) -> futures::stream::BoxStream<'static, Self::Output> {
        use futures::stream::StreamExt;

        // this is dummy stream, not used
        futures::stream::once(async { Self::Output::Stopped }).boxed()
    }
}