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

#![allow(dead_code, unused_imports)]

use client::connect_with_retry;
use commands::{
    DEFAULT_PORT,
    request_stats,
    which,
};
use env_logger;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::io::{
    self,
    Write,
};
use std::path::Path;
use std::process::{
    Command,
    Output,
    Stdio,
};
use tempdir::TempDir;
use test::utils::*;

#[cfg(unix)]
const COMPILER : &'static str = "gcc";

#[cfg(target_env="msvc")]
const COMPILER : &'static str = "cl.exe";

fn do_run<T: AsRef<OsStr>>(exe: &Path, args: &[T]) -> Output {
    let mut cmd = Command::new(exe);
    cmd.args(args)
        .stdout(Stdio::piped())
        .stderr(Stdio::piped());
    trace!("do_run: {:?}", cmd);
    cmd.spawn()
        .unwrap_or_else(|e| { panic!("failed to execute child: {}", e) })
        .wait_with_output()
        .unwrap()
}

fn run<T: AsRef<OsStr>>(exe: &Path, args: &[T]) -> bool {
    let output = do_run(exe, args);
    if output.status.success() {
        true
    } else {
        let va = args.iter().map(|a| a.as_ref().to_str().unwrap()).collect::<Vec<_>>();
        println!("Process `{:?} {}` failed:", exe, va.join(" "));
        print!("stdout: `");
        io::stdout().write(&output.stdout).unwrap();
        println!("`");
        print!("stderr: `");
        io::stdout().write(&output.stderr).unwrap();
        println!("`");
        false
    }
}

fn compile_cmdline(compiler: &str, exe: &str, input: &Path, output: &Path) -> Vec<String> {
    match compiler {
        "gcc" => vec!(exe.to_owned(), "-c".to_owned(), input.to_str().unwrap().to_owned(), "-o".to_owned(), output.to_str().unwrap().to_owned()),
        "cl.exe" => vec!(exe.to_owned(), "-c".to_owned(), input.to_str().unwrap().to_owned(), format!("-Fo{}", output.to_str().unwrap())),
        _ => panic!("Unsupported compiler: {}", compiler),
    }
}

#[allow(dead_code)]
fn run_sccache_command_test(sccache: &Path, compiler: &str, exe: &str, tempdir: &Path) {
    // Ensure there's no existing sccache server running.
    trace!("stop server");
    do_run(sccache, &["--stop-server"]);
    // Start a server.
    trace!("start server");
    // Don't run this with run() because on Windows `wait_with_output`
    // will hang because the internal server process is not detached.
    assert!(Command::new(sccache)
            .arg("--start-server")
            .status()
            .unwrap()
            .success());
    // Compile a source file.
    let source_file = Path::new(file!()).parent().unwrap().join("test.c");
    let out_file = tempdir.join("test.o");
    trace!("compile");
    assert_eq!(true, run(sccache, &compile_cmdline(compiler, exe, &source_file, &out_file)));
    trace!("connect");
    let conn = connect_with_retry(DEFAULT_PORT).unwrap();
    trace!("request stats");
    let stats = cache_stats_map(request_stats(conn).unwrap());
    assert_eq!(&CacheStat::Count(1), stats.get("Compile requests").unwrap());
    assert_eq!(&CacheStat::Count(1), stats.get("Compile requests executed").unwrap());
    assert_eq!(&CacheStat::Count(0), stats.get("Cache hits").unwrap());
    assert_eq!(&CacheStat::Count(1), stats.get("Cache misses").unwrap());
    trace!("compile");
    assert_eq!(true, run(sccache, &compile_cmdline(compiler, exe, &source_file, &out_file)));
    trace!("connect");
    let conn = connect_with_retry(DEFAULT_PORT).unwrap();
    trace!("request stats");
    let stats = cache_stats_map(request_stats(conn).unwrap());
    assert_eq!(&CacheStat::Count(2), stats.get("Compile requests").unwrap());
    assert_eq!(&CacheStat::Count(2), stats.get("Compile requests executed").unwrap());
    assert_eq!(&CacheStat::Count(1), stats.get("Cache hits").unwrap());
    assert_eq!(&CacheStat::Count(1), stats.get("Cache misses").unwrap());
    trace!("stop server");
    assert_eq!(true, run(sccache, &["--stop-server"]));
}

// Don't run this on OS X until we actually support clang.
#[test]
#[cfg(all(not(target_os="macos"), any(unix, target_env="msvc")))]
fn test_sccache_command() {
    match env_logger::init() {
        Ok(_) => {},
        Err(_) => {},
    }
    let tempdir = TempDir::new("sccache_system_test").unwrap();
    let sccache = env::current_exe().unwrap().parent().unwrap().join("sccache");
    match fs::metadata(&sccache) {
        Ok(_) => {},
        Err(_) => panic!("Error: sccache binary not found at `{:?}. Do you need to run `cargo build`?", sccache),
    }
    match which(COMPILER, env::var("PATH").ok(), &env::current_dir().unwrap()) {
        Some(c) => run_sccache_command_test(&sccache, COMPILER, &c, tempdir.path()),
        None => {
            assert!(true, "No `{}` compiler found, skipping test", COMPILER);
        }
    }
}
<commit_msg>fix sccache binary check in system test on windows<commit_after>// Copyright 2016 Mozilla Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![allow(dead_code, unused_imports)]

use client::connect_with_retry;
use commands::{
    DEFAULT_PORT,
    request_stats,
    which,
};
use env_logger;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::io::{
    self,
    Write,
};
use std::path::Path;
use std::process::{
    Command,
    Output,
    Stdio,
};
use tempdir::TempDir;
use test::utils::*;

#[cfg(unix)]
const COMPILER : &'static str = "gcc";

#[cfg(target_env="msvc")]
const COMPILER : &'static str = "cl.exe";

fn do_run<T: AsRef<OsStr>>(exe: &Path, args: &[T]) -> Output {
    let mut cmd = Command::new(exe);
    cmd.args(args)
        .stdout(Stdio::piped())
        .stderr(Stdio::piped());
    trace!("do_run: {:?}", cmd);
    cmd.spawn()
        .unwrap_or_else(|e| { panic!("failed to execute child: {}", e) })
        .wait_with_output()
        .unwrap()
}

fn run<T: AsRef<OsStr>>(exe: &Path, args: &[T]) -> bool {
    let output = do_run(exe, args);
    if output.status.success() {
        true
    } else {
        let va = args.iter().map(|a| a.as_ref().to_str().unwrap()).collect::<Vec<_>>();
        println!("Process `{:?} {}` failed:", exe, va.join(" "));
        print!("stdout: `");
        io::stdout().write(&output.stdout).unwrap();
        println!("`");
        print!("stderr: `");
        io::stdout().write(&output.stderr).unwrap();
        println!("`");
        false
    }
}

fn compile_cmdline(compiler: &str, exe: &str, input: &Path, output: &Path) -> Vec<String> {
    match compiler {
        "gcc" => vec!(exe.to_owned(), "-c".to_owned(), input.to_str().unwrap().to_owned(), "-o".to_owned(), output.to_str().unwrap().to_owned()),
        "cl.exe" => vec!(exe.to_owned(), "-c".to_owned(), input.to_str().unwrap().to_owned(), format!("-Fo{}", output.to_str().unwrap())),
        _ => panic!("Unsupported compiler: {}", compiler),
    }
}

#[allow(dead_code)]
fn run_sccache_command_test(sccache: &Path, compiler: &str, exe: &str, tempdir: &Path) {
    // Ensure there's no existing sccache server running.
    trace!("stop server");
    do_run(sccache, &["--stop-server"]);
    // Start a server.
    trace!("start server");
    // Don't run this with run() because on Windows `wait_with_output`
    // will hang because the internal server process is not detached.
    assert!(Command::new(sccache)
            .arg("--start-server")
            .status()
            .unwrap()
            .success());
    // Compile a source file.
    let source_file = Path::new(file!()).parent().unwrap().join("test.c");
    let out_file = tempdir.join("test.o");
    trace!("compile");
    assert_eq!(true, run(sccache, &compile_cmdline(compiler, exe, &source_file, &out_file)));
    trace!("connect");
    let conn = connect_with_retry(DEFAULT_PORT).unwrap();
    trace!("request stats");
    let stats = cache_stats_map(request_stats(conn).unwrap());
    assert_eq!(&CacheStat::Count(1), stats.get("Compile requests").unwrap());
    assert_eq!(&CacheStat::Count(1), stats.get("Compile requests executed").unwrap());
    assert_eq!(&CacheStat::Count(0), stats.get("Cache hits").unwrap());
    assert_eq!(&CacheStat::Count(1), stats.get("Cache misses").unwrap());
    trace!("compile");
    assert_eq!(true, run(sccache, &compile_cmdline(compiler, exe, &source_file, &out_file)));
    trace!("connect");
    let conn = connect_with_retry(DEFAULT_PORT).unwrap();
    trace!("request stats");
    let stats = cache_stats_map(request_stats(conn).unwrap());
    assert_eq!(&CacheStat::Count(2), stats.get("Compile requests").unwrap());
    assert_eq!(&CacheStat::Count(2), stats.get("Compile requests executed").unwrap());
    assert_eq!(&CacheStat::Count(1), stats.get("Cache hits").unwrap());
    assert_eq!(&CacheStat::Count(1), stats.get("Cache misses").unwrap());
    trace!("stop server");
    assert_eq!(true, run(sccache, &["--stop-server"]));
}

// Don't run this on OS X until we actually support clang.
#[test]
#[cfg(all(not(target_os="macos"), any(unix, target_env="msvc")))]
fn test_sccache_command() {
    match env_logger::init() {
        Ok(_) => {},
        Err(_) => {},
    }
    let tempdir = TempDir::new("sccache_system_test").unwrap();
    let sccache = env::current_exe().unwrap().parent().unwrap().join("sccache").with_extension(env::consts::EXE_EXTENSION);
    match fs::metadata(&sccache) {
        Ok(_) => {},
        Err(_) => panic!("Error: sccache binary not found at `{:?}. Do you need to run `cargo build`?", sccache),
    }
    match which(COMPILER, env::var("PATH").ok(), &env::current_dir().unwrap()) {
        Some(c) => run_sccache_command_test(&sccache, COMPILER, &c, tempdir.path()),
        None => {
            assert!(true, "No `{}` compiler found, skipping test", COMPILER);
        }
    }
}
<|endoftext|>


<commit_before><<<<<<< HEAD
use opengl_graphics::GlGraphics;

=======
>>>>>>> 78a5df5b7a5356f4cc2b00e7092da8234d6457d2
/// A view
pub trait View {
  /// Render the view.
  fn render(&self, gl: &GlGraphics);

  /// Call this on start of view
  fn start(&mut self) {}
  /// Call this on end of view
  fn end(&mut self) {}
}

<commit_msg>Fix unmerged stuff<commit_after>use opengl_graphics::GlGraphics;

/// A view
pub trait View {
  /// Render the view.
  fn render(&self, gl: &GlGraphics);

  /// Call this on start of view
  fn start(&mut self) {}
  /// Call this on end of view
  fn end(&mut self) {}
}

<|endoftext|>


<commit_before>use grammar::*;

fn visit(statement: Statement) -> Statement {
    match statement.clone() {
        Statement::VariableDeclarationStatement{kind: kind, declarations: declarations } => {
            if kind == VariableDeclarationKind::Const || kind == VariableDeclarationKind::Let {
                Statement::VariableDeclarationStatement {
                    kind: VariableDeclarationKind::Var,
                    declarations: declarations
                }
            } else {
                statement
            }
        },
        _ => statement
    }
}

pub fn traverse(program: Program) -> Program {
    let mut new_statements = Vec::new();

    for statement in program.body {
        new_statements.push(visit(statement));
    }

    Program {
        body: new_statements
    }
}

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

    #[test]
    fn transform_const_assignment() {
        let input_program = parse("const foo = 42;".into());
        let output_program = traverse(input_program);
        let statement = output_program.body.first().unwrap().clone();
        let success = match statement {
            Statement::VariableDeclarationStatement{kind: kind, declarations: _declarations } => {
                kind == VariableDeclarationKind::Var
            },
            _ => false
        };
        assert!(success);
    }

    #[test]
    fn transform_simple_let_assignment() {
        let input_program = parse("let foo = 42;".into());
        let output_program = traverse(input_program);
        let statement = output_program.body.first().unwrap().clone();
        let success = match statement {
            Statement::VariableDeclarationStatement{kind: kind, declarations: _declarations } => {
                kind == VariableDeclarationKind::Var
            },
            _ => false
        };
        assert!(success);
    }
}
<commit_msg>Visit tree generated by parser to make replacements<commit_after>use grammar::*;

fn visit(statement: Statement) -> Statement {
    match statement.clone() {
        Statement::IfStatement{test: t, consequent: consequent, alternate: alternate} => {
            Statement::IfStatement{
                test: t,
                consequent: Box::new(visit(*consequent)),
                alternate: alternate
            }
        },
        Statement::BlockStatement{ body: body } => {
            let mut new_body = Vec::new();
            for statement in body {
                new_body.push(visit(statement));
            }
            Statement::BlockStatement {
                body: new_body
            }
        },
        Statement::VariableDeclarationStatement{kind: kind, declarations: declarations } => {
            if kind == VariableDeclarationKind::Const || kind == VariableDeclarationKind::Let {
                Statement::VariableDeclarationStatement {
                    kind: VariableDeclarationKind::Var,
                    declarations: declarations
                }
            } else {
                statement
            }
        },
        _ => statement
    }
}

pub fn traverse(program: Program) -> Program {
    let mut new_statements = Vec::new();

    for statement in program.body {
        new_statements.push(visit(statement));
    }

    Program {
        body: new_statements
    }
}

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

    #[test]
    fn transform_const_assignment() {
        let input_program = parse("const foo = 42;".into());
        let output_program = traverse(input_program);
        let statement = output_program.body.first().unwrap().clone();
        let success = match statement {
            Statement::VariableDeclarationStatement{kind: kind, declarations: _declarations } => {
                kind == VariableDeclarationKind::Var
            },
            _ => false
        };
        assert!(success);
    }

    #[test]
    fn transform_simple_let_assignment() {
        let input_program = parse("let foo = 42;".into());
        let output_program = traverse(input_program);
        let statement = output_program.body.first().unwrap().clone();
        let success = match statement {
            Statement::VariableDeclarationStatement{kind: kind, declarations: _declarations } => {
                kind == VariableDeclarationKind::Var
            },
            _ => false
        };
        assert!(success);
    }

    #[test]
    fn transform_let_inside_of_if() {
        let input_program = "
        if(true) {
            const pi = 3.14;
        }
        ";
        let output_program = traverse(parse(input_program.into()));
        let statement = output_program.body.first().unwrap().clone();
        match statement {
            Statement::IfStatement{test: _exp, consequent: stmt, alternate: _stmt} => {
                match *stmt.clone() {
                    Statement::BlockStatement{body: body} => {
                        let first_body_stmt = body.first().unwrap().clone();
                        match first_body_stmt {
                            Statement::VariableDeclarationStatement{kind: kind, declarations: _declarations } => {
                                assert_eq!(kind, VariableDeclarationKind::Var);
                            },
                            _ => assert!(false,
                                    format!("Expected Variable Declaration, Received {:?}", first_body_stmt))
                        }
                    },
                    _ => assert!(false,
                                 format!("Expected Block statement, Got {:?}", *stmt))
                }
            },
            _ => assert!(false, "received invalid statement. Expected if")
        }
    }
}
<|endoftext|>


<commit_before>use std::{ptr};
use super::ffi;

pub struct MonitorID(uint);

pub fn get_available_monitors() -> Vec<MonitorID> {
    let nb_monitors = unsafe {
        let display = ffi::XOpenDisplay(ptr::null());
        if display.is_null() {
            fail!("get_available_monitors failed");
        }
        let nb_monitors = ffi::XScreenCount(display);
        ffi::XCloseDisplay(display);
        nb_monitors
    };

    let mut vec = Vec::new();
    vec.grow_fn(nb_monitors as uint, |i| MonitorID(i));
    vec
}

pub fn get_primary_monitor() -> MonitorID {
    let primary_monitor = unsafe {
        let display = ffi::XOpenDisplay(ptr::null());
        if display.is_null() {
            fail!("get_available_monitors failed");
        }
        let primary_monitor = ffi::XDefaultScreen(display);
        ffi::XCloseDisplay(display);
        primary_monitor
    };

    MonitorID(primary_monitor as uint)
}

impl MonitorID {
    pub fn get_name(&self) -> Option<String> {
        Some("<Unknown>".to_string())
    }

    pub fn get_dimensions(&self) -> (uint, uint) {
        let dimensions = unsafe {
            let display = ffi::XOpenDisplay(ptr::null());
            let MonitorID(screen_num) = *self;
            let screen = ffi::XScreenOfDisplay(display, screen_num as i32);
            let width = ffi::XWidthOfScreen(screen);
            let height = ffi::XHeightOfScreen(screen);
            (width as uint, height as uint)
        };

        dimensions
    }
}

<commit_msg>Added output to get_name for x11 monitors<commit_after>use std::{ptr};
use super::ffi;

pub struct MonitorID(uint);

