app 0.6.5

A easy-to-use command-line-parser.
Documentation
#[derive(Debug)]
struct ElesRef<'e, T: 'e> {
    raw: &'e [T],
    start: usize,
    end: usize,
    is_reverse: bool,
}
impl<'e, T: Clone + std::fmt::Debug> ElesRef<'e, T> {
    fn new<'l: 'e>(slice: &'l [T]) -> Self {
        ElesRef {
            raw: slice,
            start: 0,
            end: slice.len(),
            is_reverse: false,
        }
    }
    fn reverse(&mut self) {
        self.is_reverse = !self.is_reverse;
    }
    #[inline]    
    fn as_slice(&self) -> &[T] {
        &self.raw[self.start..self.end]
    }
    #[inline]    
    fn slice<RG: IntoRg>(&self, rg: RG) -> &[T] {
        let (rg0, rg1) = rg.into().into_range(self.start, self.end, self.is_reverse);
        self.check(&rg0, &rg1);
        &self.raw[rg0..rg1]
    }
    fn cut<RG: IntoRg>(&mut self, rg: RG) {
        let (rg0, rg1) = rg.into().into_range(self.start, self.end, self.is_reverse);
        self.check(&rg0, &rg1);
        self.start = rg0;
        self.end = rg1;
    }
    #[inline]
    fn check(&self, rg0: &usize, rg1: &usize) {
        if rg0 > rg1 {
            panic!("slice index starts at {} but ends at {}", rg0, rg1);
        }
        if *rg0 > self.raw.len() {
            panic!("slice index starts at {} but ends at {}",
                   rg0,
                   self.raw.len());
        }
        if *rg1 > self.raw.len() {
            panic!("index {} out of range for slice of length {}",
                   rg1,
                   self.raw.len());
        }
    }
    fn is_empty(&self) -> bool {
        self.start == self.end
    }
    fn len(&self) -> usize {
        self.end - self.start
    }
}
impl<'e, T: Clone + std::fmt::Debug> std::fmt::Display for ElesRef<'e, T> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:?}", self.as_slice())
    }
}

use std::ops::{Range, RangeFrom, RangeTo, RangeFull};
#[derive(Debug)]
enum Rg {
    FT(Range<usize>),
    F(RangeFrom<usize>),
    T(RangeTo<usize>),
    Full,
}
impl Rg {
    fn into_range(self, start: usize, end: usize, is_reverse: bool) -> (usize, usize) {
        if is_reverse {
            match self {
                Rg::FT(ft) => (end - ft.end, end - ft.start),
                Rg::F(f) => (start, end - f.start),
                Rg::T(t) => (end - t.end, end),
                Rg::Full => (start, end),
            }
        } else {
            match self {
                Rg::FT(ft) => (ft.start + start, ft.end + start),
                Rg::F(f) => (f.start + start, end),
                Rg::T(t) => (start, start + t.end),
                Rg::Full => (start, end),
            }
        }
    }
}
trait IntoRg {
    fn into(self) -> Rg;
}

impl IntoRg for Range<usize> {
    fn into(self) -> Rg {
        Rg::FT(self)
    }
}
impl IntoRg for RangeFrom<usize> {
    fn into(self) -> Rg {
        Rg::F(self)
    }
}
impl IntoRg for RangeTo<usize> {
    fn into(self) -> Rg {
        Rg::T(self)
    }
}
impl IntoRg for RangeFull {
    fn into(self) -> Rg {
        Rg::Full
    }
}