Bufany

Struct Bufany 

Source
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>

Source

pub fn deserialize(serialized: &'a [u8]) -> Result<Bufany<'a>, BufanyError>

Creates a new serializer.

Source

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 => default
Source

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 => default
Source

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));
Source

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));
Source

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));
Source

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));
Source

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));
Source

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));
Source

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));
Source

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 message
Source

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);
Source

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);
Source

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);
Source

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);
Source

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);
Source

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);
Source

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);
Source

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());
Source

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));
Source

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
Source

pub fn value(&self, field_number: u32) -> Option<Value<'_>>

Gets the value of the given field number. This returns None if the field number does not exist

Trait Implementations§

Source§

impl<'a> Debug for Bufany<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for Bufany<'a>

§

impl<'a> RefUnwindSafe for Bufany<'a>

§

impl<'a> Send for Bufany<'a>

§

impl<'a> Sync for Bufany<'a>

§

impl<'a> Unpin for Bufany<'a>

§

impl<'a> UnwindSafe for Bufany<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.