<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 devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg};
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::WorkerBinding;
use dom::bindings::codegen::Bindings::WorkerBinding::WorkerMethods;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::global::{GlobalField, GlobalRef};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::structuredclone::StructuredCloneData;
use dom::bindings::trace::JSTraceable;
use dom::dedicatedworkerglobalscope::{DedicatedWorkerGlobalScope, WorkerScriptMsg};
use dom::errorevent::ErrorEvent;
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::EventTarget;
use dom::messageevent::MessageEvent;
use dom::workerglobalscope::WorkerGlobalScopeInit;
use ipc_channel::ipc;
use js::jsapi::{HandleValue, JSContext, RootedValue};
use js::jsapi::{JSAutoCompartment, JSAutoRequest};
use js::jsval::UndefinedValue;
use script_thread::{Runnable, ScriptChan};
use std::sync::mpsc::{Sender, channel};
use util::str::DOMString;

pub type TrustedWorkerAddress = Trusted<Worker>;

// https://html.spec.whatwg.org/multipage/#worker
#[dom_struct]
pub struct Worker {
    eventtarget: EventTarget,
    global: GlobalField,
    #[ignore_heap_size_of = "Defined in std"]
    /// Sender to the Receiver associated with the DedicatedWorkerGlobalScope
    /// this Worker created.
    sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
}

impl Worker {
    fn new_inherited(global: GlobalRef,
                     sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>)
                     -> Worker {
        Worker {
            eventtarget: EventTarget::new_inherited(),
            global: GlobalField::from_rooted(&global),
            sender: sender,
        }
    }

    pub fn new(global: GlobalRef,
               sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>)
               -> Root<Worker> {
        reflect_dom_object(box Worker::new_inherited(global, sender),
                           global,
                           WorkerBinding::Wrap)
    }

    // https://html.spec.whatwg.org/multipage/#dom-worker
    pub fn Constructor(global: GlobalRef, script_url: DOMString) -> Fallible<Root<Worker>> {
        // Step 2-4.
        let worker_url = match global.get_url().join(&script_url) {
            Ok(url) => url,
            Err(_) => return Err(Error::Syntax),
        };

        let resource_thread = global.resource_thread();
        let constellation_chan = global.constellation_chan();
        let scheduler_chan = global.scheduler_chan();

        let (sender, receiver) = channel();
        let worker = Worker::new(global, sender.clone());
        let worker_ref = Trusted::new(worker.r(), global.dom_manipulation_thread_source());
        let worker_id = global.get_next_worker_id();

        let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
        let optional_sender = match global.devtools_chan() {
            Some(ref chan) => {
                let pipeline_id = global.pipeline();
                let title = format!("Worker for {}", worker_url);
                let page_info = DevtoolsPageInfo {
                    title: title,
                    url: worker_url.clone(),
                };
                chan.send(ScriptToDevtoolsControlMsg::NewGlobal((pipeline_id, Some(worker_id)),
                                                                devtools_sender.clone(),
                                                                page_info)).unwrap();
                Some(devtools_sender)
            },
            None => None,
        };

        let init = WorkerGlobalScopeInit {
            resource_thread: resource_thread,
            mem_profiler_chan: global.mem_profiler_chan(),
            to_devtools_sender: global.devtools_chan(),
            from_devtools_sender: optional_sender,
            constellation_chan: constellation_chan,
            scheduler_chan: scheduler_chan,
            worker_id: worker_id,
        };
        DedicatedWorkerGlobalScope::run_worker_scope(
            init, worker_url, global.pipeline(), devtools_receiver, worker_ref,
            global.dom_manipulation_thread_source(), sender, receiver);

        Ok(worker)
    }

    pub fn handle_message(address: TrustedWorkerAddress,
                          data: StructuredCloneData) {
        let worker = address.root();

        let global = worker.r().global.root();
        let target = worker.upcast();
        let _ar = JSAutoRequest::new(global.r().get_cx());
        let _ac = JSAutoCompartment::new(global.r().get_cx(), target.reflector().get_jsobject().get());
        let mut message = RootedValue::new(global.r().get_cx(), UndefinedValue());
        data.read(global.r(), message.handle_mut());
        MessageEvent::dispatch_jsval(target, global.r(), message.handle());
    }

    pub fn dispatch_simple_error(address: TrustedWorkerAddress) {
        let worker = address.root();
        let global = worker.r().global.root();
        worker.upcast().fire_simple_event("error", global.r());
    }

    pub fn handle_error_message(address: TrustedWorkerAddress, message: DOMString,
                                filename: DOMString, lineno: u32, colno: u32) {
        let worker = address.root();
        let global = worker.r().global.root();
        let error = RootedValue::new(global.r().get_cx(), UndefinedValue());
        let errorevent = ErrorEvent::new(global.r(), atom!("error"),
                                         EventBubbles::Bubbles, EventCancelable::Cancelable,
                                         message, filename, lineno, colno, error.handle());
        errorevent.upcast::<Event>().fire(worker.upcast());
    }
}

impl WorkerMethods for Worker {
    // https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage
    fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult {
        let data = try!(StructuredCloneData::write(cx, message));
        let address = Trusted::new(self, self.global.root().r().dom_manipulation_thread_source());
        self.sender.send((address, WorkerScriptMsg::DOMMessage(data))).unwrap();
        Ok(())
    }

    // https://html.spec.whatwg.org/multipage/#handler-dedicatedworkerglobalscope-onmessage
    event_handler!(message, GetOnmessage, SetOnmessage);

    // https://html.spec.whatwg.org/multipage/#handler-workerglobalscope-onerror
    event_handler!(error, GetOnerror, SetOnerror);
}

pub struct WorkerMessageHandler {
    addr: TrustedWorkerAddress,
    data: StructuredCloneData,
}

impl WorkerMessageHandler {
    pub fn new(addr: TrustedWorkerAddress, data: StructuredCloneData) -> WorkerMessageHandler {
        WorkerMessageHandler {
            addr: addr,
            data: data,
        }
    }
}

impl Runnable for WorkerMessageHandler {
    fn handler(self: Box<WorkerMessageHandler>) {
        let this = *self;
        Worker::handle_message(this.addr, this.data);
    }
}

pub struct SimpleWorkerErrorHandler {
    addr: TrustedWorkerAddress,
}

impl SimpleWorkerErrorHandler {
    pub fn new(addr: TrustedWorkerAddress) -> SimpleWorkerErrorHandler {
        SimpleWorkerErrorHandler {
            addr: addr
        }
    }
}

impl Runnable for SimpleWorkerErrorHandler {
    fn handler(self: Box<SimpleWorkerErrorHandler>) {
        let this = *self;
        Worker::dispatch_simple_error(this.addr);
    }
}

pub struct WorkerErrorHandler {
    addr: TrustedWorkerAddress,
    msg: DOMString,
    file_name: DOMString,
    line_num: u32,
    col_num: u32,
}

impl WorkerErrorHandler {
    pub fn new(addr: TrustedWorkerAddress, msg: DOMString, file_name: DOMString, line_num: u32, col_num: u32)
            -> WorkerErrorHandler {
        WorkerErrorHandler {
            addr: addr,
            msg: msg,
            file_name: file_name,
            line_num: line_num,
            col_num: col_num,
        }
    }
}

impl Runnable for WorkerErrorHandler {
    fn handler(self: Box<WorkerErrorHandler>) {
        let this = *self;
        Worker::handle_error_message(this.addr, this.msg, this.file_name, this.line_num, this.col_num);
    }
}
<commit_msg>Remove global field from Worker<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 devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg};
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::WorkerBinding;
use dom::bindings::codegen::Bindings::WorkerBinding::WorkerMethods;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::global::{GlobalRef, global_root_from_reflector};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::structuredclone::StructuredCloneData;
use dom::bindings::trace::JSTraceable;
use dom::dedicatedworkerglobalscope::{DedicatedWorkerGlobalScope, WorkerScriptMsg};
use dom::errorevent::ErrorEvent;
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::EventTarget;
use dom::messageevent::MessageEvent;
use dom::workerglobalscope::WorkerGlobalScopeInit;
use ipc_channel::ipc;
use js::jsapi::{HandleValue, JSContext, RootedValue};
use js::jsapi::{JSAutoCompartment, JSAutoRequest};
use js::jsval::UndefinedValue;
use script_thread::{Runnable, ScriptChan};
use std::sync::mpsc::{Sender, channel};
use util::str::DOMString;

pub type TrustedWorkerAddress = Trusted<Worker>;

// https://html.spec.whatwg.org/multipage/#worker
#[dom_struct]
pub struct Worker {
    eventtarget: EventTarget,
    #[ignore_heap_size_of = "Defined in std"]
    /// Sender to the Receiver associated with the DedicatedWorkerGlobalScope
    /// this Worker created.
    sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
}

impl Worker {
    fn new_inherited(sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>)
                     -> Worker {
        Worker {
            eventtarget: EventTarget::new_inherited(),
            sender: sender,
        }
    }

