<commit_before>import front.ast;
import front.codemap;
import util.common.span;
import util.common.ty_mach;
import std._uint;
import std.Term;
import std.io;
import std.map;

tag os {
    os_win32;
    os_macos;
    os_linux;
}

tag arch {
    arch_x86;
    arch_x64;
    arch_arm;
}

type cfg = rec(os os,
               arch arch,
               ty_mach int_type,
               ty_mach uint_type,
               ty_mach float_type);

type crate_metadata = rec(str name,
                          vec[u8] data);

fn emit_diagnostic(span sp, str msg, str kind, u8 color, codemap.codemap cm) {
    auto lo = codemap.lookup_pos(cm, sp.lo);
    auto hi = codemap.lookup_pos(cm, sp.hi);
    io.stdout().write_str(#fmt("%s:%u:%u:%u:%u: ", lo.filename, lo.line,
                               lo.col, hi.line, hi.col));
    Term.fg(io.stdout().get_buf_writer(), color);
    io.stdout().write_str(#fmt("%s:", kind));
    Term.reset(io.stdout().get_buf_writer());
    io.stdout().write_str(#fmt(" %s\n", msg));
}

state obj session(ast.crate_num cnum, cfg targ,
                  map.hashmap[int, crate_metadata] crates,
                  mutable vec[@ast.meta_item] metadata,
                  codemap.codemap cm) {

    fn get_targ_cfg() -> cfg {
        ret targ;
    }

    fn get_targ_crate_num() -> ast.crate_num {
        ret cnum;
    }

    fn span_err(span sp, str msg) {
        // FIXME: Use constants, but rustboot doesn't know how to export them.
        emit_diagnostic(sp, msg, "error", 9u8, cm);
        fail;
    }

    fn err(str msg) {
        log_err #fmt("error: %s", msg);
        fail;
    }

    fn add_metadata(vec[@ast.meta_item] data) {
        metadata = metadata + data;
    }
    fn get_metadata() -> vec[@ast.meta_item] {
        ret metadata;
    }

    fn span_warn(span sp, str msg) {
        // FIXME: Use constants, but rustboot doesn't know how to export them.
        emit_diagnostic(sp, msg, "warning", 11u8, cm);
    }

    fn bug(str msg) {
        log_err #fmt("error: internal compiler error %s", msg);
        fail;
    }

    fn span_unimpl(span sp, str msg) {
        // FIXME: Use constants, but rustboot doesn't know how to export them.
        emit_diagnostic(sp, "internal compiler error: unimplemented " + msg,
                        "error", 9u8, cm);
        fail;
    }

    fn unimpl(str msg) {
        log_err #fmt("error: unimplemented %s", msg);
        fail;
    }

    fn get_external_crate(int num) -> crate_metadata {
        ret crates.get(num);
    }

    fn set_external_crate(int num, &crate_metadata metadata) {
        crates.insert(num, metadata);
    }

    fn has_external_crate(int num) -> bool {
        ret crates.contains_key(num);
    }

    fn get_codemap() -> codemap.codemap {
        ret cm;
    }

    fn lookup_pos(uint pos) -> codemap.loc {
        ret codemap.lookup_pos(cm, pos);
    }
}

// Local Variables:
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>rustc: Only use color if it's supported<commit_after>import front.ast;
import front.codemap;
import util.common.span;
import util.common.ty_mach;
import std._uint;
import std.Term;
import std.io;
import std.map;

tag os {
    os_win32;
    os_macos;
    os_linux;
}

tag arch {
    arch_x86;
    arch_x64;
    arch_arm;
}

type cfg = rec(os os,
               arch arch,
               ty_mach int_type,
               ty_mach uint_type,
               ty_mach float_type);

type crate_metadata = rec(str name,
                          vec[u8] data);

fn emit_diagnostic(span sp, str msg, str kind, u8 color, codemap.codemap cm) {
    auto lo = codemap.lookup_pos(cm, sp.lo);
    auto hi = codemap.lookup_pos(cm, sp.hi);
    io.stdout().write_str(#fmt("%s:%u:%u:%u:%u: ", lo.filename, lo.line,
                               lo.col, hi.line, hi.col));

    if (Term.color_supported()) {
        Term.fg(io.stdout().get_buf_writer(), color);
    }

    io.stdout().write_str(#fmt("%s:", kind));

    if (Term.color_supported()) {
        Term.reset(io.stdout().get_buf_writer());
    }

    io.stdout().write_str(#fmt(" %s\n", msg));
}

state obj session(ast.crate_num cnum, cfg targ,
                  map.hashmap[int, crate_metadata] crates,
                  mutable vec[@ast.meta_item] metadata,
                  codemap.codemap cm) {

    fn get_targ_cfg() -> cfg {
        ret targ;
    }

    fn get_targ_crate_num() -> ast.crate_num {
        ret cnum;
    }

    fn span_err(span sp, str msg) {
        // FIXME: Use constants, but rustboot doesn't know how to export them.
        emit_diagnostic(sp, msg, "error", 9u8, cm);
        fail;
    }

    fn err(str msg) {
        log_err #fmt("error: %s", msg);
        fail;
    }

    fn add_metadata(vec[@ast.meta_item] data) {
        metadata = metadata + data;
    }
    fn get_metadata() -> vec[@ast.meta_item] {
        ret metadata;
    }

    fn span_warn(span sp, str msg) {
        // FIXME: Use constants, but rustboot doesn't know how to export them.
        emit_diagnostic(sp, msg, "warning", 11u8, cm);
    }

    fn bug(str msg) {
        log_err #fmt("error: internal compiler error %s", msg);
        fail;
    }

    fn span_unimpl(span sp, str msg) {
        // FIXME: Use constants, but rustboot doesn't know how to export them.
        emit_diagnostic(sp, "internal compiler error: unimplemented " + msg,
                        "error", 9u8, cm);
        fail;
    }

    fn unimpl(str msg) {
        log_err #fmt("error: unimplemented %s", msg);
        fail;
    }

    fn get_external_crate(int num) -> crate_metadata {
        ret crates.get(num);
    }

    fn set_external_crate(int num, &crate_metadata metadata) {
        crates.insert(num, metadata);
    }

    fn has_external_crate(int num) -> bool {
        ret crates.contains_key(num);
    }

    fn get_codemap() -> codemap.codemap {
        ret cm;
    }

    fn lookup_pos(uint pos) -> codemap.loc {
        ret codemap.lookup_pos(cm, pos);
    }
}

// Local Variables:
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|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/. */

//! Configuration options for a single run of the servo application. Created
//! from command line arguments.

use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend};
use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend};
use extra::getopts;

/// Global flags for Servo, currently set on the command line.
#[deriving(Clone)]
pub struct Opts {
    /// The initial URLs to load.
    urls: ~[~str],

    /// The rendering backend to use (`-r`).
    render_backend: BackendType,

    /// How many threads to use for CPU rendering (`-t`).
    ///
    /// FIXME(pcwalton): This is not currently used. All rendering is sequential.
    n_render_threads: uint,

    /// True to use CPU painting, false to use GPU painting via Skia-GL (`-c`). Note that
    /// compositing is always done on the GPU.
    cpu_painting: bool,

    /// The maximum size of each tile in pixels (`-s`).
    tile_size: uint,

    /// `None` to disable the profiler or `Some` with an interval in seconds to enable it and cause
    /// it to produce output on that interval (`-p`).
    profiler_period: Option<f64>,

    /// True to exit after the page load (`-x`).
    exit_after_load: bool,

    output_file: Option<~str>,
    headless: bool,
}

pub fn from_cmdline_args(args: &[~str]) -> Opts {
    let args = args.tail();

    let opts = ~[
        getopts::optflag("c"),      // CPU rendering
        getopts::optopt("o"),       // output file
        getopts::optopt("r"),       // rendering backend
        getopts::optopt("s"),       // size of tiles
        getopts::optopt("t"),       // threads to render with
        getopts::optflagopt("p"),   // profiler flag and output interval
        getopts::optflag("x"),      // exit after load flag
        getopts::optflag("z"),      // headless mode
    ];

    let opt_match = match getopts::getopts(args, opts) {
        Ok(m) => m,
        Err(f) => fail!(f.to_err_msg()),
    };

    let urls = if opt_match.free.is_empty() {
        fail!(~"servo asks that you provide 1 or more URLs")
    } else {
        opt_match.free.clone()
    };

    let render_backend = match opt_match.opt_str("r") {
        Some(backend_str) => {
            if backend_str == ~"direct2d" {
                Direct2DBackend
            } else if backend_str == ~"core-graphics" {
                CoreGraphicsBackend
            } else if backend_str == ~"core-graphics-accelerated" {
                CoreGraphicsAcceleratedBackend
            } else if backend_str == ~"cairo" {
                CairoBackend
            } else if backend_str == ~"skia" {
                SkiaBackend
            } else {
                fail!(~"unknown backend type")
            }
        }
        None => SkiaBackend
    };

    let tile_size: uint = match opt_match.opt_str("s") {
        Some(tile_size_str) => from_str(tile_size_str).unwrap(),
        None => 512,
    };

    let n_render_threads: uint = match opt_match.opt_str("t") {
        Some(n_render_threads_str) => from_str(n_render_threads_str).unwrap(),
        None => 1,      // FIXME: Number of cores.
    };

    // if only flag is present, default to 5 second period
    let profiler_period = do opt_match.opt_default("p", "5").map |period| {
        from_str(period).unwrap()
    };

    let cpu_painting = opt_match.opt_present("c");

    Opts {
        urls: urls,
        render_backend: render_backend,
        n_render_threads: n_render_threads,
        cpu_painting: cpu_painting,
        tile_size: tile_size,
        profiler_period: profiler_period,
        exit_after_load: opt_match.opt_present("x"),
        output_file: opt_match.opt_str("o"),
        headless: opt_match.opt_present("z"),
    }
}
<commit_msg>auto merge of #1277 : Adenilson/servo/implementingHelp, r=pcwalton<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/. */

//! Configuration options for a single run of the servo application. Created
//! from command line arguments.

use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend};
use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend};
use extra::getopts::groups;

/// Global flags for Servo, currently set on the command line.
#[deriving(Clone)]
pub struct Opts {
    /// The initial URLs to load.
    urls: ~[~str],

    /// The rendering backend to use (`-r`).
    render_backend: BackendType,

    /// How many threads to use for CPU rendering (`-t`).
    ///
    /// FIXME(pcwalton): This is not currently used. All rendering is sequential.
    n_render_threads: uint,

