<commit_before>//! Asynchronous values.

use core::cell::Cell;
use core::marker::Unpin;
use core::pin::Pin;
use core::option::Option;
use core::ptr::NonNull;
use core::task::{Context, Poll};
use core::ops::{Drop, Generator, GeneratorState};

#[doc(inline)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub use core::future::*;

/// Wrap a generator in a future.
///
/// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
/// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
#[unstable(feature = "gen_future", issue = "50547")]
pub fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> {
    GenFuture(x)
}

/// A wrapper around generators used to implement `Future` for `async`/`await` code.
#[unstable(feature = "gen_future", issue = "50547")]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
struct GenFuture<T: Generator<Yield = ()>>(T);

// We rely on the fact that async/await futures are immovable in order to create
// self-referential borrows in the underlying generator.
impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {}

#[unstable(feature = "gen_future", issue = "50547")]
impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
    type Output = T::Return;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        // Safe because we're !Unpin + !Drop mapping to a ?Unpin value
        let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
        set_task_context(cx, || match gen.resume() {
            GeneratorState::Yielded(()) => Poll::Pending,
            GeneratorState::Complete(x) => Poll::Ready(x),
        })
    }
}

thread_local! {
    static TLS_CX: Cell<Option<NonNull<Context<'static>>>> = Cell::new(None);
}

