<commit_before>use redox::*;

// TODO: Structure using loops
// TODO: Make capital commands doing the reverse of the command
//       Y: Yank before the cursor
//       D: Delete before the cursor.

use super::Mode;
use super::Mode::*;
use super::Editor;

// TODO: Move vars to `Editor`
pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window, swap: &mut usize, period: &mut String, is_recording: &mut bool, clipboard: &mut String) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match (*mode, key_event.character) {
                (Normal, '0') if !no_mult => times *= 10,

                (Normal, '1') if no_mult => times = 1,
                (Normal, '1') => times = times * 10 + 1,

                (Normal, '2') if no_mult => times = 2,
                (Normal, '2') => times = times * 10 + 2,

                (Normal, '3') if no_mult => times = 3,
                (Normal, '3') => times = times * 10 + 3,

                (Normal, '4') if no_mult => times = 4,
                (Normal, '4') => times = times * 10 + 4,

                (Normal, '5') if no_mult => times = 5,
                (Normal, '5') => times = times * 10 + 5,

                (Normal, '6') if no_mult => times = 6,
                (Normal, '6') => times = times * 10 + 6,

                (Normal, '7') if no_mult => times = 7,
                (Normal, '7') => times = times * 10 + 7,

                (Normal, '8') if no_mult => times = 8,
                (Normal, '8') => times = times * 10 + 8,

                (Normal, '9') if no_mult => times = 9,
                (Normal, '9') => times = times * 10 + 9,
                (_, _) => {
                    if *is_recording {
                        if key_event.character == ',' {
                            *is_recording = false;
                        } else {
                            period.push(key_event.character);
                        }
                    } else {
                        for _ in 0 .. times {
                            match (m, key_event.character) {
                                (Normal, 'i') => {
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'h') => editor.left(),
                                (Normal, 'l') => editor.right(),
                                (Normal, 'k') | (Normal, ' ') => editor.up(),
                                (Normal, 'j') | (Normal, '\n') => editor.down(),
                                (Normal, 'K') => {
                                    for _ in 1..15 {
                                        editor.up();
                                    }
                                },
                                (Normal, 'J') => {
                                    for _ in 1..15 {
                                        editor.down();
                                    }
                                },
                                (Normal, 'g') => editor.offset = 0,
                                (Normal, 'G') => editor.offset = editor.string.len(),
                                (Normal, 'a') => {
                                    editor.right();
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'x') => editor.delete(window),
                                (Normal, 'X') => editor.backspace(window),
                                (Normal, 'u') => {
                                    editor.offset = 0;
                                    ::core::mem::swap(last_change, &mut editor.string);
                                },
                                (Normal, 'c') => {
                                    ::core::mem::swap(&mut editor.offset, swap);
                                },
                                (Normal, 'z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = clipboard.clone().to_string() + &editor.cur().to_string();
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'Z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset >= 0 {
                                        clipboard.push(editor.cur());
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 's') => {
                                    editor.delete(window);
                                    *mode = Insert;
                                },
                                (Normal, 'o') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                    editor.insert('\n', window);
                                    *mode = Insert;
                                },
                                (Normal, 'O') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.insert('\n', window);
                                    editor.left();
                                    *mode = Insert;
                                },
                                (Normal, '^') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 0 {
                                        editor.left();
                                    }
                                    editor.right();
                                    while (editor.cur() == ' ' ||
                                          editor.cur() == '\t') &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        clipboard.push(editor.cur());
                                        editor.right();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.left();
                                    }
                                },
                                (Normal, 'Y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = editor.cur().to_string() + clipboard;
                                        editor.left();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.right();
                                    }
                                },
                                (Normal, 'p') => {
                                    for c in clipboard.chars() {
                                        editor.insert(c, window);
                                    }
                                },
                                (Normal, '$') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal,  '0') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'd') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'D') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'w') => {
                                    editor.save(window);
                                },
                                (Normal, 'e') => {
                                    editor.right();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'b') => {
                                    editor.left();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, 'E') => {
                                    editor.right();
                                    while editor.cur() != ' ' && editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'B') => {
                                    editor.left();
                                    while editor.cur() != ' ' && editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, ',') => {
                                    *is_recording = true;
                                    *period = String::new();
                                },
                                (Normal, '%') => {
                                    match editor.cur() {
                                        '(' | '[' | '{' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.right();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => 1,
                                                    ')' | ']' | '}' => -1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        ')' | ']' | '}' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.left();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => -1,
                                                    ')' | ']' | '}' => 1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        _ => {},

                                    }
                                },
                                (Normal, '!') => {
                                    for c in period.clone().chars() {
                                        exec(editor, mode, multiplier, last_change, KeyEvent {
                                            character: c,
                                            scancode: 0,
                                            pressed: true,
                                        }, window, swap, period, is_recording, clipboard);
                                    }
                                },
                                (Insert, '\0') => (),
                                (Insert, c) => {
                                    editor.insert(c, window);
                                },
                                _ => {},
                            }
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<commit_msg>Fix alias<commit_after> use redox::*;

// TODO: Structure using loops
// TODO: Make capital commands doing the reverse of the command
//       Y: Yank before the cursor
//       D: Delete before the cursor.

use super::Mode;
use super::Mode::*;
use super::Editor;

// TODO: Move vars to `Editor`
pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window, swap: &mut usize, period: &mut String, is_recording: &mut bool, clipboard: &mut String) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match (*mode, key_event.character) {
                (Normal, '0') if !no_mult => times *= 10,

                (Normal, '1') if no_mult => times = 1,
                (Normal, '1') => times = times * 10 + 1,

                (Normal, '2') if no_mult => times = 2,
                (Normal, '2') => times = times * 10 + 2,

                (Normal, '3') if no_mult => times = 3,
                (Normal, '3') => times = times * 10 + 3,

                (Normal, '4') if no_mult => times = 4,
                (Normal, '4') => times = times * 10 + 4,

                (Normal, '5') if no_mult => times = 5,
                (Normal, '5') => times = times * 10 + 5,

                (Normal, '6') if no_mult => times = 6,
                (Normal, '6') => times = times * 10 + 6,

                (Normal, '7') if no_mult => times = 7,
                (Normal, '7') => times = times * 10 + 7,

                (Normal, '8') if no_mult => times = 8,
                (Normal, '8') => times = times * 10 + 8,

                (Normal, '9') if no_mult => times = 9,
                (Normal, '9') => times = times * 10 + 9,
                (_, _) => {
                    if *is_recording {
                        if key_event.character == ',' {
                            *is_recording = false;
                        } else {
                            period.push(key_event.character);
                        }
                    } else {
                        for _ in 0 .. times {
                            match (m, key_event.character) {
                                (Normal, 'i') => {
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'h') | (Normal, ' ') => editor.left(),
                                (Normal, 'l') => editor.right(),
                                (Normal, 'k') => editor.up(),
                                (Normal, 'j') | (Normal, '\n') => editor.down(),
                                (Normal, 'K') => {
                                    for _ in 1..15 {
                                        editor.up();
                                    }
                                },
                                (Normal, 'J') => {
                                    for _ in 1..15 {
                                        editor.down();
                                    }
                                },
                                (Normal, 'g') => editor.offset = 0,
                                (Normal, 'G') => editor.offset = editor.string.len(),
                                (Normal, 'a') => {
                                    editor.right();
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'x') => editor.delete(window),
                                (Normal, 'X') => editor.backspace(window),
                                (Normal, 'u') => {
                                    editor.offset = 0;
                                    ::core::mem::swap(last_change, &mut editor.string);
                                },
                                (Normal, 'c') => {
                                    ::core::mem::swap(&mut editor.offset, swap);
                                },
                                (Normal, 'z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = clipboard.clone().to_string() + &editor.cur().to_string();
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'Z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset >= 0 {
                                        clipboard.push(editor.cur());
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 's') => {
                                    editor.delete(window);
                                    *mode = Insert;
                                },
                                (Normal, 'o') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                    editor.insert('\n', window);
                                    *mode = Insert;
                                },
                                (Normal, 'O') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.insert('\n', window);
                                    editor.left();
                                    *mode = Insert;
                                },
                                (Normal, '^') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 0 {
                                        editor.left();
                                    }
                                    editor.right();
                                    while (editor.cur() == ' ' ||
                                          editor.cur() == '\t') &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        clipboard.push(editor.cur());
                                        editor.right();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.left();
                                    }
                                },
                                (Normal, 'Y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = editor.cur().to_string() + clipboard;
                                        editor.left();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.right();
                                    }
                                },
                                (Normal, 'p') => {
                                    for c in clipboard.chars() {
                                        editor.insert(c, window);
                                    }
                                },
                                (Normal, '$') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal,  '0') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'd') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'D') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'w') => {
                                    editor.save(window);
                                },
                                (Normal, 'e') => {
                                    editor.right();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'b') => {
                                    editor.left();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, 'E') => {
                                    editor.right();
                                    while editor.cur() != ' ' && editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'B') => {
                                    editor.left();
                                    while editor.cur() != ' ' && editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, ',') => {
                                    *is_recording = true;
                                    *period = String::new();
                                },
                                (Normal, '%') => {
                                    match editor.cur() {
                                        '(' | '[' | '{' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.right();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => 1,
                                                    ')' | ']' | '}' => -1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        ')' | ']' | '}' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.left();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => -1,
                                                    ')' | ']' | '}' => 1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        _ => {},

                                    }
                                },
                                (Normal, '!') => {
                                    for c in period.clone().chars() {
                                        exec(editor, mode, multiplier, last_change, KeyEvent {
                                            character: c,
                                            scancode: 0,
                                            pressed: true,
                                        }, window, swap, period, is_recording, clipboard);
                                    }
                                },
                                (Insert, '\0') => (),
                                (Insert, c) => {
                                    editor.insert(c, window);
                                },
                                _ => {},
                            }
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>chore: borrow checker?! crash in my heart.<commit_after><|endoftext|>


