domo/domo_proto/src/commands/property_control/mod.rs
2023-12-04 14:02:53 +01:00

186 lines
6.6 KiB
Rust

use crate::data_types::DataType;
use crate::identifier::Identifier;
use crate::packet::packet_data::PacketData;
use crate::packet::raw_packet::RawPacket;
use crate::packet::{Packet, ToPacket};
use crate::prelude::as_u32_be;
use std::io;
pub mod vec;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PropertyControlCommand {
Register {
property_name: String,
data_type: u8,
read_only: bool,
// TODO: descriptive
},
Remove {
property_name: String,
},
Get {
property_name: String,
data: DataType,
},
Set {
property_name: String,
data: DataType,
},
Reset {
property_name: String,
},
Subscribe {
device_id: Identifier,
property_name: String,
},
Unsubscribe {
device_id: Identifier,
property_name: String,
},
}
impl PropertyControlCommand {
pub fn command(&self) -> u8 {
match self {
PropertyControlCommand::Register { .. } => 0x10,
PropertyControlCommand::Remove { .. } => 0x11,
PropertyControlCommand::Get { .. } => 0x12,
PropertyControlCommand::Set { .. } => 0x13,
PropertyControlCommand::Reset { .. } => 0x14,
PropertyControlCommand::Subscribe { .. } => 0x1A,
PropertyControlCommand::Unsubscribe { .. } => 0x1B,
}
}
}
impl ToPacket for PropertyControlCommand {
fn to_packet(
self,
src: Identifier,
dest: Identifier,
packet_id: Identifier,
reply_to: Identifier,
) -> Packet {
Packet {
src,
dest,
packet_id,
reply_to,
command: self.command(),
data: PacketData::PropertyControl(self.clone()),
}
}
}
impl TryFrom<RawPacket> for PropertyControlCommand {
type Error = io::Error;
fn try_from(raw_packet: RawPacket) -> io::Result<Self> {
let build_invalid_input_err = |r: &str| Err(io::Error::new(io::ErrorKind::InvalidInput, r));
match raw_packet.command {
// remove node
0x10 => {
if raw_packet.data_length == 34 {
Ok(PropertyControlCommand::Register {
property_name: String::from_utf8(raw_packet.data[..32].to_vec()).map_err(
|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"),
)?,
data_type: raw_packet.data[33],
read_only: raw_packet.data[34] != 0,
})
} else {
build_invalid_input_err("expected 34 bytes")
}
}
// remove property
0x11 => {
if raw_packet.data_length == 32 {
Ok(PropertyControlCommand::Remove {
property_name: String::from_utf8(raw_packet.data.to_vec()).map_err(
|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"),
)?,
})
} else {
build_invalid_input_err("expected 32 bytes")
}
}
// get property
0x12 => {
if raw_packet.data_length == 33 {
Ok(PropertyControlCommand::Get {
property_name: String::from_utf8(raw_packet.data[..0x34].to_vec())
.map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
})?,
data: DataType::try_from(raw_packet.data[0x34..].to_vec())?,
})
} else {
build_invalid_input_err("expected 33 bytes")
}
}
// set property
0x13 => {
if raw_packet.data_length == 33 {
Ok(PropertyControlCommand::Set {
property_name: String::from_utf8(raw_packet.data[..0x34].to_vec())
.map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
})?,
data: DataType::try_from(raw_packet.data[0x34..].to_vec())?,
})
} else {
build_invalid_input_err("expected 33 bytes")
}
}
// reset property
0x14 => {
if raw_packet.data_length == 33 {
Ok(PropertyControlCommand::Reset {
property_name: String::from_utf8(raw_packet.data[..0x34].to_vec())
.map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
})?,
})
} else {
build_invalid_input_err("expected 33 bytes")
}
}
// subscribe to property
0x1A => {
if raw_packet.data_length == 36 {
Ok(PropertyControlCommand::Subscribe {
device_id: Identifier::from(as_u32_be(
raw_packet.data[0x14..0x18].as_ref(),
)),
property_name: String::from_utf8(raw_packet.data[0x18..0x4C].to_vec())
.map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
})?,
})
} else {
build_invalid_input_err("expected 36 bytes")
}
}
// unsubscribe from property
0x1B => {
if raw_packet.data_length == 36 {
Ok(PropertyControlCommand::Unsubscribe {
device_id: Identifier::from(as_u32_be(
raw_packet.data[0x14..0x18].as_ref(),
)),
property_name: String::from_utf8(raw_packet.data[0x18..0x4C].to_vec())
.map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
})?,
})
} else {
build_invalid_input_err("expected 36 bytes")
}
}
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"command group is unsupported",
)),
}
}
}