gol-renderer 1.0.0

Renderer for gol-client.
Documentation
use tokio::sync::broadcast::{self, error::TryRecvError, Receiver, Sender};

pub struct KeyboardControl {
    sender: Sender<char>,
    receiver: Receiver<char>,
    is_receive_only: bool,
}

impl Clone for KeyboardControl {
    fn clone(&self) -> Self {
        let sender = self.sender.clone();
        let receiver = sender.subscribe();
        Self {
            sender,
            receiver,
            is_receive_only: self.is_receive_only,
        }
    }
}

impl KeyboardControl {
    pub fn new() -> Self {
        let (sender, receiver) = broadcast::channel(1);
        Self {
            sender,
            receiver,
            is_receive_only: false,
        }
    }

    pub fn is_receive_only(&self) -> bool {
        self.is_receive_only
    }

    pub fn broadcast(&self, ch: char) {
        if self.is_receive_only() {
            panic!("Cannot broadcast keyboard input on receive only control.");
        }
        self.sender.send(ch).unwrap();
    }

    pub fn receive(&mut self) -> char {
        loop {
            let res = self.try_receive();
            match res {
                Some(val) => return val,
                None => continue,
            }
        }
    }

    pub fn try_receive(&mut self) -> Option<char> {
        match self.receiver.try_recv() {
            Ok(val) => Some(val),
            Err(err) => match err {
                TryRecvError::Empty => None,
                TryRecvError::Closed => {
                    eprintln!("Error processing keyboard input: {}", err);
                    None
                }
                TryRecvError::Lagged(_) => None,
            },
        }
    }

    pub fn clone_receive_only(&self) -> Self {
        let sender = self.sender.clone();
        let receiver = sender.subscribe();
        Self {
            sender,
            receiver,
            is_receive_only: true,
        }
    }
}