struct SetOnDrop(Option<NonNull<Context<'static>>>);

impl Drop for SetOnDrop {
    fn drop(&mut self) {
        TLS_CX.with(|tls_cx| {
            tls_cx.set(self.0.take());
        });
    }
}

#[unstable(feature = "gen_future", issue = "50547")]
/// Sets the thread-local task context used by async/await futures.
pub fn set_task_context<F, R>(cx: &mut Context<'_>, f: F) -> R
where
    F: FnOnce() -> R
{
    // transmute the context's lifetime to 'static so we can store it.
    let cx = unsafe {
        core::mem::transmute::<&mut Context<'_>, &mut Context<'static>>(cx)
    };
    let old_cx = TLS_CX.with(|tls_cx| {
        tls_cx.replace(Some(NonNull::from(cx)))
    });
    let _reset = SetOnDrop(old_cx);
    f()
}

#[unstable(feature = "gen_future", issue = "50547")]
/// Retrieves the thread-local task context used by async/await futures.
///
/// This function acquires exclusive access to the task context.
///
/// Panics if no context has been set or if the context has already been
/// retrieved by a surrounding call to get_task_context.
pub fn get_task_context<F, R>(f: F) -> R
where
    F: FnOnce(&mut Context<'_>) -> R
{
    let cx_ptr = TLS_CX.with(|tls_cx| {
        // Clear the entry so that nested `get_task_waker` calls
        // will fail or set their own value.
        tls_cx.replace(None)
    });
    let _reset = SetOnDrop(cx_ptr);

    let mut cx_ptr = cx_ptr.expect(
        "TLS Context not set. This is a rustc bug. \
        Please file an issue on https://github.com/rust-lang/rust.");

    // Safety: we've ensured exclusive access to the context by
    // removing the pointer from TLS, only to be replaced once
    // we're done with it.
    //
    // The pointer that was inserted came from an `&mut Context<'_>`,
    // so it is safe to treat as mutable.
    unsafe { f(cx_ptr.as_mut()) }
}

#[unstable(feature = "gen_future", issue = "50547")]
/// Polls a future in the current thread-local task waker.
pub fn poll_with_tls_context<F>(f: Pin<&mut F>) -> Poll<F::Output>
where
    F: Future
{
    get_task_context(|cx| F::poll(f, cx))
}
<commit_msg>Rollup merge of #61523 - Nemo157:hide-gen-future, r=cramertj<commit_after>//! Asynchronous values.

use core::cell::Cell;
use core::marker::Unpin;
use core::pin::Pin;
use core::option::Option;
use core::ptr::NonNull;
use core::task::{Context, Poll};
use core::ops::{Drop, Generator, GeneratorState};

#[doc(inline)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub use core::future::*;

/// Wrap a generator in a future.
///
/// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
/// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
pub fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> {
    GenFuture(x)
}

/// A wrapper around generators used to implement `Future` for `async`/`await` code.
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
struct GenFuture<T: Generator<Yield = ()>>(T);

// We rely on the fact that async/await futures are immovable in order to create
// self-referential borrows in the underlying generator.
impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {}

#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
    type Output = T::Return;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        // Safe because we're !Unpin + !Drop mapping to a ?Unpin value
        let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
        set_task_context(cx, || match gen.resume() {
            GeneratorState::Yielded(()) => Poll::Pending,
            GeneratorState::Complete(x) => Poll::Ready(x),
        })
    }
}

thread_local! {
    static TLS_CX: Cell<Option<NonNull<Context<'static>>>> = Cell::new(None);
}

struct SetOnDrop(Option<NonNull<Context<'static>>>);

impl Drop for SetOnDrop {
    fn drop(&mut self) {
        TLS_CX.with(|tls_cx| {
            tls_cx.set(self.0.take());
        });
    }
}

#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
/// Sets the thread-local task context used by async/await futures.
pub fn set_task_context<F, R>(cx: &mut Context<'_>, f: F) -> R
where
    F: FnOnce() -> R
{
    // transmute the context's lifetime to 'static so we can store it.
    let cx = unsafe {
        core::mem::transmute::<&mut Context<'_>, &mut Context<'static>>(cx)
    };
    let old_cx = TLS_CX.with(|tls_cx| {
        tls_cx.replace(Some(NonNull::from(cx)))
    });
    let _reset = SetOnDrop(old_cx);
    f()
}

#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
/// Retrieves the thread-local task context used by async/await futures.
///
/// This function acquires exclusive access to the task context.
///
/// Panics if no context has been set or if the context has already been
/// retrieved by a surrounding call to get_task_context.
pub fn get_task_context<F, R>(f: F) -> R
where
    F: FnOnce(&mut Context<'_>) -> R
{
    let cx_ptr = TLS_CX.with(|tls_cx| {
        // Clear the entry so that nested `get_task_waker` calls
        // will fail or set their own value.
        tls_cx.replace(None)
    });
    let _reset = SetOnDrop(cx_ptr);

    let mut cx_ptr = cx_ptr.expect(
        "TLS Context not set. This is a rustc bug. \
        Please file an issue on https://github.com/rust-lang/rust.");

    // Safety: we've ensured exclusive access to the context by
    // removing the pointer from TLS, only to be replaced once
    // we're done with it.
    //
    // The pointer that was inserted came from an `&mut Context<'_>`,
    // so it is safe to treat as mutable.
    unsafe { f(cx_ptr.as_mut()) }
}

#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
/// Polls a future in the current thread-local task waker.
pub fn poll_with_tls_context<F>(f: Pin<&mut F>) -> Poll<F::Output>
where
    F: Future
{
    get_task_context(|cx| F::poll(f, cx))
}
<|endoftext|>


<commit_before>use super::prelude::*;

/// Returns the JSON representation of the current deployed commit sha.
///
/// The sha is contained within the `HEROKU_SLUG_COMMIT` environment variable.
/// If `HEROKU_SLUG_COMMIT` is not set, returns `"unknown"`.
pub fn show_deployed_sha(req: &mut dyn RequestExt) -> EndpointResult {
    let deployed_sha =
        dotenv::var("HEROKU_SLUG_COMMIT").unwrap_or_else(|_| String::from("unknown"));

    #[derive(Serialize)]
    struct R<'a> {
        deployed_sha: &'a str,
        commit: &'a str,
    }
    Ok(req.json(&R {
        deployed_sha: &deployed_sha[..],
        commit: &deployed_sha[..],
    }))
}
<commit_msg>controllers::site_metadata: Use `json!` macro to simplify JSON serialization code<commit_after>use super::prelude::*;

/// Returns the JSON representation of the current deployed commit sha.
///
/// The sha is contained within the `HEROKU_SLUG_COMMIT` environment variable.
/// If `HEROKU_SLUG_COMMIT` is not set, returns `"unknown"`.
pub fn show_deployed_sha(req: &mut dyn RequestExt) -> EndpointResult {
    let deployed_sha =
        dotenv::var("HEROKU_SLUG_COMMIT").unwrap_or_else(|_| String::from("unknown"));

    Ok(req.json(&json!({
        "deployed_sha": &deployed_sha[..],
        "commit": &deployed_sha[..],
    })))
}
<|endoftext|>


<commit_before>use crate::manifest::{Component, Manifest};
use crate::temp;
use error_chain::error_chain;
use error_chain::error_chain_processing;
use error_chain::{impl_error_chain_kind, impl_error_chain_processed, impl_extract_backtrace};
use std::io::{self, Write};
use std::path::PathBuf;

pub const TOOLSTATE_MSG: &str =
    "if you require these components, please install and use the latest successful build version, \
     which you can find at https://rust-lang-nursery.github.io/rust-toolstate, for example.\n\
     rustup install nightly-2018-12-27";

error_chain! {
    links {
        Utils(rustup_utils::Error, rustup_utils::ErrorKind);
    }

    foreign_links {
        Temp(temp::Error);
        Io(io::Error);
    }

    errors {
        InvalidToolchainName(t: String) {
            description("invalid toolchain name")
            display("invalid toolchain name: '{}'", t)
        }
        InvalidCustomToolchainName(t: String) {
            description("invalid custom toolchain name")
            display("invalid custom toolchain name: '{}'", t)
        }
        ChecksumFailed {
            url: String,
            expected: String,
            calculated: String,
        } {
            description("checksum failed")
            display("checksum failed, expected: '{}', calculated: '{}'",
                    expected,
                    calculated)
        }
        ComponentConflict {
            name: String,
            path: PathBuf,
        } {
            description("conflicting component")
            display("failed to install component: '{}', detected conflict: '{:?}'",
                    name,
                    path)
        }
        ComponentMissingFile {
            name: String,
            path: PathBuf,
        } {
            description("missing file in component")
            display("failure removing component '{}', directory does not exist: '{:?}'",
                    name,
                    path)
        }
        ComponentMissingDir {
            name: String,
            path: PathBuf,
        } {
            description("missing directory in component")
            display("failure removing component '{}', directory does not exist: '{:?}'",
                    name,
                    path)
        }
        CorruptComponent(name: String) {
            description("corrupt component manifest")
            display("component manifest for '{}' is corrupt", name)
        }
        ExtractingPackage {
            description("failed to extract package")
        }
        BadInstallerVersion(v: String) {
            description("unsupported installer version")
            display("unsupported installer version: {}", v)
        }
        BadInstalledMetadataVersion(v: String) {
            description("unsupported metadata version in existing installation")
            display("unsupported metadata version in existing installation: {}", v)
        }
        ComponentDirPermissionsFailed {
            description("I/O error walking directory during install")
        }
        ComponentFilePermissionsFailed {
            description("error setting file permissions during install")
        }
        ComponentDownloadFailed(c: String) {
            description("component download failed")
            display("component download failed for {}", c)
        }
        Parsing(e: toml::de::Error) {
            description("error parsing manifest")
        }
        UnsupportedVersion(v: String) {
            description("unsupported manifest version")
            display("manifest version '{}' is not supported", v)
        }
        MissingPackageForComponent(name: String) {
            description("missing package for component")
            display("server sent a broken manifest: missing package for component {}", name)
        }
        MissingPackageForRename(name: String) {
            description("missing package for the target of a rename")
            display("server sent a broken manifest: missing package for the target of a rename {}", name)
        }
        RequestedComponentsUnavailable(c: Vec<Component>, manifest: Manifest) {
            description("some requested components are unavailable to download")
            display("{}", component_unavailable_msg(&c, &manifest))
        }
    }
}

fn component_unavailable_msg(cs: &[Component], manifest: &Manifest) -> String {
    assert!(!cs.is_empty());

    let mut buf = vec![];

    if cs.len() == 1 {
        let _ = write!(
            buf,
            "component {} is unavailable for download",
            &cs[0].description(manifest)
        );
    } else {
        use itertools::Itertools;
        let same_target = cs
            .iter()
            .all(|c| c.target == cs[0].target || c.target.is_none());
        if same_target {
            let mut cs_strs = cs.iter().map(|c| format!("'{}'", c.short_name(manifest)));
            let cs_str = cs_strs.join(", ");
            let _ = write!(
                buf,
                "some components unavailable for download: {}\n{}",
                cs_str, TOOLSTATE_MSG,
            );
        } else {
            let mut cs_strs = cs.iter().map(|c| c.description(manifest));
            let cs_str = cs_strs.join(", ");
            let _ = write!(
                buf,
                "some components unavailable for download: {}\n{}",
                cs_str, TOOLSTATE_MSG,
            );
        }
    }

    String::from_utf8(buf).expect("")
}
<commit_msg>Make the error more verbose<commit_after>use crate::manifest::{Component, Manifest};
use crate::temp;
use error_chain::error_chain;
use error_chain::error_chain_processing;
use error_chain::{impl_error_chain_kind, impl_error_chain_processed, impl_extract_backtrace};
use std::io::{self, Write};
use std::path::PathBuf;

pub const TOOLSTATE_MSG: &str =
    "if you require these components, please install and use the latest successful build version, \
     which you can find at https://rust-lang-nursery.github.io/rust-toolstate, for example.\n\
     rustup install nightly-2018-12-27";

error_chain! {
    links {
        Utils(rustup_utils::Error, rustup_utils::ErrorKind);
    }

    foreign_links {
        Temp(temp::Error);
        Io(io::Error);
    }

    errors {
        InvalidToolchainName(t: String) {
            description("invalid toolchain name")
            display("invalid toolchain name: '{}'", t)
        }
        InvalidCustomToolchainName(t: String) {
            description("invalid custom toolchain name")
            display("invalid custom toolchain name: '{}'", t)
        }
        ChecksumFailed {
            url: String,
            expected: String,
            calculated: String,
        } {
            description("checksum failed")
            display("checksum failed, expected: '{}', calculated: '{}'",
                    expected,
                    calculated)
        }
        ComponentConflict {
            name: String,
            path: PathBuf,
        } {
            description("conflicting component")
            display("failed to install component: '{}', detected conflict: '{:?}'",
                    name,
                    path)
        }
        ComponentMissingFile {
            name: String,
            path: PathBuf,
        } {
            description("missing file in component")
            display("failure removing component '{}', directory does not exist: '{:?}'",
                    name,
                    path)
        }
        ComponentMissingDir {
            name: String,
            path: PathBuf,
        } {
            description("missing directory in component")
            display("failure removing component '{}', directory does not exist: '{:?}'",
                    name,
                    path)
        }
        CorruptComponent(name: String) {
            description("corrupt component manifest")
            display("component manifest for '{}' is corrupt", name)
        }
        ExtractingPackage {
            description("failed to extract package (perhaps you ran out of disk space?)")
        }
        BadInstallerVersion(v: String) {
            description("unsupported installer version")
            display("unsupported installer version: {}", v)
        }
        BadInstalledMetadataVersion(v: String) {
            description("unsupported metadata version in existing installation")
            display("unsupported metadata version in existing installation: {}", v)
        }
        ComponentDirPermissionsFailed {
            description("I/O error walking directory during install")
        }
        ComponentFilePermissionsFailed {
            description("error setting file permissions during install")
        }
        ComponentDownloadFailed(c: String) {
            description("component download failed")
            display("component download failed for {}", c)
        }
        Parsing(e: toml::de::Error) {
            description("error parsing manifest")
        }
        UnsupportedVersion(v: String) {
            description("unsupported manifest version")
            display("manifest version '{}' is not supported", v)
        }
        MissingPackageForComponent(name: String) {
            description("missing package for component")
            display("server sent a broken manifest: missing package for component {}", name)
        }
        MissingPackageForRename(name: String) {
            description("missing package for the target of a rename")
            display("server sent a broken manifest: missing package for the target of a rename {}", name)
        }
        RequestedComponentsUnavailable(c: Vec<Component>, manifest: Manifest) {
            description("some requested components are unavailable to download")
            display("{}", component_unavailable_msg(&c, &manifest))
        }
    }
}

fn component_unavailable_msg(cs: &[Component], manifest: &Manifest) -> String {
    assert!(!cs.is_empty());

    let mut buf = vec![];

    if cs.len() == 1 {
        let _ = write!(
            buf,
            "component {} is unavailable for download",
            &cs[0].description(manifest)
        );
    } else {
        use itertools::Itertools;
        let same_target = cs
            .iter()
            .all(|c| c.target == cs[0].target || c.target.is_none());
        if same_target {
            let mut cs_strs = cs.iter().map(|c| format!("'{}'", c.short_name(manifest)));
            let cs_str = cs_strs.join(", ");
            let _ = write!(
                buf,
                "some components unavailable for download: {}\n{}",
                cs_str, TOOLSTATE_MSG,
            );
        } else {
            let mut cs_strs = cs.iter().map(|c| c.description(manifest));
            let cs_str = cs_strs.join(", ");
            let _ = write!(
                buf,
                "some components unavailable for download: {}\n{}",
                cs_str, TOOLSTATE_MSG,
            );
        }
    }

    String::from_utf8(buf).expect("")
}
<|endoftext|>


<commit_before>//! R_ext/Applic.h
//!
//! Code based automatically generated by rust-bindgen.

pub use super::boolean::*;
pub use super::rs::*;
pub use super::blas::*;

pub type integr_fn =
    extern "C" fn(x: *mut ::libc::c_double, n: ::libc::c_int,
                  ex: *mut ::libc::c_void) -> ();
pub type optimfn =
    extern "C" fn(arg1: ::libc::c_int, arg2: *mut ::libc::c_double,
                  arg3: *mut ::libc::c_void) -> ::libc::c_double;
pub type optimgr =
    extern "C" fn(arg1: ::libc::c_int, arg2: *mut ::libc::c_double,
                  arg3: *mut ::libc::c_double, arg4: *mut ::libc::c_void)
        -> ();
pub type fcn_p =
    ::std::option::Option<extern "C" fn(arg1: ::libc::c_int,
                                        arg2: *mut ::libc::c_double,
                                        arg3: *mut ::libc::c_double,
                                        arg4: *mut ::libc::c_void) -> ()>;
pub type d2fcn_p =
    ::std::option::Option<extern "C" fn(arg1: ::libc::c_int,
                                        arg2: ::libc::c_int,
                                        arg3: *mut ::libc::c_double,
                                        arg4: *mut ::libc::c_double,
                                        arg5: *mut ::libc::c_void) -> ()>;
#[link(name = "R")]
extern {
    pub fn Rdqags(f: integr_fn,
                  ex: *mut ::libc::c_void,
                  a: *mut ::libc::c_double,
                  b: *mut ::libc::c_double,
                  epsabs: *mut ::libc::c_double,
                  epsrel: *mut ::libc::c_double,
                  result: *mut ::libc::c_double,
                  abserr: *mut ::libc::c_double,
                  neval: *mut ::libc::c_int,
                  ier: *mut ::libc::c_int,
                  limit: *mut ::libc::c_int,
                  lenw: *mut ::libc::c_int,
                  last: *mut ::libc::c_int,
                  iwork: *mut ::libc::c_int,
                  work: *mut ::libc::c_double)
                  -> ();
    pub fn Rdqagi(f: integr_fn,
                  ex: *mut ::libc::c_void,
                  bound: *mut ::libc::c_double,
                  inf: *mut ::libc::c_int,
                  epsabs: *mut ::libc::c_double,
                  epsrel: *mut ::libc::c_double,
                  result: *mut ::libc::c_double,
                  abserr: *mut ::libc::c_double,
                  neval: *mut ::libc::c_int,
                  ier: *mut ::libc::c_int,
                  limit: *mut ::libc::c_int,
                  lenw: *mut ::libc::c_int,
                  last: *mut ::libc::c_int,
                  iwork: *mut ::libc::c_int,
                  work: *mut ::libc::c_double)
                  -> ();
    pub fn vmmin(n: ::libc::c_int,
                 b: *mut ::libc::c_double,
                 Fmin: *mut ::libc::c_double,
                 _fn: optimfn,
                 gr: optimgr,
                 maxit: ::libc::c_int,
                 trace: ::libc::c_int,
                 mask: *mut ::libc::c_int,
                 abstol: ::libc::c_double,
                 reltol: ::libc::c_double,
                 nREPORT: ::libc::c_int,
                 ex: *mut ::libc::c_void,
                 fncount: *mut ::libc::c_int,
                 grcount: *mut ::libc::c_int,
                 fail: *mut ::libc::c_int)
                 -> ();
    pub fn nmmin(n: ::libc::c_int,
                 Bvec: *mut ::libc::c_double,
                 X: *mut ::libc::c_double,
                 Fmin: *mut ::libc::c_double,
                 _fn: optimfn,
                 fail: *mut ::libc::c_int,
                 abstol: ::libc::c_double,
                 intol: ::libc::c_double,
                 ex: *mut ::libc::c_void,
                 alpha: ::libc::c_double,
                 bet: ::libc::c_double,
                 gamm: ::libc::c_double,
                 trace: ::libc::c_int,
                 fncount: *mut ::libc::c_int,
                 maxit: ::libc::c_int)
                 -> ();
    pub fn cgmin(n: ::libc::c_int,
                 Bvec: *mut ::libc::c_double,
                 X: *mut ::libc::c_double,
                 Fmin: *mut ::libc::c_double,
                 _fn: optimfn,
                 gr: optimgr,
                 fail: *mut ::libc::c_int,
                 abstol: ::libc::c_double,
                 intol: ::libc::c_double,
                 ex: *mut ::libc::c_void,
                 _type: ::libc::c_int,
                 trace: ::libc::c_int,
                 fncount: *mut ::libc::c_int,
                 grcount: *mut ::libc::c_int,
                 maxit: ::libc::c_int)
                 -> ();
    pub fn lbfgsb(n: ::libc::c_int,
                  m: ::libc::c_int,
                  x: *mut ::libc::c_double,
                  l: *mut ::libc::c_double,
                  u: *mut ::libc::c_double,
                  nbd: *mut ::libc::c_int,
                  Fmin: *mut ::libc::c_double,
                  _fn: optimfn,
                  gr: optimgr,
                  fail: *mut ::libc::c_int,
                  ex: *mut ::libc::c_void,
                  factr: ::libc::c_double,
                  pgtol: ::libc::c_double,
                  fncount: *mut ::libc::c_int,
                  grcount: *mut ::libc::c_int,
                  maxit: ::libc::c_int,
                  msg: *mut ::libc::c_char,
                  trace: ::libc::c_int,
                  nREPORT: ::libc::c_int)
                  -> ();
    pub fn samin(n: ::libc::c_int,
                 pb: *mut ::libc::c_double,
                 yb: *mut ::libc::c_double,
                 _fn: optimfn,
                 maxit: ::libc::c_int,
                 tmax: ::libc::c_int,
                 ti: ::libc::c_double,
                 trace: ::libc::c_int,
                 ex: *mut ::libc::c_void)
                 -> ();
    pub fn findInterval(xt: *mut ::libc::c_double,
                        n: ::libc::c_int,
                        x: ::libc::c_double,
                        rightmost_closed: Rboolean,
                        all_inside: Rboolean,
                        ilo: ::libc::c_int,
                        mflag: *mut ::libc::c_int)
                        -> ::libc::c_int;
    pub fn dqrqty_(x: *mut ::libc::c_double,
                   n: *mut ::libc::c_int,
                   k: *mut ::libc::c_int,
                   qraux: *mut ::libc::c_double,
                   y: *mut ::libc::c_double,
                   ny: *mut ::libc::c_int,
                   qty: *mut ::libc::c_double)
                   -> ();
    pub fn dqrqy_(x: *mut ::libc::c_double,
                  n: *mut ::libc::c_int,
                  k: *mut ::libc::c_int,
                  qraux: *mut ::libc::c_double,
                  y: *mut ::libc::c_double,
                  ny: *mut ::libc::c_int,
                  qy: *mut ::libc::c_double)
                  -> ();
    pub fn dqrcf_(x: *mut ::libc::c_double,
                  n: *mut ::libc::c_int,
                  k: *mut ::libc::c_int,
                  qraux: *mut ::libc::c_double,
                  y: *mut ::libc::c_double,
                  ny: *mut ::libc::c_int,
                  b: *mut ::libc::c_double,
                  info: *mut ::libc::c_int)
                  -> ();
    pub fn dqrrsd_(x: *mut ::libc::c_double,
                   n: *mut ::libc::c_int,
                   k: *mut ::libc::c_int,
                   qraux: *mut ::libc::c_double,
                   y: *mut ::libc::c_double,
                   ny: *mut ::libc::c_int,
                   rsd: *mut ::libc::c_double)
                   -> ();
    pub fn dqrxb_(x: *mut ::libc::c_double,
                  n: *mut ::libc::c_int,
                  k: *mut ::libc::c_int,
                  qraux: *mut ::libc::c_double,
                  y: *mut ::libc::c_double,
                  ny: *mut ::libc::c_int,
                  xb: *mut ::libc::c_double)
                  -> ();
    pub fn R_pretty(lo: *mut ::libc::c_double,
                    up: *mut ::libc::c_double,
                    ndiv: *mut ::libc::c_int,
                    min_n: ::libc::c_int,
                    shrink_sml: ::libc::c_double,
                    high_u_fact: *mut ::libc::c_double,
                    eps_correction: ::libc::c_int,
                    return_bounds: ::libc::c_int)
                    -> ::libc::c_double;
    pub fn fdhess(n: ::libc::c_int,
                  x: *mut ::libc::c_double,
                  fval: ::libc::c_double,
                  fun: fcn_p,
                  state: *mut ::libc::c_void,
                  h: *mut ::libc::c_double,
                  nfd: ::libc::c_int,
                  step: *mut ::libc::c_double,
                  f: *mut ::libc::c_double,
                  ndigit: ::libc::c_int,
                  typx: *mut ::libc::c_double)
                  -> ();
    pub fn optif9(nr: ::libc::c_int,
                  n: ::libc::c_int,
                  x: *mut ::libc::c_double,
                  fcn: fcn_p,
                  d1fcn: fcn_p,
                  d2fcn: d2fcn_p,
                  state: *mut ::libc::c_void,
                  typsiz: *mut ::libc::c_double,
                  fscale: ::libc::c_double,
                  method: ::libc::c_int,
                  iexp: ::libc::c_int,
                  msg: *mut ::libc::c_int,
                  ndigit: ::libc::c_int,
                  itnlim: ::libc::c_int,
                  iagflg: ::libc::c_int,
                  iahflg: ::libc::c_int,
                  dlt: ::libc::c_double,
                  gradtl: ::libc::c_double,
                  stepmx: ::libc::c_double,
                  steptl: ::libc::c_double,
                  xpls: *mut ::libc::c_double,
                  fpls: *mut ::libc::c_double,
                  gpls: *mut ::libc::c_double,
                  itrmcd: *mut ::libc::c_int,
                  a: *mut ::libc::c_double,
                  wrk: *mut ::libc::c_double,
                  itncnt: *mut ::libc::c_int)
                  -> ();
    pub fn dqrdc2_(x: *mut ::libc::c_double,
                   ldx: *mut ::libc::c_int,
                   n: *mut ::libc::c_int,
                   p: *mut ::libc::c_int,
                   tol: *mut ::libc::c_double,
                   rank: *mut ::libc::c_int,
                   qraux: *mut ::libc::c_double,
                   pivot: *mut ::libc::c_int,
                   work: *mut ::libc::c_double)
                   -> ();
    pub fn dqrls_(x: *mut ::libc::c_double,
                  n: *mut ::libc::c_int,
                  p: *mut ::libc::c_int,
                  y: *mut ::libc::c_double,
                  ny: *mut ::libc::c_int,
                  tol: *mut ::libc::c_double,
                  b: *mut ::libc::c_double,
                  rsd: *mut ::libc::c_double,
                  qty: *mut ::libc::c_double,
                  k: *mut ::libc::c_int,
                  jpvt: *mut ::libc::c_int,
                  qraux: *mut ::libc::c_double,
                  work: *mut ::libc::c_double)
                  -> ();
}
<commit_msg>Remove duplicate pub use<commit_after>//! R_ext/Applic.h
//!
//! Code based automatically generated by rust-bindgen.

pub use super::boolean::*;
pub use super::blas::*;

pub type integr_fn =
    extern "C" fn(x: *mut ::libc::c_double, n: ::libc::c_int,
                  ex: *mut ::libc::c_void) -> ();
pub type optimfn =
    extern "C" fn(arg1: ::libc::c_int, arg2: *mut ::libc::c_double,
                  arg3: *mut ::libc::c_void) -> ::libc::c_double;
pub type optimgr =
    extern "C" fn(arg1: ::libc::c_int, arg2: *mut ::libc::c_double,
                  arg3: *mut ::libc::c_double, arg4: *mut ::libc::c_void)
        -> ();
pub type fcn_p =
    ::std::option::Option<extern "C" fn(arg1: ::libc::c_int,
                                        arg2: *mut ::libc::c_double,
                                        arg3: *mut ::libc::c_double,
                                        arg4: *mut ::libc::c_void) -> ()>;
pub type d2fcn_p =
    ::std::option::Option<extern "C" fn(arg1: ::libc::c_int,
                                        arg2: ::libc::c_int,
                                        arg3: *mut ::libc::c_double,
                                        arg4: *mut ::libc::c_double,
                                        arg5: *mut ::libc::c_void) -> ()>;
#[link(name = "R")]
extern {
    pub fn Rdqags(f: integr_fn,
                  ex: *mut ::libc::c_void,
                  a: *mut ::libc::c_double,
                  b: *mut ::libc::c_double,
                  epsabs: *mut ::libc::c_double,
                  epsrel: *mut ::libc::c_double,
                  result: *mut ::libc::c_double,
                  abserr: *mut ::libc::c_double,
                  neval: *mut ::libc::c_int,
                  ier: *mut ::libc::c_int,
                  limit: *mut ::libc::c_int,
                  lenw: *mut ::libc::c_int,
                  last: *mut ::libc::c_int,
                  iwork: *mut ::libc::c_int,
                  work: *mut ::libc::c_double)
                  -> ();
    pub fn Rdqagi(f: integr_fn,
                  ex: *mut ::libc::c_void,
                  bound: *mut ::libc::c_double,
                  inf: *mut ::libc::c_int,
                  epsabs: *mut ::libc::c_double,
                  epsrel: *mut ::libc::c_double,
                  result: *mut ::libc::c_double,
                  abserr: *mut ::libc::c_double,
                  neval: *mut ::libc::c_int,
                  ier: *mut ::libc::c_int,
                  limit: *mut ::libc::c_int,
                  lenw: *mut ::libc::c_int,
                  last: *mut ::libc::c_int,
                  iwork: *mut ::libc::c_int,
                  work: *mut ::libc::c_double)
                  -> ();
    pub fn vmmin(n: ::libc::c_int,
                 b: *mut ::libc::c_double,
                 Fmin: *mut ::libc::c_double,
                 _fn: optimfn,
                 gr: optimgr,
                 maxit: ::libc::c_int,
                 trace: ::libc::c_int,
                 mask: *mut ::libc::c_int,
                 abstol: ::libc::c_double,
                 reltol: ::libc::c_double,
                 nREPORT: ::libc::c_int,
                 ex: *mut ::libc::c_void,
                 fncount: *mut ::libc::c_int,
                 grcount: *mut ::libc::c_int,
                 fail: *mut ::libc::c_int)
                 -> ();
    pub fn nmmin(n: ::libc::c_int,
                 Bvec: *mut ::libc::c_double,
                 X: *mut ::libc::c_double,
                 Fmin: *mut ::libc::c_double,
                 _fn: optimfn,
                 fail: *mut ::libc::c_int,
                 abstol: ::libc::c_double,
                 intol: ::libc::c_double,
                 ex: *mut ::libc::c_void,
                 alpha: ::libc::c_double,
                 bet: ::libc::c_double,
                 gamm: ::libc::c_double,
                 trace: ::libc::c_int,
                 fncount: *mut ::libc::c_int,
                 maxit: ::libc::c_int)
                 -> ();
    pub fn cgmin(n: ::libc::c_int,
                 Bvec: *mut ::libc::c_double,
                 X: *mut ::libc::c_double,
                 Fmin: *mut ::libc::c_double,
                 _fn: optimfn,
                 gr: optimgr,
                 fail: *mut ::libc::c_int,
                 abstol: ::libc::c_double,
                 intol: ::libc::c_double,
                 ex: *mut ::libc::c_void,
                 _type: ::libc::c_int,
                 trace: ::libc::c_int,
                 fncount: *mut ::libc::c_int,
                 grcount: *mut ::libc::c_int,
                 maxit: ::libc::c_int)
                 -> ();
    pub fn lbfgsb(n: ::libc::c_int,
                  m: ::libc::c_int,
                  x: *mut ::libc::c_double,
                  l: *mut ::libc::c_double,
                  u: *mut ::libc::c_double,
                  nbd: *mut ::libc::c_int,
                  Fmin: *mut ::libc::c_double,
                  _fn: optimfn,
                  gr: optimgr,
                  fail: *mut ::libc::c_int,
                  ex: *mut ::libc::c_void,
                  factr: ::libc::c_double,
                  pgtol: ::libc::c_double,
                  fncount: *mut ::libc::c_int,
                  grcount: *mut ::libc::c_int,
                  maxit: ::libc::c_int,
                  msg: *mut ::libc::c_char,
                  trace: ::libc::c_int,
                  nREPORT: ::libc::c_int)
                  -> ();
    pub fn samin(n: ::libc::c_int,
                 pb: *mut ::libc::c_double,
                 yb: *mut ::libc::c_double,
                 _fn: optimfn,
                 maxit: ::libc::c_int,
                 tmax: ::libc::c_int,
                 ti: ::libc::c_double,
                 trace: ::libc::c_int,
                 ex: *mut ::libc::c_void)
                 -> ();
    pub fn findInterval(xt: *mut ::libc::c_double,
                        n: ::libc::c_int,
                        x: ::libc::c_double,
                        rightmost_closed: Rboolean,
                        all_inside: Rboolean,
                        ilo: ::libc::c_int,
                        mflag: *mut ::libc::c_int)
                        -> ::libc::c_int;
    pub fn dqrqty_(x: *mut ::libc::c_double,
                   n: *mut ::libc::c_int,
                   k: *mut ::libc::c_int,
                   qraux: *mut ::libc::c_double,
                   y: *mut ::libc::c_double,
                   ny: *mut ::libc::c_int,
                   qty: *mut ::libc::c_double)
                   -> ();
    pub fn dqrqy_(x: *mut ::libc::c_double,
                  n: *mut ::libc::c_int,
                  k: *mut ::libc::c_int,
                  qraux: *mut ::libc::c_double,
                  y: *mut ::libc::c_double,
                  ny: *mut ::libc::c_int,
                  qy: *mut ::libc::c_double)
                  -> ();
    pub fn dqrcf_(x: *mut ::libc::c_double,
                  n: *mut ::libc::c_int,
                  k: *mut ::libc::c_int,
                  qraux: *mut ::libc::c_double,
                  y: *mut ::libc::c_double,
                  ny: *mut ::libc::c_int,
                  b: *mut ::libc::c_double,
                  info: *mut ::libc::c_int)
                  -> ();
    pub fn dqrrsd_(x: *mut ::libc::c_double,
                   n: *mut ::libc::c_int,
                   k: *mut ::libc::c_int,
                   qraux: *mut ::libc::c_double,
                   y: *mut ::libc::c_double,
                   ny: *mut ::libc::c_int,
                   rsd: *mut ::libc::c_double)
                   -> ();
    pub fn dqrxb_(x: *mut ::libc::c_double,
                  n: *mut ::libc::c_int,
                  k: *mut ::libc::c_int,
                  qraux: *mut ::libc::c_double,
                  y: *mut ::libc::c_double,
                  ny: *mut ::libc::c_int,
                  xb: *mut ::libc::c_double)
                  -> ();
    pub fn R_pretty(lo: *mut ::libc::c_double,
                    up: *mut ::libc::c_double,
                    ndiv: *mut ::libc::c_int,
                    min_n: ::libc::c_int,
                    shrink_sml: ::libc::c_double,
                    high_u_fact: *mut ::libc::c_double,
                    eps_correction: ::libc::c_int,
                    return_bounds: ::libc::c_int)
                    -> ::libc::c_double;
    pub fn fdhess(n: ::libc::c_int,
                  x: *mut ::libc::c_double,
                  fval: ::libc::c_double,
                  fun: fcn_p,
                  state: *mut ::libc::c_void,
                  h: *mut ::libc::c_double,
                  nfd: ::libc::c_int,
                  step: *mut ::libc::c_double,
                  f: *mut ::libc::c_double,
                  ndigit: ::libc::c_int,
                  typx: *mut ::libc::c_double)
                  -> ();
    pub fn optif9(nr: ::libc::c_int,
                  n: ::libc::c_int,
                  x: *mut ::libc::c_double,
                  fcn: fcn_p,
                  d1fcn: fcn_p,
                  d2fcn: d2fcn_p,
                  state: *mut ::libc::c_void,
                  typsiz: *mut ::libc::c_double,
                  fscale: ::libc::c_double,
                  method: ::libc::c_int,
                  iexp: ::libc::c_int,
                  msg: *mut ::libc::c_int,
                  ndigit: ::libc::c_int,
                  itnlim: ::libc::c_int,
                  iagflg: ::libc::c_int,
                  iahflg: ::libc::c_int,
                  dlt: ::libc::c_double,
                  gradtl: ::libc::c_double,
                  stepmx: ::libc::c_double,
                  steptl: ::libc::c_double,
                  xpls: *mut ::libc::c_double,
                  fpls: *mut ::libc::c_double,
                  gpls: *mut ::libc::c_double,
                  itrmcd: *mut ::libc::c_int,
                  a: *mut ::libc::c_double,
                  wrk: *mut ::libc::c_double,
                  itncnt: *mut ::libc::c_int)
                  -> ();
    pub fn dqrdc2_(x: *mut ::libc::c_double,
                   ldx: *mut ::libc::c_int,
                   n: *mut ::libc::c_int,
                   p: *mut ::libc::c_int,
                   tol: *mut ::libc::c_double,
                   rank: *mut ::libc::c_int,
                   qraux: *mut ::libc::c_double,
                   pivot: *mut ::libc::c_int,
                   work: *mut ::libc::c_double)
                   -> ();
    pub fn dqrls_(x: *mut ::libc::c_double,
                  n: *mut ::libc::c_int,
                  p: *mut ::libc::c_int,
                  y: *mut ::libc::c_double,
                  ny: *mut ::libc::c_int,
                  tol: *mut ::libc::c_double,
                  b: *mut ::libc::c_double,
                  rsd: *mut ::libc::c_double,
                  qty: *mut ::libc::c_double,
                  k: *mut ::libc::c_int,
                  jpvt: *mut ::libc::c_int,
                  qraux: *mut ::libc::c_double,
                  work: *mut ::libc::c_double)
                  -> ();
}
<|endoftext|>


<commit_before>//! Getting the Git status of files and directories.

use std::path::{Path, PathBuf};
use std::sync::Mutex;

use git2;

use fs::fields as f;

/// A **Git cache** is assembled based on the user’s input arguments.
///
/// This uses vectors to avoid the overhead of hashing: it’s not worth it when the
/// expected number of Git repositories per exa invocation is 0 or 1...
pub struct GitCache {

    /// A list of discovered Git repositories and their paths.
    repos: Vec<GitRepo>,

    /// Paths that we’ve confirmed do not have Git repositories underneath them.
    misses: Vec<PathBuf>,
}

impl GitCache {
    pub fn has_anything_for(&self, index: &Path) -> bool {
        self.repos.iter().any(|e| e.has_path(index))
    }

    pub fn get(&self, index: &Path, prefix_lookup: bool) -> f::Git {
        self.repos.iter()
            .find(|e| e.has_path(index))
            .map(|repo| repo.search(index, prefix_lookup))
            .unwrap_or_default()
    }
}

use std::iter::FromIterator;
impl FromIterator<PathBuf> for GitCache {
    fn from_iter<I: IntoIterator<Item=PathBuf>>(iter: I) -> Self {
        let iter = iter.into_iter();
        let mut git = GitCache {
            repos: Vec::with_capacity(iter.size_hint().0),
            misses: Vec::new(),
        };

        for path in iter {
            if git.misses.contains(&path) {
                debug!("Skipping {:?} because it already came back Gitless", path);
            }
            else if git.repos.iter().any(|e| e.has_path(&path)) {
                debug!("Skipping {:?} because we already queried it", path);
            }
            else {
                match GitRepo::discover(path) {
                    Ok(r) => {
                        if let Some(mut r2) = git.repos.iter_mut().find(|e| e.has_workdir(&r.workdir)) {
                            debug!("Adding to existing repo (workdir matches with {:?})", r2.workdir);
                            r2.extra_paths.push(r.original_path);
                            continue;
                        }

                        debug!("Discovered new Git repo");
                        git.repos.push(r);
                    },
                    Err(miss) => git.misses.push(miss),
                }
            }
        }

        git
    }
}

/// A **Git repository** is one we’ve discovered somewhere on the filesystem.
pub struct GitRepo {

    /// The queryable contents of the repository: either a `git2` repo, or the
    /// cached results from when we queried it last time.
    contents: Mutex<GitContents>,

    /// The working directory of this repository.
    /// This is used to check whether two repositories are the same.
    workdir: PathBuf,

    /// The path that was originally checked to discover this repository.
    /// This is as important as the extra_paths (it gets checked first), but
    /// is separate to avoid having to deal with a non-empty Vec.
    original_path: PathBuf,

    /// Any other paths that were checked only to result in this same
    /// repository.
    extra_paths: Vec<PathBuf>,
}

/// A repository’s queried state.
enum GitContents {

    /// All the interesting Git stuff goes through this.
    Before { repo: git2::Repository },

    /// Temporary value used in `repo_to_statuses` so we can move the
    /// repository out of the `Before` variant.
    Processing,

    /// The data we’ve extracted from the repository, but only after we’ve
    /// actually done so.
    After { statuses: Git }
}

impl GitRepo {

    /// Searches through this repository for a path (to a file or directory,
    /// depending on the prefix-lookup flag) and returns its Git status.
    ///
    /// Actually querying the `git2` repository for the mapping of paths to
    /// Git statuses is only done once, and gets cached so we don't need to
    /// re-query the entire repository the times after that.
    ///
    /// The temporary `Processing` enum variant is used after the `git2`
    /// repository is moved out, but before the results have been moved in!
    /// See https://stackoverflow.com/q/45985827/3484614
    fn search(&self, index: &Path, prefix_lookup: bool) -> f::Git {
        use self::GitContents::*;
        use std::mem::replace;

        let mut contents = self.contents.lock().unwrap();
        if let After { ref statuses } = *contents {
            debug!("Git repo {:?} has been found in cache", &self.workdir);
            return statuses.status(index, prefix_lookup);
        }

        debug!("Querying Git repo {:?} for the first time", &self.workdir);
        let repo = replace(&mut *contents, Processing).inner_repo();
        let statuses = repo_to_statuses(repo, &self.workdir);
        let result = statuses.status(index, prefix_lookup);
        let _processing = replace(&mut *contents, After { statuses });
        result
    }

    /// Whether this repository has the given working directory.
    fn has_workdir(&self, path: &Path) -> bool {
        self.workdir == path
    }

    /// Whether this repository cares about the given path at all.
    fn has_path(&self, path: &Path) -> bool {
        path.starts_with(&self.original_path) || self.extra_paths.iter().any(|e| path.starts_with(e))
    }

    /// Searches for a Git repository at any point above the given path.
    /// Returns the original buffer if none is found.
    fn discover(path: PathBuf) -> Result<GitRepo, PathBuf> {
        info!("Searching for Git repository above {:?}", path);
        let repo = match git2::Repository::discover(&path) {
            Ok(r) => r,
            Err(e) => {
                error!("Error discovering Git repositories: {:?}", e);
                return Err(path);
            }
        };

        match repo.workdir().map(|wd| wd.to_path_buf()) {
            Some(workdir) => {
                let contents = Mutex::new(GitContents::Before { repo });
                Ok(GitRepo { contents, workdir, original_path: path, extra_paths: Vec::new() })
            },
            None => {
                warn!("Repository has no workdir?");
                Err(path)
            }
        }
    }
}

impl GitContents {
    /// Assumes that the repository hasn’t been queried, and extracts it
    /// (consuming the value) if it has. This is needed because the entire
    /// enum variant gets replaced when a repo is queried (see above).
    fn inner_repo(self) -> git2::Repository {
        if let GitContents::Before { repo } = self {
            repo
        }
        else {
            unreachable!("Tried to extract a non-Repository")
        }
    }
}

/// Iterates through a repository’s statuses, consuming it and returning the
/// mapping of files to their Git status.
/// We will have already used the working directory at this point, so it gets
/// passed in rather than deriving it from the `Repository` again.
fn repo_to_statuses(repo: git2::Repository, workdir: &Path) -> Git {
    let mut statuses = Vec::new();

    info!("Getting Git statuses for repo with workdir {:?}", workdir);
    match repo.statuses(None) {
        Ok(es) => {
            for e in es.iter() {
                let path = workdir.join(Path::new(e.path().unwrap()));
                let elem = (path, e.status());
                statuses.push(elem);
            }
        },
        Err(e) => error!("Error looking up Git statuses: {:?}", e),
    }

    Git { statuses }
}

// The `repo.statuses` call above takes a long time. exa debug output:
//
//   20.311276  INFO:exa::fs::feature::git: Getting Git statuses for repo with workdir "/vagrant/"
//   20.799610  DEBUG:exa::output::table: Getting Git status for file "./Cargo.toml"
//
// Even inserting another logging line immediately afterwards doesn't make it
// look any faster.

/// Container of Git statuses for all the files in this folder’s Git repository.
struct Git {
    statuses: Vec<(PathBuf, git2::Status)>,
}

impl Git {

    /// Get either the file or directory status for the given path.
    /// “Prefix lookup” means that it should report an aggregate status of all
    /// paths starting with the given prefix (in other words, a directory).
    fn status(&self, index: &Path, prefix_lookup: bool) -> f::Git {
        if prefix_lookup { self.dir_status(index) }
                    else { self.file_status(index) }
    }

    /// Get the status for the file at the given path.
    fn file_status(&self, file: &Path) -> f::Git {
        let path = reorient(file);
        self.statuses.iter()
            .find(|p| p.0.as_path() == path)
            .map(|&(_, s)| f::Git { staged: index_status(s), unstaged: working_tree_status(s) })
            .unwrap_or_default()
    }

    /// Get the combined status for all the files whose paths begin with the
    /// path that gets passed in. This is used for getting the status of
    /// directories, which don’t really have an ‘official’ status.
    fn dir_status(&self, dir: &Path) -> f::Git {
        let path = reorient(dir);
        let s = self.statuses.iter()
                             .filter(|p| p.0.starts_with(&path))
                             .fold(git2::Status::empty(), |a, b| a | b.1);

        f::Git { staged: index_status(s), unstaged: working_tree_status(s) }
    }
}

/// Converts a path to an absolute path based on the current directory.
/// Paths need to be absolute for them to be compared properly, otherwise
/// you’d ask a repo about “./README.md” but it only knows about
/// “/vagrant/REAMDE.md”, prefixed by the workdir.
fn reorient(path: &Path) -> PathBuf {
    use std::env::current_dir;
    // I’m not 100% on this func tbh
    match current_dir() {
        Err(_)  => Path::new(".").join(&path),
        Ok(dir) => dir.join(&path),
    }
}

/// The character to display if the file has been modified, but not staged.
fn working_tree_status(status: git2::Status) -> f::GitStatus {
    match status {
        s if s.contains(git2::Status::WT_NEW)         => f::GitStatus::New,
        s if s.contains(git2::Status::WT_MODIFIED)    => f::GitStatus::Modified,
        s if s.contains(git2::Status::WT_DELETED)     => f::GitStatus::Deleted,
        s if s.contains(git2::Status::WT_RENAMED)     => f::GitStatus::Renamed,
        s if s.contains(git2::Status::WT_TYPECHANGE)  => f::GitStatus::TypeChange,
        _                                             => f::GitStatus::NotModified,
    }
}

/// The character to display if the file has been modified and the change
/// has been staged.
fn index_status(status: git2::Status) -> f::GitStatus {
    match status {
        s if s.contains(git2::Status::INDEX_NEW)         => f::GitStatus::New,
        s if s.contains(git2::Status::INDEX_MODIFIED)    => f::GitStatus::Modified,
        s if s.contains(git2::Status::INDEX_DELETED)     => f::GitStatus::Deleted,
        s if s.contains(git2::Status::INDEX_RENAMED)     => f::GitStatus::Renamed,
        s if s.contains(git2::Status::INDEX_TYPECHANGE)  => f::GitStatus::TypeChange,
        _                                                => f::GitStatus::NotModified,
    }
}
<commit_msg>fixed git status not working in directories containing '../'<commit_after>//! Getting the Git status of files and directories.

use std::path::{Path, PathBuf};
use std::sync::Mutex;

use git2;

use fs::fields as f;

/// A **Git cache** is assembled based on the user’s input arguments.
///
/// This uses vectors to avoid the overhead of hashing: it’s not worth it when the
/// expected number of Git repositories per exa invocation is 0 or 1...
pub struct GitCache {

    /// A list of discovered Git repositories and their paths.
    repos: Vec<GitRepo>,

    /// Paths that we’ve confirmed do not have Git repositories underneath them.
    misses: Vec<PathBuf>,
}

impl GitCache {
    pub fn has_anything_for(&self, index: &Path) -> bool {
        self.repos.iter().any(|e| e.has_path(index))
    }

    pub fn get(&self, index: &Path, prefix_lookup: bool) -> f::Git {
        self.repos.iter()
            .find(|e| e.has_path(index))
            .map(|repo| repo.search(index, prefix_lookup))
            .unwrap_or_default()
    }
}

use std::iter::FromIterator;
impl FromIterator<PathBuf> for GitCache {
    fn from_iter<I: IntoIterator<Item=PathBuf>>(iter: I) -> Self {
        let iter = iter.into_iter();
        let mut git = GitCache {
            repos: Vec::with_capacity(iter.size_hint().0),
            misses: Vec::new(),
        };

        for path in iter {
            if git.misses.contains(&path) {
                debug!("Skipping {:?} because it already came back Gitless", path);
            }
            else if git.repos.iter().any(|e| e.has_path(&path)) {
                debug!("Skipping {:?} because we already queried it", path);
            }
            else {
                match GitRepo::discover(path) {
                    Ok(r) => {
                        if let Some(r2) = git.repos.iter_mut().find(|e| e.has_workdir(&r.workdir)) {
                            debug!("Adding to existing repo (workdir matches with {:?})", r2.workdir);
                            r2.extra_paths.push(r.original_path);
                            continue;
                        }

                        debug!("Discovered new Git repo");
                        git.repos.push(r);
                    },
                    Err(miss) => git.misses.push(miss),
                }
            }
        }

        git
    }
}

/// A **Git repository** is one we’ve discovered somewhere on the filesystem.
pub struct GitRepo {

    /// The queryable contents of the repository: either a `git2` repo, or the
    /// cached results from when we queried it last time.
    contents: Mutex<GitContents>,

    /// The working directory of this repository.
    /// This is used to check whether two repositories are the same.
    workdir: PathBuf,

    /// The path that was originally checked to discover this repository.
    /// This is as important as the extra_paths (it gets checked first), but
    /// is separate to avoid having to deal with a non-empty Vec.
    original_path: PathBuf,

    /// Any other paths that were checked only to result in this same
    /// repository.
    extra_paths: Vec<PathBuf>,
}

/// A repository’s queried state.
enum GitContents {

    /// All the interesting Git stuff goes through this.
    Before { repo: git2::Repository },

    /// Temporary value used in `repo_to_statuses` so we can move the
    /// repository out of the `Before` variant.
    Processing,

    /// The data we’ve extracted from the repository, but only after we’ve
    /// actually done so.
    After { statuses: Git }
}

impl GitRepo {

    /// Searches through this repository for a path (to a file or directory,
    /// depending on the prefix-lookup flag) and returns its Git status.
    ///
    /// Actually querying the `git2` repository for the mapping of paths to
    /// Git statuses is only done once, and gets cached so we don't need to
    /// re-query the entire repository the times after that.
    ///
    /// The temporary `Processing` enum variant is used after the `git2`
    /// repository is moved out, but before the results have been moved in!
    /// See https://stackoverflow.com/q/45985827/3484614
    fn search(&self, index: &Path, prefix_lookup: bool) -> f::Git {
        use self::GitContents::*;
        use std::mem::replace;

        let mut contents = self.contents.lock().unwrap();
        if let After { ref statuses } = *contents {
            debug!("Git repo {:?} has been found in cache", &self.workdir);
            return statuses.status(index, prefix_lookup);
        }

        debug!("Querying Git repo {:?} for the first time", &self.workdir);
        let repo = replace(&mut *contents, Processing).inner_repo();
        let statuses = repo_to_statuses(repo, &self.workdir);
        let result = statuses.status(index, prefix_lookup);
        let _processing = replace(&mut *contents, After { statuses });
        result
    }

    /// Whether this repository has the given working directory.
    fn has_workdir(&self, path: &Path) -> bool {
        self.workdir == path
    }

    /// Whether this repository cares about the given path at all.
    fn has_path(&self, path: &Path) -> bool {
        path.starts_with(&self.original_path) || self.extra_paths.iter().any(|e| path.starts_with(e))
    }

    /// Searches for a Git repository at any point above the given path.
    /// Returns the original buffer if none is found.
    fn discover(path: PathBuf) -> Result<GitRepo, PathBuf> {
        info!("Searching for Git repository above {:?}", path);
        let repo = match git2::Repository::discover(&path) {
            Ok(r) => r,
            Err(e) => {
                error!("Error discovering Git repositories: {:?}", e);
                return Err(path);
            }
        };

        match repo.workdir().map(|wd| wd.to_path_buf()) {
            Some(workdir) => {
                let contents = Mutex::new(GitContents::Before { repo });
                Ok(GitRepo { contents, workdir, original_path: path, extra_paths: Vec::new() })
            },
            None => {
                warn!("Repository has no workdir?");
                Err(path)
            }
        }
    }
}

impl GitContents {
    /// Assumes that the repository hasn’t been queried, and extracts it
    /// (consuming the value) if it has. This is needed because the entire
    /// enum variant gets replaced when a repo is queried (see above).
    fn inner_repo(self) -> git2::Repository {
        if let GitContents::Before { repo } = self {
            repo
        }
        else {
            unreachable!("Tried to extract a non-Repository")
        }
    }
}

/// Iterates through a repository’s statuses, consuming it and returning the
/// mapping of files to their Git status.
/// We will have already used the working directory at this point, so it gets
/// passed in rather than deriving it from the `Repository` again.
fn repo_to_statuses(repo: git2::Repository, workdir: &Path) -> Git {
    let mut statuses = Vec::new();

    info!("Getting Git statuses for repo with workdir {:?}", workdir);
    match repo.statuses(None) {
        Ok(es) => {
            for e in es.iter() {
                let path = workdir.join(Path::new(e.path().unwrap()));
                let elem = (path, e.status());
                statuses.push(elem);
            }
        },
        Err(e) => error!("Error looking up Git statuses: {:?}", e),
    }

    Git { statuses }
}

// The `repo.statuses` call above takes a long time. exa debug output:
//
//   20.311276  INFO:exa::fs::feature::git: Getting Git statuses for repo with workdir "/vagrant/"
//   20.799610  DEBUG:exa::output::table: Getting Git status for file "./Cargo.toml"
//
// Even inserting another logging line immediately afterwards doesn't make it
// look any faster.

/// Container of Git statuses for all the files in this folder’s Git repository.
struct Git {
    statuses: Vec<(PathBuf, git2::Status)>,
}

impl Git {

    /// Get either the file or directory status for the given path.
    /// “Prefix lookup” means that it should report an aggregate status of all
    /// paths starting with the given prefix (in other words, a directory).
    fn status(&self, index: &Path, prefix_lookup: bool) -> f::Git {
        if prefix_lookup { self.dir_status(index) }
                    else { self.file_status(index) }
    }

    /// Get the status for the file at the given path.
    fn file_status(&self, file: &Path) -> f::Git {
        let path = reorient(file);
        self.statuses.iter()
            .find(|p| p.0.as_path() == path)
            .map(|&(_, s)| f::Git { staged: index_status(s), unstaged: working_tree_status(s) })
            .unwrap_or_default()
    }

    /// Get the combined status for all the files whose paths begin with the
    /// path that gets passed in. This is used for getting the status of
    /// directories, which don’t really have an ‘official’ status.
    fn dir_status(&self, dir: &Path) -> f::Git {
        let path = reorient(dir);
        let s = self.statuses.iter()
                             .filter(|p| p.0.starts_with(&path))
                             .fold(git2::Status::empty(), |a, b| a | b.1);

        f::Git { staged: index_status(s), unstaged: working_tree_status(s) }
    }
}

/// Converts a path to an absolute path based on the current directory.
/// Paths need to be absolute for them to be compared properly, otherwise
/// you’d ask a repo about “./README.md” but it only knows about
/// “/vagrant/REAMDE.md”, prefixed by the workdir.
fn reorient(path: &Path) -> PathBuf {
    use std::env::current_dir;
    // I’m not 100% on this func tbh
    match current_dir() {
        Err(_)  => Path::new(".").join(&path),
        Ok(dir) => dir.join(&path),
    }.canonicalize().unwrap()   // errors can be ignored here because they only occur if
                                // the path does not exist / a component is not a folder
}

/// The character to display if the file has been modified, but not staged.
fn working_tree_status(status: git2::Status) -> f::GitStatus {
    match status {
        s if s.contains(git2::Status::WT_NEW)         => f::GitStatus::New,
        s if s.contains(git2::Status::WT_MODIFIED)    => f::GitStatus::Modified,
        s if s.contains(git2::Status::WT_DELETED)     => f::GitStatus::Deleted,
        s if s.contains(git2::Status::WT_RENAMED)     => f::GitStatus::Renamed,
        s if s.contains(git2::Status::WT_TYPECHANGE)  => f::GitStatus::TypeChange,
        _                                             => f::GitStatus::NotModified,
    }
}

/// The character to display if the file has been modified and the change
/// has been staged.
fn index_status(status: git2::Status) -> f::GitStatus {
    match status {
        s if s.contains(git2::Status::INDEX_NEW)         => f::GitStatus::New,
        s if s.contains(git2::Status::INDEX_MODIFIED)    => f::GitStatus::Modified,
        s if s.contains(git2::Status::INDEX_DELETED)     => f::GitStatus::Deleted,
        s if s.contains(git2::Status::INDEX_RENAMED)     => f::GitStatus::Renamed,
        s if s.contains(git2::Status::INDEX_TYPECHANGE)  => f::GitStatus::TypeChange,
        _                                                => f::GitStatus::NotModified,
    }
}
<|endoftext|>


<commit_before>#![feature (plugin, custom_derive)]
#![plugin (serde_macros)]

#[macro_use]
extern crate time_steward as steward;
extern crate rand;
extern crate serde;

use steward::{RowId, DeterministicRandomId, ColumnId, PredictorId, Column, TimeStewardSettings};
use std::marker::PhantomData;
use rand::{Rng, SeedableRng, ChaChaRng};

macro_rules! printlnerr(
    ($($arg:tt)*) => { {use std::io::Write;
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

/*Tried to hunt an ICE, but failed
trait Hack <B> {type Whatever;}
use std::iter::{self, Empty};
struct IntoIter; impl <'a> IntoIterator for & 'a IntoIter {type Item = i32; type IntoIter = Empty <i32>; fn into_iter(self)->Self::IntoIter {iter::empty()}}
struct Original <B> {field: PhantomData <B>}
impl <B> Hack <B> for Original <B> {type Whatever = IntoIter;}
struct Wrapper <B, Inner: Hack <B>> {field: PhantomData <(B, Inner)>,}
impl <B, Inner: Hack <B>> Hack <B> for Wrapper <B, Inner> {type Whatever = Inner::Whatever;}
fn thingy <B, H: Hack <B>>() where for <'a> & 'a H::Whatever: IntoIterator <Item = i32> {}
#[test]
fn chunk() {thingy::<i32, Wrapper <i32, Wrapper <i32, Original<i32>>>>();}
*/

#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug, Default)]
struct Basics;
impl steward::Basics for Basics {
  type Time = DeterministicRandomId;
  type Constants = DeterministicRandomId;
  type Columns = PhantomData <ColumnHack>;
}
  struct ColumnHack;
  impl Column for ColumnHack {
    type FieldType = DeterministicRandomId;
    fn column_id()->ColumnId {ColumnId (0x8e07f5045b91d636)}
  }
// As in, "putting it through its paces"
#[allow (unused_must_use)]
fn paces <Steward: steward::IncrementalTimeSteward <Basics>, G: Rng> (generator: &mut G)
where Steward::Settings: Clone,
for <'a> & 'a Steward::Snapshot: IntoIterator <Item = steward::SnapshotEntry <'a, Basics>>
{

  let mut settings = Steward::Settings::new();
  settings.insert_predictor (PredictorId (0x59c5a4cce2789300), ColumnHack::column_id(),
    time_steward_predictor! (Basics, struct Predictor {}, | &self, accessor, id | {
      let whatever = accessor.get::<ColumnHack> (id).unwrap().clone();
      for index in 0.. (id.data() [0] ^ accessor.constants().data() [0]).leading_zeros() {
        let data_0 = DeterministicRandomId::new (& (index, whatever, id));
        let data_1 = DeterministicRandomId::new (& (index, whatever, id, "something different"));
        accessor.predict_at_time (data_0, time_steward_event! (Basics, struct Event {id: RowId = id, data: DeterministicRandomId = data_1}, | &self, mutator | {
          if mutator.extended_now().iteration >10 {
            println!("Help! Loop!");
            mutator.set:: <ColumnHack> (self.id, None);
            return;
          }
          let mut generator = mutator.gen::<ChaChaRng>();
          for _ in 0.. (mutator.gen::<u32> ().leading_zeros()*10) {
            match mutator.gen_range::<u8>(0, 16) {
              0 => mutator.set:: <ColumnHack> (RowId::new (& generator.gen::<u8>()), Some (RowId::new (& generator.gen::<u8>()))),
              1 => mutator.set:: <ColumnHack> (RowId::new (& generator.gen::<u8>()), None),
              2 => if mutator.get:: <ColumnHack> (RowId::new (& generator.gen::<u8>())).is_some() { mutator.gen_id(); },
              _ =>(),
            }
          }
        }));
      }
    })
  );

  let mut stew: Steward = Steward::new_empty (RowId::new (& generator.gen::<u64>()), settings.clone());
  let mut snapshots: Vec<Steward::Snapshot> = Vec::new();

  fn display_snapshot <S: steward::Snapshot <Basics>> (snapshot: & S)->(usize, DeterministicRandomId) {(snapshot.num_fields(), snapshot.now().clone())}

  for index in 0..10000 {
    let time = RowId::new (& generator.gen::<u64>());
    let choice = generator.gen_range::<u64> (0, 16);
    //println!(" Index: {:?}\n Time: {:?}\n ValidSince: {:?}\n    Present: {:?}\n Choice: {:?}\n\n ", index, time, stew.valid_since(), stew.updated_until_before (), choice);
    /*for snapshot in snapshots.iter() {
      snapshot.into_iter().count();
      if let Some (snapshot2) = Steward::from_snapshot::<Steward::Snapshot> (snapshot, settings.clone()).snapshot_before (& snapshot.now()) {
        snapshot2.into_iter().count();
      }
    }*/
    match choice {
      0 => { println!("inserting fiat event"); stew.insert_fiat_event (time, RowId::new (& index),

      time_steward_event! (Basics, struct Event {}, | &self, mutator | {
        let who =RowId::new (& mutator.gen::<u8>());
          mutator.get:: <ColumnHack> (who);
          let who =RowId::new (& mutator.gen::<u8>());
          let what = if mutator.gen() {None} else {Some (mutator.gen_id())};
          mutator.set:: <ColumnHack> (who, what);

         })

      );},
      1 => if let Some (limit) = stew.updated_until_before () {if let Some (snapshot) = stew.snapshot_before (& limit) {println!("recording snapshot {:?}", display_snapshot::<Steward::Snapshot> (&snapshot));
      //(&snapshot).into_iter().count();
      snapshots.push (snapshot);}},
      //2 => if snapshots.len() >30 {println!("deleting snapshot"); let who = generator.gen_range (0, snapshots.len()); snapshots.remove (who);},
      3 => if let Some (snapshot) = generator.choose (snapshots.as_slice()) { println!("reloading from snapshot {:?}", display_snapshot::<Steward::Snapshot> (&snapshot)); stew = Steward::from_snapshot::<Steward::Snapshot> (snapshot, settings.clone());},
      _ => {
        println!("stepping");
        stew.step();
        //println!(" ValidSince: {:?}\n    Present: {:?} ", stew.valid_since(), stew.updated_until_before ());
        //use steward::MomentaryAccessor; if let Some (limit) = stew.updated_until_before () {if let Some (snapshot) = stew.snapshot_before (& limit) {println!("checking snapshot at {:?}", snapshot.now()); (&snapshot).into_iter().count();}}

      },
      //_ => ()
    }
  }
}

#[test]
//#[ignore]
fn main() {
  let mut generator = ChaChaRng::from_seed(& [1337]);
  use steward::stewards::{amortized, memoized_flat, flat_to_inefficient_full, crossverified};
  paces:: <crossverified::Steward <Basics,
    amortized::Steward <Basics>,
    flat_to_inefficient_full::Steward <Basics, memoized_flat::Steward <Basics>>
  >,_> (&mut generator);
}
<commit_msg>Finished fixing build<commit_after>#![feature (plugin, custom_derive)]
#![plugin (serde_macros)]

#[macro_use]
extern crate time_steward as steward;
extern crate rand;
extern crate serde;

use steward::{RowId, DeterministicRandomId, ColumnId, PredictorId, Column, TimeStewardSettings, ColumnType};
use rand::{Rng, SeedableRng, ChaChaRng};

macro_rules! printlnerr(
    ($($arg:tt)*) => { {use std::io::Write;
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

/*Tried to hunt an ICE, but failed
trait Hack <B> {type Whatever;}
use std::iter::{self, Empty};
struct IntoIter; impl <'a> IntoIterator for & 'a IntoIter {type Item = i32; type IntoIter = Empty <i32>; fn into_iter(self)->Self::IntoIter {iter::empty()}}
struct Original <B> {field: PhantomData <B>}
impl <B> Hack <B> for Original <B> {type Whatever = IntoIter;}
struct Wrapper <B, Inner: Hack <B>> {field: PhantomData <(B, Inner)>,}
impl <B, Inner: Hack <B>> Hack <B> for Wrapper <B, Inner> {type Whatever = Inner::Whatever;}
fn thingy <B, H: Hack <B>>() where for <'a> & 'a H::Whatever: IntoIterator <Item = i32> {}
#[test]
fn chunk() {thingy::<i32, Wrapper <i32, Wrapper <i32, Original<i32>>>>();}
*/

#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug, Default)]
struct Basics;
impl steward::Basics for Basics {
  type Time = DeterministicRandomId;
  type Constants = DeterministicRandomId;
  type Columns = ColumnType <ColumnHack>;
}
  struct ColumnHack;
  impl Column for ColumnHack {
    type FieldType = DeterministicRandomId;
    fn column_id()->ColumnId {ColumnId (0x8e07f5045b91d636)}
  }
// As in, "putting it through its paces"
#[allow (unused_must_use)]
fn paces <Steward: steward::IncrementalTimeSteward <Basics>, G: Rng> (generator: &mut G)
where Steward::Settings: Clone,
for <'a> & 'a Steward::Snapshot: IntoIterator <Item = steward::SnapshotEntry <'a, Basics>>
{

  let mut settings = Steward::Settings::new();
  settings.insert_predictor (PredictorId (0x59c5a4cce2789300), ColumnHack::column_id(),
    time_steward_predictor! (Basics, struct Predictor {}, | &self, accessor, id | {
      let whatever = accessor.get::<ColumnHack> (id).unwrap().clone();
      for index in 0.. (id.data() [0] ^ accessor.constants().data() [0]).leading_zeros() {
        let data_0 = DeterministicRandomId::new (& (index, whatever, id));
        let data_1 = DeterministicRandomId::new (& (index, whatever, id, "something different"));
        accessor.predict_at_time (data_0, time_steward_event! (Basics, struct Event {id: RowId = id, data: DeterministicRandomId = data_1}, | &self, mutator | {
          if mutator.extended_now().iteration >10 {
            println!("Help! Loop!");
            mutator.set:: <ColumnHack> (self.id, None);
            return;
          }
          let mut generator = mutator.gen::<ChaChaRng>();
          for _ in 0.. (mutator.gen::<u32> ().leading_zeros()*10) {
            match mutator.gen_range::<u8>(0, 16) {
              0 => mutator.set:: <ColumnHack> (RowId::new (& generator.gen::<u8>()), Some (RowId::new (& generator.gen::<u8>()))),
              1 => mutator.set:: <ColumnHack> (RowId::new (& generator.gen::<u8>()), None),
              2 => if mutator.get:: <ColumnHack> (RowId::new (& generator.gen::<u8>())).is_some() { mutator.gen_id(); },
              _ =>(),
            }
          }
        }));
      }
    })
  );

  let mut stew: Steward = Steward::new_empty (RowId::new (& generator.gen::<u64>()), settings.clone());
  let mut snapshots: Vec<Steward::Snapshot> = Vec::new();

  fn display_snapshot <S: steward::Snapshot <Basics>> (snapshot: & S)->(usize, DeterministicRandomId) {(snapshot.num_fields(), snapshot.now().clone())}

  for index in 0..10000 {
    let time = RowId::new (& generator.gen::<u64>());
    let choice = generator.gen_range::<u64> (0, 16);
    //println!(" Index: {:?}\n Time: {:?}\n ValidSince: {:?}\n    Present: {:?}\n Choice: {:?}\n\n ", index, time, stew.valid_since(), stew.updated_until_before (), choice);
    /*for snapshot in snapshots.iter() {
      snapshot.into_iter().count();
      if let Some (snapshot2) = Steward::from_snapshot::<Steward::Snapshot> (snapshot, settings.clone()).snapshot_before (& snapshot.now()) {
        snapshot2.into_iter().count();
      }
    }*/
    match choice {
      0 => { println!("inserting fiat event"); stew.insert_fiat_event (time, RowId::new (& index),

      time_steward_event! (Basics, struct Event {}, | &self, mutator | {
        let who =RowId::new (& mutator.gen::<u8>());
          mutator.get:: <ColumnHack> (who);
          let who =RowId::new (& mutator.gen::<u8>());
          let what = if mutator.gen() {None} else {Some (mutator.gen_id())};
          mutator.set:: <ColumnHack> (who, what);

         })

      );},
      1 => if let Some (limit) = stew.updated_until_before () {if let Some (snapshot) = stew.snapshot_before (& limit) {println!("recording snapshot {:?}", display_snapshot::<Steward::Snapshot> (&snapshot));
      //(&snapshot).into_iter().count();
      snapshots.push (snapshot);}},
      //2 => if snapshots.len() >30 {println!("deleting snapshot"); let who = generator.gen_range (0, snapshots.len()); snapshots.remove (who);},
      3 => if let Some (snapshot) = generator.choose (snapshots.as_slice()) { println!("reloading from snapshot {:?}", display_snapshot::<Steward::Snapshot> (&snapshot)); stew = Steward::from_snapshot::<Steward::Snapshot> (snapshot, settings.clone());},
      _ => {
        println!("stepping");
        stew.step();
        //println!(" ValidSince: {:?}\n    Present: {:?} ", stew.valid_since(), stew.updated_until_before ());
        //use steward::MomentaryAccessor; if let Some (limit) = stew.updated_until_before () {if let Some (snapshot) = stew.snapshot_before (& limit) {println!("checking snapshot at {:?}", snapshot.now()); (&snapshot).into_iter().count();}}

      },
      //_ => ()
    }
  }
}

#[test]
//#[ignore]
fn main() {
  let mut generator = ChaChaRng::from_seed(& [1337]);
  use steward::stewards::{amortized, memoized_flat, flat_to_inefficient_full, crossverified};
  paces:: <crossverified::Steward <Basics,
    amortized::Steward <Basics>,
    flat_to_inefficient_full::Steward <Basics, memoized_flat::Steward <Basics>>
  >,_> (&mut generator);
}
<|endoftext|>


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

//! Definition of the genesis block. Placeholder for now.

// required for genesis replacement
//! #![allow(unused_imports)]

use chrono::prelude::{TimeZone, Utc};

use crate::core;
use crate::global;
use crate::pow::{Difficulty, Proof, ProofOfWork};
use crate::util;
use crate::util::secp::constants::SINGLE_BULLET_PROOF_SIZE;
use crate::util::secp::pedersen::{Commitment, RangeProof};
use crate::util::secp::Signature;

use crate::core::hash::Hash;
use crate::keychain::BlindingFactor;

/// Genesis block definition for development networks. The proof of work size
/// is small enough to mine it on the fly, so it does not contain its own
/// proof of work solution. Can also be easily mutated for different tests.
pub fn genesis_dev() -> core::Block {
	core::Block::with_header(core::BlockHeader {
		height: 0,
		// previous: core::hash::Hash([0xff; 32]),
		timestamp: Utc.ymd(1997, 8, 4).and_hms(0, 0, 0),
		pow: ProofOfWork {
			nonce: global::get_genesis_nonce(),
			..Default::default()
		},
		..Default::default()
	})
}

/// Placeholder for floonet genesis block, will definitely change before
/// release
pub fn genesis_floo() -> core::Block {
	let gen = core::Block::with_header(core::BlockHeader {
		height: 0,
		timestamp: Utc.ymd(2018, 12, 20).and_hms(20, 0, 0), // REPLACE
		prev_root: Hash::default(),                         // REPLACE
		output_root: Hash::default(),                       // REPLACE
		range_proof_root: Hash::default(),                  // REPLACE
		kernel_root: Hash::default(),                       // REPLACE
		total_kernel_offset: BlindingFactor::zero(),        // REPLACE
		output_mmr_size: 1,
		kernel_mmr_size: 1,
		pow: ProofOfWork {
			total_difficulty: Difficulty::from_num(10_u64.pow(6)),
			secondary_scaling: 1856,
			nonce: 1, // REPLACE
			proof: Proof {
				nonces: vec![0; 42], // REPLACE
				edge_bits: 29,
			},
		},
		..Default::default()
	});
	let kernel = core::TxKernel {
		features: core::KernelFeatures::COINBASE,
		fee: 0,
		lock_height: 0,
		excess: Commitment::from_vec(vec![]), // REPLACE
		excess_sig: Signature::from_raw_data(&[0; 64]).unwrap(), //REPLACE
	};
	let output = core::Output {
		features: core::OutputFeatures::COINBASE,
		commit: Commitment::from_vec(vec![]), // REPLACE
		proof: RangeProof {
			plen: SINGLE_BULLET_PROOF_SIZE,
			proof: [0; SINGLE_BULLET_PROOF_SIZE], // REPLACE
		},
	};
	gen.with_reward(output, kernel)
}

/// Placeholder for mainnet genesis block, will definitely change before
/// release so no use trying to pre-mine it.
pub fn genesis_main() -> core::Block {
	let gen = core::Block::with_header(core::BlockHeader {
		height: 0,
		timestamp: Utc.ymd(2019, 1, 15).and_hms(12, 0, 0), // REPLACE
		prev_root: Hash::default(),                        // REPLACE
		output_root: Hash::default(),                      // REPLACE
		range_proof_root: Hash::default(),                 // REPLACE
		kernel_root: Hash::default(),                      // REPLACE
		total_kernel_offset: BlindingFactor::zero(),       // REPLACE
		output_mmr_size: 1,
		kernel_mmr_size: 1,
		pow: ProofOfWork {
			total_difficulty: Difficulty::from_num(10_u64.pow(8)),
			secondary_scaling: 1856,
			nonce: 1, // REPLACE
			proof: Proof {
				nonces: vec![0; 42], // REPLACE
				edge_bits: 29,
			},
		},
		..Default::default()
	});
	let kernel = core::TxKernel {
		features: core::KernelFeatures::COINBASE,
		fee: 0,
		lock_height: 0,
		excess: Commitment::from_vec(vec![]), // REPLACE
		excess_sig: Signature::from_raw_data(&[0; 64]).unwrap(), //REPLACE
	};
	let output = core::Output {
		features: core::OutputFeatures::COINBASE,
		commit: Commitment::from_vec(vec![]), // REPLACE
		proof: RangeProof {
			plen: SINGLE_BULLET_PROOF_SIZE,
			proof: [0; SINGLE_BULLET_PROOF_SIZE], // REPLACE
		},
	};
	gen.with_reward(output, kernel)
}

#[cfg(test)]
mod test {
	use super::*;
	use crate::ser;
	use crate::core::hash::Hashed;

	// TODO hardcode the hashes once genesis is set
	#[test]
	fn floonet_genesis_hash() {
		let gen_hash = genesis_floo().hash();
		println!("floonet genesis hash: {}", gen_hash.to_hex());
		let gen_bin = ser::ser_vec(&genesis_floo()).unwrap();
		println!("floonet genesis full hash: {}\n", gen_bin.hash().to_hex());
		//assert_eq!(gene_hash.to_hex, "");
	}

	// TODO hardcode the hashes once genesis is set
	#[test]
	fn mainnet_genesis_hash() {
		let gen_hash = genesis_main().hash();
		println!("mainnet genesis hash: {}", gen_hash.to_hex());
		let gen_bin = ser::ser_vec(&genesis_main()).unwrap();
		println!("mainnet genesis full hash: {}\n", gen_bin.hash().to_hex());
		//assert_eq!(gene_hash.to_hex, "");
	}
}
<commit_msg>Floonet genesis block<commit_after>// Copyright 2018 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Definition of the genesis block. Placeholder for now.

// required for genesis replacement
//! #![allow(unused_imports)]

use chrono::prelude::{TimeZone, Utc};

use crate::core;
use crate::global;
use crate::pow::{Difficulty, Proof, ProofOfWork};
use crate::util;
use crate::util::secp::constants::SINGLE_BULLET_PROOF_SIZE;
use crate::util::secp::pedersen::{Commitment, RangeProof};
use crate::util::secp::Signature;

use crate::core::hash::Hash;
use crate::keychain::BlindingFactor;

/// Genesis block definition for development networks. The proof of work size
/// is small enough to mine it on the fly, so it does not contain its own
/// proof of work solution. Can also be easily mutated for different tests.
pub fn genesis_dev() -> core::Block {
	core::Block::with_header(core::BlockHeader {
		height: 0,
		// previous: core::hash::Hash([0xff; 32]),
		timestamp: Utc.ymd(1997, 8, 4).and_hms(0, 0, 0),
		pow: ProofOfWork {
			nonce: global::get_genesis_nonce(),
			..Default::default()
		},
		..Default::default()
	})
}

/// Placeholder for floonet genesis block, will definitely change before
/// release
pub fn genesis_floo() -> core::Block {
	let gen = core::Block::with_header(core::BlockHeader {
		height: 0,
timestamp: Utc.ymd(2018, 12, 20).and_hms(20, 58, 32),
prev_root: Hash::from_hex("ae144568a9ec32faf57e9ca5b5f0997d33f30bd3352fd84c953e6526d847c26b").unwrap(),
output_root: Hash::from_hex("47d2570266451203c62cd003c706e3ec37e9cb4292316744abfa68a1b133bc1c").unwrap(),
range_proof_root: Hash::from_hex("53ea93e80fe37e9a0cbb9c1a1ddf467213922481a4435921aacf55ffb3f388fc").unwrap(),
kernel_root: Hash::from_hex("3ff7655b2846a1313dd72e1c516a2fa262638fabc8e0d4c1dddf80773bbd472d").unwrap(),
total_kernel_offset: BlindingFactor::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap(),
		output_mmr_size: 1,
		kernel_mmr_size: 1,
		pow: ProofOfWork {
			total_difficulty: Difficulty::from_num(10_u64.pow(6)),
			secondary_scaling: 1856,
nonce: 22,
			proof: Proof {
nonces: vec![48398361, 50434294, 73758991, 93493375, 94716564, 101961133, 153506566, 159476458, 164019912, 208165915, 216747111, 218441011, 221663358, 262514197, 264746362, 278423427, 282069592, 284508695, 297003554, 327321117, 327780367, 329474453, 333639856, 356316379, 366419120, 381872178, 386038638, 389726932, 390055244, 392425788, 399530286, 426997994, 436531599, 456084550, 456375883, 459156409, 474067792, 480904139, 487380747, 489307817, 496780560, 530227836],
				edge_bits: 29,
			},
		},
		..Default::default()
	});
	let kernel = core::TxKernel {
		features: core::KernelFeatures::COINBASE,
		fee: 0,
		lock_height: 0,
excess: Commitment::from_vec(util::from_hex("0817a9e97a070ba5f9fa185c093b4b13b262ed4b4712b6f7c92881b27168f9a2cb".to_string()).unwrap()),
excess_sig: Signature::from_raw_data(&[172, 131, 105, 224, 31, 11, 0, 70, 109, 54, 230, 184, 177, 138, 46, 137, 202, 215, 152, 37, 192, 132, 88, 254, 110, 76, 57, 32, 42, 13, 19, 89, 82, 89, 116, 66, 30, 132, 120, 148, 122, 100, 97, 38, 141, 219, 57, 184, 171, 130, 213, 235, 83, 202, 69, 13, 213, 60, 150, 172, 33, 37, 209, 57]).unwrap(),
	};
	let output = core::Output {
		features: core::OutputFeatures::COINBASE,
commit: Commitment::from_vec(util::from_hex("08f5523cbd8b2e1dae3eefdd9dd1069e0c8a7f055a0611da79f42530c5de0d044b".to_string()).unwrap()),
		proof: RangeProof {
			plen: SINGLE_BULLET_PROOF_SIZE,
proof: [47, 196, 194, 238, 233, 164, 218, 64, 54, 92, 83, 248, 225, 116, 189, 225, 202, 66, 213, 63, 195, 209, 238, 189, 153, 198, 231, 219, 3, 146, 102, 67, 26, 7, 199, 150, 160, 244, 48, 166, 113, 6, 241, 49, 133, 248, 201, 80, 34, 19, 118, 249, 44, 213, 215, 235, 228, 187, 215, 116, 212, 203, 232, 183, 12, 66, 29, 11, 28, 17, 212, 104, 126, 203, 103, 60, 176, 149, 182, 206, 70, 138, 180, 213, 76, 99, 25, 184, 40, 177, 197, 179, 71, 63, 19, 72, 253, 129, 115, 107, 90, 249, 39, 108, 134, 10, 231, 172, 172, 59, 207, 118, 175, 124, 197, 132, 73, 154, 148, 8, 73, 26, 231, 75, 24, 134, 199, 93, 15, 43, 45, 49, 69, 167, 194, 23, 114, 16, 117, 209, 127, 123, 18, 209, 12, 34, 219, 196, 37, 7, 226, 132, 70, 111, 113, 164, 203, 175, 105, 175, 196, 62, 225, 138, 162, 176, 190, 109, 96, 210, 15, 38, 245, 200, 83, 155, 185, 111, 85, 234, 6, 3, 246, 98, 175, 127, 94, 65, 29, 78, 27, 53, 32, 230, 85, 91, 195, 112, 84, 135, 56, 207, 213, 165, 40, 248, 238, 202, 225, 142, 79, 89, 81, 197, 138, 65, 14, 232, 145, 44, 73, 6, 43, 8, 43, 42, 127, 151, 68, 18, 19, 83, 14, 142, 180, 75, 25, 4, 97, 166, 237, 212, 187, 106, 154, 36, 223, 231, 177, 58, 70, 1, 195, 113, 144, 151, 45, 185, 0, 174, 116, 212, 122, 239, 96, 1, 122, 211, 41, 96, 230, 110, 242, 145, 176, 230, 55, 143, 142, 234, 151, 49, 151, 109, 252, 120, 147, 244, 178, 73, 196, 221, 150, 85, 69, 113, 50, 166, 92, 91, 98, 188, 77, 76, 48, 192, 112, 184, 108, 143, 134, 56, 46, 119, 21, 71, 247, 119, 133, 225, 72, 15, 158, 60, 64, 71, 57, 134, 243, 228, 58, 13, 58, 209, 71, 4, 72, 87, 129, 51, 46, 64, 188, 60, 157, 56, 120, 23, 2, 47, 143, 79, 176, 54, 3, 47, 227, 124, 70, 242, 8, 59, 113, 203, 51, 65, 138, 131, 121, 45, 131, 132, 171, 161, 49, 235, 129, 39, 164, 234, 69, 172, 95, 28, 180, 118, 163, 151, 148, 66, 65, 104, 222, 232, 154, 22, 30, 149, 196, 214, 163, 93, 76, 128, 142, 233, 106, 171, 213, 148, 59, 101, 56, 22, 127, 232, 4, 63, 111, 9, 188, 163, 40, 158, 24, 65, 81, 203, 231, 93, 197, 102, 170, 70, 239, 229, 13, 172, 110, 157, 226, 112, 182, 28, 150, 222, 62, 224, 94, 182, 220, 243, 236, 62, 156, 129, 220, 127, 155, 141, 0, 243, 159, 113, 28, 158, 95, 205, 35, 72, 132, 46, 235, 176, 146, 233, 93, 111, 4, 105, 236, 176, 165, 102, 168, 188, 121, 105, 175, 197, 114, 97, 40, 2, 165, 153, 85, 135, 114, 147, 95, 216, 50, 108, 52, 225, 186, 215, 110, 122, 230, 14, 246, 141, 180, 41, 22, 132, 58, 8, 31, 187, 221, 231, 14, 33, 52, 88, 219, 200, 77, 246, 134, 18, 0, 113, 144, 6, 146, 54, 24, 113, 14, 64, 182, 116, 229, 250, 201, 126, 84, 192, 80, 13, 57, 232, 55, 113, 139, 249, 166, 231, 123, 101, 236, 147, 144, 2, 9, 51, 2, 189, 188, 200, 66, 29, 16, 22, 150, 45, 220, 15, 161, 180, 214, 244, 104, 41, 77, 171, 246, 243, 56, 47, 63, 103, 216, 151, 199, 249, 169, 165, 119, 200, 243, 161, 83, 46, 225, 195, 92, 96, 150, 0, 165, 170, 14, 211, 226, 244, 70, 218, 137, 254, 197, 175, 208, 119, 199, 121, 4, 7, 190, 118, 55, 197, 208, 41, 109, 161, 34, 33, 210, 58, 99, 81, 97, 57, 156, 57, 144, 83, 97, 49, 248, 89, 201, 88, 169, 9, 211, 34, 136, 174, 195, 224, 51, 103, 12, 237, 172, 46, 216, 5, 168],
		},
	};
	gen.with_reward(output, kernel)
}

/// Placeholder for mainnet genesis block, will definitely change before
/// release so no use trying to pre-mine it.
pub fn genesis_main() -> core::Block {
	let gen = core::Block::with_header(core::BlockHeader {
		height: 0,
		timestamp: Utc.ymd(2019, 1, 15).and_hms(12, 0, 0), // REPLACE
		prev_root: Hash::default(),                        // REPLACE
		output_root: Hash::default(),                      // REPLACE
		range_proof_root: Hash::default(),                 // REPLACE
		kernel_root: Hash::default(),                      // REPLACE
		total_kernel_offset: BlindingFactor::zero(),       // REPLACE
		output_mmr_size: 1,
		kernel_mmr_size: 1,
		pow: ProofOfWork {
			total_difficulty: Difficulty::from_num(10_u64.pow(8)),
			secondary_scaling: 1856,
			nonce: 1, // REPLACE
			proof: Proof {
				nonces: vec![0; 42], // REPLACE
				edge_bits: 29,
			},
		},
		..Default::default()
	});
	let kernel = core::TxKernel {
		features: core::KernelFeatures::COINBASE,
		fee: 0,
		lock_height: 0,
		excess: Commitment::from_vec(vec![]), // REPLACE
		excess_sig: Signature::from_raw_data(&[0; 64]).unwrap(), //REPLACE
	};
	let output = core::Output {
		features: core::OutputFeatures::COINBASE,
		commit: Commitment::from_vec(vec![]), // REPLACE
		proof: RangeProof {
			plen: SINGLE_BULLET_PROOF_SIZE,
			proof: [0; SINGLE_BULLET_PROOF_SIZE], // REPLACE
		},
	};
	gen.with_reward(output, kernel)
}

#[cfg(test)]
mod test {
	use super::*;
	use crate::ser;
	use crate::core::hash::Hashed;

	// TODO hardcode the hashes once genesis is set
	#[test]
	fn floonet_genesis_hash() {
		let gen_hash = genesis_floo().hash();
		println!("floonet genesis hash: {}", gen_hash.to_hex());
		let gen_bin = ser::ser_vec(&genesis_floo()).unwrap();
		println!("floonet genesis full hash: {}\n", gen_bin.hash().to_hex());
		//assert_eq!(gene_hash.to_hex, "");
	}

	// TODO hardcode the hashes once genesis is set
	#[test]
	fn mainnet_genesis_hash() {
		let gen_hash = genesis_main().hash();
		println!("mainnet genesis hash: {}", gen_hash.to_hex());
		let gen_bin = ser::ser_vec(&genesis_main()).unwrap();
		println!("mainnet genesis full hash: {}\n", gen_bin.hash().to_hex());
		//assert_eq!(gene_hash.to_hex, "");
	}
}
<|endoftext|>