<commit_before>use gl;
use opencl;
use opencl::mem::CLBuffer;
use std::io::timer;
use std::mem;
use std::time::duration::Duration;
use sdl2;
use sdl2::event::Event;
use stopwatch::TimerSet;
use yaglw::gl_context::{GLContext, GLContextExistence};
use yaglw::shader::Shader;
use yaglw::vertex_buffer::{GLArray, GLBuffer, GLType, VertexAttribData, DrawMode};

static WINDOW_WIDTH: u32 = 800;
static WINDOW_HEIGHT: u32 = 600;

#[repr(C)]
struct RGB {
  pub r: f32,
  pub g: f32,
  pub b: f32,
}

pub fn main() {
  let timers = TimerSet::new();

  let window = make_window();

  let _sdl_gl_context = window.gl_create_context().unwrap();

  // Load the OpenGL function pointers.
  gl::load_with(|s| unsafe {
    mem::transmute(sdl2::video::gl_get_proc_address(s))
  });

  let (gl, mut gl_context) = unsafe {
    GLContext::new()
  };

  match gl_context.get_error() {
    gl::NO_ERROR => {},
    err => {
      println!("OpenGL error 0x{:x} in setup", err);
      return;
    },
  }

  let shader = make_shader(&gl);
  shader.use_shader(&mut gl_context);

  let vao = timers.time("make_picture", || {
    make_picture(&gl, &mut gl_context, &shader)
  });

  while !quit_event() {
    let vao = timers.time("draw", || {
      gl_context.clear_buffer();
      vao.draw(&mut gl_context);
      // swap buffers
      window.gl_swap_window();
    });

    timer::sleep(Duration::milliseconds(10));
  }

  timers.print();
}

fn make_shader<'a>(
  gl: &'a GLContextExistence,
) -> Shader<'a> {
  let vertex_shader: String = format!("
    #version 330 core

    const int W = {};
    const int H = {};

    in vec3 color;
    out vec4 v_color;

    void main() {{
      v_color = vec4(color, 1);
      gl_Position =
        vec4(
          float(gl_VertexID % W) / W * 2 - 1,
          float(gl_VertexID / W) / H * 2 - 1,
          0, 1
        );
    }}
  ", WINDOW_WIDTH, WINDOW_HEIGHT);

  let fragment_shader: String = "
    #version 330 core

    in vec4 v_color;

    void main() {
      gl_FragColor = v_color;
    }
  ".to_string();

  let components = vec!(
    ((vertex_shader, gl::VERTEX_SHADER)),
    ((fragment_shader, gl::FRAGMENT_SHADER)),
  );

  Shader::new(gl, components.into_iter())
}

fn make_picture<'a>(
  gl: &'a GLContextExistence,
  gl_context: &mut GLContext,
  shader: &Shader<'a>,
) -> GLArray<'a, RGB> {
  let dat = do_opencl();

  let mut vbo = GLBuffer::new(gl, gl_context, dat.len());
  vbo.push(gl_context, dat.as_slice());

  let attribs = [
    VertexAttribData {
      name: "color",
      size: 3,
      unit: GLType::Float,
    },
  ];

  GLArray::new(
    gl,
    gl_context,
    shader,
    &attribs,
    DrawMode::Points,
    vbo,
  )
}

fn do_opencl() -> Vec<RGB> {
  let (device, ctx, queue) = opencl::util::create_compute_context().unwrap();

  let len = WINDOW_WIDTH * WINDOW_HEIGHT;
  let len = len as usize;

  let output_buffer: CLBuffer<RGB> = ctx.create_buffer(len, opencl::cl::CL_MEM_WRITE_ONLY);

  let program = {
    let ker = format!("
      __kernel void color(__global float *output) {{
        int W = {};
        int H = {};
        int i = get_global_id(0);
        float x = i % W;
        float y = i / W;
        i = 3 * i;
        output[i] = 0;
        output[i + 1] = x / W;
        output[i + 2] = y / H;
      }}
    ", WINDOW_WIDTH, WINDOW_HEIGHT);
    ctx.create_program_from_source(ker.as_slice())
  };
  program.build(&device).ok().expect("Couldn't build program.");

  let kernel = program.create_kernel("color");
  // This is sketchy; we "implicitly cast" output_buffer from a CLBuffer<RGB> to a CLBuffer<f32>.
  kernel.set_arg(0, &output_buffer);

  let event = queue.enqueue_async_kernel(&kernel, len, None, ());

  queue.get(&output_buffer, &event)
}

fn make_window() -> sdl2::video::Window {
  sdl2::init(sdl2::INIT_EVERYTHING);

  sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLContextMajorVersion, 3);
  sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLContextMinorVersion, 3);
  sdl2::video::gl_set_attribute(
    sdl2::video::GLAttr::GLContextProfileMask,
    sdl2::video::GLProfile::GLCoreProfile as isize
  );

  sdl2::video::Window::new(
    "OpenCL",
    sdl2::video::WindowPos::PosCentered,
    sdl2::video::WindowPos::PosCentered,
    800,
    600,
    sdl2::video::OPENGL,
  ).unwrap()
}

fn quit_event() -> bool {
  loop {
    match sdl2::event::poll_event() {
      Event::None => {
        return false;
      },
      Event::Quit(_) => {
        return true;
      }
      Event::AppTerminating(_) => {
        return true;
      }
      _ => {},
    }
  }
}
<commit_msg>Remove unused<commit_after>use gl;
use opencl;
use opencl::mem::CLBuffer;
use std::io::timer;
use std::mem;
use std::time::duration::Duration;
use sdl2;
use sdl2::event::Event;
use stopwatch::TimerSet;
use yaglw::gl_context::{GLContext, GLContextExistence};
use yaglw::shader::Shader;
use yaglw::vertex_buffer::{GLArray, GLBuffer, GLType, VertexAttribData, DrawMode};

static WINDOW_WIDTH: u32 = 800;
static WINDOW_HEIGHT: u32 = 600;

#[repr(C)]
struct RGB {
  pub r: f32,
  pub g: f32,
  pub b: f32,
}

pub fn main() {
  let timers = TimerSet::new();

  let window = make_window();

  let _sdl_gl_context = window.gl_create_context().unwrap();

  // Load the OpenGL function pointers.
  gl::load_with(|s| unsafe {
    mem::transmute(sdl2::video::gl_get_proc_address(s))
  });

  let (gl, mut gl_context) = unsafe {
    GLContext::new()
  };

  match gl_context.get_error() {
    gl::NO_ERROR => {},
    err => {
      println!("OpenGL error 0x{:x} in setup", err);
      return;
    },
  }

  let shader = make_shader(&gl);
  shader.use_shader(&mut gl_context);

  let vao = timers.time("make_picture", || {
    make_picture(&gl, &mut gl_context, &shader)
  });

  while !quit_event() {
    timers.time("draw", || {
      gl_context.clear_buffer();
      vao.draw(&mut gl_context);
      // swap buffers
      window.gl_swap_window();
    });

    timer::sleep(Duration::milliseconds(10));
  }

  timers.print();
}

fn make_shader<'a>(
  gl: &'a GLContextExistence,
) -> Shader<'a> {
  let vertex_shader: String = format!("
    #version 330 core

    const int W = {};
    const int H = {};

    in vec3 color;
    out vec4 v_color;

    void main() {{
      v_color = vec4(color, 1);
      gl_Position =
        vec4(
          float(gl_VertexID % W) / W * 2 - 1,
          float(gl_VertexID / W) / H * 2 - 1,
          0, 1
        );
    }}
  ", WINDOW_WIDTH, WINDOW_HEIGHT);

  let fragment_shader: String = "
    #version 330 core

    in vec4 v_color;

    void main() {
      gl_FragColor = v_color;
    }
  ".to_string();

  let components = vec!(
    ((vertex_shader, gl::VERTEX_SHADER)),
    ((fragment_shader, gl::FRAGMENT_SHADER)),
  );

  Shader::new(gl, components.into_iter())
}

fn make_picture<'a>(
  gl: &'a GLContextExistence,
  gl_context: &mut GLContext,
  shader: &Shader<'a>,
) -> GLArray<'a, RGB> {
  let dat = do_opencl();

  let mut vbo = GLBuffer::new(gl, gl_context, dat.len());
  vbo.push(gl_context, dat.as_slice());

  let attribs = [
    VertexAttribData {
      name: "color",
      size: 3,
      unit: GLType::Float,
    },
  ];

  GLArray::new(
    gl,
    gl_context,
    shader,
    &attribs,
    DrawMode::Points,
    vbo,
  )
}

fn do_opencl() -> Vec<RGB> {
  let (device, ctx, queue) = opencl::util::create_compute_context().unwrap();

  let len = WINDOW_WIDTH * WINDOW_HEIGHT;
  let len = len as usize;

  let output_buffer: CLBuffer<RGB> = ctx.create_buffer(len, opencl::cl::CL_MEM_WRITE_ONLY);

  let program = {
    let ker = format!("
      __kernel void color(__global float *output) {{
        int W = {};
        int H = {};
        int i = get_global_id(0);
        float x = i % W;
        float y = i / W;
        i = 3 * i;
        output[i] = 0;
        output[i + 1] = x / W;
        output[i + 2] = y / H;
      }}
    ", WINDOW_WIDTH, WINDOW_HEIGHT);
    ctx.create_program_from_source(ker.as_slice())
  };
  program.build(&device).ok().expect("Couldn't build program.");

  let kernel = program.create_kernel("color");
  // This is sketchy; we "implicitly cast" output_buffer from a CLBuffer<RGB> to a CLBuffer<f32>.
  kernel.set_arg(0, &output_buffer);

  let event = queue.enqueue_async_kernel(&kernel, len, None, ());

  queue.get(&output_buffer, &event)
}

fn make_window() -> sdl2::video::Window {
  sdl2::init(sdl2::INIT_EVERYTHING);

  sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLContextMajorVersion, 3);
  sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLContextMinorVersion, 3);
  sdl2::video::gl_set_attribute(
    sdl2::video::GLAttr::GLContextProfileMask,
    sdl2::video::GLProfile::GLCoreProfile as isize
  );

  sdl2::video::Window::new(
    "OpenCL",
    sdl2::video::WindowPos::PosCentered,
    sdl2::video::WindowPos::PosCentered,
    800,
    600,
    sdl2::video::OPENGL,
  ).unwrap()
}

fn quit_event() -> bool {
  loop {
    match sdl2::event::poll_event() {
      Event::None => {
        return false;
      },
      Event::Quit(_) => {
        return true;
      }
      Event::AppTerminating(_) => {
        return true;
      }
      _ => {},
    }
  }
}
<|endoftext|>


<commit_before>extern crate getopts;
extern crate rayon;
extern crate libc;
extern crate rff;

mod interface;

use std::env;
use std::io::{self, BufRead, Write, BufWriter};
use std::process;
use rayon::prelude::*;
use getopts::{Options, Fail};
use rff::choice::Choice;
use interface::{Interface, Error};

fn main() {
    let code = run();
    process::exit(code);
}