<commit_before><commit_msg>Implement replaced abspos<commit_after><|endoftext|>


<commit_before><commit_msg>Add documentation to StoreId type<commit_after><|endoftext|>


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

#![cfg(not(test))]

#[macro_use]
extern crate log;
extern crate rustfmt;
extern crate toml;
extern crate env_logger;
extern crate getopts;

use rustfmt::{WriteMode, run, run_from_stdin};
use rustfmt::config::Config;

use std::env;
use std::fs::{self, File};
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};

use getopts::Options;

/// Rustfmt operations.
enum Operation {
    /// Format a file and its child modules.
    Format(PathBuf, WriteMode),
    /// Print the help message.
    Help,
    /// Print detailed configuration help.
    ConfigHelp,
    /// Invalid program input, including reason.
    InvalidInput(String),
    /// No file specified, read from stdin
    Stdin(String, WriteMode),
}

/// Try to find a project file in the input file directory and its parents.
fn lookup_project_file(input_file: &Path) -> io::Result<PathBuf> {
    let mut current = if input_file.is_relative() {
        try!(env::current_dir()).join(input_file)
    } else {
        input_file.to_path_buf()
    };

    // FIXME: We should canonize path to properly handle its parents,
    // but `canonicalize` function is unstable now (recently added API)
    // current = try!(fs::canonicalize(current));

    loop {
        let config_file = current.join("rustfmt.toml");
        if fs::metadata(&config_file).is_ok() {
            return Ok(config_file);
        }

        // If the current directory has no parent, we're done searching.
        if !current.pop() {
            return Err(io::Error::new(io::ErrorKind::NotFound, "Config not found"));
        }
    }
}

/// Try to find a project file. If it's found, read it.
fn lookup_and_read_project_file(input_file: &Path) -> io::Result<(PathBuf, String)> {
    let path = try!(lookup_project_file(input_file));
    let mut file = try!(File::open(&path));
    let mut toml = String::new();
    try!(file.read_to_string(&mut toml));
    Ok((path, toml))
}

fn execute() -> i32 {
    let mut opts = Options::new();
    opts.optflag("h", "help", "show this message");
    opts.optopt("",
                "write-mode",
                "mode to write in (not usable when piping from stdin)",
                "[replace|overwrite|display|diff|coverage]");

    opts.optflag("",
                 "config-help",
                 "show details of rustfmt configuration options");

    let operation = determine_operation(&opts, env::args().skip(1));

    match operation {
        Operation::InvalidInput(reason) => {
            print_usage(&opts, &reason);
            1
        }
        Operation::Help => {
            print_usage(&opts, "");
            0
        }
        Operation::ConfigHelp => {
            Config::print_docs();
            0
        }
        Operation::Stdin(input, write_mode) => {
            // try to read config from local directory
            let config = match lookup_and_read_project_file(&Path::new(".")) {
                Ok((_, toml)) => {
                    Config::from_toml(&toml)
                }
                Err(_) => Default::default(),
            };

            run_from_stdin(input, write_mode, &config);
            0
        }
        Operation::Format(file, write_mode) => {
            let config = match lookup_and_read_project_file(&file) {
                Ok((path, toml)) => {
                    println!("Using rustfmt config file: {}", path.display());
                    Config::from_toml(&toml)
                }
                Err(_) => Default::default(),
            };

            run(&file, write_mode, &config);
            0
        }
    }
}

fn main() {
    let _ = env_logger::init();
    let exit_code = execute();

    // Make sure standard output is flushed before we exit.
    std::io::stdout().flush().unwrap();

    // Exit with given exit code.
    //
    // NOTE: This immediately terminates the process without doing any cleanup,
    // so make sure to finish all necessary cleanup before this is called.
    std::process::exit(exit_code);
}

fn print_usage(opts: &Options, reason: &str) {
    let reason = format!("{}\nusage: {} [options] <file>",
                         reason,
                         env::current_exe().unwrap().display());
    println!("{}", opts.usage(&reason));
}

fn determine_operation<I>(opts: &Options, args: I) -> Operation
    where I: Iterator<Item = String>
{
    let matches = match opts.parse(args) {
        Ok(m) => m,
        Err(e) => return Operation::InvalidInput(e.to_string()),
    };

    if matches.opt_present("h") {
        return Operation::Help;
    }

    if matches.opt_present("config-help") {
        return Operation::ConfigHelp;
    }

    // if no file argument is supplied, read from stdin
    if matches.free.len() == 0 {

        let mut buffer = String::new();
        match io::stdin().read_to_string(&mut buffer) {
            Ok(..) => (),
            Err(e) => return Operation::InvalidInput(e.to_string()),
        }

        // WriteMode is always plain for Stdin
        return Operation::Stdin(buffer, WriteMode::Plain);
    }

    let write_mode = match matches.opt_str("write-mode") {
        Some(mode) => {
            match mode.parse() {
                Ok(mode) => mode,
                Err(..) => return Operation::InvalidInput("Unrecognized write mode".into()),
            }
        }
        None => WriteMode::Replace,
    };

    Operation::Format(PathBuf::from(&matches.free[0]), write_mode)
}
<commit_msg>Enable rustfmt to format a list of files<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg(not(test))]

#[macro_use]
extern crate log;
extern crate rustfmt;
extern crate toml;
extern crate env_logger;
extern crate getopts;

use rustfmt::{WriteMode, run, run_from_stdin};
use rustfmt::config::Config;