    pub fn new(global: GlobalRef,
               sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>)
               -> Root<Worker> {
        reflect_dom_object(box Worker::new_inherited(sender),
                           global,
                           WorkerBinding::Wrap)
    }

    // https://html.spec.whatwg.org/multipage/#dom-worker
    pub fn Constructor(global: GlobalRef, script_url: DOMString) -> Fallible<Root<Worker>> {
        // Step 2-4.
        let worker_url = match global.get_url().join(&script_url) {
            Ok(url) => url,
            Err(_) => return Err(Error::Syntax),
        };

        let resource_thread = global.resource_thread();
        let constellation_chan = global.constellation_chan();
        let scheduler_chan = global.scheduler_chan();

        let (sender, receiver) = channel();
        let worker = Worker::new(global, sender.clone());
        let worker_ref = Trusted::new(worker.r(), global.dom_manipulation_thread_source());
        let worker_id = global.get_next_worker_id();

        let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
        let optional_sender = match global.devtools_chan() {
            Some(ref chan) => {
                let pipeline_id = global.pipeline();
                let title = format!("Worker for {}", worker_url);
                let page_info = DevtoolsPageInfo {
                    title: title,
                    url: worker_url.clone(),
                };
                chan.send(ScriptToDevtoolsControlMsg::NewGlobal((pipeline_id, Some(worker_id)),
                                                                devtools_sender.clone(),
                                                                page_info)).unwrap();
                Some(devtools_sender)
            },
            None => None,
        };

        let init = WorkerGlobalScopeInit {
            resource_thread: resource_thread,
            mem_profiler_chan: global.mem_profiler_chan(),
            to_devtools_sender: global.devtools_chan(),
            from_devtools_sender: optional_sender,
            constellation_chan: constellation_chan,
            scheduler_chan: scheduler_chan,
            worker_id: worker_id,
        };
        DedicatedWorkerGlobalScope::run_worker_scope(
            init, worker_url, global.pipeline(), devtools_receiver, worker_ref,
            global.dom_manipulation_thread_source(), sender, receiver);

        Ok(worker)
    }

    pub fn handle_message(address: TrustedWorkerAddress,
                          data: StructuredCloneData) {
        let worker = address.root();

        let global = global_root_from_reflector(worker.r());
        let target = worker.upcast();
        let _ar = JSAutoRequest::new(global.r().get_cx());
        let _ac = JSAutoCompartment::new(global.r().get_cx(), target.reflector().get_jsobject().get());
        let mut message = RootedValue::new(global.r().get_cx(), UndefinedValue());
        data.read(global.r(), message.handle_mut());
        MessageEvent::dispatch_jsval(target, global.r(), message.handle());
    }

    pub fn dispatch_simple_error(address: TrustedWorkerAddress) {
        let worker = address.root();
        let global = global_root_from_reflector(worker.r());
        worker.upcast().fire_simple_event("error", global.r());
    }

    pub fn handle_error_message(address: TrustedWorkerAddress, message: DOMString,
                                filename: DOMString, lineno: u32, colno: u32) {
        let worker = address.root();
        let global = global_root_from_reflector(worker.r());
        let error = RootedValue::new(global.r().get_cx(), UndefinedValue());
        let errorevent = ErrorEvent::new(global.r(), atom!("error"),
                                         EventBubbles::Bubbles, EventCancelable::Cancelable,
                                         message, filename, lineno, colno, error.handle());
        errorevent.upcast::<Event>().fire(worker.upcast());
    }
}

impl WorkerMethods for Worker {
    // https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage
    fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult {
        let data = try!(StructuredCloneData::write(cx, message));
        let address = Trusted::new(self, global_root_from_reflector(self).r().dom_manipulation_thread_source());
        self.sender.send((address, WorkerScriptMsg::DOMMessage(data))).unwrap();
        Ok(())
    }

    // https://html.spec.whatwg.org/multipage/#handler-dedicatedworkerglobalscope-onmessage
    event_handler!(message, GetOnmessage, SetOnmessage);

    // https://html.spec.whatwg.org/multipage/#handler-workerglobalscope-onerror
    event_handler!(error, GetOnerror, SetOnerror);
}

pub struct WorkerMessageHandler {
    addr: TrustedWorkerAddress,
    data: StructuredCloneData,
}

impl WorkerMessageHandler {
    pub fn new(addr: TrustedWorkerAddress, data: StructuredCloneData) -> WorkerMessageHandler {
        WorkerMessageHandler {
            addr: addr,
            data: data,
        }
    }
}

impl Runnable for WorkerMessageHandler {
    fn handler(self: Box<WorkerMessageHandler>) {
        let this = *self;
        Worker::handle_message(this.addr, this.data);
    }
}

pub struct SimpleWorkerErrorHandler {
    addr: TrustedWorkerAddress,
}

impl SimpleWorkerErrorHandler {
    pub fn new(addr: TrustedWorkerAddress) -> SimpleWorkerErrorHandler {
        SimpleWorkerErrorHandler {
            addr: addr
        }
    }
}

impl Runnable for SimpleWorkerErrorHandler {
    fn handler(self: Box<SimpleWorkerErrorHandler>) {
        let this = *self;
        Worker::dispatch_simple_error(this.addr);
    }
}

pub struct WorkerErrorHandler {
    addr: TrustedWorkerAddress,
    msg: DOMString,
    file_name: DOMString,
    line_num: u32,
    col_num: u32,
}

impl WorkerErrorHandler {
    pub fn new(addr: TrustedWorkerAddress, msg: DOMString, file_name: DOMString, line_num: u32, col_num: u32)
            -> WorkerErrorHandler {
        WorkerErrorHandler {
            addr: addr,
            msg: msg,
            file_name: file_name,
            line_num: line_num,
            col_num: col_num,
        }
    }
}

