tnnl 0.1.17

tnnl gives you full control over whether and when your IoT devices should be reachable from the internet
use tokio::sync::mpsc::Receiver;
use tokio::sync::mpsc::Sender;

use crate::{apperror::AppError, model::packet::Packet};

pub struct Channel {
    channel_id: i32,
    sender: Sender<Vec<u8>>,
    receiver: Receiver<Vec<u8>>,
}

pub struct ChannelReadHalf {
    receiver: Receiver<Vec<u8>>,
}

pub struct ChannelWriteHalf {
    channel_id: i32,
    sender: Sender<Vec<u8>>,
}

impl Channel {
    pub fn new(sender: Sender<Vec<u8>>, receiver: Receiver<Vec<u8>>, channel_id: i32) -> Channel {
        Channel {
            channel_id,
            sender,
            receiver,
        }
    }

    pub async fn send(&self, data: &[u8]) -> Result<(), AppError> {
        let packet = Packet::serialize(self.channel_id, data)?;

        self.sender
            .send(packet)
            .await
            .map_err(|_| AppError::new("failed to post data to send channel"))?;
        Ok(())
    }

    pub async fn close(&self) -> Result<(), AppError> {
        self.send(&[]).await
    }

    pub fn split(self) -> (ChannelReadHalf, ChannelWriteHalf) {
        (
            ChannelReadHalf {
                receiver: self.receiver,
            },
            ChannelWriteHalf {
                channel_id: self.channel_id,
                sender: self.sender,
            },
        )
    }
}

impl ChannelReadHalf {
    pub async fn recv(&mut self) -> Option<Vec<u8>> {
        self.receiver.recv().await
    }
}

impl ChannelWriteHalf {
    pub async fn send(&self, data: &[u8]) -> Result<(), AppError> {
        let packet = Packet::serialize(self.channel_id, data)?;

        self.sender
            .send(packet)
            .await
            .map_err(|_| AppError::new("failed to post data to send channel"))?;
        Ok(())
    }

    pub async fn close(&self) -> Result<(), AppError> {
        self.send(&[]).await
    }
}