<commit_before>use bt_messages::Message;
use buffered_reader::BufferedReader;
use std::net::TcpStream;
use std::sync::mpsc::Sender;
use std::io::Write;
use std::cmp::Ordering;
const BLOCK_LENGTH:usize = 16384; //block length in bytes

#[derive(PartialEq, Debug, Clone)]
pub struct Position {
    index: usize,
    offset: usize
}

impl Position {
    pub fn new (index: usize, offset: usize) -> Position {
        Position {
            index: index,
            offset: offset
        }
    }
}

impl PartialOrd for Position {
    fn partial_cmp (&self, rhs: &Position) -> Option<Ordering> {
         if self.index < rhs.index {
            Some(Ordering::Less)
         } else if self.index > rhs.index {
            Some(Ordering::Greater)
         } else {
            if self.offset < rhs.offset {
                Some(Ordering::Less)
            } else if self.offset > rhs.offset {
                Some(Ordering::Greater)
            } else {
                Some(Ordering::Equal)
            }
         }
    }
}

#[derive(PartialEq, Debug, Clone)]
pub struct Piece {
    start: Position,
    end: Position
}

impl Piece {
    pub fn new (start: Position, end: Position) -> Piece {
        Piece {
            start: start,
            end: end
        }
    }

    //start is inclusive, end is exclusive
    pub fn from (piece_length: usize, index: usize, offset: usize, bytes: usize) -> Piece {
        let num_whole_pieces = bytes/piece_length;
        let rem_offset = (offset + bytes) % piece_length;

        let start = Position {
            index: index,
            offset: offset
        };
        let end = Position {
            index: index + num_whole_pieces,
            offset: rem_offset
        };

        Piece{start: start, end: end}
    }

}

/// Handles messages. This is a cheap way to force reactive style
pub trait Handler {
    type MessageType;
    fn handle(&mut self, message: Self::MessageType, peer: &mut Peer);
}

//TODO: state probably shouldn't be stored here in the handler... eventually move it back in main. for each
//torrent
pub struct DefaultHandler {
    //the global piece count
    gpc: Vec<u16>,
    //pieces owned by self. (as a bitfield)
    pub owned: Vec<u8>,
    //outgoing requests
    pub request_map: Vec<u8>,

    s_request_map: Vec<Piece>,
    piece_length: usize
}

impl DefaultHandler {
    pub fn new (piece_length: usize) -> DefaultHandler {
        DefaultHandler {
            gpc: vec![],
            owned: vec![],
            request_map: vec![],
            s_request_map: vec![],
            piece_length: piece_length
        }
    }

    ///attempts to compact the piece indexed by {index} with elements to its left and right
    #[inline]
    pub fn compact_if_possible(arr: &mut Vec<Piece>, index: usize) {
        let res = {
            let ref el = arr[index];
            match ((arr.get(index-1), arr.get(index+1))) {
                (Some(ref left), Some(ref right)) if left.end == el.start && el.end == right.start => {
                    Some((index-1, index+1, Piece::new(left.start.clone(), right.end.clone())))},
                (Some(ref left), _) if left.end == el.start => {
                    Some((index-1, index, Piece::new(left.start.clone(), el.end.clone())))},
                (_, Some(ref right)) if el.end == right.start => {
                    Some((index, index+1, Piece::new(el.start.clone(), right.end.clone())))}
                _ => None
            }
        };
        match res {
            Some((start_index, end_index, compacted_piece)) => {
                for (n, i) in (start_index..end_index+1).enumerate() {
                    arr.remove(n-i);
                }
                arr.insert(start_index, compacted_piece);
            },
            _ => ()
        }
    }

    #[inline]
    ///returns the index at which the chunk was inserted into the vector
    //pub fn add_to_boundary_vec(arr: &mut Vec<Piece>) -> usize {
    pub fn add_to_boundary_vec(arr: &mut Vec<Piece>, new_block: Piece) -> usize {
        //let new_block = DefaultHandler::get_block_boundaries(piece_length, index, offset, bytes);
        if arr.len() == 0 || new_block.start >= arr.last().unwrap().end {
            arr.push(new_block);
            arr.len() - 1
        } else if new_block.end <= arr.first().unwrap().start {
            arr.insert(0, new_block);
            0
        } else {
            let (mut win_left, mut win_right) = (0, arr.len());
            while (win_left < win_right) { //should probably just use loop {}
                let arr_index = (win_left+win_right)/2;
                let something = {
                    let block = &arr[arr_index];
                    let el_left = &arr[arr_index - 1];
                    let el_right = arr.get(arr_index + 1);
                    if new_block.start >= block.end {
                        match el_right {
                            a @ None | a @ Some(_) if new_block.end <= a.unwrap().start => {
                                Some(arr_index+1)
                            },
                            _ => {
                                win_left = arr_index + 1;
                                None
                            }
                        }
                    }
                    else if new_block.end <= block.start {
                            if new_block.start >= el_left.end {
                                Some(arr_index)
                            } else {
                                win_right = arr_index - 1;
                                None
                            }
                    }
                    else { panic!("this is bad")}
                };

                match something {
                    Some(i) => {
                        arr.insert(i, new_block);
                        return i
                    },
                    _ => ()
                }
            }
            //if (win_left > win_right) {
            panic!("this is also bad");
            //}
        }
    }

    /// Increases the value of gpc[piece_index] by n
    #[inline]
    pub fn gpc_incr (&mut self, piece_index: usize, n: u16) {
        //starting to regret making the bitfield variable in size... maybe i can preallocate. will come back and re-eval
        let len = self.gpc.len();
        if piece_index >= len {
            self.gpc.extend((0..piece_index+1 - len).map(|_| 0));
        }
        self.gpc[piece_index] += n;
    }

    /// Returns the index of the rarest piece that isn't owned or currently being requested.
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest (&self) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        for (index, byte) in self.unclaimed_fields().iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// Returns the index of the rarest piece that is owned by the peer and isn't both owned
    /// and currently being requested
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest_wrt_peer (&self, peer_bitfield: &Vec<u8>) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        let eligible = and_slice_vbr_len(&self.unclaimed_fields(), &peer_bitfield);
        for (index, byte) in eligible.iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                //println!("n: {}", n);
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// returns a complete bitfield of pieces that aren't owned or being requested
    /// this is done almost as strictly as possible - and might be a little of a waste as it isn't
    /// really necessary to get a complete picture to get a request chunk
    /// additionally the definitions of owned and request_map are not strict yet - currently they
    /// are growable, and impelementers should take note of that
    #[inline]
    pub fn unclaimed_fields (&self) -> Vec<u8> {
        nand_slice_vbr_len(&self.owned, &self.request_map)
    }

    #[inline]
    pub fn req (&mut self, peer_bitfield: &Vec<u8>) {
        let index = self.rarest_wrt_peer(peer_bitfield);
        println!("REQ: {:?}", index);
    }
}

/// The default algorithm
impl Handler for DefaultHandler {
    type MessageType = Message;
    #[inline]
    fn handle (&mut self, message: Message, peer: &mut Peer) {
        println!("{:?}", message);
        match message {
            Message::Have{piece_index: index} => {
                let i = index as usize;
                self.gpc_incr(i, 1);
                peer.state.set_have(i);
                self.req(&peer.state.bitfield);
            },
            Message::Choke => {
                peer.state.set_us_choked(true);
            },
            Message::Unchoke => {
                peer.state.set_us_choked(false);
            },
            Message::Interested => {
                peer.state.set_us_interested(true);
            },
            Message::Bitfield(bitfield) => {
                for (index, byte) in bitfield.iter().enumerate() {
                    for i in 0..8 { //cast up so i don't have to deal with overflows
                        let n = 1 & (((*byte as u16) << i) >> (8-i));
                        self.gpc_incr(index*8+i, n);
                    }
                }
                peer.state.set_bitfield(bitfield);

                /*
                let candidates = self.unclaimed_fields();
                let request = peer.get_request(&candidates);
                */

                self.req(&peer.state.bitfield);
            },
            _ => {
            }
        };
    }
}

pub struct Peer {
    pub id: String,
    stream: TcpStream,
    pub state: State
}

impl Peer {
    pub fn new (id:String, stream: TcpStream) -> Peer {
        Peer {
            id: id,
            stream: stream,
            state: State::new()
        }
    }

    pub fn send_message (&mut self, message: Message) {
        let as_bytes = message.to_byte_array();
        let _ = self.stream.write_all(&as_bytes);
    }
}

#[derive(Debug)]
pub struct State {
    //are we choked by them?
    pub us_choked: bool,
    //are we interested in them?
    pub us_interested: bool,
    //are they choked by us?
    pub is_choked: bool,
    //are they interested in us?
    pub is_interested: bool,
    //the intention is that eventually we will support growable files. so going with vector
    pub bitfield: Vec<u8>
}

impl State {
    pub fn new () -> State {
        State {
            us_choked: true,
            us_interested: false,
            is_choked: true,
            is_interested: false,
            bitfield: vec![]
        }
    }

    pub fn set_us_interested (&mut self, us_interested: bool) {
        self.us_interested = us_interested;
    }

    pub fn set_bitfield (&mut self, bitfield: Vec<u8>) {
        self.bitfield = bitfield;
    }

    pub fn set_have (&mut self, index: usize) {
        set_have_bitfield(&mut self.bitfield, index);
    }

    pub fn set_us_choked (&mut self, us_choked: bool) {
        self.us_choked = us_choked;
    }
}

#[inline]
fn set_have_bitfield (bitfield: &mut Vec<u8>, index: usize) {
    let chunk_index = index/8;
    let chunk_posit = index % 8;
    let chunk_mask = 128 >> chunk_posit;

    //bounds check needs to be here because the bitfield is a variable size - which we want in
    //the future
    if chunk_index+1 > bitfield.len() {
        bitfield.extend((0..chunk_index).map(|_| 0));
    }

    bitfield[chunk_index] = bitfield[chunk_index] | chunk_mask;
}

/// Zip-maps a generic func over two byte slices with variable lengths
#[inline]
pub fn apply_bitwise_slice_vbr_len <F, T:Clone> (lhs: &[T], rhs: &[T], default: T, func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    if lhs.len() == rhs.len() {
        bitwise_byte_slice(lhs, rhs, func)
    } else {
        if lhs.len() < rhs.len() {
            //let mut a = (&rhs[..lhs.len()]).to_owned();
            let mut a = lhs.to_owned();
            a.extend((0..rhs.len()-lhs.len()).map(|_| default.clone()));
            bitwise_byte_slice(&a, rhs, func)
        } else {
            let mut b = rhs.to_owned();
            b.extend((0..lhs.len()-rhs.len()).map(|_| default.clone()));
            bitwise_byte_slice(lhs, &b, func)
        }
    }
}

/// Zip-maps a generic func (intended bitwise) over two byte slices
#[inline]
pub fn bitwise_byte_slice <F, T> (lhs: &[T], rhs: &[T], func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    println!("llen: {}, rlen: {}", lhs.len(), rhs.len());
    assert!(lhs.len() == rhs.len());
    lhs.iter().zip(rhs)
              .map(func)
              .collect::<Vec<T>>()
}

#[inline]
pub fn nand_slice_vbr_len (lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    apply_bitwise_slice_vbr_len(lhs, rhs, 0, |(a, b)| !a & !b)
}

