<commit_before>use std::collections::HashMap;
use std::error;

use super::row::{Row, RowError};
use super::schema::{Schema, Type};
use super::value::Value;
pub use super::row_builder::RowBuilder;

#[derive(Debug)]
pub enum StreamError {
    ValidationError(String),
    FieldNotFound(String),
    MissingRowId
}

impl From<RowError> for StreamError {
    fn from(err: RowError) -> StreamError {
        StreamError::MissingRowId
    }

}

#[derive(Debug)]
pub struct Stream {
    inserts: u64, // total number of inserts this Stream has seen
    lowest_id: Option<u64>,  // lowest id we still have in the Stream
    ttl: Option<u64>,
    rows: HashMap<u64, Row>,
    schema: Schema,

}

/**
This is a weird DB.  There's no primary key, since everything is based off append only streaming

*/
impl Stream {
    pub fn new() -> Stream {
        let mut stream = Stream::new_empty();
        stream.schema.add_type("_id", Type::Int);
        stream.schema.add_type("_created", Type::Timestamp);
        stream
    }

    // used in temporary tables
    pub fn new_empty() -> Stream {
        let mut stream = Stream {
            inserts: 0,
            lowest_id: None,
            rows: HashMap::new(),
            schema: Schema::new(),
            ttl: None,
        };
        stream
    }

    /* we take a HashMap of String -> Field here
    * we're going to convert it to HashMap<u8, Field> for the Row struct
    */
    pub fn insert(&mut self, mut row_builder: RowBuilder) -> Result<u64, StreamError> {
        // validate the inserted data
        let mut row_map : HashMap<u8, Value> = HashMap::new();
        for (key, val) in row_builder.data.drain() {
            // get the field from the schema
            // TypeDef
            let tmp = try!(self.schema.get(&key)
                               .ok_or(StreamError::FieldNotFound(key.to_string())));
            row_map.insert(tmp.id, val);

        }
        let row_id = self.inserts;
        let row = try!(Row::new(row_map));
        self.rows.insert(self.inserts, row.clone());
        self.inserts += 1;
        Ok(row_id)
    }

    fn get(&self, position: u64) -> Option<&Row> {
        self.rows.get(&position)
    }

}

impl<'a> IntoIterator for &'a Stream {
    type Item = &'a Row;
    type IntoIter = StreamIterator<'a>;

    fn into_iter(self) -> Self::IntoIter {
        // TODO fix the position
        StreamIterator{position:0,
                       stream: self}
    }
}

pub struct StreamIterator<'a> {
    position: u64,
    stream: &'a Stream,
}

impl<'a> StreamIterator<'a> {
    fn offset(&'a mut self, num: u64) -> &'a mut StreamIterator {
        self.position = num;
        self
    }
}

impl<'a> Iterator for StreamIterator<'a> {
    type Item = &'a Row;
    fn next(&mut self) -> Option<&'a Row> {
        let tmp = self.stream.get(self.position);
        self.position = self.position + 1;
        tmp
    }
}

#[cfg(test)]
mod tests {
    use super::{Stream, RowBuilder};

    use db::schema::{Schema, Type};
    use db::value::Value;
    use std::collections::HashMap;

    fn get_stream() -> Stream {
        let mut s = Stream::new();
        s.schema.add_type("name", Type::String);
        s.schema.add_type("age", Type::Int);
        s.schema.add_type("created", Type::Timestamp);
        s
    }

    fn get_stream_with_data() -> Stream {
        let mut s = get_stream();

        let names = vec!["Jon", "Dani", "Pete", "Sammy", "Steph",
                         "Blake", "Mr. Robot", "Ted", "Rachel", "Gloria"];
        let ages = vec![35, 29, 45, 56, 100,
                        35, 78, 32, 32, 67];

        for x in 0..10 {
            let mut row = RowBuilder::new();
            row.set_string("name", names[x]);
            row.set_int("age", ages[x]);
            let result = s.insert(row).unwrap();
        }
        s
    }

    #[test]
    fn test_insert_works_normal_case() {
        let mut s = Stream::new();
        let name_id = s.schema.add_type("name", Type::String);

        let mut row = RowBuilder::new();
        row.set_string("name", "test");
        let result = s.insert(row).unwrap();
        assert_eq!(result, 0);
        assert_eq!(s.inserts, 1);
        let row2 = s.get(result).unwrap();
        let name = row2.get(name_id).unwrap();
        // was the data inserted?
        assert_eq!(row2.get(name_id).unwrap().clone(),
                   Value::from("test"));

    }

    #[test]
    fn test_equality() {
        assert_eq!(Value::from("jon"), Value::from("jon"));
    }

    #[test]
    fn test_builder_insertion() {
        let mut s = get_stream();
        let mut row = RowBuilder::new();

        row.set_string("name", "value")
           .set_int("age", 10);
        s.insert(row);

        let mut c = 0;
        for r in s.into_iter() {
            c += 1;
        }
        assert_eq!(c, 1);
    }

    #[test]
    fn test_iterator_offset() {
        let mut s = get_stream_with_data();
        let mut i = 0;
        for row in s.into_iter().offset(9) {
            i = i + 1;
        }
        assert_eq!(i, 1);
    }

    #[test]
    fn test_chaining() {

    }
}<commit_msg>failing code where I want cool filtering<commit_after>use std::collections::HashMap;
use std::error;

use super::row::{Row, RowError};
use super::schema::{Schema, Type};
use super::value::Value;
pub use super::row_builder::RowBuilder;

#[derive(Debug)]
pub enum StreamError {
    ValidationError(String),
    FieldNotFound(String),
    MissingRowId
}

impl From<RowError> for StreamError {
    fn from(err: RowError) -> StreamError {
        StreamError::MissingRowId
    }

}

#[derive(Debug)]
pub struct Stream {
    inserts: u64, // total number of inserts this Stream has seen
    lowest_id: Option<u64>,  // lowest id we still have in the Stream
    ttl: Option<u64>,
    rows: HashMap<u64, Row>,
    schema: Schema,

}

/**
This is a weird DB.  There's no primary key, since everything is based off append only streaming

*/
impl Stream {
    pub fn new() -> Stream {
        let mut stream = Stream::new_empty();
        stream.schema.add_type("_id", Type::Int);
        stream.schema.add_type("_created", Type::Timestamp);
        stream
    }

    // used in temporary tables
    pub fn new_empty() -> Stream {
        let mut stream = Stream {
            inserts: 0,
            lowest_id: None,
            rows: HashMap::new(),
            schema: Schema::new(),
            ttl: None,
        };
        stream
    }

    /* we take a HashMap of String -> Field here
    * we're going to convert it to HashMap<u8, Field> for the Row struct
    */
    pub fn insert(&mut self, mut row_builder: RowBuilder) -> Result<u64, StreamError> {
        // validate the inserted data
        let mut row_map : HashMap<u8, Value> = HashMap::new();
        for (key, val) in row_builder.data.drain() {
            // get the field from the schema
            // TypeDef
            let tmp = try!(self.schema.get(&key)
                               .ok_or(StreamError::FieldNotFound(key.to_string())));
            row_map.insert(tmp.id, val);

        }
        let row_id = self.inserts;
        let row = try!(Row::new(row_map));
        self.rows.insert(self.inserts, row.clone());
        self.inserts += 1;
        Ok(row_id)
    }

    fn get(&self, position: u64) -> Option<&Row> {
        self.rows.get(&position)
    }

}

impl<'a> IntoIterator for &'a Stream {
    type Item = &'a Row;
    type IntoIter = StreamIterator<'a>;

    fn into_iter(self) -> Self::IntoIter {
        // TODO fix the position
        StreamIterator{position:0,
                       stream: self}
    }
}

pub struct StreamIterator<'a> {
    position: u64,
    stream: &'a Stream,
}

impl<'a> StreamIterator<'a> {
    fn offset(&'a mut self, num: u64) -> &'a mut StreamIterator {
        self.position = num;
        self
    }
}

impl<'a> Iterator for StreamIterator<'a> {
    type Item = &'a Row;
    fn next(&mut self) -> Option<&'a Row> {
        let tmp = self.stream.get(self.position);
        self.position = self.position + 1;
        tmp
    }
}

#[cfg(test)]
mod tests {
    use super::{Stream, RowBuilder};

    use db::schema::{Schema, Type};
    use db::value::Value;
    use std::collections::HashMap;

    fn get_stream() -> Stream {
        let mut s = Stream::new();
        s.schema.add_type("name", Type::String);
        s.schema.add_type("age", Type::Int);
        s.schema.add_type("created", Type::Timestamp);
        s
    }

    fn get_stream_with_data() -> Stream {
        let mut s = get_stream();

        let names = vec!["Jon", "Dani", "Pete", "Sammy", "Steph",
                         "Blake", "Mr. Robot", "Ted", "Rachel", "Gloria"];
        let ages = vec![35, 29, 45, 56, 100,
                        35, 78, 32, 32, 67];

        for x in 0..10 {
            let mut row = RowBuilder::new();
            row.set_string("name", names[x]);
            row.set_int("age", ages[x]);
            let result = s.insert(row).unwrap();
        }
        s
    }

    #[test]
    fn test_insert_works_normal_case() {
        let mut s = Stream::new();
        let name_id = s.schema.add_type("name", Type::String);

        let mut row = RowBuilder::new();
        row.set_string("name", "test");
        let result = s.insert(row).unwrap();
        assert_eq!(result, 0);
        assert_eq!(s.inserts, 1);
        let row2 = s.get(result).unwrap();
        let name = row2.get(name_id).unwrap();
        // was the data inserted?
        assert_eq!(row2.get(name_id).unwrap().clone(),
                   Value::from("test"));

    }

    #[test]
    fn test_equality() {
        assert_eq!(Value::from("jon"), Value::from("jon"));
    }

