Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::error::Error;
- use std::fmt;
- use std::str;
- use std::mem::MaybeUninit;
- type DynError = dyn Error + Send + Sync + 'static;
- #[derive(Debug, Default)]
- pub struct AggErr {
- errors: Vec<(&'static str, Box<DynError>)>,
- }
- impl AggErr {
- pub fn new() -> Self {
- Default::default()
- }
- pub fn len(&self) -> usize {
- self.errors.len()
- }
- pub fn is_empty(&self) -> bool {
- self.errors.is_empty()
- }
- #[doc(hidden)]
- pub fn add_result<T, E: Into<Box<DynError>>>(
- &mut self,
- binding: &'static str,
- r: Result<T, E>,
- ) -> MaybeUninit<T> {
- match r {
- Ok(x) => MaybeUninit::new(x),
- Err(e) => {
- self.errors.push((binding, e.into()));
- MaybeUninit::uninit()
- }
- }
- }
- }
- impl Error for AggErr {}
- impl fmt::Display for AggErr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{} errors:\n", self.len())?;
- for (b, e) in &self.errors {
- write!(f, " {}: {}\n", b, e)?;
- }
- Ok(())
- }
- }
- macro_rules! validated {
- (let+ $($t:tt)*) => {
- validated!([] [] err => let+ $($t)*)
- };
- (
- [$($pre:tt)*] [$($post:tt)*] $err:ident =>
- let+ $p:pat = $e:expr; $($rest:tt)*
- ) => {
- validated!(
- [
- $($pre)*
- let x = $err.add_result(stringify!($p), $e);
- ]
- [
- $($post)*
- let $p = unsafe { x.assume_init() };
- ]
- $err => $($rest)*
- )
- };
- (
- [$($pre:tt)*] [$($post:tt)*] $err:ident =>
- $e:expr
- ) => {
- {
- let mut $err = $crate::AggErr::new();
- $($pre)*
- if $err.is_empty() {
- $($post)*
- Ok($e)
- } else {
- Err($err)
- }
- }
- };
- }
- #[derive(Debug, PartialEq)]
- struct Validated<'a> {
- a: &'a str,
- b: &'a str,
- c: &'a str,
- }
- fn main() {
- let res: Result<String, AggErr> = validated! {
- let+ a = str::from_utf8(b"yay");
- let+ b = str::from_utf8(b"wo\xffw");
- let+ c = str::from_utf8(b"\xff\xff");
- format!("{}, {}, {}", a, b, c)
- };
- eprintln!("{:?}", res);
- let res: Result<Validated, AggErr> = validated! {
- let+ a = str::from_utf8(b"yay");
- let+ b = str::from_utf8(b"wow");
- let+ c = str::from_utf8(b"");
- Validated { a, b, c }
- };
- eprintln!("{:?}", res);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement