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

// Regression test for #29740. Inefficient MIR matching algorithms
// generated way too much code for this sort of case, leading to OOM.

// ignore-pretty

pub mod KeyboardEventConstants {
    pub const DOM_KEY_LOCATION_STANDARD: u32 = 0;
    pub const DOM_KEY_LOCATION_LEFT: u32 = 1;
    pub const DOM_KEY_LOCATION_RIGHT: u32 = 2;
    pub const DOM_KEY_LOCATION_NUMPAD: u32 = 3;
} // mod KeyboardEventConstants

pub enum Key {
    Space,
    Apostrophe,
    Comma,
    Minus,
    Period,
    Slash,
    Num0,
    Num1,
    Num2,
    Num3,
    Num4,
    Num5,
    Num6,
    Num7,
    Num8,
    Num9,
    Semicolon,
    Equal,
    A,
    B,
    C,
    D,
    E,
    F,
    G,
    H,
    I,
    J,
    K,
    L,
    M,
    N,
    O,
    P,
    Q,
    R,
    S,
    T,
    U,
    V,
    W,
    X,
    Y,
    Z,
    LeftBracket,
    Backslash,
    RightBracket,
    GraveAccent,
    World1,
    World2,

    Escape,
    Enter,
    Tab,
    Backspace,
    Insert,
    Delete,
    Right,
    Left,
    Down,
    Up,
    PageUp,
    PageDown,
    Home,
    End,
    CapsLock,
    ScrollLock,
    NumLock,
    PrintScreen,
    Pause,
    F1,
    F2,
    F3,
    F4,
    F5,
    F6,
    F7,
    F8,
    F9,
    F10,
    F11,
    F12,
    F13,
    F14,
    F15,
    F16,
    F17,
    F18,
    F19,
    F20,
    F21,
    F22,
    F23,
    F24,
    F25,
    Kp0,
    Kp1,
    Kp2,
    Kp3,
    Kp4,
    Kp5,
    Kp6,
    Kp7,
    Kp8,
    Kp9,
    KpDecimal,
    KpDivide,
    KpMultiply,
    KpSubtract,
    KpAdd,
    KpEnter,
    KpEqual,
    LeftShift,
    LeftControl,
    LeftAlt,
    LeftSuper,
    RightShift,
    RightControl,
    RightAlt,
    RightSuper,
    Menu,
}

fn key_from_string(key_string: &str, location: u32) -> Option<Key> {
    match key_string {
        " " => Some(Key::Space),
        "\"" => Some(Key::Apostrophe),
        "'" => Some(Key::Apostrophe),
        "<" => Some(Key::Comma),
        "," => Some(Key::Comma),
        "_" => Some(Key::Minus),
        "-" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Minus),
        ">" => Some(Key::Period),
        "." if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Period),
        "?" => Some(Key::Slash),
        "/" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Slash),
        "~" => Some(Key::GraveAccent),
        "`" => Some(Key::GraveAccent),
        ")" => Some(Key::Num0),
        "0" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num0),
        "!" => Some(Key::Num1),
        "1" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num1),
        "@" => Some(Key::Num2),
        "2" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num2),
        "#" => Some(Key::Num3),
        "3" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num3),
        "$" => Some(Key::Num4),
        "4" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num4),
        "%" => Some(Key::Num5),
        "5" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num5),
        "^" => Some(Key::Num6),
        "6" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num6),
        "&" => Some(Key::Num7),
        "7" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num7),
        "*" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num8),
        "8" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num8),
        "(" => Some(Key::Num9),
        "9" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num9),
        ":" => Some(Key::Semicolon),
        ";" => Some(Key::Semicolon),
        "+" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Equal),
        "=" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Equal),
        "A" => Some(Key::A),
        "a" => Some(Key::A),
        "B" => Some(Key::B),
        "b" => Some(Key::B),
        "C" => Some(Key::C),
        "c" => Some(Key::C),
        "D" => Some(Key::D),
        "d" => Some(Key::D),
        "E" => Some(Key::E),
        "e" => Some(Key::E),
        "F" => Some(Key::F),
        "f" => Some(Key::F),
        "G" => Some(Key::G),
        "g" => Some(Key::G),
        "H" => Some(Key::H),
        "h" => Some(Key::H),
        "I" => Some(Key::I),
        "i" => Some(Key::I),
        "J" => Some(Key::J),
        "j" => Some(Key::J),
        "K" => Some(Key::K),
        "k" => Some(Key::K),
        "L" => Some(Key::L),
        "l" => Some(Key::L),
        "M" => Some(Key::M),
        "m" => Some(Key::M),
        "N" => Some(Key::N),
        "n" => Some(Key::N),
        "O" => Some(Key::O),
        "o" => Some(Key::O),
        "P" => Some(Key::P),
        "p" => Some(Key::P),
        "Q" => Some(Key::Q),
        "q" => Some(Key::Q),
        "R" => Some(Key::R),
        "r" => Some(Key::R),
        "S" => Some(Key::S),
        "s" => Some(Key::S),
        "T" => Some(Key::T),
        "t" => Some(Key::T),
        "U" => Some(Key::U),
        "u" => Some(Key::U),
        "V" => Some(Key::V),
        "v" => Some(Key::V),
        "W" => Some(Key::W),
        "w" => Some(Key::W),
        "X" => Some(Key::X),
        "x" => Some(Key::X),
        "Y" => Some(Key::Y),
        "y" => Some(Key::Y),
        "Z" => Some(Key::Z),
        "z" => Some(Key::Z),
        "{" => Some(Key::LeftBracket),
        "[" => Some(Key::LeftBracket),
        "|" => Some(Key::Backslash),
        "\\" => Some(Key::Backslash),
        "}" => Some(Key::RightBracket),
        "]" => Some(Key::RightBracket),
        "Escape" => Some(Key::Escape),
        "Enter" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Enter),
        "Tab" => Some(Key::Tab),
        "Backspace" => Some(Key::Backspace),
        "Insert" => Some(Key::Insert),
        "Delete" => Some(Key::Delete),
        "ArrowRight" => Some(Key::Right),
        "ArrowLeft" => Some(Key::Left),
        "ArrowDown" => Some(Key::Down),
        "ArrowUp" => Some(Key::Up),
        "PageUp" => Some(Key::PageUp),
        "PageDown" => Some(Key::PageDown),
        "Home" => Some(Key::Home),
        "End" => Some(Key::End),
        "CapsLock" => Some(Key::CapsLock),
        "ScrollLock" => Some(Key::ScrollLock),
        "NumLock" => Some(Key::NumLock),
        "PrintScreen" => Some(Key::PrintScreen),
        "Pause" => Some(Key::Pause),
        "F1" => Some(Key::F1),
        "F2" => Some(Key::F2),
        "F3" => Some(Key::F3),
        "F4" => Some(Key::F4),
        "F5" => Some(Key::F5),
        "F6" => Some(Key::F6),
        "F7" => Some(Key::F7),
        "F8" => Some(Key::F8),
        "F9" => Some(Key::F9),
        "F10" => Some(Key::F10),
        "F11" => Some(Key::F11),
        "F12" => Some(Key::F12),
        "F13" => Some(Key::F13),
        "F14" => Some(Key::F14),
        "F15" => Some(Key::F15),
        "F16" => Some(Key::F16),
        "F17" => Some(Key::F17),
        "F18" => Some(Key::F18),
        "F19" => Some(Key::F19),
        "F20" => Some(Key::F20),
        "F21" => Some(Key::F21),
        "F22" => Some(Key::F22),
        "F23" => Some(Key::F23),
        "F24" => Some(Key::F24),
        "F25" => Some(Key::F25),
        "0" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp0),
        "1" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp1),
        "2" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp2),
        "3" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp3),
        "4" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp4),
        "5" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp5),
        "6" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp6),
        "7" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp7),
        "8" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp8),
        "9" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp9),
        "." if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpDecimal),
        "/" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpDivide),
        "*" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpMultiply),
        "-" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpSubtract),
        "+" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpAdd),
        "Enter" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpEnter),
        "=" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpEqual),
        "Shift" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT => Some(Key::LeftShift),
        "Control" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT => Some(Key::LeftControl),
        "Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT => Some(Key::LeftAlt),
        "Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT => Some(Key::LeftSuper),
        "Shift" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT => Some(Key::RightShift),
        "Control" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT => Some(Key::RightControl),
        "Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT => Some(Key::RightAlt),
        "Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT => Some(Key::RightSuper),
        "ContextMenu" => Some(Key::Menu),
        _ => None
    }
}

fn main() { }
<commit_msg>Fixup #29776<commit_after>// Copyright 2012 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.

// Regression test for #29740. Inefficient MIR matching algorithms
// generated way too much code for this sort of case, leading to OOM.

// ignore-pretty

pub mod KeyboardEventConstants {
    pub const DOM_KEY_LOCATION_STANDARD: u32 = 0;
    pub const DOM_KEY_LOCATION_LEFT: u32 = 1;
    pub const DOM_KEY_LOCATION_RIGHT: u32 = 2;
    pub const DOM_KEY_LOCATION_NUMPAD: u32 = 3;
} // mod KeyboardEventConstants

pub enum Key {
    Space,
    Apostrophe,
    Comma,
    Minus,
    Period,
    Slash,
    Num0,
    Num1,
    Num2,
    Num3,
    Num4,
    Num5,
    Num6,
    Num7,
    Num8,
    Num9,
    Semicolon,
    Equal,
    A,
    B,
    C,
    D,
    E,
    F,
    G,
    H,
    I,
    J,
    K,
    L,
    M,
    N,
    O,
    P,
    Q,
    R,
    S,
    T,
    U,
    V,
    W,
    X,
    Y,
    Z,
    LeftBracket,
    Backslash,
    RightBracket,
    GraveAccent,
    World1,
    World2,

    Escape,
    Enter,
    Tab,
    Backspace,
    Insert,
    Delete,
    Right,
    Left,
    Down,
    Up,
    PageUp,
    PageDown,
    Home,
    End,
    CapsLock,
    ScrollLock,
    NumLock,
    PrintScreen,
    Pause,
    F1,
    F2,
    F3,
    F4,
    F5,
    F6,
    F7,
    F8,
    F9,
    F10,
    F11,
    F12,
    F13,
    F14,
    F15,
    F16,
    F17,
    F18,
    F19,
    F20,
    F21,
    F22,
    F23,
    F24,
    F25,
    Kp0,
    Kp1,
    Kp2,
    Kp3,
    Kp4,
    Kp5,
    Kp6,
    Kp7,
    Kp8,
    Kp9,
    KpDecimal,
    KpDivide,
    KpMultiply,
    KpSubtract,
    KpAdd,
    KpEnter,
    KpEqual,
    LeftShift,
    LeftControl,
    LeftAlt,
    LeftSuper,
    RightShift,
    RightControl,
    RightAlt,
    RightSuper,
    Menu,
}

fn key_from_string(key_string: &str, location: u32) -> Option<Key> {
    match key_string {
        " " => Some(Key::Space),
        "\"" => Some(Key::Apostrophe),
        "'" => Some(Key::Apostrophe),
        "<" => Some(Key::Comma),
        "," => Some(Key::Comma),
        "_" => Some(Key::Minus),
        "-" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Minus),
        ">" => Some(Key::Period),
        "." if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Period),
        "?" => Some(Key::Slash),
        "/" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Slash),
        "~" => Some(Key::GraveAccent),
        "`" => Some(Key::GraveAccent),
        ")" => Some(Key::Num0),
        "0" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num0),
        "!" => Some(Key::Num1),
        "1" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num1),
        "@" => Some(Key::Num2),
        "2" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num2),
        "#" => Some(Key::Num3),
        "3" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num3),
        "$" => Some(Key::Num4),
        "4" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num4),
        "%" => Some(Key::Num5),
        "5" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num5),
        "^" => Some(Key::Num6),
        "6" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num6),
        "&" => Some(Key::Num7),
        "7" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num7),
        "*" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num8),
        "8" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num8),
        "(" => Some(Key::Num9),
        "9" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num9),
        ":" => Some(Key::Semicolon),
        ";" => Some(Key::Semicolon),
        "+" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Equal),
        "=" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Equal),
        "A" => Some(Key::A),
        "a" => Some(Key::A),
        "B" => Some(Key::B),
        "b" => Some(Key::B),
        "C" => Some(Key::C),
        "c" => Some(Key::C),
        "D" => Some(Key::D),
        "d" => Some(Key::D),
        "E" => Some(Key::E),
        "e" => Some(Key::E),
        "F" => Some(Key::F),
        "f" => Some(Key::F),
        "G" => Some(Key::G),
        "g" => Some(Key::G),
        "H" => Some(Key::H),
        "h" => Some(Key::H),
        "I" => Some(Key::I),
        "i" => Some(Key::I),
        "J" => Some(Key::J),
        "j" => Some(Key::J),
        "K" => Some(Key::K),
        "k" => Some(Key::K),
        "L" => Some(Key::L),
        "l" => Some(Key::L),
        "M" => Some(Key::M),
        "m" => Some(Key::M),
        "N" => Some(Key::N),
        "n" => Some(Key::N),
        "O" => Some(Key::O),
        "o" => Some(Key::O),
        "P" => Some(Key::P),
        "p" => Some(Key::P),
        "Q" => Some(Key::Q),
        "q" => Some(Key::Q),
        "R" => Some(Key::R),
        "r" => Some(Key::R),
        "S" => Some(Key::S),
        "s" => Some(Key::S),
        "T" => Some(Key::T),
        "t" => Some(Key::T),
        "U" => Some(Key::U),
        "u" => Some(Key::U),
        "V" => Some(Key::V),
        "v" => Some(Key::V),
        "W" => Some(Key::W),
        "w" => Some(Key::W),
        "X" => Some(Key::X),
        "x" => Some(Key::X),
        "Y" => Some(Key::Y),
        "y" => Some(Key::Y),
        "Z" => Some(Key::Z),
        "z" => Some(Key::Z),
        "{" => Some(Key::LeftBracket),
        "[" => Some(Key::LeftBracket),
        "|" => Some(Key::Backslash),
        "\\" => Some(Key::Backslash),
        "}" => Some(Key::RightBracket),
        "]" => Some(Key::RightBracket),
        "Escape" => Some(Key::Escape),
        "Enter" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD
                => Some(Key::Enter),
        "Tab" => Some(Key::Tab),
        "Backspace" => Some(Key::Backspace),
        "Insert" => Some(Key::Insert),
        "Delete" => Some(Key::Delete),
        "ArrowRight" => Some(Key::Right),
        "ArrowLeft" => Some(Key::Left),
        "ArrowDown" => Some(Key::Down),
        "ArrowUp" => Some(Key::Up),
        "PageUp" => Some(Key::PageUp),
        "PageDown" => Some(Key::PageDown),
        "Home" => Some(Key::Home),
        "End" => Some(Key::End),
        "CapsLock" => Some(Key::CapsLock),
        "ScrollLock" => Some(Key::ScrollLock),
        "NumLock" => Some(Key::NumLock),
        "PrintScreen" => Some(Key::PrintScreen),
        "Pause" => Some(Key::Pause),
        "F1" => Some(Key::F1),
        "F2" => Some(Key::F2),
        "F3" => Some(Key::F3),
        "F4" => Some(Key::F4),
        "F5" => Some(Key::F5),
        "F6" => Some(Key::F6),
        "F7" => Some(Key::F7),
        "F8" => Some(Key::F8),
        "F9" => Some(Key::F9),
        "F10" => Some(Key::F10),
        "F11" => Some(Key::F11),
        "F12" => Some(Key::F12),
        "F13" => Some(Key::F13),
        "F14" => Some(Key::F14),
        "F15" => Some(Key::F15),
        "F16" => Some(Key::F16),
        "F17" => Some(Key::F17),
        "F18" => Some(Key::F18),
        "F19" => Some(Key::F19),
        "F20" => Some(Key::F20),
        "F21" => Some(Key::F21),
        "F22" => Some(Key::F22),
        "F23" => Some(Key::F23),
        "F24" => Some(Key::F24),
        "F25" => Some(Key::F25),
        "0" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp0),
        "1" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp1),
        "2" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp2),
        "3" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp3),
        "4" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp4),
        "5" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp5),
        "6" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp6),
        "7" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp7),
        "8" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp8),
        "9" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp9),
        "." if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpDecimal),
        "/" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpDivide),
        "*" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpMultiply),
        "-" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpSubtract),
        "+" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpAdd),
        "Enter" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD
                => Some(Key::KpEnter),
        "=" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpEqual),
        "Shift" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT
                => Some(Key::LeftShift),
        "Control" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT
                => Some(Key::LeftControl),
        "Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT => Some(Key::LeftAlt),
        "Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT
                => Some(Key::LeftSuper),
        "Shift" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT
                => Some(Key::RightShift),
        "Control" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT
                => Some(Key::RightControl),
        "Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT => Some(Key::RightAlt),
        "Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT
                => Some(Key::RightSuper),
        "ContextMenu" => Some(Key::Menu),
        _ => None
    }
}

fn main() { }
<|endoftext|>


<commit_before>use rustorm::query::TableName;
use window_service::window::{self, Window};
use rustorm::table::Table;
use std::collections::HashSet;
use global::Context;
use error::ParamError;
use rustorm::database::DatabaseDev;
use config;

/// try retrieving tables from cache, if none, then from db and cache it
pub fn get_tables(context: &mut Context) -> Vec<Table> {
    let has_cache = context.has_cached_tables();
    if has_cache {
        context.get_cached_tables().unwrap()
    } else {
        get_tables_from_db_then_cache_in_context(context)
    }
}

pub fn get_tables_from_db_then_cache_in_context(context: &mut Context) -> Vec<Table> {
    let db_tables = get_all_tables_from_db(context.db_dev().unwrap());
    context.cache_tables(db_tables.clone());
    db_tables
}

fn get_windows(context: &mut Context) -> Vec<Window> {
    let tables = get_tables(context);
    let has_cache = context.has_cached_windows();
    if has_cache {
        context.get_cached_windows().unwrap()
    } else {
        get_windows_from_db_then_cache(context, &tables)
    }
}

fn get_windows_from_db_then_cache(context: &mut Context, tables: &Vec<Table>) -> Vec<Window> {
    let db_windows = extract_windows(tables);
    context.cache_windows(db_windows.clone());
    db_windows
}
/// get a matching table
pub fn get_matching_table(context: &mut Context, arg_table_name: &str) -> Option<Table> {
    let tables = get_tables(context);
    let arg_table = TableName::from_str(arg_table_name);
    // check for exact match first
    for table in &tables {
        if arg_table.schema.is_some() {
            if table.schema == arg_table.schema && table.name == arg_table.name {
                return Some(table.clone());
            }
        }
    }
    // then check for table names only regardless of schema
    for table in &tables {
        if table.name == arg_table.name {
            return Some(table.to_owned());
        }
    }
    None
}

// check if the table exist
pub fn table_exist(context: &mut Context, arg_table_name: &str) -> bool {
    get_matching_table(context, arg_table_name).is_some()
}

// check if this is a column in the database
pub fn all_column_names(context: &mut Context) -> HashSet<String> {
    let tables = get_tables(context);
    let mut columns: HashSet<String> = HashSet::new();
    for tbl in tables {
        for col in tbl.columns {
            columns.insert(col.name.to_owned());
        }
    }
    columns
}

pub fn all_table_names(context: &mut Context) -> HashSet<String> {
    let all_tables = get_tables(context);
    let mut table_names = HashSet::new();
    for table in all_tables {
        table_names.insert(table.name.to_owned());
    }
    table_names
}

pub fn all_schema_names(context: &mut Context) -> HashSet<String> {
    let all_tables = get_tables(context);
    let mut schema_names = HashSet::new();
    for table in all_tables {
        if let Some(schema) = table.schema {
            schema_names.insert(schema.to_owned());
        }
    }
    schema_names
}

/// retrive the window definition of a table
pub fn retrieve_window(context: &mut Context, arg_table_name: &str) -> Result<Window, ParamError> {
    info!("getting window: {}", arg_table_name);
    let windows = get_windows(context);
    let table_name = TableName::from_str(arg_table_name);
    let schema = table_name.schema;
    if schema.is_some() {
        for win in windows {
            if win.table == table_name.name && win.schema == schema {
                return Ok(win.clone());
            }
        }
    } else {
        for win in windows {
            if win.table == table_name.name {
                return Ok(win.clone());
            }
        }
    }
    Err(ParamError::new(&format!("No window for {}", arg_table_name)))
}

/// list down the windows using only the summaries
pub fn list_window(context: &mut Context) -> Result<Vec<Window>, String> {
    let tables = get_tables(context);
    let windows = list_windows_summary(&tables);
    Ok(windows)
}

/// a first step to getting universal or popular tables
pub fn get_table_tally(all_tables: &[Table]) -> Vec<(&Table, usize)> {
    let mut tally = vec![];
    for table in all_tables {
        tally.push((table, table.referring_tables(all_tables).len()));
    }
    tally.sort_by(|a, b| {
        let &(t1, c1) = a;
        let &(t2, c2) = b;
        c2.cmp(&c1)
    });
    tally
}

///
/// retrieve all the table definition in the database
/// must not be called outside of this api
///
pub fn get_all_tables_from_db(db_dev: &DatabaseDev) -> Vec<Table> {
    let all_tables_names = db_dev.get_all_tables();
    let mut all_table_def: Vec<Table> = Vec::new();
    for (schema, table, is_view) in all_tables_names {
        println!("Extracted {}.{}", schema, table);
        let meta = db_dev.get_table_metadata(&schema, &table, is_view);
        all_table_def.push(meta);
    }
    all_table_def
}

