<commit_before>use request_response_matcher::*;
use chrono::*;

pub struct FilterConditions {
    pub include_terms: Option<Vec<String>>,
    pub exclude_terms: Option<Vec<String>>,
    pub latest_time: Option<Duration>,
}

fn matches_filter(pair: &RequestResponsePair, conditions: &FilterConditions) -> bool {
    let matches_include_terms: bool = match conditions.include_terms {
        Some(ref include_terms) => {
            include_terms.iter()
                .fold(
                    false,
                    |result, include_term|
                        result ||
                        pair.request.original_log_line.contains(include_term) ||
                        pair.response.original_log_line.contains(include_term)
                )
        },
        None => true
    };

    let matches_exclude_terms: bool = match conditions.exclude_terms {
        Some(ref exclude_terms) => {
            !exclude_terms.iter()
                .fold(
                    false,
                    |result, exclude_term|
                        result ||
                        pair.request.original_log_line.contains(exclude_term) ||
                        pair.response.original_log_line.contains(exclude_term)
                )
        },
        None => true
    };

    let matches_time: bool = match conditions.latest_time {
        Some(latest_time) => {
            let timezone = pair.request.time.timezone();
            let now = UTC::now().with_timezone(&timezone);
            let include_since_time = now - latest_time;
            pair.request.time >= include_since_time
        },
        None => true
    };

    matches_include_terms && matches_exclude_terms && matches_time
}

pub fn filter(pairs: Vec<RequestResponsePair>, conditions: FilterConditions) -> Vec<RequestResponsePair> {
    let filtered_pairs: Vec<RequestResponsePair> = pairs.into_iter()
        .filter(|pair| matches_filter(&pair, &conditions))
        .collect();

    filtered_pairs
}

#[cfg(test)]
mod tests {
    use log_parser::log_events::*;
    use request_response_matcher::*;
    use chrono::*;
    use super::*;

    fn get_fixture() -> Vec<RequestResponsePair> {
        vec![
            RequestResponsePair {
                request: Request::new_from_log_line(&"08/Apr/2016:09:57:47 +0200 [001] -> GET /content/some/page.html HTTP/1.1".to_string()).unwrap(),
                response: Response::new_from_log_line(&"08/Apr/2016:09:57:47 +0200 [001] <- 200 text/html 1ms".to_string()).unwrap(),
            },
            RequestResponsePair {
                request: Request::new_from_log_line(&"08/Apr/2016:09:58:47 +0200 [02] -> GET /content/some/other.html HTTP/1.1".to_string()).unwrap(),
                response: Response::new_from_log_line(&"08/Apr/2016:09:58:47 +0200 [02] <- 200 text/html 10ms".to_string()).unwrap(),
            },
            RequestResponsePair {
                request: Request::new_from_log_line(&"08/Apr/2016:10:58:47 +0200 [03] -> GET /content/some/third.html HTTP/1.1".to_string()).unwrap(),
                response: Response::new_from_log_line(&"08/Apr/2016:10:58:47 +0200 [03] <- 200 text/html 100ms".to_string()).unwrap(),
            },
        ]
    }

    #[test]
    fn test_filter_none() {
        let request_response_pairs = get_fixture();

        let conditions = FilterConditions {
            include_terms: None,
            exclude_terms: None,
            latest_time: None,
        };

        let result: Vec<RequestResponsePair> = filter(request_response_pairs, conditions);

        assert_eq!(result.len(), 3);
    }

    #[test]
    fn test_filter_include_exclude() {
        let request_response_pairs = get_fixture();

        let conditions = FilterConditions {
            include_terms: Some(vec!["text/html".to_string()]),
            exclude_terms: Some(vec!["third.html".to_string()]),
            latest_time: None,
        };

        let result: Vec<RequestResponsePair> = filter(request_response_pairs, conditions);

        assert_eq!(result.len(), 2);
        assert_eq!(result[0].request.id, 1);
        assert_eq!(result[1].request.id, 2);
    }

    #[test]
    fn test_filter_include_multiple() {
        let request_response_pairs = get_fixture();

        let conditions = FilterConditions {
            include_terms: Some(vec!["page.html".to_string(), "third.html".to_string()]),
            exclude_terms: None,
            latest_time: None,
        };

        let result: Vec<RequestResponsePair> = filter(request_response_pairs, conditions);

        assert_eq!(result.len(), 2);
        assert_eq!(result[0].request.id, 1);
        assert_eq!(result[1].request.id, 3);
    }

    #[test]
    fn test_filter_exclude_multiple() {
        let request_response_pairs = get_fixture();

        let conditions = FilterConditions {
            include_terms: None,
            exclude_terms: Some(vec!["page.html".to_string(), "third.html".to_string()]),
            latest_time: None,
        };

        let result: Vec<RequestResponsePair> = filter(request_response_pairs, conditions);

        assert_eq!(result.len(), 1);
        assert_eq!(result[0].request.id, 2);
    }

    #[test]
    fn test_filter_time() {
        let mut request_response_pairs = get_fixture();
        request_response_pairs[0].request.time = UTC::now().with_timezone(&request_response_pairs[0].request.time.timezone());
        request_response_pairs[1].request.time = UTC::now().with_timezone(&request_response_pairs[1].request.time.timezone()) - Duration::minutes(12);

        let conditions = FilterConditions {
            include_terms: None,
            exclude_terms: None,
            latest_time: Some(Duration::minutes(10)),
        };

        let result: Vec<RequestResponsePair> = filter(request_response_pairs, conditions);

        assert_eq!(result.len(), 1);
        assert_eq!(result[0].request.id, 1);
    }
}
<commit_msg>Filtering a single pair is enough<commit_after>use request_response_matcher::*;
use chrono::*;

pub struct FilterConditions {
    pub include_terms: Option<Vec<String>>,
    pub exclude_terms: Option<Vec<String>>,
    pub latest_time: Option<Duration>,
}

pub fn matches_filter(pair: &RequestResponsePair, conditions: &FilterConditions) -> bool {
    let matches_include_terms: bool = match conditions.include_terms {
        Some(ref include_terms) => {
            include_terms.iter()
                .fold(
                    false,
                    |result, include_term|
                        result ||
                        pair.request.original_log_line.contains(include_term) ||
                        pair.response.original_log_line.contains(include_term)
                )
        },
        None => true
    };

    let matches_exclude_terms: bool = match conditions.exclude_terms {
        Some(ref exclude_terms) => {
            !exclude_terms.iter()
                .fold(
                    false,
                    |result, exclude_term|
                        result ||
                        pair.request.original_log_line.contains(exclude_term) ||
                        pair.response.original_log_line.contains(exclude_term)
                )
        },
        None => true
    };

    let matches_time: bool = match conditions.latest_time {
        Some(latest_time) => {
            let timezone = pair.request.time.timezone();
            let now = UTC::now().with_timezone(&timezone);
            let include_since_time = now - latest_time;
            pair.request.time >= include_since_time
        },
        None => true
    };

    matches_include_terms && matches_exclude_terms && matches_time
}

#[cfg(test)]
mod tests {
    use log_parser::log_events::*;
    use request_response_matcher::*;
    use chrono::*;
    use super::*;

    fn get_fixture() -> RequestResponsePair {
        RequestResponsePair {
            request: Request::new_from_log_line(&"08/Apr/2016:09:57:47 +0200 [001] -> GET /content/some/page.html HTTP/1.1".to_string()).unwrap(),
            response: Response::new_from_log_line(&"08/Apr/2016:09:57:47 +0200 [001] <- 200 text/html 1ms".to_string()).unwrap(),
        }
    }

    #[test]
    fn test_filter_none() {
        let pair = get_fixture();

        let conditions = FilterConditions {
            include_terms: None,
            exclude_terms: None,
            latest_time: None,
        };

        let result = matches_filter(&pair, &conditions);

        assert_eq!(result, true);
    }

    #[test]
    fn test_filter_include_request() {
        let pair = get_fixture();

        let conditions = FilterConditions {
            include_terms: Some(vec!["page.html".to_string()]),
            exclude_terms: None,
            latest_time: None,
        };

        let result = matches_filter(&pair, &conditions);

        assert_eq!(result, true);
    }

    #[test]
    fn test_filter_include_response() {
        let pair = get_fixture();

        let conditions = FilterConditions {
            include_terms: Some(vec!["text/html".to_string()]),
            exclude_terms: None,
            latest_time: None,
        };

        let result = matches_filter(&pair, &conditions);

        assert_eq!(result, true);
    }

    #[test]
    fn test_filter_exclude_request() {
        let pair = get_fixture();

        let conditions = FilterConditions {
            include_terms: None,
            exclude_terms: Some(vec!["page.html".to_string()]),
            latest_time: None,
        };

        let result = matches_filter(&pair, &conditions);

        assert_eq!(result, false);
    }

    #[test]
    fn test_filter_exclude_response() {
        let pair = get_fixture();

        let conditions = FilterConditions {
            include_terms: None,
            exclude_terms: Some(vec!["text/html".to_string()]),
            latest_time: None,
        };

        let result = matches_filter(&pair, &conditions);

        assert_eq!(result, false);
    }

    #[test]
    fn test_filter_include_multiple() {
        let pair = get_fixture();

        let conditions = FilterConditions {
            include_terms: Some(vec!["irrelevant.html".to_string(), "page.html".to_string()]),
            exclude_terms: None,
            latest_time: None,
        };

        let result = matches_filter(&pair, &conditions);

        assert_eq!(result, true);
    }

    #[test]
    fn test_filter_exclude_multiple() {
        let pair = get_fixture();

        let conditions = FilterConditions {
            include_terms: None,
            exclude_terms: Some(vec!["irrelevant.html".to_string(), "page.html".to_string()]),
            latest_time: None,
        };

        let result = matches_filter(&pair, &conditions);

        assert_eq!(result, false);
    }