impl Runnable for WorkerErrorHandler {
    fn handler(self: Box<WorkerErrorHandler>) {
        let this = *self;
        Worker::handle_error_message(this.addr, this.msg, this.file_name, this.line_num, this.col_num);
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::path::PathBuf;

use site::Site;
use tempfile::{tempdir, TempDir};

// 2 helper macros to make all the build testing more bearable
#[macro_export]
macro_rules! file_exists {
    ($root: expr, $path: expr) => {{
        let mut path = $root.clone();
        for component in $path.split("/") {
            path = path.join(component);
        }
        std::path::Path::new(&path).exists()
    }};
}

#[macro_export]
macro_rules! file_contains {
    ($root: expr, $path: expr, $text: expr) => {{
        use std::io::prelude::*;
        let mut path = $root.clone();
        for component in $path.split("/") {
            path = path.join(component);
        }
        let mut file = std::fs::File::open(&path).expect(&format!("Failed to open {:?}", $path));
        let mut s = String::new();
        file.read_to_string(&mut s).unwrap();
        println!("{}", s);
        s.contains($text)
    }};
}

/// We return the tmpdir otherwise it would get out of scope and be deleted
/// The tests can ignore it if they dont need it by prefixing it with a `_`
pub fn build_site(name: &str) -> (Site, TempDir, PathBuf) {
    let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
    path.push(name);
    let mut site = Site::new(&path, "config.toml").unwrap();
    site.load().unwrap();
    let tmp_dir = tempdir().expect("create temp dir");
    let public = &tmp_dir.path().join("public");
    site.set_output_path(&public);
    site.build().expect("Couldn't build the site");
    (site, tmp_dir, public.clone())
}

/// Same as `build_site` but has a hook to setup some config options
pub fn build_site_with_setup<F>(name: &str, mut setup_cb: F) -> (Site, TempDir, PathBuf)
where
    F: FnMut(Site) -> (Site, bool),
{
    let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
    path.push(name);
    let site = Site::new(&path, "config.toml").unwrap();
    let (mut site, needs_loading) = setup_cb(site);
    if needs_loading {
        site.load().unwrap();
    }
    let tmp_dir = tempdir().expect("create temp dir");
    let public = &tmp_dir.path().join("public");
    site.set_output_path(&public);
    site.build().expect("Couldn't build the site");
    (site, tmp_dir, public.clone())
}
<commit_msg>Fix warning when building site tests (#936)<commit_after>#![allow(dead_code)]
use std::env;
use std::path::PathBuf;

use site::Site;
use tempfile::{tempdir, TempDir};

// 2 helper macros to make all the build testing more bearable
#[macro_export]
macro_rules! file_exists {
    ($root: expr, $path: expr) => {{
        let mut path = $root.clone();
        for component in $path.split("/") {
            path = path.join(component);
        }
        std::path::Path::new(&path).exists()
    }};
}

#[macro_export]
macro_rules! file_contains {
    ($root: expr, $path: expr, $text: expr) => {{
        use std::io::prelude::*;
        let mut path = $root.clone();
        for component in $path.split("/") {
            path = path.join(component);
        }
        let mut file = std::fs::File::open(&path).expect(&format!("Failed to open {:?}", $path));
        let mut s = String::new();
        file.read_to_string(&mut s).unwrap();
        println!("{}", s);
        s.contains($text)
    }};
}

/// We return the tmpdir otherwise it would get out of scope and be deleted
/// The tests can ignore it if they dont need it by prefixing it with a `_`
pub fn build_site(name: &str) -> (Site, TempDir, PathBuf) {
    let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
    path.push(name);
    let mut site = Site::new(&path, "config.toml").unwrap();
    site.load().unwrap();
    let tmp_dir = tempdir().expect("create temp dir");
    let public = &tmp_dir.path().join("public");
    site.set_output_path(&public);
    site.build().expect("Couldn't build the site");
    (site, tmp_dir, public.clone())
}

/// Same as `build_site` but has a hook to setup some config options
pub fn build_site_with_setup<F>(name: &str, mut setup_cb: F) -> (Site, TempDir, PathBuf)
where
    F: FnMut(Site) -> (Site, bool),
{
    let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
    path.push(name);
    let site = Site::new(&path, "config.toml").unwrap();
    let (mut site, needs_loading) = setup_cb(site);
    if needs_loading {
        site.load().unwrap();
    }
    let tmp_dir = tempdir().expect("create temp dir");
    let public = &tmp_dir.path().join("public");
    site.set_output_path(&public);
    site.build().expect("Couldn't build the site");
    (site, tmp_dir, public.clone())
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::env;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::PathBuf;
use std::str::FromStr;

use hcore::fs::find_command;
use hcore::package::{PackageIdent, PackageInstall};

use error::{Error, Result};

static LOGKEY: &'static str = "PT";

/// The package identifier for the OS specific interpreter which the Supervisor is built with,
/// or which may be independently installed
#[cfg(any(target_os = "linux", target_os = "macos"))]
const INTERPRETER_IDENT: &'static str = "core/busybox-static";
#[cfg(any(target_os = "linux", target_os = "macos"))]
const INTERPRETER_COMMAND: &'static str = "busybox";

#[cfg(target_os = "windows")]
const INTERPRETER_IDENT: &'static str = "core/powershell";
#[cfg(target_os = "windows")]
const INTERPRETER_COMMAND: &'static str = "powershell";

/// Returns a list of path entries, one of which should contain the interpreter binary.
///
/// The Supervisor provides a minimal userland of commands to the supervised process. This includes
/// binaries such as `chpst` which can be used by a package's `run` hook.
///
/// There is a series of fallback strategies used here in order to find a usable interpreter
/// installation. The general strategy is the following:
///
/// * Are we (the Supervisor) running inside a package?
///     * Yes: use the interpreter release describes in our `DEPS` metafile & return its `PATH`
///       entries
///     * No
///         * Can we find any installed interpreter package?
///             * Yes: use the latest installed interpreter release & return its `PATH` entries
///             * No
///                 * Is the interpreter binary present on `$PATH`?
///                     * Yes: return the parent directory which holds the interpreter binary
///                     * No: out of ideas, so return an error after warning the user we're done
///
/// # Errors
///
/// * If an installed package should exist, but cannot be loaded
/// * If a installed package's path metadata cannot be read or returned
/// * If a known-working package identifier string cannot be parsed
/// * If the parent directory of a located interpreter binary cannot be computed
/// * If the Supervisor is not executing inside a package, and if no interpreter package is
///   installed, and if no interpreter binary can be found on the `PATH`
pub fn interpreter_paths() -> Result<Vec<PathBuf>> {
    // First, we'll check if we're running inside a package. If we are, then we should  be able to
    // access the `../DEPS` metadata file and read it to get the specific version of the
    // interpreter.
    let my_interpreter_dep_ident = match env::current_exe() {
        Ok(p) => {
            match p.parent() {
                Some(p) => {
                    let metafile = p.join("DEPS");
                    if metafile.is_file() {
                        interpreter_dep_from_metafile(metafile)
                    } else {
                        None
                    }
                }
                None => None,
            }
        }
        Err(_) => None,
    };
    let interpreter_paths: Vec<PathBuf> = match my_interpreter_dep_ident {
        // We've found the specific release that our Supervisor was built with. Get its path
        // metadata.
        Some(ident) => {
            let pkg_install = PackageInstall::load(&ident, None)?;
            pkg_install.paths()?
        }
        // If we're not running out of a package, then see if any package of the interpreter is
        // installed.
        None => {
            let ident = PackageIdent::from_str(INTERPRETER_IDENT)?;
            match PackageInstall::load(&ident, None) {
                // We found a version of the interpreter. Get its path metadata.
                Ok(pkg_install) => pkg_install.paths()?,
                // Nope, no packages of the interpreter installed. Now we're going to see if the
                // interpreter command is present on `PATH`.
                Err(_) => {
                    match find_command(INTERPRETER_COMMAND) {
                        // We found the interpreter on `PATH`, so that its `dirname` and return
                        // that.
                        Some(bin) => {
                            match bin.parent() {
                                Some(dir) => vec![dir.to_path_buf()],
                                None => {
                                    let path = bin.to_string_lossy().into_owned();
                                    outputln!(
                                        "An unexpected error has occurred. {} was \
                                               found at {}, yet the parent directory could not \
                                               be computed. Aborting...",
                                        INTERPRETER_COMMAND,
                                        &path
                                    );
                                    return Err(sup_error!(Error::FileNotFound(path)));
                                }
                            }
                        }
                        // Well, we're not running out of a package, there is no interpreter package
                        // installed, it's not on `PATH`, what more can we do. Time to give up the
                        // chase. Too bad, we were really trying to be helpful here.
                        None => {
                            outputln!(
                                "A interpreter installation is required but could not be \
                                       found. Please install '{}' or put the \
                                       interpreter's command on your $PATH. Aborting...",
                                INTERPRETER_IDENT
                            );
                            return Err(sup_error!(Error::PackageNotFound(ident)));
                        }
                    }
                }
            }
        }
    };
    Ok(interpreter_paths)
}

pub fn append_interpreter_and_path(orig_paths: &mut Vec<PathBuf>) -> Result<String> {
    let mut paths = interpreter_paths()?.to_owned();
    orig_paths.append(&mut paths);
    if let Some(val) = env::var_os("PATH") {
        let mut os_paths = env::split_paths(&val).collect::<Vec<PathBuf>>();
        orig_paths.append(&mut os_paths);
    }
    let joined = env::join_paths(orig_paths)?;
    let path_str = joined.into_string().expect(
        "Unable to convert OsStr path to string!",
    );
    Ok(path_str)
}

/// Returns a `PackageIdent` for a interpreter package, assuming it exists in the provided metafile.
fn interpreter_dep_from_metafile(metafile: PathBuf) -> Option<PackageIdent> {
    let f = match File::open(metafile) {
        Ok(f) => f,
        Err(_) => return None,
    };
    let reader = BufReader::new(f);
    for line in reader.lines() {
        let line = match line {
            Ok(l) => l,
            Err(_) => return None,
        };
        if line.contains(INTERPRETER_IDENT) {
            match PackageIdent::from_str(&line) {
                Ok(pi) => return Some(pi),
                Err(_) => return None,
            }
        }
    }
    None
}
<commit_msg>Simplify append_interpreter_and_path function a bit<commit_after>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::env;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::PathBuf;
use std::str::FromStr;

use hcore::fs::find_command;
use hcore::package::{PackageIdent, PackageInstall};

use error::{Error, Result};

static LOGKEY: &'static str = "PT";

/// The package identifier for the OS specific interpreter which the Supervisor is built with,
/// or which may be independently installed
#[cfg(any(target_os = "linux", target_os = "macos"))]
const INTERPRETER_IDENT: &'static str = "core/busybox-static";
#[cfg(any(target_os = "linux", target_os = "macos"))]
const INTERPRETER_COMMAND: &'static str = "busybox";

#[cfg(target_os = "windows")]
const INTERPRETER_IDENT: &'static str = "core/powershell";
#[cfg(target_os = "windows")]
const INTERPRETER_COMMAND: &'static str = "powershell";

/// Returns a list of path entries, one of which should contain the interpreter binary.
///
/// The Supervisor provides a minimal userland of commands to the supervised process. This includes
/// binaries such as `chpst` which can be used by a package's `run` hook.
///
/// There is a series of fallback strategies used here in order to find a usable interpreter
/// installation. The general strategy is the following:
///
/// * Are we (the Supervisor) running inside a package?
///     * Yes: use the interpreter release describes in our `DEPS` metafile & return its `PATH`
///       entries
///     * No
///         * Can we find any installed interpreter package?
///             * Yes: use the latest installed interpreter release & return its `PATH` entries
///             * No
///                 * Is the interpreter binary present on `$PATH`?
///                     * Yes: return the parent directory which holds the interpreter binary
///                     * No: out of ideas, so return an error after warning the user we're done
///
/// # Errors
///
/// * If an installed package should exist, but cannot be loaded
/// * If a installed package's path metadata cannot be read or returned
/// * If a known-working package identifier string cannot be parsed
/// * If the parent directory of a located interpreter binary cannot be computed
/// * If the Supervisor is not executing inside a package, and if no interpreter package is
///   installed, and if no interpreter binary can be found on the `PATH`
pub fn interpreter_paths() -> Result<Vec<PathBuf>> {
    // First, we'll check if we're running inside a package. If we are, then we should  be able to
    // access the `../DEPS` metadata file and read it to get the specific version of the
    // interpreter.
    let my_interpreter_dep_ident = match env::current_exe() {
        Ok(p) => {
            match p.parent() {
                Some(p) => {
                    let metafile = p.join("DEPS");
                    if metafile.is_file() {
                        interpreter_dep_from_metafile(metafile)
                    } else {
                        None
                    }
                }
                None => None,
            }
        }
        Err(_) => None,
    };
    let interpreter_paths: Vec<PathBuf> = match my_interpreter_dep_ident {
        // We've found the specific release that our Supervisor was built with. Get its path
        // metadata.
        Some(ident) => {
            let pkg_install = PackageInstall::load(&ident, None)?;
            pkg_install.paths()?
        }
        // If we're not running out of a package, then see if any package of the interpreter is
        // installed.
        None => {
            let ident = PackageIdent::from_str(INTERPRETER_IDENT)?;
            match PackageInstall::load(&ident, None) {
                // We found a version of the interpreter. Get its path metadata.
                Ok(pkg_install) => pkg_install.paths()?,
                // Nope, no packages of the interpreter installed. Now we're going to see if the
                // interpreter command is present on `PATH`.
                Err(_) => {
                    match find_command(INTERPRETER_COMMAND) {
                        // We found the interpreter on `PATH`, so that its `dirname` and return
                        // that.
                        Some(bin) => {
                            match bin.parent() {
                                Some(dir) => vec![dir.to_path_buf()],
                                None => {
                                    let path = bin.to_string_lossy().into_owned();
                                    outputln!(
                                        "An unexpected error has occurred. {} was \
                                               found at {}, yet the parent directory could not \
                                               be computed. Aborting...",
                                        INTERPRETER_COMMAND,
                                        &path
                                    );
                                    return Err(sup_error!(Error::FileNotFound(path)));
                                }
                            }
                        }
                        // Well, we're not running out of a package, there is no interpreter package
                        // installed, it's not on `PATH`, what more can we do. Time to give up the
                        // chase. Too bad, we were really trying to be helpful here.
                        None => {
                            outputln!(
                                "A interpreter installation is required but could not be \
                                       found. Please install '{}' or put the \
                                       interpreter's command on your $PATH. Aborting...",
                                INTERPRETER_IDENT
                            );
                            return Err(sup_error!(Error::PackageNotFound(ident)));
                        }
                    }
                }
            }
        }
    };
    Ok(interpreter_paths)
}

pub fn append_interpreter_and_path(path_entries: &mut Vec<PathBuf>) -> Result<String> {
    let mut paths = interpreter_paths()?;
    path_entries.append(&mut paths);
    if let Some(val) = env::var_os("PATH") {
        let mut os_paths = env::split_paths(&val).collect();
        path_entries.append(&mut os_paths);
    }
    let joined = env::join_paths(path_entries)?;
    let path_str = joined.into_string().expect(
        "Unable to convert OsStr path to string!",
    );
    Ok(path_str)
}

/// Returns a `PackageIdent` for a interpreter package, assuming it exists in the provided metafile.
fn interpreter_dep_from_metafile(metafile: PathBuf) -> Option<PackageIdent> {
    let f = match File::open(metafile) {
        Ok(f) => f,
        Err(_) => return None,
    };
    let reader = BufReader::new(f);
    for line in reader.lines() {
        let line = match line {
            Ok(l) => l,
            Err(_) => return None,
        };
        if line.contains(INTERPRETER_IDENT) {
            match PackageIdent::from_str(&line) {
                Ok(pi) => return Some(pi),
                Err(_) => return None,
            }
        }
    }
    None
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate rmp as msgpack;

use test::Bencher;

use msgpack::decode::{
    read_i64_loosely,
    read_str,
    read_value,
};

#[bench]
fn from_string_read_str(b: &mut Bencher) {
    // Lorem ipsum dolor sit amet.
    let buf = [
        0xbb, 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, 0x73,
        0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73,
        0x69, 0x74, 0x20, 0x61, 0x6d, 0x65, 0x74, 0x2e
    ];

    let mut out = [0u8; 32];

    b.iter(|| {
        let res = read_str(&mut &buf[..], &mut out[..]).unwrap();
        test::black_box(res);
    });
}

#[bench]
fn from_string_read_value(b: &mut Bencher) {
    // Lorem ipsum dolor sit amet.
    let buf = [
        0xbb, 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, 0x73, 0x75,
        0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74,
        0x20, 0x61, 0x6d, 0x65, 0x74, 0x2e
    ];

    b.iter(|| {
        let res = read_value(&mut &buf[..]).unwrap();
        test::black_box(res);
    });
}

#[bench]
fn from_i64_read_i64_loosely(b: &mut Bencher) {
    let buf = [0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];

    b.iter(|| {
        let res = read_i64_loosely(&mut &buf[..]).unwrap();
        test::black_box(res);
    });
}

//#[bench]
//fn from_i64_read_integer(b: &mut Bencher) {
//    let buf = [0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];

//    b.iter(|| {
//        let res = read_integer(&mut &buf[..]).unwrap();
//        test::black_box(res);
//    });
//}

//#[bench]
//fn from_i8_read_i8(b: &mut Bencher) {
//    let buf = [0xd0, 0xff];

//    b.iter(|| {
//        let res = read_i8(&mut &buf[..]).unwrap();
//        test::black_box(res);
//    });
//}

//#[bench]
//fn from_u8_read_u64_loosely(b: &mut Bencher) {
//    let buf = [0xcc, 0xff];

//    b.iter(|| {
//        let res = read_u64_loosely(&mut &buf[..]).unwrap();
//        test::black_box(res);
//    });
//}
<commit_msg>[Bench] Added complex benchmark.<commit_after>#![feature(test)]

extern crate test;
extern crate rmp as msgpack;

use test::Bencher;

use msgpack::decode::{
    read_i64_loosely,
    read_str,
    read_value,
};

#[bench]
fn from_string_read_str(b: &mut Bencher) {
    // Lorem ipsum dolor sit amet.
    let buf = [
        0xbb, 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, 0x73,
        0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73,
        0x69, 0x74, 0x20, 0x61, 0x6d, 0x65, 0x74, 0x2e
    ];

    let mut out = [0u8; 32];

    b.iter(|| {
        let res = read_str(&mut &buf[..], &mut out[..]).unwrap();
        test::black_box(res);
    });
}

#[bench]
fn from_string_read_value(b: &mut Bencher) {
    // Lorem ipsum dolor sit amet.
    let buf = [
        0xbb, 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, 0x73, 0x75,
        0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74,
        0x20, 0x61, 0x6d, 0x65, 0x74, 0x2e
    ];

    b.iter(|| {
        let res = read_value(&mut &buf[..]).unwrap();
        test::black_box(res);
    });
}

#[bench]
fn from_complex_read_value(b: &mut Bencher) {
    let buf = [
        0x95, // Fixed array with 5 len.
        0xc0, // Nil.
        0x2a, // 42.
        0xcb, 0x40, 0x9, 0x21, 0xca, 0xc0, 0x83, 0x12, 0x6f, // 3.1415
        // Fixed string with "Lorem ipsum dolor sit amet." content.
        0xbb, 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, 0x73, 0x75,
        0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74,
        0x20, 0x61, 0x6d, 0x65, 0x74, 0x2e,
        0x81, // Fixed map with 1 len.
        0xa3, 0x6b, 0x65, 0x79, // Key "key".
        0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65 // Value: "value".
    ];

    b.iter(|| {
        let res = read_value(&mut &buf[..]).unwrap();
        test::black_box(res);
    });
}

#[bench]
fn from_i64_read_i64_loosely(b: &mut Bencher) {
    let buf = [0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];

    b.iter(|| {
        let res = read_i64_loosely(&mut &buf[..]).unwrap();
        test::black_box(res);
    });
}

//#[bench]
//fn from_i64_read_integer(b: &mut Bencher) {
//    let buf = [0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];

//    b.iter(|| {
//        let res = read_integer(&mut &buf[..]).unwrap();
//        test::black_box(res);
//    });
//}

//#[bench]
//fn from_i8_read_i8(b: &mut Bencher) {
//    let buf = [0xd0, 0xff];

//    b.iter(|| {
//        let res = read_i8(&mut &buf[..]).unwrap();
//        test::black_box(res);
//    });
//}

//#[bench]
//fn from_u8_read_u64_loosely(b: &mut Bencher) {
//    let buf = [0xcc, 0xff];

//    b.iter(|| {
//        let res = read_u64_loosely(&mut &buf[..]).unwrap();
//        test::black_box(res);
//    });
//}
<|endoftext|>


<commit_before>#![allow(non_camel_case_types)]

#[cfg(feature = "source")]
extern crate fftw_src as ffi;

#[cfg(feature = "intel-mkl")]
extern crate intel_mkl_src as ffi;

use libc::FILE;
pub use num_complex::Complex32 as fftwf_complex;
pub use num_complex::Complex64 as fftw_complex;

include!("fftw.rs");
<commit_msg>Add link attr<commit_after>#![allow(non_camel_case_types)]

#[cfg(feature = "source")]
extern crate fftw_src as ffi;

#[cfg(feature = "intel-mkl")]
extern crate intel_mkl_src as ffi;

use libc::FILE;
pub use num_complex::Complex32 as fftwf_complex;
pub use num_complex::Complex64 as fftw_complex;

#[cfg_attr(feature = "system", link(name = "fftw3"))]
extern "C" {}
#[cfg_attr(feature = "system", link(name = "fftw3f"))]
extern "C" {}

include!("fftw.rs");
<|endoftext|>


<commit_before>use analysis::namespaces;
use case::CaseExt;
use codegen::general::{self, version_condition, version_condition_string};
use config::gobjects::GObject;
use env::Env;
use file_saver;
use library::*;
use std::collections::HashSet;
use std::io::prelude::*;
use std::io::Result;
use std::path::Path;
use traits::*;
use version::Version;

pub fn generate(env: &Env, root_path: &Path, mod_rs: &mut Vec<String>) {
    let path = root_path.join("enums.rs");
    file_saver::save_to_file(path, env.config.make_backup, |w| {
        try!(general::start_comments(w, &env.config));
        try!(writeln!(w, "{}", "
use ffi;
use glib_ffi;
use glib::error::ErrorDomain;
use glib::translate::*;
"));

        let configs = env.config.objects.values()
            .filter(|c| {
                c.status.need_generate() &&
                    c.type_id.map_or(false, |tid| tid.ns_id == namespaces::MAIN)
            });
        let mut first = true;
        for config in configs {
            if let Type::Enumeration(ref enum_) = *env.library.type_(config.type_id.unwrap()) {
                if first {
                    mod_rs.push("\nmod enums;".into());
                    first = false;
                }
                if let Some (cfg) = version_condition_string(env, enum_.version, false, 0) {
                    mod_rs.push(cfg);
                }
                mod_rs.push(format!("pub use self::enums::{};", enum_.name));
                try!(generate_enum(env, w, enum_, config));
            }
        }

        Ok(())
    });
}

fn generate_enum(env: &Env, w: &mut Write, enum_: &Enumeration, config: &GObject) -> Result<()> {
    struct Member {
        name: String,
        c_name: String,
        version: Option<Version>,
    }

    let mut members: Vec<Member> = Vec::new();
    let mut vals: HashSet<String> = HashSet::new();

    for member in &enum_.members {
        let member_config = config.members.matched(&member.name);
        let is_alias = member_config.iter().any(|m| m.alias);
        if is_alias || vals.contains(&member.value) {
            continue
        }
        vals.insert(member.value.clone());
        let version = member_config.iter().filter_map(|m| m.version).next();
        members.push(Member {
            name: member.name.to_camel(),
            c_name: member.c_identifier.clone(),
            version: version,
        });
    }

    try!(version_condition(w, env, enum_.version, false, 0));
    try!(writeln!(w, "#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]"));
    try!(writeln!(w, "pub enum {} {{", enum_.name));
    for member in &members {
        try!(writeln!(w, "\t{},", member.name));
    }
    try!(writeln!(w, "{}", "    #[doc(hidden)]
    __Nonexhaustive,
}
"));

    try!(version_condition(w, env, enum_.version, false, 0));
    try!(writeln!(w, "#[doc(hidden)]
impl ToGlib for {name} {{
    type GlibType = ffi::{ffi_name};

    fn to_glib(&self) -> ffi::{ffi_name} {{
        match *self {{", name = enum_.name, ffi_name = enum_.c_type));
    for member in &members {
        try!(version_condition(w, env, member.version, false, 3));
        try!(writeln!(w, "\t\t\t{}::{} => ffi::{},", enum_.name, member.name, member.c_name));
    }
    try!(writeln!(w, "\t\t\t{}::__Nonexhaustive => panic!(),", enum_.name));
    try!(writeln!(w, "{}",
"        }
    }
}
"));

    let assert = if env.config.generate_safety_asserts {
        "skip_assert_initialized!();\n\t\t"
    } else {
        ""
    };

    try!(version_condition(w, env, enum_.version, false, 0));
    try!(writeln!(w, "#[doc(hidden)]
impl FromGlib<ffi::{ffi_name}> for {name} {{
    fn from_glib(value: ffi::{ffi_name}) -> Self {{
        {assert}match value {{", name = enum_.name, ffi_name = enum_.c_type, assert = assert));
    for member in &members {
        try!(version_condition(w, env, member.version, false, 3));
        try!(writeln!(w, "\t\t\tffi::{} => {}::{},", member.c_name, enum_.name, member.name));
    }
    if members.len() == 1 {
        try!(writeln!(w, "\t\t\t_ => {}::__Nonexhaustive,", enum_.name));
    }
    try!(writeln!(w, "{}",
"        }
    }
}
"));

    if let Some(ref get_quark) = enum_.error_domain {
        let get_quark = get_quark.replace("-", "_");
        let has_failed_member = members.iter().any(|m| m.name == "Failed");

        try!(version_condition(w, env, enum_.version, false, 0));
        try!(writeln!(w, "impl ErrorDomain for {name} {{
    fn domain() -> glib_ffi::GQuark {{
        {assert}unsafe {{ ffi::{get_quark}() }}
    }}

    fn code(self) -> i32 {{
        self.to_glib() as i32
    }}

    fn from(code: i32) -> Option<Self> {{
        {assert}match code {{", name = enum_.name, get_quark = get_quark, assert = assert));

        for member in &members {
            try!(version_condition(w, env, member.version, false, 3));
            try!(writeln!(w, "\t\t\tx if x == ffi::{} as i32 => Some({}::{}),", member.c_name,
                enum_.name, member.name));
        }
        if has_failed_member {
            try!(writeln!(w, "\t\t\t_ => Some({}::Failed),", enum_.name));
        } else {
            try!(writeln!(w, "\t\t\t_ => Some({}::__Nonexhaustive),", enum_.name));
        }

        try!(writeln!(w, "{}",
"        }
    }
}
"));
    }

    Ok(())
}
<commit_msg>Make cast generated enums to i32 non-scalar<commit_after>use analysis::namespaces;
use case::CaseExt;
use codegen::general::{self, version_condition, version_condition_string};
use config::gobjects::GObject;
use env::Env;
use file_saver;
use library::*;
use std::collections::HashSet;
use std::io::prelude::*;
use std::io::Result;
use std::path::Path;
use traits::*;
use version::Version;

pub fn generate(env: &Env, root_path: &Path, mod_rs: &mut Vec<String>) {
    let path = root_path.join("enums.rs");
    file_saver::save_to_file(path, env.config.make_backup, |w| {
        try!(general::start_comments(w, &env.config));
        try!(writeln!(w, "{}", "
use ffi;
use glib_ffi;
use glib::error::ErrorDomain;
use glib::translate::*;
"));

        let configs = env.config.objects.values()
            .filter(|c| {
                c.status.need_generate() &&
                    c.type_id.map_or(false, |tid| tid.ns_id == namespaces::MAIN)
            });
        let mut first = true;
        for config in configs {
            if let Type::Enumeration(ref enum_) = *env.library.type_(config.type_id.unwrap()) {
                if first {
                    mod_rs.push("\nmod enums;".into());
                    first = false;
                }
                if let Some (cfg) = version_condition_string(env, enum_.version, false, 0) {
                    mod_rs.push(cfg);
                }
                mod_rs.push(format!("pub use self::enums::{};", enum_.name));
                try!(generate_enum(env, w, enum_, config));
            }
        }

        Ok(())
    });
}

fn generate_enum(env: &Env, w: &mut Write, enum_: &Enumeration, config: &GObject) -> Result<()> {
    struct Member {
        name: String,
        c_name: String,
        version: Option<Version>,
    }

    let mut members: Vec<Member> = Vec::new();
    let mut vals: HashSet<String> = HashSet::new();

    for member in &enum_.members {
        let member_config = config.members.matched(&member.name);
        let is_alias = member_config.iter().any(|m| m.alias);
        if is_alias || vals.contains(&member.value) {
            continue
        }
        vals.insert(member.value.clone());
        let version = member_config.iter().filter_map(|m| m.version).next();
        members.push(Member {
            name: member.name.to_camel(),
            c_name: member.c_identifier.clone(),
            version: version,
        });
    }

    try!(version_condition(w, env, enum_.version, false, 0));
    try!(writeln!(w, "#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]"));
    try!(writeln!(w, "pub enum {} {{", enum_.name));
    for member in &members {
        try!(writeln!(w, "\t{},", member.name));
    }
    try!(writeln!(w, "{}", "    #[doc(hidden)]
    __Nonexhaustive(()),
}
"));

    try!(version_condition(w, env, enum_.version, false, 0));
    try!(writeln!(w, "#[doc(hidden)]
impl ToGlib for {name} {{
    type GlibType = ffi::{ffi_name};

    fn to_glib(&self) -> ffi::{ffi_name} {{
        match *self {{", name = enum_.name, ffi_name = enum_.c_type));
    for member in &members {
        try!(version_condition(w, env, member.version, false, 3));
        try!(writeln!(w, "\t\t\t{}::{} => ffi::{},", enum_.name, member.name, member.c_name));
    }
    try!(writeln!(w, "\t\t\t{}::__Nonexhaustive(_) => panic!(),", enum_.name));
    try!(writeln!(w, "{}",
"        }
    }
}
"));

    let assert = if env.config.generate_safety_asserts {
        "skip_assert_initialized!();\n\t\t"
    } else {
        ""
    };

    try!(version_condition(w, env, enum_.version, false, 0));
    try!(writeln!(w, "#[doc(hidden)]
impl FromGlib<ffi::{ffi_name}> for {name} {{
    fn from_glib(value: ffi::{ffi_name}) -> Self {{
        {assert}match value {{", name = enum_.name, ffi_name = enum_.c_type, assert = assert));
    for member in &members {
        try!(version_condition(w, env, member.version, false, 3));
        try!(writeln!(w, "\t\t\tffi::{} => {}::{},", member.c_name, enum_.name, member.name));
    }
    if members.len() == 1 {
        try!(writeln!(w, "\t\t\t_ => {}::__Nonexhaustive(()),", enum_.name));
    }
    try!(writeln!(w, "{}",
"        }
    }
}
"));

    if let Some(ref get_quark) = enum_.error_domain {
        let get_quark = get_quark.replace("-", "_");
        let has_failed_member = members.iter().any(|m| m.name == "Failed");

        try!(version_condition(w, env, enum_.version, false, 0));
        try!(writeln!(w, "impl ErrorDomain for {name} {{
    fn domain() -> glib_ffi::GQuark {{
        {assert}unsafe {{ ffi::{get_quark}() }}
    }}

    fn code(self) -> i32 {{
        self.to_glib() as i32
    }}

    fn from(code: i32) -> Option<Self> {{
        {assert}match code {{", name = enum_.name, get_quark = get_quark, assert = assert));

        for member in &members {
            try!(version_condition(w, env, member.version, false, 3));
            try!(writeln!(w, "\t\t\tx if x == ffi::{} as i32 => Some({}::{}),", member.c_name,
                enum_.name, member.name));
        }
        if has_failed_member {
            try!(writeln!(w, "\t\t\t_ => Some({}::Failed),", enum_.name));
        } else {
            try!(writeln!(w, "\t\t\t_ => Some({}::__Nonexhaustive(())),", enum_.name));
        }

        try!(writeln!(w, "{}",
"        }
    }
}
"));
    }

    Ok(())
}
<|endoftext|>


<commit_before>use num::kinds::Number;

pub trait Channel: Number {
    static pure fn max() -> self;

    static pure fn from<T:Channel>(val: T) -> self;
    pure fn convert_channel<T:Channel>(&self) -> T;

    pure fn to_channel_u8(&self)    -> u8;
    pure fn to_channel_u16(&self)   -> u16;
    pure fn to_channel_u32(&self)   -> u32;
    pure fn to_channel_u64(&self)   -> u64;
    pure fn to_channel_f32(&self)   -> f32;
    pure fn to_channel_f64(&self)   -> f64;
    pure fn to_channel_float(&self) -> float;

    pure fn inverse(&self) -> self;
}

pub impl u8: Channel {
    #[inline(always)] static pure fn max() -> u8 { 0xFF }  // 2^8

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> u8 { val.to_channel_u8() }
    #[inline(always)] pure fn convert_channel<T:Channel>(&self) -> T { Channel::from(*self) }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self) }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self as u16 << 8) | (*self) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { (self.to_channel_u16() as u32 << 16) | self.to_channel_u16() as u32 }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { (self.to_channel_u32() as u64 << 32) | self.to_channel_u32() as u64 }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self as f32)   / (0xFF as f32)   }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self as f64)   / (0xFF as f64)   }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self as float) / (0xFF as float) }

    #[inline(always)] pure fn inverse(&self) -> u8 { !(*self) }
}

pub impl u16: Channel {
    #[inline(always)] static pure fn max() -> u16 { 0xFFFF }   // 2^16

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> u16 { val.to_channel_u16() }
    #[inline(always)] pure fn convert_channel<T:Channel>(&self) -> T { Channel::from(*self) }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self >> 8) as u8 }    // this is the equivalent of `self/256`. Some folks prefer to do `self/257`
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self) }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { (*self as u32 << 16) | (*self) as u32 }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { (self.to_channel_u32() as u64 << 32) | self.to_channel_u32() as u64 }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) / 0xFFFF as f32   }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) / 0xFFFF as f64   }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) / 0xFFFF as float }

    #[inline(always)] pure fn inverse(&self) -> u16 { !(*self) }
}

pub impl u32: Channel {
    #[inline(always)] static pure fn max() -> u32 { 0xFFFF_FFFF }   // 2^32

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> u32 { val.to_channel_u32() }
    #[inline(always)] pure fn convert_channel<T:Channel>(&self) -> T { Channel::from(*self) }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self >> 24) as u8 }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self >> 16) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { (*self) }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { (*self as u64 << 32) | (*self) as u64 }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) / 0xFFFF_FFFF as f32   }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) / 0xFFFF_FFFF as f64   }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) / 0xFFFF_FFFF as float }

    #[inline(always)] pure fn inverse(&self) -> u32 { !(*self) }
}

pub impl u64: Channel {
    #[inline(always)] static pure fn max() -> u64 { 0xFFFF_FFFF_FFFF_FFFF_u64 }   // 2^64

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> u64 { val.to_channel_u64() }
    #[inline(always)] pure fn convert_channel<T:Channel>(&self) -> T { Channel::from(*self) }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self >> 56) as u8 }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self >> 48) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { (*self >> 32) as u32 }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { (*self) }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) / 0xFFFF_FFFF_FFFF_FFFF_u64 as f32   }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) / 0xFFFF_FFFF_FFFF_FFFF_u64 as f64   }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) / 0xFFFF_FFFF_FFFF_FFFF_u64 as float }

    #[inline(always)] pure fn inverse(&self) -> u64 { !(*self) }
}

pub impl f32: Channel {
    #[inline(always)] static pure fn max() -> f32 { 1f32 }

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> f32 { val.to_channel_f32() }
    #[inline(always)] pure fn convert_channel<T:Channel>(&self) -> T { Channel::from(*self) }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self) * (0xFF_u8    as f32) as u8  }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self) * (0xFFFF_u16 as f32) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { fail(~"to_channel_u32 not yet implemented for f32") }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { fail(~"to_channel_u64 not yet implemented for f32") }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) as f64 }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) as float }

    #[inline(always)] pure fn inverse(&self) -> f32 { 1f32 - (*self) }
}

pub impl f64: Channel {
    #[inline(always)] static pure fn max() -> f64 { 1f64 }

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> f64 { val.to_channel_f64() }
    #[inline(always)] pure fn convert_channel<T:Channel>(&self) -> T { Channel::from(*self) }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self) * (0xFF_u8    as f64) as u8  }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self) * (0xFFFF_u16 as f64) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { fail(~"to_channel_u32 not yet implemented for f64") }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { fail(~"to_channel_u64 not yet implemented for f64") }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) as f32 }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) as float }

    #[inline(always)] pure fn inverse(&self) -> f64 { 1f64 - (*self) }
}

pub impl float: Channel {
    #[inline(always)] static pure fn max() -> float { 1f }

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> float { val.to_channel_float() }
    #[inline(always)] pure fn convert_channel<T:Channel>(&self) -> T { Channel::from(*self) }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self) * (0xFF_u8    as float) as u8  }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self) * (0xFFFF_u16 as float) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { fail(~"to_channel_u32 not yet implemented for float") }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { fail(~"to_channel_u64 not yet implemented for float") }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) as f32 }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) as f64 }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) }

    #[inline(always)] pure fn inverse(&self) -> float { 1f - (*self) }
}<commit_msg>Remove `convert_channel` method<commit_after>use num::kinds::Number;

pub trait Channel: Number {
    static pure fn max() -> self;

    static pure fn from<T:Channel>(val: T) -> self;

    pure fn to_channel_u8(&self)    -> u8;
    pure fn to_channel_u16(&self)   -> u16;
    pure fn to_channel_u32(&self)   -> u32;
    pure fn to_channel_u64(&self)   -> u64;
    pure fn to_channel_f32(&self)   -> f32;
    pure fn to_channel_f64(&self)   -> f64;
    pure fn to_channel_float(&self) -> float;

    pure fn inverse(&self) -> self;
}

pub impl u8: Channel {
    #[inline(always)] static pure fn max() -> u8 { 0xFF }  // 2^8

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> u8 { val.to_channel_u8() }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self) }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self as u16 << 8) | (*self) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { (self.to_channel_u16() as u32 << 16) | self.to_channel_u16() as u32 }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { (self.to_channel_u32() as u64 << 32) | self.to_channel_u32() as u64 }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self as f32)   / (0xFF as f32)   }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self as f64)   / (0xFF as f64)   }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self as float) / (0xFF as float) }

    #[inline(always)] pure fn inverse(&self) -> u8 { !(*self) }
}

pub impl u16: Channel {
    #[inline(always)] static pure fn max() -> u16 { 0xFFFF }   // 2^16

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> u16 { val.to_channel_u16() }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self >> 8) as u8 }    // this is the equivalent of `self/256`. Some folks prefer to do `self/257`
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self) }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { (*self as u32 << 16) | (*self) as u32 }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { (self.to_channel_u32() as u64 << 32) | self.to_channel_u32() as u64 }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) / 0xFFFF as f32   }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) / 0xFFFF as f64   }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) / 0xFFFF as float }

    #[inline(always)] pure fn inverse(&self) -> u16 { !(*self) }
}

pub impl u32: Channel {
    #[inline(always)] static pure fn max() -> u32 { 0xFFFF_FFFF }   // 2^32

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> u32 { val.to_channel_u32() }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self >> 24) as u8 }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self >> 16) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { (*self) }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { (*self as u64 << 32) | (*self) as u64 }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) / 0xFFFF_FFFF as f32   }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) / 0xFFFF_FFFF as f64   }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) / 0xFFFF_FFFF as float }

    #[inline(always)] pure fn inverse(&self) -> u32 { !(*self) }
}

pub impl u64: Channel {
    #[inline(always)] static pure fn max() -> u64 { 0xFFFF_FFFF_FFFF_FFFF_u64 }   // 2^64

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> u64 { val.to_channel_u64() }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self >> 56) as u8 }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self >> 48) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { (*self >> 32) as u32 }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { (*self) }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) / 0xFFFF_FFFF_FFFF_FFFF_u64 as f32   }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) / 0xFFFF_FFFF_FFFF_FFFF_u64 as f64   }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) / 0xFFFF_FFFF_FFFF_FFFF_u64 as float }

    #[inline(always)] pure fn inverse(&self) -> u64 { !(*self) }
}

pub impl f32: Channel {
    #[inline(always)] static pure fn max() -> f32 { 1f32 }

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> f32 { val.to_channel_f32() }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self) * (0xFF_u8    as f32) as u8  }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self) * (0xFFFF_u16 as f32) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { fail(~"to_channel_u32 not yet implemented for f32") }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { fail(~"to_channel_u64 not yet implemented for f32") }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) as f64 }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) as float }

    #[inline(always)] pure fn inverse(&self) -> f32 { 1f32 - (*self) }
}

pub impl f64: Channel {
    #[inline(always)] static pure fn max() -> f64 { 1f64 }

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> f64 { val.to_channel_f64() }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self) * (0xFF_u8    as f64) as u8  }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self) * (0xFFFF_u16 as f64) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { fail(~"to_channel_u32 not yet implemented for f64") }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { fail(~"to_channel_u64 not yet implemented for f64") }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) as f32 }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) as float }

    #[inline(always)] pure fn inverse(&self) -> f64 { 1f64 - (*self) }
}

pub impl float: Channel {
    #[inline(always)] static pure fn max() -> float { 1f }

    #[inline(always)] static pure fn from<T:Channel>(val: T) -> float { val.to_channel_float() }

    #[inline(always)] pure fn to_channel_u8(&self)    -> u8    { (*self) * (0xFF_u8    as float) as u8  }
    #[inline(always)] pure fn to_channel_u16(&self)   -> u16   { (*self) * (0xFFFF_u16 as float) as u16 }
    #[inline(always)] pure fn to_channel_u32(&self)   -> u32   { fail(~"to_channel_u32 not yet implemented for float") }
    #[inline(always)] pure fn to_channel_u64(&self)   -> u64   { fail(~"to_channel_u64 not yet implemented for float") }
    #[inline(always)] pure fn to_channel_f32(&self)   -> f32   { (*self) as f32 }
    #[inline(always)] pure fn to_channel_f64(&self)   -> f64   { (*self) as f64 }
    #[inline(always)] pure fn to_channel_float(&self) -> float { (*self) }

    #[inline(always)] pure fn inverse(&self) -> float { 1f - (*self) }
}<|endoftext|>


<commit_before>// Txtrevise
// Command line text editing tool
// Version 1.0.0 (equivalent to Python impl. 1.1)
// Copyright (c) 2015 Sam Saint-Pettersen
// Released under the MIT License.

