<commit_before>use nom::{IResult};
use nom::{le_u32};

use blocks;

pub enum Block<'a> {
    SectionHeader(blocks::SectionHeader),
    EnhancedPacket(blocks::EnhancedPacket<'a>),
    InterfaceDescription(blocks::InterfaceDescription),
}

/// Public representation of a parsed block
#[derive(Debug)]
pub struct RawBlock<'a> {
    //  0                   1                   2                   3
    //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //  |                          Block Type                           |
    //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //  |                      Block Total Length                       |
    //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //  /                          Block Body                           /
    //  /          /* variable length, aligned to 32 bits */            /
    //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //  |                      Block Total Length                       |
    //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ty: u32,
    pub block_length: u32,
    pub body: &'a [u8],
    pub check_length: u32,
}

impl<'a> RawBlock<'a> {
    fn parse(self) -> Block<'a> {
        match self.ty {
            blocks::section_header::TY => Block::SectionHeader(blocks::section_header::parse(self)),
            blocks::enhanced_packet::TY => Block::EnhancedPacket(blocks::enhanced_packet::parse(self)),
            blocks::interface_description::TY => Block::InterfaceDescription(blocks::interface_description::parse(self)),
            _ => panic!("Unknown block type {:x}", self.ty),
        }
    }
}

named!(pub parse_block< &[u8],RawBlock >,
       chain!(
           ty: le_u32 ~
           block_length: le_u32 ~
           body: take!((block_length - 12) as usize) ~
           check_length: le_u32 ,

           ||{ RawBlock {
               ty: ty,
               block_length: block_length,
               body: body,
               check_length: check_length
           } }
           )
      );

named!(pub parse_blocks< &[u8],Vec<RawBlock> >,
       many1!(parse_block)
       );

#[test]
fn test_parse_block() {
    let input = b"\n\r\r\n\x1c\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1c\x00\x00\x00";
    match parse_block(input) {
        IResult::Done(left, RawBlock { ty, block_length, body, check_length }) => {
            // Ignored because we do not currently parse the whole block
            assert_eq!(left, b"");
            assert_eq!(ty, 0x0A0D0D0A);
            assert_eq!(block_length, 28);
            assert_eq!(body, b"M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff");
            assert_eq!(check_length, 28);
        },
        _ => {
            assert_eq!(1, 2);
        },
    }
}

#[test]
fn test_parse_blocks() {
    let input = b"\n\r\r\n\x1c\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1c\x00\x00\x00\
    \n\r\r\n\x1c\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1c\x00\x00\x00";
    match parse_blocks(input) {
        IResult::Done(left, blocks) => {
            assert_eq!(blocks.len(), 2);
            for i in blocks {
                let RawBlock { ty, block_length, body, check_length } = i;
                // Ignored because we do not currently parse the whole block
                assert_eq!(left, b"");
                assert_eq!(ty, 0x0A0D0D0A);
                assert_eq!(block_length, 28);
                assert_eq!(body, b"M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff");
                assert_eq!(check_length, 28);
            }
        },
        _ => {
            assert_eq!(1, 2);
        },
    }
}
<commit_msg>Debug for blocks<commit_after>use nom::{IResult};
use nom::{le_u32};

use blocks;

#[derive(Debug)]
pub enum Block<'a> {
    SectionHeader(blocks::SectionHeader),
    EnhancedPacket(blocks::EnhancedPacket<'a>),
    InterfaceDescription(blocks::InterfaceDescription),
}

/// Public representation of a parsed block
#[derive(Debug)]
pub struct RawBlock<'a> {
    //  0                   1                   2                   3
    //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //  |                          Block Type                           |
    //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //  |                      Block Total Length                       |
    //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //  /                          Block Body                           /
    //  /          /* variable length, aligned to 32 bits */            /
    //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //  |                      Block Total Length                       |
    //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ty: u32,
    pub block_length: u32,
    pub body: &'a [u8],
    pub check_length: u32,
}

impl<'a> RawBlock<'a> {
    fn parse(self) -> Block<'a> {
        match self.ty {
            blocks::section_header::TY => Block::SectionHeader(blocks::section_header::parse(self)),
            blocks::enhanced_packet::TY => Block::EnhancedPacket(blocks::enhanced_packet::parse(self)),
            blocks::interface_description::TY => Block::InterfaceDescription(blocks::interface_description::parse(self)),
            _ => panic!("Unknown block type {:x}", self.ty),
        }
    }
}

named!(pub parse_block< &[u8],RawBlock >,
       chain!(
           ty: le_u32 ~
           block_length: le_u32 ~
           body: take!((block_length - 12) as usize) ~
           check_length: le_u32 ,

           ||{ RawBlock {
               ty: ty,
               block_length: block_length,
               body: body,
               check_length: check_length
           } }
           )
      );

named!(pub parse_blocks< &[u8],Vec<RawBlock> >,
       many1!(parse_block)
       );

#[test]
fn test_parse_block() {
    let input = b"\n\r\r\n\x1c\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1c\x00\x00\x00";
    match parse_block(input) {
        IResult::Done(left, RawBlock { ty, block_length, body, check_length }) => {
            // Ignored because we do not currently parse the whole block
            assert_eq!(left, b"");
            assert_eq!(ty, 0x0A0D0D0A);
            assert_eq!(block_length, 28);
            assert_eq!(body, b"M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff");
            assert_eq!(check_length, 28);
        },
        _ => {
            assert_eq!(1, 2);
        },
    }
}

#[test]
fn test_parse_blocks() {
    let input = b"\n\r\r\n\x1c\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1c\x00\x00\x00\
    \n\r\r\n\x1c\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1c\x00\x00\x00";
    match parse_blocks(input) {
        IResult::Done(left, blocks) => {
            assert_eq!(blocks.len(), 2);
            for i in blocks {
                let RawBlock { ty, block_length, body, check_length } = i;
                // Ignored because we do not currently parse the whole block
                assert_eq!(left, b"");
                assert_eq!(ty, 0x0A0D0D0A);
                assert_eq!(block_length, 28);
                assert_eq!(body, b"M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff");
                assert_eq!(check_length, 28);
            }
        },
        _ => {
            assert_eq!(1, 2);
        },
    }
}
<|endoftext|>


<commit_before>use color::Color;
use game::Piece;

#[derive(Debug, PartialEq, Eq)]
pub struct Board {
    color_matrix: Vec<Vec<Option<Color>>>,
}

impl Board {
    pub fn new(width: usize, height: usize) -> Board {
        Board {
            color_matrix: vec![vec![None; width]; height],
        }
    }

    fn height(&self) -> usize {
        self.color_matrix.len()
    }

    fn width(&self) -> usize {
        self.color_matrix.get(0).unwrap_or(&vec![]).len()
    }

    pub fn set(&mut self, row: usize, col: usize, color: Color) {
        self.color_matrix.get_mut(row).unwrap()[col] = Some(color);
    }

    pub fn get(&self, row: usize, col:usize) -> Option<Color> {
        self.color_matrix.get(row)
            .unwrap_or(&vec![])
            .get(col)
            .unwrap_or(&None)
            .clone()
    }

    pub fn get_pieces(&self) -> Vec<Piece> {
        self.color_matrix.iter()
            .enumerate()
            .flat_map(|(row_num, col)| {
                let pieces: Vec<Piece> = col.iter()
                    .enumerate()
                    .filter_map(|(col_num, color)| {
                        if let Some(c) = color.clone() {
                            Some(Piece { row: row_num, col: col_num, color: c })
                        } else {
                            None
                        }
                    }).collect();
                pieces
            })
            .collect()
    }

    fn get_sequential_pieces(&self, coordinates: Vec<(usize, usize)>) -> Vec<Piece> {
        let mut sequence_coordinates: Vec<&(usize, usize)> = coordinates.windows(4)
            .filter(|sequence| {
                sequence.get(0).map_or(false, |&(row_0, col_0)| {
                    self.get(row_0, col_0).map_or(false, |first_color| {
                        sequence.iter().all(|&(row, col)| {
                            self.get(row, col) == Some(first_color.clone())
                        })
                    })
                })
            })
            .flat_map(|s| s)
            .collect();

            sequence_coordinates.sort();
            sequence_coordinates.dedup();

            sequence_coordinates.iter().map(|&&(row, col)| {
                Piece { row: row, col: col, color: self.get(row, col).unwrap() }
            }).collect()
    }

    pub fn get_pieces_to_clear(&self) -> Vec<Piece> {
        let mut pieces: Vec<Piece> = vec![];

        // vertical
        for col in 0..self.width() {
            let mut coordinates = vec![];

            for row in 0..self.height() {
                coordinates.push((row, col));
            }

            let new_pieces = self.get_sequential_pieces(coordinates);

            for s in new_pieces {
                pieces.push(s);
            }
        }

        // horizontal
        for row in 0..self.height() {
            let mut coordinates = vec![];

            for col in 0..self.width() {
                coordinates.push((row, col));
            }

            let new_pieces = self.get_sequential_pieces(coordinates);

            for s in new_pieces {
                pieces.push(s);
            }
        }

        // diagonal up by row, looks like /
        for starting_row in 0..self.height() {
            let mut coordinates = vec![];

            for (row, col) in (0...starting_row).rev().zip(0..self.width()) {
                coordinates.push((row, col));
            }

            let new_pieces = self.get_sequential_pieces(coordinates);

            for s in new_pieces {
                pieces.push(s);
            }
        }

        // diagonal up by col, looks like /
        for starting_col in 1..self.width() {
            let mut coordinates = vec![];

            for (row, col) in (0...(self.height() - 1)).rev().zip(starting_col..self.width()) {
                coordinates.push((row, col));
            }

            let new_pieces = self.get_sequential_pieces(coordinates);

            for s in new_pieces {
                pieces.push(s);
            }
        }

        pieces
    }

    pub fn clear_all(&mut self, pieces: Vec<Piece>) {
    }

    pub fn get_lowest_free_row_in_col(&self, col: usize) -> usize {
        self.color_matrix.iter()
            .rposition(|row| row.get(col).unwrap_or(&None).is_none())
            .unwrap()
    }
}

#[cfg(test)]
mod tests {
    use board::Board;
    use color::Color::*;
    use game::Piece;

