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

#![allow(non_camel_case_types)]

use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::ffi::CString;
use std::fmt::Debug;
use std::hash::{Hash, BuildHasher};
use std::iter::repeat;
use std::path::Path;
use std::time::{Duration, Instant};

// The name of the associated type for `Fn` return types
pub const FN_OUTPUT_NAME: &'static str = "Output";

// Useful type to use with `Result<>` indicate that an error has already
// been reported to the user, so no need to continue checking.
#[derive(Clone, Copy, Debug)]
pub struct ErrorReported;

thread_local!(static TIME_DEPTH: Cell<usize> = Cell::new(0));

/// Read the current depth of `time()` calls. This is used to
/// encourage indentation across threads.
pub fn time_depth() -> usize {
    TIME_DEPTH.with(|slot| slot.get())
}

/// Set the current depth of `time()` calls. The idea is to call
/// `set_time_depth()` with the result from `time_depth()` in the
/// parent thread.
pub fn set_time_depth(depth: usize) {
    TIME_DEPTH.with(|slot| slot.set(depth));
}

pub fn time<T, F>(do_it: bool, what: &str, f: F) -> T where
    F: FnOnce() -> T,
{
    if !do_it { return f(); }

    let old = TIME_DEPTH.with(|slot| {
        let r = slot.get();
        slot.set(r + 1);
        r
    });

    let start = Instant::now();
    let rv = f();
    let dur = start.elapsed();

    let mem_string = match get_resident() {
        Some(n) => {
            let mb = n as f64 / 1_000_000.0;
            format!("; rss: {}MB", mb.round() as usize)
        }
        None => "".to_owned(),
    };
    println!("{}time: {}{}\t{}",
             repeat("  ").take(old).collect::<String>(),
             duration_to_secs_str(dur),
             mem_string,
             what);

    TIME_DEPTH.with(|slot| slot.set(old));

    rv
}

// Hack up our own formatting for the duration to make it easier for scripts
// to parse (always use the same number of decimal places and the same unit).
pub fn duration_to_secs_str(dur: Duration) -> String {
    const NANOS_PER_SEC: f64 = 1_000_000_000.0;
    let secs = dur.as_secs() as f64 +
               dur.subsec_nanos() as f64 / NANOS_PER_SEC;

    format!("{:.3}", secs)
}

pub fn to_readable_str(mut val: usize) -> String {
    let mut groups = vec![];
    loop {
        let group = val % 1000;

        val /= 1000;

        if val == 0 {
            groups.push(format!("{}", group));
            break;
        } else {
            groups.push(format!("{:03}", group));
        }
    }

    groups.reverse();

    groups.join("_")
}

pub fn record_time<T, F>(accu: &Cell<Duration>, f: F) -> T where
    F: FnOnce() -> T,
{
    let start = Instant::now();
    let rv = f();
    let duration = start.elapsed();
    accu.set(duration + accu.get());
    rv
}

// Like std::macros::try!, but for Option<>.
macro_rules! option_try(
    ($e:expr) => (match $e { Some(e) => e, None => return None })
);

// Memory reporting
#[cfg(unix)]
fn get_resident() -> Option<usize> {
    use std::fs::File;
    use std::io::Read;

    let field = 1;
    let mut f = option_try!(File::open("/proc/self/statm").ok());
    let mut contents = String::new();
    option_try!(f.read_to_string(&mut contents).ok());
    let s = option_try!(contents.split_whitespace().nth(field));
    let npages = option_try!(s.parse::<usize>().ok());
    Some(npages * 4096)
}

#[cfg(windows)]
fn get_resident() -> Option<usize> {
    type BOOL = i32;
    type DWORD = u32;
    type HANDLE = *mut u8;
    use libc::size_t;
    use std::mem;
    #[repr(C)]
    #[allow(non_snake_case)]
    struct PROCESS_MEMORY_COUNTERS {
        cb: DWORD,
        PageFaultCount: DWORD,
        PeakWorkingSetSize: size_t,
        WorkingSetSize: size_t,
        QuotaPeakPagedPoolUsage: size_t,
        QuotaPagedPoolUsage: size_t,
        QuotaPeakNonPagedPoolUsage: size_t,
        QuotaNonPagedPoolUsage: size_t,
        PagefileUsage: size_t,
        PeakPagefileUsage: size_t,
    }
    type PPROCESS_MEMORY_COUNTERS = *mut PROCESS_MEMORY_COUNTERS;
    #[link(name = "psapi")]
    extern "system" {
        fn GetCurrentProcess() -> HANDLE;
        fn GetProcessMemoryInfo(Process: HANDLE,
                                ppsmemCounters: PPROCESS_MEMORY_COUNTERS,
                                cb: DWORD) -> BOOL;
    }
    let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { mem::zeroed() };
    pmc.cb = mem::size_of_val(&pmc) as DWORD;
    match unsafe { GetProcessMemoryInfo(GetCurrentProcess(), &mut pmc, pmc.cb) } {
        0 => None,
        _ => Some(pmc.WorkingSetSize as usize),
    }
}

pub fn indent<R, F>(op: F) -> R where
    R: Debug,
    F: FnOnce() -> R,
{
    // Use in conjunction with the log post-processor like `src/etc/indenter`
    // to make debug output more readable.
    debug!(">>");
    let r = op();
    debug!("<< (Result = {:?})", r);
    r
}

pub struct Indenter {
    _cannot_construct_outside_of_this_module: (),
}

impl Drop for Indenter {
    fn drop(&mut self) { debug!("<<"); }
}

pub fn indenter() -> Indenter {
    debug!(">>");
    Indenter { _cannot_construct_outside_of_this_module: () }
}

pub trait MemoizationMap {
    type Key: Clone;
    type Value: Clone;

    /// If `key` is present in the map, return the valuee,
    /// otherwise invoke `op` and store the value in the map.
    ///
    /// NB: if the receiver is a `DepTrackingMap`, special care is
    /// needed in the `op` to ensure that the correct edges are
    /// added into the dep graph. See the `DepTrackingMap` impl for
    /// more details!
    fn memoize<OP>(&self, key: Self::Key, op: OP) -> Self::Value
        where OP: FnOnce() -> Self::Value;
}

impl<K, V, S> MemoizationMap for RefCell<HashMap<K,V,S>>
    where K: Hash+Eq+Clone, V: Clone, S: BuildHasher
{
    type Key = K;
    type Value = V;

    fn memoize<OP>(&self, key: K, op: OP) -> V
        where OP: FnOnce() -> V
    {
        let result = self.borrow().get(&key).cloned();
        match result {
            Some(result) => result,
            None => {
                let result = op();
                self.borrow_mut().insert(key, result.clone());
                result
            }
        }
    }
}

#[cfg(unix)]
pub fn path2cstr(p: &Path) -> CString {
    use std::os::unix::prelude::*;
    use std::ffi::OsStr;
    let p: &OsStr = p.as_ref();
    CString::new(p.as_bytes()).unwrap()
}
#[cfg(windows)]
pub fn path2cstr(p: &Path) -> CString {
    CString::new(p.to_str().unwrap()).unwrap()
}

#[test]
fn test_to_readable_str() {
    assert_eq!("0", to_readable_str(0));
    assert_eq!("1", to_readable_str(1));
    assert_eq!("99", to_readable_str(99));
    assert_eq!("999", to_readable_str(999));
    assert_eq!("1_000", to_readable_str(1_000));
    assert_eq!("1_001", to_readable_str(1_001));
    assert_eq!("999_999", to_readable_str(999_999));
    assert_eq!("1_000_000", to_readable_str(1_000_000));
    assert_eq!("1_234_567", to_readable_str(1_234_567));
}
<commit_msg>put option_try macro def under #[cfg(unix)]<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_camel_case_types)]

use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::ffi::CString;
use std::fmt::Debug;
use std::hash::{Hash, BuildHasher};
use std::iter::repeat;
use std::path::Path;
use std::time::{Duration, Instant};

// The name of the associated type for `Fn` return types
pub const FN_OUTPUT_NAME: &'static str = "Output";

// Useful type to use with `Result<>` indicate that an error has already
// been reported to the user, so no need to continue checking.
#[derive(Clone, Copy, Debug)]
pub struct ErrorReported;

thread_local!(static TIME_DEPTH: Cell<usize> = Cell::new(0));

/// Read the current depth of `time()` calls. This is used to
/// encourage indentation across threads.
pub fn time_depth() -> usize {
    TIME_DEPTH.with(|slot| slot.get())
}

/// Set the current depth of `time()` calls. The idea is to call
/// `set_time_depth()` with the result from `time_depth()` in the
/// parent thread.
pub fn set_time_depth(depth: usize) {
    TIME_DEPTH.with(|slot| slot.set(depth));
}

pub fn time<T, F>(do_it: bool, what: &str, f: F) -> T where
    F: FnOnce() -> T,
{
    if !do_it { return f(); }

    let old = TIME_DEPTH.with(|slot| {
        let r = slot.get();
        slot.set(r + 1);
        r
    });

    let start = Instant::now();
    let rv = f();
    let dur = start.elapsed();

    let mem_string = match get_resident() {
        Some(n) => {
            let mb = n as f64 / 1_000_000.0;
            format!("; rss: {}MB", mb.round() as usize)
        }
        None => "".to_owned(),
    };
    println!("{}time: {}{}\t{}",
             repeat("  ").take(old).collect::<String>(),
             duration_to_secs_str(dur),
             mem_string,
             what);

    TIME_DEPTH.with(|slot| slot.set(old));

    rv
}

// Hack up our own formatting for the duration to make it easier for scripts
// to parse (always use the same number of decimal places and the same unit).
pub fn duration_to_secs_str(dur: Duration) -> String {
    const NANOS_PER_SEC: f64 = 1_000_000_000.0;
    let secs = dur.as_secs() as f64 +
               dur.subsec_nanos() as f64 / NANOS_PER_SEC;

    format!("{:.3}", secs)
}

pub fn to_readable_str(mut val: usize) -> String {
    let mut groups = vec![];
    loop {
        let group = val % 1000;

        val /= 1000;

        if val == 0 {
            groups.push(format!("{}", group));
            break;
        } else {
            groups.push(format!("{:03}", group));
        }
    }

    groups.reverse();

    groups.join("_")
}

pub fn record_time<T, F>(accu: &Cell<Duration>, f: F) -> T where
    F: FnOnce() -> T,
{
    let start = Instant::now();
    let rv = f();
    let duration = start.elapsed();
    accu.set(duration + accu.get());
    rv
}