extern crate regex;
use std::env;
use std::io::{BufRead, BufReader, Write};
use std::fs::File;
use regex::Regex;

// Display error and then usage information.
fn display_error(err: &str) {
    println!("Error: {}.", err);
    display_usage();
}

/// Display usage information.
fn display_usage() {
    println!("\nTxtrevise v 1.0.0 (rust)");
    println!("Command line text editing tool");
    println!("Copyright (c) 2015 Sam Saint-Pettersen");
    println!("\nReleased under the MIT License");
    println!("Usage: txtrevise.py [-h] (-q) -f <file> -l <line #> -m <word(s)>");
    println!("-r <word(s)>");
    println!("\n-f: File to edit");
    println!("-l: Line number to edit text on (starts at 1)");
    println!("-m: Word(s) to match");
    println!("-r: Replacement word(s) for matched word(s)");
    println!("-q: Quiet mode. Only output to console for errors");
    println!("-h: This help information");
}

/// Process file.
fn process_file(filename: &str, line_no: usize, matches: &str, repl: &str, verbose: bool) {
    let mut line_num: usize = 0;
    let mut index: usize = 0;
    let mut all_lines: Vec<String> = Vec::new();

    // Read each line in file sequentially, store selected line no.
    let f = File::open(filename).unwrap();
    let file = BufReader::new(&f);
    for line in file.lines() {
        all_lines.push(line.unwrap());
        if line_num == line_no - 1 { // - 1, because lines start at 0.
            index = line_num;
        }
        line_num += 1;
    }
    all_lines[index] = match_replace(&all_lines[index], line_no, matches, repl, verbose);
    all_lines.push(String::new());

    let mut w = File::create(filename).unwrap();
    let _ = w.write_all(all_lines.join("\n").as_bytes());
}