fn run() -> i32 {
    let args = env::args().skip(1).collect::<Vec<String>>();
    let mut opts = Options::new();

    opts.optopt("s", "search", "Output sorted matches of QUERY", "QUERY");
    opts.optflag("", "benchmark", "Run search in benchmark mode");
    opts.optflag("h", "help", "Display this help and exit");
    opts.optflag("v", "version", "Display version information and exit");

    let matches = match opts.parse(args).map_err(translate_parse_error) {
        Ok(matches) => matches,
        Err(err) => {
            println!("{}", err);
            print_usage(opts);
            return 1;
        }
    };

    if matches.opt_present("h") {
        print_usage(opts);
        return 0;
    }

    if matches.opt_present("v") {
        print_version();
        return 0;
    }

    if matches.opt_present("benchmark") {
        if !matches.opt_present("s") {
            println!("Must specify -s/--search with --benchmark");
            return 1;
        }

        let choices = get_choices();
        let search = matches.opt_str("s").unwrap();

        for _ in 0..100 {
            let mut choices = choices.
                par_iter().
                cloned().
                filter_map(|choice| Choice::new(&search, choice)).
                collect::<Vec<Choice>>();

            choices.sort_by(|a, b| b.partial_cmp(a).unwrap());
        }
    } else if matches.opt_present("s") {
        let search = matches.opt_str("s").unwrap();
        let mut choices = get_choices().
            into_par_iter().
            filter_map(|choice| Choice::new(&search, choice)).
            collect::<Vec<Choice>>();

        choices.sort_by(|a, b| b.partial_cmp(a).unwrap());

        let stdout = io::stdout();
        let mut stdout = BufWriter::new(stdout.lock());

        for choice in choices {
            writeln!(stdout, "{}", choice.text()).unwrap();
        }
    } else {
        let opts = interface::Options {
            choices: get_choices(),
            initial: String::new()
        };

        let mut interface = Interface::from_opts(opts);

        match interface.run() {
            Ok(result) => println!("{}", result),
            Err(Error::Exit) => return 1,
            Err(e) => {
                println!("error: {:?}", e);
                return 1;
            }
        }
    }

    0
}

fn get_choices() -> Vec<String> {
    let mut lines = vec![];

    let stdin = io::stdin();

    for line in stdin.lock().lines() {
        lines.push(line.unwrap());
    }

    lines
}

fn translate_parse_error(err: Fail) -> String {
    match err {
        Fail::ArgumentMissing(opt) => format!("Argument missing: {}", opt),
        Fail::UnrecognizedOption(opt) => format!("Invalid option: {}", opt),
        Fail::OptionMissing(opt) => format!("Missing option: {}", opt),
        Fail::OptionDuplicated(opt) => format!("Duplicated option: {}", opt),
        Fail::UnexpectedArgument(opt) => format!("Unexpected argument: {}", opt)
    }
}

fn print_usage(opts: Options) {
    let prelude = format!("Usage: {} [options]", env!("CARGO_PKG_NAME"));
    print!("{}", opts.usage(&prelude));
}

fn print_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}
<commit_msg>Provide support for specifying initial query<commit_after>extern crate getopts;
extern crate rayon;
extern crate libc;
extern crate rff;

mod interface;

use std::env;
use std::io::{self, BufRead, Write, BufWriter};
use std::process;
use rayon::prelude::*;
use getopts::{Options, Fail};
use rff::choice::Choice;
use interface::{Interface, Error};

fn main() {
    let code = run();
    process::exit(code);
}

fn run() -> i32 {
    let args = env::args().skip(1).collect::<Vec<String>>();
    let mut opts = Options::new();

    opts.optopt("s", "search", "Output sorted matches of QUERY", "QUERY");
    opts.optopt("q", "query", "Use QUERY as the initial search string", "QUERY");
    opts.optflag("", "benchmark", "Run search in benchmark mode");
    opts.optflag("h", "help", "Display this help and exit");
    opts.optflag("v", "version", "Display version information and exit");

    let matches = match opts.parse(args).map_err(translate_parse_error) {
        Ok(matches) => matches,
        Err(err) => {
            println!("{}", err);
            print_usage(opts);
            return 1;
        }
    };

    if matches.opt_present("h") {
        print_usage(opts);
        return 0;
    }

    if matches.opt_present("v") {
        print_version();
        return 0;
    }

    if matches.opt_present("benchmark") {
        if !matches.opt_present("s") {
            println!("Must specify -s/--search with --benchmark");
            return 1;
        }

        let choices = get_choices();
        let search = matches.opt_str("s").unwrap();

        for _ in 0..100 {
            let mut choices = choices.
                par_iter().
                cloned().
                filter_map(|choice| Choice::new(&search, choice)).
                collect::<Vec<Choice>>();

            choices.sort_by(|a, b| b.partial_cmp(a).unwrap());
        }
    } else if matches.opt_present("s") {
        let search = matches.opt_str("s").unwrap();
        let mut choices = get_choices().
            into_par_iter().
            filter_map(|choice| Choice::new(&search, choice)).
            collect::<Vec<Choice>>();

        choices.sort_by(|a, b| b.partial_cmp(a).unwrap());

        let stdout = io::stdout();
        let mut stdout = BufWriter::new(stdout.lock());

        for choice in choices {
            writeln!(stdout, "{}", choice.text()).unwrap();
        }
    } else {
        let opts = interface::Options {
            choices: get_choices(),
            initial: matches.opt_str("q").unwrap_or(String::new())
        };

        let mut interface = Interface::from_opts(opts);

        match interface.run() {
            Ok(result) => println!("{}", result),
            Err(Error::Exit) => return 1,
            Err(e) => {
                println!("error: {:?}", e);
                return 1;
            }
        }
    }

    0
}

fn get_choices() -> Vec<String> {
    let mut lines = vec![];

    let stdin = io::stdin();

    for line in stdin.lock().lines() {
        lines.push(line.unwrap());
    }

    lines
}

fn translate_parse_error(err: Fail) -> String {
    match err {
        Fail::ArgumentMissing(opt) => format!("Argument missing: {}", opt),
        Fail::UnrecognizedOption(opt) => format!("Invalid option: {}", opt),
        Fail::OptionMissing(opt) => format!("Missing option: {}", opt),
        Fail::OptionDuplicated(opt) => format!("Duplicated option: {}", opt),
        Fail::UnexpectedArgument(opt) => format!("Unexpected argument: {}", opt)
    }
}

fn print_usage(opts: Options) {
    let prelude = format!("Usage: {} [options]", env!("CARGO_PKG_NAME"));
    print!("{}", opts.usage(&prelude));
}

fn print_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}
<|endoftext|>


<commit_before>use jsonrpc_core::IoHandler;

use lsp_types::{
    CompletionOptions, InitializeError, InitializeParams, InitializeResult, ServerCapabilities,
    ServerInfo, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
    WorkDoneProgressOptions,
};

use crate::{rpc::LanguageServerCommand, BoxFuture};

use super::*;

struct Initialize(RootedThread);
impl LanguageServerCommand<InitializeParams> for Initialize {
    type Future = BoxFuture<Self::Output, ServerError<Self::Error>>;
    type Output = InitializeResult;
    type Error = InitializeError;
    fn execute(
        &self,
        change: InitializeParams,
    ) -> BoxFuture<InitializeResult, ServerError<InitializeError>> {
        let thread = self.0.clone();
        async move {
            let import = thread.get_macros().get("import").expect("Import macro");
            let import = import
                .downcast_ref::<Import<CheckImporter>>()
                .expect("Check importer");
            if let Some(ref uri) = change.root_uri {
                import.add_path(
                    uri.to_file_path()
                        .map_err(|()| "Unable to convert root_uri to file path")?,
                );
            }

            Ok(InitializeResult {
                server_info: Some(ServerInfo {
                    name: "Gluon language server".into(),
                    version: Some(
                        concat!(env!("CARGO_PKG_VERSION"), "-", env!("GIT_COMMIT")).into(),
                    ),
                }),
                capabilities: ServerCapabilities {
                    text_document_sync: Some(TextDocumentSyncCapability::Kind(
                        TextDocumentSyncKind::Incremental,
                    )),
                    completion_provider: Some(CompletionOptions {
                        resolve_provider: Some(true),
                        trigger_characters: Some(vec![".".into()]),
                        work_done_progress_options: WorkDoneProgressOptions {
                            work_done_progress: None,
                        },
                    }),
                    signature_help_provider: Some(SignatureHelpOptions {
                        trigger_characters: None,
                        retrigger_characters: None,
                        work_done_progress_options: WorkDoneProgressOptions {
                            work_done_progress: None,
                        },
                    }),
                    hover_provider: Some(true.into()),
                    document_formatting_provider: Some(true),
                    document_highlight_provider: Some(true),
                    document_symbol_provider: Some(true),
                    workspace_symbol_provider: Some(true),
                    definition_provider: Some(true),
                    ..ServerCapabilities::default()
                },
            })
        }
        .boxed()
    }

    fn invalid_params(&self) -> Option<Self::Error> {
        Some(InitializeError { retry: false })
    }
}

pub fn register(io: &mut IoHandler, thread: &RootedThread) {
    io.add_async_method(request!("initialize"), Initialize(thread.clone()));
}
<commit_msg>fix: Don't require building from a git repo<commit_after>use jsonrpc_core::IoHandler;

use lsp_types::{
    CompletionOptions, InitializeError, InitializeParams, InitializeResult, ServerCapabilities,
    ServerInfo, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
    WorkDoneProgressOptions,
};

use crate::{rpc::LanguageServerCommand, BoxFuture};

use super::*;

struct Initialize(RootedThread);
impl LanguageServerCommand<InitializeParams> for Initialize {
    type Future = BoxFuture<Self::Output, ServerError<Self::Error>>;
    type Output = InitializeResult;
    type Error = InitializeError;
    fn execute(
        &self,
        change: InitializeParams,
    ) -> BoxFuture<InitializeResult, ServerError<InitializeError>> {
        let thread = self.0.clone();
        async move {
            let import = thread.get_macros().get("import").expect("Import macro");
            let import = import
                .downcast_ref::<Import<CheckImporter>>()
                .expect("Check importer");
            if let Some(ref uri) = change.root_uri {
                import.add_path(
                    uri.to_file_path()
                        .map_err(|()| "Unable to convert root_uri to file path")?,
                );
            }

            Ok(InitializeResult {
                server_info: Some(ServerInfo {
                    name: "Gluon language server".into(),
                    version: Some(match option_env!("GIT_COMMIT") {
                        Some(git_commit) => format!("{}-{}", env!("CARGO_PKG_VERSION"), git_commit),
                        None => env!("CARGO_PKG_VERSION").into(),
                    }),
                }),
                capabilities: ServerCapabilities {
                    text_document_sync: Some(TextDocumentSyncCapability::Kind(
                        TextDocumentSyncKind::Incremental,
                    )),
                    completion_provider: Some(CompletionOptions {
                        resolve_provider: Some(true),
                        trigger_characters: Some(vec![".".into()]),
                        work_done_progress_options: WorkDoneProgressOptions {
                            work_done_progress: None,
                        },
                    }),
                    signature_help_provider: Some(SignatureHelpOptions {
                        trigger_characters: None,
                        retrigger_characters: None,
                        work_done_progress_options: WorkDoneProgressOptions {
                            work_done_progress: None,
                        },
                    }),
                    hover_provider: Some(true.into()),
                    document_formatting_provider: Some(true),
                    document_highlight_provider: Some(true),
                    document_symbol_provider: Some(true),
                    workspace_symbol_provider: Some(true),
                    definition_provider: Some(true),
                    ..ServerCapabilities::default()
                },
            })
        }
        .boxed()
    }

