matrix_pickle/
decode.rs

1// Copyright 2021 Damir Jelić
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14use std::io::{Cursor, Read};
15
16use crate::{DecodeError, MAX_ARRAY_LENGTH};
17
18/// A trait for decoding values that were encoded using the `matrix-pickle` binary format.
19pub trait Decode {
20    /// Try to read and decode a value from the given reader.
21    fn decode(reader: &mut impl Read) -> Result<Self, DecodeError>
22    where
23        Self: Sized;
24
25    /// Try to read and decode a value from the given byte slice.
26    fn decode_from_slice(buffer: &[u8]) -> Result<Self, DecodeError>
27    where
28        Self: Sized,
29    {
30        let mut cursor = Cursor::new(buffer);
31        Self::decode(&mut cursor)
32    }
33}
34
35impl Decode for u8 {
36    fn decode(reader: &mut impl Read) -> Result<Self, DecodeError> {
37        let mut buffer = [0u8; 1];
38
39        reader.read_exact(&mut buffer)?;
40
41        Ok(buffer[0])
42    }
43}
44
45impl Decode for bool {
46    fn decode(reader: &mut impl Read) -> Result<Self, DecodeError> {
47        let value = u8::decode(reader)?;
48
49        Ok(value != 0)
50    }
51}
52
53impl Decode for u32 {
54    fn decode(reader: &mut impl Read) -> Result<Self, DecodeError> {
55        let mut buffer = [0u8; 4];
56        reader.read_exact(&mut buffer)?;
57
58        Ok(u32::from_be_bytes(buffer))
59    }
60}
61
62impl Decode for usize {
63    fn decode(reader: &mut impl Read) -> Result<Self, DecodeError> {
64        let size = u32::decode(reader)?;
65
66        size.try_into()
67            .map_err(|_| DecodeError::OutsideUsizeRange(size as u64))
68    }
69}
70
71impl<const N: usize> Decode for [u8; N] {
72    fn decode(reader: &mut impl Read) -> Result<Self, DecodeError> {
73        let mut buffer = [0u8; N];
74        reader.read_exact(&mut buffer)?;
75
76        Ok(buffer)
77    }
78}
79
80impl<const N: usize> Decode for Box<[u8; N]> {
81    fn decode(reader: &mut impl Read) -> Result<Self, DecodeError> {
82        let mut buffer = Box::new([0u8; N]);
83        reader.read_exact(buffer.as_mut_slice())?;
84
85        Ok(buffer)
86    }
87}
88
89impl<T: Decode> Decode for Vec<T> {
90    fn decode(reader: &mut impl Read) -> Result<Self, DecodeError> {
91        let length = usize::decode(reader)?;
92
93        if length > MAX_ARRAY_LENGTH {
94            Err(DecodeError::ArrayTooBig(length))
95        } else {
96            let mut buffer = Vec::with_capacity(length);
97
98            for _ in 0..length {
99                let element = T::decode(reader)?;
100                buffer.push(element);
101            }
102
103            Ok(buffer)
104        }
105    }
106}