<commit_before>use super::callee::DeferredCallResolution;
use super::MaybeInProgressTables;

use rustc_hir as hir;
use rustc_hir::def_id::{DefIdMap, LocalDefId};
use rustc_hir::HirIdMap;
use rustc_infer::infer;
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::{self, Span};
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCause, TraitEngine, TraitEngineExt};

use std::cell::RefCell;
use std::ops::Deref;

/// Closures defined within the function. For example:
///
///     fn foo() {
///         bar(move|| { ... })
///     }
///
/// Here, the function `foo()` and the closure passed to
/// `bar()` will each have their own `FnCtxt`, but they will
/// share the inherited fields.
pub struct Inherited<'a, 'tcx> {
    pub(super) infcx: InferCtxt<'a, 'tcx>,

    pub(super) typeck_results: super::MaybeInProgressTables<'a, 'tcx>,

    pub(super) locals: RefCell<HirIdMap<super::LocalTy<'tcx>>>,

    pub(super) fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,

    // Some additional `Sized` obligations badly affect type inference.
    // These obligations are added in a later stage of typeck.
    pub(super) deferred_sized_obligations:
        RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,

    // When we process a call like `c()` where `c` is a closure type,
    // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
    // `FnOnce` closure. In that case, we defer full resolution of the
    // call until upvar inference can kick in and make the
    // decision. We keep these deferred resolutions grouped by the
    // def-id of the closure, so that once we decide, we can easily go
    // back and process them.
    pub(super) deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,

    pub(super) deferred_cast_checks: RefCell<Vec<super::cast::CastCheck<'tcx>>>,

    pub(super) deferred_generator_interiors:
        RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,

    /// Reports whether this is in a const context.
    pub(super) constness: hir::Constness,

    pub(super) body_id: Option<hir::BodyId>,
}

impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
    type Target = InferCtxt<'a, 'tcx>;
    fn deref(&self) -> &Self::Target {
        &self.infcx
    }
}

/// Helper type of a temporary returned by `Inherited::build(...)`.
/// Necessary because we can't write the following bound:
/// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
pub struct InheritedBuilder<'tcx> {
    infcx: infer::InferCtxtBuilder<'tcx>,
    def_id: LocalDefId,
}

impl Inherited<'_, 'tcx> {
    pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
        let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;

        InheritedBuilder {
            infcx: tcx.infer_ctxt().with_fresh_in_progress_typeck_results(hir_owner),
            def_id,
        }
    }
}

impl<'tcx> InheritedBuilder<'tcx> {
    pub fn enter<F, R>(&mut self, f: F) -> R
    where
        F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
    {
        let def_id = self.def_id;
        self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
    }
}

impl Inherited<'a, 'tcx> {
    pub(super) fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
        let tcx = infcx.tcx;
        let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
        Self::with_constness(infcx, def_id, tcx.hir().get(item_id).constness())
    }

    pub(super) fn with_constness(
        infcx: InferCtxt<'a, 'tcx>,
        def_id: LocalDefId,
        constness: hir::Constness,
    ) -> Self {
        let tcx = infcx.tcx;
        let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
        let body_id = tcx.hir().maybe_body_owned_by(item_id);

        Inherited {
            typeck_results: MaybeInProgressTables {
                maybe_typeck_results: infcx.in_progress_typeck_results,
            },
            infcx,
            fulfillment_cx: RefCell::new(<dyn TraitEngine<'_>>::new(tcx)),
            locals: RefCell::new(Default::default()),
            deferred_sized_obligations: RefCell::new(Vec::new()),
            deferred_call_resolutions: RefCell::new(Default::default()),
            deferred_cast_checks: RefCell::new(Vec::new()),
            deferred_generator_interiors: RefCell::new(Vec::new()),
            constness,
            body_id,
        }
    }

    #[instrument(level = "debug", skip(self))]
    fn transform_predicate(&self, p: &mut ty::Predicate<'tcx>) {
        // Don't transform non-const bounds into const bounds,
        // but transform const bounds to non-const when we are
        // not in a const context.
        if let hir::Constness::NotConst = self.constness {
            let kind = p.kind();
            if let ty::PredicateKind::Trait(pred) = kind.as_ref().skip_binder() {
                let mut pred = *pred;
                pred.constness = hir::Constness::NotConst;
                *p = kind.rebind(ty::PredicateKind::Trait(pred)).to_predicate(self.tcx);
            }
        }
    }

    pub(super) fn register_predicate(&self, mut obligation: traits::PredicateObligation<'tcx>) {
        debug!("register_predicate({:?})", obligation);
        self.transform_predicate(&mut obligation.predicate);
        if obligation.has_escaping_bound_vars() {
            span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
        }
        self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
    }

    pub(super) fn register_predicates<I>(&self, obligations: I)
    where
        I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
    {
        for obligation in obligations {
            self.register_predicate(obligation);
        }
    }

    pub(super) fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
        self.register_predicates(infer_ok.obligations);
        infer_ok.value
    }

    pub(super) fn normalize_associated_types_in<T>(
        &self,
        span: Span,
        body_id: hir::HirId,
        param_env: ty::ParamEnv<'tcx>,
        value: T,
    ) -> T
    where
        T: TypeFoldable<'tcx>,
    {
        self.normalize_associated_types_in_with_cause(
            ObligationCause::misc(span, body_id),
            param_env,
            value,
        )
    }

    pub(super) fn normalize_associated_types_in_with_cause<T>(
        &self,
        cause: ObligationCause<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        value: T,
    ) -> T
    where
        T: TypeFoldable<'tcx>,
    {
        let ok = self.partially_normalize_associated_types_in(cause, param_env, value);
        debug!(?ok);
        self.register_infer_ok_obligations(ok)
    }
}
<commit_msg>Don't transform predicates in Inherited<commit_after>use super::callee::DeferredCallResolution;
use super::MaybeInProgressTables;

use rustc_hir as hir;
use rustc_hir::def_id::{DefIdMap, LocalDefId};
use rustc_hir::HirIdMap;
use rustc_infer::infer;
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::{self, Span};
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCause, TraitEngine, TraitEngineExt};

use std::cell::RefCell;
use std::ops::Deref;

/// Closures defined within the function. For example:
///
///     fn foo() {
///         bar(move|| { ... })
///     }
///
/// Here, the function `foo()` and the closure passed to
/// `bar()` will each have their own `FnCtxt`, but they will
/// share the inherited fields.
pub struct Inherited<'a, 'tcx> {
    pub(super) infcx: InferCtxt<'a, 'tcx>,

    pub(super) typeck_results: super::MaybeInProgressTables<'a, 'tcx>,

    pub(super) locals: RefCell<HirIdMap<super::LocalTy<'tcx>>>,

    pub(super) fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,

    // Some additional `Sized` obligations badly affect type inference.
    // These obligations are added in a later stage of typeck.
    pub(super) deferred_sized_obligations:
        RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,

    // When we process a call like `c()` where `c` is a closure type,
    // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
    // `FnOnce` closure. In that case, we defer full resolution of the
    // call until upvar inference can kick in and make the
    // decision. We keep these deferred resolutions grouped by the
    // def-id of the closure, so that once we decide, we can easily go
    // back and process them.
    pub(super) deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,

    pub(super) deferred_cast_checks: RefCell<Vec<super::cast::CastCheck<'tcx>>>,

    pub(super) deferred_generator_interiors:
        RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,

    /// Reports whether this is in a const context.
    pub(super) constness: hir::Constness,

    pub(super) body_id: Option<hir::BodyId>,
}

impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
    type Target = InferCtxt<'a, 'tcx>;
    fn deref(&self) -> &Self::Target {
        &self.infcx
    }
}

/// Helper type of a temporary returned by `Inherited::build(...)`.
/// Necessary because we can't write the following bound:
/// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
pub struct InheritedBuilder<'tcx> {
    infcx: infer::InferCtxtBuilder<'tcx>,
    def_id: LocalDefId,
}

impl Inherited<'_, 'tcx> {
    pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
        let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;

        InheritedBuilder {
            infcx: tcx.infer_ctxt().with_fresh_in_progress_typeck_results(hir_owner),
            def_id,
        }
    }
}

impl<'tcx> InheritedBuilder<'tcx> {
    pub fn enter<F, R>(&mut self, f: F) -> R
    where
        F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
    {
        let def_id = self.def_id;
        self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
    }
}

impl Inherited<'a, 'tcx> {
    pub(super) fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
        let tcx = infcx.tcx;
        let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
        Self::with_constness(infcx, def_id, tcx.hir().get(item_id).constness())
    }

    pub(super) fn with_constness(
        infcx: InferCtxt<'a, 'tcx>,
        def_id: LocalDefId,
        constness: hir::Constness,
    ) -> Self {
        let tcx = infcx.tcx;
        let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
        let body_id = tcx.hir().maybe_body_owned_by(item_id);

        Inherited {
            typeck_results: MaybeInProgressTables {
                maybe_typeck_results: infcx.in_progress_typeck_results,
            },
            infcx,
            fulfillment_cx: RefCell::new(<dyn TraitEngine<'_>>::new(tcx)),
            locals: RefCell::new(Default::default()),
            deferred_sized_obligations: RefCell::new(Vec::new()),
            deferred_call_resolutions: RefCell::new(Default::default()),
            deferred_cast_checks: RefCell::new(Vec::new()),
            deferred_generator_interiors: RefCell::new(Vec::new()),
            constness,
            body_id,
        }
    }

    pub(super) fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
        debug!("register_predicate({:?})", obligation);
        if obligation.has_escaping_bound_vars() {
            span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
        }
        self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
    }

    pub(super) fn register_predicates<I>(&self, obligations: I)
    where
        I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
    {
        for obligation in obligations {
            self.register_predicate(obligation);
        }
    }

    pub(super) fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
        self.register_predicates(infer_ok.obligations);
        infer_ok.value
    }

    pub(super) fn normalize_associated_types_in<T>(
        &self,
        span: Span,
        body_id: hir::HirId,
        param_env: ty::ParamEnv<'tcx>,
        value: T,
    ) -> T
    where
        T: TypeFoldable<'tcx>,
    {
        self.normalize_associated_types_in_with_cause(
            ObligationCause::misc(span, body_id),
            param_env,
            value,
        )
    }

    pub(super) fn normalize_associated_types_in_with_cause<T>(
        &self,
        cause: ObligationCause<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        value: T,
    ) -> T
    where
        T: TypeFoldable<'tcx>,
    {
        let ok = self.partially_normalize_associated_types_in(cause, param_env, value);
        debug!(?ok);
        self.register_infer_ok_obligations(ok)
    }
}
<|endoftext|>


