Module scroll::ctx [] [src]

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

Discussion

Let us postulate that there is a deep relationship between trying to make something from something else, and the generic concept of "parsing" or "reading".

Further let us suppose that central to this notion is also the importance of codified failure, in addition to a context in which this reading/parsing/from-ing occurs.

A context in this case is a set of values, preconditions, etc., which make the parsing meaningful for a particular type of input.

For example, to make this more concrete, when parsing an array of bytes, for a concrete numeric type, say u32, we might be interested in parsing this value at a given offset in a "big endian" byte order. Consequently, we might say our context is a 2-tuple, (offset, endianness).

Another example might be parsing a &str from a stream of bytes, which would require both an offset and a size. Still another might be parsing a list of ELF dynamic table entries from a byte array - which requires both something called a "load bias" and an array of program headers maybe pointing to their location.

Scroll builds on this idea by providing a generic context as a parameter to conversion traits (the parsing Ctx, akin to a "contextual continuation"), which is typically sufficient to model a large amount of data constructs using this single conversion trait, but with different Ctx implementations. In particular, parsing a u64, a leb128, a byte, a custom datatype, can all be modelled using a single trait - TryFromCtx<Ctx, This, Error = E>. What this enables is a single method for parsing disparate datatypes out of a given type, with a given context - without re-implementing the reader functions, and all done at compile time, without runtime dispatch!

Consequently, instead of "hand specializing" function traits by appending pread_<type>, almost all of the complexity of Pread and its sister trait Gread can be collapsed into two methods (pread_with and pread_slice).

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, using the convention (usize, YourCtx), you will automatically get access to calling pread_with::<YourDatatype> on arrays of bytes.

use scroll::{self, ctx, Pread, BE};
struct Data<'a> {
  name: &'a str,
  id: u32,
}

// we could use a `(usize, endian::Scroll)` if we wanted
#[derive(Debug, Clone, Copy, Default)]
struct DataCtx { pub size: usize, pub endian: scroll::Endian }

impl<'a> ctx::TryFromCtx<'a, (usize, DataCtx)> for Data<'a> {
  type Error = scroll::Error;
  fn try_from_ctx (src: &'a [u8], (offset, DataCtx {size, endian}): (usize, DataCtx))
    -> Result<Self, Self::Error> {
    let name = src.pread_slice::<str>(offset, size)?;
    let id = src.pread_with(offset+size, endian)?;
    Ok(Data { name: name, id: id })
  }
}

let bytes = scroll::Buffer::new(b"UserName\x01\x02\x03\x04");
let data = bytes.pread_with::<Data>(0, DataCtx { size: 8, endian: BE }).unwrap();
assert_eq!(data.id, 0x01020304);
assert_eq!(data.name.to_string(), "UserName".to_string());

Structs

StrCtx

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

Constants

CTX

Convenience constant for the default parsing context

NULL

A C-style, null terminator based delimiter for a StrCtx

RET

A newline-based delimiter for a StrCtx

SPACE

A space-based delimiter for a StrCtx

TAB

A tab-based delimiter for a StrCtx

Traits

FromCtx

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

IntoCtx

Writes Self into This using the context Ctx

RefFrom
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

TryRefFromCtx

Tries to read a reference to Self from This using the context Ctx

TryRefIntoCtx

Tries to write a reference to Self into This using the context Ctx

Type Definitions

DefaultCtx

The default parsing context; use this when the context isn't important for your datatype