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

// The rust-book CSS in string form.

pub static STYLE: &'static str = r#"
@import url("../rust.css");

body {
    max-width:none;
}

#toc {
    position: absolute;
    left: 0px;
    top: 0px;
    bottom: 0px;
    width: 250px;
    overflow-y: auto;
    border-right: 1px solid rgba(0, 0, 0, 0.07);
    padding: 10px 10px;
    font-size: 16px;
    background: none repeat scroll 0% 0% #FFF;
    box-sizing: border-box;
}

#page-wrapper {
    position: absolute;
    overflow-y: auto;
    left: 260px;
    right: 0px;
    top: 0px;
    bottom: 0px;
    box-sizing: border-box;
    background: none repeat scroll 0% 0% #FFF;
}

#page {
    margin-left: auto;
    margin-right:auto;
    max-width: 750px;
}

.chapter {
    list-style: none outside none;
    padding-left: 0px;
    line-height: 30px;
}

.section {
    list-style: none outside none;
    padding-left: 20px;
    line-height: 30px;
}

.section li {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}

.chapter li a {
    color: #000000;
}

@media only screen and (max-width: 1060px) {
    #toc {
        width: 100%;
        margin-right: 0;
        top: 40px;
    }
    #page-wrapper {
        top: 40px;
        left: 15px;
        padding-right: 15px;
    }
    .mobile-hidden {
        display: none;
    }
}

#toggle-nav {
    height: 20px;
    width:  30px;
    padding: 3px 3px 0 3px;
}

#toggle-nav {
    margin-top: 5px;
    width: 30px;
    height: 30px;
    background-color: #FFF;
    border: 1px solid #666;
    border-radius: 3px 3px 3px 3px;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0;
}

.bar {
    display: block;
    background-color: #000;
    border-radius: 2px;
    width: 100%;
    height: 2px;
    margin: 2px 0 3px;
    padding: 0;
}

"#;
<commit_msg>Rollup merge of 21651 - nelsonjchen:add--webkit-overflow-scrolling-touch-to-book-css, r=alexcrichton<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// The rust-book CSS in string form.

pub static STYLE: &'static str = r#"
@import url("../rust.css");

body {
    max-width:none;
}

#toc {
    position: absolute;
    left: 0px;
    top: 0px;
    bottom: 0px;
    width: 250px;
    overflow-y: auto;
    border-right: 1px solid rgba(0, 0, 0, 0.07);
    padding: 10px 10px;
    font-size: 16px;
    background: none repeat scroll 0% 0% #FFF;
    box-sizing: border-box;
    -webkit-overflow-scrolling: touch;
}

#page-wrapper {
    position: absolute;
    overflow-y: auto;
    left: 260px;
    right: 0px;
    top: 0px;
    bottom: 0px;
    box-sizing: border-box;
    background: none repeat scroll 0% 0% #FFF;
    -webkit-overflow-scrolling: touch;
}

#page {
    margin-left: auto;
    margin-right:auto;
    max-width: 750px;
}

.chapter {
    list-style: none outside none;
    padding-left: 0px;
    line-height: 30px;
}

.section {
    list-style: none outside none;
    padding-left: 20px;
    line-height: 30px;
}

.section li {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}

.chapter li a {
    color: #000000;
}

@media only screen and (max-width: 1060px) {
    #toc {
        width: 100%;
        margin-right: 0;
        top: 40px;
    }
    #page-wrapper {
        top: 40px;
        left: 15px;
        padding-right: 15px;
    }
    .mobile-hidden {
        display: none;
    }
}

#toggle-nav {
    height: 20px;
    width:  30px;
    padding: 3px 3px 0 3px;
}

#toggle-nav {
    margin-top: 5px;
    width: 30px;
    height: 30px;
    background-color: #FFF;
    border: 1px solid #666;
    border-radius: 3px 3px 3px 3px;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0;
}

.bar {
    display: block;
    background-color: #000;
    border-radius: 2px;
    width: 100%;
    height: 2px;
    margin: 2px 0 3px;
    padding: 0;
}

"#;
<|endoftext|>


<commit_before>// no-reformat

#[doc = "

    A demonstration module

    Contains documentation in various forms that rustdoc understands,
    for testing purposes. It doesn't surve any functional
    purpose. This here, for instance, is just some filler text.

    FIXME (1654): It would be nice if we could run some automated
    tests on this file

"];

#[doc = "The base price of a muffin on a non-holiday"]
const price_of_a_muffin: float = 70f;

type waitress = {
    hair_color: str
};

#[doc = "The type of things that produce omnomnom"]
enum omnomnomy {
    #[doc = "Delicious sugar cookies"]
    cookie,
    #[doc = "It's pizza"]
    pizza_pie([uint])
}

fn take_my_order_please(
    _waitress: waitress,
    _order: [omnomnomy]
) -> uint {

    #[doc(
        desc = "OMG would you take my order already?",
        args(_waitress = "The waitress that you want to bother",
             _order = "The order vector. It should be filled with food."),
        return = "The price of the order, including tax",
        failure = "This function is full of fail"
    )];

    fail;
}

mod fortress_of_solitude {
    #[doc(
        brief = "Superman's vacation home",
        desc = "

        The fortress of solitude is located in the Arctic and it is
        cold. What you may not know about the fortress of solitude
        though is that it contains two separate bowling alleys. One of
        them features bumper-bowling and is kind of lame.

        Really, it's pretty cool.

    ")];

}

mod blade_runner {
    #[doc(
        brief = "Blade Runner is probably the best movie ever",
        desc = "I like that in the world of Blade Runner it is always
                raining, and that it's always night time. And Aliens
                was also a really good movie.

                Alien 3 was crap though."
    )];
}

#[doc(
    brief = "Bored",
    desc = "

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec
    molestie nisl. Duis massa risus, pharetra a scelerisque a,
    molestie eu velit. Donec mattis ligula at ante imperdiet ut
    dapibus mauris malesuada. Sed gravida nisi a metus elementum sit
    amet hendrerit dolor bibendum. Aenean sit amet neque massa, sed
    tempus tortor. Sed ut lobortis enim. Proin a mauris quis nunc
    fermentum ultrices eget a erat. Mauris in lectus vitae metus
    sodales auctor. Morbi nunc quam, ultricies at venenatis non,
    pellentesque ac dui.

    Quisque vitae est id eros placerat laoreet sit amet eu
    nisi. Curabitur suscipit neque porttitor est euismod
    lacinia. Curabitur non quam vitae ipsum adipiscing
    condimentum. Mauris ut ante eget metus sollicitudin
    blandit. Aliquam erat volutpat. Morbi sed nisl mauris. Nulla
    facilisi. Phasellus at mollis ipsum. Maecenas sed convallis
    sapien. Nullam in ligula turpis. Pellentesque a neque augue. Sed
    eget ante feugiat tortor congue auctor ac quis ante. Proin
    condimentum lacinia tincidunt.

")]
resource bored(bored: bool) {
    log(error, bored);
}

#[doc(
    brief = "The Shunned House",
    desc = "

From even the greatest of horrors irony is seldom absent. Sometimes it
enters directly into the composition of the events, while sometimes it
relates only to their fortuitous position among persons and
places. The latter sort is splendidly exemplified by a case in the
ancient city of Providence, where in the late forties Edgar Allan Poe
used to sojourn often during his unsuccessful wooing of the gifted
poetess, Mrs.  Whitman. Poe generally stopped at the Mansion House in
Benefit Street--the renamed Golden Ball Inn whose roof has sheltered
Washington, Jefferson, and Lafayette--and his favorite walk led
northward along the same street to Mrs. Whitman's home and the
neighboring hillside churchyard of St. John's, whose hidden expanse of
Eighteenth Century gravestones had for him a peculiar fascination.

")]
iface the_shunned_house {
    #[doc(
        desc = "

    Now the irony is this. In this walk, so many times repeated, the
    world's greatest master of the terrible and the bizarre was
    obliged to pass a particular house on the eastern side of the
    street; a dingy, antiquated structure perched on the abruptly
    rising side hill, with a great unkempt yard dating from a time
    when the region was partly open country. It does not appear that
    he ever wrote or spoke of it, nor is there any evidence that he
    even noticed it. And yet that house, to the two persons in
    possession of certain information, equals or outranks in horror
    the wildest fantasy of the genius who so often passed it
    unknowingly, and stands starkly leering as a symbol of all that is
    unutterably hideous.

    ",
        args(
            a =
            "A yard dating from a time when the region was partly
             open country"
    ))]
    fn dingy_house(unkempt_yard: int);

    #[doc(
        desc = "

    The house was--and for that matter still is--of a kind to attract
    the attention of the curious. Originally a farm or semi-farm
    building, it followed the average New England colonial lines of
    the middle Eighteenth Century--the prosperous peaked-roof sort,
    with two stories and dormerless attic, and with the Georgian
    doorway and interior panelling dictated by the progress of taste
    at that time. It faced south, with one gable end buried to the
    lower windows in the eastward rising hill, and the other exposed
    to the foundations toward the street. Its construction, over a
    century and a half ago, had followed the grading and straightening
    of the road in that especial vicinity; for Benefit Street--at
    first called Back Street--was laid out as a lane winding amongst
    the graveyards of the first settlers, and straightened only when
    the removal of the bodies to the North Burial Ground made it
    decently possible to cut through the old family plots.

    ",
        return = "A dingy house with an unkempt yard",
        failure = "Will fail if bodies are removed from premises"
    )]
    fn construct() -> bool;
}

#[doc = "Whatever"]
impl of the_shunned_house for omnomnomy {
    #[doc(args(_unkempt_yard = "Whatever"))]
    fn dingy_house(_unkempt_yard: int) {
    }

    fn construct() -> bool {
        fail;
    }
}<commit_msg>rustdoc: Add some more demo docs<commit_after>// no-reformat

#[doc = "

    A demonstration module

    Contains documentation in various forms that rustdoc understands,
    for testing purposes. It doesn't surve any functional
    purpose. This here, for instance, is just some filler text.

    FIXME (1654): It would be nice if we could run some automated
    tests on this file

"];

#[doc = "The base price of a muffin on a non-holiday"]
const price_of_a_muffin: float = 70f;

type waitress = {
    hair_color: str
};

#[doc = "The type of things that produce omnomnom"]
enum omnomnomy {
    #[doc = "Delicious sugar cookies"]
    cookie,
    #[doc = "It's pizza"]
    pizza_pie([uint])
}