<commit_before>use {Clipboard, Item, Result};

#[cfg(Debug)]
macro_rules! debug_println {
    ($msg:expr) => {
        println!($msg)
    },
    ($msg:expr, $rest:tt) => {
        println!($msg, $rest)
    }
}

#[cfg(not(Debug))]
macro_rules! debug_println {
    ($msg:expr) => { },
    ($msg:expr, $rest:tt) => { }
}

pub trait ClipboardExt: Clipboard {}

pub struct DummyClipboard {
    _priv: ()
}

impl Clipboard for DummyClipboard {
    fn get() -> Result<Self> where Self: Sized {
        debug_println!("Calling DummyClipboard::get()");
        Ok(DummyClipboard {
            _priv: ()
        })
    }

    fn copy(&mut self, item: &Item) -> Result<()> {
        debug_println!("calling DummyClipboard::copy(): this operation is not available");
        Ok(())
    }

    fn copy_items(&mut self, items: &[Item]) -> Result<()> {
        debug_println!("calling DummyClipboard::copy_items(): this operation is not available");
        Ok(())
    }

    fn get_paste_text(&self) -> Result<&str> {
        debug_println!("calling DummyClipboard::paste(): this operation is not available");
        Ok("")
    }

    fn get_items(&self) -> &[Item] {
        debug_println!("calling DummyClipboard::get_items(): this operation is not available");
        Ok([])
    }
}

impl ClipboardExt for DummyClipboard { }
<commit_msg>Small tidy<commit_after>use {Clipboard, Item, Result};

#[cfg(Debug)]
macro_rules! debug_println {
    ($msg:expr) => {
        println!($msg)
    },
    ($msg:expr, $rest:tt) => {
        println!($msg, $rest)
    }
}

#[cfg(not(Debug))]
macro_rules! debug_println {
    ($msg:expr) => { },
    ($msg:expr, $rest:tt) => { }
}

pub trait ClipboardExt: Clipboard {}

pub struct DummyClipboard {
    _priv: ()
}

impl Clipboard for DummyClipboard {
    fn get() -> Result<Self> {
        debug_println!("Calling DummyClipboard::get()");
        Ok(DummyClipboard {
            _priv: ()
        })
    }

    fn copy(&mut self, item: &Item) -> Result<()> {
        debug_println!("calling DummyClipboard::copy(): this operation is not available");
        Ok(())
    }

    fn copy_items(&mut self, items: &[Item]) -> Result<()> {
        debug_println!("calling DummyClipboard::copy_items(): this operation is not available");
        Ok(())
    }

    fn get_paste_text(&self) -> Result<&str> {
        debug_println!("calling DummyClipboard::paste(): this operation is not available");
        Ok("")
    }

    fn get_items(&self) -> &[Item] {
        debug_println!("calling DummyClipboard::get_items(): this operation is not available");
        Ok([])
    }
}

impl ClipboardExt for DummyClipboard { }
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Empty_directory
use std::fs;
use std::path::Path;
use std::env::args;

fn main() {

    // Open path
    let path = if let Some(arg) = args().nth(1) {
        arg
    } else {
        println!("You must give a path as argument");
        return;
    };

    let dir = Path::new(&path);

    let paths = match fs::read_dir(dir) {
        Err(e) => {
            println!("Error: {}", e);
            return;
        },
        Ok(f) => f,
    };

    if paths.count() > 0 {
        println!("Directory is not empty");
    } else {
        println!("Directory is empty");
    }
}
<commit_msg>Implemented the suggestion of @aochagavia that is a lot easier to read and is also a lot shorter too<commit_after>// http://rosettacode.org/wiki/Empty_directory
use std::fs;
use std::env::args;

fn main() {

    // Open path
    let dir = if let Some(arg) = args().nth(1) {
        arg
    } else {
        println!("You must give a path as argument");
        return;
    };

    // map function for type Result executes a function (closure)
    // on Ok(_) types but leaves Err(_) untouched.
    //
    // The directory is empty if the result of paths.count() == Ok(0)
    // In any other case, the directory is not empty
    //
    match fs::read_dir(dir).map(|paths| paths.count()) {
        Err(e) => println!("Error: {}", e),
        Ok(0) => println!("Directory is empty"),
        Ok(_) => println!("Directory is not empty")
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
mod chunk {

    use std::fmt;
    struct Address(u64, u64, u64);

    struct Chunk {
        children: [Option<Box<Chunk>>; 8],
        parent: Option<Box<Chunk>>,
        summary: i32,
        address: Address,
    }

    impl Address {
        fn from_string(address: String) -> Option<Address> {
            let mut xyz: (u64, u64, u64) = (1, 1, 1);
            let mut xyz_add: (u64, u64, u64);

            for (i, c) in address.chars().enumerate() {
                if i > 63 {
                    break;
                }
                xyz_add =  match c.to_digit(8){
                    Some(0) => (0, 0, 0),
                    Some(1) => (0, 0, 1),
                    Some(2) => (0, 1, 0),
                    Some(3) => (0, 1, 1),
                    Some(4) => (1, 0, 0),
                    Some(5) => (1, 0, 1),
                    Some(6) => (1, 1, 0),
                    Some(7) => (1, 1, 1),
                    _ => return None,
                };
                xyz = (xyz.0 << 1, xyz.1 << 1, xyz.2 << 1);
                xyz = (xyz.0 + xyz_add.0, xyz.1 + xyz_add.1, xyz.2 + xyz_add.2);
            }
            Some(Address(xyz.0, xyz.1, xyz.2))
        }
    }

    impl ToString for Address {
        fn to_string(&self) -> String {
            String::from_str("")
        }
    }

    impl PartialEq for Address {
        fn eq(&self, other: &Self) -> bool {
            (((self.0 == other.0) && (self.1 == other.1)) && (self.2 == other.2))
        }
    }

    impl fmt::Show for Address {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "Address({}, {}, {})", self.0, self.1, self.2)
        }
    }

    #[test]
    fn test_adder_from_string() {
        let known = Address(0b11, 0b11, 0b11);
        let unknown = Address::from_string(String::from_str("7"));
    }
}
<commit_msg>Fill out actual test code<commit_after>#![allow(dead_code)]
mod chunk {

    use std::fmt;
    struct Address(u64, u64, u64);

    struct Chunk {
        children: [Option<Box<Chunk>>; 8],
        parent: Option<Box<Chunk>>,
        summary: i32,
        address: Address,
    }

    impl Address {
        fn from_string(address: String) -> Option<Address> {
            let mut xyz: (u64, u64, u64) = (1, 1, 1);
            let mut xyz_add: (u64, u64, u64);

            for (i, c) in address.chars().enumerate() {
                if i > 63 {
                    break;
                }
                xyz_add =  match c.to_digit(8){
                    Some(0) => (0, 0, 0),
                    Some(1) => (0, 0, 1),
                    Some(2) => (0, 1, 0),
                    Some(3) => (0, 1, 1),
                    Some(4) => (1, 0, 0),
                    Some(5) => (1, 0, 1),
                    Some(6) => (1, 1, 0),
                    Some(7) => (1, 1, 1),
                    _ => return None,
                };
                xyz = (xyz.0 << 1, xyz.1 << 1, xyz.2 << 1);
                xyz = (xyz.0 + xyz_add.0, xyz.1 + xyz_add.1, xyz.2 + xyz_add.2);
            }
            Some(Address(xyz.0, xyz.1, xyz.2))
        }
    }

    impl ToString for Address {
        fn to_string(&self) -> String {
            String::from_str("")
        }
    }

    impl PartialEq for Address {
        fn eq(&self, other: &Self) -> bool {
            (((self.0 == other.0) && (self.1 == other.1)) && (self.2 == other.2))
        }
    }

    impl fmt::Show for Address {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "Address({}, {}, {})", self.0, self.1, self.2)
        }
    }

    #[test]
    fn test_adder_from_string() {
        let known = Option::Some(Address(0b11, 0b11, 0b11));
        let unknown = Address::from_string(String::from_str("7"));
        assert_eq!(known, unknown)
    }
}
<|endoftext|>


<commit_before>
<commit_msg>Implement factory container.<commit_after>use std::any::{ Any, AnyMutRefExt };
use std::boxed::BoxAny;
use metafactory::factory::{ Factory, Getter };

/// Proxy for configuring facotry list
/// without caring about the type used.
pub struct FactoryContainer<'a> {
    any_getter: Box<Any>,
    do_push_items: |&mut Box<Any>, Vec<Box<Any>>|:'a -> (),
    do_new_factory: |&mut Box<Any>|:'a -> Box<Any>, // Don't worry, it's like Javascript ;)
}

impl<'a> FactoryContainer<'a> {
    pub fn new<T: 'static>() -> FactoryContainer<'a> {
        FactoryContainer {
            any_getter: box FactoryVecGetter::<T>::new(),
            do_push_items: |any_getter, items| {
                let getter: &mut FactoryVecGetter<T> = any_getter
                    .downcast_mut::<FactoryVecGetter<T>>().unwrap();

                let len = items.len();
                let items_iter = items.into_iter()
                    .map(|i| *i.downcast::<Factory<T>>().ok().unwrap());

                getter.factories.reserve_exact(len);
                getter.factories.extend(items_iter);
            },
            do_new_factory: |any_getter| {
                let getter: &mut FactoryVecGetter<T> = any_getter
                    .downcast_mut::<FactoryVecGetter<T>>().unwrap();

                box Factory::<Vec<T>>::new(getter.boxed_clone())
            }
        }
    }

    /// Push factory items into container.
    ///
    /// Note that all items should already match container type:
    /// if container was created for `int`, all pushed factories should
    /// produce int. Otherwise this method will panic your app.
    pub fn push_items(&mut self, items: Vec<Box<Any>>) {
        (self.do_push_items)(&mut self.any_getter, items);
    }

    /// Produces factory usable as argument for other factories.
    ///
    /// If inner factories make `int` values, this method will make factory
    /// that makes `Vec<int>` values.
    pub fn new_factory(&mut self) -> Box<Any> {
        (self.do_new_factory)(&mut self.any_getter)
    }
}

struct FactoryVecGetter<T: 'static> {
    factories: Vec<Factory<T>>,
}

impl<T> Clone for FactoryVecGetter<T> {
    fn clone(&self) -> FactoryVecGetter<T> {
        FactoryVecGetter::<T> {
            factories: self.factories.clone()
        }
    }
}

impl<T> FactoryVecGetter<T> {
    pub fn new() -> FactoryVecGetter<T> {
        FactoryVecGetter::<T> {
            factories: Vec::with_capacity(0)
        }
    }
}

impl<T> Getter<Vec<T>> for FactoryVecGetter<T> {
    fn take(&self) -> Vec<T> {
        // Reserve exact result size.
        let mut items = Vec::<T>::with_capacity(self.factories.len());

        // Construct results from factory results.
        items.extend(
            self.factories.iter()
                .map(|f| f.take())
        );

        // I love Rust.
        items
    }

    fn boxed_clone(&self) -> Box<Getter<Vec<T>> + 'static> {
        box self.clone()
    }
}

#[cfg(test)]
mod test {
    use metafactory::{ constant, metafactory, AsFactoryExt };
    use super::{ FactoryContainer };

    #[test]
    fn should_be_usable_as_vec_of_types() {
        let mut container = FactoryContainer::new::<int>();
        container.push_items(vec![
            constant(5i),
            constant(13i)
        ]);

        let parent_metafactory = metafactory(
            |items: Vec<int>|
                items.into_iter()
                    .map(|i| format!("{}", i))
                    .collect::<Vec<String>>()
                    .connect(", ")
        );

        let parent_getter = parent_metafactory
            .new(vec![
                container.new_factory()
            ]).ok().unwrap()
            .as_factory_of::<String>().unwrap()
        ;

        assert_eq!(parent_getter.take(), "5, 13");
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate boxfuture;
extern crate bytes;
extern crate clap;
extern crate env_logger;
extern crate fs;
extern crate futures;
extern crate hashing;
extern crate protobuf;

use boxfuture::{BoxFuture, Boxable};
use bytes::Bytes;
use clap::{App, Arg, SubCommand};
use fs::{GlobMatching, ResettablePool, Snapshot, Store, StoreFileByDigest};
use futures::future::Future;
use hashing::{Digest, Fingerprint};
use protobuf::Message;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process::exit;
use std::sync::{Arc, Mutex};
use std::time::Duration;

#[derive(Debug)]
enum ExitCode {
  UnknownError = 1,
  NotFound = 2,
}

#[derive(Debug)]
struct ExitError(String, ExitCode);

impl From<String> for ExitError {
  fn from(s: String) -> Self {
    ExitError(s, ExitCode::UnknownError)
  }
}

fn main() {
  env_logger::init();

  match execute(
    &App::new("fs_util")
      .subcommand(
        SubCommand::with_name("file")
          .subcommand(
            SubCommand::with_name("cat")
              .about("Output the contents of a file by fingerprint.")
              .arg(Arg::with_name("fingerprint").required(true).takes_value(
                true,
              ))
              .arg(Arg::with_name("size_bytes").required(true).takes_value(
                true,
              )),
          )
          .subcommand(
            SubCommand::with_name("save")
              .about(
                "Ingest a file by path, which allows it to be used in Directories/Snapshots. \
Outputs a fingerprint of its contents and its size in bytes, separated by a space.",
              )
              .arg(Arg::with_name("path").required(true).takes_value(true)),
          ),
      )
      .subcommand(
        SubCommand::with_name("directory")
          .subcommand(
            SubCommand::with_name("materialize")
              .about(
                "Materialize a directory by fingerprint to the filesystem. \
Destination must not exist before this command is run.",
              )
              .arg(Arg::with_name("fingerprint").required(true).takes_value(
                true,
              ))
              .arg(Arg::with_name("size_bytes").required(true).takes_value(
                true,
              ))
              .arg(Arg::with_name("destination").required(true).takes_value(
                true,
              )),
          )
          .subcommand(
            SubCommand::with_name("save")
              .about(
                "Ingest a directory recursively. Saves all files found therein and saves Directory \
protos for each directory found. Outputs a fingerprint of the canonical top-level Directory proto \
and the size of the serialized proto in bytes, separated by a space.",
              )
              .arg(
                Arg::with_name("globs")
                  .required(true)
                  .takes_value(true)
                  .multiple(true)
                  .help(
                    "globs matching the files and directories which should be included in the \
directory, relative to the root.",
                  ),
              )
                .arg(Arg::with_name("root").long("root").required(true).takes_value(true).help(
                  "Root under which the globs live. The Directory proto produced will be relative \
to this directory.",
                )),
          )
          .subcommand(
            SubCommand::with_name("cat-proto")
              .about(
                "Output the bytes of a serialized Directory proto addressed by fingerprint.",
              )
              .arg(
                Arg::with_name("output-format")
                  .long("output-format")
                  .takes_value(true)
                  .default_value("binary")
                  .possible_values(&["binary", "recursive-file-list", "text"]),
              )
              .arg(Arg::with_name("fingerprint").required(true).takes_value(
                true,
              ))
              .arg(Arg::with_name("size_bytes").required(true).takes_value(
                true,
              )),
          ),
      )
      .subcommand(
        SubCommand::with_name("cat")
          .about(
            "Output the contents of a file or Directory proto addressed by fingerprint.",
          )
          .arg(Arg::with_name("fingerprint").required(true).takes_value(
            true,
          ))
          .arg(Arg::with_name("size_bytes").required(true).takes_value(
            true,
          )),
      )
      .arg(
        Arg::with_name("local-store-path")
          .takes_value(true)
          .long("local-store-path")
          .required(true),
      )
        .arg(
          Arg::with_name("server-address")
              .takes_value(true)
              .long("server-address")
              .required(false)
        )
      .get_matches(),
  ) {
    Ok(_) => {}
    Err(err) => {
      eprintln!("{}", err.0);
      exit(err.1 as i32)
    }
  };
}

fn execute(top_match: &clap::ArgMatches) -> Result<(), ExitError> {
  let store_dir = top_match.value_of("local-store-path").unwrap();
  let pool = Arc::new(ResettablePool::new("fsutil-pool-".to_string()));
  let (store, store_has_remote) = {
    let (store_result, store_has_remote) = match top_match.value_of("server-address") {
      Some(cas_address) => (
        Store::with_remote(
          store_dir,
          pool.clone(),
          cas_address.to_owned(),
          1,
          10 * 1024 * 1024,
          Duration::from_secs(30),
        ),
        true,
      ),
      None => (Store::local_only(store_dir, pool.clone()), false),
    };
    let store = store_result.map_err(|e| {
      format!(
        "Failed to open/create store for directory {}: {}",
        store_dir, e
      )
    })?;
    (store, store_has_remote)
  };

  match top_match.subcommand() {
    ("file", Some(sub_match)) => {
      match sub_match.subcommand() {
        ("cat", Some(args)) => {
          let fingerprint = Fingerprint::from_hex_string(args.value_of("fingerprint").unwrap())?;
          let size_bytes = args
            .value_of("size_bytes")
            .unwrap()
            .parse::<usize>()
            .expect("size_bytes must be a non-negative number");
          let digest = Digest(fingerprint, size_bytes);
          let write_result = store
            .load_file_bytes_with(digest, |bytes| io::stdout().write_all(&bytes).unwrap())
            .wait()?;
          write_result.ok_or_else(|| {
            ExitError(
              format!("File with digest {:?} not found", digest),
              ExitCode::NotFound,
            )
          })
        }
        ("save", Some(args)) => {
          let path = PathBuf::from(args.value_of("path").unwrap());
          // Canonicalize path to guarantee that a relative path has a parent.
          let posix_fs = make_posix_fs(
            path
              .canonicalize()
              .map_err(|e| format!("Error canonicalizing path {:?}: {:?}", path, e))?
              .parent()
              .ok_or_else(|| format!("File being saved must have parent but {:?} did not", path))?,
            pool,
          );
          let file = posix_fs
            .stat(PathBuf::from(path.file_name().unwrap()))
            .unwrap();
          match file {
            fs::Stat::File(f) => {
              let digest = fs::OneOffStoreFileByDigest::new(store.clone(), Arc::new(posix_fs))
                .store_by_digest(f)
                .wait()
                .unwrap();
              if store_has_remote {
                store.ensure_remote_has_recursive(vec![digest]).wait()?;
              }
              println!("{} {}", digest.0, digest.1);
              Ok(())
            }
            o => Err(
              format!(
                "Tried to save file {:?} but it was not a file, was a {:?}",
                path, o
              ).into(),
            ),
          }
        }
        (_, _) => unimplemented!(),
      }
    }
    ("directory", Some(sub_match)) => match sub_match.subcommand() {
      ("materialize", Some(args)) => {
        let destination = PathBuf::from(args.value_of("destination").unwrap());
        let fingerprint = Fingerprint::from_hex_string(args.value_of("fingerprint").unwrap())?;
        let size_bytes = args
          .value_of("size_bytes")
          .unwrap()
          .parse::<usize>()
          .expect("size_bytes must be a non-negative number");
        let digest = Digest(fingerprint, size_bytes);
        store
          .materialize_directory(destination, digest)
          .wait()
          .map_err(|err| {
            if err.contains("not found") {
              ExitError(err, ExitCode::NotFound)
            } else {
              err.into()
            }
          })
      }
      ("save", Some(args)) => {
        let posix_fs = Arc::new(make_posix_fs(args.value_of("root").unwrap(), pool));
        let store_copy = store.clone();
        let digest = posix_fs
          .expand(fs::PathGlobs::create(
            &args
              .values_of("globs")
              .unwrap()
              .map(|s| s.to_string())
              .collect::<Vec<String>>(),
            &[],
            // By using `Ignore`, we assume all elements of the globs will definitely expand to
            // something here, or we don't care. Is that a valid assumption?
            fs::StrictGlobMatching::Ignore,
          )?)
          .map_err(|e| format!("Error expanding globs: {:?}", e))
          .and_then(move |paths| {
            Snapshot::from_path_stats(
              store_copy.clone(),
              fs::OneOffStoreFileByDigest::new(store_copy, posix_fs),
              paths,
            )
          })
          .map(|snapshot| snapshot.digest)
          .wait()?;
        if store_has_remote {
          store.ensure_remote_has_recursive(vec![digest]).wait()?;
        }
        println!("{} {}", digest.0, digest.1);
        Ok(())
      }
      ("cat-proto", Some(args)) => {
        let fingerprint = Fingerprint::from_hex_string(args.value_of("fingerprint").unwrap())?;
        let size_bytes = args
          .value_of("size_bytes")
          .unwrap()
          .parse::<usize>()
          .expect("size_bytes must be a non-negative number");
        let digest = Digest(fingerprint, size_bytes);
        let proto_bytes = match args.value_of("output-format").unwrap() {
          "binary" => store
            .load_directory(digest)
            .wait()
            .map(|maybe_d| maybe_d.map(|d| d.write_to_bytes().unwrap())),
          "text" => store
            .load_directory(digest)
            .wait()
            .map(|maybe_p| maybe_p.map(|p| format!("{:?}\n", p).as_bytes().to_vec())),
          "recursive-file-list" => expand_files(store, digest).map(|maybe_v| {
            maybe_v
              .map(|v| {
                v.into_iter()
                  .map(|f| format!("{}\n", f))
                  .collect::<Vec<String>>()
                  .join("")
              })
              .map(|s| s.into_bytes())
          }),
          format => Err(format!(
            "Unexpected value of --output-format arg: {}",
            format
          )),
        }?;
        match proto_bytes {
          Some(bytes) => {
            io::stdout().write_all(&bytes).unwrap();
            Ok(())
          }
          None => Err(ExitError(
            format!("Directory with digest {:?} not found", digest),
            ExitCode::NotFound,
          )),
        }
      }
      (_, _) => unimplemented!(),
    },
    ("cat", Some(args)) => {
      let fingerprint = Fingerprint::from_hex_string(args.value_of("fingerprint").unwrap())?;
      let size_bytes = args
        .value_of("size_bytes")
        .unwrap()
        .parse::<usize>()
        .expect("size_bytes must be a non-negative number");
      let digest = Digest(fingerprint, size_bytes);
      let v = match store.load_file_bytes_with(digest, |bytes| bytes).wait()? {
        None => store
          .load_directory(digest)
          .map(|maybe_dir| {
            maybe_dir.map(|dir| {
              Bytes::from(
                dir
                  .write_to_bytes()
                  .expect("Error serializing Directory proto"),
              )
            })
          })
          .wait()?,
        some => some,
      };
      match v {
        Some(bytes) => {
          io::stdout().write_all(&bytes).unwrap();
          Ok(())
        }
        None => Err(ExitError(
          format!("Digest {:?} not found", digest),
          ExitCode::NotFound,
        )),
      }
    }

    (_, _) => unimplemented!(),
  }
}

fn expand_files(store: Store, digest: Digest) -> Result<Option<Vec<String>>, String> {
  let files = Arc::new(Mutex::new(Vec::new()));
  expand_files_helper(store, digest, String::new(), files.clone())
    .wait()
    .map(|maybe| {
      maybe.map(|()| {
        let mut v = Arc::try_unwrap(files).unwrap().into_inner().unwrap();
        v.sort();
        v
      })
    })
}

fn expand_files_helper(
  store: Store,
  digest: Digest,
  prefix: String,
  files: Arc<Mutex<Vec<String>>>,
) -> BoxFuture<Option<()>, String> {
  store
    .load_directory(digest)
    .and_then(|maybe_dir| match maybe_dir {
      Some(dir) => {
        {
          let mut files_unlocked = files.lock().unwrap();
          for file in dir.get_files() {
            files_unlocked.push(format!("{}{}", prefix, file.name));
          }
        }
        futures::future::join_all(
          dir
            .get_directories()
            .into_iter()
            .map(move |dir| {
              let digest: Result<Digest, String> = dir.get_digest().into();
              expand_files_helper(
                store.clone(),
                try_future!(digest),
                format!("{}{}/", prefix, dir.name),
                files.clone(),
              )
            })
            .collect::<Vec<_>>(),
        ).map(|_| Some(()))
          .to_boxed()
      }
      None => futures::future::ok(None).to_boxed(),
    })
    .to_boxed()
}

fn make_posix_fs<P: AsRef<Path>>(root: P, pool: Arc<ResettablePool>) -> fs::PosixFS {
  fs::PosixFS::new(&root, pool, &[]).unwrap()
}
<commit_msg>Allow user to specify chunk size (#6173)<commit_after>#[macro_use]
extern crate boxfuture;
extern crate bytes;
#[macro_use(value_t)]
extern crate clap;
extern crate env_logger;
extern crate fs;
extern crate futures;
extern crate hashing;
extern crate protobuf;

use boxfuture::{BoxFuture, Boxable};
use bytes::Bytes;
use clap::{App, Arg, SubCommand};
use fs::{GlobMatching, ResettablePool, Snapshot, Store, StoreFileByDigest};
use futures::future::Future;
use hashing::{Digest, Fingerprint};
use protobuf::Message;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process::exit;
use std::sync::{Arc, Mutex};
use std::time::Duration;

#[derive(Debug)]
enum ExitCode {
  UnknownError = 1,
  NotFound = 2,
}

#[derive(Debug)]
struct ExitError(String, ExitCode);

impl From<String> for ExitError {
  fn from(s: String) -> Self {
    ExitError(s, ExitCode::UnknownError)
  }
}

fn main() {
  env_logger::init();

  match execute(
    &App::new("fs_util")
      .subcommand(
        SubCommand::with_name("file")
          .subcommand(
            SubCommand::with_name("cat")
              .about("Output the contents of a file by fingerprint.")
              .arg(Arg::with_name("fingerprint").required(true).takes_value(
                true,
              ))
              .arg(Arg::with_name("size_bytes").required(true).takes_value(
                true,
              )),
          )
          .subcommand(
            SubCommand::with_name("save")
              .about(
                "Ingest a file by path, which allows it to be used in Directories/Snapshots. \
Outputs a fingerprint of its contents and its size in bytes, separated by a space.",
              )
              .arg(Arg::with_name("path").required(true).takes_value(true)),
          ),
      )
      .subcommand(
        SubCommand::with_name("directory")
          .subcommand(
            SubCommand::with_name("materialize")
              .about(
                "Materialize a directory by fingerprint to the filesystem. \
Destination must not exist before this command is run.",
              )
              .arg(Arg::with_name("fingerprint").required(true).takes_value(
                true,
              ))
              .arg(Arg::with_name("size_bytes").required(true).takes_value(
                true,
              ))
              .arg(Arg::with_name("destination").required(true).takes_value(
                true,
              )),
          )
          .subcommand(
            SubCommand::with_name("save")
              .about(
                "Ingest a directory recursively. Saves all files found therein and saves Directory \
protos for each directory found. Outputs a fingerprint of the canonical top-level Directory proto \
and the size of the serialized proto in bytes, separated by a space.",
              )
              .arg(
                Arg::with_name("globs")
                  .required(true)
                  .takes_value(true)
                  .multiple(true)
                  .help(
                    "globs matching the files and directories which should be included in the \
directory, relative to the root.",
                  ),
              )
                .arg(Arg::with_name("root").long("root").required(true).takes_value(true).help(
                  "Root under which the globs live. The Directory proto produced will be relative \
to this directory.",
                )),
          )
          .subcommand(
            SubCommand::with_name("cat-proto")
              .about(
                "Output the bytes of a serialized Directory proto addressed by fingerprint.",
              )
              .arg(
                Arg::with_name("output-format")
                  .long("output-format")
                  .takes_value(true)
                  .default_value("binary")
                  .possible_values(&["binary", "recursive-file-list", "text"]),
              )
              .arg(Arg::with_name("fingerprint").required(true).takes_value(
                true,
              ))
              .arg(Arg::with_name("size_bytes").required(true).takes_value(
                true,
              )),
          ),
      )
      .subcommand(
        SubCommand::with_name("cat")
          .about(
            "Output the contents of a file or Directory proto addressed by fingerprint.",
          )
          .arg(Arg::with_name("fingerprint").required(true).takes_value(
            true,
          ))
          .arg(Arg::with_name("size_bytes").required(true).takes_value(
            true,
          )),
      )
      .arg(
        Arg::with_name("local-store-path")
          .takes_value(true)
          .long("local-store-path")
          .required(true),
      )
        .arg(
          Arg::with_name("server-address")
              .takes_value(true)
              .long("server-address")
              .required(false)
        )
        .arg(
          Arg::with_name("chunk-bytes")
              .help("Number of bytes to include per-chunk when uploading bytes. grpc imposes a hard message-size limit of around 4MB.")
              .takes_value(true)
              .long("chunk-bytes")
              .required(false)
              .default_value(&format!("{}", 3 * 1024 * 1024))
        )
      .get_matches(),
  ) {
    Ok(_) => {}
    Err(err) => {
      eprintln!("{}", err.0);
      exit(err.1 as i32)
    }
  };
}

fn execute(top_match: &clap::ArgMatches) -> Result<(), ExitError> {
  let store_dir = top_match.value_of("local-store-path").unwrap();
  let pool = Arc::new(ResettablePool::new("fsutil-pool-".to_string()));
  let (store, store_has_remote) = {
    let (store_result, store_has_remote) = match top_match.value_of("server-address") {
      Some(cas_address) => {
        let chunk_size =
          value_t!(top_match.value_of("chunk-bytes"), usize).expect("Bad chunk-bytes flag");
        (
          Store::with_remote(
            store_dir,
            pool.clone(),
            cas_address.to_owned(),
            1,
            chunk_size,
            Duration::from_secs(30),
          ),
          true,
        )
      }
      None => (Store::local_only(store_dir, pool.clone()), false),
    };
    let store = store_result.map_err(|e| {
      format!(
        "Failed to open/create store for directory {}: {}",
        store_dir, e
      )
    })?;
    (store, store_has_remote)
  };

  match top_match.subcommand() {
    ("file", Some(sub_match)) => {
      match sub_match.subcommand() {
        ("cat", Some(args)) => {
          let fingerprint = Fingerprint::from_hex_string(args.value_of("fingerprint").unwrap())?;
          let size_bytes = args
            .value_of("size_bytes")
            .unwrap()
            .parse::<usize>()
            .expect("size_bytes must be a non-negative number");
          let digest = Digest(fingerprint, size_bytes);
          let write_result = store
            .load_file_bytes_with(digest, |bytes| io::stdout().write_all(&bytes).unwrap())
            .wait()?;
          write_result.ok_or_else(|| {
            ExitError(
              format!("File with digest {:?} not found", digest),
              ExitCode::NotFound,
            )
          })
        }
        ("save", Some(args)) => {
          let path = PathBuf::from(args.value_of("path").unwrap());
          // Canonicalize path to guarantee that a relative path has a parent.
          let posix_fs = make_posix_fs(
            path
              .canonicalize()
              .map_err(|e| format!("Error canonicalizing path {:?}: {:?}", path, e))?
              .parent()
              .ok_or_else(|| format!("File being saved must have parent but {:?} did not", path))?,
            pool,
          );
          let file = posix_fs
            .stat(PathBuf::from(path.file_name().unwrap()))
            .unwrap();
          match file {
            fs::Stat::File(f) => {
              let digest = fs::OneOffStoreFileByDigest::new(store.clone(), Arc::new(posix_fs))
                .store_by_digest(f)
                .wait()
                .unwrap();
              if store_has_remote {
                store.ensure_remote_has_recursive(vec![digest]).wait()?;
              }
              println!("{} {}", digest.0, digest.1);
              Ok(())
            }
            o => Err(
              format!(
                "Tried to save file {:?} but it was not a file, was a {:?}",
                path, o
              ).into(),
            ),
          }
        }
        (_, _) => unimplemented!(),
      }
    }
    ("directory", Some(sub_match)) => match sub_match.subcommand() {
      ("materialize", Some(args)) => {
        let destination = PathBuf::from(args.value_of("destination").unwrap());
        let fingerprint = Fingerprint::from_hex_string(args.value_of("fingerprint").unwrap())?;
        let size_bytes = args
          .value_of("size_bytes")
          .unwrap()
          .parse::<usize>()
          .expect("size_bytes must be a non-negative number");
        let digest = Digest(fingerprint, size_bytes);
        store
          .materialize_directory(destination, digest)
          .wait()
          .map_err(|err| {
            if err.contains("not found") {
              ExitError(err, ExitCode::NotFound)
            } else {
              err.into()
            }
          })
      }
      ("save", Some(args)) => {
        let posix_fs = Arc::new(make_posix_fs(args.value_of("root").unwrap(), pool));
        let store_copy = store.clone();
        let digest = posix_fs
          .expand(fs::PathGlobs::create(
            &args
              .values_of("globs")
              .unwrap()
              .map(|s| s.to_string())
              .collect::<Vec<String>>(),
            &[],
            // By using `Ignore`, we assume all elements of the globs will definitely expand to
            // something here, or we don't care. Is that a valid assumption?
            fs::StrictGlobMatching::Ignore,
          )?)
          .map_err(|e| format!("Error expanding globs: {:?}", e))
          .and_then(move |paths| {
            Snapshot::from_path_stats(
              store_copy.clone(),
              fs::OneOffStoreFileByDigest::new(store_copy, posix_fs),
              paths,
            )
          })
          .map(|snapshot| snapshot.digest)
          .wait()?;
        if store_has_remote {
          store.ensure_remote_has_recursive(vec![digest]).wait()?;
        }
        println!("{} {}", digest.0, digest.1);
        Ok(())
      }
      ("cat-proto", Some(args)) => {
        let fingerprint = Fingerprint::from_hex_string(args.value_of("fingerprint").unwrap())?;
        let size_bytes = args
          .value_of("size_bytes")
          .unwrap()
          .parse::<usize>()
          .expect("size_bytes must be a non-negative number");
        let digest = Digest(fingerprint, size_bytes);
        let proto_bytes = match args.value_of("output-format").unwrap() {
          "binary" => store
            .load_directory(digest)
            .wait()
            .map(|maybe_d| maybe_d.map(|d| d.write_to_bytes().unwrap())),
          "text" => store
            .load_directory(digest)
            .wait()
            .map(|maybe_p| maybe_p.map(|p| format!("{:?}\n", p).as_bytes().to_vec())),
          "recursive-file-list" => expand_files(store, digest).map(|maybe_v| {
            maybe_v
              .map(|v| {
                v.into_iter()
                  .map(|f| format!("{}\n", f))
                  .collect::<Vec<String>>()
                  .join("")
              })
              .map(|s| s.into_bytes())
          }),
          format => Err(format!(
            "Unexpected value of --output-format arg: {}",
            format
          )),
        }?;
        match proto_bytes {
          Some(bytes) => {
            io::stdout().write_all(&bytes).unwrap();
            Ok(())
          }
          None => Err(ExitError(
            format!("Directory with digest {:?} not found", digest),
            ExitCode::NotFound,
          )),
        }
      }
      (_, _) => unimplemented!(),
    },
    ("cat", Some(args)) => {
      let fingerprint = Fingerprint::from_hex_string(args.value_of("fingerprint").unwrap())?;
      let size_bytes = args
        .value_of("size_bytes")
        .unwrap()
        .parse::<usize>()
        .expect("size_bytes must be a non-negative number");
      let digest = Digest(fingerprint, size_bytes);
      let v = match store.load_file_bytes_with(digest, |bytes| bytes).wait()? {
        None => store
          .load_directory(digest)
          .map(|maybe_dir| {
            maybe_dir.map(|dir| {
              Bytes::from(
                dir
                  .write_to_bytes()
                  .expect("Error serializing Directory proto"),
              )
            })
          })
          .wait()?,
        some => some,
      };
      match v {
        Some(bytes) => {
          io::stdout().write_all(&bytes).unwrap();
          Ok(())
        }
        None => Err(ExitError(
          format!("Digest {:?} not found", digest),
          ExitCode::NotFound,
        )),
      }
    }

    (_, _) => unimplemented!(),
  }
}

fn expand_files(store: Store, digest: Digest) -> Result<Option<Vec<String>>, String> {
  let files = Arc::new(Mutex::new(Vec::new()));
  expand_files_helper(store, digest, String::new(), files.clone())
    .wait()
    .map(|maybe| {
      maybe.map(|()| {
        let mut v = Arc::try_unwrap(files).unwrap().into_inner().unwrap();
        v.sort();
        v
      })
    })
}

fn expand_files_helper(
  store: Store,
  digest: Digest,
  prefix: String,
  files: Arc<Mutex<Vec<String>>>,
) -> BoxFuture<Option<()>, String> {
  store
    .load_directory(digest)
    .and_then(|maybe_dir| match maybe_dir {
      Some(dir) => {
        {
          let mut files_unlocked = files.lock().unwrap();
          for file in dir.get_files() {
            files_unlocked.push(format!("{}{}", prefix, file.name));
          }
        }
        futures::future::join_all(
          dir
            .get_directories()
            .into_iter()
            .map(move |dir| {
              let digest: Result<Digest, String> = dir.get_digest().into();
              expand_files_helper(
                store.clone(),
                try_future!(digest),
                format!("{}{}/", prefix, dir.name),
                files.clone(),
              )
            })
            .collect::<Vec<_>>(),
        ).map(|_| Some(()))
          .to_boxed()
      }
      None => futures::future::ok(None).to_boxed(),
    })
    .to_boxed()
}

fn make_posix_fs<P: AsRef<Path>>(root: P, pool: Arc<ResettablePool>) -> fs::PosixFS {
  fs::PosixFS::new(&root, pool, &[]).unwrap()
}
<|endoftext|>


<commit_before>// This is a part of rust-encoding.
// Copyright (c) 2013, Kang Seonghoon.
// See README.md and LICENSE.txt for details.

//! Internal utilities.

use std::str::CharRange;
use std::cast::transmute;

/// Unchecked conversion to `char`.
pub fn as_char<T:Integer+NumCast>(ch: T) -> char {
    unsafe { transmute(ch.to_u32().unwrap()) }
}

/// External iterator for a string's characters with its corresponding byte offset range.
pub struct StrCharIndexIterator<'self> {
    priv index: uint,
    priv string: &'self str,
}

impl<'self> Iterator<((uint,uint), char)> for StrCharIndexIterator<'self> {
    #[inline]
    fn next(&mut self) -> Option<((uint,uint), char)> {
        if self.index < self.string.len() {
            let CharRange {ch, next} = self.string.char_range_at(self.index);
            let prev = self.index;
            self.index = next;
            Some(((prev, next), ch))
        } else {
            None
        }
    }
}

/// A trait providing an `index_iter` method.
pub trait StrCharIndex<'self> {
    fn index_iter(&self) -> StrCharIndexIterator<'self>;
}

impl<'self> StrCharIndex<'self> for &'self str {
    /// Iterates over each character with corresponding byte offset range.
    fn index_iter(&self) -> StrCharIndexIterator<'self> {
        StrCharIndexIterator { index: 0, string: *self }
    }
}
<commit_msg>language update: no more 'self.<commit_after>// This is a part of rust-encoding.
// Copyright (c) 2013, Kang Seonghoon.
// See README.md and LICENSE.txt for details.

