Trait scroll::ctx::TryFromCtx
source · [−]pub trait TryFromCtx<'a, Ctx: Copy = (), This: ?Sized = [u8]> where
Self: 'a + Sized, {
type Error;
fn try_from_ctx(
from: &'a This,
ctx: Ctx
) -> Result<(Self, usize), Self::Error>;
}
Expand description
Tries to read Self
from This
using the context Ctx
Implementing Your Own Reader
If you want to implement your own reader for a type Foo
from some kind of buffer (say
[u8]
), then you need to implement this trait
use scroll::{self, ctx, Pread};
#[derive(Debug, PartialEq, Eq)]
pub struct Foo(u16);
impl<'a> ctx::TryFromCtx<'a, scroll::Endian> for Foo {
type Error = scroll::Error;
fn try_from_ctx(this: &'a [u8], le: scroll::Endian) -> Result<(Self, usize), Self::Error> {
if this.len() < 2 { return Err((scroll::Error::Custom("whatever".to_string())).into()) }
let n = this.pread_with(0, le)?;
Ok((Foo(n), 2))
}
}
let bytes: [u8; 4] = [0xde, 0xad, 0, 0];
let foo = bytes.pread_with::<Foo>(0, scroll::LE).unwrap();
assert_eq!(Foo(0xadde), foo);
let foo2 = bytes.pread_with::<Foo>(0, scroll::BE).unwrap();
assert_eq!(Foo(0xdeadu16), foo2);
Advanced: Using Your Own Error in TryFromCtx
use scroll::{self, ctx, Pread};
use std::error;
use std::fmt::{self, Display};
// make some kind of normal error which also can transformed from a scroll error
#[derive(Debug)]
pub struct ExternalError {}
impl Display for ExternalError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "ExternalError")
}
}
impl error::Error for ExternalError {
fn description(&self) -> &str {
"ExternalError"
}
fn cause(&self) -> Option<&error::Error> { None}
}
impl From<scroll::Error> for ExternalError {
fn from(err: scroll::Error) -> Self {
match err {
_ => ExternalError{},
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct Foo(u16);
impl<'a> ctx::TryFromCtx<'a, scroll::Endian> for Foo {
type Error = ExternalError;
fn try_from_ctx(this: &'a [u8], le: scroll::Endian) -> Result<(Self, usize), Self::Error> {
if this.len() <= 2 { return Err((ExternalError {}).into()) }
let offset = &mut 0;
let n = this.gread_with(offset, le)?;
Ok((Foo(n), *offset))
}
}
let bytes: [u8; 4] = [0xde, 0xad, 0, 0];
let foo: Result<Foo, ExternalError> = bytes.pread(0);