flic-rust-client 0.4.0

Flic 2 Button Client Library written in Rust
Documentation
use tokio::io::*;
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
use tokio::net::TcpStream;
use tokio::sync::Mutex;

use super::commands::stream_mapper::CommandToByteMapper;
use super::commands::Command;
use super::events::stream_mapper::*;
use super::events::Event;

pub fn event_handler<F>(f: F) -> EventClosureMutex
where
    F: FnMut(&Event) + Sync + Send + 'static,
{
    Box::new(f)
}

type EventClosure = dyn FnMut(&Event) + Sync + Send + 'static;
type EventClosureMutex = Box<EventClosure>;

pub struct FlicClient {
    reader: Mutex<OwnedReadHalf>,
    writer: Mutex<OwnedWriteHalf>,
    is_running: Mutex<bool>,
    command_mapper: Mutex<CommandToByteMapper>,
    event_mapper: Mutex<ByteToEventMapper>,
    handlers: Mutex<Vec<EventClosureMutex>>,
}

impl FlicClient {
    pub async fn new(conn: &str) -> Result<FlicClient> {
        TcpStream::connect(conn)
            .await
            .map(|s| s.into_split())
            .map(|(reader, writer)| FlicClient {
                reader: Mutex::new(reader),
                writer: Mutex::new(writer),
                is_running: Mutex::new(true),
                command_mapper: Mutex::new(CommandToByteMapper::new()),
                event_mapper: Mutex::new(ByteToEventMapper::new()),
                handlers: Mutex::new(vec![]),
            })
    }
    pub async fn register_event_handler(self, event: EventClosureMutex) -> Self {
        self.handlers.lock().await.push(event);
        self
    }

    pub async fn listen(&self) {
        while *self.is_running.lock().await {
            let mut reader = self.reader.lock().await;
            let mut buffer = vec![0; 2048];

            let size = reader.read(&mut buffer).await;

            match size {
                Ok(size) if size > 0 => {
                    buffer.truncate(size);
                    for b in buffer.iter() {
                        match self.event_mapper.lock().await.map(*b) {
                            EventResult::Some(Event::NoOp) => { }
                            EventResult::Some(event) => {
                                self.handlers
                                    .lock()
                                    .await
                                    .iter_mut()
                                    .for_each(|handler| handler(&event))
                            }
                            _ => {}
                        }
                    }
                }
                Ok(_) => {
                    tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
                }
                Err(e) => {
                    eprintln!("Error reading from reader: {}", e);
                    break;
                }
            }
        }
    }

    pub async fn stop(&self) {
        *self.is_running.lock().await = false;
    }

    pub async fn submit(&self, cmd: Command) {
        let mut writer = self.writer.lock().await;
        for b in self.command_mapper.lock().await.map(cmd) {
            let _ = writer.write_u8(b).await;
        }
    }
}