//! Internal utilities.

use std::str::CharRange;
use std::cast::transmute;

/// Unchecked conversion to `char`.
pub fn as_char<T:Integer+NumCast>(ch: T) -> char {
    unsafe { transmute(ch.to_u32().unwrap()) }
}

/// External iterator for a string's characters with its corresponding byte offset range.
pub struct StrCharIndexIterator<'r> {
    priv index: uint,
    priv string: &'r str,
}

impl<'r> Iterator<((uint,uint), char)> for StrCharIndexIterator<'r> {
    #[inline]
    fn next(&mut self) -> Option<((uint,uint), char)> {
        if self.index < self.string.len() {
            let CharRange {ch, next} = self.string.char_range_at(self.index);
            let prev = self.index;
            self.index = next;
            Some(((prev, next), ch))
        } else {
            None
        }
    }
}

/// A trait providing an `index_iter` method.
pub trait StrCharIndex<'r> {
    fn index_iter(&self) -> StrCharIndexIterator<'r>;
}

impl<'r> StrCharIndex<'r> for &'r str {
    /// Iterates over each character with corresponding byte offset range.
    fn index_iter(&self) -> StrCharIndexIterator<'r> {
        StrCharIndexIterator { index: 0, string: *self }
    }
}
<|endoftext|>