    #[test]
    fn test_builder_insertion() {
        let mut s = get_stream();
        let mut row = RowBuilder::new();

        row.set_string("name", "value")
           .set_int("age", 10);
        s.insert(row);

        let mut c = 0;
        for r in s.into_iter() {
            c += 1;
        }
        assert_eq!(c, 1);
    }

    #[test]
    fn test_iterator_offset() {
        let mut s = get_stream_with_data();
        let mut i = 0;
        for row in s.into_iter().offset(9) {
            i = i + 1;
        }
        assert_eq!(i, 1);
    }

    #[test]
    fn test_chaining() {
        let mut s = get_stream_with_data();
        // SELECT * from X where age > 25
        for row in s.into_iter().filter(|x| x["age"] > 25)  {

        }

    }
}<|endoftext|>


<commit_before>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::ffi::CString;
use std::fs::{File, OpenOptions};
use std::os::raw::{c_char, c_int, c_uint, c_ulonglong};
use std::path::Path;
use std::ptr::null_mut;

use sys_util::ioctl_with_mut_ref;

const DRM_IOCTL_BASE: c_uint = 0x64;

#[repr(C)]
#[derive(Copy, Clone)]
struct drm_version {
    version_major: c_int,
    version_minor: c_int,
    version_patchlevel: c_int,
    name_len: c_ulonglong,
    name: *mut c_char,
    date_len: c_ulonglong,
    date: *mut c_char,
    desc_len: c_ulonglong,
    desc: *mut c_char,
}

ioctl_iowr_nr!(DRM_IOCTL_VERSION, DRM_IOCTL_BASE, 0x0, drm_version);

fn get_drm_device_name(fd: &File) -> Result<String, ()> {
    let mut version = drm_version {
        version_major: 0,
        version_minor: 0,
        version_patchlevel: 0,
        name_len: 0,
        name: null_mut(),
        date_len: 0,
        date: null_mut(),
        desc_len: 0,
        desc: null_mut(),
    };

    // Get the length of the device name.
    if unsafe { ioctl_with_mut_ref(fd, DRM_IOCTL_VERSION(), &mut version) } < 0 {
        return Err(());
    }

    // Enough bytes to hold the device name and terminating null character.
    let mut name_bytes: Vec<u8> = vec![0; (version.name_len + 1) as usize];
    let mut version = drm_version {
        version_major: 0,
        version_minor: 0,
        version_patchlevel: 0,
        name_len: name_bytes.len() as c_ulonglong,
        name: name_bytes.as_mut_ptr() as *mut c_char,
        date_len: 0,
        date: null_mut(),
        desc_len: 0,
        desc: null_mut(),
    };

    // Safe as no more than name_len + 1 bytes will be written to name.
    if unsafe { ioctl_with_mut_ref(fd, DRM_IOCTL_VERSION(), &mut version) } < 0 {
        return Err(());
    }

    Ok(CString::new(&name_bytes[..(version.name_len as usize)])
       .map_err(|_| ())?
       .into_string().map_err(|_| ())?)
}

/// Returns a `fd` for an opened rendernode device, while filtering out specified
/// undesired drivers.
pub fn open_device(undesired: &[&str]) -> Result<File, ()> {
    const DRM_DIR_NAME: &str = "/dev/dri";
    const DRM_MAX_MINOR: u32 = 15;
    const RENDER_NODE_START: u32 = 128;

    for n in RENDER_NODE_START..(RENDER_NODE_START + DRM_MAX_MINOR + 1) {
        let path = Path::new(DRM_DIR_NAME).join(format!("renderD{}", n));

        if let Ok(fd) = OpenOptions::new().read(true).write(true).open(path) {
            if let Ok(name) = get_drm_device_name(&fd) {
                if !undesired.iter().any(|item| *item == name) {
                    return Ok(fd);
                }
            }
        }
    }

    Err(())
}

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

    #[test]
    #[ignore] // no access to /dev/dri
    fn open_rendernode_device() {
        let undesired: &[&str] = &["bad_driver", "another_bad_driver"];
        open_device(undesired).expect("failed to open rendernode");
    }
}
<commit_msg>virtwl: Fix DMABuf support on when building for 32bit.<commit_after>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::ffi::CString;
use std::fs::{File, OpenOptions};
use std::os::raw::{c_char, c_int, c_uint};
#[cfg(target_pointer_width = "64")]
use std::os::raw::c_ulong;
use std::path::Path;
use std::ptr::null_mut;

use sys_util::ioctl_with_mut_ref;

// Consistent with __kernel_size_t in include/uapi/asm-generic/posix_types.h.
#[cfg(not(target_pointer_width = "64"))]
#[allow(non_camel_case_types)]
type __kernel_size_t = c_uint;
#[cfg(target_pointer_width = "64")]
#[allow(non_camel_case_types)]
type __kernel_size_t = c_ulong;

const DRM_IOCTL_BASE: c_uint = 0x64;

#[repr(C)]
#[derive(Copy, Clone)]
struct drm_version {
    version_major: c_int,
    version_minor: c_int,
    version_patchlevel: c_int,
    name_len: __kernel_size_t,
    name: *mut c_char,
    date_len: __kernel_size_t,
    date: *mut c_char,
    desc_len: __kernel_size_t,
    desc: *mut c_char,
}

ioctl_iowr_nr!(DRM_IOCTL_VERSION, DRM_IOCTL_BASE, 0x0, drm_version);

fn get_drm_device_name(fd: &File) -> Result<String, ()> {
    let mut version = drm_version {
        version_major: 0,
        version_minor: 0,
        version_patchlevel: 0,
        name_len: 0,
        name: null_mut(),
        date_len: 0,
        date: null_mut(),
        desc_len: 0,
        desc: null_mut(),
    };

    // Get the length of the device name.
    if unsafe { ioctl_with_mut_ref(fd, DRM_IOCTL_VERSION(), &mut version) } < 0 {
        return Err(());
    }

    // Enough bytes to hold the device name and terminating null character.
    let mut name_bytes: Vec<u8> = vec![0; (version.name_len + 1) as usize];
    let mut version = drm_version {
        version_major: 0,
        version_minor: 0,
        version_patchlevel: 0,
        name_len: name_bytes.len() as __kernel_size_t,
        name: name_bytes.as_mut_ptr() as *mut c_char,
        date_len: 0,
        date: null_mut(),
        desc_len: 0,
        desc: null_mut(),
    };

    // Safe as no more than name_len + 1 bytes will be written to name.
    if unsafe { ioctl_with_mut_ref(fd, DRM_IOCTL_VERSION(), &mut version) } < 0 {
        return Err(());
    }

    Ok(CString::new(&name_bytes[..(version.name_len as usize)])
       .map_err(|_| ())?
       .into_string().map_err(|_| ())?)
}

/// Returns a `fd` for an opened rendernode device, while filtering out specified
/// undesired drivers.
pub fn open_device(undesired: &[&str]) -> Result<File, ()> {
    const DRM_DIR_NAME: &str = "/dev/dri";
    const DRM_MAX_MINOR: u32 = 15;
    const RENDER_NODE_START: u32 = 128;

    for n in RENDER_NODE_START..(RENDER_NODE_START + DRM_MAX_MINOR + 1) {
        let path = Path::new(DRM_DIR_NAME).join(format!("renderD{}", n));

        if let Ok(fd) = OpenOptions::new().read(true).write(true).open(path) {
            if let Ok(name) = get_drm_device_name(&fd) {
                if !undesired.iter().any(|item| *item == name) {
                    return Ok(fd);
                }
            }
        }
    }

    Err(())
}

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

    #[test]
    #[ignore] // no access to /dev/dri
    fn open_rendernode_device() {
        let undesired: &[&str] = &["bad_driver", "another_bad_driver"];
        open_device(undesired).expect("failed to open rendernode");
    }
}
<|endoftext|>


<commit_before>//! Tidy check to verify the validity of long error diagnostic codes.
//!
//! This ensures that error codes are used at most once and also prints out some
//! statistics about the error codes.

use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

pub fn check(path: &Path, bad: &mut bool) {
    let mut contents = String::new();
    let mut map: HashMap<_, Vec<_>> = HashMap::new();
    super::walk(path,
                &mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
                &mut |file| {
        let filename = file.file_name().unwrap().to_string_lossy();
        if filename != "error_codes.rs" && filename != "diagnostic_list.rs" {
            return
        }

        contents.truncate(0);
        t!(t!(File::open(file)).read_to_string(&mut contents));

        // In the `register_long_diagnostics!` macro, entries look like this:
        //
        // ```
        // EXXXX: r##"
        // <Long diagnostic message>
        // "##,
        // ```
        //
        // and these long messages often have error codes themselves inside
        // them, but we don't want to report duplicates in these cases. This
        // variable keeps track of whether we're currently inside one of these
        // long diagnostic messages.
        let mut inside_long_diag = false;
        for (num, line) in contents.lines().enumerate() {
            if inside_long_diag {
                inside_long_diag = !line.contains("\"##");
                continue
            }

            let mut search = line;
            while let Some(i) = search.find('E') {
                search = &search[i + 1..];
                let code = if search.len() > 4 {
                    search[..4].parse::<u32>()
                } else {
                    continue
                };
                let code = match code {
                    Ok(n) => n,
                    Err(..) => continue,
                };
                map.entry(code).or_default()
                   .push((file.to_owned(), num + 1, line.to_owned()));
                break
            }

            inside_long_diag = line.contains("r##\"");
        }
    });

    let mut max = 0;
    for (&code, entries) in map.iter() {
        if code > max {
            max = code;
        }
        if entries.len() == 1 {
            continue
        }

        tidy_error!(bad, "duplicate error code: {}", code);
        for &(ref file, line_num, ref line) in entries.iter() {
            tidy_error!(bad, "{}:{}: {}", file.display(), line_num, line);
        }
    }

    if !*bad {
        println!("* {} error codes", map.len());
        println!("* highest error code: E{:04}", max);
    }
}
<commit_msg>Remove unnecessary condition<commit_after>//! Tidy check to verify the validity of long error diagnostic codes.
//!
//! This ensures that error codes are used at most once and also prints out some
//! statistics about the error codes.

