<commit_before>use ::*;

// Timer
pub struct Timer {
    time : Duration,
    time_left : Duration,
    pub ready : bool,
}

impl Timer {
    pub fn from_millis(milliseconds : u64) -> Self {
        let duration = Duration::from_millis(milliseconds);
        Self {
            time : duration,
            time_left : duration,
            ready : false,
        }
    }

    pub fn reset(&mut self) {
        self.ready = false;
        self.time_left = self.time;
    }

    pub fn update(&mut self, delta : Duration) {
        if self.ready {
            return;
        }
        if let Some(result) = self.time_left.checked_sub(delta) {
            self.time_left = result;
        } else {
            self.ready = true;
        }
    }
}
<commit_msg>Another unnecessary comment.<commit_after>use ::*;

pub struct Timer {
    time : Duration,
    time_left : Duration,
    pub ready : bool,
}

impl Timer {
    pub fn from_millis(milliseconds : u64) -> Self {
        let duration = Duration::from_millis(milliseconds);
        Self {
            time : duration,
            time_left : duration,
            ready : false,
        }
    }

    pub fn reset(&mut self) {
        self.ready = false;
        self.time_left = self.time;
    }

    pub fn update(&mut self, delta : Duration) {
        if self.ready {
            return;
        }
        if let Some(result) = self.time_left.checked_sub(delta) {
            self.time_left = result;
        } else {
            self.ready = true;
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was not
// distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.

use std::sync::{Arc, Mutex};
use std::collections::LinkedList;
use std::os::unix::io::RawFd;

use stream::Stream;

/// The `EventHandler` trait allows for hydrogen event dispatching.
///
/// Hydrogen uses multiple threads to dispatch events. Implementors should
/// take care to ensure any state within `self` is properly safeguarded
/// against race conditions that may occur.
pub trait EventHandler {
    fn on_data_received(&mut self, stream: Stream, buffer: Vec<u8>);
    fn on_stream_closed(&mut self, fd: RawFd);
}

/// Internal list of all currently connected streams
type StreamList = Arc<Mutex<LinkedList<Stream>>>;

/// Used as a strongly typed wrapper for passing around `EventHandler`
struct Handler(pub *mut EventHandler);
unsafe impl Send for Handler {}
unsafe impl Sync for Handler {}
impl Clone for Handler {
    fn clone(&self) -> Handler {
        let Handler(ptr) = *self;
        unsafe {
            let same_location = &mut *ptr;
            Handler(same_location)
        }
    }
}

/// Used as a strongly typed wrapper for passing around `EventHandler` functions
struct Event(pub *mut Fn());
unsafe impl Send for Event {}
unsafe impl Sync for Event {}
impl Clone for Event {
    fn clone(&self) -> Event {
        let Event(ptr) = *self;
        unsafe {
            let same_location = &mut *ptr;
            Event(same_location)
        }
    }
}
<commit_msg>Remote debugging<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was not
// distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.

use std::sync::{Arc, Mutex};
use std::collections::LinkedList;
use std::os::unix::io::RawFd;

use stream::Stream;

/// The `EventHandler` trait allows for hydrogen event dispatching.
///
/// Hydrogen uses multiple threads to dispatch events. Implementors should
/// take care to ensure any state within `self` is properly safeguarded
/// against race conditions that may occur.
pub trait EventHandler {
    fn on_data_received(&mut self, stream: Stream, buffer: Vec<u8>);
    fn on_stream_closed(&mut self, fd: RawFd);
}

/// Internal list of all currently connected streams
type StreamList = Arc<Mutex<LinkedList<Stream>>>;

/// Used as a strongly typed wrapper for passing around `EventHandler`
pub struct Handler(pub *mut EventHandler);
unsafe impl Send for Handler {}
unsafe impl Sync for Handler {}
impl Clone for Handler {
    fn clone(&self) -> Handler {
        let Handler(ptr) = *self;
        unsafe {
            let same_location = &mut *ptr;
            Handler(same_location)
        }
    }
}

/// Used as a strongly typed wrapper for passing around `EventHandler` functions
pub struct Event(pub *mut Fn());
unsafe impl Send for Event {}
unsafe impl Sync for Event {}
impl Clone for Event {
    fn clone(&self) -> Event {
        let Event(ptr) = *self;
        unsafe {
            let same_location = &mut *ptr;
            Event(same_location)
        }
    }
}
<|endoftext|>


<commit_before>use errors::Result;
use libc::{futimens, timespec, c_long, time_t};
use std::fs::File;
use std::io::Error as IOError;
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::time::{SystemTime, UNIX_EPOCH};

/// Set file acessed and modified time.
pub fn set_file_times<P: AsRef<Path>>(path: P,
                                      atime: &SystemTime,
                                      mtime: &SystemTime)
                                      -> Result<()> {
    let atime_since_epoch = atime.duration_since(UNIX_EPOCH)?;
    let mtime_since_epoch = mtime.duration_since(UNIX_EPOCH)?;

    let times = [timespec {
                     tv_sec: atime_since_epoch.as_secs() as time_t,
                     tv_nsec: atime_since_epoch.subsec_nanos() as c_long,
                 },
                 timespec {
                     tv_sec: mtime_since_epoch.as_secs() as time_t,
                     tv_nsec: mtime_since_epoch.subsec_nanos() as c_long,
                 }];

    let file = File::open(path)?;
    let ret = unsafe { futimens(file.as_raw_fd(), times.as_ptr()) };
    if ret == 0 {
        Ok(())
    } else {
        bail!(IOError::last_os_error())
    }
}

#[cfg(test)]
mod tests {
    use std::time::{Duration, UNIX_EPOCH};
    use std::fs::copy;
    use super::set_file_times;
    use tempdir::TempDir;

    #[test]
    fn test_set_file_times() {
        // Oct, 27 -> a special date! :D
        let atime = UNIX_EPOCH + Duration::from_secs(1509062400);
        let mtime = UNIX_EPOCH + Duration::from_secs(1509105600);

        let temp_dir = TempDir::new("test_set_file_times").unwrap();
        let test_filepath = temp_dir.path().join("a.txt");
        copy("./test_files/a.txt", &test_filepath).unwrap();

        set_file_times(&test_filepath, &atime, &mtime).unwrap();
    }
}
<commit_msg>Use futimes on macos to set atime and mtime of files<commit_after>use errors::Result;
use std::fs::File;
use std::io::Error as IOError;
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::time::{SystemTime, UNIX_EPOCH};

#[cfg(not(target_os="macos"))]
fn futime(file: &File, atime: &SystemTime, mtime: &SystemTime) -> Result<()> {
    use libc::{futimens, timespec, c_long, time_t};

    let atime_since_epoch = atime.duration_since(UNIX_EPOCH)?;
    let mtime_since_epoch = mtime.duration_since(UNIX_EPOCH)?;

    let times = [timespec {
                     tv_sec: atime_since_epoch.as_secs() as time_t,
                     tv_nsec: atime_since_epoch.subsec_nanos() as c_long,
                 },
                 timespec {
                     tv_sec: mtime_since_epoch.as_secs() as time_t,
                     tv_nsec: mtime_since_epoch.subsec_nanos() as c_long,
                 }];

    if unsafe { futimens(file.as_raw_fd(), times.as_ptr()) } == 0 {
        Ok(())
    } else {
        bail!(IOError::last_os_error())
    }
}

#[cfg(target_os="macos")]
fn futime(file: &File, atime: &SystemTime, mtime: &SystemTime) -> Result<()> {
    use libc::{futimes, timeval, suseconds_t, time_t};

    let atime_since_epoch = atime.duration_since(UNIX_EPOCH)?;
    let mtime_since_epoch = mtime.duration_since(UNIX_EPOCH)?;

    let times = [timeval {
                     tv_sec: atime_since_epoch.as_secs() as time_t,
                     tv_usec: atime_since_epoch.subsec_nanos() as suseconds_t,
                 },
                 timeval {
                     tv_sec: mtime_since_epoch.as_secs() as time_t,
                     tv_usec: mtime_since_epoch.subsec_nanos() as suseconds_t,
                 }];

    if unsafe { futimes(file.as_raw_fd(), times.as_ptr()) } == 0 {
        Ok(())
    } else {
        bail!(IOError::last_os_error())
    }
}

/// Set file acessed and modified time.
pub fn set_file_times<P: AsRef<Path>>(path: P,
                                      atime: &SystemTime,
                                      mtime: &SystemTime)
                                      -> Result<()> {
    let file = File::open(path)?;
    futime(&file, &atime, &mtime)
}

#[cfg(test)]
mod tests {
    use std::time::{Duration, UNIX_EPOCH};
    use std::fs::copy;
    use super::set_file_times;
    use tempdir::TempDir;

    #[test]
    fn test_set_file_times() {
        // Oct, 27 -> a special date! :D
        let atime = UNIX_EPOCH + Duration::from_secs(1509062400);
        let mtime = UNIX_EPOCH + Duration::from_secs(1509105600);

        let temp_dir = TempDir::new("test_set_file_times").unwrap();
        let test_filepath = temp_dir.path().join("a.txt");
        copy("./test_files/a.txt", &test_filepath).unwrap();

        set_file_times(&test_filepath, &atime, &mtime).unwrap();
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 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.

use std::borrow::Cow;
use std::cmp::Ordering;

use itertools::Itertools;

use syntax::ast::{self, Visibility, Attribute, MetaItem, MetaItemKind, NestedMetaItem,
                  NestedMetaItemKind, Path};
use syntax::codemap::BytePos;
use syntax::abi;

use Shape;
use rewrite::{Rewrite, RewriteContext};

use SKIP_ANNOTATION;

// Computes the length of a string's last line, minus offset.
pub fn extra_offset(text: &str, shape: Shape) -> usize {
    match text.rfind('\n') {
        // 1 for newline character
        Some(idx) => {
            text.len()
                .checked_sub(idx + 1 + shape.used_width())
                .unwrap_or(0)
        }
        None => text.len(),
    }
}

// Uses Cow to avoid allocating in the common cases.
pub fn format_visibility(vis: &Visibility) -> Cow<'static, str> {
    match *vis {
        Visibility::Public => Cow::from("pub "),
        Visibility::Inherited => Cow::from(""),
        Visibility::Crate(_) => Cow::from("pub(crate) "),
        Visibility::Restricted { ref path, .. } => {
            let Path { ref segments, .. } = **path;
            let mut segments_iter = segments.iter().map(|seg| seg.identifier.name.as_str());
            if path.is_global() {
                segments_iter
                    .next()
                    .expect("Non-global path in pub(restricted)?");
            }

            Cow::from(format!("pub({}) ", segments_iter.join("::")))
        }
    }
}

#[inline]
pub fn format_unsafety(unsafety: ast::Unsafety) -> &'static str {
    match unsafety {
        ast::Unsafety::Unsafe => "unsafe ",
        ast::Unsafety::Normal => "",
    }
}

#[inline]
pub fn format_mutability(mutability: ast::Mutability) -> &'static str {
    match mutability {
        ast::Mutability::Mutable => "mut ",
        ast::Mutability::Immutable => "",
    }
}

#[inline]
pub fn format_abi(abi: abi::Abi, explicit_abi: bool) -> String {
    if abi == abi::Abi::C && !explicit_abi {
        "extern ".into()
    } else {
        format!("extern {} ", abi)
    }
}

// The width of the first line in s.
#[inline]
pub fn first_line_width(s: &str) -> usize {
    match s.find('\n') {
        Some(n) => n,
        None => s.len(),
    }
}

// The width of the last line in s.
#[inline]
pub fn last_line_width(s: &str) -> usize {
    match s.rfind('\n') {
        Some(n) => s.len() - n - 1,
        None => s.len(),
    }
}
#[inline]
pub fn trimmed_last_line_width(s: &str) -> usize {
    match s.rfind('\n') {
        Some(n) => s[(n + 1)..].trim().len(),
        None => s.trim().len(),
    }
}

#[inline]
fn is_skip(meta_item: &MetaItem) -> bool {
    match meta_item.node {
        MetaItemKind::Word => meta_item.name == SKIP_ANNOTATION,
        MetaItemKind::List(ref l) => {
            meta_item.name == "cfg_attr" && l.len() == 2 && is_skip_nested(&l[1])
        }
        _ => false,
    }
}

#[inline]
fn is_skip_nested(meta_item: &NestedMetaItem) -> bool {
    match meta_item.node {
        NestedMetaItemKind::MetaItem(ref mi) => is_skip(mi),
        NestedMetaItemKind::Literal(_) => false,
    }
}

#[inline]
pub fn contains_skip(attrs: &[Attribute]) -> bool {
    attrs.iter().any(|a| is_skip(&a.value))
}

// Find the end of a TyParam
#[inline]
pub fn end_typaram(typaram: &ast::TyParam) -> BytePos {
    typaram
        .bounds
        .last()
        .map_or(typaram.span, |bound| match *bound {
            ast::RegionTyParamBound(ref lt) => lt.span,
            ast::TraitTyParamBound(ref prt, _) => prt.span,
        })
        .hi
}

#[inline]
pub fn semicolon_for_expr(expr: &ast::Expr) -> bool {
    match expr.node {
        ast::ExprKind::Ret(..) |
        ast::ExprKind::Continue(..) |
        ast::ExprKind::Break(..) => true,
        _ => false,
    }
}

#[inline]
pub fn semicolon_for_stmt(stmt: &ast::Stmt) -> bool {
    match stmt.node {
        ast::StmtKind::Semi(ref expr) => {
            match expr.node {
                ast::ExprKind::While(..) |
                ast::ExprKind::WhileLet(..) |
                ast::ExprKind::Loop(..) |
                ast::ExprKind::ForLoop(..) => false,
                _ => true,
            }
        }
        ast::StmtKind::Expr(..) => false,
        _ => true,
    }
}

#[inline]
pub fn stmt_expr(stmt: &ast::Stmt) -> Option<&ast::Expr> {
    match stmt.node {
        ast::StmtKind::Expr(ref expr) => Some(expr),
        _ => None,
    }
}

#[inline]
pub fn trim_newlines(input: &str) -> &str {
    match input.find(|c| c != '\n' && c != '\r') {
        Some(start) => {
            let end = input.rfind(|c| c != '\n' && c != '\r').unwrap_or(0) + 1;
            &input[start..end]
        }
        None => "",
    }
}

// Macro for deriving implementations of Decodable for enums
#[macro_export]
macro_rules! impl_enum_decodable {
    ( $e:ident, $( $x:ident ),* ) => {
        impl<'de> ::serde::de::Deserialize<'de> for $e {
            fn deserialize<D>(d: D) -> Result<Self, D::Error>
                    where D: ::serde::Deserializer<'de> {
                use std::ascii::AsciiExt;
                use serde::de::{Error, Visitor};
                use std::marker::PhantomData;
                use std::fmt;
                struct StringOnly<T>(PhantomData<T>);
                impl<'de, T> Visitor<'de> for StringOnly<T>
                        where T: ::serde::Deserializer<'de> {
                    type Value = String;
                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                        formatter.write_str("string")
                    }
                    fn visit_str<E>(self, value :&str) -> Result<String, E> {
                        Ok(String::from(value))
                    }
                }
                let s = try!(d.deserialize_string(StringOnly::<D>(PhantomData)));
                $(
                    if stringify!($x).eq_ignore_ascii_case(&s) {
                      return Ok($e::$x);
                    }
                )*
                static ALLOWED: &'static[&str] = &[$(stringify!($x),)*];
                Err(D::Error::unknown_variant(&s, ALLOWED))
            }
        }

