bytecodec/encode.rs
1use crate::combinator::{
2 Last, Length, MapErr, MapFrom, MaxBytes, Optional, PreEncode, Repeat, Slice, TryMapFrom,
3};
4use crate::io::IoEncodeExt;
5use crate::tuple::TupleEncoder;
6use crate::{ByteCount, Eos, Error, ErrorKind, Result};
7
8/// This trait allows for encoding items into a byte sequence incrementally.
9pub trait Encode {
10 /// The type of items to be encoded.
11 type Item;
12
13 /// Encodes the items in the encoder and writes the encoded bytes to the given buffer.
14 ///
15 /// It returns the number of bytes written to the given buffer.
16 ///
17 /// If the encoded bytes are larger than the length of `buf`,
18 /// the encoder must consume as many bytes in the buffer as possible.
19 ///
20 /// The completion of the encoding can be detected by using `is_idle` method.
21 ///
22 /// If `self.is_idle()` returns `false` but the number of written bytes in the last `encode` invocation
23 /// is smaller than the length of `buf`, it means the encoder has been suspended its work in any reasons.
24 /// In that case the encoder may require some instructions from clients to resume the work,
25 /// but its concrete method is beyond the scope of this trait.
26 ///
27 /// The encoded bytes that could not be written to the given buffer is held by
28 /// the encoder until the next invocation of the `encode` method.
29 ///
30 /// # Errors
31 ///
32 /// Encoders return the following kinds of errors as necessary:
33 /// - `ErrorKind::InvalidInput`:
34 /// - An item that the encoder could not encode was passed
35 /// - `ErrorKind::UnexpectedEos`:
36 /// - The output byte stream has reached the end in the middle of an encoding process
37 /// - `ErrorKind::InconsistentState`:
38 /// - The state of the encoder bocame inconsistent
39 /// - This means the implementation contains a bug
40 /// - `ErrorKind::Other`:
41 /// - Other errors has occurred
42 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize>;
43
44 /// Tries to start encoding the given item.
45 ///
46 /// If the encoder has no items to be encoded and the passed item is valid, it must accept the item.
47 ///
48 /// # Errors
49 ///
50 /// - `ErrorKind::EncoderFull`:
51 /// - The encoder currently cannot accept any more items
52 /// - `ErrorKind::InvalidInput`:
53 /// - An invalid item was passed
54 /// - `ErrorKind::InconsistentState`:
55 /// - The state of the encoder bocame inconsistent
56 /// - This means the implementation contains a bug
57 /// - `ErrorKind::Other`:
58 /// - Other errors has occurred
59 fn start_encoding(&mut self, item: Self::Item) -> Result<()>;
60
61 /// Returns the number of bytes required to encode all the items in the encoder.
62 ///
63 /// If there are no items to be encoded, the encoder must return `ByteCount::Finite(0)`.
64 fn requiring_bytes(&self) -> ByteCount;
65
66 /// Returns `true` if there are no items to be encoded in the encoder, otherwise `false`.
67 ///
68 /// The default implementation returns the result of `self.requiring_bytes() == ByteCount::Finite(0)`.
69 fn is_idle(&self) -> bool {
70 self.requiring_bytes() == ByteCount::Finite(0)
71 }
72}
73impl<E: ?Sized + Encode> Encode for &mut E {
74 type Item = E::Item;
75
76 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
77 (**self).encode(buf, eos)
78 }
79
80 fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
81 (**self).start_encoding(item)
82 }
83
84 fn requiring_bytes(&self) -> ByteCount {
85 (**self).requiring_bytes()
86 }
87
88 fn is_idle(&self) -> bool {
89 (**self).is_idle()
90 }
91}
92impl<E: ?Sized + Encode> Encode for Box<E> {
93 type Item = E::Item;
94
95 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
96 (**self).encode(buf, eos)
97 }
98
99 fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
100 (**self).start_encoding(item)
101 }
102
103 fn requiring_bytes(&self) -> ByteCount {
104 (**self).requiring_bytes()
105 }
106
107 fn is_idle(&self) -> bool {
108 (**self).is_idle()
109 }
110}
111
112/// This trait indicates that the encoder always knows the exact bytes required to encode remaining items.
113pub trait SizedEncode: Encode {
114 /// Returns the exact number of bytes required to encode all the items remaining in the encoder.
115 fn exact_requiring_bytes(&self) -> u64;
116}
117impl<E: ?Sized + SizedEncode> SizedEncode for &mut E {
118 fn exact_requiring_bytes(&self) -> u64 {
119 (**self).exact_requiring_bytes()
120 }
121}
122impl<E: ?Sized + SizedEncode> SizedEncode for Box<E> {
123 fn exact_requiring_bytes(&self) -> u64 {
124 (**self).exact_requiring_bytes()
125 }
126}
127
128/// An extension of `Encode` trait.
129pub trait EncodeExt: Encode + Sized {
130 /// Creates a new encoder instance that has the given initial item.
131 ///
132 /// # Examples
133 ///
134 /// ```
135 /// use bytecodec::{Encode, EncodeExt};
136 /// use bytecodec::fixnum::U8Encoder;
137 /// use bytecodec::io::IoEncodeExt;
138 ///
139 /// let mut output = Vec::new();
140 /// let mut encoder = U8Encoder::with_item(7).unwrap();
141 /// encoder.encode_all(&mut output).unwrap();
142 /// assert_eq!(output, [7]);
143 /// assert!(encoder.is_idle());
144 /// ```
145 fn with_item(item: Self::Item) -> Result<Self>
146 where
147 Self: Default,
148 {
149 let mut this = Self::default();
150 track!(this.start_encoding(item))?;
151 Ok(this)
152 }
153
154 /// Creates an encoder for modifying encoding errors produced by `self`.
155 ///
156 /// # Examples
157 ///
158 /// The following code shows the idiomatic way to track encoding errors:
159 ///
160 /// ```
161 /// use bytecodec::{Encode, EncodeExt, Eos};
162 /// use bytecodec::fixnum::U8Encoder;
163 /// use trackable::track;
164 ///
165 /// let encoder = U8Encoder::with_item(7).unwrap();
166 /// let mut encoder = encoder.map_err(|e| track!(e, "oops!")); // or track_err!(encoder, "oops!")
167 /// let error = track!(encoder.encode(&mut [][..], Eos::new(true))).err().unwrap();
168 ///
169 /// assert_eq!(error.to_string(), "\
170 /// UnexpectedEos (cause; assertion failed: `!eos.is_reached()`; \
171 /// buf.len()=0, size=0, self.offset=0, b.as_ref().len()=1)
172 /// HISTORY:
173 /// [0] at src/bytes.rs:53
174 /// [1] at src/fixnum.rs:116
175 /// [2] at src/encode.rs:10 -- oops!
176 /// [3] at src/encode.rs:11\n");
177 /// ```
178 fn map_err<E, F>(self, f: F) -> MapErr<Self, E, F>
179 where
180 F: Fn(Error) -> E,
181 Error: From<E>,
182 {
183 MapErr::new(self, f)
184 }
185
186 /// Creates an encoder that converts items into ones that
187 /// suited to the `self` encoder by calling the given function.
188 ///
189 /// # Examples
190 ///
191 /// ```
192 /// use bytecodec::{Encode, EncodeExt};
193 /// use bytecodec::fixnum::U8Encoder;
194 /// use bytecodec::io::IoEncodeExt;
195 ///
196 /// let mut output = Vec::new();
197 /// let mut encoder = U8Encoder::new().map_from(|s: String| s.len() as u8);
198 /// let item = "Hello World!".to_owned();
199 /// encoder.start_encoding(item).unwrap();
200 /// encoder.encode_all(&mut output).unwrap();
201 /// assert_eq!(output, [12]);
202 /// ```
203 fn map_from<T, F>(self, f: F) -> MapFrom<Self, T, F>
204 where
205 F: Fn(T) -> Self::Item,
206 {
207 MapFrom::new(self, f)
208 }
209
210 /// Creates an encoder that tries to convert items into ones that
211 /// suited to the `self` encoder by calling the given function.
212 ///
213 /// # Examples
214 ///
215 /// ```
216 /// use bytecodec::{Encode, EncodeExt, ErrorKind, Result};
217 /// use bytecodec::fixnum::U8Encoder;
218 /// use bytecodec::io::IoEncodeExt;
219 /// use trackable::{track, track_assert, track_panic};
220 ///
221 /// let mut output = Vec::new();
222 /// let mut encoder = U8Encoder::new().try_map_from(|s: String| -> Result<_> {
223 /// track_assert!(s.len() <= 0xFF, ErrorKind::InvalidInput);
224 /// Ok(s.len() as u8)
225 /// });
226 /// let item = "Hello World!".to_owned();
227 /// encoder.start_encoding(item).unwrap();
228 /// encoder.encode_all(&mut output).unwrap();
229 /// assert_eq!(output, [12]);
230 /// ```
231 fn try_map_from<T, E, F>(self, f: F) -> TryMapFrom<Self, T, E, F>
232 where
233 F: Fn(T) -> std::result::Result<Self::Item, E>,
234 Error: From<E>,
235 {
236 TryMapFrom::new(self, f)
237 }
238
239 /// Creates an encoder that represents an optional encoder.
240 ///
241 /// It takes `Option<Self::Item>` items.
242 /// If `Some(_)` is passed as an argument for `start_encoding` method, it will be encoded as ordinally.
243 /// On the other hand, if `None` is passed, it will be ignored completely.
244 ///
245 /// # Examples
246 ///
247 /// ```
248 /// use bytecodec::{Encode, EncodeExt};
249 /// use bytecodec::fixnum::U8Encoder;
250 /// use bytecodec::io::IoEncodeExt;
251 ///
252 /// let mut output = Vec::new();
253 /// let mut encoder = U8Encoder::new().optional();
254 ///
255 /// encoder.start_encoding(None).unwrap();
256 /// encoder.encode_all(&mut output).unwrap();
257 ///
258 /// encoder.start_encoding(Some(9)).unwrap();
259 /// encoder.encode_all(&mut output).unwrap();
260 ///
261 /// assert_eq!(output, [9]);
262 /// ```
263 fn optional(self) -> Optional<Self> {
264 Optional::new(self)
265 }
266
267 /// Creates an encoder that will fail if the number of encoded bytes of an item exceeds `n`.
268 ///
269 /// # Examples
270 ///
271 /// ```
272 /// use bytecodec::{Encode, EncodeExt, ErrorKind};
273 /// use bytecodec::bytes::Utf8Encoder;
274 /// use bytecodec::io::IoEncodeExt;
275 ///
276 /// let mut output = Vec::new();
277 /// let mut encoder = Utf8Encoder::new().max_bytes(3);
278 ///
279 /// encoder.start_encoding("foo").unwrap(); // OK
280 /// encoder.encode_all(&mut output).unwrap();
281 /// assert_eq!(output, b"foo");
282 ///
283 /// encoder.start_encoding("hello").unwrap(); // Error
284 /// let error = encoder.encode_all(&mut output).err().unwrap();
285 /// assert_eq!(*error.kind(), ErrorKind::InvalidInput);
286 /// ```
287 fn max_bytes(self, n: u64) -> MaxBytes<Self> {
288 MaxBytes::new(self, n)
289 }
290
291 /// Creates an encoder that required to encode each item exactly at the specified number of bytes.
292 ///
293 /// # Examples
294 ///
295 /// ```
296 /// use bytecodec::{Encode, EncodeExt, ErrorKind};
297 /// use bytecodec::bytes::Utf8Encoder;
298 /// use bytecodec::io::IoEncodeExt;
299 ///
300 /// let mut output = Vec::new();
301 /// let mut encoder = Utf8Encoder::new().length(3);
302 /// encoder.start_encoding("hey").unwrap(); // OK
303 /// encoder.encode_all(&mut output).unwrap();
304 /// assert_eq!(output, b"hey");
305 ///
306 /// let mut encoder = Utf8Encoder::new().length(3);
307 /// encoder.start_encoding("hello").unwrap(); // Error (too long)
308 /// let error = encoder.encode_all(&mut output).err().unwrap();
309 /// assert_eq!(*error.kind(), ErrorKind::UnexpectedEos);
310 ///
311 /// let mut encoder = Utf8Encoder::new().length(3);
312 /// encoder.start_encoding("hi").unwrap(); // Error (too short)
313 /// let error = encoder.encode_all(&mut output).err().unwrap();
314 /// assert_eq!(*error.kind(), ErrorKind::InvalidInput);
315 /// ```
316 fn length(self, n: u64) -> Length<Self> {
317 Length::new(self, n)
318 }
319
320 /// Takes two encoders and creates a new encoder that encodes both items in sequence.
321 ///
322 /// This is equivalent to call `TupleEncoder::new((self, other))`.
323 fn chain<T: Encode>(self, other: T) -> TupleEncoder<(Self, T)> {
324 TupleEncoder::new((self, other))
325 }
326
327 /// Creates an encoder that repeats encoding of `Self::Item`.
328 ///
329 /// # Examples
330 ///
331 /// ```
332 /// use bytecodec::{Encode, EncodeExt, ErrorKind};
333 /// use bytecodec::fixnum::U8Encoder;
334 /// use bytecodec::io::IoEncodeExt;
335 ///
336 /// let mut output = Vec::new();
337 /// let mut encoder = U8Encoder::new().repeat();
338 /// encoder.start_encoding(0..4).unwrap();
339 /// encoder.encode_all(&mut output).unwrap();
340 /// assert_eq!(output, [0, 1, 2, 3]);
341 /// ```
342 fn repeat<I>(self) -> Repeat<Self, I>
343 where
344 I: Iterator<Item = Self::Item>,
345 {
346 Repeat::new(self)
347 }
348
349 /// Creates an encoder that pre-encodes items when `start_encoding` method is called.
350 ///
351 /// Although the number of memory copies increases,
352 /// pre-encoding will enable to acquire the exact size of encoded items.
353 ///
354 /// # Examples
355 ///
356 /// ```ignore
357 /// use bytecodec::{Encode, EncodeExt, ExactBytesEncode};
358 /// use bytecodec::fixnum::U8Encoder;
359 /// use bytecodec::io::IoEncodeExt;
360 ///
361 /// let mut output = Vec::new();
362 /// let mut encoder =
363 /// U8Encoder::new()
364 /// .repeat()
365 /// .pre_encode()
366 /// .with_prefix(U8Encoder::new(), |body| body.exact_requiring_bytes() as u8);
367 ///
368 /// encoder.start_encoding(0..3).unwrap();
369 /// encoder.encode_all(&mut output).unwrap();
370 /// assert_eq!(output, [3, 0, 1, 2]);
371 /// ```
372 fn pre_encode(self) -> PreEncode<Self> {
373 PreEncode::new(self)
374 }
375
376 /// Creates an encoder that makes it possible to slice the encoded byte sequence in arbitrary units.
377 ///
378 /// Slicing encoded byte sequences makes it easier to multiplex them into a single sequence.
379 ///
380 /// # Examples
381 ///
382 /// ```
383 /// use bytecodec::{Encode, EncodeExt, Eos};
384 /// use bytecodec::bytes::Utf8Encoder;
385 ///
386 /// let mut encoder = Utf8Encoder::new().slice();
387 /// encoder.start_encoding("foobarbaz").unwrap();
388 ///
389 /// let eos = Eos::new(true);
390 /// let mut output = [0; 9];
391 /// let mut offset = 0;
392 ///
393 /// encoder.set_consumable_bytes(3);
394 /// offset += encoder.encode(&mut output[offset..], eos).unwrap();
395 /// assert_eq!(offset, 3);
396 /// assert_eq!(encoder.is_idle(), false);
397 /// assert_eq!(encoder.consumable_bytes(), 0);
398 ///
399 /// offset += encoder.encode(&mut output[offset..], eos).unwrap();
400 /// assert_eq!(offset, 3);
401 ///
402 /// encoder.set_consumable_bytes(6);
403 /// offset += encoder.encode(&mut output[offset..], eos).unwrap();
404 /// assert_eq!(offset, 9);
405 /// assert_eq!(encoder.is_idle(), true);
406 /// assert_eq!(output.as_ref(), b"foobarbaz");
407 /// ```
408 fn slice(self) -> Slice<Self> {
409 Slice::new(self)
410 }
411
412 /// Creates an encoder that cannot accept any more items except the given one.
413 fn last(self, item: Self::Item) -> Last<Self> {
414 Last::new(self, item)
415 }
416
417 /// Encodes the given item and returns the resulting bytes.
418 ///
419 /// # Examples
420 ///
421 /// ```
422 /// use bytecodec::EncodeExt;
423 /// use bytecodec::fixnum::U16beEncoder;
424 ///
425 /// let mut encoder = U16beEncoder::new();
426 /// assert_eq!(encoder.encode_into_bytes(0x1234).unwrap(), [0x12, 0x34]);
427 /// ```
428 fn encode_into_bytes(&mut self, item: Self::Item) -> Result<Vec<u8>> {
429 track!(self.start_encoding(item))?;
430
431 match self.requiring_bytes() {
432 ByteCount::Finite(size) => {
433 track_assert!(size <= usize::MAX as u64, ErrorKind::Other; size);
434
435 let mut buf = vec![0; size as usize];
436 track!(self.encode(&mut buf, Eos::new(true)))?;
437 track_assert!(self.is_idle(), ErrorKind::InconsistentState);
438 Ok(buf)
439 }
440 ByteCount::Unknown => {
441 let mut buf = Vec::new();
442 track!(self.encode_all(&mut buf))?;
443 Ok(buf)
444 }
445 ByteCount::Infinite => track_panic!(ErrorKind::InvalidInput),
446 }
447 }
448}
449impl<T: Encode> EncodeExt for T {}
450
451#[cfg(test)]
452mod test {
453 use super::*;
454 use crate::fixnum::U16beEncoder;
455
456 #[test]
457 fn encode_into_bytes_works() {
458 let mut encoder = U16beEncoder::new();
459 assert_eq!(encoder.encode_into_bytes(0x1234).unwrap(), [0x12, 0x34]);
460 }
461}