s2n_codec/decoder/
value.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    decoder::{
6        buffer::{DecoderBuffer, DecoderBufferResult},
7        buffer_mut::{DecoderBufferMut, DecoderBufferMutResult},
8    },
9    unaligned::{i24, i48, u24, u48},
10};
11use byteorder::{ByteOrder, NetworkEndian};
12use core::mem::size_of;
13
14pub trait DecoderValue<'a>: Sized {
15    fn decode(bytes: DecoderBuffer<'a>) -> DecoderBufferResult<'a, Self>;
16}
17
18pub trait DecoderValueMut<'a>: Sized {
19    fn decode_mut(bytes: DecoderBufferMut<'a>) -> DecoderBufferMutResult<'a, Self>;
20}
21
22#[macro_export]
23macro_rules! decoder_value {
24    (impl<$lt:lifetime $(, $generic:ident)*> $ty:ty {
25        fn decode($buffer:ident: Buffer) -> Result<$ret:ty> $impl:block
26    }) => {
27        impl<$lt $(, $generic: $crate::DecoderValue<$lt>)*> $crate::DecoderValue<$lt> for $ty {
28            #[inline]
29            fn decode($buffer: $crate::DecoderBuffer<$lt>) -> $crate::DecoderBufferResult<$lt, $ret> $impl
30        }
31
32        impl<$lt $(, $generic: $crate::DecoderValueMut<$lt>)*> $crate::DecoderValueMut<$lt> for $ty {
33            #[inline]
34            fn decode_mut($buffer: $crate::DecoderBufferMut<$lt>) -> $crate::DecoderBufferMutResult<$lt, $ret> $impl
35        }
36    };
37}
38
39macro_rules! decoder_value_byte {
40    ($ty:ident) => {
41        decoder_value!(
42            impl<'a> $ty {
43                fn decode(buffer: Buffer) -> Result<Self> {
44                    let (value, buffer) = buffer.decode_slice(size_of::<Self>())?;
45                    let value = value.as_less_safe_slice()[0] as $ty;
46                    Ok((value, buffer))
47                }
48            }
49        );
50    };
51}
52
53decoder_value_byte!(u8);
54decoder_value_byte!(i8);
55
56macro_rules! decoder_value_network_endian {
57    ($call:ident, $ty:ty) => {
58        decoder_value!(
59            impl<'a> $ty {
60                fn decode(buffer: Buffer) -> Result<Self> {
61                    let (value, buffer) = buffer.decode_slice(size_of::<Self>())?;
62                    let value = value.as_less_safe_slice();
63                    let value = NetworkEndian::$call(value);
64                    Ok((value.into(), buffer))
65                }
66            }
67        );
68    };
69}
70
71decoder_value_network_endian!(read_u16, u16);
72decoder_value_network_endian!(read_i16, i16);
73decoder_value_network_endian!(read_u32, u32);
74decoder_value_network_endian!(read_i32, i32);
75decoder_value_network_endian!(read_u64, u64);
76decoder_value_network_endian!(read_i64, i64);
77decoder_value_network_endian!(read_u128, u128);
78decoder_value_network_endian!(read_i128, i128);
79decoder_value_network_endian!(read_f32, f32);
80decoder_value_network_endian!(read_f64, f64);
81
82macro_rules! decoder_value_unaligned_integer {
83    ($call:ident, $ty:ident, $bitsize:expr) => {
84        decoder_value!(
85            impl<'a> $ty {
86                fn decode(buffer: Buffer) -> Result<Self> {
87                    let (value, buffer) = buffer.decode_slice($bitsize / 8)?;
88                    let value = value.as_less_safe_slice();
89                    let value = NetworkEndian::$call(value);
90                    Ok(($ty::new_truncated(value), buffer))
91                }
92            }
93        );
94    };
95}
96
97decoder_value_unaligned_integer!(read_u24, u24, 24);
98decoder_value_unaligned_integer!(read_i24, i24, 24);
99decoder_value_unaligned_integer!(read_u48, u48, 48);
100decoder_value_unaligned_integer!(read_i48, i48, 48);
101
102decoder_value!(
103    impl<'a> DecoderBuffer<'a> {
104        fn decode(buffer: Buffer) -> Result<Self> {
105            let len = buffer.len();
106            let (slice, buffer) = buffer.decode_slice(len)?;
107            #[allow(clippy::useless_conversion)]
108            let slice = slice.into();
109            Ok((slice, buffer))
110        }
111    }
112);
113
114decoder_value!(
115    impl<'a> () {
116        fn decode(buffer: Buffer) -> Result<Self> {
117            Ok(((), buffer))
118        }
119    }
120);
121
122decoder_value!(
123    impl<'a, T> Option<T> {
124        fn decode(buffer: Buffer) -> Result<Self> {
125            if buffer.is_empty() {
126                Ok((None, buffer))
127            } else {
128                let (value, buffer) = buffer.decode()?;
129                Ok((Some(value), buffer))
130            }
131        }
132    }
133);
134
135impl<'a> DecoderValueMut<'a> for DecoderBufferMut<'a> {
136    #[inline]
137    fn decode_mut(buffer: DecoderBufferMut<'a>) -> DecoderBufferMutResult<'a, Self> {
138        let len = buffer.len();
139        buffer.decode_slice(len)
140    }
141}
142
143/// A value whose decoding implementation can be altered
144/// by a provided parameter.
145pub trait DecoderParameterizedValue<'a>: Sized {
146    type Parameter;
147
148    fn decode_parameterized(
149        parameter: Self::Parameter,
150        bytes: DecoderBuffer<'a>,
151    ) -> DecoderBufferResult<'a, Self>;
152}
153
154/// A mutable value whose decoding implementation can be altered
155/// by a provided parameter.
156pub trait DecoderParameterizedValueMut<'a>: Sized {
157    type Parameter;
158
159    fn decode_parameterized_mut(
160        parameter: Self::Parameter,
161        bytes: DecoderBufferMut<'a>,
162    ) -> DecoderBufferMutResult<'a, Self>;
163}
164
165#[macro_export]
166macro_rules! decoder_parameterized_value {
167    (impl<$lt:lifetime $(, $generic:ident)*> $ty:ty {
168        fn decode($tag:ident: $tag_ty:ty, $buffer:ident: Buffer) -> Result<$ret:ty> $impl:block
169    }) => {
170        impl<$lt $(, $generic: $crate::DecoderValue<$lt>)*> $crate::DecoderParameterizedValue<$lt> for $ty {
171            type Parameter = $tag_ty;
172
173            #[inline]
174            fn decode_parameterized($tag: Self::Parameter, $buffer: $crate::DecoderBuffer<$lt>) -> $crate::DecoderBufferResult<$lt, $ret> $impl
175        }
176
177        impl<$lt $(, $generic: $crate::DecoderValueMut<$lt>)*> $crate::DecoderParameterizedValueMut<$lt> for $ty {
178            type Parameter = $tag_ty;
179
180            #[inline]
181            fn decode_parameterized_mut($tag: Self::Parameter, $buffer: $crate::DecoderBufferMut<$lt>) -> $crate::DecoderBufferMutResult<$lt, $ret> $impl
182        }
183    };
184}