#[inline]
pub fn and_slice_vbr_len(lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    println!("lhs: {:?}", lhs);
    println!("rhs: {:?}", rhs);
    apply_bitwise_slice_vbr_len(lhs, rhs, 255, |(a, b)| a & b)
}
<commit_msg>convert_bitfield_to_piece_vec<commit_after>use bt_messages::Message;
use buffered_reader::BufferedReader;
use std::net::TcpStream;
use std::sync::mpsc::Sender;
use std::io::Write;
use std::cmp::Ordering;
const BLOCK_LENGTH:usize = 16384; //block length in bytes

#[derive(PartialEq, Debug, Clone)]
pub struct Position {
    index: usize,
    offset: usize
}

impl Position {
    pub fn new (index: usize, offset: usize) -> Position {
        Position {
            index: index,
            offset: offset
        }
    }
}

impl PartialOrd for Position {
    fn partial_cmp (&self, rhs: &Position) -> Option<Ordering> {
         if self.index < rhs.index {
            Some(Ordering::Less)
         } else if self.index > rhs.index {
            Some(Ordering::Greater)
         } else {
            if self.offset < rhs.offset {
                Some(Ordering::Less)
            } else if self.offset > rhs.offset {
                Some(Ordering::Greater)
            } else {
                Some(Ordering::Equal)
            }
         }
    }
}

#[derive(PartialEq, Debug, Clone)]
pub struct Piece {
    start: Position,
    end: Position
}

impl Piece {
    pub fn new (start: Position, end: Position) -> Piece {
        Piece {
            start: start,
            end: end
        }
    }

    //start is inclusive, end is exclusive
    pub fn from (piece_length: usize, index: usize, offset: usize, bytes: usize) -> Piece {
        let num_whole_pieces = bytes/piece_length;
        let rem_offset = (offset + bytes) % piece_length;

        let start = Position {
            index: index,
            offset: offset
        };
        let end = Position {
            index: index + num_whole_pieces,
            offset: rem_offset
        };

        Piece{start: start, end: end}
    }

}

/// Handles messages. This is a cheap way to force reactive style
pub trait Handler {
    type MessageType;
    fn handle(&mut self, message: Self::MessageType, peer: &mut Peer);
}

//TODO: state probably shouldn't be stored here in the handler... eventually move it back in main. for each
//torrent
pub struct DefaultHandler {
    //the global piece count
    gpc: Vec<u16>,
    //pieces owned by self. (as a bitfield)
    pub owned: Vec<u8>,
    //outgoing requests
    pub request_map: Vec<u8>,

    s_request_map: Vec<Piece>,

    piece_length: usize
}

impl DefaultHandler {
    pub fn new (piece_length: usize) -> DefaultHandler {
        DefaultHandler {
            gpc: vec![],
            owned: vec![],
            request_map: vec![],
            s_request_map: vec![],
            piece_length: piece_length
        }
    }

    pub fn convert_bitfield_to_piece_vec (bitfield: &[u8]) -> Vec<Piece> {
        let mut vec = Vec::new();
        let mut a_start = None;
        for (bitmap_byte_num, byte) in bitfield.iter().enumerate() {
            let mut bitmap_offset = 0;
            let mut remainder = byte.to_owned();
            loop {
                match remainder.leading_zeros() {
                    0 => (),
                    x => {
                        let n = if x > 8 - bitmap_offset { 8 -bitmap_offset} else {x};
                        bitmap_offset += n;

                        match a_start {
                            Some(_) => {
                                let end = Position::new((bitmap_byte_num as u32 * 8 + bitmap_offset - n as u32) as usize, 0);
                                vec.push(Piece::new(a_start.unwrap(), end));
                                a_start = None;
                            },
                            None => {}
                        }

                        remainder = remainder << n;
                    }
                };
                match (!remainder).leading_zeros() { //leading 1's after shifting
                    0 => (),
                    n => {
                        match a_start {
                            Some(_) => {/*do nothing*/},
                            None => {
                                a_start = Some(Position::new((bitmap_byte_num as u32 * 8 + bitmap_offset as u32) as usize, 0));
                            }
                        }

                        bitmap_offset += n;
                        println!("br: {}", remainder);
                        remainder = remainder << n;
                        println!("{}, shifted {}", remainder, n);
                    }
                };
                if bitmap_offset == 8 {
                    bitmap_offset = 0;
                    break;
                };
            }
        }

        match a_start {
            Some(_) => {
                vec.push((
                    Piece::new(a_start.unwrap(),
                    Position::new(bitfield.len() * 8, 0))));
            },
            _ => ()
        };
        vec
    }

    ///attempts to compact the piece indexed by {index} with elements to its left and right
    #[inline]
    pub fn compact_if_possible(arr: &mut Vec<Piece>, index: usize) {
        let res = {
            let ref el = arr[index];
            match ((arr.get(index-1), arr.get(index+1))) {
                (Some(ref left), Some(ref right)) if left.end == el.start && el.end == right.start => {
                    Some((index-1, index+1, Piece::new(left.start.clone(), right.end.clone())))},
                (Some(ref left), _) if left.end == el.start => {
                    Some((index-1, index, Piece::new(left.start.clone(), el.end.clone())))},
                (_, Some(ref right)) if el.end == right.start => {
                    Some((index, index+1, Piece::new(el.start.clone(), right.end.clone())))}
                _ => None
            }
        };
        match res {
            Some((start_index, end_index, compacted_piece)) => {
                for (n, i) in (start_index..end_index+1).enumerate() {
                    arr.remove(n-i);
                }
                arr.insert(start_index, compacted_piece);
            },
            _ => ()
        }
    }

    #[inline]
    ///returns the index at which the chunk was inserted into the vector
    //pub fn add_to_boundary_vec(arr: &mut Vec<Piece>) -> usize {
    pub fn add_to_boundary_vec(arr: &mut Vec<Piece>, new_block: Piece) -> usize {
        //let new_block = DefaultHandler::get_block_boundaries(piece_length, index, offset, bytes);
        if arr.len() == 0 || new_block.start >= arr.last().unwrap().end {
            arr.push(new_block);
            arr.len() - 1
        } else if new_block.end <= arr.first().unwrap().start {
            arr.insert(0, new_block);
            0
        } else {
            let (mut win_left, mut win_right) = (0, arr.len());
            while (win_left < win_right) { //should probably just use loop {}
                let arr_index = (win_left+win_right)/2;
                let something = {
                    let block = &arr[arr_index];
                    let el_left = &arr[arr_index - 1];
                    let el_right = arr.get(arr_index + 1);
                    if new_block.start >= block.end {
                        match el_right {
                            a @ None | a @ Some(_) if new_block.end <= a.unwrap().start => {
                                Some(arr_index+1)
                            },
                            _ => {
                                win_left = arr_index + 1;
                                None
                            }
                        }
                    }
                    else if new_block.end <= block.start {
                            if new_block.start >= el_left.end {
                                Some(arr_index)
                            } else {
                                win_right = arr_index - 1;
                                None
                            }
                    }
                    else { panic!("this is bad")}
                };

                match something {
                    Some(i) => {
                        arr.insert(i, new_block);
                        return i
                    },
                    _ => ()
                }
            }
            //if (win_left > win_right) {
            panic!("this is also bad");
            //}
        }
    }

    /// Increases the value of gpc[piece_index] by n
    #[inline]
    pub fn gpc_incr (&mut self, piece_index: usize, n: u16) {
        //starting to regret making the bitfield variable in size... maybe i can preallocate. will come back and re-eval
        let len = self.gpc.len();
        if piece_index >= len {
            self.gpc.extend((0..piece_index+1 - len).map(|_| 0));
        }
        self.gpc[piece_index] += n;
    }

    /// Returns the index of the rarest piece that isn't owned or currently being requested.
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest (&self) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        for (index, byte) in self.unclaimed_fields().iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// Returns the index of the rarest piece that is owned by the peer and isn't both owned
    /// and currently being requested
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest_wrt_peer (&self, peer_bitfield: &Vec<u8>) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        let eligible = and_slice_vbr_len(&self.unclaimed_fields(), &peer_bitfield);
        for (index, byte) in eligible.iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                //println!("n: {}", n);
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// returns a complete bitfield of pieces that aren't owned or being requested
    /// this is done almost as strictly as possible - and might be a little of a waste as it isn't
    /// really necessary to get a complete picture to get a request chunk
    /// additionally the definitions of owned and request_map are not strict yet - currently they
    /// are growable, and impelementers should take note of that
    #[inline]
    pub fn unclaimed_fields (&self) -> Vec<u8> {
        nand_slice_vbr_len(&self.owned, &self.request_map)
    }

    #[inline]
    pub fn req (&mut self, peer_bitfield: &Vec<u8>) {
        let index = self.rarest_wrt_peer(peer_bitfield);
        println!("REQ: {:?}", index);
    }
}

/// The default algorithm
impl Handler for DefaultHandler {
    type MessageType = Message;
    #[inline]
    fn handle (&mut self, message: Message, peer: &mut Peer) {
        println!("{:?}", message);
        match message {
            Message::Have{piece_index: index} => {
                let i = index as usize;
                self.gpc_incr(i, 1);
                peer.state.set_have(i);
                self.req(&peer.state.bitfield);
            },
            Message::Choke => {
                peer.state.set_us_choked(true);
            },
            Message::Unchoke => {
                peer.state.set_us_choked(false);
            },
            Message::Interested => {
                peer.state.set_us_interested(true);
            },
            Message::Bitfield(bitfield) => {
                for (index, byte) in bitfield.iter().enumerate() {
                    for i in 0..8 { //cast up so i don't have to deal with overflows
                        let n = 1 & (((*byte as u16) << i) >> (8-i));
                        self.gpc_incr(index*8+i, n);
                    }
                }
                peer.state.set_bitfield(bitfield);

                /*
                let candidates = self.unclaimed_fields();
                let request = peer.get_request(&candidates);
                */

                self.req(&peer.state.bitfield);
            },
            _ => {
            }
        };
    }
}

pub struct Peer {
    pub id: String,
    stream: TcpStream,
    pub state: State
}

impl Peer {
    pub fn new (id:String, stream: TcpStream) -> Peer {
        Peer {
            id: id,
            stream: stream,
            state: State::new()
        }
    }

    pub fn send_message (&mut self, message: Message) {
        let as_bytes = message.to_byte_array();
        let _ = self.stream.write_all(&as_bytes);
    }
}

#[derive(Debug)]
pub struct State {
    //are we choked by them?
    pub us_choked: bool,
    //are we interested in them?
    pub us_interested: bool,
    //are they choked by us?
    pub is_choked: bool,
    //are they interested in us?
    pub is_interested: bool,
    //the intention is that eventually we will support growable files. so going with vector
    pub bitfield: Vec<u8>
}

impl State {
    pub fn new () -> State {
        State {
            us_choked: true,
            us_interested: false,
            is_choked: true,
            is_interested: false,
            bitfield: vec![]
        }
    }

    pub fn set_us_interested (&mut self, us_interested: bool) {
        self.us_interested = us_interested;
    }

    pub fn set_bitfield (&mut self, bitfield: Vec<u8>) {
        self.bitfield = bitfield;
    }

    pub fn set_have (&mut self, index: usize) {
        set_have_bitfield(&mut self.bitfield, index);
    }

    pub fn set_us_choked (&mut self, us_choked: bool) {
        self.us_choked = us_choked;
    }
}

