psdk_fruit_emapi/
command.rs1use crate::constants::{TYPE_ERROR, TYPE_PASSTHROUGH_ERROR, TYPE_RESPONSE};
2use crate::error::{EmapiError, Result};
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct EmapiCommand {
6 pub command_type: u8,
7 pub parent: u8,
8 pub child: u8,
9 pub payload: Vec<u8>,
10}
11
12impl EmapiCommand {
13 pub fn new(command_type: u8, parent: u8, child: u8, payload: impl Into<Vec<u8>>) -> Self {
14 Self {
15 command_type,
16 parent,
17 child,
18 payload: payload.into(),
19 }
20 }
21
22 pub fn try_new(
23 command_type: u16,
24 parent: u16,
25 child: u16,
26 payload: impl Into<Vec<u8>>,
27 ) -> Result<Self> {
28 Ok(Self::new(
29 check_byte(command_type, "type")?,
30 check_byte(parent, "parent")?,
31 check_byte(child, "child")?,
32 payload,
33 ))
34 }
35
36 pub fn is_ack_for(&self, parent: u8, child: u8) -> bool {
37 self.is_response_for(TYPE_RESPONSE, parent, child) && self.payload.is_empty()
38 }
39
40 pub fn is_response_for(&self, command_type: u8, parent: u8, child: u8) -> bool {
41 self.command_type == command_type && self.parent == parent && self.child == child
42 }
43
44 pub fn is_error(&self) -> bool {
45 self.command_type == TYPE_ERROR || self.command_type == TYPE_PASSTHROUGH_ERROR
46 }
47
48 pub fn is_protocol_error(&self) -> bool {
49 self.command_type == TYPE_ERROR
50 }
51
52 pub fn is_passthrough_error(&self) -> bool {
53 self.command_type == TYPE_PASSTHROUGH_ERROR
54 }
55}
56
57fn check_byte(value: u16, name: &'static str) -> Result<u8> {
58 if value > 0xFF {
59 return Err(EmapiError::Range {
60 name,
61 min: 0,
62 max: 0xFF,
63 value: u64::from(value),
64 });
65 }
66 Ok(value as u8)
67}