1 // Copyright 2023 Google LLC
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 //     https://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.
14 
15 //! Helper definitions used used by the generated Rust backend.
16 
17 use bytes::{BufMut, Bytes, BytesMut};
18 
19 /// Type of parsing errors.
20 #[derive(Debug, thiserror::Error, PartialEq, Eq)]
21 pub enum DecodeError {
22     #[error("packet parsing failed")]
23     InvalidPacketError,
24     #[error("{field} was {value:x}, which is not known")]
25     ConstraintOutOfBounds { field: &'static str, value: u64 },
26     #[error("Got {actual:x}, expected {expected:x}")]
27     InvalidFixedValue { expected: u64, actual: u64 },
28     #[error("when parsing {obj} needed length of {wanted} but got {got}")]
29     InvalidLengthError { obj: &'static str, wanted: usize, got: usize },
30     #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")]
31     InvalidArraySize { array: usize, element: usize },
32     #[error("Due to size restrictions a struct could not be parsed.")]
33     ImpossibleStructError,
34     #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")]
35     InvalidEnumValueError {
36         obj: &'static str,
37         field: &'static str,
38         value: u64,
39         type_: &'static str,
40     },
41     #[error("invalid field {packet}::{field} value, {expected} != {actual}")]
42     InvalidFieldValue {
43         packet: &'static str,
44         field: &'static str,
45         expected: &'static str,
46         actual: String,
47     },
48     #[error("expected child {expected}, got {actual}")]
49     InvalidChildError { expected: &'static str, actual: String },
50     #[error("packet has trailing bytes")]
51     TrailingBytes,
52     #[error("packet has trailing bytes inside {obj}.{field} array")]
53     TrailingBytesInArray { obj: &'static str, field: &'static str },
54 }
55 
56 /// Type of serialization errors.
57 #[derive(Debug, thiserror::Error, PartialEq, Eq)]
58 pub enum EncodeError {
59     #[error("the size of {packet}::{field} ({size}) is outside the range of valid values 0..{maximum_size}")]
60     SizeOverflow { packet: &'static str, field: &'static str, size: usize, maximum_size: usize },
61     #[error(
62         "the count of {packet}::{field} ({count}) is outside the range of valid values 0..{maximum_count}"
63     )]
64     CountOverflow { packet: &'static str, field: &'static str, count: usize, maximum_count: usize },
65     #[error(
66         "the value of {packet}::{field} ({value}) is outside the range of valid values 0..{maximum_value}"
67     )]
68     InvalidScalarValue { packet: &'static str, field: &'static str, value: u64, maximum_value: u64 },
69     #[error(
70         "{packet}.{field}[{element_index}] size is {size}, but {expected_size} was expected (size of {packet}.{field}[0])"
71     )]
72     InvalidArrayElementSize {
73         packet: &'static str,
74         field: &'static str,
75         size: usize,
76         expected_size: usize,
77         element_index: usize,
78     },
79 }
80 
81 /// Trait implemented for all toplevel packet declarations.
82 pub trait Packet: Sized {
83     /// Try parsing an instance of Self from the input slice.
84     /// On success, returns the parsed object and the remaining unparsed slice.
85     /// On failure, returns an error with the reason for the parsing failure.
decode(buf: &[u8]) -> Result<(Self, &[u8]), DecodeError>86     fn decode(buf: &[u8]) -> Result<(Self, &[u8]), DecodeError>;
87 
88     /// Try parsing an instance of Packet updating the slice in place
89     /// to the remainder of the data. The input buffer is not updated if
90     /// parsing fails.
decode_mut(buf: &mut &[u8]) -> Result<Self, DecodeError>91     fn decode_mut(buf: &mut &[u8]) -> Result<Self, DecodeError> {
92         let (packet, remaining) = Self::decode(buf)?;
93         *buf = remaining;
94         Ok(packet)
95     }
96 
97     /// Try parsing an instance of Packet from the input slice.
98     /// Returns an error if unparsed bytes remain at the end of the input slice.
decode_full(buf: &[u8]) -> Result<Self, DecodeError>99     fn decode_full(buf: &[u8]) -> Result<Self, DecodeError> {
100         let (packet, remaining) = Self::decode(buf)?;
101         if remaining.is_empty() {
102             Ok(packet)
103         } else {
104             Err(DecodeError::TrailingBytes)
105         }
106     }
107 
108     /// Return the length of the encoded packet.
encoded_len(&self) -> usize109     fn encoded_len(&self) -> usize;
110 
111     /// Write the packet to an output buffer.
encode(&self, buf: &mut impl BufMut) -> Result<(), EncodeError>112     fn encode(&self, buf: &mut impl BufMut) -> Result<(), EncodeError>;
113 
114     /// Encode the packet to a byte vector.
encode_to_vec(&self) -> Result<Vec<u8>, EncodeError>115     fn encode_to_vec(&self) -> Result<Vec<u8>, EncodeError> {
116         let mut buf = Vec::with_capacity(self.encoded_len());
117         self.encode(&mut buf)?;
118         Ok(buf)
119     }
120 
121     /// Encode the packet to a Bytes object.
encode_to_bytes(&self) -> Result<Bytes, EncodeError>122     fn encode_to_bytes(&self) -> Result<Bytes, EncodeError> {
123         let mut buf = BytesMut::with_capacity(self.encoded_len());
124         self.encode(&mut buf)?;
125         Ok(buf.freeze())
126     }
127 }
128