pub fn get_available_monitors() -> Vec<MonitorID> {
    let nb_monitors = unsafe {
        let display = ffi::XOpenDisplay(ptr::null());
        if display.is_null() {
            fail!("get_available_monitors failed");
        }
        let nb_monitors = ffi::XScreenCount(display);
        ffi::XCloseDisplay(display);
        nb_monitors
    };

    let mut vec = Vec::new();
    vec.grow_fn(nb_monitors as uint, |i| MonitorID(i));
    vec
}

pub fn get_primary_monitor() -> MonitorID {
    let primary_monitor = unsafe {
        let display = ffi::XOpenDisplay(ptr::null());
        if display.is_null() {
            fail!("get_available_monitors failed");
        }
        let primary_monitor = ffi::XDefaultScreen(display);
        ffi::XCloseDisplay(display);
        primary_monitor
    };

    MonitorID(primary_monitor as uint)
}

impl MonitorID {
    pub fn get_name(&self) -> Option<String> {
        let MonitorID(screen_num) = *self;
        Some(format!("Monitor #{}", screen_num))
    }

    pub fn get_dimensions(&self) -> (uint, uint) {
        let dimensions = unsafe {
            let display = ffi::XOpenDisplay(ptr::null());
            let MonitorID(screen_num) = *self;
            let screen = ffi::XScreenOfDisplay(display, screen_num as i32);
            let width = ffi::XWidthOfScreen(screen);
            let height = ffi::XHeightOfScreen(screen);
            (width as uint, height as uint)
        };

        dimensions
    }
}

<|endoftext|>


<commit_before>use std::num::NonZeroU8;

use crate::Error;

pub fn validate(s: &str) -> Result<NonZeroU8, Error> {
    let colon_idx = NonZeroU8::new(s.find(':').ok_or(Error::MissingDelimiter)? as u8)
        .ok_or(Error::InvalidKeyAlgorithm)?;

    validate_version(&s[colon_idx.get() as usize + 1..])?;

    Ok(colon_idx)
}

fn validate_version(version: &str) -> Result<(), Error> {
    if version.is_empty() {
        return Err(Error::EmptyRoomVersionId);
    } else if !version.chars().all(|c| c.is_alphanumeric() || c == '_') {
        return Err(Error::InvalidCharacters);
    }

    Ok(())
}
<commit_msg>identifiers-validation: Don't validate key ID version with feature = "compat"<commit_after>use std::num::NonZeroU8;

use crate::Error;

pub fn validate(s: &str) -> Result<NonZeroU8, Error> {
    let colon_idx = NonZeroU8::new(s.find(':').ok_or(Error::MissingDelimiter)? as u8)
        .ok_or(Error::InvalidKeyAlgorithm)?;

    #[cfg(not(feature = "compat"))]
    validate_version(&s[colon_idx.get() as usize + 1..])?;

    Ok(colon_idx)
}

#[cfg(not(feature = "compat"))]
fn validate_version(version: &str) -> Result<(), Error> {
    if version.is_empty() {
        return Err(Error::EmptyRoomVersionId);
    } else if !version.chars().all(|c| c.is_alphanumeric() || c == '_') {
        return Err(Error::InvalidCharacters);
    }

    Ok(())
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate askama;

use askama::Template;

#[derive(Template)]
#[template(path = "filters.html")]
struct TestTemplate {
    strvar: String,
}

#[test]
fn filter_escape() {
    let s = TestTemplate {
        strvar: "my <html> is unsafe & should be escaped".to_string(),
    };
    assert_eq!(s.render().unwrap(),
               "my <html> is unsafe & should be escaped");
}

#[derive(Template)]
#[template(path = "format.html")]
struct FormatTemplate<'a> {
    var: &'a str,
}

#[test]
fn filter_format() {
    let t = FormatTemplate { var: "formatted" };
    assert_eq!(t.render().unwrap(), "\"formatted\"");
}
<commit_msg>Add test case for user-defined filters<commit_after>#[macro_use]
extern crate askama;

use askama::Template;

#[derive(Template)]
#[template(path = "filters.html")]
struct TestTemplate {
    strvar: String,
}

#[test]
fn filter_escape() {
    let s = TestTemplate {
        strvar: "my <html> is unsafe & should be escaped".to_string(),
    };
    assert_eq!(s.render().unwrap(),
               "my <html> is unsafe & should be escaped");
}

#[derive(Template)]
#[template(path = "format.html")]
struct FormatTemplate<'a> {
    var: &'a str,
}

#[test]
fn filter_format() {
    let t = FormatTemplate { var: "formatted" };
    assert_eq!(t.render().unwrap(), "\"formatted\"");
}

#[derive(Template)]
#[template(source = "{{ s|myfilter }}")]
struct MyFilterTemplate<'a> {
    s: &'a str,
}

mod filters {
    pub fn myfilter(s: &str) -> ::askama::Result<String> {
        Ok(s.replace("oo", "aa").to_string())
    }
}

#[test]
fn test_my_filter() {
    let t = MyFilterTemplate { s: "foo" };
    assert_eq!(t.render().unwrap(), "faa");
}
<|endoftext|>


<commit_before>#![cfg(feature = "full")]

#[macro_use]
extern crate quote;
extern crate syn;
extern crate syntex_pos;
extern crate syntex_syntax;
extern crate walkdir;

use syntex_pos::Span;
use syntex_syntax::ast;
use syntex_syntax::parse::{self, ParseSess, PResult};
use walkdir::{DirEntry, WalkDir, WalkDirIterator};

use std::fs::File;
use std::io::{self, Read, Write};
use std::panic;
use std::time::Instant;

macro_rules! errorf {
    ($($tt:tt)*) => {
        write!(io::stderr(), $($tt)*).unwrap();
    };
}

fn filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }
    let path = path.to_string_lossy();
    // TODO assert that parsing fails on the parse-fail cases
    if path.starts_with("tests/rust/src/test/parse-fail") ||
       path.starts_with("tests/rust/src/test/compile-fail") {
        return false;
    }
    match path.as_ref() {
        // TODO better support for attributes
        "tests/rust/src/test/pretty/stmt_expr_attributes.rs" |
        // not actually a test case
        "tests/rust/src/test/run-pass/auxiliary/macro-include-items-expr.rs" |
        // TODO better support for attributes
        "tests/rust/src/test/run-pass/cfg_stmt_expr.rs" |
        // TODO weird glob import
        "tests/rust/src/test/run-pass/import-glob-crate.rs" |
        // TODO better support for attributes
        "tests/rust/src/test/run-pass/inner-attrs-on-impl.rs" |
        // TODO better support for attributes
        "tests/rust/src/test/run-pass/item-attributes.rs" |
        // TODO precedence issue with binop vs poly trait ref
        "tests/rust/src/test/run-pass/try-macro.rs" => false,
        _ => true,
    }
}