    /// True to use CPU painting, false to use GPU painting via Skia-GL (`-c`). Note that
    /// compositing is always done on the GPU.
    cpu_painting: bool,

    /// The maximum size of each tile in pixels (`-s`).
    tile_size: uint,

    /// `None` to disable the profiler or `Some` with an interval in seconds to enable it and cause
    /// it to produce output on that interval (`-p`).
    profiler_period: Option<f64>,

    /// True to exit after the page load (`-x`).
    exit_after_load: bool,

    output_file: Option<~str>,
    headless: bool,
}

fn print_usage(app: &str, opts: &[groups::OptGroup]) {
    let message = format!("Usage: {} [ options ... ] [URL]\n\twhere options include", app);
    println(groups::usage(message, opts));
}

pub fn from_cmdline_args(args: &[~str]) -> Opts {
    let app_name = args[0].to_str();
    let args = args.tail();

    let opts = ~[
        groups::optflag("c", "cpu", "CPU rendering"),
        groups::optopt("o", "output", "Output file", "output.png"),
        groups::optopt("r", "rendering", "Rendering backend", "direct2d|core-graphics|core-graphics-accelerated|cairo|skia."),
        groups::optopt("s", "size", "Size of tiles", "512"),
        groups::optopt("t", "threads", "Number of render threads", "1"),
        groups::optflagopt("p", "profile", "Profiler flag and output interval", "10"),
        groups::optflag("x", "exit", "Exit after load flag"),
        groups::optflag("z", "headless", "Headless mode"),
        groups::optflag("h", "help", "Print this message")
    ];

    let opt_match = match groups::getopts(args, opts) {
        Ok(m) => m,
        Err(f) => fail!(f.to_err_msg()),
    };

    if opt_match.opt_present("h") || opt_match.opt_present("help") {
        print_usage(app_name, opts);
        // TODO: how to return a null struct and let the caller know that
        // it should abort?
        fail!("")
    };

    let urls = if opt_match.free.is_empty() {
        print_usage(app_name, opts);
        fail!(~"servo asks that you provide 1 or more URLs")
    } else {
        opt_match.free.clone()
    };

    let render_backend = match opt_match.opt_str("r") {
        Some(backend_str) => {
            if backend_str == ~"direct2d" {
                Direct2DBackend
            } else if backend_str == ~"core-graphics" {
                CoreGraphicsBackend
            } else if backend_str == ~"core-graphics-accelerated" {
                CoreGraphicsAcceleratedBackend
            } else if backend_str == ~"cairo" {
                CairoBackend
            } else if backend_str == ~"skia" {
                SkiaBackend
            } else {
                fail!(~"unknown backend type")
            }
        }
        None => SkiaBackend
    };

    let tile_size: uint = match opt_match.opt_str("s") {
        Some(tile_size_str) => from_str(tile_size_str).unwrap(),
        None => 512,
    };

    let n_render_threads: uint = match opt_match.opt_str("t") {
        Some(n_render_threads_str) => from_str(n_render_threads_str).unwrap(),
        None => 1,      // FIXME: Number of cores.
    };

    // if only flag is present, default to 5 second period
    let profiler_period = do opt_match.opt_default("p", "5").map |period| {
        from_str(period).unwrap()
    };

    let cpu_painting = opt_match.opt_present("c");

    Opts {
        urls: urls,
        render_backend: render_backend,
        n_render_threads: n_render_threads,
        cpu_painting: cpu_painting,
        tile_size: tile_size,
        profiler_period: profiler_period,
        exit_after_load: opt_match.opt_present("x"),
        output_file: opt_match.opt_str("o"),
        headless: opt_match.opt_present("z"),
    }
}
<|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 extra::url;
use extra::url::Url;
use std::hashmap::HashMap;
use std::os;

/**
Create a URL object from a string. Does various helpful browsery things like

* If there's no current url and the path looks like a file then it will
  create a file url based of the current working directory
* If there's a current url and the new path is relative then the new url
  is based off the current url

*/
// TODO: about:failure->
pub fn make_url(str_url: ~str, current_url: Option<Url>) -> Url {
    let schm = url::get_scheme(str_url);
    let str_url = match schm {
        Err(_) => {
            if current_url.is_none() {
                // Assume we've been given a file path. If it's absolute just return
                // it, otherwise make it absolute with the cwd.
                if str_url.starts_with("/") {
                    ~"file://" + str_url
                } else {
                    let mut path = os::getcwd();
                    path.push(str_url);
                    // FIXME (#1094): not the right way to transform a path
                    ~"file://" + path.display().to_str()
                }
            } else {
                let current_url = current_url.unwrap();
                debug!("make_url: current_url: {:?}", current_url);
                if str_url.starts_with("//") {
                    current_url.scheme + ":" + str_url
                } else if current_url.path.is_empty() ||
                    str_url.starts_with("/") {
                    current_url.scheme + "://" +
                        current_url.host + "/" +
                        str_url.trim_left_chars(&'/')
                } else if str_url.starts_with("#") {
                    current_url.scheme + "://" + current_url.host + current_url.path + str_url
                } else {
                    let mut path = ~[];
                    for p in current_url.path.split_iter('/') {
                        path.push(p.to_str());
                    }
                    let path = path.init();
                    let mut path = path.iter().map(|x| (*x).clone()).collect::<~[~str]>();
                    path.push(str_url);
                    let path = path.connect("/");

                    current_url.scheme + "://" + current_url.host + path
                }
            }
        },
        Ok((scheme, page)) => {
            match scheme {
                ~"about" => {
                    match page {
                        ~"failure" => {
                            let mut path = os::getcwd();
                            path.push("../src/test/html/failure.html");
                            // FIXME (#1094): not the right way to transform a path
                            ~"file://" + path.display().to_str()
                        }
                        // TODO: handle the rest of the about: pages
                        _ => str_url
                    }
                },
                ~"data" => {
                    // Drop whitespace within data: URLs, e.g. newlines within a base64
                    // src="..." block.  Whitespace intended as content should be
                    // %-encoded or base64'd.
                    str_url.iter().filter(|&c| !c.is_whitespace()).collect()
                },
                _ => str_url
            }
        }
    };

    // FIXME: Need to handle errors
    url::from_str(str_url).unwrap()
}

#[cfg(test)]
mod make_url_tests {
    use super::make_url;
    use std::os;

    #[test]
    fn should_create_absolute_file_url_if_current_url_is_none_and_str_url_looks_filey() {
        let file = ~"local.html";
        let url = make_url(file, None);
        debug!("url: {:?}", url);
        assert!(url.scheme == ~"file");
        let path = os::getcwd();
        // FIXME (#1094): not the right way to transform a path
        assert!(url.path.contains(path.display().to_str()));
    }

    #[test]
    fn should_create_url_based_on_old_url_1() {
        let old_str = ~"http://example.com";
        let old_url = make_url(old_str, None);
        let new_str = ~"index.html";
        let new_url = make_url(new_str, Some(old_url));
        assert!(new_url.scheme == ~"http");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/index.html");
    }

    #[test]
    fn should_create_url_based_on_old_url_2() {
        let old_str = ~"http://example.com/";
        let old_url = make_url(old_str, None);
        let new_str = ~"index.html";
        let new_url = make_url(new_str, Some(old_url));
        assert!(new_url.scheme == ~"http");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/index.html");
    }

    #[test]
    fn should_create_url_based_on_old_url_3() {
        let old_str = ~"http://example.com/index.html";
        let old_url = make_url(old_str, None);
        let new_str = ~"crumpet.html";
        let new_url = make_url(new_str, Some(old_url));
        assert!(new_url.scheme == ~"http");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/crumpet.html");
    }

    #[test]
    fn should_create_url_based_on_old_url_4() {
        let old_str = ~"http://example.com/snarf/index.html";
        let old_url = make_url(old_str, None);
        let new_str = ~"crumpet.html";
        let new_url = make_url(new_str, Some(old_url));
        assert!(new_url.scheme == ~"http");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/snarf/crumpet.html");
    }

    #[test]
    fn should_create_url_based_on_old_url_5() {
        let old_str = ~"http://example.com/index.html";
        let old_url = make_url(old_str, None);
        let new_str = ~"#top";
        let new_url = make_url(new_str, Some(old_url));

        assert!(new_url.scheme == ~"http");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/index.html");
        assert!(new_url.fragment == Some(~"top"));
    }
}

pub type UrlMap<T> = HashMap<Url, T>;

pub fn url_map<T: Clone + 'static>() -> UrlMap<T> {
    HashMap::new()
}

<commit_msg>auto merge of #1353 : dhedlund/servo/resource_port_and_user, r=pcwalton<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 extra::url;
use extra::url::Url;
use std::hashmap::HashMap;
use std::os;

/**
Create a URL object from a string. Does various helpful browsery things like

* If there's no current url and the path looks like a file then it will
  create a file url based of the current working directory
* If there's a current url and the new path is relative then the new url
  is based off the current url

*/
// TODO: about:failure->
pub fn make_url(str_url: ~str, current_url: Option<Url>) -> Url {
    let schm = url::get_scheme(str_url);
    let str_url = match schm {
        Err(_) => {
            if current_url.is_none() {
                // Assume we've been given a file path. If it's absolute just return
                // it, otherwise make it absolute with the cwd.
                if str_url.starts_with("/") {
                    ~"file://" + str_url
                } else {
                    let mut path = os::getcwd();
                    path.push(str_url);
                    // FIXME (#1094): not the right way to transform a path
                    ~"file://" + path.display().to_str()
                }
            } else {
                let current_url = current_url.unwrap();
                debug!("make_url: current_url: {:?}", current_url);

                let mut new_url = current_url.clone();
                new_url.query = ~[];
                new_url.fragment = None;

                if str_url.starts_with("//") {
                    new_url.scheme + ":" + str_url
                } else if current_url.path.is_empty() || str_url.starts_with("/") {
                    new_url.path = ~"/";
                    new_url.to_str() + str_url.trim_left_chars(&'/')
                } else if str_url.starts_with("#") {
                    new_url.to_str() + str_url
                } else { // relative path
                    let base_path = current_url.path.trim_right_chars(&|c: char| c != '/');
                    new_url.path = base_path.to_owned();
                    new_url.to_str() + str_url
                }
            }
        },
        Ok((scheme, page)) => {
            match scheme {
                ~"about" => {
                    match page {
                        ~"failure" => {
                            let mut path = os::getcwd();
                            path.push("../src/test/html/failure.html");
                            // FIXME (#1094): not the right way to transform a path
                            ~"file://" + path.display().to_str()
                        }
                        // TODO: handle the rest of the about: pages
                        _ => str_url
                    }
                },
                ~"data" => {
                    // Drop whitespace within data: URLs, e.g. newlines within a base64
                    // src="..." block.  Whitespace intended as content should be
                    // %-encoded or base64'd.
                    str_url.iter().filter(|&c| !c.is_whitespace()).collect()
                },
                _ => str_url
            }
        }
    };

    // FIXME: Need to handle errors
    url::from_str(str_url).unwrap()
}