<commit_before>//! Types for counting and recording time in a simulation.
//!
//! `clock` is the primary module for time tracking in `game_time`. It
//! provides two primary types: `GameClock`, a "clock" for tracking frames
//! and time progression within the simulation and `GameTime`, a specific
//! point in time within the simulation.
use std::thread;
use std::time;

use chrono;
use float_duration::{FloatDuration, TimePoint};
use step::TimeStep;

use framerate::FrameCount;

/// A specific point of time in a simulation.
///
/// `GameTime` knows both the wall time and game time of the simulation at a
/// fixed time. A `GameTime` object is usually created by calling
/// [`tick`](./struct.GameClock.html#method.tick) on a [`GameClock`](./struct.GameClock.html)
/// object.
#[derive(Debug, Clone)]
pub struct GameTime {
    frame_wall_time: chrono::DateTime<chrono::Local>,
    frame_game_time: time::Duration,
    elapsed_game_time: FloatDuration,
    elapsed_wall_time: FloatDuration,
    frame_number: u64,
}

/// Time-tracking for use in real-time simulations.
///
/// `GameClock` provides time tracking for simulations. It
/// tracks total time the simulation has run for as well as
/// the elapsed time between individual frames.
///
/// In addition to tracking wall time, it tracks "game time"
/// which is the time used by the simulation itself. This game time is updated
/// each frame and
/// can be coupled directly to wall time [`VariableStep`](../step/struct.VariableStep.html)
/// or can be updated by a fixed amount (see the [`step`](../step/index.html) module for more
/// options).
///
/// `GameClock` uses [`GameTime`](./struct.GameTime.html) objects
/// to report the time at each frame to the program. The [`tick`](./fn.tick.html)
/// tells `GameClock` when a new frame is started, and returns
/// the `GameTime` object for that frame. This object can then be passed
/// to the rest of the simulation independently of `GameClock`.
#[derive(Debug, Clone)]
pub struct GameClock {
    last_frame_time: GameTime,
    start_wall_time: chrono::DateTime<chrono::Local>,
    total_game_time: time::Duration,
    current_frame: u64,
    clock_multiplier: f64,
}

