use prost::Message;
mod error;
mod proto {
include!(concat!(env!("OUT_DIR"), "/cmdproto.rs"));
pub mod msg {
include!(concat!(env!("OUT_DIR"), "/cmdproto.msg.rs"));
}
}
pub use error::{Error, Result};
pub use proto::msg::*;
pub use proto::{Cmd, PacketToc, PacketTos};
pub fn encode_tos<T: Message>(cmd: u32, seq: u32, msg: &T) -> Result<Vec<u8>> {
let packet = PacketTos {
cmd,
seq,
payload: msg.encode_to_vec(),
};
Ok(packet.encode_to_vec())
}
pub fn encode_toc<T: Message>(cmd: u32, seq: u32, error_code: u32, msg: &T) -> Result<Vec<u8>> {
let packet = PacketToc {
cmd,
seq,
error_code,
payload: msg.encode_to_vec(),
};
Ok(packet.encode_to_vec())
}
pub fn decode_packet_tos(data: &[u8]) -> Result<PacketTos> {
Ok(PacketTos::decode(data)?)
}
pub fn decode_packet_toc(data: &[u8]) -> Result<PacketToc> {
Ok(PacketToc::decode(data)?)
}
pub fn decode_payload<T: Message + Default>(payload: &[u8]) -> Result<T> {
Ok(T::decode(payload)?)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn roundtrip_1001() {
let req = M1001Tos {
username: "alice".into(),
password: "secret".into(),
};
let bytes = encode_tos(Cmd::Cmd1001 as u32, 1, &req).unwrap();
let packet = decode_packet_tos(&bytes).unwrap();
assert_eq!(packet.cmd, 1001);
assert_eq!(packet.seq, 1);
let decoded: M1001Tos = decode_payload(&packet.payload).unwrap();
assert_eq!(decoded.username, "alice");
assert_eq!(decoded.password, "secret");
}
#[test]
fn roundtrip_1001_toc() {
let resp = M1001Toc {
code: 0,
token: "token".into(),
message: "ok".into(),
};
let bytes = encode_toc(Cmd::Cmd1001 as u32, 1, 7, &resp).unwrap();
let packet = decode_packet_toc(&bytes).unwrap();
assert_eq!(packet.cmd, 1001);
assert_eq!(packet.seq, 1);
assert_eq!(packet.error_code, 7);
let decoded: M1001Toc = decode_payload(&packet.payload).unwrap();
assert_eq!(decoded.code, 0);
assert_eq!(decoded.token, "token");
assert_eq!(decoded.message, "ok");
}
}