        impl ::std::str::FromStr for $e {
            type Err = &'static str;

            fn from_str(s: &str) -> Result<Self, Self::Err> {
                use std::ascii::AsciiExt;
                $(
                    if stringify!($x).eq_ignore_ascii_case(s) {
                        return Ok($e::$x);
                    }
                )*
                Err("Bad variant")
            }
        }

        impl ::config::ConfigType for $e {
            fn doc_hint() -> String {
                let mut variants = Vec::new();
                $(
                    variants.push(stringify!($x));
                )*
                format!("[{}]", variants.join("|"))
            }
        }
    };
}

// Same as try!, but for Option
#[macro_export]
macro_rules! try_opt {
    ($expr:expr) => (match $expr {
        Some(val) => val,
        None => { return None; }
    })
}

macro_rules! msg {
    ($($arg:tt)*) => (
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
}

// For format_missing and last_pos, need to use the source callsite (if applicable).
// Required as generated code spans aren't guaranteed to follow on from the last span.
macro_rules! source {
    ($this:ident, $sp: expr) => {
        $this.codemap.source_callsite($sp)
    }
}

// Wraps string-like values in an Option. Returns Some when the string adheres
// to the Rewrite constraints defined for the Rewrite trait and else otherwise.
pub fn wrap_str<S: AsRef<str>>(s: S, max_width: usize, shape: Shape) -> Option<S> {
    {
        let snippet = s.as_ref();

        if !snippet.contains('\n') && snippet.len() > shape.width {
            return None;
        } else {
            let mut lines = snippet.lines();

            // The caller of this function has already placed `shape.offset`
            // characters on the first line.
            let first_line_max_len = try_opt!(max_width.checked_sub(shape.indent.width()));
            if lines.next().unwrap().len() > first_line_max_len {
                return None;
            }

            // The other lines must fit within the maximum width.
            if lines.any(|line| line.len() > max_width) {
                return None;
            }

            // `width` is the maximum length of the last line, excluding
            // indentation.
            // A special check for the last line, since the caller may
            // place trailing characters on this line.
            if snippet.lines().rev().next().unwrap().len() > shape.indent.width() + shape.width {
                return None;
            }
        }
    }

    Some(s)
}

impl Rewrite for String {
    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
        wrap_str(self, context.config.max_width, shape).map(ToOwned::to_owned)
    }
}

// Binary search in integer range. Returns the first Ok value returned by the
// callback.
// The callback takes an integer and returns either an Ok, or an Err indicating
// whether the `guess' was too high (Ordering::Less), or too low.
// This function is guaranteed to try to the hi value first.
pub fn binary_search<C, T>(mut lo: usize, mut hi: usize, callback: C) -> Option<T>
    where C: Fn(usize) -> Result<T, Ordering>
{
    let mut middle = hi;

    while lo <= hi {
        match callback(middle) {
            Ok(val) => return Some(val),
            Err(Ordering::Less) => {
                hi = middle - 1;
            }
            Err(..) => {
                lo = middle + 1;
            }
        }
        middle = (hi + lo) / 2;
    }

    None
}

#[inline]
pub fn colon_spaces(before: bool, after: bool) -> &'static str {
    match (before, after) {
        (true, true) => " : ",
        (true, false) => " :",
        (false, true) => ": ",
        (false, false) => ":",
    }
}

#[test]
fn bin_search_test() {
    let closure = |i| match i {
        4 => Ok(()),
        j if j > 4 => Err(Ordering::Less),
        j if j < 4 => Err(Ordering::Greater),
        _ => unreachable!(),
    };

    assert_eq!(Some(()), binary_search(1, 10, &closure));
    assert_eq!(None, binary_search(1, 3, &closure));
    assert_eq!(Some(()), binary_search(0, 44, &closure));
    assert_eq!(Some(()), binary_search(4, 125, &closure));
    assert_eq!(None, binary_search(6, 100, &closure));
}

pub fn left_most_sub_expr(e: &ast::Expr) -> &ast::Expr {
    match e.node {
        ast::ExprKind::InPlace(ref e, _) |
        ast::ExprKind::Call(ref e, _) |
        ast::ExprKind::Binary(_, ref e, _) |
        ast::ExprKind::Cast(ref e, _) |
        ast::ExprKind::Type(ref e, _) |
        ast::ExprKind::Assign(ref e, _) |
        ast::ExprKind::AssignOp(_, ref e, _) |
        ast::ExprKind::Field(ref e, _) |
        ast::ExprKind::TupField(ref e, _) |
        ast::ExprKind::Index(ref e, _) |
        ast::ExprKind::Range(Some(ref e), _, _) |
        ast::ExprKind::Try(ref e) => left_most_sub_expr(e),
        _ => e,
    }
}
<commit_msg>Format fix<commit_after>// Copyright 2015 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.

use std::borrow::Cow;
use std::cmp::Ordering;

use itertools::Itertools;

use syntax::ast::{self, Visibility, Attribute, MetaItem, MetaItemKind, NestedMetaItem,
                  NestedMetaItemKind, Path};
use syntax::codemap::BytePos;
use syntax::abi;

use Shape;
use rewrite::{Rewrite, RewriteContext};

use SKIP_ANNOTATION;

// Computes the length of a string's last line, minus offset.
pub fn extra_offset(text: &str, shape: Shape) -> usize {
    match text.rfind('\n') {
        // 1 for newline character
        Some(idx) => {
            text.len()
                .checked_sub(idx + 1 + shape.used_width())
                .unwrap_or(0)
        }
        None => text.len(),
    }
}