#[test]
fn test_round_trip() {
    let mut failed = 0;

    let walk = WalkDir::new("tests/rust").sort_by(|a, b| a.cmp(b));
    for entry in walk.into_iter().filter_entry(filter) {
        let entry = entry.unwrap();

        let path = entry.path();
        if path.is_dir() {
            continue;
        }
        errorf!("=== {}: ", path.display());

        let mut file = File::open(path).unwrap();
        let mut content = String::new();
        file.read_to_string(&mut content).unwrap();

        let start = Instant::now();
        let (krate, elapsed) = match syn::parse_crate(&content) {
            Ok(krate) => (krate, start.elapsed()),
            Err(msg) => {
                errorf!("syn failed to parse\n{}\n", msg);
                failed += 1;
                continue;
            }
        };
        let back = quote!(#krate).to_string();

        let equal = panic::catch_unwind(|| {
            let sess = ParseSess::new();
            let before = match syntex_parse(content, &sess) {
                Ok(before) => before,
                Err(mut diagnostic) => {
                    diagnostic.cancel();
                    if diagnostic.message().starts_with("file not found for module") {
                        errorf!("ignore\n");
                        return true;
                    } else {
                        errorf!("FAIL: {}\n", diagnostic.message());
                        return false;
                    }
                }
            };
            let after = match syntex_parse(back, &sess) {
                Ok(after) => after,
                Err(mut diagnostic) => {
                    errorf!("syntex failed to parse");
                    diagnostic.emit();
                    return false;
                }
            };

            if before == after {
                errorf!("pass in {}ms\n",
                        elapsed.as_secs() * 1000 + elapsed.subsec_nanos() as u64 / 1_000_000);
                true
            } else {
                errorf!("FAIL\nbefore: {}\nafter: {}\n",
                        format!("{:?}", before).replace("\n", ""),
                        format!("{:?}", after).replace("\n", ""));
                false
            }
        });
        match equal {
            Err(_) => errorf!("ignoring syntex panic\n"),
            Ok(true) => {}
            Ok(false) => failed += 1,
        }
    }

    if failed > 0 {
        panic!("{} failures", failed);
    }
}

fn syntex_parse(content: String, sess: &ParseSess) -> PResult<ast::Crate> {
    let name = "test_round_trip".to_string();
    parse::parse_crate_from_source_str(name, content, sess).map(respan_crate)
}

fn respan_crate(krate: ast::Crate) -> ast::Crate {
    use std::rc::Rc;
    use syntex_syntax::ast::{Attribute, Expr, ExprKind, Field, FnDecl, FunctionRetTy, ImplItem,
                             ImplItemKind, ItemKind, Mac, MetaItem, MetaItemKind, MethodSig,
                             NestedMetaItem, NestedMetaItemKind, TraitItem, TraitItemKind, TyParam,
                             Visibility};
    use syntex_syntax::codemap::{self, Spanned};
    use syntex_syntax::fold::{self, Folder};
    use syntex_syntax::parse::token::{Lit, Token};
    use syntex_syntax::ptr::P;
    use syntex_syntax::symbol::Symbol;
    use syntex_syntax::tokenstream::{Delimited, SequenceRepetition, TokenTree};
    use syntex_syntax::util::move_map::MoveMap;
    use syntex_syntax::util::small_vector::SmallVector;

    struct Respanner;

    impl Respanner {
        fn fold_spanned<T>(&mut self, spanned: Spanned<T>) -> Spanned<T> {
            codemap::respan(self.new_span(spanned.span), spanned.node)
        }

        fn fold_lit(&mut self, l: Lit) -> Lit {
            // Give up on comparing literals inside of macros because there are
            // so many equivalent representations of the same literal; they are
            // tested elsewhere
            match l {
                Lit::Byte(_) => Lit::Byte(Symbol::intern("")),
                Lit::Char(_) => Lit::Char(Symbol::intern("")),
                Lit::Integer(_) => Lit::Integer(Symbol::intern("")),
                Lit::Float(_) => Lit::Float(Symbol::intern("")),
                Lit::Str_(_) => Lit::Str_(Symbol::intern("")),
                Lit::ByteStr(_) => Lit::ByteStr(Symbol::intern("")),
                _ => l,
            }
        }
    }

    impl Folder for Respanner {
        fn new_span(&mut self, _: Span) -> Span {
            syntex_pos::DUMMY_SP
        }

        fn fold_item_kind(&mut self, i: ItemKind) -> ItemKind {
            match i {
                ItemKind::Fn(decl, unsafety, constness, abi, generics, body) => {
                    let generics = self.fold_generics(generics);
                    let decl = self.fold_fn_decl(decl);
                    let body = self.fold_block(body);
                    // default fold_item_kind does not fold this span
                    let constness = self.fold_spanned(constness);
                    ItemKind::Fn(decl, unsafety, constness, abi, generics, body)
                }
                _ => fold::noop_fold_item_kind(i, self),
            }
        }

        fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
            e.map(|e| {
                let folded = fold::noop_fold_expr(e, self);
                Expr {
                    node: match folded.node {
                        ExprKind::Lit(l) => {
                            // default fold_expr does not fold lits
                            ExprKind::Lit(l.map(|l| self.fold_spanned(l)))
                        }
                        ExprKind::Binary(op, lhs, rhs) => {
                            // default fold_expr does not fold the op span
                            ExprKind::Binary(self.fold_spanned(op),
                                             self.fold_expr(lhs),
                                             self.fold_expr(rhs))
                        }
                        ExprKind::AssignOp(op, lhs, rhs) => {
                            // default fold_expr does not fold the op span
                            ExprKind::AssignOp(self.fold_spanned(op),
                                               self.fold_expr(lhs),
                                               self.fold_expr(rhs))
                        }
                        other => other,
                    },
                    ..folded
                }
            })
        }

        fn fold_ty_param(&mut self, tp: TyParam) -> TyParam {
            TyParam {
                // default fold_ty_param does not fold the span
                span: self.new_span(tp.span),
                ..fold::noop_fold_ty_param(tp, self)
            }
        }

        fn fold_fn_decl(&mut self, decl: P<FnDecl>) -> P<FnDecl> {
            decl.map(|FnDecl { inputs, output, variadic }| {
                FnDecl {
                    inputs: inputs.move_map(|x| self.fold_arg(x)),
                    output: match output {
                        FunctionRetTy::Ty(ty) => FunctionRetTy::Ty(self.fold_ty(ty)),
                        // default fold_fn_decl does not fold this span
                        FunctionRetTy::Default(span) => FunctionRetTy::Default(self.new_span(span)),
                    },
                    variadic: variadic,
                }
            })
        }

        fn fold_field(&mut self, field: Field) -> Field {
            Field {
                ident: codemap::respan(// default fold_field does not fold this span
                                       self.new_span(field.ident.span),
                                       self.fold_ident(field.ident.node)),
                expr: self.fold_expr(field.expr),
                span: self.new_span(field.span),
                is_shorthand: field.is_shorthand,
                attrs: ast::ThinVec::new(),
            }
        }

        fn fold_trait_item(&mut self, i: TraitItem) -> SmallVector<TraitItem> {
            let noop = fold::noop_fold_trait_item(i, self).expect_one("");
            SmallVector::one(TraitItem {
                                 node: match noop.node {
                                     TraitItemKind::Method(sig, body) => {
                        TraitItemKind::Method(MethodSig {
                                                  constness: self.fold_spanned(sig.constness),
                                                  ..sig
                                              },
                                              body)
                    }
                                     node => node,
                                 },
                                 ..noop
                             })
        }

        fn fold_impl_item(&mut self, i: ImplItem) -> SmallVector<ImplItem> {
            let noop = fold::noop_fold_impl_item(i, self).expect_one("");
            SmallVector::one(ImplItem {
                                 node: match noop.node {
                                     ImplItemKind::Method(sig, body) => {
                        ImplItemKind::Method(MethodSig {
                                                 constness: self.fold_spanned(sig.constness),
                                                 ..sig
                                             },
                                             body)
                    }
                                     node => node,
                                 },
                                 ..noop
                             })
        }

        fn fold_attribute(&mut self, mut at: Attribute) -> Option<Attribute> {
            at.id.0 = 0;
            fold::noop_fold_attribute(at, self)
        }

        fn fold_meta_item(&mut self, meta_item: MetaItem) -> MetaItem {
            let MetaItem { name, node, span } = meta_item;
            MetaItem {
                name: name,
                node: match node {
                    MetaItemKind::Word => MetaItemKind::Word,
                    MetaItemKind::List(nested) => {
                        MetaItemKind::List(nested.move_map(|e| self.fold_meta_list_item(e)))
                    }
                    // default fold_meta_item does not fold the value span
                    MetaItemKind::NameValue(lit) => MetaItemKind::NameValue(self.fold_spanned(lit)),
                },
                span: self.new_span(span),
            }
        }

        fn fold_meta_list_item(&mut self, list_item: NestedMetaItem) -> NestedMetaItem {
            Spanned {
                node: match list_item.node {
                    NestedMetaItemKind::MetaItem(mi) => {
                        NestedMetaItemKind::MetaItem(self.fold_meta_item(mi))
                    }
                    // default fold_meta_list_item does not fold the span
                    NestedMetaItemKind::Literal(lit) => {
                        NestedMetaItemKind::Literal(self.fold_spanned(lit))
                    }
                },
                span: self.new_span(list_item.span),
            }
        }

        fn fold_mac(&mut self, mac: Mac) -> Mac {
            fold::noop_fold_mac(mac, self)
        }

        fn fold_tt(&mut self, tt: &TokenTree) -> TokenTree {
            match *tt {
                TokenTree::Token(span, ref tok) => {
                    TokenTree::Token(self.new_span(span), self.fold_token(tok.clone()))
                }
                TokenTree::Delimited(span, ref delimed) => {
                    TokenTree::Delimited(self.new_span(span),
                                         Rc::new(Delimited {
                                                     delim: delimed.delim,
                                                     tts: self.fold_tts(&delimed.tts),
                                                 }))
                }
                TokenTree::Sequence(span, ref seq) => {
                    TokenTree::Sequence(self.new_span(span),
                                        Rc::new(SequenceRepetition {
                                            tts: self.fold_tts(&seq.tts),
                                            separator: seq.separator
                                                .clone()
                                                .map(|tok| self.fold_token(tok)),
                                            ..**seq
                                        }))
                }
            }
        }

        fn fold_token(&mut self, t: Token) -> Token {
            match t {
                // default fold_token does not fold literals
                Token::Literal(lit, repr) => Token::Literal(self.fold_lit(lit), repr),
                Token::Ident(id) => Token::Ident(self.fold_ident(id)),
                Token::Lifetime(id) => Token::Lifetime(self.fold_ident(id)),
                Token::Interpolated(nt) => {
                    let nt = match Rc::try_unwrap(nt) {
                        Ok(nt) => nt,
                        Err(nt) => (*nt).clone(),
                    };
                    Token::Interpolated(Rc::new(self.fold_interpolated(nt)))
                }
                Token::SubstNt(ident) => Token::SubstNt(self.fold_ident(ident)),
                Token::MatchNt(name, kind) => {
                    Token::MatchNt(self.fold_ident(name), self.fold_ident(kind))
                }
                _ => t,
            }
        }

        fn fold_vis(&mut self, vis: Visibility) -> Visibility {
            match vis {
                Visibility::Crate(span) => Visibility::Crate(self.new_span(span)),
                _ => fold::noop_fold_vis(vis, self),
            }
        }
    }

    Respanner.fold_crate(krate)
}
<commit_msg>Fix test_round_trip to properly ignore paths on Windows.<commit_after>#![cfg(feature = "full")]

