# `treeerror`
This crate is intended to provide some convenience enums for mapping enums from one type to
another. This is intended to work with compile time mapping between sets of enums as well
as shortcutting `From` implementations.
This is how to use wrapped the crate:
```rs
#![feature(more_qualified_paths)]
treeerror::treeerror! {
#[derive(PartialEq, Debug)]
Root {
#[derive(PartialEq, Debug)]
Child0 {
#[derive(PartialEq, Debug)]
Child0_0 {
#[derive(PartialEq, Debug)]
Child0_0_0(&'static str),
},
#[derive(PartialEq, Debug)]
Child0_1 @unit,
Child0_2 @flatunit,
},
#[derive(PartialEq, Debug)]
Child1 {
#[derive(PartialEq, Debug)]
Child1_0 @unit,
#[derive(PartialEq, Debug)]
Child1_1 @unit,
Child1_2(u64),
Child1_3 @skipfrom (&'static str)
},
},
#[derive(PartialEq, Debug)]
SiblingRoot {
SiblingChild0(String),
SiblingChild1(&'static str)
}
}
const MSG: &'static str = "hello from below";
fn root_error() -> Result<(), Root> {
Err(MSG)?;
unreachable!("error should have returned earlier");
}
assert_eq!(
Err(Root::Child0(Child0::Child0_0(RenamedChild0_0::Child0_0_0(MSG)))),
root_error()
);
```
We also provide some utilities for generating simple `From` implementations.
```rs
#![feature(more_qualified_paths)]
use treeerror::{from_many, from};
#[derive(PartialEq, Debug)]
enum Root {
A(A),
}
#[derive(PartialEq, Debug)]
enum A {
Alpha(Alpha),
}
#[derive(PartialEq, Debug)]
enum Alpha {
One(One),
}
#[derive(PartialEq, Debug)]
enum One {
Child(Child),
}
#[derive(PartialEq, Debug)]
struct Child;
from_many!(Root: A, A, Alpha, One, Child);
from_many!(A: Alpha, Alpha, One, Child);
from_many!(Alpha: One, One, Child);
from!(One = Child(Child));
const MSG: &'static str = "hello from below";
fn root_error() -> Result<(), Root> {
Err(Child)?;
unreachable!("error should have returned earlier");
}
assert_eq!(
Err(Root::A(A::Alpha(Alpha::One(One::Child(Child))))),
root_error()
);
```
You'll notice that there are many `from_many` call here -- automatically generating this
tree is not yet complete and in progress.
We can also handle "flatter" error structures where, instead of nesting these enums by
wrapping them, we destructure the internal values instead.
There are several ways to use this as well, but here's the most basic use case.
```rs
#![feature(more_qualified_paths)]
use treeerror::map_enum;
#[derive(PartialEq, Eq, Debug)]
pub enum ParentError {
Child(&'static str),
}
#[derive(PartialEq, Eq, Debug)]
pub enum ChildError {
SomeError(&'static str),
}
map_enum!(ChildError > ParentError {
SomeError > Child
});
const MSG: &'static str = "hello there";
fn parent_error() -> Result<(), ParentError> {
Err(ChildError::SomeError(MSG))?;
unreachable!("error should have returned earlier");
}
assert_eq!(
Err(ParentError::Child(MSG)),
parent_error(),
);
```
Future work potentially includes a proc macro rewrite to enable better error messages
and configurability.
# Some old notes
One Ring to rule them all
```rs
treeerror! {
Mordor {
Hobbit {
Peregrin @unit,
Meriadoc @unit,
Samwise @unit,
Frodo @unit,
Bilbo @unit,
Gollum @unit,
},
Elf {
Galadriel @unit,
Elrond @unit,
Legolas @unit,
Celebrimbor @unit,
Arwen @unit,
},
Wizard {
Saruman @unit,
Gandalf @unit,
Radagast @unit,
},
Ents {
@unit SorryIDoNotRememberYourName,
},
Man {
Theoden @unit,
Denethor @unit,
Eowyn @unit,
Faramir @unit,
Isildur @unit,
Elendil @unit,
Aragorn @unit,
},
Orc @unit,
Shelob @unit,
GenericPerson @unit,
Gollum @unit,
}
}
```
One Ring to find them
```rs
// This and the rest do work though!
map_enum! {
MiddleEarth > Mordor {
Shire = Hobbit,
Lothlorien = Elf,
Rohan = Man,
Gondor = Man,
Wizard = Wizard,
Gollum = Gollum,