fn take_my_order_please(
    _waitress: waitress,
    _order: [omnomnomy]
) -> uint {

    #[doc(
        desc = "OMG would you take my order already?",
        args(_waitress = "The waitress that you want to bother",
             _order = "The order vector. It should be filled with food."),
        return = "The price of the order, including tax",
        failure = "This function is full of fail"
    )];

    fail;
}

fn take_my_order_now(
    _waitress: waitress,
    _order: [omnomnomy]
) -> uint {

    #[doc(
        desc = "OMG would you take my order already?",
        args(_waitress = "The waitress that you want to bother",
             _order = "The order vector. It should be filled with food."),
        return = "

        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
        nec molestie nisl. Duis massa risus, pharetra a scelerisque a,
        molestie eu velit. Donec mattis ligula at ante imperdiet ut
        dapibus mauris malesuada.

        Sed gravida nisi a metus elementum sit amet hendrerit dolor
        bibendum. Aenean sit amet neque massa, sed tempus tortor. Sed
        ut lobortis enim. Proin a mauris quis nunc fermentum ultrices
        eget a erat. Mauris in lectus vitae metus sodales
        auctor. Morbi nunc quam, ultricies at venenatis non,
        pellentesque ac dui.

        ",
        failure = "This function is full of fail"
    )];

    fail;
}

mod fortress_of_solitude {
    #[doc(
        brief = "Superman's vacation home",
        desc = "

        The fortress of solitude is located in the Arctic and it is
        cold. What you may not know about the fortress of solitude
        though is that it contains two separate bowling alleys. One of
        them features bumper-bowling and is kind of lame.

        Really, it's pretty cool.

    ")];

}

mod blade_runner {
    #[doc(
        brief = "Blade Runner is probably the best movie ever",
        desc = "I like that in the world of Blade Runner it is always
                raining, and that it's always night time. And Aliens
                was also a really good movie.

                Alien 3 was crap though."
    )];
}

#[doc(
    brief = "Bored",
    desc = "

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec
    molestie nisl. Duis massa risus, pharetra a scelerisque a,
    molestie eu velit. Donec mattis ligula at ante imperdiet ut
    dapibus mauris malesuada. Sed gravida nisi a metus elementum sit
    amet hendrerit dolor bibendum. Aenean sit amet neque massa, sed
    tempus tortor. Sed ut lobortis enim. Proin a mauris quis nunc
    fermentum ultrices eget a erat. Mauris in lectus vitae metus
    sodales auctor. Morbi nunc quam, ultricies at venenatis non,
    pellentesque ac dui.

    Quisque vitae est id eros placerat laoreet sit amet eu
    nisi. Curabitur suscipit neque porttitor est euismod
    lacinia. Curabitur non quam vitae ipsum adipiscing
    condimentum. Mauris ut ante eget metus sollicitudin
    blandit. Aliquam erat volutpat. Morbi sed nisl mauris. Nulla
    facilisi. Phasellus at mollis ipsum. Maecenas sed convallis
    sapien. Nullam in ligula turpis. Pellentesque a neque augue. Sed
    eget ante feugiat tortor congue auctor ac quis ante. Proin
    condimentum lacinia tincidunt.

")]
resource bored(bored: bool) {
    log(error, bored);
}

#[doc(
    brief = "The Shunned House",
    desc = "

From even the greatest of horrors irony is seldom absent. Sometimes it
enters directly into the composition of the events, while sometimes it
relates only to their fortuitous position among persons and
places. The latter sort is splendidly exemplified by a case in the
ancient city of Providence, where in the late forties Edgar Allan Poe
used to sojourn often during his unsuccessful wooing of the gifted
poetess, Mrs.  Whitman. Poe generally stopped at the Mansion House in
Benefit Street--the renamed Golden Ball Inn whose roof has sheltered
Washington, Jefferson, and Lafayette--and his favorite walk led
northward along the same street to Mrs. Whitman's home and the
neighboring hillside churchyard of St. John's, whose hidden expanse of
Eighteenth Century gravestones had for him a peculiar fascination.

")]
iface the_shunned_house {
    #[doc(
        desc = "

    Now the irony is this. In this walk, so many times repeated, the
    world's greatest master of the terrible and the bizarre was
    obliged to pass a particular house on the eastern side of the
    street; a dingy, antiquated structure perched on the abruptly
    rising side hill, with a great unkempt yard dating from a time
    when the region was partly open country. It does not appear that
    he ever wrote or spoke of it, nor is there any evidence that he
    even noticed it. And yet that house, to the two persons in
    possession of certain information, equals or outranks in horror
    the wildest fantasy of the genius who so often passed it
    unknowingly, and stands starkly leering as a symbol of all that is
    unutterably hideous.

    ",
        args(
            a =
            "A yard dating from a time when the region was partly
             open country"
    ))]
    fn dingy_house(unkempt_yard: int);

    #[doc(
        desc = "

    The house was--and for that matter still is--of a kind to attract
    the attention of the curious. Originally a farm or semi-farm
    building, it followed the average New England colonial lines of
    the middle Eighteenth Century--the prosperous peaked-roof sort,
    with two stories and dormerless attic, and with the Georgian
    doorway and interior panelling dictated by the progress of taste
    at that time. It faced south, with one gable end buried to the
    lower windows in the eastward rising hill, and the other exposed
    to the foundations toward the street. Its construction, over a
    century and a half ago, had followed the grading and straightening
    of the road in that especial vicinity; for Benefit Street--at
    first called Back Street--was laid out as a lane winding amongst
    the graveyards of the first settlers, and straightened only when
    the removal of the bodies to the North Burial Ground made it
    decently possible to cut through the old family plots.

    ",
        return = "A dingy house with an unkempt yard",
        failure = "Will fail if bodies are removed from premises"
    )]
    fn construct() -> bool;
}

#[doc = "Whatever"]
impl of the_shunned_house for omnomnomy {
    #[doc(args(_unkempt_yard = "Whatever"))]
    fn dingy_house(_unkempt_yard: int) {
    }

    fn construct() -> bool {
        fail;
    }
}<|endoftext|>


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

use hbs_pow::HeartbeatPow as Heartbeat;
use hbs_pow::HeartbeatPowContext as HeartbeatContext;
use profile_traits::time::ProfilerCategory;
use std::collections::HashMap;
use std::env::var_os;
use std::error::Error;
use std::fs::File;
use std::mem;

static mut HBS: Option<*mut HashMap<ProfilerCategory, Heartbeat>> = None;

/// Initialize heartbeats
pub fn init() {
    let mut hbs: HashMap<ProfilerCategory, Heartbeat> = HashMap::new();
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::Compositing);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutPerform);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutStyleRecalc);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutRestyleDamagePropagation);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutNonIncrementalReset);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutSelectorMatch);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutTreeBuilder);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDamagePropagate);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutGeneratedContent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutMain);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutParallelWarmup);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutShaping);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDispListBuild);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPerTile);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPrepBuff);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::Painting);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ImageDecoding);
    unsafe {
        HBS = Some(mem::transmute(Box::new(hbs)));
    }
}

/// Log regmaining buffer data and cleanup heartbeats
pub fn cleanup() {
    unsafe {
        if let Some(hbs) = HBS {
            let mut h: Box<HashMap<ProfilerCategory, Heartbeat>> = mem::transmute(hbs);
            for (_, mut v) in h.iter_mut() {
                // log any remaining heartbeat records before dropping
                log_heartbeat_records(v);
            }
            h.clear();
        }
        HBS = None;
    }
}

/// Issue a heartbeat (if one exists) for the given category
pub fn maybe_heartbeat(category: &ProfilerCategory,
                       start_time: u64,
                       end_time: u64,
                       start_energy: u64,
                       end_energy: u64) {
    unsafe {
        if let Some(map) = HBS {
            if let Some(mut h) = (*map).get_mut(category) {
                (*h).heartbeat(0, 1, start_time, end_time, start_energy, end_energy);
            }
        }
    }
}

/// Create a heartbeat if the correct environment variable is set
fn maybe_create_heartbeat(hbs: &mut HashMap<ProfilerCategory, Heartbeat>,
                          category: ProfilerCategory) {
    static WINDOW_SIZE_DEFAULT: usize = 20;
    if let Some(_) = var_os(format!("SERVO_HEARTBEAT_ENABLE_{:?}", category)) {
        // get optional log file
        let logfile: Option<File> = var_os(format!("SERVO_HEARTBEAT_LOG_{:?}", category))
                                    .and_then(|name| File::create(name).ok());
        // get window size
        let window_size: usize = match var_os(format!("SERVO_HEARTBEAT_WINDOW_{:?}", category)) {
            Some(w) => match w.into_string() {
                Ok(s) => s.parse::<usize>().unwrap_or(WINDOW_SIZE_DEFAULT),
                _ => WINDOW_SIZE_DEFAULT,
            },
            None => WINDOW_SIZE_DEFAULT,
        };
        // create the heartbeat
        match Heartbeat::new(window_size, Some(heartbeat_window_callback), logfile) {
            Ok(hb) => {
                debug!("Created heartbeat for {:?}", category);
                hbs.insert(category, hb);
            },
            Err(e) => warn!("Failed to create heartbeat for {:?}: {}", category, e),
        }
    };
}

/// Log heartbeat records up to the buffer index
fn log_heartbeat_records(hb: &mut Heartbeat) {
    match hb.log_to_buffer_index() {
        Ok(_) => (),
        Err(e) => warn!("Failed to write heartbeat log: {}", Error::description(&e)),
    }
}

/// Callback function used to log the window buffer.
/// When this is called from native C, the heartbeat is safely locked
extern fn heartbeat_window_callback(hb: *const HeartbeatContext) {
    unsafe {
        if let Some(map) = HBS {
            for (_, v) in (*map).iter_mut() {
                if &v.hb as *const HeartbeatContext == hb {
                    log_heartbeat_records(v);
                }
            }
        }
    }
}
<commit_msg>Auto merge of #7567 - connorimes:script-heartbeats, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use hbs_pow::HeartbeatPow as Heartbeat;
use hbs_pow::HeartbeatPowContext as HeartbeatContext;
use profile_traits::time::ProfilerCategory;
use std::collections::HashMap;
use std::env::var_os;
use std::error::Error;
use std::fs::File;
use std::mem;

static mut HBS: Option<*mut HashMap<ProfilerCategory, Heartbeat>> = None;