#[cfg(test)]
mod make_url_tests {
    use super::make_url;
    use std::os;

    #[test]
    fn should_create_absolute_file_url_if_current_url_is_none_and_str_url_looks_filey() {
        let file = ~"local.html";
        let url = make_url(file, None);
        debug!("url: {:?}", url);
        assert!(url.scheme == ~"file");
        let path = os::getcwd();
        // FIXME (#1094): not the right way to transform a path
        assert!(url.path.contains(path.display().to_str()));
    }

    #[test]
    fn should_create_url_based_on_old_url_1() {
        let old_str = ~"http://example.com";
        let old_url = make_url(old_str, None);
        let new_str = ~"index.html";
        let new_url = make_url(new_str, Some(old_url));
        assert!(new_url.scheme == ~"http");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/index.html");
    }

    #[test]
    fn should_create_url_based_on_old_url_2() {
        let old_str = ~"http://example.com/";
        let old_url = make_url(old_str, None);
        let new_str = ~"index.html";
        let new_url = make_url(new_str, Some(old_url));
        assert!(new_url.scheme == ~"http");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/index.html");
    }

    #[test]
    fn should_create_url_based_on_old_url_3() {
        let old_str = ~"http://example.com/index.html";
        let old_url = make_url(old_str, None);
        let new_str = ~"crumpet.html";
        let new_url = make_url(new_str, Some(old_url));
        assert!(new_url.scheme == ~"http");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/crumpet.html");
    }

    #[test]
    fn should_create_url_based_on_old_url_4() {
        let old_str = ~"http://example.com/snarf/index.html";
        let old_url = make_url(old_str, None);
        let new_str = ~"crumpet.html";
        let new_url = make_url(new_str, Some(old_url));
        assert!(new_url.scheme == ~"http");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/snarf/crumpet.html");
    }

    #[test]
    fn should_create_url_based_on_old_url_5() {
        let old_str = ~"http://example.com/index.html";
        let old_url = make_url(old_str, None);
        let new_str = ~"#top";
        let new_url = make_url(new_str, Some(old_url));

        assert!(new_url.scheme == ~"http");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/index.html");
        assert!(new_url.fragment == Some(~"top"));
    }

    #[test]
    fn should_create_url_based_on_old_url_6() {
        use extra::url::UserInfo;

        let old_str = ~"http://foo:bar@example.com:8080/index.html";
        let old_url = make_url(old_str, None);
        let new_str = ~"#top";
        let new_url = make_url(new_str, Some(old_url));

        assert!(new_url.scheme == ~"http");
        assert!(new_url.user == Some(UserInfo { user: ~"foo", pass: Some(~"bar") }));
        assert!(new_url.host == ~"example.com");
        assert!(new_url.port == Some(~"8080"));
        assert!(new_url.path == ~"/index.html");
        assert!(new_url.fragment == Some(~"top"));
    }

    #[test]
    fn should_create_url_based_on_old_url_7() {
        let old_str = ~"https://example.com/snarf/index.html";
        let old_url = make_url(old_str, None);
        let new_str = ~"//example.com/crumpet.html";
        let new_url = make_url(new_str, Some(old_url));
        assert!(new_url.scheme == ~"https");
        assert!(new_url.host == ~"example.com");
        assert!(new_url.path == ~"/crumpet.html");
    }

}

pub type UrlMap<T> = HashMap<Url, T>;

pub fn url_map<T: Clone + 'static>() -> UrlMap<T> {
    HashMap::new()
}

<|endoftext|>


<commit_before>

pub enum SqlType{
    Bool,
    Tinyint,
    Smallint,
    Int,
    Bigint,

    SmallSerial,
    Serial,
    BigSerial,

    Real,
    Float,
    Double,

    Tinyblob,
    Mediumblob,
    Blob,
    Longblob,
    Varbinary,

    Char,
    Varchar,
    Tinytext,
    Mediumtext,
    Text,

    Uuid,
    UuidRandom,
    Date,
    DateToday,
    Timestamp,
    TimestampNow,
}
<commit_msg>move types to intel module<commit_after><|endoftext|>


<commit_before>//! Utilities for working with the WTF-8 encoding.
//!
//! WTF-8 is a hack that allows to represent potentially ill-formed UTF-16 byte
//! strings in a way somewhat compatible with UTF-8. Such bugs UTF-16 strings
//! can be found for example in Windows paths for legacy reasons.
//!
//! See the official [WTF-8][wtf8] specification for more information.
//!
//! [wtf8]: https://simonsapin.github.io/wtf-8

/// Converts the given potentially ill-formed UTF-16 into a WTF-8 byte sequence.
///
/// If the given byte sequence is a well-formed UTF-16 string, then the result
/// is guaranteed to be a valid UTF-8string.
pub fn from_ill_formed_utf16(units: impl Iterator<Item=u16>) -> Vec<u8> {
    let mut res = Vec::new();

    let mut iter = units.peekable();
    loop {
        let unit = match iter.next() {
            Some(unit) => unit,
            None => return res,
        };

        // Potentially ill-formed UTF-16 to code point conversion based on [1].
        //
        // [1]: https://simonsapin.github.io/wtf-8/#decoding-ill-formed-utf-16
        let mut point = unit as u32;
        if is_lead_surrogate(&unit) {
            if let Some(next) = iter.next_if(is_trail_surrogate) {
                let lead = (unit as u32 - 0xD800) << 10;
                let trail = next as u32 - 0xDC00;
                point = 0x10000 + lead + trail;
            }
        }

        // Code point to WTF-8 encoding procedure based on [1].
        //
        // [1]: https://simonsapin.github.io/wtf-8/#encoding-wtf-8
        match point {
            0x0000..=0x007F => {
                res.push(point as u8);
            }
            0x0080..=0x07FF => {
                res.push(0xC0 | (point >> 6) as u8);
                res.push(0x80 | (point & 0x3F) as u8);
            }
            0x0800..=0xFFFF => {
                res.push(0xE0 | (point >> 12) as u8);
                res.push(0x80 | ((point >> 6) as u8 & 0x3F));
                res.push(0x80 | (point & 0x3F) as u8);
            }
            0x10000..=0x10FFFF => {
                res.push(0xF0 | (point >> 18) as u8);
                res.push(0x80 | ((point >> 12) as u8 & 0x3F));
                res.push(0x80 | ((point >> 6) as u8 & 0x3F));
                res.push(0x80 | (point & 0x3F) as u8);
            }
            _ => unreachable!(), // Not possible by construction.
        }
    }
}

/// Converts the given WTF-8 byte sequence into potentially ill-formed UTF-16.
///
/// If the given byte sequence is a valid UTF-8 string, then the result is
/// guaranteed to be a well-formed UTF-16 string.
pub fn into_ill_formed_utf16(units: impl Iterator<Item=u8>) -> Vec<u16> {
    let mut res = Vec::new();

    let mut iter = units.peekable();
    loop {
        let byte1 = match iter.next() {
            Some(byte1) => byte1,
            None => return res,
        };

        // TODO: Add support for proper error handling.

        // WTF-8 to a code point decoding procedure based on [1].
        //
        // [1]: https://simonsapin.github.io/wtf-8/#decoding-wtf-8
        let mut point = 0;
        match byte1 {
            0x00..=0x7F => {
                point += byte1 as u32;
            }
            0xC2..=0xDF => {
                let byte2 = iter.next().unwrap_or_else(|| todo!());
                point += ((byte1 & 0x1F) as u32) << 6;
                point += ((byte2 & 0x3F) as u32) << 0;
            }
            0xE0..=0xEF => {
                let byte2 = iter.next().unwrap_or_else(|| todo!());
                let byte3 = iter.next().unwrap_or_else(|| todo!());
                point += ((byte1 & 0x0F) as u32) << 12;
                point += ((byte2 & 0x3F) as u32) << 6;
                point += ((byte3 & 0x3F) as u32) << 0;
            }
            0xF0..=0xF4 => {
                let byte2 = iter.next().unwrap_or_else(|| todo!());
                let byte3 = iter.next().unwrap_or_else(|| todo!());
                let byte4 = iter.next().unwrap_or_else(|| todo!());
                point += ((byte1 & 0x07) as u32) << 18;
                point += ((byte2 & 0x3F) as u32) << 12;
                point += ((byte3 & 0x3F) as u32) << 6;
                point += ((byte4 & 0x3F) as u32) << 0;
            }
            _ => todo!(),
        }

        // Code point to potentially ill-formed UTF-16 coversion based on [1].
        //
        // [1]: https://simonsapin.github.io/wtf-8/#encoding-ill-formed-utf-16
        if is_supplementary(&point) {
            res.push(((point - 0x10000) >> 10) as u16 + 0xD800);
            res.push(((point - 0x10000) as u16 & 0x3FF) + 0xDC00);
        } else {
            res.push(point as u16);
        }
    }
}

/// Determines whether the given UTF-16 code unit is a lead surrogate.
#[inline]
fn is_lead_surrogate(unit: &u16) -> bool {
    matches!(unit, 0xD800..=0xDBFF)
}

/// Determines whether the given UTF-16 code unit is a trail surrogate.
#[inline]
fn is_trail_surrogate(unit: &u16) -> bool {
    matches!(unit, 0xDC00..=0xDFFF)
}

/// Determines whether the given code point is in the supplementary.
#[inline]
fn is_supplementary(point: &u32) -> bool {
    matches!(point, 0x10000..=0x10FFFF)
}

#[cfg(test)]
mod tests {

    use super::*;

    use quickcheck_macros::quickcheck;

    #[test]
    fn from_empty() {
        assert_eq!(from_ill_formed_utf16(std::iter::empty()), b"");
    }

    #[test]
    fn from_small_bytes() {
        let bytes_utf16 = vec![0x04, 0x08, 0x16, 0x23, 0x42];
        let bytes_wtf8 = from_ill_formed_utf16(bytes_utf16.into_iter());
        assert_eq!(bytes_wtf8, b"\x04\x08\x16\x23\x42");
    }