#[macro_use]
extern crate quote;
extern crate syn;
extern crate syntex_pos;
extern crate syntex_syntax;
extern crate walkdir;

use syntex_pos::Span;
use syntex_syntax::ast;
use syntex_syntax::parse::{self, ParseSess, PResult};
use walkdir::{DirEntry, WalkDir, WalkDirIterator};

use std::fs::File;
use std::io::{self, Read, Write};
use std::panic;
use std::time::Instant;

macro_rules! errorf {
    ($($tt:tt)*) => {
        write!(io::stderr(), $($tt)*).unwrap();
    };
}

fn filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }
    let path = path.to_string_lossy();
    let path = if cfg!(windows) {
        path.replace('\\', "/").into()
    } else {
        path
    };
    // TODO assert that parsing fails on the parse-fail cases
    if path.starts_with("tests/rust/src/test/parse-fail") ||
       path.starts_with("tests/rust/src/test/compile-fail") {
        return false;
    }
    match path.as_ref() {
        // TODO better support for attributes
        "tests/rust/src/test/pretty/stmt_expr_attributes.rs" |
        // not actually a test case
        "tests/rust/src/test/run-pass/auxiliary/macro-include-items-expr.rs" |
        // TODO better support for attributes
        "tests/rust/src/test/run-pass/cfg_stmt_expr.rs" |
        // TODO weird glob import
        "tests/rust/src/test/run-pass/import-glob-crate.rs" |
        // TODO better support for attributes
        "tests/rust/src/test/run-pass/inner-attrs-on-impl.rs" |
        // TODO better support for attributes
        "tests/rust/src/test/run-pass/item-attributes.rs" |
        // TODO precedence issue with binop vs poly trait ref
        "tests/rust/src/test/run-pass/try-macro.rs" => false,
        _ => true,
    }
}

