orchestra_toolkit/hgtp/message/
unpacker.rs1use std::string::FromUtf8Error;
14
15use crate::{taxonomy::*, Entity, String255, Token, Value, ValueCreationError};
16use thiserror::Error;
17use time::OffsetDateTime;
18
19use super::HGTPMessage;
20
21#[derive(Error, Debug)]
22pub enum UnpackError {
23 #[error("invalid command {0}")]
24 Command(u16),
25 #[error("invalid error code {0}: {1}")]
26 Error(u16, String),
27 #[error("invalid report {0}")]
28 Report(u16),
29 #[error("invalid method {0}")]
30 Method(u16),
31 #[error("invalid attribute {0}")]
32 Attribute(u16),
33 #[error("invalid event {0}")]
34 Event(u16),
35 #[error("invalid mode {0}")]
36 Mode(u16),
37 #[error("invalid category {0}")]
38 Category(u16),
39 #[error("invalid class {0}")]
40 Class(u16),
41 #[error("invalid context {0}")]
42 Context(u16),
43 #[error("invalid aspect {0}")]
44 Aspect(u16),
45 #[error("invalid state {0}")]
46 State(u16),
47 #[error("invalid condition {0}")]
48 Condition(u16),
49 #[error("invalid time: {0}")]
50 Time(time::error::ComponentRange),
51 #[error("invalid name: {0}")]
52 Name(FromUtf8Error),
53 #[error("invalid key: {0}")]
54 Key(FromUtf8Error),
55 #[error("invalid value: {0}")]
56 Value(#[from] UnpackValueError),
57}
58
59#[derive(Error, Debug)]
60#[error("invalid tag {0}")]
61pub struct UnpackTagError(pub u16);
62
63#[derive(Error, Debug)]
64pub enum UnpackValueError {
65 #[error(transparent)]
66 UnpackTag(#[from] UnpackTagError),
67 #[error("invalid bytes: {0}")]
68 InvalidBytes(FromUtf8Error),
69 #[error(transparent)]
70 ValueCreationError(#[from] ValueCreationError),
71}
72
73impl HGTPMessage {
74 pub fn unpack_command(&self) -> Result<Command, UnpackError> {
75 let raw = u16::from_le_bytes(self.frame[0..2].try_into().unwrap());
76
77 Command::try_from(raw).map_err(|_| UnpackError::Command(raw))
78 }
79
80 pub fn unpack_error_code(&self) -> Result<HGTPError, UnpackError> {
82 let raw = u16::from_le_bytes(self.frame[2..4].try_into().unwrap());
83
84 HGTPError::try_from(raw).map_err(|_| {
85 UnpackError::Error(
86 raw,
87 String::from_utf8_lossy(self.unpack_bytes()).to_string(),
88 )
89 })
90 }
91
92 pub fn unpack_version(&self) -> u16 {
93 u16::from_le_bytes(self.frame[4..6].try_into().unwrap())
94 }
95
96 pub fn unpack_report(&self) -> Result<Report, UnpackError> {
97 let raw = u16::from_le_bytes(self.frame[6..8].try_into().unwrap());
98
99 Report::try_from(raw).map_err(|_| UnpackError::Report(raw))
100 }
101
102 pub fn unpack_method(&self) -> Result<Method, UnpackError> {
103 let v = u16::from_le_bytes(self.frame[8..10].try_into().unwrap());
104 Method::try_from(v).map_err(|_| UnpackError::Method(v))
105 }
106
107 pub fn unpack_attribute(&self) -> Result<Attribute, UnpackError> {
108 let v = u16::from_le_bytes(self.frame[10..12].try_into().unwrap());
109 Attribute::try_from(v).map_err(|_| UnpackError::Attribute(v))
110 }
111
112 pub fn unpack_event(&self) -> Result<Event, UnpackError> {
113 let v = u16::from_le_bytes(self.frame[12..14].try_into().unwrap());
114 Event::try_from(v).map_err(|_| UnpackError::Event(v))
115 }
116
117 pub fn unpack_mode(&self) -> Result<Mode, UnpackError> {
118 let v = u16::from_le_bytes(self.frame[14..16].try_into().unwrap());
119 Mode::try_from(v).map_err(|_| UnpackError::Mode(v))
120 }
121
122 pub fn unpack_category(&self) -> Result<Category, UnpackError> {
123 let v = u16::from_le_bytes(self.frame[16..18].try_into().unwrap());
124 Category::try_from(v).map_err(|_| UnpackError::Category(v))
125 }
126
127 pub fn unpack_class(&self) -> Result<Class, UnpackError> {
128 let v = u16::from_le_bytes(self.frame[18..20].try_into().unwrap());
129 Class::try_from(v).map_err(|_| UnpackError::Class(v))
130 }
131
132 pub fn unpack_context(&self) -> Result<Context, UnpackError> {
133 let v = u16::from_le_bytes(self.frame[20..22].try_into().unwrap());
134 Context::try_from(v).map_err(|_| UnpackError::Context(v))
135 }
136
137 pub fn unpack_aspect(&self) -> Result<Aspect, UnpackError> {
138 let v = u16::from_le_bytes(self.frame[22..24].try_into().unwrap());
139 Aspect::try_from(v).map_err(|_| UnpackError::Aspect(v))
140 }
141
142 pub fn unpack_state(&self) -> Result<State, UnpackError> {
143 let v = u16::from_le_bytes(self.frame[24..26].try_into().unwrap());
144 State::try_from(v).map_err(|_| UnpackError::State(v))
145 }
146
147 pub fn unpack_precedence(&self) -> u16 {
148 u16::from_le_bytes(self.frame[26..28].try_into().unwrap())
149 }
150
151 pub fn unpack_tag(&self) -> Result<Tag, UnpackTagError> {
153 let v = u16::from_le_bytes(self.frame[28..30].try_into().unwrap());
154 Tag::try_from(v).map_err(|_| UnpackTagError(v))
155 }
156
157 pub fn unpack_condition(&self) -> Result<Condition, UnpackError> {
158 let v = u16::from_le_bytes(self.frame[30..32].try_into().unwrap());
159 Condition::try_from(v).map_err(|_| UnpackError::Condition(v))
160 }
161
162 pub fn unpack_instance(&self) -> i32 {
163 i32::from_le_bytes(self.frame[32..36].try_into().unwrap())
164 }
165
166 pub fn unpack_offset(&self) -> i32 {
167 i32::from_le_bytes(self.frame[36..40].try_into().unwrap())
168 }
169
170 pub fn unpack_time(&self) -> Result<OffsetDateTime, UnpackError> {
171 let timestamp = i64::from_le_bytes(self.frame[40..48].try_into().unwrap());
172
173 OffsetDateTime::from_unix_timestamp(timestamp).map_err(|e| UnpackError::Time(e))
174 }
175
176 pub fn unpack_index(&self) -> i64 {
177 i64::from_le_bytes(self.frame[48..56].try_into().unwrap())
178 }
179
180 pub fn unpack_count(&self) -> i64 {
181 i64::from_le_bytes(self.frame[56..64].try_into().unwrap())
182 }
183
184 pub fn unpack_extension(&self) -> i64 {
185 i64::from_le_bytes(self.frame[64..72].try_into().unwrap())
186 }
187
188 pub fn unpack_parameter(&self) -> i64 {
189 i64::from_le_bytes(self.frame[72..80].try_into().unwrap())
190 }
191
192 pub fn unpack_resultant(&self) -> i64 {
193 i64::from_le_bytes(self.frame[80..88].try_into().unwrap())
194 }
195
196 pub fn unpack_timeout(&self) -> i64 {
197 i64::from_le_bytes(self.frame[88..96].try_into().unwrap())
198 }
199
200 pub fn unpack_entity(&self) -> Entity {
203 Entity {
204 pid: u32::from_le_bytes(self.frame[160..164].try_into().unwrap()),
205 hid: u32::from_le_bytes(self.frame[164..168].try_into().unwrap()),
206 uid: u64::from_le_bytes(self.frame[168..176].try_into().unwrap()),
207 }
208 }
209
210 pub fn unpack_outlet(&self) -> Entity {
211 Entity {
212 pid: u32::from_le_bytes(self.frame[176..180].try_into().unwrap()),
213 hid: u32::from_le_bytes(self.frame[180..184].try_into().unwrap()),
214 uid: u64::from_le_bytes(self.frame[184..192].try_into().unwrap()),
215 }
216 }
217
218 pub fn unpack_auxiliary(&self) -> Entity {
219 Entity {
220 pid: u32::from_le_bytes(self.frame[192..196].try_into().unwrap()),
221 hid: u32::from_le_bytes(self.frame[196..200].try_into().unwrap()),
222 uid: u64::from_le_bytes(self.frame[200..208].try_into().unwrap()),
223 }
224 }
225
226 pub fn unpack_ancillary(&self) -> Entity {
227 Entity {
228 pid: u32::from_le_bytes(self.frame[208..212].try_into().unwrap()),
229 hid: u32::from_le_bytes(self.frame[212..216].try_into().unwrap()),
230 uid: u64::from_le_bytes(self.frame[216..224].try_into().unwrap()),
231 }
232 }
233
234 pub fn unpack_authorization(&self) -> Token {
235 Token::from_bytes(self.frame[224..240].try_into().unwrap())
236 }
237
238 pub fn unpack_authority(&self) -> Token {
239 Token::from_bytes(self.frame[240..256].try_into().unwrap())
240 }
241
242 pub fn unpack_name(&self) -> Result<String255, UnpackError> {
243 let len = self.frame[256];
244 let bytes = &self.frame[257..257 + len as usize];
245 match String::from_utf8(bytes.to_vec()) {
246 Ok(s) => Ok(String255::unchecked(&s)),
247 Err(e) => Err(UnpackError::Name(e)),
248 }
249 }
250
251 pub fn unpack_key(&self) -> Result<String255, UnpackError> {
252 let len = self.frame[512];
253 let bytes = &self.frame[513..513 + len as usize];
254 match String::from_utf8(bytes.to_vec()) {
255 Ok(s) => Ok(String255::unchecked(&s)),
256 Err(e) => Err(UnpackError::Key(e)),
257 }
258 }
259
260 pub fn unpack_bytes(&self) -> &[u8] {
262 let extension = self.unpack_extension();
263 if extension == 0 {
264 let len = self.frame[768] as usize;
265 &self.frame[769..769 + len]
266 } else {
267 &self.unbounded
268 }
269 }
270
271 pub fn unpack_value(&self) -> Result<Value, UnpackError> {
272 let t = self.unpack_tag().map_err(UnpackValueError::UnpackTag)?;
273 let b = self.unpack_bytes().to_vec();
274 let s = String::from_utf8(b).map_err(UnpackValueError::InvalidBytes)?;
275 Ok(Value::new(t, s).map_err(UnpackValueError::ValueCreationError)?)
276 }
277}