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}