    #[test]
    fn test_filter_time_matches() {
        let mut pair = get_fixture();
        pair.request.time = UTC::now().with_timezone(&pair.request.time.timezone());

        let conditions = FilterConditions {
            include_terms: None,
            exclude_terms: None,
            latest_time: Some(Duration::minutes(10)),
        };

        let result = matches_filter(&pair, &conditions);

        assert_eq!(result, true);
    }

    #[test]
    fn test_filter_time_matches_not() {
        let mut pair = get_fixture();
        pair.request.time = UTC::now().with_timezone(&pair.request.time.timezone()) - Duration::minutes(12);;

        let conditions = FilterConditions {
            include_terms: None,
            exclude_terms: None,
            latest_time: Some(Duration::minutes(10)),
        };

        let result = matches_filter(&pair, &conditions);

        assert_eq!(result, false);
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Revolution Solid & Contributors.
// author(s): sysnett
// rust-monster is licensed under a MIT License.

//! GA Test Utilities
//! Reusable classes for testing

use super::ga_core::*;
use super::ga_population::*;

#[cfg(test)]
extern crate env_logger;
pub const GA_TEST_FITNESS_VAL: f32 = 3.14159;

/// GA Test Setup
/// Utility function to setup useful test systems (like logging)
pub fn ga_test_setup(test_name: &str)
{
    ga_test_setup_internal(test_name);
}

#[cfg(not(test))]
fn ga_test_setup_internal(_: &str)
{
    // This only exists to avoid bringing env_logger in non-test builds
    // but keeping ga_test_setup documented
    // This is needed because [cfg(test)] conditional compilation wont
    // work on non-item statements as of rustc 1.9 (is experimental)
    // DO NOT ADD CODE HERE (See below)
}

#[cfg(test)]
fn ga_test_setup_internal(test_name: &str)
{
    let _ = env_logger::init();
    debug!("{:?}", test_name);
}

/// GA Test Teardown
/// Utlity function to teardown used test systems
pub fn ga_test_teardown(){}

/// GATestSolution
/// Implements the GASolution Trait with only no-ops
pub struct GATestSolution
{
    score: f32,
    fitness: f32
}
impl GASolution for GATestSolution
{
    fn new(rs:f32) -> GATestSolution
    {
        GATestSolution{ score: rs, fitness: 1.0/rs }
    }

    fn evaluate(&mut self) -> f32 { self.fitness }
    fn crossover(&self, _: &Self) -> Self { GATestSolution::new(self.fitness) }
    fn mutate(&mut self, _: f32) {}
    fn fitness(&self) -> f32 { self.fitness }
    fn set_fitness(&mut self, fitness:f32) { self.fitness = fitness; }
    fn score(&self) -> f32 { self.score}
}

pub struct GATestFactory
{
    starting_score: f32
}
impl GATestFactory
{
    pub fn new(starting_score: f32) -> GATestFactory
    {
        GATestFactory {starting_score: starting_score}
    }
}
impl GAFactory<GATestSolution> for GATestFactory
{
    fn initial_population(&mut self) -> GAPopulation<GATestSolution>
    {
        GAPopulation::new(vec![GATestSolution::new(self.starting_score)], GAPopulationSortOrder::HighIsBest)
    }
}
<commit_msg>Derive Clone trait implementation for GATestSolution.<commit_after>// Copyright 2016 Revolution Solid & Contributors.
// author(s): sysnett
// rust-monster is licensed under a MIT License.

//! GA Test Utilities
//! Reusable classes for testing

use super::ga_core::*;
use super::ga_population::*;

#[cfg(test)]
extern crate env_logger;
pub const GA_TEST_FITNESS_VAL: f32 = 3.14159;

/// GA Test Setup
/// Utility function to setup useful test systems (like logging)
pub fn ga_test_setup(test_name: &str)
{
    ga_test_setup_internal(test_name);
}

#[cfg(not(test))]
fn ga_test_setup_internal(_: &str)
{
    // This only exists to avoid bringing env_logger in non-test builds
    // but keeping ga_test_setup documented
    // This is needed because [cfg(test)] conditional compilation wont
    // work on non-item statements as of rustc 1.9 (is experimental)
    // DO NOT ADD CODE HERE (See below)
}

#[cfg(test)]
fn ga_test_setup_internal(test_name: &str)
{
    let _ = env_logger::init();
    debug!("{:?}", test_name);
}

/// GA Test Teardown
/// Utlity function to teardown used test systems
pub fn ga_test_teardown(){}

/// GATestSolution
/// Implements the GASolution Trait with only no-ops
#[derive(Clone)]
pub struct GATestSolution
{
    score: f32,
    fitness: f32
}
impl GASolution for GATestSolution
{
    fn new(rs:f32) -> GATestSolution
    {
        GATestSolution{ score: rs, fitness: 1.0/rs }
    }

    fn evaluate(&mut self) -> f32 { self.fitness }
    fn crossover(&self, _: &Self) -> Self { GATestSolution::new(self.fitness) }
    fn mutate(&mut self, _: f32) {}
    fn fitness(&self) -> f32 { self.fitness }
    fn set_fitness(&mut self, fitness:f32) { self.fitness = fitness; }
    fn score(&self) -> f32 { self.score}
}

pub struct GATestFactory
{
    starting_score: f32
}
impl GATestFactory
{
    pub fn new(starting_score: f32) -> GATestFactory
    {
        GATestFactory {starting_score: starting_score}
    }
}
impl GAFactory<GATestSolution> for GATestFactory
{
    fn initial_population(&mut self) -> GAPopulation<GATestSolution>
    {
        GAPopulation::new(vec![GATestSolution::new(self.starting_score)], GAPopulationSortOrder::HighIsBest)
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Joe Wilm, The Alacritty Project Contributors
//
// 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.

//! Tests for the Gird

use super::{Grid, BidirectionalIterator};
use index::{Point, Line, Column};

// Scroll up moves lines upwards
#[test]
fn scroll_up() {
    info!("");

    let mut grid = Grid::new(Line(10), Column(1), 0, 0);
    for i in 0..10 {
        grid[Line(i)][Column(0)] = i;
    }

    info!("grid: {:?}", grid);

    grid.scroll_up(&(Line(0)..Line(10)), Line(2));

    info!("grid: {:?}", grid);

    let mut other = Grid::new(Line(10), Column(1), 0, 9);

    other[Line(0)][Column(0)] = 2;
    other[Line(1)][Column(0)] = 3;
    other[Line(2)][Column(0)] = 4;
    other[Line(3)][Column(0)] = 5;
    other[Line(4)][Column(0)] = 6;
    other[Line(5)][Column(0)] = 7;
    other[Line(6)][Column(0)] = 8;
    other[Line(7)][Column(0)] = 9;
    other[Line(8)][Column(0)] = 0;
    other[Line(9)][Column(0)] = 1;

    for i in 0..10 {
        assert_eq!(grid[Line(i)][Column(0)], other[Line(i)][Column(0)]);
    }
}

// Scroll down moves lines downwards
#[test]
fn scroll_down() {
    info!("");

    let mut grid = Grid::new(Line(10), Column(1), 0, 0);
    for i in 0..10 {
        grid[Line(i)][Column(0)] = i;
    }

    info!("grid: {:?}", grid);

    grid.scroll_down(&(Line(0)..Line(10)), Line(2));

    info!("grid: {:?}", grid);

    let mut other = Grid::new(Line(10), Column(1), 0, 9);

    other[Line(0)][Column(0)] = 8;
    other[Line(1)][Column(0)] = 9;
    other[Line(2)][Column(0)] = 0;
    other[Line(3)][Column(0)] = 1;
    other[Line(4)][Column(0)] = 2;
    other[Line(5)][Column(0)] = 3;
    other[Line(6)][Column(0)] = 4;
    other[Line(7)][Column(0)] = 5;
    other[Line(8)][Column(0)] = 6;
    other[Line(9)][Column(0)] = 7;

    for i in 0..10 {
        assert_eq!(grid[Line(i)][Column(0)], other[Line(i)][Column(0)]);
    }
}

// Test that GridIterator works
#[test]
fn test_iter() {
    info!("");

    let mut grid = Grid::new(Line(5), Column(5), 0, 0);
    for i in 0..5 {
        for j in 0..5 {
            grid[Line(i)][Column(j)] = i*5 + j;
        }
    }

    info!("grid: {:?}", grid);

    let mut iter = grid.iter_from(Point {
        line: 4,
        col: Column(0),
    });

    assert_eq!(None, iter.prev());
    assert_eq!(Some(&1), iter.next());
    assert_eq!(Column(1), iter.cur.col);
    assert_eq!(4, iter.cur.line);

    assert_eq!(Some(&2), iter.next());
    assert_eq!(Some(&3), iter.next());
    assert_eq!(Some(&4), iter.next());

    // test linewrapping
    assert_eq!(Some(&5), iter.next());
    assert_eq!(Column(0), iter.cur.col);
    assert_eq!(3, iter.cur.line);

    assert_eq!(Some(&4), iter.prev());
    assert_eq!(Column(4), iter.cur.col);
    assert_eq!(4, iter.cur.line);

    // test that iter ends at end of grid
    let mut final_iter = grid.iter_from(Point {
        line: 0,
        col: Column(4),
    });
    assert_eq!(None, final_iter.next());
    assert_eq!(Some(&23), final_iter.prev());
}
<commit_msg>Fix grid scroll tests<commit_after>// Copyright 2016 Joe Wilm, The Alacritty Project Contributors
//
// 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.

//! Tests for the Gird

use super::{Grid, BidirectionalIterator};
use index::{Point, Line, Column};

// Scroll up moves lines upwards
#[test]
fn scroll_up() {
    info!("");

    let mut grid = Grid::new(Line(10), Column(1), 0, 0);
    for i in 0..10 {
        grid[Line(i)][Column(0)] = i;
    }

    info!("grid: {:?}", grid);

    grid.scroll_up(&(Line(0)..Line(10)), Line(2));

    info!("grid: {:?}", grid);

    let mut other = Grid::new(Line(10), Column(1), 0, 9);

    other[Line(0)][Column(0)] = 2;
    other[Line(1)][Column(0)] = 3;
    other[Line(2)][Column(0)] = 4;
    other[Line(3)][Column(0)] = 5;
    other[Line(4)][Column(0)] = 6;
    other[Line(5)][Column(0)] = 7;
    other[Line(6)][Column(0)] = 8;
    other[Line(7)][Column(0)] = 9;
    other[Line(8)][Column(0)] = 0; // should be cleared on scroll; was 0
    other[Line(9)][Column(0)] = 0; // should be cleared on scroll; was 1

    for i in 0..10 {
        assert_eq!(grid[Line(i)][Column(0)], other[Line(i)][Column(0)],
            "index={}; actual: {:?}, expected: {:?}",
            Line(i), grid[Line(i)][Column(0)], other[Line(i)][Column(0)]);
    }
}

// Scroll down moves lines downwards
#[test]
fn scroll_down() {
    info!("");

    let mut grid = Grid::new(Line(10), Column(1), 0, 0);
    for i in 0..10 {
        grid[Line(i)][Column(0)] = i;
    }

    info!("grid: {:?}", grid);

    grid.scroll_down(&(Line(0)..Line(10)), Line(2));

    info!("grid: {:?}", grid);

    let mut other = Grid::new(Line(10), Column(1), 0, 9);

    other[Line(0)][Column(0)] = 0; // Should be cleared upon recycle; was 8
    other[Line(1)][Column(0)] = 0; // Should be cleared upon recycle; was 9
    other[Line(2)][Column(0)] = 0;
    other[Line(3)][Column(0)] = 1;
    other[Line(4)][Column(0)] = 2;
    other[Line(5)][Column(0)] = 3;
    other[Line(6)][Column(0)] = 4;
    other[Line(7)][Column(0)] = 5;
    other[Line(8)][Column(0)] = 6;
    other[Line(9)][Column(0)] = 7;

    for i in 0..10 {
        assert_eq!(grid[Line(i)][Column(0)], other[Line(i)][Column(0)],
            "index={}; actual: {:?}, expected: {:?}",
            Line(i), grid[Line(i)][Column(0)], other[Line(i)][Column(0)]);
    }
}

// Test that GridIterator works
#[test]
fn test_iter() {
    info!("");

    let mut grid = Grid::new(Line(5), Column(5), 0, 0);
    for i in 0..5 {
        for j in 0..5 {
            grid[Line(i)][Column(j)] = i*5 + j;
        }
    }

    info!("grid: {:?}", grid);

    let mut iter = grid.iter_from(Point {
        line: 4,
        col: Column(0),
    });

    assert_eq!(None, iter.prev());
    assert_eq!(Some(&1), iter.next());
    assert_eq!(Column(1), iter.cur.col);
    assert_eq!(4, iter.cur.line);

    assert_eq!(Some(&2), iter.next());
    assert_eq!(Some(&3), iter.next());
    assert_eq!(Some(&4), iter.next());

    // test linewrapping
    assert_eq!(Some(&5), iter.next());
    assert_eq!(Column(0), iter.cur.col);
    assert_eq!(3, iter.cur.line);

    assert_eq!(Some(&4), iter.prev());
    assert_eq!(Column(4), iter.cur.col);
    assert_eq!(4, iter.cur.line);

    // test that iter ends at end of grid
    let mut final_iter = grid.iter_from(Point {
        line: 0,
        col: Column(4),
    });
    assert_eq!(None, final_iter.next());
    assert_eq!(Some(&23), final_iter.prev());
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 Élisabeth HENRY.
//
// This file is part of Crowbook.
//
// Crowbook is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received ba copy of the GNU Lesser General Public License
// along with Crowbook.  If not, see <http://www.gnu.org/licenses/>.

//! Provides utility functions for escaping text to HTML or LaTeX

use std::borrow::Cow;

/// Escape characters `<`, `>`, and `&`
///
/// # Examples
///
/// ```
/// use crowbook::escape::escape_html;
/// let s = escape_html("<foo> & <bar>");
/// assert_eq!(&s, "<foo> & <bar>");
/// ```
pub fn escape_html<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    const NB_CHAR:char = ' '; // non breaking space
    const NB_CHAR_NARROW:char = '\u{202F}'; // narrow non breaking space
    const NB_CHAR_EM:char = '\u{2002}'; // demi em space

    let input = input.into();
    if input.contains(|c| match c {
        '<'|'>'|'&'| NB_CHAR_NARROW | NB_CHAR_EM | NB_CHAR  => true,
        _ => false
    }) {
        let mut output = String::with_capacity(input.len());
        for c in input.chars() {
            match c {
                '<' => output.push_str("<"),
                '>' => output.push_str(">"),
                '&' => output.push_str("&"),
                NB_CHAR_NARROW
                    | NB_CHAR_EM
                    | NB_CHAR
                    => output.push_str(&format!("{}",
                                               match c {
                                                   NB_CHAR => "#ffff66",
                                                   NB_CHAR_NARROW => "#9999ff",
                                                   NB_CHAR_EM => "#ffcccc",
                                                   _ => unreachable!()
                                               },
                                                c)),

                _ => output.push(c),
            }
        }

        Cow::Owned(output)
    } else {
        input.into()
    }
}

/// Escape characters for LaTeX
///
/// # Examples
///
/// ```
/// use crowbook::escape::escape_tex;
/// let s = escape_tex("command --foo # calls command with option foo");
/// assert_eq!(&s, r"command -{}-foo \# calls command with option foo");
/// ```
pub fn escape_tex<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    let input = input.into();
    if input.contains(|c| match c {
        '&'|'%'|'$'|'#'|'_'|'{'|'}'|'~'|'^'|'\\'|'-' => true,
        _ => false
    }) {
        let mut output = String::with_capacity(input.len());
        let mut chars:Vec<char> = input.chars().collect();
        chars.push(' '); // add a dummy char for call to .windows()
        // for &[c, next] in chars.windows(2) { // still experimental, uncomment when stable
        for win in chars.windows(2) {
            let c = win[0];
            let next = win[1];
            match c {
                '-' => {
                    if next == '-' {
                        output.push_str(r"-{}"); // if next char is also a -, to avoid tex ligatures
                    } else {
                        output.push(c);
                    }
                },
                '&' => output.push_str(r"\&"),
                '%' => output.push_str(r"\%"),
                '$' => output.push_str(r"\$"),
                '#' => output.push_str(r"\#"),
                '_' => output.push_str(r"\_"),
                '{' => output.push_str(r"\{"),
                '}' => output.push_str(r"\}"),
                '~' => output.push_str(r"\textasciitilde{}" ),
                '^' => output.push_str(r"\textasciicircum{}"),
                '\\' => output.push_str(r"\textbackslash{}"),
                _  => output.push(c)
            }
        }
        Cow::Owned(output)
    } else {
        input
    }
}
<commit_msg>Change colours<commit_after>// Copyright (C) 2016 Élisabeth HENRY.
//
// This file is part of Crowbook.
//
// Crowbook is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received ba copy of the GNU Lesser General Public License
// along with Crowbook.  If not, see <http://www.gnu.org/licenses/>.

//! Provides utility functions for escaping text to HTML or LaTeX

use std::borrow::Cow;

/// Escape characters `<`, `>`, and `&`
///
/// # Examples
///
/// ```
/// use crowbook::escape::escape_html;
/// let s = escape_html("<foo> & <bar>");
/// assert_eq!(&s, "<foo> & <bar>");
/// ```
pub fn escape_html<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    const NB_CHAR:char = ' '; // non breaking space
    const NB_CHAR_NARROW:char = '\u{202F}'; // narrow non breaking space
    const NB_CHAR_EM:char = '\u{2002}'; // demi em space

    let input = input.into();
    if input.contains(|c| match c {
        '<'|'>'|'&'| NB_CHAR_NARROW | NB_CHAR_EM | NB_CHAR  => true,
        _ => false
    }) {
        let mut output = String::with_capacity(input.len());
        for c in input.chars() {
            match c {
                '<' => output.push_str("<"),
                '>' => output.push_str(">"),
                '&' => output.push_str("&"),
                NB_CHAR_NARROW
                    | NB_CHAR_EM
                    | NB_CHAR
                    => output.push_str(&format!("{}",
                                               match c {
                                                   NB_CHAR => "#ffff66",
                                                   NB_CHAR_NARROW => "#9999ff",
                                                   NB_CHAR_EM => "#ff9999",
                                                   _ => unreachable!()
                                               },
                                                c)),

                _ => output.push(c),
            }
        }

        Cow::Owned(output)
    } else {
        input.into()
    }
}

/// Escape characters for LaTeX
///
/// # Examples
///
/// ```
/// use crowbook::escape::escape_tex;
/// let s = escape_tex("command --foo # calls command with option foo");
/// assert_eq!(&s, r"command -{}-foo \# calls command with option foo");
/// ```
pub fn escape_tex<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    let input = input.into();
    if input.contains(|c| match c {
        '&'|'%'|'$'|'#'|'_'|'{'|'}'|'~'|'^'|'\\'|'-' => true,
        _ => false
    }) {
        let mut output = String::with_capacity(input.len());
        let mut chars:Vec<char> = input.chars().collect();
        chars.push(' '); // add a dummy char for call to .windows()
        // for &[c, next] in chars.windows(2) { // still experimental, uncomment when stable
        for win in chars.windows(2) {
            let c = win[0];
            let next = win[1];
            match c {
                '-' => {
                    if next == '-' {
                        output.push_str(r"-{}"); // if next char is also a -, to avoid tex ligatures
                    } else {
                        output.push(c);
                    }
                },
                '&' => output.push_str(r"\&"),
                '%' => output.push_str(r"\%"),
                '$' => output.push_str(r"\$"),
                '#' => output.push_str(r"\#"),
                '_' => output.push_str(r"\_"),
                '{' => output.push_str(r"\{"),
                '}' => output.push_str(r"\}"),
                '~' => output.push_str(r"\textasciitilde{}" ),
                '^' => output.push_str(r"\textasciicircum{}"),
                '\\' => output.push_str(r"\textbackslash{}"),
                _  => output.push(c)
            }
        }
        Cow::Owned(output)
    } else {
        input
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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 Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
//!
//! The rust standard library is available to all rust crates by
//! default, just as if contained an `extern crate std` import at the
//! crate root. Therefore the standard library can be accessed in
//! `use` statements through the path `std`, as in `use std::thread`,
//! or in expressions through the absolute path `::std`, as in
//! `::std::thread::sleep_ms(100)`.
//!
//! Furthermore, the standard library defines [The Rust
//! Prelude](prelude/index.html), a small collection of items, mostly
//! traits, that are imported into and available in every module.
//!
//! ## What is in the standard library
//!
//! The standard library is minimal, a set of battle-tested
//! core types and shared abstractions for the [broader Rust
//! ecosystem](https://crates.io) to build on.
//!
//! The [primitive types](#primitives), though not defined in the
//! standard library, are documented here, as are the predefined
//! [macros](#macros).
//!
//! ## Containers and collections
//!
//! The [`option`](option/index.html) and
//! [`result`](result/index.html) modules define optional and
//! error-handling types, `Option` and `Result`. The
//! [`iter`](iter/index.html) module defines Rust's iterator trait,
//! [`Iterater`](iter/trait.Iterator.html), which works with the `for`
//! loop to access collections.
//!
//! The common container type, `Vec`, a growable vector backed by an array,
//! lives in the [`vec`](vec/index.html) module. Contiguous, unsized regions
//! of memory, `[T]`, commonly called "slices", and their borrowed versions,
//! `&[T]`, commonly called "borrowed slices", are built-in types for which the
//! [`slice`](slice/index.html) module defines many methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
//! [`str`](str/index.html) module. Rust strings are immutable;
//! use the `String` type defined in [`string`](string/index.html)
//! for a mutable string builder.
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! Data may be shared by placing it in a reference-counted box or the
//! [`Rc`][rc/index.html] type, and if further contained in a [`Cell`
//! or `RefCell`](cell/index.html), may be mutated as well as shared.
//! Likewise, in a concurrent setting it is common to pair an
//! atomically-reference-counted box, [`Arc`](sync/struct.Arc.html),
//! with a [`Mutex`](sync/struct.Mutex.html) to get the same effect.
//!
//! The [`collections`](collections/index.html) module defines maps,
//! sets, linked lists and other typical collection types, including
//! the common [`HashMap`](collections/struct.HashMap.html).
//!
//! ## Platform abstractions and I/O
//!
//! Besides basic data types, the standard library is largely concerned
//! with abstracting over differences in common platforms, most notably
//! Windows and Unix derivatives.
//!
//! Common types of I/O, including [files](fs/struct.File.html),
//! [TCP](net/struct.TcpStream.html),
//! [UDP](net/struct.UdpSocket.html), are defined in the
//! [`io`](io/index.html), [`fs`](fs/index.html), and
//! [`net`](net/index.html) modules.
//!
//! The [`thread`](thread/index.html) module contains Rust's threading
//! abstractions. [`sync`](sync/index.html) contains further
//! primitive shared memory types, including
//! [`atomic`](sync/atomic/index.html) and
//! [`mpsc`](sync/mpsc/index.html), which contains the channel types
//! for message passing.

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "std"]
#![stable(feature = "rust1", since = "1.0.0")]
#![staged_api]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]
#![doc(test(no_crate_inject, attr(deny(warnings))))]
#![doc(test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]

#![feature(alloc)]
#![feature(allow_internal_unstable)]
#![feature(associated_consts)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(debug_builders)]
#![feature(into_cow)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage, thread_local, asm)]
#![feature(macro_reexport)]
#![feature(optin_builtin_traits)]
#![feature(rand)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(str_char)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unique)]
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(zero_one)]
#![cfg_attr(test, feature(float_from_str_radix))]
#![cfg_attr(test, feature(test, rustc_private, std_misc))]

// Don't link to std. We are std.
#![feature(no_std)]
#![no_std]

#![allow(trivial_casts)]
#![deny(missing_docs)]

#[cfg(test)] extern crate test;
#[cfg(test)] #[macro_use] extern crate log;

#[macro_use]
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
    unreachable, unimplemented, write, writeln)]
