use std::boxed::Box;
use std::hash::Hasher;
use async_channel::Receiver;
use std::hash::Hash;
use std::any::TypeId;
use iced_futures::subscription::Recipe;
use iced_futures::futures::stream::unfold;
use iced_futures::futures::stream::BoxStream;
use crate::error::GuiError;
use crate::messages::RenderMessage;
use crate::messages::Page;
enum State
{
Running(Receiver<RenderMessage>),
Terminate
}
pub struct MessageQueue
{
pub channel: Receiver<RenderMessage>
}
impl <H: Hasher, I> Recipe<H, I> for MessageQueue
{
type Output = RenderMessage;
fn hash(&self, state: &mut H)
{
TypeId::of::<Self>().hash(state);
}
fn stream(self: Box<Self>, _: BoxStream<'static, I>) -> BoxStream<'static, Self::Output>
{
return Box::pin(unfold(State::Running(self.channel), |state| async move
{
match state
{
State::Running(channel) =>
{
match channel.recv().await
{
Ok(msg) =>
{
match msg
{
RenderMessage::SwitchPage(Page::Finish(_)) => return Some((msg, State::Terminate)),
RenderMessage::SwitchPage(Page::Error(_)) => return Some((msg, State::Terminate)),
_ => return Some((msg, State::Running(channel)))
};
},
Err(e) => return Some((RenderMessage::SwitchPage(Page::Error(GuiError::channel_recv(e))), State::Terminate))
};
},
State::Terminate =>
{
let _: () = iced::futures::future::pending().await;
return None;
}
}
}));
}
}