use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

pub fn check(path: &Path, bad: &mut bool) {
    let mut contents = String::new();
    let mut map: HashMap<_, Vec<_>> = HashMap::new();
    super::walk(path,
                &mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
                &mut |file| {
        let filename = file.file_name().unwrap().to_string_lossy();
        if filename != "error_codes.rs" {
            return
        }

        contents.truncate(0);
        t!(t!(File::open(file)).read_to_string(&mut contents));

        // In the `register_long_diagnostics!` macro, entries look like this:
        //
        // ```
        // EXXXX: r##"
        // <Long diagnostic message>
        // "##,
        // ```
        //
        // and these long messages often have error codes themselves inside
        // them, but we don't want to report duplicates in these cases. This
        // variable keeps track of whether we're currently inside one of these
        // long diagnostic messages.
        let mut inside_long_diag = false;
        for (num, line) in contents.lines().enumerate() {
            if inside_long_diag {
                inside_long_diag = !line.contains("\"##");
                continue
            }

            let mut search = line;
            while let Some(i) = search.find('E') {
                search = &search[i + 1..];
                let code = if search.len() > 4 {
                    search[..4].parse::<u32>()
                } else {
                    continue
                };
                let code = match code {
                    Ok(n) => n,
                    Err(..) => continue,
                };
                map.entry(code).or_default()
                   .push((file.to_owned(), num + 1, line.to_owned()));
                break
            }

            inside_long_diag = line.contains("r##\"");
        }
    });

    let mut max = 0;
    for (&code, entries) in map.iter() {
        if code > max {
            max = code;
        }
        if entries.len() == 1 {
            continue
        }

        tidy_error!(bad, "duplicate error code: {}", code);
        for &(ref file, line_num, ref line) in entries.iter() {
            tidy_error!(bad, "{}:{}: {}", file.display(), line_num, line);
        }
    }

    if !*bad {
        println!("* {} error codes", map.len());
        println!("* highest error code: E{:04}", max);
    }
}
<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// 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. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#![allow(clippy::range_plus_one)]

extern crate once_cell;
extern crate maplit;
#[cfg(test)]
#[macro_use]
extern crate pest;
#[cfg(not(test))]
extern crate pest;

use std::fmt::Display;

pub mod ast;
pub mod optimizer;
pub mod parser;
pub mod validator;

pub fn unwrap_or_report<T, E>(result: Result<T, E>) -> T
where
    E: IntoIterator,
    E::Item: Display,
{
    result.unwrap_or_else(|e| {
        panic!(
            "grammar error\n\n{}",
            &e.into_iter()
                .map(|error| format!("{}", error))
                .collect::<Vec<_>>()
                .join("\n\n")
        )
    })
}

#[doc(hidden)]
pub static UNICODE_PROPERTY_NAMES: &[&str] = &[
    /* BINARY */
    "ALPHABETIC",
    "BIDI_CONTROL",
    "CASE_IGNORABLE",
    "CASED",
    "CHANGES_WHEN_CASEFOLDED",
    "CHANGES_WHEN_CASEMAPPED",
    "CHANGES_WHEN_LOWERCASED",
    "CHANGES_WHEN_TITLECASED",
    "CHANGES_WHEN_UPPERCASED",
    "DASH",
    "DEFAULT_IGNORABLE_CODE_POINT",
    "DEPRECATED",
    "DIACRITIC",
    "EXTENDER",
    "GRAPHEME_BASE",
    "GRAPHEME_EXTEND",
    "GRAPHEME_LINK",
    "HEX_DIGIT",
    "HYPHEN",
    "IDS_BINARY_OPERATOR",
    "IDS_TRINARY_OPERATOR",
    "ID_CONTINUE",
    "ID_START",
    "IDEOGRAPHIC",
    "JOIN_CONTROL",
    "LOGICAL_ORDER_EXCEPTION",
    "LOWERCASE",
    "MATH",
    "NONCHARACTER_CODE_POINT",
    "OTHER_ALPHABETIC",
    "OTHER_DEFAULT_IGNORABLE_CODE_POINT",
    "OTHER_GRAPHEME_EXTEND",
    "OTHER_ID_CONTINUE",
    "OTHER_ID_START",
    "OTHER_LOWERCASE",
    "OTHER_MATH",
    "OTHER_UPPERCASE",
    "PATTERN_SYNTAX",
    "PATTERN_WHITE_SPACE",
    "PREPENDED_CONCATENATION_MARK",
    "QUOTATION_MARK",
    "RADICAL",
    "REGIONAL_INDICATOR",
    "SENTENCE_TERMINAL",
    "SOFT_DOTTED",
    "TERMINAL_PUNCTUATION",
    "UNIFIED_IDEOGRAPH",
    "UPPERCASE",
    "VARIATION_SELECTOR",
    "WHITE_SPACE",
    "XID_CONTINUE",
    "XID_START",
    /* CATEGORY */
    "CASED_LETTER",
    "CLOSE_PUNCTUATION",
    "CONNECTOR_PUNCTUATION",
    "CONTROL",
    "CURRENCY_SYMBOL",
    "DASH_PUNCTUATION",
    "DECIMAL_NUMBER",
    "ENCLOSING_MARK",
    "FINAL_PUNCTUATION",
    "FORMAT",
    "INITIAL_PUNCTUATION",
    "LETTER",
    "LETTER_NUMBER",
    "LINE_SEPARATOR",
    "LOWERCASE_LETTER",
    "MARK",
    "MATH_SYMBOL",
    "MODIFIER_LETTER",
    "MODIFIER_SYMBOL",
    "NONSPACING_MARK",
    "NUMBER",
    "OPEN_PUNCTUATION",
    "OTHER",
    "OTHER_LETTER",
    "OTHER_NUMBER",
    "OTHER_PUNCTUATION",
    "OTHER_SYMBOL",
    "PARAGRAPH_SEPARATOR",
    "PRIVATE_USE",
    "PUNCTUATION",
    "SEPARATOR",
    "SPACE_SEPARATOR",
    "SPACING_MARK",
    "SURROGATE",
    "SYMBOL",
    "TITLECASE_LETTER",
    "UNASSIGNED",
    "UPPERCASE_LETTER",
];
<commit_msg>Update lib.rs<commit_after>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// 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. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#![allow(clippy::range_plus_one)]

extern crate once_cell;
#[cfg(test)]
#[macro_use]
extern crate pest;
#[cfg(not(test))]
extern crate pest;

use std::fmt::Display;

pub mod ast;
pub mod optimizer;
pub mod parser;
pub mod validator;

pub fn unwrap_or_report<T, E>(result: Result<T, E>) -> T
where
    E: IntoIterator,
    E::Item: Display,
{
    result.unwrap_or_else(|e| {
        panic!(
            "grammar error\n\n{}",
            &e.into_iter()
                .map(|error| format!("{}", error))
                .collect::<Vec<_>>()
                .join("\n\n")
        )
    })
}

#[doc(hidden)]
pub static UNICODE_PROPERTY_NAMES: &[&str] = &[
    /* BINARY */
    "ALPHABETIC",
    "BIDI_CONTROL",
    "CASE_IGNORABLE",
    "CASED",
    "CHANGES_WHEN_CASEFOLDED",
    "CHANGES_WHEN_CASEMAPPED",
    "CHANGES_WHEN_LOWERCASED",
    "CHANGES_WHEN_TITLECASED",
    "CHANGES_WHEN_UPPERCASED",
    "DASH",
    "DEFAULT_IGNORABLE_CODE_POINT",
    "DEPRECATED",
    "DIACRITIC",
    "EXTENDER",
    "GRAPHEME_BASE",
    "GRAPHEME_EXTEND",
    "GRAPHEME_LINK",
    "HEX_DIGIT",
    "HYPHEN",
    "IDS_BINARY_OPERATOR",
    "IDS_TRINARY_OPERATOR",
    "ID_CONTINUE",
    "ID_START",
    "IDEOGRAPHIC",
    "JOIN_CONTROL",
    "LOGICAL_ORDER_EXCEPTION",
    "LOWERCASE",
    "MATH",
    "NONCHARACTER_CODE_POINT",
    "OTHER_ALPHABETIC",
    "OTHER_DEFAULT_IGNORABLE_CODE_POINT",
    "OTHER_GRAPHEME_EXTEND",
    "OTHER_ID_CONTINUE",
    "OTHER_ID_START",
    "OTHER_LOWERCASE",
    "OTHER_MATH",
    "OTHER_UPPERCASE",
    "PATTERN_SYNTAX",
    "PATTERN_WHITE_SPACE",
    "PREPENDED_CONCATENATION_MARK",
    "QUOTATION_MARK",
    "RADICAL",
    "REGIONAL_INDICATOR",
    "SENTENCE_TERMINAL",
    "SOFT_DOTTED",
    "TERMINAL_PUNCTUATION",
    "UNIFIED_IDEOGRAPH",
    "UPPERCASE",
    "VARIATION_SELECTOR",
    "WHITE_SPACE",
    "XID_CONTINUE",
    "XID_START",
    /* CATEGORY */
    "CASED_LETTER",
    "CLOSE_PUNCTUATION",
    "CONNECTOR_PUNCTUATION",
    "CONTROL",
    "CURRENCY_SYMBOL",
    "DASH_PUNCTUATION",
    "DECIMAL_NUMBER",
    "ENCLOSING_MARK",
    "FINAL_PUNCTUATION",
    "FORMAT",
    "INITIAL_PUNCTUATION",
    "LETTER",
    "LETTER_NUMBER",
    "LINE_SEPARATOR",
    "LOWERCASE_LETTER",
    "MARK",
    "MATH_SYMBOL",
    "MODIFIER_LETTER",
    "MODIFIER_SYMBOL",
    "NONSPACING_MARK",
    "NUMBER",
    "OPEN_PUNCTUATION",
    "OTHER",
    "OTHER_LETTER",
    "OTHER_NUMBER",
    "OTHER_PUNCTUATION",
    "OTHER_SYMBOL",
    "PARAGRAPH_SEPARATOR",
    "PRIVATE_USE",
    "PUNCTUATION",
    "SEPARATOR",
    "SPACE_SEPARATOR",
    "SPACING_MARK",
    "SURROGATE",
    "SYMBOL",
    "TITLECASE_LETTER",
    "UNASSIGNED",
    "UPPERCASE_LETTER",
];
<|endoftext|>


<commit_before>//! The `force` module
//!
//! This module will focus on internal game logic (outside of combat)
//! and building the necessary components for a smooth game experience.

pub mod startup;
pub mod shutdown;

//=========================================================================
// Base Definitions
//=========================================================================
use std::collections::HashMap;

//-------------------------------------------------------------------------
// Enums
//-------------------------------------------------------------------------
// To Do: To be expanded, fill in Class enum
enum Class {
	Consular(u8), //cleric
	Guardian(u8), //paladin
	Juggernaut(u8), //berserker
	Smuggler(u8), //rogue
	Operative(u8), //slayer
	BountyHunter(u8), //ranger
	Commoner, //Default
}

// To Do: To be expanded, fill in Species enum
enum Species {
	Human,
	Twilek,
	Zaabrak,

}

// To Do: To be expanded, fill in and detail the Effect enum
 enum Effect {
	Damage(i16),
	Buff,
	Debuff,
}

// To Do: Think about Enums to specify status effects like Buffs/Debuffs

//-------------------------------------------------------------------------
// Types
//-------------------------------------------------------------------------
type Interactive = Box<FnMut(Entity, Option<Vec<Entity>>) -> Option<Effect>>;

//-------------------------------------------------------------------------
// Traits
//-------------------------------------------------------------------------

// To Do: Perhaps some `temporary` trait to indicate buffs and debuffs ticks.

//-------------------------------------------------------------------------
// Structs
//-------------------------------------------------------------------------
// To Do: Need to look into Item Types or Item Enums more closely to resolve easy equipping
// as well as quick item action resolving
struct Item {
	name: String,
	description: String,
	value: u32,
	effect: Option<Interactive>,
}

struct Outfit {
	head: Option<Item>,
	shoulders: Option<Item>,
	body: Option<Item>,
	hand: Option<Item>,
	shoes: Option<Item>,
	enhance1: Option<Item>,
	enhance2: Option<Item>,
	weapon1: Option<Item>,
	weapon2: Option<Item>,
}

struct CoreBlock {
	strength: u8,
	dexterity: u8,
	constitution: u8,
	wisdom: u8,
	intelligence: u8,
	charisma: u8,
}

struct DefenseBlock {
	armor: u8,
	cmd: u8,
	ref_save: u8,
	fort_save: u8,
	will_save: u8,
}

#[derive(Default)]
struct AttackBlock {
	bab: u8,
	melee: u8,
	ranged: u8,
}

#[derive(Default)]
struct StatBlock {
	core: CoreBlock,
	attack: AttackBlock,
	defense: DefenseBlock,
}

struct Trait
{
	name: String,
	description: String,
	effect: Interactive
}

struct Ability
{
	name: String,
	description: String,
	effect: Interactive
}

//To Do: Figure out how to update HP with class hit dice
//To Do: Figure out how to dynamically keep interconnected values updated
struct Entity {
	hp: u32,
	level: u8,
	class: Vec<Class>,
	species: Species,
	skills: HashMap<String, u8>,
	stats: StatBlock,
	traits: HashMap<String, Trait>,
	abilities: HashMap<String, Ability>,
	statuses: Option<Vec<Effect>>,
	inventory: Vec<Item>,
	equipped: Outfit,
}

//=========================================================================
// Impl
//=========================================================================

//-------------------------------------------------------------------------
// Trait Impls
//-------------------------------------------------------------------------
// Default
impl Default for CoreBlock {
	fn default() -> CoreBlock{
		CoreBlock { strength:10, dexterity:10, constitution:10,
			wisdom:10, intelligence:10, charisma:10}
	}
}

impl Default for DefenseBlock {
	fn default() -> DefenseBlock{
		DefenseBlock { armor: 10, cmd: 10, ..Default::default()}
	}
}

impl Default for Outfit {
	fn default() -> Outfit {
		Outfit { head: None, shoulders: None, body: None,
			hand: None, shoes: None, enhance1: None, enhance2: None,
			weapon1: None, weapon2: None,
}
	}
}
impl Default for Entity {
	fn default() -> Entity{
		Entity{ hp: 0, level: 0, class: vec![Class::Commoner], species: Species::Human,
			skills: HashMap::new(), stats: Default::default(), traits: HashMap::new(),
			abilities: HashMap::new(), statuses: None, inventory: Vec::new(),
			equipped: Default::default()}
	}
}

// To Do: Think about implementing a `textNode` trait of some sort for easy conversion from structs to Cursive

//-------------------------------------------------------------------------
// Method Impls
//-------------------------------------------------------------------------

//=========================================================================
// Functions
//=========================================================================
// To Do: Fill in the `drinks_served` function (aka roll macros)
pub fn drinks_served(drink: &str) {

}<commit_msg>Changing item handling<commit_after>//! The `force` module
//!
//! This module will focus on internal game logic (outside of combat)
//! and building the necessary components for a smooth game experience.

pub mod startup;
pub mod shutdown;

//=========================================================================
// Base Definitions
//=========================================================================
use std::collections::HashMap;

//-------------------------------------------------------------------------
// Enums
//-------------------------------------------------------------------------
// To Do: To be expanded, fill in Class enum
enum Class {
	Consular(u8), //cleric
	Guardian(u8), //paladin
	Juggernaut(u8), //berserker
	Smuggler(u8), //rogue
	Operative(u8), //slayer
	BountyHunter(u8), //ranger
	Commoner, //Default
}

// To Do: To be expanded, fill in Species enum
enum Species {
	Human,
	Twilek,
	Zaabrak,

}

// To Do: To be expanded, fill in and detail the Effect enum
 enum Effect {
	Damage(i16),
	Buff,
	Debuff,
}

// To Do: Think about Enums to specify status effects like Buffs/Debuffs

//-------------------------------------------------------------------------
// Types
//-------------------------------------------------------------------------
type Interactive = Box<FnMut(Entity, Option<Vec<Entity>>) -> Option<Effect>>;

//-------------------------------------------------------------------------
// Traits
//-------------------------------------------------------------------------

// To Do: Perhaps some `temporary` trait to indicate buffs and debuffs ticks.
trait Item {
    fn appraise(&self) -> u16;
}
trait Equipment {
    fn equip(&self, person: Entity);
}

//-------------------------------------------------------------------------
// Structs
//-------------------------------------------------------------------------
// To Do: Need to look into Item Types or Item Enums more closely to resolve easy equipping
// as well as quick item action resolving

struct Armor;

enum Weapon {
    Lightsaber,
    Blaster,
    Stick,
}

struct Acessory;

enum Tool {
    Grenade,
    Holocron,
    Stim,
    Adrenal,
}

struct Loot;

struct Outfit {
	head: Option<Armor>,
	shoulders: Option<Armor>,
	body: Option<Armor>,
	hand: Option<Armor>,
	shoes: Option<Armor>,
	enhance: Vec<Option<Acessory>>,
	main_hand: Option<Weapon>,
	off_hand: Option<Weapon>,
}

struct CoreBlock {
	strength: u8,
	dexterity: u8,
	constitution: u8,
	wisdom: u8,
	intelligence: u8,
	charisma: u8,
}

struct DefenseBlock {
	armor: u8,
	cmd: u8,
	ref_save: u8,
	fort_save: u8,
	will_save: u8,
}

#[derive(Default)]
struct AttackBlock {
	bab: u8,
	melee: u8,
	ranged: u8,
}

#[derive(Default)]
struct StatBlock {
	core: CoreBlock,
	attack: AttackBlock,
	defense: DefenseBlock,
}

struct Trait
{
	name: String,
	description: String,
	effect: Interactive
}

struct Ability
{
	name: String,
	description: String,
	effect: Interactive
}

//To Do: Figure out how to update HP with class hit dice
//To Do: Figure out how to dynamically keep interconnected values updated
struct Entity {
	hp: u32,
	level: u8,
	class: Vec<Class>,
	species: Species,
	skills: HashMap<String, u8>,
	stats: StatBlock,
	traits: HashMap<String, Trait>,
	abilities: HashMap<String, Ability>,
	statuses: Option<Vec<Effect>>,
	inventory: Vec<Box<Item>>,
	equipped: Outfit,
}

//=========================================================================
// Impl
//=========================================================================

//-------------------------------------------------------------------------
// Trait Impls
//-------------------------------------------------------------------------
// Default
impl Default for CoreBlock {
	fn default() -> CoreBlock{
		CoreBlock { strength:10, dexterity:10, constitution:10,
			wisdom:10, intelligence:10, charisma:10}
	}
}

impl Default for DefenseBlock {
	fn default() -> DefenseBlock{
		DefenseBlock { armor: 10, cmd: 10, ..Default::default()}
	}
}