/// Match and replace word(s).
fn match_replace(line: &str, line_no: usize, matches: &str, repl: &str, verbose: bool) -> String {
    let new_line: String;
    let re = Regex::new(matches).unwrap();

    // If word(s) are matched, return edited line with replacment word(s).
    if re.is_match(line) {
        if verbose {
            println!("\nMatched at Line {}: {}", line_no, line);
        }
        new_line = re.replace_all(line, repl);
        if verbose {
            println!("Replaced with: {}", new_line);
        }
    }
    // Otherwise, return same line as before
    else {
        if verbose {
            println!("\nNo matches at Line {}", line_no);
        }
        new_line = line.to_string();
    }
    new_line
}

/// Entry method.
fn main() {
    let args: Vec<_> = env::args().collect();
    let mut i: usize = 0;
    let mut filename = String::new();
    let mut matches = String::new();
    let mut repl = String::new();
    let mut verbose: bool = true;
    let mut line_no: usize = 1;
    if args.len() > 1 {
        for a in args {
            if a == "-h" {
                display_usage();
            }
            if a == "-f" {
                filename = format!("{:?}", env::args().nth(i + 1));
                filename = filename[6..filename.len() - 2].to_string();
            }
            if a == "-l" {
                let mut l = format!("{:?}", env::args().nth(i + 1));
                l = l[6..l.len() - 2].to_string();
                let ol = l.parse::<usize>().ok();
                line_no = match ol {
                    Some(line_no) => line_no,
                    None => {
                        display_error("Line number must be an integer");
                        return;
                    }
                };
                if line_no == 0 {
                    display_error("Line number must be greater than 0");
                    return;
                }
            }
            if a == "-m" {
                matches = format!("{:?}", env::args().nth(i + 1));
                matches = matches[6..matches.len() - 2].to_string();
            }
            if a == "-r" {
                repl = format!("{:?}", env::args().nth(i + 1));
                repl = repl[6..repl.len() - 2].to_string();
            }
            if a == "-q" {
                verbose = false;
            }
            i = i + 1;
        }
    }
    else {
        display_error("No options specified");
    }

    // With necessary arguments, process file.
    if env::args().len() > 2 && filename.len() > 0 {
        process_file(&filename, line_no, &matches, &repl, verbose);
    }
}
<commit_msg>tidied up.<commit_after>/*
    Txtrevise (rust)
    Command line text editing tool
    Version 1.0.0 (equivalent to Python impl. 1.1)
    Copyright (c) 2015 Sam Saint-Pettersen
    Released under the MIT License.
*/