extern crate core;

#[macro_use]
#[macro_reexport(vec, format)]
extern crate collections as core_collections;

#[allow(deprecated)] extern crate rand as core_rand;
extern crate alloc;
extern crate rustc_unicode;
extern crate libc;

#[macro_use] #[no_link] extern crate rustc_bitflags;

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate std as realstd;
#[cfg(test)] pub use realstd::marker;
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::boxed;

// NB: These reexports are in the order they should be listed in rustdoc

pub use core::any;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::convert;
pub use core::default;
pub use core::hash;
pub use core::intrinsics;
pub use core::iter;
#[cfg(not(test))] pub use core::marker;
pub use core::mem;
#[cfg(not(test))] pub use core::ops;
pub use core::ptr;
pub use core::raw;
pub use core::simd;
pub use core::result;
pub use core::option;
pub mod error;

#[cfg(not(test))] pub use alloc::boxed;
pub use alloc::rc;

pub use core_collections::borrow;
pub use core_collections::fmt;
pub use core_collections::slice;
pub use core_collections::str;
pub use core_collections::string;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::vec;

pub use rustc_unicode::char;

/* Exported macros */

#[macro_use]
mod macros;

mod rtdeps;

/* The Prelude. */

pub mod prelude;

/* Primitive types */

// NB: slice and str are primitive types too, but their module docs + primitive doc pages
// are inlined from the public re-exports of core_collections::{slice, str} above.

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod ascii;