    #[test]
    fn get_pieces_to_clear_diagonal_up() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None, None, Some(Red) ],
                vec![ None, None, Some(Red), None ],
                vec![ None, Some(Red), None, None ],
                vec![ Some(Red), None, None, None ],
            ],
        };

        let mut expected_pieces_to_clear = vec![
            Piece { row: 3, col: 0, color: Red },
            Piece { row: 2, col: 1, color: Red },
            Piece { row: 1, col: 2, color: Red },
            Piece { row: 0, col: 3, color: Red },
        ];

        let mut pieces_to_clear = board.get_pieces_to_clear();

        expected_pieces_to_clear.sort();
        pieces_to_clear.sort();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_diagonal_up_off_center_up() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None, None, Some(Red), None ],
                vec![ None, None, Some(Red), None, None ],
                vec![ None, Some(Red), None, None, None ],
                vec![ Some(Red), None, None, None, None ],
                vec![ None, None, None, None, None ],
            ],
        };

        let mut expected_pieces_to_clear = vec![
            Piece { row: 3, col: 0, color: Red },
            Piece { row: 2, col: 1, color: Red },
            Piece { row: 1, col: 2, color: Red },
            Piece { row: 0, col: 3, color: Red },
        ];

        let mut pieces_to_clear = board.get_pieces_to_clear();

        expected_pieces_to_clear.sort();
        pieces_to_clear.sort();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_diagonal_up_off_center_down() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None, None, None, None ],
                vec![ None, None, None, None, Some(Red) ],
                vec![ None, None, None, Some(Red), None ],
                vec![ None, None, Some(Red), None, None ],
                vec![ None, Some(Red), None, None, None ],
            ],
        };

        let mut expected_pieces_to_clear = vec![
            Piece { row: 4, col: 1, color: Red },
            Piece { row: 3, col: 2, color: Red },
            Piece { row: 2, col: 3, color: Red },
            Piece { row: 1, col: 4, color: Red },
        ];

        let mut pieces_to_clear = board.get_pieces_to_clear();

        expected_pieces_to_clear.sort();
        pieces_to_clear.sort();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_horizontal() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None, None, None ],
                vec![ None, None, None, None ],
                vec![ Some(Red), Some(Red), Some(Red), Some(Red) ],
                vec![ None, None, None, None ],
            ],
        };

        let expected_pieces_to_clear = vec![
            Piece { row: 2, col: 0, color: Red },
            Piece { row: 2, col: 1, color: Red },
            Piece { row: 2, col: 2, color: Red },
            Piece { row: 2, col: 3, color: Red },
        ];

        let pieces_to_clear = board.get_pieces_to_clear();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_vertical() {
        let board = Board {
            color_matrix: vec![
                vec![ Some(Red), None ],
                vec![ Some(Red), None ],
                vec![ Some(Red), None ],
                vec![ Some(Red), None ],
                vec![ Some(Yellow), None ],
            ],
        };

        let expected_pieces_to_clear = vec![
            Piece { row: 0, col: 0, color: Red },
            Piece { row: 1, col: 0, color: Red },
            Piece { row: 2, col: 0, color: Red },
            Piece { row: 3, col: 0, color: Red },
        ];

        let pieces_to_clear = board.get_pieces_to_clear();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_vertical_none_eligible() {
        let board = Board {
            color_matrix: vec![
                vec![ Some(Red), None ],
                vec![ Some(Blue), None ],
                vec![ Some(Red), None ],
                vec![ Some(Red), None ],
            ],
        };

        let expected_pieces_to_clear: Vec<Piece> = vec![];

        let pieces_to_clear = board.get_pieces_to_clear();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn set_a_color() {
        let mut board = Board {
            color_matrix: vec![
                vec![ Some(Red), Some(Red) ],
                vec![ Some(Red), Some(Red) ],
            ],
        };

        board.set(1, 1, Yellow);

        let expected_board = Board {
            color_matrix: vec![
                vec![ Some(Red), Some(Red) ],
                vec![ Some(Red), Some(Yellow) ],
            ],
        };

        assert_eq!(expected_board, board);
    }

    #[test]
    fn get_a_color() {
        let board = Board {
            color_matrix: vec![
                vec![ Some(Red), Some(Blue) ],
                vec![ Some(Red), Some(Yellow) ],
            ],
        };

        let color = board.get(0, 1);

        let expected_color = Some(Blue);

        assert_eq!(expected_color, color);
    }

    #[test]
    fn get_lowest_free_row_in_col() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None ],
                vec![ None, None ],
            ],
        };

        let row = board.get_lowest_free_row_in_col(0);
        let expected_row = 1;

        assert_eq!(expected_row, row);
    }

    #[test]
    fn get_lowest_free_row_in_col_with_another_existing_piece() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None ],
                vec![ Some(Red), None ],
            ],
        };

        let row = board.get_lowest_free_row_in_col(0);
        let expected_row = 0;

        assert_eq!(expected_row, row);
    }
}
<commit_msg>basic diagonal down<commit_after>use color::Color;
use game::Piece;

#[derive(Debug, PartialEq, Eq)]
pub struct Board {
    color_matrix: Vec<Vec<Option<Color>>>,
}

impl Board {
    pub fn new(width: usize, height: usize) -> Board {
        Board {
            color_matrix: vec![vec![None; width]; height],
        }
    }

    fn height(&self) -> usize {
        self.color_matrix.len()
    }

    fn width(&self) -> usize {
        self.color_matrix.get(0).unwrap_or(&vec![]).len()
    }

    pub fn set(&mut self, row: usize, col: usize, color: Color) {
        self.color_matrix.get_mut(row).unwrap()[col] = Some(color);
    }

    pub fn get(&self, row: usize, col:usize) -> Option<Color> {
        self.color_matrix.get(row)
            .unwrap_or(&vec![])
            .get(col)
            .unwrap_or(&None)
            .clone()
    }

    pub fn get_pieces(&self) -> Vec<Piece> {
        self.color_matrix.iter()
            .enumerate()
            .flat_map(|(row_num, col)| {
                let pieces: Vec<Piece> = col.iter()
                    .enumerate()
                    .filter_map(|(col_num, color)| {
                        if let Some(c) = color.clone() {
                            Some(Piece { row: row_num, col: col_num, color: c })
                        } else {
                            None
                        }
                    }).collect();
                pieces
            })
            .collect()
    }

    fn get_sequential_pieces(&self, coordinates: Vec<(usize, usize)>) -> Vec<Piece> {
        let mut sequence_coordinates: Vec<&(usize, usize)> = coordinates.windows(4)
            .filter(|sequence| {
                sequence.get(0).map_or(false, |&(row_0, col_0)| {
                    self.get(row_0, col_0).map_or(false, |first_color| {
                        sequence.iter().all(|&(row, col)| {
                            self.get(row, col) == Some(first_color.clone())
                        })
                    })
                })
            })
            .flat_map(|s| s)
            .collect();

            sequence_coordinates.sort();
            sequence_coordinates.dedup();

            sequence_coordinates.iter().map(|&&(row, col)| {
                Piece { row: row, col: col, color: self.get(row, col).unwrap() }
            }).collect()
    }

    pub fn get_pieces_to_clear(&self) -> Vec<Piece> {
        let mut pieces: Vec<Piece> = vec![];

        // vertical
        for col in 0..self.width() {
            let mut coordinates = vec![];

            for row in 0..self.height() {
                coordinates.push((row, col));
            }

            let new_pieces = self.get_sequential_pieces(coordinates);

            for s in new_pieces {
                pieces.push(s);
            }
        }

        // horizontal
        for row in 0..self.height() {
            let mut coordinates = vec![];

            for col in 0..self.width() {
                coordinates.push((row, col));
            }

            let new_pieces = self.get_sequential_pieces(coordinates);

            for s in new_pieces {
                pieces.push(s);
            }
        }

        // diagonal up by row, looks like /
        for starting_row in 0..self.height() {
            let mut coordinates = vec![];

            for (row, col) in (0...starting_row).rev().zip(0..self.width()) {
                coordinates.push((row, col));
            }

            let new_pieces = self.get_sequential_pieces(coordinates);

            for s in new_pieces {
                pieces.push(s);
            }
        }

        // diagonal up by col, looks like /
        for starting_col in 1..self.width() {
            let mut coordinates = vec![];

            for (row, col) in (0..self.height()).rev().zip(starting_col..self.width()) {
                coordinates.push((row, col));
            }

            let new_pieces = self.get_sequential_pieces(coordinates);

            for s in new_pieces {
                pieces.push(s);
            }
        }

        // diagonal down by row, looks like \
        for starting_row in 0..self.height() {
            let mut coordinates = vec![];

            for (row, col) in (starting_row..self.height()).zip(0..self.width()) {
                coordinates.push((row, col));
            }

            let new_pieces = self.get_sequential_pieces(coordinates);

            for s in new_pieces {
                pieces.push(s);
            }
        }

        pieces
    }

    pub fn clear_all(&mut self, pieces: Vec<Piece>) {
    }

    pub fn get_lowest_free_row_in_col(&self, col: usize) -> usize {
        self.color_matrix.iter()
            .rposition(|row| row.get(col).unwrap_or(&None).is_none())
            .unwrap()
    }
}

#[cfg(test)]
mod tests {
    use board::Board;
    use color::Color::*;
    use game::Piece;