impl Default for Outfit {
	fn default() -> Outfit {
		Outfit { head: None, shoulders: None, body: None,
			hand: None, shoes: None, enhance: vec![None],
			main_hand: None, off_hand: None,
}
	}
}
impl Default for Entity {
	fn default() -> Entity{
		Entity{ hp: 0, level: 0, class: vec![Class::Commoner], species: Species::Human,
			skills: HashMap::new(), stats: Default::default(), traits: HashMap::new(),
			abilities: HashMap::new(), statuses: None, inventory: Vec::new(),
			equipped: Default::default()}
	}
}

// To Do: Think about implementing a `textNode` trait of some sort for easy conversion from structs to Cursive

//-------------------------------------------------------------------------
// Method Impls
//-------------------------------------------------------------------------

//=========================================================================
// Functions
//=========================================================================
// To Do: Fill in the `drinks_served` function (aka roll macros)
pub fn drinks_served(drink: &str) {

}
<|endoftext|>


<commit_before>// (c) 2016 Productize SPRL <joost@productize.be>

use std::io;

use Sexp;
use symbolic_expressions::Result;
use symbolic_expressions::Formatter;

// custom symbolic_expressions formatter that aims to be
// kicad compatible

pub struct KicadFormatter {
    initial_indent_level:i64,
    indent:i64,
    stack:Vec<Option<String>>,
    ind:Vec<u8>,
    poly_xy_count:i64,
}

impl KicadFormatter {

    pub fn new(initial_indent_level:i64) -> KicadFormatter {
        KicadFormatter {
            initial_indent_level:initial_indent_level,
            indent:initial_indent_level,
            stack:vec![],
            ind:vec![b' ',b' '], // two spaces
            poly_xy_count:0,
        }
    }

    fn is(&self, what:&'static str) -> bool {
        self.stack.iter().find(
            |x:&&Option<String>| {
                if let Some(ref y) = **x {
                    y == what
                } else {
                    false
                }
            }).is_some()
    }

    fn parent_is(&self, what:&'static str) -> bool {
        if let Some(s) = self.stack.last() {
            if let Some(ref t) = *s {
                return t == what
            }
        }
        false
    }

    fn indent<W:io::Write>(&self, writer:&mut W) -> Result<()> {
        try!(writer.write_all(b"\n"));
        for _ in 0..self.indent {
            try!(writer.write_all(&self.ind));
        }
        Ok(())
    }

    fn indent_plus<W:io::Write>(&mut self, writer:&mut W) -> Result<()> {
        self.indent+=1;
        let res = self.indent(writer);
        self.indent-=1;
        res
    }
}

impl Formatter for KicadFormatter {
    fn open<W>(&mut self, writer: &mut W, value:Option<&Sexp>) -> Result<()>
        where W: io::Write
    {
        let mut ele = String::new();
        // if first element is string
        if let Some(ref sexp) = value {
            if let Sexp::String(ref s) = **sexp {
                ele.push_str(s);
            }
        }
        if self.parent_is("module") {
            match &ele[..] {
                "at" | "descr" | "fp_text" |
                "fp_line" | "fp_poly" | "pad" |
                "model"
                    => {
                        try!(self.indent_plus(writer));
                    },
                _ => ()
            }
            match &ele[..] {
                "fp_text" | "fp_poly" | "model" => {
                    self.indent += 1;
                },
                _ => ()
            }
            if let "fp_poly" = &ele[..] {
                self.poly_xy_count = 0;
            }
        }
        if self.is("fp_poly") {
            if let "xy" = &ele[..] {
                self.poly_xy_count += 1;
                if self.poly_xy_count == 5 {
                    try!(self.indent_plus(writer));
                    self.poly_xy_count = 1;
                }
            }
        }
        if self.is("fp_text") {
            if let "effects" = &ele[..] {
                try!(self.indent_plus(writer));
            }
        }
        if !ele.is_empty() {
            self.stack.push(Some(ele))
        } else {
            self.stack.push(None)
        }
        writer.write_all(b"(").map_err(From::from)
    }
    fn element<W>(&mut self, writer: &mut W, _value:&Sexp) -> Result<()>
        where W: io::Write
    {
        writer.write_all(b" ").map_err(From::from)
    }

    fn close<W>(&mut self, writer: &mut W) -> Result<()>
        where W: io::Write
    {
        if let Some(Some(s)) = self.stack.pop() {
            if self.is("module") {
                match &s[..] {
                    "fp_text" | "fp_poly" | "model" => {
                        self.indent -= 1
                    },
                    _ => ()
                }
                match &s[..] {
                    "fp_text" | "model" => {
                        try!(self.indent_plus(writer));
                    },
                    _ => (),
                }
            }
            if let "module" = &s[..] {
                try!(self.indent(writer));
            }
        }
        writer.write_all(b")").map_err(From::from)
    }
}

<commit_msg>kicad formatter work<commit_after>// (c) 2016 Productize SPRL <joost@productize.be>

use std::io;

use Sexp;
use symbolic_expressions::Result;
use symbolic_expressions::Formatter;

// custom symbolic_expressions formatter that aims to be
// kicad compatible

pub struct KicadFormatter {
    initial_indent_level:i64,
    indent:i64,
    stack:Vec<Option<String>>,
    ind:Vec<u8>,
    poly_xy_count:i64,
}

impl KicadFormatter {

    pub fn new(initial_indent_level:i64) -> KicadFormatter {
        KicadFormatter {
            initial_indent_level:initial_indent_level,
            indent:initial_indent_level,
            stack:vec![],
            ind:vec![b' ',b' '], // two spaces
            poly_xy_count:0,
        }
    }

    fn is(&self, what:&'static str) -> bool {
        self.stack.iter().find(
            |x:&&Option<String>| {
                if let Some(ref y) = **x {
                    y == what
                } else {
                    false
                }
            }).is_some()
    }

    fn parent_is(&self, what:&'static str) -> bool {
        if let Some(s) = self.stack.last() {
            if let Some(ref t) = *s {
                return t == what
            }
        }
        false
    }

    fn indent<W:io::Write>(&self, writer:&mut W) -> Result<()> {
        try!(writer.write_all(b"\n"));
        for _ in 0..self.indent {
            try!(writer.write_all(&self.ind));
        }
        Ok(())
    }

    fn indent_plus<W:io::Write>(&mut self, writer:&mut W) -> Result<()> {
        self.indent+=1;
        let res = self.indent(writer);
        self.indent-=1;
        res
    }

    fn want_indent(&self, value:&Sexp) -> bool {
        let l = if let Sexp::List(ref l) = *value {
            l
        } else {
            return false
        };
        if l.is_empty() {
            return false
        }
        let first = &l[0];
        if let Sexp::String(ref ele) = *first {
            if self.parent_is("module") {
                match &ele[..] {
                    "at" | "descr" | "fp_text" |
                    "fp_line" | "fp_poly" | "pad" |
                    "model" => return true,
                    _ => (),
                }
            }
            if self.parent_is("fp_text") {
                match &ele[..] {
                    "effects" => return true,
                    _ => (),
                }
            }
            if self.parent_is("pts") {
                match &ele[..] {
                    "xy" => {
                        if self.poly_xy_count == 4 {
                            return true
                        }
                    },
                    _ => ()
                }
            }
        }
        false
    }

}

impl Formatter for KicadFormatter {

    fn open<W>(&mut self, writer: &mut W, value:Option<&Sexp>) -> Result<()>
        where W: io::Write
    {
        let mut ele = String::new();
        // if first element is string
        if let Some(ref sexp) = value {
            if let Sexp::String(ref s) = **sexp {
                ele.push_str(s);
            }
        }
        if self.parent_is("module") {
            match &ele[..] {
                "at" | "descr" | "fp_text" |
                "fp_line" | "fp_poly" | "pad" |
                "model"
                    => {
                        try!(self.indent_plus(writer));
                    },
                _ => ()
            }
            match &ele[..] {
                "fp_text" | "fp_poly" | "model" => {
                    self.indent += 1;
                },
                _ => ()
            }
            if let "fp_poly" = &ele[..] {
                self.poly_xy_count = 0;
            }
        }
        if self.is("fp_poly") {
            if let "xy" = &ele[..] {
                self.poly_xy_count += 1;
                if self.poly_xy_count == 5 {
                    try!(self.indent_plus(writer));
                    self.poly_xy_count = 1;
                }
            }
        }
        if self.is("fp_text") {
            if let "effects" = &ele[..] {
                try!(self.indent_plus(writer));
            }
        }
        if !ele.is_empty() {
            self.stack.push(Some(ele))
        } else {
            self.stack.push(None)
        }
        writer.write_all(b"(").map_err(From::from)
    }

    fn element<W>(&mut self, writer: &mut W, value:&Sexp) -> Result<()>
        where W: io::Write
    {
        // get rid of the space if we will be putting a newline next
        if !self.want_indent(value) {
            writer.write_all(b" ").map_err(From::from)
        } else {
            Ok(())
        }

    }

    fn close<W>(&mut self, writer: &mut W) -> Result<()>
        where W: io::Write
    {
        if let Some(Some(s)) = self.stack.pop() {
            if self.is("module") {
                match &s[..] {
                    "fp_text" | "fp_poly" | "model" => {
                        self.indent -= 1
                    },
                    _ => ()
                }
                match &s[..] {
                    "fp_text" | "model" => {
                        try!(self.indent_plus(writer));
                    },
                    _ => (),
                }
            }
            if let "module" = &s[..] {
                try!(self.indent(writer));
            }
        }
        writer.write_all(b")").map_err(From::from)
    }
}

<|endoftext|>


<commit_before>//! Functions related to formatting and printing lines from a `Tokenizer`.

use std::io::BufRead;

use ansi_term::Colour;

use tokenizer::Tokenizer;
use types::LineType;

