nihility-rpc 0.1.1

nihility project rpc module
Documentation
use crate::error::NihilityRpcError;
use prost::Message;
use std::ops::Deref;

tonic::include_proto!("nihility.execute");

#[derive(Debug, Clone)]
pub enum AudioEndiannessType {
    LittleEndian,
    BigEndian,
}

#[derive(Debug, Clone)]
pub struct AudioData {
    pub sample_rate: u32,
    pub sample_size: u32,
    pub channels: u32,
    pub sign: bool,
    pub byte_order: AudioEndiannessType,
    pub data: Vec<f32>,
}

#[derive(Debug, Clone)]
pub enum ExecuteData {
    String(String),
    Audio(AudioData),
}

impl TryFrom<ExecuteRequest> for ExecuteData {
    type Error = NihilityRpcError;

    fn try_from(value: ExecuteRequest) -> Result<Self, Self::Error> {
        match value.r#type() {
            ExecuteType::String => Ok(ExecuteData::String(String::from_utf8(value.payload)?)),
            ExecuteType::Audio => Ok(ExecuteData::Audio(
                AudioChunk::decode(value.payload.deref())?.into(),
            )),
        }
    }
}

impl From<ExecuteData> for ExecuteRequest {
    fn from(value: ExecuteData) -> Self {
        match value {
            ExecuteData::String(string_value) => ExecuteRequest {
                r#type: ExecuteType::String.into(),
                payload: string_value.into_bytes(),
            },
            ExecuteData::Audio(audio_data) => ExecuteRequest {
                r#type: ExecuteType::Audio.into(),
                payload: AudioChunk::from(audio_data).encode_to_vec(),
            },
        }
    }
}

impl TryFrom<ExecuteResponse> for ExecuteData {
    type Error = NihilityRpcError;

    fn try_from(value: ExecuteResponse) -> Result<Self, Self::Error> {
        match value.r#type() {
            ExecuteType::String => Ok(ExecuteData::String(String::from_utf8(value.payload)?)),
            ExecuteType::Audio => Ok(ExecuteData::Audio(
                AudioChunk::decode(value.payload.deref())?.into(),
            )),
        }
    }
}

impl From<ExecuteData> for ExecuteResponse {
    fn from(value: ExecuteData) -> Self {
        match value {
            ExecuteData::String(string_value) => ExecuteResponse {
                r#type: ExecuteType::String.into(),
                payload: string_value.into_bytes(),
            },
            ExecuteData::Audio(audio_data) => ExecuteResponse {
                r#type: ExecuteType::Audio.into(),
                payload: AudioChunk::from(audio_data).encode_to_vec(),
            },
        }
    }
}

impl From<AudioData> for AudioChunk {
    fn from(value: AudioData) -> Self {
        AudioChunk {
            sample_rate: value.sample_rate,
            sample_size: value.sample_size,
            channels: value.channels,
            sign: value.sign,
            byte_order: match value.byte_order {
                AudioEndiannessType::LittleEndian => AudioEndianness::Little.into(),
                AudioEndiannessType::BigEndian => AudioEndianness::Big.into(),
            },
            data: value.data,
        }
    }
}

impl From<AudioChunk> for AudioData {
    fn from(value: AudioChunk) -> Self {
        AudioData {
            sample_rate: value.sample_rate,
            sample_size: value.sample_size,
            channels: value.channels,
            sign: value.sign,
            byte_order: match value.byte_order() {
                AudioEndianness::Big => AudioEndiannessType::BigEndian,
                AudioEndianness::Little => AudioEndiannessType::LittleEndian,
            },
            data: value.data,
        }
    }
}

impl Default for AudioData {
    fn default() -> Self {
        AudioData {
            sample_rate: 32000,
            sample_size: 16,
            channels: 1,
            sign: true,
            byte_order: AudioEndiannessType::LittleEndian,
            data: vec![],
        }
    }
}