#[inline]
fn set_have_bitfield (bitfield: &mut Vec<u8>, index: usize) {
    let chunk_index = index/8;
    let chunk_posit = index % 8;
    let chunk_mask = 128 >> chunk_posit;

    //bounds check needs to be here because the bitfield is a variable size - which we want in
    //the future
    if chunk_index+1 > bitfield.len() {
        bitfield.extend((0..chunk_index).map(|_| 0));
    }

    bitfield[chunk_index] = bitfield[chunk_index] | chunk_mask;
}

/// Zip-maps a generic func over two byte slices with variable lengths
#[inline]
pub fn apply_bitwise_slice_vbr_len <F, T:Clone> (lhs: &[T], rhs: &[T], default: T, func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    if lhs.len() == rhs.len() {
        bitwise_byte_slice(lhs, rhs, func)
    } else {
        if lhs.len() < rhs.len() {
            //let mut a = (&rhs[..lhs.len()]).to_owned();
            let mut a = lhs.to_owned();
            a.extend((0..rhs.len()-lhs.len()).map(|_| default.clone()));
            bitwise_byte_slice(&a, rhs, func)
        } else {
            let mut b = rhs.to_owned();
            b.extend((0..lhs.len()-rhs.len()).map(|_| default.clone()));
            bitwise_byte_slice(lhs, &b, func)
        }
    }
}

/// Zip-maps a generic func (intended bitwise) over two byte slices
#[inline]
pub fn bitwise_byte_slice <F, T> (lhs: &[T], rhs: &[T], func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    println!("llen: {}, rlen: {}", lhs.len(), rhs.len());
    assert!(lhs.len() == rhs.len());
    lhs.iter().zip(rhs)
              .map(func)
              .collect::<Vec<T>>()
}

#[inline]
pub fn nand_slice_vbr_len (lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    apply_bitwise_slice_vbr_len(lhs, rhs, 0, |(a, b)| !a & !b)
}

