bt_common/
packet_encoding.rs1use thiserror::Error;
6
7pub trait Decodable: ::core::marker::Sized {
10 type Error;
11
12 fn decode(buf: &[u8]) -> (::core::result::Result<Self, Self::Error>, usize);
18
19 fn decode_multiple(
25 buf: &[u8],
26 max: Option<usize>,
27 ) -> (Vec<::core::result::Result<Self, Self::Error>>, usize) {
28 let mut idx = 0;
29 let mut result = Vec::new();
30 while idx < buf.len() && Some(result.len()) != max {
31 let (one_result, consumed) = Self::decode(&buf[idx..]);
32 result.push(one_result);
33 idx += consumed;
34 }
35 (result, idx)
36 }
37}
38
39pub trait FixedSizeDecodable: ::core::marker::Sized {
41 type Error;
42 const WRONG_SIZE_ERROR: Self::Error;
43 const BYTE_SIZE: usize;
44
45 fn decode_checked(buf: &[u8]) -> core::result::Result<Self, Self::Error>;
48}
49
50pub trait Encodable {
52 type Error;
53
54 fn encoded_len(&self) -> ::core::primitive::usize;
56
57 fn encode(&self, buf: &mut [u8]) -> ::core::result::Result<(), Self::Error>;
60}
61
62#[macro_export]
77macro_rules! decodable_enum {
78 ($(#[$meta:meta])* $visibility:vis enum $name:ident<
79 $raw_type:ty,
80 $error_type:ty,
81 $error_path:ident
82 > {
83 $($(#[$variant_meta:meta])* $variant:ident = $val:expr),*,
84 }) => {
85 $(#[$meta])*
86 #[derive(
87 ::core::clone::Clone,
88 ::core::marker::Copy,
89 ::core::fmt::Debug,
90 ::core::cmp::Eq,
91 ::core::hash::Hash,
92 ::core::cmp::PartialEq)]
93 $visibility enum $name {
94 $($(#[$variant_meta])* $variant = $val),*
95 }
96
97 impl $name {
98 pub const VALUES : &'static [$raw_type] = &[$($val),*,];
99 pub const VARIANTS : &'static [$name] = &[$($name::$variant),*,];
100 pub fn name(&self) -> &'static ::core::primitive::str {
101 match self {
102 $($name::$variant => ::core::stringify!($variant)),*
103 }
104 }
105 }
106
107 impl ::core::convert::From<$name> for $raw_type {
108 fn from(v: $name) -> $raw_type {
109 match v {
110 $($name::$variant => $val),*,
111 }
112 }
113 }
114
115 impl ::core::convert::TryFrom<$raw_type> for $name {
116 type Error = $error_type;
117
118 fn try_from(value: $raw_type) -> ::core::result::Result<Self, $error_type> {
119 match value {
120 $($val => ::core::result::Result::Ok($name::$variant)),*,
121 _ => ::core::result::Result::Err(<$error_type>::$error_path),
122 }
123 }
124 }
125 }
126}
127
128#[macro_export]
129macro_rules! codable_as_bitmask {
130 ($type:ty, $raw_type:ty) => {
131 impl $type {
132 pub fn from_bits(v: $raw_type) -> impl Iterator<Item = $type> {
133 (0..<$raw_type>::BITS)
134 .map(|bit| 1 << bit)
135 .filter(move |val| (v & val) != 0)
136 .filter_map(|val| val.try_into().ok())
137 }
138
139 pub fn to_bits<'a>(it: impl Iterator<Item = &'a $type>) -> $raw_type {
140 it.fold(0, |acc, item| acc | Into::<$raw_type>::into(*item))
141 }
142 }
143 };
144}
145
146#[derive(Error, Debug, PartialEq)]
147pub enum Error {
148 #[error("Parameter is not valid: {0}")]
149 InvalidParameter(String),
150
151 #[error("Out-of-range enum value")]
152 OutOfRange,
153
154 #[error("Encoding buffer is too small")]
155 BufferTooSmall,
156
157 #[error("Buffer being decoded is invalid length")]
158 UnexpectedDataLength,
159
160 #[error("Unrecognized type for {0}: {1}")]
161 UnrecognizedType(String, u8),
162
163 #[error("Uuid parsing error: {0}")]
164 Uuid(uuid::Error),
165}