Struct rubble::bytes::BytesOr[][src]

pub struct BytesOr<'a, T: ?Sized>(Inner<'a, T>);
Expand description

Reference to a T, or to a byte slice that can be decoded as a T.

Motivation

Many packets can contain dynamically-sized lists of objects. These packets all need to implement ToBytes and FromBytes. For FromBytes, it is impossible to go from &[u8] to &[T].

A workaround is to just store the &[u8] and decode Ts only when necessary. However, this isn’t very type-safe and also makes it difficult to create the type when you have a list of Ts, but can’t easily get a &[u8] (such as when creating a packet to be sent out). You’d have to define your own byte buffer and serialize the Ts into it, which is problematic due to the potentially unknown size requirement and lifetime management.

A workaround around the workaround would be to use 2 types for the same packet: One storing a &[u8] and implementing FromBytes which can only do deserialization, and one storing a &[T] and implementing ToBytes, which can only do serialization. This has the obvious drawback of essentially duplicating all packet definitions.

Rubble’s solution for this is BytesOr: It can store either an &[u8] or a &T (where T might be a slice), and always implements ToBytes and FromBytes if T does. Methods allowing access to the stored T (or the elements in the &[T] slice) will either directly return the value, or decode it using its FromBytes implementation.

When encoding a T, BytesOr::from_ref can be used to store a &T in a BytesOr, which can then be turned into bytes via ToBytes. When decoding data, FromBytes can be used to create a BytesOr from bytes.

This type can also be used in structures when storing a T directly is not desirable due to size concerns: It could be inside a rarely-encountered variant or would blow up the total size of the containing enum). The size of BytesOr is currently 2 usizes plus a discriminant byte, but could potentially be (unsafely) reduced further, should that be required.

Tuple Fields

0: Inner<'a, T>

Implementations

Creates a BytesOr that holds on to a T via reference.

For creating a BytesOr that references a byte slice, the FromBytes impl(s) can be used.

Reads the T, possibly by parsing the stored bytes.

If self already stores a reference to a T, the T will just be copied out. If self stores a byte slice, the T will be parsed using its FromBytes implementation.

Returns an iterator over all Ts stored in self (which is just one T in this case).

This method exists to mirror its twin implemented for BytesOr<'a, [T]>.

Returns an iterator over all Ts stored in self.

The iterator will copy or decode Ts out of self.

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Formats the value using the given formatter. Read more

Performs the conversion.

Creates a BytesOr that stores bytes that can be decoded to a T.

This will check that bytes can indeed be decoded as a T using its FromBytes implementation, and returns an error if not.

The ByteReader will be advanced to point past the decoded T if the conversion succeeds.

Decode a Self from a byte slice, advancing bytes to point past the data that was read. Read more

Creates a BytesOr that stores bytes that can be decoded to a sequence of Ts.

This will check that bytes can indeed be decoded as a sequence of Ts, and returns an error if not. Note that this will read as many Ts as possible until the ByteReader is at its end of input. Any trailing data after the list of Ts will result in an error.

The ByteReader will be advanced to point past the decoded list of Ts if the conversion succeeds. In that case, it will be at EOF and no more data can be read.

Decode a Self from a byte slice, advancing bytes to point past the data that was read. Read more

Converts self to bytes and writes them into writer, advancing writer to point past the encoded value. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

Should always be Self

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

recently added

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.