#[test]
fn test_round_trip() {
    let mut failed = 0;

    let walk = WalkDir::new("tests/rust").sort_by(|a, b| a.cmp(b));
    for entry in walk.into_iter().filter_entry(filter) {
        let entry = entry.unwrap();

        let path = entry.path();
        if path.is_dir() {
            continue;
        }
        errorf!("=== {}: ", path.display());

        let mut file = File::open(path).unwrap();
        let mut content = String::new();
        file.read_to_string(&mut content).unwrap();

        let start = Instant::now();
        let (krate, elapsed) = match syn::parse_crate(&content) {
            Ok(krate) => (krate, start.elapsed()),
            Err(msg) => {
                errorf!("syn failed to parse\n{}\n", msg);
                failed += 1;
                continue;
            }
        };
        let back = quote!(#krate).to_string();

        let equal = panic::catch_unwind(|| {
            let sess = ParseSess::new();
            let before = match syntex_parse(content, &sess) {
                Ok(before) => before,
                Err(mut diagnostic) => {
                    diagnostic.cancel();
                    if diagnostic.message().starts_with("file not found for module") {
                        errorf!("ignore\n");
                        return true;
                    } else {
                        errorf!("FAIL: {}\n", diagnostic.message());
                        return false;
                    }
                }
            };
            let after = match syntex_parse(back, &sess) {
                Ok(after) => after,
                Err(mut diagnostic) => {
                    errorf!("syntex failed to parse");
                    diagnostic.emit();
                    return false;
                }
            };

            if before == after {
                errorf!("pass in {}ms\n",
                        elapsed.as_secs() * 1000 + elapsed.subsec_nanos() as u64 / 1_000_000);
                true
            } else {
                errorf!("FAIL\nbefore: {}\nafter: {}\n",
                        format!("{:?}", before).replace("\n", ""),
                        format!("{:?}", after).replace("\n", ""));
                false
            }
        });
        match equal {
            Err(_) => errorf!("ignoring syntex panic\n"),
            Ok(true) => {}
            Ok(false) => failed += 1,
        }
    }

    if failed > 0 {
        panic!("{} failures", failed);
    }
}

fn syntex_parse(content: String, sess: &ParseSess) -> PResult<ast::Crate> {
    let name = "test_round_trip".to_string();
    parse::parse_crate_from_source_str(name, content, sess).map(respan_crate)
}

fn respan_crate(krate: ast::Crate) -> ast::Crate {
    use std::rc::Rc;
    use syntex_syntax::ast::{Attribute, Expr, ExprKind, Field, FnDecl, FunctionRetTy, ImplItem,
                             ImplItemKind, ItemKind, Mac, MetaItem, MetaItemKind, MethodSig,
                             NestedMetaItem, NestedMetaItemKind, TraitItem, TraitItemKind, TyParam,
                             Visibility};
    use syntex_syntax::codemap::{self, Spanned};
    use syntex_syntax::fold::{self, Folder};
    use syntex_syntax::parse::token::{Lit, Token};
    use syntex_syntax::ptr::P;
    use syntex_syntax::symbol::Symbol;
    use syntex_syntax::tokenstream::{Delimited, SequenceRepetition, TokenTree};
    use syntex_syntax::util::move_map::MoveMap;
    use syntex_syntax::util::small_vector::SmallVector;

    struct Respanner;

    impl Respanner {
        fn fold_spanned<T>(&mut self, spanned: Spanned<T>) -> Spanned<T> {
            codemap::respan(self.new_span(spanned.span), spanned.node)
        }

        fn fold_lit(&mut self, l: Lit) -> Lit {
            // Give up on comparing literals inside of macros because there are
            // so many equivalent representations of the same literal; they are
            // tested elsewhere
            match l {
                Lit::Byte(_) => Lit::Byte(Symbol::intern("")),
                Lit::Char(_) => Lit::Char(Symbol::intern("")),
                Lit::Integer(_) => Lit::Integer(Symbol::intern("")),
                Lit::Float(_) => Lit::Float(Symbol::intern("")),
                Lit::Str_(_) => Lit::Str_(Symbol::intern("")),
                Lit::ByteStr(_) => Lit::ByteStr(Symbol::intern("")),
                _ => l,
            }
        }
    }

    impl Folder for Respanner {
        fn new_span(&mut self, _: Span) -> Span {
            syntex_pos::DUMMY_SP
        }

        fn fold_item_kind(&mut self, i: ItemKind) -> ItemKind {
            match i {
                ItemKind::Fn(decl, unsafety, constness, abi, generics, body) => {
                    let generics = self.fold_generics(generics);
                    let decl = self.fold_fn_decl(decl);
                    let body = self.fold_block(body);
                    // default fold_item_kind does not fold this span
                    let constness = self.fold_spanned(constness);
                    ItemKind::Fn(decl, unsafety, constness, abi, generics, body)
                }
                _ => fold::noop_fold_item_kind(i, self),
            }
        }

        fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
            e.map(|e| {
                let folded = fold::noop_fold_expr(e, self);
                Expr {
                    node: match folded.node {
                        ExprKind::Lit(l) => {
                            // default fold_expr does not fold lits
                            ExprKind::Lit(l.map(|l| self.fold_spanned(l)))
                        }
                        ExprKind::Binary(op, lhs, rhs) => {
                            // default fold_expr does not fold the op span
                            ExprKind::Binary(self.fold_spanned(op),
                                             self.fold_expr(lhs),
                                             self.fold_expr(rhs))
                        }
                        ExprKind::AssignOp(op, lhs, rhs) => {
                            // default fold_expr does not fold the op span
                            ExprKind::AssignOp(self.fold_spanned(op),
                                               self.fold_expr(lhs),
                                               self.fold_expr(rhs))
                        }
                        other => other,
                    },
                    ..folded
                }
            })
        }

        fn fold_ty_param(&mut self, tp: TyParam) -> TyParam {
            TyParam {
                // default fold_ty_param does not fold the span
                span: self.new_span(tp.span),
                ..fold::noop_fold_ty_param(tp, self)
            }
        }

        fn fold_fn_decl(&mut self, decl: P<FnDecl>) -> P<FnDecl> {
            decl.map(|FnDecl { inputs, output, variadic }| {
                FnDecl {
                    inputs: inputs.move_map(|x| self.fold_arg(x)),
                    output: match output {
                        FunctionRetTy::Ty(ty) => FunctionRetTy::Ty(self.fold_ty(ty)),
                        // default fold_fn_decl does not fold this span
                        FunctionRetTy::Default(span) => FunctionRetTy::Default(self.new_span(span)),
                    },
                    variadic: variadic,
                }
            })
        }

        fn fold_field(&mut self, field: Field) -> Field {
            Field {
                ident: codemap::respan(// default fold_field does not fold this span
                                       self.new_span(field.ident.span),
                                       self.fold_ident(field.ident.node)),
                expr: self.fold_expr(field.expr),
                span: self.new_span(field.span),
                is_shorthand: field.is_shorthand,
                attrs: ast::ThinVec::new(),
            }
        }

        fn fold_trait_item(&mut self, i: TraitItem) -> SmallVector<TraitItem> {
            let noop = fold::noop_fold_trait_item(i, self).expect_one("");
            SmallVector::one(TraitItem {
                                 node: match noop.node {
                                     TraitItemKind::Method(sig, body) => {
                        TraitItemKind::Method(MethodSig {
                                                  constness: self.fold_spanned(sig.constness),
                                                  ..sig
                                              },
                                              body)
                    }
                                     node => node,
                                 },
                                 ..noop
                             })
        }

        fn fold_impl_item(&mut self, i: ImplItem) -> SmallVector<ImplItem> {
            let noop = fold::noop_fold_impl_item(i, self).expect_one("");
            SmallVector::one(ImplItem {
                                 node: match noop.node {
                                     ImplItemKind::Method(sig, body) => {
                        ImplItemKind::Method(MethodSig {
                                                 constness: self.fold_spanned(sig.constness),
                                                 ..sig
                                             },
                                             body)
                    }
                                     node => node,
                                 },
                                 ..noop
                             })
        }

        fn fold_attribute(&mut self, mut at: Attribute) -> Option<Attribute> {
            at.id.0 = 0;
            fold::noop_fold_attribute(at, self)
        }

        fn fold_meta_item(&mut self, meta_item: MetaItem) -> MetaItem {
            let MetaItem { name, node, span } = meta_item;
            MetaItem {
                name: name,
                node: match node {
                    MetaItemKind::Word => MetaItemKind::Word,
                    MetaItemKind::List(nested) => {
                        MetaItemKind::List(nested.move_map(|e| self.fold_meta_list_item(e)))
                    }
                    // default fold_meta_item does not fold the value span
                    MetaItemKind::NameValue(lit) => MetaItemKind::NameValue(self.fold_spanned(lit)),
                },
                span: self.new_span(span),
            }
        }

        fn fold_meta_list_item(&mut self, list_item: NestedMetaItem) -> NestedMetaItem {
            Spanned {
                node: match list_item.node {
                    NestedMetaItemKind::MetaItem(mi) => {
                        NestedMetaItemKind::MetaItem(self.fold_meta_item(mi))
                    }
                    // default fold_meta_list_item does not fold the span
                    NestedMetaItemKind::Literal(lit) => {
                        NestedMetaItemKind::Literal(self.fold_spanned(lit))
                    }
                },
                span: self.new_span(list_item.span),
            }
        }

        fn fold_mac(&mut self, mac: Mac) -> Mac {
            fold::noop_fold_mac(mac, self)
        }

        fn fold_tt(&mut self, tt: &TokenTree) -> TokenTree {
            match *tt {
                TokenTree::Token(span, ref tok) => {
                    TokenTree::Token(self.new_span(span), self.fold_token(tok.clone()))
                }
                TokenTree::Delimited(span, ref delimed) => {
                    TokenTree::Delimited(self.new_span(span),
                                         Rc::new(Delimited {
                                                     delim: delimed.delim,
                                                     tts: self.fold_tts(&delimed.tts),
                                                 }))
                }
                TokenTree::Sequence(span, ref seq) => {
                    TokenTree::Sequence(self.new_span(span),
                                        Rc::new(SequenceRepetition {
                                            tts: self.fold_tts(&seq.tts),
                                            separator: seq.separator
                                                .clone()
                                                .map(|tok| self.fold_token(tok)),
                                            ..**seq
                                        }))
                }
            }
        }

        fn fold_token(&mut self, t: Token) -> Token {
            match t {
                // default fold_token does not fold literals
                Token::Literal(lit, repr) => Token::Literal(self.fold_lit(lit), repr),
                Token::Ident(id) => Token::Ident(self.fold_ident(id)),
                Token::Lifetime(id) => Token::Lifetime(self.fold_ident(id)),
                Token::Interpolated(nt) => {
                    let nt = match Rc::try_unwrap(nt) {
                        Ok(nt) => nt,
                        Err(nt) => (*nt).clone(),
                    };
                    Token::Interpolated(Rc::new(self.fold_interpolated(nt)))
                }
                Token::SubstNt(ident) => Token::SubstNt(self.fold_ident(ident)),
                Token::MatchNt(name, kind) => {
                    Token::MatchNt(self.fold_ident(name), self.fold_ident(kind))
                }
                _ => t,
            }
        }

        fn fold_vis(&mut self, vis: Visibility) -> Visibility {
            match vis {
                Visibility::Crate(span) => Visibility::Crate(self.new_span(span)),
                _ => fold::noop_fold_vis(vis, self),
            }
        }
    }

    Respanner.fold_crate(krate)
}
<|endoftext|>


<commit_before>use std::ascii::*;
use regex::Regex;

use cases::classcase::is_class_case;
use cases::camelcase::is_camel_case;

pub fn to_sentence_case<'a>(non_sentence_case_string: String) -> String {
    if is_sentence_case(non_sentence_case_string.clone()) {
        return non_sentence_case_string
    } else if
        is_camel_case(non_sentence_case_string.clone())
        || is_class_case(non_sentence_case_string.clone()){
        return to_sentence_from_class_or_camel(non_sentence_case_string)
    } else {
        return to_sentence_from_snake_or_kebab(non_sentence_case_string)
    }
}
    fn to_sentence_from_class_or_camel<'a>(non_sentence_case_string: String) -> String {
        let mut result:String = "".to_string();
        let mut first_character: bool = true;
        for character in non_sentence_case_string.chars() {
            if character == character.to_ascii_uppercase() && !first_character {
                result = format!("{} {}", result, character.to_ascii_lowercase());
            } else if !first_character {
                result = format!("{}{}", result, character.to_ascii_lowercase());
            } else {
                result = format!("{}{}", result, character.to_ascii_uppercase());
                first_character = false;
            }
        }
        println!("{}", result);
        return result
    }

    fn to_sentence_from_snake_or_kebab<'a>(non_sentence_case_string: String) -> String {
        let mut result:String = "".to_string();
        let mut first_character: bool = true;
        for character in non_sentence_case_string.chars() {
            if character.to_string() != "_" && character.to_string() != "-" && !first_character {
                result = format!("{}{}", result, character.to_ascii_lowercase());
            } else if character.to_string() == "_" || character.to_string() == "-" {
                result = format!("{} ", result);
            } else {
                result = format!("{}{}", result, character.to_ascii_uppercase());
                first_character = false;
            }
        }
        return result
    }

pub fn is_sentence_case<'a>(test_string: String) -> bool{
    let sentence_matcher= Regex::new(r"(^[A-Z])([^-|^_]*[a-z]+)").unwrap();
    let mut is_sentence_case= false;
    if sentence_matcher.is_match(test_string.as_ref())
        && !is_class_case(test_string.clone()){
            is_sentence_case = true;
        }
    return is_sentence_case;
}

#[cfg(test)]
mod sentencecase_test;
<commit_msg>Fixed a wild println, that was added during testing and missed getting removed.<commit_after>use std::ascii::*;
use regex::Regex;

use cases::classcase::is_class_case;
use cases::camelcase::is_camel_case;