pub mod thunk;

/* Common traits */

pub mod num;

/* Runtime and platform support */

#[macro_use]
pub mod thread;

pub mod collections;
pub mod dynamic_lib;
pub mod env;
pub mod ffi;
pub mod fs;
pub mod io;
pub mod net;
pub mod os;
pub mod path;
pub mod process;
pub mod sync;
pub mod time;

#[macro_use]
#[path = "sys/common/mod.rs"] mod sys_common;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

pub mod rt;
mod panicking;
mod rand;

// Some external utilities of the standard library rely on randomness (aka
// rustc_back::TempDir and tests) and need a way to get at the OS rng we've got
// here. This module is not at all intended for stabilization as-is, however,
// but it may be stabilized long-term. As a result we're exposing a hidden,
// unstable module so we can get our build working.
#[doc(hidden)]
#[unstable(feature = "rand")]
pub mod __rand {
    pub use rand::{thread_rng, ThreadRng, Rng};
}

// Modules that exist purely to document + host impl docs for primitive types

mod array;
mod bool;
mod unit;
mod tuple;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    pub use sync; // used for select!()
    pub use error; // used for try!()
    pub use fmt; // used for any formatting strings
    pub use option; // used for thread_local!{}
    pub use rt; // used for panic!()
    pub use vec; // used for vec![]
    pub use cell; // used for tls!
    pub use thread; // used for thread_local!
    pub use marker;  // used for tls!

    // The test runner calls ::std::env::args() but really wants realstd
    #[cfg(test)] pub use realstd::env as env;
    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
    //
    // It is also used in vec![]
    pub use slice;

    pub use boxed; // used for vec![]
}
<commit_msg>Rollup merge of #25414 - apasel422:patch-1, r=alexcrichton<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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 Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
//!
//! The rust standard library is available to all rust crates by
//! default, just as if contained an `extern crate std` import at the
//! crate root. Therefore the standard library can be accessed in
//! `use` statements through the path `std`, as in `use std::thread`,
//! or in expressions through the absolute path `::std`, as in
//! `::std::thread::sleep_ms(100)`.
//!
//! Furthermore, the standard library defines [The Rust
//! Prelude](prelude/index.html), a small collection of items, mostly
//! traits, that are imported into and available in every module.
//!
//! ## What is in the standard library
//!
//! The standard library is minimal, a set of battle-tested
//! core types and shared abstractions for the [broader Rust
//! ecosystem](https://crates.io) to build on.
//!
//! The [primitive types](#primitives), though not defined in the
//! standard library, are documented here, as are the predefined
//! [macros](#macros).
//!
//! ## Containers and collections
//!
//! The [`option`](option/index.html) and
//! [`result`](result/index.html) modules define optional and
//! error-handling types, `Option` and `Result`. The
//! [`iter`](iter/index.html) module defines Rust's iterator trait,
//! [`Iterator`](iter/trait.Iterator.html), which works with the `for`
//! loop to access collections.
//!
//! The common container type, `Vec`, a growable vector backed by an array,
//! lives in the [`vec`](vec/index.html) module. Contiguous, unsized regions
//! of memory, `[T]`, commonly called "slices", and their borrowed versions,
//! `&[T]`, commonly called "borrowed slices", are built-in types for which the
//! [`slice`](slice/index.html) module defines many methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
//! [`str`](str/index.html) module. Rust strings are immutable;
//! use the `String` type defined in [`string`](string/index.html)
//! for a mutable string builder.
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! Data may be shared by placing it in a reference-counted box or the
//! [`Rc`][rc/index.html] type, and if further contained in a [`Cell`
//! or `RefCell`](cell/index.html), may be mutated as well as shared.
//! Likewise, in a concurrent setting it is common to pair an
//! atomically-reference-counted box, [`Arc`](sync/struct.Arc.html),
//! with a [`Mutex`](sync/struct.Mutex.html) to get the same effect.
//!
//! The [`collections`](collections/index.html) module defines maps,
//! sets, linked lists and other typical collection types, including
//! the common [`HashMap`](collections/struct.HashMap.html).
//!
//! ## Platform abstractions and I/O
//!
//! Besides basic data types, the standard library is largely concerned
//! with abstracting over differences in common platforms, most notably
//! Windows and Unix derivatives.
//!
//! Common types of I/O, including [files](fs/struct.File.html),
//! [TCP](net/struct.TcpStream.html),
//! [UDP](net/struct.UdpSocket.html), are defined in the
//! [`io`](io/index.html), [`fs`](fs/index.html), and
//! [`net`](net/index.html) modules.
//!
//! The [`thread`](thread/index.html) module contains Rust's threading
//! abstractions. [`sync`](sync/index.html) contains further
//! primitive shared memory types, including
//! [`atomic`](sync/atomic/index.html) and
//! [`mpsc`](sync/mpsc/index.html), which contains the channel types
//! for message passing.

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "std"]
#![stable(feature = "rust1", since = "1.0.0")]
#![staged_api]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]
#![doc(test(no_crate_inject, attr(deny(warnings))))]
#![doc(test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]