    #[test]
    fn from_bmp_bytes() {
        let bytes_utf16 = vec![0xABCD, 0xBEEF, 0xFFFF];
        let bytes_wtf8 = from_ill_formed_utf16(bytes_utf16.into_iter());
        assert_eq!(bytes_wtf8, b"\xEA\xAF\x8D\xEB\xBB\xAF\xEF\xBF\xBF");
    }

    #[test]
    fn from_sup_bytes() {
        let bytes_utf16 = vec![0xD800, 0xDC00, 0xDBFF, 0xDFFF];
        let bytes_wtf8 = from_ill_formed_utf16(bytes_utf16.into_iter());
        assert_eq!(bytes_wtf8, b"\xF0\x90\x80\x80\xF4\x8F\xBF\xBF");
    }

    #[test]
    fn from_ascii_string() {
        let string = "foo bar baz";
        let string_wtf8 = from_ill_formed_utf16(string.encode_utf16());
        let string_utf8 = string.as_bytes();
        assert_eq!(string_wtf8, string_utf8);
    }

    #[test]
    fn from_unicode_string() {
        let string = "zażółć gęślą jaźń";
        let string_wtf8 = from_ill_formed_utf16(string.encode_utf16());
        let string_utf8 = string.as_bytes();
        assert_eq!(string_wtf8, string_utf8);
    }

    #[test]
    fn into_empty() {
        assert_eq!(into_ill_formed_utf16(std::iter::empty()), vec![]);
    }

    #[test]
    fn into_ascii_string() {
        let string = "foo bar baz";
        let string_wtf8 = into_ill_formed_utf16(string.bytes());
        let string_utf16 = string.encode_utf16().collect::<Vec<_>>();
        assert_eq!(string_wtf8, string_utf16);
    }

    #[test]
    fn into_unicode_string() {
        let string = "zażółć gęślą jaźń";
        let string_wtf8 = into_ill_formed_utf16(string.bytes());
        let string_utf16 = string.encode_utf16().collect::<Vec<_>>();
        assert_eq!(string_wtf8, string_utf16);
    }

    #[quickcheck]
    fn from_any_string(input: String) {
        let units = input.encode_utf16();

        let string_wtf8 = from_ill_formed_utf16(units);
        let string_utf8 = input.as_bytes();
        assert_eq!(string_wtf8, string_utf8);
    }

    #[quickcheck]
    fn into_from_any_string(input: String) {
        let units = input.bytes();

        let string_utf16 = into_ill_formed_utf16(units);
        let string_wtf8 = from_ill_formed_utf16(string_utf16.into_iter());
        assert_eq!(String::from_utf8(string_wtf8).unwrap(), input);
    }

    #[quickcheck]
    fn from_into_any_units(input: Vec<u16>) {
        let units = input.iter().map(|unit| *unit);

        let string_wtf8 = from_ill_formed_utf16(units);
        let string_utf16 = into_ill_formed_utf16(string_wtf8.into_iter());
        assert_eq!(string_utf16, input);
    }
}
<commit_msg>Use trait bounds instead of the `impl` syntax.<commit_after>//! Utilities for working with the WTF-8 encoding.
//!
//! WTF-8 is a hack that allows to represent potentially ill-formed UTF-16 byte
//! strings in a way somewhat compatible with UTF-8. Such bugs UTF-16 strings
//! can be found for example in Windows paths for legacy reasons.
//!
//! See the official [WTF-8][wtf8] specification for more information.
//!
//! [wtf8]: https://simonsapin.github.io/wtf-8

/// Converts the given potentially ill-formed UTF-16 into a WTF-8 byte sequence.
///
/// If the given byte sequence is a well-formed UTF-16 string, then the result
/// is guaranteed to be a valid UTF-8string.
pub fn from_ill_formed_utf16<I>(units: I) -> Vec<u8>
where
    I: Iterator<Item = u16>,
{
    let mut res = Vec::new();

    let mut iter = units.peekable();
    loop {
        let unit = match iter.next() {
            Some(unit) => unit,
            None => return res,
        };

        // Potentially ill-formed UTF-16 to code point conversion based on [1].
        //
        // [1]: https://simonsapin.github.io/wtf-8/#decoding-ill-formed-utf-16
        let mut point = unit as u32;
        if is_lead_surrogate(&unit) {
            if let Some(next) = iter.next_if(is_trail_surrogate) {
                let lead = (unit as u32 - 0xD800) << 10;
                let trail = next as u32 - 0xDC00;
                point = 0x10000 + lead + trail;
            }
        }

        // Code point to WTF-8 encoding procedure based on [1].
        //
        // [1]: https://simonsapin.github.io/wtf-8/#encoding-wtf-8
        match point {
            0x0000..=0x007F => {
                res.push(point as u8);
            }
            0x0080..=0x07FF => {
                res.push(0xC0 | (point >> 6) as u8);
                res.push(0x80 | (point & 0x3F) as u8);
            }
            0x0800..=0xFFFF => {
                res.push(0xE0 | (point >> 12) as u8);
                res.push(0x80 | ((point >> 6) as u8 & 0x3F));
                res.push(0x80 | (point & 0x3F) as u8);
            }
            0x10000..=0x10FFFF => {
                res.push(0xF0 | (point >> 18) as u8);
                res.push(0x80 | ((point >> 12) as u8 & 0x3F));
                res.push(0x80 | ((point >> 6) as u8 & 0x3F));
                res.push(0x80 | (point & 0x3F) as u8);
            }
            _ => unreachable!(), // Not possible by construction.
        }
    }
}

/// Converts the given WTF-8 byte sequence into potentially ill-formed UTF-16.
///
/// If the given byte sequence is a valid UTF-8 string, then the result is
/// guaranteed to be a well-formed UTF-16 string.
pub fn into_ill_formed_utf16<I>(units: I) -> Vec<u16>
where
    I: Iterator<Item = u8>
{
    let mut res = Vec::new();

    let mut iter = units.peekable();
    loop {
        let byte1 = match iter.next() {
            Some(byte1) => byte1,
            None => return res,
        };

        // TODO: Add support for proper error handling.

        // WTF-8 to a code point decoding procedure based on [1].
        //
        // [1]: https://simonsapin.github.io/wtf-8/#decoding-wtf-8
        let mut point = 0;
        match byte1 {
            0x00..=0x7F => {
                point += byte1 as u32;
            }
            0xC2..=0xDF => {
                let byte2 = iter.next().unwrap_or_else(|| todo!());
                point += ((byte1 & 0x1F) as u32) << 6;
                point += ((byte2 & 0x3F) as u32) << 0;
            }
            0xE0..=0xEF => {
                let byte2 = iter.next().unwrap_or_else(|| todo!());
                let byte3 = iter.next().unwrap_or_else(|| todo!());
                point += ((byte1 & 0x0F) as u32) << 12;
                point += ((byte2 & 0x3F) as u32) << 6;
                point += ((byte3 & 0x3F) as u32) << 0;
            }
            0xF0..=0xF4 => {
                let byte2 = iter.next().unwrap_or_else(|| todo!());
                let byte3 = iter.next().unwrap_or_else(|| todo!());
                let byte4 = iter.next().unwrap_or_else(|| todo!());
                point += ((byte1 & 0x07) as u32) << 18;
                point += ((byte2 & 0x3F) as u32) << 12;
                point += ((byte3 & 0x3F) as u32) << 6;
                point += ((byte4 & 0x3F) as u32) << 0;
            }
            _ => todo!(),
        }

        // Code point to potentially ill-formed UTF-16 coversion based on [1].
        //
        // [1]: https://simonsapin.github.io/wtf-8/#encoding-ill-formed-utf-16
        if is_supplementary(&point) {
            res.push(((point - 0x10000) >> 10) as u16 + 0xD800);
            res.push(((point - 0x10000) as u16 & 0x3FF) + 0xDC00);
        } else {
            res.push(point as u16);
        }
    }
}

/// Determines whether the given UTF-16 code unit is a lead surrogate.
#[inline]
fn is_lead_surrogate(unit: &u16) -> bool {
    matches!(unit, 0xD800..=0xDBFF)
}

/// Determines whether the given UTF-16 code unit is a trail surrogate.
#[inline]
fn is_trail_surrogate(unit: &u16) -> bool {
    matches!(unit, 0xDC00..=0xDFFF)
}

/// Determines whether the given code point is in the supplementary.
#[inline]
fn is_supplementary(point: &u32) -> bool {
    matches!(point, 0x10000..=0x10FFFF)
}

#[cfg(test)]
mod tests {

    use super::*;

    use quickcheck_macros::quickcheck;

    #[test]
    fn from_empty() {
        assert_eq!(from_ill_formed_utf16(std::iter::empty()), b"");
    }

    #[test]
    fn from_small_bytes() {
        let bytes_utf16 = vec![0x04, 0x08, 0x16, 0x23, 0x42];
        let bytes_wtf8 = from_ill_formed_utf16(bytes_utf16.into_iter());
        assert_eq!(bytes_wtf8, b"\x04\x08\x16\x23\x42");
    }

    #[test]
    fn from_bmp_bytes() {
        let bytes_utf16 = vec![0xABCD, 0xBEEF, 0xFFFF];
        let bytes_wtf8 = from_ill_formed_utf16(bytes_utf16.into_iter());
        assert_eq!(bytes_wtf8, b"\xEA\xAF\x8D\xEB\xBB\xAF\xEF\xBF\xBF");
    }

    #[test]
    fn from_sup_bytes() {
        let bytes_utf16 = vec![0xD800, 0xDC00, 0xDBFF, 0xDFFF];
        let bytes_wtf8 = from_ill_formed_utf16(bytes_utf16.into_iter());
        assert_eq!(bytes_wtf8, b"\xF0\x90\x80\x80\xF4\x8F\xBF\xBF");
    }

    #[test]
    fn from_ascii_string() {
        let string = "foo bar baz";
        let string_wtf8 = from_ill_formed_utf16(string.encode_utf16());
        let string_utf8 = string.as_bytes();
        assert_eq!(string_wtf8, string_utf8);
    }

    #[test]
    fn from_unicode_string() {
        let string = "zażółć gęślą jaźń";
        let string_wtf8 = from_ill_formed_utf16(string.encode_utf16());
        let string_utf8 = string.as_bytes();
        assert_eq!(string_wtf8, string_utf8);
    }

