use core::convert::TryFrom; use dangerous::{error, BytesReader, Error, Expected, Input}; fn main() { println!("=== VALID PARSE ==="); let input = dangerous::input(b"foo"); let result: Result<_, Expected<'_>> = input.read_all(read_custom); println!("{:?}", result.unwrap()); println!("\n=== INVALID PARSE ==="); let input = dangerous::input(b"bar"); let error: Expected<'_> = input.read_all(read_custom).unwrap_err(); println!("{:#}", error); } #[derive(Debug)] pub struct Custom<'i>(&'i str); impl<'i> TryFrom> for Custom<'i> { type Error = ParseCustomError; fn try_from(s: dangerous::String<'i>) -> Result { if s.as_dangerous() == "foo" { Ok(Self(s.as_dangerous())) } else { Err(ParseCustomError) } } } pub struct ParseCustomError; impl<'i> error::External<'i> for ParseCustomError { fn push_backtrace(self, error: E) -> E where E: error::WithContext<'i>, { error.with_context(error::ExternalContext { operation: Some("read my custom type"), expected: Some("my custom type"), }) } } fn read_custom<'i, E>(r: &mut BytesReader<'i, E>) -> Result, E> where E: Error<'i>, { r.take_remaining_str()? .into_external("my custom type", Custom::try_from) }