pub struct Bufany<'a> { /* private fields */ }Expand description
A minmal protobuf decoder.
Decodes protobuf bytes and allows you to access the field.
The decoding step is zero-copy for variable length values, i.e. no heap allocations are done for bytes and string fields as long as you do not access them. The accessors then copy the values you need.
§Example
use anybuf::{Anybuf, Bufany};
let serialized: Vec<u8> = Anybuf::new()
.append_uint64(1, 150)
.append_uint32(2, 38)
.append_bytes(3, vec![0xF0, 0x00])
.append_string(4, "valid utf8 string")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.uint64(1), Some(150));
assert_eq!(decoded.uint32(2), Some(38));
assert_eq!(decoded.bytes(3), Some(vec![0xF0, 0x00]));
assert_eq!(decoded.string(4), Some("valid utf8 string".to_string()));
assert_eq!(decoded.string(5), Some("".to_string()));Implementations§
Source§impl<'a> Bufany<'a>
impl<'a> Bufany<'a>
Sourcepub fn deserialize(serialized: &'a [u8]) -> Result<Bufany<'a>, BufanyError>
pub fn deserialize(serialized: &'a [u8]) -> Result<Bufany<'a>, BufanyError>
Creates a new serializer.
Sourcepub fn bytes(&self, field_number: u32) -> Option<Vec<u8>>
pub fn bytes(&self, field_number: u32) -> Option<Vec<u8>>
Gets bytes from the given field number. This returns None if
- the value type is not variable length
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_uint64(1, 150)
.append_bytes(2, vec![0xF0, 0x00])
.append_bytes(3, vec![])
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.bytes(1), None); // wrong type
assert_eq!(decoded.bytes(2), Some(vec![0xF0, 0x00]));
assert_eq!(decoded.bytes(3), Some(vec![])); // not serialized => default
assert_eq!(decoded.bytes(4), Some(vec![])); // not serialized => defaultSourcepub fn string(&self, field_number: u32) -> Option<String>
pub fn string(&self, field_number: u32) -> Option<String>
Gets bytes from the given field number. This returns None if
- the value type is not variable length
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_uint64(1, 150)
.append_bytes(2, vec![0xF0, 0x00])
.append_string(3, "valid utf8 string")
.append_string(4, "")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.string(1), None); // wrong type
assert_eq!(decoded.string(2), None); // invalid utf8
assert_eq!(decoded.string(3), Some("valid utf8 string".to_string()));
assert_eq!(decoded.string(4), Some("".to_string())); // not serialized => default
assert_eq!(decoded.string(5), Some("".to_string())); // not serialized => defaultSourcepub fn uint64(&self, field_number: u32) -> Option<u64>
pub fn uint64(&self, field_number: u32) -> Option<u64>
Gets a uint64 from the given field number. This returns None if
- the value type is not of type varint
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_uint64(1, 150)
.append_bytes(2, vec![0xF0, 0x00])
.append_uint64(3, 0)
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.uint64(1), Some(150));
assert_eq!(decoded.uint64(2), None);
assert_eq!(decoded.uint64(3), Some(0));
assert_eq!(decoded.uint64(4), Some(0));Sourcepub fn uint32(&self, field_number: u32) -> Option<u32>
pub fn uint32(&self, field_number: u32) -> Option<u32>
Gets a uint32 from the given field number. This returns None if
- the value type is not of type varint
- the value exceeds the uint32 range
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_uint32(1, 150)
.append_uint64(2, 17)
.append_uint64(3, 36028797018963970)
.append_bytes(4, vec![0xF0, 0x00])
.append_uint32(5, 0)
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.uint32(1), Some(150));
assert_eq!(decoded.uint32(2), Some(17)); // works because on the wire we don't differentiate
assert_eq!(decoded.uint32(3), None); // too large
assert_eq!(decoded.uint32(4), None);
assert_eq!(decoded.uint32(5), Some(0));Sourcepub fn bool(&self, field_number: u32) -> Option<bool>
pub fn bool(&self, field_number: u32) -> Option<bool>
Gets a bool from the given field number. This returns None if
- the value type is not of type varint
- the value is not 0 or 1
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_uint32(1, 150)
.append_uint64(2, 17)
.append_uint64(3, 1)
.append_bytes(4, vec![0xF0, 0x00])
.append_bool(5, true)
.append_bool(6, false)
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.bool(1), None); // too large
assert_eq!(decoded.bool(2), None); // too large
assert_eq!(decoded.bool(3), Some(true)); // 1 and true cannot be differentiated
assert_eq!(decoded.bool(4), None); // wrong type
assert_eq!(decoded.bool(5), Some(true));
assert_eq!(decoded.bool(6), Some(false));Sourcepub fn sint64(&self, field_number: u32) -> Option<i64>
pub fn sint64(&self, field_number: u32) -> Option<i64>
Gets a sint64 from the given field number. This returns None if the value type is not of type varint.
Please note that protobuf has two different 64 bit signed integer types with different encodings: sint64 and int64. This only works for sint64.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_sint64(1, 150)
.append_sint64(2, -534214672)
.append_sint64(3, 0)
.append_bytes(4, vec![0xF0, 0x00])
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.sint64(1), Some(150));
assert_eq!(decoded.sint64(2), Some(-534214672));
assert_eq!(decoded.sint64(3), Some(0));
assert_eq!(decoded.sint64(4), None);
assert_eq!(decoded.sint64(5), Some(0));Sourcepub fn sint32(&self, field_number: u32) -> Option<i32>
pub fn sint32(&self, field_number: u32) -> Option<i32>
Gets a sint32 from the given field number. This returns None if the value type is not of type varint or the value exceeds the 32 bit range.
Please note that protobuf has two different 32 bit signed integer types with different encodings: sint32 and int32. This only works for sint32.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_sint32(1, 150)
.append_sint32(2, -534214672)
.append_sint32(3, 0)
.append_bytes(4, vec![0xF0, 0x00])
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.sint32(1), Some(150));
assert_eq!(decoded.sint32(2), Some(-534214672));
assert_eq!(decoded.sint32(3), Some(0));
assert_eq!(decoded.sint32(4), None);
assert_eq!(decoded.sint32(5), Some(0));Sourcepub fn int64(&self, field_number: u32) -> Option<i64>
pub fn int64(&self, field_number: u32) -> Option<i64>
Gets an int64 from the given field number. This returns None if the value type is not of type varint.
Please note that protobuf has two different 64 bit signed integer types with different encodings: sint64 and int64. This only works for int64.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_int64(1, 150)
.append_int64(2, -534214672)
.append_int64(3, 0)
.append_bytes(4, vec![0xF0, 0x00])
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.int64(1), Some(150));
assert_eq!(decoded.int64(2), Some(-534214672));
assert_eq!(decoded.int64(3), Some(0));
assert_eq!(decoded.int64(4), None);
assert_eq!(decoded.int64(5), Some(0));Sourcepub fn int32(&self, field_number: u32) -> Option<i32>
pub fn int32(&self, field_number: u32) -> Option<i32>
Gets an int32 from the given field number. This returns None if the value type is not of type varint or the value exceeds the 32 bit range.
Please note that protobuf has two different 32 bit signed integer types with different encodings: sint32 and int32. This only works for int32.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_int32(1, 150)
.append_int32(2, -534214672)
.append_int32(3, 0)
.append_bytes(4, vec![0xF0, 0x00])
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.int32(1), Some(150));
assert_eq!(decoded.int32(2), Some(-534214672));
assert_eq!(decoded.int32(3), Some(0));
assert_eq!(decoded.int32(4), None);
assert_eq!(decoded.int32(5), Some(0));Sourcepub fn message(&'a self, field_number: u32) -> Option<Bufany<'a>>
pub fn message(&'a self, field_number: u32) -> Option<Bufany<'a>>
Gets a nested message from the given field number. This returns None if the value type is not of type variable length or the inner message cannot be decoded.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_message(
1,
&Anybuf::new()
.append_bool(1, true)
.append_string(2, "foo")
.append_sint64(3, -37648762834),
)
.append_sint32(2, 150)
.append_bytes(3, b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
let nested = decoded.message(1).unwrap();
assert_eq!(nested.bool(1), Some(true));
assert_eq!(nested.string(2), Some("foo".to_string()));
assert_eq!(nested.sint64(3), Some(-37648762834));
assert!(decoded.message(2).is_none()); // wrong type
assert!(decoded.message(3).is_none()); // not a valid proto messageSourcepub fn repeated_uint64(&self, field_number: u32) -> Option<Vec<u64>>
pub fn repeated_uint64(&self, field_number: u32) -> Option<Vec<u64>>
Gets repeated uint64 from the given field number. Returns None in case a wrong wire type was found.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_repeated_uint64(1, &[150])
.append_repeated_uint64(2, &[150, 0, u64::MAX])
.append_string(3, "foo")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.repeated_uint64(1), Some(vec![150]));
assert_eq!(decoded.repeated_uint64(2), Some(vec![150, 0, u64::MAX]));
assert_eq!(decoded.repeated_uint64(3), None);Sourcepub fn repeated_uint32(&self, field_number: u32) -> Option<Vec<u32>>
pub fn repeated_uint32(&self, field_number: u32) -> Option<Vec<u32>>
Gets repeated uint32 from the given field number. Returns None in case a wrong wire type was found or the value exceeds the 32 bit range.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_repeated_uint32(1, &[150])
.append_repeated_uint32(2, &[150, 0, u32::MAX])
.append_string(3, "foo")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.repeated_uint32(1), Some(vec![150]));
assert_eq!(decoded.repeated_uint32(2), Some(vec![150, 0, u32::MAX]));
assert_eq!(decoded.repeated_uint32(3), None);Sourcepub fn repeated_bool(&self, field_number: u32) -> Option<Vec<bool>>
pub fn repeated_bool(&self, field_number: u32) -> Option<Vec<bool>>
Gets repeated bool from the given field number. Returns None in case a wrong wire type was found or the value is not 0 or 1.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_repeated_bool(1, &[true])
.append_repeated_bool(2, &[true, false, true])
.append_string(3, "foo")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.repeated_bool(1), Some(vec![true]));
assert_eq!(decoded.repeated_bool(2), Some(vec![true, false, true]));
assert_eq!(decoded.repeated_bool(3), None);Sourcepub fn repeated_sint64(&self, field_number: u32) -> Option<Vec<i64>>
pub fn repeated_sint64(&self, field_number: u32) -> Option<Vec<i64>>
Gets repeated sint64 from the given field number. Returns None in case a wrong wire type was found.
Please note that protobuf has two different 64 bit signed integer types with different encodings: sint64 and int64. This only works for sint64.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_repeated_sint64(1, &[150, -150])
.append_repeated_sint64(2, &[150, 0, i64::MAX])
.append_string(3, "foo")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.repeated_sint64(1), Some(vec![150, -150]));
assert_eq!(decoded.repeated_sint64(2), Some(vec![150, 0, i64::MAX]));
assert_eq!(decoded.repeated_sint64(3), None);Sourcepub fn repeated_sint32(&self, field_number: u32) -> Option<Vec<i32>>
pub fn repeated_sint32(&self, field_number: u32) -> Option<Vec<i32>>
Gets repeated sint32 from the given field number. Returns None in case a wrong wire type was found or the value exceeds the 32 bit range.
Please note that protobuf has two different 32 bit signed integer types with different encodings: sint32 and int32. This only works for sint32.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_repeated_sint32(1, &[150, -150])
.append_repeated_sint32(2, &[150, 0, i32::MIN])
.append_string(3, "foo")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.repeated_sint32(1), Some(vec![150, -150]));
assert_eq!(decoded.repeated_sint32(2), Some(vec![150, 0, i32::MIN]));
assert_eq!(decoded.repeated_sint32(3), None);Sourcepub fn repeated_int64(&self, field_number: u32) -> Option<Vec<i64>>
pub fn repeated_int64(&self, field_number: u32) -> Option<Vec<i64>>
Gets repeated int64 from the given field number. Returns None in case a wrong wire type was found.
Please note that protobuf has two different 64 bit signed integer types with different encodings: sint64 and int64. This only works for int64.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_repeated_int64(1, &[150, -150])
.append_repeated_int64(2, &[150, 0, i64::MAX])
.append_string(3, "foo")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.repeated_int64(1), Some(vec![150, -150]));
assert_eq!(decoded.repeated_int64(2), Some(vec![150, 0, i64::MAX]));
assert_eq!(decoded.repeated_int64(3), None);Sourcepub fn repeated_int32(&self, field_number: u32) -> Option<Vec<i32>>
pub fn repeated_int32(&self, field_number: u32) -> Option<Vec<i32>>
Gets repeated sint32 from the given field number. Returns None in case a wrong wire type was found or the value exceeds the 32 bit range.
Please note that protobuf has two different 32 bit signed integer types with different encodings: sint32 and int32. This only works for int32.
§Example
use anybuf::{Anybuf, Bufany};
let serialized = Anybuf::new()
.append_repeated_int32(1, &[150, -150])
.append_repeated_int32(2, &[150, 0, i32::MIN])
.append_string(3, "foo")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.repeated_int32(1), Some(vec![150, -150]));
assert_eq!(decoded.repeated_int32(2), Some(vec![150, 0, i32::MIN]));
assert_eq!(decoded.repeated_int32(3), None);Sourcepub fn repeated_bytes(&self, field_number: u32) -> Option<Vec<Vec<u8>>>
pub fn repeated_bytes(&self, field_number: u32) -> Option<Vec<Vec<u8>>>
Gets repeated bytes from the given field number. Returns None in case a wrong wire type was found.
§Example
use anybuf::{Anybuf, Bufany};
let myvec = vec![0xF0u8, 0x00];
let serialized = Anybuf::new()
.append_uint64(1, 150)
.append_repeated_bytes(2, &[&myvec])
.append_repeated_bytes::<&[u8]>(3, &[b"\x01\x02\x03", b"\x00"])
.append_repeated_string(4, &["valid utf8 string", "hello"])
.append_repeated_bytes::<&[u8]>(5, &[])
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
assert_eq!(decoded.repeated_bytes(2).unwrap(), &[&[0xF0, 0x00]]);
assert_eq!(decoded.repeated_bytes(3).unwrap(), [&[1u8, 2, 3] as &[u8], &[0]]);
assert_eq!(decoded.repeated_bytes(4).unwrap(), [b"valid utf8 string" as &[u8], b"hello"]);
assert_eq!(decoded.repeated_bytes(5).unwrap(), Vec::<Vec<u8>>::new());
assert_eq!(decoded.repeated_bytes(12).unwrap(), Vec::<Vec<u8>>::new());Sourcepub fn repeated_string(
&self,
field_number: u32,
) -> Result<Vec<String>, RepeatedStringError>
pub fn repeated_string( &self, field_number: u32, ) -> Result<Vec<String>, RepeatedStringError>
Gets repeated string from the given field number.
§Example
use anybuf::{Anybuf, Bufany, RepeatedStringError};
let serialized = Anybuf::new()
.append_uint64(1, 150)
.append_bytes(2, vec![0xF0, 0x00])
.append_repeated_string(3, &["valid utf8 string", "hello"])
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
// happy path
let strings = decoded.repeated_string(3).unwrap();
assert_eq!(strings, ["valid utf8 string".to_string(), "hello".to_string()]);
// cannot get strings from int field
assert!(matches!(decoded.repeated_string(1).unwrap_err(), RepeatedStringError::TypeMismatch));Sourcepub fn repeated_message(
&'a self,
field_number: u32,
) -> Result<Vec<Bufany<'a>>, RepeatedMessageError>
pub fn repeated_message( &'a self, field_number: u32, ) -> Result<Vec<Bufany<'a>>, RepeatedMessageError>
Gets repeated message from the given field number.
Returns an error in case a wrong wire type was found or the message cannot be decoded.
§Example
use anybuf::{Anybuf, Bufany, RepeatedMessageError};
let serialized = Anybuf::new()
.append_message(
1,
&Anybuf::new()
.append_bool(1, true)
.append_string(2, "foo")
.append_sint64(3, -37648762834),
)
.append_message(
1,
&Anybuf::new()
.append_bool(1, true)
.append_string(2, "bar")
.append_sint64(3, -37648762834),
)
.append_message(
1,
&Anybuf::new()
.append_bool(1, true)
.append_string(2, "baz")
.append_sint64(3, -37648762834),
)
.append_sint32(2, 150)
.append_bytes(3, b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
.into_vec();
let decoded = Bufany::deserialize(&serialized).unwrap();
let nested = decoded.repeated_message(1).unwrap();
assert_eq!(nested.len(), 3);
assert_eq!(nested[0].bool(1), Some(true));
assert_eq!(nested[0].string(2), Some("foo".to_string()));
assert_eq!(nested[0].sint64(3), Some(-37648762834));
assert_eq!(nested[1].bool(1), Some(true));
assert_eq!(nested[1].string(2), Some("bar".to_string()));
assert_eq!(nested[1].sint64(3), Some(-37648762834));
assert_eq!(nested[2].bool(1), Some(true));
assert_eq!(nested[2].string(2), Some("baz".to_string()));
assert_eq!(nested[2].sint64(3), Some(-37648762834));
assert!(matches!(decoded.repeated_message(2).unwrap_err(), RepeatedMessageError::TypeMismatch)); // wrong type
assert!(matches!(decoded.repeated_message(3).unwrap_err(), RepeatedMessageError::DecodingError(_))); // not a valid proto message