// Like std::macros::try!, but for Option<>.
#[cfg(unix)]
macro_rules! option_try(
    ($e:expr) => (match $e { Some(e) => e, None => return None })
);

// Memory reporting
#[cfg(unix)]
fn get_resident() -> Option<usize> {
    use std::fs::File;
    use std::io::Read;

    let field = 1;
    let mut f = option_try!(File::open("/proc/self/statm").ok());
    let mut contents = String::new();
    option_try!(f.read_to_string(&mut contents).ok());
    let s = option_try!(contents.split_whitespace().nth(field));
    let npages = option_try!(s.parse::<usize>().ok());
    Some(npages * 4096)
}

#[cfg(windows)]
fn get_resident() -> Option<usize> {
    type BOOL = i32;
    type DWORD = u32;
    type HANDLE = *mut u8;
    use libc::size_t;
    use std::mem;
    #[repr(C)]
    #[allow(non_snake_case)]
    struct PROCESS_MEMORY_COUNTERS {
        cb: DWORD,
        PageFaultCount: DWORD,
        PeakWorkingSetSize: size_t,
        WorkingSetSize: size_t,
        QuotaPeakPagedPoolUsage: size_t,
        QuotaPagedPoolUsage: size_t,
        QuotaPeakNonPagedPoolUsage: size_t,
        QuotaNonPagedPoolUsage: size_t,
        PagefileUsage: size_t,
        PeakPagefileUsage: size_t,
    }
    type PPROCESS_MEMORY_COUNTERS = *mut PROCESS_MEMORY_COUNTERS;
    #[link(name = "psapi")]
    extern "system" {
        fn GetCurrentProcess() -> HANDLE;
        fn GetProcessMemoryInfo(Process: HANDLE,
                                ppsmemCounters: PPROCESS_MEMORY_COUNTERS,
                                cb: DWORD) -> BOOL;
    }
    let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { mem::zeroed() };
    pmc.cb = mem::size_of_val(&pmc) as DWORD;
    match unsafe { GetProcessMemoryInfo(GetCurrentProcess(), &mut pmc, pmc.cb) } {
        0 => None,
        _ => Some(pmc.WorkingSetSize as usize),
    }
}

pub fn indent<R, F>(op: F) -> R where
    R: Debug,
    F: FnOnce() -> R,
{
    // Use in conjunction with the log post-processor like `src/etc/indenter`
    // to make debug output more readable.
    debug!(">>");
    let r = op();
    debug!("<< (Result = {:?})", r);
    r
}

pub struct Indenter {
    _cannot_construct_outside_of_this_module: (),
}

impl Drop for Indenter {
    fn drop(&mut self) { debug!("<<"); }
}

pub fn indenter() -> Indenter {
    debug!(">>");
    Indenter { _cannot_construct_outside_of_this_module: () }
}

pub trait MemoizationMap {
    type Key: Clone;
    type Value: Clone;

    /// If `key` is present in the map, return the valuee,
    /// otherwise invoke `op` and store the value in the map.
    ///
    /// NB: if the receiver is a `DepTrackingMap`, special care is
    /// needed in the `op` to ensure that the correct edges are
    /// added into the dep graph. See the `DepTrackingMap` impl for
    /// more details!
    fn memoize<OP>(&self, key: Self::Key, op: OP) -> Self::Value
        where OP: FnOnce() -> Self::Value;
}

impl<K, V, S> MemoizationMap for RefCell<HashMap<K,V,S>>
    where K: Hash+Eq+Clone, V: Clone, S: BuildHasher
{
    type Key = K;
    type Value = V;

    fn memoize<OP>(&self, key: K, op: OP) -> V
        where OP: FnOnce() -> V
    {
        let result = self.borrow().get(&key).cloned();
        match result {
            Some(result) => result,
            None => {
                let result = op();
                self.borrow_mut().insert(key, result.clone());
                result
            }
        }
    }
}

#[cfg(unix)]
pub fn path2cstr(p: &Path) -> CString {
    use std::os::unix::prelude::*;
    use std::ffi::OsStr;
    let p: &OsStr = p.as_ref();
    CString::new(p.as_bytes()).unwrap()
}
#[cfg(windows)]
pub fn path2cstr(p: &Path) -> CString {
    CString::new(p.to_str().unwrap()).unwrap()
}

#[test]
fn test_to_readable_str() {
    assert_eq!("0", to_readable_str(0));
    assert_eq!("1", to_readable_str(1));
    assert_eq!("99", to_readable_str(99));
    assert_eq!("999", to_readable_str(999));
    assert_eq!("1_000", to_readable_str(1_000));
    assert_eq!("1_001", to_readable_str(1_001));
    assert_eq!("999_999", to_readable_str(999_999));
    assert_eq!("1_000_000", to_readable_str(1_000_000));
    assert_eq!("1_234_567", to_readable_str(1_234_567));
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #36840 - eulerdisk:incr_test_for_hash_enum, r=michaelwoerister<commit_after><|endoftext|>


<commit_before><commit_msg>Remove outdated comment FIXME.<commit_after><|endoftext|>


<commit_before><commit_msg>Start sketching some traitorous code (xfail'd)<commit_after>//xfail-test

// Sketching traits.

// methods with no implementation are required; methods with an
// implementation are provided.  No "req" keyword necessary.
trait Eq {
    fn eq(a: self) -> bool;

    fn neq(a: self) -> bool {
        !self.neq(a)
    }
}

// The `<` is pronounced `extends`.  Also under consideration is `<:`.
// Just using `:` is frowned upon, because (paraphrasing dherman) `:`
// is supposed to separate things from different universes.
trait Ord < Eq {

    fn lt(a: self) -> bool;

    fn lte(a: self) -> bool {
        self.lt(a) || self.eq(a)
    }

    fn gt(a: self) -> bool {
        !self.lt(a) && !self.eq(a)
    }

    fn gte(a: self) -> bool {
        !self.lt(a)
    }
}

// pronounced "impl of Ord for int" -- not sold on this yet
impl int: Ord {
    fn lt(a: self) -> bool {
        self < a
    }

    // is this the place to put this?
    fn eq(a: self) -> bool {
        self == a
    }
}

<|endoftext|>


<commit_before><commit_msg>feat(filtering): insert filtering into hashmap<commit_after><|endoftext|>


<commit_before>//! Definition of the Shared combinator, a future that is cloneable,
//! and can be polled in multiple threads.
//!
//! # Examples
//!
//! ```
//! use futures::future::*;
//!
//! let future = ok::<_, bool>(6);
//! let shared1 = future.shared();
//! let shared2 = shared1.clone();
//! assert_eq!(6, *shared1.wait().unwrap());
//! assert_eq!(6, *shared2.wait().unwrap());
//! ```

use std::mem;
use std::vec::Vec;
use std::sync::{Arc, RwLock};
use std::sync::atomic::{AtomicBool, Ordering};
use std::ops::Deref;

use {Future, Poll, Async};
use task::{self, Task};
use lock::Lock;

/// A future that is cloneable and can be polled in multiple threads.
/// Use Future::shared() method to convert any future into a `Shared` future.
#[must_use = "futures do nothing unless polled"]
pub struct Shared<F>
    where F: Future
{
    inner: Arc<Inner<F>>,
}

struct Inner<F>
    where F: Future
{
    /// The original future.
    original_future: Lock<F>,
    /// Indicates whether the result is ready, and the state is `State::Done`.
    result_ready: AtomicBool,
    /// The state of the shared future.
    state: RwLock<State<F::Item, F::Error>>,
}

/// The state of the shared future. It can be one of the following:
/// 1. Done - contains the result of the original future.
/// 2. Waiting - contains the waiting tasks.
enum State<T, E> {
    Waiting(Vec<Task>),
    Done(Result<SharedItem<T>, SharedError<E>>),
}

impl<F> Shared<F>
    where F: Future
{
    /// Creates a new `Shared` from another future.
    pub fn new(future: F) -> Self {
        Shared {
            inner: Arc::new(Inner {
                original_future: Lock::new(future),
                result_ready: AtomicBool::new(false),
                state: RwLock::new(State::Waiting(vec![])),
            }),
        }
    }

    /// Converts a result as it's stored in `State::Done` into `Poll`.
    fn result_to_polled_result(result: Result<SharedItem<F::Item>, SharedError<F::Error>>)
                               -> Result<Async<SharedItem<F::Item>>, SharedError<F::Error>> {
        match result {
            Ok(item) => Ok(Async::Ready(item)),
            Err(error) => Err(error),
        }
    }

    /// Clones the result from self.inner.state.
    /// Assumes state is `State::Done`.
    fn read_result(&self) -> Result<Async<SharedItem<F::Item>>, SharedError<F::Error>> {
        match *self.inner.state.read().unwrap() {
            State::Done(ref result) => Self::result_to_polled_result(result.clone()),
            State::Waiting(_) => panic!("read_result() was called but State is not Done"),
        }
    }

    /// Stores the result in self.inner.state, unparks the waiting tasks,
    /// and returns the result.
    fn store_result(&self,
                    result: Result<SharedItem<F::Item>, SharedError<F::Error>>)
                    -> Result<Async<SharedItem<F::Item>>, SharedError<F::Error>> {
        let ref mut state = *self.inner.state.write().unwrap();

        match mem::replace(state, State::Done(result.clone())) {
            State::Waiting(waiters) => {
                self.inner.result_ready.store(true, Ordering::Relaxed);
                for task in waiters {
                    task.unpark();
                }
            }
            State::Done(_) => panic!("store_result() was called twice"),
        }

        Self::result_to_polled_result(result)
    }
}

impl<F> Future for Shared<F>
    where F: Future
{
    type Item = SharedItem<F::Item>;
    type Error = SharedError<F::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        // The logic is as follows:
        // 1. Check if the result is ready (with result_ready)
        //  - If the result is ready, return it.
        //  - Otherwise:
        // 2. Try lock the self.inner.original_future:
        //    - If successfully locked, check again if the result is ready.
        //      If it's ready, just return it.
        //      Otherwise, poll the original future.
        //      If the future is ready, unpark the waiting tasks from
        //      self.inner.state and return the result.
        //    - If the future is not ready, or if the lock failed:
        // 3. Lock the state for write.
        // 4. If the state is `State::Done`, return the result. Otherwise:
        // 5. Create a task, push it to the waiters vector, and return `Ok(Async::NotReady)`.

        // If the result is ready, just return it
        if self.inner.result_ready.load(Ordering::Relaxed) {
            return self.read_result();
        }

        // The result was not ready.
        // Try lock the original future.
        match self.inner.original_future.try_lock() {
            Some(mut original_future) => {
                // Other thread could already poll the result, so we check if result_ready.
                if self.inner.result_ready.load(Ordering::Relaxed) {
                    return self.read_result();
                }

                match original_future.poll() {
                    Ok(Async::Ready(item)) => {
                        return self.store_result(Ok(SharedItem::new(item)));
                    }
                    Err(error) => {
                        return self.store_result(Err(SharedError::new(error)));
                    }
                    Ok(Async::NotReady) => {} // A task will be parked
                }
            }
            None => {} // A task will be parked
        }

        let ref mut state = *self.inner.state.write().unwrap();
        match state {
            &mut State::Done(ref result) => return Self::result_to_polled_result(result.clone()),
            &mut State::Waiting(ref mut waiters) => {
                waiters.push(task::park());
            }
        }

        Ok(Async::NotReady)
    }
}

impl<F> Clone for Shared<F>
    where F: Future
{
    fn clone(&self) -> Self {
        Shared { inner: self.inner.clone() }
    }
}

/// A wrapped item of the original future.
/// It is clonable and implements Deref for ease of use.
#[derive(Debug)]
pub struct SharedItem<T> {
    item: Arc<T>,
}

impl<T> SharedItem<T> {
    fn new(item: T) -> Self {
        SharedItem { item: Arc::new(item) }
    }
}

impl<T> Clone for SharedItem<T> {
    fn clone(&self) -> Self {
        SharedItem { item: self.item.clone() }
    }
}

impl<T> Deref for SharedItem<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.item.as_ref()
    }
}

/// A wrapped error of the original future.
/// It is clonable and implements Deref for ease of use.
#[derive(Debug)]
pub struct SharedError<E> {
    error: Arc<E>,
}

impl<E> SharedError<E> {
    fn new(error: E) -> Self {
        SharedError { error: Arc::new(error) }
    }
}

impl<T> Clone for SharedError<T> {
    fn clone(&self) -> Self {
        SharedError { error: self.error.clone() }
    }
}

impl<E> Deref for SharedError<E> {
    type Target = E;

    fn deref(&self) -> &E {
        &self.error.as_ref()
    }
}
<commit_msg>Removed result_to_polled_result, use map() instead<commit_after>//! Definition of the Shared combinator, a future that is cloneable,
//! and can be polled in multiple threads.
//!
//! # Examples
//!
//! ```
//! use futures::future::*;
//!
//! let future = ok::<_, bool>(6);
//! let shared1 = future.shared();
//! let shared2 = shared1.clone();
//! assert_eq!(6, *shared1.wait().unwrap());
//! assert_eq!(6, *shared2.wait().unwrap());
//! ```

use std::mem;
use std::vec::Vec;
use std::sync::{Arc, RwLock};
use std::sync::atomic::{AtomicBool, Ordering};
use std::ops::Deref;

use {Future, Poll, Async};
use task::{self, Task};
use lock::Lock;

/// A future that is cloneable and can be polled in multiple threads.
/// Use Future::shared() method to convert any future into a `Shared` future.
#[must_use = "futures do nothing unless polled"]
pub struct Shared<F>
    where F: Future
{
    inner: Arc<Inner<F>>,
}

struct Inner<F>
    where F: Future
{
    /// The original future.
    original_future: Lock<F>,
    /// Indicates whether the result is ready, and the state is `State::Done`.
    result_ready: AtomicBool,
    /// The state of the shared future.
    state: RwLock<State<F::Item, F::Error>>,
}

/// The state of the shared future. It can be one of the following:
/// 1. Done - contains the result of the original future.
/// 2. Waiting - contains the waiting tasks.
enum State<T, E> {
    Waiting(Vec<Task>),
    Done(Result<SharedItem<T>, SharedError<E>>),
}

impl<F> Shared<F>
    where F: Future
{
    /// Creates a new `Shared` from another future.
    pub fn new(future: F) -> Self {
        Shared {
            inner: Arc::new(Inner {
                original_future: Lock::new(future),
                result_ready: AtomicBool::new(false),
                state: RwLock::new(State::Waiting(vec![])),
            }),
        }
    }

    /// Clones the result from self.inner.state.
    /// Assumes state is `State::Done`.
    fn read_result(&self) -> Result<Async<SharedItem<F::Item>>, SharedError<F::Error>> {
        match *self.inner.state.read().unwrap() {
            State::Done(ref result) => result.clone().map(Async::Ready),
            State::Waiting(_) => panic!("read_result() was called but State is not Done"),
        }
    }

    /// Stores the result in self.inner.state, unparks the waiting tasks,
    /// and returns the result.
    fn store_result(&self,
                    result: Result<SharedItem<F::Item>, SharedError<F::Error>>)
                    -> Result<Async<SharedItem<F::Item>>, SharedError<F::Error>> {
        let ref mut state = *self.inner.state.write().unwrap();

        match mem::replace(state, State::Done(result.clone())) {
            State::Waiting(waiters) => {
                self.inner.result_ready.store(true, Ordering::Relaxed);
                for task in waiters {
                    task.unpark();
                }
            }
            State::Done(_) => panic!("store_result() was called twice"),
        }

        result.clone().map(Async::Ready)
    }
}

impl<F> Future for Shared<F>
    where F: Future
{
    type Item = SharedItem<F::Item>;
    type Error = SharedError<F::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        // The logic is as follows:
        // 1. Check if the result is ready (with result_ready)
        //  - If the result is ready, return it.
        //  - Otherwise:
        // 2. Try lock the self.inner.original_future:
        //    - If successfully locked, check again if the result is ready.
        //      If it's ready, just return it.
        //      Otherwise, poll the original future.
        //      If the future is ready, unpark the waiting tasks from
        //      self.inner.state and return the result.
        //    - If the future is not ready, or if the lock failed:
        // 3. Lock the state for write.
        // 4. If the state is `State::Done`, return the result. Otherwise:
        // 5. Create a task, push it to the waiters vector, and return `Ok(Async::NotReady)`.

        // If the result is ready, just return it
        if self.inner.result_ready.load(Ordering::Relaxed) {
            return self.read_result();
        }

        // The result was not ready.
        // Try lock the original future.
        match self.inner.original_future.try_lock() {
            Some(mut original_future) => {
                // Other thread could already poll the result, so we check if result_ready.
                if self.inner.result_ready.load(Ordering::Relaxed) {
                    return self.read_result();
                }

                match original_future.poll() {
                    Ok(Async::Ready(item)) => {
                        return self.store_result(Ok(SharedItem::new(item)));
                    }
                    Err(error) => {
                        return self.store_result(Err(SharedError::new(error)));
                    }
                    Ok(Async::NotReady) => {} // A task will be parked
                }
            }
            None => {} // A task will be parked
        }

        let ref mut state = *self.inner.state.write().unwrap();
        match state {
            &mut State::Done(ref result) => return result.clone().map(Async::Ready),
            &mut State::Waiting(ref mut waiters) => {
                waiters.push(task::park());
            }
        }

        Ok(Async::NotReady)
    }
}

impl<F> Clone for Shared<F>
    where F: Future
{
    fn clone(&self) -> Self {
        Shared { inner: self.inner.clone() }
    }
}

/// A wrapped item of the original future.
/// It is clonable and implements Deref for ease of use.
#[derive(Debug)]
pub struct SharedItem<T> {
    item: Arc<T>,
}

impl<T> SharedItem<T> {
    fn new(item: T) -> Self {
        SharedItem { item: Arc::new(item) }
    }
}

impl<T> Clone for SharedItem<T> {
    fn clone(&self) -> Self {
        SharedItem { item: self.item.clone() }
    }
}

impl<T> Deref for SharedItem<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.item.as_ref()
    }
}

/// A wrapped error of the original future.
/// It is clonable and implements Deref for ease of use.
#[derive(Debug)]
pub struct SharedError<E> {
    error: Arc<E>,
}

impl<E> SharedError<E> {
    fn new(error: E) -> Self {
        SharedError { error: Arc::new(error) }
    }
}

impl<T> Clone for SharedError<T> {
    fn clone(&self) -> Self {
        SharedError { error: self.error.clone() }
    }
}

impl<E> Deref for SharedError<E> {
    type Target = E;

    fn deref(&self) -> &E {
        &self.error.as_ref()
    }
}
<|endoftext|>


<commit_before><commit_msg>add helpers - implement get_block_hash<commit_after>/*
 * Collection of helper functions used in the state transition modules
 */
use super::active_state::ActiveState;
use super::block::Block;
use super::chain_config::ChainConfig;
use super::utils::errors::ParameterError;
use super::utils::types::Hash256;

/*
   pub fn get_signed_parent_hashes(
   active_state: &ActiveState,
   block: &Block,
   attestation: &AttestationRecord,
   chain_config: &ChainConfig)
   -> Vec<Hash256> {
   }
   */

pub fn get_block_hash(
    active_state_recent_block_hashes: &Vec<Hash256>,
    current_block_slot: &u64,
    slot: &u64,
    cycle_length: &u64, // convert from standard u8
) -> Result<Hash256, ParameterError> {
    // active_state must have at 2*cycle_length hashes
    assert_error!(
        active_state_recent_block_hashes.len() as u64 == cycle_length * 2,
        ParameterError::InvalidInput(String::from(
            "active state has incorrect number of block hashes"
        ))
    );

    let state_start_slot = (*current_block_slot)
        .checked_sub(cycle_length * 2)
        .unwrap_or(0);

    assert_error!(
        (state_start_slot <= *slot) && (*slot < *current_block_slot),
        ParameterError::InvalidInput(String::from("incorrect slot number"))
    );

    let index = 2 * cycle_length + (*slot) - *current_block_slot; // should always be positive
    Ok(active_state_recent_block_hashes[index as usize])
}

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

    #[test]
    fn test_get_block_hash() {
        let block_slot: u64 = 10;
        let slot: u64 = 3;
        let cycle_length: u64 = 8;

        let mut block_hashes: Vec<Hash256> = Vec::new();
        for _i in 0..2 * cycle_length {
            block_hashes.push(Hash256::random());
        }

        let result = get_block_hash(&block_hashes, &block_slot, &slot, &cycle_length).unwrap();

        assert_eq!(
            result,
            block_hashes[(2 * cycle_length + slot - block_slot) as usize]
        );

        println!("{:?}", result);
    }
}
<|endoftext|>


<commit_before><commit_msg>fixed cargo build error<commit_after>pub fn estimate_price(mileage: u32, theta0: f32, theta1: f32) -> u32 {
    (theta0 + (theta1 * mileage as f32)) as u32
}
<|endoftext|>