extern crate regex;
use std::env;
use std::io::{BufRead, BufReader, Write};
use std::fs::File;
use regex::Regex;

// Display error and then usage information.
fn display_error(err: &str) {
    println!("Error: {}.", err);
    display_usage();
}

/// Display usage information.
fn display_usage() {
    println!("\nTxtrevise v 1.0.0 (rust)");
    println!("Command line text editing tool");
    println!("Copyright (c) 2015 Sam Saint-Pettersen");
    println!("\nReleased under the MIT License");
    println!("Usage: txtrevise.py [-h] (-q) -f <file> -l <line #> -m <word(s)>");
    println!("-r <word(s)>");
    println!("\n-f: File to edit");
    println!("-l: Line number to edit text on (starts at 1)");
    println!("-m: Word(s) to match");
    println!("-r: Replacement word(s) for matched word(s)");
    println!("-q: Quiet mode. Only output to console for errors");
    println!("-h: This help information");
}

/// Process file.
fn process_file(filename: &str, line_no: usize, matches: &str, repl: &str, verbose: bool) {
    let mut line_num: usize = 0;
    let mut index: usize = 0;
    let mut all_lines: Vec<String> = Vec::new();

    // Read each line in file sequentially, store selected line no.
    let f = File::open(filename).unwrap();
    let file = BufReader::new(&f);
    for line in file.lines() {
        all_lines.push(line.unwrap());
        if line_num == line_no - 1 { // - 1, because lines start at 0.
            index = line_num;
        }
        line_num += 1;
    }

    // Revise the selected line and append newline.
    all_lines[index] = match_replace(&all_lines[index], line_no, matches, repl, verbose);
    all_lines.push(String::new());

    // Write out changed lines to file.
    let mut w = File::create(filename).unwrap();
    let _ = w.write_all(all_lines.join("\n").as_bytes());
}