pub fn to_sentence_case<'a>(non_sentence_case_string: String) -> String {
    if is_sentence_case(non_sentence_case_string.clone()) {
        return non_sentence_case_string
    } else if
        is_camel_case(non_sentence_case_string.clone())
        || is_class_case(non_sentence_case_string.clone()){
        return to_sentence_from_class_or_camel(non_sentence_case_string)
    } else {
        return to_sentence_from_snake_or_kebab(non_sentence_case_string)
    }
}
    fn to_sentence_from_class_or_camel<'a>(non_sentence_case_string: String) -> String {
        let mut result:String = "".to_string();
        let mut first_character: bool = true;
        for character in non_sentence_case_string.chars() {
            if character == character.to_ascii_uppercase() && !first_character {
                result = format!("{} {}", result, character.to_ascii_lowercase());
            } else if !first_character {
                result = format!("{}{}", result, character.to_ascii_lowercase());
            } else {
                result = format!("{}{}", result, character.to_ascii_uppercase());
                first_character = false;
            }
        }
        return result
    }

    fn to_sentence_from_snake_or_kebab<'a>(non_sentence_case_string: String) -> String {
        let mut result:String = "".to_string();
        let mut first_character: bool = true;
        for character in non_sentence_case_string.chars() {
            if character.to_string() != "_" && character.to_string() != "-" && !first_character {
                result = format!("{}{}", result, character.to_ascii_lowercase());
            } else if character.to_string() == "_" || character.to_string() == "-" {
                result = format!("{} ", result);
            } else {
                result = format!("{}{}", result, character.to_ascii_uppercase());
                first_character = false;
            }
        }
        return result
    }

pub fn is_sentence_case<'a>(test_string: String) -> bool{
    let sentence_matcher= Regex::new(r"(^[A-Z])([^-|^_]*[a-z]+)").unwrap();
    let mut is_sentence_case= false;
    if sentence_matcher.is_match(test_string.as_ref())
        && !is_class_case(test_string.clone()){
            is_sentence_case = true;
        }
    return is_sentence_case;
}

#[cfg(test)]
mod sentencecase_test;
<|endoftext|>


<commit_before>use std::env;
use std::error::Error;
use std::io::BufReader;
use std::io::BufRead;
use std::io::LineWriter;
use std::io::Write;
use std::fs::File;
use std::str;
use std::collections::BTreeSet;

const POS_VECTOR: usize = 9;
const ELEMENTOS_VECTOR: usize = 23;
const TAM_PERIODO: usize = 6;
const CANT_INSTITUCIONES: usize = 6;
const TAM_VECTOR: usize = ELEMENTOS_VECTOR * TAM_PERIODO;
const TAM_VECTOR_ENTRADA: usize = TAM_VECTOR * CANT_INSTITUCIONES;
const LARGO_LINEA: usize = POS_VECTOR + TAM_VECTOR_ENTRADA;
const TAM_SALIDA: usize = POS_VECTOR + 1 + TAM_VECTOR;

fn periodo_valido(periodo:&[u8]) -> bool {
	let mut i = 0;
	while i < TAM_PERIODO {
		if periodo[i] != b'0' {
			return true;
		}
		i += 1;
	}
	false
}

fn ordenar_vector(vector:&[u8],  result:&mut [u8]) {
	let mut periodos = BTreeSet::new();

	for p in vector.chunks(TAM_PERIODO) {
		if periodo_valido(p) {
			periodos.insert(p);
		}
	}

	// retorna el resultado
	if periodos.is_empty() {
		result[0] = b'N';
	} else if periodos.len() > ELEMENTOS_VECTOR {
		result[0] = b'S';
	} else {
		result[0] = b'D';
		let mut p = 1;
		for per in periodos.iter().rev() {
			result[p..p+TAM_PERIODO].clone_from_slice(&per);
			p += TAM_PERIODO;
		}
	}
}

fn procesar_linea(buf: &[u8]) -> [u8; TAM_SALIDA] {
	let mut res : [u8; TAM_SALIDA] = [b' '; TAM_SALIDA];
	res[0..POS_VECTOR].clone_from_slice(&buf[0..POS_VECTOR]);
	ordenar_vector(&buf[POS_VECTOR..], &mut res[POS_VECTOR..]);
	res
}

fn main() {
	let args: Vec<String> = env::args().collect();
	if args.len() != 3 {
		println!("Uso: ordena_vector archivo_entrada archivo_salida");
		return
	}

    let t0 = std::time::Instant::now();

	let entrada = match File::open(&args[1]) {
		Err(e) => panic!("No pudo abrir archivo {}, causa: {}", args[1], e.description()),
		Ok(file) => BufReader::with_capacity(1024*1024, file)
	};
	let mut salida = match File::create(&args[2]) {
		Err(e) => panic!("No pudo crear archivo {}, causa: {}", args[2], e.description()),
		Ok(file) => LineWriter::with_capacity(1024*1024, file)
	};

	for (num_linea, linea) in entrada.lines().enumerate() {
		let buf = &linea.unwrap().into_bytes();

		if buf.len() != LARGO_LINEA {
			println!("Error en el largo de la linea {}", num_linea);
			writeln!(salida, "{}", str::from_utf8(&buf).unwrap()).unwrap();
		} else {
			let vector = procesar_linea(buf);
			writeln!(salida, "{}", str::from_utf8(&vector).unwrap()).unwrap();
		};

	}

	let dur  = t0.elapsed();
	let secs = dur.as_secs();
    let frac = dur.subsec_millis();
    println!("tiempo ocupado: {}.{}s", secs, frac);
}
<commit_msg>simplifica periodo_valido usando estilo funcional<commit_after>use std::env;
use std::error::Error;
use std::io::BufReader;
use std::io::BufRead;
use std::io::LineWriter;
use std::io::Write;
use std::fs::File;
use std::str;
use std::collections::BTreeSet;

const POS_VECTOR: usize = 9;
const ELEMENTOS_VECTOR: usize = 23;
const TAM_PERIODO: usize = 6;
const CANT_INSTITUCIONES: usize = 6;
const TAM_VECTOR: usize = ELEMENTOS_VECTOR * TAM_PERIODO;
const TAM_VECTOR_ENTRADA: usize = TAM_VECTOR * CANT_INSTITUCIONES;
const LARGO_LINEA: usize = POS_VECTOR + TAM_VECTOR_ENTRADA;
const TAM_SALIDA: usize = POS_VECTOR + 1 + TAM_VECTOR;

fn periodo_valido(periodo:&[u8]) -> bool {
	periodo.iter().any(|&x| x != b'0')
}

fn ordenar_vector(vector:&[u8],  result:&mut [u8]) {
	let mut periodos = BTreeSet::new();

	for p in vector.chunks(TAM_PERIODO) {
		if periodo_valido(p) {
			periodos.insert(p);
		}
	}

	// retorna el resultado
	if periodos.is_empty() {
		result[0] = b'N';
	} else if periodos.len() > ELEMENTOS_VECTOR {
		result[0] = b'S';
	} else {
		result[0] = b'D';
		let mut p = 1;
		for per in periodos.iter().rev() {
			result[p..p+TAM_PERIODO].clone_from_slice(&per);
			p += TAM_PERIODO;
		}
	}
}

fn procesar_linea(buf: &[u8]) -> [u8; TAM_SALIDA] {
	let mut res : [u8; TAM_SALIDA] = [b' '; TAM_SALIDA];
	res[0..POS_VECTOR].clone_from_slice(&buf[0..POS_VECTOR]);
	ordenar_vector(&buf[POS_VECTOR..], &mut res[POS_VECTOR..]);
	res
}

fn main() {
	let args: Vec<String> = env::args().collect();
	if args.len() != 3 {
		println!("Uso: ordena_vector archivo_entrada archivo_salida");
		return
	}

    let t0 = std::time::Instant::now();

	let entrada = match File::open(&args[1]) {
		Err(e) => panic!("No pudo abrir archivo {}, causa: {}", args[1], e.description()),
		Ok(file) => BufReader::with_capacity(1024*1024, file)
	};
	let mut salida = match File::create(&args[2]) {
		Err(e) => panic!("No pudo crear archivo {}, causa: {}", args[2], e.description()),
		Ok(file) => LineWriter::with_capacity(1024*1024, file)
	};

	for (num_linea, linea) in entrada.lines().enumerate() {
		let buf = &linea.unwrap().into_bytes();

		if buf.len() != LARGO_LINEA {
			println!("Error en el largo de la linea {}", num_linea);
			writeln!(salida, "{}", str::from_utf8(&buf).unwrap()).unwrap();
		} else {
			let vector = procesar_linea(buf);
			writeln!(salida, "{}", str::from_utf8(&vector).unwrap()).unwrap();
		};

	}

	let dur  = t0.elapsed();
	let secs = dur.as_secs();
    let frac = dur.subsec_millis();
    println!("tiempo ocupado: {}.{}s", secs, frac);
}
<|endoftext|>


<commit_before>use conduit::{Request, Response};
use diesel::prelude::*;
use time::Timespec;
use serde_json;

