hotfix_encoding/
encoder.rs1use crate::dict::IsFieldDefinition;
2use crate::field_types::CheckSum;
3use crate::Config;
4use crate::{Buffer, BufferWriter, FieldType, GetConfig, TagU32};
5use std::fmt::Write;
6use std::ops::Range;
7
8pub trait SetField<F> {
10 fn set<'a, V>(&'a mut self, field: F, value: V)
12 where
13 V: FieldType<'a>,
14 {
15 self.set_with(field, value, <V::SerializeSettings as Default>::default())
16 }
17
18 fn set_with<'a, V>(&'a mut self, field: F, value: V, setting: V::SerializeSettings)
20 where
21 V: FieldType<'a>;
22}
23
24#[derive(Debug, Clone, Default)]
42pub struct Encoder {
43 config: Config,
44}
45
46impl Encoder {
47 pub fn new() -> Self {
49 Self::default()
50 }
51
52 pub fn start_message<'a, B>(
56 &'a mut self,
57 begin_string: &[u8],
58 buffer: &'a mut B,
59 msg_type: &[u8],
60 ) -> EncoderHandle<'a, B>
61 where
62 B: Buffer,
63 {
64 let initial_buffer_len = buffer.len();
65 let mut state = EncoderHandle {
66 encoder: self,
67 buffer,
68 initial_buffer_len,
69 body_start_i: 0,
70 };
71 state.set(8, begin_string);
72 state.set(9, b"00000000" as &[u8]);
88 state.body_start_i = state.buffer.len();
89 state.set(35, msg_type);
90 state
91 }
92}
93
94impl GetConfig for Encoder {
95 type Config = Config;
96
97 fn config(&self) -> &Self::Config {
98 &self.config
99 }
100
101 fn config_mut(&mut self) -> &mut Self::Config {
102 &mut self.config
103 }
104}
105
106#[derive(Debug)]
109pub struct EncoderHandle<'a, B> {
110 encoder: &'a mut Encoder,
111 buffer: &'a mut B,
112 initial_buffer_len: usize,
113 body_start_i: usize,
114}
115
116impl<'a, B> EncoderHandle<'a, B>
117where
118 B: Buffer,
119{
120 pub fn done(mut self) -> (&'a [u8], usize) {
124 self.write_body_length();
125 self.write_checksum();
126 (self.buffer.as_slice(), self.initial_buffer_len)
127 }
128
129 fn body_length_writable_range(&self) -> Range<usize> {
130 self.body_start_i - 9..self.body_start_i - 1
131 }
132
133 fn body_length(&self) -> usize {
134 self.buffer.as_slice().len() - self.body_start_i
135 }
136
137 fn write_body_length(&mut self) {
138 use std::io::Write;
139
140 let body_length = self.body_length();
141 let body_length_range = self.body_length_writable_range();
142 let mut slice = &mut self.buffer.as_mut_slice()[body_length_range];
143 write!(slice, "{:08}", body_length).unwrap();
144 }
145
146 fn write_checksum(&mut self) {
147 let checksum = CheckSum::compute(self.buffer.as_slice());
148 self.set(10, checksum);
149 }
150}
151
152impl<'a, B> SetField<u32> for EncoderHandle<'a, B>
153where
154 B: Buffer,
155{
156 fn set_with<'s, V>(&'s mut self, tag: u32, value: V, settings: V::SerializeSettings)
157 where
158 V: FieldType<'s>,
159 {
160 write!(BufferWriter(self.buffer), "{}=", tag).unwrap();
161 value.serialize_with(self.buffer, settings);
162 self.buffer
163 .extend_from_slice(&[self.encoder.config().separator]);
164 }
165}
166
167impl<'a, B> SetField<TagU32> for EncoderHandle<'a, B>
168where
169 B: Buffer,
170{
171 fn set_with<'s, V>(&'s mut self, tag: TagU32, value: V, settings: V::SerializeSettings)
172 where
173 V: FieldType<'s>,
174 {
175 self.set_with(tag.get(), value, settings)
176 }
177}
178
179impl<'a, B, F> SetField<&F> for EncoderHandle<'a, B>
180where
181 B: Buffer,
182 F: IsFieldDefinition,
183{
184 fn set_with<'s, V>(&'s mut self, field: &F, value: V, settings: V::SerializeSettings)
185 where
186 V: FieldType<'s>,
187 {
188 self.set_with(field.tag(), value, settings)
189 }
190}