#[inline]
pub fn and_slice_vbr_len(lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    println!("lhs: {:?}", lhs);
    println!("rhs: {:?}", rhs);
    apply_bitwise_slice_vbr_len(lhs, rhs, 255, |(a, b)| a & b)
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Sorting_algorithms/Pancake_sort
fn pancake_sort<T: Ord>(mut v: &mut [T]) {
    let len = v.len();
    // trivial case -- no flips
    if len < 2 {
        return;
    }
    for i in (1..len + 1).rev() {
        // find index of maximum from 0 to i
        let mut max_index = 0;
        for j in 0..i {
            if v[max_index] < v[j] {
                max_index = j;
            }
        }
        // if max_index is not where it's supposed to be
        // do two flips to move it to i - 1
        if max_index != i - 1 {
            flip(&mut v, max_index);
            flip(&mut v, i - 1);
        }
    }
}
// function to flip a section of a mutable collection from 0..num
fn flip<E: PartialOrd>(v: &mut [E], num: usize) {
    for i in 0..(num + 1) / 2 {
        v.swap(i, num - i);
    }
}
fn main() {
    // Sort numbers
    let mut numbers = [4i32, 65, 2, -31, 0, 99, 2, 83, 782, 1];
    println!("Before: {:?}", numbers);
    pancake_sort(&mut numbers);
    println!("After: {:?}", numbers);
    // Sort strings
    let mut strings = ["beach", "hotel", "airplane", "car", "house", "art"];
    println!("Before: {:?}", strings);
    pancake_sort(&mut strings);
    println!("After: {:?}", strings);
}
#[cfg(test)]
mod tests {
    use super::pancake_sort;
    fn check_sort<T: Ord>(v: &[T]) {
        if v.len() > 1 {
            for i in 0..(v.len() - 1) {
                assert!(v[i] <= v[i + 1]);
            }
        }
    }
    #[test]
    fn test_rosetta_vector() {
        let numbers = &mut [4i32, 65, 2, -31, 0, 99, 2, 83, 782, 1];
        pancake_sort(numbers);
        check_sort(numbers);
    }
    #[test]
    fn test_empty_vector() {
        let mut numbers: Vec<i32> = Vec::new();
        pancake_sort(&mut numbers[..]);
        check_sort(&mut numbers[..]);
    }
    #[test]
    fn test_one_element_vector() {
        let numbers = &mut [0i32];
        pancake_sort(numbers);
        check_sort(numbers);
    }
    #[test]
    fn test_repeat_vector() {
        let numbers = &mut [1i32, 1, 1, 1, 1];
        pancake_sort(numbers);
        check_sort(numbers);
    }
    #[test]
    fn test_string_vector() {
        let strings = &mut ["beach", "hotel", "airplane", "car", "house", "art"];
        pancake_sort(strings);
        check_sort(strings);
    }
}<commit_msg>format pancake_sort.rs<commit_after>// http://rosettacode.org/wiki/Sorting_algorithms/Pancake_sort
fn pancake_sort<T: Ord>(mut v: &mut [T]) {
    let len = v.len();
    // trivial case -- no flips
    if len < 2 {
        return;
    }
    for i in (1..len + 1).rev() {
        // find index of maximum from 0 to i
        let mut max_index = 0;
        for j in 0..i {
            if v[max_index] < v[j] {
                max_index = j;
            }
        }
        // if max_index is not where it's supposed to be
        // do two flips to move it to i - 1
        if max_index != i - 1 {
            flip(&mut v, max_index);
            flip(&mut v, i - 1);
        }
    }
}

// function to flip a section of a mutable collection from 0..num
fn flip<E: PartialOrd>(v: &mut [E], num: usize) {
    for i in 0..(num + 1) / 2 {
        v.swap(i, num - i);
    }
}

fn main() {
    // Sort numbers
    let mut numbers = [4i32, 65, 2, -31, 0, 99, 2, 83, 782, 1];
    println!("Before: {:?}", numbers);
    pancake_sort(&mut numbers);
    println!("After: {:?}", numbers);
    // Sort strings
    let mut strings = ["beach", "hotel", "airplane", "car", "house", "art"];
    println!("Before: {:?}", strings);
    pancake_sort(&mut strings);
    println!("After: {:?}", strings);
}

#[cfg(test)]
mod tests {
    use super::pancake_sort;

    fn check_sort<T: Ord>(v: &[T]) {
        if v.len() > 1 {
            for i in 0..(v.len() - 1) {
                assert!(v[i] <= v[i + 1]);
            }
        }
    }

    #[test]
    fn test_rosetta_vector() {
        let numbers = &mut [4i32, 65, 2, -31, 0, 99, 2, 83, 782, 1];
        pancake_sort(numbers);
        check_sort(numbers);
    }

    #[test]
    fn test_empty_vector() {
        let mut numbers: Vec<i32> = Vec::new();
        pancake_sort(&mut numbers[..]);
        check_sort(&mut numbers[..]);
    }

    #[test]
    fn test_one_element_vector() {
        let numbers = &mut [0i32];
        pancake_sort(numbers);
        check_sort(numbers);
    }

    #[test]
    fn test_repeat_vector() {
        let numbers = &mut [1i32, 1, 1, 1, 1];
        pancake_sort(numbers);
        check_sort(numbers);
    }

    #[test]
    fn test_string_vector() {
        let strings = &mut ["beach", "hotel", "airplane", "car", "house", "art"];
        pancake_sort(strings);
        check_sort(strings);
    }
}
<|endoftext|>


<commit_before>use graph::{Edge, Graph};
use adjacency_matrix::AdjacencyMatrix;

use std::usize;

// maximum_flow returns the maximum flow from source to sink in g.
pub fn maximum_flow(g: &Graph, source: usize, sink: usize) -> u32 {
    // Initially, the residual flow graph of g is just the same as g.
    let mut residual_flow_graph = AdjacencyMatrix::from_graph(g);

    let mut flow = 0;
    while let Some(path_capacity) = residual_flow_graph.add_augmenting_path(source, sink) {
        flow += path_capacity;
    }
    flow
}

impl AdjacencyMatrix {
    // addAugmentingPath looks for an augmenting path from source to sink in the residual flow
    // graph.
    // If an augmenting path is found, addAugmentingPath updates the residual flow graph to reflect
    // the addition of the augmenting path, and returns the capacity of the augmenting path.
    // If no augmenting path is found, addAugmentingPath returns None.
    fn add_augmenting_path(&mut self, source: usize, sink: usize) -> Option<u32> {
        let mut parents = vec![usize::MAX; self.size()];

        for Edge { x, y } in self.breadth_first_search(source) {
            parents[y] = x;
            if y == sink {
                // Abort the BFS.
                break;
            }
        }

        // self.breadth_first_search(source, |Edge { x, y }| {
        //     parents[y] = x;
        //     // Return true to abort the BFS.
        //     y == sink
        // });

        self.substract_path(&parents, sink)
    }

    // substractPath substracts the path described by parents and end from the residual flow graph,
    // and returns the capacity of the path.
    fn substract_path(&mut self, parents: &Vec<usize>, end: usize) -> Option<u32> {
        let capacity = self.path_capacity(parents, end);

        if let Some(c) = capacity {
            for Edge {x, y} in edges(parents, end) {
                self[x][y] -= c;
                self[y][x] += c;
            }
        }

        capacity
    }

    // pathCapacity returns the capacity of the path described by parents and end in the residual
    // flow graph.
    fn path_capacity(&self, parents: &Vec<usize>, end: usize) -> Option<u32> {
        let edges = edges(parents, end);
        let capacities = edges.iter().map(|edge| self[edge.x][edge.y]);
        capacities.min()
    }
}

// edges returns the edges of the path described by parents and end.
fn edges(parents: &Vec<usize>, mut end: usize) -> Vec<Edge> {
    let mut edges = vec![];

    while parents[end] < usize::MAX {
        let edge = Edge { x: parents[end], y: end };
        edges.push(edge);
        end = parents[end];
    }

    edges.reverse();
    edges
}
<commit_msg>[edge_connectivity/rust] Use optional instead of usize::MAX as a guard value<commit_after>use graph::{Edge, Graph};
use adjacency_matrix::AdjacencyMatrix;

// maximum_flow returns the maximum flow from source to sink in g.
pub fn maximum_flow(g: &Graph, source: usize, sink: usize) -> u32 {
    // Initially, the residual flow graph of g is just the same as g.
    let mut residual_flow_graph = AdjacencyMatrix::from_graph(g);

    let mut flow = 0;
    while let Some(path_capacity) = residual_flow_graph.add_augmenting_path(source, sink) {
        flow += path_capacity;
    }
    flow
}

impl AdjacencyMatrix {
    // addAugmentingPath looks for an augmenting path from source to sink in the residual flow
    // graph.
    // If an augmenting path is found, addAugmentingPath updates the residual flow graph to reflect
    // the addition of the augmenting path, and returns the capacity of the augmenting path.
    // If no augmenting path is found, addAugmentingPath returns None.
    fn add_augmenting_path(&mut self, source: usize, sink: usize) -> Option<u32> {
        let mut parents = vec![None; self.size()];

        for Edge { x, y } in self.breadth_first_search(source) {
            parents[y] = Some(x);
            if y == sink {
                // Abort the BFS.
                break;
            }
        }

        // self.breadth_first_search(source, |Edge { x, y }| {
        //     parents[y] = x;
        //     // Return true to abort the BFS.
        //     y == sink
        // });

        self.substract_path(&parents, sink)
    }

    // substractPath substracts the path described by parents and end from the residual flow graph,
    // and returns the capacity of the path.
    fn substract_path(&mut self, parents: &Vec<Option<usize>>, end: usize) -> Option<u32> {
        let capacity = self.path_capacity(parents, end);

        if let Some(c) = capacity {
            for Edge {x, y} in edges(parents, end) {
                self[x][y] -= c;
                self[y][x] += c;
            }
        }

        capacity
    }

    // pathCapacity returns the capacity of the path described by parents and end in the residual
    // flow graph.
    fn path_capacity(&self, parents: &Vec<Option<usize>>, end: usize) -> Option<u32> {
        let edges = edges(parents, end);
        let capacities = edges.iter().map(|edge| self[edge.x][edge.y]);
        capacities.min()
    }
}

// edges returns the edges of the path described by parents and end.
fn edges(parents: &Vec<Option<usize>>, mut end: usize) -> Vec<Edge> {
    let mut edges = vec![];

    while let Some(parent) = parents[end] {
        edges.push(Edge { x: parent, y: end });
        end = parent;
    }

    edges.reverse();
    edges
}
<|endoftext|>


<commit_before>pub enum Protocol {
    Version(uint),
    Binary(Vec<u8>),
    Text(~str)
}<commit_msg>Parser<commit_after>pub enum Protocol {
    Version(uint),
    Binary(Vec<u8>),
    Text(~str)
}

pub enum TextProtocol {
    Key(~str),
    Value(Vec<u8>)
}

// The TextProtocol's parser. All we need to spit out is a key->value combination.
// Because we allow streaming within the protocol, we'll only return each
// key->value pair once we have fully parsed both.
//
// There could be an option to receive the raw data as we get it for the value,
// but not the key.
//
// ```rust
// Parser::new()
// ```
pub struct Parser {
    input: Vec<u8>,
    // This is the current character's position
    position: 0,
    curr_ch: '',
    prev_ch: ''
}<|endoftext|>


<commit_before>use std::collections::{HashMap};

use num::bigint::{BigInt};

use opcode::{OpCode, BooleanOrInt};
use value::{Value};

pub struct Machine {
    stack: Vec<Value>,
    memo: HashMap<usize, Value>,
}

impl Machine {
    fn new() -> Self {
        Machine {
            stack: Vec::new(),
            memo: HashMap::new(),
        }
    }

    fn execute(&mut self, opcode: OpCode) {
        match opcode {
            OpCode::Proto(_) => (),
            OpCode::Stop => (),  // TODO: !!!

            OpCode::Int(value) => {
                self.stack.push(match value {
                    BooleanOrInt::Boolean(v) => Value::Bool(v),
                    BooleanOrInt::Int(v) => Value::Int(BigInt::from(v)),
                })
            },
            OpCode::BinInt(i) => self.stack.push(Value::Int(BigInt::from(i))),
            OpCode::BinInt1(i) => self.stack.push(Value::Int(BigInt::from(i))),
            OpCode::BinInt2(i) => self.stack.push(Value::Int(BigInt::from(i))),
            OpCode::Long(i) => self.stack.push(Value::Int(BigInt::from(i))),
            OpCode::Long1(i) => self.stack.push(Value::Int(BigInt::from(i))),
            OpCode::Long4(i) => self.stack.push(Value::Int(BigInt::from(i))),

            OpCode::String(s) => self.stack.push(Value::String(s)),
            OpCode::BinString(s) => self.stack.push(Value::String(s)),
            OpCode::ShortBinString(s) => self.stack.push(Value::String(s)),

            OpCode::None => self.stack.push(Value::None),

            OpCode::NewTrue => self.stack.push(Value::Bool(true)),
            OpCode::NewFalse => self.stack.push(Value::Bool(false)),

            OpCode::Unicode(s) => self.stack.push(Value::Unicode(s)),
            OpCode::BinUnicode(s) => self.stack.push(Value::Unicode(s)),

            OpCode::Float(i) => self.stack.push(Value::Float(i)),
            OpCode::BinFloat(i) => self.stack.push(Value::Float(i)),
            _ => panic!("Not implemented")
        }
    }
}<commit_msg>Implement pickle machine for list<commit_after>use std::collections::{HashMap};

use num::bigint::{BigInt};

use opcode::{OpCode, BooleanOrInt};
use value::{Value};

pub struct Machine {
    stack: Vec<Value>,
    memo: HashMap<usize, Value>,
    marker: Option<usize>,
}

impl Machine {
    fn new() -> Self {
        Machine {
            stack: Vec::new(),
            memo: HashMap::new(),
            marker: None,
        }
    }

    fn execute(&mut self, opcode: OpCode) {
        match opcode {
            OpCode::Proto(_) => (),
            OpCode::Stop => (),  // TODO: !!!

            OpCode::Int(value) => {
                self.stack.push(match value {
                    BooleanOrInt::Boolean(v) => Value::Bool(v),
                    BooleanOrInt::Int(v) => Value::Int(BigInt::from(v)),
                })
            },
            OpCode::BinInt(i) => self.stack.push(Value::Int(BigInt::from(i))),
            OpCode::BinInt1(i) => self.stack.push(Value::Int(BigInt::from(i))),
            OpCode::BinInt2(i) => self.stack.push(Value::Int(BigInt::from(i))),
            OpCode::Long(i) => self.stack.push(Value::Int(BigInt::from(i))),
            OpCode::Long1(i) => self.stack.push(Value::Int(BigInt::from(i))),
            OpCode::Long4(i) => self.stack.push(Value::Int(BigInt::from(i))),

            OpCode::String(s) => self.stack.push(Value::String(s)),
            OpCode::BinString(s) => self.stack.push(Value::String(s)),
            OpCode::ShortBinString(s) => self.stack.push(Value::String(s)),

            OpCode::None => self.stack.push(Value::None),

            OpCode::NewTrue => self.stack.push(Value::Bool(true)),
            OpCode::NewFalse => self.stack.push(Value::Bool(false)),

            OpCode::Unicode(s) => self.stack.push(Value::Unicode(s)),
            OpCode::BinUnicode(s) => self.stack.push(Value::Unicode(s)),

            OpCode::Float(i) => self.stack.push(Value::Float(i)),
            OpCode::BinFloat(i) => self.stack.push(Value::Float(i)),

            OpCode::EmptyList => self.stack.push(Value::List(Vec::new())),
            OpCode::Append => {
                match self.stack.pop() {
                    None => panic!("Empty stack"),
                    Some(v) => {
                        match self.stack.last_mut() {
                            None => panic!("Empty stack"),
                            Some(&mut Value::List(ref mut list)) => list.push(v),
                            _ => panic!("Invalid value on stack"),
                        }
                    }
                }
            },
            OpCode::Appends => {
                match self.marker {
                    None => panic!("Empty marker"),
                    Some(marker) => {
                        let values = self.stack.split_off(marker);
                        match self.stack.last_mut() {
                            None => panic!("Empty stack"),
                            Some(&mut Value::List(ref mut list)) => {
                                list.extend(values);
                            },
                            _ => panic!("Invalid value on stack"),
                        }
                    }
                }
            },
            OpCode::List => {
                match self.marker {
                    None => panic!("Empty marker"),
                    Some(marker) => {
                        let values = self.stack.split_off(marker);
                        self.stack.push(Value::List(values));
                    }
                }
            },
            _ => panic!("Not implemented")
        }
    }
}<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Hamming_numbers
// port of one of the scala solutions
extern crate num;
use num::bigint::BigUint;
use std::cmp::min;
use std::sync::spsc_queue::Queue;

fn int_to_biguint(i: int) -> BigUint {
    FromPrimitive::from_int(i).unwrap()
}

#[cfg(not(test))]
fn main() {
    let mut hamming = Hamming::new(1691);

    println!("first 20 Hamming numbers")
    for _ in range(0,20) {
        print!("{} ", hamming.next().unwrap());
    }

    println!("\n\n1691st Hamming number");
    println!("{}",hamming.nth(1691-20).unwrap())
}

struct Hamming {
    q2: Queue<BigUint>,
    q3: Queue<BigUint>,
    q5: Queue<BigUint>
}

impl Hamming {
    fn new(n: uint) -> Hamming {
        let h = Hamming {
            q2: Queue::new(n),
            q3: Queue::new(n),
            q5: Queue::new(n)
        };

        h.q2.push(int_to_biguint(1));
        h.q3.push(int_to_biguint(1));
        h.q5.push(int_to_biguint(1));

        h
    }

    fn enqueue(&self, n: BigUint) {
        self.q2.push(n * int_to_biguint(2));
        self.q3.push(n * int_to_biguint(3));
        self.q5.push(n * int_to_biguint(5));
    }

}

impl Iterator<BigUint> for Hamming {
    fn next(&mut self) -> Option<BigUint> {
        let (head2, head3, head5) =
            (   self.q2.peek().unwrap(),
                self.q3.peek().unwrap(),
                self.q5.peek().unwrap());

        let n = min(head2.clone(), min(head3.clone(), head5.clone()));

        if *head2 == n {self.q2.pop();}
        if *head3 == n {self.q3.pop();}
        if *head5 == n {self.q5.pop();}

        self.enqueue(n.clone());
        Some(n)
    }
}

#[test]
fn create() {
    let h = Hamming::new(5);
    h.q2.push(int_to_biguint(1));
    h.q2.push(int_to_biguint(2));
    h.q2.push(int_to_biguint(4));

    let _ = h.q2.peek();
    assert!(h.q2.pop().unwrap() == int_to_biguint(1));
}

#[test]
fn try_enqueue() {
    let h = Hamming::new(5);
    h.enqueue(int_to_biguint(1));
    h.enqueue(int_to_biguint(2));
    h.enqueue(int_to_biguint(3));

    assert!(h.q2.pop().unwrap() == int_to_biguint(1));
    assert!(h.q3.pop().unwrap() == int_to_biguint(1));
    assert!(h.q5.pop().unwrap() == int_to_biguint(1));
    assert!(h.q2.pop().unwrap() == int_to_biguint(2));
    assert!(h.q3.pop().unwrap() == int_to_biguint(3));
    assert!(h.q5.pop().unwrap() == int_to_biguint(5));
 }

#[test]
fn hamming_iter() {
    let mut hamming = Hamming::new(20);
    assert!(hamming.nth(19).unwrap() == int_to_biguint(36));
}<commit_msg>commented code<commit_after>// Implements http://rosettacode.org/wiki/Hamming_numbers
// port of one of the scala solutions
extern crate num;
use num::bigint::BigUint;
use std::cmp::min;
use std::sync::spsc_queue::Queue;

// helper function to avoid repeating
// FromPrimitive::from_int(i).unwrap()
// for every BigUint creation
fn int_to_biguint(i: int) -> BigUint {
    FromPrimitive::from_int(i).unwrap()
}

#[cfg(not(test))]
fn main() {
    let mut hamming = Hamming::new(1691);

    println!("first 20 Hamming numbers")
    for _ in range(0,20) {
        print!("{} ", hamming.next().unwrap());
    }

    println!("\n\n1691st Hamming number");
    // we've already iterated over the first 20 numbers
    // so to get at number 1691 we have to subtract 20
    println!("{}",hamming.nth(1691-20).unwrap())
}

// Hamming numbers are multiples
// of 2, 3 or 5. We keep them on three
// queues and extract the lowest (leftmost) value
// from the three queues at each iteration
struct Hamming {
    q2: Queue<BigUint>,
    q3: Queue<BigUint>,
    q5: Queue<BigUint>
}

impl Hamming {
    // constructor method
    // n initializes the capacity of the queues
    fn new(n: uint) -> Hamming {
        let h = Hamming {
            q2: Queue::new(n),
            q3: Queue::new(n),
            q5: Queue::new(n)
        };

        h.q2.push(int_to_biguint(1));
        h.q3.push(int_to_biguint(1));
        h.q5.push(int_to_biguint(1));

        h
    }

    // adds the next multiple (x2, x3, x5)
    // to the queues
    fn enqueue(&self, n: BigUint) {
        self.q2.push(n * int_to_biguint(2));
        self.q3.push(n * int_to_biguint(3));
        self.q5.push(n * int_to_biguint(5));
    }
}

// implements an Iterator, so we
// can extract Hamming numbers more easily
impl Iterator<BigUint> for Hamming {
    // the core of the work is done in the next method.
    // We check which of the 3 queues has the lowest
    // candidate and extract it as the next Hamming number
    fn next(&mut self) -> Option<BigUint> {
        let (head2, head3, head5) =
            (   self.q2.peek().unwrap(),
                self.q3.peek().unwrap(),
                self.q5.peek().unwrap());

        let n = min(head2.clone(), min(head3.clone(), head5.clone()));

        if *head2 == n {self.q2.pop();}
        if *head3 == n {self.q3.pop();}
        if *head5 == n {self.q5.pop();}

        self.enqueue(n.clone());
        Some(n)
    }
}

#[test]
fn create() {
    let h = Hamming::new(5);
    h.q2.push(int_to_biguint(1));
    h.q2.push(int_to_biguint(2));
    h.q2.push(int_to_biguint(4));

    let _ = h.q2.peek();
    assert!(h.q2.pop().unwrap() == int_to_biguint(1));
}

#[test]
fn try_enqueue() {
    let h = Hamming::new(5);
    h.enqueue(int_to_biguint(1));
    h.enqueue(int_to_biguint(2));
    h.enqueue(int_to_biguint(3));

    assert!(h.q2.pop().unwrap() == int_to_biguint(1));
    assert!(h.q3.pop().unwrap() == int_to_biguint(1));
    assert!(h.q5.pop().unwrap() == int_to_biguint(1));
    assert!(h.q2.pop().unwrap() == int_to_biguint(2));
    assert!(h.q3.pop().unwrap() == int_to_biguint(3));
    assert!(h.q5.pop().unwrap() == int_to_biguint(5));
 }

#[test]
fn hamming_iter() {
    let mut hamming = Hamming::new(20);
    assert!(hamming.nth(19).unwrap() == int_to_biguint(36));
}<|endoftext|>


<commit_before>//
//   Copyright 2016 Andrew Hunter
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//

//!
//! # Matches
//!
//! ```
//! # use ndfa::*;
//! # assert!(matches("abcabc", "abc".repeat_forever(1)).is_some());
//! # assert!(matches("abcabcabc", "abc".repeat_forever(1)).is_some());
//! # assert!(matches("abc", "abc").is_some());
//! # assert!(matches("def", "abc".repeat_forever(1)).is_none());
//! if matches("abcabc", "abc".repeat_forever(1)).is_some() { /* ... */ }
//! ```

use super::symbol_range_dfa::*;
use super::symbol_reader::*;
use super::pattern_matcher::*;
use super::prepare::*;

///
/// Runs a pattern matcher against a stream, and returns the number of characters matching if it accepted the stream
///
fn matches_symbol_range<InputSymbol: Ord, OutputSymbol: 'static>(dfa: &SymbolRangeDfa<InputSymbol, OutputSymbol>, symbol_reader: &mut SymbolReader<InputSymbol>) -> Option<usize> {
    // Run until there are no more states
    let mut current_state = dfa.start();

    while let More(this_state) = current_state {
        let next_state =
            if let Some(next_char) = symbol_reader.next_symbol() {
                this_state.next(next_char)
            } else {
                this_state.finish()
            };

        current_state = next_state;
    }

    if let Accept(count, _) = current_state {
        Some(count)
    } else {
        None
    }
}