use db::RequestTransaction;
use schema::{crate_owner_invitations, users, crates, crate_owners};
use user::RequestUser;
use util::errors::{CargoResult, human};
use util::RequestUtils;
use owner::{CrateOwner, OwnerKind};

/// The model representing a row in the `crate_owner_invitations` database table.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Identifiable, Queryable)]
#[primary_key(invited_user_id, crate_id)]
pub struct CrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
    pub created_at: Timespec,
}

#[derive(Insertable, Clone, Copy, Debug)]
#[table_name = "crate_owner_invitations"]
pub struct NewCrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
}

impl CrateOwnerInvitation {
    pub fn invited_by_username(&self, conn: &PgConnection) -> String {
        users::table
            .find(self.invited_by_user_id)
            .select(users::gh_login)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown username)"))
    }

    pub fn crate_name(&self, conn: &PgConnection) -> String {
        crates::table
            .find(self.crate_id)
            .select(crates::name)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown crate name)"))
    }

    pub fn encodable(self, conn: &PgConnection) -> EncodableCrateOwnerInvitation {
        EncodableCrateOwnerInvitation {
            invited_by_username: self.invited_by_username(conn),
            crate_name: self.crate_name(conn),
            crate_id: self.crate_id,
            created_at: ::encode_time(self.created_at),
        }
    }
}

/// The serialization format for the `CrateOwnerInvitation` model.
#[derive(Deserialize, Serialize, Debug)]
pub struct EncodableCrateOwnerInvitation {
    pub invited_by_username: String,
    pub crate_name: String,
    pub crate_id: i32,
    pub created_at: String,
}

/// Handles the `GET /me/crate_owner_invitations` route.
pub fn list(req: &mut Request) -> CargoResult<Response> {
    let conn = &*req.db_conn()?;
    let user_id = req.user()?.id;

    let crate_owner_invitations = crate_owner_invitations::table
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .load::<CrateOwnerInvitation>(&*conn)?
        .into_iter()
        .map(|i| i.encodable(conn))
        .collect();

    #[derive(Serialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }
    Ok(req.json(&R { crate_owner_invitations }))
}

#[derive(Deserialize)]
struct OwnerInvitation {
    crate_owner_invite: InvitationResponse,
}

#[derive(Deserialize, Serialize, Debug, Copy, Clone)]
pub struct InvitationResponse {
    pub crate_id: i32,
    pub accepted: bool,
}

/// Handles the `PUT /me/crate_owner_invitations/:crate_id` route.
pub fn handle_invite(req: &mut Request) -> CargoResult<Response> {

    let conn = &*req.db_conn()?;

    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    let crate_invite: OwnerInvitation = serde_json::from_str(&body).map_err(|_| {
        human("invalid json request")
    })?;

    let crate_invite = crate_invite.crate_owner_invite;

    if crate_invite.accepted {
        accept_invite(req, conn, crate_invite)
    } else {
        decline_invite(req, conn, crate_invite)
    }
}

fn accept_invite(
    req: &mut Request,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
) -> CargoResult<Response> {
    let user_id = req.user()?.id;
    use diesel::{insert, delete};
    let pending_crate_owner = crate_owner_invitations::table
        .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .first::<CrateOwnerInvitation>(&*conn)?;

    let owner = CrateOwner {
        crate_id: crate_invite.crate_id,
        owner_id: user_id,
        created_by: pending_crate_owner.invited_by_user_id,
        owner_kind: OwnerKind::User as i32,
    };

    conn.transaction(|| {
        insert(&owner).into(crate_owners::table).execute(conn)?;
        delete(
            crate_owner_invitations::table
                .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
                .filter(crate_owner_invitations::invited_user_id.eq(user_id)),
        ).execute(conn)?;

        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R { crate_owner_invitation: crate_invite }))
    })
}

fn decline_invite(req: &mut Request, conn: &PgConnection, crate_invite: InvitationResponse) -> CargoResult<Response> {
    use diesel::delete;
    let user_id = req.user()?.id;

    delete(crate_owner_invitations::table
        .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
        .filter(crate_owner_invitations::invited_user_id.eq(user_id)))
        .execute(conn)?;

    #[derive(Serialize)]
    struct R {
        crate_owner_invitation: InvitationResponse,
    }

    Ok(req.json(&R { crate_owner_invitation: crate_invite }))
}
<commit_msg>cargo fmt<commit_after>use conduit::{Request, Response};
use diesel::prelude::*;
use time::Timespec;
use serde_json;

use db::RequestTransaction;
use schema::{crate_owner_invitations, users, crates, crate_owners};
use user::RequestUser;
use util::errors::{CargoResult, human};
use util::RequestUtils;
use owner::{CrateOwner, OwnerKind};

/// The model representing a row in the `crate_owner_invitations` database table.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Identifiable, Queryable)]
#[primary_key(invited_user_id, crate_id)]
pub struct CrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
    pub created_at: Timespec,
}

#[derive(Insertable, Clone, Copy, Debug)]
#[table_name = "crate_owner_invitations"]
pub struct NewCrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
}

impl CrateOwnerInvitation {
    pub fn invited_by_username(&self, conn: &PgConnection) -> String {
        users::table
            .find(self.invited_by_user_id)
            .select(users::gh_login)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown username)"))
    }

    pub fn crate_name(&self, conn: &PgConnection) -> String {
        crates::table
            .find(self.crate_id)
            .select(crates::name)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown crate name)"))
    }

    pub fn encodable(self, conn: &PgConnection) -> EncodableCrateOwnerInvitation {
        EncodableCrateOwnerInvitation {
            invited_by_username: self.invited_by_username(conn),
            crate_name: self.crate_name(conn),
            crate_id: self.crate_id,
            created_at: ::encode_time(self.created_at),
        }
    }
}

/// The serialization format for the `CrateOwnerInvitation` model.
#[derive(Deserialize, Serialize, Debug)]
pub struct EncodableCrateOwnerInvitation {
    pub invited_by_username: String,
    pub crate_name: String,
    pub crate_id: i32,
    pub created_at: String,
}

/// Handles the `GET /me/crate_owner_invitations` route.
pub fn list(req: &mut Request) -> CargoResult<Response> {
    let conn = &*req.db_conn()?;
    let user_id = req.user()?.id;

    let crate_owner_invitations = crate_owner_invitations::table
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .load::<CrateOwnerInvitation>(&*conn)?
        .into_iter()
        .map(|i| i.encodable(conn))
        .collect();

    #[derive(Serialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }
    Ok(req.json(&R { crate_owner_invitations }))
}

#[derive(Deserialize)]
struct OwnerInvitation {
    crate_owner_invite: InvitationResponse,
}

#[derive(Deserialize, Serialize, Debug, Copy, Clone)]
pub struct InvitationResponse {
    pub crate_id: i32,
    pub accepted: bool,
}

/// Handles the `PUT /me/crate_owner_invitations/:crate_id` route.
pub fn handle_invite(req: &mut Request) -> CargoResult<Response> {

    let conn = &*req.db_conn()?;

    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    let crate_invite: OwnerInvitation = serde_json::from_str(&body).map_err(|_| {
        human("invalid json request")
    })?;

    let crate_invite = crate_invite.crate_owner_invite;

    if crate_invite.accepted {
        accept_invite(req, conn, crate_invite)
    } else {
        decline_invite(req, conn, crate_invite)
    }
}

fn accept_invite(
    req: &mut Request,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
) -> CargoResult<Response> {
    let user_id = req.user()?.id;
    use diesel::{insert, delete};
    let pending_crate_owner = crate_owner_invitations::table
        .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .first::<CrateOwnerInvitation>(&*conn)?;

    let owner = CrateOwner {
        crate_id: crate_invite.crate_id,
        owner_id: user_id,
        created_by: pending_crate_owner.invited_by_user_id,
        owner_kind: OwnerKind::User as i32,
    };

    conn.transaction(|| {
        insert(&owner).into(crate_owners::table).execute(conn)?;
        delete(
            crate_owner_invitations::table
                .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
                .filter(crate_owner_invitations::invited_user_id.eq(user_id)),
        ).execute(conn)?;

        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R { crate_owner_invitation: crate_invite }))
    })
}

fn decline_invite(
    req: &mut Request,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
) -> CargoResult<Response> {
    use diesel::delete;
    let user_id = req.user()?.id;

    delete(
        crate_owner_invitations::table
            .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
            .filter(crate_owner_invitations::invited_user_id.eq(user_id)),
    ).execute(conn)?;

    #[derive(Serialize)]
    struct R {
        crate_owner_invitation: InvitationResponse,
    }

    Ok(req.json(&R { crate_owner_invitation: crate_invite }))
}
<|endoftext|>