Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::error::Error;
- use std::fmt;
- use std::str;
- type DynError = dyn Error + Send + Sync + 'static;
- #[derive(Debug)]
- struct AggErr {
- err: Vec<Box<DynError>>,
- }
- impl AggErr {
- fn push<E: Into<Box<DynError>>>(&mut self, err: E) {
- self.err.push(err.into())
- }
- }
- impl Error for AggErr {}
- impl fmt::Display for AggErr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{} errors:\n", self.err.len())?;
- for e in &self.err {
- write!(f, " {}\n", e)?;
- }
- Ok(())
- }
- }
- // NOTE: Would probably require `Try` operator support to also allow `Some` and
- // `None`.
- macro_rules! validated_inner {
- (
- [$($pre:tt)*] [$($post:tt)*] $err:ident =>
- let+ $p:pat = $e:expr; $($rest:tt)*
- ) => {
- validated_inner!(
- [
- $($pre)*
- let x = match $e {
- Ok(x) => Some(x),
- Err(e) => {
- $err.push(e);
- None
- }
- };
- ]
- [
- $($post)*
- let $p = match x {
- Some(x) => x,
- None => break Err($err),
- };
- ]
- $err => $($rest)*
- )
- };
- (
- [$($pre:tt)*] [$($post:tt)*] $err:ident =>
- $e:expr
- ) => {
- loop {
- let mut $err = AggErr { err: Vec::new() };
- $($pre)*
- $($post)*
- break Ok($e);
- }
- };
- }
- macro_rules! validated {
- (let+ $($t:tt)*) => {
- validated_inner!([] [] err => let+ $($t)*)
- }
- }
- fn main() {
- let res: Result<String, AggErr> = validated! {
- let+ x = str::from_utf8(b"yay");
- let+ y = str::from_utf8(b"wo\xffw");
- let+ z = str::from_utf8(b"\xff\xff");
- format!("{}, {}, {}", x, y, z)
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement