pub trait Readable: Sized {
// Required method
fn take_from(b: &mut Reader<'_>) -> Result<Self>;
}
Expand description
Trait for an object that can be extracted from a Reader.
Implement this trait in order to make an object that can (maybe) be decoded from a reader. Most code won’t need to call this directly, but will instead use it implicitly via the Reader::extract() method.
§Correctness (determinism), and error handling
The take_from
method should produce consistent and deterministic results.
If take_from
returns Ok
, consuming some data,
a future call with a reader which has that consumed data as a prefix,
must consume the same data and succeed with an equivalent value.
If take_from
returns Err
, it is allowed to have consumed
none, any, or all, of the Reader
.
If take_from
returns Error::Incomplete
:
then calling take_from
again on a similar Reader
(ie, where the old reader is a prefix of the new, or vice versa)
must do one of the following:
- Succeed, consuming at least as many bytes as
were available in the previous reader plus
deficit
. - Return
Error::Incomplete
with a consistent value ofdeficit
.
If take_from
fails another way with some reader, it must fail the same way
with all other readers which have that reader as a prefix.
(Here, “prefix” and “length” relate only to the remaining bytes in the Reader
,
irrespective of the length or value of any bytes which were previously consumed.)
(tor-socksproto relies on these properties.)
Specific implementations may provide stronger guarantees.
§Example
use tor_bytes::{Readable,Reader,Result};
#[derive(Debug, Eq, PartialEq)]
struct Message {
flags: u32,
cmd: u8
}
impl Readable for Message {
fn take_from(r: &mut Reader<'_>) -> Result<Self> {
// A "Message" is encoded as flags, then command.
let flags = r.take_u32()?;
let cmd = r.take_u8()?;
Ok(Message{ flags, cmd })
}
}
let encoded = [0x00, 0x00, 0x00, 0x43, 0x07 ];
let mut reader = Reader::from_slice(&encoded);
let m: Message = reader.extract()?;
assert_eq!(m, Message { flags: 0x43, cmd: 0x07 });
reader.should_be_exhausted()?; // make sure there are no bytes left over
Required Methods§
Sourcefn take_from(b: &mut Reader<'_>) -> Result<Self>
fn take_from(b: &mut Reader<'_>) -> Result<Self>
Try to extract an object of this type from a Reader.
Implementations should generally try to be efficient: this is not the right place to check signatures or perform expensive operations. If you have an object that must not be used until it is finally validated, consider making this function return a wrapped type that can be unwrapped later on once it gets checked.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementations on Foreign Types§
Source§impl Readable for Ed25519Identity
Available on crate feature tor-llcrypto
only.
impl Readable for Ed25519Identity
tor-llcrypto
only.Source§impl Readable for RsaIdentity
Available on crate feature tor-llcrypto
only.
impl Readable for RsaIdentity
tor-llcrypto
only.Source§impl<const N: usize> Readable for CtByteArray<N>
Available on crate feature tor-llcrypto
only.
impl<const N: usize> Readable for CtByteArray<N>
tor-llcrypto
only.