/// A [`GameClock`](./struct.GameClock.html) builder,
/// allowing for customization of the initial time and parameters.
///
/// `GameClockBuilder` offers fine control over the initial state of a `GameClock`. For
/// most cases, using [`GameClock::new()`](./struct.GameClock.html#method.new) is good enough.
/// However, it can be useful to have more control in some situations, especially testing.
#[derive(Debug, Clone)]
pub struct GameClockBuilder {
    start_game_time: time::Duration,
    start_wall_time: chrono::DateTime<chrono::Local>,
    start_frame: u64,
    clock_multiplier: f64,
}

impl GameClock {
    /// Construct a new `GameClock` object, initialized to start at
    /// zero game time and a wall time of `chrono::Local::now()`.
    pub fn new() -> GameClock {
        let now = chrono::Local::now();
        let start_game_time = GameTime {
            frame_wall_time: now,
            frame_game_time: time::Duration::new(0, 0),
            elapsed_game_time: FloatDuration::zero(),
            elapsed_wall_time: FloatDuration::zero(),
            frame_number: 0,
        };

        GameClock {
            last_frame_time: start_game_time,
            start_wall_time: now,
            total_game_time: time::Duration::new(0, 0),
            current_frame: 0,
            clock_multiplier: 1.0,
        }
    }

    /// Return the current frame number.
    ///
    /// The frame number starts at `0` for "before the first frame"
    /// and increases by 1 every time `tick` is called.
    pub fn current_frame_number(&self) -> u64 {
        self.current_frame
    }
    /// Return the wall time when the `GameClock` was created.
    pub fn start_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.start_wall_time
    }
    /// Return the wall time at the start of the current frame.
    ///
    /// This is equivalent to the value returned by
    /// `last_frame_time().frame_wall_time()`
    pub fn frame_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.last_frame_time.frame_wall_time
    }

    /// Return the amount of wall time elapsed since the start of the current frame.
    pub fn frame_elapsed_time(&self) -> FloatDuration {
        chrono::Local::now()
            .float_duration_since(self.frame_wall_time())
            .unwrap()
    }
    /// Return the [`GameTime`](./struct.GameTime.html) for the current frame.
    pub fn last_frame_time(&self) -> &GameTime {
        &self.last_frame_time
    }
    /// Return the rate at which game time is increasing.
    pub fn clock_multiplier(&self) -> f64 {
        self.clock_multiplier
    }
    /// Set the rate at which game time is increasing.
    pub fn set_clock_multiplier(&mut self, val: f64) -> &mut GameClock {
        self.clock_multiplier = val;
        self
    }

    /// Mark the start of a new frame, updating time statistics.
    ///
    /// The `GameTime` for the new frame is returned. This gives the time
    /// statistics for the entirety of the current frame. It is cached and
    /// can be later obtained by calling `last_frame_time`.
    ///
    /// `time_progress` is a [`TimeStep`](../step/trait.TimeStep.html) reference used to
    /// compute the elapsed game time for the frame..
    pub fn tick<T>(&mut self, time_progress: &mut T) -> GameTime
    where
        T: TimeStep + ?Sized,
    {
        let frame_start = chrono::Local::now();

        self.current_frame += 1;

        let elapsed_wall_time = frame_start
            .float_duration_since(self.frame_wall_time())
            .unwrap();

        let elapsed_game_time = time_progress.time_step(&elapsed_wall_time) * self.clock_multiplier;
        let total_game_time = self.total_game_time + elapsed_game_time.to_std().unwrap();

        self.total_game_time = total_game_time;

        let time = GameTime {
            frame_wall_time: frame_start,
            frame_game_time: total_game_time,
            elapsed_game_time,
            elapsed_wall_time,
            frame_number: self.current_frame,
        };

        self.last_frame_time = time.clone();

        time
    }

    /// Put the current thread to sleep if necessary in order to maintain the target frame rate.
    ///
    /// If the current frame has taken more time than the target frame rate allows, then the
    /// thread will not sleep. Otherwise it will sleep for
    /// `counter.target_time_per_frame() - self.frame_elapsed_time()`
    ///
    /// This method relies on the passed function `f` to actually perform the sleep.
    /// `f` receives the amount of sleep time requested and it is up to itself to
    /// sleep for that amount of time. If you don't care how the sleep is performed,
    /// use the [`sleep_remaining`](./struct.GameClock.html#method.sleep_remaining)
    /// method instead.
    pub fn sleep_remaining_via<C, F>(&mut self, counter: &C, f: F)
    where
        C: FrameCount + ?Sized,
        F: FnOnce(FloatDuration),
    {
        let remaining_time = counter.target_time_per_frame() -
            self.last_frame_time.elapsed_time_since_frame_start();
        if !remaining_time.is_negative() {
            f(remaining_time)
        }
    }

    /// Put the current thread to sleep if necessary in order to maintain the target frame rate.
    ///
    /// If the current frame has taken more time than the target frame rate allows, then the
    /// thread will not sleep. Otherwise it will sleep for
    /// `counter.target_time_per_frame() - self.frame_elapsed_time()`
    ///
    /// This method uses [`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)
    /// to put the thread to sleep. If a different sleep function is desired, use
    /// the [`sleep_remaining_via`](./struct.GameClock.html#method.sleep_remaining_via)
    /// method instead.
    pub fn sleep_remaining<C>(&mut self, counter: &C)
    where
        C: FrameCount + ?Sized,
    {
        self.sleep_remaining_via(counter, |rem| thread::sleep(rem.to_std().unwrap()))
    }
}

impl Default for GameClock {
    fn default() -> GameClock {
        GameClock::new()
    }
}

impl GameTime {
    /// Construct a `GameTime` object directly.
    ///
    /// This is useful primarily for writing tests or for constructing a
    /// `GameTime` without using a `GameClock`.
    pub fn new(
        frame_wall_time: chrono::DateTime<chrono::Local>,
        frame_game_time: time::Duration,
        elapsed_game_time: FloatDuration,
        elapsed_wall_time: FloatDuration,
        frame_number: u64,
    ) -> GameTime {
        GameTime {
            frame_wall_time,
            frame_game_time,
            elapsed_game_time,
            elapsed_wall_time,
            frame_number,
        }
    }

    /// The game time at the time of creation of this `GameTime` object.
    pub fn frame_game_time(&self) -> time::Duration {
        self.frame_game_time
    }
    /// The wall time at the time of creation of this `GameTime` object.
    pub fn frame_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.frame_wall_time
    }
    /// The amount of game time that passed since the previous frame.
    pub fn elapsed_game_time(&self) -> FloatDuration {
        self.elapsed_game_time
    }
    /// The amount of wall time that passed since the previous frame.
    pub fn elapsed_wall_time(&self) -> FloatDuration {
        self.elapsed_wall_time
    }
    /// The amount of elapsed wall time since the start of the current frame.
    ///
    /// This value is computed from the current instant when called, based
    /// on the frame start time. This can be used for intra-frame profiling.
    pub fn elapsed_time_since_frame_start(&self) -> FloatDuration {
        chrono::Local::now()
            .float_duration_since(self.frame_wall_time)
            .unwrap()
    }
    /// The index of the current frame.
    ///
    /// This value increases by 1 for each frame created, and represents the total
    /// number of frames executed in the simulation.
    pub fn frame_number(&self) -> u64 {
        self.frame_number
    }
    /// Return the instantaneous frame rate between the last and current frames.
    ///
    /// The "instantaneous" frame rate is computed from the last frame's elapsed
    /// time, and takes no previous frames into account.
    ///
    /// For a more stable frame rate, use a
    /// [`FrameCount`](../framerate/counter/trait.FrameCount.html) object.
    pub fn instantaneous_frame_rate(&self) -> f64 {
        1.0 / self.elapsed_game_time.as_seconds()
    }
}

impl GameClockBuilder {
    /// Construct a new `GameClockBuilder` with default values.
    ///
    /// Calling `build` on the returned object returns immediately gives the same
    /// result as `GameClock::new()`.
    pub fn new() -> GameClockBuilder {
        GameClockBuilder {
            start_game_time: time::Duration::new(0, 0),
            start_wall_time: chrono::Local::now(),
            start_frame: 0,
            clock_multiplier: 1.0,
        }
    }