/// Initialize heartbeats
pub fn init() {
    let mut hbs: HashMap<ProfilerCategory, Heartbeat> = HashMap::new();
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::Compositing);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutPerform);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutStyleRecalc);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutRestyleDamagePropagation);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutNonIncrementalReset);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutSelectorMatch);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutTreeBuilder);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDamagePropagate);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutGeneratedContent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutMain);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutParallelWarmup);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutShaping);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDispListBuild);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPerTile);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPrepBuff);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::Painting);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ImageDecoding);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptAttachLayout);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptConstellationMsg);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptDevtoolsMsg);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptDocumentEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptDomEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptFileRead);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptImageCacheMsg);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptInputEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptNetworkEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptResize);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptUpdateReplacedElement);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptSetViewport);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptWebSocketEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptWorkerEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptXhrEvent);
    unsafe {
        HBS = Some(mem::transmute(Box::new(hbs)));
    }
}

/// Log regmaining buffer data and cleanup heartbeats
pub fn cleanup() {
    unsafe {
        if let Some(hbs) = HBS {
            let mut h: Box<HashMap<ProfilerCategory, Heartbeat>> = mem::transmute(hbs);
            for (_, mut v) in h.iter_mut() {
                // log any remaining heartbeat records before dropping
                log_heartbeat_records(v);
            }
            h.clear();
        }
        HBS = None;
    }
}

/// Issue a heartbeat (if one exists) for the given category
pub fn maybe_heartbeat(category: &ProfilerCategory,
                       start_time: u64,
                       end_time: u64,
                       start_energy: u64,
                       end_energy: u64) {
    unsafe {
        if let Some(map) = HBS {
            if let Some(mut h) = (*map).get_mut(category) {
                (*h).heartbeat(0, 1, start_time, end_time, start_energy, end_energy);
            }
        }
    }
}

/// Create a heartbeat if the correct environment variable is set
fn maybe_create_heartbeat(hbs: &mut HashMap<ProfilerCategory, Heartbeat>,
                          category: ProfilerCategory) {
    static WINDOW_SIZE_DEFAULT: usize = 20;
    if let Some(_) = var_os(format!("SERVO_HEARTBEAT_ENABLE_{:?}", category)) {
        // get optional log file
        let logfile: Option<File> = var_os(format!("SERVO_HEARTBEAT_LOG_{:?}", category))
                                    .and_then(|name| File::create(name).ok());
        // get window size
        let window_size: usize = match var_os(format!("SERVO_HEARTBEAT_WINDOW_{:?}", category)) {
            Some(w) => match w.into_string() {
                Ok(s) => s.parse::<usize>().unwrap_or(WINDOW_SIZE_DEFAULT),
                _ => WINDOW_SIZE_DEFAULT,
            },
            None => WINDOW_SIZE_DEFAULT,
        };
        // create the heartbeat
        match Heartbeat::new(window_size, Some(heartbeat_window_callback), logfile) {
            Ok(hb) => {
                debug!("Created heartbeat for {:?}", category);
                hbs.insert(category, hb);
            },
            Err(e) => warn!("Failed to create heartbeat for {:?}: {}", category, e),
        }
    };
}

/// Log heartbeat records up to the buffer index
fn log_heartbeat_records(hb: &mut Heartbeat) {
    match hb.log_to_buffer_index() {
        Ok(_) => (),
        Err(e) => warn!("Failed to write heartbeat log: {}", Error::description(&e)),
    }
}