    #[test]
    fn into_empty() {
        assert_eq!(into_ill_formed_utf16(std::iter::empty()), vec![]);
    }

    #[test]
    fn into_ascii_string() {
        let string = "foo bar baz";
        let string_wtf8 = into_ill_formed_utf16(string.bytes());
        let string_utf16 = string.encode_utf16().collect::<Vec<_>>();
        assert_eq!(string_wtf8, string_utf16);
    }

    #[test]
    fn into_unicode_string() {
        let string = "zażółć gęślą jaźń";
        let string_wtf8 = into_ill_formed_utf16(string.bytes());
        let string_utf16 = string.encode_utf16().collect::<Vec<_>>();
        assert_eq!(string_wtf8, string_utf16);
    }

    #[quickcheck]
    fn from_any_string(input: String) {
        let units = input.encode_utf16();

        let string_wtf8 = from_ill_formed_utf16(units);
        let string_utf8 = input.as_bytes();
        assert_eq!(string_wtf8, string_utf8);
    }

    #[quickcheck]
    fn into_from_any_string(input: String) {
        let units = input.bytes();

        let string_utf16 = into_ill_formed_utf16(units);
        let string_wtf8 = from_ill_formed_utf16(string_utf16.into_iter());
        assert_eq!(String::from_utf8(string_wtf8).unwrap(), input);
    }

    #[quickcheck]
    fn from_into_any_units(input: Vec<u16>) {
        let units = input.iter().map(|unit| *unit);

        let string_wtf8 = from_ill_formed_utf16(units);
        let string_utf16 = into_ill_formed_utf16(string_wtf8.into_iter());
        assert_eq!(string_utf16, input);
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::str::FromStr;
use std::thread;

fn load_matrix(file_path: &Path) -> Vec<Vec<u32>> {

    let mat_file = File::open(file_path).unwrap();

    let mat_reader = BufReader::new(mat_file);

    let mut mat_line_iterator = mat_reader.lines();

    let mut mat_content: Vec<Vec<u32>> = Vec::new();

    loop {
        match mat_line_iterator.next() {
            Some(result) => {
                                let mat_line = result.unwrap();
                                let slice_iter = mat_line.as_slice().trim_matches(',').split(',')
                                    .map(|x| {
                                                FromStr::from_str(x).unwrap()
                                            });
                                mat_content.push(slice_iter.collect());
                            },

            None => break,
        }
    }

    mat_content
}

fn main() {

    let matrix_1: Vec<Vec<u32>> = load_matrix(Path::new("big_matrix_1.txt"));
    let matrix_2: Vec<Vec<u32>> = load_matrix(Path::new("big_matrix_2.txt"));

    println!("{}", matrix_1[3][10]);
    println!("{}", matrix_2[72][0]);

}
<commit_msg>Single-thread multiplication<commit_after>#![feature(core)]

use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::str::FromStr;
use std::thread;

fn load_matrix(file_path: &Path) -> Vec<Vec<u32>> {

    let mat_file = File::open(file_path).unwrap();

    let mat_reader = BufReader::new(mat_file);

    let mut mat_line_iterator = mat_reader.lines();

    let mut mat_content: Vec<Vec<u32>> = Vec::new();

    loop {
        match mat_line_iterator.next() {
            Some(result) => {
                                let mat_line = result.unwrap();
                                let slice_iter = mat_line.as_slice().trim_matches(',').split(',')
                                    .map(|x| {
                                                FromStr::from_str(x).unwrap()
                                            });
                                mat_content.push(slice_iter.collect());
                            },

            None => break,
        }
    }

    mat_content
}

fn main() {

    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        println!("incorrect arguments");
        return;
    }

    let matrix_1: Vec<Vec<u32>> = load_matrix(Path::new(&args[1]));
    let matrix_2: Vec<Vec<u32>> = load_matrix(Path::new(&args[2]));

    assert!(matrix_1[0].len() == matrix_2.len());

    let mut result: Vec<Vec<u32>> = Vec::new();
    let mul_length = matrix_2.len();

    for y in 0..matrix_1.len() {

        let mut result_row: Vec<u32> = Vec::new();
        let mut entry_value: u32 = 0;

        for x in 0..matrix_2[0].len() {

            for i in 0..mul_length {
                entry_value += matrix_1[y][i] * matrix_2[i][x];
            }

            result_row.push(entry_value);
        }

        result.push(result_row);
    }

    for y in 0..result.len() {
        for x in 0..result[0].len() {
            print!("{},", result[y][x]);
        }
        print!("\n");
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::str::FromStr;
use std::thread;

fn main() {

    let mat_path = Path::new("big_matrix_1.txt");

    let mat_file = File::open(&mat_path).unwrap();

    let mat_reader = BufReader::new(mat_file);

    let mut mat_line_iterator = mat_reader.lines();

    let mut mat_content: Vec<Vec<u32>> = Vec::new();

    loop {
        match mat_line_iterator.next() {
            Some(result) => {
                                let mat_line = result.unwrap();
                                let slice_iter = mat_line.as_slice().split(',')
                                    .map(|x| {
                                                FromStr::from_str(x).unwrap()
                                            });
                                mat_content.push(slice_iter.collect());
                            },

            None => break,
        }
    }
}
<commit_msg>Trim the last comma<commit_after>use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::str::FromStr;
use std::thread;

fn main() {

    let mat_path = Path::new("big_matrix_1.txt");

    let mat_file = File::open(&mat_path).unwrap();

    let mat_reader = BufReader::new(mat_file);

    let mut mat_line_iterator = mat_reader.lines();

    let mut mat_content: Vec<Vec<u32>> = Vec::new();

    loop {
        match mat_line_iterator.next() {
            Some(result) => {
                                let mat_line = result.unwrap();
                                let slice_iter = mat_line.as_slice().trim_matches(',').split(',')
                                    .map(|x| {
                                                FromStr::from_str(x).unwrap()
                                            });
                                mat_content.push(slice_iter.collect());
                            },

            None => break,
        }
    }
}
<|endoftext|>


<commit_before>
use ndarray::*;
use ndarray_linalg::*;
use super::traits::*;

pub struct TimeSeries<'a, TEO, S, D>
    where S: DataMut,
          D: Dimension,
          TEO: TimeEvolutionBase<S, D> + 'a
{
    state: ArrayBase<S, D>,
    teo: &'a TEO,
}

pub fn time_series<'a, TEO, S, D>(x0: ArrayBase<S, D>, teo: &'a TEO) -> TimeSeries<'a, TEO, S, D>
    where S: DataMut,
          D: Dimension,
          TEO: TimeEvolutionBase<S, D>
{
    TimeSeries {
        state: x0,
        teo: teo,
    }
}

impl<'a, TEO, S, D> TimeSeries<'a, TEO, S, D>
    where S: DataMut + DataClone,
          D: Dimension,
          TEO: TimeEvolutionBase<S, D>
{
    pub fn iterate(&mut self) {
        self.teo.iterate(&mut self.state);
    }
}

impl<'a, TEO, S, D> Iterator for TimeSeries<'a, TEO, S, D>
    where S: DataMut + DataClone,
          D: Dimension,
          TEO: TimeEvolutionBase<S, D>
{
    type Item = ArrayBase<S, D>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iterate();
        Some(self.state.clone())
    }
}

/// N-step adaptor
///
/// ```rust
/// use ndarray_odeint::*;
/// let teo = explicit::rk4(model::Lorenz63::default(), 0.01);
/// let nstep = nstep(teo, 10);
/// ```
pub struct NStep<TEO> {
    teo: TEO,
    n: usize,
}

pub fn nstep<TEO>(teo: TEO, n: usize) -> NStep<TEO> {
    NStep { teo, n }
}

impl<TEO, D> ModelSize<D> for NStep<TEO>
    where TEO: ModelSize<D>,
          D: Dimension
{
    fn model_size(&self) -> D::Pattern {
        self.teo.model_size()
    }
}

impl<TEO> TimeStep for NStep<TEO>
    where TEO: TimeStep
{
    type Time = TEO::Time;

    fn get_dt(&self) -> Self::Time {
        self.teo.get_dt() * into_scalar(self.n as f64)
    }

    fn set_dt(&mut self, dt: Self::Time) {
        self.teo.set_dt(dt / into_scalar(self.n as f64));
    }
}

impl<TEO, S, D> TimeEvolutionBase<S, D> for NStep<TEO>
    where TEO: TimeEvolutionBase<S, D>,
          S: DataMut,
          D: Dimension
{
    type Scalar = TEO::Scalar;
    type Time = TEO::Time;

    fn iterate<'a>(&self, x: &'a mut ArrayBase<S, D>) -> &'a mut ArrayBase<S, D> {
        for _ in 0..self.n {
            self.teo.iterate(x);
        }
        x
    }
}
<commit_msg>make NStep TimeEvolution<commit_after>
use ndarray::*;
use ndarray_linalg::*;
use super::traits::*;

pub struct TimeSeries<'a, TEO, S, D>
    where S: DataMut,
          D: Dimension,
          TEO: TimeEvolutionBase<S, D> + 'a
{
    state: ArrayBase<S, D>,
    teo: &'a TEO,
}

pub fn time_series<'a, TEO, S, D>(x0: ArrayBase<S, D>, teo: &'a TEO) -> TimeSeries<'a, TEO, S, D>
    where S: DataMut,
          D: Dimension,
          TEO: TimeEvolutionBase<S, D>
{
    TimeSeries {
        state: x0,
        teo: teo,
    }
}

impl<'a, TEO, S, D> TimeSeries<'a, TEO, S, D>
    where S: DataMut + DataClone,
          D: Dimension,
          TEO: TimeEvolutionBase<S, D>
{
    pub fn iterate(&mut self) {
        self.teo.iterate(&mut self.state);
    }
}

impl<'a, TEO, S, D> Iterator for TimeSeries<'a, TEO, S, D>
    where S: DataMut + DataClone,
          D: Dimension,
          TEO: TimeEvolutionBase<S, D>
{
    type Item = ArrayBase<S, D>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iterate();
        Some(self.state.clone())
    }
}

/// N-step adaptor
///
/// ```rust
/// use ndarray_odeint::*;
/// let teo = explicit::rk4(model::Lorenz63::default(), 0.01);
/// let nstep = nstep(teo, 10);
/// ```
pub struct NStep<TEO> {
    teo: TEO,
    n: usize,
}

pub fn nstep<TEO>(teo: TEO, n: usize) -> NStep<TEO> {
    NStep { teo, n }
}

