escvpnet 0.3.3

ESC/VP.net protocol library
Documentation
use std::{ pin::Pin, str::FromStr};

use async_trait::async_trait;
use tokio::io::{AsyncReadExt, AsyncBufReadExt, BufReader, AsyncWriteExt};

use crate::{
    error::ErrorKind,
    io::{DecodeFrom, EncodeTo},
};
#[derive(Debug, Clone, PartialEq)]
pub enum Command {
    Get { name: String },
    Set { name: String, value: String },
}

impl FromStr for Command {
    type Err = crate::Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let s = s.trim_end();
        if s.contains("?") {
            let mut parts = s.split('?');
            let name = parts.next().ok_or(crate::Error::new(
                ErrorKind::Decoding,
                "Failed to decode command".to_string(),
            ))?;
            Ok(Self::Get {
                name: name.to_string(),
            })
        } else {
            let mut parts = s.split(' ');
            let name = parts.next().ok_or(crate::Error::new(
                ErrorKind::Decoding,
                "Failed to decode command".to_string(),
            ))?;
            let value = parts.next().ok_or(crate::Error::new(
                ErrorKind::Decoding,
                "Failed to decode command".to_string(),
            ))?;
            Ok(Self::Set {
                name: name.to_string(),
                value: value.to_string(),
            })
        }
    }
}
#[async_trait]
impl<R: AsyncReadExt+Send> DecodeFrom<R> for Command {
    type Error = crate::Error;
    async fn decode_from(reader: &mut Pin<&mut R>) -> Result<Self, Self::Error> {
        let mut reader = BufReader::new(reader);
        let mut buf = String::new();
        reader.read_line(&mut buf).await?;
        buf.parse()

    }
}
#[async_trait]
impl<W: AsyncWriteExt+Send> EncodeTo<W> for Command {
    type Error = crate::Error;
    async fn encode_to(self, writer: &mut Pin<&mut W>) -> Result<usize, Self::Error> {
        let command = match self {
            Self::Get { name } => {
                format!("{name}?\n")
            }
            Self::Set { name, value } => {
                format!("{name} {value}\n")
            }
        };
        writer.write_all(command.as_bytes()).await?;
        Ok(command.len())
    }
}

pub struct Response {
    name: String,
    value: String,
}

impl Response {
    pub fn name(&self) -> &str {
        self.name.as_ref()
    }

    pub fn value(&self) -> &str {
        self.value.as_ref()
    }
}
#[async_trait]
impl<R: AsyncReadExt+ Send> DecodeFrom<R> for Response {
    type Error = crate::Error;
    async fn decode_from(reader: &mut Pin<&mut R>) -> Result<Self, Self::Error> {
        let mut buf_reader = BufReader::new(reader);
        let mut buf = String::new();
        buf_reader.read_line(&mut buf).await?;
        let mut parts = buf.split("=");
        let name = parts
            .next()
            .ok_or(crate::Error::new(
                ErrorKind::Decoding,
                "Failed to decode response".to_string(),
            ))?
            .to_string();
        let value = parts
            .next()
            .ok_or(crate::Error::new(
                ErrorKind::Decoding,
                "Failed to decode response".to_string(),
            ))?
            .to_string();

        Ok(Self { name, value })
    }
}
#[cfg(test)]
mod tests {
use super::*;
    #[test]
    fn command() {
        let data = "PWR?\n";
        let command = Command::Get { name: "PWR".to_string() };
        let decoded_command:Command = data.parse().unwrap();
        assert_eq!(decoded_command, command);

        let data = "PWR ON\n";
        let command = Command::Set { name: "PWR".to_string(), value: "ON".to_string() } ;
        let decoded_command:Command = data.parse().unwrap();
        assert_eq!(decoded_command, command)

    }
}