[][src]Module scroll::ctx

Generic context-aware conversion traits, for automatic downstream extension of Pread, et. al

Discussion

Implementors of TryFromCtx automatically grant any client user of pread, pwrite, gread, gwrite the ability to parse their structure out of the source it has been implemented for, typically &[u8].

The implementor only needs to specify the error type, and the type of their size, and then implement the parsing/marshalling logic given a byte sequence, starting at the offset pread, et. al was called at, with the context you have implemented it for.

Returning the size allows dynamic content (e.g., &strs) to be parsed alongside fixed size content (e.g., u64). The parsing context is any information you the implementor need to correctly parse out your datatype - this could be the endianness of the type, more offsets, or other complex data. The only requirement is that your Ctx be Copy, and hence encourages lightweight contexts (but this isn't required of course).

Example

Suppose we have a datatype and we want to specify how to parse or serialize this datatype out of some arbitrary byte buffer. In order to do this, we need to provide a TryFromCtx impl for our datatype. In particular, if we do this for the [u8] target, with a "parsing contex", YourCtx, you will automatically get access to calling pread_with::<YourDatatype>(offset, your_ctx) on arrays of bytes.

In the example below, we implement TryFromCtx using the Endian parsing context provided by scroll, which is used to specifying the endianness at which numbers should be parsed, but you could provide anything, as long as it implements Copy.

use scroll::{self, ctx, Endian, Pread, BE};

struct Data<'a> {
  name: &'a str,
  id: u32,
}

impl<'a> ctx::TryFromCtx<'a, Endian> for Data<'a> {
  type Error = scroll::Error;
  fn try_from_ctx (src: &'a [u8], ctx: Endian)
    -> Result<(Self, usize), Self::Error> {
    let name = src.pread::<&str>(0)?;
    let id = src.pread_with(name.len() + 1, ctx)?;
    Ok((Data { name: name, id: id }, name.len() + 1 + 4))
  }
}

let bytes = b"UserName\x00\x01\x02\x03\x04";
let data = bytes.pread_with::<Data>(0, BE).unwrap();
assert_eq!(data.id, 0x01020304);
assert_eq!(data.name.to_string(), "UserName".to_string());

Enums

StrCtx

The parsing context for converting a byte sequence to a &str

Constants

NULL

A C-style, null terminator based delimiter

RET

A newline-based delimiter

SPACE

A space-based delimiter

TAB

A tab-based delimiter

Traits

FromCtx

Reads Self from This using the context Ctx; must not fail

IntoCtx

Writes Self into This using the context Ctx

MeasureWith

A trait for measuring how large something is; for a byte sequence, it will be its length.

SizeWith

Gets the size of Self with a Ctx, and in Self::Units. Implementors can then call Gread related functions

TryFromCtx

Tries to read Self from This using the context Ctx

TryIntoCtx

Tries to write Self into This using the context Ctx