/// a summary of windows
/// build windows from a set of tables
///
pub fn extract_windows(tables: &Vec<Table>) -> Vec<Window> {
    let window_tables = window_tables(tables);
    let mut all_windows = vec![];
    for wt in window_tables {
        info!("{}", wt);
        let window = Window::from_table(&wt, tables);
        all_windows.push(window);
    }
    all_windows
}

/// list a sumamary of window tables
pub fn list_windows_summary(tables: &Vec<Table>) -> Vec<Window> {
    let window_tables = window_tables(&tables);
    let mut window_list = vec![];
    for t in window_tables {
        let window = Window::summary_from_table(&t, tables);
        window_list.push(window);
    }
    window_list
}

fn window_tables(tables: &Vec<Table>) -> Vec<Table>{
    let table_tally = get_table_tally(tables);
    let sorted_tables: Vec<Table> =
        table_tally.iter().map(|&(table, tally)| table.clone()).collect();
    if config::INCLUDE_HAS_MANY {
        get_window_tables(&sorted_tables)
    } else {
       sorted_tables
    }
}

///
/// return the list of tables that has a window
///
fn get_window_tables(tables: &Vec<Table>) -> Vec<Table> {
    let mut window_tables = Vec::new();
    let all_extension_tables = get_all_extension_tables(tables);
    for t in tables {
        if t.is_linker_table() {
            info!("NOT a Window: {} <<-linker table", t.name);
        } else {
            if t.is_owned_or_semi_owned(tables) {
                info!("OWNED table: {}", t.name);
            } else {
                if all_extension_tables.contains(&&t) {
                    info!("EXTENSION table: {}", t);
                } else {
                    info!("{}", t.name);
                    window_tables.push(t.clone());
                    for (col, has1) in t.referred_tables(tables) {
                        info!("\t has one: {} -> {}", col.condense_name(), has1);
                    }
                    for ext in t.extension_tables(tables) {
                        info!("\t ext tab: {} [{}]",
                              ext.name,
                              ext.condensed_displayname(&t));
                    }
                    for (has_many, column) in t.referring_tables(tables) {
                        if !has_many.is_linker_table() {
                            info!("\t has many direct: {} [{}] via column: {}",
                                  has_many.name,
                                  has_many.condensed_displayname(&t),
                                  column.name);
                        } else {
                            // println!("\t has many direct: {} <---- but is a linker table, so no!", has_many.name);
                        }
                    }
                    for (has_many, linker, via_column) in t.indirect_referring_tables(tables) {
                        info!("\t has many INDIRECT: {}[{}], via {} via column {}",
                              has_many.name,
                              has_many.condensed_displayname(&t),
                              linker.name,
                              via_column.name);
                    }
                }
            }
        }
    }
    window_tables
}

fn get_all_extension_tables(tables: &Vec<Table>) -> Vec<&Table> {
    let mut all_extension_tables = Vec::new();
    for t in tables {
        for ext in t.extension_tables(tables) {
            if !all_extension_tables.contains(&ext) {
                info!("extension table: {}", ext);
                all_extension_tables.push(ext);
            }
        }
    }
    all_extension_tables

}
<commit_msg>add special case for tables beginning in __<commit_after>use rustorm::query::TableName;
use window_service::window::{self, Window};
use rustorm::table::Table;
use std::collections::HashSet;
use global::Context;
use error::ParamError;
use rustorm::database::DatabaseDev;
use config;

/// try retrieving tables from cache, if none, then from db and cache it
pub fn get_tables(context: &mut Context) -> Vec<Table> {
    let has_cache = context.has_cached_tables();
    if has_cache {
        context.get_cached_tables().unwrap()
    } else {
        get_tables_from_db_then_cache_in_context(context)
    }
}

pub fn get_tables_from_db_then_cache_in_context(context: &mut Context) -> Vec<Table> {
    let db_tables = get_all_tables_from_db(context.db_dev().unwrap());
    context.cache_tables(db_tables.clone());
    db_tables
}

fn get_windows(context: &mut Context) -> Vec<Window> {
    let tables = get_tables(context);
    let has_cache = context.has_cached_windows();
    if has_cache {
        context.get_cached_windows().unwrap()
    } else {
        get_windows_from_db_then_cache(context, &tables)
    }
}

fn get_windows_from_db_then_cache(context: &mut Context, tables: &Vec<Table>) -> Vec<Window> {
    let db_windows = extract_windows(tables);
    context.cache_windows(db_windows.clone());
    db_windows
}
/// get a matching table
pub fn get_matching_table(context: &mut Context, arg_table_name: &str) -> Option<Table> {
    let tables = get_tables(context);
    let arg_table = TableName::from_str(arg_table_name);
    // check for exact match first
    for table in &tables {
        if arg_table.schema.is_some() {
            if table.schema == arg_table.schema && table.name == arg_table.name {
                return Some(table.clone());
            }
        }
    }
    // then check for table names only regardless of schema
    for table in &tables {
        if table.name == arg_table.name {
            return Some(table.to_owned());
        }
    }
    None
}

// check if the table exist
pub fn table_exist(context: &mut Context, arg_table_name: &str) -> bool {
    get_matching_table(context, arg_table_name).is_some()
}

// check if this is a column in the database
pub fn all_column_names(context: &mut Context) -> HashSet<String> {
    let tables = get_tables(context);
    let mut columns: HashSet<String> = HashSet::new();
    for tbl in tables {
        for col in tbl.columns {
            columns.insert(col.name.to_owned());
        }
    }
    columns
}

pub fn all_table_names(context: &mut Context) -> HashSet<String> {
    let all_tables = get_tables(context);
    let mut table_names = HashSet::new();
    for table in all_tables {
        table_names.insert(table.name.to_owned());
    }
    table_names
}

pub fn all_schema_names(context: &mut Context) -> HashSet<String> {
    let all_tables = get_tables(context);
    let mut schema_names = HashSet::new();
    for table in all_tables {
        if let Some(schema) = table.schema {
            schema_names.insert(schema.to_owned());
        }
    }
    schema_names
}

/// retrive the window definition of a table
pub fn retrieve_window(context: &mut Context, arg_table_name: &str) -> Result<Window, ParamError> {
    info!("getting window: {}", arg_table_name);
    let windows = get_windows(context);
    let table_name = TableName::from_str(arg_table_name);
    let schema = table_name.schema;
    if schema.is_some() {
        for win in windows {
            if win.table == table_name.name && win.schema == schema {
                return Ok(win.clone());
            }
        }
    } else {
        for win in windows {
            if win.table == table_name.name {
                return Ok(win.clone());
            }
        }
    }
    Err(ParamError::new(&format!("No window for {}", arg_table_name)))
}

/// list down the windows using only the summaries
pub fn list_window(context: &mut Context) -> Result<Vec<Window>, String> {
    let tables = get_tables(context);
    let windows = list_windows_summary(&tables);
    Ok(windows)
}

/// a first step to getting universal or popular tables
pub fn get_table_tally(all_tables: &[Table]) -> Vec<(&Table, usize)> {
    let mut tally = vec![];
    for table in all_tables {
        tally.push((table, table.referring_tables(all_tables).len()));
    }
    tally.sort_by(|a, b| {
        let &(t1, c1) = a;
        let &(t2, c2) = b;
        c2.cmp(&c1)
    });
    tally
}

///
/// retrieve all the table definition in the database
/// must not be called outside of this api
///
pub fn get_all_tables_from_db(db_dev: &DatabaseDev) -> Vec<Table> {
    let all_tables_names = db_dev.get_all_tables();
    let mut all_table_def: Vec<Table> = Vec::new();
    for (schema, table, is_view) in all_tables_names {
        println!("Extracted {}.{}", schema, table);
        let meta = db_dev.get_table_metadata(&schema, &table, is_view);
        all_table_def.push(meta);
    }
    all_table_def
}

/// a summary of windows
/// build windows from a set of tables
///
pub fn extract_windows(tables: &Vec<Table>) -> Vec<Window> {
    let window_tables = window_tables(tables);
    let mut all_windows = vec![];
    for wt in window_tables {
        info!("{}", wt);
        let window = Window::from_table(&wt, tables);
        all_windows.push(window);
    }
    all_windows
}

/// list a sumamary of window tables
pub fn list_windows_summary(tables: &Vec<Table>) -> Vec<Window> {
    let window_tables = window_tables(&tables);
    let mut window_list = vec![];
    for t in window_tables {
        let window = Window::summary_from_table(&t, tables);
        window_list.push(window);
    }
    window_list
}

fn window_tables(tables: &Vec<Table>) -> Vec<Table>{
    let table_tally = get_table_tally(tables);
    let sorted_tables: Vec<Table> =
        table_tally.iter().map(|&(table, tally)| table.clone()).collect();
    if config::INCLUDE_HAS_MANY {
        get_window_tables(&sorted_tables)
    } else {
       sorted_tables
    }
}

///
/// return the list of tables that has a window
///
fn get_window_tables(tables: &Vec<Table>) -> Vec<Table> {
    let mut window_tables = Vec::new();
    let all_extension_tables = get_all_extension_tables(tables);
    for t in tables {
        if t.is_linker_table() {
            info!("NOT a Window: {} <<-linker table", t.name);
        } else {
            if t.is_owned_or_semi_owned(tables) {
                info!("OWNED table: {}", t.name);
            } else {
                if all_extension_tables.contains(&&t) {
                    info!("EXTENSION table: {}", t);
                } else {
                    if t.name.starts_with("__"){
                        info!("Special table: {}", t.name);
                    }else{
                        info!("{}", t.name);
                        window_tables.push(t.clone());
                        for (col, has1) in t.referred_tables(tables) {
                            info!("\t has one: {} -> {}", col.condense_name(), has1);
                        }
                        for ext in t.extension_tables(tables) {
                            info!("\t ext tab: {} [{}]",
                                  ext.name,
                                  ext.condensed_displayname(&t));
                        }
                        for (has_many, column) in t.referring_tables(tables) {
                            if !has_many.is_linker_table() {
                                info!("\t has many direct: {} [{}] via column: {}",
                                      has_many.name,
                                      has_many.condensed_displayname(&t),
                                      column.name);
                            } else {
                                // println!("\t has many direct: {} <---- but is a linker table, so no!", has_many.name);
                            }
                        }
                        for (has_many, linker, via_column) in t.indirect_referring_tables(tables) {
                            info!("\t has many INDIRECT: {}[{}], via {} via column {}",
                                  has_many.name,
                                  has_many.condensed_displayname(&t),
                                  linker.name,
                                  via_column.name);
                        }
                     }
                }
            }
        }
    }
    window_tables
}

fn get_all_extension_tables(tables: &Vec<Table>) -> Vec<&Table> {
    let mut all_extension_tables = Vec::new();
    for t in tables {
        for ext in t.extension_tables(tables) {
            if !all_extension_tables.contains(&ext) {
                info!("extension table: {}", ext);
                all_extension_tables.push(ext);
            }
        }
    }
    all_extension_tables

}
<|endoftext|>


<commit_before>use rustc::hir::*;
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::mir::interpret::ConstValue;
use rustc::ty;
use rustc::{declare_tool_lint, impl_lint_pass};

use if_chain::if_chain;

use crate::rustc_target::abi::LayoutOf;
use crate::utils::{snippet, span_help_and_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for local arrays that may be too large.
    ///
    /// **Why is this bad?** Large local arrays may cause stack overflow.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust,ignore
    /// let a = [0u32; 1_000_000];
    /// ```
    pub LARGE_STACK_ARRAYS,
    pedantic,
    "allocating large arrays on stack may cause stack overflow"
}

pub struct LargeStackArrays {
    maximum_allowed_size: u64,
}

impl LargeStackArrays {
    #[must_use]
    pub fn new(maximum_allowed_size: u64) -> Self {
        Self { maximum_allowed_size }
    }
}

impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeStackArrays {
    fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr) {
        if_chain! {
            if let ExprKind::Repeat(_, _) = expr.kind;
            if let ty::Array(element_type, cst) = cx.tables.expr_ty(expr).kind;
            if let ConstValue::Scalar(element_count) = cst.val;
            if let Ok(element_count) = element_count.to_machine_usize(&cx.tcx);
            if let Ok(element_size) = cx.layout_of(element_type).map(|l| l.size.bytes());
            if self.maximum_allowed_size < element_count * element_size;
            then {
                span_help_and_lint(
                    cx,
                    LARGE_STACK_ARRAYS,
                    expr.span,
                    &format!(
                        "allocating a local array larger than {} bytes",
                        self.maximum_allowed_size
                    ),
                    &format!(
                        "consider allocating on the heap with vec!{}.into_boxed_slice()",
                        snippet(cx, expr.span, "[...]")
                    ),
                );
            }
        }
    }
}
<commit_msg>Fix fallout<commit_after>use rustc::hir::*;
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::mir::interpret::ConstValue;
use rustc::ty::{self, ConstKind};
use rustc::{declare_tool_lint, impl_lint_pass};

use if_chain::if_chain;

use crate::rustc_target::abi::LayoutOf;
use crate::utils::{snippet, span_help_and_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for local arrays that may be too large.
    ///
    /// **Why is this bad?** Large local arrays may cause stack overflow.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust,ignore
    /// let a = [0u32; 1_000_000];
    /// ```
    pub LARGE_STACK_ARRAYS,
    pedantic,
    "allocating large arrays on stack may cause stack overflow"
}

pub struct LargeStackArrays {
    maximum_allowed_size: u64,
}

impl LargeStackArrays {
    #[must_use]
    pub fn new(maximum_allowed_size: u64) -> Self {
        Self { maximum_allowed_size }
    }
}

impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeStackArrays {
    fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr) {
        if_chain! {
            if let ExprKind::Repeat(_, _) = expr.kind;
            if let ty::Array(element_type, cst) = cx.tables.expr_ty(expr).kind;
            if let ConstKind::Value(val) = cst.val;
            if let ConstValue::Scalar(element_count) = val;
            if let Ok(element_count) = element_count.to_machine_usize(&cx.tcx);
            if let Ok(element_size) = cx.layout_of(element_type).map(|l| l.size.bytes());
            if self.maximum_allowed_size < element_count * element_size;
            then {
                span_help_and_lint(
                    cx,
                    LARGE_STACK_ARRAYS,
                    expr.span,
                    &format!(
                        "allocating a local array larger than {} bytes",
                        self.maximum_allowed_size
                    ),
                    &format!(
                        "consider allocating on the heap with vec!{}.into_boxed_slice()",
                        snippet(cx, expr.span, "[...]")
                    ),
                );
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::error::Error;
use std::fmt;

pub type ProtobufResult<T> = Result<T, ProtobufError>;

#[derive(Debug)]
pub enum ProtobufError {
    IoError(io::Error),
    WireError(String),
    MessageNotInitialized { message: &'static str },
}

impl ProtobufError {
    pub fn message_not_initialized(message: &'static str) -> ProtobufError {
        ProtobufError::MessageNotInitialized {
            message: message
        }
    }
}

impl fmt::Display for ProtobufError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(self, f)
    }
}

impl Error for ProtobufError {
    fn description(&self) -> &str {
        match self {
            // not sure that cause should be included in message
            &ProtobufError::IoError(ref e) => e.description(),
            &ProtobufError::WireError(ref e) => &e,
            &ProtobufError::MessageNotInitialized { .. } => "not all message fields set",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match self {
            &ProtobufError::IoError(ref e) => Some(e),
            &ProtobufError::WireError(..) => None,
            &ProtobufError::MessageNotInitialized { .. } => None,
        }
    }
}

impl From<io::Error> for ProtobufError {
    fn from(err: io::Error) -> Self {
        ProtobufError::IoError(err)
    }
}
<commit_msg>Implemented conversion From<ProtobufError> for io::Error.<commit_after>use std::io;
use std::error::Error;
use std::fmt;

pub type ProtobufResult<T> = Result<T, ProtobufError>;

#[derive(Debug)]
pub enum ProtobufError {
    IoError(io::Error),
    WireError(String),
    MessageNotInitialized { message: &'static str },
}

impl ProtobufError {
    pub fn message_not_initialized(message: &'static str) -> ProtobufError {
        ProtobufError::MessageNotInitialized {
            message: message
        }
    }
}

impl fmt::Display for ProtobufError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(self, f)
    }
}

impl Error for ProtobufError {
    fn description(&self) -> &str {
        match self {
            // not sure that cause should be included in message
            &ProtobufError::IoError(ref e) => e.description(),
            &ProtobufError::WireError(ref e) => &e,
            &ProtobufError::MessageNotInitialized { .. } => "not all message fields set",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match self {
            &ProtobufError::IoError(ref e) => Some(e),
            &ProtobufError::WireError(..) => None,
            &ProtobufError::MessageNotInitialized { .. } => None,
        }
    }
}

impl From<io::Error> for ProtobufError {
    fn from(err: io::Error) -> Self {
        ProtobufError::IoError(err)
    }
}

impl From<ProtobufError> for io::Error {
    fn from(err: ProtobufError) -> Self {
        match err {
            ProtobufError::IoError(e) => e,
            ProtobufError::WireError(e) => io::Error::new(io::ErrorKind::InvalidData, ProtobufError::WireError(e)),
            ProtobufError::MessageNotInitialized { message: msg } => io::Error::new(io::ErrorKind::InvalidInput, ProtobufError::MessageNotInitialized { message: msg }),
        }
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;

use proc_macro2::Span;
use syn::buffer::Cursor;

use error;
use parse::Error;
use token::Token;

/// Support for checking the next token in a stream to decide how to parse.
///
/// Use [`ParseStream::lookahead1`] to construct this object.
///
/// [`ParseStream::lookahead1`]: struct.ParseBuffer.html#method.lookahead1
pub struct Lookahead1<'a> {
    scope: Span,
    cursor: Cursor<'a>,
    comparisons: RefCell<Vec<String>>,
}

impl<'a> Lookahead1<'a> {
    // Not public API.
    #[doc(hidden)]
    pub fn new(scope: Span, cursor: Cursor<'a>) -> Self {
        Lookahead1 {
            scope: scope,
            cursor: cursor,
            comparisons: RefCell::new(Vec::new()),
        }
    }

    pub fn peek<T: Peek>(&self, token: T) -> bool {
        let _ = token;
        if T::Token::peek(self) {
            return true;
        }
        self.comparisons.borrow_mut().push(T::Token::display());
        false
    }

    pub fn error(self) -> Error {
        let comparisons = self.comparisons.borrow();
        match comparisons.len() {
            0 => if self.cursor.eof() {
                Error::new(self.scope, "unexpected end of input")
            } else {
                Error::new(self.cursor.span(), "unexpected token")
            },
            1 => {
                let message = format!("expected {}", comparisons[0]);
                error::new_at(self.scope, self.cursor, message)
            }
            _ => {
                let message = format!("expected one of {:?}", comparisons);
                error::new_at(self.scope, self.cursor, message)
            }
        }
    }
}

/// Types that can be parsed by looking at just one token.
///
/// This trait is sealed and cannot be implemented for types outside of Syn.
pub trait Peek: private::Sealed {
    // Not public API.
    #[doc(hidden)]
    type Token: Token;
}

impl<F: FnOnce(Span) -> T, T: Token> Peek for F {
    type Token = T;
}

// Not public API.
#[doc(hidden)]
pub fn is_token(lookahead: &Lookahead1, repr: &'static str) -> bool {
    if let Some((token, _rest)) = lookahead.cursor.token_tree() {
        token.to_string() == repr
    } else {
        false
    }
}

mod private {
    use super::{Span, Token};
    pub trait Sealed {}
    impl<F, T: Token> Sealed for F where F: FnOnce(Span) -> T {}
}
<commit_msg>Join expected cases in lookahead error<commit_after>use std::cell::RefCell;

use proc_macro2::Span;
use syn::buffer::Cursor;

use error;
use parse::Error;
use token::Token;

/// Support for checking the next token in a stream to decide how to parse.
///
/// Use [`ParseStream::lookahead1`] to construct this object.
///
/// [`ParseStream::lookahead1`]: struct.ParseBuffer.html#method.lookahead1
pub struct Lookahead1<'a> {
    scope: Span,
    cursor: Cursor<'a>,
    comparisons: RefCell<Vec<String>>,
}

impl<'a> Lookahead1<'a> {
    // Not public API.
    #[doc(hidden)]
    pub fn new(scope: Span, cursor: Cursor<'a>) -> Self {
        Lookahead1 {
            scope: scope,
            cursor: cursor,
            comparisons: RefCell::new(Vec::new()),
        }
    }

    pub fn peek<T: Peek>(&self, token: T) -> bool {
        let _ = token;
        if T::Token::peek(self) {
            return true;
        }
        self.comparisons.borrow_mut().push(T::Token::display());
        false
    }

    pub fn error(self) -> Error {
        let comparisons = self.comparisons.borrow();
        match comparisons.len() {
            0 => if self.cursor.eof() {
                Error::new(self.scope, "unexpected end of input")
            } else {
                Error::new(self.cursor.span(), "unexpected token")
            },
            1 => {
                let message = format!("expected {}", comparisons[0]);
                error::new_at(self.scope, self.cursor, message)
            }
            _ => {
                let join = comparisons.join(", ");
                let message = format!("expected one of: {}", join);
                error::new_at(self.scope, self.cursor, message)
            }
        }
    }
}

/// Types that can be parsed by looking at just one token.
///
/// This trait is sealed and cannot be implemented for types outside of Syn.
pub trait Peek: private::Sealed {
    // Not public API.
    #[doc(hidden)]
    type Token: Token;
}

impl<F: FnOnce(Span) -> T, T: Token> Peek for F {
    type Token = T;
}

// Not public API.
#[doc(hidden)]
pub fn is_token(lookahead: &Lookahead1, repr: &'static str) -> bool {
    if let Some((token, _rest)) = lookahead.cursor.token_tree() {
        token.to_string() == repr
    } else {
        false
    }
}

mod private {
    use super::{Span, Token};
    pub trait Sealed {}
    impl<F, T: Token> Sealed for F where F: FnOnce(Span) -> T {}
}
<|endoftext|>


<commit_before>use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
use rustc_hir::LangItem;
use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::AssocKind;
use rustc_session::config::EntryFnType;
use rustc_span::symbol::Ident;

use crate::prelude::*;

/// Create the `main` function which will initialize the rust runtime and call
/// users main function.
pub(crate) fn maybe_create_entry_wrapper(
    tcx: TyCtxt<'_>,
    module: &mut impl Module,
    unwind_context: &mut UnwindContext,
    is_jit: bool,
) {
    let (main_def_id, is_main_fn) = match tcx.entry_fn(LOCAL_CRATE) {
        Some((def_id, entry_ty)) => (
            def_id.to_def_id(),
            match entry_ty {
                EntryFnType::Main => true,
                EntryFnType::Start => false,
            },
        ),
        None => return,
    };

    let instance = Instance::mono(tcx, main_def_id).polymorphize(tcx);
    if !is_jit && module.get_name(&*tcx.symbol_name(instance).name).is_none() {
        return;
    }

    create_entry_fn(tcx, module, unwind_context, main_def_id, is_jit, is_main_fn);

    fn create_entry_fn(
        tcx: TyCtxt<'_>,
        m: &mut impl Module,
        unwind_context: &mut UnwindContext,
        rust_main_def_id: DefId,
        ignore_lang_start_wrapper: bool,
        is_main_fn: bool,
    ) {
        let main_ret_ty = tcx.fn_sig(rust_main_def_id).output();
        // Given that `main()` has no arguments,
        // then its return type cannot have
        // late-bound regions, since late-bound
        // regions must appear in the argument
        // listing.
        let main_ret_ty = tcx.erase_regions(main_ret_ty.no_bound_vars().unwrap());

        let cmain_sig = Signature {
            params: vec![
                AbiParam::new(m.target_config().pointer_type()),
                AbiParam::new(m.target_config().pointer_type()),
            ],
            returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)],
            call_conv: CallConv::triple_default(m.isa().triple()),
        };

        let cmain_func_id = m.declare_function("main", Linkage::Export, &cmain_sig).unwrap();

        let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);

        let main_name = tcx.symbol_name(instance).name;
        let main_sig = get_function_sig(tcx, m.isa().triple(), instance);
        let main_func_id = m.declare_function(main_name, Linkage::Import, &main_sig).unwrap();

        let mut ctx = Context::new();
        ctx.func = Function::with_name_signature(ExternalName::user(0, 0), cmain_sig);
        {
            let mut func_ctx = FunctionBuilderContext::new();
            let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);

            let block = bcx.create_block();
            bcx.switch_to_block(block);
            let arg_argc = bcx.append_block_param(block, m.target_config().pointer_type());
            let arg_argv = bcx.append_block_param(block, m.target_config().pointer_type());

            let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func);

            let result = if is_main_fn && ignore_lang_start_wrapper {
                // regular main fn, but ignoring #[lang = "start"] as we are running in the jit
                // FIXME set program arguments somehow
                let call_inst = bcx.ins().call(main_func_ref, &[]);
                let call_results = bcx.func.dfg.inst_results(call_inst).to_owned();

                let termination_trait = tcx.require_lang_item(LangItem::Termination, None);
                let report = tcx
                    .associated_items(termination_trait)
                    .find_by_name_and_kind(
                        tcx,
                        Ident::from_str("report"),
                        AssocKind::Fn,
                        termination_trait,
                    )
                    .unwrap();
                let report = Instance::resolve(
                    tcx,
                    ParamEnv::reveal_all(),
                    report.def_id,
                    tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()),
                )
                .unwrap()
                .unwrap();

                let report_name = tcx.symbol_name(report).name;
                let report_sig = get_function_sig(tcx, m.isa().triple(), report);
                let report_func_id =
                    m.declare_function(report_name, Linkage::Import, &report_sig).unwrap();
                let report_func_ref = m.declare_func_in_func(report_func_id, &mut bcx.func);

                // FIXME do proper abi handling instead of expecting the pass mode to be identical
                // for returns and arguments.
                let report_call_inst = bcx.ins().call(report_func_ref, &call_results);
                let res = bcx.func.dfg.inst_results(report_call_inst)[0];
                match m.target_config().pointer_type() {
                    types::I32 => res,
                    types::I64 => bcx.ins().sextend(types::I64, res),
                    _ => unimplemented!("16bit systems are not yet supported"),
                }
            } else if is_main_fn {
                let start_def_id = tcx.require_lang_item(LangItem::Start, None);
                let start_instance = Instance::resolve(
                    tcx,
                    ParamEnv::reveal_all(),
                    start_def_id,
                    tcx.intern_substs(&[main_ret_ty.into()]),
                )
                .unwrap()
                .unwrap()
                .polymorphize(tcx);
                let start_func_id = import_function(tcx, m, start_instance);

                let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref);

                let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func);
                let call_inst = bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv]);
                bcx.inst_results(call_inst)[0]
            } else {
                // using user-defined start fn
                let call_inst = bcx.ins().call(main_func_ref, &[arg_argc, arg_argv]);
                bcx.inst_results(call_inst)[0]
            };

            bcx.ins().return_(&[result]);
            bcx.seal_all_blocks();
            bcx.finalize();
        }
        m.define_function(cmain_func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {})
            .unwrap();
        unwind_context.add_function(cmain_func_id, &ctx, m.isa());
    }
}
<commit_msg>Sync from rust 7a0f1781d04662041db5deaef89598a8edd53717<commit_after>use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
use rustc_hir::LangItem;
use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::AssocKind;
use rustc_session::config::EntryFnType;
use rustc_span::symbol::Ident;

use crate::prelude::*;

/// Create the `main` function which will initialize the rust runtime and call
/// users main function.
pub(crate) fn maybe_create_entry_wrapper(
    tcx: TyCtxt<'_>,
    module: &mut impl Module,
    unwind_context: &mut UnwindContext,
    is_jit: bool,
) {
    let (main_def_id, is_main_fn) = match tcx.entry_fn(LOCAL_CRATE) {
        Some((def_id, entry_ty)) => (
            def_id,
            match entry_ty {
                EntryFnType::Main => true,
                EntryFnType::Start => false,
            },
        ),
        None => return,
    };

    let instance = Instance::mono(tcx, main_def_id).polymorphize(tcx);
    if !is_jit && module.get_name(&*tcx.symbol_name(instance).name).is_none() {
        return;
    }

    create_entry_fn(tcx, module, unwind_context, main_def_id, is_jit, is_main_fn);

    fn create_entry_fn(
        tcx: TyCtxt<'_>,
        m: &mut impl Module,
        unwind_context: &mut UnwindContext,
        rust_main_def_id: DefId,
        ignore_lang_start_wrapper: bool,
        is_main_fn: bool,
    ) {
        let main_ret_ty = tcx.fn_sig(rust_main_def_id).output();
        // Given that `main()` has no arguments,
        // then its return type cannot have
        // late-bound regions, since late-bound
        // regions must appear in the argument
        // listing.
        let main_ret_ty = tcx.erase_regions(main_ret_ty.no_bound_vars().unwrap());

        let cmain_sig = Signature {
            params: vec![
                AbiParam::new(m.target_config().pointer_type()),
                AbiParam::new(m.target_config().pointer_type()),
            ],
            returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)],
            call_conv: CallConv::triple_default(m.isa().triple()),
        };

        let cmain_func_id = m.declare_function("main", Linkage::Export, &cmain_sig).unwrap();

        let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);

        let main_name = tcx.symbol_name(instance).name;
        let main_sig = get_function_sig(tcx, m.isa().triple(), instance);
        let main_func_id = m.declare_function(main_name, Linkage::Import, &main_sig).unwrap();

        let mut ctx = Context::new();
        ctx.func = Function::with_name_signature(ExternalName::user(0, 0), cmain_sig);
        {
            let mut func_ctx = FunctionBuilderContext::new();
            let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);

            let block = bcx.create_block();
            bcx.switch_to_block(block);
            let arg_argc = bcx.append_block_param(block, m.target_config().pointer_type());
            let arg_argv = bcx.append_block_param(block, m.target_config().pointer_type());

            let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func);

            let result = if is_main_fn && ignore_lang_start_wrapper {
                // regular main fn, but ignoring #[lang = "start"] as we are running in the jit
                // FIXME set program arguments somehow
                let call_inst = bcx.ins().call(main_func_ref, &[]);
                let call_results = bcx.func.dfg.inst_results(call_inst).to_owned();

                let termination_trait = tcx.require_lang_item(LangItem::Termination, None);
                let report = tcx
                    .associated_items(termination_trait)
                    .find_by_name_and_kind(
                        tcx,
                        Ident::from_str("report"),
                        AssocKind::Fn,
                        termination_trait,
                    )
                    .unwrap();
                let report = Instance::resolve(
                    tcx,
                    ParamEnv::reveal_all(),
                    report.def_id,
                    tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()),
                )
                .unwrap()
                .unwrap();

                let report_name = tcx.symbol_name(report).name;
                let report_sig = get_function_sig(tcx, m.isa().triple(), report);
                let report_func_id =
                    m.declare_function(report_name, Linkage::Import, &report_sig).unwrap();
                let report_func_ref = m.declare_func_in_func(report_func_id, &mut bcx.func);

                // FIXME do proper abi handling instead of expecting the pass mode to be identical
                // for returns and arguments.
                let report_call_inst = bcx.ins().call(report_func_ref, &call_results);
                let res = bcx.func.dfg.inst_results(report_call_inst)[0];
                match m.target_config().pointer_type() {
                    types::I32 => res,
                    types::I64 => bcx.ins().sextend(types::I64, res),
                    _ => unimplemented!("16bit systems are not yet supported"),
                }
            } else if is_main_fn {
                let start_def_id = tcx.require_lang_item(LangItem::Start, None);
                let start_instance = Instance::resolve(
                    tcx,
                    ParamEnv::reveal_all(),
                    start_def_id,
                    tcx.intern_substs(&[main_ret_ty.into()]),
                )
                .unwrap()
                .unwrap()
                .polymorphize(tcx);
                let start_func_id = import_function(tcx, m, start_instance);

                let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref);

                let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func);
                let call_inst = bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv]);
                bcx.inst_results(call_inst)[0]
            } else {
                // using user-defined start fn
                let call_inst = bcx.ins().call(main_func_ref, &[arg_argc, arg_argv]);
                bcx.inst_results(call_inst)[0]
            };

            bcx.ins().return_(&[result]);
            bcx.seal_all_blocks();
            bcx.finalize();
        }
        m.define_function(cmain_func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {})
            .unwrap();
        unwind_context.add_function(cmain_func_id, &ctx, m.isa());
    }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;

use std::collections::HashMap;

use self::rustc_serialize::json::{JsonEvent, Parser, StackElement};

use key_builder::{KeyBuilder, SegmentType};
use stems::Stems;

// Good example of using rustc_serialize: https://github.com/ajroetker/beautician/blob/master/src/lib.rs
// Callback based JSON streaming parser: https://github.com/gyscos/json-streamer.rs
// Another parser pased on rustc_serializ: https://github.com/isagalaev/ijson-rust/blob/master/src/test.rs#L11

#[derive(Debug)]
struct WordInfo {
    //offset in the text field where the stemmed text starts
    stemmed_offset: usize,

    // the suffix of the stemmed text. When applied over stemmed, the original
    // text is returned.
    suffix_text: String,

    // the start of the suffixText
    suffix_offset: usize,
}

type ArrayOffsets = Vec<usize>;
type ArrayOffsetsToWordInfo = HashMap<ArrayOffsets, Vec<WordInfo>>;
type WordPathInfoMap = HashMap<String, ArrayOffsetsToWordInfo>;

#[derive(Debug)]
struct Shredder {
    keybuilder: KeyBuilder,
    map: WordPathInfoMap,
    path_array_offsets: ArrayOffsets,
}

impl Shredder {
    fn new() -> Shredder {
        Shredder{
            keybuilder: KeyBuilder::new(),
            map: WordPathInfoMap::new(),
            path_array_offsets: Vec::new(),
        }
    }
    fn add_entries(&mut self, text: String, docseq: u64) {
        let stems = Stems::new(text.as_str());
        for stem in stems {
            self.keybuilder.push_word(stem.stemmed.to_string());
            self.keybuilder.push_doc_seq(docseq);
            let map_path_array_offsets = self.map.entry(self.keybuilder.key())
                                                        .or_insert(ArrayOffsetsToWordInfo::new());
            let map_word_infos = map_path_array_offsets.entry(self.path_array_offsets.clone())
                .or_insert(Vec::new());
            map_word_infos.push(WordInfo{
                stemmed_offset: stem.stemmed_offset,
                suffix_text: stem.suffix.to_string(),
                suffix_offset: stem.suffix_offset,
            });
            self.keybuilder.pop_doc_seq();
            self.keybuilder.pop_word();
        }
        println!("add_entries: map: {:?}", self.map);
    }

    fn inc_top_array_offset(&mut self) {
        // we encounter a new element. if we are a child element of an array
        // increment the offset. If we aren't (we are the root value or a map
        // value) we don't increment
        if let Some(SegmentType::Array) = self.keybuilder.last_pushed_segment_type() {
            if let Some(last) = self.path_array_offsets.last_mut() {
                *last += 1;
            }
        }
    }

    fn shred(&mut self, json: &str, docseq: u64) {
        println!("{}", json);
        let mut parser = Parser::new(json.chars());
        let mut token = parser.next();

        loop {
            // Get the next token, so that in case of an `ObjectStart` the key is already
            // on the stack.
            let nexttoken = parser.next();

            match token.take() {
                Some(JsonEvent::ObjectStart) => {
                    match parser.stack().top() {
                        Some(StackElement::Key(key)) => {
                            println!("object start: {:?}", key);
                            self.keybuilder.push_object_key(key.to_string());
                            self.inc_top_array_offset();
                        },
                        _ => {
                            panic!("XXX This is probably an object end");
                        }
                    }
                },
                Some(JsonEvent::ObjectEnd) => {
                    self.keybuilder.pop_object_key();
                },
                Some(JsonEvent::ArrayStart) => {
                    println!("array start");
                    self.keybuilder.push_array();
                    //self.inc_top_array_offset();
                    self.path_array_offsets.push(0);
                },
                Some(JsonEvent::ArrayEnd) => {
                    self.path_array_offsets.pop();
                    self.keybuilder.pop_array();
                },
                Some(JsonEvent::StringValue(value)) => {
                    self.add_entries(value, docseq);
                    self.inc_top_array_offset();
                    //self.keybuilder.pop_object_key();
                },
                not_implemented => {
                    panic!("Not yet implemented other JSON types! {:?}", not_implemented);
                }
            };

            token = nexttoken;
            if token == None {
                break;
            }
        }
        println!("keybuilder: {}", self.keybuilder.key());
        println!("shredder: keys:");
        for key in self.map.keys() {
            println!("  {}", key);
        }
    }
}

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

    #[test]
    fn test_shred() {
        let mut shredder = super::Shredder::new();
        //let json = r#"{"hello": {"my": "world!"}, "anumber": 2}"#;
        //let json = r#"{"A":[{"B":"B2VMX two three","C":"C2"},{"B": "b1","C":"C2"}]}"#;
        //let json = r#"{"A":[[[{"B": "string within deeply nested array should be stemmed"}]]]}"#;
        //let json = r#"[{"A": 1, "B": 2, "C": 3}]"#;
        //let json = r#"{"foo": {"bar": 1}}"#;
        let json = r#"{"some": ["array", "data", ["also", "nested"]]}"#;
        let docseq = 123;
        shredder.shred(json, docseq);
    }
}
<commit_msg>Encode JSON shredded data for RocksDB<commit_after>extern crate rocksdb;
extern crate rustc_serialize;

use std::collections::HashMap;

use self::rustc_serialize::json::{JsonEvent, Parser, StackElement};
// Needed for a trait in order to `put()` into a `rocksdb::WriteBatch`
use self::rocksdb::Writable;

use key_builder::{KeyBuilder, SegmentType};
use records_capnp::payload;
use stems::Stems;

// Good example of using rustc_serialize: https://github.com/ajroetker/beautician/blob/master/src/lib.rs
// Callback based JSON streaming parser: https://github.com/gyscos/json-streamer.rs
// Another parser pased on rustc_serializ: https://github.com/isagalaev/ijson-rust/blob/master/src/test.rs#L11

#[derive(Debug, PartialEq)]
struct WordInfo {
    //offset in the text field where the stemmed text starts
    stemmed_offset: u64,

    // the suffix of the stemmed text. When applied over stemmed, the original
    // text is returned.
    suffix_text: String,

    // the start of the suffixText
    suffix_offset: u64,
}

type ArrayOffsets = Vec<u64>;
type ArrayOffsetsToWordInfo = HashMap<ArrayOffsets, Vec<WordInfo>>;
type WordPathInfoMap = HashMap<String, ArrayOffsetsToWordInfo>;

#[derive(Debug)]
pub struct Shredder {
    keybuilder: KeyBuilder,
    map: WordPathInfoMap,
    path_array_offsets: ArrayOffsets,
}

impl Shredder {
    pub fn new() -> Shredder {
        Shredder{
            keybuilder: KeyBuilder::new(),
            map: WordPathInfoMap::new(),
            path_array_offsets: Vec::new(),
        }
    }
    fn add_entries(&mut self, text: String, docseq: u64) {
        let stems = Stems::new(text.as_str());
        for stem in stems {
            self.keybuilder.push_word(stem.stemmed.to_string());
            self.keybuilder.push_doc_seq(docseq);
            let map_path_array_offsets = self.map.entry(self.keybuilder.key())
                                                        .or_insert(ArrayOffsetsToWordInfo::new());
            let map_word_infos = map_path_array_offsets.entry(self.path_array_offsets.clone())
                .or_insert(Vec::new());
            map_word_infos.push(WordInfo{
                stemmed_offset: stem.stemmed_offset as u64,
                suffix_text: stem.suffix.to_string(),
                suffix_offset: stem.suffix_offset as u64,
            });
            self.keybuilder.pop_doc_seq();
            self.keybuilder.pop_word();
        }
        println!("add_entries: map: {:?}", self.map);
    }

    fn inc_top_array_offset(&mut self) {
        // we encounter a new element. if we are a child element of an array
        // increment the offset. If we aren't (we are the root value or a map
        // value) we don't increment
        if let Some(SegmentType::Array) = self.keybuilder.last_pushed_segment_type() {
            if let Some(last) = self.path_array_offsets.last_mut() {
                *last += 1;
            }
        }
    }

    pub fn shred(&mut self, json: &str, docseq: u64) -> Result<&str, String> {
        println!("{}", json);
        let mut parser = Parser::new(json.chars());
        let mut token = parser.next();

        loop {
            // Get the next token, so that in case of an `ObjectStart` the key is already
            // on the stack.
            let nexttoken = parser.next();

            match token.take() {
                Some(JsonEvent::ObjectStart) => {
                    match parser.stack().top() {
                        Some(StackElement::Key(key)) => {
                            println!("object start: {:?}", key);
                            self.keybuilder.push_object_key(key.to_string());
                            self.inc_top_array_offset();
                        },
                        _ => {
                            panic!("XXX This is probably an object end");
                        }
                    }
                },
                Some(JsonEvent::ObjectEnd) => {
                    self.keybuilder.pop_object_key();
                },
                Some(JsonEvent::ArrayStart) => {
                    println!("array start");
                    self.keybuilder.push_array();
                    //self.inc_top_array_offset();
                    self.path_array_offsets.push(0);
                },
                Some(JsonEvent::ArrayEnd) => {
                    self.path_array_offsets.pop();
                    self.keybuilder.pop_array();
                },
                Some(JsonEvent::StringValue(value)) => {
                    self.add_entries(value, docseq);
                    self.inc_top_array_offset();
                    //self.keybuilder.pop_object_key();
                },
                not_implemented => {
                    panic!("Not yet implemented other JSON types! {:?}", not_implemented);
                }
            };

            token = nexttoken;
            if token == None {
                break;
            }
        }
        println!("keybuilder: {}", self.keybuilder.key());
        println!("shredder: keys:");
        for key in self.map.keys() {
            println!("  {}", key);
        }
        Ok(&"thedocid")
    }

    pub fn add_to_batch(&self, batch: &rocksdb::WriteBatch) {
        for (key_path, word_path_infos) in &self.map {
            let mut message = ::capnp::message::Builder::new_default();
            {
                let mut capn_payload = message.init_root::<payload::Builder>();
                let mut capn_arrayoffsets_to_wordinfo = capn_payload.init_arrayoffsets_to_wordinfos(
                    word_path_infos.len() as u32);
                for (infos_pos, (arrayoffsets, wordinfos)) in word_path_infos.iter().enumerate() {

                    let mut capn_a2w = capn_arrayoffsets_to_wordinfo.borrow().get(infos_pos as u32);
                    {
                        let mut capn_arrayoffsets =
                            capn_a2w.borrow().init_arrayoffsets(arrayoffsets.len() as u32);
                        for (pos, arrayoffset) in arrayoffsets.iter().enumerate() {
                            capn_arrayoffsets.set(pos as u32, arrayoffset.clone());
                        }
                    }
                    {
                        let mut capn_wordinfos = capn_a2w.init_wordinfos(wordinfos.len() as u32);
                        for (pos, wordinfo) in wordinfos.iter().enumerate() {
                            let mut capn_wordinfo = capn_wordinfos.borrow().get(pos as u32);
                            capn_wordinfo.set_stemmed_offset(wordinfo.stemmed_offset);
                            capn_wordinfo.set_suffix_text(&wordinfo.suffix_text);
                            capn_wordinfo.set_suffix_offset(wordinfo.suffix_offset);
                        }
                    }
                }
            }
            let mut bytes = Vec::new();
            ::capnp::serialize_packed::write_message(&mut bytes, &message);
            batch.put(&key_path.clone().into_bytes(), &bytes);
        }

    }
}