impl<TEO, D> ModelSize<D> for NStep<TEO>
    where TEO: ModelSize<D>,
          D: Dimension
{
    fn model_size(&self) -> D::Pattern {
        self.teo.model_size()
    }
}

impl<TEO> TimeStep for NStep<TEO>
    where TEO: TimeStep
{
    type Time = TEO::Time;

    fn get_dt(&self) -> Self::Time {
        self.teo.get_dt() * into_scalar(self.n as f64)
    }

    fn set_dt(&mut self, dt: Self::Time) {
        self.teo.set_dt(dt / into_scalar(self.n as f64));
    }
}

impl<TEO, S, D> TimeEvolutionBase<S, D> for NStep<TEO>
    where TEO: TimeEvolutionBase<S, D>,
          S: DataMut,
          D: Dimension
{
    type Scalar = TEO::Scalar;
    type Time = TEO::Time;

    fn iterate<'a>(&self, x: &'a mut ArrayBase<S, D>) -> &'a mut ArrayBase<S, D> {
        for _ in 0..self.n {
            self.teo.iterate(x);
        }
        x
    }
}

impl<TEO, A, D> TimeEvolution<A, D> for NStep<TEO>
    where A: Scalar,
          D: Dimension,
          TEO: TimeEvolution<A, D>
{
}
<|endoftext|>


<commit_before>#[allow(unused)]
pub mod response;
pub mod entity;
pub mod http;

use std;
use std::option::Option;
use std::result::Result;
use hyper;
use hyper::client;
use std::collections::HashMap;
use std::fmt::Debug;
use std::io::Read;
use serde_json;
use std::process::exit;

#[derive(Debug)]
pub struct Api {
    base_uri: &'static str,
    api_key: String,
    login_token: String,
    client: hyper::client::Client,
    version: String,
    user_agent: String,
}

#[allow(unused)]
impl Api {

    /// Create a new api client
    pub fn new(api_key: String) -> Api {
        let crates_version = &std::env::var("CARGO_PKG_VERSION")
            .unwrap_or("unknown".to_string());
        let crates_name = std::env::var("CARGO_PKG_NAME").
            unwrap_or("unknown".to_string());

        let ua = format!("libproxer-rust({}/v{})", crates_name, crates_version);

        Api {
            base_uri:    "http://proxer.me/api/v1/",
            api_key:     api_key,
            login_token: "None".to_string(),
            client:      hyper::client::Client::new(),
            user_agent:  ua,
            version:     std::env::var("HOME").unwrap()
        }
    }

    pub fn info_get_full_info(self, id: u32) -> Result<client::response::Response, hyper::Error> {
        use api::entity::response::*;
        let url = "info/fullentry";

        response::Response::new::<info::fullinfo::FullInfo>(self.http_req(url))
    }

    fn http_req(self, url: &str) -> Result<client::response::Response, hyper::Error> {
        let uri = self.base_uri.to_string()+url;
        let hyper_url = hyper::Url::parse(&uri).unwrap();
        header! {(ProxerApiKeyHeader, "proxer-api-key") => [String]}
        header! {(UserAgent, "User-Agent") => [String]}

        let mut headers = hyper::header::Headers::new();
        headers.set(ProxerApiKeyHeader(self.api_key));
        headers.set(ProxerApiKeyHeader(self.user_agent));

        self.client
            .post(hyper_url)
            .headers(headers)
            .send()
    }

    pub fn read_json(json: String) -> std::result::Result<serde_json::Value, serde_json::Error> {
        serde_json::from_str(&json)
    }
}

fn hashmap_to_encoded_url(params: HashMap<String, String>) -> String{
    "foobar".to_string()
}
<commit_msg>remove version field<commit_after>#[allow(unused)]
pub mod response;
pub mod entity;
pub mod http;

use std;
use std::option::Option;
use std::result::Result;
use hyper;
use hyper::client;
use std::collections::HashMap;
use std::fmt::Debug;
use std::io::Read;
use serde_json;
use std::process::exit;

#[derive(Debug)]
pub struct Api {
    base_uri: &'static str,
    api_key: String,
    login_token: String,
    client: hyper::client::Client,
    user_agent: String,
}

#[allow(unused)]
impl Api {

    /// Create a new api client
    pub fn new(api_key: String) -> Api {
        let crates_version = &std::env::var("CARGO_PKG_VERSION")
            .unwrap_or("unknown".to_string());
        let crates_name = std::env::var("CARGO_PKG_NAME").
            unwrap_or("unknown".to_string());

        let ua = format!("libproxer-rust({}/v{})", crates_name, crates_version);

        Api {
            base_uri:    "http://proxer.me/api/v1/",
            api_key:     api_key,
            login_token: "None".to_string(),
            client:      hyper::client::Client::new(),
            user_agent:  ua,
        }
    }

    pub fn info_get_full_info(self, id: u32) -> Result<client::response::Response, hyper::Error> {
        use api::entity::response::*;
        let url = "info/fullentry";

        response::Response::new::<info::fullinfo::FullInfo>(self.http_req(url))
    }

    fn http_req(self, url: &str) -> Result<client::response::Response, hyper::Error> {
        let uri = self.base_uri.to_string()+url;
        let hyper_url = hyper::Url::parse(&uri).unwrap();
        header! {(ProxerApiKeyHeader, "proxer-api-key") => [String]}
        header! {(UserAgent, "User-Agent") => [String]}

        let mut headers = hyper::header::Headers::new();
        headers.set(ProxerApiKeyHeader(self.api_key));
        headers.set(ProxerApiKeyHeader(self.user_agent));

        self.client
            .post(hyper_url)
            .headers(headers)
            .send()
    }

    pub fn read_json(json: String) -> std::result::Result<serde_json::Value, serde_json::Error> {
        serde_json::from_str(&json)
    }
}

fn hashmap_to_encoded_url(params: HashMap<String, String>) -> String{
    "foobar".to_string()
}
<|endoftext|>


<commit_before>use Environment;
use config::Config;

use lalafell::bot::Bot;
use lalafell::listeners::ReceivesEvents;

use xivdb::XivDb;
use error::*;

use discord::{Discord, State};

use diesel::Connection;
use diesel::sqlite::SqliteConnection;

use std::sync::RwLock;
use std::sync::mpsc::{channel, Receiver};
use std::thread;
use std::env;

mod creation;

thread_local! {
  pub static CONNECTION: SqliteConnection = LalafellBot::database_connection(&env::var("LB_DATABASE_LOCATION").unwrap()).unwrap();
}

pub use self::creation::create_bot;

pub struct LalafellBot {
  pub environment: Environment,
  pub config: Config,
  pub discord: Discord,
  pub state: RwLock<Option<State>>,
  pub xivdb: XivDb,
  pub listeners: RwLock<Vec<Box<ReceivesEvents + Send + Sync>>>
}

impl Bot for LalafellBot {
  fn discord(&self) -> &Discord {
    &self.discord
  }

  fn discord_mut(&mut self) -> &mut Discord {
    &mut self.discord
  }

  fn state(&self) -> &RwLock<Option<State>> {
    &self.state
  }

  fn listeners(&self) -> &RwLock<Vec<Box<ReceivesEvents + Send + Sync>>> {
    &self.listeners
  }
}

impl LalafellBot {
  pub fn new(environment: Environment, config: Config) -> Result<LalafellBot> {
    let discord = Discord::from_bot_token(&environment.discord_bot_token).chain_err(|| "could not start discord from bot token")?;
    Ok(LalafellBot {
      environment: environment,
      config: config,
      discord: discord,
      state: RwLock::default(),
      xivdb: XivDb::default(),
      listeners: RwLock::default()
    })
  }

  pub fn database_connection(location: &str) -> Result<SqliteConnection> {
    SqliteConnection::establish(location)
      .chain_err(|| format!("could not connect to sqlite database at {}", location))
  }

  pub fn start_loop(&self, loop_cancel: Receiver<()>) -> Result<()> {
    let (mut connection, ready) = self.discord.connect().chain_err(|| "could not connect to discord")?;
    *self.state.write().unwrap() = Some(State::new(ready));

    connection.set_game_name("with other Lalafell.".to_string());

    let (event_channel_tx, event_channel_rx) = channel();
    thread::spawn(move || {
      loop {
        if let Err(e) = event_channel_tx.send(connection.recv_event()) {
          error!("error sending event: {}", e);
        }
      }
    });
    info!("Starting main loop");
    loop {
      let event = select! {
        _ = loop_cancel.recv() => break,
        event = event_channel_rx.recv() => event
      };
      let event = match event {
        Ok(Ok(e)) => e,
        Ok(Err(e)) => {
          warn!("could not receive event from select: {}", e);
          continue;
        },
        Err(e) => {
          warn!("could not receive discord event: {}", e);
          continue;
        }
      };
      {
        let mut state_option = self.state.write().unwrap();
        let mut state = state_option.as_mut().unwrap();
        state.update(&event);
      }
      {
        let listeners = self.listeners.read().unwrap();
        for listener in listeners.iter() {
          listener.receive(&event);
        }
      }
    }
    info!("Main loop stopped");
    Ok(())
  }
}
<commit_msg>fix: enable foreign keys, just in case<commit_after>use Environment;
use config::Config;

use lalafell::bot::Bot;
use lalafell::listeners::ReceivesEvents;

use xivdb::XivDb;
use error::*;

use discord::{Discord, State};

use diesel::Connection;
use diesel::connection::SimpleConnection;
use diesel::sqlite::SqliteConnection;

use std::sync::RwLock;
use std::sync::mpsc::{channel, Receiver};
use std::thread;
use std::env;

mod creation;

thread_local! {
  pub static CONNECTION: SqliteConnection = LalafellBot::database_connection(&env::var("LB_DATABASE_LOCATION").unwrap()).unwrap();
}

pub use self::creation::create_bot;

pub struct LalafellBot {
  pub environment: Environment,
  pub config: Config,
  pub discord: Discord,
  pub state: RwLock<Option<State>>,
  pub xivdb: XivDb,
  pub listeners: RwLock<Vec<Box<ReceivesEvents + Send + Sync>>>
}

impl Bot for LalafellBot {
  fn discord(&self) -> &Discord {
    &self.discord
  }

  fn discord_mut(&mut self) -> &mut Discord {
    &mut self.discord
  }

  fn state(&self) -> &RwLock<Option<State>> {
    &self.state
  }

  fn listeners(&self) -> &RwLock<Vec<Box<ReceivesEvents + Send + Sync>>> {
    &self.listeners
  }
}