#![feature(alloc)]
#![feature(allow_internal_unstable)]
#![feature(associated_consts)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(debug_builders)]
#![feature(into_cow)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage, thread_local, asm)]
#![feature(macro_reexport)]
#![feature(optin_builtin_traits)]
#![feature(rand)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(str_char)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unique)]
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(zero_one)]
#![cfg_attr(test, feature(float_from_str_radix))]
#![cfg_attr(test, feature(test, rustc_private, std_misc))]

// Don't link to std. We are std.
#![feature(no_std)]
#![no_std]

#![allow(trivial_casts)]
#![deny(missing_docs)]

#[cfg(test)] extern crate test;
#[cfg(test)] #[macro_use] extern crate log;

#[macro_use]
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
    unreachable, unimplemented, write, writeln)]
extern crate core;

#[macro_use]
#[macro_reexport(vec, format)]
extern crate collections as core_collections;

#[allow(deprecated)] extern crate rand as core_rand;
extern crate alloc;
extern crate rustc_unicode;
extern crate libc;

#[macro_use] #[no_link] extern crate rustc_bitflags;

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate std as realstd;
#[cfg(test)] pub use realstd::marker;
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::boxed;

// NB: These reexports are in the order they should be listed in rustdoc

pub use core::any;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::convert;
pub use core::default;
pub use core::hash;
pub use core::intrinsics;
pub use core::iter;
#[cfg(not(test))] pub use core::marker;
pub use core::mem;
#[cfg(not(test))] pub use core::ops;
pub use core::ptr;
pub use core::raw;
pub use core::simd;
pub use core::result;
pub use core::option;
pub mod error;

#[cfg(not(test))] pub use alloc::boxed;
pub use alloc::rc;

pub use core_collections::borrow;
pub use core_collections::fmt;
pub use core_collections::slice;
pub use core_collections::str;
pub use core_collections::string;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::vec;

pub use rustc_unicode::char;

/* Exported macros */

#[macro_use]
mod macros;

mod rtdeps;

/* The Prelude. */

pub mod prelude;

/* Primitive types */

// NB: slice and str are primitive types too, but their module docs + primitive doc pages
// are inlined from the public re-exports of core_collections::{slice, str} above.

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod ascii;

pub mod thunk;

/* Common traits */

pub mod num;

/* Runtime and platform support */

#[macro_use]
pub mod thread;

pub mod collections;
pub mod dynamic_lib;
pub mod env;
pub mod ffi;
pub mod fs;
pub mod io;
pub mod net;
pub mod os;
pub mod path;
pub mod process;
pub mod sync;
pub mod time;

#[macro_use]
#[path = "sys/common/mod.rs"] mod sys_common;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

pub mod rt;
mod panicking;
mod rand;

// Some external utilities of the standard library rely on randomness (aka
// rustc_back::TempDir and tests) and need a way to get at the OS rng we've got
// here. This module is not at all intended for stabilization as-is, however,
// but it may be stabilized long-term. As a result we're exposing a hidden,
// unstable module so we can get our build working.
#[doc(hidden)]
#[unstable(feature = "rand")]
pub mod __rand {
    pub use rand::{thread_rng, ThreadRng, Rng};
}

// Modules that exist purely to document + host impl docs for primitive types

mod array;
mod bool;
mod unit;
mod tuple;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    pub use sync; // used for select!()
    pub use error; // used for try!()
    pub use fmt; // used for any formatting strings
    pub use option; // used for thread_local!{}
    pub use rt; // used for panic!()
    pub use vec; // used for vec![]
    pub use cell; // used for tls!
    pub use thread; // used for thread_local!
    pub use marker;  // used for tls!

    // The test runner calls ::std::env::args() but really wants realstd
    #[cfg(test)] pub use realstd::env as env;
    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
    //
    // It is also used in vec![]
    pub use slice;

    pub use boxed; // used for vec![]
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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 Rust standard library
//!
//! The Rust standard library is a group of interrelated modules defining
//! the core language traits, operations on built-in data types, collections,
//! platform abstractions, the task scheduler, runtime support for language
//! features and other common functionality.
//!
//! `std` includes modules corresponding to each of the integer types,
//! each of the floating point types, the `bool` type, tuples, characters,
//! strings (`str`), vectors (`vec`), managed boxes (`managed`), owned
//! boxes (`owned`), and unsafe and borrowed pointers (`ptr`, `borrowed`).
//! Additionally, `std` provides pervasive types (`option` and `result`),
//! task creation and communication primitives (`task`, `comm`), platform
//! abstractions (`os` and `path`), basic I/O abstractions (`io`), common
//! traits (`kinds`, `ops`, `cmp`, `num`, `to_str`), and complete bindings
//! to the C standard library (`libc`).
//!
//! # Standard library injection and the Rust prelude
//!
//! `std` is imported at the topmost level of every crate by default, as
//! if the first line of each crate was
//!
//!     extern mod std;
//!
//! This means that the contents of std can be accessed from any context
//! with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
//! etc.
//!
//! Additionally, `std` contains a `prelude` module that reexports many of the
//! most common types, traits and functions. The contents of the prelude are
//! imported into every *module* by default.  Implicitly, all modules behave as if
//! they contained the following prologue:
//!
//!     use std::prelude::*;

#[link(name = "std",
       vers = "0.9-pre",
       uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8",
       url = "https://github.com/mozilla/rust/tree/master/src/libstd")];

#[comment = "The Rust standard library"];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];

#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
      html_root_url = "http://static.rust-lang.org/doc/master")];

#[feature(macro_rules, globs, asm, managed_boxes)];

// Don't link to std. We are std.
#[no_std];

#[deny(non_camel_case_types)];
#[deny(missing_doc)];

// When testing libstd, bring in libuv as the I/O backend so tests can print
// things and all of the std::rt::io tests have an I/O interface to run on top
// of
#[cfg(test)] extern mod rustuv(vers = "0.9-pre");

// Make extra accessible for benchmarking
#[cfg(test)] extern mod extra(vers = "0.9-pre");

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern mod realstd(name = "std");
#[cfg(test)] pub use kinds = realstd::kinds;
#[cfg(test)] pub use ops = realstd::ops;
#[cfg(test)] pub use cmp = realstd::cmp;

// On Linux, link to the runtime with -lrt.
#[cfg(target_os = "linux")]
#[doc(hidden)]
pub mod linkhack {
    #[link_args="-lrustrt -lrt"]
    #[link_args = "-lpthread"]
    extern {
    }
}

/* The Prelude. */

pub mod prelude;

/* Primitive types */

#[path = "num/int_macros.rs"]   mod int_macros;
#[path = "num/uint_macros.rs"]  mod uint_macros;

#[path = "num/int.rs"]  pub mod int;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/uint.rs"] pub mod uint;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod unit;
pub mod bool;
pub mod char;
pub mod tuple;

pub mod vec;
pub mod at_vec;
pub mod str;

pub mod ascii;
pub mod send_str;

pub mod ptr;
pub mod owned;
pub mod managed;
pub mod borrow;
pub mod rc;

/* Core language traits */

#[cfg(not(test))] pub mod kinds;
#[cfg(not(test))] pub mod ops;
#[cfg(not(test))] pub mod cmp;

/* Common traits */

pub mod from_str;
pub mod num;
pub mod iter;
pub mod to_str;
pub mod to_bytes;
pub mod clone;
pub mod hash;
pub mod container;
pub mod default;
pub mod any;

/* Common data structures */

pub mod option;
pub mod result;
pub mod either;
pub mod hashmap;
pub mod cell;
pub mod trie;

/* Tasks and communication */

pub mod task;
pub mod comm;
pub mod select;
pub mod local_data;

/* Runtime and platform support */

pub mod libc;
pub mod c_str;
pub mod os;
pub mod path;
pub mod rand;
pub mod run;
pub mod cast;
pub mod fmt;
pub mod repr;
pub mod cleanup;
pub mod reflect;
pub mod condition;
pub mod logging;
pub mod util;
pub mod routine;
pub mod mem;

