use {Coil, Transport, Client, Result};
pub enum CoilDropFunction {
On,
Off,
Toggle,
}
pub enum RegisterDropFunction<'a> {
Zero,
Increment,
Decrement,
Value(u16),
Fun(&'a Fn(u16) -> u16),
}
pub struct ScopedCoil<'a> {
address: u16,
fun: CoilDropFunction,
transport: &'a mut Transport,
}
impl<'a> Drop for ScopedCoil<'a> {
fn drop(&mut self) {
let _ = self.transport
.read_coils(self.address, 1)
.and_then(|value| match value.len() {
1 => {
let drop_value = match self.fun {
CoilDropFunction::On => Coil::On,
CoilDropFunction::Off => Coil::Off,
CoilDropFunction::Toggle => {
match value[0] {
Coil::On => Coil::Off,
Coil::Off => Coil::On,
}
}
};
let _ = self.transport.write_single_coil(self.address, drop_value);
Ok(())
}
_ => Ok(()),
});
}
}
impl<'a> ScopedCoil<'a> {
pub fn new(transport: &mut Transport,
address: u16,
fun: CoilDropFunction)
-> Result<ScopedCoil> {
Ok(ScopedCoil {
address: address,
fun: fun,
transport: transport,
})
}
pub fn mut_transport(&mut self) -> &mut Transport {
self.transport
}
}
pub struct ScopedRegister<'a> {
address: u16,
fun: RegisterDropFunction<'a>,
transport: &'a mut Transport,
}
impl<'a> Drop for ScopedRegister<'a> {
fn drop(&mut self) {
let _ = self.transport
.read_holding_registers(self.address, 1)
.and_then(|value| match value.len() {
1 => {
let drop_value = match self.fun {
RegisterDropFunction::Zero => 0u16,
RegisterDropFunction::Increment => value[0] + 1,
RegisterDropFunction::Decrement => value[0] - 1,
RegisterDropFunction::Value(v) => v,
RegisterDropFunction::Fun(f) => f(value[0]),
};
let _ = self.transport.write_single_register(self.address, drop_value);
Ok(())
}
_ => Ok(()),
});
}
}
impl<'a> ScopedRegister<'a> {
pub fn new<'b>(transport: &'b mut Transport,
address: u16,
fun: RegisterDropFunction<'b>)
-> Result<ScopedRegister<'b>> {
Ok(ScopedRegister {
address: address,
fun: fun,
transport: transport,
})
}
pub fn mut_transport(&mut self) -> &mut Transport {
self.transport
}
}