modbus-mapping 0.4.0

Modbus register mapping traits and derive macros
Documentation
/// TCP Modbus client without use of macros
use modbus_mapping::core::{HoldingRegisterMap, InputRegisterMap};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use tokio_modbus::{
    client::{tcp::connect_slave, Reader, Writer},
    slave::Slave,
};

#[derive(Debug, Clone, Default)]
pub struct BatteryInputRegisters {
    pub power: f32,
}

#[derive(Debug, Clone, Default)]
pub struct BatteryHoldingRegisters {
    pub setpoint: u16,
}

#[async_trait::async_trait]
impl InputRegisterMap for BatteryInputRegisters {
    async fn update_from_input_registers(
        &mut self,
        client: &mut dyn Reader,
    ) -> tokio_modbus::Result<()> {
        let _words = match client.read_input_registers(0, 2).await? {
            Ok(power) => power,
            Err(exc) => return Ok(Err(exc)),
        };
        // TODO: set

        Ok(Err(tokio_modbus::Exception::IllegalDataAddress))
    }
}

#[async_trait::async_trait]
impl HoldingRegisterMap for BatteryHoldingRegisters {
    async fn update_from_holding_registers(
        &mut self,
        client: &mut dyn Reader,
    ) -> tokio_modbus::Result<()> {
        let words = match client.read_input_registers(0, 1).await? {
            Ok(power) => power,
            Err(exc) => return Ok(Err(exc)),
        };
        self.setpoint = words[0];

        Ok(Err(tokio_modbus::Exception::IllegalDataAddress))
    }

    async fn write_to_registers(&self, client: &mut dyn Writer) -> tokio_modbus::Result<()> {
        match client.write_single_register(5, 0).await? {
            Ok(_) => Ok(Ok(())),
            Err(exc) => Ok(Err(exc)),
        }
    }
}

#[tokio::main]
async fn main() {
    let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
    let slave = Slave(0);

    let mut client = connect_slave(socket_addr, slave).await.unwrap();

    loop {
        let ir = BatteryInputRegisters::from_input_registers(&mut client)
            .await
            .unwrap()
            .unwrap();
        std::thread::sleep(std::time::Duration::from_millis(200));
        println!("{:?}", ir);
    }
}