// Uses Cow to avoid allocating in the common cases.
pub fn format_visibility(vis: &Visibility) -> Cow<'static, str> {
    match *vis {
        Visibility::Public => Cow::from("pub "),
        Visibility::Inherited => Cow::from(""),
        Visibility::Crate(_) => Cow::from("pub(crate) "),
        Visibility::Restricted { ref path, .. } => {
            let Path { ref segments, .. } = **path;
            let mut segments_iter = segments.iter().map(|seg| seg.identifier.name.as_str());
            if path.is_global() {
                segments_iter
                    .next()
                    .expect("Non-global path in pub(restricted)?");
            }

            Cow::from(format!("pub({}) ", segments_iter.join("::")))
        }
    }
}

#[inline]
pub fn format_unsafety(unsafety: ast::Unsafety) -> &'static str {
    match unsafety {
        ast::Unsafety::Unsafe => "unsafe ",
        ast::Unsafety::Normal => "",
    }
}

#[inline]
pub fn format_mutability(mutability: ast::Mutability) -> &'static str {
    match mutability {
        ast::Mutability::Mutable => "mut ",
        ast::Mutability::Immutable => "",
    }
}

#[inline]
pub fn format_abi(abi: abi::Abi, explicit_abi: bool) -> String {
    if abi == abi::Abi::C && !explicit_abi {
        "extern ".into()
    } else {
        format!("extern {} ", abi)
    }
}

// The width of the first line in s.
#[inline]
pub fn first_line_width(s: &str) -> usize {
    match s.find('\n') {
        Some(n) => n,
        None => s.len(),
    }
}

// The width of the last line in s.
#[inline]
pub fn last_line_width(s: &str) -> usize {
    match s.rfind('\n') {
        Some(n) => s.len() - n - 1,
        None => s.len(),
    }
}
#[inline]
pub fn trimmed_last_line_width(s: &str) -> usize {
    match s.rfind('\n') {
        Some(n) => s[(n + 1)..].trim().len(),
        None => s.trim().len(),
    }
}

#[inline]
fn is_skip(meta_item: &MetaItem) -> bool {
    match meta_item.node {
        MetaItemKind::Word => meta_item.name == SKIP_ANNOTATION,
        MetaItemKind::List(ref l) => {
            meta_item.name == "cfg_attr" && l.len() == 2 && is_skip_nested(&l[1])
        }
        _ => false,
    }
}

#[inline]
fn is_skip_nested(meta_item: &NestedMetaItem) -> bool {
    match meta_item.node {
        NestedMetaItemKind::MetaItem(ref mi) => is_skip(mi),
        NestedMetaItemKind::Literal(_) => false,
    }
}

#[inline]
pub fn contains_skip(attrs: &[Attribute]) -> bool {
    attrs.iter().any(|a| is_skip(&a.value))
}

// Find the end of a TyParam
#[inline]
pub fn end_typaram(typaram: &ast::TyParam) -> BytePos {
    typaram
        .bounds
        .last()
        .map_or(typaram.span, |bound| match *bound {
            ast::RegionTyParamBound(ref lt) => lt.span,
            ast::TraitTyParamBound(ref prt, _) => prt.span,
        })
        .hi
}

#[inline]
pub fn semicolon_for_expr(expr: &ast::Expr) -> bool {
    match expr.node {
        ast::ExprKind::Ret(..) |
        ast::ExprKind::Continue(..) |
        ast::ExprKind::Break(..) => true,
        _ => false,
    }
}

#[inline]
pub fn semicolon_for_stmt(stmt: &ast::Stmt) -> bool {
    match stmt.node {
        ast::StmtKind::Semi(ref expr) => {
            match expr.node {
                ast::ExprKind::While(..) |
                ast::ExprKind::WhileLet(..) |
                ast::ExprKind::Loop(..) |
                ast::ExprKind::ForLoop(..) => false,
                _ => true,
            }
        }
        ast::StmtKind::Expr(..) => false,
        _ => true,
    }
}

#[inline]
pub fn stmt_expr(stmt: &ast::Stmt) -> Option<&ast::Expr> {
    match stmt.node {
        ast::StmtKind::Expr(ref expr) => Some(expr),
        _ => None,
    }
}

#[inline]
pub fn trim_newlines(input: &str) -> &str {
    match input.find(|c| c != '\n' && c != '\r') {
        Some(start) => {
            let end = input.rfind(|c| c != '\n' && c != '\r').unwrap_or(0) + 1;
            &input[start..end]
        }
        None => "",
    }
}

// Macro for deriving implementations of Decodable for enums
#[macro_export]
macro_rules! impl_enum_decodable {
    ( $e:ident, $( $x:ident ),* ) => {
        impl<'de> ::serde::de::Deserialize<'de> for $e {
            fn deserialize<D>(d: D) -> Result<Self, D::Error>
                    where D: ::serde::Deserializer<'de> {
                use std::ascii::AsciiExt;
                use serde::de::{Error, Visitor};
                use std::marker::PhantomData;
                use std::fmt;
                struct StringOnly<T>(PhantomData<T>);
                impl<'de, T> Visitor<'de> for StringOnly<T>
                        where T: ::serde::Deserializer<'de> {
                    type Value = String;
                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                        formatter.write_str("string")
                    }
                    fn visit_str<E>(self, value: &str) -> Result<String, E> {
                        Ok(String::from(value))
                    }
                }
                let s = try!(d.deserialize_string(StringOnly::<D>(PhantomData)));
                $(
                    if stringify!($x).eq_ignore_ascii_case(&s) {
                      return Ok($e::$x);
                    }
                )*
                static ALLOWED: &'static[&str] = &[$(stringify!($x),)*];
                Err(D::Error::unknown_variant(&s, ALLOWED))
            }
        }

        impl ::std::str::FromStr for $e {
            type Err = &'static str;

            fn from_str(s: &str) -> Result<Self, Self::Err> {
                use std::ascii::AsciiExt;
                $(
                    if stringify!($x).eq_ignore_ascii_case(s) {
                        return Ok($e::$x);
                    }
                )*
                Err("Bad variant")
            }
        }

        impl ::config::ConfigType for $e {
            fn doc_hint() -> String {
                let mut variants = Vec::new();
                $(
                    variants.push(stringify!($x));
                )*
                format!("[{}]", variants.join("|"))
            }
        }
    };
}

// Same as try!, but for Option
#[macro_export]
macro_rules! try_opt {
    ($expr:expr) => (match $expr {
        Some(val) => val,
        None => { return None; }
    })
}

macro_rules! msg {
    ($($arg:tt)*) => (
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
}

// For format_missing and last_pos, need to use the source callsite (if applicable).
// Required as generated code spans aren't guaranteed to follow on from the last span.
macro_rules! source {
    ($this:ident, $sp: expr) => {
        $this.codemap.source_callsite($sp)
    }
}

// Wraps string-like values in an Option. Returns Some when the string adheres
// to the Rewrite constraints defined for the Rewrite trait and else otherwise.
pub fn wrap_str<S: AsRef<str>>(s: S, max_width: usize, shape: Shape) -> Option<S> {
    {
        let snippet = s.as_ref();

        if !snippet.contains('\n') && snippet.len() > shape.width {
            return None;
        } else {
            let mut lines = snippet.lines();

            // The caller of this function has already placed `shape.offset`
            // characters on the first line.
            let first_line_max_len = try_opt!(max_width.checked_sub(shape.indent.width()));
            if lines.next().unwrap().len() > first_line_max_len {
                return None;
            }

            // The other lines must fit within the maximum width.
            if lines.any(|line| line.len() > max_width) {
                return None;
            }

            // `width` is the maximum length of the last line, excluding
            // indentation.
            // A special check for the last line, since the caller may
            // place trailing characters on this line.
            if snippet.lines().rev().next().unwrap().len() > shape.indent.width() + shape.width {
                return None;
            }
        }
    }

    Some(s)
}

impl Rewrite for String {
    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
        wrap_str(self, context.config.max_width, shape).map(ToOwned::to_owned)
    }
}

// Binary search in integer range. Returns the first Ok value returned by the
// callback.
// The callback takes an integer and returns either an Ok, or an Err indicating
// whether the `guess' was too high (Ordering::Less), or too low.
// This function is guaranteed to try to the hi value first.
pub fn binary_search<C, T>(mut lo: usize, mut hi: usize, callback: C) -> Option<T>
    where C: Fn(usize) -> Result<T, Ordering>
{
    let mut middle = hi;

    while lo <= hi {
        match callback(middle) {
            Ok(val) => return Some(val),
            Err(Ordering::Less) => {
                hi = middle - 1;
            }
            Err(..) => {
                lo = middle + 1;
            }
        }
        middle = (hi + lo) / 2;
    }

    None
}

#[inline]
pub fn colon_spaces(before: bool, after: bool) -> &'static str {
    match (before, after) {
        (true, true) => " : ",
        (true, false) => " :",
        (false, true) => ": ",
        (false, false) => ":",
    }
}

#[test]
fn bin_search_test() {
    let closure = |i| match i {
        4 => Ok(()),
        j if j > 4 => Err(Ordering::Less),
        j if j < 4 => Err(Ordering::Greater),
        _ => unreachable!(),
    };

    assert_eq!(Some(()), binary_search(1, 10, &closure));
    assert_eq!(None, binary_search(1, 3, &closure));
    assert_eq!(Some(()), binary_search(0, 44, &closure));
    assert_eq!(Some(()), binary_search(4, 125, &closure));
    assert_eq!(None, binary_search(6, 100, &closure));
}

pub fn left_most_sub_expr(e: &ast::Expr) -> &ast::Expr {
    match e.node {
        ast::ExprKind::InPlace(ref e, _) |
        ast::ExprKind::Call(ref e, _) |
        ast::ExprKind::Binary(_, ref e, _) |
        ast::ExprKind::Cast(ref e, _) |
        ast::ExprKind::Type(ref e, _) |
        ast::ExprKind::Assign(ref e, _) |
        ast::ExprKind::AssignOp(_, ref e, _) |
        ast::ExprKind::Field(ref e, _) |
        ast::ExprKind::TupField(ref e, _) |
        ast::ExprKind::Index(ref e, _) |
        ast::ExprKind::Range(Some(ref e), _, _) |
        ast::ExprKind::Try(ref e) => left_most_sub_expr(e),
        _ => e,
    }
}
<|endoftext|>


<commit_before>//! Graph visitor algorithms.
//!