    #[test]
    fn get_pieces_to_clear_diagonal_down() {
        let board = Board {
            color_matrix: vec![
                vec![ Some(Red), None, None, None ],
                vec![ None, Some(Red), None, None ],
                vec![ None, None, Some(Red), None ],
                vec![ None, None, None, Some(Red) ],
            ],
        };

        let mut expected_pieces_to_clear = vec![
            Piece { row: 0, col: 0, color: Red },
            Piece { row: 1, col: 1, color: Red },
            Piece { row: 2, col: 2, color: Red },
            Piece { row: 3, col: 3, color: Red },
        ];

        let mut pieces_to_clear = board.get_pieces_to_clear();

        expected_pieces_to_clear.sort();
        pieces_to_clear.sort();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_diagonal_up() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None, None, Some(Red) ],
                vec![ None, None, Some(Red), None ],
                vec![ None, Some(Red), None, None ],
                vec![ Some(Red), None, None, None ],
            ],
        };

        let mut expected_pieces_to_clear = vec![
            Piece { row: 3, col: 0, color: Red },
            Piece { row: 2, col: 1, color: Red },
            Piece { row: 1, col: 2, color: Red },
            Piece { row: 0, col: 3, color: Red },
        ];

        let mut pieces_to_clear = board.get_pieces_to_clear();

        expected_pieces_to_clear.sort();
        pieces_to_clear.sort();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_diagonal_up_off_center_up() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None, None, Some(Red), None ],
                vec![ None, None, Some(Red), None, None ],
                vec![ None, Some(Red), None, None, None ],
                vec![ Some(Red), None, None, None, None ],
                vec![ None, None, None, None, None ],
            ],
        };

        let mut expected_pieces_to_clear = vec![
            Piece { row: 3, col: 0, color: Red },
            Piece { row: 2, col: 1, color: Red },
            Piece { row: 1, col: 2, color: Red },
            Piece { row: 0, col: 3, color: Red },
        ];

        let mut pieces_to_clear = board.get_pieces_to_clear();

        expected_pieces_to_clear.sort();
        pieces_to_clear.sort();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_diagonal_up_off_center_down() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None, None, None, None ],
                vec![ None, None, None, None, Some(Red) ],
                vec![ None, None, None, Some(Red), None ],
                vec![ None, None, Some(Red), None, None ],
                vec![ None, Some(Red), None, None, None ],
            ],
        };

        let mut expected_pieces_to_clear = vec![
            Piece { row: 4, col: 1, color: Red },
            Piece { row: 3, col: 2, color: Red },
            Piece { row: 2, col: 3, color: Red },
            Piece { row: 1, col: 4, color: Red },
        ];

        let mut pieces_to_clear = board.get_pieces_to_clear();

        expected_pieces_to_clear.sort();
        pieces_to_clear.sort();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_horizontal() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None, None, None ],
                vec![ None, None, None, None ],
                vec![ Some(Red), Some(Red), Some(Red), Some(Red) ],
                vec![ None, None, None, None ],
            ],
        };

        let expected_pieces_to_clear = vec![
            Piece { row: 2, col: 0, color: Red },
            Piece { row: 2, col: 1, color: Red },
            Piece { row: 2, col: 2, color: Red },
            Piece { row: 2, col: 3, color: Red },
        ];

        let pieces_to_clear = board.get_pieces_to_clear();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_vertical() {
        let board = Board {
            color_matrix: vec![
                vec![ Some(Red), None ],
                vec![ Some(Red), None ],
                vec![ Some(Red), None ],
                vec![ Some(Red), None ],
                vec![ Some(Yellow), None ],
            ],
        };

        let expected_pieces_to_clear = vec![
            Piece { row: 0, col: 0, color: Red },
            Piece { row: 1, col: 0, color: Red },
            Piece { row: 2, col: 0, color: Red },
            Piece { row: 3, col: 0, color: Red },
        ];

        let pieces_to_clear = board.get_pieces_to_clear();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn get_pieces_to_clear_vertical_none_eligible() {
        let board = Board {
            color_matrix: vec![
                vec![ Some(Red), None ],
                vec![ Some(Blue), None ],
                vec![ Some(Red), None ],
                vec![ Some(Red), None ],
            ],
        };

        let expected_pieces_to_clear: Vec<Piece> = vec![];

        let pieces_to_clear = board.get_pieces_to_clear();

        assert_eq!(expected_pieces_to_clear, pieces_to_clear);
    }

    #[test]
    fn set_a_color() {
        let mut board = Board {
            color_matrix: vec![
                vec![ Some(Red), Some(Red) ],
                vec![ Some(Red), Some(Red) ],
            ],
        };

        board.set(1, 1, Yellow);

        let expected_board = Board {
            color_matrix: vec![
                vec![ Some(Red), Some(Red) ],
                vec![ Some(Red), Some(Yellow) ],
            ],
        };

        assert_eq!(expected_board, board);
    }

    #[test]
    fn get_a_color() {
        let board = Board {
            color_matrix: vec![
                vec![ Some(Red), Some(Blue) ],
                vec![ Some(Red), Some(Yellow) ],
            ],
        };

        let color = board.get(0, 1);

        let expected_color = Some(Blue);

        assert_eq!(expected_color, color);
    }

    #[test]
    fn get_lowest_free_row_in_col() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None ],
                vec![ None, None ],
            ],
        };

        let row = board.get_lowest_free_row_in_col(0);
        let expected_row = 1;

        assert_eq!(expected_row, row);
    }

    #[test]
    fn get_lowest_free_row_in_col_with_another_existing_piece() {
        let board = Board {
            color_matrix: vec![
                vec![ None, None ],
                vec![ Some(Red), None ],
            ],
        };

        let row = board.get_lowest_free_row_in_col(0);
        let expected_row = 0;

        assert_eq!(expected_row, row);
    }
}
<|endoftext|>


<commit_before>use std::rc::{self, Rc};
use std::sync::{self, Arc};

/// Trait for generalizing downgrading a strong reference to a weak reference.
pub trait Downgrade
where
    Self: Sized,
{
    /// Weak reference type.
    type Weak;

    /// Downgrade to a weak reference.
    fn downgrade(&self) -> Self::Weak;
}

/// Trait for generalizing upgrading a weak reference to a strong reference.
pub trait Upgrade
where
    Self: Sized,
{
    /// Strong reference type.
    type Strong;

    /// Try upgrading a weak reference to a strong reference.
    fn upgrade(&self) -> Option<Self::Strong>;
}

impl<T: Downgrade + crate::ObjectType> Upgrade for crate::WeakRef<T> {
    type Strong = T;

    fn upgrade(&self) -> Option<Self::Strong> {
        self.upgrade()
    }
}

impl<T: Downgrade> Downgrade for &T {
    type Weak = T::Weak;

    fn downgrade(&self) -> Self::Weak {
        T::downgrade(*self)
    }
}

impl<T> Downgrade for Arc<T> {
    type Weak = sync::Weak<T>;

    fn downgrade(&self) -> Self::Weak {
        Arc::downgrade(self)
    }
}

impl<T> Upgrade for sync::Weak<T> {
    type Strong = Arc<T>;

    fn upgrade(&self) -> Option<Self::Strong> {
        self.upgrade()
    }
}

impl<T> Downgrade for Rc<T> {
    type Weak = rc::Weak<T>;

    fn downgrade(&self) -> Self::Weak {
        Rc::downgrade(self)
    }
}

impl<T> Upgrade for rc::Weak<T> {
    type Strong = Rc<T>;

    fn upgrade(&self) -> Option<Self::Strong> {
        self.upgrade()
    }
}

#[doc(hidden)]
#[macro_export]
macro_rules! to_type_before {
    (_) => ();
    ($variable:ident) => (
        compile_error!("You need to specify if this is a weak or a strong clone.");
    );
    (@strong $variable:ident) => (
        let $variable = $variable.clone();
    );
    (@weak $variable:ident) => (
        let $variable = $crate::clone::Downgrade::downgrade(&$variable);
    );
    (@ $keyword:ident $variable:ident) => (
        compile_error!("Unknown keyword, only `weak` and `strong` are allowed");
    );
}

#[doc(hidden)]
#[macro_export]
macro_rules! to_type_after {
    (@weak self, $return_value:expr) => {};
    (@strong self, $return_value:expr) => {};
    (@default-panic, @weak $variable:ident) => {
        let $variable = match $crate::clone::Upgrade::upgrade(&$variable) {
            Some(val) => val,
            None => panic!("failed to upgrade {}", stringify!($variable)),
        };
    };
    (@default-panic, @strong $variable:ident) => {};
    (@weak $variable:ident , $return_value:expr) => {
        let $variable = match $crate::clone::Upgrade::upgrade(&$variable) {
            Some(val) => val,
            None => return ($return_value)(),
        };
    };
    (@strong $variable:ident , $return_value:expr) => {};
    (@ $keyword:ident $variable:ident, $return_value:expr) => {};
}

#[doc(hidden)]
#[macro_export]
macro_rules! to_return_value {
    () => {
        ()
    };
    ($value:expr) => {
        $value
    };
}