/// Print a token stream to an ANSI terminal.
pub fn print_lines<R>(tokenizer: &mut Tokenizer<R>) where R: BufRead {
    while let Some(token) = tokenizer.next() {
        match token {
            LineType::Empty => println!(""),
            LineType::Title(_) => debug!("Ignoring title"),
            LineType::Description(text) => println!("  {}", text),
            LineType::ExampleText(text) => println!("  {}", Colour::Green.paint(format!("- {}", text))),
            LineType::ExampleCode(text) => println!("  {}", Colour::Cyan.paint(format!("  {}", text))),
            LineType::Other(text) => debug!("Unknown line type: {:?}", text),
        }
    }
    println!("");
}
<commit_msg>Underline parameters in example code<commit_after>//! Functions related to formatting and printing lines from a `Tokenizer`.

use std::io::BufRead;

use ansi_term::{Colour, ANSIStrings};

use tokenizer::Tokenizer;
use types::LineType;

/// Provide formatting for {{ curly braces }} in ExampleCode lines
fn format_braces(text: &str) -> String {
    let parts = text.split("{{").flat_map(|s| s.split("}}"))
                    .enumerate()
                    .map(|(i, v)| {
                        if i % 2 == 0 {
                            Colour::Cyan.paint(v)
                        } else {
                            Colour::Cyan.underline().paint(v)
                        }
                    })
                    .collect::<Vec<_>>();
    return ANSIStrings(&parts).to_string()
}

/// Print a token stream to an ANSI terminal.
pub fn print_lines<R>(tokenizer: &mut Tokenizer<R>) where R: BufRead {
    while let Some(token) = tokenizer.next() {
        match token {
            LineType::Empty => println!(""),
            LineType::Title(_) => debug!("Ignoring title"),
            LineType::Description(text) => println!("  {}", text),
            LineType::ExampleText(text) => println!("  {}", Colour::Green.paint(format!("- {}", text))),
            LineType::ExampleCode(text) => println!("  {}", &format_braces(&text)),
            LineType::Other(text) => debug!("Unknown line type: {:?}", text),
        }
    }
    println!("");
}
<|endoftext|>


<commit_before>// Copyright (c) 2018, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use crate::util::*;
use crate::api::ChromaSampling;
use crate::context::SB_SIZE;
use crate::mc::SUBPEL_FILTER_SIZE;

#[cfg(test)]
use crate::tiling::*;

mod plane;
pub use plane::*;

const FRAME_MARGIN: usize = 16 + SUBPEL_FILTER_SIZE;

/// Override the frame type decision
///
/// Only certain frame types can be selected.
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum FrameTypeOverride {
  /// Do not force any decision.
  No,
  /// Force the frame to be a Keyframe.
  Key,
}

/// Optional per-frame encoder parameters
#[derive(Debug, Clone, Copy)]
pub struct FrameParameters {
  /// Force emitted frame to be of the type selected
  pub frame_type_override: FrameTypeOverride,
}

#[derive(Debug, Clone)]
pub struct Frame<T: Pixel> {
  pub planes: [Plane<T>; 3]
}

impl<T: Pixel> Frame<T> {
  pub fn new(width: usize, height: usize, chroma_sampling: ChromaSampling) -> Self {
    let luma_width = width.align_power_of_two(3);
    let luma_height = height.align_power_of_two(3);
    let luma_padding = SB_SIZE + FRAME_MARGIN;

    let (chroma_sampling_period_x, chroma_sampling_period_y) =
      chroma_sampling.sampling_period();
    let chroma_width = luma_width / chroma_sampling_period_x;
    let chroma_height = luma_height / chroma_sampling_period_y;
    let chroma_padding_x = luma_padding / chroma_sampling_period_x;
    let chroma_padding_y = luma_padding / chroma_sampling_period_y;
    let chroma_decimation_x = chroma_sampling_period_x - 1;
    let chroma_decimation_y = chroma_sampling_period_y - 1;

    Frame {
      planes: [
        Plane::new(
          luma_width, luma_height,
          0, 0,
          luma_padding, luma_padding
        ),
        Plane::new(
          chroma_width, chroma_height,
          chroma_decimation_x, chroma_decimation_y,
          chroma_padding_x, chroma_padding_y
        ),
        Plane::new(
          chroma_width, chroma_height,
          chroma_decimation_x, chroma_decimation_y,
          chroma_padding_x, chroma_padding_y
        )
      ]
    }
  }

  pub(crate) fn pad(&mut self, w: usize, h: usize) {
    for p in self.planes.iter_mut() {
      p.pad(w, h);
    }
  }

  #[inline(always)]
  #[cfg(test)]
  pub(crate) fn as_tile(&self) -> Tile<'_, T> {
    let PlaneConfig { width, height, .. } = self.planes[0].cfg;
    Tile::new(self, TileRect { x: 0, y: 0, width, height })
  }

  #[inline(always)]
  #[cfg(test)]
  pub fn as_tile_mut(&mut self) -> TileMut<'_, T> {
    let PlaneConfig { width, height, .. } = self.planes[0].cfg;
    TileMut::new(self, TileRect { x: 0, y: 0, width, height })
  }

  /// Returns a `PixelIter` containing the data of this frame's planes in YUV format.
  /// Each point in the `PixelIter` is a triple consisting of a Y, U, and V component.
  /// The `PixelIter` is laid out as contiguous rows, e.g. to get a given 0-indexed row
  /// you could use `data.skip(width * row_idx).take(width)`.
  ///
  /// This data retains any padding, e.g. it uses the width and height specifed in
  /// the Y-plane's `cfg` struct, and not the display width and height specied in
  /// `FrameInvariants`.
  pub(crate) fn iter(&self) -> PixelIter<'_, T> {
    PixelIter::new(&self.planes)
  }
}

#[derive(Debug)]
pub(crate) struct PixelIter<'a, T: Pixel> {
  planes: &'a [Plane<T>; 3],
  y: usize,
  x: usize,
}

impl<'a, T: Pixel> PixelIter<'a, T> {
  pub fn new(planes: &'a [Plane<T>; 3]) -> Self {
    PixelIter {
      planes,
      y: 0,
      x: 0,
    }
  }

  fn width(&self) -> usize {
    self.planes[0].cfg.width
  }

  fn height(&self) -> usize {
    self.planes[0].cfg.height
  }
}

impl<'a, T: Pixel> Iterator for PixelIter<'a, T> {
  type Item = (T, T, T);

  fn next(&mut self) -> Option<<Self as Iterator>::Item> {
    if self.y == self.height() - 1 && self.x == self.width() - 1 {
      return None;
    }
    let pixel = (
      self.planes[0].p(self.x, self.y),
      self.planes[1].p(self.x >> self.planes[1].cfg.xdec, self.y >> self.planes[1].cfg.ydec),
      self.planes[2].p(self.x >> self.planes[2].cfg.xdec, self.y >> self.planes[2].cfg.ydec),
    );
    if self.x == self.width() - 1 {
      self.x = 0;
      self.y += 1;
    } else {
      self.x += 1;
    }
    Some(pixel)
  }
}

<commit_msg>FrameTypeOverride: Add missing repr(C) and FromPrimitive<commit_after>// Copyright (c) 2018, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use num_derive::FromPrimitive;

use crate::util::*;
use crate::api::ChromaSampling;
use crate::context::SB_SIZE;
use crate::mc::SUBPEL_FILTER_SIZE;

#[cfg(test)]
use crate::tiling::*;

mod plane;
pub use plane::*;

const FRAME_MARGIN: usize = 16 + SUBPEL_FILTER_SIZE;

/// Override the frame type decision
///
/// Only certain frame types can be selected.
#[derive(Debug, PartialEq, Clone, Copy, FromPrimitive)]
#[repr(C)]
pub enum FrameTypeOverride {
  /// Do not force any decision.
  No,
  /// Force the frame to be a Keyframe.
  Key,
}

/// Optional per-frame encoder parameters
#[derive(Debug, Clone, Copy)]
pub struct FrameParameters {
  /// Force emitted frame to be of the type selected
  pub frame_type_override: FrameTypeOverride,
}

#[derive(Debug, Clone)]
pub struct Frame<T: Pixel> {
  pub planes: [Plane<T>; 3]
}

impl<T: Pixel> Frame<T> {
  pub fn new(width: usize, height: usize, chroma_sampling: ChromaSampling) -> Self {
    let luma_width = width.align_power_of_two(3);
    let luma_height = height.align_power_of_two(3);
    let luma_padding = SB_SIZE + FRAME_MARGIN;

    let (chroma_sampling_period_x, chroma_sampling_period_y) =
      chroma_sampling.sampling_period();
    let chroma_width = luma_width / chroma_sampling_period_x;
    let chroma_height = luma_height / chroma_sampling_period_y;
    let chroma_padding_x = luma_padding / chroma_sampling_period_x;
    let chroma_padding_y = luma_padding / chroma_sampling_period_y;
    let chroma_decimation_x = chroma_sampling_period_x - 1;
    let chroma_decimation_y = chroma_sampling_period_y - 1;

    Frame {
      planes: [
        Plane::new(
          luma_width, luma_height,
          0, 0,
          luma_padding, luma_padding
        ),
        Plane::new(
          chroma_width, chroma_height,
          chroma_decimation_x, chroma_decimation_y,
          chroma_padding_x, chroma_padding_y
        ),
        Plane::new(
          chroma_width, chroma_height,
          chroma_decimation_x, chroma_decimation_y,
          chroma_padding_x, chroma_padding_y
        )
      ]
    }
  }

  pub(crate) fn pad(&mut self, w: usize, h: usize) {
    for p in self.planes.iter_mut() {
      p.pad(w, h);
    }
  }

