Skip to content

Commit

Permalink
types: expand switch data command
Browse files Browse the repository at this point in the history
  • Loading branch information
johnlettman committed Aug 16, 2024
1 parent 40d9b6e commit 94a1afb
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 14 deletions.
4 changes: 2 additions & 2 deletions src/switch_data.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::types::{RangeIndex, Reverse};
use crate::types::{Command, RangeIndex};
use binrw::{BinRead, BinWrite};

#[derive(Debug, BinRead, BinWrite)]
Expand All @@ -9,5 +9,5 @@ pub struct SwitchData {
range_index: RangeIndex,

#[brw(pad_after = 1)]
reverse: Reverse,
command: Command,
}
52 changes: 52 additions & 0 deletions src/types/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::types::util::primitive::read_u8_bits;
use crate::types::{ProfilePointDetection, StepDirection};
use binrw::meta::{EndianKind, ReadEndian, WriteEndian};
use binrw::{BinRead, BinResult, Endian};
use std::io::{Read, Seek};

const MASK_STEP_DIRECTION: u8 = 0b0100_0000;
const SHIFT_STEP_DIRECTION: usize = 6;

const MASK_PROFILE_POINT_DETECTION: u8 = 0b0000_0001;

#[derive(Debug, Clone, Eq, PartialEq, derive_new::new)]
pub struct Command {
pub profile_point_detection: ProfilePointDetection,
pub step_direction: StepDirection,
}

impl ReadEndian for Command {
const ENDIAN: EndianKind = EndianKind::None;
}

impl WriteEndian for Command {
const ENDIAN: EndianKind = EndianKind::None;
}

impl BinRead for Command {
type Args<'a> = ();

fn read<R: Read + Seek>(reader: &mut R) -> BinResult<Self>
where
Self: ReadEndian,
{
let raw = u8::read(reader)?;
let pos = reader.stream_position()?;

let profile_point_detection =
read_u8_bits::<ProfilePointDetection>(raw, MASK_PROFILE_POINT_DETECTION, 0, pos)?;
let step_direction =
read_u8_bits::<StepDirection>(raw, MASK_STEP_DIRECTION, SHIFT_STEP_DIRECTION, pos)?;

Ok(Self { profile_point_detection, step_direction })
}

#[inline]
fn read_options<R: Read + Seek>(
reader: &mut R,
_: Endian,
_: Self::Args<'_>,
) -> BinResult<Self> {
Self::read(reader)
}
}
8 changes: 6 additions & 2 deletions src/types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod acceleration;
mod angle;
mod command;
mod config;
mod data;
mod data_bits;
Expand All @@ -13,21 +14,23 @@ mod motion_config;
mod motor_calibrate;
pub mod primitive;
mod profile_grid;
mod profile_point_detection;
mod range_index;
mod reverse;
mod sensor_available;
mod sensor_information;
mod sonar_return_header;
mod sonar_return_magic;
mod sonar_return_status;
mod sonar_type;
mod step_direction;
mod step_size;
mod transducer;
mod util;
mod zero;

