1use std::{
2 convert::{TryFrom, TryInto},
3 mem::size_of,
4};
5
6use super::{Binary, Error, Result};
7use crate::{spec::BinarySubtype, Bson, RawBson};
8
9const INT8: u8 = 0x03;
10const FLOAT32: u8 = 0x27;
11const PACKED_BIT: u8 = 0x10;
12
13#[derive(Clone, Debug, PartialEq)]
44pub enum Vector {
45 Int8(Vec<i8>),
47
48 Float32(Vec<f32>),
50
51 PackedBit(PackedBitVector),
53}
54
55#[derive(Clone, Debug, PartialEq)]
57pub struct PackedBitVector {
58 vector: Vec<u8>,
59 padding: u8,
60}
61
62impl PackedBitVector {
63 pub fn new(vector: Vec<u8>, padding: impl Into<Option<u8>>) -> Result<Self> {
92 let padding = padding.into().unwrap_or(0);
93 if !(0..8).contains(&padding) {
94 return Err(Error::binary(format!(
95 "vector padding must be within 0-7 inclusive, got {padding}"
96 )));
97 }
98 match vector.last() {
99 Some(last) => {
100 if last.trailing_zeros() < u32::from(padding) {
101 return Err(Error::binary(
102 "the ignored bits in a packed bit vector must all be 0",
103 ));
104 }
105 }
106 None => {
107 if padding != 0 {
108 return Err(Error::binary(format!(
109 "cannot specify non-zero padding if the provided vector is empty, got \
110 {padding}"
111 )));
112 }
113 }
114 }
115 Ok(Self { vector, padding })
116 }
117}
118
119impl Vector {
120 pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result<Self> {
124 let bytes = bytes.as_ref();
125
126 if bytes.len() < 2 {
127 return Err(Error::binary(format!(
128 "the provided vector bytes must have a length of at least 2, got {}",
129 bytes.len()
130 )));
131 }
132
133 let d_type = bytes[0];
134 let padding = bytes[1];
135 if d_type != PACKED_BIT && padding != 0 {
136 return Err(Error::binary(format!(
137 "padding can only be specified for a packed bit vector (data type {}), got type {}",
138 PACKED_BIT, d_type
139 )));
140 }
141 let number_bytes = &bytes[2..];
142
143 match d_type {
144 INT8 => {
145 let vector = number_bytes
146 .iter()
147 .map(|n| i8::from_le_bytes([*n]))
148 .collect();
149 Ok(Self::Int8(vector))
150 }
151 FLOAT32 => {
152 const F32_BYTES: usize = size_of::<f32>();
153
154 let mut vector = Vec::new();
155 for chunk in number_bytes.chunks(F32_BYTES) {
156 let bytes: [u8; F32_BYTES] = chunk.try_into().map_err(|_| {
157 Error::binary(format!(
158 "f32 vector values must be {} bytes, got {:?}",
159 F32_BYTES, chunk,
160 ))
161 })?;
162 vector.push(f32::from_le_bytes(bytes));
163 }
164 Ok(Self::Float32(vector))
165 }
166 PACKED_BIT => {
167 let packed_bit_vector = PackedBitVector::new(number_bytes.to_vec(), padding)?;
168 Ok(Self::PackedBit(packed_bit_vector))
169 }
170 other => Err(Error::binary(format!(
171 "unsupported vector data type: {other}"
172 ))),
173 }
174 }
175
176 fn d_type(&self) -> u8 {
177 match self {
178 Self::Int8(_) => INT8,
179 Self::Float32(_) => FLOAT32,
180 Self::PackedBit(_) => PACKED_BIT,
181 }
182 }
183
184 fn padding(&self) -> u8 {
185 match self {
186 Self::Int8(_) => 0,
187 Self::Float32(_) => 0,
188 Self::PackedBit(PackedBitVector { padding, .. }) => *padding,
189 }
190 }
191}
192
193impl From<&Vector> for Binary {
194 fn from(vector: &Vector) -> Self {
195 let d_type = vector.d_type();
196 let padding = vector.padding();
197 let mut bytes = vec![d_type, padding];
198
199 match vector {
200 Vector::Int8(vector) => {
201 for n in vector {
202 bytes.extend_from_slice(&n.to_le_bytes());
203 }
204 }
205 Vector::Float32(vector) => {
206 for n in vector {
207 bytes.extend_from_slice(&n.to_le_bytes());
208 }
209 }
210 Vector::PackedBit(PackedBitVector { vector, .. }) => {
211 for n in vector {
212 bytes.extend_from_slice(&n.to_le_bytes());
213 }
214 }
215 }
216
217 Self {
218 subtype: BinarySubtype::Vector,
219 bytes,
220 }
221 }
222}
223
224impl From<Vector> for Binary {
225 fn from(vector: Vector) -> Binary {
226 Self::from(&vector)
227 }
228}
229
230impl TryFrom<&Binary> for Vector {
231 type Error = Error;
232
233 fn try_from(binary: &Binary) -> Result<Self> {
234 if binary.subtype != BinarySubtype::Vector {
235 return Err(Error::binary(format!(
236 "expected vector binary subtype, got {:?}",
237 binary.subtype
238 )));
239 }
240 Self::from_bytes(&binary.bytes)
241 }
242}
243
244impl TryFrom<Binary> for Vector {
245 type Error = Error;
246
247 fn try_from(binary: Binary) -> std::result::Result<Self, Self::Error> {
248 Self::try_from(&binary)
249 }
250}
251
252impl From<Vector> for Bson {
255 fn from(vector: Vector) -> Self {
256 Self::Binary(Binary::from(vector))
257 }
258}
259
260impl From<&Vector> for RawBson {
262 fn from(vector: &Vector) -> Self {
263 Self::Binary(Binary::from(vector))
264 }
265}
266
267impl From<Vector> for RawBson {
268 fn from(vector: Vector) -> Self {
269 Self::from(&vector)
270 }
271}
272
273#[cfg(feature = "serde")]
274impl serde::Serialize for Vector {
275 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
276 where
277 S: serde::Serializer,
278 {
279 let binary = Binary::from(self);
280 binary.serialize(serializer)
281 }
282}
283
284#[cfg(feature = "serde")]
285impl<'de> serde::Deserialize<'de> for Vector {
286 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
287 where
288 D: serde::Deserializer<'de>,
289 {
290 let binary = Binary::deserialize(deserializer)?;
291 Self::try_from(binary).map_err(serde::de::Error::custom)
292 }
293}