    fn invalid_params(&self) -> Option<Self::Error> {
        Some(InitializeError { retry: false })
    }
}

pub fn register(io: &mut IoHandler, thread: &RootedThread) {
    io.add_async_method(request!("initialize"), Initialize(thread.clone()));
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
use rustc_serialize::json;

use std::fmt;
use std::env;

use std::fs::File;
use std::io::Read;

use std::thread;
use std::sync::{Mutex, Arc};
use std::process::Command;

struct WorkConf {
    project: String,
    operate: String,
    head:    String,
}

impl fmt::Debug for WorkConf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "WorkConf:{}\"project\": {}, \"operate\": {}, \"head\": {}{}",
            "{", self.project, self.operate, self.head, "}")
    }
}

// Automatically generate `RustcDecodable` and `RustcEncodable` trait
// implementations
#[derive(RustcDecodable, RustcEncodable)]
struct DeployConf {
    user: String,
    path: String,
    hosts_conf: Vec<String>,
}

fn usage(argv_0: &String) {
    println!("-----USAGE----");
    println!("{} project deploy             deploy project with latest <head>.", argv_0);
    println!("{} project rollback <head>    rollback with <head>.", argv_0);
    std::process::exit(0);
}

static DEBUG: bool = false;

fn main() {
    let args: Vec<_> = env::args().collect();
    let argc = args.len();

    if argc < 3 {
        usage(&args[0]);
    }

    // 处理命令行参数
    let project = args[1].to_string();
    let operate = args[2].to_string();
    if ("deploy".to_string() != operate && "rollback".to_string() != operate) || ("rollback".to_string() == operate && argc < 4) {
        usage(&args[0]);
    }

    let head = if argc > 3 { args[3].to_string() } else { "".to_string() };

    let work_conf = WorkConf{
        project: project,
        operate: operate,
        head:    head,
    };
    if DEBUG { println!("{:?}", work_conf); }

    let config_filename = format!("./conf/{}.json", work_conf.project);
    if DEBUG { println!("config_filename: {}", config_filename); }

    let mut data = String::new();
    let mut f = File::open(config_filename)
        .ok()
        .expect("Can NOT open file.");
    f.read_to_string(&mut data)
        .ok()
        .expect("Can NOT read cofing file.");
    if DEBUG { println!("deploy_conf: {}", data)}
    let deploy_conf: DeployConf = json::decode(&data)
        .ok()
        .expect("Can NOT parse JSON config data.");
    if DEBUG { println!("JSON: {}", json::encode(&deploy_conf).unwrap()); }

    let mut hosts_conf = Vec::new();
    let hosts_len = deploy_conf.hosts_conf.len();
    for index in 0 .. hosts_len {
        hosts_conf.push(deploy_conf.hosts_conf[index].clone());
    }
    let mutex_ct = Arc::new(Mutex::new(vec![1]));

    println!("          ===== {} ======\n", work_conf.project);

    let handles: Vec<_> = hosts_conf.into_iter().map(|host| {
        let user = deploy_conf.user.clone();
        let path = deploy_conf.path.clone();
        let operate = work_conf.operate.clone();
        let head    = work_conf.head.clone();
        let mutex_ct= mutex_ct.clone();
        thread::spawn(move || {
            let cmd = if "deploy".to_string() == operate {
                format!("ssh {}@{} \"cd {} && git pull && git log -1 | awk '{{if (\\$1 ~/commit/) {{print \\$2}}}}' 2>&1\"",
                user, host, path)
            } else {
                format!("ssh {}@{} \"cd {} && git reset --hard {} && git log -1 | awk '{{if (\\$1 ~/commit/) {{print \\$2}}}}' 2>&1\"",
                user, host, path, head)
            };
            if DEBUG { println!("CMD: {}", cmd); }
            let output = Command::new("sh")
                .arg("-c")
                .arg(cmd)
                .output()
                .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });

            // 解决多线程穿插输出的问题
            let mut output_buf = "".to_string();
            output_buf = output_buf + &(format!("--- Start {} for {}@{} ---\n", operate, user, host));
            if DEBUG { println!("status: {}", output.status); }
            output_buf = output_buf + &(format!("stdout: {}\n", String::from_utf8_lossy(&output.stdout)));
            output_buf = output_buf + &(format!("stderr: {}\n", String::from_utf8_lossy(&output.stderr)));
            output_buf = output_buf + &(format!("--- End {} for {}@{} ---\n\n", operate, user, host));

            let _ct = mutex_ct.lock().unwrap();
            println!("{}", output_buf);
        })
    }).collect();

    for h in handles {
        h.join().unwrap();
    }
}
<commit_msg>加入更小的作用域.<commit_after>extern crate rustc_serialize;
use rustc_serialize::json;

use std::fmt;
use std::env;

use std::fs::File;
use std::io::Read;

use std::thread;
use std::sync::{Mutex, Arc};
use std::process::Command;

struct WorkConf {
    project: String,
    operate: String,
    head:    String,
}

impl fmt::Debug for WorkConf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "WorkConf:{}\"project\": {}, \"operate\": {}, \"head\": {}{}",
            "{", self.project, self.operate, self.head, "}")
    }
}

// Automatically generate `RustcDecodable` and `RustcEncodable` trait
// implementations
#[derive(RustcDecodable, RustcEncodable)]
struct DeployConf {
    user: String,
    path: String,
    hosts_conf: Vec<String>,
}

fn usage(argv_0: &String) {
    println!("-----USAGE----");
    println!("{} project deploy             deploy project with latest <head>.", argv_0);
    println!("{} project rollback <head>    rollback with <head>.", argv_0);
    std::process::exit(0);
}

static DEBUG: bool = false;

fn main() {
    let args: Vec<_> = env::args().collect();
    let argc = args.len();

    if argc < 3 {
        usage(&args[0]);
    }

    // 处理命令行参数
    let project = args[1].to_string();
    let operate = args[2].to_string();
    if ("deploy".to_string() != operate && "rollback".to_string() != operate) || ("rollback".to_string() == operate && argc < 4) {
        usage(&args[0]);
    }

    let head = if argc > 3 { args[3].to_string() } else { "".to_string() };

    let work_conf = WorkConf{
        project: project,
        operate: operate,
        head:    head,
    };
    if DEBUG { println!("{:?}", work_conf); }

    let config_filename = format!("./conf/{}.json", work_conf.project);
    if DEBUG { println!("config_filename: {}", config_filename); }

    let mut data = String::new();
    let mut f = File::open(config_filename)
        .ok()
        .expect("Can NOT open file.");
    f.read_to_string(&mut data)
        .ok()
        .expect("Can NOT read cofing file.");
    if DEBUG { println!("deploy_conf: {}", data)}
    let deploy_conf: DeployConf = json::decode(&data)
        .ok()
        .expect("Can NOT parse JSON config data.");
    if DEBUG { println!("JSON: {}", json::encode(&deploy_conf).unwrap()); }

    let mut hosts_conf = Vec::new();
    let hosts_len = deploy_conf.hosts_conf.len();
    for index in 0 .. hosts_len {
        hosts_conf.push(deploy_conf.hosts_conf[index].clone());
    }
    let mutex_ct = Arc::new(Mutex::new(vec![1]));

    println!("          ===== {} ======\n", work_conf.project);

    let handles: Vec<_> = hosts_conf.into_iter().map(|host| {
        let user = deploy_conf.user.clone();
        let path = deploy_conf.path.clone();
        let operate = work_conf.operate.clone();
        let head    = work_conf.head.clone();
        let mutex_ct= mutex_ct.clone();
        thread::spawn(move || {
            let cmd = if "deploy".to_string() == operate {
                format!("ssh {}@{} \"cd {} && git pull && git log -1 | awk '{{if (\\$1 ~/commit/) {{print \\$2}}}}' 2>&1\"",
                user, host, path)
            } else {
                format!("ssh {}@{} \"cd {} && git reset --hard {} && git log -1 | awk '{{if (\\$1 ~/commit/) {{print \\$2}}}}' 2>&1\"",
                user, host, path, head)
            };
            if DEBUG { println!("CMD: {}", cmd); }
            let output = Command::new("sh")
                .arg("-c")
                .arg(cmd)
                .output()
                .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });

            // 解决多线程穿插输出的问题
            let mut output_buf = "".to_string();
            output_buf = output_buf + &(format!("--- Start {} for {}@{} ---\n", operate, user, host));
            if DEBUG { println!("status: {}", output.status); }
            output_buf = output_buf + &(format!("stdout: {}\n", String::from_utf8_lossy(&output.stdout)));
            output_buf = output_buf + &(format!("stderr: {}\n", String::from_utf8_lossy(&output.stderr)));
            output_buf = output_buf + &(format!("--- End {} for {}@{} ---\n\n", operate, user, host));

            {
                let _ct = mutex_ct.lock().unwrap();
                println!("{}", output_buf);
            }
        })
    }).collect();

    for h in handles {
        h.join().unwrap();
    }
}
<|endoftext|>


<commit_before>#![feature(iter_arith)] // sum is not stable?

use std::io;
use std::fs::File;
use std::io::prelude::*;

#[macro_use]
extern crate scan_fmt;

fn main() {
    try_main().unwrap()
}

fn try_main() -> io::Result<()> {
    try!(run_from_file("input_1.txt", day1::main));
    try!(run_from_file("input_2.txt", day2::main));
    Ok(())
}

fn run_from_file<F>(file: &str, it: F) -> io::Result<()>
    where F: Fn(&str) -> io::Result<()>
{
    let mut f = try!(File::open(file));
    let mut input = String::new();
    try!(f.read_to_string(&mut input));
    try!(it(&input));
    Ok(())
}

// 74
// 1795
// 1586300
// 3737498

mod day1 {
    use std::io;
    use std::io::prelude::*;

    pub fn main(input: &str) -> io::Result<()> {
        println!("{}", adv_one_one(&input));
        println!("{}", adv_one_two(&input, -1));
        Ok(())
    }

    fn inmap(c: char) -> i32 {
        match c {
            '(' => 1,
            ')' => -1,
            _ => panic!("invalid input"),
        }
    }

    fn adv_one_one(input: &str) -> i32 {
        input.chars().map(inmap).sum()
    }

    #[test]
    fn one_one_test() {
        assert!(adv_one_one("(())") == 0);
        assert!(adv_one_one("()()") == 0);
        assert!(adv_one_one("(((") == 3);
        assert!(adv_one_one("(()(()(") == 3);
        assert!(adv_one_one("))(((((") == 3);
        assert!(adv_one_one("())") == -1);
        assert!(adv_one_one("))(") == -1);
        assert!(adv_one_one(")))") == -3);
        assert!(adv_one_one(")())())") == -3);
    }