<commit_before><commit_msg>moved row builder<commit_after>use std::collections::HashMap;
use super::value::Value;

pub struct RowBuilder {
    pub data: HashMap<String, Value>,
}

impl RowBuilder {
    pub fn new() -> RowBuilder {
        RowBuilder{data:HashMap::new()}
    }
    pub fn set_string(&mut self, key: &str, val: &str) -> &mut RowBuilder {
        self.data.insert(key.to_string(), Value::from(val));
        self
    }
    pub fn set_int(&mut self, key: &str, val: i64) -> &mut RowBuilder {
        self.data.insert(key.to_string(), Value::from(val));
        self
    }
}
<|endoftext|>


<commit_before><commit_msg>update page<commit_after>extern crate diesel;
extern crate dotenv;
extern crate kuchiki;
extern crate server;

use diesel::pg::PgConnection;
use diesel::prelude::*;
use dotenv::dotenv;
use kuchiki::traits::*;
use server::models::Ad;
use server::schema::ads::*;
use server::start_logging;
use std::env;

fn main() {
    dotenv().ok();
    start_logging();
    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    let conn = PgConnection::establish(&database_url).unwrap();
    let dbads: Vec<Ad> = ads.order(create_at.desc())
        .filter(page.is_null())
        .load::<Ad>(&*conn)
        .expect("Couldn't get ads.");
    for ad in dbads {
        let document = kuchiki::parse_html().one(ad.html.clone());

        let html_page = get_advertiser_link(&document).ok().and_then(|l| {
            l.attributes.borrow().get("href").map(|i| i.to_string())
        });
        if html_page.is_ok() {
            diesel::update(ads.find(ad.id))
                .set((page.eq(html_page.unwrap())))
                .execute(&conn)
                .unwrap();
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Refactor error handling<commit_after><|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before><commit_msg>Readded import test<commit_after>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate gltf;

use std::{fs, io, path};

fn try_import(path: &path::Path) {
    let _ = gltf::import(&path).map_err(|err| {
        println!("{:?}: {:#?}", path, err);
        panic!();
    });
}

fn run() -> io::Result<()> {
    let sample_dir_path = path::Path::new("./glTF-Sample-Models/2.0");
    for entry in fs::read_dir(&sample_dir_path)? {
        let entry = entry?;
        let metadata = entry.metadata()?;
        if metadata.is_dir() {
            let entry_path = entry.path();
            if let Some(file_name) = entry_path.file_name() {
                let mut gltf_path = entry_path.join("glTF").join(file_name);
                gltf_path.set_extension("gltf");
                try_import(&gltf_path);
            }
        }
    }
    Ok(())
}

#[test]
fn import() {
    // Import all 'standard' glTF in the glTF-Sample-Models/2.0 directory.
    run().expect("No I/O errors");

    // Minimal example taken from https://github.com/javagl/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_003_MinimalGltfFile.md
    try_import(path::Path::new("tests/minimal.gltf"));
}

<|endoftext|>


<commit_before><commit_msg>Add a test with non-Copy data<commit_after>use std::borrow::ToOwned;

#[macro_use]
extern crate literator;

#[test]
fn test_non_copy() {
    let v: Vec<String> = container!["foo".to_owned(), "bar".to_owned()];
    assert_eq!(&v, &["foo", "bar"]);
}
<|endoftext|>


<commit_before>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

//! A widget for displaying both trees and lists

use gtk;
use gtk::ffi::{mod, FFIWidget};
use gtk::traits;
use gtk::cast::GTK_TREE_VIEW;

/// TreeView — A widget for displaying both trees and lists
struct_Widget!(TreeView)

impl TreeView {
    pub fn new() -> Option<TreeView> {
        let tmp_pointer = unsafe { ffi::gtk_tree_view_new() };
        check_pointer!(tmp_pointer, TreeView)
    }

    pub fn new_with_model(model: &gtk::TreeModel) -> Option<TreeView> {
        let tmp_pointer = unsafe { ffi::gtk_tree_view_new_with_model(model.get_pointer()) };
        check_pointer!(tmp_pointer, TreeView)
    }

    pub fn get_headers_visible(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_headers_visible(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_headers_visible(&mut self, visible: bool) {
        unsafe {
            ffi::gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(self.pointer),
                                                   ffi::to_gboolean(visible))
        }
    }

    pub fn columns_autosize(&mut self) {
        unsafe {
            ffi::gtk_tree_view_columns_autosize(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn get_headers_clickable(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_headers_clickable(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_headers_clickable(&mut self, setting: bool) {
        unsafe {
            ffi::gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(self.pointer),
                                                     ffi::to_gboolean(setting))
        }
    }

    pub fn get_rules_hint(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_rules_hint(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_rules_hint(&mut self, setting: bool) {
        unsafe {
            ffi::gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(self.pointer),
                                              ffi::to_gboolean(setting))
        }
    }

    #[cfg(any(GTK_3_8, GTK_3_10, GTK_3_12))]
    pub fn get_activate_on_single_click(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_activate_on_single_click(GTK_TREE_VIEW(self.pointer)))
        }
    }

    #[cfg(any(GTK_3_8, GTK_3_10, GTK_3_12))]
    pub fn set_activate_on_single_click(&mut self, setting: bool) {
        unsafe {
            ffi::gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(self.pointer),
                                                            ffi::to_gboolean(setting))
        }
    }

    #[cfg(any(GTK_3_4, GTK_3_6, GTK_3_8, GTK_3_10, GTK_3_12))]
    pub fn get_n_columns(&self) -> uint {
        unsafe {
            ffi::gtk_tree_view_get_n_columns(GTK_TREE_VIEW(self.pointer)) as uint
        }
    }

    pub fn scroll_to_point(&mut self, tree_x: i32, tree_y: i32) {
        unsafe {
            ffi::gtk_tree_view_scroll_to_point(GTK_TREE_VIEW(self.pointer), tree_x, tree_y)
        }
    }

    pub fn expand_all(&mut self) {
        unsafe {
            ffi::gtk_tree_view_expand_all(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn collapse_all(&mut self) {
        unsafe {
            ffi::gtk_tree_view_collapse_all(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn get_reorderable(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_reorderable(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_reorderable(&mut self, reorderable: bool) {
        unsafe {
            ffi::gtk_tree_view_set_reorderable(GTK_TREE_VIEW(self.pointer),
                                               ffi::to_gboolean(reorderable))
        }
    }

    pub fn unset_rows_drag_source(&mut self) {
        unsafe {
            ffi::gtk_tree_view_unset_rows_drag_source(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn unset_rows_drag_dest(&mut self) {
        unsafe {
            ffi::gtk_tree_view_unset_rows_drag_dest(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn get_enable_search(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_enable_search(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_enable_search(&mut self, enable_search: bool) {
        unsafe {
            ffi::gtk_tree_view_set_enable_search(GTK_TREE_VIEW(self.pointer),
                                                 ffi::to_gboolean(enable_search))
        }
    }

    pub fn get_search_column(&self) -> i32 {
        unsafe {
            ffi::gtk_tree_view_get_search_column(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn set_search_column(&mut self, column: i32) {
        unsafe {
            ffi::gtk_tree_view_set_search_column(GTK_TREE_VIEW(self.pointer), column)
        }
    }

    pub fn get_search_entry(&self) -> gtk::Entry {
        unsafe {
            ffi::FFIWidget::wrap(ffi::gtk_tree_view_get_search_entry(GTK_TREE_VIEW(self.pointer))
                                 as *mut ffi::C_GtkWidget)
        }
    }

    pub fn set_search_entry(&mut self, entry: &mut gtk::Entry) {
        unsafe {
            ffi::gtk_tree_view_set_search_entry(GTK_TREE_VIEW(self.pointer),
                                                entry.get_widget() as *mut ffi::C_GtkEntry)
        }
    }

    pub fn widget_to_tree_coords(&self, wx: i32, wy: i32) -> (i32, i32) {
        let mut tx = 0i32;
        let mut ty = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             wx, wy, &mut tx, &mut ty);
        }
        (tx, ty)
    }

    pub fn tree_to_widget_coords(&self, tx: i32, ty: i32) -> (i32, i32) {
        let mut wx = 0i32;
        let mut wy = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             tx, ty, &mut wx, &mut wy);
        }
        (wx, wy)
    }

    pub fn widget_to_bin_window_coords(&self, wx: i32, wy: i32) -> (i32, i32) {
        let mut bx = 0i32;
        let mut by = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             wx, wy, &mut bx, &mut by);
        }
        (bx, by)
    }

    pub fn bin_window_to_widget_coords(&self, bx: i32, by: i32) -> (i32, i32) {
        let mut wx = 0i32;
        let mut wy = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             bx, by, &mut wx, &mut wy);
        }
        (wx, wy)
    }

    pub fn tree_to_bin_window_coords(&self, tx: i32, ty: i32) -> (i32, i32) {
        let mut bx = 0i32;
        let mut by = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             tx, ty, &mut bx, &mut by);
        }
        (bx, by)
    }

    pub fn bin_window_to_tree_coords(&self, bx: i32, by: i32) -> (i32, i32) {
        let mut tx = 0i32;
        let mut ty = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             bx, by, &mut tx, &mut ty);
        }
        (tx, ty)
    }

    pub fn get_fixed_height_mode(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_fixed_height_mode(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_fixed_height_mode(&mut self, enable: bool) {
        unsafe {
            ffi::gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(self.pointer),
                                                     ffi::to_gboolean(enable))
        }
    }

    pub fn get_hover_selection(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_hover_selection(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_hover_selection(&mut self, hover: bool) {
        unsafe {
            ffi::gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(self.pointer),
                                                   ffi::to_gboolean(hover))
        }
    }

    pub fn get_hover_expand(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_hover_expand(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_hover_expand(&mut self, expand: bool) {
        unsafe {
            ffi::gtk_tree_view_set_hover_expand(GTK_TREE_VIEW(self.pointer),
                                                ffi::to_gboolean(expand))
        }
    }

    pub fn get_rubber_banding(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_rubber_banding(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_rubber_banding(&mut self, enable: bool) {
        unsafe {
            ffi::gtk_tree_view_set_rubber_banding(GTK_TREE_VIEW(self.pointer),
                                                  ffi::to_gboolean(enable))
        }
    }

    pub fn is_rubber_banding_active(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_is_rubber_banding_active(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn get_grid_lines(&self) -> gtk::TreeViewGridLines {
        unsafe {
            ffi::gtk_tree_view_get_grid_lines(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn set_grid_lines(&mut self, grid_lines: gtk::TreeViewGridLines) {
        unsafe {
            ffi::gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(self.pointer), grid_lines)
        }
    }

    pub fn get_enable_tree_lines(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_enable_tree_lines(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_enable_tree_lines(&mut self, enable: bool) {
        unsafe {
            ffi::gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(self.pointer),
                                                     ffi::to_gboolean(enable))
        }
    }

    pub fn get_show_expanders(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_show_expanders(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_show_expanders(&mut self, enable: bool) {
        unsafe {
            ffi::gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(self.pointer),
                                                  ffi::to_gboolean(enable))
        }
    }

    pub fn get_level_indentation(&self) -> i32 {
        unsafe {
            ffi::gtk_tree_view_get_level_indentation(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn set_level_indentation(&mut self, indentation: i32) {
        unsafe {
            ffi::gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(self.pointer),
                                                     indentation)
        }
    }

    pub fn get_tooltip_column(&self) -> i32 {
        unsafe {
            ffi::gtk_tree_view_get_tooltip_column(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn set_tooltip_column(&mut self, column: i32) {
        unsafe {
            ffi::gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(self.pointer),
                                                  column)
        }
    }

    pub fn get_model(&self) -> Option<gtk::TreeModel> {
        let tmp_pointer = unsafe { ffi::gtk_tree_view_get_model(GTK_TREE_VIEW(self.pointer)) };

        if tmp_pointer.is_null() {
            None
        } else {
            Some(gtk::TreeModel::wrap_pointer(tmp_pointer))
        }
    }

    pub fn set_model(&mut self, model: &gtk::TreeModel) {
        unsafe {
            ffi::gtk_tree_view_set_model(GTK_TREE_VIEW(self.pointer),
                                         model.get_pointer())
        }
    }

    pub fn append_column(&mut self, column: &gtk::TreeViewColumn) -> i32 {
        unsafe { ffi::gtk_tree_view_append_column(GTK_TREE_VIEW(self.pointer),
                                                  column.get_pointer()) }
    }
}

impl_drop!(TreeView)
impl_TraitWidget!(TreeView)

impl traits::Container for TreeView {}
impl traits::Scrollable for TreeView {}
<commit_msg>Add convenience function<commit_after>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

//! A widget for displaying both trees and lists

use gtk;
use gtk::ffi::{mod, FFIWidget};
use gtk::traits;
use gtk::cast::GTK_TREE_VIEW;

/// TreeView — A widget for displaying both trees and lists
struct_Widget!(TreeView)

impl TreeView {
    pub fn new() -> Option<TreeView> {
        let tmp_pointer = unsafe { ffi::gtk_tree_view_new() };
        check_pointer!(tmp_pointer, TreeView)
    }

    pub fn new_with_model(model: &gtk::TreeModel) -> Option<TreeView> {
        let tmp_pointer = unsafe { ffi::gtk_tree_view_new_with_model(model.get_pointer()) };
        check_pointer!(tmp_pointer, TreeView)
    }

    pub fn get_headers_visible(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_headers_visible(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_headers_visible(&mut self, visible: bool) {
        unsafe {
            ffi::gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(self.pointer),
                                                   ffi::to_gboolean(visible))
        }
    }

    pub fn columns_autosize(&mut self) {
        unsafe {
            ffi::gtk_tree_view_columns_autosize(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn get_headers_clickable(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_headers_clickable(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_headers_clickable(&mut self, setting: bool) {
        unsafe {
            ffi::gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(self.pointer),
                                                     ffi::to_gboolean(setting))
        }
    }

    pub fn get_rules_hint(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_rules_hint(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_rules_hint(&mut self, setting: bool) {
        unsafe {
            ffi::gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(self.pointer),
                                              ffi::to_gboolean(setting))
        }
    }

    #[cfg(any(GTK_3_8, GTK_3_10, GTK_3_12))]
    pub fn get_activate_on_single_click(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_activate_on_single_click(GTK_TREE_VIEW(self.pointer)))
        }
    }

    #[cfg(any(GTK_3_8, GTK_3_10, GTK_3_12))]
    pub fn set_activate_on_single_click(&mut self, setting: bool) {
        unsafe {
            ffi::gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(self.pointer),
                                                            ffi::to_gboolean(setting))
        }
    }

    #[cfg(any(GTK_3_4, GTK_3_6, GTK_3_8, GTK_3_10, GTK_3_12))]
    pub fn get_n_columns(&self) -> uint {
        unsafe {
            ffi::gtk_tree_view_get_n_columns(GTK_TREE_VIEW(self.pointer)) as uint
        }
    }

    pub fn scroll_to_point(&mut self, tree_x: i32, tree_y: i32) {
        unsafe {
            ffi::gtk_tree_view_scroll_to_point(GTK_TREE_VIEW(self.pointer), tree_x, tree_y)
        }
    }

    pub fn expand_all(&mut self) {
        unsafe {
            ffi::gtk_tree_view_expand_all(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn collapse_all(&mut self) {
        unsafe {
            ffi::gtk_tree_view_collapse_all(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn get_reorderable(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_reorderable(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_reorderable(&mut self, reorderable: bool) {
        unsafe {
            ffi::gtk_tree_view_set_reorderable(GTK_TREE_VIEW(self.pointer),
                                               ffi::to_gboolean(reorderable))
        }
    }

    pub fn unset_rows_drag_source(&mut self) {
        unsafe {
            ffi::gtk_tree_view_unset_rows_drag_source(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn unset_rows_drag_dest(&mut self) {
        unsafe {
            ffi::gtk_tree_view_unset_rows_drag_dest(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn get_enable_search(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_enable_search(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_enable_search(&mut self, enable_search: bool) {
        unsafe {
            ffi::gtk_tree_view_set_enable_search(GTK_TREE_VIEW(self.pointer),
                                                 ffi::to_gboolean(enable_search))
        }
    }

    pub fn get_search_column(&self) -> i32 {
        unsafe {
            ffi::gtk_tree_view_get_search_column(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn set_search_column(&mut self, column: i32) {
        unsafe {
            ffi::gtk_tree_view_set_search_column(GTK_TREE_VIEW(self.pointer), column)
        }
    }

    pub fn get_search_entry(&self) -> gtk::Entry {
        unsafe {
            ffi::FFIWidget::wrap(ffi::gtk_tree_view_get_search_entry(GTK_TREE_VIEW(self.pointer))
                                 as *mut ffi::C_GtkWidget)
        }
    }

    pub fn set_search_entry(&mut self, entry: &mut gtk::Entry) {
        unsafe {
            ffi::gtk_tree_view_set_search_entry(GTK_TREE_VIEW(self.pointer),
                                                entry.get_widget() as *mut ffi::C_GtkEntry)
        }
    }

    pub fn widget_to_tree_coords(&self, wx: i32, wy: i32) -> (i32, i32) {
        let mut tx = 0i32;
        let mut ty = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             wx, wy, &mut tx, &mut ty);
        }
        (tx, ty)
    }

    pub fn tree_to_widget_coords(&self, tx: i32, ty: i32) -> (i32, i32) {
        let mut wx = 0i32;
        let mut wy = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             tx, ty, &mut wx, &mut wy);
        }
        (wx, wy)
    }

    pub fn widget_to_bin_window_coords(&self, wx: i32, wy: i32) -> (i32, i32) {
        let mut bx = 0i32;
        let mut by = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             wx, wy, &mut bx, &mut by);
        }
        (bx, by)
    }

    pub fn bin_window_to_widget_coords(&self, bx: i32, by: i32) -> (i32, i32) {
        let mut wx = 0i32;
        let mut wy = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             bx, by, &mut wx, &mut wy);
        }
        (wx, wy)
    }

    pub fn tree_to_bin_window_coords(&self, tx: i32, ty: i32) -> (i32, i32) {
        let mut bx = 0i32;
        let mut by = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             tx, ty, &mut bx, &mut by);
        }
        (bx, by)
    }

    pub fn bin_window_to_tree_coords(&self, bx: i32, by: i32) -> (i32, i32) {
        let mut tx = 0i32;
        let mut ty = 0i32;
        unsafe {
            ffi::gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self.pointer),
                                                             bx, by, &mut tx, &mut ty);
        }
        (tx, ty)
    }

    pub fn get_fixed_height_mode(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_fixed_height_mode(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_fixed_height_mode(&mut self, enable: bool) {
        unsafe {
            ffi::gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(self.pointer),
                                                     ffi::to_gboolean(enable))
        }
    }

    pub fn get_hover_selection(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_hover_selection(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_hover_selection(&mut self, hover: bool) {
        unsafe {
            ffi::gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(self.pointer),
                                                   ffi::to_gboolean(hover))
        }
    }

    pub fn get_hover_expand(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_hover_expand(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_hover_expand(&mut self, expand: bool) {
        unsafe {
            ffi::gtk_tree_view_set_hover_expand(GTK_TREE_VIEW(self.pointer),
                                                ffi::to_gboolean(expand))
        }
    }

    pub fn get_rubber_banding(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_rubber_banding(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_rubber_banding(&mut self, enable: bool) {
        unsafe {
            ffi::gtk_tree_view_set_rubber_banding(GTK_TREE_VIEW(self.pointer),
                                                  ffi::to_gboolean(enable))
        }
    }

    pub fn is_rubber_banding_active(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_is_rubber_banding_active(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn get_grid_lines(&self) -> gtk::TreeViewGridLines {
        unsafe {
            ffi::gtk_tree_view_get_grid_lines(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn set_grid_lines(&mut self, grid_lines: gtk::TreeViewGridLines) {
        unsafe {
            ffi::gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(self.pointer), grid_lines)
        }
    }

    pub fn get_enable_tree_lines(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_enable_tree_lines(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_enable_tree_lines(&mut self, enable: bool) {
        unsafe {
            ffi::gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(self.pointer),
                                                     ffi::to_gboolean(enable))
        }
    }

    pub fn get_show_expanders(&self) -> bool {
        unsafe {
            ffi::to_bool(ffi::gtk_tree_view_get_show_expanders(GTK_TREE_VIEW(self.pointer)))
        }
    }

    pub fn set_show_expanders(&mut self, enable: bool) {
        unsafe {
            ffi::gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(self.pointer),
                                                  ffi::to_gboolean(enable))
        }
    }

    pub fn get_level_indentation(&self) -> i32 {
        unsafe {
            ffi::gtk_tree_view_get_level_indentation(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn set_level_indentation(&mut self, indentation: i32) {
        unsafe {
            ffi::gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(self.pointer),
                                                     indentation)
        }
    }

    pub fn get_tooltip_column(&self) -> i32 {
        unsafe {
            ffi::gtk_tree_view_get_tooltip_column(GTK_TREE_VIEW(self.pointer))
        }
    }

    pub fn set_tooltip_column(&mut self, column: i32) {
        unsafe {
            ffi::gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(self.pointer),
                                                  column)
        }
    }

    pub fn get_model(&self) -> Option<gtk::TreeModel> {
        let tmp_pointer = unsafe { ffi::gtk_tree_view_get_model(GTK_TREE_VIEW(self.pointer)) };

        if tmp_pointer.is_null() {
            None
        } else {
            Some(gtk::TreeModel::wrap_pointer(tmp_pointer))
        }
    }

    pub fn set_model(&mut self, model: &gtk::TreeModel) {
        unsafe {
            ffi::gtk_tree_view_set_model(GTK_TREE_VIEW(self.pointer),
                                         model.get_pointer())
        }
    }

    pub fn append_column(&mut self, column: &gtk::TreeViewColumn) -> i32 {
        unsafe { ffi::gtk_tree_view_append_column(GTK_TREE_VIEW(self.pointer),
                                                  column.get_pointer()) }
    }

    pub fn append_text_column(&mut self, column: &gtk::TreeViewColumn) -> i32 {
        let cell = gtk::CellRendererText::new().unwrap();
        column.pack_start(&cell, true);
        column.add_attribute(&cell, "text", 0);
        self.append_column(column)
    }
}

impl_drop!(TreeView)
impl_TraitWidget!(TreeView)

impl traits::Container for TreeView {}
impl traits::Scrollable for TreeView {}
<|endoftext|>


<commit_before>use std::error::Error;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Error as FmtError;
use std::io::Error as IOError;

generate_error_types!(RuntimeError, RuntimeErrorKind,
    Instantiate        => "Could not instantiate",
    IOError            => "IO Error",
    ProcessExitFailure => "Process exited with failure"
);

impl From<IOError> for RuntimeError {

    fn from(ioe: IOError) -> RuntimeError {
        RuntimeError::new(RuntimeErrorKind::IOError, Some(Box::new(ioe)))
    }

}

<commit_msg>libimagrt: Replace error module imports with macro helper<commit_after>generate_error_imports!();
use std::io::Error as IOError;

generate_error_types!(RuntimeError, RuntimeErrorKind,
    Instantiate        => "Could not instantiate",
    IOError            => "IO Error",
    ProcessExitFailure => "Process exited with failure"
);

impl From<IOError> for RuntimeError {

    fn from(ioe: IOError) -> RuntimeError {
        RuntimeError::new(RuntimeErrorKind::IOError, Some(Box::new(ioe)))
    }

}

<|endoftext|>


<commit_before><commit_msg>Use static maps for simple color lookups<commit_after><|endoftext|>


<commit_before><commit_msg>Fix Array Checks<commit_after><|endoftext|>


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

// This file must never have a trailing newline

fn main() {
    let x = Some(3);
    let y = x.as_ref().unwrap_or(&5); //~ ERROR: borrowed value does not live long enough
}<|endoftext|>


<commit_before><commit_msg>FS notify now uses secondary thread to batch up FS events and do sync<commit_after><|endoftext|>


<commit_before><commit_msg>Added bitboard tests<commit_after>use board::sjadam_move_gen::BitBoard;
use board::std_board;
use board::std_board::ChessBoard;
use board::std_move::ChessMove;
use search_algorithms::board::EvalBoard;
use search_algorithms::game_move::Move;

#[test]
fn rotate() {
    let start_board = BitBoard::from_board(&ChessBoard::start_board(), |p| !p.is_empty());
    let mut empty = BitBoard::empty();
    empty.rotate();
    assert_eq!(BitBoard::empty(), empty);
    let mut board = start_board.clone();
    board.rotate();
    println!("{:?}", board);
    board.rotate();
    assert_eq!(start_board, board);

    board.rotate();
    board.rotate();
    assert_eq!(start_board, board);

    board.rotate();
    for rank in 0..8 {
        for &file in [0, 1, 6, 7].iter() {
            assert!(board.get(std_board::Square::from_ints(file, rank)));
        }
        for &file in [2, 3, 4, 5].iter() {
            assert!(!board.get(std_board::Square::from_ints(file, rank)),
            "Found piece in the middle of board \n{:?}", board);
        }
    }

    board = BitBoard::from_u64(0b01000100_01001000_01010000_01010000_01110000_01000100_01000100_01111000);
    board.rotate();
    board.rotate();
    board.rotate();
    board.rotate();
    assert_eq!(board, BitBoard::from_u64(0b01000100_01001000_01010000_01010000_01110000_01000100_01000100_01111000));
}

#[test]
fn rank() {
    let start_board = BitBoard::all_from_board(&ChessBoard::start_board());
    println!("{:?}", start_board);
    for rank in 0..8 {
        println!("{}", start_board.rank(rank));
    }
    assert_eq!(start_board.rank(0), 255);
    assert_eq!(start_board.rank(1), 255);
    assert_eq!(start_board.rank(2), 0);
    assert_eq!(start_board.rank(6), 255);
}

#[test]
fn file() {
    let start_board = BitBoard::all_from_board(&ChessBoard::start_board());
    assert_eq!(start_board.file(0), 0b1100_0011);
    let mut chess_board = ChessBoard::start_board();
    chess_board.do_move(ChessMove::from_alg("a2a4").unwrap());
    let board = BitBoard::all_from_board(&chess_board);
    assert_eq!(board.file(0), 0b1100_1001);
}
<|endoftext|>


<commit_before><commit_msg>Add a new "ui" example<commit_after>extern crate rustty;

use rustty::{
    Terminal,
    Event,
};
use rustty::ui::{
    Widget,
    Painter,
    Alignable,
    HorizontalAlign,
    VerticalAlign,
    create_button,
};

fn create_maindlg() -> Widget {
    let mut maindlg = Widget::new(60, 10);
    let s = "Hello! This is a showcase of the ui module!";
    let x = maindlg.halign_line(s, HorizontalAlign::Middle, 1);
    maindlg.printline(x, 2, s);
    let mut b = create_button("Quit", Some('q'));
    b.align(&maindlg, HorizontalAlign::Middle, VerticalAlign::Bottom, 1);
    b.draw_into(&mut maindlg);
    maindlg.draw_box();
    maindlg
}

fn main() {
    let mut term = Terminal::new().unwrap();
    let mut maindlg = create_maindlg();
    maindlg.align(&term, HorizontalAlign::Middle, VerticalAlign::Middle, 0);
    'main: loop {
        while let Some(Event::Key(ch)) = term.get_event(0).unwrap() {
            match ch {
                'q' | 'Q' => break 'main,
                _ => {},
            }
        }

        maindlg.draw_into(&mut term);
        term.swap_buffers().unwrap();
    }
}

<|endoftext|>


<commit_before><commit_msg>Add tutorial-15_3-do.rs<commit_after>/**
 * 15.3 Do syntax
 * http://static.rust-lang.org/doc/master/tutorial.html#do-syntax
 *
 * @license MIT license <http://www.opensource.org/licenses/mit-license.php>
 */
// The do expression makes it easier to call functions that take procedures as arguments.

// A function that takes a procedure as argument:
fn call_it(op: proc(v: int)) {
	    op(10)
}

fn main() {
	// As a caller, if we use a closure to provide the final operator argument, we can write it in a way that has a pleasant, block-like structure.
	call_it(proc(n) {
		    println(n.to_str());
	});

	// This is such a useful pattern that Rust has a special form of function call for these functions.
	do call_it() |n| {
		    println(n.to_str());
	}

}
<|endoftext|>


<commit_before><commit_msg>Clarify segment handling for '..'.<commit_after><|endoftext|>


<commit_before>use std::path::PathBuf;
use std::process::Command;
use std::env;
use std::io::stderr;
use std::io::Write;

pub use clap::App;

use clap::{Arg, ArgMatches};
use log;
use log::LogLevelFilter;

use configuration::Configuration;
use error::RuntimeError;
use error::RuntimeErrorKind;
use error::MapErrInto;
use logger::ImagLogger;

use libimagstore::store::Store;

#[derive(Debug)]
pub struct Runtime<'a> {
    rtp: PathBuf,
    configuration: Option<Configuration>,
    cli_matches: ArgMatches<'a>,
    store: Store,
}

impl<'a> Runtime<'a> {

    /**
     * Gets the CLI spec for the program and retreives the config file path (or uses the default on
     * in $HOME/.imag/config, $XDG_CONFIG_DIR/imag/config or from env("$IMAG_CONFIG")
     * and builds the Runtime object with it.
     *
     * The cli_spec object should be initially build with the ::get_default_cli_builder() function.
     *
     */
    pub fn new(cli_spec: App<'a, 'a>) -> Result<Runtime<'a>, RuntimeError> {
        use std::env;

        use libimagstore::hook::position::HookPosition as HP;
        use libimagstore::hook::Hook;
        use libimagstore::error::StoreErrorKind;
        use libimagstorestdhook::debug::DebugHook;
        use libimagstorestdhook::vcs::git::create::CreateHook as GitCreateHook;
        use libimagstorestdhook::vcs::git::delete::DeleteHook as GitDeleteHook;
        use libimagstorestdhook::vcs::git::retrieve::RetrieveHook as GitRetrieveHook;
        use libimagstorestdhook::vcs::git::update::UpdateHook as GitUpdateHook;
        use libimagerror::trace::trace_error;
        use libimagerror::trace::trace_error_dbg;
        use libimagerror::into::IntoError;

        use configuration::error::ConfigErrorKind;

        let matches = cli_spec.get_matches();

        let is_debugging = matches.is_present("debugging");
        let is_verbose   = matches.is_present("verbosity");
        let colored      = !matches.is_present("no-color-output");

        Runtime::init_logger(is_debugging, is_verbose, colored);

        let rtp : PathBuf = matches.value_of("runtimepath")
            .map_or_else(|| {
                env::var("HOME")
                    .map(PathBuf::from)
                    .map(|mut p| { p.push(".imag"); p})
                    .unwrap_or_else(|_| {
                        panic!("You seem to be $HOME-less. Please get a $HOME before using this software. We are sorry for you and hope you have some accommodation anyways.");
                    })
            }, PathBuf::from);
        let storepath = matches.value_of("storepath")
                                .map_or_else(|| {
                                    let mut spath = rtp.clone();
                                    spath.push("store");
                                    spath
                                }, PathBuf::from);

        let configpath = matches.value_of("config")
                                .map_or_else(|| rtp.clone(), PathBuf::from);

        let cfg = match Configuration::new(&configpath) {
            Err(e) => if e.err_type() != ConfigErrorKind::NoConfigFileFound {
                return Err(RuntimeErrorKind::Instantiate.into_error_with_cause(Box::new(e)));
            } else {
                warn!("No config file found.");
                warn!("Continuing without configuration file");
                None
            },

            Ok(mut cfg) => {
                if let Err(e) = cfg.override_config(get_override_specs(&matches)) {
                    error!("Could not apply config overrides");
                    trace_error(&e);

                    // TODO: continue question (interactive)
                }

                Some(cfg)
            }
        };

        let store_config = match cfg {
            Some(ref c) => c.store_config().cloned(),
            None        => None,
        };

        if is_debugging {
            write!(stderr(), "Config: {:?}\n", cfg).ok();
            write!(stderr(), "Store-config: {:?}\n", store_config).ok();
        }

        Store::new(storepath.clone(), store_config).map(|mut store| {
            // If we are debugging, generate hooks for all positions
            if is_debugging {
                let hooks : Vec<(Box<Hook>, &str, HP)> = vec![
                    (Box::new(DebugHook::new(HP::PreCreate))          , "debug", HP::PreCreate),
                    (Box::new(DebugHook::new(HP::PostCreate))         , "debug", HP::PostCreate),
                    (Box::new(DebugHook::new(HP::PreRetrieve))        , "debug", HP::PreRetrieve),
                    (Box::new(DebugHook::new(HP::PostRetrieve))       , "debug", HP::PostRetrieve),
                    (Box::new(DebugHook::new(HP::PreUpdate))          , "debug", HP::PreUpdate),
                    (Box::new(DebugHook::new(HP::PostUpdate))         , "debug", HP::PostUpdate),
                    (Box::new(DebugHook::new(HP::PreDelete))          , "debug", HP::PreDelete),
                    (Box::new(DebugHook::new(HP::PostDelete))         , "debug", HP::PostDelete),
                ];

                // If hook registration fails, trace the error and warn, but continue.
                for (hook, aspectname, position) in hooks {
                    if let Err(e) = store.register_hook(position, &String::from(aspectname), hook) {
                        if e.err_type() == StoreErrorKind::HookRegisterError {
                            trace_error_dbg(&e);
                            warn!("Registering debug hook with store failed");
                        } else {
                            trace_error(&e);
                        };
                    }
                }
            }

            let sp = storepath;

            let hooks : Vec<(Box<Hook>, &str, HP)> = vec![
                (Box::new(GitCreateHook::new(sp.clone(), HP::PostCreate))    , "vcs", HP::PostCreate),
                (Box::new(GitDeleteHook::new(sp.clone(), HP::PreDelete))     , "vcs", HP::PreDelete),
                (Box::new(GitRetrieveHook::new(sp.clone(), HP::PostRetrieve)), "vcs", HP::PostRetrieve),
                (Box::new(GitUpdateHook::new(sp, HP::PostUpdate))    , "vcs", HP::PostUpdate),
            ];

            for (hook, aspectname, position) in hooks {
                if let Err(e) = store.register_hook(position, &String::from(aspectname), hook) {
                    if e.err_type() == StoreErrorKind::HookRegisterError {
                        trace_error_dbg(&e);
                        warn!("Registering debug hook with store failed");
                    } else {
                        trace_error(&e);
                    };
                }
            }

            Runtime {
                cli_matches: matches,
                configuration: cfg,
                rtp: rtp,
                store: store,
            }
        })
        .map_err_into(RuntimeErrorKind::Instantiate)
    }

    /**
     * Get a commandline-interface builder object from `clap`
     *
     * This commandline interface builder object already contains some predefined interface flags:
     *   * -v | --verbose for verbosity
     *   * --debug for debugging
     *   * -c <file> | --config <file> for alternative configuration file
     *   * -r <path> | --rtp <path> for alternative runtimepath
     *   * --store <path> for alternative store path
     * Each has the appropriate help text included.
     *
     * The `appname` shall be "imag-<command>".
     */
    pub fn get_default_cli_builder(appname: &'a str,
                                   version: &'a str,
                                   about: &'a str)
        -> App<'a, 'a>
    {
        App::new(appname)
            .version(version)
            .author("Matthias Beyer <mail@beyermatthias.de>")
            .about(about)
            .arg(Arg::with_name(Runtime::arg_verbosity_name())
                .short("v")
                .long("verbose")
                .help("Enables verbosity")
                .required(false)
                .takes_value(false))

            .arg(Arg::with_name(Runtime::arg_debugging_name())
                .long("debug")
                .help("Enables debugging output")
                .required(false)
                .takes_value(false))

            .arg(Arg::with_name(Runtime::arg_no_color_output_name())
                .long("no-color")
                .help("Disable color output")
                .required(false)
                .takes_value(false))

            .arg(Arg::with_name(Runtime::arg_config_name())
                .long("config")
                .help("Path to alternative config file")
                .required(false)
                .takes_value(true))

            .arg(Arg::with_name(Runtime::arg_config_override_name())
                 .long("override-config")
                 .help("Override a configuration settings. Use 'key=value' pairs, where the key is a path in the TOML configuration. The value must be present in the configuration and be convertible to the type of the configuration setting. If the argument does not contain a '=', it gets ignored. Setting Arrays and Tables is not yet supported.")
                 .required(false)
                 .takes_value(true))

            .arg(Arg::with_name(Runtime::arg_runtimepath_name())
                .long("rtp")
                .help("Alternative runtimepath")
                .required(false)
                .takes_value(true))

            .arg(Arg::with_name(Runtime::arg_storepath_name())
                .long("store")
                .help("Alternative storepath. Must be specified as full path, can be outside of the RTP")
                .required(false)
                .takes_value(true))

            .arg(Arg::with_name(Runtime::arg_editor_name())
                .long("editor")
                .help("Set editor")
                .required(false)
                .takes_value(true))
    }

    pub fn arg_names() -> Vec<&'static str> {
        vec![
            Runtime::arg_verbosity_name(),
            Runtime::arg_debugging_name(),
            Runtime::arg_no_color_output_name(),
            Runtime::arg_config_name(),
            Runtime::arg_config_override_name(),
            Runtime::arg_runtimepath_name(),
            Runtime::arg_storepath_name(),
            Runtime::arg_editor_name(),
        ]
    }

    pub fn arg_verbosity_name() -> &'static str {
        "verbosity"
    }

    pub fn arg_debugging_name() -> &'static str {
        "debugging"
    }

    pub fn arg_no_color_output_name() -> &'static str {
        "no-color-output"
    }

    pub fn arg_config_name() -> &'static str {
        "config"
    }

    pub fn arg_config_override_name() -> &'static str {
        "config-override"
    }

    pub fn arg_runtimepath_name() -> &'static str {
        "runtimepath"
    }

    pub fn arg_storepath_name() -> &'static str {
        "storepath"
    }

    pub fn arg_editor_name() -> &'static str {
        "editor"
    }

    /**
     * Initialize the internal logger
     */
    fn init_logger(is_debugging: bool, is_verbose: bool, colored: bool) {
        use std::env::var as env_var;
        use env_logger;

        if env_var("IMAG_LOG_ENV").is_ok() {
            env_logger::init().unwrap();
        } else {
            let lvl = if is_debugging {
                LogLevelFilter::Debug
            } else if is_verbose {
                LogLevelFilter::Info
            } else {
                LogLevelFilter::Warn
            };

            log::set_logger(|max_log_lvl| {
                max_log_lvl.set(lvl);
                debug!("Init logger with {}", lvl);
                Box::new(ImagLogger::new(lvl.to_log_level().unwrap()).with_color(colored))
            })
            .map_err(|_| {
                panic!("Could not setup logger");
            })
            .ok();
        }
    }

    /**
     * Get the verbosity flag value
     */
    pub fn is_verbose(&self) -> bool {
        self.cli_matches.is_present("verbosity")
    }

    /**
     * Get the debugging flag value
     */
    pub fn is_debugging(&self) -> bool {
        self.cli_matches.is_present("debugging")
    }

    /**
     * Get the runtimepath
     */
    pub fn rtp(&self) -> &PathBuf {
        &self.rtp
    }

    /**
     * Get the commandline interface matches
     */
    pub fn cli(&self) -> &ArgMatches {
        &self.cli_matches
    }

    /**
     * Get the configuration object
     */
    pub fn config(&self) -> Option<&Configuration> {
        self.configuration.as_ref()
    }

    /**
     * Get the store object
     */
    pub fn store(&self) -> &Store {
        &self.store
    }

    pub fn editor(&self) -> Option<Command> {
        self.cli()
            .value_of("editor")
            .map(String::from)
            .or({
                match self.configuration {
                    Some(ref c) => c.editor().cloned(),
                    _ => None,
                }
            })
            .or(env::var("EDITOR").ok())
            .map(Command::new)
    }
}

fn get_override_specs(matches: &ArgMatches) -> Vec<String> {
    matches
        .values_of("config-override")
        .map(|values| {
             values
             .filter(|s| {
                 let b = s.contains("=");
                 if !b { warn!("override '{}' does not contain '=' - will be ignored!", s); }
                 b
             })
             .map(String::from)
             .collect()
        })
        .unwrap_or(vec![])
}

<commit_msg>Remove hook initialization from runtime setup<commit_after>use std::path::PathBuf;
use std::process::Command;
use std::env;
use std::io::stderr;
use std::io::Write;

pub use clap::App;

use clap::{Arg, ArgMatches};
use log;
use log::LogLevelFilter;

use configuration::Configuration;
use error::RuntimeError;
use error::RuntimeErrorKind;
use error::MapErrInto;
use logger::ImagLogger;

use libimagstore::store::Store;

#[derive(Debug)]
pub struct Runtime<'a> {
    rtp: PathBuf,
    configuration: Option<Configuration>,
    cli_matches: ArgMatches<'a>,
    store: Store,
}

impl<'a> Runtime<'a> {

    /**
     * Gets the CLI spec for the program and retreives the config file path (or uses the default on
     * in $HOME/.imag/config, $XDG_CONFIG_DIR/imag/config or from env("$IMAG_CONFIG")
     * and builds the Runtime object with it.
     *
     * The cli_spec object should be initially build with the ::get_default_cli_builder() function.
     *
     */
    pub fn new(cli_spec: App<'a, 'a>) -> Result<Runtime<'a>, RuntimeError> {
        use std::env;

        use libimagstore::hook::position::HookPosition as HP;
        use libimagstore::hook::Hook;
        use libimagstore::error::StoreErrorKind;
        use libimagstorestdhook::debug::DebugHook;
        use libimagstorestdhook::vcs::git::delete::DeleteHook as GitDeleteHook;
        use libimagstorestdhook::vcs::git::update::UpdateHook as GitUpdateHook;
        use libimagerror::trace::trace_error;
        use libimagerror::trace::trace_error_dbg;
        use libimagerror::into::IntoError;

        use configuration::error::ConfigErrorKind;

        let matches = cli_spec.get_matches();

        let is_debugging = matches.is_present("debugging");
        let is_verbose   = matches.is_present("verbosity");
        let colored      = !matches.is_present("no-color-output");

        Runtime::init_logger(is_debugging, is_verbose, colored);

        let rtp : PathBuf = matches.value_of("runtimepath")
            .map_or_else(|| {
                env::var("HOME")
                    .map(PathBuf::from)
                    .map(|mut p| { p.push(".imag"); p})
                    .unwrap_or_else(|_| {
                        panic!("You seem to be $HOME-less. Please get a $HOME before using this software. We are sorry for you and hope you have some accommodation anyways.");
                    })
            }, PathBuf::from);
        let storepath = matches.value_of("storepath")
                                .map_or_else(|| {
                                    let mut spath = rtp.clone();
                                    spath.push("store");
                                    spath
                                }, PathBuf::from);

        let configpath = matches.value_of("config")
                                .map_or_else(|| rtp.clone(), PathBuf::from);

        let cfg = match Configuration::new(&configpath) {
            Err(e) => if e.err_type() != ConfigErrorKind::NoConfigFileFound {
                return Err(RuntimeErrorKind::Instantiate.into_error_with_cause(Box::new(e)));
            } else {
                warn!("No config file found.");
                warn!("Continuing without configuration file");
                None
            },

            Ok(mut cfg) => {
                if let Err(e) = cfg.override_config(get_override_specs(&matches)) {
                    error!("Could not apply config overrides");
                    trace_error(&e);

                    // TODO: continue question (interactive)
                }

                Some(cfg)
            }
        };

        let store_config = match cfg {
            Some(ref c) => c.store_config().cloned(),
            None        => None,
        };

        if is_debugging {
            write!(stderr(), "Config: {:?}\n", cfg).ok();
            write!(stderr(), "Store-config: {:?}\n", store_config).ok();
        }

        Store::new(storepath.clone(), store_config).map(|mut store| {
            // If we are debugging, generate hooks for all positions
            if is_debugging {
                let hooks : Vec<(Box<Hook>, &str, HP)> = vec![
                    (Box::new(DebugHook::new(HP::PreCreate))          , "debug", HP::PreCreate),
                    (Box::new(DebugHook::new(HP::PostCreate))         , "debug", HP::PostCreate),
                    (Box::new(DebugHook::new(HP::PreRetrieve))        , "debug", HP::PreRetrieve),
                    (Box::new(DebugHook::new(HP::PostRetrieve))       , "debug", HP::PostRetrieve),
                    (Box::new(DebugHook::new(HP::PreUpdate))          , "debug", HP::PreUpdate),
                    (Box::new(DebugHook::new(HP::PostUpdate))         , "debug", HP::PostUpdate),
                    (Box::new(DebugHook::new(HP::PreDelete))          , "debug", HP::PreDelete),
                    (Box::new(DebugHook::new(HP::PostDelete))         , "debug", HP::PostDelete),
                ];

                // If hook registration fails, trace the error and warn, but continue.
                for (hook, aspectname, position) in hooks {
                    if let Err(e) = store.register_hook(position, &String::from(aspectname), hook) {
                        if e.err_type() == StoreErrorKind::HookRegisterError {
                            trace_error_dbg(&e);
                            warn!("Registering debug hook with store failed");
                        } else {
                            trace_error(&e);
                        };
                    }
                }
            }

            let sp = storepath;

            let hooks : Vec<(Box<Hook>, &str, HP)> = vec![
                (Box::new(GitDeleteHook::new(sp.clone(), HP::PreDelete))     , "vcs", HP::PreDelete),
                (Box::new(GitUpdateHook::new(sp, HP::PostUpdate))    , "vcs", HP::PostUpdate),
            ];

            for (hook, aspectname, position) in hooks {
                if let Err(e) = store.register_hook(position, &String::from(aspectname), hook) {
                    if e.err_type() == StoreErrorKind::HookRegisterError {
                        trace_error_dbg(&e);
                        warn!("Registering debug hook with store failed");
                    } else {
                        trace_error(&e);
                    };
                }
            }

            Runtime {
                cli_matches: matches,
                configuration: cfg,
                rtp: rtp,
                store: store,
            }
        })
        .map_err_into(RuntimeErrorKind::Instantiate)
    }

    /**
     * Get a commandline-interface builder object from `clap`
     *
     * This commandline interface builder object already contains some predefined interface flags:
     *   * -v | --verbose for verbosity
     *   * --debug for debugging
     *   * -c <file> | --config <file> for alternative configuration file
     *   * -r <path> | --rtp <path> for alternative runtimepath
     *   * --store <path> for alternative store path
     * Each has the appropriate help text included.
     *
     * The `appname` shall be "imag-<command>".
     */
    pub fn get_default_cli_builder(appname: &'a str,
                                   version: &'a str,
                                   about: &'a str)
        -> App<'a, 'a>
    {
        App::new(appname)
            .version(version)
            .author("Matthias Beyer <mail@beyermatthias.de>")
            .about(about)
            .arg(Arg::with_name(Runtime::arg_verbosity_name())
                .short("v")
                .long("verbose")
                .help("Enables verbosity")
                .required(false)
                .takes_value(false))

            .arg(Arg::with_name(Runtime::arg_debugging_name())
                .long("debug")
                .help("Enables debugging output")
                .required(false)
                .takes_value(false))

            .arg(Arg::with_name(Runtime::arg_no_color_output_name())
                .long("no-color")
                .help("Disable color output")
                .required(false)
                .takes_value(false))

            .arg(Arg::with_name(Runtime::arg_config_name())
                .long("config")
                .help("Path to alternative config file")
                .required(false)
                .takes_value(true))

            .arg(Arg::with_name(Runtime::arg_config_override_name())
                 .long("override-config")
                 .help("Override a configuration settings. Use 'key=value' pairs, where the key is a path in the TOML configuration. The value must be present in the configuration and be convertible to the type of the configuration setting. If the argument does not contain a '=', it gets ignored. Setting Arrays and Tables is not yet supported.")
                 .required(false)
                 .takes_value(true))

            .arg(Arg::with_name(Runtime::arg_runtimepath_name())
                .long("rtp")
                .help("Alternative runtimepath")
                .required(false)
                .takes_value(true))

            .arg(Arg::with_name(Runtime::arg_storepath_name())
                .long("store")
                .help("Alternative storepath. Must be specified as full path, can be outside of the RTP")
                .required(false)
                .takes_value(true))

            .arg(Arg::with_name(Runtime::arg_editor_name())
                .long("editor")
                .help("Set editor")
                .required(false)
                .takes_value(true))
    }

    pub fn arg_names() -> Vec<&'static str> {
        vec![
            Runtime::arg_verbosity_name(),
            Runtime::arg_debugging_name(),
            Runtime::arg_no_color_output_name(),
            Runtime::arg_config_name(),
            Runtime::arg_config_override_name(),
            Runtime::arg_runtimepath_name(),
            Runtime::arg_storepath_name(),
            Runtime::arg_editor_name(),
        ]
    }

    pub fn arg_verbosity_name() -> &'static str {
        "verbosity"
    }

    pub fn arg_debugging_name() -> &'static str {
        "debugging"
    }

    pub fn arg_no_color_output_name() -> &'static str {
        "no-color-output"
    }

    pub fn arg_config_name() -> &'static str {
        "config"
    }

    pub fn arg_config_override_name() -> &'static str {
        "config-override"
    }

    pub fn arg_runtimepath_name() -> &'static str {
        "runtimepath"
    }

    pub fn arg_storepath_name() -> &'static str {
        "storepath"
    }

    pub fn arg_editor_name() -> &'static str {
        "editor"
    }

    /**
     * Initialize the internal logger
     */
    fn init_logger(is_debugging: bool, is_verbose: bool, colored: bool) {
        use std::env::var as env_var;
        use env_logger;

        if env_var("IMAG_LOG_ENV").is_ok() {
            env_logger::init().unwrap();
        } else {
            let lvl = if is_debugging {
                LogLevelFilter::Debug
            } else if is_verbose {
                LogLevelFilter::Info
            } else {
                LogLevelFilter::Warn
            };

            log::set_logger(|max_log_lvl| {
                max_log_lvl.set(lvl);
                debug!("Init logger with {}", lvl);
                Box::new(ImagLogger::new(lvl.to_log_level().unwrap()).with_color(colored))
            })
            .map_err(|_| {
                panic!("Could not setup logger");
            })
            .ok();
        }
    }

    /**
     * Get the verbosity flag value
     */
    pub fn is_verbose(&self) -> bool {
        self.cli_matches.is_present("verbosity")
    }

    /**
     * Get the debugging flag value
     */
    pub fn is_debugging(&self) -> bool {
        self.cli_matches.is_present("debugging")
    }

    /**
     * Get the runtimepath
     */
    pub fn rtp(&self) -> &PathBuf {
        &self.rtp
    }

    /**
     * Get the commandline interface matches
     */
    pub fn cli(&self) -> &ArgMatches {
        &self.cli_matches
    }

    /**
     * Get the configuration object
     */
    pub fn config(&self) -> Option<&Configuration> {
        self.configuration.as_ref()
    }

    /**
     * Get the store object
     */
    pub fn store(&self) -> &Store {
        &self.store
    }

    pub fn editor(&self) -> Option<Command> {
        self.cli()
            .value_of("editor")
            .map(String::from)
            .or({
                match self.configuration {
                    Some(ref c) => c.editor().cloned(),
                    _ => None,
                }
            })
            .or(env::var("EDITOR").ok())
            .map(Command::new)
    }
}

fn get_override_specs(matches: &ArgMatches) -> Vec<String> {
    matches
        .values_of("config-override")
        .map(|values| {
             values
             .filter(|s| {
                 let b = s.contains("=");
                 if !b { warn!("override '{}' does not contain '=' - will be ignored!", s); }
                 b
             })
             .map(String::from)
             .collect()
        })
        .unwrap_or(vec![])
}

<|endoftext|>


<commit_before><commit_msg>Fix git http.proxy config setting.<commit_after><|endoftext|>