    /// Set the initial game time when the game is started.
    ///
    /// Defaults to zero.
    pub fn start_game_time(&mut self, time: time::Duration) -> &mut GameClockBuilder {
        self.start_game_time = time;
        self
    }
    /// Set the initial wall time when the game is started.
    ///
    /// Defaults to `chrono::Local::now()`.
    pub fn start_wall_time(
        &mut self,
        time: chrono::DateTime<chrono::Local>,
    ) -> &mut GameClockBuilder {
        self.start_wall_time = time;
        self
    }
    /// Set the initial frame number.
    ///
    /// Defaults to `0`.
    pub fn start_frame(&mut self, frame_num: u64) -> &mut GameClockBuilder {
        self.start_frame = frame_num;
        self
    }
    /// Set the initial clock multiplier.
    ///
    /// Defaults to `1.0`.
    pub fn clock_multiplier(&mut self, multiplier: f64) -> &mut GameClockBuilder {
        self.clock_multiplier = multiplier;
        self
    }
    /// Construct a `GameClock` object with the set parameters.
    pub fn build(&self) -> GameClock {
        let start_game_time = GameTime {
            frame_wall_time: self.start_wall_time,
            frame_game_time: self.start_game_time,
            elapsed_game_time: FloatDuration::zero(),
            elapsed_wall_time: FloatDuration::zero(),
            frame_number: self.start_frame,
        };

        GameClock {
            last_frame_time: start_game_time,
            start_wall_time: self.start_wall_time,
            total_game_time: time::Duration::new(0, 0),
            current_frame: self.start_frame,
            clock_multiplier: self.clock_multiplier,
        }
    }
}

impl Default for GameClockBuilder {
    fn default() -> GameClockBuilder {
        GameClockBuilder::new()
    }
}
<commit_msg>Added tests to `clock` module.<commit_after>//! Types for counting and recording time in a simulation.
//!
//! `clock` is the primary module for time tracking in `game_time`. It
//! provides two primary types: `GameClock`, a "clock" for tracking frames
//! and time progression within the simulation and `GameTime`, a specific
//! point in time within the simulation.
use std::thread;
use std::time;

use chrono;
use float_duration::{FloatDuration, TimePoint};
use step::TimeStep;

use framerate::FrameCount;

/// A specific point of time in a simulation.
///
/// `GameTime` knows both the wall time and game time of the simulation at a
/// fixed time. A `GameTime` object is usually created by calling
/// [`tick`](./struct.GameClock.html#method.tick) on a [`GameClock`](./struct.GameClock.html)
/// object.
#[derive(Debug, Clone)]
pub struct GameTime {
    frame_wall_time: chrono::DateTime<chrono::Local>,
    frame_game_time: time::Duration,
    elapsed_game_time: FloatDuration,
    elapsed_wall_time: FloatDuration,
    frame_number: u64,
}

/// Time-tracking for use in real-time simulations.
///
/// `GameClock` provides time tracking for simulations. It
/// tracks total time the simulation has run for as well as
/// the elapsed time between individual frames.
///
/// In addition to tracking wall time, it tracks "game time"
/// which is the time used by the simulation itself. This game time is updated
/// each frame and
/// can be coupled directly to wall time [`VariableStep`](../step/struct.VariableStep.html)
/// or can be updated by a fixed amount (see the [`step`](../step/index.html) module for more
/// options).
///
/// `GameClock` uses [`GameTime`](./struct.GameTime.html) objects
/// to report the time at each frame to the program. The [`tick`](./fn.tick.html)
/// tells `GameClock` when a new frame is started, and returns
/// the `GameTime` object for that frame. This object can then be passed
/// to the rest of the simulation independently of `GameClock`.
#[derive(Debug, Clone)]
pub struct GameClock {
    last_frame_time: GameTime,
    start_wall_time: chrono::DateTime<chrono::Local>,
    total_game_time: time::Duration,
    current_frame: u64,
    clock_multiplier: f64,
}

/// A [`GameClock`](./struct.GameClock.html) builder,
/// allowing for customization of the initial time and parameters.
///
/// `GameClockBuilder` offers fine control over the initial state of a `GameClock`. For
/// most cases, using [`GameClock::new()`](./struct.GameClock.html#method.new) is good enough.
/// However, it can be useful to have more control in some situations, especially testing.
#[derive(Debug, Clone)]
pub struct GameClockBuilder {
    start_game_time: time::Duration,
    start_wall_time: chrono::DateTime<chrono::Local>,
    start_frame: u64,
    clock_multiplier: f64,
}

impl GameClock {
    /// Construct a new `GameClock` object, initialized to start at
    /// zero game time and a wall time of `chrono::Local::now()`.
    pub fn new() -> GameClock {
        let now = chrono::Local::now();
        let start_game_time = GameTime {
            frame_wall_time: now,
            frame_game_time: time::Duration::new(0, 0),
            elapsed_game_time: FloatDuration::zero(),
            elapsed_wall_time: FloatDuration::zero(),
            frame_number: 0,
        };

        GameClock {
            last_frame_time: start_game_time,
            start_wall_time: now,
            total_game_time: time::Duration::new(0, 0),
            current_frame: 0,
            clock_multiplier: 1.0,
        }
    }

    /// Return the current frame number.
    ///
    /// The frame number starts at `0` for "before the first frame"
    /// and increases by 1 every time `tick` is called.
    pub fn current_frame_number(&self) -> u64 {
        self.current_frame
    }
    /// Return the wall time when the `GameClock` was created.
    pub fn start_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.start_wall_time
    }
    /// Return the wall time at the start of the current frame.
    ///
    /// This is equivalent to the value returned by
    /// `last_frame_time().frame_wall_time()`
    pub fn frame_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.last_frame_time.frame_wall_time
    }

    /// Return the amount of wall time elapsed since the start of the current frame.
    pub fn frame_elapsed_time(&self) -> FloatDuration {
        chrono::Local::now()
            .float_duration_since(self.frame_wall_time())
            .unwrap()
    }
    /// Return the [`GameTime`](./struct.GameTime.html) for the current frame.
    pub fn last_frame_time(&self) -> &GameTime {
        &self.last_frame_time
    }
    /// Return the rate at which game time is increasing.
    pub fn clock_multiplier(&self) -> f64 {
        self.clock_multiplier
    }
    /// Set the rate at which game time is increasing.
    pub fn set_clock_multiplier(&mut self, val: f64) -> &mut GameClock {
        self.clock_multiplier = val;
        self
    }

    /// Mark the start of a new frame, updating time statistics.
    ///
    /// The `GameTime` for the new frame is returned. This gives the time
    /// statistics for the entirety of the current frame. It is cached and
    /// can be later obtained by calling `last_frame_time`.
    ///
    /// `time_progress` is a [`TimeStep`](../step/trait.TimeStep.html) reference used to
    /// compute the elapsed game time for the frame..
    pub fn tick<T>(&mut self, time_progress: &mut T) -> GameTime
    where
        T: TimeStep + ?Sized,
    {
        let frame_start = chrono::Local::now();

        self.current_frame += 1;

        let elapsed_wall_time = frame_start
            .float_duration_since(self.frame_wall_time())
            .unwrap();

        let elapsed_game_time = time_progress.time_step(&elapsed_wall_time) * self.clock_multiplier;
        let total_game_time = self.total_game_time + elapsed_game_time.to_std().unwrap();

        self.total_game_time = total_game_time;

        let time = GameTime {
            frame_wall_time: frame_start,
            frame_game_time: total_game_time,
            elapsed_game_time,
            elapsed_wall_time,
            frame_number: self.current_frame,
        };

        self.last_frame_time = time.clone();

        time
    }

    /// Put the current thread to sleep if necessary in order to maintain the target frame rate.
    ///
    /// If the current frame has taken more time than the target frame rate allows, then the
    /// thread will not sleep. Otherwise it will sleep for
    /// `counter.target_time_per_frame() - self.frame_elapsed_time()`
    ///
    /// This method relies on the passed function `f` to actually perform the sleep.
    /// `f` receives the amount of sleep time requested and it is up to itself to
    /// sleep for that amount of time. If you don't care how the sleep is performed,
    /// use the [`sleep_remaining`](./struct.GameClock.html#method.sleep_remaining)
    /// method instead.
    pub fn sleep_remaining_via<C, F>(&mut self, counter: &C, f: F)
    where
        C: FrameCount + ?Sized,
        F: FnOnce(FloatDuration),
    {
        let remaining_time = counter.target_time_per_frame() -
            self.last_frame_time.elapsed_time_since_frame_start();
        if !remaining_time.is_negative() {
            f(remaining_time)
        }
    }

    /// Put the current thread to sleep if necessary in order to maintain the target frame rate.
    ///
    /// If the current frame has taken more time than the target frame rate allows, then the
    /// thread will not sleep. Otherwise it will sleep for
    /// `counter.target_time_per_frame() - self.frame_elapsed_time()`
    ///
    /// This method uses [`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)
    /// to put the thread to sleep. If a different sleep function is desired, use
    /// the [`sleep_remaining_via`](./struct.GameClock.html#method.sleep_remaining_via)
    /// method instead.
    pub fn sleep_remaining<C>(&mut self, counter: &C)
    where
        C: FrameCount + ?Sized,
    {
        self.sleep_remaining_via(counter, |rem| thread::sleep(rem.to_std().unwrap()))
    }
}

impl Default for GameClock {
    fn default() -> GameClock {
        GameClock::new()
    }
}

impl GameTime {
    /// Construct a `GameTime` object directly.
    ///
    /// This is useful primarily for writing tests or for constructing a
    /// `GameTime` without using a `GameClock`.
    pub fn new(
        frame_wall_time: chrono::DateTime<chrono::Local>,
        frame_game_time: time::Duration,
        elapsed_game_time: FloatDuration,
        elapsed_wall_time: FloatDuration,
        frame_number: u64,
    ) -> GameTime {
        GameTime {
            frame_wall_time,
            frame_game_time,
            elapsed_game_time,
            elapsed_wall_time,
            frame_number,
        }
    }

