use crate::services::lfo::CompressionFormats;
use crate::services::{DEFAULT_AID_HEX, DEFAULT_CID_HEX};
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct LfoRequest {
pub(crate) cid: [u8; 16],
pub(crate) aid: [u8; 16],
pub(crate) compression: u16,
pub(crate) remote_path: String,
pub(crate) offset: u32,
}
impl LfoRequest {
pub fn new_simple(remote_path: String) -> Self {
Self {
cid: hex::decode(DEFAULT_CID_HEX).unwrap().try_into().unwrap(),
aid: hex::decode(DEFAULT_AID_HEX).unwrap().try_into().unwrap(),
compression: 0,
remote_path,
offset: 0,
}
}
pub fn new_custom(
cid: [u8; 16],
aid: [u8; 16],
compression: CompressionFormats,
remote_path: String,
) -> Self {
Self {
cid,
aid,
compression: compression as u16,
remote_path,
offset: 0,
}
}
pub(crate) fn to_payload(&self) -> Vec<u8> {
let mut payload = vec![];
payload.extend_from_slice(&self.cid); payload.extend_from_slice(&self.aid); payload.extend_from_slice(8u32.to_be_bytes().as_slice());
payload.extend_from_slice(&self.offset.to_be_bytes());
payload.extend_from_slice(&self.compression.to_be_bytes());
payload.extend_from_slice(self.remote_path.as_bytes());
payload
}
#[cfg(test)]
pub(crate) fn try_from_payload(payload: &[u8]) -> Result<Self, super::LfoError> {
use super::LfoError;
use byteorder::{ReadBytesExt, BE};
use std::io::Read;
let mut cursor = std::io::Cursor::new(payload);
let mut cid = [0u8; 16];
cursor.read_exact(&mut cid)?;
let mut aid = [0u8; 16];
cursor.read_exact(&mut aid)?;
_ = cursor.read_u32::<BE>()?;
let offset = cursor.read_u32::<BE>()?;
let compression = cursor.read_u16::<BE>()?;
let remote_path = String::from_utf8(payload[cursor.position() as usize..].into())
.map_err(|_| LfoError::InvalidRequest)?;
Ok(Self {
cid,
aid,
compression,
remote_path,
offset,
})
}
}