impl LalafellBot {
  pub fn new(environment: Environment, config: Config) -> Result<LalafellBot> {
    let discord = Discord::from_bot_token(&environment.discord_bot_token).chain_err(|| "could not start discord from bot token")?;
    Ok(LalafellBot {
      environment: environment,
      config: config,
      discord: discord,
      state: RwLock::default(),
      xivdb: XivDb::default(),
      listeners: RwLock::default()
    })
  }

  pub fn database_connection(location: &str) -> Result<SqliteConnection> {
    let connection = SqliteConnection::establish(location)
      .chain_err(|| format!("could not connect to sqlite database at {}", location))?;
    connection.batch_execute("PRAGMA foreign_keys = ON;").chain_err(|| "could not enable foreign keys")?;
    Ok(connection)
  }

  pub fn start_loop(&self, loop_cancel: Receiver<()>) -> Result<()> {
    let (mut connection, ready) = self.discord.connect().chain_err(|| "could not connect to discord")?;
    *self.state.write().unwrap() = Some(State::new(ready));

    connection.set_game_name("with other Lalafell.".to_string());

    let (event_channel_tx, event_channel_rx) = channel();
    thread::spawn(move || {
      loop {
        if let Err(e) = event_channel_tx.send(connection.recv_event()) {
          error!("error sending event: {}", e);
        }
      }
    });
    info!("Starting main loop");
    loop {
      let event = select! {
        _ = loop_cancel.recv() => break,
        event = event_channel_rx.recv() => event
      };
      let event = match event {
        Ok(Ok(e)) => e,
        Ok(Err(e)) => {
          warn!("could not receive event from select: {}", e);
          continue;
        },
        Err(e) => {
          warn!("could not receive discord event: {}", e);
          continue;
        }
      };
      {
        let mut state_option = self.state.write().unwrap();
        let mut state = state_option.as_mut().unwrap();
        state.update(&event);
      }
      {
        let listeners = self.listeners.read().unwrap();
        for listener in listeners.iter() {
          listener.receive(&event);
        }
      }
    }
    info!("Main loop stopped");
    Ok(())
  }
}
<|endoftext|>


<commit_before>use collections::slice::{mod, AsSlice, SlicePrelude};
use collections::vec::{mod, Vec};
use core::mem;
use core::iter::{mod, AdditiveIterator, Iterator};
use core::option::{mod, Some, None, Option};

use iobuf::Iobuf;

/// A span over potentially many Iobufs. This is useful as a "string" type where
/// the contents of the string can potentially come from multiple IObufs, and
/// you want to avoid copying.
///
/// As an optimization, pushing an Iobuf that points to data immediately after
/// the range represented by the last Iobuf pushed will result in just expanding
/// the held Iobuf's range. This prevents allocating lots of unnecessary
/// intermediate buffers, while still maintaining the illusion of "pushing lots
/// of buffers" while incrementally parsing.
///
/// A `BufSpan` is internally represented as either an `Iobuf` or a `Vec<Iobuf>`,
/// depending on how many different buffers were used.
pub enum BufSpan<Buf> {
  Empty,
  One (Buf),
  Many(Vec<Buf>),
}

impl<Buf: Iobuf> BufSpan<Buf> {
  /// Creates a new, empty `Bufspan`.
  ///
  /// ```
  /// use iobuf::{BufSpan, ROIobuf};
  ///
  /// let s: BufSpan<ROIobuf<'static>> = BufSpan::new();
  /// assert!(s.is_empty());
  /// ```
  #[inline]
  pub fn new() -> BufSpan<Buf> {
    Empty
  }

  /// Creates a new `BufSpan` from a slice of bytes.
  ///
  /// ```
  /// use iobuf::{BufSpan, Iobuf, ROIobuf};
  /// use std::iter::AdditiveIterator;
  ///
  /// let s = BufSpan::from_buf(ROIobuf::from_slice(b"hello"));
  /// assert_eq!(s.iter().count(), 1);
  /// assert_eq!(s.iter().map(|b| b.len()).sum(), 5);
  /// ```
  #[inline]
  pub fn from_buf(b: Buf) -> BufSpan<Buf> {
    One(b)
  }

  /// Returns `true` iff the span is over an empty range.
  ///
  /// ```
  /// use iobuf::{BufSpan, Iobuf, ROIobuf};
  ///
  /// let mut s = BufSpan::new();
  ///
  /// assert!(s.is_empty());
  ///
  /// s.push(ROIobuf::from_str(""));
  /// assert!(s.is_empty());
  ///
  /// s.push(ROIobuf::from_str("hello, world!"));
  /// assert!(!s.is_empty());
  /// ```
  #[inline]
  pub fn is_empty(&self) -> bool {
    match *self {
      Empty       => true,
      One (ref b) => b.is_empty(),
      Many(ref v) => v.iter().all(|b| b.is_empty()),
    }
  }

  /// The fast path during pushing -- either fills in the first buffer, or
  /// extends an existing one.
  ///
  /// Returns `None` if the fast path was taken and nothing more needs to be
  /// done. Returns `Some` if we need to do a slow push.
  #[inline]
  fn try_to_extend(&mut self, b: Buf) -> Option<Buf> {
    match *self {
      Empty => {},
      One(ref mut b0) => {
        unsafe {
          if b0.is_extended_by(&b) {
            b0.unsafe_extend(b.len());
            return None;
          } else {
            return Some(b); // Upgrade the `One` into a `Many` in the slow path.
          }
        }
      }
      Many(ref mut v) => {
        // I wish this wouldn't unwind, and just abort... :(
        let last = v.last_mut().unwrap();
        unsafe {
          if last.is_extended_by(&b) {
            last.unsafe_extend(b.len());
            return None;
          } else {
            return Some(b);
          }
        }
      }
    }

    // Handle this case in the fast path, instead of leaving it for slow_push
    // to clean up.
    *self = One(b);
    None
  }

  /// Appends a buffer to a `BufSpan`. If the buffer is an extension of the
  /// previously pushed buffer, the range will be extended. Otherwise, the new
  /// non-extension buffer will be added to the end of a vector.
  #[inline]
  pub fn push(&mut self, b: Buf) {
    match self.try_to_extend(b) {
      None    => {},
      Some(b) => self.slow_push(b),
    }
  }

  /// The slow path during a push. This is only taken if a `BufSpan` must span
  /// multiple backing buffers.
  #[cold]
  fn slow_push(&mut self, b: Buf) {
    let this = mem::replace(self, Empty);
    *self =
      match this {
        Empty   => One(b),
        One(b0) => {
          let mut v = Vec::with_capacity(2);
          v.push(b0);
          v.push(b);
          Many(v)
        },
        Many(mut bs) => { bs.push(b); Many(bs) }
      };
  }

  /// Returns an iterator over references to the buffers inside the `BufSpan`.
  #[inline]
  pub fn iter<'a>(&'a self) -> SpanIter<'a, Buf> {
    match *self {
      Empty       => Opt(None.into_iter()),
      One (ref b) => Opt(Some(b).into_iter()),
      Many(ref v) => Lot(v.as_slice().iter()),
    }
  }

  /// Returns a moving iterator over the buffers inside the `BufSpan`.
  #[inline]
  pub fn into_iter(self) -> SpanMoveIter<Buf> {
    match self {
      Empty   => MoveOpt(None.into_iter()),
      One (b) => MoveOpt(Some(b).into_iter()),
      Many(v) => MoveLot(v.into_iter()),
    }
  }

  /// Returns an iterator over the bytes in the `BufSpan`.
  #[inline]
  pub fn iter_bytes<'a>(&'a self) -> ByteIter<'a, Buf> {
    self.iter()
        .flat_map(|buf| unsafe { buf.as_window_slice().iter() })
        .map(|&b| b)
  }

  /// Returns `true` iff the bytes in this `BufSpan` are the same as the bytes
  /// in the other `BufSpan`.
  ///
  /// ```
  /// use iobuf::{BufSpan, ROIobuf, RWIobuf};
  ///
  /// let a = BufSpan::from_buf(ROIobuf::from_str("hello"));
  /// let b = BufSpan::from_buf(RWIobuf::from_string("hello".into_string()));
  ///
  /// assert!(a.byte_equal(&b));
  ///
  /// let mut c = BufSpan::from_buf(ROIobuf::from_str("hel"));
  /// c.push(ROIobuf::from_str("lo"));
  ///
  /// assert!(a.byte_equal(&c)); assert!(c.byte_equal(&a));
  ///
  /// let d = BufSpan::from_buf(ROIobuf::from_str("helo"));
  /// assert!(!a.byte_equal(&d));
  /// ```
  #[inline]
  pub fn byte_equal<Buf2: Iobuf>(&self, other: &BufSpan<Buf2>) -> bool {
    self.count_bytes() == other.count_bytes()
    && self.iter_bytes().zip(other.iter_bytes()).all(|(a, b)| a == b)
  }

  /// A more efficient version of byte_equal, specialized to work exclusively on
  /// slices.
  ///
  /// ```
  /// use iobuf::{BufSpan, ROIobuf};
  ///
  /// let a = BufSpan::from_buf(ROIobuf::from_str("hello"));
  ///
  /// assert!(a.byte_equal_slice(b"hello"));
  /// assert!(!a.byte_equal_slice(b"helo"));
  /// ```
  #[inline]
  pub fn byte_equal_slice(&self, other: &[u8]) -> bool {
    self.count_bytes() as uint == other.len()
    && self.iter_bytes().zip(other.iter()).all(|(a, &b)| a == b)
  }

  /// Counts the number of bytes this `BufSpan` is over. This is
  /// `O(self.iter().len())`.
  #[inline]
  pub fn count_bytes(&self) -> u32 {
    // `self.iter().map(|b| b.len()).sum()` would be shorter, but I like to
    // specialize for the much more common case of empty or singular `BufSpan`s.
    match *self {
      Empty       => 0,
      One (ref b) => b.len(),
      Many(ref v) => v.iter().map(|b| b.len()).sum(),
    }
  }
}

/// An iterator over the bytes in a `BufSpan`.
pub type ByteIter<'a, Buf> =
  iter::Map<'static, &'a u8, u8,
    iter::FlatMap<'static, &'a Buf,
      SpanIter<'a, Buf>,
      slice::Items<'a, u8>>>;