    fn adv_one_two(input: &str, target: i32) -> i32 {
        input.chars()
             .map(inmap)
             .scan(0, |floor, direction| {
                 *floor += direction;
                 Some(*floor)
             })
             .position(|floor| floor == target)
             .unwrap() as i32 + 1
    }

    #[test]
    fn one_two_test() {
        assert!(adv_one_two(")", -1) == 1);
        assert!(adv_one_two("()())", -1) == 5);
    }
}

mod day2 {
    use std::io;
    use std::io::prelude::*;

    pub fn main(input: &str) -> io::Result<()> {
        println!("{}", adv_two_one(&input));
        println!("{}", adv_two_two(&input));
        Ok(())
    }

    fn adv_two_one(input: &str) -> u32 {
        fn pkg(l: u32, w: u32, h: u32) -> u32 {
            let sides = vec![l * w, w * h, h * l];
            let extra = sides.iter().min().unwrap();
            2 * l * w + 2 * w * h + 2 * h * l + extra
        }

        input.lines()
             .map(|line| {
                 let (l, w, h) = scan_fmt!(line, "{d}x{d}x{d}", u32, u32, u32);
                 pkg(l.unwrap(), w.unwrap(), h.unwrap())
             })
             .sum()
    }

    #[test]
    fn two_one_test() {
        assert!(adv_two_one("2x3x4") == 58);
        assert!(adv_two_one("1x1x10") == 43);
    }

    fn adv_two_two(input: &str) -> u32 {
        fn pkg(l: u32, w: u32, h: u32) -> u32 {
            let sides = vec![2 * l + 2 * w, 2 * w + 2 * h, 2 * h + 2 * l];
            let ribbon = sides.iter().min().unwrap();
            let bow = l * w * h;
            ribbon + bow
        }

        input.lines()
             .map(|line| {
                 let (l, w, h) = scan_fmt!(line, "{d}x{d}x{d}", u32, u32, u32);
                 pkg(l.unwrap(), w.unwrap(), h.unwrap())
             })
             .sum()
    }

    #[test]
    fn two_two_test() {
        assert!(adv_two_two("2x3x4") == 34);
        assert!(adv_two_two("1x1x10") == 14);
    }
}
<commit_msg>return strings, print from main, test against old solutions<commit_after>#![feature(iter_arith)] // sum is not stable?

use std::io;
use std::fs::File;
use std::io::prelude::*;

#[macro_use]
extern crate scan_fmt;

fn main() {
    try_main().unwrap()
}

fn try_main() -> io::Result<()> {
    let s = try!(run_from_file("input_1.txt", day1::main));
    s.iter().map(|s| println!("{}", s)).collect::<Vec<()>>();

    let s = try!(run_from_file("input_2.txt", day2::main));
    s.iter().map(|s| println!("{}", s)).collect::<Vec<()>>();

    Ok(())
}

fn run_from_file<F>(file: &str, it: F) -> io::Result<Vec<String>>
    where F: Fn(&str) -> Vec<String>
{
    let mut f = try!(File::open(file));
    let mut input = String::new();
    try!(f.read_to_string(&mut input));
    Ok(it(&input))
}

#[test]
fn verify_my_answers() {
    assert!(run_from_file("input_1.txt", day1::main).unwrap() == vec!["74", "1795"]);
    assert!(run_from_file("input_2.txt", day2::main).unwrap() == vec!["1586300", "3737498"]);
}

mod day1 {
    pub fn main(input: &str) -> Vec<String> {
        let s1 = adv_one_one(&input);
        let s2 = adv_one_two(&input, -1);
        vec![s1.to_string(), s2.to_string()]
    }

    fn inmap(c: char) -> i32 {
        match c {
            '(' => 1,
            ')' => -1,
            _ => panic!("invalid input"),
        }
    }

    fn adv_one_one(input: &str) -> i32 {
        input.chars().map(inmap).sum()
    }

    #[test]
    fn one_one_test() {
        assert!(adv_one_one("(())") == 0);
        assert!(adv_one_one("()()") == 0);
        assert!(adv_one_one("(((") == 3);
        assert!(adv_one_one("(()(()(") == 3);
        assert!(adv_one_one("))(((((") == 3);
        assert!(adv_one_one("())") == -1);
        assert!(adv_one_one("))(") == -1);
        assert!(adv_one_one(")))") == -3);
        assert!(adv_one_one(")())())") == -3);
    }

    fn adv_one_two(input: &str, target: i32) -> i32 {
        input.chars()
             .map(inmap)
             .scan(0, |floor, direction| {
                 *floor += direction;
                 Some(*floor)
             })
             .position(|floor| floor == target)
             .unwrap() as i32 + 1
    }

    #[test]
    fn one_two_test() {
        assert!(adv_one_two(")", -1) == 1);
        assert!(adv_one_two("()())", -1) == 5);
    }
}

mod day2 {
    pub fn main(input: &str) -> Vec<String> {
        let s1 = adv_two_one(&input);
        let s2 = adv_two_two(&input);
        vec![s1.to_string(), s2.to_string()]
    }

    fn adv_two_one(input: &str) -> u32 {
        fn pkg(l: u32, w: u32, h: u32) -> u32 {
            let sides = vec![l * w, w * h, h * l];
            let extra = sides.iter().min().unwrap();
            2 * l * w + 2 * w * h + 2 * h * l + extra
        }

        input.lines()
             .map(|line| {
                 let (l, w, h) = scan_fmt!(line, "{d}x{d}x{d}", u32, u32, u32);
                 pkg(l.unwrap(), w.unwrap(), h.unwrap())
             })
             .sum()
    }

    #[test]
    fn two_one_test() {
        assert!(adv_two_one("2x3x4") == 58);
        assert!(adv_two_one("1x1x10") == 43);
    }

    fn adv_two_two(input: &str) -> u32 {
        fn pkg(l: u32, w: u32, h: u32) -> u32 {
            let sides = vec![2 * l + 2 * w, 2 * w + 2 * h, 2 * h + 2 * l];
            let ribbon = sides.iter().min().unwrap();
            let bow = l * w * h;
            ribbon + bow
        }

        input.lines()
             .map(|line| {
                 let (l, w, h) = scan_fmt!(line, "{d}x{d}x{d}", u32, u32, u32);
                 pkg(l.unwrap(), w.unwrap(), h.unwrap())
             })
             .sum()
    }

    #[test]
    fn two_two_test() {
        assert!(adv_two_two("2x3x4") == 34);
        assert!(adv_two_two("1x1x10") == 14);
    }
}
<|endoftext|>


<commit_before>use crate::run::run;
use crate::verify::verify;
use clap::{crate_version, App, Arg, SubCommand};
use notify::DebouncedEvent;
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::ffi::OsStr;
use std::io::BufRead;
use std::sync::mpsc::channel;
use std::time::Duration;
use syntect::easy::HighlightFile;
use syntect::highlighting::{Style, ThemeSet};
use syntect::parsing::SyntaxSet;
use syntect::util::as_24_bit_terminal_escaped;

mod run;
mod util;
mod verify;