use std::env;
use std::fs::{self, File};
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};

use getopts::Options;

/// Rustfmt operations.
enum Operation {
    /// Format files and its child modules.
    Format(Vec<PathBuf>, WriteMode),
    /// Print the help message.
    Help,
    /// Print detailed configuration help.
    ConfigHelp,
    /// Invalid program input, including reason.
    InvalidInput(String),
    /// No file specified, read from stdin
    Stdin(String, WriteMode),
}

/// Try to find a project file in the input file directory and its parents.
fn lookup_project_file(input_file: &Path) -> io::Result<PathBuf> {
    let mut current = if input_file.is_relative() {
        try!(env::current_dir()).join(input_file)
    } else {
        input_file.to_path_buf()
    };

    // FIXME: We should canonize path to properly handle its parents,
    // but `canonicalize` function is unstable now (recently added API)
    // current = try!(fs::canonicalize(current));

    loop {
        let config_file = current.join("rustfmt.toml");
        if fs::metadata(&config_file).is_ok() {
            return Ok(config_file);
        }

        // If the current directory has no parent, we're done searching.
        if !current.pop() {
            return Err(io::Error::new(io::ErrorKind::NotFound, "Config not found"));
        }
    }
}

/// Try to find a project file. If it's found, read it.
fn lookup_and_read_project_file(input_file: &Path) -> io::Result<(PathBuf, String)> {
    let path = try!(lookup_project_file(input_file));
    let mut file = try!(File::open(&path));
    let mut toml = String::new();
    try!(file.read_to_string(&mut toml));
    Ok((path, toml))
}

fn execute() -> i32 {
    let mut opts = Options::new();
    opts.optflag("h", "help", "show this message");
    opts.optopt("",
                "write-mode",
                "mode to write in (not usable when piping from stdin)",
                "[replace|overwrite|display|diff|coverage]");

    opts.optflag("",
                 "config-help",
                 "show details of rustfmt configuration options");

    let operation = determine_operation(&opts, env::args().skip(1));

    match operation {
        Operation::InvalidInput(reason) => {
            print_usage(&opts, &reason);
            1
        }
        Operation::Help => {
            print_usage(&opts, "");
            0
        }
        Operation::ConfigHelp => {
            Config::print_docs();
            0
        }
        Operation::Stdin(input, write_mode) => {
            // try to read config from local directory
            let config = match lookup_and_read_project_file(&Path::new(".")) {
                Ok((_, toml)) => {
                    Config::from_toml(&toml)
                }
                Err(_) => Default::default(),
            };

            run_from_stdin(input, write_mode, &config);
            0
        }
        Operation::Format(files, write_mode) => {
            for file in files {
                let config = match lookup_and_read_project_file(&file) {
                    Ok((path, toml)) => {
                        println!("Using rustfmt config file {} for {}",
                                 path.display(),
                                 file.display());
                        Config::from_toml(&toml)
                    }
                    Err(_) => Default::default(),
                };

                run(&file, write_mode, &config);
            }
            0
        }
    }
}

fn main() {
    let _ = env_logger::init();
    let exit_code = execute();

    // Make sure standard output is flushed before we exit.
    std::io::stdout().flush().unwrap();

    // Exit with given exit code.
    //
    // NOTE: This immediately terminates the process without doing any cleanup,
    // so make sure to finish all necessary cleanup before this is called.
    std::process::exit(exit_code);
}

fn print_usage(opts: &Options, reason: &str) {
    let reason = format!("{}\nusage: {} [options] <file>...",
                         reason,
                         env::current_exe().unwrap().display());
    println!("{}", opts.usage(&reason));
}

fn determine_operation<I>(opts: &Options, args: I) -> Operation
    where I: Iterator<Item = String>
{
    let matches = match opts.parse(args) {
        Ok(m) => m,
        Err(e) => return Operation::InvalidInput(e.to_string()),
    };

    if matches.opt_present("h") {
        return Operation::Help;
    }

    if matches.opt_present("config-help") {
        return Operation::ConfigHelp;
    }

    // if no file argument is supplied, read from stdin
    if matches.free.len() == 0 {

        let mut buffer = String::new();
        match io::stdin().read_to_string(&mut buffer) {
            Ok(..) => (),
            Err(e) => return Operation::InvalidInput(e.to_string()),
        }

        // WriteMode is always plain for Stdin
        return Operation::Stdin(buffer, WriteMode::Plain);
    }

    let write_mode = match matches.opt_str("write-mode") {
        Some(mode) => {
            match mode.parse() {
                Ok(mode) => mode,
                Err(..) => return Operation::InvalidInput("Unrecognized write mode".into()),
            }
        }
        None => WriteMode::Replace,
    };

    let mut files = Vec::with_capacity(matches.free.len());

    for arg in matches.free {
        files.push(PathBuf::from(arg));
    }

    Operation::Format(files, write_mode)
}
<|endoftext|>


<commit_before><commit_msg>Add entry method to SignatureMap.<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unused imports. Partial fix for #18.<commit_after><|endoftext|>


<commit_before><commit_msg>Replace r#try! with the ? operator<commit_after><|endoftext|>


<commit_before><commit_msg>Sample executable<commit_after>
extern crate ndarray;
extern crate ndarray_odeint;
extern crate itertools;
extern crate simple_complex;
extern crate num_traits;

use ndarray::rcarr1;
use itertools::iterate;
use ndarray_odeint::prelude::*;
use simple_complex::c64;
use num_traits::Zero;

fn main() {
    let dt = 1e-5;
    let eom = GoyShell::default();
    let teo = semi_implicit::diag_rk4(eom, dt);
    let x0 = rcarr1(&vec![c64::zero(); 27]);
    let ts = iterate(x0, |y| teo.iterate(y.clone()));
    let end_time = 10000;
    for (_, v) in ts.take(end_time).enumerate() {
        println!("{:?}", v);
    }
}
<|endoftext|>


<commit_before><commit_msg>filter! is now correctly exported<commit_after><|endoftext|>


<commit_before><commit_msg>Solve problem 2351<commit_after>// https://leetcode.com/problems/first-letter-to-appear-twice/
pub fn repeated_character(s: String) -> char {
    let mut char_counts = vec![0; 26];
    let chars: Vec<char> = s.chars().into_iter().collect();
    for c in chars.iter() {
        char_counts[*c as usize - 'a' as usize] += 1;
        if char_counts[*c as usize - 'a' as usize] == 2 {
            return *c;
        }
    }
    panic!()
}

fn main() {
    println!("{}", repeated_character("abccbaacz".to_string())); // "c"
    println!("{}", repeated_character("abcdd".to_string())); // "d"
}
<|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2395<commit_after>// https://leetcode.com/problems/find-subarrays-with-equal-sum/
pub fn find_subarrays(nums: Vec<i32>) -> bool {
    todo!()
}

fn main() {
    println!("{}", find_subarrays(vec![4, 2, 4])); // true
    println!("{}", find_subarrays(vec![1, 2, 3, 4, 5])); // false
    println!("{}", find_subarrays(vec![0, 0, 0])); // true
}
<|endoftext|>