/// Callback function used to log the window buffer.
/// When this is called from native C, the heartbeat is safely locked
extern fn heartbeat_window_callback(hb: *const HeartbeatContext) {
    unsafe {
        if let Some(map) = HBS {
            for (_, v) in (*map).iter_mut() {
                if &v.hb as *const HeartbeatContext == hb {
                    log_heartbeat_records(v);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate rlua;

use self::rlua::prelude::*;
use antidote::RwLock;
use irc::client::prelude::*;
use std::fmt;
use std::str::FromStr;

use chrono::NaiveDateTime;
use time;

use plugin::*;
pub mod database;
use self::database::Database;

mod utils;
use self::utils::*;
use utils::Url;

use self::error::*;
use error::ErrorKind as FrippyErrorKind;
use error::FrippyError;
use failure::ResultExt;

static LUA_SANDBOX: &'static str = include_str!("sandbox.lua");

enum FactoidResponse {
    Public(String),
    Private(String),
}

#[derive(PluginName)]
pub struct Factoids<T: Database> {
    factoids: RwLock<T>,
}

impl<T: Database> Factoids<T> {
    pub fn new(db: T) -> Factoids<T> {
        Factoids {
            factoids: RwLock::new(db),
        }
    }

    fn create_factoid(
        &self,
        name: &str,
        content: &str,
        author: &str,
    ) -> Result<&str, FactoidsError> {
        let count = self.factoids.read().count_factoids(name)?;
        let tm = time::now().to_timespec();

        let factoid = database::NewFactoid {
            name: name,
            idx: count,
            content: content,
            author: author,
            created: NaiveDateTime::from_timestamp(tm.sec, 0u32),
        };

        Ok(self.factoids
            .write()
            .insert_factoid(&factoid)
            .map(|()| "Successfully added!")?)
    }

    fn add(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> {
        if command.tokens.len() < 2 {
            Err(ErrorKind::InvalidCommand)?;
        }

        let name = command.tokens.remove(0);
        let content = command.tokens.join(" ");

        Ok(self.create_factoid(&name, &content, &command.source)?)
    }

    fn add_from_url(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> {
        if command.tokens.len() < 2 {
            Err(ErrorKind::InvalidCommand)?;
        }

        let name = command.tokens.remove(0);
        let url = &command.tokens[0];
        let content = Url::from(url.as_ref())
            .max_kib(1024)
            .request()
            .context(ErrorKind::Download)?;

        Ok(self.create_factoid(&name, &content, &command.source)?)
    }

    fn remove(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> {
        if command.tokens.len() < 1 {
            Err(ErrorKind::InvalidCommand)?;
        }

        let name = command.tokens.remove(0);
        let count = self.factoids.read().count_factoids(&name)?;

        match self.factoids.write().delete_factoid(&name, count - 1) {
            Ok(()) => Ok("Successfully removed"),
            Err(e) => Err(e)?,
        }
    }

    fn get(&self, command: &PluginCommand) -> Result<String, FactoidsError> {
        let (name, idx) = match command.tokens.len() {
            0 => Err(ErrorKind::InvalidCommand)?,
            1 => {
                let name = &command.tokens[0];
                let count = self.factoids.read().count_factoids(name)?;

                if count < 1 {
                    Err(ErrorKind::NotFound)?;
                }

                (name, count - 1)
            }
            _ => {
                let name = &command.tokens[0];
                let idx = match i32::from_str(&command.tokens[1]) {
                    Ok(i) => i,
                    Err(_) => Err(ErrorKind::InvalidCommand)?,
                };

                (name, idx)
            }
        };

        let factoid = self.factoids
            .read()
            .get_factoid(name, idx)
            .context(ErrorKind::NotFound)?;

        let message = factoid.content.replace("\n", "|").replace("\r", "");

        Ok(format!("{}: {}", factoid.name, message))
    }

    fn info(&self, command: &PluginCommand) -> Result<String, FactoidsError> {
        match command.tokens.len() {
            0 => Err(ErrorKind::InvalidCommand)?,
            1 => {
                let name = &command.tokens[0];
                let count = self.factoids.read().count_factoids(name)?;

                Ok(match count {
                    0 => Err(ErrorKind::NotFound)?,
                    1 => format!("There is 1 version of {}", name),
                    _ => format!("There are {} versions of {}", count, name),
                })
            }
            _ => {
                let name = &command.tokens[0];
                let idx = i32::from_str(&command.tokens[1]).context(ErrorKind::InvalidIndex)?;
                let factoid = self.factoids.read().get_factoid(name, idx)?;

                Ok(format!(
                    "{}: Added by {} at {} UTC",
                    name, factoid.author, factoid.created
                ))
            }
        }
    }

    fn exec(&self, mut command: PluginCommand) -> Result<String, FactoidsError> {
        if command.tokens.len() < 1 {
            Err(ErrorKind::InvalidIndex)?
        } else {
            let name = command.tokens.remove(0);
            let count = self.factoids.read().count_factoids(&name)?;
            let factoid = self.factoids.read().get_factoid(&name, count - 1)?;

            let content = factoid.content;
            let value = if content.starts_with('>') {
                let content = String::from(&content[1..]);

                if content.starts_with('>') {
                    content
                } else {
                    match self.run_lua(&name, &content, &command) {
                        Ok(v) => v,
                        Err(e) => match e {
                            LuaError::CallbackError { cause, .. } => cause.to_string(),
                            _ => e.to_string(),
                        },
                    }
                }
            } else {
                content
            };

            Ok(value.replace("\n", "|").replace("\r", ""))
        }
    }

    fn run_lua(&self, name: &str, code: &str, command: &PluginCommand) -> Result<String, LuaError> {
        let args = command
            .tokens
            .iter()
            .filter(|x| !x.is_empty())
            .map(ToOwned::to_owned)
            .collect::<Vec<String>>();

        let lua = unsafe { Lua::new_with_debug() };
        let globals = lua.globals();

        globals.set("factoid", code)?;
        globals.set("download", lua.create_function(download)?)?;
        globals.set("sleep", lua.create_function(sleep)?)?;
        globals.set("args", args)?;
        globals.set("input", command.tokens.join(" "))?;
        globals.set("user", command.source.clone())?;
        globals.set("channel", command.target.clone())?;
        globals.set("output", lua.create_table()?)?;

        lua.exec::<()>(LUA_SANDBOX, Some(name))?;
        let output: Vec<String> = globals.get::<_, Vec<String>>("output")?;

        Ok(output.join("|"))
    }

    fn help(&self) -> &str {
        "usage: factoids <subcommand>\r\n\
         subcommands: add, fromurl, remove, info, get, exec, help"
    }
}

impl<T: Database> Plugin for Factoids<T> {
    fn execute(&self, _: &IrcClient, message: &Message) -> ExecutionStatus {
        match message.command {
            Command::PRIVMSG(_, ref content) => if content.starts_with('!') {
                ExecutionStatus::RequiresThread
            } else {
                ExecutionStatus::Done
            },
            _ => ExecutionStatus::Done,
        }
    }

    fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), FrippyError> {
        if let Command::PRIVMSG(_, mut content) = message.command.clone() {
            content.remove(0);

            let t: Vec<String> = content.split(' ').map(ToOwned::to_owned).collect();

            let c = PluginCommand {
                source: message.source_nickname().unwrap().to_owned(),
                target: message.response_target().unwrap().to_owned(),
                tokens: t,
            };

            Ok(match self.exec(c) {
                Ok(f) => client
                    .send_privmsg(&message.response_target().unwrap(), &f)
                    .context(FrippyErrorKind::Connection)?,
                Err(_) => (),
            })
        } else {
            Ok(())
        }
    }

    fn command(&self, client: &IrcClient, mut command: PluginCommand) -> Result<(), FrippyError> {
        use self::FactoidResponse::{Private, Public};

        if command.tokens.is_empty() {
            return Ok(client
                .send_notice(&command.target, "Invalid command")
                .context(FrippyErrorKind::Connection)?);
        }

        let target = command.target.clone();
        let source = command.source.clone();

        let sub_command = command.tokens.remove(0);
        let result = match sub_command.as_ref() {
            "add" => self.add(&mut command).map(|s| Private(s.to_owned())),
            "fromurl" => self.add_from_url(&mut command)
                .map(|s| Private(s.to_owned())),
            "remove" => self.remove(&mut command).map(|s| Private(s.to_owned())),
            "get" => self.get(&command).map(|s| Public(s)),
            "info" => self.info(&command).map(|s| Public(s)),
            "exec" => self.exec(command).map(|s| Public(s)),
            "help" => Ok(Private(self.help().to_owned())),
            _ => Err(ErrorKind::InvalidCommand.into()),
        };

        Ok(match result {
            Ok(v) => match v {
                Public(m) => client
                    .send_privmsg(&target, &m)
                    .context(FrippyErrorKind::Connection)?,
                Private(m) => client
                    .send_notice(&source, &m)
                    .context(FrippyErrorKind::Connection)?,
            },
            Err(e) => {
                let message = e.to_string();
                client
                    .send_notice(&source, &message)
                    .context(FrippyErrorKind::Connection)?;
                Err(e).context(FrippyErrorKind::Factoids)?
            }
        })
    }

    fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result<String, String> {
        Err(String::from(
            "Evaluation of commands is not implemented for Factoids at this time",
        ))
    }
}

impl<T: Database> fmt::Debug for Factoids<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Factoids {{ ... }}")
    }
}

pub mod error {
    #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)]
    #[error = "FactoidsError"]
    pub enum ErrorKind {
        /// Invalid command error
        #[fail(display = "Invalid Command")]
        InvalidCommand,

        /// Invalid index error
        #[fail(display = "Invalid index")]
        InvalidIndex,

        /// Download  error
        #[fail(display = "Download failed")]
        Download,

        /// Duplicate error
        #[fail(display = "Entry already exists")]
        Duplicate,

        /// Not found error
        #[fail(display = "Factoid was not found")]
        NotFound,

        /// MySQL error
        #[cfg(feature = "mysql")]
        #[fail(display = "Failed to execute MySQL Query")]
        MysqlError,

        /// No connection error
        #[cfg(feature = "mysql")]
        #[fail(display = "No connection to the database")]
        NoConnection,
    }
}
<commit_msg>Factoids: Fix notice target on missing subcmd<commit_after>extern crate rlua;

use self::rlua::prelude::*;
use antidote::RwLock;
use irc::client::prelude::*;
use std::fmt;
use std::str::FromStr;

use chrono::NaiveDateTime;
use time;

use plugin::*;
pub mod database;
use self::database::Database;

mod utils;
use self::utils::*;
use utils::Url;

use self::error::*;
use error::ErrorKind as FrippyErrorKind;
use error::FrippyError;
use failure::ResultExt;

static LUA_SANDBOX: &'static str = include_str!("sandbox.lua");

enum FactoidResponse {
    Public(String),
    Private(String),
}

#[derive(PluginName)]
pub struct Factoids<T: Database> {
    factoids: RwLock<T>,
}

impl<T: Database> Factoids<T> {
    pub fn new(db: T) -> Factoids<T> {
        Factoids {
            factoids: RwLock::new(db),
        }
    }

    fn create_factoid(
        &self,
        name: &str,
        content: &str,
        author: &str,
    ) -> Result<&str, FactoidsError> {
        let count = self.factoids.read().count_factoids(name)?;
        let tm = time::now().to_timespec();

        let factoid = database::NewFactoid {
            name: name,
            idx: count,
            content: content,
            author: author,
            created: NaiveDateTime::from_timestamp(tm.sec, 0u32),
        };

        Ok(self.factoids
            .write()
            .insert_factoid(&factoid)
            .map(|()| "Successfully added!")?)
    }

    fn add(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> {
        if command.tokens.len() < 2 {
            Err(ErrorKind::InvalidCommand)?;
        }

        let name = command.tokens.remove(0);
        let content = command.tokens.join(" ");

        Ok(self.create_factoid(&name, &content, &command.source)?)
    }

    fn add_from_url(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> {
        if command.tokens.len() < 2 {
            Err(ErrorKind::InvalidCommand)?;
        }

        let name = command.tokens.remove(0);
        let url = &command.tokens[0];
        let content = Url::from(url.as_ref())
            .max_kib(1024)
            .request()
            .context(ErrorKind::Download)?;

        Ok(self.create_factoid(&name, &content, &command.source)?)
    }

    fn remove(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> {
        if command.tokens.len() < 1 {
            Err(ErrorKind::InvalidCommand)?;
        }

        let name = command.tokens.remove(0);
        let count = self.factoids.read().count_factoids(&name)?;

        match self.factoids.write().delete_factoid(&name, count - 1) {
            Ok(()) => Ok("Successfully removed"),
            Err(e) => Err(e)?,
        }
    }

    fn get(&self, command: &PluginCommand) -> Result<String, FactoidsError> {
        let (name, idx) = match command.tokens.len() {
            0 => Err(ErrorKind::InvalidCommand)?,
            1 => {
                let name = &command.tokens[0];
                let count = self.factoids.read().count_factoids(name)?;

                if count < 1 {
                    Err(ErrorKind::NotFound)?;
                }

                (name, count - 1)
            }
            _ => {
                let name = &command.tokens[0];
                let idx = match i32::from_str(&command.tokens[1]) {
                    Ok(i) => i,
                    Err(_) => Err(ErrorKind::InvalidCommand)?,
                };

                (name, idx)
            }
        };

        let factoid = self.factoids
            .read()
            .get_factoid(name, idx)
            .context(ErrorKind::NotFound)?;

        let message = factoid.content.replace("\n", "|").replace("\r", "");

        Ok(format!("{}: {}", factoid.name, message))
    }

    fn info(&self, command: &PluginCommand) -> Result<String, FactoidsError> {
        match command.tokens.len() {
            0 => Err(ErrorKind::InvalidCommand)?,
            1 => {
                let name = &command.tokens[0];
                let count = self.factoids.read().count_factoids(name)?;

                Ok(match count {
                    0 => Err(ErrorKind::NotFound)?,
                    1 => format!("There is 1 version of {}", name),
                    _ => format!("There are {} versions of {}", count, name),
                })
            }
            _ => {
                let name = &command.tokens[0];
                let idx = i32::from_str(&command.tokens[1]).context(ErrorKind::InvalidIndex)?;
                let factoid = self.factoids.read().get_factoid(name, idx)?;

                Ok(format!(
                    "{}: Added by {} at {} UTC",
                    name, factoid.author, factoid.created
                ))
            }
        }
    }

    fn exec(&self, mut command: PluginCommand) -> Result<String, FactoidsError> {
        if command.tokens.len() < 1 {
            Err(ErrorKind::InvalidIndex)?
        } else {
            let name = command.tokens.remove(0);
            let count = self.factoids.read().count_factoids(&name)?;
            let factoid = self.factoids.read().get_factoid(&name, count - 1)?;

            let content = factoid.content;
            let value = if content.starts_with('>') {
                let content = String::from(&content[1..]);

                if content.starts_with('>') {
                    content
                } else {
                    match self.run_lua(&name, &content, &command) {
                        Ok(v) => v,
                        Err(e) => match e {
                            LuaError::CallbackError { cause, .. } => cause.to_string(),
                            _ => e.to_string(),
                        },
                    }
                }
            } else {
                content
            };

            Ok(value.replace("\n", "|").replace("\r", ""))
        }
    }

    fn run_lua(&self, name: &str, code: &str, command: &PluginCommand) -> Result<String, LuaError> {
        let args = command
            .tokens
            .iter()
            .filter(|x| !x.is_empty())
            .map(ToOwned::to_owned)
            .collect::<Vec<String>>();

        let lua = unsafe { Lua::new_with_debug() };
        let globals = lua.globals();

        globals.set("factoid", code)?;
        globals.set("download", lua.create_function(download)?)?;
        globals.set("sleep", lua.create_function(sleep)?)?;
        globals.set("args", args)?;
        globals.set("input", command.tokens.join(" "))?;
        globals.set("user", command.source.clone())?;
        globals.set("channel", command.target.clone())?;
        globals.set("output", lua.create_table()?)?;

        lua.exec::<()>(LUA_SANDBOX, Some(name))?;
        let output: Vec<String> = globals.get::<_, Vec<String>>("output")?;

        Ok(output.join("|"))
    }

    fn help(&self) -> &str {
        "usage: factoids <subcommand>\r\n\
         subcommands: add, fromurl, remove, info, get, exec, help"
    }
}

impl<T: Database> Plugin for Factoids<T> {
    fn execute(&self, _: &IrcClient, message: &Message) -> ExecutionStatus {
        match message.command {
            Command::PRIVMSG(_, ref content) => if content.starts_with('!') {
                ExecutionStatus::RequiresThread
            } else {
                ExecutionStatus::Done
            },
            _ => ExecutionStatus::Done,
        }
    }

    fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), FrippyError> {
        if let Command::PRIVMSG(_, mut content) = message.command.clone() {
            content.remove(0);

            let t: Vec<String> = content.split(' ').map(ToOwned::to_owned).collect();

            let c = PluginCommand {
                source: message.source_nickname().unwrap().to_owned(),
                target: message.response_target().unwrap().to_owned(),
                tokens: t,
            };

            Ok(match self.exec(c) {
                Ok(f) => client
                    .send_privmsg(&message.response_target().unwrap(), &f)
                    .context(FrippyErrorKind::Connection)?,
                Err(_) => (),
            })
        } else {
            Ok(())
        }
    }

    fn command(&self, client: &IrcClient, mut command: PluginCommand) -> Result<(), FrippyError> {
        use self::FactoidResponse::{Private, Public};

        if command.tokens.is_empty() {
            return Ok(client
                .send_notice(&command.source, "Invalid command")
                .context(FrippyErrorKind::Connection)?);
        }

        let target = command.target.clone();
        let source = command.source.clone();

        let sub_command = command.tokens.remove(0);
        let result = match sub_command.as_ref() {
            "add" => self.add(&mut command).map(|s| Private(s.to_owned())),
            "fromurl" => self.add_from_url(&mut command)
                .map(|s| Private(s.to_owned())),
            "remove" => self.remove(&mut command).map(|s| Private(s.to_owned())),
            "get" => self.get(&command).map(|s| Public(s)),
            "info" => self.info(&command).map(|s| Public(s)),
            "exec" => self.exec(command).map(|s| Public(s)),
            "help" => Ok(Private(self.help().to_owned())),
            _ => Err(ErrorKind::InvalidCommand.into()),
        };

        Ok(match result {
            Ok(v) => match v {
                Public(m) => client
                    .send_privmsg(&target, &m)
                    .context(FrippyErrorKind::Connection)?,
                Private(m) => client
                    .send_notice(&source, &m)
                    .context(FrippyErrorKind::Connection)?,
            },
            Err(e) => {
                let message = e.to_string();
                client
                    .send_notice(&source, &message)
                    .context(FrippyErrorKind::Connection)?;
                Err(e).context(FrippyErrorKind::Factoids)?
            }
        })
    }

    fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result<String, String> {
        Err(String::from(
            "Evaluation of commands is not implemented for Factoids at this time",
        ))
    }
}

impl<T: Database> fmt::Debug for Factoids<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Factoids {{ ... }}")
    }
}

pub mod error {
    #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)]
    #[error = "FactoidsError"]
    pub enum ErrorKind {
        /// Invalid command error
        #[fail(display = "Invalid Command")]
        InvalidCommand,

        /// Invalid index error
        #[fail(display = "Invalid index")]
        InvalidIndex,

        /// Download  error
        #[fail(display = "Download failed")]
        Download,

        /// Duplicate error
        #[fail(display = "Entry already exists")]
        Duplicate,

        /// Not found error
        #[fail(display = "Factoid was not found")]
        NotFound,

        /// MySQL error
        #[cfg(feature = "mysql")]
        #[fail(display = "Failed to execute MySQL Query")]
        MysqlError,

        /// No connection error
        #[cfg(feature = "mysql")]
        #[fail(display = "No connection to the database")]
        NoConnection,
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::process::Command;
use std::str::{self, FromStr};

fn main() {
    let rustc = match env::var_os("RUSTC") {
        Some(rustc) => rustc,
        None => return,
    };

    let output = match Command::new(rustc).arg("--version").output() {
        Ok(output) => output,
        Err(_) => return,
    };

    let version = match str::from_utf8(&output.stdout) {
        Ok(version) => version,
        Err(_) => return,
    };

    let mut pieces = version.split('.');
    if pieces.next() != Some("rustc 1") {
        return;
    }

    let next = match pieces.next() {
        Some(next) => next,
        None => return,
    };

    let minor = match u32::from_str(next) {
        Ok(minor) => minor,
        Err(_) => return,
    };

    if minor >= 26 {
        println!("cargo:rustc-cfg=integer128");
    }
}
<commit_msg>Link to i128 announcement<commit_after>use std::env;
use std::process::Command;
use std::str::{self, FromStr};

fn main() {
    let rustc = match env::var_os("RUSTC") {
        Some(rustc) => rustc,
        None => return,
    };

    let output = match Command::new(rustc).arg("--version").output() {
        Ok(output) => output,
        Err(_) => return,
    };

    let version = match str::from_utf8(&output.stdout) {
        Ok(version) => version,
        Err(_) => return,
    };

    let mut pieces = version.split('.');
    if pieces.next() != Some("rustc 1") {
        return;
    }

    let next = match pieces.next() {
        Some(next) => next,
        None => return,
    };

    let minor = match u32::from_str(next) {
        Ok(minor) => minor,
        Err(_) => return,
    };

    // 128-bit integers stabilized in Rust 1.26:
    // https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
    if minor >= 26 {
        println!("cargo:rustc-cfg=integer128");
    }
}
<|endoftext|>


<commit_before>extern crate docopt;
extern crate flac;
extern crate hound;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::{ErrorKind, StreamReader};

use std::env;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

const USAGE: &'static str = "
Usage: decode <input> <output>
       decode <input>... <dir>
       decode --help

Options:
  -h, --help   Show this message.
";

#[derive(RustcDecodable)]
struct Arguments {
  arg_input: Vec<String>,
  arg_output: Option<String>,
  arg_dir: Option<String>,
}

fn to_io_error(kind: ErrorKind) -> hound::Error {
  match kind {
    ErrorKind::IO(e) => {
      let io_error = io::Error::new(e, "io error");

      hound::Error::IoError(io_error)
    }
    _                => hound::Error::Unsupported,
  }
}

fn decode_file(input_file: &str, output_file: &str)
               -> Result<(), hound::Error> {
  let mut stream = try! {
    StreamReader::<fs::File>::from_file(input_file)
      .map_err(to_io_error)
  };

  let info = stream.info();
  let spec = hound::WavSpec {
    channels: info.channels as u16,
    sample_rate: info.sample_rate,
    bits_per_sample: info.bits_per_sample as u16,
  };

  let mut output = try!(hound::WavWriter::create(output_file, spec));

  if info.bits_per_sample <= 8 {
    for sample in stream.iter::<i16>() {
      try!(output.write_sample(sample));
    }
  }

  output.finalize()
}

fn to_output_file(buffer: &mut PathBuf, path: &Path, directory: &str)
                  -> Result<(), hound::Error> {
  buffer.push(directory);

  path.file_name().map(|name| {
    buffer.push(name);
    buffer.set_extension("wav");
  }).ok_or_else(|| {
    let kind    = io::ErrorKind::NotFound;
    let message = "no file name found";
    let error   = io::Error::new(kind, message);

    hound::Error::IoError(error)
  })
}

fn decode_all_files(input_files: &Vec<String>, directory: &str)
                    -> Result<(), hound::Error> {
  let dir_path = Path::new(directory);

  if !dir_path.exists() {
    try!(fs::create_dir(dir_path).map_err(hound::Error::IoError))
  }

  for ref input_file in input_files {
    let mut buffer = PathBuf::new();
    let path       = Path::new(input_file);

    try!(to_output_file(&mut buffer, path, directory));

    let output_file = try! {
      buffer.to_str().ok_or_else(|| {
        let kind    = io::ErrorKind::InvalidInput;
        let message = "invalid unicode with file path";
        let error   = io::Error::new(kind, message);

        hound::Error::IoError(error)
      })
    };

    let result = decode_file(input_file, output_file);

    if result.is_ok() {
      println!("decoded: {} -> {}", input_file, output_file);
    } else {
      return result;
    }
  }

  Ok(())
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  if let Some(ref output_file) = args.arg_output {
    let input_file = &args.arg_input[0];

    if let Err(e) = decode_file(input_file, output_file) {
      println!("{:?}", e);
    } else {
      println!("decoded: {} -> {}", input_file, output_file);
    }
  } else if let Some(ref directory) = args.arg_dir {
    if let Err(e) = decode_all_files(&args.arg_input, directory) {
      println!("{:?}", e);
    }
  }
}
<commit_msg>Add specific size for bits_per_sample 16 and lower<commit_after>extern crate docopt;
extern crate flac;
extern crate hound;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::{ErrorKind, StreamReader};

use std::env;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

const USAGE: &'static str = "
Usage: decode <input> <output>
       decode <input>... <dir>
       decode --help

Options:
  -h, --help   Show this message.
";

#[derive(RustcDecodable)]
struct Arguments {
  arg_input: Vec<String>,
  arg_output: Option<String>,
  arg_dir: Option<String>,
}

fn to_io_error(kind: ErrorKind) -> hound::Error {
  match kind {
    ErrorKind::IO(e) => {
      let io_error = io::Error::new(e, "io error");

      hound::Error::IoError(io_error)
    }
    _                => hound::Error::Unsupported,
  }
}

fn decode_file(input_file: &str, output_file: &str)
               -> Result<(), hound::Error> {
  let mut stream = try! {
    StreamReader::<fs::File>::from_file(input_file)
      .map_err(to_io_error)
  };

  let info = stream.info();
  let spec = hound::WavSpec {
    channels: info.channels as u16,
    sample_rate: info.sample_rate,
    bits_per_sample: info.bits_per_sample as u16,
  };

  let mut output = try!(hound::WavWriter::create(output_file, spec));

  if info.bits_per_sample <= 8 {
    for sample in stream.iter::<i16>() {
      try!(output.write_sample(sample));
    }
  } else if info.bits_per_sample <= 16 {
    for sample in stream.iter::<i32>() {
      try!(output.write_sample(sample));
    }
  }

  output.finalize()
}

fn to_output_file(buffer: &mut PathBuf, path: &Path, directory: &str)
                  -> Result<(), hound::Error> {
  buffer.push(directory);

  path.file_name().map(|name| {
    buffer.push(name);
    buffer.set_extension("wav");
  }).ok_or_else(|| {
    let kind    = io::ErrorKind::NotFound;
    let message = "no file name found";
    let error   = io::Error::new(kind, message);

    hound::Error::IoError(error)
  })
}

fn decode_all_files(input_files: &Vec<String>, directory: &str)
                    -> Result<(), hound::Error> {
  let dir_path = Path::new(directory);

  if !dir_path.exists() {
    try!(fs::create_dir(dir_path).map_err(hound::Error::IoError))
  }

  for ref input_file in input_files {
    let mut buffer = PathBuf::new();
    let path       = Path::new(input_file);

    try!(to_output_file(&mut buffer, path, directory));

    let output_file = try! {
      buffer.to_str().ok_or_else(|| {
        let kind    = io::ErrorKind::InvalidInput;
        let message = "invalid unicode with file path";
        let error   = io::Error::new(kind, message);

        hound::Error::IoError(error)
      })
    };

    let result = decode_file(input_file, output_file);

    if result.is_ok() {
      println!("decoded: {} -> {}", input_file, output_file);
    } else {
      return result;
    }
  }

  Ok(())
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  if let Some(ref output_file) = args.arg_output {
    let input_file = &args.arg_input[0];

    if let Err(e) = decode_file(input_file, output_file) {
      println!("{:?}", e);
    } else {
      println!("decoded: {} -> {}", input_file, output_file);
    }
  } else if let Some(ref directory) = args.arg_dir {
    if let Err(e) = decode_all_files(&args.arg_input, directory) {
      println!("{:?}", e);
    }
  }
}
<|endoftext|>


<commit_before>use crate::utils::{is_type_diagnostic_item, span_lint_and_help};
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind, Mutability};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for `&mut Mutex::lock` calls
    ///
    /// **Why is this bad?** `Mutex::lock` is less efficient than
    /// calling `Mutex::get_mut`
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// use std::sync::{Arc, Mutex};
    ///
    /// let mut value_rc = Arc::new(Mutex::new(42_u8));
    /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
    ///
    /// let mut value = value_mutex.lock().unwrap();
    /// *value += 1;
    /// ```
    /// Use instead:
    /// ```rust
    /// use std::sync::{Arc, Mutex};
    ///
    /// let mut value_rc = Arc::new(Mutex::new(42_u8));
    /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
    ///
    /// let value = value_mutex.get_mut().unwrap();
    /// *value += 1;
    /// ```
    pub MUT_MUTEX_LOCK,
    correctness,
    "`&mut Mutex::lock` does unnecessary locking"
}

declare_lint_pass!(MutMutexLock => [MUT_MUTEX_LOCK]);

impl<'tcx> LateLintPass<'tcx> for MutMutexLock {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>) {
        if_chain! {
            if is_mut_mutex_lock_call(cx, ex).is_some();
            then {
                span_lint_and_help(
                    cx,
                    MUT_MUTEX_LOCK,
                    ex.span,
                    "calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference",
                    None,
                    "use `&mut Mutex::get_mut` instead",
                );
            }
        }
    }
}

fn is_mut_mutex_lock_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
    if_chain! {
        if let ExprKind::MethodCall(path, _span, args, _) = &expr.kind;
        if path.ident.name == sym!(lock);
        let ty = cx.typeck_results().expr_ty(&args[0]);
        if let ty::Ref(_, inner_ty, Mutability::Mut) = ty.kind();
        if is_type_diagnostic_item(cx, inner_ty, sym!(mutex_type));
        then {
            Some(&args[0])
        } else {
            None
        }
    }
}
<commit_msg>Inline is_mut_mutex_lock_call<commit_after>use crate::utils::{is_type_diagnostic_item, span_lint_and_help};
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind, Mutability};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for `&mut Mutex::lock` calls
    ///
    /// **Why is this bad?** `Mutex::lock` is less efficient than
    /// calling `Mutex::get_mut`
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// use std::sync::{Arc, Mutex};
    ///
    /// let mut value_rc = Arc::new(Mutex::new(42_u8));
    /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
    ///
    /// let mut value = value_mutex.lock().unwrap();
    /// *value += 1;
    /// ```
    /// Use instead:
    /// ```rust
    /// use std::sync::{Arc, Mutex};
    ///
    /// let mut value_rc = Arc::new(Mutex::new(42_u8));
    /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
    ///
    /// let value = value_mutex.get_mut().unwrap();
    /// *value += 1;
    /// ```
    pub MUT_MUTEX_LOCK,
    correctness,
    "`&mut Mutex::lock` does unnecessary locking"
}

declare_lint_pass!(MutMutexLock => [MUT_MUTEX_LOCK]);

impl<'tcx> LateLintPass<'tcx> for MutMutexLock {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>) {
        if_chain! {
            if let ExprKind::MethodCall(path, _span, args, _) = &ex.kind;
            if path.ident.name == sym!(lock);
            let ty = cx.typeck_results().expr_ty(&args[0]);
            if let ty::Ref(_, inner_ty, Mutability::Mut) = ty.kind();
            if is_type_diagnostic_item(cx, inner_ty, sym!(mutex_type));
            then {
                span_lint_and_help(
                    cx,
                    MUT_MUTEX_LOCK,
                    ex.span,
                    "calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference",
                    None,
                    "use `&mut Mutex::get_mut` instead",
                );
            }
        }
    }
}
<|endoftext|>