  #[inline(always)]
  #[cfg(test)]
  pub(crate) fn as_tile(&self) -> Tile<'_, T> {
    let PlaneConfig { width, height, .. } = self.planes[0].cfg;
    Tile::new(self, TileRect { x: 0, y: 0, width, height })
  }

  #[inline(always)]
  #[cfg(test)]
  pub fn as_tile_mut(&mut self) -> TileMut<'_, T> {
    let PlaneConfig { width, height, .. } = self.planes[0].cfg;
    TileMut::new(self, TileRect { x: 0, y: 0, width, height })
  }

  /// Returns a `PixelIter` containing the data of this frame's planes in YUV format.
  /// Each point in the `PixelIter` is a triple consisting of a Y, U, and V component.
  /// The `PixelIter` is laid out as contiguous rows, e.g. to get a given 0-indexed row
  /// you could use `data.skip(width * row_idx).take(width)`.
  ///
  /// This data retains any padding, e.g. it uses the width and height specifed in
  /// the Y-plane's `cfg` struct, and not the display width and height specied in
  /// `FrameInvariants`.
  pub(crate) fn iter(&self) -> PixelIter<'_, T> {
    PixelIter::new(&self.planes)
  }
}

#[derive(Debug)]
pub(crate) struct PixelIter<'a, T: Pixel> {
  planes: &'a [Plane<T>; 3],
  y: usize,
  x: usize,
}

impl<'a, T: Pixel> PixelIter<'a, T> {
  pub fn new(planes: &'a [Plane<T>; 3]) -> Self {
    PixelIter {
      planes,
      y: 0,
      x: 0,
    }
  }

  fn width(&self) -> usize {
    self.planes[0].cfg.width
  }

  fn height(&self) -> usize {
    self.planes[0].cfg.height
  }
}

impl<'a, T: Pixel> Iterator for PixelIter<'a, T> {
  type Item = (T, T, T);

  fn next(&mut self) -> Option<<Self as Iterator>::Item> {
    if self.y == self.height() - 1 && self.x == self.width() - 1 {
      return None;
    }
    let pixel = (
      self.planes[0].p(self.x, self.y),
      self.planes[1].p(self.x >> self.planes[1].cfg.xdec, self.y >> self.planes[1].cfg.ydec),
      self.planes[2].p(self.x >> self.planes[2].cfg.xdec, self.y >> self.planes[2].cfg.ydec),
    );
    if self.x == self.width() - 1 {
      self.x = 0;
      self.y += 1;
    } else {
      self.x += 1;
    }
    Some(pixel)
  }
}

<|endoftext|>


<commit_before>use syntax::abi;
use syntax::ast;
use syntax::ast_util;
use syntax::codemap::DUMMY_SP;
use syntax::ext::base::ExtCtxt;
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use syntax::parse::token;

use block::{Block, Describe, It, Bench};

pub trait Generate {
    fn generate(self, cx: &mut ExtCtxt, up: Option<&Describe>) -> P<ast::Item>;
}

impl Generate for Block {
    fn generate(self, cx: &mut ExtCtxt, up: Option<&Describe>) -> P<ast::Item> {
        match self {
            Block::Describe(describe) => describe.generate(cx, up),
            Block::It(it) => it.generate(cx, up),
            Block::Bench(bench) => bench.generate(cx, up)
        }
    }
}

impl Generate for Describe {
    fn generate(mut self,
                cx: &mut ExtCtxt,
                up: Option<&Describe>) -> P<ast::Item> {
        let name = cx.ident_of(&*self.name);

        if let Some(ref up) = up {
            if let Some(ref before) = up.before {
                self.before = match self.before {
                    Some(ref now) => Some(merge_blocks(before, now)),
                    None => Some(before.clone())
                }
            }

            if let Some(ref after) = up.after {
                self.after = match self.after {
                    Some(ref now) => Some(merge_blocks(now, after)),
                    None => Some(after.clone())
                }
            }
        }

        let items = self.blocks.iter().map(|block| {
            block.clone().generate(cx, Some(&self))
        }).collect();

        let pub_use_super_star = cx.view_use_glob(DUMMY_SP,
                                                  ast::Visibility::Public,
                                                  vec![cx.ident_of("super")]);

        cx.item_mod(DUMMY_SP,
                    DUMMY_SP,
                    name,
                    vec![],
                    vec![pub_use_super_star],
                    items)
    }
}

impl Generate for It {
    fn generate(self, cx: &mut ExtCtxt, up: Option<&Describe>) -> P<ast::Item> {
        let name = cx.ident_of(&*self.name);
        let attrs = vec![
            cx.attribute(
                DUMMY_SP,
                cx.meta_word(DUMMY_SP, token::InternedString::new("test"))
            )
        ];

        let block = if let Some(ref up) = up {
            match (&up.before, &up.after) {
                (&Some(ref before), &Some(ref after)) => {
                    merge_blocks(&merge_blocks(before, &self.block), after)
                },
                (&Some(ref before), &None) => merge_blocks(before, &self.block),
                (&None, &Some(ref after)) => merge_blocks(&self.block, after),
                (&None, &None) => self.block.clone()
            }
        } else {
            self.block
        };

        cx.item(DUMMY_SP, name, attrs,
                ast::ItemFn(
                    cx.fn_decl(vec![], cx.ty(DUMMY_SP, ast::TyTup(vec![]))),
                    ast::Unsafety::Normal,
                    abi::Rust,
                    ast_util::empty_generics(),
                    block
                ))
    }
}

impl Generate for Bench {
    fn generate(self, cx: &mut ExtCtxt, up: Option<&Describe>) -> P<ast::Item> {
        let name = cx.ident_of(&*self.name);

        let attrs = vec![
            cx.attribute(
                DUMMY_SP,
                cx.meta_word(DUMMY_SP, token::InternedString::new("bench"))
            )
        ];

        let args = vec![
            cx.arg(DUMMY_SP, self.ident, quote_ty!(cx, &mut ::test::Bencher))
        ];

        let block = if let Some(ref up) = up {
            match (&up.before, &up.after) {
                (&Some(ref before), &Some(ref after)) => {
                    merge_blocks(&merge_blocks(before, &self.block), after)
                },
                (&Some(ref before), &None) => merge_blocks(before, &self.block),
                (&None, &Some(ref after)) => merge_blocks(&self.block, after),
                (&None, &None) => self.block.clone()
            }
        } else {
            self.block
        };

        cx.item(DUMMY_SP, name, attrs,
                ast::ItemFn(
                    cx.fn_decl(args, cx.ty(DUMMY_SP, ast::TyTup(vec![]))),
                    ast::Unsafety::Normal,
                    abi::Rust,
                    ast_util::empty_generics(),
                    block
                ))
    }
}

fn merge_blocks(left: &P<ast::Block>, right: &P<ast::Block>) -> P<ast::Block> {
    use std::ops::Deref;

    P(ast::Block {
        view_items: left.view_items.clone() + &*right.view_items,
        stmts: left.stmts.clone() + &*right.stmts,
        ..left.deref().clone()
    })
}
<commit_msg>Fix for `rustc 1.0.0-dev (710dcdc2e 2015-01-21 03:54:21 +0000)`.<commit_after>use syntax::abi;
use syntax::ast;
use syntax::ast_util;
use syntax::codemap::DUMMY_SP;
use syntax::ext::base::ExtCtxt;
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use syntax::parse::token;

use block::{Block, Describe, It, Bench};

pub trait Generate {
    fn generate(self, cx: &mut ExtCtxt, up: Option<&Describe>) -> P<ast::Item>;
}

impl Generate for Block {
    fn generate(self, cx: &mut ExtCtxt, up: Option<&Describe>) -> P<ast::Item> {
        match self {
            Block::Describe(describe) => describe.generate(cx, up),
            Block::It(it) => it.generate(cx, up),
            Block::Bench(bench) => bench.generate(cx, up)
        }
    }
}

impl Generate for Describe {
    fn generate(mut self,
                cx: &mut ExtCtxt,
                up: Option<&Describe>) -> P<ast::Item> {
        let name = cx.ident_of(&*self.name);

        if let Some(ref up) = up {
            if let Some(ref before) = up.before {
                self.before = match self.before {
                    Some(ref now) => Some(merge_blocks(before, now)),
                    None => Some(before.clone())
                }
            }

            if let Some(ref after) = up.after {
                self.after = match self.after {
                    Some(ref now) => Some(merge_blocks(now, after)),
                    None => Some(after.clone())
                }
            }
        }

        let items = self.blocks.iter().map(|block| {
            block.clone().generate(cx, Some(&self))
        }).collect();

        let pub_use_super_star = cx.view_use_glob(DUMMY_SP,
                                                  ast::Visibility::Public,
                                                  vec![cx.ident_of("super")]);

        cx.item_mod(DUMMY_SP,
                    DUMMY_SP,
                    name,
                    vec![],
                    vec![pub_use_super_star],
                    items)
    }
}

impl Generate for It {
    fn generate(self, cx: &mut ExtCtxt, up: Option<&Describe>) -> P<ast::Item> {
        let name = cx.ident_of(&*self.name);
        let attrs = vec![
            cx.attribute(
                DUMMY_SP,
                cx.meta_word(DUMMY_SP, token::InternedString::new("test"))
            )
        ];

        let block = if let Some(ref up) = up {
            match (&up.before, &up.after) {
                (&Some(ref before), &Some(ref after)) => {
                    merge_blocks(&merge_blocks(before, &self.block), after)
                },
                (&Some(ref before), &None) => merge_blocks(before, &self.block),
                (&None, &Some(ref after)) => merge_blocks(&self.block, after),
                (&None, &None) => self.block.clone()
            }
        } else {
            self.block
        };

        cx.item(DUMMY_SP, name, attrs,
                ast::ItemFn(
                    P(ast::FnDecl {
                        inputs: vec![],
                        output: ast::DefaultReturn(DUMMY_SP),
                        variadic: false
                    }),
                    ast::Unsafety::Normal,
                    abi::Rust,
                    ast_util::empty_generics(),
                    block
                ))
    }
}