#[cfg(test)]
mod tests {
    use super::{ArrayOffsetsToWordInfo, WordInfo, WordPathInfoMap};

    #[test]
    fn test_shred_nested() {
        let mut shredder = super::Shredder::new();
        //let json = r#"{"hello": {"my": "world!"}, "anumber": 2}"#;
        //let json = r#"{"A":[{"B":"B2VMX two three","C":"C2"},{"B": "b1","C":"C2"}]}"#;
        //let json = r#"{"A":[[[{"B": "string within deeply nested array should be stemmed"}]]]}"#;
        //let json = r#"[{"A": 1, "B": 2, "C": 3}]"#;
        //let json = r#"{"foo": {"bar": 1}}"#;
        let json = r#"{"some": ["array", "data", ["also", "nested"]]}"#;
        let docseq = 123;
        shredder.shred(json, docseq);
        let expected = vec![
            ("W.some$!array#123", vec![
                (vec![0], vec![WordInfo {
                    stemmed_offset: 0, suffix_text: "".to_string(), suffix_offset: 5 }])]),
            ("W.some$!data#123", vec![
                (vec![1], vec![WordInfo {
                    stemmed_offset: 0, suffix_text: "".to_string(), suffix_offset: 4 }])]),
            ("W.some$$!also#123", vec![
                (vec![2, 0], vec![WordInfo {
                    stemmed_offset: 0, suffix_text: "".to_string(), suffix_offset: 4 }])]),
            ("W.some$$!nest#123", vec![
                (vec![2, 1], vec![WordInfo {
                    stemmed_offset: 0, suffix_text: "ed".to_string(), suffix_offset: 4 }])]),
            ];
        compare_shredded(&shredder.map, &expected);
    }

    #[test]
    fn test_shred_objects() {
        let mut shredder = super::Shredder::new();
        let json = r#"{"A":[{"B":"B2VMX two three","C":"..C2"},{"B": "b1","C":"..C2"}]}"#;
        let docseq = 1234;
        shredder.shred(json, docseq);
        let expected = vec![
            ("W.A$.B!b1#1234", vec![
                (vec![0], vec![
                    WordInfo {
                        stemmed_offset: 0, suffix_text: "".to_string(), suffix_offset: 2 }])]),
            ("W.A$.B!b2vmx#1234", vec![
                (vec![0], vec![
                    WordInfo {
                        stemmed_offset: 0, suffix_text: "".to_string(), suffix_offset: 5 }])]),
            ("W.A$.B!c2#1234", vec![
                (vec![0], vec![
                    WordInfo {
                        stemmed_offset: 2, suffix_text: "".to_string(), suffix_offset: 4 },
                    WordInfo {
                        stemmed_offset: 2, suffix_text: "".to_string(), suffix_offset: 4 }])]),
            ("W.A$.B!three#1234", vec![
                (vec![0], vec![WordInfo {
                    stemmed_offset: 10, suffix_text: "".to_string(), suffix_offset: 15 }])]),
            ("W.A$.B!two#1234", vec![
                (vec![0], vec![WordInfo {
                    stemmed_offset: 6, suffix_text: "".to_string(), suffix_offset: 9 }])]),
            ];
        compare_shredded(&shredder.map, &expected);
    }

    fn compare_shredded(result_map: &WordPathInfoMap,
                        expected: &Vec<(&str, Vec<(Vec<u64>, Vec<WordInfo>)>)>) {
        // HashMap have an arbitraty order of the elements
        let mut result: Vec<(&String, &ArrayOffsetsToWordInfo)> = result_map.into_iter().collect();
        result.sort_by(|a, b| Ord::cmp(&a.0, &b.0));
        for (ii, &(key, values)) in result.iter().enumerate() {
            assert_eq!(key, expected[ii].0);
            let mut wordinfos: Vec<(&Vec<u64>, &Vec<WordInfo>)> = values.iter().collect();
            wordinfos.sort_by_key(|item| item.0);
            for (jj, wordinfo) in wordinfos.iter().enumerate() {
                assert_eq!(wordinfo.0, &expected[ii].1[jj].0);
                assert_eq!(wordinfo.1, &expected[ii].1[jj].1);
            }
        }
    }
}
<|endoftext|>


<commit_before>use graph::Graph;
use maximum_flow::maximum_flow;

pub fn edge_connectivity(g: &Graph) -> u32 {
    assert!(!g.directed, "This edge connectivity algorithm only supports undirected graphs");

    let maximum_flows = (1..g.vertex_count).map(|i| maximum_flow(g, 0, i));
    let connectivity = maximum_flows.min();

    match connectivity {
        Some(c) => c,
        None => 0,
    }
}
<commit_msg>[edge_connectivity/rust] Replace trivial pattern matching by unwrap_or<commit_after>use graph::Graph;
use maximum_flow::maximum_flow;

pub fn edge_connectivity(g: &Graph) -> u32 {
    assert!(!g.directed, "This edge connectivity algorithm only supports undirected graphs");

    let maximum_flows = (1..g.vertex_count).map(|i| maximum_flow(g, 0, i));
    let connectivity = maximum_flows.min();

    connectivity.unwrap_or(0)
}
<|endoftext|>


<commit_before>//! This module implements the in-memory database
//!
//! A support folder with SDK debug symbols can be processed into a
//! in-memory database format which is a flat file on the file system
//! that gets mmaped into the process.
use std::io::{Write, Seek, SeekFrom};
use std::mem;
use std::slice;
use std::cell::RefCell;
use std::collections::HashMap;

use uuid::Uuid;

use super::Result;
use super::sdk::SdkInfo;
use super::dsym::{Object, Variant};
use super::shoco::compress;
use super::memdbtypes::{IndexItem, StoredSlice, MemDbHeader, IndexedUuid};

// stored information:
//
//      object name + arch -> uuid
//      uuid -> stored variant
//      stored variant + addr -> symbol
//      symbol -> [object name id, symbol name id, symbol addr]
//      object name id -> object name
//      symbol name id -> symbol name
//

pub struct MemDbBuilder<W> {
    writer: RefCell<W>,
    info: SdkInfo,
    symbols: Vec<String>,
    symbols_map: HashMap<String, u32>,
    object_names: Vec<String>,
    object_names_map: HashMap<String, u16>,
    object_uuid_mapping: Vec<(String, Uuid)>,
    variant_uuids: Vec<IndexedUuid>,
    variants: Vec<Vec<IndexItem>>,
}

impl<W: Write + Seek> MemDbBuilder<W> {

    pub fn new(writer: W, info: &SdkInfo) -> Result<MemDbBuilder<W>> {
        let rv = MemDbBuilder {
            writer: RefCell::new(writer),
            info: info.clone(),
            symbols: vec![],
            symbols_map: HashMap::new(),
            object_names: vec![],
            object_names_map: HashMap::new(),
            object_uuid_mapping: vec![],
            variant_uuids: vec![],
            variants: vec![],
        };
        let header = MemDbHeader { ..Default::default() };
        rv.write(&header)?;
        Ok(rv)
    }

    fn write_bytes(&self, x: &[u8]) -> Result<usize> {
        self.writer.borrow_mut().write_all(x)?;
        Ok(x.len())
    }

    fn write<T>(&self, x: &T) -> Result<usize> {
        unsafe {
            let bytes : *const u8 = mem::transmute(x);
            let size = mem::size_of_val(x);
            self.writer.borrow_mut().write_all(slice::from_raw_parts(bytes, size))?;
            Ok(size)
        }
    }

    fn seek(&self, new_pos: usize) -> Result<()> {
        self.writer.borrow_mut().seek(SeekFrom::Start(new_pos as u64))?;
        Ok(())
    }

    fn tell(&self) -> Result<usize> {
        Ok(self.writer.borrow_mut().seek(SeekFrom::Current(0))? as usize)
    }

    fn add_symbol(&mut self, sym: &str) -> usize {
        if let Some(&sym_id) = self.symbols_map.get(sym) {
            return sym_id as usize;
        }
        let symbol_count = self.symbols.len();
        self.symbols.push(sym.to_string());
        self.symbols_map.insert(sym.to_string(), symbol_count as u32);
        symbol_count
    }

    fn add_object_name(&mut self, src: &str) -> usize {
        if let Some(&src_id) = self.object_names_map.get(src) {
            return src_id as usize;
        }
        let object_count = self.object_names.len();
        self.object_names.push(src.to_string());
        self.object_names_map.insert(src.to_string(), object_count as u16);
        object_count
    }

    pub fn write_object(&mut self, obj: &Object, filename: Option<&str>) -> Result<()> {
        for variant in obj.variants() {
            self.write_object_variant(&obj, &variant, filename)?;
        }
        Ok(())
    }

    pub fn write_object_variant(&mut self, obj: &Object, var: &Variant,
                                filename: Option<&str>) -> Result<()> {
        let mut symbols = obj.symbols(var.arch())?;
        let src = var.name().or(filename).unwrap();
        let src_id = self.add_object_name(src);

        // build symbol index
        let mut index = vec![];
        for (addr, sym) in symbols.iter() {
            let sym_id = self.add_symbol(sym);
            index.push(IndexItem::new(addr, src_id, sym_id));
        }
        index.sort_by_key(|item| item.addr());

        // register variant and uuid
        self.variant_uuids.push(IndexedUuid::new(&var.uuid().unwrap(), self.variants.len()));
        self.object_uuid_mapping.push((
            format!("{}:{}", src, var.arch()),
            var.uuid().unwrap()
        ));
        self.variants.push(index);

        Ok(())
    }

    fn make_string_slices(&self, strings: &[String], try_compress: bool) -> Result<Vec<StoredSlice>> {
        let mut slices = vec![];
        for string in strings {
            let offset = self.tell()?;
            if try_compress {
                let compressed = compress(string.as_bytes());
                if compressed.len() < string.as_bytes().len() {
                    let len = self.write_bytes(compressed.as_slice())?;
                    slices.push(StoredSlice::new(offset, len, true));
                    continue;
                }
            }
            let len = self.write_bytes(string.as_bytes())?;
            slices.push(StoredSlice::new(offset, len, false));
        }
        Ok(slices)
    }

    fn write_slices(&self, slices: &[StoredSlice], start: &mut u32, len: &mut u32) -> Result<()> {
        *start = self.tell()? as u32;
        for item in slices.iter() {
            self.write(item)?;
        }
        *len = slices.len() as u32;
        Ok(())
    }