///
/// Matches a source stream against a pattern
///
pub fn matches<'a, Symbol, OutputSymbol, Prepare, Reader, Source>(source: Source, pattern: Prepare) -> Option<usize>
where   Prepare: PrepareToMatch<SymbolRangeDfa<Symbol, OutputSymbol>>
,       Reader: SymbolReader<Symbol>+'a
,       Source: SymbolSource<'a, Symbol, SymbolReader=Reader>
,       Symbol: Ord
,       OutputSymbol: 'static {
    let matcher    = pattern.prepare_to_match();
    let mut reader = source.read_symbols();

    matches_symbol_range(&matcher, &mut reader)
}

///
/// Matches a source stream against a pattern
///
pub fn matches_prepared<'a, Symbol, OutputSymbol, Reader, Source>(source: Source, matcher: &SymbolRangeDfa<Symbol, OutputSymbol>) -> Option<usize>
where   Reader: SymbolReader<Symbol>+'a
,       Source: SymbolSource<'a, Symbol, SymbolReader=Reader>
,       Symbol: Ord
,       OutputSymbol: 'static {
    let mut reader = source.read_symbols();

    matches_symbol_range(&matcher, &mut reader)
}

#[cfg(test)]
mod test {
    use super::super::*;

    #[test]
    fn match_multiple_repeats() {
        assert!(matches("abcabc", "abc".repeat_forever(1)).is_some());
    }

    #[test]
    fn match_single_repeat() {
        assert!(matches("abc", "abc".repeat_forever(1)).is_some());
    }

    #[test]
    fn match_with_zero_or_more() {
        assert!(matches("abc", "abc".repeat_forever(0)).is_some());
        assert!(matches("abcabc", "abc".repeat_forever(0)).is_some());
        assert!(matches("abcabcabc", "abc".repeat_forever(0)).is_some());
    }

    #[test]
    fn match_with_zero_or_more_following() {
        assert!(matches("abc", "abc".repeat_forever(0).append("def")).is_none());
        assert!(matches("abcabc", "abc".repeat_forever(0).append("def")).is_none());

        assert!(matches("abcdef", "abc".repeat_forever(0).append("def")).is_some());
        assert!(matches("abcabcdef", "abc".repeat_forever(0).append("def")).is_some());
    }

    #[test]
    fn match_limited_range() {
        assert!(matches("abc", "abc".repeat(2..4)).is_none());
        assert!(matches("abcabc", "abc".repeat(2..4)).is_some());
        assert!(matches("abcabcabc", "abc".repeat(2..4)) == Some(3*3));
        assert!(matches("abcabcabcabc", "abc".repeat(2..4)) == Some(3*3));
    }

    /* -- BROKEN
    #[test]
    fn match_zero_repeats() {
        assert!(matches("", "abc".repeat_forever(0)).is_some());
    }
    */
}
<commit_msg>Add a run_dfa() function to run a DFA until it accepts or rejects an input stream<commit_after>//
//   Copyright 2016 Andrew Hunter
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//

//!
//! # Matches
//!
//! ```
//! # use ndfa::*;
//! # assert!(matches("abcabc", "abc".repeat_forever(1)).is_some());
//! # assert!(matches("abcabcabc", "abc".repeat_forever(1)).is_some());
//! # assert!(matches("abc", "abc").is_some());
//! # assert!(matches("def", "abc".repeat_forever(1)).is_none());
//! if matches("abcabc", "abc".repeat_forever(1)).is_some() { /* ... */ }
//! ```

use super::symbol_range_dfa::*;
use super::symbol_reader::*;
use super::pattern_matcher::*;
use super::prepare::*;

///
/// Runs a pattern matcher against a stream, and returns the number of characters matching if it accepted the stream
///
fn matches_symbol_range<InputSymbol: Ord, OutputSymbol: 'static>(dfa: &SymbolRangeDfa<InputSymbol, OutputSymbol>, symbol_reader: &mut SymbolReader<InputSymbol>) -> Option<usize> {
    // Run the DFA
    let final_state = run_dfa(dfa.start(), symbol_reader);

    if let Accept(count, _) = final_state {
        Some(count)
    } else {
        None
    }
}

///
/// Runs a DFA against a symbol stream and returns its final state
///
pub fn run_dfa<'a, InputSymbol: Ord, OutputSymbol, State>(start_state: MatchAction<'a, OutputSymbol, State>, symbol_reader: &mut SymbolReader<InputSymbol>) -> MatchAction<'a, OutputSymbol, State>
where State: MatchingState<'a, InputSymbol, OutputSymbol> {
    let mut current_state = start_state;

    while let More(this_state) = current_state {
        let next_state =
            if let Some(next_char) = symbol_reader.next_symbol() {
                this_state.next(next_char)
            } else {
                this_state.finish()
            };

        current_state = next_state;
    }

    current_state
}

///
/// Matches a source stream against a pattern
///
pub fn matches<'a, Symbol, OutputSymbol, Prepare, Reader, Source>(source: Source, pattern: Prepare) -> Option<usize>
where   Prepare: PrepareToMatch<SymbolRangeDfa<Symbol, OutputSymbol>>
,       Reader: SymbolReader<Symbol>+'a
,       Source: SymbolSource<'a, Symbol, SymbolReader=Reader>
,       Symbol: Ord
,       OutputSymbol: 'static {
    let matcher    = pattern.prepare_to_match();
    let mut reader = source.read_symbols();

    matches_symbol_range(&matcher, &mut reader)
}

///
/// Matches a source stream against a pattern
///
pub fn matches_prepared<'a, Symbol, OutputSymbol, Reader, Source>(source: Source, matcher: &SymbolRangeDfa<Symbol, OutputSymbol>) -> Option<usize>
where   Reader: SymbolReader<Symbol>+'a
,       Source: SymbolSource<'a, Symbol, SymbolReader=Reader>
,       Symbol: Ord
,       OutputSymbol: 'static {
    let mut reader = source.read_symbols();

    matches_symbol_range(&matcher, &mut reader)
}

#[cfg(test)]
mod test {
    use super::super::*;

    #[test]
    fn match_multiple_repeats() {
        assert!(matches("abcabc", "abc".repeat_forever(1)).is_some());
    }

    #[test]
    fn match_single_repeat() {
        assert!(matches("abc", "abc".repeat_forever(1)).is_some());
    }

    #[test]
    fn match_with_zero_or_more() {
        assert!(matches("abc", "abc".repeat_forever(0)).is_some());
        assert!(matches("abcabc", "abc".repeat_forever(0)).is_some());
        assert!(matches("abcabcabc", "abc".repeat_forever(0)).is_some());
    }

    #[test]
    fn match_with_zero_or_more_following() {
        assert!(matches("abc", "abc".repeat_forever(0).append("def")).is_none());
        assert!(matches("abcabc", "abc".repeat_forever(0).append("def")).is_none());

        assert!(matches("abcdef", "abc".repeat_forever(0).append("def")).is_some());
        assert!(matches("abcabcdef", "abc".repeat_forever(0).append("def")).is_some());
    }