/// Macro for passing variables as strong or weak references into a closure.
///
/// This macro can be useful in combination with closures, e.g. signal handlers, to reduce the
/// boilerplate required for passing strong or weak references into the closure. It will
/// automatically create the new reference and pass it with the same name into the closure.
///
/// If upgrading the weak reference to a strong reference inside the closure is failing, the
/// closure is immediately returning an optional default return value. If none is provided, `()` is
/// returned.
///
/// ### Passing a strong reference
///
/// ```
/// use glib::clone;
/// use std::rc::Rc;
///
/// let v = Rc::new(1);
/// let closure = clone!(@strong v => move |x| {
///     println!("v: {}, x: {}", v, x);
/// });
///
/// closure(2);
/// ```
///
/// ### Passing a strong and weak reference
///
/// ```
/// use glib::clone;
/// use std::rc::Rc;
///
/// let v = Rc::new(1);
/// let u = Rc::new(2);
/// let closure = clone!(@strong v, @weak u => move |x| {
///     println!("v: {}, u: {}, x: {}", v, u, x);
/// });
///
/// closure(3);
/// ```
///
/// ### Providing a default return value if upgrading a weak reference fails
///
/// You can do it in two different ways:
///
/// Either by providing the value yourself using `@default-return`:
///
/// ```
/// use glib::clone;
/// use std::rc::Rc;
///
/// let v = Rc::new(1);
/// let closure = clone!(@weak v => @default-return false, move |x| {
///     println!("v: {}, x: {}", v, x);
///     true
/// });
///
/// // Drop value so that the weak reference can't be upgraded.
/// drop(v);
///
/// assert_eq!(closure(2), false);
/// ```
///
/// Or by using `@default-panic` (if the value fails to get upgraded, it'll panic):
///
/// ```run_fail
/// # use glib::clone;
/// # use std::rc::Rc;
/// # let v = Rc::new(1);
/// let closure = clone!(@weak v => @default-panic, move |x| {
///     println!("v: {}, x: {}", v, x);
///     true
/// });
/// # drop(v);
/// # assert_eq!(closure(2), false);
/// ```
///
/// ### Errors
///
/// Here is a list of errors you might encounter:
///
/// **Missing `@weak` or `@strong`**:
///
/// ```compile_fail
/// # use glib::clone;
/// # use std::rc::Rc;
/// let v = Rc::new(1);
///
/// let closure = clone!(v => move |x| {
///     println!("v: {}, x: {}", v, x);
/// });
/// ```
///
/// **Passing `self` as an argument**:
///
/// ```compile_fail
/// # use glib::clone;
/// # use std::rc::Rc;
/// struct Foo;
///
/// impl Foo {
///     fn foo(&self) {
///         let v = Rc::new(1);
///
///         let closure = clone!(@strong self => move |x| {
///             println!("v: {}, x: {}", v, x);
///         });
///     }
/// }
#[macro_export]
macro_rules! clone {
    ($($(@ $strength:ident)? self),+ => $($_:tt)* ) => (
        compile_error!("Can't use `self` as variable name. Try storing it in a temporary variable.");
    );
    ($($(@ $strength:ident)? $variables:ident),+ => @default-panic, move || $body:block ) => (
        {
            $( $crate::to_type_before!($(@ $strength)? $variables); )*
            move || {
                $( $crate::to_type_after!(@default-panic, $(@ $strength)? $variables );)*
                $body
            }
        }
    );
    ($($(@ $strength:ident)? $variables:ident),+ => $(@default-return $return_value:expr,)? move || $body:block ) => (
        {
            $( $crate::to_type_before!($(@ $strength)? $variables); )*
            move || {
                let return_value = || $crate::to_return_value!($($return_value)?);
                $( $crate::to_type_after!($(@ $strength)? $variables, return_value );)*
                $body
            }
        }
    );
    ($($(@ $strength:ident)? $variables:ident),+ => @default-panic, move | $($pattern:pat),* | $body:block ) => (
        {
            $( $crate::to_type_before!($(@ $strength)? $variables); )*
            move |$($pattern),*| {
                $( $crate::to_type_after!(@default-panic, $(@ $strength)? $variables );)*
                $body
            }
        }
    );
    ($($(@ $strength:ident)? $variables:ident),+ => $(@default-return $return_value:expr,)? move | $($pattern:pat),* | $body:block ) => (
        {
            $( $crate::to_type_before!($(@ $strength)? $variables); )*
            move |$($pattern),*| {
                let return_value = || $crate::to_return_value!($($return_value)?);
                $( $crate::to_type_after!($(@ $strength)? $variables, return_value );)*
                $body
            }
        }
    );
    ($($(@ $strength:ident)? $variables:expr),+ => $($_:tt)* ) => (
        compile_error!("Variables need to be valid identifiers, e.g. field accesses are not allowed");
    );
}
<commit_msg>fmt pass<commit_after>use std::rc::{self, Rc};
use std::sync::{self, Arc};

/// Trait for generalizing downgrading a strong reference to a weak reference.
pub trait Downgrade
where
    Self: Sized,
{
    /// Weak reference type.
    type Weak;

    /// Downgrade to a weak reference.
    fn downgrade(&self) -> Self::Weak;
}

/// Trait for generalizing upgrading a weak reference to a strong reference.
pub trait Upgrade
where
    Self: Sized,
{
    /// Strong reference type.
    type Strong;

    /// Try upgrading a weak reference to a strong reference.
    fn upgrade(&self) -> Option<Self::Strong>;
}

impl<T: Downgrade + crate::ObjectType> Upgrade for crate::WeakRef<T> {
    type Strong = T;

    fn upgrade(&self) -> Option<Self::Strong> {
        self.upgrade()
    }
}

impl<T: Downgrade> Downgrade for &T {
    type Weak = T::Weak;

    fn downgrade(&self) -> Self::Weak {
        T::downgrade(*self)
    }
}

impl<T> Downgrade for Arc<T> {
    type Weak = sync::Weak<T>;

    fn downgrade(&self) -> Self::Weak {
        Arc::downgrade(self)
    }
}

impl<T> Upgrade for sync::Weak<T> {
    type Strong = Arc<T>;

    fn upgrade(&self) -> Option<Self::Strong> {
        self.upgrade()
    }
}

impl<T> Downgrade for Rc<T> {
    type Weak = rc::Weak<T>;

    fn downgrade(&self) -> Self::Weak {
        Rc::downgrade(self)
    }
}

impl<T> Upgrade for rc::Weak<T> {
    type Strong = Rc<T>;

    fn upgrade(&self) -> Option<Self::Strong> {
        self.upgrade()
    }
}