    /// The game time at the time of creation of this `GameTime` object.
    pub fn frame_game_time(&self) -> time::Duration {
        self.frame_game_time
    }
    /// The wall time at the time of creation of this `GameTime` object.
    pub fn frame_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.frame_wall_time
    }
    /// The amount of game time that passed since the previous frame.
    pub fn elapsed_game_time(&self) -> FloatDuration {
        self.elapsed_game_time
    }
    /// The amount of wall time that passed since the previous frame.
    pub fn elapsed_wall_time(&self) -> FloatDuration {
        self.elapsed_wall_time
    }
    /// The amount of elapsed wall time since the start of the current frame.
    ///
    /// This value is computed from the current instant when called, based
    /// on the frame start time. This can be used for intra-frame profiling.
    pub fn elapsed_time_since_frame_start(&self) -> FloatDuration {
        chrono::Local::now()
            .float_duration_since(self.frame_wall_time)
            .unwrap()
    }
    /// The index of the current frame.
    ///
    /// This value increases by 1 for each frame created, and represents the total
    /// number of frames executed in the simulation.
    pub fn frame_number(&self) -> u64 {
        self.frame_number
    }
    /// Return the instantaneous frame rate between the last and current frames.
    ///
    /// The "instantaneous" frame rate is computed from the last frame's elapsed
    /// time, and takes no previous frames into account.
    ///
    /// For a more stable frame rate, use a
    /// [`FrameCount`](../framerate/counter/trait.FrameCount.html) object.
    pub fn instantaneous_frame_rate(&self) -> f64 {
        1.0 / self.elapsed_game_time.as_seconds()
    }
}

impl GameClockBuilder {
    /// Construct a new `GameClockBuilder` with default values.
    ///
    /// Calling `build` on the returned object returns immediately gives the same
    /// result as `GameClock::new()`.
    pub fn new() -> GameClockBuilder {
        GameClockBuilder {
            start_game_time: time::Duration::new(0, 0),
            start_wall_time: chrono::Local::now(),
            start_frame: 0,
            clock_multiplier: 1.0,
        }
    }

    /// Set the initial game time when the game is started.
    ///
    /// Defaults to zero.
    pub fn start_game_time(&mut self, time: time::Duration) -> &mut GameClockBuilder {
        self.start_game_time = time;
        self
    }
    /// Set the initial wall time when the game is started.
    ///
    /// Defaults to `chrono::Local::now()`.
    pub fn start_wall_time(
        &mut self,
        time: chrono::DateTime<chrono::Local>,
    ) -> &mut GameClockBuilder {
        self.start_wall_time = time;
        self
    }
    /// Set the initial frame number.
    ///
    /// Defaults to `0`.
    pub fn start_frame(&mut self, frame_num: u64) -> &mut GameClockBuilder {
        self.start_frame = frame_num;
        self
    }
    /// Set the initial clock multiplier.
    ///
    /// Defaults to `1.0`.
    pub fn clock_multiplier(&mut self, multiplier: f64) -> &mut GameClockBuilder {
        self.clock_multiplier = multiplier;
        self
    }
    /// Construct a `GameClock` object with the set parameters.
    pub fn build(&self) -> GameClock {
        let start_game_time = GameTime {
            frame_wall_time: self.start_wall_time,
            frame_game_time: self.start_game_time,
            elapsed_game_time: FloatDuration::zero(),
            elapsed_wall_time: FloatDuration::zero(),
            frame_number: self.start_frame,
        };

        GameClock {
            last_frame_time: start_game_time,
            start_wall_time: self.start_wall_time,
            total_game_time: time::Duration::new(0, 0),
            current_frame: self.start_frame,
            clock_multiplier: self.clock_multiplier,
        }
    }
}

impl Default for GameClockBuilder {
    fn default() -> GameClockBuilder {
        GameClockBuilder::new()
    }
}

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

    #[test]
    fn test_clock_construct() {
        let clock = GameClock::new();
        assert_eq!(clock.clock_multiplier(), 1.0);
        assert_eq!(
            clock.last_frame_time().elapsed_game_time(),
            FloatDuration::zero()
        );

        let clock2 = GameClockBuilder::new()
            .clock_multiplier(5.0)
            .start_frame(100)
            .build();

        assert_eq!(clock2.current_frame_number(), 100);
        assert_eq!(clock2.clock_multiplier(), 5.0);
        assert_eq!(
            clock2.last_frame_time().elapsed_game_time(),
            FloatDuration::zero()
        );
        assert_eq!(
            clock2.last_frame_time().elapsed_wall_time(),
            FloatDuration::zero()
        );
        assert!(clock2.last_frame_time().frame_wall_time() <= Local::now());

        let start_time = Local::today().and_hms(12, 0, 0);
        let clock3 = GameClockBuilder::new()
            .start_game_time(time::Duration::new(100, 0))
            .start_wall_time(start_time)
            .build();

        assert_eq!(clock3.current_frame_number(), 0);
        assert_eq!(
            clock3.last_frame_time().frame_game_time(),
            time::Duration::new(100, 0)
        );
        assert_eq!(clock3.last_frame_time().frame_wall_time(), start_time);

        assert_eq!(GameClock::default().current_frame_number(), 0);
        assert_eq!(
            GameClock::default().last_frame_time().frame_game_time(),
            time::Duration::new(0, 0)
        );
    }

    #[test]
    fn test_clock_tick() {
        let mut clock = GameClock::new();
        let time = clock.tick(&mut step::ConstantStep::new(FloatDuration::seconds(1.0)));
        assert_eq!(time.frame_number(), 1);
        assert_eq!(time.frame_game_time(), time::Duration::new(1, 0));
        assert!(time.frame_wall_time() > clock.start_wall_time());
        assert!(time.frame_wall_time() < Local::now());
        assert_eq!(time.elapsed_game_time(), FloatDuration::seconds(1.0));
        assert!(time.elapsed_wall_time() < FloatDuration::seconds(1.0));

        let time2 = clock.tick(&mut step::VariableStep::new());
        assert_eq!(time2.frame_number(), 2);
        assert!(time2.frame_wall_time() > time.frame_wall_time());
        assert_eq!(time2.elapsed_game_time(), time2.elapsed_wall_time());
        assert!(time2.frame_game_time() > time.frame_game_time());
    }

    #[test]
    fn test_clock_tick_loop() {
        let dt = FloatDuration::milliseconds(50.0);
        let mut step = step::ConstantStep::new(dt);
        let mut clock = GameClock::default();

        for x in 0..10 {
            let frame_time = clock.tick(&mut step);

            assert_eq!(frame_time.frame_number(), x + 1);
            assert_eq!(frame_time.elapsed_game_time(), dt);
            assert_eq!(
                frame_time.frame_game_time(),
                time::Duration::new(0, (50000000 * (x + 1)) as u32)
            );
        }

        let frame_time = clock.last_frame_time();
        assert_eq!(
            FloatDuration::from_std(frame_time.frame_game_time()),
            FloatDuration::seconds(0.5)
        );
        assert!(frame_time.frame_wall_time() > clock.start_wall_time());
    }
}
<|endoftext|>


<commit_before>//! Unimplemented.
<commit_msg>Finish empty libextern.h<commit_after>// LibImport #

// LibExport #

// LibExtern extern LibImport #
<|endoftext|>


<commit_before>extern crate futures;
extern crate gopher_core;
extern crate tokio_core;
extern crate tokio_proto;
extern crate tokio_service;

use futures::{future, Future, BoxFuture};
use gopher_core::{DirEntity, ItemType};
use gopher_core::{GopherRequest, GopherResponse, GopherStr};
use gopher_core::proto::GopherServer;
use std::io;
use tokio_proto::TcpServer;
use tokio_service::Service;

pub struct HelloGopherServer;

impl Service for HelloGopherServer {
    type Request = GopherRequest;
    type Response = GopherResponse;
    type Error = io::Error;
    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, request: Self::Request) -> Self::Future {
        let response = match &request.selector[..] {
            b"" => GopherResponse::Menu(vec![
                DirEntity {
                    item_type: ItemType::Dir,
                    name: GopherStr::from_latin1(b"hello, world"),
                    selector: GopherStr::from_latin1(b"hello"),
                    host: GopherStr::from_latin1(b"0.0.0.0"),
                    port: 12345,
                },
                DirEntity {
                    item_type: ItemType::Dir,
                    name: GopherStr::from_latin1(b"Goodbye, world"),
                    selector: GopherStr::from_latin1(b"bye"),
                    host: GopherStr::from_latin1(b"0.0.0.0"),
                    port: 12345,
                },
            ]),
            b"hello" => GopherResponse::TextFile(
                GopherStr::from_latin1(b"Hello, world.\r\nWelcome to Gopher.").into_buf()),
            b"bye" => GopherResponse::TextFile(GopherStr::from_latin1(b"Goodbye").into_buf()),
            _ => GopherResponse::error(GopherStr::from_latin1(b"File not found")),
        };

        future::ok(response).boxed()
    }
}

fn main() {
    TcpServer::new(GopherServer, "0.0.0.0:12345".parse().unwrap())
        .serve(|| Ok(HelloGopherServer));
}
<commit_msg>Fixes for example server<commit_after>extern crate futures;
extern crate gopher_core;
extern crate tokio_core;
extern crate tokio_proto;
extern crate tokio_service;

use futures::{future, Future, BoxFuture};
use gopher_core::{DirEntity, ItemType};
use gopher_core::{GopherRequest, GopherResponse, GopherStr};
use gopher_core::proto::GopherServer;
use std::io;
use tokio_proto::TcpServer;
use tokio_service::Service;

pub struct HelloGopherServer;

impl Service for HelloGopherServer {
    type Request = GopherRequest;
    type Response = GopherResponse;
    type Error = io::Error;
    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, request: Self::Request) -> Self::Future {
        println!("got request {:?}", request);

        let response = match &request.selector[..] {
            b"" => GopherResponse::Menu(vec![
                DirEntity {
                    item_type: ItemType::File,
                    name: GopherStr::from_latin1(b"hello, world"),
                    selector: GopherStr::from_latin1(b"hello"),
                    host: GopherStr::from_latin1(b"0.0.0.0"),
                    port: 12345,
                },
                DirEntity {
                    item_type: ItemType::File,
                    name: GopherStr::from_latin1(b"Goodbye, world"),
                    selector: GopherStr::from_latin1(b"bye"),
                    host: GopherStr::from_latin1(b"0.0.0.0"),
                    port: 12345,
                },
            ]),
            b"hello" => GopherResponse::TextFile(
                GopherStr::from_latin1(b"Hello, world.\r\nWelcome to Gopher.").into_buf()),
            b"bye" => GopherResponse::TextFile(GopherStr::from_latin1(b"Goodbye").into_buf()),
            _ => GopherResponse::error(GopherStr::from_latin1(b"File not found")),
        };

        future::ok(response).boxed()
    }
}

fn main() {
    TcpServer::new(GopherServer, "0.0.0.0:12345".parse().unwrap())
        .serve(|| Ok(HelloGopherServer));
}
<|endoftext|>