mybound 0.1.2

tools for RangeBounds
Documentation
use std::ops::{Bound, RangeBounds};
use std::pin::Pin;

pub fn is_included<T>(bound: &Bound<T>) -> bool {
    match bound {
        Bound::Included(_) => true,
        _ => false,
    }
}
pub fn is_excluded<T>(bound: &Bound<T>) -> bool {
    match bound {
        Bound::Excluded(_) => true,
        _ => false,
    }
}
pub fn is_unbounded<T>(bound: &Bound<T>) -> bool {
    match bound {
        Bound::Unbounded => true,
        _ => false,
    }
}
pub fn map<T, U, F: FnOnce(T) -> U>(bound: Bound<T>, f: F) -> Bound<U> {
    match bound {
        Bound::Excluded(b) => Bound::Excluded(f(b)),
        Bound::Included(b) => Bound::Included(f(b)),
        Bound::Unbounded => Bound::Unbounded,
    }
}
pub fn as_ref<U: ?Sized, T: AsRef<U>>(bound: &Bound<T>) -> Bound<&U> {
    match bound {
        Bound::Excluded(b) => Bound::Excluded(b.as_ref()),
        Bound::Included(b) => Bound::Included(b.as_ref()),
        Bound::Unbounded => Bound::Unbounded,
    }
}
pub fn as_mut<U: ?Sized, T: AsMut<U>>(bound: &mut Bound<T>) -> Bound<&mut U> {
    match bound {
        Bound::Excluded(b) => Bound::Excluded(b.as_mut()),
        Bound::Included(b) => Bound::Included(b.as_mut()),
        Bound::Unbounded => Bound::Unbounded,
    }
}
pub fn as_pin_ref<'a, U: ?Sized, T: AsRef<U>>(bound: Pin<&'a Bound<T>>) -> Bound<Pin<&'a U>> {
    unsafe { map(as_ref(Pin::get_ref(bound)), |x| Pin::new_unchecked(x)) }
}
pub fn as_pin_mut<'a, U: ?Sized, T: AsMut<U>>(
    bound: Pin<&'a mut Bound<T>>,
) -> Bound<Pin<&'a mut U>> {
    unsafe {
        map(as_mut(Pin::get_unchecked_mut(bound)), |x| {
            Pin::new_unchecked(x)
        })
    }
}
pub fn unwrap<T>(bound: Bound<T>) -> T {
    expect(
        bound,
        "called `rangetools::unwrap()` on a `Unbounded` value",
    )
}
pub fn unwrap_or<T>(bound: Bound<T>, def: T) -> T {
    match bound {
        Bound::Excluded(b) => b,
        Bound::Included(b) => b,
        Bound::Unbounded => def,
    }
}
pub fn unwrap_or_else<T, F>(bound: Bound<T>, f: F) -> T
where
    F: FnOnce() -> T,
{
    match bound {
        Bound::Excluded(b) => b,
        Bound::Included(b) => b,
        Bound::Unbounded => f(),
    }
}
pub fn expect<T>(bound: Bound<T>, msg: &str) -> T {
    match bound {
        Bound::Excluded(b) => b,
        Bound::Included(b) => b,
        Bound::Unbounded => panic!("{}", msg),
    }
}
pub fn cloned<T: Clone>(bound: Bound<&T>) -> Bound<T> {
    map(bound, |t| t.clone())
}
pub fn cloned_mut<T: Clone>(bound: Bound<&mut T>) -> Bound<T> {
    map(bound, |t| t.clone())
}
pub fn copied<T: Copy>(bound: Bound<&T>) -> Bound<T> {
    map(bound, |&t| t)
}
pub fn copied_mut<T: Copy>(bound: Bound<&mut T>) -> Bound<T> {
    map(bound, |&mut t| t)
}

pub struct MyBound<T>(Bound<T>);
impl<T> MyBound<T> {
    pub fn is_included(&self) -> bool {
        is_included(&self.0)
    }
    pub fn is_excluded(&self) -> bool {
        is_excluded(&self.0)
    }
    pub fn is_unbounded(&self) -> bool {
        is_unbounded(&self.0)
    }
    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> MyBound<U> {
        MyBound(map(self.0, f))
    }
    pub fn as_ref<U: ?Sized>(&self) -> MyBound<&U>
    where
        T: AsRef<U>,
    {
        MyBound(as_ref(&self.0))
    }
    pub fn as_mut<U: ?Sized>(&mut self) -> MyBound<&mut U>
    where
        T: AsMut<U>,
    {
        MyBound(as_mut(&mut self.0))
    }
    pub fn as_pin_ref<'a, U: ?Sized>(self: Pin<&'a MyBound<T>>) -> MyBound<Pin<&'a U>>
    where
        T: AsRef<U>,
    {
        MyBound(unsafe { map(as_ref(&Pin::get_ref(self).0), |x| Pin::new_unchecked(x)) })
    }
    pub fn as_pin_mut<'a, U: ?Sized>(self: Pin<&'a mut MyBound<T>>) -> MyBound<Pin<&'a mut U>>
    where
        T: AsMut<U>,
    {
        MyBound(unsafe {
            map(as_mut(&mut Pin::get_unchecked_mut(self).0), |x| {
                Pin::new_unchecked(x)
            })
        })
    }
    pub fn unwrap(self) -> T {
        unwrap(self.0)
    }
    pub fn unwrap_or(self, def: T) -> T {
        unwrap_or(self.0, def)
    }
    pub fn unwrap_or_else<F>(self, f: F) -> T
    where
        F: FnOnce() -> T,
    {
        unwrap_or_else(self.0, f)
    }
    pub fn expect(self, msg: &str) -> T {
        expect(self.0, msg)
    }
}
impl<'a, T> MyBound<&'a T> {
    pub fn cloned(self) -> MyBound<T>
    where
        T: Clone,
    {
        MyBound(cloned(self.0))
    }
    pub fn copied(self) -> MyBound<T>
    where
        T: Copy,
    {
        MyBound(copied(self.0))
    }
}
impl<'a, T> MyBound<&'a mut T> {
    pub fn cloned(self) -> MyBound<T>
    where
        T: Clone,
    {
        MyBound(cloned_mut(self.0))
    }
    pub fn copied(self) -> MyBound<T>
    where
        T: Copy,
    {
        MyBound(copied_mut(self.0))
    }
}

pub trait MyRangeBounds<T: ?Sized>: RangeBounds<T> {
    fn start_bound(&self) -> MyBound<&T> {
        MyBound(RangeBounds::start_bound(self))
    }
    fn end_bound(&self) -> MyBound<&T> {
        MyBound(RangeBounds::end_bound(self))
    }
}
impl<T, U: RangeBounds<T>> MyRangeBounds<T> for U {}

impl<T> Into<Bound<T>> for MyBound<T> {
    fn into(self) -> Bound<T> {
        self.0
    }
}

impl<T> From<Bound<T>> for MyBound<T> {
    fn from(src: Bound<T>) -> MyBound<T> {
        MyBound(src)
    }
}

#[test]
fn test_as_ref() {
    let s: MyBound<String> = Bound::Included("abcd".to_owned()).into();
    let u: &[u8] = s.as_ref().unwrap();
    assert_eq!(u, b"abcd");
}