matter_interaction/
path.rs1#![forbid(unsafe_code)]
5
6use crate::error::ImError;
7use matter_codec::{Tag, Value};
8
9#[derive(Copy, Clone, Debug, PartialEq, Eq)]
14pub struct CommandPath {
15 pub endpoint: u16,
17 pub cluster: u32,
19 pub command: u32,
21}
22
23#[derive(Copy, Clone, Debug, PartialEq, Eq)]
30pub struct AttributePath {
31 pub endpoint: u16,
33 pub cluster: u32,
35 pub attribute: u32,
37}
38
39#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
45pub struct ReadPath {
46 pub endpoint: Option<u16>,
48 pub cluster: Option<u32>,
50 pub attribute: Option<u32>,
52}
53
54impl ReadPath {
55 #[must_use]
57 pub fn concrete(endpoint: u16, cluster: u32, attribute: u32) -> Self {
58 Self {
59 endpoint: Some(endpoint),
60 cluster: Some(cluster),
61 attribute: Some(attribute),
62 }
63 }
64
65 #[must_use]
67 pub fn cluster(endpoint: u16, cluster: u32) -> Self {
68 Self {
69 endpoint: Some(endpoint),
70 cluster: Some(cluster),
71 attribute: None,
72 }
73 }
74
75 #[must_use]
77 pub fn all() -> Self {
78 Self {
79 endpoint: None,
80 cluster: None,
81 attribute: None,
82 }
83 }
84}
85
86impl From<AttributePath> for ReadPath {
87 fn from(p: AttributePath) -> Self {
88 Self {
89 endpoint: Some(p.endpoint),
90 cluster: Some(p.cluster),
91 attribute: Some(p.attribute),
92 }
93 }
94}
95
96pub(crate) fn attribute_path_from_value(
100 members: &[(Tag, Value)],
101) -> Result<AttributePath, ImError> {
102 let mut endpoint = None;
103 let mut cluster = None;
104 let mut attribute = None;
105 for (tag, v) in members {
106 match (tag, v) {
107 (Tag::Context(2), Value::Uint(n)) => {
108 endpoint =
109 Some(u16::try_from(*n).map_err(|_| {
110 ImError::UnexpectedValue("AttributePath.endpoint exceeds u16")
111 })?);
112 }
113 (Tag::Context(3), Value::Uint(n)) => {
114 cluster =
115 Some(u32::try_from(*n).map_err(|_| {
116 ImError::UnexpectedValue("AttributePath.cluster exceeds u32")
117 })?);
118 }
119 (Tag::Context(4), Value::Uint(n)) => {
120 attribute = Some(u32::try_from(*n).map_err(|_| {
121 ImError::UnexpectedValue("AttributePath.attribute exceeds u32")
122 })?);
123 }
124 _ => {}
125 }
126 }
127 Ok(AttributePath {
128 endpoint: endpoint.ok_or(ImError::MissingField("AttributePath.endpoint"))?,
129 cluster: cluster.ok_or(ImError::MissingField("AttributePath.cluster"))?,
130 attribute: attribute.ok_or(ImError::MissingField("AttributePath.attribute"))?,
131 })
132}
133
134pub(crate) fn attribute_path_and_append_from_value(
139 members: &[(Tag, Value)],
140) -> Result<(AttributePath, bool), ImError> {
141 let path = attribute_path_from_value(members)?;
142 let append = members
143 .iter()
144 .any(|(tag, v)| matches!(tag, Tag::Context(5)) && matches!(v, Value::Null));
145 Ok((path, append))
146}