<commit_before>pub fn editor(source: &str) -> String {
    format!("

<button class=\"btn btn-primary\" type=\"button\" id=\"run-code\">Run</button>
<button class=\"btn btn-primary\" type=\"button\" id=\"reset-code\">Reset</button>

{}

", escape(source))
}

fn escape(source: &str) -> String {
    let mut s = String::new();

    for chr in source.trim().chars() {
        match chr {
            '*' => s.push_str("*"),
            '<' => s.push_str("<"),
            '>' => s.push_str(">"),
            '\\' => s.push_str("\"),
            '_' => s.push_str("_"),
            '`' => s.push_str("`"),
            chr => s.push(chr),
        }
    }

    s
}
<commit_msg>Allow '$' in rust files<commit_after>pub fn editor(source: &str) -> String {
    format!("

<button class=\"btn btn-primary\" type=\"button\" id=\"run-code\">Run</button>
<button class=\"btn btn-primary\" type=\"button\" id=\"reset-code\">Reset</button>

{}

", escape(source))
}

fn escape(source: &str) -> String {
    let mut s = String::new();

    for chr in source.trim().chars() {
        match chr {
            '$' => s.push_str("$"),
            '*' => s.push_str("*"),
            '<' => s.push_str("<"),
            '>' => s.push_str(">"),
            '\\' => s.push_str("\"),
            '_' => s.push_str("_"),
            '`' => s.push_str("`"),
            chr => s.push(chr),
        }
    }

    s
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #29273 - Manishearth:regression, r=alexcrichton<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::sync::{self, Arc}; //~ NOTE previous import
                            //~^ NOTE previous import
use std::sync::Arc; //~ ERROR a type named
use std::sync; //~ ERROR a module named

fn main() {
}
<|endoftext|>


<commit_before><commit_msg>Add test for #28324<commit_after>// Copyright 2016 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.

extern {
    static error_message_count: u32;
}

pub static BAZ: u32 = *&error_message_count;
//~^ ERROR cannot refer to other statics by value

fn main() {}
<|endoftext|>


<commit_before><commit_msg>test for issue #77175<commit_after>#[deny(single_use_lifetimes)]
// edition:2018
// check-pass

// Prior to the fix, the compiler complained that the 'a lifetime was only used
// once. This was obviously wrong since the lifetime is used twice: For the s3
// parameter and the return type. The issue was caused by the compiler
// desugaring the async function into a generator that uses only a single
// lifetime, which then the validator complained about becauase of the
// single_use_lifetimes constraints.
async fn bar<'a>(s1: String, s2: &'_ str, s3: &'a str) -> &'a str {
    s3
}

fn foo<'a>(s1: String, s2: &'_ str, s3: &'a str) -> &'a str {
    s3
}

fn main() {}
<|endoftext|>


<commit_before>use redox::{Box, String, Vec};

use super::avl;
use super::nvpair::NvList;
use super::vdev;
use super::zfs;

pub enum ImportType {
    Existing,
    Assemble,
}

// Storage pool allocator
pub struct Spa {
    name: String, // Pool name
    state: zfs::PoolState,
    load_state: zfs::SpaLoadState,
    root_vdev: vdev::Vdev,
}

impl Spa {
    // TODO
    /*pub fn create(name: String, config: NvList) -> Self {
        let root_vdev = vdev::Vdev::new();
        Self::new(name, root_vdev)
    }*/

    pub fn open(&mut self) -> zfs::Result<()> {
        let load_state = zfs::SpaLoadState::Open;
        if self.state == zfs::PoolState::Uninitialized {
            // First time opening

            self.activate();

            try!(self.load(load_state, ImportType::Existing, false));

        }

        Ok(())
    }

    fn new(name: String, root_vdev: vdev::Vdev) -> Self {
        Spa {
            name: name,
            state: zfs::PoolState::Uninitialized,
            load_state: zfs::SpaLoadState::None,
            root_vdev: root_vdev,
        }
    }

    fn load(&mut self, load_state: zfs::SpaLoadState,
            import_type: ImportType, mos_config: bool) -> zfs::Result<()> {
        let ref config = NvList::new(0); // TODO: this should be replaced by self.config

        let pool_guid = try!(config.get("pool_guid").ok_or(zfs::Error::Invalid));

        self.load_impl(pool_guid, config, load_state, import_type, mos_config);
        self.load_state = zfs::SpaLoadState::None;

        Ok(())
    }

    /// mosconfig: Whether `config` came from on-disk MOS and so is trusted, or was user-made and so
    /// is untrusted.
    fn load_impl(&mut self, pool_guid: u64, config: &NvList, load_state: zfs::SpaLoadState,
                 import_type: ImportType, mos_config: bool) -> zfs::Result<()> {
        self.load_state = load_state;

        // Parse the vdev tree config
        let nvroot = try!(config.get("vdev_tree").ok_or(zfs::Error::Invalid));
        let vdev_alloc_type =
            match import_type {
                ImportType::Existing => vdev::AllocType::Load,
                ImportType::Assemble => vdev::AllocType::Split,
            };
        let root_vdev = try!(self.parse_vdev_tree(nvroot, vdev_alloc_type));

        Ok(())
    }

    fn parse_vdev_tree(&mut self, nv: &NvList, alloc_type: vdev::AllocType) -> zfs::Result<vdev::Vdev> {
        let vdev = vdev::Vdev::load(nv, 0, alloc_type);

        // TODO: return here if the vdev is a leaf node

        // Get the vdev's children
        let children: &Vec<NvList> = try!(nv.get("children").ok_or(zfs::Error::Invalid));

        vdev
    }

    fn activate(&mut self) {
        assert!(self.state == zfs::PoolState::Uninitialized);

        self.state = zfs::PoolState::Active;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////

pub struct SpaNamespace {
    // TODO: Use &str instead of String as key type. Lifetimes are hard.
    avl: avl::Tree<Spa, String>, // AVL tree of Spa sorted by name
}

impl SpaNamespace {
    pub fn new() -> Self {
        SpaNamespace {
            avl: avl::Tree::new(Box::new(|x| x.name.clone())),
        }
    }

    pub fn add(&mut self, spa: Spa) {
        self.avl.insert(spa);
    }

    pub fn find(&self, name: String) -> Option<&Spa> {
        self.avl.find(name)
    }

    pub fn find_mut(&mut self, name: String) -> Option<&mut Spa> {
        self.avl.find_mut(name)
    }
}
<commit_msg>spa stuff<commit_after>use redox::{Box, String, Vec};

use super::avl;
use super::nvpair::NvList;
use super::uberblock::Uberblock;
use super::vdev;
use super::zfs;

pub enum ImportType {
    Existing,
    Assemble,
}

// Storage pool allocator
pub struct Spa {
    name: String, // Pool name
    state: zfs::PoolState,
    load_state: zfs::SpaLoadState,
    root_vdev: vdev::Vdev,
    //ubsync: Uberblock, // Last synced uberblock
    //uberblock: Uberblock, // Current active uberblock
    did: u64, // if procp != p0, did of t1
}

impl Spa {
    // TODO
    /*pub fn create(name: String, config: NvList) -> Self {
        let root_vdev = vdev::Vdev::new();
        Self::new(name, root_vdev)
    }*/

    pub fn open(&mut self) -> zfs::Result<()> {
        let load_state = zfs::SpaLoadState::Open;
        if self.state == zfs::PoolState::Uninitialized {
            // First time opening

            self.activate();

            try!(self.load(load_state, ImportType::Existing, false));

        }

        Ok(())
    }

    fn new(name: String, root_vdev: vdev::Vdev) -> Self {
        Spa {
            name: name,
            state: zfs::PoolState::Uninitialized,
            load_state: zfs::SpaLoadState::None,
            root_vdev: root_vdev,
            did: 0,
        }
    }

    fn load(&mut self, load_state: zfs::SpaLoadState,
            import_type: ImportType, mos_config: bool) -> zfs::Result<()> {
        let ref config = NvList::new(0); // TODO: this should be replaced by self.config

        let pool_guid = try!(config.get("pool_guid").ok_or(zfs::Error::Invalid));

        self.load_impl(pool_guid, config, load_state, import_type, mos_config);
        self.load_state = zfs::SpaLoadState::None;

        Ok(())
    }

    /// mosconfig: Whether `config` came from on-disk MOS and so is trusted, or was user-made and so
    /// is untrusted.
    fn load_impl(&mut self, pool_guid: u64, config: &NvList, load_state: zfs::SpaLoadState,
                 import_type: ImportType, mos_config: bool) -> zfs::Result<()> {
        self.load_state = load_state;

        // Parse the vdev tree config
        let nvroot = try!(config.get("vdev_tree").ok_or(zfs::Error::Invalid));
        let vdev_alloc_type =
            match import_type {
                ImportType::Existing => vdev::AllocType::Load,
                ImportType::Assemble => vdev::AllocType::Split,
            };
        let root_vdev = try!(self.parse_vdev_tree(nvroot, vdev_alloc_type));

        Ok(())
    }

    fn parse_vdev_tree(&mut self, nv: &NvList, alloc_type: vdev::AllocType) -> zfs::Result<vdev::Vdev> {
        let vdev = vdev::Vdev::load(nv, 0, alloc_type);

        // TODO: return here if the vdev is a leaf node

        // Get the vdev's children
        let children: &Vec<NvList> = try!(nv.get("children").ok_or(zfs::Error::Invalid));

        vdev
    }

    fn activate(&mut self) {
        assert!(self.state == zfs::PoolState::Uninitialized);

        self.state = zfs::PoolState::Active;

        //self.normal_class = MetaslabClass::create(self, zfs_metaslab_ops);
        //self.log_class = MetaslabClass::create(self, zfs_metaslab_ops);

        self.did = 0;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////

pub struct SpaNamespace {
    // TODO: Use &str instead of String as key type. Lifetimes are hard.
    avl: avl::Tree<Spa, String>, // AVL tree of Spa sorted by name
}

impl SpaNamespace {
    pub fn new() -> Self {
        SpaNamespace {
            avl: avl::Tree::new(Box::new(|x| x.name.clone())),
        }
    }

    pub fn add(&mut self, spa: Spa) {
        self.avl.insert(spa);
    }

    pub fn find(&self, name: String) -> Option<&Spa> {
        self.avl.find(name)
    }

    pub fn find_mut(&mut self, name: String) -> Option<&mut Spa> {
        self.avl.find_mut(name)
    }
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for issue #17373<commit_after>// Copyright 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.

fn main() {
    *return; //~ ERROR type `!` cannot be dereferenced
}
<|endoftext|>


<commit_before>use gl::types::GLint;
use hgl;
use image;

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

pub enum MinecraftTexture {
    Grass,
}

impl MinecraftTexture {
    pub fn get_src_xy(&self) -> (i32, i32) {
        match *self {
            Grass => (0, 0),
        }
    }
}

pub struct Texture {
    tex: hgl::texture::Texture,
    width: u32,
    height: u32,
    unit_u: f32,
    unit_v: f32
}

impl Texture {
    /// Loads image by relative file name to the asset root.
    pub fn from_path(path: &Path) -> Result<Texture, String> {
        let file = match File::open(path) {
            Ok(file) => file,
            Err(e)  => return Err(format!("Could not load '{}': {}",
                                          path.filename_str().unwrap(), e)),
        };

        let img = match image::Image::load(file, image::PNG) {
            Ok(img) => img,
            Err(e)  => return Err(format!("Could not load '{}': {}",
                                          path.filename_str().unwrap(), e)),
        };

        match img.colortype() {
            image::RGBA(8) => {},
            c => fail!("Unsupported color type {} in png", c),
        };

        let (width, height) = img.dimensions();

        let ii = hgl::texture::ImageInfo::new()
            .pixel_format(hgl::texture::pixel::RGBA).pixel_type(hgl::texture::pixel::UNSIGNED_BYTE)
            .width(width as GLint).height(height as GLint);

        let tex = hgl::Texture::new(hgl::texture::Texture2D, ii, img.raw_pixels().as_ptr());
        tex.gen_mipmaps();
        tex.filter(hgl::texture::Nearest);
        tex.wrap(hgl::texture::Repeat);

        Ok(Texture {
            tex: tex,
            width: width,
            height: height,
            unit_u: 16.0 / (width as f32),
            unit_v: 16.0 / (height as f32)
        })
    }

    pub fn square(&self, x: i32, y: i32) -> [[f32, ..2], ..4] {
        let (u1, v1) = (self.unit_u, self.unit_v);
        let (u, v) = (x as f32 * u1, y as f32 * v1);
        [
            [u, v],
            [u + u1, v],
            [u, v + v1],
            [u + u1, v + v1]
        ]
    }
}
<commit_msg>texture: update for rust-image API changes.<commit_after>use gl::types::GLint;
use hgl;
use image;
use image::GenericImage;

pub enum MinecraftTexture {
    Grass,
}

impl MinecraftTexture {
    pub fn get_src_xy(&self) -> (i32, i32) {
        match *self {
            Grass => (0, 0),
        }
    }
}

pub struct Texture {
    tex: hgl::texture::Texture,
    width: u32,
    height: u32,
    unit_u: f32,
    unit_v: f32
}

impl Texture {
    /// Loads image by relative file name to the asset root.
    pub fn from_path(path: &Path) -> Result<Texture, String> {
        let img = match image::open(path) {
            Ok(img) => img,
            Err(e)  => return Err(format!("Could not load '{}': {}",
                                          path.filename_str().unwrap(), e)),
        };

        match img.color() {
            image::RGBA(8) => {},
            c => fail!("Unsupported color type {} in png", c),
        };

        let (width, height) = img.dimensions();

        let ii = hgl::texture::ImageInfo::new()
            .pixel_format(hgl::texture::pixel::RGBA).pixel_type(hgl::texture::pixel::UNSIGNED_BYTE)
            .width(width as GLint).height(height as GLint);

        let tex = hgl::Texture::new(hgl::texture::Texture2D, ii, img.raw_pixels().as_ptr());
        tex.gen_mipmaps();
        tex.filter(hgl::texture::Nearest);
        tex.wrap(hgl::texture::Repeat);

        Ok(Texture {
            tex: tex,
            width: width,
            height: height,
            unit_u: 16.0 / (width as f32),
            unit_v: 16.0 / (height as f32)
        })
    }

    pub fn square(&self, x: i32, y: i32) -> [[f32, ..2], ..4] {
        let (u1, v1) = (self.unit_u, self.unit_v);
        let (u, v) = (x as f32 * u1, y as f32 * v1);
        [
            [u, v],
            [u + u1, v],
            [u, v + v1],
            [u + u1, v + v1]
        ]
    }
}
<|endoftext|>


<commit_before><commit_msg>Update problem 2191<commit_after>// https://leetcode.com/problems/sort-the-jumbled-numbers/
pub fn sort_jumbled(mapping: Vec<i32>, nums: Vec<i32>) -> Vec<i32> {
    fn pad(s: &str, length: usize) -> String {
        "0".repeat(length) + &s.to_owned()
    }
    let mut sorted_nums = nums.clone();
    let longest = nums.iter().map(|a| a.to_string().len()).max().unwrap();
    sorted_nums.sort_by(|a, b| {
        let a: Vec<char> = a.to_string().chars().collect();
        let mut s1 = String::from("");
        for c in a {
            s1.push_str(&mapping[c as usize - '0' as usize].to_string());
        }
        let b: Vec<char> = b.to_string().chars().collect();
        let mut s2 = String::from("");
        for c in b {
            s2.push_str(&mapping[c as usize - '0' as usize].to_string());
        }
        let s1 = pad(&s1, longest - s1.len());
        let s2 = pad(&s2, longest - s2.len());
        s1.cmp(&s2)
    });
    sorted_nums
}

fn main() {
    println!(
        "{:?}",
        sort_jumbled(vec![8, 9, 4, 0, 2, 1, 3, 5, 7, 6], vec![991, 338, 38])
    ); // [338,38,991]
    println!(
        "{:?}",
        sort_jumbled(vec![8, 9, 4, 0, 2, 1, 3, 5, 7, 6], vec![991, 38, 338])
    ); // [38,338,991]
    println!(
        "{:?}",
        sort_jumbled(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9], vec![789, 456, 123])
    ); // [123,456,789]
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for #32797 (fixes #32797)<commit_after>// Copyright 2016 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.

pub use bar::*;
mod bar {
    pub use super::*;
}

pub use baz::*; //~ ERROR already been imported
mod baz {
    pub use main as f;
}

pub fn main() {}
<|endoftext|>


<commit_before><commit_msg>blank message<commit_after><|endoftext|>


<commit_before><commit_msg>Can now delete posts<commit_after>extern crate diesel_demo;
extern crate diesel;

use self::diesel::prelude::*;
use self::diesel_demo::*;
use std::env::args;

fn main() {
    use diesel_demo::schema::posts::dsl::*;

    let target = args().nth(1).expect("Expected a target to match against");
    let pattern = format!("%{}%", target);

    let connection = establish_connection();
    let num_deleted = diesel::delete(posts.filter(title.like(pattern)))
        .execute(&connection)
        .expect("Error deleting posts");

    println!("Deleted {} posts", num_deleted);
}<|endoftext|>


<commit_before><commit_msg>Initial version of the 'references' chapter.<commit_after><|endoftext|>


<commit_before>use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::fmt;

use regex::Regex;

pub mod id;
pub mod id_type;
pub mod header;
pub mod hash;

use module::Module;
use storage::file::id::*;
use storage::file::id_type::FileIDType;
use storage::file::hash::FileHash;
use super::parser::{FileHeaderParser, Parser, ParserError};

use self::header::spec::*;
use self::header::data::*;

/*
 * Internal abstract view on a file. Does not exist on the FS and is just kept
 * internally until it is written to disk.
 */
pub struct File<'a> {
    owning_module   : &'a Module<'a>,
    header          : FileHeaderData,
    data            : String,
    id              : FileID,
}

impl<'a> File<'a> {

    pub fn new(module: &'a Module<'a>) -> File<'a> {
        let f = File {
            owning_module: module,
            header: FileHeaderData::Null,
            data: String::from(""),
            id: File::get_new_file_id(),
        };
        debug!("Create new File object: {:?}", f);
        f
    }

    pub fn from_parser_result(module: &'a Module<'a>, id: FileID, header: FileHeaderData, data: String) -> File<'a> {
        let f = File {
            owning_module: module,
            header: header,
            data: data,
            id: id,
        };
        debug!("Create new File object from parser result: {:?}", f);
        f
    }

    pub fn new_with_header(module: &'a Module<'a>, h: FileHeaderData) -> File<'a> {
        let f = File {
            owning_module: module,
            header: h,
            data: String::from(""),
            id: File::get_new_file_id(),
        };
        debug!("Create new File object with header: {:?}", f);
        f
    }

    pub fn new_with_data(module: &'a Module<'a>, d: String) -> File<'a> {
        let f = File {
            owning_module: module,
            header: FileHeaderData::Null,
            data: d,
            id: File::get_new_file_id(),
        };
        debug!("Create new File object with data: {:?}", f);
        f
    }

    pub fn new_with_content(module: &'a Module<'a>, h: FileHeaderData, d: String) -> File<'a> {
        let f = File {
            owning_module: module,
            header: h,
            data: d,
            id: File::get_new_file_id(),
        };
        debug!("Create new File object with content: {:?}", f);
        f
    }

    pub fn header(&self) -> FileHeaderData {
        self.header.clone()
    }

    pub fn data(&self) -> String {
        self.data.clone()
    }

    pub fn contents(&self) -> (FileHeaderData, String) {
        (self.header(), self.data())
    }

    pub fn id(&self) -> FileID {
        self.id.clone()
    }

    pub fn owner(&self) -> &'a Module<'a> {
        self.owning_module
    }

    pub fn matches_with(&self, r: &Regex) -> bool {
        r.is_match(&self.data[..]) || self.header.matches_with(r)
    }

    fn get_new_file_id() -> FileID {
        use uuid::Uuid;
        let hash = FileHash::from(Uuid::new_v4().to_hyphenated_string());
        FileID::new(FileIDType::UUID, hash);
    }
}

impl<'a> Display for File<'a> {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt,
"[File] Owner : '{:?}'
        FileID: '{:?}'
        Header: '{:?}'
        Data  : '{:?}'",
               self.owning_module,
               self.header,
               self.data,
               self.id);
        Ok(())
    }

}

impl<'a> Debug for File<'a> {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt,
"[File] Owner : '{:?}'
        FileID: '{:?}'
        Header: '{:?}'
        Data  : '{:?}'",
               self.owning_module,
               self.header,
               self.data,
               self.id);
        Ok(())
    }

}

