1use deku::bitvec::{BitSlice, BitVec, Msb0};
2use deku::prelude::*;
4
5#[allow(dead_code)]
6pub(crate) enum Op {
7 Multiply,
8 Divide,
9 Add,
10 Subtract,
11}
12
13impl Op {
14 pub(crate) fn calculate(&self, value: f32, modifier: f32) -> f32 {
15 match self {
16 Op::Multiply => value * modifier,
17 Op::Divide => value / modifier,
18 Op::Add => value + modifier,
19 Op::Subtract => value - modifier,
20 }
21 }
22}
23
24pub(crate) mod read {
25 use super::*;
26
27 pub(crate) fn bits_to_f32(
29 rest: &BitSlice<u8, Msb0>,
30 bits: usize,
31 modifier: f32,
32 modifier_op: Op,
33 ) -> Result<(&BitSlice<u8, Msb0>, f32), DekuError> {
34 let (rest, value) = u32::read(rest, (deku::ctx::Endian::Big, deku::ctx::BitSize(bits)))?;
35 Ok(op(rest, value as f32, modifier, modifier_op))
36 }
37
38 pub(crate) fn bits_i16_to_f32(
40 rest: &BitSlice<u8, Msb0>,
41 bits: usize,
42 modifier: f32,
43 modifier_op: Op,
44 ) -> Result<(&BitSlice<u8, Msb0>, f32), DekuError> {
45 let (rest, value) = i16::read(rest, (deku::ctx::Endian::Big, deku::ctx::BitSize(bits)))?;
46 Ok(op(rest, f32::from(value), modifier, modifier_op))
47 }
48
49 pub(crate) fn op(
50 rest: &BitSlice<u8, Msb0>,
51 value: f32,
52 modifier: f32,
53 modifier_op: Op,
54 ) -> (&BitSlice<u8, Msb0>, f32) {
55 (rest, modifier_op.calculate(value, modifier))
56 }
57
58 pub(crate) fn bits_to_optionf32(
60 rest: &BitSlice<u8, Msb0>,
61 bits: usize,
62 modifier: f32,
63 modifier_op: Op,
64 ) -> Result<(&BitSlice<u8, Msb0>, Option<f32>), DekuError> {
65 bits_to_f32(rest, bits, modifier, modifier_op).map(|(rest, f)| (rest, Some(f)))
66 }
67}
68
69pub mod write {
70 use super::*;
71
72 pub(crate) fn f32_u32(
73 value: &f32,
74 bits: usize,
75 modifier: f32,
76 modifier_op: Op,
77 output: &mut BitVec<u8, Msb0>,
78 ) -> Result<(), DekuError> {
79 let value = modifier_op.calculate(*value, modifier);
81 (value as u32).write(output, (deku::ctx::Endian::Big, deku::ctx::BitSize(bits)))
82 }
83
84 pub(crate) fn f32_optionu32(
85 value: &Option<f32>,
86 bits: usize,
87 modifier: f32,
88 modifier_op: Op,
89 output: &mut BitVec<u8, Msb0>,
90 ) -> Result<(), DekuError> {
91 value.map_or(Ok(()), |value| f32_u32(&value, bits, modifier, modifier_op, output))
92 }
93
94 pub(crate) fn f32_i32(
95 value: &f32,
96 bits: usize,
97 modifier: f32,
98 modifier_op: Op,
99 output: &mut BitVec<u8, Msb0>,
100 ) -> Result<(), DekuError> {
101 let value = modifier_op.calculate(*value, modifier);
102 (value as i32).write(output, (deku::ctx::Endian::Big, deku::ctx::BitSize(bits)))
103 }
104}