/* Unsupported interfaces */

// Private APIs
pub mod unstable;

/* For internal use, not exported */

mod unicode;
#[path = "num/cmath.rs"]
mod cmath;

// FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable'
// but name resolution doesn't work without it being pub.
pub mod rt;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    pub use clone;
    pub use cmp;
    pub use condition;
    pub use fmt;
    pub use kinds;
    pub use local_data;
    pub use logging;
    pub use logging;
    pub use option;
    pub use os;
    pub use rt;
    pub use str;
    pub use to_bytes;
    pub use to_str;
    pub use unstable;
}
<commit_msg>auto merge of #10341 : willingc/rust/minor-docfix, r=huonw<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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 Rust standard library
//!
//! The Rust standard library is a group of interrelated modules defining
//! the core language traits, operations on built-in data types, collections,
//! platform abstractions, the task scheduler, runtime support for language
//! features and other common functionality.
//!
//! `std` includes modules corresponding to each of the integer types,
//! each of the floating point types, the `bool` type, tuples, characters,
//! strings (`str`), vectors (`vec`), managed boxes (`managed`), owned
//! boxes (`owned`), and unsafe and borrowed pointers (`ptr`, `borrowed`).
//! Additionally, `std` provides pervasive types (`option` and `result`),
//! task creation and communication primitives (`task`, `comm`), platform
//! abstractions (`os` and `path`), basic I/O abstractions (`rt::io`), common
//! traits (`kinds`, `ops`, `cmp`, `num`, `to_str`), and complete bindings
//! to the C standard library (`libc`).
//!
//! # Standard library injection and the Rust prelude
//!
//! `std` is imported at the topmost level of every crate by default, as
//! if the first line of each crate was
//!
//!     extern mod std;
//!
//! This means that the contents of std can be accessed from any context
//! with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
//! etc.
//!
//! Additionally, `std` contains a `prelude` module that reexports many of the
//! most common types, traits and functions. The contents of the prelude are
//! imported into every *module* by default.  Implicitly, all modules behave as if
//! they contained the following prologue:
//!
//!     use std::prelude::*;

#[link(name = "std",
       vers = "0.9-pre",
       uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8",
       url = "https://github.com/mozilla/rust/tree/master/src/libstd")];

#[comment = "The Rust standard library"];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];

#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
      html_root_url = "http://static.rust-lang.org/doc/master")];

#[feature(macro_rules, globs, asm, managed_boxes)];

// Don't link to std. We are std.
#[no_std];

#[deny(non_camel_case_types)];
#[deny(missing_doc)];

// When testing libstd, bring in libuv as the I/O backend so tests can print
// things and all of the std::rt::io tests have an I/O interface to run on top
// of
#[cfg(test)] extern mod rustuv(vers = "0.9-pre");

// Make extra accessible for benchmarking
#[cfg(test)] extern mod extra(vers = "0.9-pre");

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern mod realstd(name = "std");
#[cfg(test)] pub use kinds = realstd::kinds;
#[cfg(test)] pub use ops = realstd::ops;
#[cfg(test)] pub use cmp = realstd::cmp;

// On Linux, link to the runtime with -lrt.
#[cfg(target_os = "linux")]
#[doc(hidden)]
pub mod linkhack {
    #[link_args="-lrustrt -lrt"]
    #[link_args = "-lpthread"]
    extern {
    }
}

/* The Prelude. */

pub mod prelude;

/* Primitive types */

#[path = "num/int_macros.rs"]   mod int_macros;
#[path = "num/uint_macros.rs"]  mod uint_macros;

#[path = "num/int.rs"]  pub mod int;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/uint.rs"] pub mod uint;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod unit;
pub mod bool;
pub mod char;
pub mod tuple;

pub mod vec;
pub mod at_vec;
pub mod str;

pub mod ascii;
pub mod send_str;

pub mod ptr;
pub mod owned;
pub mod managed;
pub mod borrow;
pub mod rc;

/* Core language traits */

#[cfg(not(test))] pub mod kinds;
#[cfg(not(test))] pub mod ops;
#[cfg(not(test))] pub mod cmp;

/* Common traits */

pub mod from_str;
pub mod num;
pub mod iter;
pub mod to_str;
pub mod to_bytes;
pub mod clone;
pub mod hash;
pub mod container;
pub mod default;
pub mod any;

/* Common data structures */

pub mod option;
pub mod result;
pub mod either;
pub mod hashmap;
pub mod cell;
pub mod trie;

/* Tasks and communication */

pub mod task;
pub mod comm;
pub mod select;
pub mod local_data;

/* Runtime and platform support */

pub mod libc;
pub mod c_str;
pub mod os;
pub mod path;
pub mod rand;
pub mod run;
pub mod cast;
pub mod fmt;
pub mod repr;
pub mod cleanup;
pub mod reflect;
pub mod condition;
pub mod logging;
pub mod util;
pub mod routine;
pub mod mem;

/* Unsupported interfaces */

// Private APIs
pub mod unstable;

/* For internal use, not exported */

mod unicode;
#[path = "num/cmath.rs"]
mod cmath;

// FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable'
// but name resolution doesn't work without it being pub.
pub mod rt;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    pub use clone;
    pub use cmp;
    pub use condition;
    pub use fmt;
    pub use kinds;
    pub use local_data;
    pub use logging;
    pub use logging;
    pub use option;
    pub use os;
    pub use rt;
    pub use str;
    pub use to_bytes;
    pub use to_str;
    pub use unstable;
}
<|endoftext|>


<commit_before>use std::io::{Read, Seek, SeekFrom};
use std::fs::File;
use std::io::ErrorKind::UnexpectedEof;

#[cfg(feature = "zstd")]
use zstd::block::decompress;

use super::*;

pub trait LogReader {
    fn read_segment_header(
        &mut self,
        id: LogID,
    ) -> std::io::Result<SegmentHeader>;

    fn read_segment_trailer(
        &mut self,
        id: LogID,
    ) -> std::io::Result<SegmentTrailer>;

    fn read_message_header(
        &mut self,
        id: LogID,
    ) -> std::io::Result<MessageHeader>;

    fn read_entry(
        &mut self,
        id: LogID,
        segment_len: usize,
        use_compression: bool,
    ) -> std::io::Result<LogRead>;
}

impl LogReader for File {
    fn read_segment_header(
        &mut self,
        id: LogID,
    ) -> std::io::Result<SegmentHeader> {
        // println!("seeking to {}", id);
        self.seek(SeekFrom::Start(id))?;

        // println!("trying to read {} bytes", SEG_HEADER_LEN);

        let mut seg_header_buf = [0u8; SEG_HEADER_LEN];
        self.read_exact(&mut seg_header_buf)?;

        // println!("read the header!!!");

        Ok(seg_header_buf.into())
    }

    fn read_segment_trailer(
        &mut self,
        id: LogID,
    ) -> std::io::Result<SegmentTrailer> {
        self.seek(SeekFrom::Start(id))?;

        let mut seg_trailer_buf = [0u8; SEG_TRAILER_LEN];
        self.read_exact(&mut seg_trailer_buf)?;

        Ok(seg_trailer_buf.into())
    }

    fn read_message_header(
        &mut self,
        id: LogID,
    ) -> std::io::Result<MessageHeader> {
        self.seek(SeekFrom::Start(id))?;

        let mut msg_header_buf = [0u8; MSG_HEADER_LEN];
        self.read_exact(&mut msg_header_buf)?;

        Ok(msg_header_buf.into())
    }

    /// read a buffer from the disk
    fn read_entry(
        &mut self,
        id: LogID,
        segment_len: usize,
        _use_compression: bool,
    ) -> std::io::Result<LogRead> {
        // println!("read_entry({})", id);
        let start = clock();
        let seg_start = id / segment_len as LogID * segment_len as LogID;
        assert!(seg_start + MSG_HEADER_LEN as LogID <= id);

        let ceiling = seg_start + segment_len as LogID -
            SEG_TRAILER_LEN as LogID;
        // println!("ceiling: {} id: {}", ceiling, id);

        assert!(id + MSG_HEADER_LEN as LogID <= ceiling);

        let header = self.read_message_header(id)?;
        assert!(id + MSG_HEADER_LEN as LogID + header.len as LogID <= ceiling);

        self.seek(SeekFrom::Start(id + MSG_HEADER_LEN as LogID))?;

        let max = (ceiling - id - MSG_HEADER_LEN as LogID) as usize;
        let mut len = header.len;
        if len > max {
            error!(
                "log read invalid message length, {} should be <= {}",
                len,
                max
            );
            M.read.measure(clock() - start);
            return Ok(LogRead::Corrupted(len));
        } else if len == 0 && !header.valid {
            // skip to next record, which starts with 1
            while len <= max {
                let mut byte = [0u8; 1];
                if let Err(e) = self.read_exact(&mut byte) {
                    if e.kind() == UnexpectedEof {
                        // we've hit the end of the file
                        break;
                    }
                    panic!("{:?}", e);
                }
                if byte[0] != 1 {
                    if byte[0] != 0 {
                        println!("failing at len {}, header {:?}", len, header);
                    }
                    debug_assert_eq!(byte[0], 0);
                    len += 1;
                } else {
                    break;
                }
            }
        }

        if !header.valid {
            M.read.measure(clock() - start);
            return Ok(LogRead::Zeroed(len + MSG_HEADER_LEN));
        }

        let mut buf = Vec::with_capacity(len);
        unsafe {
            buf.set_len(len);
        }
        self.read_exact(&mut buf)?;

        let checksum = crc16_arr(&buf);
        if checksum != header.crc16 {
            M.read.measure(clock() - start);
            return Ok(LogRead::Corrupted(len));
        }

        #[cfg(feature = "zstd")]
        let res = {
            if _use_compression {
                let start = clock();
                let res = Ok(LogRead::Flush(
                    header.lsn,
                    decompress(&*buf, max).unwrap(),
                    len,
                ));
                M.decompress.measure(clock() - start);
                res
            } else {
                Ok(LogRead::Flush(header.lsn, buf, len))
            }
        };

        #[cfg(not(feature = "zstd"))]
        let res = Ok(LogRead::Flush(header.lsn, buf, len));

        M.read.measure(clock() - start);
        res
    }
}
<commit_msg>fix overzealous panic<commit_after>use std::io::{Read, Seek, SeekFrom};
use std::fs::File;
use std::io::ErrorKind::UnexpectedEof;