#[cfg(test)]
mod test {
    // we use the JSON parser here, so we can generate FileHeaderData
    use storage::json::parser::JsonHeaderParser;
    use super::match_header_spec;
    use storage::parser::{FileHeaderParser, ParserError};
    use storage::file::FileHeaderData as FHD;
    use storage::file::FileHeaderSpec as FHS;

    #[test]
    fn test_spec_matching() {
        let text = String::from("{\"a\": 1, \"b\": -2}");
        let spec = FHS::Map {
            keys: vec![
                FHS::Key {
                    name: String::from("a"),
                    value_type: Box::new(FHS::UInteger)
                },
                FHS::Key {
                    name: String::from("b"),
                    value_type: Box::new(FHS::Integer)
                }
            ]
        };

        let parser  = JsonHeaderParser::new(Some(spec.clone()));
        let datares = parser.read(Some(text.clone()));
        assert!(datares.is_ok(), "Text could not be parsed: '{}'", text);
        let data = datares.unwrap();

        let matchres = match_header_spec(&spec, &data);
        assert!(matchres.is_none(), "Matching returns error: {:?}", matchres);
    }
}

<commit_msg>Fixup File::get_new_file_id()<commit_after>use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::fmt;

use regex::Regex;

pub mod id;
pub mod id_type;
pub mod header;
pub mod hash;