    pub fn flush(&mut self) -> Result<()> {
        let mut header = MemDbHeader { ..Default::default() };
        header.version = 1;

        // start by writing out the index of the variants and record the slices.
        let mut slices = vec![];
        for variant in self.variants.iter() {
            let offset = self.tell()?;
            for index_item in variant {
                self.write(index_item)?;
            }
            slices.push(StoredSlice::new(offset, (self.tell()? - offset), false));
        }
        self.write_slices(&slices[..], &mut header.variants_start,
                          &mut header.variants_count)?;

        // next write out the UUIDs.  Since these are fixed length we do not
        // need to use slices here.
        header.uuids_start = self.tell()? as u32;
        header.uuids_count = self.variant_uuids.len() as u32;
        self.variant_uuids.sort_by_key(|x| x.uuid);
        for indexed_uuid in self.variant_uuids.iter() {
            self.write(indexed_uuid)?;
        }

        // next we write out the name + arch -> uuid index mapping.  We also sort
        // this by uuid so that the index matches up.
        header.tagged_object_names_start = self.tell()? as u32;
        self.object_uuid_mapping.sort_by_key(|&(_, b)| b);
        for &(ref tagged_object, _) in self.object_uuid_mapping.iter() {
            self.write_bytes(format!("{}\x00", tagged_object).as_bytes())?;
        }
        header.tagged_object_names_end = self.tell()? as u32;

        // now write out all the object name sources
        let slices = self.make_string_slices(&self.object_names[..], true)?;
        self.write_slices(&slices[..], &mut header.object_names_start,
                          &mut header.object_names_count)?;

        // now write out all the symbols
        let slices = self.make_string_slices(&self.symbols[..], true)?;
        self.write_slices(&slices[..], &mut header.symbols_start,
                          &mut header.symbols_count)?;

        // write the updated header
        self.seek(0)?;
        self.write(&header)?;

        Ok(())
    }
}
<commit_msg>Kill a comment<commit_after>//! This module implements the in-memory database
//!
//! A support folder with SDK debug symbols can be processed into a
//! in-memory database format which is a flat file on the file system
//! that gets mmaped into the process.
use std::io::{Write, Seek, SeekFrom};
use std::mem;
use std::slice;
use std::cell::RefCell;
use std::collections::HashMap;

use uuid::Uuid;

use super::Result;
use super::sdk::SdkInfo;
use super::dsym::{Object, Variant};
use super::shoco::compress;
use super::memdbtypes::{IndexItem, StoredSlice, MemDbHeader, IndexedUuid};

pub struct MemDbBuilder<W> {
    writer: RefCell<W>,
    info: SdkInfo,
    symbols: Vec<String>,
    symbols_map: HashMap<String, u32>,
    object_names: Vec<String>,
    object_names_map: HashMap<String, u16>,
    object_uuid_mapping: Vec<(String, Uuid)>,
    variant_uuids: Vec<IndexedUuid>,
    variants: Vec<Vec<IndexItem>>,
}

impl<W: Write + Seek> MemDbBuilder<W> {

    pub fn new(writer: W, info: &SdkInfo) -> Result<MemDbBuilder<W>> {
        let rv = MemDbBuilder {
            writer: RefCell::new(writer),
            info: info.clone(),
            symbols: vec![],
            symbols_map: HashMap::new(),
            object_names: vec![],
            object_names_map: HashMap::new(),
            object_uuid_mapping: vec![],
            variant_uuids: vec![],
            variants: vec![],
        };
        let header = MemDbHeader { ..Default::default() };
        rv.write(&header)?;
        Ok(rv)
    }

    fn write_bytes(&self, x: &[u8]) -> Result<usize> {
        self.writer.borrow_mut().write_all(x)?;
        Ok(x.len())
    }

    fn write<T>(&self, x: &T) -> Result<usize> {
        unsafe {
            let bytes : *const u8 = mem::transmute(x);
            let size = mem::size_of_val(x);
            self.writer.borrow_mut().write_all(slice::from_raw_parts(bytes, size))?;
            Ok(size)
        }
    }

    fn seek(&self, new_pos: usize) -> Result<()> {
        self.writer.borrow_mut().seek(SeekFrom::Start(new_pos as u64))?;
        Ok(())
    }

    fn tell(&self) -> Result<usize> {
        Ok(self.writer.borrow_mut().seek(SeekFrom::Current(0))? as usize)
    }

    fn add_symbol(&mut self, sym: &str) -> usize {
        if let Some(&sym_id) = self.symbols_map.get(sym) {
            return sym_id as usize;
        }
        let symbol_count = self.symbols.len();
        self.symbols.push(sym.to_string());
        self.symbols_map.insert(sym.to_string(), symbol_count as u32);
        symbol_count
    }

    fn add_object_name(&mut self, src: &str) -> usize {
        if let Some(&src_id) = self.object_names_map.get(src) {
            return src_id as usize;
        }
        let object_count = self.object_names.len();
        self.object_names.push(src.to_string());
        self.object_names_map.insert(src.to_string(), object_count as u16);
        object_count
    }

    pub fn write_object(&mut self, obj: &Object, filename: Option<&str>) -> Result<()> {
        for variant in obj.variants() {
            self.write_object_variant(&obj, &variant, filename)?;
        }
        Ok(())
    }

    pub fn write_object_variant(&mut self, obj: &Object, var: &Variant,
                                filename: Option<&str>) -> Result<()> {
        let mut symbols = obj.symbols(var.arch())?;
        let src = var.name().or(filename).unwrap();
        let src_id = self.add_object_name(src);

        // build symbol index
        let mut index = vec![];
        for (addr, sym) in symbols.iter() {
            let sym_id = self.add_symbol(sym);
            index.push(IndexItem::new(addr, src_id, sym_id));
        }
        index.sort_by_key(|item| item.addr());

        // register variant and uuid
        self.variant_uuids.push(IndexedUuid::new(&var.uuid().unwrap(), self.variants.len()));
        self.object_uuid_mapping.push((
            format!("{}:{}", src, var.arch()),
            var.uuid().unwrap()
        ));
        self.variants.push(index);

        Ok(())
    }

    fn make_string_slices(&self, strings: &[String], try_compress: bool) -> Result<Vec<StoredSlice>> {
        let mut slices = vec![];
        for string in strings {
            let offset = self.tell()?;
            if try_compress {
                let compressed = compress(string.as_bytes());
                if compressed.len() < string.as_bytes().len() {
                    let len = self.write_bytes(compressed.as_slice())?;
                    slices.push(StoredSlice::new(offset, len, true));
                    continue;
                }
            }
            let len = self.write_bytes(string.as_bytes())?;
            slices.push(StoredSlice::new(offset, len, false));
        }
        Ok(slices)
    }

    fn write_slices(&self, slices: &[StoredSlice], start: &mut u32, len: &mut u32) -> Result<()> {
        *start = self.tell()? as u32;
        for item in slices.iter() {
            self.write(item)?;
        }
        *len = slices.len() as u32;
        Ok(())
    }

    pub fn flush(&mut self) -> Result<()> {
        let mut header = MemDbHeader { ..Default::default() };
        header.version = 1;

        // start by writing out the index of the variants and record the slices.
        let mut slices = vec![];
        for variant in self.variants.iter() {
            let offset = self.tell()?;
            for index_item in variant {
                self.write(index_item)?;
            }
            slices.push(StoredSlice::new(offset, (self.tell()? - offset), false));
        }
        self.write_slices(&slices[..], &mut header.variants_start,
                          &mut header.variants_count)?;

        // next write out the UUIDs.  Since these are fixed length we do not
        // need to use slices here.
        header.uuids_start = self.tell()? as u32;
        header.uuids_count = self.variant_uuids.len() as u32;
        self.variant_uuids.sort_by_key(|x| x.uuid);
        for indexed_uuid in self.variant_uuids.iter() {
            self.write(indexed_uuid)?;
        }

        // next we write out the name + arch -> uuid index mapping.  We also sort
        // this by uuid so that the index matches up.
        header.tagged_object_names_start = self.tell()? as u32;
        self.object_uuid_mapping.sort_by_key(|&(_, b)| b);
        for &(ref tagged_object, _) in self.object_uuid_mapping.iter() {
            self.write_bytes(format!("{}\x00", tagged_object).as_bytes())?;
        }
        header.tagged_object_names_end = self.tell()? as u32;

        // now write out all the object name sources
        let slices = self.make_string_slices(&self.object_names[..], true)?;
        self.write_slices(&slices[..], &mut header.object_names_start,
                          &mut header.object_names_count)?;

        // now write out all the symbols
        let slices = self.make_string_slices(&self.symbols[..], true)?;
        self.write_slices(&slices[..], &mut header.symbols_start,
                          &mut header.symbols_count)?;

        // write the updated header
        self.seek(0)?;
        self.write(&header)?;

        Ok(())
    }
}
<|endoftext|>


<commit_before>// Make me compile! Scroll down for hints :)

mod us_presidential_frontrunners {
    use self::democrats::HILLARY_CLINTON as democrat;
    use self::republicans::DONALD_TRUMP as republican;

    mod democrats {
        pub const HILLARY_CLINTON: &'static str = "Hillary Clinton";
        pub const BERNIE_SANDERS: &'static str = "Bernie Sanders";
    }

    mod republicans {
        pub const DONALD_TRUMP: &'static str = "Donald Trump";
        pub const JEB_BUSH: &'static str = "Jeb Bush";
    }
}

fn main() {
    println!("candidates: {} and {}",
             us_presidential_frontrunners::democrat,
             us_presidential_frontrunners::republican);
}

// The us_presidential_frontrunners module is trying to present an external
// interface (the `democrat` and `republican` constants) that is different than
// its internal structure (the `democrats` and `republicans` modules and
// associated constants). It's almost there except for one keyword missing for
// each constant.
// One more hint: I wish the compiler error, instead of saying "unresolved name
// `us_presidential_frontrunners::democrat`", could say  "constant
// `us_presidential_frontrunners::democrat` is private"!<commit_msg>Update modules2.rs<commit_after>// Make me compile! Scroll down for hints :)

mod us_presidential_frontrunners {
    use self::democrats::HILLARY_CLINTON as democrat;
    use self::republicans::DONALD_TRUMP as republican;

    mod democrats {
        pub const HILLARY_CLINTON: &'static str = "Hillary Clinton";
        pub const BERNIE_SANDERS: &'static str = "Bernie Sanders";
    }

    mod republicans {
        pub const DONALD_TRUMP: &'static str = "Donald Trump";
        pub const JEB_BUSH: &'static str = "Jeb Bush";
    }
}

fn main() {
    println!("candidates: {} and {}",
             us_presidential_frontrunners::democrat,
             us_presidential_frontrunners::republican);
}

// The us_presidential_frontrunners module is trying to present an external
// interface (the `democrat` and `republican` constants) that is different than
// its internal structure (the `democrats` and `republicans` modules and
// associated constants). It's almost there except for one keyword missing for
// each constant.
<|endoftext|>