#[cfg(feature = "zstd")]
use zstd::block::decompress;

use super::*;

pub trait LogReader {
    fn read_segment_header(
        &mut self,
        id: LogID,
    ) -> std::io::Result<SegmentHeader>;

    fn read_segment_trailer(
        &mut self,
        id: LogID,
    ) -> std::io::Result<SegmentTrailer>;

    fn read_message_header(
        &mut self,
        id: LogID,
    ) -> std::io::Result<MessageHeader>;

    fn read_entry(
        &mut self,
        id: LogID,
        segment_len: usize,
        use_compression: bool,
    ) -> std::io::Result<LogRead>;
}

impl LogReader for File {
    fn read_segment_header(
        &mut self,
        id: LogID,
    ) -> std::io::Result<SegmentHeader> {
        // println!("seeking to {}", id);
        self.seek(SeekFrom::Start(id))?;

        // println!("trying to read {} bytes", SEG_HEADER_LEN);

        let mut seg_header_buf = [0u8; SEG_HEADER_LEN];
        self.read_exact(&mut seg_header_buf)?;

        // println!("read the header!!!");

        Ok(seg_header_buf.into())
    }

    fn read_segment_trailer(
        &mut self,
        id: LogID,
    ) -> std::io::Result<SegmentTrailer> {
        self.seek(SeekFrom::Start(id))?;

        let mut seg_trailer_buf = [0u8; SEG_TRAILER_LEN];
        self.read_exact(&mut seg_trailer_buf)?;

        Ok(seg_trailer_buf.into())
    }

    fn read_message_header(
        &mut self,
        id: LogID,
    ) -> std::io::Result<MessageHeader> {
        self.seek(SeekFrom::Start(id))?;

        let mut msg_header_buf = [0u8; MSG_HEADER_LEN];
        self.read_exact(&mut msg_header_buf)?;

        Ok(msg_header_buf.into())
    }

    /// read a buffer from the disk
    fn read_entry(
        &mut self,
        id: LogID,
        segment_len: usize,
        _use_compression: bool,
    ) -> std::io::Result<LogRead> {
        // println!("read_entry({})", id);
        let start = clock();
        let seg_start = id / segment_len as LogID * segment_len as LogID;
        assert!(seg_start + MSG_HEADER_LEN as LogID <= id);

        let ceiling = seg_start + segment_len as LogID -
            SEG_TRAILER_LEN as LogID;
        // println!("ceiling: {} id: {}", ceiling, id);

        assert!(id + MSG_HEADER_LEN as LogID <= ceiling);

        let header = self.read_message_header(id)?;
        assert!(id + MSG_HEADER_LEN as LogID + header.len as LogID <= ceiling);

        self.seek(SeekFrom::Start(id + MSG_HEADER_LEN as LogID))?;

        let max = (ceiling - id - MSG_HEADER_LEN as LogID) as usize;
        let mut len = header.len;
        if len > max {
            error!(
                "log read invalid message length, {} should be <= {}",
                len,
                max
            );
            M.read.measure(clock() - start);
            return Ok(LogRead::Corrupted(len));
        } else if len == 0 && !header.valid {
            // skip to next record, which starts with 1
            while len <= max {
                let mut byte = [0u8; 1];
                if let Err(e) = self.read_exact(&mut byte) {
                    if e.kind() == UnexpectedEof {
                        // we've hit the end of the file
                        break;
                    }
                    panic!("{:?}", e);
                }
                if byte[0] != 1 {
                    len += 1;
                } else {
                    break;
                }
            }
        }

        if !header.valid {
            M.read.measure(clock() - start);
            return Ok(LogRead::Zeroed(len + MSG_HEADER_LEN));
        }

        let mut buf = Vec::with_capacity(len);
        unsafe {
            buf.set_len(len);
        }
        self.read_exact(&mut buf)?;

        let checksum = crc16_arr(&buf);
        if checksum != header.crc16 {
            M.read.measure(clock() - start);
            return Ok(LogRead::Corrupted(len));
        }

        #[cfg(feature = "zstd")]
        let res = {
            if _use_compression {
                let start = clock();
                let res = Ok(LogRead::Flush(
                    header.lsn,
                    decompress(&*buf, max).unwrap(),
                    len,
                ));
                M.decompress.measure(clock() - start);
                res
            } else {
                Ok(LogRead::Flush(header.lsn, buf, len))
            }
        };

        #[cfg(not(feature = "zstd"))]
        let res = Ok(LogRead::Flush(header.lsn, buf, len));

        M.read.measure(clock() - start);
        res
    }
}
<|endoftext|>


<commit_before>extern crate graphics_impl;
use std::bool;

static MAX_HORIZONTAL_PIXELS : uint = 128;
static MAX_VERTICAL_PIXELS : uint = 64;

struct Dimensions {
    width:  uint,
    height: uint
}

static SCHIP_dimensions :Dimensions = Dimensions{ width: 128, height: 64};
static  CHIP_dimensions :Dimensions = Dimensions{ width: 64,  height: 32};

/* Either CHIP or Super CHIP mode */
pub enum Mode { CHIP,
                SCHIP}

impl Mode {

    fn get_width(&self) -> uint {
        match *self {
            CHIP => CHIP_dimensions.width,
            SCHIP => SCHIP_dimensions.width
        }
    }

    fn get_height(&self) -> uint {
        match *self {
            CHIP  =>  CHIP_dimensions.width,
            SCHIP => SCHIP_dimensions.height
        }
    }
}

pub struct Graphics {
    mode :Mode,
    screen : [[bool, ..MAX_HORIZONTAL_PIXELS], ..MAX_VERTICAL_PIXELS],
    out : graphics_impl::Screen
}

impl Graphics {

    pub fn new() -> Graphics {
        Graphics { mode: CHIP,
                   /* Initialize all pixels to blank */
                   screen: [[false, ..MAX_HORIZONTAL_PIXELS], ..MAX_VERTICAL_PIXELS],
                   out: graphics_impl::Screen::new(256, 128,
                    CHIP_dimensions.width, CHIP_dimensions.height)
         }
    }

    pub fn set_mode(&mut self, mode:Mode) {
        self.mode = mode;
        self.out.set_x_max(mode.get_width());
        self.out.set_y_max(mode.get_height());
    }

    pub fn draw_pix(&mut self, x:uint, y:uint, set:bool) {
        self.screen[y][x] = set;
        self.out.draw_pix(x as int, y as int, set);
    }

    /* Draws a given line of 8 pixels starting at startx, starty,
     * returns whether a pixel was unset or not */
    pub fn draw_8_pix(&mut self, startx:u8, starty:u8, line:u8) -> bool {
        let mut unset_occured = false;
        for i in range(0, 8) {

            let x = ((startx + i as u8) as uint) % self.mode.get_width();
            let y = (starty as uint) % self.mode.get_height();
            let pix_state = if (line & (0x80 >> i)) != 0 {true} else {false};

            /* get set value of current pixel in line */
            let set = pix_state ^ self.screen[y][x];
            self.draw_pix(x, y, set);
            unset_occured = unset_occured || (pix_state && (!set));
        }

        return unset_occured;
    }

    pub fn scroll_right(&mut self, n:u8) {
        for y in range(0, self.mode.get_height()) {
            /*TODO research how to properly use a decreasing
             * iterator in a range instead of this solution */
            for x1 in range(-(self.mode.get_width() - 1), - (n as uint - 1)) {
                let x = -x1;
                let set = self.screen[x - n as uint][y];
                self.draw_pix(x, y, set);
            }
            for x  in range(0, n as uint) {
                self.draw_pix(x, y, false);
            }
        }
    }

    pub fn scroll_left(&mut self, n:u8) {
        let x_max = self.mode.get_width();

        for y in range(0 , self.mode.get_height()) {
            for x in range(0, x_max - n as uint) {
                let set = self.screen[x + n as uint][y];
                self.draw_pix(x, y, set);
            }
            for x in range(x_max - n as uint, x_max) {
                self.draw_pix(x, y, false);
            }
        }
    }

    pub fn scroll_down(&mut self, n:u8) {
        let y_max = self.mode.get_height();
        for x in range(0, self.mode.get_width()) {
            for y in range(0, y_max - n as uint) {
                let set = self.screen[x][y + n as uint];
                self.draw_pix(x, y, set);
            }

            for y in range(y_max - n as uint, y_max) {
                self.draw_pix(x, y, false);
            }
        }
    }

    pub fn clear_screen(&mut self) {
        for y in range(0, MAX_VERTICAL_PIXELS) {
            for x in range(0, MAX_HORIZONTAL_PIXELS) {
                self.screen[y][x] = false;
            }
        }
        self.out.clear_screen();
    }

    pub fn show(&self) {
        self.out.show();
    }
}

<commit_msg>added extended drawing to graphics for 16x16 sprites<commit_after>extern crate graphics_impl;
use std::bool;