use module::Module;
use storage::file::id::*;
use storage::file::id_type::FileIDType;
use storage::file::hash::FileHash;
use super::parser::{FileHeaderParser, Parser, ParserError};

use self::header::spec::*;
use self::header::data::*;

/*
 * Internal abstract view on a file. Does not exist on the FS and is just kept
 * internally until it is written to disk.
 */
pub struct File<'a> {
    owning_module   : &'a Module<'a>,
    header          : FileHeaderData,
    data            : String,
    id              : FileID,
}

impl<'a> File<'a> {

    pub fn new(module: &'a Module<'a>) -> File<'a> {
        let f = File {
            owning_module: module,
            header: FileHeaderData::Null,
            data: String::from(""),
            id: File::get_new_file_id(),
        };
        debug!("Create new File object: {:?}", f);
        f
    }

    pub fn from_parser_result(module: &'a Module<'a>, id: FileID, header: FileHeaderData, data: String) -> File<'a> {
        let f = File {
            owning_module: module,
            header: header,
            data: data,
            id: id,
        };
        debug!("Create new File object from parser result: {:?}", f);
        f
    }

    pub fn new_with_header(module: &'a Module<'a>, h: FileHeaderData) -> File<'a> {
        let f = File {
            owning_module: module,
            header: h,
            data: String::from(""),
            id: File::get_new_file_id(),
        };
        debug!("Create new File object with header: {:?}", f);
        f
    }

    pub fn new_with_data(module: &'a Module<'a>, d: String) -> File<'a> {
        let f = File {
            owning_module: module,
            header: FileHeaderData::Null,
            data: d,
            id: File::get_new_file_id(),
        };
        debug!("Create new File object with data: {:?}", f);
        f
    }

    pub fn new_with_content(module: &'a Module<'a>, h: FileHeaderData, d: String) -> File<'a> {
        let f = File {
            owning_module: module,
            header: h,
            data: d,
            id: File::get_new_file_id(),
        };
        debug!("Create new File object with content: {:?}", f);
        f
    }

    pub fn header(&self) -> FileHeaderData {
        self.header.clone()
    }

    pub fn data(&self) -> String {
        self.data.clone()
    }

    pub fn contents(&self) -> (FileHeaderData, String) {
        (self.header(), self.data())
    }

    pub fn id(&self) -> FileID {
        self.id.clone()
    }

    pub fn owner(&self) -> &'a Module<'a> {
        self.owning_module
    }

    pub fn matches_with(&self, r: &Regex) -> bool {
        r.is_match(&self.data[..]) || self.header.matches_with(r)
    }

    fn get_new_file_id() -> FileID {
        use uuid::Uuid;
        let hash = FileHash::from(Uuid::new_v4().to_hyphenated_string());
        FileID::new(FileIDType::UUID, hash)
    }
}

