Skip to main content

fennec_modbus/protocol/
address.rs

1use core::marker::PhantomData;
2
3use bytes::BufMut;
4
5use crate::protocol::{
6    Address,
7    codec::{BitSize, Encode},
8};
9
10/// Address specified via a constant generic argument.
11#[must_use]
12#[derive(Copy, Clone)]
13pub struct Const<const A: u16>;
14
15impl<const A: u16> Address for Const<A> {}
16
17impl<const A: u16> Encode for Const<A> {
18    fn encode_to(&self, buf: &mut impl BufMut) {
19        buf.put_u16(A);
20    }
21}
22
23/// Address computed as `BASE` + size-of-`V` × `index`.
24///
25/// `BASE` is a bare register address. `N_STRIDES` is the number of valid strides.
26#[must_use]
27#[derive(Copy, Clone)]
28pub struct Stride<const BASE: u16, const N_STRIDES: u16, V>(
29    /// Value index within the stride.
30    pub u16,
31    /// Binding to the value type.
32    PhantomData<V>,
33);
34
35impl<const BASE: u16, const N_STRIDES: u16, V> Stride<BASE, N_STRIDES, V> {
36    /// Create a stride address at the specified index.
37    ///
38    /// # Panics
39    ///
40    /// The index violates the maximum number of strides for this type.
41    pub const fn new(index: u16) -> Self {
42        assert!(index < N_STRIDES, "the stride index is out of the bounds");
43        Self(index, PhantomData)
44    }
45}
46
47impl<const BASE: u16, const N_STRIDES: u16, V: BitSize> Address for Stride<BASE, N_STRIDES, V> {}
48
49impl<const BASE: u16, const N_STRIDES: u16, V: BitSize> Encode for Stride<BASE, N_STRIDES, V> {
50    fn encode_to(&self, buf: &mut impl BufMut) {
51        buf.put_u16(BASE + self.0 * V::N_WORDS);
52    }
53}