    #[test]
    fn match_limited_range() {
        assert!(matches("abc", "abc".repeat(2..4)).is_none());
        assert!(matches("abcabc", "abc".repeat(2..4)).is_some());
        assert!(matches("abcabcabc", "abc".repeat(2..4)) == Some(3*3));
        assert!(matches("abcabcabcabc", "abc".repeat(2..4)) == Some(3*3));
    }

    /* -- BROKEN
    #[test]
    fn match_zero_repeats() {
        assert!(matches("", "abc".repeat_forever(0)).is_some());
    }
    */
}
<|endoftext|>


<commit_before>extern crate nom;

use std::str;
use nom::{
    is_digit,
    is_hex_digit,
};

fn is_ws(c: char) -> bool {
    let u = c as u32;
    u == 0x20 || u == 0x9 || u == 0xD || u == 0xA
}

fn is_anon(c: char) -> bool {
    c == '[' || c == ']' || is_ws(c)
}

fn is_digit_c(c: char) -> bool {
    is_digit(c as u8)
}

#[derive(PartialEq, Debug)]
pub struct Decimal<'a> {
    sign:          Option<&'a str>,
    integer_part:  &'a str,
    decimal_point: &'a str,
    decimal_part:  &'a str,
}
/* [20] DECIMAL */
named!(pub decimal<&str, Decimal>, do_parse!(
    sign:          opt!(alt!(tag!("+") | tag!("-"))) >>
    integer_part:  take_while_s!(is_digit_c)         >>
    decimal_point: tag!(".")                         >>
    decimal_part:  take_while1_s!(is_digit_c)        >>
    (Decimal{
        sign:          sign,
        integer_part:  integer_part,
        decimal_point: decimal_point,
        decimal_part:  decimal_part,
    })
));

#[derive(PartialEq, Debug)]
pub enum Mantissa<'a> {
    IntegerDecimal {
        integer_part:  &'a str,
        decimal_point: &'a str,
        decimal_part:  &'a str,
    },
    Decimal {
        decimal_point: &'a str,
        decimal_part:  &'a str,
    },
    Integer {
        integer_part: &'a str,
    },
}
#[derive(PartialEq, Debug)]
pub struct Double<'a> {
    sign:     Option<&'a str>,
    mantissa: Mantissa<'a>,
    exponent: Exponent<'a>,
}
/* [21] DOUBLE */
named!(pub double<&str, Double>, do_parse!(
    sign:     opt!(alt!(tag!("+") | tag!("-"))) >>
    mantissa: alt!(
        do_parse!(
            integer_part:  take_while1_s!(is_digit_c) >>
            decimal_point: tag!(".")                  >>
            decimal_part:  take_while_s!(is_digit_c)  >>
            (Mantissa::IntegerDecimal{
                integer_part:  integer_part,
                decimal_point: decimal_point,
                decimal_part:  decimal_part,
            })
        ) |
        do_parse!(
            decimal_point: tag!(".")                  >>
            decimal_part:  take_while1_s!(is_digit_c) >>
            (Mantissa::Decimal{
                decimal_point: decimal_point,
                decimal_part:  decimal_part,
            })
        ) |
        do_parse!(
            integer_part: take_while1_s!(is_digit_c) >>
            (Mantissa::Integer{
                integer_part: integer_part,
            })
        )
    ) >>
    exponent: exponent >>
    (Double{
        sign:     sign,
        mantissa: mantissa,
        exponent: exponent,
    })
));

#[derive(PartialEq, Debug)]
pub struct Exponent<'a> {
    exponent_symbol: &'a str,
    sign:            Option<&'a str>,
    exponent_number: &'a str,
}

/* [154s] EXPONENT */
named!(pub exponent<&str, Exponent>, do_parse!(
    exponent_symbol: alt!(tag!("e") | tag!("E"))       >>
    sign:            opt!(alt!(tag!("+") | tag!("-"))) >>
    exponent_number: take_while1_s!(is_digit_c)        >>
    (Exponent{
        exponent_symbol: exponent_symbol,
        sign:            sign,
        exponent_number: exponent_number,
    })
));

/* [161s] WS */
named!(pub ws<&str, &str>, take_while_s!(is_ws));

/* [162s] ANON */
named!(pub anon<&str, &str>, verify!(
    take_while_s!(is_anon),
    |val:&str| {
        let len = val.char_indices().count();
        val.char_indices().all(|(idx, c)| {
            if idx == 0 {
                c == '['
            } else if idx == len - 1 {
                c == ']'
            } else {
                is_ws(c)
            }
        })
    }
));

/* [170s] PERCENT */
named!(pub percent<&str, &str>, verify!(
    take_s!(3),
    |val:&str| {
        let bytes = val.as_bytes();
        bytes[0] == 0x25 && is_hex_digit(bytes[1]) && is_hex_digit(bytes[2])
    }
));

#[cfg(test)]
mod test {
    use super::*;
    use nom::IResult;

    #[test]
    fn decimal_normal_test() {
        let input    = "-1234.5678rest";
        let expected = IResult::Done("rest", Decimal{
            sign:          Some("-"),
            integer_part:  "1234",
            decimal_point: ".",
            decimal_part:  "5678",
        });
        assert_eq!(decimal(input), expected);
    }

    #[test]
    fn double_normal_test() {
        let input    = "-1234.5678e-0123456789rest";
        let expected = IResult::Done("rest", Double{
            sign:     Some("-"),
            mantissa: Mantissa::IntegerDecimal {
                integer_part:  "1234",
                decimal_point: ".",
                decimal_part:  "5678",
            },
            exponent: Exponent {
                exponent_symbol: "e",
                sign:            Some("-"),
                exponent_number: "0123456789",
            },
        });
        assert_eq!(double(input), expected);

        let input    = "-.5678e-0123456789rest";
        let expected = IResult::Done("rest", Double{
            sign:     Some("-"),
            mantissa: Mantissa::Decimal {
                decimal_point: ".",
                decimal_part:  "5678",
            },
            exponent: Exponent {
                exponent_symbol: "e",
                sign:            Some("-"),
                exponent_number: "0123456789",
            },
        });
        assert_eq!(double(input), expected);

        let input    = "+5678e-0123456789rest";
        let expected = IResult::Done("rest", Double{
            sign:     Some("+"),
            mantissa: Mantissa::Integer {
                integer_part: "5678",
            },
            exponent: Exponent {
                exponent_symbol: "e",
                sign:            Some("-"),
                exponent_number: "0123456789",
            },
        });
        assert_eq!(double(input), expected);
    }

    #[test]
    fn exponent_normal_test() {
        let input    = "e-0123456789rest";
        let expected = IResult::Done("rest", Exponent{
            exponent_symbol: "e",
            sign:            Some("-"),
            exponent_number: "0123456789",
        });
        assert_eq!(exponent(input), expected);

        let input    = "E+0123456789rest";
        let expected = IResult::Done("rest", Exponent{
            exponent_symbol: "E",
            sign:            Some("+"),
            exponent_number: "0123456789",
        });
        assert_eq!(exponent(input), expected);

        let input    = "e0123456789rest";
        let expected = IResult::Done("rest", Exponent{
            exponent_symbol: "e",
            sign:            None,
            exponent_number: "0123456789",
        });
        assert_eq!(exponent(input), expected);
    }

    #[test]
    fn ws_test() {
        assert_eq!(ws("   a"), IResult::Done("a", "   "));
    }

    #[test]
    fn anon_test() {
        assert_eq!(anon("[ ]a"), IResult::Done("a", "[ ]"));
    }

    #[test]
    fn percent_test() {
        assert_eq!(percent("%2Abc"), IResult::Done("bc", "%2A"));
    }
}
<commit_msg>Implement INTEGER<commit_after>extern crate nom;

use std::str;
use nom::{
    is_digit,
    is_hex_digit,
};

fn is_ws(c: char) -> bool {
    let u = c as u32;
    u == 0x20 || u == 0x9 || u == 0xD || u == 0xA
}

fn is_anon(c: char) -> bool {
    c == '[' || c == ']' || is_ws(c)
}

fn is_digit_c(c: char) -> bool {
    is_digit(c as u8)
}

#[derive(PartialEq, Debug)]
pub struct Integer<'a> {
    sign:          Option<&'a str>,
    integer_part:  &'a str,
}
/* [19] INTEGER */
named!(pub integer<&str, Integer>, do_parse!(
    sign:          opt!(alt!(tag!("+") | tag!("-"))) >>
    integer_part:  take_while1_s!(is_digit_c)        >>
    (Integer{
        sign:          sign,
        integer_part:  integer_part,
    })
));

#[derive(PartialEq, Debug)]
pub struct Decimal<'a> {
    sign:          Option<&'a str>,
    integer_part:  &'a str,
    decimal_point: &'a str,
    decimal_part:  &'a str,
}
/* [20] DECIMAL */
named!(pub decimal<&str, Decimal>, do_parse!(
    sign:          opt!(alt!(tag!("+") | tag!("-"))) >>
    integer_part:  take_while_s!(is_digit_c)         >>
    decimal_point: tag!(".")                         >>
    decimal_part:  take_while1_s!(is_digit_c)        >>
    (Decimal{
        sign:          sign,
        integer_part:  integer_part,
        decimal_point: decimal_point,
        decimal_part:  decimal_part,
    })
));

#[derive(PartialEq, Debug)]
pub enum Mantissa<'a> {
    IntegerDecimal {
        integer_part:  &'a str,
        decimal_point: &'a str,
        decimal_part:  &'a str,
    },
    Decimal {
        decimal_point: &'a str,
        decimal_part:  &'a str,
    },
    Integer {
        integer_part: &'a str,
    },
}
#[derive(PartialEq, Debug)]
pub struct Double<'a> {
    sign:     Option<&'a str>,
    mantissa: Mantissa<'a>,
    exponent: Exponent<'a>,
}
/* [21] DOUBLE */
named!(pub double<&str, Double>, do_parse!(
    sign:     opt!(alt!(tag!("+") | tag!("-"))) >>
    mantissa: alt!(
        do_parse!(
            integer_part:  take_while1_s!(is_digit_c) >>
            decimal_point: tag!(".")                  >>
            decimal_part:  take_while_s!(is_digit_c)  >>
            (Mantissa::IntegerDecimal{
                integer_part:  integer_part,
                decimal_point: decimal_point,
                decimal_part:  decimal_part,
            })
        ) |
        do_parse!(
            decimal_point: tag!(".")                  >>
            decimal_part:  take_while1_s!(is_digit_c) >>
            (Mantissa::Decimal{
                decimal_point: decimal_point,
                decimal_part:  decimal_part,
            })
        ) |
        do_parse!(
            integer_part: take_while1_s!(is_digit_c) >>
            (Mantissa::Integer{
                integer_part: integer_part,
            })
        )
    ) >>
    exponent: exponent >>
    (Double{
        sign:     sign,
        mantissa: mantissa,
        exponent: exponent,
    })
));

#[derive(PartialEq, Debug)]
pub struct Exponent<'a> {
    exponent_symbol: &'a str,
    sign:            Option<&'a str>,
    exponent_number: &'a str,
}

/* [154s] EXPONENT */
named!(pub exponent<&str, Exponent>, do_parse!(
    exponent_symbol: alt!(tag!("e") | tag!("E"))       >>
    sign:            opt!(alt!(tag!("+") | tag!("-"))) >>
    exponent_number: take_while1_s!(is_digit_c)        >>
    (Exponent{
        exponent_symbol: exponent_symbol,
        sign:            sign,
        exponent_number: exponent_number,
    })
));

