skimmer 0.0.2

Simple streams reader
Documentation
use marker::Marker;

// use std::sync::Arc;
use std::fmt::Debug;


pub trait Datum : Clone + Debug {
    fn len (&self) -> usize;

    fn as_slice (&self) -> &[u8];
}




pub struct Data<Datum> {
    data: Vec<Datum>
}



impl<D> Data<D>
  where
    D: Datum
{
    pub fn with_capacity (size: usize) -> Data<D> { Data { data: Vec::with_capacity (size) } }

    pub fn clear (&mut self) { self.data.clear () }

    pub fn amount (&self) -> usize { self.data.len () }

    pub fn push (&mut self, datum: D) { self.data.push (datum) }

    pub fn marker_len (&self, marker: &Marker) -> usize {
        if marker.pos1.0 == marker.pos2.0 { marker.pos2.1 - marker.pos1.1 } else {
            let mut tot_len = 0;

            tot_len += self.data[marker.pos1.0].len () - marker.pos1.1;
            tot_len += marker.pos2.1;

            for i in marker.pos1.0 + 1 .. marker.pos2.0 { tot_len += self.data[i].len (); }

            tot_len
        }
    }

    pub fn resize (&self, marker: Marker, newlen: usize) -> Marker {
        if marker.pos1.0 == marker.pos2.0 {
            Marker::new (
                (marker.pos1.0, marker.pos1.1),
                (marker.pos2.0, marker.pos1.1 + newlen)
            )
        } else {
            let ref datum = self.data[marker.pos1.0];

            if datum.len () - marker.pos1.1 >= newlen {
                Marker::new (
                    (marker.pos1.0, marker.pos1.1),
                    (marker.pos1.0, marker.pos1.1 + newlen)
                )
            } else {
                let pos1 = marker.pos1;
                let mut pos2 = marker.pos1;
                let mut tot_len = newlen - (datum.len () - marker.pos1.1);

                loop {
                    pos2.0 += 1;
                    let ref datum = self.data[pos2.0];
                    if datum.len () >= tot_len {
                        pos2.1 = tot_len;
                        break;
                    } else {
                        tot_len -= datum.len ();
                    }
                }

                Marker::new ( pos1, pos2 )
            }
        }
    }


    pub fn chunk<'a, 'b> (&'a self, marker: &'b Marker) -> Chunk<'a> {
        if marker.pos1.0 == marker.pos2.0 {
            self._chunk_slice (marker.pos1.0, marker.pos1.1, marker.pos2.1)
        } else {
            self._chunk_vec (marker)
        }
    }

    fn _chunk_slice<'a> (&'a self, datum_idx: usize, start: usize, end: usize) -> Chunk<'a> {
        Chunk::Slice (&self.data[datum_idx].as_slice ()[start .. end])
    }

    fn _chunk_vec<'a, 'b> (&'a self, marker: &'b Marker) -> Chunk<'a> {
        let mut vec: Vec<u8>;

        let mut len = 0;

        len += self.data[marker.pos1.0].len () - marker.pos1.1;
        len += marker.pos2.1;

        if marker.pos2.0 - marker.pos1.0 > 1 {
            for i in marker.pos1.0 + 1 .. marker.pos2.0 {
                len += self.data[i].len ();
            }
        }

        vec = Vec::with_capacity (len);

        vec.extend (&self.data[marker.pos1.0].as_slice ()[marker.pos1.1 .. ]);

        if marker.pos2.0 - marker.pos1.0 > 1 {
            for i in marker.pos1.0 + 1 .. marker.pos2.0 {
                vec.extend (self.data[i].as_slice ());
            }
        }

        vec.extend (&self.data[marker.pos2.0].as_slice ()[ .. marker.pos2.1]);

        Chunk::Vec (vec)
    }
}




pub enum Chunk<'a> {
    Slice (&'a [u8]),
    Vec (Vec<u8>)
}



impl<'a> Chunk<'a> {
    pub fn as_slice (&self) -> &[u8] { self.into () }
}



impl<'a, 'b> Into<&'b [u8]> for &'b Chunk<'a> {
    fn into (self) -> &'b [u8] {
        match *self {
            Chunk::Slice (slice) => slice,
            Chunk::Vec (ref v) => v.as_slice ()
        }
    }
}



impl<'a> From<Vec<u8>> for Chunk<'a> {
    fn from (v: Vec<u8>) -> Chunk<'a> { Chunk::Vec (v) }
}