pub use acceleration::Acceleration;
pub use angle::Angle;
pub use command::Command;
pub use config::Config;
pub use data_bits::DataBits;
pub use data_length::DataSizeIndex;
Expand All @@ -38,14 +41,15 @@ pub use logf::Logf;
pub use mode::Mode;
pub use motion_config::MotionConfig;
pub use profile_grid::ProfileGrid;
pub use profile_point_detection::ProfilePointDetection;
pub use range_index::RangeIndex;
pub use reverse::Reverse;
pub use sensor_available::SensorAvailable;
pub use sensor_information::SensorInformation;
pub use sonar_return_header::SonarReturnHeader;
pub use sonar_return_magic::SonarReturnMagic;
pub use sonar_return_status::SonarReturnStatus;
pub use sonar_type::SonarType;
pub use step_direction::StepDirection;
pub use step_size::StepSize;
pub use transducer::Transducer;
pub use zero::Zero;
40 changes: 40 additions & 0 deletions src/types/primitive/profile_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,43 @@ pub fn write(profile_range: &f32, range_index: &RangeIndex) -> BinResult<()> {
value.write_options(writer, endian, ())?;
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use crate::types::primitive::u14;
use crate::types::RangeIndex;
use binrw::{io::Cursor, BinRead, BinWrite, Endian};
use std::ops::Range;

use log::info;
use test_log::test;

const BINARY_ENDIAN: Endian = Endian::Little;
const BINARY_CASES: [(f32, [u8; 2], RangeIndex); 2] =
[(16.383, [0b1111_1111, 0b0111_1111], RangeIndex::X2m), (0.0, [0, 0], RangeIndex::X25cm)];

#[test]
fn test_parse() {
for &(want, bytes, range_index) in BINARY_CASES.iter() {
info!("Parsing {bytes:?} with RangeIndex {range_index:?}, want {want:?}");
let mut cursor = Cursor::new(bytes);
let got = parse(&mut cursor, BINARY_ENDIAN, (range_index,))
.expect("It should not return an error");
assert!((got - want).abs() < f32::EPSILON);
}
}

#[test]
fn test_write() {
for (profile_range, want, range_index) in BINARY_CASES.iter() {
info!("Writing {profile_range:?} with RangeIndex {range_index:?}, want {want:?}");
let mut cursor = Cursor::new(Vec::new());
write(&profile_range, &mut cursor, BINARY_ENDIAN, (range_index,))
.expect("It should not return an error");
let inner = cursor.into_inner();
let got = inner.as_slice();
assert_eq!(want, got);
}
}
}
9 changes: 9 additions & 0 deletions src/types/profile_point_detection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use num_derive::{FromPrimitive, ToPrimitive};

/// New in Ethernet Specification v1.01, revision `03` from March 22, 2023.
#[derive(Debug, Copy, Clone, Eq, PartialEq, FromPrimitive, ToPrimitive)]
#[repr(u8)]
pub enum ProfilePointDetection {
CenterOfPulse = 0,
StartOfPulse = 1,
}
22 changes: 12 additions & 10 deletions src/types/reverse.rs → src/types/step_direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,26 @@ use binrw::{BinRead, BinWrite};
use num_derive::{FromPrimitive, ToPrimitive};
use std::fmt::{Display, Formatter};

#[derive(Debug, Eq, PartialEq, Copy, Clone, BinRead, BinWrite, ToPrimitive, FromPrimitive)]
#[derive(Debug, Eq, PartialEq, Copy, Clone, ToPrimitive, FromPrimitive)]
#[repr(u8)]
#[brw(repr = u8)]
#[cfg_attr(
target_family = "wasm",
derive(tsify::Tsify, serde::Serialize, serde::Deserialize),
tsify(into_wasm_abi, from_wasm_abi),
serde(rename_all = "UPPERCASE")
)]
pub enum Reverse {
Normal = 0b0000_0000,
Reverse = 0b0100_0000,
pub enum StepDirection {
Normal = 0,
Reverse = 1,
}

impl Default for Reverse {
impl Default for StepDirection {
fn default() -> Self {
Self::Normal
}
}

impl Display for Reverse {
impl Display for StepDirection {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
Expand All @@ -44,13 +43,16 @@ mod tests {

#[test]
fn test_default() {
let got = Reverse::default();
assert_eq!(Reverse::Normal, got);
let got = StepDirection::default();
assert_eq!(StepDirection::Normal, got);
}

#[test]
fn test_display() {
let cases = vec![(Reverse::Normal, "normal"), (Reverse::Reverse, "reverse step direction")];
let cases = vec![
(StepDirection::Normal, "normal"),
(StepDirection::Reverse, "reverse step direction"),
];

for (reverse, want) in cases {
info!("Displaying {reverse:?}, expecting {want:?}");
Expand Down

0 comments on commit 94a1afb

Please sign in to comment.