anybuf/bufany.rs
1use alloc::collections::BTreeMap;
2use alloc::string::String;
3use alloc::vec::Vec;
4
5use crate::{
6 slice_reader::SliceReader,
7 varint::{from_zigzag32, from_zigzag64, read_unsigned_varint},
8};
9
10/// A minmal protobuf decoder.
11///
12/// Decodes protobuf bytes and allows you to access the field.
13///
14/// The decoding step is zero-copy for variable length values, i.e.
15/// no heap allocations are done for bytes and string fields as long as you do not access them.
16/// The accessors then copy the values you need.
17///
18/// ## Example
19///
20/// ```
21/// use anybuf::{Anybuf, Bufany};
22///
23/// let serialized: Vec<u8> = Anybuf::new()
24/// .append_uint64(1, 150)
25/// .append_uint32(2, 38)
26/// .append_bytes(3, vec![0xF0, 0x00])
27/// .append_string(4, "valid utf8 string")
28/// .into_vec();
29/// let decoded = Bufany::deserialize(&serialized).unwrap();
30/// assert_eq!(decoded.uint64(1), Some(150));
31/// assert_eq!(decoded.uint32(2), Some(38));
32/// assert_eq!(decoded.bytes(3), Some(vec![0xF0, 0x00]));
33/// assert_eq!(decoded.string(4), Some("valid utf8 string".to_string()));
34/// assert_eq!(decoded.string(5), Some("".to_string()));
35/// ```
36#[derive(Debug)]
37pub struct Bufany<'a> {
38 // A map from field number to decoded value.
39 fields: BTreeMap<u32, Vec<Value<'a>>>,
40 // A vector that is always empty and has the lifetime we need.
41 empty_vec: Vec<Value<'a>>,
42}
43
44#[derive(Debug, PartialEq)]
45pub enum BufanyError {
46 /// Found tag that is either not valid protobuf or unsuppored
47 InvalidTag,
48 /// Field number must be between 1 and 536,870,911
49 InvalidFieldNumber,
50 UnsupportedWireType(u8),
51 ErrorDecodingVarint,
52 /// The remaining data is not long enough to read the expected length
53 UnexpectedEndOfData,
54}
55
56#[derive(Debug, PartialEq)]
57pub enum RepeatedStringError {
58 /// Found a value of the wrong wire type
59 TypeMismatch,
60 /// A variable length field did not contain valid UTF-8.
61 InvalidUtf8,
62}
63
64#[derive(Debug, PartialEq)]
65pub enum RepeatedMessageError {
66 /// Found a value of the wrong wire type
67 TypeMismatch,
68 /// Found a value that cannot be decoded
69 DecodingError(BufanyError),
70}
71
72impl core::fmt::Display for BufanyError {
73 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
74 f.write_str("Error decoding protobuf: ")?;
75 match self {
76 BufanyError::InvalidTag => f.write_str("Invalid tag"),
77 BufanyError::InvalidFieldNumber => {
78 f.write_str("Invalid field number, must be between 1 and 536,870,911")
79 }
80 BufanyError::UnsupportedWireType(wire_type) => {
81 write!(f, "Unsupported wire type: {}", wire_type)
82 }
83 BufanyError::ErrorDecodingVarint => f.write_str("Error decoding varint"),
84 BufanyError::UnexpectedEndOfData => f.write_str("Unexpected end of data"),
85 }
86 }
87}
88
89impl core::fmt::Display for RepeatedStringError {
90 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
91 f.write_str("Error decoding repeated string: ")?;
92 match self {
93 RepeatedStringError::TypeMismatch => {
94 f.write_str("Found a value of the wrong wire type")
95 }
96 RepeatedStringError::InvalidUtf8 => {
97 f.write_str("A variable length field did not contain valid UTF-8")
98 }
99 }
100 }
101}
102
103impl core::fmt::Display for RepeatedMessageError {
104 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
105 f.write_str("Error decoding repeated message: ")?;
106 match self {
107 RepeatedMessageError::TypeMismatch => {
108 f.write_str("Found a value of the wrong wire type")
109 }
110 RepeatedMessageError::DecodingError(_) => {
111 f.write_str("Could not decode nested message")
112 }
113 }
114 }
115}
116
117#[cfg(feature = "std")]
118impl std::error::Error for BufanyError {}
119
120#[cfg(feature = "std")]
121impl std::error::Error for RepeatedStringError {}
122
123#[cfg(feature = "std")]
124impl std::error::Error for RepeatedMessageError {}
125
126impl Bufany<'_> {
127 /// Creates an empty instance with the given lifetime.
128 ///
129 /// This is a private constructor. Users of the library should always use [`Bufany::deserialize`].
130 fn new<'a>() -> Bufany<'a> {
131 Bufany {
132 fields: Default::default(),
133 empty_vec: Default::default(),
134 }
135 }
136}
137
138impl<'a> Bufany<'a> {
139 /// Creates a new serializer.
140 pub fn deserialize(serialized: &'a [u8]) -> Result<Bufany<'a>, BufanyError> {
141 let mut out = Bufany::new::<'a>();
142
143 let mut reader = SliceReader::new(serialized);
144
145 loop {
146 if reader.is_empty() {
147 break;
148 }
149
150 let Some(tag) = read_unsigned_varint(&mut reader) else {
151 return Err(BufanyError::InvalidTag);
152 };
153
154 // valid field numbers are between 1 and 536,870,911
155 let field_number = match tag >> 3 {
156 1..=536870911 => (tag >> 3) as u32,
157 _ => return Err(BufanyError::InvalidFieldNumber),
158 };
159 let wire_type = (tag & 0x07) as u8;
160
161 let value = read_value(&mut reader, wire_type)?;
162 out.fields.entry(field_number).or_default().push(value);
163 }
164
165 Ok(out)
166 }
167
168 /// Gets bytes from the given field number. This returns None if
169 /// - the value type is not variable length
170 ///
171 /// ## Example
172 ///
173 /// ```
174 /// use anybuf::{Anybuf, Bufany};
175 ///
176 /// let serialized = Anybuf::new()
177 /// .append_uint64(1, 150)
178 /// .append_bytes(2, vec![0xF0, 0x00])
179 /// .append_bytes(3, vec![])
180 /// .into_vec();
181 /// let decoded = Bufany::deserialize(&serialized).unwrap();
182 /// assert_eq!(decoded.bytes(1), None); // wrong type
183 /// assert_eq!(decoded.bytes(2), Some(vec![0xF0, 0x00]));
184 /// assert_eq!(decoded.bytes(3), Some(vec![])); // not serialized => default
185 /// assert_eq!(decoded.bytes(4), Some(vec![])); // not serialized => default
186 /// ```
187 pub fn bytes(&self, field_number: u32) -> Option<Vec<u8>> {
188 match self.value_ref(field_number) {
189 Some(Value::VariableLength(data)) => Some(data.to_vec()),
190 Some(_) => None, // wrong type
191 None => Some(Vec::new()),
192 }
193 }
194
195 /// Gets bytes from the given field number. This returns None if
196 /// - the value type is not variable length
197 ///
198 /// ## Example
199 ///
200 /// ```
201 /// use anybuf::{Anybuf, Bufany};
202 ///
203 /// let serialized = Anybuf::new()
204 /// .append_uint64(1, 150)
205 /// .append_bytes(2, vec![0xF0, 0x00])
206 /// .append_string(3, "valid utf8 string")
207 /// .append_string(4, "")
208 /// .into_vec();
209 /// let decoded = Bufany::deserialize(&serialized).unwrap();
210 /// assert_eq!(decoded.string(1), None); // wrong type
211 /// assert_eq!(decoded.string(2), None); // invalid utf8
212 /// assert_eq!(decoded.string(3), Some("valid utf8 string".to_string()));
213 /// assert_eq!(decoded.string(4), Some("".to_string())); // not serialized => default
214 /// assert_eq!(decoded.string(5), Some("".to_string())); // not serialized => default
215 /// ```
216 pub fn string(&self, field_number: u32) -> Option<String> {
217 let bytes = self.bytes(field_number)?;
218 String::from_utf8(bytes).ok()
219 }
220
221 /// Gets a uint64 from the given field number. This returns None if
222 /// - the value type is not of type varint
223 ///
224 /// ## Example
225 ///
226 /// ```
227 /// use anybuf::{Anybuf, Bufany};
228 ///
229 /// let serialized = Anybuf::new()
230 /// .append_uint64(1, 150)
231 /// .append_bytes(2, vec![0xF0, 0x00])
232 /// .append_uint64(3, 0)
233 /// .into_vec();
234 /// let decoded = Bufany::deserialize(&serialized).unwrap();
235 /// assert_eq!(decoded.uint64(1), Some(150));
236 /// assert_eq!(decoded.uint64(2), None);
237 /// assert_eq!(decoded.uint64(3), Some(0));
238 /// assert_eq!(decoded.uint64(4), Some(0));
239 /// ```
240 pub fn uint64(&self, field_number: u32) -> Option<u64> {
241 match self.value_ref(field_number) {
242 Some(Value::Varint(data)) => Some(*data),
243 Some(_) => None, // found but wrong type
244 None => Some(0), // Field not serialized, i.e. can be the default value
245 }
246 }
247
248 /// Gets a uint32 from the given field number. This returns None if
249 /// - the value type is not of type varint
250 /// - the value exceeds the uint32 range
251 ///
252 /// ## Example
253 ///
254 /// ```
255 /// use anybuf::{Anybuf, Bufany};
256 ///
257 /// let serialized = Anybuf::new()
258 /// .append_uint32(1, 150)
259 /// .append_uint64(2, 17)
260 /// .append_uint64(3, 36028797018963970)
261 /// .append_bytes(4, vec![0xF0, 0x00])
262 /// .append_uint32(5, 0)
263 /// .into_vec();
264 /// let decoded = Bufany::deserialize(&serialized).unwrap();
265 /// assert_eq!(decoded.uint32(1), Some(150));
266 /// assert_eq!(decoded.uint32(2), Some(17)); // works because on the wire we don't differentiate
267 /// assert_eq!(decoded.uint32(3), None); // too large
268 /// assert_eq!(decoded.uint32(4), None);
269 /// assert_eq!(decoded.uint32(5), Some(0));
270 /// ```
271 pub fn uint32(&self, field_number: u32) -> Option<u32> {
272 match self.value_ref(field_number) {
273 Some(Value::Varint(data)) => (*data).try_into().ok(),
274 Some(_) => None, // found but wrong type
275 None => Some(0), // Field not serialized, i.e. can be the default value
276 }
277 }
278
279 /// Gets a bool from the given field number. This returns None if
280 /// - the value type is not of type varint
281 /// - the value is not 0 or 1
282 ///
283 /// ## Example
284 ///
285 /// ```
286 /// use anybuf::{Anybuf, Bufany};
287 ///
288 /// let serialized = Anybuf::new()
289 /// .append_uint32(1, 150)
290 /// .append_uint64(2, 17)
291 /// .append_uint64(3, 1)
292 /// .append_bytes(4, vec![0xF0, 0x00])
293 /// .append_bool(5, true)
294 /// .append_bool(6, false)
295 /// .into_vec();
296 /// let decoded = Bufany::deserialize(&serialized).unwrap();
297 /// assert_eq!(decoded.bool(1), None); // too large
298 /// assert_eq!(decoded.bool(2), None); // too large
299 /// assert_eq!(decoded.bool(3), Some(true)); // 1 and true cannot be differentiated
300 /// assert_eq!(decoded.bool(4), None); // wrong type
301 /// assert_eq!(decoded.bool(5), Some(true));
302 /// assert_eq!(decoded.bool(6), Some(false));
303 /// ```
304 pub fn bool(&self, field_number: u32) -> Option<bool> {
305 match self.value_ref(field_number) {
306 Some(Value::Varint(1)) => Some(true),
307 Some(Value::Varint(0)) => Some(false),
308 Some(Value::Varint(_)) => None,
309 Some(_) => None, // found but wrong type
310 None => Some(false), // Field not serialized, i.e. can be the default value
311 }
312 }
313
314 /// Gets a sint64 from the given field number.
315 /// This returns None if the value type is not of type varint.
316 ///
317 /// Please note that protobuf has two different 64 bit signed integer types
318 /// with different encodings: sint64 and int64. This only works for sint64.
319 ///
320 /// ## Example
321 ///
322 /// ```
323 /// use anybuf::{Anybuf, Bufany};
324 ///
325 /// let serialized = Anybuf::new()
326 /// .append_sint64(1, 150)
327 /// .append_sint64(2, -534214672)
328 /// .append_sint64(3, 0)
329 /// .append_bytes(4, vec![0xF0, 0x00])
330 /// .into_vec();
331 /// let decoded = Bufany::deserialize(&serialized).unwrap();
332 /// assert_eq!(decoded.sint64(1), Some(150));
333 /// assert_eq!(decoded.sint64(2), Some(-534214672));
334 /// assert_eq!(decoded.sint64(3), Some(0));
335 /// assert_eq!(decoded.sint64(4), None);
336 /// assert_eq!(decoded.sint64(5), Some(0));
337 /// ```
338 pub fn sint64(&self, field_number: u32) -> Option<i64> {
339 match self.value_ref(field_number) {
340 Some(Value::Varint(data)) => Some(from_zigzag64(*data)),
341 Some(_) => None, // found but wrong type
342 None => Some(0), // Field not serialized, i.e. can be the default value
343 }
344 }
345
346 /// Gets a sint32 from the given field number.
347 /// This returns None if the value type is not of type varint
348 /// or the value exceeds the 32 bit range.
349 ///
350 /// Please note that protobuf has two different 32 bit signed integer types
351 /// with different encodings: sint32 and int32. This only works for sint32.
352 ///
353 /// ## Example
354 ///
355 /// ```
356 /// use anybuf::{Anybuf, Bufany};
357 ///
358 /// let serialized = Anybuf::new()
359 /// .append_sint32(1, 150)
360 /// .append_sint32(2, -534214672)
361 /// .append_sint32(3, 0)
362 /// .append_bytes(4, vec![0xF0, 0x00])
363 /// .into_vec();
364 /// let decoded = Bufany::deserialize(&serialized).unwrap();
365 /// assert_eq!(decoded.sint32(1), Some(150));
366 /// assert_eq!(decoded.sint32(2), Some(-534214672));
367 /// assert_eq!(decoded.sint32(3), Some(0));
368 /// assert_eq!(decoded.sint32(4), None);
369 /// assert_eq!(decoded.sint32(5), Some(0));
370 /// ```
371 pub fn sint32(&self, field_number: u32) -> Option<i32> {
372 match self.value_ref(field_number) {
373 Some(Value::Varint(data)) => Some(from_zigzag32((*data).try_into().ok()?)),
374 Some(_) => None, // found but wrong type
375 None => Some(0), // Field not serialized, i.e. can be the default value
376 }
377 }
378
379 /// Gets an int64 from the given field number.
380 /// This returns None if the value type is not of type varint.
381 ///
382 /// Please note that protobuf has two different 64 bit signed integer types
383 /// with different encodings: sint64 and int64. This only works for int64.
384 ///
385 /// ## Example
386 ///
387 /// ```
388 /// use anybuf::{Anybuf, Bufany};
389 ///
390 /// let serialized = Anybuf::new()
391 /// .append_int64(1, 150)
392 /// .append_int64(2, -534214672)
393 /// .append_int64(3, 0)
394 /// .append_bytes(4, vec![0xF0, 0x00])
395 /// .into_vec();
396 /// let decoded = Bufany::deserialize(&serialized).unwrap();
397 /// assert_eq!(decoded.int64(1), Some(150));
398 /// assert_eq!(decoded.int64(2), Some(-534214672));
399 /// assert_eq!(decoded.int64(3), Some(0));
400 /// assert_eq!(decoded.int64(4), None);
401 /// assert_eq!(decoded.int64(5), Some(0));
402 /// ```
403 pub fn int64(&self, field_number: u32) -> Option<i64> {
404 match self.value_ref(field_number) {
405 Some(Value::Varint(data)) => Some(*data as i64),
406 Some(_) => None, // found but wrong type
407 None => Some(0), // Field not serialized, i.e. can be the default value
408 }
409 }
410
411 /// Gets an int32 from the given field number.
412 /// This returns None if the value type is not of type varint
413 /// or the value exceeds the 32 bit range.
414 ///
415 /// Please note that protobuf has two different 32 bit signed integer types
416 /// with different encodings: sint32 and int32. This only works for int32.
417 ///
418 /// ## Example
419 ///
420 /// ```
421 /// use anybuf::{Anybuf, Bufany};
422 ///
423 /// let serialized = Anybuf::new()
424 /// .append_int32(1, 150)
425 /// .append_int32(2, -534214672)
426 /// .append_int32(3, 0)
427 /// .append_bytes(4, vec![0xF0, 0x00])
428 /// .into_vec();
429 /// let decoded = Bufany::deserialize(&serialized).unwrap();
430 /// assert_eq!(decoded.int32(1), Some(150));
431 /// assert_eq!(decoded.int32(2), Some(-534214672));
432 /// assert_eq!(decoded.int32(3), Some(0));
433 /// assert_eq!(decoded.int32(4), None);
434 /// assert_eq!(decoded.int32(5), Some(0));
435 /// ```
436 pub fn int32(&self, field_number: u32) -> Option<i32> {
437 match self.value_ref(field_number) {
438 Some(Value::Varint(value)) => Some((*value as i64).try_into().ok()?),
439 Some(_) => None, // found but wrong type
440 None => Some(0), // Field not serialized, i.e. can be the default value
441 }
442 }
443
444 /// Gets a nested message from the given field number.
445 /// This returns None if the value type is not of type variable length or the inner message cannot be decoded.
446 ///
447 /// ## Example
448 ///
449 /// ```
450 /// use anybuf::{Anybuf, Bufany};
451 ///
452 /// let serialized = Anybuf::new()
453 /// .append_message(
454 /// 1,
455 /// &Anybuf::new()
456 /// .append_bool(1, true)
457 /// .append_string(2, "foo")
458 /// .append_sint64(3, -37648762834),
459 /// )
460 /// .append_sint32(2, 150)
461 /// .append_bytes(3, b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
462 /// .into_vec();
463 /// let decoded = Bufany::deserialize(&serialized).unwrap();
464 ///
465 /// let nested = decoded.message(1).unwrap();
466 /// assert_eq!(nested.bool(1), Some(true));
467 /// assert_eq!(nested.string(2), Some("foo".to_string()));
468 /// assert_eq!(nested.sint64(3), Some(-37648762834));
469 ///
470 /// assert!(decoded.message(2).is_none()); // wrong type
471 /// assert!(decoded.message(3).is_none()); // not a valid proto message
472 /// ```
473 pub fn message(&'a self, field_number: u32) -> Option<Bufany<'a>> {
474 match self.value_ref(field_number) {
475 Some(Value::VariableLength(data)) => Some(Bufany::deserialize(data).ok()?),
476 Some(_) => None, // found but wrong type
477 None => Some(Bufany::new::<'a>()), // Field not serialized, i.e. can be the default value
478 }
479 }
480
481 /// Gets repeated uint64 from the given field number.
482 /// Returns None in case a wrong wire type was found.
483 ///
484 /// ## Example
485 ///
486 /// ```
487 /// use anybuf::{Anybuf, Bufany};
488 ///
489 /// let serialized = Anybuf::new()
490 /// .append_repeated_uint64(1, &[150])
491 /// .append_repeated_uint64(2, &[150, 0, u64::MAX])
492 /// .append_string(3, "foo")
493 /// .into_vec();
494 /// let decoded = Bufany::deserialize(&serialized).unwrap();
495 /// assert_eq!(decoded.repeated_uint64(1), Some(vec![150]));
496 /// assert_eq!(decoded.repeated_uint64(2), Some(vec![150, 0, u64::MAX]));
497 /// assert_eq!(decoded.repeated_uint64(3), None);
498 /// ```
499 pub fn repeated_uint64(&self, field_number: u32) -> Option<Vec<u64>> {
500 let values = self.repeated_value_ref(field_number);
501 let mut out = Vec::with_capacity(values.len());
502 for value in values {
503 match value {
504 Value::Varint(data) => out.push(*data),
505 _ => return None, // Wrong type, we can't handle this
506 }
507 }
508 Some(out)
509 }
510
511 /// Gets repeated uint32 from the given field number.
512 /// Returns None in case a wrong wire type was found or the value exceeds the 32 bit range.
513 ///
514 /// ## Example
515 ///
516 /// ```
517 /// use anybuf::{Anybuf, Bufany};
518 ///
519 /// let serialized = Anybuf::new()
520 /// .append_repeated_uint32(1, &[150])
521 /// .append_repeated_uint32(2, &[150, 0, u32::MAX])
522 /// .append_string(3, "foo")
523 /// .into_vec();
524 /// let decoded = Bufany::deserialize(&serialized).unwrap();
525 /// assert_eq!(decoded.repeated_uint32(1), Some(vec![150]));
526 /// assert_eq!(decoded.repeated_uint32(2), Some(vec![150, 0, u32::MAX]));
527 /// assert_eq!(decoded.repeated_uint32(3), None);
528 /// ```
529 pub fn repeated_uint32(&self, field_number: u32) -> Option<Vec<u32>> {
530 let values = self.repeated_value_ref(field_number);
531 let mut out = Vec::with_capacity(values.len());
532 for value in values {
533 match value {
534 Value::Varint(data) => out.push((*data).try_into().ok()?),
535 _ => return None, // Wrong type, we can't handle this
536 }
537 }
538 Some(out)
539 }
540
541 /// Gets repeated bool from the given field number.
542 /// Returns None in case a wrong wire type was found or the value is not 0 or 1.
543 ///
544 /// ## Example
545 ///
546 /// ```
547 /// use anybuf::{Anybuf, Bufany};
548 ///
549 /// let serialized = Anybuf::new()
550 /// .append_repeated_bool(1, &[true])
551 /// .append_repeated_bool(2, &[true, false, true])
552 /// .append_string(3, "foo")
553 /// .into_vec();
554 /// let decoded = Bufany::deserialize(&serialized).unwrap();
555 /// assert_eq!(decoded.repeated_bool(1), Some(vec![true]));
556 /// assert_eq!(decoded.repeated_bool(2), Some(vec![true, false, true]));
557 /// assert_eq!(decoded.repeated_bool(3), None);
558 /// ```
559 pub fn repeated_bool(&self, field_number: u32) -> Option<Vec<bool>> {
560 let values = self.repeated_value_ref(field_number);
561 let mut out = Vec::with_capacity(values.len());
562 for value in values {
563 match value {
564 Value::Varint(0) => out.push(false),
565 Value::Varint(1) => out.push(true),
566 _ => return None, // Wrong type, we can't handle this
567 }
568 }
569 Some(out)
570 }
571
572 /// Gets repeated sint64 from the given field number.
573 /// Returns None in case a wrong wire type was found.
574 ///
575 /// Please note that protobuf has two different 64 bit signed integer types
576 /// with different encodings: sint64 and int64. This only works for sint64.
577 ///
578 /// ## Example
579 ///
580 /// ```
581 /// use anybuf::{Anybuf, Bufany};
582 ///
583 /// let serialized = Anybuf::new()
584 /// .append_repeated_sint64(1, &[150, -150])
585 /// .append_repeated_sint64(2, &[150, 0, i64::MAX])
586 /// .append_string(3, "foo")
587 /// .into_vec();
588 /// let decoded = Bufany::deserialize(&serialized).unwrap();
589 /// assert_eq!(decoded.repeated_sint64(1), Some(vec![150, -150]));
590 /// assert_eq!(decoded.repeated_sint64(2), Some(vec![150, 0, i64::MAX]));
591 /// assert_eq!(decoded.repeated_sint64(3), None);
592 /// ```
593 pub fn repeated_sint64(&self, field_number: u32) -> Option<Vec<i64>> {
594 let values = self.repeated_value_ref(field_number);
595 let mut out = Vec::with_capacity(values.len());
596 for value in values {
597 match value {
598 Value::Varint(data) => out.push(from_zigzag64(*data)),
599 _ => return None, // Wrong type, we can't handle this
600 }
601 }
602 Some(out)
603 }
604
605 /// Gets repeated sint32 from the given field number.
606 /// Returns None in case a wrong wire type was found or the value exceeds the 32 bit range.
607 ///
608 /// Please note that protobuf has two different 32 bit signed integer types
609 /// with different encodings: sint32 and int32. This only works for sint32.
610 ///
611 /// ## Example
612 ///
613 /// ```
614 /// use anybuf::{Anybuf, Bufany};
615 ///
616 /// let serialized = Anybuf::new()
617 /// .append_repeated_sint32(1, &[150, -150])
618 /// .append_repeated_sint32(2, &[150, 0, i32::MIN])
619 /// .append_string(3, "foo")
620 /// .into_vec();
621 /// let decoded = Bufany::deserialize(&serialized).unwrap();
622 /// assert_eq!(decoded.repeated_sint32(1), Some(vec![150, -150]));
623 /// assert_eq!(decoded.repeated_sint32(2), Some(vec![150, 0, i32::MIN]));
624 /// assert_eq!(decoded.repeated_sint32(3), None);
625 /// ```
626 pub fn repeated_sint32(&self, field_number: u32) -> Option<Vec<i32>> {
627 let values = self.repeated_value_ref(field_number);
628 let mut out = Vec::with_capacity(values.len());
629 for value in values {
630 match value {
631 Value::Varint(data) => out.push(from_zigzag32((*data).try_into().ok()?)),
632 _ => return None, // Wrong type, we can't handle this
633 }
634 }
635 Some(out)
636 }
637
638 /// Gets repeated int64 from the given field number.
639 /// Returns None in case a wrong wire type was found.
640 ///
641 /// Please note that protobuf has two different 64 bit signed integer types
642 /// with different encodings: sint64 and int64. This only works for int64.
643 ///
644 /// ## Example
645 ///
646 /// ```
647 /// use anybuf::{Anybuf, Bufany};
648 ///
649 /// let serialized = Anybuf::new()
650 /// .append_repeated_int64(1, &[150, -150])
651 /// .append_repeated_int64(2, &[150, 0, i64::MAX])
652 /// .append_string(3, "foo")
653 /// .into_vec();
654 /// let decoded = Bufany::deserialize(&serialized).unwrap();
655 /// assert_eq!(decoded.repeated_int64(1), Some(vec![150, -150]));
656 /// assert_eq!(decoded.repeated_int64(2), Some(vec![150, 0, i64::MAX]));
657 /// assert_eq!(decoded.repeated_int64(3), None);
658 /// ```
659 pub fn repeated_int64(&self, field_number: u32) -> Option<Vec<i64>> {
660 let values = self.repeated_value_ref(field_number);
661 let mut out = Vec::with_capacity(values.len());
662 for value in values {
663 match value {
664 Value::Varint(data) => out.push(*data as i64),
665 _ => return None, // Wrong type, we can't handle this
666 }
667 }
668 Some(out)
669 }
670
671 /// Gets repeated sint32 from the given field number.
672 /// Returns None in case a wrong wire type was found or the value exceeds the 32 bit range.
673 ///
674 /// Please note that protobuf has two different 32 bit signed integer types
675 /// with different encodings: sint32 and int32. This only works for int32.
676 ///
677 /// ## Example
678 ///
679 /// ```
680 /// use anybuf::{Anybuf, Bufany};
681 ///
682 /// let serialized = Anybuf::new()
683 /// .append_repeated_int32(1, &[150, -150])
684 /// .append_repeated_int32(2, &[150, 0, i32::MIN])
685 /// .append_string(3, "foo")
686 /// .into_vec();
687 /// let decoded = Bufany::deserialize(&serialized).unwrap();
688 /// assert_eq!(decoded.repeated_int32(1), Some(vec![150, -150]));
689 /// assert_eq!(decoded.repeated_int32(2), Some(vec![150, 0, i32::MIN]));
690 /// assert_eq!(decoded.repeated_int32(3), None);
691 /// ```
692 pub fn repeated_int32(&self, field_number: u32) -> Option<Vec<i32>> {
693 let values = self.repeated_value_ref(field_number);
694 let mut out = Vec::with_capacity(values.len());
695 for value in values {
696 match value {
697 Value::Varint(data) => out.push((*data as i64).try_into().ok()?),
698 _ => return None, // Wrong type, we can't handle this
699 }
700 }
701 Some(out)
702 }
703
704 /// Gets repeated bytes from the given field number.
705 /// Returns None in case a wrong wire type was found.
706 ///
707 /// ## Example
708 ///
709 /// ```
710 /// use anybuf::{Anybuf, Bufany};
711 ///
712 /// let myvec = vec![0xF0u8, 0x00];
713 /// let serialized = Anybuf::new()
714 /// .append_uint64(1, 150)
715 /// .append_repeated_bytes(2, &[&myvec])
716 /// .append_repeated_bytes::<&[u8]>(3, &[b"\x01\x02\x03", b"\x00"])
717 /// .append_repeated_string(4, &["valid utf8 string", "hello"])
718 /// .append_repeated_bytes::<&[u8]>(5, &[])
719 /// .into_vec();
720 /// let decoded = Bufany::deserialize(&serialized).unwrap();
721 /// assert_eq!(decoded.repeated_bytes(2).unwrap(), &[&[0xF0, 0x00]]);
722 /// assert_eq!(decoded.repeated_bytes(3).unwrap(), [&[1u8, 2, 3] as &[u8], &[0]]);
723 /// assert_eq!(decoded.repeated_bytes(4).unwrap(), [b"valid utf8 string" as &[u8], b"hello"]);
724 /// assert_eq!(decoded.repeated_bytes(5).unwrap(), Vec::<Vec<u8>>::new());
725 /// assert_eq!(decoded.repeated_bytes(12).unwrap(), Vec::<Vec<u8>>::new());
726 /// ```
727 pub fn repeated_bytes(&self, field_number: u32) -> Option<Vec<Vec<u8>>> {
728 let values = self.repeated_value_ref(field_number);
729 let mut out = Vec::with_capacity(values.len());
730 for value in values {
731 match value {
732 Value::VariableLength(data) => out.push(data.to_vec()),
733 _ => return None, // Wrong type, we can't handle this
734 }
735 }
736 Some(out)
737 }
738
739 /// Gets repeated string from the given field number.
740 ///
741 /// ## Example
742 ///
743 /// ```
744 /// use anybuf::{Anybuf, Bufany, RepeatedStringError};
745 ///
746 /// let serialized = Anybuf::new()
747 /// .append_uint64(1, 150)
748 /// .append_bytes(2, vec![0xF0, 0x00])
749 /// .append_repeated_string(3, &["valid utf8 string", "hello"])
750 /// .into_vec();
751 /// let decoded = Bufany::deserialize(&serialized).unwrap();
752 ///
753 /// // happy path
754 /// let strings = decoded.repeated_string(3).unwrap();
755 /// assert_eq!(strings, ["valid utf8 string".to_string(), "hello".to_string()]);
756 ///
757 /// // cannot get strings from int field
758 /// assert!(matches!(decoded.repeated_string(1).unwrap_err(), RepeatedStringError::TypeMismatch));
759 /// ```
760 pub fn repeated_string(&self, field_number: u32) -> Result<Vec<String>, RepeatedStringError> {
761 let values = self.repeated_value_ref(field_number);
762 let mut out = Vec::with_capacity(values.len());
763 for value in values {
764 match value {
765 Value::VariableLength(data) => out.push(
766 String::from_utf8(data.to_vec())
767 .map_err(|_e| RepeatedStringError::InvalidUtf8)?,
768 ),
769 _ => return Err(RepeatedStringError::TypeMismatch),
770 }
771 }
772 Ok(out)
773 }
774
775 /// Gets repeated message from the given field number.
776 ///
777 /// Returns an error in case a wrong wire type was found
778 /// or the message cannot be decoded.
779 ///
780 /// ## Example
781 ///
782 /// ```
783 /// use anybuf::{Anybuf, Bufany, RepeatedMessageError};
784 ///
785 /// let serialized = Anybuf::new()
786 /// .append_message(
787 /// 1,
788 /// &Anybuf::new()
789 /// .append_bool(1, true)
790 /// .append_string(2, "foo")
791 /// .append_sint64(3, -37648762834),
792 /// )
793 /// .append_message(
794 /// 1,
795 /// &Anybuf::new()
796 /// .append_bool(1, true)
797 /// .append_string(2, "bar")
798 /// .append_sint64(3, -37648762834),
799 /// )
800 /// .append_message(
801 /// 1,
802 /// &Anybuf::new()
803 /// .append_bool(1, true)
804 /// .append_string(2, "baz")
805 /// .append_sint64(3, -37648762834),
806 /// )
807 /// .append_sint32(2, 150)
808 /// .append_bytes(3, b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
809 /// .into_vec();
810 /// let decoded = Bufany::deserialize(&serialized).unwrap();
811 ///
812 /// let nested = decoded.repeated_message(1).unwrap();
813 /// assert_eq!(nested.len(), 3);
814 /// assert_eq!(nested[0].bool(1), Some(true));
815 /// assert_eq!(nested[0].string(2), Some("foo".to_string()));
816 /// assert_eq!(nested[0].sint64(3), Some(-37648762834));
817 /// assert_eq!(nested[1].bool(1), Some(true));
818 /// assert_eq!(nested[1].string(2), Some("bar".to_string()));
819 /// assert_eq!(nested[1].sint64(3), Some(-37648762834));
820 /// assert_eq!(nested[2].bool(1), Some(true));
821 /// assert_eq!(nested[2].string(2), Some("baz".to_string()));
822 /// assert_eq!(nested[2].sint64(3), Some(-37648762834));
823 ///
824 /// assert!(matches!(decoded.repeated_message(2).unwrap_err(), RepeatedMessageError::TypeMismatch)); // wrong type
825 /// assert!(matches!(decoded.repeated_message(3).unwrap_err(), RepeatedMessageError::DecodingError(_))); // not a valid proto message
826 /// ```
827 pub fn repeated_message(
828 &'a self,
829 field_number: u32,
830 ) -> Result<Vec<Bufany<'a>>, RepeatedMessageError> {
831 let values = self.repeated_value_ref(field_number);
832 let mut out = Vec::with_capacity(values.len());
833
834 for value in values {
835 let data = match value {
836 Value::VariableLength(data) => *data,
837 _ => return Err(RepeatedMessageError::TypeMismatch),
838 };
839 match Bufany::deserialize(data) {
840 Ok(m) => out.push(m),
841 Err(err) => return Err(RepeatedMessageError::DecodingError(err)),
842 }
843 }
844 Ok(out)
845 }
846
847 /// Gets the value of the given field number. This returns None if
848 /// the field number does not exist
849 pub fn value(&self, field_number: u32) -> Option<Value> {
850 self.value_ref(field_number).cloned()
851 }
852
853 /// Gets the last value of the given field number as a reference.
854 /// This allows us to comply to the "Last One Wins" rule: <https://protobuf.dev/programming-guides/encoding/#last-one-wins>.
855 /// This returns None if the field number does not exist.
856 fn value_ref(&self, field_number: u32) -> Option<&Value<'_>> {
857 match self.fields.get(&field_number) {
858 Some(field) => field.last(),
859 None => None,
860 }
861 }
862
863 fn repeated_value_ref(&self, field_number: u32) -> &Vec<Value<'_>> {
864 self.fields.get(&field_number).unwrap_or(&self.empty_vec)
865 }
866}
867
868/// A deserialized value
869#[derive(Debug, PartialEq, Clone)]
870pub enum Value<'a> {
871 /// Unknown varint (wire type = 0).
872 Varint(u64),
873
874 /// A 64-bit value (wire type = 1). Used for fixed64, sfixed64, double.
875 I64([u8; 8]),
876
877 /// Unknown variable length value (wire type = 2).
878 VariableLength(&'a [u8]),
879
880 /// A 32-bit value (wire type = 5). Used for fixed32, sfixed32, float.
881 I32([u8; 4]),
882}
883
884impl PartialEq<Value<'_>> for &Value<'_> {
885 fn eq(&self, rhs: &Value) -> bool {
886 *self == rhs
887 }
888}
889
890impl PartialEq<&Value<'_>> for Value<'_> {
891 fn eq(&self, rhs: &&Value) -> bool {
892 self == *rhs
893 }
894}
895
896fn read_value<'a>(data: &mut SliceReader<'a>, wire_type: u8) -> Result<Value<'a>, BufanyError> {
897 let value = match wire_type {
898 0 => Value::Varint(read_unsigned_varint(data).ok_or(BufanyError::ErrorDecodingVarint)?),
899 1 => Value::I64(
900 data.read_array::<8>()
901 .ok_or(BufanyError::UnexpectedEndOfData)?,
902 ),
903 2 => {
904 let length = read_unsigned_varint(data).ok_or(BufanyError::ErrorDecodingVarint)?;
905 let length = length as usize; // Is this safe?
906 let Some(consumed) = data.read(length) else {
907 return Err(BufanyError::UnexpectedEndOfData);
908 };
909 Value::VariableLength(consumed)
910 }
911 // group start/end (deprecated, unsupported)
912 // SGROUP = 3,
913 // EGROUP = 4,
914 5 => Value::I32(
915 data.read_array::<4>()
916 .ok_or(BufanyError::UnexpectedEndOfData)?,
917 ),
918 _ => return Err(BufanyError::UnsupportedWireType(wire_type)),
919 };
920 Ok(value)
921}
922
923#[cfg(test)]
924mod tests {
925 use crate::Anybuf;
926
927 use super::*;
928 use alloc::string::ToString;
929 use alloc::vec;
930
931 #[test]
932 fn deserialize_works() {
933 // no field
934 let serialized = Anybuf::new().into_vec();
935 let decoded = Bufany::deserialize(&serialized).unwrap();
936 assert_eq!(decoded.fields.len(), 0);
937
938 // one field
939 let serialized = Anybuf::new().append_uint64(1, 150).into_vec();
940 let decoded = Bufany::deserialize(&serialized).unwrap();
941 assert_eq!(decoded.fields.len(), 1);
942 assert_eq!(decoded.fields.get(&1).unwrap(), &[Value::Varint(150)]);
943
944 // two fields
945 let serialized = Anybuf::new()
946 .append_uint64(1, 150)
947 .append_uint64(2, 42)
948 .into_vec();
949 let decoded = Bufany::deserialize(&serialized).unwrap();
950 assert_eq!(decoded.fields.len(), 2);
951 assert_eq!(decoded.fields.get(&1).unwrap(), &[Value::Varint(150)]);
952 assert_eq!(decoded.fields.get(&2).unwrap(), &[Value::Varint(42)]);
953
954 // two fields out of order
955 let serialized = Anybuf::new()
956 .append_uint64(2, 42)
957 .append_uint64(1, 150)
958 .into_vec();
959 let decoded = Bufany::deserialize(&serialized).unwrap();
960 assert_eq!(decoded.fields.len(), 2);
961 assert_eq!(decoded.fields.get(&1).unwrap(), &[Value::Varint(150)]);
962 assert_eq!(decoded.fields.get(&2).unwrap(), &[Value::Varint(42)]);
963
964 // two fields of the same number
965 let serialized = Anybuf::new()
966 .append_uint64(7, 42)
967 .append_uint64(7, 150)
968 .into_vec();
969 let decoded = Bufany::deserialize(&serialized).unwrap();
970 assert_eq!(decoded.fields.len(), 1);
971 assert_eq!(
972 decoded.fields.get(&7).unwrap(),
973 &[Value::Varint(42), Value::Varint(150)]
974 );
975
976 // A single variable length field
977 let serialized = [10, 4, 116, 114, 117, 101];
978 let decoded = Bufany::deserialize(&serialized).unwrap();
979 assert_eq!(decoded.fields.len(), 1);
980 assert_eq!(
981 decoded.fields.get(&1).unwrap(),
982 &[Value::VariableLength(&[116, 114, 117, 101])]
983 );
984 }
985
986 #[test]
987 fn deserialize_repeated_works() {
988 // An uint64 list in field number 7
989 let serialized = Anybuf::new()
990 .append_repeated_uint64(7, &[150, 42, 1, 0, 0xFFFFFFFFFFFFFFFF])
991 .into_vec();
992 let decoded = Bufany::deserialize(&serialized).unwrap();
993 assert_eq!(decoded.fields.len(), 1);
994 assert_eq!(
995 decoded.fields.get(&7).unwrap(),
996 &[
997 Value::Varint(150),
998 Value::Varint(42),
999 Value::Varint(1),
1000 Value::Varint(0),
1001 Value::Varint(0xFFFFFFFFFFFFFFFF)
1002 ]
1003 );
1004 }
1005
1006 #[test]
1007 fn deserialize_handles_errors() {
1008 // length (5) loger than remaining data (5)
1009 let serialized = [10, 5, 116, 114, 117, 101];
1010 let err = Bufany::deserialize(&serialized).unwrap_err();
1011 match err {
1012 BufanyError::UnexpectedEndOfData => {}
1013 err => panic!("Unexpected error: {err:?}"),
1014 }
1015
1016 // length (3) shorter than remaining data (4), i.e. we have one garbage byte at the end
1017 let serialized = [10, 3, 116, 114, 117, 101];
1018 let err = Bufany::deserialize(&serialized).unwrap_err();
1019 match err {
1020 BufanyError::UnexpectedEndOfData => {}
1021 err => panic!("Unexpected error: {err:?}"),
1022 }
1023
1024 // First byte is not a valid tag (must be a varint)
1025 let serialized = [130];
1026 let err = Bufany::deserialize(&serialized).unwrap_err();
1027 match err {
1028 BufanyError::InvalidTag => {}
1029 err => panic!("Unexpected error: {err:?}"),
1030 }
1031 }
1032
1033 #[test]
1034 fn bytes_works() {
1035 let serialized = Anybuf::new()
1036 .append_uint64(1, 150)
1037 .append_bytes(2, vec![0xF0, 0x00])
1038 .append_bytes(3, vec![])
1039 .into_vec();
1040 let decoded = Bufany::deserialize(&serialized).unwrap();
1041 assert_eq!(decoded.bytes(1), None); // wrong type
1042 assert_eq!(decoded.bytes(2), Some(vec![0xF0, 0x00]));
1043 assert_eq!(decoded.bytes(3), Some(vec![]));
1044 assert_eq!(decoded.bytes(4), Some(vec![]));
1045 }
1046
1047 #[test]
1048 fn string_works() {
1049 let serialized = Anybuf::new()
1050 .append_uint64(1, 150)
1051 .append_string(2, "blub")
1052 .append_string(3, "")
1053 .into_vec();
1054 let decoded = Bufany::deserialize(&serialized).unwrap();
1055 assert_eq!(decoded.string(1), None);
1056 assert_eq!(decoded.string(2), Some("blub".to_string()));
1057 assert_eq!(decoded.string(3), Some("".to_string()));
1058 assert_eq!(decoded.string(4), Some("".to_string()));
1059
1060 // Last One Wins (https://protobuf.dev/programming-guides/encoding/#last-one-wins)
1061 let serialized = Anybuf::new()
1062 .append_uint64(1, 150)
1063 .append_string(2, "one")
1064 .append_string(2, "two")
1065 .append_string(2, "three")
1066 .into_vec();
1067 let decoded = Bufany::deserialize(&serialized).unwrap();
1068 assert_eq!(decoded.string(1), None);
1069 assert_eq!(decoded.string(2), Some("three".to_string()));
1070 }
1071
1072 #[test]
1073 fn uint64_works() {
1074 let serialized = Anybuf::new()
1075 .append_uint64(1, 150)
1076 .append_uint64(2, 17)
1077 .append_uint64(3, 36028797018963970)
1078 .append_bytes(4, vec![0xF0, 0x00])
1079 .append_uint64(5, 0)
1080 .into_vec();
1081 let decoded = Bufany::deserialize(&serialized).unwrap();
1082 assert_eq!(decoded.uint64(1), Some(150));
1083 assert_eq!(decoded.uint64(2), Some(17));
1084 assert_eq!(decoded.uint64(3), Some(36028797018963970));
1085 assert_eq!(decoded.uint64(4), None); // wrong type
1086 assert_eq!(decoded.uint64(5), Some(0));
1087 assert_eq!(decoded.uint64(6), Some(0));
1088 }
1089
1090 #[test]
1091 fn uint32_works() {
1092 let serialized = Anybuf::new()
1093 .append_uint32(1, 150)
1094 .append_uint64(2, 17)
1095 .append_uint64(3, 36028797018963970)
1096 .append_bytes(4, vec![0xF0, 0x00])
1097 .append_uint32(5, 0)
1098 .into_vec();
1099 let decoded = Bufany::deserialize(&serialized).unwrap();
1100 assert_eq!(decoded.uint32(1), Some(150));
1101 assert_eq!(decoded.uint32(2), Some(17)); // works because on the wire we don't differentiate
1102 assert_eq!(decoded.uint32(3), None); // too large
1103 assert_eq!(decoded.uint32(4), None);
1104 assert_eq!(decoded.uint32(5), Some(0));
1105 assert_eq!(decoded.uint32(6), Some(0));
1106 }
1107
1108 #[test]
1109 fn bool_works() {
1110 let serialized = Anybuf::new()
1111 .append_uint32(1, 150)
1112 .append_uint64(2, 17)
1113 .append_uint64(3, 1)
1114 .append_bytes(4, vec![0xF0, 0x00])
1115 .append_bool(5, true)
1116 .append_bool(6, false)
1117 .into_vec();
1118 let decoded = Bufany::deserialize(&serialized).unwrap();
1119 assert_eq!(decoded.bool(1), None); // too large
1120 assert_eq!(decoded.bool(2), None); // too large
1121 assert_eq!(decoded.bool(3), Some(true)); // 1 and true cannot be differentiated
1122 assert_eq!(decoded.bool(4), None); // wrong type
1123 assert_eq!(decoded.bool(5), Some(true));
1124 assert_eq!(decoded.bool(6), Some(false));
1125 assert_eq!(decoded.bool(7), Some(false));
1126 }
1127
1128 #[test]
1129 fn sint64_works() {
1130 let serialized = Anybuf::new()
1131 .append_sint64(1, 150)
1132 .append_sint64(2, -534214672)
1133 .append_sint64(3, 0)
1134 .append_bytes(4, vec![0xF0, 0x00])
1135 .append_sint64(5, i64::MIN)
1136 .append_sint64(6, i64::MAX)
1137 .into_vec();
1138 let decoded = Bufany::deserialize(&serialized).unwrap();
1139 assert_eq!(decoded.sint64(1), Some(150));
1140 assert_eq!(decoded.sint64(2), Some(-534214672));
1141 assert_eq!(decoded.sint64(3), Some(0));
1142 assert_eq!(decoded.sint64(4), None);
1143 assert_eq!(decoded.sint64(5), Some(i64::MIN));
1144 assert_eq!(decoded.sint64(6), Some(i64::MAX));
1145 assert_eq!(decoded.sint64(85), Some(0)); // not serialized => default
1146 }
1147
1148 #[test]
1149 fn sint32_works() {
1150 let serialized = Anybuf::new()
1151 .append_sint32(1, 150)
1152 .append_sint32(2, -534214672)
1153 .append_sint32(3, 0)
1154 .append_bytes(4, vec![0xF0, 0x00])
1155 .append_sint32(5, i32::MIN)
1156 .append_sint32(6, i32::MAX)
1157 .append_sint64(7, i32::MAX as i64 + 1)
1158 .into_vec();
1159 let decoded = Bufany::deserialize(&serialized).unwrap();
1160 assert_eq!(decoded.sint32(1), Some(150));
1161 assert_eq!(decoded.sint32(2), Some(-534214672));
1162 assert_eq!(decoded.sint32(3), Some(0));
1163 assert_eq!(decoded.sint32(4), None);
1164 assert_eq!(decoded.sint32(5), Some(i32::MIN));
1165 assert_eq!(decoded.sint32(6), Some(i32::MAX));
1166 assert_eq!(decoded.sint32(7), None); // value out of range
1167 assert_eq!(decoded.sint32(85), Some(0)); // not serialized => default
1168 }
1169
1170 #[test]
1171 fn int64_works() {
1172 let serialized = Anybuf::new()
1173 .append_int64(1, 150)
1174 .append_int64(2, -534214672)
1175 .append_int64(3, 0)
1176 .append_bytes(4, vec![0xF0, 0x00])
1177 .append_int64(5, i64::MIN)
1178 .append_int64(6, i64::MAX)
1179 .into_vec();
1180 let decoded = Bufany::deserialize(&serialized).unwrap();
1181 assert_eq!(decoded.int64(1), Some(150));
1182 assert_eq!(decoded.int64(2), Some(-534214672));
1183 assert_eq!(decoded.int64(3), Some(0));
1184 assert_eq!(decoded.int64(4), None);
1185 assert_eq!(decoded.int64(5), Some(i64::MIN));
1186 assert_eq!(decoded.int64(6), Some(i64::MAX));
1187 assert_eq!(decoded.int64(85), Some(0)); // not serialized => default
1188 }
1189
1190 #[test]
1191 fn int32_works() {
1192 let serialized = Anybuf::new()
1193 .append_int32(1, 150)
1194 .append_int32(2, -534214672)
1195 .append_int32(3, 0)
1196 .append_bytes(4, vec![0xF0, 0x00])
1197 .append_int32(5, i32::MIN)
1198 .append_int32(6, i32::MAX)
1199 .append_int64(7, i32::MAX as i64 + 1)
1200 .into_vec();
1201 let decoded = Bufany::deserialize(&serialized).unwrap();
1202 assert_eq!(decoded.int32(1), Some(150));
1203 assert_eq!(decoded.int32(2), Some(-534214672));
1204 assert_eq!(decoded.int32(3), Some(0));
1205 assert_eq!(decoded.int32(4), None);
1206 assert_eq!(decoded.int32(5), Some(i32::MIN));
1207 assert_eq!(decoded.int32(6), Some(i32::MAX));
1208 assert_eq!(decoded.int32(7), None); // value out of range
1209 assert_eq!(decoded.int32(85), Some(0)); // not serialized => default
1210 }
1211
1212 #[test]
1213 fn message_works() {
1214 let serialized = Anybuf::new()
1215 .append_message(
1216 1,
1217 &Anybuf::new()
1218 .append_bool(1, true)
1219 .append_string(2, "foo")
1220 .append_sint64(3, -37648762834),
1221 )
1222 .append_sint32(2, 150)
1223 .append_bytes(3, b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
1224 .into_vec();
1225 let decoded = Bufany::deserialize(&serialized).unwrap();
1226
1227 let nested = decoded.message(1).unwrap();
1228 assert_eq!(nested.bool(1), Some(true));
1229 assert_eq!(nested.string(2), Some("foo".to_string()));
1230 assert_eq!(nested.sint64(3), Some(-37648762834));
1231
1232 assert!(decoded.message(2).is_none()); // wrong type
1233 assert!(decoded.message(3).is_none()); // not a valid proto message
1234 }
1235
1236 #[test]
1237 fn repeated_uint64_works() {
1238 let serialized = Anybuf::new()
1239 .append_repeated_uint64(1, &[150])
1240 .append_repeated_uint64(2, &[150, 0, u64::MAX])
1241 .append_string(3, "foo")
1242 .into_vec();
1243 let decoded = Bufany::deserialize(&serialized).unwrap();
1244 assert_eq!(decoded.repeated_uint64(1), Some(vec![150]));
1245 assert_eq!(decoded.repeated_uint64(2), Some(vec![150, 0, u64::MAX]));
1246 assert_eq!(decoded.repeated_uint64(3), None);
1247 assert_eq!(decoded.repeated_uint64(85), Some(vec![])); // not serialized => default
1248 }
1249
1250 #[test]
1251 fn repeated_uint32_works() {
1252 let serialized = Anybuf::new()
1253 .append_repeated_uint32(1, &[150])
1254 .append_repeated_uint32(2, &[150, 0, u32::MAX])
1255 .append_string(3, "foo")
1256 .append_repeated_uint64(4, &[150, 0, u64::MAX])
1257 .into_vec();
1258 let decoded = Bufany::deserialize(&serialized).unwrap();
1259 assert_eq!(decoded.repeated_uint32(1), Some(vec![150]));
1260 assert_eq!(decoded.repeated_uint32(2), Some(vec![150, 0, u32::MAX]));
1261 assert_eq!(decoded.repeated_uint32(3), None);
1262 assert_eq!(decoded.repeated_uint32(4), None); // Value exceeded 32 bit range
1263 assert_eq!(decoded.repeated_uint32(85), Some(vec![])); // not serialized => default
1264 }
1265
1266 #[test]
1267 fn repeated_bool() {
1268 let serialized = Anybuf::new()
1269 .append_repeated_bool(1, &[true])
1270 .append_repeated_bool(2, &[true, false, true])
1271 .append_string(3, "foo")
1272 .append_repeated_uint64(4, &[0, 1, 17])
1273 .into_vec();
1274 let decoded = Bufany::deserialize(&serialized).unwrap();
1275 assert_eq!(decoded.repeated_bool(1), Some(vec![true]));
1276 assert_eq!(decoded.repeated_bool(2), Some(vec![true, false, true]));
1277 assert_eq!(decoded.repeated_bool(3), None);
1278 assert_eq!(decoded.repeated_bool(4), None); // Value exceeded 1 bit range
1279 assert_eq!(decoded.repeated_bool(85), Some(vec![])); // not serialized => default
1280 }
1281
1282 #[test]
1283 fn repeated_sint64_works() {
1284 let serialized = Anybuf::new()
1285 .append_repeated_sint64(1, &[150, -150])
1286 .append_repeated_sint64(2, &[150, 0, i64::MIN, i64::MAX])
1287 .append_string(3, "foo")
1288 .into_vec();
1289 let decoded = Bufany::deserialize(&serialized).unwrap();
1290 assert_eq!(decoded.repeated_sint64(1), Some(vec![150, -150]));
1291 assert_eq!(
1292 decoded.repeated_sint64(2),
1293 Some(vec![150, 0, i64::MIN, i64::MAX])
1294 );
1295 assert_eq!(decoded.repeated_sint64(3), None);
1296 assert_eq!(decoded.repeated_sint64(85), Some(vec![])); // not serialized => default
1297 }
1298
1299 #[test]
1300 fn repeated_sint32_works() {
1301 let serialized = Anybuf::new()
1302 .append_repeated_sint32(1, &[150, -150])
1303 .append_repeated_sint32(2, &[150, 0, i32::MIN])
1304 .append_string(3, "foo")
1305 .append_repeated_sint64(4, &[150, 0, i64::MAX])
1306 .into_vec();
1307 let decoded = Bufany::deserialize(&serialized).unwrap();
1308 assert_eq!(decoded.repeated_sint32(1), Some(vec![150, -150]));
1309 assert_eq!(decoded.repeated_sint32(2), Some(vec![150, 0, i32::MIN]));
1310 assert_eq!(decoded.repeated_sint32(3), None);
1311 assert_eq!(decoded.repeated_sint32(4), None); // Value exceeded 32 bit range
1312 assert_eq!(decoded.repeated_sint32(85), Some(vec![])); // not serialized => default
1313 }
1314
1315 #[test]
1316 fn repeated_int64_works() {
1317 let serialized = Anybuf::new()
1318 .append_repeated_int64(1, &[150, -150])
1319 .append_repeated_int64(2, &[150, 0, i64::MIN, i64::MAX])
1320 .append_string(3, "foo")
1321 .into_vec();
1322 let decoded = Bufany::deserialize(&serialized).unwrap();
1323 assert_eq!(decoded.repeated_int64(1), Some(vec![150, -150]));
1324 assert_eq!(
1325 decoded.repeated_int64(2),
1326 Some(vec![150, 0, i64::MIN, i64::MAX])
1327 );
1328 assert_eq!(decoded.repeated_int64(3), None);
1329 assert_eq!(decoded.repeated_int64(85), Some(vec![])); // not serialized => default
1330 }
1331
1332 #[test]
1333 fn repeated_int32_works() {
1334 let serialized = Anybuf::new()
1335 .append_repeated_int32(1, &[150, -150])
1336 .append_repeated_int32(2, &[150, 0, i32::MIN])
1337 .append_string(3, "foo")
1338 .append_repeated_int64(4, &[150, 0, i64::MAX])
1339 .into_vec();
1340 let decoded = Bufany::deserialize(&serialized).unwrap();
1341 assert_eq!(decoded.repeated_int32(1), Some(vec![150, -150]));
1342 assert_eq!(decoded.repeated_int32(2), Some(vec![150, 0, i32::MIN]));
1343 assert_eq!(decoded.repeated_int32(3), None);
1344 assert_eq!(decoded.repeated_int32(4), None); // Value exceeded 32 bit range
1345 assert_eq!(decoded.repeated_int32(85), Some(vec![])); // not serialized => default
1346 }
1347
1348 #[test]
1349 fn repeated_bytes_works() {
1350 let serialized = Anybuf::new()
1351 .append_uint64(1, 150)
1352 .append_repeated_bytes(2, &[vec![0xF0u8, 0x00].as_slice()])
1353 .append_repeated_bytes::<&[u8]>(3, &[b"\x01\x02\x03", b"\x00", b"", b"blub"])
1354 .append_repeated_string(4, &["valid utf8 string", "hello"])
1355 .append_repeated_bytes::<&[u8]>(5, &[])
1356 .into_vec();
1357 let decoded = Bufany::deserialize(&serialized).unwrap();
1358 // Wrong type
1359 assert_eq!(decoded.repeated_bytes(1), None);
1360 // One element
1361 assert_eq!(decoded.repeated_bytes(2).unwrap(), [b"\xF0\0"]);
1362 // Multiple elements
1363 assert_eq!(
1364 decoded.repeated_bytes(3).unwrap(),
1365 [b"\x01\x02\x03" as &[u8], b"\x00", b"", b"blub"]
1366 );
1367 // String elements decoded as bytes
1368 assert_eq!(
1369 decoded.repeated_bytes(4).unwrap(),
1370 [b"valid utf8 string" as &[u8], b"hello"]
1371 );
1372 // No elements
1373 assert_eq!(decoded.repeated_bytes(5).unwrap(), Vec::<Vec<u8>>::new());
1374 // not serialized => default
1375 assert_eq!(decoded.repeated_bytes(85).unwrap(), Vec::<Vec<u8>>::new());
1376 }
1377
1378 #[test]
1379 fn repeated_string_works() {
1380 let serialized = Anybuf::new()
1381 .append_repeated_sint32(1, &[1, 2, 3])
1382 .append_repeated_string(2, &["foo", "bar"])
1383 .append_repeated_string(3, &["foo", "foo", "", "ok"])
1384 .append_repeated_string::<String>(4, &[])
1385 .append_repeated_bytes(5, &[b"hello", b"world"])
1386 .append_repeated_bytes(6, &[b"\xf0\x00"])
1387 .into_vec();
1388 let decoded = Bufany::deserialize(&serialized).unwrap();
1389 // wrong type
1390 let err = decoded.repeated_string(1).unwrap_err();
1391 assert!(matches!(err, RepeatedStringError::TypeMismatch));
1392 // two strings
1393 assert_eq!(decoded.repeated_string(2).unwrap(), &["foo", "bar"]);
1394 // duplicates and empty values
1395 assert_eq!(
1396 decoded.repeated_string(3).unwrap(),
1397 &["foo", "foo", "", "ok"]
1398 );
1399 // empty list
1400 assert_eq!(decoded.repeated_string(4).unwrap(), Vec::<String>::new());
1401 // interprets repeated bytes as repeated string
1402 assert_eq!(decoded.repeated_string(5).unwrap(), &["hello", "world"]);
1403 // invalid-utf8 is rejected
1404 let err = decoded.repeated_string(6).unwrap_err();
1405 assert!(matches!(err, RepeatedStringError::InvalidUtf8));
1406 // not serialized => default
1407 assert_eq!(decoded.repeated_string(85).unwrap(), Vec::<String>::new());
1408 }
1409
1410 #[test]
1411 fn repeated_message_works() {
1412 let serialized = Anybuf::new()
1413 .append_message(
1414 1,
1415 &Anybuf::new()
1416 .append_bool(1, true)
1417 .append_string(2, "foo")
1418 .append_sint64(3, -37648762834),
1419 )
1420 .append_message(
1421 1,
1422 &Anybuf::new()
1423 .append_bool(1, true)
1424 .append_string(2, "bar")
1425 .append_sint64(3, -37648762834),
1426 )
1427 .append_message(
1428 1,
1429 &Anybuf::new()
1430 .append_bool(1, true)
1431 .append_string(2, "baz")
1432 .append_sint64(3, -37648762834),
1433 )
1434 .append_message(2, &Anybuf::new().append_uint32(1, 42))
1435 .append_message(3, &Anybuf::new())
1436 .append_sint32(10, 150)
1437 .append_message(
1438 11,
1439 &Anybuf::new()
1440 .append_bool(1, true)
1441 .append_string(2, "baz")
1442 .append_sint64(3, -37648762834),
1443 )
1444 .append_uint32(11, 22)
1445 .append_bytes(12, b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
1446 .into_vec();
1447 let decoded = Bufany::deserialize(&serialized).unwrap();
1448
1449 let nested = decoded.repeated_message(1).unwrap();
1450 assert_eq!(nested.len(), 3);
1451 assert_eq!(nested[0].bool(1), Some(true));
1452 assert_eq!(nested[0].string(2), Some("foo".to_string()));
1453 assert_eq!(nested[0].sint64(3), Some(-37648762834));
1454 assert_eq!(nested[1].bool(1), Some(true));
1455 assert_eq!(nested[1].string(2), Some("bar".to_string()));
1456 assert_eq!(nested[1].sint64(3), Some(-37648762834));
1457 assert_eq!(nested[2].bool(1), Some(true));
1458 assert_eq!(nested[2].string(2), Some("baz".to_string()));
1459 assert_eq!(nested[2].sint64(3), Some(-37648762834));
1460
1461 let nested = decoded.repeated_message(2).unwrap();
1462 assert_eq!(nested.len(), 1);
1463 assert_eq!(nested[0].uint32(1), Some(42));
1464
1465 // An empty message is non existent
1466 let nested = decoded.repeated_message(3).unwrap();
1467 assert_eq!(nested.len(), 0);
1468
1469 // int
1470 assert!(matches!(
1471 decoded.repeated_message(10).unwrap_err(),
1472 RepeatedMessageError::TypeMismatch
1473 ));
1474 // mixed type string and int
1475 assert!(matches!(
1476 decoded.repeated_message(11).unwrap_err(),
1477 RepeatedMessageError::TypeMismatch
1478 ));
1479 // invalid data in variable length field
1480 assert!(matches!(
1481 decoded.repeated_message(12).unwrap_err(),
1482 RepeatedMessageError::DecodingError(_)
1483 ));
1484 }
1485}