/// Match and replace word(s).
fn match_replace(line: &str, line_no: usize, matches: &str, repl: &str, verbose: bool) -> String {
    let new_line: String;
    let re = Regex::new(matches).unwrap();

    // If word(s) are matched, return edited line with replacment word(s).
    if re.is_match(line) {
        if verbose {
            println!("\nMatched at Line {}: {}", line_no, line);
        }
        new_line = re.replace_all(line, repl);
        if verbose {
            println!("Replaced with: {}", new_line);
        }
    }
    // Otherwise, return same line as before.
    else {
        if verbose {
            println!("\nNo matches at Line {}", line_no);
        }
        new_line = line.to_string();
    }
    new_line
}

/// Get next argument.
fn next_argument(ref i: usize) -> String {
    let a = env::args().nth(i + 1);
    let arg = match a {
        Some(a) => a,
        None => {
            display_error("Invalid argument");
            return String::new();
        }
    };
    arg
}

/// Entry method.
fn main() {
    let args: Vec<_> = env::args().collect();
    let mut i: usize = 0;
    let mut filename = String::new();
    let mut matches = String::new();
    let mut repl = String::new();
    let mut verbose: bool = true;
    let mut line_no: usize = 1;
    if args.len() > 1 {
        for a in args {
            if a == "-h" {
                display_usage();
            }
            if a == "-f" {
                filename = next_argument(i);
            }
            if a == "-l" {
                let l = next_argument(i);
                let ol = l.parse::<usize>().ok();
                line_no = match ol {
                    Some(line_no) => line_no,
                    None => {
                        display_error("Line number must be an integer");
                        return;
                    }
                };
                if line_no == 0 {
                    display_error("Line number must be greater than 0");
                    return;
                }
            }
            if a == "-m" {
                matches = next_argument(i);
            }
            if a == "-r" {
                repl = next_argument(i);
            }
            if a == "-q" {
                verbose = false;
            }
            i = i + 1;
        }
    }
    else {
        display_error("No options specified");
    }

    // With necessary arguments, process file.
    if env::args().len() > 2 && filename.len() > 0 {
        process_file(&filename, line_no, &matches, &repl, verbose);
    }
}
<|endoftext|>


<commit_before>use super::{DataStore, DataStoreError};
use std::collections::HashMap;

pub type HashMapStore = HashMap<String,String>;

/// Implement the DataStore methods for HashMap
impl DataStore for HashMapStore {

    fn store(&mut self, key: &str, value: &str) -> Result<(), DataStoreError> {
        self.insert(key.into(), value.into());
        Ok(())
    }

    fn retrieve(&self, key: &str) -> Result<String, DataStoreError> {
        self.get(key).map(|v| v.clone()).ok_or(DataStoreError::HashMapError)
    }

    fn delete(&mut self, key: &str) -> Result<(), DataStoreError> {
        self.remove(key);
        Ok(())
    }

}

<commit_msg>server: Add unit tests for HashMapStore<commit_after>use super::{DataStore, DataStoreError};
use std::collections::HashMap;

pub type HashMapStore = HashMap<String,String>;

/// Implement the DataStore methods for HashMap
impl DataStore for HashMapStore {

    fn store(&mut self, key: &str, value: &str) -> Result<(), DataStoreError> {
        self.insert(key.into(), value.into());
        Ok(())
    }

    fn retrieve(&self, key: &str) -> Result<String, DataStoreError> {
        self.get(key).map(|v| v.clone()).ok_or(DataStoreError::HashMapError)
    }

    fn delete(&mut self, key: &str) -> Result<(), DataStoreError> {
        self.remove(key);
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use datastore::DataStore;
    use super::*;

    #[test]
    fn roundtrip() {
        let mut store = HashMapStore::new();
        store.store("key", "value");
        let result = store.retrieve("key").unwrap();
        assert_eq!(result, "value");
        store.delete("key");
    }

    #[test]
    #[should_panic()]
    fn nonexistant() {
        let store = HashMapStore::new();
        store.retrieve("nonexistant").unwrap();
    }

}
<|endoftext|>


<commit_before>use std::os;
use std::io;
use std::io::fs::File;
use std::path::Path;

fn copy_to_stdout(f: &mut std::io::Reader) {
    let mut buf = [0u8, ..1024];
    let mut out = io::stdout();
    while !f.eof() {
        let len = f.read(buf);
        if len.is_some() {
            out.write(buf.slice(0, len.unwrap()))
        } else {
            break;
        }
    }
}

fn main() {
    match os::args() {
        [_] => {
            match io::result(|| {
                copy_to_stdout(& mut io::stdin() as &mut Reader);
            }) {
                Err(e) => {
                    if e.kind != io::EndOfFile {
                        io::stderr().write_line(format!("cat: stdin: {:s}", e.desc));
                    }
                }
                _ => {}
            }
        }
        [_, ..filenames] => {
            for fname in filenames.iter() {
                match io::result(|| {
                    let mut f = File::open(&Path::new(fname.as_slice()));
                    if f.is_none() {
                        return;
                    }
                    copy_to_stdout(f.get_mut_ref());
                }) {
                    Err(e) => {
                        io::stderr().write_line(format!("cat: {:s}: {:s}", *fname, e.desc));
                    }
                    _ => {}
                }
            }
        }
        _ => unreachable!()
    }
}
<commit_msg>Remove unneeded space<commit_after>use std::os;
use std::io;
use std::io::fs::File;
use std::path::Path;

fn copy_to_stdout(f: &mut std::io::Reader) {
    let mut buf = [0u8, ..1024];
    let mut out = io::stdout();
    while !f.eof() {
        let len = f.read(buf);
        if len.is_some() {
            out.write(buf.slice(0, len.unwrap()))
        } else {
            break;
        }
    }
}

fn main() {
    match os::args() {
        [_] => {
            match io::result(|| {
                copy_to_stdout(&mut io::stdin() as &mut Reader);
            }) {
                Err(e) => {
                    if e.kind != io::EndOfFile {
                        io::stderr().write_line(format!("cat: stdin: {:s}", e.desc));
                    }
                }
                _ => {}
            }
        }
        [_, ..filenames] => {
            for fname in filenames.iter() {
                match io::result(|| {
                    let mut f = File::open(&Path::new(fname.as_slice()));
                    if f.is_none() {
                        return;
                    }
                    copy_to_stdout(f.get_mut_ref());
                }) {
                    Err(e) => {
                        io::stderr().write_line(format!("cat: {:s}: {:s}", *fname, e.desc));
                    }
                    _ => {}
                }
            }
        }
        _ => unreachable!()
    }
}
<|endoftext|>