<commit_before>use crate::time;
use crate::context;
use crate::syscall::data::TimeSpec;
use crate::syscall::error::*;
use crate::syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC};

pub fn clock_gettime(clock: usize, time: &mut TimeSpec) -> Result<usize> {
    let arch_time = match clock {
        CLOCK_REALTIME => time::realtime(),
        CLOCK_MONOTONIC => time::monotonic(),
        _ => return Err(Error::new(EINVAL))
    };

    time.tv_sec = arch_time.0 as i64;
    time.tv_nsec = arch_time.1 as i32;
    Ok(0)
}

/// Nanosleep will sleep by switching the current context
pub fn nanosleep(req: &TimeSpec, rem_opt: Option<&mut TimeSpec>) -> Result<usize> {
    //start is a tuple of (seconds, nanoseconds)
    let start = time::monotonic();
    let sum = start.1 + req.tv_nsec as u64;
    let end = (start.0 + req.tv_sec as u64 + sum / 1_000_000_000, sum % 1_000_000_000);

    {
        let contexts = context::contexts();
        let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
        let mut context = context_lock.write();

        context.wake = Some(end);
        context.block();
    }

    unsafe { context::switch(); }

    if let Some(rem) = rem_opt {
        //TODO let current = time::monotonic();
        rem.tv_sec = 0;
        rem.tv_nsec = 0;
    }

    Ok(0)
}