impl Generate for Bench {
    fn generate(self, cx: &mut ExtCtxt, up: Option<&Describe>) -> P<ast::Item> {
        let name = cx.ident_of(&*self.name);

        let attrs = vec![
            cx.attribute(
                DUMMY_SP,
                cx.meta_word(DUMMY_SP, token::InternedString::new("bench"))
            )
        ];

        let args = vec![
            cx.arg(DUMMY_SP, self.ident, quote_ty!(cx, &mut ::test::Bencher))
        ];

        let block = if let Some(ref up) = up {
            match (&up.before, &up.after) {
                (&Some(ref before), &Some(ref after)) => {
                    merge_blocks(&merge_blocks(before, &self.block), after)
                },
                (&Some(ref before), &None) => merge_blocks(before, &self.block),
                (&None, &Some(ref after)) => merge_blocks(&self.block, after),
                (&None, &None) => self.block.clone()
            }
        } else {
            self.block
        };

        cx.item(DUMMY_SP, name, attrs,
                ast::ItemFn(
                    P(ast::FnDecl {
                        inputs: args,
                        output: ast::DefaultReturn(DUMMY_SP),
                        variadic: false
                    }),
                    ast::Unsafety::Normal,
                    abi::Rust,
                    ast_util::empty_generics(),
                    block
                ))
    }
}

fn merge_blocks(left: &P<ast::Block>, right: &P<ast::Block>) -> P<ast::Block> {
    use std::ops::Deref;

    P(ast::Block {
        view_items: left.view_items.clone() + &*right.view_items,
        stmts: left.stmts.clone() + &*right.stmts,
        ..left.deref().clone()
    })
}
<|endoftext|>


<commit_before>/**
 * alarm.rs - Trait for a hardware timer based on a counter. Assumes 32 bits.
 *
 * Author: Amit Levy <levya@cs.stanford.edu>
 * Date: 7/15/15
 */
pub trait AlarmClient {
    fn fired(&self);
}

pub trait Alarm {
    fn now(&self) -> u32;
    fn set_alarm(&self, when: u32);
    fn disable_alarm(&self);
    fn get_alarm(&self) -> u32;
}

<commit_msg>Documentation for `Alarm` and `AlarmClient` traits<commit_after>/// The `Alarm` trait keeps track of a counter such as a hardware AST.
///
/// Alarms represent a resource that keeps track of time in some fixed unit
/// (usually clock tics). Implementors should use the
/// [`AlarmClient`](trait.AlarmClient.html) trait to signal when the counter has
/// reached a pre-specified value set in [`set_alarm`](#tymethod.set_alarm).
pub trait Alarm {
    /// Returns the current time in hardware clock units.
    fn now(&self) -> u32;

    /// Sets a one-shot alarm fire when the clock reaches `tics`.
    ///
    /// [`AlarmClient#fired`](trait.AlarmClient.html#tymethod.fired) is signaled
    /// when `tics` is reached.
    ///
    /// # Examples
    ///
    /// ```rust
    /// let delta = 1337;
    /// let tics = alarm.now().wrapping_add(delta);
    /// alarm.set_alarm(tics);
    /// ```
    fn set_alarm(&self, tics: u32);

    /// Disables the alarm.
    fn disable_alarm(&self);

    /// Returns the value set in [`set_alarm`](#tymethod.set_alarm)
    fn get_alarm(&self) -> u32;
}

/// A client of an implementor of the [`Alarm`](trait.Alarm.html) trait.
pub trait AlarmClient {
    /// Callback signaled when the alarm's clock reaches the value set in
    /// [`Alarm#set_alarm`](trait.Alarm.html#tymethod.set_alarm).
    fn fired(&self);
}

<|endoftext|>


<commit_before>use brotli2::stream::{CompressMode as BrotliCompressMode, CompressParams as BrotliCompressParams};
use flate2::write::{DeflateEncoder, GzEncoder};
use flate2::{Compression as Flate2Compression};
use bzip2::Compression as BzCompression;
use iron::headers::{QualityItem, Encoding};
use brotli2::write::BrotliEncoder;
use bzip2::write::BzEncoder;
use std::io::Write;

lazy_static! {
    /// The list of content encodings we handle.
    pub static ref SUPPORTED_ENCODINGS: Vec<Encoding> = vec![Encoding::Gzip,
                                                             Encoding::Deflate,
                                                             Encoding::EncodingExt("br".to_string()),
                                                             Encoding::EncodingExt("bzip2".to_string())];
}

/// Find best supported encoding to use, or `None` for identity.
pub fn response_encoding(requested: &mut [QualityItem<Encoding>]) -> Option<Encoding> {
    requested.sort_by_key(|e| e.quality);
    requested.iter().filter(|e| e.quality.0 != 0).find(|e| SUPPORTED_ENCODINGS.contains(&e.item)).map(|e| e.item.clone())
}

/// Encode a string slice using a given encoding or `None` if encoding failed or is not recognised.
pub fn encode_str(dt: &str, enc: &Encoding) -> Option<Vec<u8>> {
    match *enc {
        Encoding::Gzip => encode_gzip(dt),
        Encoding::Deflate => encode_deflate(dt),
        Encoding::EncodingExt(ref e) => {
            match &e[..] {
                "br" => encode_brotli(dt),
                "bzip2" => encode_bzip2(dt),
                _ => None,
            }
        }
        _ => None,
    }
}

macro_rules! encode_fn_flate2_write_iface {
    ($fn_name:ident, $enc_tp:ident) => {
        fn $fn_name(dt: &str) -> Option<Vec<u8>> {
            let mut cmp = $enc_tp::new(Vec::new(), Flate2Compression::Default);
            cmp.write_all(dt.as_bytes()).ok().and_then(|_| cmp.finish().ok())
        }
    }
}

encode_fn_flate2_write_iface!(encode_gzip, GzEncoder);
encode_fn_flate2_write_iface!(encode_deflate, DeflateEncoder);

fn encode_brotli(dt: &str) -> Option<Vec<u8>> {
    let mut cmp = BrotliEncoder::new(Vec::new(), 0);
    cmp.set_params(BrotliCompressParams::new().mode(BrotliCompressMode::Text));
    cmp.write_all(dt.as_bytes()).ok().and_then(|_| cmp.finish().ok())
}

fn encode_bzip2(dt: &str) -> Option<Vec<u8>> {
    let mut cmp = BzEncoder::new(Vec::new(), BzCompression::Default);
    cmp.write_all(dt.as_bytes()).ok().and_then(|_| cmp.finish().ok())
}
<commit_msg>Handle x- prefixed encodings as well<commit_after>use brotli2::stream::{CompressMode as BrotliCompressMode, CompressParams as BrotliCompressParams};
use flate2::write::{DeflateEncoder, GzEncoder};
use flate2::Compression as Flate2Compression;
use bzip2::Compression as BzCompression;
use iron::headers::{QualityItem, Encoding};
use brotli2::write::BrotliEncoder;
use bzip2::write::BzEncoder;
use std::io::Write;

lazy_static! {
    /// The list of content encodings we handle.
    pub static ref SUPPORTED_ENCODINGS: Vec<Encoding> = {
        let es = vec![Encoding::Gzip, Encoding::Deflate, Encoding::EncodingExt("br".to_string()), Encoding::EncodingExt("bzip2".to_string())];
        [es.clone(), es.into_iter().map(|e| Encoding::EncodingExt(format!("x-{}", e))).collect()].into_iter().flat_map(|e| e.clone()).collect()
    };
}

/// Find best supported encoding to use, or `None` for identity.
pub fn response_encoding(requested: &mut [QualityItem<Encoding>]) -> Option<Encoding> {
    requested.sort_by_key(|e| e.quality);
    requested.iter().filter(|e| e.quality.0 != 0).find(|e| SUPPORTED_ENCODINGS.contains(&e.item)).map(|e| e.item.clone())
}

/// Encode a string slice using a given encoding or `None` if encoding failed or is not recognised.
pub fn encode_str(dt: &str, enc: &Encoding) -> Option<Vec<u8>> {
    match *enc {
        Encoding::Gzip => encode_gzip(dt),
        Encoding::Deflate => encode_deflate(dt),
        Encoding::EncodingExt(ref e) => {
            match &e[..] {
                "x-gzip" => encode_gzip(dt),
                "x-deflate" => encode_deflate(dt),
                "br" | "x-br" => encode_brotli(dt),
                "bzip2" | "x-bzip2" => encode_bzip2(dt),
                _ => None,
            }
        }
        _ => None,
    }
}

macro_rules! encode_fn_flate2_write_iface {
    ($fn_name:ident, $enc_tp:ident) => {
        fn $fn_name(dt: &str) -> Option<Vec<u8>> {
            let mut cmp = $enc_tp::new(Vec::new(), Flate2Compression::Default);
            cmp.write_all(dt.as_bytes()).ok().and_then(|_| cmp.finish().ok())
        }
    }
}

encode_fn_flate2_write_iface!(encode_gzip, GzEncoder);
encode_fn_flate2_write_iface!(encode_deflate, DeflateEncoder);

fn encode_brotli(dt: &str) -> Option<Vec<u8>> {
    let mut cmp = BrotliEncoder::new(Vec::new(), 0);
    cmp.set_params(BrotliCompressParams::new().mode(BrotliCompressMode::Text));
    cmp.write_all(dt.as_bytes()).ok().and_then(|_| cmp.finish().ok())
}

fn encode_bzip2(dt: &str) -> Option<Vec<u8>> {
    let mut cmp = BzEncoder::new(Vec::new(), BzCompression::Default);
    cmp.write_all(dt.as_bytes()).ok().and_then(|_| cmp.finish().ok())
}
<|endoftext|>