#[macro_use]
extern crate log;
use std::fmt;
use std::iter::FromIterator;
use self::WResult::*;
#[must_use]
pub enum WResult<T, W, E> {
WOk(T, Vec<W>),
WErr(E),
}
impl<T, W, E> WResult<T, W, E> {
pub fn is_ok(&self) -> bool {
match *self {
WOk(_, _) => true,
WErr(_) => false,
}
}
pub fn is_err(&self) -> bool {
match *self {
WOk(_, _) => true,
WErr(_) => false,
}
}
pub fn is_warn_or_err(&self) -> bool {
match *self {
WOk(_, ref ws) => ws.len() > 0,
WErr(_) => true,
}
}
pub fn ok_discard(self) -> Option<T> {
match self {
WOk(t, _) => Some(t),
WErr(_) => None,
}
}
pub fn err(self) -> Option<E> {
match self {
WOk(_, _) => None,
WErr(e) => Some(e),
}
}
pub fn ok_werr(self) -> Option<T> {
match self {
WOk(t, ws) => match ws.len() {
0 => Some(t),
_ => None,
},
WErr(_) => None,
}
}
pub fn map<U, F>(self, op: F) -> WResult<U, W, E>
where F: FnOnce(T) -> U
{
match self {
WOk(t, ws) => WOk(op(t), ws),
WErr(e) => WErr(e),
}
}
pub fn map_err<U, F>(self, op: F) -> WResult<T, W, U>
where F: FnOnce(E) -> U
{
match self {
WOk(t, ws) => WOk(t, ws),
WErr(e) => WErr(op(e)),
}
}
pub fn map_warnings<U, F>(self, op: F) -> WResult<T, U, E>
where F: FnMut(W) -> U
{
match self {
WOk(t, ws) => WOk(t, ws.into_iter().map(op).collect()),
WErr(e) => WErr(e),
}
}
pub fn and<U>(self, res: WResult<U, W, E>) -> WResult<U, W, E> {
match self {
WOk(_, mut ws0) => match res {
WOk(t, ws1) => {
ws0.extend(ws1);
WOk(t, ws0)
}
WErr(e) => WErr(e)
},
WErr(e) => WErr(e),
}
}
pub fn and_then<U, V, F>(self, op: F) -> WResult<U, V, E>
where F: FnOnce(T, Vec<W>) -> WResult<U, V, E>
{
match self {
WOk(t, ws) => op(t, ws),
WErr(e) => WErr(e),
}
}
pub fn or<U>(self, res: WResult<T, W, U>) -> WResult<T, W, U> {
match self {
WOk(t, ws) => WOk(t, ws),
WErr(_) => res,
}
}
pub fn or_else<U, F>(self, op: F) -> WResult<T, W, F>
where F: FnOnce(E) -> WResult<T, W, F>
{
match self {
WOk(t, ws) => WOk(t, ws),
WErr(e) => op(e),
}
}
pub fn result_discard(self) -> Result<T, E> {
match self {
WOk(t, _) => Ok(t),
WErr(e) => Err(e),
}
}
pub fn result_werr_res(self) -> Result<T, Result<W, E>> {
match self {
WOk(t, mut ws) => {
ws.truncate(1);
match ws.pop() {
Some(w) => Err(Ok(w)),
None => Ok(t),
}
}
WErr(e) => Err(Err(e)),
}
}
pub fn unwrap_discard_or(self, optb: T) -> T {
match self {
WOk(t, _) => t,
WErr(_) => optb,
}
}
pub fn unwrap_or_werr(self, optb: T) -> T {
match self {
WOk(t, ws) => match ws.len() {
0 => optb,
_ => t,
},
WErr(_) => optb,
}
}
pub fn unwrap_discard_or_else<F>(self, op: F) -> T
where F: FnOnce(E) -> T
{
match self {
WOk(t, _) => t,
WErr(e) => op(e),
}
}
}
impl<T, E> WResult<T, E, E> {
pub fn err_werr(self) -> Option<E> {
match self {
WOk(_, mut ws) => {
ws.truncate(1);
ws.pop()
},
WErr(e) => Some(e),
}
}
pub fn result_werr(self) -> Result<T, E> {
match self {
WOk(t, mut ws) => {
ws.truncate(1);
match ws.pop() {
Some(w) => Err(w),
None => Ok(t),
}
},
WErr(e) => Err(e),
}
}
pub fn unwrap_or_else_werr<F>(self, op: F) -> T
where F: FnOnce(E) -> T
{
match self {
WOk(t, mut ws) => {
ws.truncate(1);
match ws.pop() {
Some(w) => op(w),
None => t,
}
},
WErr(e) => op(e),
}
}
}
impl<T, W, E> WResult<T, W, E>
where W: fmt::Display
{
pub fn ok_log(self) -> Option<T> {
match self {
WOk(t, ws) => {
for w in ws {
warn!("{}", w);
}
Some(t)
},
WErr(_) => None,
}
}
pub fn result_log(self) -> Result<T, E> {
match self {
WOk(t, ws) => {
for w in ws {
warn!("{}", w);
}
Ok(t)
}
WErr(e) => Err(e),
}
}
pub fn unwrap_log_or(self, optb: T) -> T {
match self {
WOk(t, ws) => {
for w in ws {
warn!("{}", w);
}
t
},
WErr(_) => optb,
}
}
pub fn unwrap_log_or_else<F>(self, op: F) -> T
where F: FnOnce(E) -> T
{
match self {
WOk(t, ws) => {
for w in ws {
warn!("{}", w);
}
t
},
WErr(e) => op(e),
}
}
}
impl<T, W, E> From<Result<T, E>> for WResult<T, W, E> {
fn from(val: Result<T, E>) -> WResult<T, W, E> {
match val {
Ok(t) => WOk(t, Vec::new()),
Err(e) => WErr(e),
}
}
}
impl<A, T, W, E> FromIterator<WResult<A, W, E>> for WResult<T, W, E>
where T: FromIterator<A>
{
fn from_iter<I>(iter: I) -> Self
where I: IntoIterator<Item=WResult<A, W, E>>
{
struct Adapter<Iter, W, E> {
iter: Iter,
warnings: Vec<W>,
err: Option<E>,
}
impl<T, W, E, Iter: Iterator<Item=WResult<T, W, E>>> Iterator for Adapter<Iter, W, E> {
type Item = T;
fn next(&mut self) -> Option<T> {
match self.iter.next() {
Some(WOk(t, ws)) => {
self.warnings.extend(ws);
Some(t)
},
Some(WErr(e)) => {
self.err = Some(e);
None
},
None => None,
}
}
}
let mut adapter = Adapter { iter: iter.into_iter(), warnings: Vec::new(), err: None };
let t: T = FromIterator::from_iter(adapter.by_ref());
match adapter.err {
Some(e) => WErr(e),
None => WOk(t, adapter.warnings),
}
}
}