pub fn sched_yield() -> Result<usize> {
    unsafe { context::switch(); }
    Ok(0)
}
<commit_msg>implement remaninder for nanosleep<commit_after>use crate::time;
use crate::context;
use crate::syscall::data::TimeSpec;
use crate::syscall::error::*;
use crate::syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC};

pub fn clock_gettime(clock: usize, time: &mut TimeSpec) -> Result<usize> {
    let arch_time = match clock {
        CLOCK_REALTIME => time::realtime(),
        CLOCK_MONOTONIC => time::monotonic(),
        _ => return Err(Error::new(EINVAL))
    };

    time.tv_sec = arch_time.0 as i64;
    time.tv_nsec = arch_time.1 as i32;
    Ok(0)
}

/// Nanosleep will sleep by switching the current context
pub fn nanosleep(req: &TimeSpec, rem_opt: Option<&mut TimeSpec>) -> Result<usize> {
    //start is a tuple of (seconds, nanoseconds)
    let start = time::monotonic();
    let sum = start.1 + req.tv_nsec as u64;
    let mut end = (start.0 + req.tv_sec as u64 + sum / 1_000_000_000, sum % 1_000_000_000);

    {
        let contexts = context::contexts();
        let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
        let mut context = context_lock.write();

        context.wake = Some(end);
        context.block();
    }

    unsafe { context::switch(); }

    if let Some(rem) = rem_opt {
        let current = time::monotonic();

        if current.0 < end.0 || (current.0 == end.0 && current.1 < end.1) {
            if end.1 < current.1 {
                end.0 -= 1;
                end.1 += 1_000_000_000;
            }

            rem.tv_sec = (end.0 - current.0) as i64;
            rem.tv_nsec = (end.1 - current.1) as i32;
        } else {
            rem.tv_sec = 0;
            rem.tv_nsec = 0;
        }
    }

    Ok(0)
}

pub fn sched_yield() -> Result<usize> {
    unsafe { context::switch(); }
    Ok(0)
}
<|endoftext|>


<commit_before>//! **Plexus** is a library for polygonal mesh processing.
//!
//! Please note that versions in the `0.0.*` series are experimental and
//! unstable! Use exact version constraints when specifying a dependency to
//! avoid spurious breakage.

// TODO: Documentation comments include static image content from the GitHub
//       repository. This is fragile and difficult to maintain. Use a mechanism
//       provided by rustdoc or doxidize for this instead.

use std::fmt::Debug;

// Feature modules. These are empty unless features are enabled.
mod cgmath;
mod mint;
mod nalgebra;

pub mod buffer;
pub mod encoding;
pub mod graph;
pub mod index;
pub mod primitive;

pub use theon::{AsPosition, Position};
pub use typenum::{U2, U3, U4};

use crate::graph::PayloadBinding;

pub mod prelude {
    //! Re-exports commonly used types and traits.
    //!
    //! Importing the contents of this module is recommended when working with
    //! generators and iterator expressions, as those operations are expressed
    //! mostly through traits.
    //!
    //! # Traits
    //!
    //! This module re-exports numerous traits. Traits from the `primitive`
    //! module for generating and decomposing iterators over topological data
    //! (e.g., `Trigon`, `Tetragon`, etc.) are re-exported so that functions in
    //! iterator expressions can be used without lengthy imports.
    //!
    //! Basic traits for (de)constructing `MeshBuffer`s and `MeshGraph`s are
    //! also re-exported. These traits allow mesh types to be constructed from
    //! raw buffers and buffers to be re-indexed.
    //!
    //! # Types
    //!
    //! The `Selector` enum and its variants are re-exported for convenience.
    //! `Selector` is often used when mutating `MeshGraph`s.

    pub use crate::buffer::{IntoFlatIndex as _, IntoStructuredIndex as _};
    pub use crate::graph::Selector;
    pub use crate::index::{CollectWithIndexer as _, IndexVertices as _};
    pub use crate::primitive::decompose::{
        Edges as _, IntoEdges as _, IntoSubdivisions as _, IntoTetrahedrons as _, IntoTrigons as _,
        IntoVertices as _, Subdivide as _, Tetrahedrons as _, Triangulate as _, Vertices as _,
    };
    pub use crate::primitive::generate::Generator as _;
    pub use crate::primitive::{MapVertices as _, Topological as _};
    pub use crate::IteratorExt as _;
    pub use crate::{
        FromGeometry as _, FromRawBuffers as _, FromRawBuffersWithArity as _, IntoGeometry as _,
    };

    pub use Selector::ByIndex;
    pub use Selector::ByKey;
}

pub enum Arity {
    Uniform(usize),
    NonUniform(usize, usize),
}

pub trait FromRawBuffers<N, G>: Sized {
    type Error: Debug;

    fn from_raw_buffers<I, J>(indices: I, vertices: J) -> Result<Self, Self::Error>
    where
        I: IntoIterator<Item = N>,
        J: IntoIterator<Item = G>;
}

pub trait FromRawBuffersWithArity<N, G>: Sized {
    type Error: Debug;