static MAX_HORIZONTAL_PIXELS : uint = 128;
static MAX_VERTICAL_PIXELS : uint = 64;

struct Dimensions {
    width:  uint,
    height: uint
}

static SCHIP_dimensions :Dimensions = Dimensions{ width: 128, height: 64};
static  CHIP_dimensions :Dimensions = Dimensions{ width: 64,  height: 32};

/* Either CHIP or Super CHIP mode */
pub enum Mode { CHIP,
                SCHIP}

impl Mode {

    fn get_width(&self) -> uint {
        match *self {
            CHIP => CHIP_dimensions.width,
            SCHIP => SCHIP_dimensions.width
        }
    }

    fn get_height(&self) -> uint {
        match *self {
            CHIP  =>  CHIP_dimensions.width,
            SCHIP => SCHIP_dimensions.height
        }
    }
}

pub struct Graphics {
    mode :Mode,
    screen : [[bool, ..MAX_HORIZONTAL_PIXELS], ..MAX_VERTICAL_PIXELS],
    out : graphics_impl::Screen
}

impl Graphics {

    pub fn new() -> Graphics {
        Graphics { mode: CHIP,
                   /* Initialize all pixels to blank */
                   screen: [[false, ..MAX_HORIZONTAL_PIXELS], ..MAX_VERTICAL_PIXELS],
                   out: graphics_impl::Screen::new(256, 128,
                    CHIP_dimensions.width, CHIP_dimensions.height)
         }
    }

    pub fn set_mode(&mut self, mode:Mode) {
        self.mode = mode;
        self.out.set_x_max(mode.get_width());
        self.out.set_y_max(mode.get_height());
    }

    pub fn draw_pix(&mut self, x:uint, y:uint, set:bool) {
        self.screen[y][x] = set;
        self.out.draw_pix(x as int, y as int, set);
    }

    //TODO combine these two functions into a more generic one

    /* Draws a given line of 8 pixels starting at startx, starty,
     * returns whether a pixel was unset or not */
    pub fn draw_8_pix(&mut self, startx:u8, starty:u8, line:u8) -> bool {
        let mut unset_occured = false;
        for i in range(0u8, 8u8) {

            let x = ((startx + i) as uint) % self.mode.get_width();
            let y = (starty as uint) % self.mode.get_height();
            let pix_state = if (line & (0x80 >> i)) != 0 {true} else {false};

            /* get set value of current pixel in line */
            let set = pix_state ^ self.screen[y][x];
            self.draw_pix(x, y, set);
            unset_occured = unset_occured || (pix_state && (!set));
        }

        return unset_occured;
    }

    pub fn draw_16_pix(&mut self, startx:u8, starty:u8, line:u16) -> bool {
        let mut unset_occured = false;
        for i in range(0u16, 16u16) {

            let x = ((startx as u16 + i) as uint) % self.mode.get_width();
            let y = (starty as uint) % self.mode.get_height();
            let pix_state = if (line & (0x8000 >> i)) != 0 {true} else {false};
            let set = pix_state ^ self.screen[y][x];
            self.draw_pix(x, y, set);
            unset_occured = unset_occured || (pix_state && (!set));
        }

        return unset_occured;
    }

    pub fn scroll_right(&mut self, n:u8) {
        for y in range(0, self.mode.get_height()) {
            /*TODO research how to properly use a decreasing
             * iterator in a range instead of this solution */
            for x1 in range(-(self.mode.get_width() - 1), - (n as uint - 1)) {
                let x = -x1;
                let set = self.screen[x - n as uint][y];
                self.draw_pix(x, y, set);
            }
            for x  in range(0, n as uint) {
                self.draw_pix(x, y, false);
            }
        }
    }

    pub fn scroll_left(&mut self, n:u8) {
        let x_max = self.mode.get_width();

        for y in range(0 , self.mode.get_height()) {
            for x in range(0, x_max - n as uint) {
                let set = self.screen[x + n as uint][y];
                self.draw_pix(x, y, set);
            }
            for x in range(x_max - n as uint, x_max) {
                self.draw_pix(x, y, false);
            }
        }
    }

    pub fn scroll_down(&mut self, n:u8) {
        let y_max = self.mode.get_height();
        for x in range(0, self.mode.get_width()) {
            for y in range(0, y_max - n as uint) {
                let set = self.screen[x][y + n as uint];
                self.draw_pix(x, y, set);
            }

            for y in range(y_max - n as uint, y_max) {
                self.draw_pix(x, y, false);
            }
        }
    }

    pub fn clear_screen(&mut self) {
        for y in range(0, MAX_VERTICAL_PIXELS) {
            for x in range(0, MAX_HORIZONTAL_PIXELS) {
                self.screen[y][x] = false;
            }
        }
        self.out.clear_screen();
    }

    pub fn show(&self) {
        self.out.show();
    }
}

<|endoftext|>


<commit_before>extern crate glob;
extern crate log;
extern crate env_logger;

extern crate protobuf_codegen_pure;

extern crate protobuf_test_common;

use std::io::Read;
use std::io::Write;

use std::fs;
use std::path::Path;

use protobuf_test_common::build::*;

fn copy_test<P1 : AsRef<Path>, P2 : AsRef<Path>>(src: P1, dst: P2) {
    let mut content = Vec::new();
    fs::File::open(src.as_ref()).expect(&format!("open {}", src.as_ref().display()))
        .read_to_end(&mut content).expect("read_to_end");

    let mut write = fs::File::create(dst).expect("create");
    writeln!(write, "// generated").expect("write");
    writeln!(write, "// copied from {}", src.as_ref().display()).expect("write");
    writeln!(write, "").expect("write");
    write.write_all(&content).expect("write_all");
    write.flush().expect("flush");
}

// Copy tests from `protobuf-test` directory to the same directory here
fn copy_tests(dir: &str) {
    let src_dir = format!("../protobuf-test/{}", dir);
    for entry in fs::read_dir(&src_dir).expect(&format!("read_dir {}", src_dir)) {
        let file_name = entry.expect("entry").file_name().into_string().unwrap();

        if !file_name.ends_with(".rs") && !file_name.ends_with(".proto") {
            continue;
        }

        // skip temporary and generated files
        if file_name.starts_with(".") || file_name.ends_with("_pb.rs") || file_name == "mod.rs" {
            continue;
        }

        copy_test(
            &format!("../protobuf-test/{}/{}", dir, file_name),
            &format!("{}/{}", dir, file_name),
        )
    }
}

fn gen_in_dir(dir: &str) {
    gen_in_dir_impl(dir, |GenInDirArgs { out_dir, input, includes, customize }| {
        protobuf_codegen_pure::run(protobuf_codegen_pure::Args {
            out_dir, input, includes, customize
        })
    });
}

fn generate_pb_rs() {
    copy_tests("src/v2");
    copy_tests("src/v3");

    copy_tests("src/common/v2");
    copy_tests_v2_v3("src/common/v2", "src/common/v3");

    gen_in_dir("src/v2");
    gen_in_dir("src/v3");
    gen_in_dir("src/common/v2");
    gen_in_dir("src/common/v3");
}

fn main() {
    env_logger::init();

    clean_old_files();
    generate_pb_rs();
}
<commit_msg>Properly copy tests<commit_after>extern crate glob;
extern crate log;
extern crate env_logger;

extern crate protobuf_codegen_pure;

extern crate protobuf_test_common;

use std::io::Read;
use std::io::Write;

use std::fs;
use std::path::Path;

use protobuf_test_common::build::*;

fn copy_test<P1 : AsRef<Path>, P2 : AsRef<Path>>(src: P1, dst: P2) {
    let mut content = Vec::new();
    fs::File::open(src.as_ref()).expect(&format!("open {}", src.as_ref().display()))
        .read_to_end(&mut content).expect("read_to_end");

    let mut write = fs::File::create(dst).expect("create");
    writeln!(write, "// generated").expect("write");
    writeln!(write, "// copied from {}", src.as_ref().display()).expect("write");
    writeln!(write, "").expect("write");
    write.write_all(&content).expect("write_all");
    write.flush().expect("flush");
}

// Copy tests from `protobuf-test` directory to the same directory here
fn copy_tests(dir: &str) {
    let src_dir = format!("../protobuf-test/{}", dir);
    for entry in fs::read_dir(&src_dir).expect(&format!("read_dir {}", src_dir)) {
        let file_name = entry.expect("entry").file_name().into_string().unwrap();

        // Only copy rust and proto files
        if !file_name.ends_with(".rs")
            && !file_name.ends_with(".proto") && !file_name.ends_with(".proto3")
        {
            continue;
        }

        // Generated proto files
        if file_name.ends_with("_pb.rs") || file_name.ends_with("_pb_proto3.rs") {
            continue;
        }

        if file_name.starts_with(".") || file_name == "mod.rs" {
            continue;
        }

        copy_test(
            &format!("../protobuf-test/{}/{}", dir, file_name),
            &format!("{}/{}", dir, file_name),
        )
    }
}

fn gen_in_dir(dir: &str) {
    gen_in_dir_impl(dir, |GenInDirArgs { out_dir, input, includes, customize }| {
        protobuf_codegen_pure::run(protobuf_codegen_pure::Args {
            out_dir, input, includes, customize
        })
    });
}

fn generate_pb_rs() {
    copy_tests("src/v2");
    copy_tests("src/v3");

    copy_tests("src/common/v2");
    copy_tests_v2_v3("src/common/v2", "src/common/v3");

    gen_in_dir("src/v2");
    gen_in_dir("src/v3");
    gen_in_dir("src/common/v2");
    gen_in_dir("src/common/v3");
}

fn main() {
    env_logger::init();

    clean_old_files();
    generate_pb_rs();
}
<|endoftext|>