use binrw::{BinWrite, binread};
use crate::protocol::{Error, Exception, Function, function, r#struct::Writable};
#[derive(Copy, Clone, BinWrite)]
#[bw(big)]
pub struct Request<T: Writable> {
pub function_code: function::Code,
pub args: T,
}
impl<T: Writable> Request<T> {
pub const fn wrap<F: Function<Args = T>>(args: T) -> Self {
Self { function_code: F::CODE, args }
}
}
#[binread]
#[br(big)]
#[derive(Copy, Clone)]
pub enum Response<F: Function> {
Ok {
#[br(temp, assert(function_code == F::CODE))]
function_code: function::Code,
output: F::Output,
},
Exception {
#[br(temp, assert(function_code == F::CODE.with_error_flag()))]
function_code: u8,
exception: Exception,
},
}
impl<F: Function> Response<F> {
pub fn into_result(self) -> Result<F::Output, Error> {
match self {
Self::Ok { output, .. } => Ok(output),
Self::Exception { exception, .. } => Err(Error::Exception(exception)),
}
}
}