pub trait TryFromCtx<'a, Ctx: Copy = (), This: ?Sized = [u8]>where
Self: 'a + Sized,{
type Error;
// Required method
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<&dyn 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);
Required Associated Types§
Required Methods§
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.