fn main() {
    let matches = App::new("rustlings")
        .version(crate_version!())
        .author("Olivia Hugger, Carol Nichols")
        .about("Rustlings is a collection of small exercises to get you used to writing and reading Rust code")
        .subcommand(SubCommand::with_name("verify").alias("v").about("Verifies all exercises according to the recommended order"))
        .subcommand(SubCommand::with_name("watch").alias("w").about("Reruns `verify` when files were edited"))
        .subcommand(
            SubCommand::with_name("run")
                .alias("r")
                .about("Runs/Tests a single exercise")
                .arg(Arg::with_name("file").required(true).index(1))
                .arg(Arg::with_name("test").short("t").long("test").help("Run the file as a test")),
        )
        .get_matches();

    let ss = SyntaxSet::load_defaults_newlines();
    let ts = ThemeSet::load_defaults();

    if None == matches.subcommand_name() {
        println!();
        println!(r#"       welcome to...                      "#);
        println!(r#"                 _   _ _                  "#);
        println!(r#"  _ __ _   _ ___| |_| (_)_ __   __ _ ___  "#);
        println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
        println!(r#" | |  | |_| \__ \ |_| | | | | | (_| \__ \ "#);
        println!(r#" |_|   \__,_|___/\__|_|_|_| |_|\__, |___/ "#);
        println!(r#"                               |___/      "#);
        println!();
    }

    if let Some(matches) = matches.subcommand_matches("run") {
        run(matches.clone()).unwrap();
    }

    if matches.subcommand_matches("verify").is_some() {
        match verify(None) {
            Ok(_) => {}
            Err(_) => std::process::exit(1),
        }
    }

    if matches.subcommand_matches("watch").is_some() {
        watch().unwrap();
    }

    if matches.subcommand_name().is_none() {
        let mut highlighter =
            HighlightFile::new("default_out.md", &ss, &ts.themes["base16-eighties.dark"]).unwrap();
        for maybe_line in highlighter.reader.lines() {
            let line = maybe_line.unwrap();
            let regions: Vec<(Style, &str)> = highlighter.highlight_lines.highlight(&line, &ss);
            println!("{}", as_24_bit_terminal_escaped(&regions[..], true));
        }
    }

    println!("\x1b[0m");
}

fn watch() -> notify::Result<()> {
    let (tx, rx) = channel();

    let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(2))?;
    watcher.watch("./exercises", RecursiveMode::Recursive)?;

    let _ignored = verify(None);

    loop {
        match rx.recv() {
            Ok(event) => match event {
                DebouncedEvent::Create(b) | DebouncedEvent::Chmod(b) | DebouncedEvent::Write(b) => {
                    if b.extension() == Some(OsStr::new("rs")) {
                        println!("----------**********----------");
                        println!();
                        let _ignored = verify(Some(b.as_path().to_str().unwrap()));
                    }
                }
                _ => {}
            },
            Err(e) => println!("watch error: {:?}", e),
        }
    }
}
<commit_msg>Change to \n<commit_after>use crate::run::run;
use crate::verify::verify;
use clap::{crate_version, App, Arg, SubCommand};
use notify::DebouncedEvent;
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::ffi::OsStr;
use std::io::BufRead;
use std::sync::mpsc::channel;
use std::time::Duration;
use syntect::easy::HighlightFile;
use syntect::highlighting::{Style, ThemeSet};
use syntect::parsing::SyntaxSet;
use syntect::util::as_24_bit_terminal_escaped;

mod run;
mod util;
mod verify;

fn main() {
    let matches = App::new("rustlings")
        .version(crate_version!())
        .author("Olivia Hugger, Carol Nichols")
        .about("Rustlings is a collection of small exercises to get you used to writing and reading Rust code")
        .subcommand(SubCommand::with_name("verify").alias("v").about("Verifies all exercises according to the recommended order"))
        .subcommand(SubCommand::with_name("watch").alias("w").about("Reruns `verify` when files were edited"))
        .subcommand(
            SubCommand::with_name("run")
                .alias("r")
                .about("Runs/Tests a single exercise")
                .arg(Arg::with_name("file").required(true).index(1))
                .arg(Arg::with_name("test").short("t").long("test").help("Run the file as a test")),
        )
        .get_matches();

    let ss = SyntaxSet::load_defaults_newlines();
    let ts = ThemeSet::load_defaults();

    if None == matches.subcommand_name() {
        println!();
        println!(r#"       welcome to...                      "#);
        println!(r#"                 _   _ _                  "#);
        println!(r#"  _ __ _   _ ___| |_| (_)_ __   __ _ ___  "#);
        println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
        println!(r#" | |  | |_| \__ \ |_| | | | | | (_| \__ \ "#);
        println!(r#" |_|   \__,_|___/\__|_|_|_| |_|\__, |___/ "#);
        println!(r#"                               |___/      "#);
        println!();
    }

    if let Some(matches) = matches.subcommand_matches("run") {
        run(matches.clone()).unwrap();
    }

    if matches.subcommand_matches("verify").is_some() {
        match verify(None) {
            Ok(_) => {}
            Err(_) => std::process::exit(1),
        }
    }

    if matches.subcommand_matches("watch").is_some() {
        watch().unwrap();
    }

    if matches.subcommand_name().is_none() {
        let mut highlighter =
            HighlightFile::new("default_out.md", &ss, &ts.themes["base16-eighties.dark"]).unwrap();
        for maybe_line in highlighter.reader.lines() {
            let line = maybe_line.unwrap();
            let regions: Vec<(Style, &str)> = highlighter.highlight_lines.highlight(&line, &ss);
            println!("{}", as_24_bit_terminal_escaped(&regions[..], true));
        }
    }

    println!("\x1b[0m");
}

fn watch() -> notify::Result<()> {
    let (tx, rx) = channel();

    let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(2))?;
    watcher.watch("./exercises", RecursiveMode::Recursive)?;

    let _ignored = verify(None);

    loop {
        match rx.recv() {
            Ok(event) => match event {
                DebouncedEvent::Create(b) | DebouncedEvent::Chmod(b) | DebouncedEvent::Write(b) => {
                    if b.extension() == Some(OsStr::new("rs")) {
                        println!("----------**********----------\n");
                        let _ignored = verify(Some(b.as_path().to_str().unwrap()));
                    }
                }
                _ => {}
            },
            Err(e) => println!("watch error: {:?}", e),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use self::WhichLine::*;

use std::fmt;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::Path;
use std::str::FromStr;

#[derive(Clone, Debug, PartialEq)]
pub enum ErrorKind {
    Help,
    Error,
    Note,
    Suggestion,
    Warning,
}

impl FromStr for ErrorKind {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match &s.trim_right_matches(':') as &str {
            "HELP" => Ok(ErrorKind::Help),
            "ERROR" => Ok(ErrorKind::Error),
            "NOTE" => Ok(ErrorKind::Note),
            "SUGGESTION" => Ok(ErrorKind::Suggestion),
            "WARN" => Ok(ErrorKind::Warning),
            "WARNING" => Ok(ErrorKind::Warning),
            _ => Err(()),
        }
    }
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ErrorKind::Help => write!(f, "help"),
            ErrorKind::Error => write!(f, "error"),
            ErrorKind::Note => write!(f, "note"),
            ErrorKind::Suggestion => write!(f, "suggestion"),
            ErrorKind::Warning => write!(f, "warning"),
        }
    }
}

pub struct ExpectedError {
    pub line_num: usize,
    /// What kind of message we expect (e.g. warning, error, suggestion).
    /// `None` if not specified or unknown message kind.
    pub kind: Option<ErrorKind>,
    pub msg: String,
}

#[derive(PartialEq, Debug)]
enum WhichLine { ThisLine, FollowPrevious(usize), AdjustBackward(usize) }

/// Looks for either "//~| KIND MESSAGE" or "//~^^... KIND MESSAGE"
/// The former is a "follow" that inherits its target from the preceding line;
/// the latter is an "adjusts" that goes that many lines up.
///
/// Goal is to enable tests both like: //~^^^ ERROR go up three
/// and also //~^ ERROR message one for the preceding line, and
///          //~| ERROR message two for that same line.
///
/// If cfg is not None (i.e., in an incremental test), then we look
/// for `//[X]~` instead, where `X` is the current `cfg`.
pub fn load_errors(testfile: &Path, cfg: Option<&str>) -> Vec<ExpectedError> {
    let rdr = BufReader::new(File::open(testfile).unwrap());

    // `last_nonfollow_error` tracks the most recently seen
    // line with an error template that did not use the
    // follow-syntax, "//~| ...".
    //
    // (pnkfelix could not find an easy way to compose Iterator::scan
    // and Iterator::filter_map to pass along this information into
    // `parse_expected`. So instead I am storing that state here and
    // updating it in the map callback below.)
    let mut last_nonfollow_error = None;

    let tag = match cfg {
        Some(rev) => format!("//[{}]~", rev),
        None => format!("//~")
    };

    rdr.lines()
       .enumerate()
       .filter_map(|(line_num, line)| {
           parse_expected(last_nonfollow_error,
                          line_num + 1,
                          &line.unwrap(),
                          &tag)
               .map(|(which, error)| {
                   match which {
                       FollowPrevious(_) => {}
                       _ => last_nonfollow_error = Some(error.line_num),
                   }
                   error
               })
       })
       .collect()
}

fn parse_expected(last_nonfollow_error: Option<usize>,
                  line_num: usize,
                  line: &str,
                  tag: &str)
                  -> Option<(WhichLine, ExpectedError)> {
    let start = match line.find(tag) { Some(i) => i, None => return None };
    let (follow, adjusts) = if line.char_at(start + tag.len()) == '|' {
        (true, 0)
    } else {
        (false, line[start + tag.len()..].chars().take_while(|c| *c == '^').count())
    };
    let kind_start = start + tag.len() + adjusts + (follow as usize);
    let letters = line[kind_start..].chars();
    let kind = letters.skip_while(|c| c.is_whitespace())
                      .take_while(|c| !c.is_whitespace())
                      .collect::<String>()
                      .parse::<ErrorKind>()
                      .ok();
    let letters = line[kind_start..].chars();
    let msg = letters.skip_while(|c| c.is_whitespace())
                     .skip_while(|c| !c.is_whitespace())
                     .collect::<String>().trim().to_owned();

    let (which, line_num) = if follow {
        assert!(adjusts == 0, "use either //~| or //~^, not both.");
        let line_num = last_nonfollow_error.expect("encountered //~| without \
                                                    preceding //~^ line.");
        (FollowPrevious(line_num), line_num)
    } else {
        let which =
            if adjusts > 0 { AdjustBackward(adjusts) } else { ThisLine };
        let line_num = line_num - adjusts;
        (which, line_num)
    };

    debug!("line={} tag={:?} which={:?} kind={:?} msg={:?}",
           line_num, tag, which, kind, msg);
    Some((which, ExpectedError { line_num: line_num,
                                 kind: kind,
                                 msg: msg, }))
}
<commit_msg>Refactor 'kind' extraction to use `str::split_whitespace`.<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use self::WhichLine::*;

use std::fmt;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::Path;
use std::str::FromStr;

#[derive(Clone, Debug, PartialEq)]
pub enum ErrorKind {
    Help,
    Error,
    Note,
    Suggestion,
    Warning,
}

impl FromStr for ErrorKind {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match &s.trim_right_matches(':') as &str {
            "HELP" => Ok(ErrorKind::Help),
            "ERROR" => Ok(ErrorKind::Error),
            "NOTE" => Ok(ErrorKind::Note),
            "SUGGESTION" => Ok(ErrorKind::Suggestion),
            "WARN" => Ok(ErrorKind::Warning),
            "WARNING" => Ok(ErrorKind::Warning),
            _ => Err(()),
        }
    }
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ErrorKind::Help => write!(f, "help"),
            ErrorKind::Error => write!(f, "error"),
            ErrorKind::Note => write!(f, "note"),
            ErrorKind::Suggestion => write!(f, "suggestion"),
            ErrorKind::Warning => write!(f, "warning"),
        }
    }
}

pub struct ExpectedError {
    pub line_num: usize,
    /// What kind of message we expect (e.g. warning, error, suggestion).
    /// `None` if not specified or unknown message kind.
    pub kind: Option<ErrorKind>,
    pub msg: String,
}

#[derive(PartialEq, Debug)]
enum WhichLine { ThisLine, FollowPrevious(usize), AdjustBackward(usize) }

/// Looks for either "//~| KIND MESSAGE" or "//~^^... KIND MESSAGE"
/// The former is a "follow" that inherits its target from the preceding line;
/// the latter is an "adjusts" that goes that many lines up.
///
/// Goal is to enable tests both like: //~^^^ ERROR go up three
/// and also //~^ ERROR message one for the preceding line, and
///          //~| ERROR message two for that same line.
///
/// If cfg is not None (i.e., in an incremental test), then we look
/// for `//[X]~` instead, where `X` is the current `cfg`.
pub fn load_errors(testfile: &Path, cfg: Option<&str>) -> Vec<ExpectedError> {
    let rdr = BufReader::new(File::open(testfile).unwrap());

    // `last_nonfollow_error` tracks the most recently seen
    // line with an error template that did not use the
    // follow-syntax, "//~| ...".
    //
    // (pnkfelix could not find an easy way to compose Iterator::scan
    // and Iterator::filter_map to pass along this information into
    // `parse_expected`. So instead I am storing that state here and
    // updating it in the map callback below.)
    let mut last_nonfollow_error = None;

    let tag = match cfg {
        Some(rev) => format!("//[{}]~", rev),
        None => format!("//~")
    };

    rdr.lines()
       .enumerate()
       .filter_map(|(line_num, line)| {
           parse_expected(last_nonfollow_error,
                          line_num + 1,
                          &line.unwrap(),
                          &tag)
               .map(|(which, error)| {
                   match which {
                       FollowPrevious(_) => {}
                       _ => last_nonfollow_error = Some(error.line_num),
                   }
                   error
               })
       })
       .collect()
}

fn parse_expected(last_nonfollow_error: Option<usize>,
                  line_num: usize,
                  line: &str,
                  tag: &str)
                  -> Option<(WhichLine, ExpectedError)> {
    let start = match line.find(tag) { Some(i) => i, None => return None };
    let (follow, adjusts) = if line.char_at(start + tag.len()) == '|' {
        (true, 0)
    } else {
        (false, line[start + tag.len()..].chars().take_while(|c| *c == '^').count())
    };
    let kind_start = start + tag.len() + adjusts + (follow as usize);
    let kind = line[kind_start..].split_whitespace()
                                 .next()
                                 .expect("Encountered unexpected empty comment")
                                 .parse::<ErrorKind>()
                                 .ok();
    let letters = line[kind_start..].chars();
    let msg = letters.skip_while(|c| c.is_whitespace())
                     .skip_while(|c| !c.is_whitespace())
                     .collect::<String>().trim().to_owned();

    let (which, line_num) = if follow {
        assert!(adjusts == 0, "use either //~| or //~^, not both.");
        let line_num = last_nonfollow_error.expect("encountered //~| without \
                                                    preceding //~^ line.");
        (FollowPrevious(line_num), line_num)
    } else {
        let which =
            if adjusts > 0 { AdjustBackward(adjusts) } else { ThisLine };
        let line_num = line_num - adjusts;
        (which, line_num)
    };

    debug!("line={} tag={:?} which={:?} kind={:?} msg={:?}",
           line_num, tag, which, kind, msg);
    Some((which, ExpectedError { line_num: line_num,
                                 kind: kind,
                                 msg: msg, }))
}
<|endoftext|>


<commit_before>#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate num;
extern crate rand;
extern crate bincode;
extern crate serde;
extern crate vec_map;
extern crate image;
extern crate euclid;
extern crate vitral;
extern crate vitral_atlas;
extern crate calx_alg;
extern crate calx_grid;
extern crate calx_color;
#[macro_use]
extern crate calx_ecs;
#[macro_use]
extern crate calx_resource;

mod ability;

mod brush;
pub use brush::{Brush, BrushBuilder, Color, Frame, ImageRef, Splat};

pub mod components;
mod field;
mod flags;
mod fov;
pub mod item;

mod location;
pub use location::{Location, Portal};

mod location_set;

mod query;
pub use query::Query;

mod spatial;
mod stats;
pub mod terrain;

mod world;
pub use world::World;

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum FovStatus {
    Seen,
    Remembered,
}

/// Light level value.
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub struct Light {
    lum: f32,
}

impl Light {
    pub fn new(lum: f32) -> Light {
        assert!(lum >= 0.0 && lum <= 2.0);
        Light { lum: lum }
    }

    pub fn apply(&self, color: calx_color::Rgba) -> calx_color::Rgba {
        let darkness_color = calx_color::Rgba::new(0.05, 0.10, 0.25, color.a);
        calx_alg::lerp(color * darkness_color, color, self.lum)
    }
}
<commit_msg>Remove half-baked Light type for now<commit_after>#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate num;
extern crate rand;
extern crate bincode;
extern crate serde;
extern crate vec_map;
extern crate image;
extern crate euclid;
extern crate vitral;
extern crate vitral_atlas;
extern crate calx_alg;
extern crate calx_grid;
extern crate calx_color;
#[macro_use]
extern crate calx_ecs;
#[macro_use]
extern crate calx_resource;

mod ability;

mod brush;
pub use brush::{Brush, BrushBuilder, Color, Frame, ImageRef, Splat};

pub mod components;
mod field;
mod flags;
mod fov;
pub mod item;

mod location;
pub use location::{Location, Portal};

mod location_set;

mod query;
pub use query::Query;

mod spatial;
mod stats;
pub mod terrain;

mod world;
pub use world::World;

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum FovStatus {
    Seen,
    Remembered,
}
<|endoftext|>


<commit_before>//! Solve linear diagonal dynamics

use ndarray::*;
use ndarray_linalg::Scalar;
use super::traits::*;

/// Linear ODE with diagonalized matrix (exactly solvable)
pub struct Diagonal<A, S, D>
    where A: Scalar,
          S: Data<Elem = A>,
          D: Dimension
{
    diag: ArrayBase<S, D>,
    diag_of_matrix: ArrayBase<S, D>,
    dt: A::Real,
}

impl<A, S, D> TimeStep for Diagonal<A, S, D>
    where A: Scalar,
          S: DataMut<Elem = A>,
          D: Dimension
{
    type Time = A::Real;

    fn get_dt(&self) -> Self::Time {
        self.dt
    }
    fn set_dt(&mut self, dt: Self::Time) {
        Zip::from(&mut self.diag)
            .and(&self.diag_of_matrix)
            .apply(|a, &b| { *a = b.mul_real(dt).exp(); });
    }
}

impl<A, S, D> ModelSize<D> for Diagonal<A, S, D>
    where A: Scalar,
          S: Data<Elem = A>,
          D: Dimension
{
    fn model_size(&self) -> D::Pattern {
        self.diag.dim()
    }
}

impl<A, S, D> Diagonal<A, S, D>
    where A: Scalar,
          S: DataClone<Elem = A> + DataMut,
          D: Dimension
{
    pub fn new(diag_of_matrix: ArrayBase<S, D>, dt: A::Real) -> Self {
        let mut diag = diag_of_matrix.clone();
        for v in diag.iter_mut() {
            *v = v.mul_real(dt).exp();
        }
        Diagonal {
            diag: diag,
            diag_of_matrix: diag_of_matrix,
            dt: dt,
        }
    }
}

impl<A, S, Sr, D> TimeEvolutionBase<Sr, D> for Diagonal<A, S, D>
    where A: Scalar,
          S: DataMut<Elem = A>,
          Sr: DataMut<Elem = A>,
          D: Dimension
{
    type Scalar = A;
    type Time = A::Real;

    fn iterate<'a>(&self, mut x: &'a mut ArrayBase<Sr, D>) -> &'a mut ArrayBase<Sr, D> {
        for (val, d) in x.iter_mut().zip(self.diag.iter()) {
            *val = *val * *d;
        }
        x
    }
}

impl<A, S, D> TimeEvolution<A, D> for Diagonal<A, S, D>
    where A: Scalar,
          D: Dimension,
          S: DataMut<Elem = A>
{
}
<commit_msg>Add Diagonal SemiImplicitLinear struct<commit_after>//! Solve linear diagonal dynamics

use ndarray::*;
use ndarray_linalg::Scalar;
use super::traits::*;

/// Linear ODE with diagonalized matrix (exactly solvable)
pub struct Diagonal<A, D>
    where A: Scalar,
          D: Dimension
{
    diag: Array<A, D>,
    diag_of_matrix: Array<A, D>,
    dt: A::Real,
}

impl<A, D> TimeStep for Diagonal<A, D>
    where A: Scalar,
          D: Dimension
{
    type Time = A::Real;

    fn get_dt(&self) -> Self::Time {
        self.dt
    }
    fn set_dt(&mut self, dt: Self::Time) {
        Zip::from(&mut self.diag)
            .and(&self.diag_of_matrix)
            .apply(|a, &b| { *a = b.mul_real(dt).exp(); });
    }
}

impl<A, D> ModelSize<D> for Diagonal<A, D>
    where A: Scalar,
          D: Dimension
{
    fn model_size(&self) -> D::Pattern {
        self.diag.dim()
    }
}

impl<A, D> Diagonal<A, D>
    where A: Scalar,
          D: Dimension
{
    pub fn new<S: Data<Elem = A>>(diag_of_matrix: &ArrayBase<S, D>, dt: A::Real) -> Self {
        let mut diag = diag_of_matrix.to_owned();
        for v in diag.iter_mut() {
            *v = v.mul_real(dt).exp();
        }
        Diagonal {
            diag: diag,
            diag_of_matrix: diag_of_matrix.to_owned(),
            dt: dt,
        }
    }
}

impl<A, Sr, D> SemiImplicitLinear<Sr, D> for Diagonal<A, D>
    where A: Scalar,
          Sr: DataMut<Elem = A>,
          D: Dimension
{
    type Scalar = A;

    fn lin<'a>(&self, mut x: &'a mut ArrayBase<Sr, D>) -> &'a mut ArrayBase<Sr, D> {
        for (val, d) in x.iter_mut().zip(self.diag.iter()) {
            *val = *val * *d;
        }
        x
    }
}
<|endoftext|>


<commit_before>
//! A module contains implementation of ease functions.

use std::num::{
    Float,
};

#[allow(missing_docs)]
#[derive(Copy, Clone, PartialEq)]
pub enum EaseFunction {
    QuadraticIn,
    QuadraticOut,
    QuadraticInOut,

    CubicIn,
    CubicOut,
    CubicInOut,

    QuarticIn,
    QuarticOut,
    QuarticInOut,

    QuinticIn,
    QuinticOut,
    QuinticInOut,

    SineIn,
    SineOut,
    SineInOut,

    CircularIn,
    CircularOut,
    CircularInOut,

    ExponentialIn,
    ExponentialOut,
    ExponentialInOut,

    ElasticIn,
    ElasticOut,
    ElasticInOut,

    BackIn,
    BackOut,
    BackInOut,

    BounceIn,
    BounceOut,
    BounceInOut,
}

#[allow(missing_docs)]
pub trait Ease {
    /// Calculate the eased value, normalized
    fn calc(self, f: EaseFunction) -> Self;

    fn quadratic_in(self) -> Self;
    fn quadratic_out(self) -> Self;
    fn quadratic_in_out(self) -> Self;

    fn cubic_in(self) -> Self;
    fn cubic_out(self) -> Self;
    fn cubic_in_out(self) -> Self;

    fn quartic_in(self) -> Self;
    fn quartic_out(self) -> Self;
    fn quartic_in_out(self) -> Self;

    fn quintic_in(self) -> Self;
    fn quintic_out(self) -> Self;
    fn quintic_in_out(self) -> Self;

    fn sine_in(self) -> Self;
    fn sine_out(self) -> Self;
    fn sine_in_out(self) -> Self;

    fn circular_in(self) -> Self;
    fn circular_out(self) -> Self;
    fn circular_in_out(self) -> Self;

    fn exponential_in(self) -> Self;
    fn exponential_out(self) -> Self;
    fn exponential_in_out(self) -> Self;

    fn elastic_in(self) -> Self;
    fn elastic_out(self) -> Self;
    fn elastic_in_out(self) -> Self;

    fn back_in(self) -> Self;
    fn back_out(self) -> Self;
    fn back_in_out(self) -> Self;

    fn bounce_in(self) -> Self;
    fn bounce_out(self) -> Self;
    fn bounce_in_out(self) -> Self;
}

macro_rules! impl_ease_trait_for {
    ($T: ident) => (
        impl Ease for $T {
            fn calc(self, f: EaseFunction) -> Self {
                match f {
                    EaseFunction::QuadraticIn => self.quadratic_in(),
                    EaseFunction::QuadraticOut => self.quadratic_out(),
                    EaseFunction::QuadraticInOut => self.quadratic_in_out(),

                    EaseFunction::CubicIn => self.cubic_in(),
                    EaseFunction::CubicOut => self.cubic_out(),
                    EaseFunction::CubicInOut => self.cubic_in_out(),

                    EaseFunction::QuarticIn => self.quartic_in(),
                    EaseFunction::QuarticOut => self.quartic_out(),
                    EaseFunction::QuarticInOut => self.quartic_in_out(),

                    EaseFunction::QuinticIn => self.quintic_in(),
                    EaseFunction::QuinticOut => self.quintic_out(),
                    EaseFunction::QuinticInOut => self.quintic_in_out(),

                    EaseFunction::SineIn => self.sine_in(),
                    EaseFunction::SineOut => self.sine_out(),
                    EaseFunction::SineInOut => self.sine_in_out(),

                    EaseFunction::CircularIn => self.circular_in(),
                    EaseFunction::CircularOut => self.circular_out(),
                    EaseFunction::CircularInOut => self.circular_in_out(),

                    EaseFunction::ExponentialIn => self.exponential_in(),
                    EaseFunction::ExponentialOut => self.exponential_out(),
                    EaseFunction::ExponentialInOut => self.exponential_in_out(),

                    EaseFunction::ElasticIn => self.elastic_in(),
                    EaseFunction::ElasticOut => self.elastic_out(),
                    EaseFunction::ElasticInOut => self.elastic_in_out(),

                    EaseFunction::BackIn => self.back_in(),
                    EaseFunction::BackOut => self.back_out(),
                    EaseFunction::BackInOut => self.back_in_out(),

                    EaseFunction::BounceIn => self.bounce_in(),
                    EaseFunction::BounceOut => self.bounce_out(),
                    EaseFunction::BounceInOut => self.bounce_in_out(),
                }
            }

            fn quadratic_in(self) -> Self {
                let p = normalized(self);
                p * p
            }

            fn quadratic_out(self) -> Self {
                let p = normalized(self);
                -(p * (p - 2.0))
            }

            fn quadratic_in_out(self) -> Self {
                let p = normalized(self);
                if p < 0.5 {
                    2.0 * p * p
                } else {
                    (-2.0 * p * p) + (4.0 * p) - 1.0
                }
            }

            fn cubic_in(self) -> Self {
                let p = normalized(self);
                p * p * p
            }

            fn cubic_out(self) -> Self {
                let p = normalized(self);
                let f = p - 1.0;
                f * f * f + 1.0
            }

            fn cubic_in_out(self) -> Self {
                let p = normalized(self);
                if p < 0.5 {
                    4.0 * p * p * p
                } else {
                    let f = (2.0 * p) - 2.0;
                    0.5 * f * f * f + 1.0
                }
            }

            fn quartic_in(self) -> Self {
                let p = normalized(self);
                p * p * p * p
            }

            fn quartic_out(self) -> Self {
                let p = normalized(self);
                let f = p - 1.0;
                f * f * f * (1.0 - p) + 1.0
            }

            fn quartic_in_out(self) -> Self {
                let p = normalized(self);
                if p < 0.5 {
                    8.0 * p * p * p * p
                } else {
                    let f = p - 1.0;
                    -8.0 * f * f * f * f + 1.0
                }
            }

            fn quintic_in(self) -> Self {
                let p = normalized(self);
                p * p * p * p * p
            }

            fn quintic_out(self) -> Self {
                let p = normalized(self);
                let f = p - 1.0;
                f * f * f * f * f + 1.0
            }

            fn quintic_in_out(self) -> Self {
                let p = normalized(self);
                if p < 0.5  {
                    16.0 * p * p * p * p * p
                } else {
                    let f = (2.0 * p) - 2.0;
                    0.5 * f * f * f * f * f + 1.0
                }
            }

            fn sine_in(self) -> Self {
                use std::$T::consts::PI_2;
                let p = normalized(self);
                ((p - 1.0) * PI_2).sin() + 1.0
            }

            fn sine_out(self) -> Self {
                use std::$T::consts::PI_2;
                let p = normalized(self);
                (p * PI_2).sin()
            }

            fn sine_in_out(self) -> Self {
                use std::$T::consts::PI;
                let p = normalized(self);
                0.5 * (1.0 - (p * PI).cos())
            }

            fn circular_in(self) -> Self {
                let p = normalized(self);
                1.0 - (1.0 - (p * p)).sqrt()
            }

            fn circular_out(self) -> Self {
                let p = normalized(self);
                ((2.0 - p) * p).sqrt()
            }

            fn circular_in_out(self) -> Self {
                let p = normalized(self);
                if p < 0.5 {
                    0.5 * (1.0 - (1.0 - 4.0 * (p * p)).sqrt())
                } else {
                    0.5 * ((-((2.0 * p) - 3.0) * ((2.0 * p) - 1.0)).sqrt() + 1.0)
                }
            }

            fn exponential_in(self) -> Self {
                let p = normalized(self);
                if p == 0.0 {
                    p
                } else {
                    2.0.powf(10.0 * (p - 1.0))
                }
            }

            fn exponential_out(self) -> Self {
                let p = normalized(self);
                if p == 1.0 {
                    p
                } else {
                    1.0 - 2.0.powf(-10.0 * p)
                }
            }

            fn exponential_in_out(self) -> Self {
                let p = normalized(self);
                if p == 0.0 || p == 1.0 {
                    return p;
                }

                if p < 0.5  {
                    0.5 * 2.0.powf((20.0 * p) - 10.0)
                } else {
                    -0.5 * 2.0.powf((-20.0 * p) + 10.0) + 1.0
                }
            }

            fn elastic_in(self) -> Self {
                use std::$T::consts::PI_2;
                let p = normalized(self);
                (13.0 * PI_2 * p).sin() * 2.0.powf(10.0 * (p - 1.0))
            }

            fn elastic_out(self) -> Self {
                use std::$T::consts::PI_2;
                let p = normalized(self);
                (-13.0 * PI_2 * (p + 1.0)).sin() * 2.0.powf(-10.0 * p) + 1.0
            }

            fn elastic_in_out(self) -> Self {
                use std::$T::consts::PI_2;
                let p = normalized(self);
                if p < 0.5 {
                    0.5 * (13.0 * PI_2 * (2.0 * p)).sin() * 2.0.powf(10.0 * ((2.0 * p) - 1.0))
                } else {
                    0.5 * ((-13.0 * PI_2 * ((2.0 * p - 1.0) + 1.0)).sin() * 2.0.powf(-10.0 * (2.0 * p - 1.0)) + 2.0)
                }
            }

            fn back_in(self) -> Self {
                use std::$T::consts::PI;
                let p = normalized(self);
                p * p * p - p * (p * PI).sin()
            }

            fn back_out(self) -> Self {
                use std::$T::consts::PI;
                let p = normalized(self);
                let f = 1.0 - p;
                1.0 - (f * f * f - f * (f * PI).sin())
            }

            fn back_in_out(self) -> Self {
                use std::$T::consts::PI;
                let p = normalized(self);
                if p < 0.5 {
                    let f = 2.0 * p;
                    0.5 * (f * f * f - f * (f * PI).sin())
                } else {
                    let f = 1.0 - (2.0 * p - 1.0);
                    0.5 * (1.0 - (f * f * f - f * (f * PI).sin())) + 0.5
                }
            }

            fn bounce_in(self) -> Self {
                let p = normalized(self);
                1.0 - Ease::bounce_out(1.0 - p)
            }

            fn bounce_out(self) -> Self {
                let p = normalized(self);
                if p < 4.0 / 11.0 {
                    (121.0 * p * p) / 16.0
                } else if p < 8.0 / 11.0 {
                    (363.0 / 40.0 * p * p) - (99.0 / 10.0 * p) + 17.0 / 5.0
                } else if p < 9.0 / 10.0 {
                    (4356.0 / 361.0 * p * p) - (35442.0 / 1805.0 * p) + 16061.0 / 1805.0
                } else {
                    (54.0 / 5.0 * p * p) - (513.0 / 25.0 * p) + 268.0 / 25.0
                }
            }

            fn bounce_in_out(self) -> Self {
                let p = normalized(self);
                if p < 0.5 {
                    0.5 * Ease::bounce_in(p * 2.0)
                } else {
                    0.5 * Ease::bounce_out(p * 2.0 - 1.0) + 0.5
                }
            }
        }
    )
}

impl_ease_trait_for!(f32);
impl_ease_trait_for!(f64);

fn normalized<T: Float>(p: T) -> T {
    if p > Float::one() {
        Float::one()
    } else if p < Float::zero() {
        Float::zero()
    } else {
        p
    }
}
<commit_msg>Renamed 'normalized' function to 'clamp'.<commit_after>
//! A module contains implementation of ease functions.

use std::num::{
    Float,
};

#[allow(missing_docs)]
#[derive(Copy, Clone, PartialEq)]
pub enum EaseFunction {
    QuadraticIn,
    QuadraticOut,
    QuadraticInOut,

    CubicIn,
    CubicOut,
    CubicInOut,

    QuarticIn,
    QuarticOut,
    QuarticInOut,

    QuinticIn,
    QuinticOut,
    QuinticInOut,

    SineIn,
    SineOut,
    SineInOut,

    CircularIn,
    CircularOut,
    CircularInOut,

    ExponentialIn,
    ExponentialOut,
    ExponentialInOut,

    ElasticIn,
    ElasticOut,
    ElasticInOut,

    BackIn,
    BackOut,
    BackInOut,

    BounceIn,
    BounceOut,
    BounceInOut,
}

#[allow(missing_docs)]
pub trait Ease {
    /// Calculate the eased value, normalized
    fn calc(self, f: EaseFunction) -> Self;

    fn quadratic_in(self) -> Self;
    fn quadratic_out(self) -> Self;
    fn quadratic_in_out(self) -> Self;

    fn cubic_in(self) -> Self;
    fn cubic_out(self) -> Self;
    fn cubic_in_out(self) -> Self;

    fn quartic_in(self) -> Self;
    fn quartic_out(self) -> Self;
    fn quartic_in_out(self) -> Self;

    fn quintic_in(self) -> Self;
    fn quintic_out(self) -> Self;
    fn quintic_in_out(self) -> Self;

    fn sine_in(self) -> Self;
    fn sine_out(self) -> Self;
    fn sine_in_out(self) -> Self;

    fn circular_in(self) -> Self;
    fn circular_out(self) -> Self;
    fn circular_in_out(self) -> Self;

    fn exponential_in(self) -> Self;
    fn exponential_out(self) -> Self;
    fn exponential_in_out(self) -> Self;

    fn elastic_in(self) -> Self;
    fn elastic_out(self) -> Self;
    fn elastic_in_out(self) -> Self;

    fn back_in(self) -> Self;
    fn back_out(self) -> Self;
    fn back_in_out(self) -> Self;

    fn bounce_in(self) -> Self;
    fn bounce_out(self) -> Self;
    fn bounce_in_out(self) -> Self;
}

macro_rules! impl_ease_trait_for {
    ($T: ident) => (
        impl Ease for $T {
            fn calc(self, f: EaseFunction) -> Self {
                match f {
                    EaseFunction::QuadraticIn => self.quadratic_in(),
                    EaseFunction::QuadraticOut => self.quadratic_out(),
                    EaseFunction::QuadraticInOut => self.quadratic_in_out(),

                    EaseFunction::CubicIn => self.cubic_in(),
                    EaseFunction::CubicOut => self.cubic_out(),
                    EaseFunction::CubicInOut => self.cubic_in_out(),

                    EaseFunction::QuarticIn => self.quartic_in(),
                    EaseFunction::QuarticOut => self.quartic_out(),
                    EaseFunction::QuarticInOut => self.quartic_in_out(),

                    EaseFunction::QuinticIn => self.quintic_in(),
                    EaseFunction::QuinticOut => self.quintic_out(),
                    EaseFunction::QuinticInOut => self.quintic_in_out(),

                    EaseFunction::SineIn => self.sine_in(),
                    EaseFunction::SineOut => self.sine_out(),
                    EaseFunction::SineInOut => self.sine_in_out(),

                    EaseFunction::CircularIn => self.circular_in(),
                    EaseFunction::CircularOut => self.circular_out(),
                    EaseFunction::CircularInOut => self.circular_in_out(),

                    EaseFunction::ExponentialIn => self.exponential_in(),
                    EaseFunction::ExponentialOut => self.exponential_out(),
                    EaseFunction::ExponentialInOut => self.exponential_in_out(),

                    EaseFunction::ElasticIn => self.elastic_in(),
                    EaseFunction::ElasticOut => self.elastic_out(),
                    EaseFunction::ElasticInOut => self.elastic_in_out(),

                    EaseFunction::BackIn => self.back_in(),
                    EaseFunction::BackOut => self.back_out(),
                    EaseFunction::BackInOut => self.back_in_out(),

                    EaseFunction::BounceIn => self.bounce_in(),
                    EaseFunction::BounceOut => self.bounce_out(),
                    EaseFunction::BounceInOut => self.bounce_in_out(),
                }
            }

            fn quadratic_in(self) -> Self {
                let p = clamp(self);
                p * p
            }

            fn quadratic_out(self) -> Self {
                let p = clamp(self);
                -(p * (p - 2.0))
            }

            fn quadratic_in_out(self) -> Self {
                let p = clamp(self);
                if p < 0.5 {
                    2.0 * p * p
                } else {
                    (-2.0 * p * p) + (4.0 * p) - 1.0
                }
            }

            fn cubic_in(self) -> Self {
                let p = clamp(self);
                p * p * p
            }

            fn cubic_out(self) -> Self {
                let p = clamp(self);
                let f = p - 1.0;
                f * f * f + 1.0
            }

            fn cubic_in_out(self) -> Self {
                let p = clamp(self);
                if p < 0.5 {
                    4.0 * p * p * p
                } else {
                    let f = (2.0 * p) - 2.0;
                    0.5 * f * f * f + 1.0
                }
            }

            fn quartic_in(self) -> Self {
                let p = clamp(self);
                p * p * p * p
            }

            fn quartic_out(self) -> Self {
                let p = clamp(self);
                let f = p - 1.0;
                f * f * f * (1.0 - p) + 1.0
            }

            fn quartic_in_out(self) -> Self {
                let p = clamp(self);
                if p < 0.5 {
                    8.0 * p * p * p * p
                } else {
                    let f = p - 1.0;
                    -8.0 * f * f * f * f + 1.0
                }
            }

            fn quintic_in(self) -> Self {
                let p = clamp(self);
                p * p * p * p * p
            }

            fn quintic_out(self) -> Self {
                let p = clamp(self);
                let f = p - 1.0;
                f * f * f * f * f + 1.0
            }

            fn quintic_in_out(self) -> Self {
                let p = clamp(self);
                if p < 0.5  {
                    16.0 * p * p * p * p * p
                } else {
                    let f = (2.0 * p) - 2.0;
                    0.5 * f * f * f * f * f + 1.0
                }
            }

            fn sine_in(self) -> Self {
                use std::$T::consts::PI_2;
                let p = clamp(self);
                ((p - 1.0) * PI_2).sin() + 1.0
            }

            fn sine_out(self) -> Self {
                use std::$T::consts::PI_2;
                let p = clamp(self);
                (p * PI_2).sin()
            }

            fn sine_in_out(self) -> Self {
                use std::$T::consts::PI;
                let p = clamp(self);
                0.5 * (1.0 - (p * PI).cos())
            }

            fn circular_in(self) -> Self {
                let p = clamp(self);
                1.0 - (1.0 - (p * p)).sqrt()
            }

            fn circular_out(self) -> Self {
                let p = clamp(self);
                ((2.0 - p) * p).sqrt()
            }

            fn circular_in_out(self) -> Self {
                let p = clamp(self);
                if p < 0.5 {
                    0.5 * (1.0 - (1.0 - 4.0 * (p * p)).sqrt())
                } else {
                    0.5 * ((-((2.0 * p) - 3.0) * ((2.0 * p) - 1.0)).sqrt() + 1.0)
                }
            }

            fn exponential_in(self) -> Self {
                let p = clamp(self);
                if p == 0.0 {
                    p
                } else {
                    2.0.powf(10.0 * (p - 1.0))
                }
            }

            fn exponential_out(self) -> Self {
                let p = clamp(self);
                if p == 1.0 {
                    p
                } else {
                    1.0 - 2.0.powf(-10.0 * p)
                }
            }

            fn exponential_in_out(self) -> Self {
                let p = clamp(self);
                if p == 0.0 || p == 1.0 {
                    return p;
                }

                if p < 0.5  {
                    0.5 * 2.0.powf((20.0 * p) - 10.0)
                } else {
                    -0.5 * 2.0.powf((-20.0 * p) + 10.0) + 1.0
                }
            }

            fn elastic_in(self) -> Self {
                use std::$T::consts::PI_2;
                let p = clamp(self);
                (13.0 * PI_2 * p).sin() * 2.0.powf(10.0 * (p - 1.0))
            }

            fn elastic_out(self) -> Self {
                use std::$T::consts::PI_2;
                let p = clamp(self);
                (-13.0 * PI_2 * (p + 1.0)).sin() * 2.0.powf(-10.0 * p) + 1.0
            }

            fn elastic_in_out(self) -> Self {
                use std::$T::consts::PI_2;
                let p = clamp(self);
                if p < 0.5 {
                    0.5 * (13.0 * PI_2 * (2.0 * p)).sin() * 2.0.powf(10.0 * ((2.0 * p) - 1.0))
                } else {
                    0.5 * ((-13.0 * PI_2 * ((2.0 * p - 1.0) + 1.0)).sin() * 2.0.powf(-10.0 * (2.0 * p - 1.0)) + 2.0)
                }
            }

            fn back_in(self) -> Self {
                use std::$T::consts::PI;
                let p = clamp(self);
                p * p * p - p * (p * PI).sin()
            }

            fn back_out(self) -> Self {
                use std::$T::consts::PI;
                let p = clamp(self);
                let f = 1.0 - p;
                1.0 - (f * f * f - f * (f * PI).sin())
            }

            fn back_in_out(self) -> Self {
                use std::$T::consts::PI;
                let p = clamp(self);
                if p < 0.5 {
                    let f = 2.0 * p;
                    0.5 * (f * f * f - f * (f * PI).sin())
                } else {
                    let f = 1.0 - (2.0 * p - 1.0);
                    0.5 * (1.0 - (f * f * f - f * (f * PI).sin())) + 0.5
                }
            }

            fn bounce_in(self) -> Self {
                let p = clamp(self);
                1.0 - Ease::bounce_out(1.0 - p)
            }

            fn bounce_out(self) -> Self {
                let p = clamp(self);
                if p < 4.0 / 11.0 {
                    (121.0 * p * p) / 16.0
                } else if p < 8.0 / 11.0 {
                    (363.0 / 40.0 * p * p) - (99.0 / 10.0 * p) + 17.0 / 5.0
                } else if p < 9.0 / 10.0 {
                    (4356.0 / 361.0 * p * p) - (35442.0 / 1805.0 * p) + 16061.0 / 1805.0
                } else {
                    (54.0 / 5.0 * p * p) - (513.0 / 25.0 * p) + 268.0 / 25.0
                }
            }

            fn bounce_in_out(self) -> Self {
                let p = clamp(self);
                if p < 0.5 {
                    0.5 * Ease::bounce_in(p * 2.0)
                } else {
                    0.5 * Ease::bounce_out(p * 2.0 - 1.0) + 0.5
                }
            }
        }
    )
}

impl_ease_trait_for!(f32);
impl_ease_trait_for!(f64);

fn clamp<T: Float>(p: T) -> T {
    if p > Float::one() {
        Float::one()
    } else if p < Float::zero() {
        Float::zero()
    } else {
        p
    }
}
<|endoftext|>


<commit_before>extern crate sdl2;
extern crate native;

use sdl2::video::{Window, PosCentered, OpenGL};
use sdl2::event::{QuitEvent, poll_event};
use sdl2::surface::{Surface};

#[start]
fn start(argc: int, argv: **u8) -> int {
    native::start(argc, argv, main)
}

#[main]
fn main() {
    sdl2::init(sdl2::InitEverything);

    let window  = match Window::new("eg03", PosCentered, PosCentered, 640, 480, OpenGL) {
        Ok(window) => window,
        Err(err)   => fail!("failed to create window: {}", err)
    };
    let renderer = match sdl2::render::Renderer::from_window(window, sdl2::render::DriverAuto, sdl2::render::Accelerated) {
        Ok(renderer) => renderer,
        Err(err) => fail!("failed to create renderer: {}", err)
    };

    // Load a surface.
    // Surfaces live in system RAM, so they aren't ideal for performance.
    let surface = match Surface::from_bmp(&Path::new("res/ice-troll.bmp")) {
        Ok(surface) => surface,
        Err(err)    => fail!("failed to load surface: {}", err)
    };

    // Convert a surface to a texture.
    // Textures can be used more efficiently by the GPU. (If one is available.)
    let texture = match renderer.create_texture_from_surface(&surface) {
        Ok(texture) => texture,
        Err(err)    => fail!("failed to convert surface: {}", err)
    };

    let _ = renderer.clear();
    // Display the texture.
    // Omitting the src & dst Rect arguments will cause our image to stretch across the entire buffer.
    // Try passing Some(surface.get_rect()) for src & dst instead of None & see how things change.
    let _ = renderer.copy(&texture, None, None);
    let _ = renderer.present();

    // loop until we receive a QuitEvent
    'event : loop {
        match poll_event() {
            QuitEvent(_) => break 'event,
            _            => continue
        }
    }

    sdl2::quit();
}

<commit_msg>Set correct title<commit_after>extern crate sdl2;
extern crate native;

use sdl2::video::{Window, PosCentered, OpenGL};
use sdl2::event::{QuitEvent, poll_event};
use sdl2::surface::{Surface};

#[start]
fn start(argc: int, argv: **u8) -> int {
    native::start(argc, argv, main)
}

#[main]
fn main() {
    sdl2::init(sdl2::InitEverything);

    let window  = match Window::new("eg04", PosCentered, PosCentered, 640, 480, OpenGL) {
        Ok(window) => window,
        Err(err)   => fail!("failed to create window: {}", err)
    };
    let renderer = match sdl2::render::Renderer::from_window(window, sdl2::render::DriverAuto, sdl2::render::Accelerated) {
        Ok(renderer) => renderer,
        Err(err) => fail!("failed to create renderer: {}", err)
    };

    // Load a surface.
    // Surfaces live in system RAM, so they aren't ideal for performance.
    let surface = match Surface::from_bmp(&Path::new("res/ice-troll.bmp")) {
        Ok(surface) => surface,
        Err(err)    => fail!("failed to load surface: {}", err)
    };

    // Convert a surface to a texture.
    // Textures can be used more efficiently by the GPU. (If one is available.)
    let texture = match renderer.create_texture_from_surface(&surface) {
        Ok(texture) => texture,
        Err(err)    => fail!("failed to convert surface: {}", err)
    };

    let _ = renderer.clear();
    // Display the texture.
    // Omitting the src & dst Rect arguments will cause our image to stretch across the entire buffer.
    // Try passing Some(surface.get_rect()) for src & dst instead of None & see how things change.
    let _ = renderer.copy(&texture, None, None);
    let _ = renderer.present();

    // loop until we receive a QuitEvent
    'event : loop {
        match poll_event() {
            QuitEvent(_) => break 'event,
            _            => continue
        }
    }

    sdl2::quit();
}

<|endoftext|>