/* [161s] WS */
named!(pub ws<&str, &str>, take_while_s!(is_ws));

/* [162s] ANON */
named!(pub anon<&str, &str>, verify!(
    take_while_s!(is_anon),
    |val:&str| {
        let len = val.char_indices().count();
        val.char_indices().all(|(idx, c)| {
            if idx == 0 {
                c == '['
            } else if idx == len - 1 {
                c == ']'
            } else {
                is_ws(c)
            }
        })
    }
));

/* [170s] PERCENT */
named!(pub percent<&str, &str>, verify!(
    take_s!(3),
    |val:&str| {
        let bytes = val.as_bytes();
        bytes[0] == 0x25 && is_hex_digit(bytes[1]) && is_hex_digit(bytes[2])
    }
));

#[cfg(test)]
mod test {
    use super::*;
    use nom::IResult;

    #[test]
    fn integer_normal_test() {
        let input    = "-1234rest";
        let expected = IResult::Done("rest", Integer{
            sign:          Some("-"),
            integer_part:  "1234",
        });
        assert_eq!(integer(input), expected);
    }

    #[test]
    fn decimal_normal_test() {
        let input    = "-1234.5678rest";
        let expected = IResult::Done("rest", Decimal{
            sign:          Some("-"),
            integer_part:  "1234",
            decimal_point: ".",
            decimal_part:  "5678",
        });
        assert_eq!(decimal(input), expected);
    }

    #[test]
    fn double_normal_test() {
        let input    = "-1234.5678e-0123456789rest";
        let expected = IResult::Done("rest", Double{
            sign:     Some("-"),
            mantissa: Mantissa::IntegerDecimal {
                integer_part:  "1234",
                decimal_point: ".",
                decimal_part:  "5678",
            },
            exponent: Exponent {
                exponent_symbol: "e",
                sign:            Some("-"),
                exponent_number: "0123456789",
            },
        });
        assert_eq!(double(input), expected);

        let input    = "-.5678e-0123456789rest";
        let expected = IResult::Done("rest", Double{
            sign:     Some("-"),
            mantissa: Mantissa::Decimal {
                decimal_point: ".",
                decimal_part:  "5678",
            },
            exponent: Exponent {
                exponent_symbol: "e",
                sign:            Some("-"),
                exponent_number: "0123456789",
            },
        });
        assert_eq!(double(input), expected);

        let input    = "+5678e-0123456789rest";
        let expected = IResult::Done("rest", Double{
            sign:     Some("+"),
            mantissa: Mantissa::Integer {
                integer_part: "5678",
            },
            exponent: Exponent {
                exponent_symbol: "e",
                sign:            Some("-"),
                exponent_number: "0123456789",
            },
        });
        assert_eq!(double(input), expected);
    }

    #[test]
    fn exponent_normal_test() {
        let input    = "e-0123456789rest";
        let expected = IResult::Done("rest", Exponent{
            exponent_symbol: "e",
            sign:            Some("-"),
            exponent_number: "0123456789",
        });
        assert_eq!(exponent(input), expected);

        let input    = "E+0123456789rest";
        let expected = IResult::Done("rest", Exponent{
            exponent_symbol: "E",
            sign:            Some("+"),
            exponent_number: "0123456789",
        });
        assert_eq!(exponent(input), expected);

        let input    = "e0123456789rest";
        let expected = IResult::Done("rest", Exponent{
            exponent_symbol: "e",
            sign:            None,
            exponent_number: "0123456789",
        });
        assert_eq!(exponent(input), expected);
    }

    #[test]
    fn ws_test() {
        assert_eq!(ws("   a"), IResult::Done("a", "   "));
    }

    #[test]
    fn anon_test() {
        assert_eq!(anon("[ ]a"), IResult::Done("a", "[ ]"));
    }

    #[test]
    fn percent_test() {
        assert_eq!(percent("%2Abc"), IResult::Done("bc", "%2A"));
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::hash::{Hash, Hasher};
use std::str::from_utf8;
use std::collections::HashMap;

use hdata::HData;
use errors::WeechatError;
use errors::WeechatError::ParseError;
use parse::Parse;
use strdata::StrData;

/// Holds header information for data received from relay
#[derive(Debug)]
pub struct Header {
    /// Size of the message body (not including header size)
    pub length: usize,
    /// Flag if zlib compression is enabled
    pub compression: bool,
}

impl Header {
    /// Takes a new message received by the relay, and parses out the header for it
    ///
    /// The header protocol has the first 4 bytes make an integer which is the,
    /// total size of the message, and a single byte which represents if zlib
    /// compression is enabled for the rest of the message
    pub fn new(bytes: &[u8]) -> Result<Header, WeechatError> {
        let mut cur_pos = 0; // Rolling counter of where we are in the byte array

        // Grab the message length
        let parsed = try!(Parse::integer(bytes));
        let total_msg_length = try!(parsed.object.as_integer());
        cur_pos += parsed.bytes_read;

        // Grab the compression character
        let parsed = try!(Parse::character(&bytes[cur_pos..]));
        let compression = try!(parsed.object.as_character());
        let compression = match compression as u8 {
            0 => false,
            1 => true,
            _ => return Err(WeechatError::ParseError("Bad compression byte".to_string())),
        };
        cur_pos += parsed.bytes_read;

        // Headers has length of full message, we need to chop off the
        // legth of the header as we have already read that from the socket
        let length = total_msg_length as usize - cur_pos;

        // Create the struct
        Ok(Header {
            length: length,
            compression: compression,
        })
    }
}

/// Message received from weechat
#[derive(Debug)]
pub struct Message {
    /// Identifier of the message. For a complete list of identifiers, see:
    /// https://weechat.org/files/doc/devel/weechat_relay_protocol.en.html#message_identifier
    pub identifier: String,
    /// Data contained in this message
    data_type: Type,
}

/// Possible types of messages received from relay (almost every message, excluding pongs,
/// will use HData)
#[derive(Debug)]
pub enum Type {
    StrData(StrData),
    HData(HData),
}

impl Message {
    pub fn new(bytes: &[u8]) -> Result<Message, WeechatError> {
        // First thing encoded is the identifier for what this command is
        let parsed = try!(Parse::string(bytes));
        let identifier = try!(parsed.object.as_not_null_str());

        // Next 3 bytes determin type of data in this command (hdata or str).
        let start = parsed.bytes_read;
        let end = start + 3;
        let msg_type = match try!(from_utf8(&bytes[start..end])) {
            "str" => Type::StrData(try!(StrData::new(&bytes[end..]))),
            "hda" => Type::HData(try!(HData::new(&bytes[end..]))),
            _ => return Err(WeechatError::ParseError("Unknown message type".to_string())),
        };

        // Return our struct
        Ok(Message {
            identifier: String::from(identifier),
            data_type: msg_type,
        })
    }

    /// Returns the contents of this message as an HData (if it is an HData)
    pub fn as_hdata(&self) -> Result<&HData, WeechatError> {
        match self.data_type {
            Type::HData(ref hdata) => Ok(hdata),
            _                      => Err(ParseError("Message is not an hdata".to_string())),
        }
    }

    /// Returns the contents of this message as a StrData (if it is a StrData)
    pub fn as_strdata(&self) -> Result<&StrData, WeechatError> {
        match self.data_type {
            Type::StrData(ref strdata) => Ok(strdata),
            _                          => Err(ParseError("Message is not a strdata".to_string())),
        }
    }
}

/// All possible types of data that can be returned from a weechat message
/// See: https://weechat.org/files/doc/devel/weechat_relay_protocol.en.html#objects
#[derive(Debug, PartialEq, Eq)]
pub enum Object {
    Arr(Vec<Object>),
    Buf(Option<Vec<u8>>),
    Chr(char),
    Htb(HashMap<Object, Object>),
    Int(i32),
    Lon(i64),
    Ptr(Option<String>),
    Str(Option<String>),
    Tim(i32),
}

// TODO will this actually work? Looking at the example here: https://doc.rust-lang.org/std/hash/
// they had to define what the hash function was, but here I'm just calling hash and it's
// working. I think it is because those values already implement a hash function so I'm
// alright there, but do double check this and make sure it works. Also add support
// for nested hash maps (maybe convert to string or something? Dunno, but figure out
impl Hash for Object {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match *self {
            Object::Arr(ref x) => x.hash(state),
            Object::Buf(ref x) => x.hash(state),
            Object::Chr(ref x) => x.hash(state),
            Object::Htb(ref x) => panic!("Nested hashmaps not supported yet"),
            Object::Int(ref x) => x.hash(state),
            Object::Lon(ref x) => x.hash(state),
            Object::Ptr(ref x) => x.hash(state),
            Object::Str(ref x) => x.hash(state),
            Object::Tim(ref x) => x.hash(state),
        };
    }
}

impl Object {
    pub fn as_array(&self) -> Result<&[Object], WeechatError> {
        match *self {
            Object::Arr(ref arr) => Ok(arr.as_slice()),
            _                    => Err(ParseError("Item is not an array".to_string())),
        }
    }

    /// Returns this data as a buffer if it is a buffer.
    pub fn as_buffer(&self) -> Result<Option<&[u8]>, WeechatError> {
        match *self {
            Object::Buf(Some(ref vec)) => Ok(Some(vec.as_slice())),
            Object::Buf(None)          => Ok(None),
            _                          => Err(ParseError("Item is not a buffer".to_string()))
        }
    }

    /// Returns this data as a buffer if it is a non-null buffer. Note: null != empty
    pub fn as_not_null_buffer(&self) -> Result<&[u8], WeechatError> {
        try!(self.as_buffer().map(|b| b.ok_or(ParseError("Buffer is null".to_string()))))
    }

    /// Returns this data as a character if it is a character.
    pub fn as_character(&self) -> Result<char, WeechatError> {
        match *self {
            Object::Chr(c) => Ok(c),
            _              => Err(ParseError("Item is not a character".to_string()))
        }
    }

    /// Returns this data as a integer if it is a integer.
    pub fn as_integer(&self) -> Result<i32, WeechatError> {
        match *self {
            Object::Int(i) => Ok(i),
            _              => Err(ParseError("Item is not a integer".to_string()))
        }
    }

    /// Returns this data as a long if it is a long.
    pub fn as_long(&self) -> Result<i64, WeechatError> {
        match *self {
            Object::Lon(l) => Ok(l),
            _              => Err(ParseError("Item is not a long".to_string()))
        }
    }

    /// Returns this data as a pointer if it is a pointer (pointer is encoded as a str).
    pub fn as_pointer(&self) -> Result<Option<&str>, WeechatError> {
        match *self {
            Object::Ptr(Some(ref p)) => Ok(Some(p)),
            Object::Ptr(None)        => Ok(None),
            _                        => Err(ParseError("Item is not a buffer".to_string()))
        }
    }

    /// Returns this data as a pointer if it is a non-null pointer (pointer is
    /// encoded as a str). Note: null != empty
    pub fn as_not_null_pointer(&self) -> Result<&str, WeechatError> {
        try!(self.as_pointer().map(|p| p.ok_or(ParseError("pointer is null".to_string()))))
    }

    /// Returns this data as a string if it is a string.
    pub fn as_str(&self) -> Result<Option<&str>, WeechatError> {
        match *self {
            Object::Str(Some(ref s)) => Ok(Some(s)),
            Object::Str(None)        => Ok(None),
            _                        => Err(ParseError("Item is not a buffer".to_string()))
        }
    }