#[doc(hidden)]
#[macro_export]
macro_rules! to_type_before {
    (_) => {};
    ($variable:ident) => {
        compile_error!("You need to specify if this is a weak or a strong clone.");
    };
    (@strong $variable:ident) => {
        let $variable = $variable.clone();
    };
    (@weak $variable:ident) => {
        let $variable = $crate::clone::Downgrade::downgrade(&$variable);
    };
    (@ $keyword:ident $variable:ident) => {
        compile_error!("Unknown keyword, only `weak` and `strong` are allowed");
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! to_type_after {
    (@weak self, $return_value:expr) => {};
    (@strong self, $return_value:expr) => {};
    (@default-panic, @weak $variable:ident) => {
        let $variable = match $crate::clone::Upgrade::upgrade(&$variable) {
            Some(val) => val,
            None => panic!("failed to upgrade {}", stringify!($variable)),
        };
    };
    (@default-panic, @strong $variable:ident) => {};
    (@weak $variable:ident , $return_value:expr) => {
        let $variable = match $crate::clone::Upgrade::upgrade(&$variable) {
            Some(val) => val,
            None => return ($return_value)(),
        };
    };
    (@strong $variable:ident , $return_value:expr) => {};
    (@ $keyword:ident $variable:ident, $return_value:expr) => {};
}

#[doc(hidden)]
#[macro_export]
macro_rules! to_return_value {
    () => {
        ()
    };
    ($value:expr) => {
        $value
    };
}

/// Macro for passing variables as strong or weak references into a closure.
///
/// This macro can be useful in combination with closures, e.g. signal handlers, to reduce the
/// boilerplate required for passing strong or weak references into the closure. It will
/// automatically create the new reference and pass it with the same name into the closure.
///
/// If upgrading the weak reference to a strong reference inside the closure is failing, the
/// closure is immediately returning an optional default return value. If none is provided, `()` is
/// returned.
///
/// ### Passing a strong reference
///
/// ```
/// use glib::clone;
/// use std::rc::Rc;
///
/// let v = Rc::new(1);
/// let closure = clone!(@strong v => move |x| {
///     println!("v: {}, x: {}", v, x);
/// });
///
/// closure(2);
/// ```
///
/// ### Passing a strong and weak reference
///
/// ```
/// use glib::clone;
/// use std::rc::Rc;
///
/// let v = Rc::new(1);
/// let u = Rc::new(2);
/// let closure = clone!(@strong v, @weak u => move |x| {
///     println!("v: {}, u: {}, x: {}", v, u, x);
/// });
///
/// closure(3);
/// ```
///
/// ### Providing a default return value if upgrading a weak reference fails
///
/// You can do it in two different ways:
///
/// Either by providing the value yourself using `@default-return`:
///
/// ```
/// use glib::clone;
/// use std::rc::Rc;
///
/// let v = Rc::new(1);
/// let closure = clone!(@weak v => @default-return false, move |x| {
///     println!("v: {}, x: {}", v, x);
///     true
/// });
///
/// // Drop value so that the weak reference can't be upgraded.
/// drop(v);
///
/// assert_eq!(closure(2), false);
/// ```
///
/// Or by using `@default-panic` (if the value fails to get upgraded, it'll panic):
///
/// ```run_fail
/// # use glib::clone;
/// # use std::rc::Rc;
/// # let v = Rc::new(1);
/// let closure = clone!(@weak v => @default-panic, move |x| {
///     println!("v: {}, x: {}", v, x);
///     true
/// });
/// # drop(v);
/// # assert_eq!(closure(2), false);
/// ```
///
/// ### Errors
///
/// Here is a list of errors you might encounter:
///
/// **Missing `@weak` or `@strong`**:
///
/// ```compile_fail
/// # use glib::clone;
/// # use std::rc::Rc;
/// let v = Rc::new(1);
///
/// let closure = clone!(v => move |x| {
///     println!("v: {}, x: {}", v, x);
/// });
/// ```
///
/// **Passing `self` as an argument**:
///
/// ```compile_fail
/// # use glib::clone;
/// # use std::rc::Rc;
/// struct Foo;
///
/// impl Foo {
///     fn foo(&self) {
///         let v = Rc::new(1);
///
///         let closure = clone!(@strong self => move |x| {
///             println!("v: {}, x: {}", v, x);
///         });
///     }
/// }
#[macro_export]
macro_rules! clone {
    ($($(@ $strength:ident)? self),+ => $($_:tt)* ) => (
        compile_error!("Can't use `self` as variable name. Try storing it in a temporary variable.");
    );
    ($($(@ $strength:ident)? $variables:ident),+ => @default-panic, move || $body:block ) => (
        {
            $( $crate::to_type_before!($(@ $strength)? $variables); )*
            move || {
                $( $crate::to_type_after!(@default-panic, $(@ $strength)? $variables );)*
                $body
            }
        }
    );
    ($($(@ $strength:ident)? $variables:ident),+ => $(@default-return $return_value:expr,)? move || $body:block ) => (
        {
            $( $crate::to_type_before!($(@ $strength)? $variables); )*
            move || {
                let return_value = || $crate::to_return_value!($($return_value)?);
                $( $crate::to_type_after!($(@ $strength)? $variables, return_value );)*
                $body
            }
        }
    );
    ($($(@ $strength:ident)? $variables:ident),+ => @default-panic, move | $($pattern:pat),* | $body:block ) => (
        {
            $( $crate::to_type_before!($(@ $strength)? $variables); )*
            move |$($pattern),*| {
                $( $crate::to_type_after!(@default-panic, $(@ $strength)? $variables );)*
                $body
            }
        }
    );
    ($($(@ $strength:ident)? $variables:ident),+ => $(@default-return $return_value:expr,)? move | $($pattern:pat),* | $body:block ) => (
        {
            $( $crate::to_type_before!($(@ $strength)? $variables); )*
            move |$($pattern),*| {
                let return_value = || $crate::to_return_value!($($return_value)?);
                $( $crate::to_type_after!($(@ $strength)? $variables, return_value );)*
                $body
            }
        }
    );
    ($($(@ $strength:ident)? $variables:expr),+ => $($_:tt)* ) => (
        compile_error!("Variables need to be valid identifiers, e.g. field accesses are not allowed");
    );
}
<|endoftext|>


<commit_before>//! Utilities for encoding and decoding frames.
//!
//! Contains adapters to go from strams of bytes, [`AsyncRead`] and
//! [`AsyncWrite`], to framed streams implementing [`Sink`] and [`Stream`].
//! Framed streams are also known as [transports].
//!
//! [`AsyncRead`]: #
//! [`AsyncWrite`]: #
//! [`Sink`]: #
//! [`Stream`]: #
//! [transports]: #

pub use framed::Framed;
pub use framed_read::{FramedRead, Decoder};
pub use framed_write::{FramedWrite, Encoder};

pub mod length_delimited {
    //! Frame a stream of bytes based on a length prefix
    //!
    //! Many protocols delimit their frames by prefacing frame data with a
    //! frame head that specifies the length of the frame. The
    //! `length_delimited` module provides utilities for handling the length
    //! based framing. This allows the consumer to work with entire frames
    //! without having to worry about buffering or other framing logic.
    //!
    //! # Getting started
    //!
    //! If implementing a protocol from scratch, using length delimited framing
    //! is an easy way to get started. [`Framed::new()`] will adapt a
    //! full-duplex byte stream with a length delimited framer using default
    //! configuration values.
    //!
    //! ```
    //! use tokio_io::{AsyncRead, AsyncWrite};
    //! use tokio_io::codec::length_delimited;
    //!
    //! fn bind_transport<T: AsyncRead + AsyncWrite>(io: T)
    //!     -> length_delimited::Framed<T>
    //! {
    //!     length_delimited::Framed::new(io)
    //! }
    //! ```
    //!
    //! The returned transport implements `Sink + Stream` for `BytesMut`. It
    //! encodes the frame with a big-endian `u32` header denotating the frame
    //! payload length:
    //!
    //! ```text
    //! +----------+--------------------------------+
    //! | len: u32 |          frame payload         |
    //! +----------+--------------------------------+
    //! ```
    //!
    //! Specifically, given the following:
    //!
    //! ```
    //! # extern crate tokio_io;
    //! # extern crate bytes;
    //! # extern crate futures;
    //! #
    //! use tokio_io::{AsyncRead, AsyncWrite};
    //! use tokio_io::codec::length_delimited;
    //! use bytes::BytesMut;
    //! use futures::{Sink, Future};
    //!
    //! fn write_frame<T: AsyncRead + AsyncWrite>(io: T) {
    //!     let mut transport = length_delimited::Framed::new(io);
    //!     let frame = BytesMut::from("hello world");
    //!
    //!     transport.send(frame).wait().unwrap();
    //! }
    //! #
    //! # pub fn main() {}
    //! ```
    //!
    //! The encoded frame will look like this:
    //!
    //! ```text
    //! +---- len: u32 ----+---- data ----+
    //! | \x00\x00\x00\x0b |  hello world |
    //! +------------------+--------------+
    //! ```
    //!
    //! # Decoding
    //!
    //! [`FramedRead`] adapts an [`AsyncRead`] into a `Stream` of [`BytesMut`],
    //! such that each yielded [`BytesMut`] value contains the contents of an
    //! entire frame. There are many configuration paramaters enabling
    //! [`FrameRead`] to handle a wide range of protocols. Here are some
    //! examples that will cover the various options at a high level.
    //!
    //! ## Example 1
    //!
    //! The following will parse a `u16` length field at offset 0, including the
    //! frame head in the yielded `BytesMut`.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(0) // default value
    //!     .length_field_length(2)
    //!     .length_adjustment(0)   // default value
    //!     .num_skip(0) // Do not strip frame header
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!          INPUT                           DECODED
    //! +-- len ---+--- Payload ---+     +-- len ---+--- Payload ---+
    //! | \x00\x0B |  Hello world  | --> | \x00\x0B |  Hello world  |
    //! +----------+---------------+     +----------+---------------+
    //! ```
    //!
    //! The value of the length field is 11 (`\x0B`) which represents the length
    //! of the payload, `hello world`. By default, [`FramedRead`] assumes that
    //! the length field represents the number of bytes that **follows** the
    //! length field. Thus, the entire frame has a length of 13: 2 bytes for the
    //! frame head + 11 bytes for the payload.
    //!
    //! ## Example 2
    //!
    //! The following will parse a `u16` length field at offset 0, omitting the
    //! frame head in the yielded `BytesMut`.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(0) // default value
    //!     .length_field_length(2)
    //!     .length_adjustment(0)   // default value
    //!     // `num_skip` is not needed, the default is to skip
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!          INPUT                        DECODED
    //! +-- len ---+--- Payload ---+     +--- Payload ---+
    //! | \x00\x0B |  Hello world  | --> |  Hello world  |
    //! +----------+---------------+     +---------------+
    //! ```
    //!
    //! This is similar to the first example, the only difference is that the
    //! frame head is **not** included in the yielded `BytesMut` value.
    //!
    //! ## Example 3
    //!
    //! The following will parse a `u16` length field at offset 0, including the
    //! frame head in the yielded `BytesMut`. In this case, the length field
    //! **includes** the frame head length.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(0) // default value
    //!     .length_field_length(2)
    //!     .length_adjustment(-2)  // size of head
    //!     .num_skip(0)
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!          INPUT                           DECODED
    //! +-- len ---+--- Payload ---+     +-- len ---+--- Payload ---+
    //! | \x00\x0D |  Hello world  | --> | \x00\x0D |  Hello world  |
    //! +----------+---------------+     +----------+---------------+
    //! ```
    //!
    //! In most cases, the length field represents the length of the payload
    //! only, as shown in the previous examples. However, in some protocols the
    //! length field represents the length of the whole frame, including the
    //! head. In such cases, we specify a negative `length_adjustment` to adjust
    //! the value provided in the frame head to represent the payload length.
    //!
    //! ## Example 4
    //!
    //! The following will parse a 3 byte length field at offset 0 in a 5 byte
    //! frame head, including the frame head in the yielded `BytesMut`.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(0) // default value
    //!     .length_field_length(3)
    //!     .length_adjustment(2)  // remaining head
    //!     .num_skip(0)
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!                  INPUT
    //! +---- len -----+- head -+--- Payload ---+
    //! | \x00\x00\x0B | \xCAFE |  Hello world  |
    //! +--------------+--------+---------------+
    //!
    //!                  DECODED
    //! +---- len -----+- head -+--- Payload ---+
    //! | \x00\x00\x0B | \xCAFE |  Hello world  |
    //! +--------------+--------+---------------+
    //! ```
    //!
    //! A more advanced example that shows a case where there is extra frame
    //! head data between the length field and the payload. In such cases, it is
    //! usually desirable to include the frame head as part of the yielded
    //! `BytesMut`. This lets consumers of the length delimited framer to
    //! process the frame head as needed.
    //!
    //! The positive `length_adjustment` value lets `FramedRead` factor in the
    //! additional head into the frame length calculation.
    //!
    //! ## Example 5
    //!
    //! The following will parse a `u16` length field at offset 1 of a 4 byte
    //! frame head. The first byte and the length field will be omitted from the
    //! yielded `BytesMut`, but the trailing 2 bytes of the frame head will be
    //! included.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(1) // length of hdr1
    //!     .length_field_length(2)
    //!     .length_adjustment(1)  // length of hdr2
    //!     .num_skip(3) // length of hdr1 + LEN
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!                  INPUT
    //! +- hdr1 -+-- len ---+- hdr2 -+--- Payload ---+
    //! |  \xCA  | \x00\x0B |  \xFE  |  Hello world  |
    //! +--------+----------+--------+---------------+
    //!
    //!          DECODED
    //! +- hdr2 -+--- Payload ---+
    //! |  \xFE  |  Hello world  |
    //! +--------+---------------+
    //! ```
    //!
    //! The length field is situated in the middle of the frame head. In this
    //! case, the first byte in the frame head could be a version or some other
    //! identifier that is not needed for processing. On the other hand, the
    //! second half of the head is needed.
    //!
    //! `length_field_offset` indicates how many bytes to skip before starting
    //! to read the length field.  `length_adjustment` is the number of bytes to
    //! skip starting at the end of the length field. In this case, it is the
    //! second half of the head.
    //!
    //! ## Example 6
    //!
    //! The following will parse a `u16` length field at offset 1 of a 4 byte
    //! frame head. The first byte and the length field will be omitted from the
    //! yielded `BytesMut`, but the trailing 2 bytes of the frame head will be
    //! included. In this case, the length field **includes** the frame head
    //! length.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(1) // length of hdr1
    //!     .length_field_length(2)
    //!     .length_adjustment(-3)  // length of hdr1 + LEN, negative
    //!     .num_skip(3)
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!                  INPUT
    //! +- hdr1 -+-- len ---+- hdr2 -+--- Payload ---+
    //! |  \xCA  | \x00\x0F |  \xFE  |  Hello world  |
    //! +--------+----------+--------+---------------+
    //!
    //!          DECODED
    //! +- hdr2 -+--- Payload ---+
    //! |  \xFE  |  Hello world  |
    //! +--------+---------------+
    //! ```
    //!
    //! Similar to the example above, the difference is that the length field
    //! represents the length of the entire frame instead of just the payload.
    //! The length of `hdr1` and `len` must be counted in `length_adjustment`.
    //! Note that the length of `hdr2` does **not** need to be explicitly set
    //! anywhere because it already is factored into the total frame length that
    //! is read from the byte stream.
    //!
    //! # Encoding
    //!
    //! [`FramedWrite`] adapts an [`AsyncWrite`] into a `Sink` of [`BytesMut`],
    //! such that each submitted [`BytesMut`] is prefaced by a length field.
    //! There are fewer configuration options than [`FramedRead`]. Given
    //! protocols that have more complex frame heads, an encoder should probably
    //! be written by hand using [`Encoder`].
    //!
    //! Here is a simple example, given a `FramedWrite` with the following
    //! configuration:
    //!
    //! ```
    //! # extern crate tokio_io;
    //! # extern crate bytes;
    //! # use tokio_io::AsyncWrite;
    //! # use tokio_io::codec::length_delimited;
    //! # use bytes::BytesMut;
    //! # fn write_frame<T: AsyncWrite>(io: T) {
    //! # let _: length_delimited::FramedWrite<T, BytesMut> =
    //! length_delimited::Builder::new()
    //!     .length_field_length(2)
    //!     .new_write(io);
    //! # }
    //! # pub fn main() {}
    //! ```
    //!
    //! A payload of `hello world` will be encoded as:
    //!
    //! ```text
    //! +- len: u16 -+---- data ----+
    //! |  \x00\x0b  |  hello world |
    //! +------------+--------------+
    //! ```
    //!
    //! [`FramedRead`]: struct.FramedRead.html
    //! [`FramedWrite`]: struct.FramedWrite.html
    //! [`AsyncRead`]: ../../trait.AsyncRead.html
    //! [`AsyncWrite`]: ../../trait.AsyncWrite.html
    //! [`Encoder`]: ../trait.Encoder.html
    //! [`BytesMut`]: https://docs.rs/bytes/~0.4/bytes/struct.BytesMut.html

    pub use ::length_delimited::*;
}
<commit_msg>Fix typo in codec module docs<commit_after>//! Utilities for encoding and decoding frames.
//!
//! Contains adapters to go from streams of bytes, [`AsyncRead`] and
//! [`AsyncWrite`], to framed streams implementing [`Sink`] and [`Stream`].
//! Framed streams are also known as [transports].
//!
//! [`AsyncRead`]: #
//! [`AsyncWrite`]: #
//! [`Sink`]: #
//! [`Stream`]: #
//! [transports]: #

pub use framed::Framed;
pub use framed_read::{FramedRead, Decoder};
pub use framed_write::{FramedWrite, Encoder};

pub mod length_delimited {
    //! Frame a stream of bytes based on a length prefix
    //!
    //! Many protocols delimit their frames by prefacing frame data with a
    //! frame head that specifies the length of the frame. The
    //! `length_delimited` module provides utilities for handling the length
    //! based framing. This allows the consumer to work with entire frames
    //! without having to worry about buffering or other framing logic.
    //!
    //! # Getting started
    //!
    //! If implementing a protocol from scratch, using length delimited framing
    //! is an easy way to get started. [`Framed::new()`] will adapt a
    //! full-duplex byte stream with a length delimited framer using default
    //! configuration values.
    //!
    //! ```
    //! use tokio_io::{AsyncRead, AsyncWrite};
    //! use tokio_io::codec::length_delimited;
    //!
    //! fn bind_transport<T: AsyncRead + AsyncWrite>(io: T)
    //!     -> length_delimited::Framed<T>
    //! {
    //!     length_delimited::Framed::new(io)
    //! }
    //! ```
    //!
    //! The returned transport implements `Sink + Stream` for `BytesMut`. It
    //! encodes the frame with a big-endian `u32` header denotating the frame
    //! payload length:
    //!
    //! ```text
    //! +----------+--------------------------------+
    //! | len: u32 |          frame payload         |
    //! +----------+--------------------------------+
    //! ```
    //!
    //! Specifically, given the following:
    //!
    //! ```
    //! # extern crate tokio_io;
    //! # extern crate bytes;
    //! # extern crate futures;
    //! #
    //! use tokio_io::{AsyncRead, AsyncWrite};
    //! use tokio_io::codec::length_delimited;
    //! use bytes::BytesMut;
    //! use futures::{Sink, Future};
    //!
    //! fn write_frame<T: AsyncRead + AsyncWrite>(io: T) {
    //!     let mut transport = length_delimited::Framed::new(io);
    //!     let frame = BytesMut::from("hello world");
    //!
    //!     transport.send(frame).wait().unwrap();
    //! }
    //! #
    //! # pub fn main() {}
    //! ```
    //!
    //! The encoded frame will look like this:
    //!
    //! ```text
    //! +---- len: u32 ----+---- data ----+
    //! | \x00\x00\x00\x0b |  hello world |
    //! +------------------+--------------+
    //! ```
    //!
    //! # Decoding
    //!
    //! [`FramedRead`] adapts an [`AsyncRead`] into a `Stream` of [`BytesMut`],
    //! such that each yielded [`BytesMut`] value contains the contents of an
    //! entire frame. There are many configuration paramaters enabling
    //! [`FrameRead`] to handle a wide range of protocols. Here are some
    //! examples that will cover the various options at a high level.
    //!
    //! ## Example 1
    //!
    //! The following will parse a `u16` length field at offset 0, including the
    //! frame head in the yielded `BytesMut`.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(0) // default value
    //!     .length_field_length(2)
    //!     .length_adjustment(0)   // default value
    //!     .num_skip(0) // Do not strip frame header
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!          INPUT                           DECODED
    //! +-- len ---+--- Payload ---+     +-- len ---+--- Payload ---+
    //! | \x00\x0B |  Hello world  | --> | \x00\x0B |  Hello world  |
    //! +----------+---------------+     +----------+---------------+
    //! ```
    //!
    //! The value of the length field is 11 (`\x0B`) which represents the length
    //! of the payload, `hello world`. By default, [`FramedRead`] assumes that
    //! the length field represents the number of bytes that **follows** the
    //! length field. Thus, the entire frame has a length of 13: 2 bytes for the
    //! frame head + 11 bytes for the payload.
    //!
    //! ## Example 2
    //!
    //! The following will parse a `u16` length field at offset 0, omitting the
    //! frame head in the yielded `BytesMut`.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(0) // default value
    //!     .length_field_length(2)
    //!     .length_adjustment(0)   // default value
    //!     // `num_skip` is not needed, the default is to skip
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!          INPUT                        DECODED
    //! +-- len ---+--- Payload ---+     +--- Payload ---+
    //! | \x00\x0B |  Hello world  | --> |  Hello world  |
    //! +----------+---------------+     +---------------+
    //! ```
    //!
    //! This is similar to the first example, the only difference is that the
    //! frame head is **not** included in the yielded `BytesMut` value.
    //!
    //! ## Example 3
    //!
    //! The following will parse a `u16` length field at offset 0, including the
    //! frame head in the yielded `BytesMut`. In this case, the length field
    //! **includes** the frame head length.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(0) // default value
    //!     .length_field_length(2)
    //!     .length_adjustment(-2)  // size of head
    //!     .num_skip(0)
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!          INPUT                           DECODED
    //! +-- len ---+--- Payload ---+     +-- len ---+--- Payload ---+
    //! | \x00\x0D |  Hello world  | --> | \x00\x0D |  Hello world  |
    //! +----------+---------------+     +----------+---------------+
    //! ```
    //!
    //! In most cases, the length field represents the length of the payload
    //! only, as shown in the previous examples. However, in some protocols the
    //! length field represents the length of the whole frame, including the
    //! head. In such cases, we specify a negative `length_adjustment` to adjust
    //! the value provided in the frame head to represent the payload length.
    //!
    //! ## Example 4
    //!
    //! The following will parse a 3 byte length field at offset 0 in a 5 byte
    //! frame head, including the frame head in the yielded `BytesMut`.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(0) // default value
    //!     .length_field_length(3)
    //!     .length_adjustment(2)  // remaining head
    //!     .num_skip(0)
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!                  INPUT
    //! +---- len -----+- head -+--- Payload ---+
    //! | \x00\x00\x0B | \xCAFE |  Hello world  |
    //! +--------------+--------+---------------+
    //!
    //!                  DECODED
    //! +---- len -----+- head -+--- Payload ---+
    //! | \x00\x00\x0B | \xCAFE |  Hello world  |
    //! +--------------+--------+---------------+
    //! ```
    //!
    //! A more advanced example that shows a case where there is extra frame
    //! head data between the length field and the payload. In such cases, it is
    //! usually desirable to include the frame head as part of the yielded
    //! `BytesMut`. This lets consumers of the length delimited framer to
    //! process the frame head as needed.
    //!
    //! The positive `length_adjustment` value lets `FramedRead` factor in the
    //! additional head into the frame length calculation.
    //!
    //! ## Example 5
    //!
    //! The following will parse a `u16` length field at offset 1 of a 4 byte
    //! frame head. The first byte and the length field will be omitted from the
    //! yielded `BytesMut`, but the trailing 2 bytes of the frame head will be
    //! included.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(1) // length of hdr1
    //!     .length_field_length(2)
    //!     .length_adjustment(1)  // length of hdr2
    //!     .num_skip(3) // length of hdr1 + LEN
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!                  INPUT
    //! +- hdr1 -+-- len ---+- hdr2 -+--- Payload ---+
    //! |  \xCA  | \x00\x0B |  \xFE  |  Hello world  |
    //! +--------+----------+--------+---------------+
    //!
    //!          DECODED
    //! +- hdr2 -+--- Payload ---+
    //! |  \xFE  |  Hello world  |
    //! +--------+---------------+
    //! ```
    //!
    //! The length field is situated in the middle of the frame head. In this
    //! case, the first byte in the frame head could be a version or some other
    //! identifier that is not needed for processing. On the other hand, the
    //! second half of the head is needed.
    //!
    //! `length_field_offset` indicates how many bytes to skip before starting
    //! to read the length field.  `length_adjustment` is the number of bytes to
    //! skip starting at the end of the length field. In this case, it is the
    //! second half of the head.
    //!
    //! ## Example 6
    //!
    //! The following will parse a `u16` length field at offset 1 of a 4 byte
    //! frame head. The first byte and the length field will be omitted from the
    //! yielded `BytesMut`, but the trailing 2 bytes of the frame head will be
    //! included. In this case, the length field **includes** the frame head
    //! length.
    //!
    //! ```
    //! # use tokio_io::AsyncRead;
    //! # use tokio_io::codec::length_delimited;
    //! # fn bind_read<T: AsyncRead>(io: T) {
    //! length_delimited::Builder::new()
    //!     .length_field_offset(1) // length of hdr1
    //!     .length_field_length(2)
    //!     .length_adjustment(-3)  // length of hdr1 + LEN, negative
    //!     .num_skip(3)
    //!     .new_read(io);
    //! # }
    //! ```
    //!
    //! The following frame will be decoded as such:
    //!
    //! ```text
    //!                  INPUT
    //! +- hdr1 -+-- len ---+- hdr2 -+--- Payload ---+
    //! |  \xCA  | \x00\x0F |  \xFE  |  Hello world  |
    //! +--------+----------+--------+---------------+
    //!
    //!          DECODED
    //! +- hdr2 -+--- Payload ---+
    //! |  \xFE  |  Hello world  |
    //! +--------+---------------+
    //! ```
    //!
    //! Similar to the example above, the difference is that the length field
    //! represents the length of the entire frame instead of just the payload.
    //! The length of `hdr1` and `len` must be counted in `length_adjustment`.
    //! Note that the length of `hdr2` does **not** need to be explicitly set
    //! anywhere because it already is factored into the total frame length that
    //! is read from the byte stream.
    //!
    //! # Encoding
    //!
    //! [`FramedWrite`] adapts an [`AsyncWrite`] into a `Sink` of [`BytesMut`],
    //! such that each submitted [`BytesMut`] is prefaced by a length field.
    //! There are fewer configuration options than [`FramedRead`]. Given
    //! protocols that have more complex frame heads, an encoder should probably
    //! be written by hand using [`Encoder`].
    //!
    //! Here is a simple example, given a `FramedWrite` with the following
    //! configuration:
    //!
    //! ```
    //! # extern crate tokio_io;
    //! # extern crate bytes;
    //! # use tokio_io::AsyncWrite;
    //! # use tokio_io::codec::length_delimited;
    //! # use bytes::BytesMut;
    //! # fn write_frame<T: AsyncWrite>(io: T) {
    //! # let _: length_delimited::FramedWrite<T, BytesMut> =
    //! length_delimited::Builder::new()
    //!     .length_field_length(2)
    //!     .new_write(io);
    //! # }
    //! # pub fn main() {}
    //! ```
    //!
    //! A payload of `hello world` will be encoded as:
    //!
    //! ```text
    //! +- len: u16 -+---- data ----+
    //! |  \x00\x0b  |  hello world |
    //! +------------+--------------+
    //! ```
    //!
    //! [`FramedRead`]: struct.FramedRead.html
    //! [`FramedWrite`]: struct.FramedWrite.html
    //! [`AsyncRead`]: ../../trait.AsyncRead.html
    //! [`AsyncWrite`]: ../../trait.AsyncWrite.html
    //! [`Encoder`]: ../trait.Encoder.html
    //! [`BytesMut`]: https://docs.rs/bytes/~0.4/bytes/struct.BytesMut.html

    pub use ::length_delimited::*;
}
<|endoftext|>


<commit_before>// Copyright 2013 The color-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

#[link( author = "Brendan Zabarauskas", url = "https://github.com/bjz/color-rs")];

#[comment = "A library that provides types and conversions for working with
             various color formats."];
#[license = "ASL2"];
#[crate_type = "lib"];

#[feature(globs)];

pub use self::alpha::AlphaColor;
pub use self::channel::{Channel, FloatChannel};
pub use self::hsv::{HSV, ToHSV};
pub use self::rgb::{RGB, ToRGB};
pub use self::srgb::SRGB;
pub use self::ycbcr::YCbCr;

use std::num::{One, Zero};

pub mod alpha;
pub mod channel;
pub mod hsv;
pub mod rgb;
pub mod srgb;
pub mod ycbcr;

pub fn zero<T:Zero>() -> T { Zero::zero() }
pub fn one<T:One>() -> T { One::one() }

pub trait Color<T> {
    fn clamp_s(&self, lo: T, hi: T) -> Self;
    fn clamp_c(&self, lo: &Self, hi: &Self) -> Self;
    fn inverse(&self) -> Self;
    // fn mix(&self, other: &Self, value: T) -> Self;
    // fn saturation(&self, value: T) -> Self;
    // fn exposure(&self, value: T) -> Self;
    // fn brightness(&self, value: T) -> Self;
}

pub trait FloatColor<T>: Color<T> {
    fn normalize(&self) -> Self;
}
<commit_msg>Add crate name (rustdoc needs it)<commit_after>// Copyright 2013 The color-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

#[link(name="color", author = "Brendan Zabarauskas", url = "https://github.com/bjz/color-rs")];

#[comment = "A library that provides types and conversions for working with
             various color formats."];
#[license = "ASL2"];
#[crate_type = "lib"];

#[feature(globs)];

pub use self::alpha::AlphaColor;
pub use self::channel::{Channel, FloatChannel};
pub use self::hsv::{HSV, ToHSV};
pub use self::rgb::{RGB, ToRGB};
pub use self::srgb::SRGB;
pub use self::ycbcr::YCbCr;

use std::num::{One, Zero};

pub mod alpha;
pub mod channel;
pub mod hsv;
pub mod rgb;
pub mod srgb;
pub mod ycbcr;

pub fn zero<T:Zero>() -> T { Zero::zero() }
pub fn one<T:One>() -> T { One::one() }

pub trait Color<T> {
    fn clamp_s(&self, lo: T, hi: T) -> Self;
    fn clamp_c(&self, lo: &Self, hi: &Self) -> Self;
    fn inverse(&self) -> Self;
    // fn mix(&self, other: &Self, value: T) -> Self;
    // fn saturation(&self, value: T) -> Self;
    // fn exposure(&self, value: T) -> Self;
    // fn brightness(&self, value: T) -> Self;
}

pub trait FloatColor<T>: Color<T> {
    fn normalize(&self) -> Self;
}
<|endoftext|>


<commit_before>#[derive(Copy, Clone, Debug)]
pub struct Color(f32, f32, f32, f32);

impl Color {
    /// Scale the brightness of the color
    pub fn scale(self, factor: f32) -> Color {
        Color(self.0 * factor, self.1 * factor, self.2 * factor, self.3)
    }

    /// Scale the brightness of the color
    pub fn alpha(self, factor: f32) -> Color {
        Color(self.0, self.1, self.2, self.3 * factor)
    }
}

impl From<(u8, u8, u8, u8)> for Color {
    fn from(tup: (u8, u8, u8, u8)) -> Color {
        Color(
            tup.0 as f32 / 255.0,
            tup.1 as f32 / 255.0,
            tup.2 as f32 / 255.0,
            tup.3 as f32 / 255.0,
        )
    }
}

impl From<[u8; 4]> for Color {
    fn from(arr: [u8; 4]) -> Color {
        Color(
            arr[0] as f32 / 255.0,
            arr[1] as f32 / 255.0,
            arr[2] as f32 / 255.0,
            arr[3] as f32 / 255.0,
        )
    }
}

impl From<(f32, f32, f32, f32)> for Color {
    fn from(tup: (f32, f32, f32, f32)) -> Color {
        Color(tup.0, tup.1, tup.2, tup.3)
    }
}

impl From<[f32; 4]> for Color {
    fn from(arr: [f32; 4]) -> Color {
        Color(arr[0], arr[1], arr[2], arr[3])
    }
}

pub const WHITE: Color = Color(0.0, 0.0, 1.0, 1.0);
pub const RED: Color = Color(1.0, 0.0, 0.0, 1.0);
pub const GREEN: Color = Color(0.0, 1.0, 0.0, 1.0);
pub const BLUE: Color = Color(0.0, 0.0, 1.0, 1.0);
pub const YELLOW: Color = Color(1.0, 1.0, 0.0, 1.0);
pub const CYAN: Color = Color(0.0, 1.0, 1.0, 1.0);
pub const MAGENTA: Color = Color(1.0, 0.0, 1.0, 1.0);
<commit_msg>allow color to be a uniform<commit_after>use glium::uniforms::{AsUniformValue, UniformValue};

#[derive(Copy, Clone, Debug)]
pub struct Color(f32, f32, f32, f32);

impl Color {
    /// Scale the brightness of the color
    pub fn scale(self, factor: f32) -> Color {
        Color(self.0 * factor, self.1 * factor, self.2 * factor, self.3)
    }

    /// Scale the brightness of the color
    pub fn alpha(self, factor: f32) -> Color {
        Color(self.0, self.1, self.2, self.3 * factor)
    }
}

impl AsUniformValue for Color {
    fn as_uniform_value(&self) -> UniformValue {
        UniformValue::Vec4([self.0, self.1, self.2, self.3])
    }
}

impl From<(u8, u8, u8, u8)> for Color {
    fn from(tup: (u8, u8, u8, u8)) -> Color {
        Color(
            tup.0 as f32 / 255.0,
            tup.1 as f32 / 255.0,
            tup.2 as f32 / 255.0,
            tup.3 as f32 / 255.0,
        )
    }
}

impl From<[u8; 4]> for Color {
    fn from(arr: [u8; 4]) -> Color {
        Color(
            arr[0] as f32 / 255.0,
            arr[1] as f32 / 255.0,
            arr[2] as f32 / 255.0,
            arr[3] as f32 / 255.0,
        )
    }
}

impl From<(f32, f32, f32, f32)> for Color {
    fn from(tup: (f32, f32, f32, f32)) -> Color {
        Color(tup.0, tup.1, tup.2, tup.3)
    }
}

impl From<[f32; 4]> for Color {
    fn from(arr: [f32; 4]) -> Color {
        Color(arr[0], arr[1], arr[2], arr[3])
    }
}

pub const WHITE: Color = Color(0.0, 0.0, 1.0, 1.0);
pub const RED: Color = Color(1.0, 0.0, 0.0, 1.0);
pub const GREEN: Color = Color(0.0, 1.0, 0.0, 1.0);
pub const BLUE: Color = Color(0.0, 0.0, 1.0, 1.0);
pub const YELLOW: Color = Color(1.0, 1.0, 0.0, 1.0);
pub const CYAN: Color = Color(0.0, 1.0, 1.0, 1.0);
pub const MAGENTA: Color = Color(1.0, 0.0, 1.0, 1.0);
<|endoftext|>


<commit_before>// Copyright 2015-2017 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! The Resolver is responsible for performing recursive queries to lookup domain names.
//!
//! This is a 100% in process DNS resolver. It *does not* use the Host OS' resolver. If what is desired is to use the Host OS' resolver, generally in the system's libc, then the `std::net::ToSocketAddrs` variant over `&str` is what should be used. As of the initial release, `trust-dns-resolver` it does not currently support search paths or ndot recursive lookups. It only supports FQDN, where the name must be specified with the final dot, e.g. `www.example.com.`. This limitation will be removed in future releases.
//!
//! Unlike the `trust-dns` client, this tries to provide a simpler interface to perform DNS queries. For update options, i.e. Dynamic DNS, the `trust-dns` crate must be used directly.
//!
//! There are two types for performing DNS queries, `Resolver` and `ResolverFuture`. `Resolver` is the easiest to work with, it is a wrapper around `ResolverFuture`. `ResolverFuture` is a `Tokio` based async resolver, and can be used inside any `Tokio` based system.
//!
//! *Notes on current limitations*: DNSSec is not yet supported in the Resolver, use the `trust-dns` Client if DNSSec validation is needed. Many standard system options and configurations are not yet supported. The host system `/etc/resolv.conf` is not yet being used. Recursion is not yet built, i.e. CNAME chains will not be fully resolved if an address is not returned. IPv6 lookups are not included in queries. Due to many of these limitations, you may not yet want to use this library.
//!
//! This as best as possible attempts to abide by the the DNS RFCs, please file issues at https://github.com/bluejekyll/trust-dns .
//!
//! # Usage
//!
//! ## Declare dependency
//!
//! ```toml
//! [dependency]
//! trust-dns-resolver = "^0.1"
//! ```
//!
//! ## Extern the crate for usage in the library
//!
//! ```rust
//! extern crate trust_dns_resolver;
//! ```
//!
//! ## Using the Synchronous Resolver
//!
//! This uses the default configuration. Currently this sets the google resolvers as the upstream resolvers.
//!
//! ```rust
//! use std::net::*;
//! use trust_dns_resolver::Resolver;
//! use trust_dns_resolver::config::*;
//!
//! // Construct a new Resolver with default configuration options
//! let mut resolver = Resolver::new(ResolverConfig::default(), ResolverOpts::default()).unwrap();
//!
//! // Lookup the IP addresses associated with a name.
//! // NOTE: do not forget the final dot, as the resolver does not yet support search paths.
//! let mut response = resolver.lookup_ip("www.example.com.").unwrap();
//!
//! // There can be many addresses associated with the name,
//! //  this can return IPv4 and/or IPv6 addresses
//! let address = response.next().expect("no addresses returned!");
//! assert_eq!(address, IpAddr::V4(Ipv4Addr::new(93, 184, 216, 34)));
//! ```
//!
//! ## Using the Tokio/Async Resolver
//!
//! For more advanced asynchronous usage, the ResolverFuture is integrated with Tokio. In fact, the ResolverFuture is used by the synchronous Resolver for all lookups.
//!
//! ```rust
//! # extern crate futures;
//! # extern crate tokio_core;
//! # extern crate trust_dns_resolver;
//! # fn main() {
//! use std::net::{IpAddr, Ipv4Addr};
//! use futures::Future;
//! use self::tokio_core::reactor::Core;
//! use trust_dns_resolver::ResolverFuture;
//! use trust_dns_resolver::config::*;
//!
//! // We need a Tokio reactor::Core to run the resolver
//! //  this is responsible for running all Future tasks and registering interest in IO channels
//! let mut io_loop = Core::new().unwrap();
//!
//! // Construct a new Resolver with default configuration options
//! let mut resolver = ResolverFuture::new(ResolverConfig::default(), ResolverOpts::default(), io_loop.handle());
//!
//! // Lookup the IP addresses associated with a name.
//! // NOTE: do not forget the final dot, as the resolver does not yet support search paths.
//! let mut response = io_loop.run(resolver.lookup_ip("www.example.com.")).unwrap();
//!
//! // There can be many addresses associated with the name,
//! //  this can return IPv4 and/or IPv6 addresses
//! let address = response.next().expect("no addresses returned!");
//! assert_eq!(address, IpAddr::V4(Ipv4Addr::new(93, 184, 216, 34)));
//! # }
//! ```

#![deny(missing_docs)]

extern crate futures;
#[macro_use]
extern crate log;
extern crate tokio_core;
extern crate trust_dns;

pub mod config;
pub mod lookup_ip;
mod name_server_pool;
mod resolver;
mod resolver_future;

pub use resolver::Resolver;
pub use resolver_future::ResolverFuture;

/// returns a version as specified in Cargo.toml
pub fn version() -> &'static str {
    env!("CARGO_PKG_VERSION")
}
<commit_msg>make the docs clearer<commit_after>// Copyright 2015-2017 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! The Resolver is responsible for performing recursive queries to lookup domain names.
//!
//! This is a 100% in process DNS resolver. It *does not* use the Host OS' resolver. If what is desired is to use the Host OS' resolver, generally in the system's libc, then the `std::net::ToSocketAddrs` variant over `&str` is what should be used. As of the initial release, `trust-dns-resolver` it does not currently support search paths or ndot recursive lookups. It only supports FQDN, where the name must be specified with the final dot, e.g. `www.example.com.`. This limitation will be removed in future releases.
//!
//! Unlike the `trust-dns` client, this tries to provide a simpler interface to perform DNS queries. For update options, i.e. Dynamic DNS, the `trust-dns` crate must be used directly.
//!
//! There are two types for performing DNS queries, `Resolver` and `ResolverFuture`. `Resolver` is the easiest to work with, it is a wrapper around `ResolverFuture`. `ResolverFuture` is a `Tokio` based async resolver, and can be used inside any `Tokio` based system.
//!
//! *Notes on current limitations*: DNSSec is not yet supported in the Resolver, use the `trust-dns` Client if DNSSec validation is needed. Many standard system options and configurations are not yet supported. The host system `/etc/resolv.conf` is not yet being used. Recursion is not yet built, i.e. CNAME chains will not be fully resolved if an address is not returned. IPv6 lookups are not included in queries. Due to many of these limitations, you may not yet want to use this library.
//!
//! This as best as possible attempts to abide by the the DNS RFCs, please file issues at https://github.com/bluejekyll/trust-dns .
//!
//! # Usage
//!
//! ## Declare dependency
//!
//! ```toml
//! [dependency]
//! trust-dns-resolver = "^0.1"
//! ```
//!
//! ## Extern the crate for usage in the library
//!
//! ```rust
//! extern crate trust_dns_resolver;
//! ```
//!
//! ## Using the Synchronous Resolver
//!
//! This uses the default configuration. Currently this sets the google resolvers as the upstream resolvers.
//!
//! ```rust
//! use std::net::*;
//! use trust_dns_resolver::Resolver;
//! use trust_dns_resolver::config::*;
//!
//! // Construct a new Resolver with default configuration options
//! let mut resolver = Resolver::new(ResolverConfig::default(), ResolverOpts::default()).unwrap();
//!
//! // Lookup the IP addresses associated with a name.
//! // NOTE: do not forget the final dot, as the resolver does not yet support search paths.
//! let mut response = resolver.lookup_ip("www.example.com.").unwrap();
//!
//! // There can be many addresses associated with the name,
//! //  this can return IPv4 and/or IPv6 addresses
//! let address = response.next().expect("no addresses returned!");
//! assert_eq!(address, IpAddr::V4(Ipv4Addr::new(93, 184, 216, 34)));
//! ```
//!
//! ## Using the Tokio/Async Resolver
//!
//! For more advanced asynchronous usage, the ResolverFuture is integrated with Tokio. In fact, the ResolverFuture is used by the synchronous Resolver for all lookups.
//!
//! ```rust
//! # extern crate futures;
//! # extern crate tokio_core;
//! # extern crate trust_dns_resolver;
//! # fn main() {
//! use std::net::{IpAddr, Ipv4Addr};
//! use futures::Future;
//! use tokio_core::reactor::Core;
//! use trust_dns_resolver::ResolverFuture;
//! use trust_dns_resolver::config::*;
//!
//! // We need a Tokio reactor::Core to run the resolver
//! //  this is responsible for running all Future tasks and registering interest in IO channels
//! let mut io_loop = Core::new().unwrap();
//!
//! // Construct a new Resolver with default configuration options
//! let mut resolver = ResolverFuture::new(ResolverConfig::default(), ResolverOpts::default(), io_loop.handle());
//!
//! // Lookup the IP addresses associated with a name.
//! // NOTE: do not forget the final dot, as the resolver does not yet support search paths.
//! // This returns a future that will lookup the IP addresses, it must be run in the Core to
//! //  to get the actual result.
//! let lookup_future = resolver.lookup_ip("www.example.com.");
//!
//! // Run the lookup until it resolves or errors
//! let mut response = io_loop.run(lookup_future).unwrap();
//!
//! // There can be many addresses associated with the name,
//! //  this can return IPv4 and/or IPv6 addresses
//! let address = response.next().expect("no addresses returned!");
//! assert_eq!(address, IpAddr::V4(Ipv4Addr::new(93, 184, 216, 34)));
//! # }
//! ```
//!
//! Generaally after a lookup in an asynchornous context, there would probably be a connection made to a server, for example:
//!
//! ```rust,no_compile
//! let result = io_loop.run(lookup_future.and_then(|ips| {
//!                              let ip = ips.next().unwrap();
//!                              TcpStream::connect()
//!                          }).and_then(|conn| /* do something with the connection... */)
//! ).unwrap();
//! ```
//!
//! It's beyond the scope of these examples to show how to deal with connection failures and looping etc. But if you wanted to say try a different address from the result set after a connection failure, it will be necessary to create a type that implements the `Future` trait. Inside the `Future::poll` method would be the place to implement a loop over the different IP addresses.

#![deny(missing_docs)]

extern crate futures;
#[macro_use]
extern crate log;
extern crate tokio_core;
extern crate trust_dns;

pub mod config;
pub mod lookup_ip;
mod name_server_pool;
mod resolver;
mod resolver_future;

pub use resolver::Resolver;
pub use resolver_future::ResolverFuture;

/// returns a version as specified in Cargo.toml
pub fn version() -> &'static str {
    env!("CARGO_PKG_VERSION")
}
<|endoftext|>