bytecodec/
decode.rs

1use crate::combinator::{
2    AndThen, Collect, CollectN, Length, Map, MapErr, MaxBytes, MaybeEos, Omittable, Peekable,
3    Slice, TryMap,
4};
5use crate::tuple::TupleDecoder;
6use crate::{ByteCount, Eos, Error, ErrorKind, Result};
7
8/// This trait allows for decoding items from a byte sequence incrementally.
9pub trait Decode {
10    /// The type of items to be decoded.
11    type Item;
12
13    /// Consumes the given buffer (a part of a byte sequence), and proceeds the decoding process.
14    ///
15    /// It returns the number of bytes consumed from the input buffer.
16    ///
17    /// If an item is completely decoded, the next invocation of `is_idle` method will return `true`.
18    /// And if `is_idle` method returns `true`, `decode` method should consume no bytes.
19    ///
20    /// The decoder must consume as many bytes in the buffer as possible.
21    /// If an item is not yet decoded but the number of consumed bytes in the last `decode` invocation
22    /// is smaller than the length of `buf`, it means the decoder has been suspended its work in any reasons.
23    /// In that case the decoder may require some instructions from clients to resume the work,
24    /// but its concrete method is beyond the scope of this trait.
25    ///
26    /// # Errors
27    ///
28    /// The following errors may be returned by the decoder:
29    /// - `ErrorKind::DecoderTerminated`:
30    ///   - If all decodable items have been decoded,
31    ///     the decoder must return this kind of error when `decode` method is called.
32    /// - `ErrorKind::UnexpectedEos`:
33    ///   - The invocation of `eos.is_reached()` returns `true` despite of
34    ///     the decoder requires more bytes to decode the next item.
35    /// - `ErrorKind::InvalidInput`:
36    ///   - Decoded items have invalid values
37    ///   - Invalid parameters were given to decoders
38    /// - `ErrorKind::InconsistentState`:
39    ///   - The state of the decoder bocame inconsistent
40    ///   - This means the implementation contains a bug
41    /// - `ErrorKind::Other`:
42    ///   - Other errors
43    fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize>;
44
45    /// Finishes the current decoding process and returns the decoded item.
46    ///
47    /// # Errors
48    ///
49    /// The following errors may be returned by the decoder:
50    /// - `ErrorKind::IncompleteDecoding`:
51    ///   - The decoding process has not been completed
52    /// - `ErrorKind::DecoderTerminated`:
53    ///   - The decoder has terminated (i.e., cannot decode any more items)
54    /// - `ErrorKind::InconsistentState`:
55    ///   - The state of the decoder bocame inconsistent
56    ///   - This means the implementation contains a bug
57    /// - `ErrorKind::Other`:
58    ///   - Other errors
59    fn finish_decoding(&mut self) -> Result<Self::Item>;
60
61    /// Returns the lower bound of the number of bytes needed to decode the next item.
62    ///
63    /// If the decoder does not know the value, it will return `ByteCount::Unknown`
64    /// (e.g., null-terminated strings have no pre-estimable length).
65    ///
66    /// If the decoder returns `ByteCount::Finite(0)`, it means one of the followings:
67    /// - (a) There is an already decoded item
68    ///   - The next invocation of `decode()` will return it without consuming any bytes
69    /// - (b) There are no decodable items
70    ///   - All decodable items have been decoded, and the decoder cannot do any further works
71    ///   - In this case, the next invocation of `decode` method will fail.
72    fn requiring_bytes(&self) -> ByteCount;
73
74    /// Returns `true` if there are no items to be decoded by the decoder
75    /// at the next invocation of `decode` method, otherwise `false`.
76    ///
77    /// Typically, `true` means the decoder already has a decoded item and
78    /// it is waiting for `finish_decoding` to be called.
79    ///
80    /// The default implementation returns the result of `self.requiring_bytes() == ByteCount::Finite(0)`.
81    fn is_idle(&self) -> bool {
82        self.requiring_bytes() == ByteCount::Finite(0)
83    }
84}
85impl<'a, D: ?Sized + Decode> Decode for &'a mut D {
86    type Item = D::Item;
87
88    fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
89        (**self).decode(buf, eos)
90    }
91
92    fn finish_decoding(&mut self) -> Result<Self::Item> {
93        (**self).finish_decoding()
94    }
95
96    fn requiring_bytes(&self) -> ByteCount {
97        (**self).requiring_bytes()
98    }
99
100    fn is_idle(&self) -> bool {
101        (**self).is_idle()
102    }
103}
104impl<D: ?Sized + Decode> Decode for Box<D> {
105    type Item = D::Item;
106
107    fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
108        (**self).decode(buf, eos)
109    }
110
111    fn finish_decoding(&mut self) -> Result<Self::Item> {
112        (**self).finish_decoding()
113    }
114
115    fn requiring_bytes(&self) -> ByteCount {
116        (**self).requiring_bytes()
117    }
118
119    fn is_idle(&self) -> bool {
120        (**self).is_idle()
121    }
122}
123
124/// An extension of `Decode` trait.
125pub trait DecodeExt: Decode + Sized {
126    /// Creates a decoder that converts decoded values by calling the given function.
127    ///
128    /// # Examples
129    ///
130    /// ```
131    /// use bytecodec::{Decode, DecodeExt};
132    /// use bytecodec::fixnum::U8Decoder;
133    /// use bytecodec::io::IoDecodeExt;
134    ///
135    /// let mut decoder = U8Decoder::new().map(|b| b * 2);
136    /// let item = decoder.decode_exact([10].as_ref()).unwrap();
137    /// assert_eq!(item, 20);
138    /// ```
139    fn map<T, F>(self, f: F) -> Map<Self, T, F>
140    where
141        F: Fn(Self::Item) -> T,
142    {
143        Map::new(self, f)
144    }
145
146    /// Creates a decoder that tries to convert decoded values by calling the given function.
147    ///
148    /// # Examples
149    ///
150    /// ```
151    /// use bytecodec::{Decode, DecodeExt, ErrorKind, Result};
152    /// use bytecodec::fixnum::U8Decoder;
153    /// use bytecodec::io::IoDecodeExt;
154    /// use trackable::{track, track_assert, track_assert_ne, track_panic};
155    ///
156    /// let mut decoder = U8Decoder::new().try_map(|b| -> Result<_> {
157    ///     track_assert_ne!(b, 0, ErrorKind::InvalidInput);
158    ///     Ok(b * 2)
159    /// });
160    ///
161    /// let error = decoder.decode_exact([0].as_ref()).err().unwrap();
162    /// assert_eq!(*error.kind(), ErrorKind::InvalidInput);
163    ///
164    /// let item = decoder.decode_exact([4].as_ref()).unwrap();
165    /// assert_eq!(item, 8);
166    /// ```
167    fn try_map<T, E, F>(self, f: F) -> TryMap<Self, T, E, F>
168    where
169        F: Fn(Self::Item) -> std::result::Result<T, E>,
170        Error: From<E>,
171    {
172        TryMap::new(self, f)
173    }
174
175    /// Creates a decoder for modifying decoding errors produced by `self`.
176    ///
177    /// # Examples
178    ///
179    /// The following code shows the idiomatic way to track decoding errors:
180    ///
181    /// ```
182    /// use bytecodec::{Decode, DecodeExt};
183    /// use bytecodec::fixnum::U16beDecoder;
184    /// use bytecodec::io::IoDecodeExt;
185    /// use trackable::track;
186    ///
187    /// let mut decoder =
188    ///     U16beDecoder::new().map_err(|e| track!(e, "oops!"));
189    ///     // or `track_err!(U16beDecoder::new(), "oops!")`
190    ///
191    /// let input = [0]; // Insufficient bytes
192    /// let error = track!(decoder.decode_exact(input.as_ref())).err().unwrap();
193    ///
194    /// assert_eq!(error.to_string(), "\
195    /// UnexpectedEos (cause; assertion failed: `!eos.is_reached()`; \
196    ///                self.offset=1, self.bytes.as_ref().len()=2)
197    /// HISTORY:
198    ///   [0] at src/bytes.rs:152
199    ///   [1] at src/fixnum.rs:200
200    ///   [2] at src/decode.rs:10 -- oops!
201    ///   [3] at src/io.rs:45
202    ///   [4] at src/decode.rs:14\n");
203    /// ```
204    fn map_err<E, F>(self, f: F) -> MapErr<Self, E, F>
205    where
206        F: Fn(Error) -> E,
207        Error: From<E>,
208    {
209        MapErr::new(self, f)
210    }
211
212    /// Creates a decoder that enables conditional decoding.
213    ///
214    /// If the first item is successfully decoded,
215    /// it will start decoding the second item by using the decoder returned by `f` function.
216    ///
217    /// # Examples
218    ///
219    /// Decodes a length-prefixed string:
220    ///
221    /// ```
222    /// use bytecodec::{Decode, DecodeExt};
223    /// use bytecodec::bytes::Utf8Decoder;
224    /// use bytecodec::fixnum::U8Decoder;
225    /// use bytecodec::io::IoDecodeExt;
226    ///
227    /// let mut decoder = U8Decoder::new().and_then(|len| Utf8Decoder::new().length(len as u64));
228    /// let item = decoder.decode_exact(b"\x03foobar".as_ref()).unwrap();
229    /// assert_eq!(item, "foo");
230    /// ```
231    fn and_then<D, F>(self, f: F) -> AndThen<Self, D, F>
232    where
233        F: Fn(Self::Item) -> D,
234        D: Decode,
235    {
236        AndThen::new(self, f)
237    }
238
239    /// Creates a decoder for collecting decoded items.
240    ///
241    /// # Examples
242    ///
243    /// ```
244    /// use bytecodec::{Decode, DecodeExt};
245    /// use bytecodec::fixnum::U8Decoder;
246    /// use bytecodec::io::IoDecodeExt;
247    ///
248    /// let mut decoder = U8Decoder::new().collect::<Vec<_>>();
249    /// let item = decoder.decode_exact(b"foo".as_ref()).unwrap();
250    /// assert_eq!(item, vec![b'f', b'o', b'o']);
251    /// ```
252    fn collect<T>(self) -> Collect<Self, T>
253    where
254        T: Extend<Self::Item> + Default,
255    {
256        Collect::new(self)
257    }
258
259    /// Creates a decoder that decodes `n` items by using `self` and collecting the result.
260    ///
261    /// # Examples
262    ///
263    /// ```
264    /// use bytecodec::{Decode, DecodeExt};
265    /// use bytecodec::fixnum::U8Decoder;
266    /// use bytecodec::io::IoDecodeExt;
267    ///
268    /// let mut decoder = U8Decoder::new().collectn::<Vec<_>>(2);
269    /// let item = decoder.decode_exact(b"foo".as_ref()).unwrap();
270    /// assert_eq!(item, vec![b'f', b'o']);
271    /// ```
272    fn collectn<T>(self, n: usize) -> CollectN<Self, T>
273    where
274        T: Extend<Self::Item> + Default,
275    {
276        CollectN::new(self, n)
277    }
278
279    /// Creates a decoder that consumes the specified number of bytes exactly.
280    ///
281    /// # Examples
282    ///
283    /// ```
284    /// use bytecodec::{Decode, DecodeExt, ErrorKind};
285    /// use bytecodec::bytes::Utf8Decoder;
286    /// use bytecodec::io::IoDecodeExt;
287    ///
288    /// let mut decoder = Utf8Decoder::new().length(3);
289    /// let mut input = &b"foobarba"[..];
290    ///
291    /// let item = decoder.decode_exact(&mut input).unwrap();
292    /// assert_eq!(item, "foo");
293    ///
294    /// let item = decoder.decode_exact(&mut input).unwrap();
295    /// assert_eq!(item, "bar");
296    ///
297    /// let error = decoder.decode_exact(&mut input).err().unwrap();
298    /// assert_eq!(*error.kind(), ErrorKind::UnexpectedEos);
299    /// ```
300    fn length(self, expected_bytes: u64) -> Length<Self> {
301        Length::new(self, expected_bytes)
302    }
303
304    /// Creates a decoder that will omit decoding items if `do_omit = true` is specified.
305    ///
306    /// # Examples
307    ///
308    /// ```
309    /// use bytecodec::{Decode, DecodeExt};
310    /// use bytecodec::fixnum::U8Decoder;
311    /// use bytecodec::io::IoDecodeExt;
312    ///
313    /// let mut input = &b"foo"[..];
314    ///
315    /// let mut decoder = U8Decoder::new().omit(true);
316    /// let item = decoder.decode_exact(&mut input).unwrap();
317    /// assert_eq!(item, None);
318    ///
319    /// let mut decoder = U8Decoder::new().omit(false);
320    /// let item = decoder.decode_exact(&mut input).unwrap();
321    /// assert_eq!(item, Some(b'f'));
322    /// ```
323    fn omit(self, do_omit: bool) -> Omittable<Self> {
324        Omittable::new(self, do_omit)
325    }
326
327    /// Creates a decoder that will fail if the number of consumed bytes exceeds `bytes`.
328    ///
329    /// # Examples
330    ///
331    /// ```
332    /// use bytecodec::{Decode, DecodeExt, ErrorKind};
333    /// use bytecodec::bytes::Utf8Decoder;
334    /// use bytecodec::io::IoDecodeExt;
335    ///
336    /// let mut decoder = Utf8Decoder::new().max_bytes(3);
337    ///
338    /// let item = decoder.decode_exact(b"foo".as_ref()).unwrap();
339    /// assert_eq!(item, "foo"); // OK
340    ///
341    /// let error = decoder.decode_exact(b"hello".as_ref()).err();
342    /// assert_eq!(error.map(|e| *e.kind()), Some(ErrorKind::InvalidInput)); // Error
343    /// ```
344    fn max_bytes(self, bytes: u64) -> MaxBytes<Self> {
345        MaxBytes::new(self, bytes)
346    }
347
348    /// Takes two decoders and creates a new decoder that decodes both items in sequence.
349    ///
350    /// This is equivalent to call `TupleDecoder::new((self, other))`.
351    fn chain<T: Decode>(self, other: T) -> TupleDecoder<(Self, T)> {
352        TupleDecoder::new((self, other))
353    }
354
355    /// Creates a decoder that makes it possible to slice the input byte sequence in arbitrary units.
356    ///
357    /// Slicing an input byte sequence makes it easier to demultiplex multiple sequences from it.
358    ///
359    /// # Examples
360    ///
361    /// ```
362    /// use bytecodec::{Decode, DecodeExt, Eos};
363    /// use bytecodec::bytes::Utf8Decoder;
364    ///
365    /// let mut decoder0 = Utf8Decoder::new().length(3).slice();
366    /// let mut decoder1 = Utf8Decoder::new().length(3).slice();
367    ///
368    /// let eos = Eos::new(true);
369    /// let input = b"fboaor";
370    /// let mut offset = 0;
371    ///
372    /// for _ in 0..3 {
373    ///     decoder0.set_consumable_bytes(1);
374    ///     offset += decoder0.decode(&input[offset..], eos).unwrap();
375    ///
376    ///     decoder1.set_consumable_bytes(1);
377    ///     offset += decoder1.decode(&input[offset..], eos).unwrap();
378    /// }
379    ///
380    /// assert_eq!(offset, input.len());
381    /// assert_eq!(decoder0.finish_decoding().unwrap(), "foo");
382    /// assert_eq!(decoder1.finish_decoding().unwrap(), "bar");
383    /// ```
384    fn slice(self) -> Slice<Self> {
385        Slice::new(self)
386    }
387
388    /// Creates a decoder that enables to peek decoded items before calling `finish_decoding` method.
389    ///
390    /// # Examples
391    ///
392    /// ```
393    /// use bytecodec::{Decode, DecodeExt, Eos};
394    /// use bytecodec::fixnum::U8Decoder;
395    /// use bytecodec::tuple::TupleDecoder;
396    ///
397    /// let mut decoder = TupleDecoder::new((
398    ///     U8Decoder::new(),
399    ///     U8Decoder::new(),
400    ///     U8Decoder::new(),
401    /// )).peekable();
402    /// let size = decoder.decode(b"foo", Eos::new(false)).unwrap();
403    /// assert_eq!(size, 3);
404    /// assert_eq!(decoder.peek(), Some(&(b'f', b'o', b'o')));
405    /// assert_eq!(decoder.finish_decoding().unwrap(), (b'f', b'o', b'o'));
406    /// assert_eq!(decoder.peek(), None);
407    /// ```
408    fn peekable(self) -> Peekable<Self> {
409        Peekable::new(self)
410    }
411
412    /// Creates a decoder that ignores EOS if there is no item being decoded.
413    ///
414    /// # Examples
415    ///
416    /// ```
417    /// use bytecodec::{Decode, DecodeExt, Eos};
418    /// use bytecodec::fixnum::U16beDecoder;
419    ///
420    /// let mut decoder = U16beDecoder::new();
421    /// assert!(decoder.decode(&[][..], Eos::new(true)).is_err()); // UnexpectedEos
422    ///
423    /// let mut decoder = U16beDecoder::new().maybe_eos();
424    /// assert!(decoder.decode(&[][..], Eos::new(true)).is_ok()); // EOS is ignored
425    ///
426    /// let mut decoder = U16beDecoder::new().maybe_eos();
427    /// assert!(decoder.decode(&[1][..], Eos::new(true)).is_err()); // UnexpectedEos
428    /// ```
429    fn maybe_eos(self) -> MaybeEos<Self> {
430        MaybeEos::new(self)
431    }
432
433    /// Decodes an item by consuming the whole part of the given bytes.
434    ///
435    /// # Examples
436    ///
437    /// ```
438    /// use bytecodec::DecodeExt;
439    /// use bytecodec::fixnum::U16beDecoder;
440    ///
441    /// let mut decoder = U16beDecoder::new();
442    /// assert_eq!(
443    ///     decoder.decode_from_bytes(&[0x12, 0x34][..]).unwrap(),
444    ///     0x1234
445    /// );
446    /// ```
447    fn decode_from_bytes(&mut self, buf: &[u8]) -> Result<Self::Item> {
448        let size = track!(self.decode(buf, Eos::new(true)))?;
449        track_assert_eq!(size, buf.len(), ErrorKind::InvalidInput; self.is_idle());
450        track!(self.finish_decoding())
451    }
452}
453impl<T: Decode> DecodeExt for T {}
454
455/// This trait allows for decoding tagged items from a byte sequence incrementally.
456pub trait TaggedDecode: Decode {
457    /// The type of tags prefixed to the items to be decoded.
458    type Tag;
459
460    /// Prepares to start decoding an item tagged by `tag`.
461    ///
462    /// # Errors
463    ///
464    /// The following errors may be returned by the decoder:
465    /// - `ErrorKind::InvalidInput`:
466    ///   - Unexpected tag was passed
467    /// - `ErrorKind::IncompleteDecoding`:
468    ///   - The previous decoding process has not been completed
469    /// - `ErrorKind::DecoderTerminated`:
470    ///   - The decoder has terminated (i.e., cannot decode any more items)
471    /// - `ErrorKind::Other`:
472    ///   - Other errors has occurred
473    fn start_decoding(&mut self, tag: Self::Tag) -> Result<()>;
474}
475impl<'a, D: ?Sized + TaggedDecode> TaggedDecode for &'a mut D {
476    type Tag = D::Tag;
477
478    fn start_decoding(&mut self, tag: Self::Tag) -> Result<()> {
479        (**self).start_decoding(tag)
480    }
481}
482impl<D: ?Sized + TaggedDecode> TaggedDecode for Box<D> {
483    type Tag = D::Tag;
484
485    fn start_decoding(&mut self, tag: Self::Tag) -> Result<()> {
486        (**self).start_decoding(tag)
487    }
488}
489
490/// This trait allows for decoding known-tagged or unknown-tagged items from a byte sequence incrementally.
491pub trait TryTaggedDecode: Decode {
492    /// The type of tags prefixed to the items to be decoded.
493    type Tag;
494
495    /// Tries to prepare to start decoding an item tagged by `tag`.
496    ///
497    /// If the given tag is unknown, it will return `Ok(false)`.
498    ///
499    /// # Errors
500    ///
501    /// The following errors may be returned by the decoder:
502    /// - `ErrorKind::IncompleteDecoding`:
503    ///   - The previous decoding process has not been completed
504    /// - `ErrorKind::DecoderTerminated`:
505    ///   - The decoder has terminated (i.e., cannot decode any more items)
506    /// - `ErrorKind::Other`:
507    ///   - Other errors has occurred
508    fn try_start_decoding(&mut self, tag: Self::Tag) -> Result<bool>;
509}
510impl<'a, D: ?Sized + TryTaggedDecode> TryTaggedDecode for &'a mut D {
511    type Tag = D::Tag;
512
513    fn try_start_decoding(&mut self, tag: Self::Tag) -> Result<bool> {
514        (**self).try_start_decoding(tag)
515    }
516}
517impl<D: ?Sized + TryTaggedDecode> TryTaggedDecode for Box<D> {
518    type Tag = D::Tag;
519
520    fn try_start_decoding(&mut self, tag: Self::Tag) -> Result<bool> {
521        (**self).try_start_decoding(tag)
522    }
523}
524
525#[cfg(test)]
526mod test {
527    use super::*;
528    use crate::fixnum::U16beDecoder;
529
530    #[test]
531    fn decode_from_bytes_works() {
532        let mut decoder = U16beDecoder::new();
533        assert_eq!(
534            decoder.decode_from_bytes(&[0x12, 0x34][..]).unwrap(),
535            0x1234
536        );
537    }
538}