    /// Returns this data as a string if it is a non-null string. Note: null != empty
    pub fn as_not_null_str(&self) -> Result<&str, WeechatError> {
        try!(self.as_str().map(|s| s.ok_or(ParseError("String is null".to_string()))))
    }

    /// Returns this data as an epoch time if it is a time (encdoed as an i32)
    pub fn as_time(&self) -> Result<i32, WeechatError> {
        match *self {
            Object::Tim(t) => Ok(t),
            _              => Err(ParseError("Item is not a time".to_string()))
        }
    }
}

/// A simple display for Objects (all of the data types that can be returned
/// as object in an HDAta). This is primarily used for debugging
impl fmt::Display for Object {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Object::Str(Some(ref s)) => write!(f, "\"{}\"", s),
            Object::Ptr(Some(ref p)) => write!(f, "0x{}", p),
            Object::Buf(Some(ref b)) => {
                                              try!(write!(f, "[ "));
                                              for byte in b {
                                                  try!(write!(f, "{}, ", byte));
                                              }
                                              write!(f, "]")
                                          }
            Object::Buf(None)  => write!(f, "null"),
            Object::Str(None)  => write!(f, "null"),
            Object::Ptr(None)  => write!(f, "0x0"),
            Object::Chr(ref c) => write!(f, "{} ('{}')", *c as u8, c),
            Object::Int(ref i) => write!(f, "{}", i),
            Object::Lon(ref l) => write!(f, "{}", l),
            Object::Tim(ref t) => write!(f, "{}", t),
            Object::Htb(ref h) => write!(f, "TODO"), // TODO Pretty print me
            Object::Arr(ref d) => {
                                        try!(write!(f, "[ "));
                                        for i in d {
                                            try!(i.fmt(f));
                                            try!(write!(f, ", "));
                                        }
                                        write!(f, "]")
                                    },
        }
    }
}

<commit_msg>Updates to hashtable realy objects<commit_after>use std::fmt;
use std::hash::{Hash, Hasher};
use std::str::from_utf8;
use std::collections::HashMap;

use hdata::HData;
use errors::WeechatError;
use errors::WeechatError::ParseError;
use parse::Parse;
use strdata::StrData;

/// Holds header information for data received from relay
#[derive(Debug)]
pub struct Header {
    /// Size of the message body (not including header size)
    pub length: usize,
    /// Flag if zlib compression is enabled
    pub compression: bool,
}

impl Header {
    /// Takes a new message received by the relay, and parses out the header for it
    ///
    /// The header protocol has the first 4 bytes make an integer which is the,
    /// total size of the message, and a single byte which represents if zlib
    /// compression is enabled for the rest of the message
    pub fn new(bytes: &[u8]) -> Result<Header, WeechatError> {
        let mut cur_pos = 0; // Rolling counter of where we are in the byte array

        // Grab the message length
        let parsed = try!(Parse::integer(bytes));
        let total_msg_length = try!(parsed.object.as_integer());
        cur_pos += parsed.bytes_read;

        // Grab the compression character
        let parsed = try!(Parse::character(&bytes[cur_pos..]));
        let compression = try!(parsed.object.as_character());
        let compression = match compression as u8 {
            0 => false,
            1 => true,
            _ => return Err(WeechatError::ParseError("Bad compression byte".to_string())),
        };
        cur_pos += parsed.bytes_read;

        // Headers has length of full message, we need to chop off the
        // legth of the header as we have already read that from the socket
        let length = total_msg_length as usize - cur_pos;

        // Create the struct
        Ok(Header {
            length: length,
            compression: compression,
        })
    }
}

/// Message received from weechat
#[derive(Debug)]
pub struct Message {
    /// Identifier of the message. For a complete list of identifiers, see:
    /// https://weechat.org/files/doc/devel/weechat_relay_protocol.en.html#message_identifier
    pub identifier: String,
    /// Data contained in this message
    data_type: Type,
}

/// Possible types of messages received from relay (almost every message, excluding pongs,
/// will use HData)
#[derive(Debug)]
pub enum Type {
    StrData(StrData),
    HData(HData),
}

impl Message {
    pub fn new(bytes: &[u8]) -> Result<Message, WeechatError> {
        // First thing encoded is the identifier for what this command is
        let parsed = try!(Parse::string(bytes));
        let identifier = try!(parsed.object.as_not_null_str());

        // Next 3 bytes determin type of data in this command (hdata or str).
        let start = parsed.bytes_read;
        let end = start + 3;
        let msg_type = match try!(from_utf8(&bytes[start..end])) {
            "str" => Type::StrData(try!(StrData::new(&bytes[end..]))),
            "hda" => Type::HData(try!(HData::new(&bytes[end..]))),
            _ => return Err(WeechatError::ParseError("Unknown message type".to_string())),
        };

        // Return our struct
        Ok(Message {
            identifier: String::from(identifier),
            data_type: msg_type,
        })
    }

    /// Returns the contents of this message as an HData (if it is an HData)
    pub fn as_hdata(&self) -> Result<&HData, WeechatError> {
        match self.data_type {
            Type::HData(ref hdata) => Ok(hdata),
            _                      => Err(ParseError("Message is not an hdata".to_string())),
        }
    }

    /// Returns the contents of this message as a StrData (if it is a StrData)
    pub fn as_strdata(&self) -> Result<&StrData, WeechatError> {
        match self.data_type {
            Type::StrData(ref strdata) => Ok(strdata),
            _                          => Err(ParseError("Message is not a strdata".to_string())),
        }
    }
}

/// All possible types of data that can be returned from a weechat message
/// See: https://weechat.org/files/doc/devel/weechat_relay_protocol.en.html#objects
#[derive(Debug, PartialEq, Eq)]
pub enum Object {
    Arr(Vec<Object>),
    Buf(Option<Vec<u8>>),
    Chr(char),
    Htb(HashMap<Object, Object>),
    Int(i32),
    Lon(i64),
    Ptr(Option<String>),
    Str(Option<String>),
    Tim(i32),
}

// I need to implement this to get nested hash tables to work. Derive hash
// on Object isn't working for it, so I'm manually doing it here
impl Hash for Object {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match *self {
            Object::Arr(ref x) => x.hash(state),
            Object::Buf(ref x) => x.hash(state),
            Object::Chr(ref x) => x.hash(state),
            Object::Htb(ref x) => format!("{:?}", x).hash(state), // Not ideal
            Object::Int(ref x) => x.hash(state),
            Object::Lon(ref x) => x.hash(state),
            Object::Ptr(ref x) => x.hash(state),
            Object::Str(ref x) => x.hash(state),
            Object::Tim(ref x) => x.hash(state),
        };
    }
}

impl Object {
    pub fn as_array(&self) -> Result<&[Object], WeechatError> {
        match *self {
            Object::Arr(ref arr) => Ok(arr.as_slice()),
            _                    => Err(ParseError("Item is not an array".to_string())),
        }
    }

    /// Returns this data as a buffer if it is a buffer.
    pub fn as_buffer(&self) -> Result<Option<&[u8]>, WeechatError> {
        match *self {
            Object::Buf(Some(ref vec)) => Ok(Some(vec.as_slice())),
            Object::Buf(None)          => Ok(None),
            _                          => Err(ParseError("Item is not a buffer".to_string()))
        }
    }

    /// Returns this data as a buffer if it is a non-null buffer. Note: null != empty
    pub fn as_not_null_buffer(&self) -> Result<&[u8], WeechatError> {
        try!(self.as_buffer().map(|b| b.ok_or(ParseError("Buffer is null".to_string()))))
    }

    /// Returns this data as a character if it is a character.
    pub fn as_character(&self) -> Result<char, WeechatError> {
        match *self {
            Object::Chr(c) => Ok(c),
            _              => Err(ParseError("Item is not a character".to_string()))
        }
    }

    /// Returns this data as a integer if it is a integer.
    pub fn as_integer(&self) -> Result<i32, WeechatError> {
        match *self {
            Object::Int(i) => Ok(i),
            _              => Err(ParseError("Item is not a integer".to_string()))
        }
    }

    /// Returns this data as a long if it is a long.
    pub fn as_long(&self) -> Result<i64, WeechatError> {
        match *self {
            Object::Lon(l) => Ok(l),
            _              => Err(ParseError("Item is not a long".to_string()))
        }
    }

    /// Returns this data as a pointer if it is a pointer (pointer is encoded as a str).
    pub fn as_pointer(&self) -> Result<Option<&str>, WeechatError> {
        match *self {
            Object::Ptr(Some(ref p)) => Ok(Some(p)),
            Object::Ptr(None)        => Ok(None),
            _                        => Err(ParseError("Item is not a buffer".to_string()))
        }
    }

    /// Returns this data as a pointer if it is a non-null pointer (pointer is
    /// encoded as a str). Note: null != empty
    pub fn as_not_null_pointer(&self) -> Result<&str, WeechatError> {
        try!(self.as_pointer().map(|p| p.ok_or(ParseError("pointer is null".to_string()))))
    }

    /// Returns this data as a string if it is a string.
    pub fn as_str(&self) -> Result<Option<&str>, WeechatError> {
        match *self {
            Object::Str(Some(ref s)) => Ok(Some(s)),
            Object::Str(None)        => Ok(None),
            _                        => Err(ParseError("Item is not a buffer".to_string()))
        }
    }

    /// Returns this data as a string if it is a non-null string. Note: null != empty
    pub fn as_not_null_str(&self) -> Result<&str, WeechatError> {
        try!(self.as_str().map(|s| s.ok_or(ParseError("String is null".to_string()))))
    }

    /// Returns this data as an epoch time if it is a time (encdoed as an i32)
    pub fn as_time(&self) -> Result<i32, WeechatError> {
        match *self {
            Object::Tim(t) => Ok(t),
            _              => Err(ParseError("Item is not a time".to_string()))
        }
    }
}

/// A simple display for Objects (all of the data types that can be returned
/// as object in an HDAta). This is primarily used for debugging
impl fmt::Display for Object {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Object::Str(Some(ref s)) => write!(f, "\"{}\"", s),
            Object::Ptr(Some(ref p)) => write!(f, "0x{}", p),
            Object::Buf(Some(ref b)) => {
                try!(write!(f, "[ "));
                for byte in b {
                    try!(write!(f, "{}, ", byte));
                }
                write!(f, "]")
            }
            Object::Buf(None)  => write!(f, "null"),
            Object::Str(None)  => write!(f, "null"),
            Object::Ptr(None)  => write!(f, "0x0"),
            Object::Chr(ref c) => write!(f, "{} ('{}')", *c as u8, c),
            Object::Int(ref i) => write!(f, "{}", i),
            Object::Lon(ref l) => write!(f, "{}", l),
            Object::Tim(ref t) => write!(f, "{}", t),
            Object::Htb(ref h) =>  {
                try!(write!(f, "{{ "));
                for (key, value) in h {
                    try!(key.fmt(f));
                    try!(write!(f, ": "));
                    try!(value.fmt(f));
                    try!(write!(f, ", "));
                }
                write!(f, "}}")
            }
            Object::Arr(ref d) => {
                try!(write!(f, "[ "));
                for i in d {
                    try!(i.fmt(f));
                    try!(write!(f, ", "));
                }
                write!(f, "]")
            },
        }
    }
}

<|endoftext|>