mem-query 0.0.1

Relational algebra interface for Rust collections
use std::ops::{RangeBounds, Bound, Bound::*};
use std::collections::{BTreeMap,BTreeSet};

#[derive(Copy,Clone)]
pub enum VerifiedRange<T> {
    Empty,
    Exact(T),
    Range((Bound<T>, Bound<T>))
}

pub enum VerifiedRangeIter<EI, RI> {
    Empty,
    Exact(EI),
    Range(RI)
}

impl<EI, RI, Item> Iterator for VerifiedRangeIter<EI, RI>
    where EI: Iterator<Item = Item>, RI: Iterator<Item = Item> {
    type Item = Item;

    #[inline(always)]
    fn next(&mut self)->Option<Item> {
        match self {
            VerifiedRangeIter::Empty => None,
            VerifiedRangeIter::Exact(ref mut i) => i.next(),
            VerifiedRangeIter::Range(ref mut i) => i.next()
        }
    }
}

pub trait RangeExt<T> {
    fn into_verified(self)->VerifiedRange<T>;
}

impl<'a, T:'a + Ord> RangeExt<&'a T> for (Bound<&'a T>, Bound<&'a T>) {
    #[inline(always)]
    fn into_verified(self)->VerifiedRange<&'a T> {
        match self {
            (Included(lo), Included(hi)) if lo == hi => VerifiedRange::Exact(lo),
            (Included(lo), Included(hi)) if lo > hi => VerifiedRange::Empty,
            (Included(lo), Excluded(hi)) if lo >= hi => VerifiedRange::Empty,
            (Excluded(lo), Included(hi)) if lo >= hi => VerifiedRange::Empty,
            (Excluded(lo), Excluded(hi)) if lo >= hi => VerifiedRange::Empty,
            range => VerifiedRange::Range(range)
        }
    }
}

impl<'a, T: 'a + Ord> VerifiedRange<&'a T> {
    #[inline(always)]
    pub fn get_from_map<'b:'a,U>(self, map: &'b BTreeMap<T, U>)
    ->impl Iterator<Item = (&'b T, &'b U)> {
        use VerifiedRange::*;
        match self {
            Exact(x) => VerifiedRangeIter::Exact(
                map.get_key_value::<T>(x).into_iter()
            ),
            Empty => VerifiedRangeIter::Empty,
            Range(r) => VerifiedRangeIter::Range(
                map.range::<T,_>(r)
            )
        }
    }

    pub fn get_from_set<'b:'a>(self, set: &'b BTreeSet<T>)->impl Iterator<Item = &'b T> {
        use VerifiedRange::*;
        match self {
            Exact(x) => VerifiedRangeIter::Exact(
                set.get::<T>(x).into_iter()
            ),
            Empty => VerifiedRangeIter::Empty,
            Range(r) => VerifiedRangeIter::Range(
                set.range::<T,_>(r)
            )
        }
    }
}