/// An iterator over references to buffers inside a `BufSpan`.
pub enum SpanIter<'a, Buf: 'a> {
  Opt(option::Item<&'a Buf>),
  Lot(slice::Items<'a, Buf>),
}

impl<'a, Buf: Iobuf> Iterator<&'a Buf> for SpanIter<'a, Buf> {
  #[inline(always)]
  fn next(&mut self) -> Option<&'a Buf> {
    // I'm couting on this match getting lifted out of the loop with
    // loop-invariant code motion.
    match *self {
      Opt(ref mut iter) => iter.next(),
      Lot(ref mut iter) => iter.next(),
    }
  }
}

/// A moving iterator over buffers inside a `BufSpan`.
pub enum SpanMoveIter<Buf> {
  MoveOpt(option::Item<Buf>),
  MoveLot(vec::MoveItems<Buf>),
}

impl<Buf: Iobuf> Iterator<Buf> for SpanMoveIter<Buf> {
  #[inline(always)]
  fn next(&mut self) -> Option<Buf> {
    // I'm couting on this match getting lifted out of the loop with
    // loop-invariant code motion.
    match *self {
      MoveOpt(ref mut iter) => iter.next(),
      MoveLot(ref mut iter) => iter.next(),
    }
  }
}
<commit_msg>less aggressive inlining<commit_after>use collections::slice::{mod, AsSlice, SlicePrelude};
use collections::vec::{mod, Vec};
use core::mem;
use core::iter::{mod, AdditiveIterator, Iterator};
use core::option::{mod, Some, None, Option};

use iobuf::Iobuf;

/// A span over potentially many Iobufs. This is useful as a "string" type where
/// the contents of the string can potentially come from multiple IObufs, and
/// you want to avoid copying.
///
/// As an optimization, pushing an Iobuf that points to data immediately after
/// the range represented by the last Iobuf pushed will result in just expanding
/// the held Iobuf's range. This prevents allocating lots of unnecessary
/// intermediate buffers, while still maintaining the illusion of "pushing lots
/// of buffers" while incrementally parsing.
///
/// A `BufSpan` is internally represented as either an `Iobuf` or a `Vec<Iobuf>`,
/// depending on how many different buffers were used.
pub enum BufSpan<Buf> {
  Empty,
  One (Buf),
  Many(Vec<Buf>),
}

impl<Buf: Iobuf> BufSpan<Buf> {
  /// Creates a new, empty `Bufspan`.
  ///
  /// ```
  /// use iobuf::{BufSpan, ROIobuf};
  ///
  /// let s: BufSpan<ROIobuf<'static>> = BufSpan::new();
  /// assert!(s.is_empty());
  /// ```
  #[inline]
  pub fn new() -> BufSpan<Buf> {
    Empty
  }

  /// Creates a new `BufSpan` from a slice of bytes.
  ///
  /// ```
  /// use iobuf::{BufSpan, Iobuf, ROIobuf};
  /// use std::iter::AdditiveIterator;
  ///
  /// let s = BufSpan::from_buf(ROIobuf::from_slice(b"hello"));
  /// assert_eq!(s.iter().count(), 1);
  /// assert_eq!(s.iter().map(|b| b.len()).sum(), 5);
  /// ```
  #[inline]
  pub fn from_buf(b: Buf) -> BufSpan<Buf> {
    One(b)
  }

  /// Returns `true` iff the span is over an empty range.
  ///
  /// ```
  /// use iobuf::{BufSpan, Iobuf, ROIobuf};
  ///
  /// let mut s = BufSpan::new();
  ///
  /// assert!(s.is_empty());
  ///
  /// s.push(ROIobuf::from_str(""));
  /// assert!(s.is_empty());
  ///
  /// s.push(ROIobuf::from_str("hello, world!"));
  /// assert!(!s.is_empty());
  /// ```
  #[inline]
  pub fn is_empty(&self) -> bool {
    match *self {
      Empty       => true,
      One (ref b) => b.is_empty(),
      Many(ref v) => v.iter().all(|b| b.is_empty()),
    }
  }

  /// The fast path during pushing -- either fills in the first buffer, or
  /// extends an existing one.
  ///
  /// Returns `None` if the fast path was taken and nothing more needs to be
  /// done. Returns `Some` if we need to do a slow push.
  fn try_to_extend(&mut self, b: Buf) -> Option<Buf> {
    match *self {
      Empty => {},
      One(ref mut b0) => {
        unsafe {
          if b0.is_extended_by(&b) {
            b0.unsafe_extend(b.len());
            return None;
          } else {
            return Some(b); // Upgrade the `One` into a `Many` in the slow path.
          }
        }
      }
      Many(ref mut v) => {
        // I wish this wouldn't unwind, and just abort... :(
        let last = v.last_mut().unwrap();
        unsafe {
          if last.is_extended_by(&b) {
            last.unsafe_extend(b.len());
            return None;
          } else {
            return Some(b);
          }
        }
      }
    }

    // Handle this case in the fast path, instead of leaving it for slow_push
    // to clean up.
    *self = One(b);
    None
  }

  /// Appends a buffer to a `BufSpan`. If the buffer is an extension of the
  /// previously pushed buffer, the range will be extended. Otherwise, the new
  /// non-extension buffer will be added to the end of a vector.
  pub fn push(&mut self, b: Buf) {
    match self.try_to_extend(b) {
      None    => {},
      Some(b) => self.slow_push(b),
    }
  }

  /// The slow path during a push. This is only taken if a `BufSpan` must span
  /// multiple backing buffers.
  #[cold]
  fn slow_push(&mut self, b: Buf) {
    let this = mem::replace(self, Empty);
    *self =
      match this {
        Empty   => One(b),
        One(b0) => {
          let mut v = Vec::with_capacity(2);
          v.push(b0);
          v.push(b);
          Many(v)
        },
        Many(mut bs) => { bs.push(b); Many(bs) }
      };
  }

  /// Returns an iterator over references to the buffers inside the `BufSpan`.
  #[inline]
  pub fn iter<'a>(&'a self) -> SpanIter<'a, Buf> {
    match *self {
      Empty       => Opt(None.into_iter()),
      One (ref b) => Opt(Some(b).into_iter()),
      Many(ref v) => Lot(v.as_slice().iter()),
    }
  }

  /// Returns a moving iterator over the buffers inside the `BufSpan`.
  #[inline]
  pub fn into_iter(self) -> SpanMoveIter<Buf> {
    match self {
      Empty   => MoveOpt(None.into_iter()),
      One (b) => MoveOpt(Some(b).into_iter()),
      Many(v) => MoveLot(v.into_iter()),
    }
  }

  /// Returns an iterator over the bytes in the `BufSpan`.
  #[inline]
  pub fn iter_bytes<'a>(&'a self) -> ByteIter<'a, Buf> {
    self.iter()
        .flat_map(|buf| unsafe { buf.as_window_slice().iter() })
        .map(|&b| b)
  }

  /// Returns `true` iff the bytes in this `BufSpan` are the same as the bytes
  /// in the other `BufSpan`.
  ///
  /// ```
  /// use iobuf::{BufSpan, ROIobuf, RWIobuf};
  ///
  /// let a = BufSpan::from_buf(ROIobuf::from_str("hello"));
  /// let b = BufSpan::from_buf(RWIobuf::from_string("hello".into_string()));
  ///
  /// assert!(a.byte_equal(&b));
  ///
  /// let mut c = BufSpan::from_buf(ROIobuf::from_str("hel"));
  /// c.push(ROIobuf::from_str("lo"));
  ///
  /// assert!(a.byte_equal(&c)); assert!(c.byte_equal(&a));
  ///
  /// let d = BufSpan::from_buf(ROIobuf::from_str("helo"));
  /// assert!(!a.byte_equal(&d));
  /// ```
  #[inline]
  pub fn byte_equal<Buf2: Iobuf>(&self, other: &BufSpan<Buf2>) -> bool {
    self.count_bytes() == other.count_bytes()
    && self.iter_bytes().zip(other.iter_bytes()).all(|(a, b)| a == b)
  }

  /// A more efficient version of byte_equal, specialized to work exclusively on
  /// slices.
  ///
  /// ```
  /// use iobuf::{BufSpan, ROIobuf};
  ///
  /// let a = BufSpan::from_buf(ROIobuf::from_str("hello"));
  ///
  /// assert!(a.byte_equal_slice(b"hello"));
  /// assert!(!a.byte_equal_slice(b"helo"));
  /// ```
  #[inline]
  pub fn byte_equal_slice(&self, other: &[u8]) -> bool {
    self.count_bytes() as uint == other.len()
    && self.iter_bytes().zip(other.iter()).all(|(a, &b)| a == b)
  }

  /// Counts the number of bytes this `BufSpan` is over. This is
  /// `O(self.iter().len())`.
  #[inline]
  pub fn count_bytes(&self) -> u32 {
    // `self.iter().map(|b| b.len()).sum()` would be shorter, but I like to
    // specialize for the much more common case of empty or singular `BufSpan`s.
    match *self {
      Empty       => 0,
      One (ref b) => b.len(),
      Many(ref v) => v.iter().map(|b| b.len()).sum(),
    }
  }
}

/// An iterator over the bytes in a `BufSpan`.
pub type ByteIter<'a, Buf> =
  iter::Map<'static, &'a u8, u8,
    iter::FlatMap<'static, &'a Buf,
      SpanIter<'a, Buf>,
      slice::Items<'a, u8>>>;

/// An iterator over references to buffers inside a `BufSpan`.
pub enum SpanIter<'a, Buf: 'a> {
  Opt(option::Item<&'a Buf>),
  Lot(slice::Items<'a, Buf>),
}

impl<'a, Buf: Iobuf> Iterator<&'a Buf> for SpanIter<'a, Buf> {
  #[inline(always)]
  fn next(&mut self) -> Option<&'a Buf> {
    // I'm couting on this match getting lifted out of the loop with
    // loop-invariant code motion.
    match *self {
      Opt(ref mut iter) => iter.next(),
      Lot(ref mut iter) => iter.next(),
    }
  }
}

/// A moving iterator over buffers inside a `BufSpan`.
pub enum SpanMoveIter<Buf> {
  MoveOpt(option::Item<Buf>),
  MoveLot(vec::MoveItems<Buf>),
}

impl<Buf: Iobuf> Iterator<Buf> for SpanMoveIter<Buf> {
  #[inline(always)]
  fn next(&mut self) -> Option<Buf> {
    // I'm couting on this match getting lifted out of the loop with
    // loop-invariant code motion.
    match *self {
      MoveOpt(ref mut iter) => iter.next(),
      MoveLot(ref mut iter) => iter.next(),
    }
  }
}
<|endoftext|>