use crate::{DtcSettings, Error, SUCCESS, SingleValueWireFormat, WireFormat};
use byteorder::{ReadBytesExt, WriteBytesExt};
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Clone, Copy, Debug, PartialEq)]
#[non_exhaustive]
pub struct ControlDTCSettingsRequest {
pub setting: DtcSettings,
pub suppress_response: bool,
}
impl ControlDTCSettingsRequest {
pub(crate) fn new(setting: DtcSettings, suppress_response: bool) -> Self {
Self {
setting,
suppress_response,
}
}
}
impl WireFormat for ControlDTCSettingsRequest {
fn decode<T: std::io::Read>(reader: &mut T) -> Result<Option<Self>, Error> {
let request_byte = reader.read_u8()?;
let setting = DtcSettings::from(request_byte & !SUCCESS);
let suppress_response = request_byte & SUCCESS != 0;
Ok(Some(Self {
setting,
suppress_response,
}))
}
fn required_size(&self) -> usize {
1
}
fn encode<T: std::io::Write>(&self, writer: &mut T) -> Result<usize, Error> {
let request_byte =
u8::from(self.setting) | if self.suppress_response { SUCCESS } else { 0 };
writer.write_u8(request_byte)?;
Ok(1)
}
fn is_positive_response_suppressed(&self) -> bool {
self.suppress_response
}
}
impl SingleValueWireFormat for ControlDTCSettingsRequest {}
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Clone, Copy, Debug, PartialEq)]
#[non_exhaustive]
pub struct ControlDTCSettingsResponse {
pub setting: DtcSettings,
}
impl ControlDTCSettingsResponse {
pub(crate) fn new(setting: DtcSettings) -> Self {
Self { setting }
}
}
impl WireFormat for ControlDTCSettingsResponse {
fn decode<T: std::io::Read>(reader: &mut T) -> Result<Option<Self>, Error> {
let setting = DtcSettings::from(reader.read_u8()?);
Ok(Some(Self { setting }))
}
fn required_size(&self) -> usize {
1
}
fn encode<T: std::io::Write>(&self, writer: &mut T) -> Result<usize, Error> {
writer.write_u8(u8::from(self.setting))?;
Ok(1)
}
}
impl SingleValueWireFormat for ControlDTCSettingsResponse {}
#[cfg(test)]
mod request {
use super::*;
use crate::DtcSettings;
#[test]
fn simple_request() {
let req = ControlDTCSettingsRequest::new(DtcSettings::On, true);
let mut buffer = Vec::new();
let written = req.encode(&mut buffer).unwrap();
assert_eq!(buffer, vec![0x81]);
assert_eq!(written, buffer.len());
assert_eq!(req.required_size(), buffer.len());
let parsed =
ControlDTCSettingsRequest::decode_single_value(&mut buffer.as_slice()).unwrap();
assert_eq!(parsed.setting, DtcSettings::On);
assert!(parsed.suppress_response);
}
}
#[cfg(test)]
mod response {
use super::*;
use crate::DtcSettings;
#[test]
fn simple_response() {
let req = ControlDTCSettingsResponse::new(DtcSettings::On);
let mut buffer = Vec::new();
let written = req.encode(&mut buffer).unwrap();
assert_eq!(buffer, vec![0x01]);
assert_eq!(written, buffer.len());
assert_eq!(req.required_size(), buffer.len());
let parsed =
ControlDTCSettingsResponse::decode_single_value(&mut buffer.as_slice()).unwrap();
assert_eq!(parsed.setting, DtcSettings::On);
}
}