[][src]Crate sum_error

Here we present a library for convinient summing already defined unique Errors. We provide a derive macros that can be applied towards a enum of variants each containing single unnamed field of type that implements Error trait.

To provide more details, deriving from SumError will implement Debug, Display, Error and From traits using contained errors.

Examples

The macros was designed to work in pair with Try paradigm. It is often tiring when different called methods return Results with different Error types. In order to easily combinate and store them one may use SumError derive macros to create a summing error type and automatically convert all the possible errors to it and write all the Try calls without spending spacetime on converting errors.

Here goes a simple example.

use std::fs::File;
use std::rc::Rc;
use sprite::Sprite;
use piston_window::Texture;
use image::gif::Decoder;
use image::AnimationDecoder;
use piston_window::{TextureContext, TextureSettings};
use sum_error::*;

/// Load a gif sprite.
pub fn load<F: gfx::Factory<R>,
            R: gfx::Resources,
            C: gfx::CommandBuffer<R>>(ctx: &mut TextureContext<F, R, C>)
                -> Result<Vec<Sprite<Texture<R>>>, CombineError> {
    let file = File::open("file.gif")?;
    let decoder = Decoder::new(file)?;
    let frames = decoder.into_frames().collect_frames()?;
    frames.iter()
        .map(|frame| {
            Texture::from_image(ctx, frame.buffer(), &TextureSettings::new())
                .map(Rc::new)
                .map(Sprite::from_texture)
                .map_err(|e| e.into())
        }).collect()
}

#[derive(SumError)]
pub enum CombineError {
    FileError(std::io::Error),
    ImageError(image::ImageError),
    GfxError(gfx_texture::Error),
}

Generated Code

To provide simplest illustration of the derive macros work let us discuss the following peace of code.

#[derive(SumError)]
enum A {
    A(std::io::Error)
}

In order to check in the compile time that contained types implemet Error trait we generate this code.

struct ___AssertNameA
where
   std::io::Error: std::error::Error;

After that given types auto implements Debug and Display traits.

impl std::fmt::Debug for A {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            A::A(error) => write!("{:?}", error),
        }
    }
}

impl std::fmt::Display for A {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            A::A(error) => write!("{}", error),
        }
    }
}

The following generated code is an example of default Error trait implementation.

impl std::error::Error for A {
    fn description(&self) -> &str {
        match self {
            A::A(error) => error.description(),
        }
    }
    fn cause(&self) -> Option<&dyn std::error::Error> {
        match self {
            A::A(error) => Some(error),
        }
    }
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            A::A(error) => Some(error),
        }
    }
}

The last generated auto trait is From.

impl From<std::io::Error> for A {
    fn from(error: std::io::Error) -> Self {
        A::A(error)
    }
}

Derive Macros

SumError

The whole point. Refer to the whole crate desription for a guide.