use std::collections::{
    HashSet,
    VecDeque,
};
use std::hash::Hash;
use fb::FixedBitSet;

use super::{
    graphmap,
    graph,
    EdgeType,
    EdgeDirection,
    Graph,
    GraphMap,
};

use graph::{
    IndexType,
};

/// Base trait for graphs that defines the node identifier.
pub trait Graphlike {
    type NodeId: Clone;
}

/// A graph trait for accessing the neighbors iterator
pub trait NeighborIter<'a> : Graphlike {
    type Iter: Iterator<Item=Self::NodeId>;

    /// Return an iterator that visits all neighbors of the node **n**.
    fn neighbors(&'a self, n: Self::NodeId) -> Self::Iter;
}

impl<'a, N, E, Ty, Ix> NeighborIter<'a> for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N, E> NeighborIter<'a> for GraphMap<N, E>
where N: Copy + Ord + Hash
{
    type Iter = graphmap::Neighbors<'a, N>;
    fn neighbors(&'a self, n: N) -> graphmap::Neighbors<'a, N>
    {
        GraphMap::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct AsUndirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for AsUndirected<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;

    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_undirected(self.0, n)
    }
}

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for Reversed<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

/// A mapping from node → is_visited.
pub trait VisitMap<N> {
    /// Return **true** if the value is not already present.
    fn visit(&mut self, N) -> bool;
    fn is_visited(&self, &N) -> bool;
}

impl<Ix> VisitMap<graph::NodeIndex<Ix>> for FixedBitSet where
    Ix: IndexType,
{
    fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool {
        let present = self.contains(x.index());
        self.insert(x.index());
        !present
    }
    fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool {
        self.contains(x.index())
    }
}

impl<Ix> VisitMap<graph::EdgeIndex<Ix>> for FixedBitSet where
    Ix: IndexType,
{
    fn visit(&mut self, x: graph::EdgeIndex<Ix>) -> bool {
        let present = self.contains(x.index());
        self.insert(x.index());
        !present
    }
    fn is_visited(&self, x: &graph::EdgeIndex<Ix>) -> bool {
        self.contains(x.index())
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn is_visited(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for which datastructure to use for a graph’s visitor map
pub trait Visitable : Graphlike {
    type Map: VisitMap<Self::NodeId>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, Ty, Ix> Graphlike for Graph<N, E, Ty, Ix> where
    Ix: IndexType,
{
    type NodeId = graph::NodeIndex<Ix>;
}

impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Map = FixedBitSet;
    fn visit_map(&self) -> FixedBitSet { FixedBitSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for GraphMap<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for GraphMap<N, E>
    where N: Copy + Ord + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

/// Create or access the adjacency matrix of a graph
pub trait GetAdjacencyMatrix : Graphlike {
    type AdjMatrix;
    fn adjacency_matrix(&self) -> Self::AdjMatrix;
    fn is_adjacent(&self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
}

/// The **GraphMap** keeps an adjacency matrix internally.
impl<N, E> GetAdjacencyMatrix for GraphMap<N, E>
    where N: Copy + Ord + Hash
{
    type AdjMatrix = ();
    #[inline]
    fn adjacency_matrix(&self) { }
    #[inline]
    fn is_adjacent(&self, _: &(), a: N, b: N) -> bool {
        self.contains_edge(a, b)
    }
}

/// A depth first search (DFS) of a graph.
///
/// Using a **Dfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Dfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut dfs = Dfs::new(&graph, a);
/// while let Some(nx) = dfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone, Debug)]
pub struct Dfs<N, VM> {
    /// The stack of nodes to visit
    pub stack: Vec<N>,
    /// The map of discovered nodes
    pub discovered: VM,
}

impl<N, VM> Dfs<N, VM>
    where N: Clone,
          VM: VisitMap<N>,
{
    /// Create a new **Dfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new<G>(graph: &G, start: N) -> Self
        where G: Visitable<NodeId=N, Map=VM>
    {
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        dfs
    }

    /// Create a new **Dfs** using the graph's visitor map, and no stack.
    pub fn empty<G>(graph: &G) -> Self
        where G: Visitable<NodeId=N, Map=VM>
    {
        Dfs {
            stack: Vec::new(),
            discovered: graph.visit_map(),
        }
    }

    /// Keep the discovered map, but clear the visit stack and restart
    /// the dfs from a particular node.
    pub fn move_to(&mut self, start: N)
    {
        self.discovered.visit(start.clone());
        self.stack.clear();
        self.stack.push(start);
    }

    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<G>(&mut self, graph: &G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'a> NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// An iterator for a depth first traversal of a graph.
pub struct DfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    dfs: Dfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> DfsIter<'a, G>
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Dfs::new to
        // work around rust bug #22841
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        DfsIter {
            graph: graph,
            dfs: dfs,
        }
    }

    /// Keep the discovered map, but clear the visit stack and restart
    /// the DFS traversal from a particular node.
    pub fn move_to(&mut self, start: G::NodeId)
    {
        self.dfs.move_to(start)
    }
}

impl<'a, G: 'a + Visitable> Iterator for DfsIter<'a, G> where
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;

    #[inline]
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.dfs.next(self.graph)
    }

    fn size_hint(&self) -> (usize, Option<usize>)
    {
        // Very vauge info about size of traversal
        (self.dfs.stack.len(), None)
    }
}

impl<'a, G: Visitable> Clone for DfsIter<'a, G> where Dfs<G::NodeId, G::Map>: Clone
{
    fn clone(&self) -> Self {
        DfsIter {
            graph: self.graph,
            dfs: self.dfs.clone(),
        }
    }
}

/// A breadth first search (BFS) of a graph.
///
/// Using a **Bfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Bfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut bfs = Bfs::new(&graph, a);
/// while let Some(nx) = bfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone)]
pub struct Bfs<N, VM> {
    /// The queue of nodes to visit
    pub stack: VecDeque<N>,
    /// The map of discovered nodes
    pub discovered: VM,
}

impl<N, VM> Bfs<N, VM>
    where N: Clone,
          VM: VisitMap<N>,
{
    /// Create a new **Bfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new<G>(graph: &G, start: N) -> Self
        where G: Visitable<NodeId=N, Map=VM>
    {
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        Bfs {
            stack: stack,
            discovered: discovered,
        }
    }

    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<G>(&mut self, graph: &G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'a> NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop_front() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }

}

/// An iterator for a breadth first traversal of a graph.
pub struct BfsIter<'a, G: 'a + Visitable> {
    graph: &'a G,
    bfs: Bfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> BfsIter<'a, G> where
    G::NodeId: Clone,
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Bfs::new to
        // work around rust bug #22841
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        let bfs = Bfs {
            stack: stack,
            discovered: discovered,
        };
        BfsIter {
            graph: graph,
            bfs: bfs,
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for BfsIter<'a, G> where
    G::NodeId: Clone,
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.bfs.next(self.graph)
    }

    fn size_hint(&self) -> (usize, Option<usize>)
    {
        (self.bfs.stack.len(), None)
    }
}

impl<'a, G: Visitable> Clone for BfsIter<'a, G> where Bfs<G::NodeId, G::Map>: Clone
{
    fn clone(&self) -> Self {
        BfsIter {
            graph: self.graph,
            bfs: self.bfs.clone(),
        }
    }
}
<commit_msg>Update for well-formedness (Rust RFC 1214)<commit_after>//! Graph visitor algorithms.
//!

use std::collections::{
    HashSet,
    VecDeque,
};
use std::hash::Hash;
use fb::FixedBitSet;

use super::{
    graphmap,
    graph,
    EdgeType,
    EdgeDirection,
    Graph,
    GraphMap,
};

use graph::{
    IndexType,
};

/// Base trait for graphs that defines the node identifier.
pub trait Graphlike {
    type NodeId: Clone;
}

/// A graph trait for accessing the neighbors iterator
pub trait NeighborIter<'a> : Graphlike {
    type Iter: Iterator<Item=Self::NodeId>;

    /// Return an iterator that visits all neighbors of the node **n**.
    fn neighbors(&'a self, n: Self::NodeId) -> Self::Iter;
}

impl<'a, N, E: 'a, Ty, Ix> NeighborIter<'a> for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N: 'a, E> NeighborIter<'a> for GraphMap<N, E>
where N: Copy + Ord + Hash
{
    type Iter = graphmap::Neighbors<'a, N>;
    fn neighbors(&'a self, n: N) -> graphmap::Neighbors<'a, N>
    {
        GraphMap::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct AsUndirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E: 'a, Ty, Ix> NeighborIter<'a> for AsUndirected<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;

    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_undirected(self.0, n)
    }
}

impl<'a, 'b, N, E: 'a, Ty, Ix> NeighborIter<'a> for Reversed<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

/// A mapping from node → is_visited.
pub trait VisitMap<N> {
    /// Return **true** if the value is not already present.
    fn visit(&mut self, N) -> bool;
    fn is_visited(&self, &N) -> bool;
}

impl<Ix> VisitMap<graph::NodeIndex<Ix>> for FixedBitSet where
    Ix: IndexType,
{
    fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool {
        let present = self.contains(x.index());
        self.insert(x.index());
        !present
    }
    fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool {
        self.contains(x.index())
    }
}

impl<Ix> VisitMap<graph::EdgeIndex<Ix>> for FixedBitSet where
    Ix: IndexType,
{
    fn visit(&mut self, x: graph::EdgeIndex<Ix>) -> bool {
        let present = self.contains(x.index());
        self.insert(x.index());
        !present
    }
    fn is_visited(&self, x: &graph::EdgeIndex<Ix>) -> bool {
        self.contains(x.index())
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn is_visited(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for which datastructure to use for a graph’s visitor map
pub trait Visitable : Graphlike {
    type Map: VisitMap<Self::NodeId>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, Ty, Ix> Graphlike for Graph<N, E, Ty, Ix> where
    Ix: IndexType,
{
    type NodeId = graph::NodeIndex<Ix>;
}

impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Map = FixedBitSet;
    fn visit_map(&self) -> FixedBitSet { FixedBitSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for GraphMap<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for GraphMap<N, E>
    where N: Copy + Ord + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

/// Create or access the adjacency matrix of a graph
pub trait GetAdjacencyMatrix : Graphlike {
    type AdjMatrix;
    fn adjacency_matrix(&self) -> Self::AdjMatrix;
    fn is_adjacent(&self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
}

/// The **GraphMap** keeps an adjacency matrix internally.
impl<N, E> GetAdjacencyMatrix for GraphMap<N, E>
    where N: Copy + Ord + Hash
{
    type AdjMatrix = ();
    #[inline]
    fn adjacency_matrix(&self) { }
    #[inline]
    fn is_adjacent(&self, _: &(), a: N, b: N) -> bool {
        self.contains_edge(a, b)
    }
}

/// A depth first search (DFS) of a graph.
///
/// Using a **Dfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Dfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut dfs = Dfs::new(&graph, a);
/// while let Some(nx) = dfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone, Debug)]
pub struct Dfs<N, VM> {
    /// The stack of nodes to visit
    pub stack: Vec<N>,
    /// The map of discovered nodes
    pub discovered: VM,
}

impl<N, VM> Dfs<N, VM>
    where N: Clone,
          VM: VisitMap<N>,
{
    /// Create a new **Dfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new<G>(graph: &G, start: N) -> Self
        where G: Visitable<NodeId=N, Map=VM>
    {
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        dfs
    }

    /// Create a new **Dfs** using the graph's visitor map, and no stack.
    pub fn empty<G>(graph: &G) -> Self
        where G: Visitable<NodeId=N, Map=VM>
    {
        Dfs {
            stack: Vec::new(),
            discovered: graph.visit_map(),
        }
    }

    /// Keep the discovered map, but clear the visit stack and restart
    /// the dfs from a particular node.
    pub fn move_to(&mut self, start: N)
    {
        self.discovered.visit(start.clone());
        self.stack.clear();
        self.stack.push(start);
    }

    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<'a, G>(&mut self, graph: &'a G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// An iterator for a depth first traversal of a graph.
pub struct DfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    dfs: Dfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> DfsIter<'a, G>
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Dfs::new to
        // work around rust bug #22841
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        DfsIter {
            graph: graph,
            dfs: dfs,
        }
    }

    /// Keep the discovered map, but clear the visit stack and restart
    /// the DFS traversal from a particular node.
    pub fn move_to(&mut self, start: G::NodeId)
    {
        self.dfs.move_to(start)
    }
}

impl<'a, G: 'a + Visitable> Iterator for DfsIter<'a, G> where
    G: NeighborIter<'a>,
{
    type Item = G::NodeId;

    #[inline]
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.dfs.next(self.graph)
    }

    fn size_hint(&self) -> (usize, Option<usize>)
    {
        // Very vauge info about size of traversal
        (self.dfs.stack.len(), None)
    }
}

impl<'a, G: Visitable> Clone for DfsIter<'a, G> where Dfs<G::NodeId, G::Map>: Clone
{
    fn clone(&self) -> Self {
        DfsIter {
            graph: self.graph,
            dfs: self.dfs.clone(),
        }
    }
}

/// A breadth first search (BFS) of a graph.
///
/// Using a **Bfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Bfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut bfs = Bfs::new(&graph, a);
/// while let Some(nx) = bfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone)]
pub struct Bfs<N, VM> {
    /// The queue of nodes to visit
    pub stack: VecDeque<N>,
    /// The map of discovered nodes
    pub discovered: VM,
}

impl<N, VM> Bfs<N, VM>
    where N: Clone,
          VM: VisitMap<N>,
{
    /// Create a new **Bfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new<G>(graph: &G, start: N) -> Self
        where G: Visitable<NodeId=N, Map=VM>
    {
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        Bfs {
            stack: stack,
            discovered: discovered,
        }
    }

    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<'a, G>(&mut self, graph: &'a G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop_front() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }

}

/// An iterator for a breadth first traversal of a graph.
pub struct BfsIter<'a, G: 'a + Visitable> {
    graph: &'a G,
    bfs: Bfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> BfsIter<'a, G> where
    G::NodeId: Clone,
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Bfs::new to
        // work around rust bug #22841
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        let bfs = Bfs {
            stack: stack,
            discovered: discovered,
        };
        BfsIter {
            graph: graph,
            bfs: bfs,
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for BfsIter<'a, G> where
    G::NodeId: Clone,
    G: NeighborIter<'a>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.bfs.next(self.graph)
    }

    fn size_hint(&self) -> (usize, Option<usize>)
    {
        (self.bfs.stack.len(), None)
    }
}

impl<'a, G: Visitable> Clone for BfsIter<'a, G> where Bfs<G::NodeId, G::Map>: Clone
{
    fn clone(&self) -> Self {
        BfsIter {
            graph: self.graph,
            bfs: self.bfs.clone(),
        }
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate quick_protobuf;
extern crate test;

mod perftest_data;

use test::{Bencher, black_box};
use perftest_data::*;
use std::cmp::min;

use quick_protobuf::{Reader, Writer};
use quick_protobuf::message::{MessageRead, MessageWrite};

#[bench]
fn read_file(b: &mut Bencher) {
    b.iter(|| {
        let _ = black_box(::perftest_data::PerftestData::from_file("../rust-protobuf/perftest_data.pbbin").unwrap());
    })
}

macro_rules! perfbench {
    ($gen: ident, $write:ident, $read:ident) => {
#[bench]
fn $write(b: &mut Bencher) {
    let v = $gen();
    b.iter(|| {
        let mut buf = black_box(Vec::new());
        let mut w = Writer::new(&mut buf);
        for i in &v {
            i.write_message(&mut w).unwrap();
        }
    })
}

#[bench]
fn $read(b: &mut Bencher) {
    let v = $gen();
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        for i in &v {
            i.write_message(&mut w).unwrap();
        }
    }
    let len = buf.len();
    b.iter(|| {
        let mut buf = &*buf;
        let mut r = Reader::from_reader(&mut buf, len);
        while !r.is_eof() {
            let _ = black_box(Test1::from_reader(&mut r).unwrap());
        }
    })
}
    }
}

fn generate_test1() -> Vec<Test1> {
    (0..500).map(|i| Test1 { value: Some(i) })
        .chain((0..100).map(|_| Test1 { value: None }))
        .collect()
}

perfbench!(generate_test1, write_test1, read_test1);

fn generate_repeated_bool() -> Vec<TestRepeatedBool> {
    (1..10).map(|j| TestRepeatedBool { values: (0..100).map(|i| i % j == 0).collect() })
        .collect()
}

perfbench!(generate_repeated_bool, write_repeated_bool, read_repeated_bool);

fn generate_repeated_packed_int32() -> Vec<TestRepeatedPackedInt32> {
    (1..400).map(|j| TestRepeatedPackedInt32 { values: (0..1000).map(|i| i * j).collect() })
        .collect()
}

perfbench!(generate_repeated_packed_int32, write_repeated_packed_int32, read_repeated_packed_int32);

fn generate_repeated_messages() -> Vec<TestRepeatedMessages> {
    let mut messages = Vec::new();
    messages.push(TestRepeatedMessages {
        messages1: vec![],
        messages2: vec![],
        messages3: vec![],
    });

    for _ in 0..100 {
        let i1 = min(messages.len() % 3, messages.len() - 1);
        let i2 = min(messages.len() % 6, messages.len() - 1);
        let i3 = min(messages.len() % 9, messages.len() - 1);
        let m1 = messages[i1].clone();
        let m2 = messages[i2].clone();
        let m3 = messages[i3].clone();
        messages.push(TestRepeatedMessages {
            messages1: vec![m1.clone()],
            messages2: vec![m1.clone(), m2.clone()],
            messages3: vec![m1.clone(), m2.clone(), m3.clone()],
        });
    }
    messages
}

perfbench!(generate_repeated_messages, write_repeated_messages, read_repeated_messages);

fn generate_optional_messages() -> Vec<TestOptionalMessages> {
    let mut messages = Vec::new();
    messages.push(TestOptionalMessages {
        message1: None,
        message2: None,
        message3: None,
    });

    for _ in 0..60 {
        let i1 = min(messages.len() % 3, messages.len() - 1);
        let i2 = min(messages.len() % 6, messages.len() - 1);
        let i3 = min(messages.len() % 9, messages.len() - 1);
        let m1 = messages[i1].clone();
        let m2 = messages[i2].clone();
        let m3 = messages[i3].clone();
        messages.push(TestOptionalMessages {
            message1: Some(Box::new(m1.clone())),
            message2: Some(Box::new(m2.clone())),
            message3: Some(Box::new(m3.clone())),
        });
    }
    messages
}

perfbench!(generate_optional_messages, write_optional_messages, read_optional_messages);

fn generate_strings() -> Vec<TestStrings> {
    let mut s = "hello world from quick-protobuf!!!".split('_').cycle().map(|s| s.to_string());
    (1..100).map(|_| TestStrings {
        s1: s.by_ref().next(),
        s2: s.by_ref().next(),
        s3: s.by_ref().next(),
    }).collect()
}

perfbench!(generate_strings, write_strings, read_strings);

fn generate_small_bytes() -> Vec<TestBytes> {
    let mut s = "hello world from quick-protobuf!!!".split('_').cycle()
        .map(|s| s.as_bytes().to_vec());
    (1..800).map(|_| TestBytes { b1: s.by_ref().next() })
        .collect()
}

perfbench!(generate_small_bytes, write_small_bytes, read_small_bytes);

fn generate_large_bytes() -> Vec<TestBytes> {
    let mut s = "hello world from quick-protobuf!!!".split('_').cycle().map(|s| s.as_bytes());
    (1..300).map(|_| TestBytes {
        b1: Some(s.by_ref().take(500).fold(Vec::new(), |mut cur, nxt| {
                cur.extend_from_slice(nxt);
                cur
            }))
    }).collect()
}

perfbench!(generate_large_bytes, write_large_bytes, read_large_bytes);

fn generate_all() -> Vec<PerftestData> {
    vec![PerftestData {
        test1: generate_test1(),
        test_repeated_bool: generate_repeated_bool(),
        test_repeated_messages: generate_repeated_messages(),
        test_optional_messages: generate_optional_messages(),
        test_strings: generate_strings(),
        test_repeated_packed_int32: generate_repeated_packed_int32(),
        test_small_bytearrays: generate_small_bytes(),
        test_large_bytearrays: generate_large_bytes(),
    }]
}

perfbench!(generate_all, write_all, read_all);
<commit_msg>fix benches<commit_after>#![feature(test)]

extern crate quick_protobuf;
extern crate test;

mod perftest_data;

use test::{Bencher, black_box};
use perftest_data::*;
use std::cmp::min;

use quick_protobuf::{Reader, Writer};
use quick_protobuf::message::{MessageRead, MessageWrite};

#[bench]
fn read_file(b: &mut Bencher) {
    b.iter(|| {
        let _ = black_box(::perftest_data::PerftestData::from_file("../rust-protobuf/perftest_data.pbbin").unwrap());
    })
}

macro_rules! perfbench {
    ($gen: ident, $m:ident, $write:ident, $read:ident) => {
#[bench]
fn $write(b: &mut Bencher) {
    let v = $gen();
    b.iter(|| {
        let mut buf = black_box(Vec::new());
        let mut w = Writer::new(&mut buf);
        for i in &v {
            i.write_message(&mut w).unwrap();
        }
    })
}

#[bench]
fn $read(b: &mut Bencher) {
    let v = $gen();
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        for i in &v {
            i.write_message(&mut w).unwrap();
        }
    }
    let len = buf.len();
    b.iter(|| {
        let mut buf = &*buf;
        let mut r = Reader::from_reader(&mut buf, len);
        while !r.is_eof() {
            let _ = black_box($m::from_reader(&mut r).unwrap());
        }
    })
}
    }
}

fn generate_test1() -> Vec<Test1> {
    (0..500).map(|i| Test1 { value: Some(i) })
        .chain((0..200).map(|_| Test1 { value: None }))
        .collect()
}

perfbench!(generate_test1, Test1, write_test1, read_test1);

fn generate_repeated_bool() -> Vec<TestRepeatedBool> {
    (1..10).map(|j| TestRepeatedBool { values: (0..100).map(|i| i % j == 0).collect() })
        .collect()
}

perfbench!(generate_repeated_bool, TestRepeatedBool, write_repeated_bool, read_repeated_bool);

fn generate_repeated_packed_int32() -> Vec<TestRepeatedPackedInt32> {
    (1..40).map(|j| TestRepeatedPackedInt32 { values: (0..100).map(|i| i * j).collect() })
        .collect()
}

perfbench!(generate_repeated_packed_int32, TestRepeatedPackedInt32, write_repeated_packed_int32, read_repeated_packed_int32);

fn generate_repeated_messages() -> Vec<TestRepeatedMessages> {
    let mut messages = Vec::new();
    messages.push(TestRepeatedMessages {
        messages1: vec![],
        messages2: vec![],
        messages3: vec![],
    });

    for _ in 0..10 {
        let i1 = min(messages.len() % 3, messages.len() - 1);
        let i2 = min(messages.len() % 6, messages.len() - 1);
        let i3 = min(messages.len() % 9, messages.len() - 1);
        let m1 = messages[i1].clone();
        let m2 = messages[i2].clone();
        let m3 = messages[i3].clone();
        messages.push(TestRepeatedMessages {
            messages1: vec![m1.clone()],
            messages2: vec![m1.clone(), m2.clone()],
            messages3: vec![m1.clone(), m2.clone(), m3.clone()],
        });
    }
    messages
}

perfbench!(generate_repeated_messages, TestRepeatedMessages, write_repeated_messages, read_repeated_messages);

fn generate_optional_messages() -> Vec<TestOptionalMessages> {
    let mut messages = Vec::new();
    messages.push(TestOptionalMessages {
        message1: None,
        message2: None,
        message3: None,
    });

    for _ in 0..10 {
        let i1 = min(messages.len() % 3, messages.len() - 1);
        let i2 = min(messages.len() % 6, messages.len() - 1);
        let i3 = min(messages.len() % 9, messages.len() - 1);
        let m1 = messages[i1].clone();
        let m2 = messages[i2].clone();
        let m3 = messages[i3].clone();
        messages.push(TestOptionalMessages {
            message1: Some(Box::new(m1.clone())),
            message2: Some(Box::new(m2.clone())),
            message3: Some(Box::new(m3.clone())),
        });
    }
    messages
}

perfbench!(generate_optional_messages, TestOptionalMessages, write_optional_messages, read_optional_messages);

fn generate_strings() -> Vec<TestStrings> {
    let mut s = "hello world from quick-protobuf!!!".split('_').cycle().map(|s| s.to_string());
    (1..100).map(|_| TestStrings {
        s1: s.by_ref().next(),
        s2: s.by_ref().next(),
        s3: s.by_ref().next(),
    }).collect()
}

perfbench!(generate_strings, TestStrings, write_strings, read_strings);

fn generate_small_bytes() -> Vec<TestBytes> {
    let mut s = "hello world from quick-protobuf!!!".split('_').cycle()
        .map(|s| s.as_bytes().to_vec());
    (1..800).map(|_| TestBytes { b1: s.by_ref().next() })
        .collect()
}

perfbench!(generate_small_bytes, TestBytes, write_small_bytes, read_small_bytes);

fn generate_large_bytes() -> Vec<TestBytes> {
    let mut s = "hello world from quick-protobuf!!!".split('_').cycle().map(|s| s.as_bytes());
    (1..30).map(|_| TestBytes {
        b1: Some(s.by_ref().take(500).fold(Vec::new(), |mut cur, nxt| {
                cur.extend_from_slice(nxt);
                cur
            }))
    }).collect()
}

perfbench!(generate_large_bytes, TestBytes, write_large_bytes, read_large_bytes);

fn generate_all() -> Vec<PerftestData> {
    vec![PerftestData {
        test1: generate_test1(),
        test_repeated_bool: generate_repeated_bool(),
        test_repeated_messages: generate_repeated_messages(),
        test_optional_messages: generate_optional_messages(),
        test_strings: generate_strings(),
        test_repeated_packed_int32: generate_repeated_packed_int32(),
        test_small_bytearrays: generate_small_bytes(),
        test_large_bytearrays: generate_large_bytes(),
    }]
}

perfbench!(generate_all, PerftestData, write_all, read_all);
<|endoftext|>


<commit_before>#![cfg(target_pointer_width = "64")]

use std::mem;
use syn::{Expr, Item, Lit, Pat, Type};

#[test]
fn test_expr_size() {
    assert_eq!(mem::size_of::<Expr>(), 280);
}

#[test]
fn test_item_size() {
    assert_eq!(mem::size_of::<Item>(), 344);
}

#[test]
fn test_type_size() {
    assert_eq!(mem::size_of::<Type>(), 304);
}

#[test]
fn test_pat_size() {
    assert_eq!(mem::size_of::<Pat>(), 144);
}

#[test]
fn test_lit_size() {
    assert_eq!(mem::size_of::<Lit>(), 40);
}
<commit_msg>Update test suite to nightly-2022-09-09<commit_after>#![cfg(target_pointer_width = "64")]

use std::mem;
use syn::{Expr, Item, Lit, Pat, Type};

#[test]
fn test_expr_size() {
    assert_eq!(mem::size_of::<Expr>(), 264);
}

#[test]
fn test_item_size() {
    assert_eq!(mem::size_of::<Item>(), 320);
}

#[test]
fn test_type_size() {
    assert_eq!(mem::size_of::<Type>(), 280);
}

#[test]
fn test_pat_size() {
    assert_eq!(mem::size_of::<Pat>(), 144);
}

#[test]
fn test_lit_size() {
    assert_eq!(mem::size_of::<Lit>(), 32);
}
<|endoftext|>


<commit_before>pub mod ngram_generator;
pub mod lucene_asciifold;
pub mod registry;
pub mod tokenizers;
pub mod filters;

use term::Term;
use token::Token;

use analysis::ngram_generator::Edge;
use analysis::tokenizers::standard::StandardTokenizer;
use analysis::filters::lowercase::LowercaseFilter;
use analysis::filters::asciifolding::ASCIIFoldingFilter;
use analysis::filters::ngram::NGramFilter;

#[derive(Debug, PartialEq)]
pub enum Analyzer {
    None,
    Standard,
    EdgeNGram,
}

impl Analyzer {
    pub fn run(&self, input: String) -> Vec<Token> {
        match *self {
            Analyzer::None => vec![Token{term: Term::String(input), position: 1}],
            Analyzer::Standard => {
                let tokens = Box::new(StandardTokenizer::new(&input));

                // Lowercase
                let tokens = Box::new(LowercaseFilter::new(tokens));

                // ASCII Folding (not standard in Elasticsearch, but Wagtail needs it)
                let tokens = Box::new(ASCIIFoldingFilter::new(tokens));

                tokens.collect::<Vec<Token>>()
            }
            Analyzer::EdgeNGram => {
                let tokens = Box::new(StandardTokenizer::new(&input));

                // Lowercase
                let tokens = Box::new(LowercaseFilter::new(tokens));

                // ASCII Folding (not standard in Elasticsearch, but Wagtail needs it)
                let tokens = Box::new(ASCIIFoldingFilter::new(tokens));

                // Ngrams
                let tokens = Box::new(NGramFilter::new(tokens, 2, 15, Edge::Left));

                tokens.collect::<Vec<Token>>()
            }
        }
    }
}
<commit_msg>Implemented AnalyzerSpec<commit_after>pub mod ngram_generator;
pub mod lucene_asciifold;
pub mod registry;
pub mod tokenizers;
pub mod filters;

use term::Term;
use token::Token;

use analysis::tokenizers::TokenizerSpec;
use analysis::filters::FilterSpec;
use analysis::ngram_generator::Edge;
use analysis::tokenizers::standard::StandardTokenizer;
use analysis::filters::lowercase::LowercaseFilter;
use analysis::filters::asciifolding::ASCIIFoldingFilter;
use analysis::filters::ngram::NGramFilter;

#[derive(Debug)]
pub struct AnalyzerSpec {
    pub tokenizer: TokenizerSpec,
    pub filters: Vec<FilterSpec>,
}

impl AnalyzerSpec {
    pub fn initialise<'a>(&self, input: &'a str) -> Box<Iterator<Item=Token> + 'a> {
        let mut analyzer = self.tokenizer.initialise(input);

        for filter in self.filters.iter() {
            analyzer = filter.initialise(analyzer);
        }

        analyzer
    }
}

#[derive(Debug, PartialEq)]
pub enum Analyzer {
    None,
    Standard,
    EdgeNGram,
}

impl Analyzer {
    pub fn run(&self, input: String) -> Vec<Token> {
        match *self {
            Analyzer::None => vec![Token{term: Term::String(input), position: 1}],
            Analyzer::Standard => {
                let tokens = Box::new(StandardTokenizer::new(&input));

                // Lowercase
                let tokens = Box::new(LowercaseFilter::new(tokens));

                // ASCII Folding (not standard in Elasticsearch, but Wagtail needs it)
                let tokens = Box::new(ASCIIFoldingFilter::new(tokens));

                tokens.collect::<Vec<Token>>()
            }
            Analyzer::EdgeNGram => {
                let tokens = Box::new(StandardTokenizer::new(&input));

                // Lowercase
                let tokens = Box::new(LowercaseFilter::new(tokens));

                // ASCII Folding (not standard in Elasticsearch, but Wagtail needs it)
                let tokens = Box::new(ASCIIFoldingFilter::new(tokens));

                // Ngrams
                let tokens = Box::new(NGramFilter::new(tokens, 2, 15, Edge::Left));

                tokens.collect::<Vec<Token>>()
            }
        }
    }
}
<|endoftext|>


<commit_before>#![crate_id(name="nl", vers="1.0.0", author="Tobias Schottdorf")]
#![feature(macro_rules)]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Tobias Bohumir Schottdorf <tobias.schottdorf@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */

#![feature(phase)]
#[phase(plugin)]
extern crate regex_macros;
extern crate regex;
extern crate getopts;

use std::os;
use std::io::{stdin};
use std::io::BufferedReader;
use std::io::fs::File;
use std::path::Path;
use getopts::{optopt, optflag, getopts, usage, OptGroup};

#[path="../common/util.rs"]
mod util;
mod helper;

static NAME: &'static str = "nl";
static USAGE: &'static str = "nl [OPTION]... [FILE]...";
// A regular expression matching everything.
static REGEX_DUMMY: &'static regex::Regex = &regex!(r".?");

// Settings store options used by nl to produce its output.
struct Settings {
    // The variables corresponding to the options -h, -b, and -f.
    header_numbering: NumberingStyle,
    body_numbering: NumberingStyle,
    footer_numbering: NumberingStyle,
    // The variable corresponding to -d
    section_delimiter: [char, ..2],
    // The variables corresponding to the options -v, -i, -l, -w.
    starting_line_number: u64,
    line_increment: u64,
    join_blank_lines: u64,
    number_width: uint, // Used with String::from_char, hence uint.
    // The format of the number and the (default value for)
    // renumbering each page.
    number_format: NumberFormat,
    renumber: bool,
    // The string appended to each line number output.
    number_separator: String
}

// NumberingStyle stores which lines are to be numberd.
// The possible options are:
// 1. Number all lines
// 2. Number only nonempty lines
// 3. Don't number any lines at all
// 4. Number all lines that match a basic regular expression.
enum NumberingStyle {
    NumberForAll,
    NumberForNonEmpty,
    NumberForNone,
    NumberForRegularExpression(regex::Regex)
}

// NumberFormat specifies how line numbers are output within their allocated
// space. They are justified to the left or right, in the latter case with
// the option of having all unused space to its left turned into leading zeroes.
enum NumberFormat {
    Left,
    Right,
    RightZero,
}

#[allow(dead_code)]
fn main () {
  os::set_exit_status(uumain(os::args()));
}

pub fn uumain(args: Vec<String>) -> int {
    let possible_options = [
        optopt("b", "body-numbering", "use STYLE for numbering body lines", "STYLE"),
        optopt("d", "section-delimiter", "use CC for separating logical pages", "CC"),
        optopt("f", "footer-numbering", "use STYLE for numbering footer lines", "STYLE"),
        optopt("h", "header-numbering", "use STYLE for numbering header lines", "STYLE"),
        optopt("i", "line-increment", "line number increment at each line", ""),
        optopt("l", "join-blank-lines", "group of NUMBER empty lines counted as one", "NUMBER"),
        optopt("n", "number-format", "insert line numbers according to FORMAT", "FORMAT"),
        optflag("p", "no-renumber", "do not reset line numbers at logical pages"),
        optopt("s", "number-separator", "add STRING after (possible) line number", "STRING"),
        optopt("v", "starting-line-number", "first line number on each logical page", "NUMBER"),
        optopt("w", "number-width", "use NUMBER columns for line numbers", "NUMBER"),
        optflag("", "help", "display this help and exit"),
        optflag("V", "version", "version"),
    ];

    // A mutable settings object, initialized with the defaults.
    let mut settings = Settings {
        header_numbering: NumberForNone,
        body_numbering: NumberForAll,
        footer_numbering: NumberForNone,
        section_delimiter: ['\\', ':'],
        starting_line_number: 1,
        line_increment: 1,
        join_blank_lines: 1,
        number_width: 6,
        number_format: Right,
        renumber: true,
        number_separator: String::from_str("\t"),
    };

    let given_options = match getopts(args.tail(), possible_options) {
        Ok (m) => { m }
        Err(f) => {
            show_error!("{}", f);
            print_usage(possible_options);
            return 1
        }
    };

    if given_options.opt_present("help") {
        print_usage(possible_options);
        return 0;
    }
    if given_options.opt_present("version") { version(); return 0; }

    // Update the settings from the command line options, and terminate the
    // program if some options could not successfully be parsed.
    let parse_errors = helper::parse_options(&mut settings, &given_options);
    if parse_errors.len() > 0 {
        show_error!("Invalid arguments supplied.");
        for message in parse_errors.iter() {
            println!("{}", message.as_slice());
        }
        return 1;
    }

    let files = given_options.free;
    let mut read_stdin = files.is_empty();

    for file in files.iter() {
        if file.as_slice() == "-" {
            // If both file names and '-' are specified, we choose to treat first all
            // regular files, and then read from stdin last.
            read_stdin = true;
            continue
        }
        let path = Path::new(file.as_slice());
        let reader = File::open(&path).unwrap();
        let mut buffer = BufferedReader::new(reader);
        nl(&mut buffer, &settings);
    }

    if read_stdin {
        let mut buffer = BufferedReader::new(stdin());
        nl(&mut buffer, &settings);
    }
    0
}

// nl implements the main functionality for an individual buffer.
fn nl<T: Reader> (reader: &mut BufferedReader<T>, settings: &Settings) {
    let mut line_no = settings.starting_line_number;
    // The current line number's width as a string. Using to_str is inefficient
    // but since we only do it once, it should not hurt.
    let mut line_no_width = line_no.to_str().len();
    let line_no_width_initial = line_no_width;
    // Stores the smallest integer with one more digit than line_no, so that
    // when line_no >= line_no_threshold, we need to use one more digit.
    let mut line_no_threshold = std::num::pow(10u64, line_no_width);
    let mut empty_line_count: u64 = 0;
    let fill_char = match settings.number_format {
        RightZero => '0',
        _ => ' '
    };
    // Initially, we use the body's line counting settings
    let mut regex_filter = match settings.body_numbering {
        NumberForRegularExpression(ref re) => re,
        _ => REGEX_DUMMY,
    };
    let mut line_filter = pass_regex;
    for mut l in reader.lines().map(|r| r.unwrap()) {
        // Sanitize the string. We want to print the newline ourselves.
        if l.as_slice().chars().rev().next().unwrap() == '\n' {
            l.pop_char();
        }
        // Next we iterate through the individual chars to see if this
        // is one of the special lines starting a new "section" in the
        // document.
        let line = l.as_slice();
        let mut odd = false;
        // matched_group counts how many copies of section_delimiter
        // this string consists of (0 if there's anything else)
        let mut matched_groups = 0u8;
        for c in line.chars() {
            // If this is a newline character, the loop should end.
            if c == '\n' {
                break;
            }
            // If we have already seen three groups (corresponding to
            // a header) or the current char does not form part of
            // a new group, then this line is not a segment indicator.
            if matched_groups >= 3
                || settings.section_delimiter[std::bool::to_bit::<uint>(odd)] != c {
                matched_groups = 0;
                break;
            }
            if odd {
                // We have seen a new group and count it.
                matched_groups += 1;
            }
            odd = !odd;
        }

        // See how many groups we matched. That will tell us if this is
        // a line starting a new segment, and the number of groups
        // indicates what type of segment.
        if matched_groups > 0 {
            // The current line is a section delimiter, so we output
            // a blank line.
            println!("");
            // However the line does not count as a blank line, so we
            // reset the counter used for --join-blank-lines.
            empty_line_count = 0;
            match *match matched_groups {
                3 => {
                    // This is a header, so we may need to reset the
                    // line number and the line width
                    if settings.renumber {
                        line_no = settings.starting_line_number;
                        line_no_width = line_no_width_initial;
                        line_no_threshold = std::num::pow(10u64, line_no_width);
                    }
                    &settings.header_numbering
                },
                1 => {
                    &settings.footer_numbering
                },
                // The only option left is 2, but rust wants
                // a catch-all here.
                _ => {
                    &settings.body_numbering
                }
            } {
                NumberForAll => {
                    line_filter = pass_all;
                },
                NumberForNonEmpty => {
                    line_filter = pass_nonempty;
                },
                NumberForNone => {
                    line_filter = pass_none;
                }
                NumberForRegularExpression(ref re) => {
                    line_filter = pass_regex;
                    regex_filter = re;
                }
            }
            continue;
        }
        // From this point on we format and print a "regular" line.
        if line == "" {
            // The line is empty, which means that we have to care
            // about the --join-blank-lines parameter.
            empty_line_count += 1;
        } else {
            // This saves us from having to check for an empty string
            // in the next selector.
            empty_line_count = 0;
        }
        if !line_filter(line, regex_filter)
            || ( empty_line_count > 0 && empty_line_count < settings.join_blank_lines) {
            // No number is printed for this line. Either we did not
            // want to print one in the first place, or it is a blank
            // line but we are still collecting more blank lines via
            // the option --join-blank-lines.
            println!("{}", line);
            continue;
        }
        // If we make it here, then either we are printing a non-empty
        // line or assigning a line number to an empty line. Either
        // way, start counting empties from zero once more.
        empty_line_count = 0;
        // A line number is to be printed.
        let mut w: uint = 0;
        if settings.number_width > line_no_width {
            w = settings.number_width - line_no_width;
        }
        let fill = String::from_char(w, fill_char);
        match settings.number_format {
            Left => {
                println!("{1}{0}{2}{3}", fill, line_no, settings.number_separator, line)
            },
            _ => {
                println!("{0}{1}{2}{3}", fill, line_no, settings.number_separator, line)
            }
        }
        // Now update the variables for the (potential) next
        // line.
        line_no += settings.line_increment;
        while line_no >= line_no_threshold {
            // The line number just got longer.
            line_no_threshold *= 10;
            line_no_width += 1;
        }

    }
}

fn pass_regex(line: &str, re: &regex::Regex) -> bool {
    re.is_match(line)
}

fn pass_nonempty(line: &str, _: &regex::Regex) -> bool {
    line.len() > 0
}

fn pass_none(_: &str, _: &regex::Regex) -> bool {
    false
}

fn pass_all(_: &str, _: &regex::Regex) -> bool {
    true
}

fn print_usage(opts: &[OptGroup]) {
    println!("{:s}", usage(USAGE, opts));
}

fn version () {
    println!("{} version 1.0.0", NAME);
}
<commit_msg>std::bool::to_bit was removed<commit_after>#![crate_id(name="nl", vers="1.0.0", author="Tobias Schottdorf")]
#![feature(macro_rules)]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Tobias Bohumir Schottdorf <tobias.schottdorf@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */

#![feature(phase)]
#[phase(plugin)]
extern crate regex_macros;
extern crate regex;
extern crate getopts;

use std::os;
use std::io::{stdin};
use std::io::BufferedReader;
use std::io::fs::File;
use std::path::Path;
use getopts::{optopt, optflag, getopts, usage, OptGroup};

#[path="../common/util.rs"]
mod util;
mod helper;

static NAME: &'static str = "nl";
static USAGE: &'static str = "nl [OPTION]... [FILE]...";
// A regular expression matching everything.
static REGEX_DUMMY: &'static regex::Regex = &regex!(r".?");

// Settings store options used by nl to produce its output.
struct Settings {
    // The variables corresponding to the options -h, -b, and -f.
    header_numbering: NumberingStyle,
    body_numbering: NumberingStyle,
    footer_numbering: NumberingStyle,
    // The variable corresponding to -d
    section_delimiter: [char, ..2],
    // The variables corresponding to the options -v, -i, -l, -w.
    starting_line_number: u64,
    line_increment: u64,
    join_blank_lines: u64,
    number_width: uint, // Used with String::from_char, hence uint.
    // The format of the number and the (default value for)
    // renumbering each page.
    number_format: NumberFormat,
    renumber: bool,
    // The string appended to each line number output.
    number_separator: String
}

// NumberingStyle stores which lines are to be numberd.
// The possible options are:
// 1. Number all lines
// 2. Number only nonempty lines
// 3. Don't number any lines at all
// 4. Number all lines that match a basic regular expression.
enum NumberingStyle {
    NumberForAll,
    NumberForNonEmpty,
    NumberForNone,
    NumberForRegularExpression(regex::Regex)
}

// NumberFormat specifies how line numbers are output within their allocated
// space. They are justified to the left or right, in the latter case with
// the option of having all unused space to its left turned into leading zeroes.
enum NumberFormat {
    Left,
    Right,
    RightZero,
}

#[allow(dead_code)]
fn main () {
  os::set_exit_status(uumain(os::args()));
}

pub fn uumain(args: Vec<String>) -> int {
    let possible_options = [
        optopt("b", "body-numbering", "use STYLE for numbering body lines", "STYLE"),
        optopt("d", "section-delimiter", "use CC for separating logical pages", "CC"),
        optopt("f", "footer-numbering", "use STYLE for numbering footer lines", "STYLE"),
        optopt("h", "header-numbering", "use STYLE for numbering header lines", "STYLE"),
        optopt("i", "line-increment", "line number increment at each line", ""),
        optopt("l", "join-blank-lines", "group of NUMBER empty lines counted as one", "NUMBER"),
        optopt("n", "number-format", "insert line numbers according to FORMAT", "FORMAT"),
        optflag("p", "no-renumber", "do not reset line numbers at logical pages"),
        optopt("s", "number-separator", "add STRING after (possible) line number", "STRING"),
        optopt("v", "starting-line-number", "first line number on each logical page", "NUMBER"),
        optopt("w", "number-width", "use NUMBER columns for line numbers", "NUMBER"),
        optflag("", "help", "display this help and exit"),
        optflag("V", "version", "version"),
    ];

    // A mutable settings object, initialized with the defaults.
    let mut settings = Settings {
        header_numbering: NumberForNone,
        body_numbering: NumberForAll,
        footer_numbering: NumberForNone,
        section_delimiter: ['\\', ':'],
        starting_line_number: 1,
        line_increment: 1,
        join_blank_lines: 1,
        number_width: 6,
        number_format: Right,
        renumber: true,
        number_separator: String::from_str("\t"),
    };

    let given_options = match getopts(args.tail(), possible_options) {
        Ok (m) => { m }
        Err(f) => {
            show_error!("{}", f);
            print_usage(possible_options);
            return 1
        }
    };

    if given_options.opt_present("help") {
        print_usage(possible_options);
        return 0;
    }
    if given_options.opt_present("version") { version(); return 0; }

    // Update the settings from the command line options, and terminate the
    // program if some options could not successfully be parsed.
    let parse_errors = helper::parse_options(&mut settings, &given_options);
    if parse_errors.len() > 0 {
        show_error!("Invalid arguments supplied.");
        for message in parse_errors.iter() {
            println!("{}", message.as_slice());
        }
        return 1;
    }

    let files = given_options.free;
    let mut read_stdin = files.is_empty();

    for file in files.iter() {
        if file.as_slice() == "-" {
            // If both file names and '-' are specified, we choose to treat first all
            // regular files, and then read from stdin last.
            read_stdin = true;
            continue
        }
        let path = Path::new(file.as_slice());
        let reader = File::open(&path).unwrap();
        let mut buffer = BufferedReader::new(reader);
        nl(&mut buffer, &settings);
    }

    if read_stdin {
        let mut buffer = BufferedReader::new(stdin());
        nl(&mut buffer, &settings);
    }
    0
}

// nl implements the main functionality for an individual buffer.
fn nl<T: Reader> (reader: &mut BufferedReader<T>, settings: &Settings) {
    let mut line_no = settings.starting_line_number;
    // The current line number's width as a string. Using to_str is inefficient
    // but since we only do it once, it should not hurt.
    let mut line_no_width = line_no.to_str().len();
    let line_no_width_initial = line_no_width;
    // Stores the smallest integer with one more digit than line_no, so that
    // when line_no >= line_no_threshold, we need to use one more digit.
    let mut line_no_threshold = std::num::pow(10u64, line_no_width);
    let mut empty_line_count: u64 = 0;
    let fill_char = match settings.number_format {
        RightZero => '0',
        _ => ' '
    };
    // Initially, we use the body's line counting settings
    let mut regex_filter = match settings.body_numbering {
        NumberForRegularExpression(ref re) => re,
        _ => REGEX_DUMMY,
    };
    let mut line_filter = pass_regex;
    for mut l in reader.lines().map(|r| r.unwrap()) {
        // Sanitize the string. We want to print the newline ourselves.
        if l.as_slice().chars().rev().next().unwrap() == '\n' {
            l.pop_char();
        }
        // Next we iterate through the individual chars to see if this
        // is one of the special lines starting a new "section" in the
        // document.
        let line = l.as_slice();
        let mut odd = false;
        // matched_group counts how many copies of section_delimiter
        // this string consists of (0 if there's anything else)
        let mut matched_groups = 0u8;
        for c in line.chars() {
            // If this is a newline character, the loop should end.
            if c == '\n' {
                break;
            }
            // If we have already seen three groups (corresponding to
            // a header) or the current char does not form part of
            // a new group, then this line is not a segment indicator.
            if matched_groups >= 3
                || settings.section_delimiter[if odd { 1 } else { 0 }] != c {
                matched_groups = 0;
                break;
            }
            if odd {
                // We have seen a new group and count it.
                matched_groups += 1;
            }
            odd = !odd;
        }

        // See how many groups we matched. That will tell us if this is
        // a line starting a new segment, and the number of groups
        // indicates what type of segment.
        if matched_groups > 0 {
            // The current line is a section delimiter, so we output
            // a blank line.
            println!("");
            // However the line does not count as a blank line, so we
            // reset the counter used for --join-blank-lines.
            empty_line_count = 0;
            match *match matched_groups {
                3 => {
                    // This is a header, so we may need to reset the
                    // line number and the line width
                    if settings.renumber {
                        line_no = settings.starting_line_number;
                        line_no_width = line_no_width_initial;
                        line_no_threshold = std::num::pow(10u64, line_no_width);
                    }
                    &settings.header_numbering
                },
                1 => {
                    &settings.footer_numbering
                },
                // The only option left is 2, but rust wants
                // a catch-all here.
                _ => {
                    &settings.body_numbering
                }
            } {
                NumberForAll => {
                    line_filter = pass_all;
                },
                NumberForNonEmpty => {
                    line_filter = pass_nonempty;
                },
                NumberForNone => {
                    line_filter = pass_none;
                }
                NumberForRegularExpression(ref re) => {
                    line_filter = pass_regex;
                    regex_filter = re;
                }
            }
            continue;
        }
        // From this point on we format and print a "regular" line.
        if line == "" {
            // The line is empty, which means that we have to care
            // about the --join-blank-lines parameter.
            empty_line_count += 1;
        } else {
            // This saves us from having to check for an empty string
            // in the next selector.
            empty_line_count = 0;
        }
        if !line_filter(line, regex_filter)
            || ( empty_line_count > 0 && empty_line_count < settings.join_blank_lines) {
            // No number is printed for this line. Either we did not
            // want to print one in the first place, or it is a blank
            // line but we are still collecting more blank lines via
            // the option --join-blank-lines.
            println!("{}", line);
            continue;
        }
        // If we make it here, then either we are printing a non-empty
        // line or assigning a line number to an empty line. Either
        // way, start counting empties from zero once more.
        empty_line_count = 0;
        // A line number is to be printed.
        let mut w: uint = 0;
        if settings.number_width > line_no_width {
            w = settings.number_width - line_no_width;
        }
        let fill = String::from_char(w, fill_char);
        match settings.number_format {
            Left => {
                println!("{1}{0}{2}{3}", fill, line_no, settings.number_separator, line)
            },
            _ => {
                println!("{0}{1}{2}{3}", fill, line_no, settings.number_separator, line)
            }
        }
        // Now update the variables for the (potential) next
        // line.
        line_no += settings.line_increment;
        while line_no >= line_no_threshold {
            // The line number just got longer.
            line_no_threshold *= 10;
            line_no_width += 1;
        }

    }
}

fn pass_regex(line: &str, re: &regex::Regex) -> bool {
    re.is_match(line)
}

fn pass_nonempty(line: &str, _: &regex::Regex) -> bool {
    line.len() > 0
}

fn pass_none(_: &str, _: &regex::Regex) -> bool {
    false
}

fn pass_all(_: &str, _: &regex::Regex) -> bool {
    true
}

fn print_usage(opts: &[OptGroup]) {
    println!("{:s}", usage(USAGE, opts));
}

fn version () {
    println!("{} version 1.0.0", NAME);
}
<|endoftext|>