orchestra_toolkit/hgtp/message/
packer.rs

1/* Copyright 2024-2025 LEDR Technologies Inc.
2* This file is part of the Orchestra library, which helps developer use our Orchestra technology which is based on AvesTerra, owned and developped by Georgetown University, under license agreement with LEDR Technologies Inc.
3*
4* The Orchestra library is a free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.
5*
6* The Orchestra library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
7*
8* You should have received a copy of the GNU Lesser General Public License along with the Orchestra library. If not, see <https://www.gnu.org/licenses/>.
9*
10* If you have any questions, feedback or issues about the Orchestra library, you can contact us at support@ledr.io.
11*/
12
13use time::OffsetDateTime;
14
15use super::HGTPMessage;
16use crate::{taxonomy::*, AvesterraError, Entity, String255, Token, Value};
17
18impl HGTPMessage {
19    pub fn pack_command(&mut self, value: Command) {
20        self.frame[0..2].copy_from_slice(&(value as u16).to_le_bytes());
21    }
22
23    // Consider using `pack_error`
24    pub fn pack_error_code(&mut self, value: HGTPError) {
25        self.frame[2..4].copy_from_slice(&(value as u16).to_le_bytes());
26    }
27
28    pub fn pack_version(&mut self, value: u16) {
29        self.frame[4..6].copy_from_slice(&value.to_le_bytes());
30    }
31
32    pub fn pack_report(&mut self, value: Report) {
33        self.frame[6..8].copy_from_slice(&(value as u16).to_le_bytes());
34    }
35
36    pub fn pack_method(&mut self, value: Method) {
37        self.frame[8..10].copy_from_slice(&(value as u16).to_le_bytes());
38    }
39
40    pub fn pack_attribute(&mut self, value: Attribute) {
41        self.frame[10..12].copy_from_slice(&(value as u16).to_le_bytes());
42    }
43
44    pub fn pack_event(&mut self, value: Event) {
45        self.frame[12..14].copy_from_slice(&(value as u16).to_le_bytes());
46    }
47
48    pub fn pack_mode(&mut self, value: Mode) {
49        self.frame[14..16].copy_from_slice(&(value as u16).to_le_bytes());
50    }
51
52    pub fn pack_category(&mut self, value: Category) {
53        self.frame[16..18].copy_from_slice(&(value as u16).to_le_bytes());
54    }
55
56    pub fn pack_class(&mut self, value: Class) {
57        self.frame[18..20].copy_from_slice(&(value as u16).to_le_bytes());
58    }
59
60    pub fn pack_context(&mut self, value: Context) {
61        self.frame[20..22].copy_from_slice(&(value as u16).to_le_bytes());
62    }
63
64    pub fn pack_aspect(&mut self, value: Aspect) {
65        self.frame[22..24].copy_from_slice(&(value as u16).to_le_bytes());
66    }
67
68    pub fn pack_state(&mut self, value: State) {
69        self.frame[24..26].copy_from_slice(&(value as u16).to_le_bytes());
70    }
71
72    pub fn pack_precedence(&mut self, value: u16) {
73        self.frame[26..28].copy_from_slice(&value.to_le_bytes());
74    }
75
76    // You probably want to use `pack_value`
77    pub fn pack_tag(&mut self, value: Tag) {
78        self.frame[28..30].copy_from_slice(&(value as u16).to_le_bytes());
79    }
80
81    pub fn pack_condition(&mut self, value: Condition) {
82        self.frame[30..32].copy_from_slice(&(value as u16).to_le_bytes());
83    }
84
85    pub fn pack_instance(&mut self, value: i32) {
86        self.frame[32..36].copy_from_slice(&value.to_le_bytes());
87    }
88
89    pub fn pack_offset(&mut self, value: i32) {
90        self.frame[36..40].copy_from_slice(&value.to_le_bytes());
91    }
92
93    pub fn pack_time(&mut self, value: OffsetDateTime) {
94        self.frame[40..48].copy_from_slice(&value.unix_timestamp().to_le_bytes());
95    }
96
97    pub fn pack_index(&mut self, value: i64) {
98        self.frame[48..56].copy_from_slice(&value.to_le_bytes());
99    }
100
101    pub fn pack_count(&mut self, value: i64) {
102        self.frame[56..64].copy_from_slice(&value.to_le_bytes());
103    }
104
105    fn pack_extension(&mut self, value: i64) {
106        self.frame[64..72].copy_from_slice(&value.to_le_bytes());
107    }
108
109    pub fn pack_parameter(&mut self, value: i64) {
110        self.frame[72..80].copy_from_slice(&value.to_le_bytes());
111    }
112
113    pub fn pack_resultant(&mut self, value: i64) {
114        self.frame[80..88].copy_from_slice(&value.to_le_bytes());
115    }
116
117    pub fn pack_timeout(&mut self, value: i64) {
118        // Looking at the Ada implementation, the valid range is
119        // type timeout_type      is new integer range 0..2**31-1;
120        // so it could be a i32, but it is written as 64 bits in the HGTP frame.
121        self.frame[88..96].copy_from_slice(&value.to_le_bytes());
122    }
123
124    // -- 64 reserved bytes --
125
126    pub fn pack_entity(&mut self, value: Entity) {
127        self.frame[160..164].copy_from_slice(&value.pid.to_le_bytes());
128        self.frame[164..168].copy_from_slice(&value.hid.to_le_bytes());
129        self.frame[168..176].copy_from_slice(&value.uid.to_le_bytes());
130    }
131
132    pub fn pack_outlet(&mut self, value: Entity) {
133        self.frame[176..180].copy_from_slice(&value.pid.to_le_bytes());
134        self.frame[180..184].copy_from_slice(&value.hid.to_le_bytes());
135        self.frame[184..192].copy_from_slice(&value.uid.to_le_bytes());
136    }
137
138    pub fn pack_auxiliary(&mut self, value: Entity) {
139        self.frame[192..196].copy_from_slice(&value.pid.to_le_bytes());
140        self.frame[196..200].copy_from_slice(&value.hid.to_le_bytes());
141        self.frame[200..208].copy_from_slice(&value.uid.to_le_bytes());
142    }
143
144    pub fn pack_ancillary(&mut self, value: Entity) {
145        self.frame[208..212].copy_from_slice(&value.pid.to_le_bytes());
146        self.frame[212..216].copy_from_slice(&value.hid.to_le_bytes());
147        self.frame[216..224].copy_from_slice(&value.uid.to_le_bytes());
148    }
149
150    pub fn pack_authorization(&mut self, value: Token) {
151        self.frame[224..240].copy_from_slice(value.as_bytes());
152    }
153
154    pub fn pack_authority(&mut self, value: Token) {
155        self.frame[240..256].copy_from_slice(value.as_bytes());
156    }
157
158    pub fn pack_name(&mut self, value: String255) {
159        let bytes = value.as_bytes();
160        self.frame[256] = bytes.len() as u8;
161        self.frame[257..257 + bytes.len()].copy_from_slice(bytes);
162        self.frame[257 + bytes.len()..512].fill(0x00);
163    }
164
165    pub fn pack_key(&mut self, value: String255) {
166        let bytes = value.as_bytes();
167        self.frame[512] = bytes.len() as u8;
168        self.frame[513..513 + bytes.len()].copy_from_slice(bytes);
169        self.frame[513 + bytes.len()..768].fill(0x00);
170    }
171
172    // You probably want to use `pack_value` or `pack_error`
173    pub fn pack_bytes(&mut self, value: &[u8]) {
174        if value.len() <= 255 {
175            self.pack_extension(0);
176            self.frame[768] = value.len() as u8;
177            self.frame[769..769 + value.len()].copy_from_slice(value);
178            self.frame[769 + value.len()..1024].fill(0x00);
179        } else {
180            self.pack_extension(value.len() as i64);
181            self.frame[768..1024].fill(0x00);
182            self.unbounded.extend_from_slice(value);
183        }
184    }
185
186    pub fn pack_value(&mut self, value: &Value) {
187        self.pack_tag(value.get_tag());
188        self.pack_bytes(value.get_bytes().as_bytes());
189    }
190
191    pub fn pack_error(&mut self, err: &AvesterraError) {
192        self.pack_error_code(err.errcode);
193        self.pack_bytes(err.message.as_bytes());
194    }
195}