    fn from_raw_buffers_with_arity<I, J>(
        indices: I,
        vertices: J,
        arity: usize,
    ) -> Result<Self, Self::Error>
    where
        I: IntoIterator<Item = N>,
        J: IntoIterator<Item = G>;
}

pub trait FromGeometry<T> {
    fn from_geometry(other: T) -> Self;
}

impl<T> FromGeometry<T> for T {
    fn from_geometry(other: T) -> Self {
        other
    }
}

impl<T> FromGeometry<()> for T
where
    T: UnitGeometry,
{
    fn from_geometry(_: ()) -> Self {
        T::default()
    }
}

pub trait UnitGeometry: Default {}

pub trait IntoGeometry<T> {
    fn into_geometry(self) -> T;
}

impl<T, U> IntoGeometry<U> for T
where
    U: FromGeometry<T>,
{
    fn into_geometry(self) -> U {
        U::from_geometry(self)
    }
}

/// Extension methods for types implementing `Iterator`.
pub trait IteratorExt: Iterator + Sized {
    /// Provides an iterator over a window of duplets that includes the first
    /// value in the sequence at the beginning and end of the iteration.
    ///
    /// Given a collection of ordered elements $\\{a, b, c\\}$, this iterator
    /// yeilds the ordered items $\\{(a, b), (b, c), (c, a)\\}$.
    fn perimeter(self) -> Perimeter<Self>
    where
        Self::Item: Clone,
    {
        Perimeter::new(self)
    }

    /// Maps an iterator over topological views to the keys of those views.
    ///
    /// It is often useful to examine or collect the keys of views over a
    /// `MeshGraph`. This iterator avoids redundant use of `map` to extract
    /// keys.
    ///
    /// # Examples
    ///
    /// Collecting keys of faces before a topological mutation:
    ///
    /// ```rust
    /// # extern crate decorum;
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use decorum::R64;
    /// use nalgebra::Point3;
    /// use plexus::graph::MeshGraph;
    /// use plexus::prelude::*;
    /// use plexus::primitive::generate::Position;
    /// use plexus::primitive::sphere::UvSphere;
    ///
    /// type E3 = Point3<R64>;
    ///
    /// # fn main() {
    /// let mut graph = UvSphere::new(6, 6)
    ///     .polygons::<Position<E3>>()
    ///     .collect::<MeshGraph<E3>>();
    ///
    /// let keys = graph
    ///     .faces()
    ///     .filter(|face| face.arity() > 3)
    ///     .keys()
    ///     .collect::<Vec<_>>();
    /// for key in keys {
    ///     graph.face_mut(key).unwrap().poke_with_offset(0.5);
    /// }
    /// # }
    /// ```
    fn keys(self) -> Keys<Self>
    where
        Self::Item: PayloadBinding,
    {
        Keys::new(self)
    }
}

impl<I> IteratorExt for I where I: Iterator {}

/// Iterator that produces a window of duplets over its input.
///
/// The duplets produced include the first value in the input sequence at both
/// the beginning and end of the iteration, forming a perimeter. Given a
/// collection of ordered elements $\\{a, b, c\\}$, this iterator yields the
/// ordered items $\\{(a, b), (b, c), (c, a)\\}$.
pub struct Perimeter<I>
where
    I: Iterator,
    I::Item: Clone,
{
    input: I,
    first: Option<I::Item>,
    previous: Option<I::Item>,
}

impl<I> Perimeter<I>
where
    I: Iterator,
    I::Item: Clone,
{
    fn new(mut input: I) -> Self {
        let first = input.next();
        let previous = first.clone();
        Perimeter {
            input,
            first,
            previous,
        }
    }
}

impl<I> Iterator for Perimeter<I>
where
    I: Iterator,
    I::Item: Clone,
{
    type Item = (I::Item, I::Item);

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.input.next();
        match (self.previous.clone(), next.or_else(|| self.first.take())) {
            (Some(a), Some(b)) => {
                self.previous = Some(b.clone());
                Some((a, b))
            }
            _ => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.input.size_hint()
    }
}

pub struct Keys<I>
where
    I: Iterator,
    I::Item: PayloadBinding,
{
    input: I,
}

impl<I> Keys<I>
where
    I: Iterator,
    I::Item: PayloadBinding,
{
    fn new(input: I) -> Self {
        Keys { input }
    }
}

impl<I> Iterator for Keys<I>
where
    I: Iterator,
    I::Item: PayloadBinding,
{
    type Item = <I::Item as PayloadBinding>::Key;

    fn next(&mut self) -> Option<Self::Item> {
        self.input.next().map(|view| view.key())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.input.size_hint()
    }
}
<commit_msg>Add `Polygonal` to the prelude.<commit_after>//! **Plexus** is a library for polygonal mesh processing.
//!
//! Please note that versions in the `0.0.*` series are experimental and
//! unstable! Use exact version constraints when specifying a dependency to
//! avoid spurious breakage.

// TODO: Documentation comments include static image content from the GitHub
//       repository. This is fragile and difficult to maintain. Use a mechanism
//       provided by rustdoc or doxidize for this instead.

use std::fmt::Debug;

// Feature modules. These are empty unless features are enabled.
mod cgmath;
mod mint;
mod nalgebra;

pub mod buffer;
pub mod encoding;
pub mod graph;
pub mod index;
pub mod primitive;

pub use theon::{AsPosition, Position};
pub use typenum::{U2, U3, U4};

use crate::graph::PayloadBinding;

pub mod prelude {
    //! Re-exports commonly used types and traits.
    //!
    //! Importing the contents of this module is recommended when working with
    //! generators and iterator expressions, as those operations are expressed
    //! mostly through traits.
    //!
    //! # Traits
    //!
    //! This module re-exports numerous traits. Traits from the `primitive`
    //! module for generating and decomposing iterators over topological data
    //! (e.g., `Trigon`, `Tetragon`, etc.) are re-exported so that functions in
    //! iterator expressions can be used without lengthy imports.
    //!
    //! Basic traits for (de)constructing `MeshBuffer`s and `MeshGraph`s are
    //! also re-exported. These traits allow mesh types to be constructed from
    //! raw buffers and buffers to be re-indexed.
    //!
    //! # Types
    //!
    //! The `Selector` enum and its variants are re-exported for convenience.
    //! `Selector` is often used when mutating `MeshGraph`s.

    pub use crate::buffer::{IntoFlatIndex as _, IntoStructuredIndex as _};
    pub use crate::graph::Selector;
    pub use crate::index::{CollectWithIndexer as _, IndexVertices as _};
    pub use crate::primitive::decompose::{
        Edges as _, IntoEdges as _, IntoSubdivisions as _, IntoTetrahedrons as _, IntoTrigons as _,
        IntoVertices as _, Subdivide as _, Tetrahedrons as _, Triangulate as _, Vertices as _,
    };
    pub use crate::primitive::generate::Generator as _;
    pub use crate::primitive::{MapVertices as _, Polygonal as _, Topological as _};
    pub use crate::IteratorExt as _;
    pub use crate::{
        FromGeometry as _, FromRawBuffers as _, FromRawBuffersWithArity as _, IntoGeometry as _,
    };

    pub use Selector::ByIndex;
    pub use Selector::ByKey;
}

pub enum Arity {
    Uniform(usize),
    NonUniform(usize, usize),
}

pub trait FromRawBuffers<N, G>: Sized {
    type Error: Debug;

    fn from_raw_buffers<I, J>(indices: I, vertices: J) -> Result<Self, Self::Error>
    where
        I: IntoIterator<Item = N>,
        J: IntoIterator<Item = G>;
}

pub trait FromRawBuffersWithArity<N, G>: Sized {
    type Error: Debug;

    fn from_raw_buffers_with_arity<I, J>(
        indices: I,
        vertices: J,
        arity: usize,
    ) -> Result<Self, Self::Error>
    where
        I: IntoIterator<Item = N>,
        J: IntoIterator<Item = G>;
}

pub trait FromGeometry<T> {
    fn from_geometry(other: T) -> Self;
}

impl<T> FromGeometry<T> for T {
    fn from_geometry(other: T) -> Self {
        other
    }
}

impl<T> FromGeometry<()> for T
where
    T: UnitGeometry,
{
    fn from_geometry(_: ()) -> Self {
        T::default()
    }
}

pub trait UnitGeometry: Default {}

pub trait IntoGeometry<T> {
    fn into_geometry(self) -> T;
}

impl<T, U> IntoGeometry<U> for T
where
    U: FromGeometry<T>,
{
    fn into_geometry(self) -> U {
        U::from_geometry(self)
    }
}

/// Extension methods for types implementing `Iterator`.
pub trait IteratorExt: Iterator + Sized {
    /// Provides an iterator over a window of duplets that includes the first
    /// value in the sequence at the beginning and end of the iteration.
    ///
    /// Given a collection of ordered elements $\\{a, b, c\\}$, this iterator
    /// yeilds the ordered items $\\{(a, b), (b, c), (c, a)\\}$.
    fn perimeter(self) -> Perimeter<Self>
    where
        Self::Item: Clone,
    {
        Perimeter::new(self)
    }

    /// Maps an iterator over topological views to the keys of those views.
    ///
    /// It is often useful to examine or collect the keys of views over a
    /// `MeshGraph`. This iterator avoids redundant use of `map` to extract
    /// keys.
    ///
    /// # Examples
    ///
    /// Collecting keys of faces before a topological mutation:
    ///
    /// ```rust
    /// # extern crate decorum;
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use decorum::R64;
    /// use nalgebra::Point3;
    /// use plexus::graph::MeshGraph;
    /// use plexus::prelude::*;
    /// use plexus::primitive::generate::Position;
    /// use plexus::primitive::sphere::UvSphere;
    ///
    /// type E3 = Point3<R64>;
    ///
    /// # fn main() {
    /// let mut graph = UvSphere::new(6, 6)
    ///     .polygons::<Position<E3>>()
    ///     .collect::<MeshGraph<E3>>();
    ///
    /// let keys = graph
    ///     .faces()
    ///     .filter(|face| face.arity() > 3)
    ///     .keys()
    ///     .collect::<Vec<_>>();
    /// for key in keys {
    ///     graph.face_mut(key).unwrap().poke_with_offset(0.5);
    /// }
    /// # }
    /// ```
    fn keys(self) -> Keys<Self>
    where
        Self::Item: PayloadBinding,
    {
        Keys::new(self)
    }
}

impl<I> IteratorExt for I where I: Iterator {}