impl<'a> Display for File<'a> {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt,
"[File] Owner : '{:?}'
        FileID: '{:?}'
        Header: '{:?}'
        Data  : '{:?}'",
               self.owning_module,
               self.header,
               self.data,
               self.id);
        Ok(())
    }

}

impl<'a> Debug for File<'a> {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt,
"[File] Owner : '{:?}'
        FileID: '{:?}'
        Header: '{:?}'
        Data  : '{:?}'",
               self.owning_module,
               self.header,
               self.data,
               self.id);
        Ok(())
    }

}

#[cfg(test)]
mod test {
    // we use the JSON parser here, so we can generate FileHeaderData
    use storage::json::parser::JsonHeaderParser;
    use super::match_header_spec;
    use storage::parser::{FileHeaderParser, ParserError};
    use storage::file::FileHeaderData as FHD;
    use storage::file::FileHeaderSpec as FHS;

    #[test]
    fn test_spec_matching() {
        let text = String::from("{\"a\": 1, \"b\": -2}");
        let spec = FHS::Map {
            keys: vec![
                FHS::Key {
                    name: String::from("a"),
                    value_type: Box::new(FHS::UInteger)
                },
                FHS::Key {
                    name: String::from("b"),
                    value_type: Box::new(FHS::Integer)
                }
            ]
        };

        let parser  = JsonHeaderParser::new(Some(spec.clone()));
        let datares = parser.read(Some(text.clone()));
        assert!(datares.is_ok(), "Text could not be parsed: '{}'", text);
        let data = datares.unwrap();

        let matchres = match_header_spec(&spec, &data);
        assert!(matchres.is_none(), "Matching returns error: {:?}", matchres);
    }
}

<|endoftext|>


<commit_before>use error::*;
use bot::BotEnv;
use tasks::RunsTask;
use util::parse_duration_secs;
use database::models::{RoleCheckTime, NewRoleCheckTime};

use diesel::prelude::*;

use chrono::{Utc, TimeZone, Duration};

use serenity::prelude::Mentionable;
use serenity::model::id::{GuildId, ChannelId, RoleId, UserId};
use serenity::model::guild::{Member, Role};

use serde_json;

use std::thread;
use std::sync::Arc;
use std::collections::HashMap;

macro_rules! config {
  ($env:expr) => {{
    match $env.config.read().bot.tasks.get("role_check").cloned().map(serde_json::from_value) {
      Some(Ok(rc)) => rc,
      Some(Err(e)) => {
        warn!("invalid role_check in config: {}", e);
        return;
      },
      None => {
        warn!("missing role_check in config");
        return;
      }
    }
  }}
}

pub struct RoleCheckTask {
  first_run: bool
}

impl RoleCheckTask {
  pub fn new() -> Self {
    RoleCheckTask { first_run: true }
  }
}

impl RunsTask for RoleCheckTask {
  fn start(mut self, env: Arc<BotEnv>) {
    loop {
      let config: RoleCheckConfig = config!(env.as_ref());
      let sleep = if self.first_run {
        self.first_run = false;
        config.delay
      } else {
        config.period
      };
      info!("Waiting {} second{}", sleep, if sleep == 1 { "" } else { "s" });
      thread::sleep(Duration::seconds(sleep).to_std().unwrap());

      let now = Utc::now();
      for check in config.checks {
        let reminder_secs = match parse_duration_secs(&check.reminder.time) {
          Ok(s) => s,
          Err(_) => {
            warn!("invalid reminder time: {}", check.reminder.time);
            continue;
          }
        };
        let kick_secs = match parse_duration_secs(&check.kick.time) {
          Ok(s) => s,
          Err(_) => {
            warn!("invalid kick time: {}", check.kick.time);
            continue;
          }
        };
        let guild = some_or!(GuildId(check.guild).find(), continue);
        let roles = guild.read().roles.clone();
        let times: Result<Vec<RoleCheckTime>> = ::bot::CONNECTION.with(|c| {
          use database::schema::role_check_times::dsl;
          dsl::role_check_times
            .filter(dsl::check_id.eq(check.id))
            .load(c)
            .chain_err(|| "could not load role_check_times")
        });
        let times = match times {
          Ok(t) => t,
          Err(e) => {
            warn!("{}", e);
            continue;
          }
        };
        let members: Vec<(UserId, Member)> = guild.read().members.iter()
          .filter(|&(_, m)| check.necessary_roles.matches(m, &roles))
          .map(|(id, m)| (*id, m.clone()))
          .collect();
        let mut reminders = Vec::new();
        for (user_id, member) in members {
          match times.iter().find(|x| *x.user_id == user_id.0) {
            Some(time) => {
              if Utc.timestamp(time.reminded_at, 0) + Duration::seconds(i64::from(time.kick_after)) > now {
                // TODO: use message when able
                info!("Kicking user {} ({}) on {} ({}) due to check {}",
                  member.display_name(),
                  user_id.0,
                  guild.read().name,
                  guild.read().id.0,
                  check.id);
                match member.kick() {
                  Ok(_) => ::bot::CONNECTION.with(|c| {
                    if let Err(e) = ::diesel::delete(time).execute(c) {
                      warn!("Could not remove database entry for check after kick: {}", e);
                    }
                  }),
                  Err(e) => warn!("Kick was not successful: {}", e)
                }
              }
            },
            None => if let Some(joined) = member.joined_at {
              if now.signed_duration_since(joined.with_timezone(&Utc)) >= Duration::seconds(reminder_secs as i64) {
                reminders.push(member.mention());
                let new_time = NewRoleCheckTime::new(check.id, user_id.0, now.timestamp(), kick_secs as i32);
                ::bot::CONNECTION.with(move |c| {
                  use database::schema::role_check_times::dsl;
                  ::diesel::insert_into(dsl::role_check_times)
                    .values(&new_time)
                    .execute(c)
                    .ok();
                });
              }
            }
          }
        }
        if reminders.is_empty() {
          continue;
        }
        let mentions = reminders.join(" ");
        if let Err(e) = ChannelId(check.channel).send_message(|m| m.content(check.reminder.message.replace("{mentions}", &mentions))) {
          warn!("Could not send reminder message for check {}: {}", check.id, e);
        }
      }
    }
  }
}

#[derive(Debug, Deserialize)]
struct RoleCheckConfig {
  delay: i64,
  period: i64,
  checks: Vec<RoleCheck>
}