/// Iterator that produces a window of duplets over its input.
///
/// The duplets produced include the first value in the input sequence at both
/// the beginning and end of the iteration, forming a perimeter. Given a
/// collection of ordered elements $\\{a, b, c\\}$, this iterator yields the
/// ordered items $\\{(a, b), (b, c), (c, a)\\}$.
pub struct Perimeter<I>
where
    I: Iterator,
    I::Item: Clone,
{
    input: I,
    first: Option<I::Item>,
    previous: Option<I::Item>,
}

impl<I> Perimeter<I>
where
    I: Iterator,
    I::Item: Clone,
{
    fn new(mut input: I) -> Self {
        let first = input.next();
        let previous = first.clone();
        Perimeter {
            input,
            first,
            previous,
        }
    }
}

impl<I> Iterator for Perimeter<I>
where
    I: Iterator,
    I::Item: Clone,
{
    type Item = (I::Item, I::Item);

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.input.next();
        match (self.previous.clone(), next.or_else(|| self.first.take())) {
            (Some(a), Some(b)) => {
                self.previous = Some(b.clone());
                Some((a, b))
            }
            _ => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.input.size_hint()
    }
}

pub struct Keys<I>
where
    I: Iterator,
    I::Item: PayloadBinding,
{
    input: I,
}

impl<I> Keys<I>
where
    I: Iterator,
    I::Item: PayloadBinding,
{
    fn new(input: I) -> Self {
        Keys { input }
    }
}

impl<I> Iterator for Keys<I>
where
    I: Iterator,
    I::Item: PayloadBinding,
{
    type Item = <I::Item as PayloadBinding>::Key;

    fn next(&mut self) -> Option<Self::Item> {
        self.input.next().map(|view| view.key())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.input.size_hint()
    }
}
<|endoftext|>


<commit_before>// xfail-stage0
// xfail-stage1
// xfail-stage2
// xfail-stage3
// error-pattern: binding alias slot

fn f(x: &int) { }

fn main() { bind f(10); }<commit_msg>Remove the bind-alias test, since binding to aliases is fine.<commit_after><|endoftext|>


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

extern mod std;
extern mod extra;

use std::cell::Cell;
use std::io;
use std::os;
use std::run;
use extra::digest::{Digest, DigestUtil};
use extra::sha1::Sha1;
use extra::test::{DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn};
use extra::test::run_tests_console;

fn main() {
    let args = os::args();
    if args.len() < 2 {
        println("error: at least one reftest list must be given");
        os::set_exit_status(1);
        return;
    }

    let tests = parse_lists(args.tail());
    let test_opts = TestOpts {
        filter: None,
        run_ignored: false,
        logfile: None,
        run_tests: true,
        run_benchmarks: false,
        save_results: None,
        compare_results: None,
    };

    if !run_tests_console(&test_opts, tests) {
        os::set_exit_status(1);
    }
}

enum ReftestKind {
    Same,
    Different,
}

struct Reftest {
    name: ~str,
    kind: ReftestKind,
    left: ~str,
    right: ~str,
}

fn parse_lists(filenames: &[~str]) -> ~[TestDescAndFn] {
    let mut tests: ~[TestDescAndFn] = ~[];
    for filenames.iter().advance |file| {
        let file_path = Path(*file);
        let contents = match io::read_whole_file_str(&file_path) {
            Ok(x) => x,
            Err(s) => fail!(s)
        };

        for contents.line_iter().advance |line| {
            let parts: ~[&str] = line.split_iter(' ').filter(|p| !p.is_empty()).collect();

            if parts.len() != 3 {
                fail!(fmt!("reftest line: '%s' doesn't match 'KIND LEFT RIGHT'", line));
            }

            let kind = match parts[0] {
                "==" => Same,
                "!=" => Different,
                _ => fail!(fmt!("reftest line: '%s' has invalid kind '%s'",
                                line, parts[0]))
            };
            let src_dir = file_path.dirname();
            let file_left = src_dir + "/" + parts[1];
            let file_right = src_dir + "/" + parts[2];

            let reftest = Reftest {
                name: parts[1] + " / " + parts[2],
                kind: kind,
                left: file_left,
                right: file_right,
            };

            tests.push(make_test(reftest));
        }
    }
    tests
}

fn make_test(reftest: Reftest) -> TestDescAndFn {
    let name = reftest.name.clone();
    let reftest = Cell::new(reftest);
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(name),
            ignore: false,
            should_fail: false,
        },
        testfn: DynTestFn(|| {
            check_reftest(reftest.take());
        }),
    }
}

fn check_reftest(reftest: Reftest) {
    let id = gen_id(&reftest);
    let left_filename = fmt!("/tmp/%s-left.png", id);
    let right_filename = fmt!("/tmp/%s-right.png", id);
    let left_path = Path(left_filename);
    let right_path = Path(right_filename);

    let options = run::ProcessOptions::new();
    let args = ~[~"-o", left_filename.clone(), reftest.left.clone()];
    let mut process = run::Process::new("./servo", args, options);
    let _retval = process.finish();
    // assert!(retval == 0);

    let args = ~[~"-o", right_filename.clone(), reftest.right.clone()];
    let mut process = run::Process::new("./servo", args, options);
    let _retval = process.finish();
    // assert!(retval == 0);

    // check the pngs are bit equal
    let left_sha = calc_hash(&left_path);
    os::remove_file(&left_path);

    let right_sha = calc_hash(&right_path);
    os::remove_file(&right_path);

    assert!(left_sha.is_some());
    assert!(right_sha.is_some());
    match reftest.kind {
        Same => assert!(left_sha == right_sha),
        Different => assert!(left_sha != right_sha),
    }
}

fn gen_id(reftest: &Reftest) -> ~str {
    let mut sha = Sha1::new();
    match reftest.kind {
        Same => sha.input_str("=="),
        Different => sha.input_str("!="),
    }
    sha.input_str(reftest.left);
    sha.input_str(reftest.right);
    sha.result_str()
}

fn calc_hash(path: &Path) -> Option<~str> {
    match io::file_reader(path) {
        Err(*) => None,
        Ok(reader) => {
            let mut sha = Sha1::new();
            loop {
                let bytes = reader.read_bytes(4096);
                sha.input(bytes);
                if bytes.len() < 4096 { break; }
            }
            Some(sha.result_str())
        }
    }
}<commit_msg>auto merge of #738 : recrack/servo/ref-test, r=metajack<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod std;
extern mod extra;

use std::cell::Cell;
use std::io;
use std::os;
use std::run;
use extra::digest::Digest;
use extra::sha1::Sha1;
use extra::test::{DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn};
use extra::test::run_tests_console;

fn main() {
    let args = os::args();
    if args.len() < 2 {
        println("error: at least one reftest list must be given");
        os::set_exit_status(1);
        return;
    }

    let tests = parse_lists(args.tail());
    let test_opts = TestOpts {
        filter: None,
        run_ignored: false,
        logfile: None,
        run_tests: true,
        run_benchmarks: false,
        ratchet_noise_percent: None,
        ratchet_metrics: None,
        save_metrics: None,
    };

    if !run_tests_console(&test_opts, tests) {
        os::set_exit_status(1);
    }
}

enum ReftestKind {
    Same,
    Different,
}

struct Reftest {
    name: ~str,
    kind: ReftestKind,
    left: ~str,
    right: ~str,
}

fn parse_lists(filenames: &[~str]) -> ~[TestDescAndFn] {
    let mut tests: ~[TestDescAndFn] = ~[];
    for file in filenames.iter() {
        let file_path = Path(*file);
        let contents = match io::read_whole_file_str(&file_path) {
            Ok(x) => x,
            Err(s) => fail!(s)
        };

        for line in contents.line_iter() {
            let parts: ~[&str] = line.split_iter(' ').filter(|p| !p.is_empty()).collect();

            if parts.len() != 3 {
                fail!(fmt!("reftest line: '%s' doesn't match 'KIND LEFT RIGHT'", line));
            }

            let kind = match parts[0] {
                "==" => Same,
                "!=" => Different,
                _ => fail!(fmt!("reftest line: '%s' has invalid kind '%s'",
                                line, parts[0]))
            };
            let src_dir = file_path.dirname();
            let file_left = src_dir + "/" + parts[1];
            let file_right = src_dir + "/" + parts[2];

            let reftest = Reftest {
                name: parts[1] + " / " + parts[2],
                kind: kind,
                left: file_left,
                right: file_right,
            };

            tests.push(make_test(reftest));
        }
    }
    tests
}

fn make_test(reftest: Reftest) -> TestDescAndFn {
    let name = reftest.name.clone();
    let reftest = Cell::new(reftest);
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(name),
            ignore: false,
            should_fail: false,
        },
        testfn: DynTestFn(|| {
            check_reftest(reftest.take());
        }),
    }
}

fn check_reftest(reftest: Reftest) {
    let id = gen_id(&reftest);
    let left_filename = fmt!("/tmp/%s-left.png", id);
    let right_filename = fmt!("/tmp/%s-right.png", id);
    let left_path = Path(left_filename);
    let right_path = Path(right_filename);

    let options = run::ProcessOptions::new();
    let args = ~[~"-o", left_filename.clone(), reftest.left.clone()];
    let mut process = run::Process::new("./servo", args, options);
    let _retval = process.finish();
    // assert!(retval == 0);

    let args = ~[~"-o", right_filename.clone(), reftest.right.clone()];
    let mut process = run::Process::new("./servo", args, options);
    let _retval = process.finish();
    // assert!(retval == 0);

    // check the pngs are bit equal
    let left_sha = calc_hash(&left_path);
    os::remove_file(&left_path);

    let right_sha = calc_hash(&right_path);
    os::remove_file(&right_path);

    assert!(left_sha.is_some());
    assert!(right_sha.is_some());
    match reftest.kind {
        Same => assert!(left_sha == right_sha),
        Different => assert!(left_sha != right_sha),
    }
}

fn gen_id(reftest: &Reftest) -> ~str {
    let mut sha = Sha1::new();
    match reftest.kind {
        Same => sha.input_str("=="),
        Different => sha.input_str("!="),
    }
    sha.input_str(reftest.left);
    sha.input_str(reftest.right);
    sha.result_str()
}

fn calc_hash(path: &Path) -> Option<~str> {
    match io::file_reader(path) {
        Err(*) => None,
        Ok(reader) => {
            let mut sha = Sha1::new();
            loop {
                let bytes = reader.read_bytes(4096);
                sha.input(bytes);
                if bytes.len() < 4096 { break; }
            }
            Some(sha.result_str())
        }
    }
}
<|endoftext|>