#[derive(Debug, Deserialize)]
struct RoleCheck {
  id: i32,
  guild: u64,
  channel: u64,
  necessary_roles: NeededRole,
  reminder: RoleCheckMessage,
  kick: RoleCheckMessage
}

#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum NeededRole {
  Simple(String),
  Logical(NeededRoleLogical)
}

impl NeededRole {
  fn matches(&self, member: &Member, roles: &HashMap<RoleId, Role>) -> bool {
    match *self {
      NeededRole::Simple(ref role) => roles.iter().find(|x| x.1.name.to_lowercase() == role.to_lowercase()).map(|r| member.roles.contains(r.0)).unwrap_or_default(),
      NeededRole::Logical(NeededRoleLogical::And(ref b)) => b.iter().all(|x| x.matches(member, roles)),
      NeededRole::Logical(NeededRoleLogical::Or(ref b)) => b.iter().any(|x| x.matches(member, roles)),
      NeededRole::Logical(NeededRoleLogical::Not(ref x)) => !x.matches(member, roles)
    }
  }
}

#[derive(Debug, Deserialize)]
enum NeededRoleLogical {
  #[serde(rename = "and")]
  And(Vec<Box<NeededRole>>),
  #[serde(rename = "or")]
  Or(Vec<Box<NeededRole>>),
  #[serde(rename = "not")]
  Not(Box<NeededRole>)
}

#[derive(Debug, Deserialize)]
struct RoleCheckMessage {
  time: String,
  message: String
}
<commit_msg>fix: don't kick too early<commit_after>use error::*;
use bot::BotEnv;
use tasks::RunsTask;
use util::parse_duration_secs;
use database::models::{RoleCheckTime, NewRoleCheckTime};

use diesel::prelude::*;

use chrono::{Utc, TimeZone, Duration};

use serenity::prelude::Mentionable;
use serenity::model::id::{GuildId, ChannelId, RoleId, UserId};
use serenity::model::guild::{Member, Role};

use serde_json;

use std::thread;
use std::sync::Arc;
use std::collections::HashMap;

macro_rules! config {
  ($env:expr) => {{
    match $env.config.read().bot.tasks.get("role_check").cloned().map(serde_json::from_value) {
      Some(Ok(rc)) => rc,
      Some(Err(e)) => {
        warn!("invalid role_check in config: {}", e);
        return;
      },
      None => {
        warn!("missing role_check in config");
        return;
      }
    }
  }}
}

pub struct RoleCheckTask {
  first_run: bool
}

impl RoleCheckTask {
  pub fn new() -> Self {
    RoleCheckTask { first_run: true }
  }
}

impl RunsTask for RoleCheckTask {
  fn start(mut self, env: Arc<BotEnv>) {
    loop {
      let config: RoleCheckConfig = config!(env.as_ref());
      let sleep = if self.first_run {
        self.first_run = false;
        config.delay
      } else {
        config.period
      };
      info!("Waiting {} second{}", sleep, if sleep == 1 { "" } else { "s" });
      thread::sleep(Duration::seconds(sleep).to_std().unwrap());

      let now = Utc::now();
      for check in config.checks {
        let reminder_secs = match parse_duration_secs(&check.reminder.time) {
          Ok(s) => s,
          Err(_) => {
            warn!("invalid reminder time: {}", check.reminder.time);
            continue;
          }
        };
        let kick_secs = match parse_duration_secs(&check.kick.time) {
          Ok(s) => s,
          Err(_) => {
            warn!("invalid kick time: {}", check.kick.time);
            continue;
          }
        };
        let guild = some_or!(GuildId(check.guild).find(), continue);
        let roles = guild.read().roles.clone();
        let times: Result<Vec<RoleCheckTime>> = ::bot::CONNECTION.with(|c| {
          use database::schema::role_check_times::dsl;
          dsl::role_check_times
            .filter(dsl::check_id.eq(check.id))
            .load(c)
            .chain_err(|| "could not load role_check_times")
        });
        let times = match times {
          Ok(t) => t,
          Err(e) => {
            warn!("{}", e);
            continue;
          }
        };
        let members: Vec<(UserId, Member)> = guild.read().members.iter()
          .filter(|&(_, m)| check.necessary_roles.matches(m, &roles))
          .map(|(id, m)| (*id, m.clone()))
          .collect();
        let mut reminders = Vec::new();
        for (user_id, member) in members {
          match times.iter().find(|x| *x.user_id == user_id.0) {
            Some(time) => {
              if Utc.timestamp(time.reminded_at, 0) + Duration::seconds(i64::from(time.kick_after)) <= now {
                // TODO: use message when able
                info!("Kicking user {} ({}) on {} ({}) due to check {}",
                  member.display_name(),
                  user_id.0,
                  guild.read().name,
                  guild.read().id.0,
                  check.id);
                match member.kick() {
                  Ok(_) => ::bot::CONNECTION.with(|c| {
                    if let Err(e) = ::diesel::delete(time).execute(c) {
                      warn!("Could not remove database entry for check after kick: {}", e);
                    }
                  }),
                  Err(e) => warn!("Kick was not successful: {}", e)
                }
              }
            },
            None => if let Some(joined) = member.joined_at {
              if now.signed_duration_since(joined.with_timezone(&Utc)) >= Duration::seconds(reminder_secs as i64) {
                reminders.push(member.mention());
                let new_time = NewRoleCheckTime::new(check.id, user_id.0, now.timestamp(), kick_secs as i32);
                ::bot::CONNECTION.with(move |c| {
                  use database::schema::role_check_times::dsl;
                  ::diesel::insert_into(dsl::role_check_times)
                    .values(&new_time)
                    .execute(c)
                    .ok();
                });
              }
            }
          }
        }
        if reminders.is_empty() {
          continue;
        }
        let mentions = reminders.join(" ");
        if let Err(e) = ChannelId(check.channel).send_message(|m| m.content(check.reminder.message.replace("{mentions}", &mentions))) {
          warn!("Could not send reminder message for check {}: {}", check.id, e);
        }
      }
    }
  }
}

#[derive(Debug, Deserialize)]
struct RoleCheckConfig {
  delay: i64,
  period: i64,
  checks: Vec<RoleCheck>
}

#[derive(Debug, Deserialize)]
struct RoleCheck {
  id: i32,
  guild: u64,
  channel: u64,
  necessary_roles: NeededRole,
  reminder: RoleCheckMessage,
  kick: RoleCheckMessage
}

#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum NeededRole {
  Simple(String),
  Logical(NeededRoleLogical)
}

impl NeededRole {
  fn matches(&self, member: &Member, roles: &HashMap<RoleId, Role>) -> bool {
    match *self {
      NeededRole::Simple(ref role) => roles.iter().find(|x| x.1.name.to_lowercase() == role.to_lowercase()).map(|r| member.roles.contains(r.0)).unwrap_or_default(),
      NeededRole::Logical(NeededRoleLogical::And(ref b)) => b.iter().all(|x| x.matches(member, roles)),
      NeededRole::Logical(NeededRoleLogical::Or(ref b)) => b.iter().any(|x| x.matches(member, roles)),
      NeededRole::Logical(NeededRoleLogical::Not(ref x)) => !x.matches(member, roles)
    }
  }
}

#[derive(Debug, Deserialize)]
enum NeededRoleLogical {
  #[serde(rename = "and")]
  And(Vec<Box<NeededRole>>),
  #[serde(rename = "or")]
  Or(Vec<Box<NeededRole>>),
  #[serde(rename = "not")]
  Not(Box<NeededRole>)
}

#[derive(Debug, Deserialize)]
struct RoleCheckMessage {
  time: String,
  message: String
}
<|endoftext|>