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

use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::subst::{Kind, Subst, UnpackedKind};
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::util::nodemap::FxHashMap;

use super::explicit::ExplicitPredicatesMap;
use super::utils::*;

/// Infer predicates for the items in the crate.
///
/// global_inferred_outlives: this is initially the empty map that
///     was generated by walking the items in the crate. This will
///     now be filled with inferred predicates.
pub fn infer_predicates<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
) -> FxHashMap<DefId, RequiredPredicates<'tcx>> {
    debug!("infer_predicates");

    let mut predicates_added = true;

    let mut global_inferred_outlives = FxHashMap::default();

    // If new predicates were added then we need to re-calculate
    // all crates since there could be new implied predicates.
    while predicates_added {
        predicates_added = false;

        let mut visitor = InferVisitor {
            tcx: tcx,
            global_inferred_outlives: &mut global_inferred_outlives,
            predicates_added: &mut predicates_added,
            explicit_map: explicit_map,
        };

        // Visit all the crates and infer predicates
        tcx.hir.krate().visit_all_item_likes(&mut visitor);
    }

    global_inferred_outlives
}

pub struct InferVisitor<'cx, 'tcx: 'cx> {
    tcx: TyCtxt<'cx, 'tcx, 'tcx>,
    global_inferred_outlives: &'cx mut FxHashMap<DefId, RequiredPredicates<'tcx>>,
    predicates_added: &'cx mut bool,
    explicit_map: &'cx mut ExplicitPredicatesMap<'tcx>,
}

impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> {
    fn visit_item(&mut self, item: &hir::Item) {
        let item_did = self.tcx.hir.local_def_id(item.id);

        debug!("InferVisitor::visit_item(item={:?})", item_did);

        let node_id = self
            .tcx
            .hir
            .as_local_node_id(item_did)
            .expect("expected local def-id");
        let item = match self.tcx.hir.get(node_id) {
            hir::map::NodeItem(item) => item,
            _ => bug!(),
        };

        let mut item_required_predicates = RequiredPredicates::default();
        match item.node {
            hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) => {
                let adt_def = self.tcx.adt_def(item_did);

                // Iterate over all fields in item_did
                for field_def in adt_def.all_fields() {
                    // Calculating the predicate requirements necessary
                    // for item_did.
                    //
                    // For field of type &'a T (reference) or Adt
                    // (struct/enum/union) there will be outlive
                    // requirements for adt_def.
                    let field_ty = self.tcx.type_of(field_def.did);
                    insert_required_predicates_to_be_wf(
                        self.tcx,
                        field_ty,
                        self.global_inferred_outlives,
                        &mut item_required_predicates,
                        &mut self.explicit_map,
                    );
                }
            }

            _ => {}
        };

        // If new predicates were added (`local_predicate_map` has more
        // predicates than the `global_inferred_outlives`), the new predicates
        // might result in implied predicates for their parent types.
        // Therefore mark `predicates_added` as true and which will ensure
        // we walk the crates again and re-calculate predicates for all
        // items.
        let item_predicates_len: usize = self
            .global_inferred_outlives
            .get(&item_did)
            .map(|p| p.len())
            .unwrap_or(0);
        if item_required_predicates.len() > item_predicates_len {
            *self.predicates_added = true;
            self.global_inferred_outlives
                .insert(item_did, item_required_predicates);
        }
    }

    fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem) {}

    fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) {}
}

fn insert_required_predicates_to_be_wf<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    field_ty: Ty<'tcx>,
    global_inferred_outlives: &FxHashMap<DefId, RequiredPredicates<'tcx>>,
    required_predicates: &mut RequiredPredicates<'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
) {
    for ty in field_ty.walk() {
        match ty.sty {
            // The field is of type &'a T which means that we will have
            // a predicate requirement of T: 'a (T outlives 'a).
            //
            // We also want to calculate potential predicates for the T
            ty::Ref(region, rty, _) => {
                debug!("Ref");
                insert_outlives_predicate(tcx, rty.into(), region, required_predicates);
            }

            // For each Adt (struct/enum/union) type `Foo<'a, T>`, we
            // can load the current set of inferred and explicit
            // predicates from `global_inferred_outlives` and filter the
            // ones that are TypeOutlives.
            ty::Adt(def, substs) => {
                // First check the inferred predicates
                //
                // Example 1:
                //
                //     struct Foo<'a, T> {
                //         field1: Bar<'a, T>
                //     }
                //
                //     struct Bar<'b, U> {
                //         field2: &'b U
                //     }
                //
                // Here, when processing the type of `field1`, we would
                // request the set of implicit predicates computed for `Bar`
                // thus far. This will initially come back empty, but in next
                // round we will get `U: 'b`. We then apply the substitution
                // `['b => 'a, U => T]` and thus get the requirement that `T:
                // 'a` holds for `Foo`.
                debug!("Adt");
                if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did) {
                    for unsubstituted_predicate in unsubstituted_predicates {
                        // `unsubstituted_predicate` is `U: 'b` in the
                        // example above.  So apply the substitution to
                        // get `T: 'a` (or `predicate`):
                        let predicate = unsubstituted_predicate.subst(tcx, substs);
                        insert_outlives_predicate(
                            tcx,
                            predicate.0,
                            predicate.1,
                            required_predicates,
                        );
                    }
                }

                // Check if the type has any explicit predicates that need
                // to be added to `required_predicates`
                // let _: () = substs.region_at(0);
                check_explicit_predicates(
                    tcx,
                    &def.did,
                    substs,
                    required_predicates,
                    explicit_map,
                    false,
                );
            }

            ty::Dynamic(obj, ..) => {
                // This corresponds to `dyn Trait<..>`. In this case, we should
                // use the explicit predicates as well.

                // We are passing type `ty` as a placeholder value with the function
                // `with_self_ty`, since there is no concrete type `Self` for a
                // `dyn Trait` at this stage. Therefore when checking explicit
                // predicates in `check_explicit_predicates` we need to ignore
                // checking the explicit_map for Self type.
                debug!("Dynamic");
                debug!("field_ty = {}", &field_ty);
                debug!("ty in field = {}", &ty);
                if let Some(ex_trait_ref) = obj.principal() {
                    // The method `has_escaping_regions` checks if
                    // there are any late-bound regions, which is
                    // the lifetime `'r`. It is safe to ignore
                    // these since `'r` is not in scope for `Foo`.
                    //
                    // ```
                    // struct Foo {
                    //   bar: for<'r> Fn(usize, &'r FnMut())
                    // }
                    // ```
                    if !ty.has_escaping_regions() {
                        check_explicit_predicates(
                            tcx,
                            &ex_trait_ref.skip_binder().def_id,
                            ex_trait_ref.with_self_ty(tcx, ty).skip_binder().substs,
                            required_predicates,
                            explicit_map,
                            true,
                        );
                    }
                }
            }

            ty::Projection(obj) => {
                // This corresponds to `<T as Foo<'a>>::Bar`. In this case, we should use the
                // explicit predicates as well.
                debug!("Projection");
                check_explicit_predicates(
                    tcx,
                    &tcx.associated_item(obj.item_def_id).container.id(),
                    obj.substs,
                    required_predicates,
                    explicit_map,
                    false,
                );
            }

            _ => {}
        }
    }
}

/// We also have to check the explicit predicates
/// declared on the type.
///
///     struct Foo<'a, T> {
///         field1: Bar<T>
///     }
///
///     struct Bar<U> where U: 'static, U: Foo {
///         ...
///     }
///
/// Here, we should fetch the explicit predicates, which
/// will give us `U: 'static` and `U: Foo`. The latter we
/// can ignore, but we will want to process `U: 'static`,
/// applying the substitution as above.
pub fn check_explicit_predicates<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    def_id: &DefId,
    substs: &[Kind<'tcx>],
    required_predicates: &mut RequiredPredicates<'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
    ignore_self_ty: bool,
) {
    debug!("def_id = {:?}", &def_id);
    debug!("substs = {:?}", &substs);
    debug!("explicit_map =  {:?}", explicit_map);
    debug!("required_predicates = {:?}", required_predicates);
    let explicit_predicates = explicit_map.explicit_predicates_of(tcx, *def_id);

    for outlives_predicate in explicit_predicates.iter() {
        debug!("outlives_predicate = {:?}", &outlives_predicate);

        // Careful: If we are inferring the effects of a `dyn Trait<..>`
        // type, then when we look up the predicates for `Trait`,
        // we may find some that reference `Self`. e.g., perhaps the
        // definition of `Trait` was:
        //
        // ```
        // trait Trait<'a, T> where Self: 'a  { .. }
        // ```
        //
        // we want to ignore such predicates here, because
        // there is no type parameter for them to affect. Consider
        // a struct containing `dyn Trait`:
        //
        // ```
        // struct MyStruct<'x, X> { field: Box<dyn Trait<'x, X>> }
        // ```
        //
        // The `where Self: 'a` predicate refers to the *existential, hidden type*
        // that is represented by the `dyn Trait`, not to the `X` type parameter
        // (or any other generic parameter) declared on `MyStruct`.
        //
        // Note that we do this check for self **before** applying `substs`. In the
        // case that `substs` come from a `dyn Trait` type, our caller will have
        // included `Self = dyn Trait<'x, X>` as the value for `Self`. If we were
        // to apply the substs, and not filter this predicate, we might then falsely
        // conclude that e.g. `X: 'x` was a reasonable inferred requirement.
        if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
            if ty.is_self() && ignore_self_ty {
                debug!("skipping self ty = {:?}", &ty);
                continue;
            }
        }

        let predicate = outlives_predicate.subst(tcx, substs);
        debug!("predicate = {:?}", &predicate);
        insert_outlives_predicate(tcx, predicate.0.into(), predicate.1, required_predicates);
    }
    // }
}
<commit_msg>use `usize` for self instead of `ty`<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::subst::{Kind, Subst, UnpackedKind};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::util::nodemap::FxHashMap;

use super::explicit::ExplicitPredicatesMap;
use super::utils::*;

/// Infer predicates for the items in the crate.
///
/// global_inferred_outlives: this is initially the empty map that
///     was generated by walking the items in the crate. This will
///     now be filled with inferred predicates.
pub fn infer_predicates<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
) -> FxHashMap<DefId, RequiredPredicates<'tcx>> {
    debug!("infer_predicates");

    let mut predicates_added = true;

    let mut global_inferred_outlives = FxHashMap::default();

    // If new predicates were added then we need to re-calculate
    // all crates since there could be new implied predicates.
    while predicates_added {
        predicates_added = false;

        let mut visitor = InferVisitor {
            tcx: tcx,
            global_inferred_outlives: &mut global_inferred_outlives,
            predicates_added: &mut predicates_added,
            explicit_map: explicit_map,
        };

        // Visit all the crates and infer predicates
        tcx.hir.krate().visit_all_item_likes(&mut visitor);
    }

    global_inferred_outlives
}

pub struct InferVisitor<'cx, 'tcx: 'cx> {
    tcx: TyCtxt<'cx, 'tcx, 'tcx>,
    global_inferred_outlives: &'cx mut FxHashMap<DefId, RequiredPredicates<'tcx>>,
    predicates_added: &'cx mut bool,
    explicit_map: &'cx mut ExplicitPredicatesMap<'tcx>,
}

impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> {
    fn visit_item(&mut self, item: &hir::Item) {
        let item_did = self.tcx.hir.local_def_id(item.id);

        debug!("InferVisitor::visit_item(item={:?})", item_did);

        let node_id = self
            .tcx
            .hir
            .as_local_node_id(item_did)
            .expect("expected local def-id");
        let item = match self.tcx.hir.get(node_id) {
            hir::map::NodeItem(item) => item,
            _ => bug!(),
        };

        let mut item_required_predicates = RequiredPredicates::default();
        match item.node {
            hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) => {
                let adt_def = self.tcx.adt_def(item_did);

                // Iterate over all fields in item_did
                for field_def in adt_def.all_fields() {
                    // Calculating the predicate requirements necessary
                    // for item_did.
                    //
                    // For field of type &'a T (reference) or Adt
                    // (struct/enum/union) there will be outlive
                    // requirements for adt_def.
                    let field_ty = self.tcx.type_of(field_def.did);
                    insert_required_predicates_to_be_wf(
                        self.tcx,
                        field_ty,
                        self.global_inferred_outlives,
                        &mut item_required_predicates,
                        &mut self.explicit_map,
                    );
                }
            }

            _ => {}
        };

        // If new predicates were added (`local_predicate_map` has more
        // predicates than the `global_inferred_outlives`), the new predicates
        // might result in implied predicates for their parent types.
        // Therefore mark `predicates_added` as true and which will ensure
        // we walk the crates again and re-calculate predicates for all
        // items.
        let item_predicates_len: usize = self
            .global_inferred_outlives
            .get(&item_did)
            .map(|p| p.len())
            .unwrap_or(0);
        if item_required_predicates.len() > item_predicates_len {
            *self.predicates_added = true;
            self.global_inferred_outlives
                .insert(item_did, item_required_predicates);
        }
    }

    fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem) {}

    fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) {}
}

fn insert_required_predicates_to_be_wf<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    field_ty: Ty<'tcx>,
    global_inferred_outlives: &FxHashMap<DefId, RequiredPredicates<'tcx>>,
    required_predicates: &mut RequiredPredicates<'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
) {
    for ty in field_ty.walk() {
        match ty.sty {
            // The field is of type &'a T which means that we will have
            // a predicate requirement of T: 'a (T outlives 'a).
            //
            // We also want to calculate potential predicates for the T
            ty::Ref(region, rty, _) => {
                debug!("Ref");
                insert_outlives_predicate(tcx, rty.into(), region, required_predicates);
            }

            // For each Adt (struct/enum/union) type `Foo<'a, T>`, we
            // can load the current set of inferred and explicit
            // predicates from `global_inferred_outlives` and filter the
            // ones that are TypeOutlives.
            ty::Adt(def, substs) => {
                // First check the inferred predicates
                //
                // Example 1:
                //
                //     struct Foo<'a, T> {
                //         field1: Bar<'a, T>
                //     }
                //
                //     struct Bar<'b, U> {
                //         field2: &'b U
                //     }
                //
                // Here, when processing the type of `field1`, we would
                // request the set of implicit predicates computed for `Bar`
                // thus far. This will initially come back empty, but in next
                // round we will get `U: 'b`. We then apply the substitution
                // `['b => 'a, U => T]` and thus get the requirement that `T:
                // 'a` holds for `Foo`.
                debug!("Adt");
                if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did) {
                    for unsubstituted_predicate in unsubstituted_predicates {
                        // `unsubstituted_predicate` is `U: 'b` in the
                        // example above.  So apply the substitution to
                        // get `T: 'a` (or `predicate`):
                        let predicate = unsubstituted_predicate.subst(tcx, substs);
                        insert_outlives_predicate(
                            tcx,
                            predicate.0,
                            predicate.1,
                            required_predicates,
                        );
                    }
                }

                // Check if the type has any explicit predicates that need
                // to be added to `required_predicates`
                // let _: () = substs.region_at(0);
                check_explicit_predicates(
                    tcx,
                    &def.did,
                    substs,
                    required_predicates,
                    explicit_map,
                    IgnoreSelfTy(false),
                );
            }

            ty::Dynamic(obj, ..) => {
                // This corresponds to `dyn Trait<..>`. In this case, we should
                // use the explicit predicates as well.

                debug!("Dynamic");
                debug!("field_ty = {}", &field_ty);
                debug!("ty in field = {}", &ty);
                if let Some(ex_trait_ref) = obj.principal() {
                    // Here, we are passing the type `usize` as a
                    // placeholder value with the function
                    // `with_self_ty`, since there is no concrete type
                    // `Self` for a `dyn Trait` at this
                    // stage. Therefore when checking explicit
                    // predicates in `check_explicit_predicates` we
                    // need to ignore checking the explicit_map for
                    // Self type.
                    let substs = ex_trait_ref.with_self_ty(tcx, tcx.types.usize).skip_binder().substs;
                    check_explicit_predicates(
                        tcx,
                        &ex_trait_ref.skip_binder().def_id,
                        substs,
                        required_predicates,
                        explicit_map,
                        IgnoreSelfTy(true),
                    );
                }
            }

            ty::Projection(obj) => {
                // This corresponds to `<T as Foo<'a>>::Bar`. In this case, we should use the
                // explicit predicates as well.
                debug!("Projection");
                check_explicit_predicates(
                    tcx,
                    &tcx.associated_item(obj.item_def_id).container.id(),
                    obj.substs,
                    required_predicates,
                    explicit_map,
                    IgnoreSelfTy(false),
                );
            }

            _ => {}
        }
    }
}

pub struct IgnoreSelfTy(bool);

/// We also have to check the explicit predicates
/// declared on the type.
///
///     struct Foo<'a, T> {
///         field1: Bar<T>
///     }
///
///     struct Bar<U> where U: 'static, U: Foo {
///         ...
///     }
///
/// Here, we should fetch the explicit predicates, which
/// will give us `U: 'static` and `U: Foo`. The latter we
/// can ignore, but we will want to process `U: 'static`,
/// applying the substitution as above.
pub fn check_explicit_predicates<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    def_id: &DefId,
    substs: &[Kind<'tcx>],
    required_predicates: &mut RequiredPredicates<'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
    ignore_self_ty: IgnoreSelfTy,
) {
    debug!("def_id = {:?}", &def_id);
    debug!("substs = {:?}", &substs);
    debug!("explicit_map =  {:?}", explicit_map);
    debug!("required_predicates = {:?}", required_predicates);
    let explicit_predicates = explicit_map.explicit_predicates_of(tcx, *def_id);

    for outlives_predicate in explicit_predicates.iter() {
        debug!("outlives_predicate = {:?}", &outlives_predicate);

        // Careful: If we are inferring the effects of a `dyn Trait<..>`
        // type, then when we look up the predicates for `Trait`,
        // we may find some that reference `Self`. e.g., perhaps the
        // definition of `Trait` was:
        //
        // ```
        // trait Trait<'a, T> where Self: 'a  { .. }
        // ```
        //
        // we want to ignore such predicates here, because
        // there is no type parameter for them to affect. Consider
        // a struct containing `dyn Trait`:
        //
        // ```
        // struct MyStruct<'x, X> { field: Box<dyn Trait<'x, X>> }
        // ```
        //
        // The `where Self: 'a` predicate refers to the *existential, hidden type*
        // that is represented by the `dyn Trait`, not to the `X` type parameter
        // (or any other generic parameter) declared on `MyStruct`.
        //
        // Note that we do this check for self **before** applying `substs`. In the
        // case that `substs` come from a `dyn Trait` type, our caller will have
        // included `Self = dyn Trait<'x, X>` as the value for `Self`. If we were
        // to apply the substs, and not filter this predicate, we might then falsely
        // conclude that e.g. `X: 'x` was a reasonable inferred requirement.
        if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
            if ty.is_self() && ignore_self_ty.0 {
                debug!("skipping self ty = {:?}", &ty);
                continue;
            }
        }

        let predicate = outlives_predicate.subst(tcx, substs);
        debug!("predicate = {:?}", &predicate);
        insert_outlives_predicate(tcx, predicate.0.into(), predicate.1, required_predicates);
    }
}
<|endoftext|>


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

pub mod perm;
pub mod sys;

use std::error;
use std::fmt;
use std::marker::PhantomData;
use std::result;
use std::str::FromStr;

use serde;

pub fn deserialize_using_from_str<T, E, D>(d: D) -> result::Result<T, D::Error>
    where T: FromStr<Err = E>,
          E: error::Error,
          D: serde::Deserializer
{
    struct FromStringable<T, E>(PhantomData<T>, PhantomData<E>);

    impl<T, E> serde::de::Visitor for FromStringable<T, E>
        where T: FromStr<Err = E>,
              E: error::Error
    {
        type Value = T;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a string")
        }

        fn visit_str<R>(self, value: &str) -> result::Result<T, R>
            where R: serde::de::Error
        {
            match FromStr::from_str(value) {
                Ok(t) => Ok(t),
                Err(err) => {
                    Err(R::custom(format!("string cannot be parsed: \"{}\" ({})",
                                          value,
                                          err.description())))
                }
            }
        }
    }

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

pub mod perm;
pub mod sys;

use std::error;
use std::fmt;
use std::marker::PhantomData;
use std::result;
use std::str::FromStr;

use serde;

pub fn deserialize_using_from_str<T, E, D>(d: D) -> result::Result<T, D::Error>
    where T: FromStr<Err = E>,
          E: error::Error,
          D: serde::Deserializer
{
    struct FromStringable<T, E>(PhantomData<T>, PhantomData<E>);

    impl<T, E> serde::de::Visitor for FromStringable<T, E>
        where T: FromStr<Err = E>,
              E: error::Error
    {
        type Value = T;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a string")
        }

        fn visit_str<R>(self, value: &str) -> result::Result<T, R>
            where R: serde::de::Error
        {
            match FromStr::from_str(value) {
                Ok(t) => Ok(t),
                Err(err) => {
                    Err(R::custom(format!("string cannot be parsed: \"{}\" ({})",
                                          value,
                                          err.description())))
                }
            }
        }
    }

    d.deserialize(FromStringable(PhantomData, PhantomData))
}

pub fn serialize_using_to_string<T, S>(t: &T, s: S) -> result::Result<S::Ok, S::Error>
    where T: ToString,
          S: serde::Serializer
{
    s.serialize_str(&t.to_string())
}
<|endoftext|>


<commit_before>// Copyright:: Copyright (c) 2015-2016 The Habitat Maintainers
//
// The terms of the Evaluation Agreement (Habitat) between Chef Software Inc.
// and the party accessing this file ("Licensee") apply to Licensee's use of
// the Software until such time that the Software is made available under an
// open source license such as the Apache 2.0 License.

use error::{Error, Result};
use std::process::Command;

pub fn ip() -> Result<String> {
    debug!("Shelling out to determine IP address");
    let output = try!(Command::new("sh")
        .arg("-c")
        .arg("ip route get 8.8.8.8 | awk '{printf \"%s\", $NF; exit}'")
        .output());
    match output.status.success() {
        true => {
            debug!("IP address is {}", String::from_utf8_lossy(&output.stdout));
            let ip = try!(String::from_utf8(output.stdout));
            Ok(ip)
        }
        false => {
            debug!("IP address command returned: OUT: {} ERR: {}",
                   String::from_utf8_lossy(&output.stdout),
                   String::from_utf8_lossy(&output.stderr));
            Err(Error::NoOutboundAddr)
        }
    }
}
<commit_msg>[sup,core] Set optional PATH when shelling out for ip & hostname.<commit_after>// Copyright:: Copyright (c) 2015-2016 The Habitat Maintainers
//
// The terms of the Evaluation Agreement (Habitat) between Chef Software Inc.
// and the party accessing this file ("Licensee") apply to Licensee's use of
// the Software until such time that the Software is made available under an
// open source license such as the Apache 2.0 License.

use error::{Error, Result};
use std::process::Command;

pub fn ip(path: Option<&str>) -> Result<String> {
    debug!("Shelling out to determine IP address");
    let mut cmd = Command::new("sh");
    cmd.arg("-c").arg("ip route get 8.8.8.8 | awk '{printf \"%s\", $NF; exit}'");
    if let Some(path) = path {
        cmd.env("PATH", path);
        debug!("Setting shell out PATH={}", path);
    }
    let output = try!(cmd.output());
    match output.status.success() {
        true => {
            debug!("IP address is {}", String::from_utf8_lossy(&output.stdout));
            let ip = try!(String::from_utf8(output.stdout));
            Ok(ip)
        }
        false => {
            debug!("IP address command returned: OUT: {} ERR: {}",
                   String::from_utf8_lossy(&output.stdout),
                   String::from_utf8_lossy(&output.stderr));
            Err(Error::NoOutboundAddr)
        }
    }
}
<|endoftext|>


<commit_before>use cairo;
use cairo_sys;
use glib;
use glib::translate::*;
use glib_sys;
use libc;
use std::cell::{Cell, RefCell};
use std::ptr;

use aspect_ratio::AspectRatio;
use attributes::Attribute;
use draw::{add_clipping_rect, draw_surface};
use drawing_ctx::{self, RsvgDrawingCtx};
use handle::RsvgHandle;
use length::*;
use node::*;
use parsers::parse;
use property_bag::PropertyBag;
use state::{self, RsvgState};

struct NodeImage {
    aspect: Cell<AspectRatio>,
    x: Cell<RsvgLength>,
    y: Cell<RsvgLength>,
    w: Cell<RsvgLength>,
    h: Cell<RsvgLength>,
    surface: RefCell<Option<cairo::ImageSurface>>,
}

impl NodeImage {
    fn new() -> NodeImage {
        NodeImage {
            aspect: Cell::new(AspectRatio::default()),
            x: Cell::new(RsvgLength::default()),
            y: Cell::new(RsvgLength::default()),
            w: Cell::new(RsvgLength::default()),
            h: Cell::new(RsvgLength::default()),
            surface: RefCell::new(None),
        }
    }
}

impl NodeTrait for NodeImage {
    fn set_atts(&self, _: &RsvgNode, handle: *const RsvgHandle, pbag: &PropertyBag) -> NodeResult {
        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::X => self.x.set(parse("x", value, LengthDir::Horizontal, None)?),
                Attribute::Y => self.y.set(parse("y", value, LengthDir::Vertical, None)?),
                Attribute::Width => self.w.set(parse(
                    "width",
                    value,
                    LengthDir::Horizontal,
                    Some(RsvgLength::check_nonnegative),
                )?),
                Attribute::Height => self.h.set(parse(
                    "height",
                    value,
                    LengthDir::Vertical,
                    Some(RsvgLength::check_nonnegative),
                )?),

                Attribute::PreserveAspectRatio => {
                    self.aspect
                        .set(parse("preserveAspectRatio", value, (), None)?)
                }

                Attribute::XlinkHref | Attribute::Path => {
                    // "path" is used by some older Adobe Illustrator versions

                    extern "C" {
                        fn rsvg_cairo_surface_new_from_href(
                            handle: *const RsvgHandle,
                            href: *const libc::c_char,
                            error: *mut *mut glib_sys::GError,
                        ) -> *mut cairo_sys::cairo_surface_t;
                    }

                    let mut error = ptr::null_mut();

                    let raw_surface = unsafe {
                        rsvg_cairo_surface_new_from_href(handle, value.to_glib_none().0, &mut error)
                    };
                    if !raw_surface.is_null() {
                        *self.surface.borrow_mut() = Some(unsafe {
                            cairo::ImageSurface::from_raw_full(raw_surface).unwrap()
                        });
                    } else {
                        let _: glib::Error = unsafe { from_glib_full(error) }; // FIXME: we should note that the image couldn't be loaded
                    }
                }

                _ => (),
            }
        }

        Ok(())
    }

    fn draw(
        &self,
        node: &RsvgNode,
        draw_ctx: *mut RsvgDrawingCtx,
        state: *mut RsvgState,
        dominate: i32,
        clipping: bool,
    ) {
        if let Some(ref surface) = *self.surface.borrow() {
            let x = self.x.get().normalize(draw_ctx);
            let y = self.y.get().normalize(draw_ctx);
            let w = self.w.get().normalize(draw_ctx);
            let h = self.h.get().normalize(draw_ctx);

            let state = node.get_state();

            drawing_ctx::state_reinherit_top(draw_ctx, state, dominate);
            drawing_ctx::push_discrete_layer(draw_ctx, clipping);

            let aspect = self.aspect.get();

            if !state::is_overflow(state) && aspect.is_slice() {
                let ctx_rstate = state::get_state_rust(drawing_ctx::get_current_state(draw_ctx));
                add_clipping_rect(draw_ctx, &ctx_rstate.affine, x, y, w, h);
            }

            let (x, y, w, h) = aspect.compute(
                f64::from(surface.get_width()),
                f64::from(surface.get_height()),
                x,
                y,
                w,
                h,
            );

            draw_surface(
                draw_ctx,
                drawing_ctx::get_current_state(draw_ctx),
                surface,
                x,
                y,
                w,
                h,
                clipping,
            );

            drawing_ctx::pop_discrete_layer(draw_ctx, clipping);
        }
    }

    fn get_c_impl(&self) -> *const RsvgCNodeImpl {
        unreachable!();
    }
}

#[no_mangle]
pub extern "C" fn rsvg_node_image_new(
    _: *const libc::c_char,
    raw_parent: *const RsvgNode,
) -> *const RsvgNode {
    boxed_node_new(NodeType::Image, raw_parent, Box::new(NodeImage::new()))
}
<commit_msg>NodeImage::draw(): Use the passed-in state<commit_after>use cairo;
use cairo_sys;
use glib;
use glib::translate::*;
use glib_sys;
use libc;
use std::cell::{Cell, RefCell};
use std::ptr;

use aspect_ratio::AspectRatio;
use attributes::Attribute;
use draw::{add_clipping_rect, draw_surface};
use drawing_ctx::{self, RsvgDrawingCtx};
use handle::RsvgHandle;
use length::*;
use node::*;
use parsers::parse;
use property_bag::PropertyBag;
use state::{self, RsvgState};

struct NodeImage {
    aspect: Cell<AspectRatio>,
    x: Cell<RsvgLength>,
    y: Cell<RsvgLength>,
    w: Cell<RsvgLength>,
    h: Cell<RsvgLength>,
    surface: RefCell<Option<cairo::ImageSurface>>,
}

impl NodeImage {
    fn new() -> NodeImage {
        NodeImage {
            aspect: Cell::new(AspectRatio::default()),
            x: Cell::new(RsvgLength::default()),
            y: Cell::new(RsvgLength::default()),
            w: Cell::new(RsvgLength::default()),
            h: Cell::new(RsvgLength::default()),
            surface: RefCell::new(None),
        }
    }
}

impl NodeTrait for NodeImage {
    fn set_atts(&self, _: &RsvgNode, handle: *const RsvgHandle, pbag: &PropertyBag) -> NodeResult {
        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::X => self.x.set(parse("x", value, LengthDir::Horizontal, None)?),
                Attribute::Y => self.y.set(parse("y", value, LengthDir::Vertical, None)?),
                Attribute::Width => self.w.set(parse(
                    "width",
                    value,
                    LengthDir::Horizontal,
                    Some(RsvgLength::check_nonnegative),
                )?),
                Attribute::Height => self.h.set(parse(
                    "height",
                    value,
                    LengthDir::Vertical,
                    Some(RsvgLength::check_nonnegative),
                )?),

                Attribute::PreserveAspectRatio => {
                    self.aspect
                        .set(parse("preserveAspectRatio", value, (), None)?)
                }

                Attribute::XlinkHref | Attribute::Path => {
                    // "path" is used by some older Adobe Illustrator versions

                    extern "C" {
                        fn rsvg_cairo_surface_new_from_href(
                            handle: *const RsvgHandle,
                            href: *const libc::c_char,
                            error: *mut *mut glib_sys::GError,
                        ) -> *mut cairo_sys::cairo_surface_t;
                    }

                    let mut error = ptr::null_mut();

                    let raw_surface = unsafe {
                        rsvg_cairo_surface_new_from_href(handle, value.to_glib_none().0, &mut error)
                    };
                    if !raw_surface.is_null() {
                        *self.surface.borrow_mut() = Some(unsafe {
                            cairo::ImageSurface::from_raw_full(raw_surface).unwrap()
                        });
                    } else {
                        let _: glib::Error = unsafe { from_glib_full(error) }; // FIXME: we should note that the image couldn't be loaded
                    }
                }

                _ => (),
            }
        }

        Ok(())
    }

    fn draw(
        &self,
        _node: &RsvgNode,
        draw_ctx: *mut RsvgDrawingCtx,
        state: *mut RsvgState,
        _dominate: i32,
        clipping: bool,
    ) {
        if let Some(ref surface) = *self.surface.borrow() {
            let x = self.x.get().normalize(draw_ctx);
            let y = self.y.get().normalize(draw_ctx);
            let w = self.w.get().normalize(draw_ctx);
            let h = self.h.get().normalize(draw_ctx);

            drawing_ctx::push_discrete_layer(draw_ctx, clipping);

            let aspect = self.aspect.get();

            if !state::is_overflow(state) && aspect.is_slice() {
                let rstate = state::get_state_rust(state);
                add_clipping_rect(draw_ctx, &rstate.affine, x, y, w, h);
            }

            let (x, y, w, h) = aspect.compute(
                f64::from(surface.get_width()),
                f64::from(surface.get_height()),
                x,
                y,
                w,
                h,
            );

            draw_surface(draw_ctx, state, surface, x, y, w, h, clipping);

            drawing_ctx::pop_discrete_layer(draw_ctx, clipping);
        }
    }

    fn get_c_impl(&self) -> *const RsvgCNodeImpl {
        unreachable!();
    }
}

#[no_mangle]
pub extern "C" fn rsvg_node_image_new(
    _: *const libc::c_char,
    raw_parent: *const RsvgNode,
) -> *const RsvgNode {
    boxed_node_new(NodeType::Image, raw_parent, Box::new(NodeImage::new()))
}
<|endoftext|>


<commit_before>//! Create virtual tables.
//! (See http://sqlite.org/vtab.html)
use std::borrow::Cow;
use std::borrow::Cow::{Borrowed, Owned};
use std::ffi::CString;
use std::mem;
use std::ptr;
use libc;

use {Connection, Error, Result, InnerConnection, str_to_cstring};
use error::error_from_sqlite_code;
use ffi;

// let conn: Connection = ...;
// let mod: Module = ...; // VTab builder
// conn.create_module("module", mod);
//
// conn.execute("CREATE VIRTUAL TABLE foo USING module(...)");
// \-> Module::xcreate
//  |-> let vtab: VTab = ...; // on the heap
//  \-> conn.declare_vtab("CREATE TABLE foo (...)");
// conn = Connection::open(...);
// \-> Module::xconnect
//  |-> let vtab: VTab = ...; // on the heap
//  \-> conn.declare_vtab("CREATE TABLE foo (...)");
//
// conn.close();
// \-> vtab.xdisconnect
// conn.execute("DROP TABLE foo");
// \-> vtab.xDestroy
//
// let stmt = conn.prepare("SELECT ... FROM foo WHERE ...");
// \-> vtab.xbestindex
// stmt.query().next();
// \-> vtab.xopen
//  |-> let cursor: Cursor = ...; // on the heap
//  |-> cursor.xfilter or xnext
//  |-> cursor.xeof
//  \-> if not eof { cursor.column or xrowid } else { cursor.xclose }
//

/// Virtual table instance trait.
pub trait VTab<C: VTabCursor<Self>>: Sized {
    /// Create a new instance of a virtual table in response to a CREATE VIRTUAL TABLE statement.
    /// The `db` parameter is a pointer to the SQLite database connection that is executing the CREATE VIRTUAL TABLE statement.
    fn create(db: *mut ffi::sqlite3,
              aux: *mut libc::c_void,
              args: &[*const libc::c_char])
              -> Result<Self>;
    /// Determine the best way to access the virtual table.
    fn best_index(&self, info: *mut ffi::sqlite3_index_info);
    /// Create a new cursor used for accessing a virtual table.
    fn open(&self) -> Result<C>;
}

/// Virtual table cursor trait.
pub trait VTabCursor<V: VTab<Self>>: Sized {
    /// Accessor to the associated virtual table.
    fn vtab(&self) -> &mut V;
    /// Begin a search of a virtual table.
    fn filter(&mut self,
              idx_num: libc::c_int,
              idx_str: *const libc::c_char,
              argc: libc::c_int,
              argv: *mut *mut ffi::sqlite3_value)
              -> Result<()>;
    /// Advance cursor to the next row of a result set initiated by `filter`.
    fn next(&mut self) -> Result<()>;
    /// Must return `false` if the cursor currently points to a valid row of data, or `true` otherwise.
    fn eof(&self) -> bool;
    /// Find the value for the `i`-th column of the current row. `i` is zero-based so the first column is numbered 0.
    /// May return its result back to SQLite using one of the specified `ctx`.
    fn column(&self, ctx: *mut ffi::sqlite3_context, i: libc::c_int) -> Result<()>;
    /// Return the rowid of row that the cursor is currently pointing at.
    fn rowid(&self) -> Result<i64>;
}

impl Connection {
    /// Register a virtual table implementation.
    pub fn create_module<A>(&self,
                            module_name: &str,
                            module: *const ffi::sqlite3_module,
                            aux: Option<A>)
                            -> Result<()> {
        self.db
            .borrow_mut()
            .create_module(module_name, module, aux)
    }
}

impl InnerConnection {
    fn create_module<A>(&mut self,
                        module_name: &str,
                        module: *const ffi::sqlite3_module,
                        aux: Option<A>)
                        -> Result<()> {
        let c_name = try!(str_to_cstring(module_name));
        let r = match aux {
            Some(aux) => {
                let boxed_aux: *mut A = Box::into_raw(Box::new(aux));
                unsafe {
                    ffi::sqlite3_create_module_v2(self.db(),
                                                  c_name.as_ptr(),
                                                  module,
                                                  mem::transmute(boxed_aux),
                                                  Some(mem::transmute(free_boxed_value::<A>)))
                }
            }
            None => unsafe {
                ffi::sqlite3_create_module_v2(self.db(),
                                              c_name.as_ptr(),
                                              module,
                                              ptr::null_mut(),
                                              None)
            },
        };
        self.decode_result(r)
    }
}

/// Declare the schema of a virtual table.
pub fn declare_vtab(db: *mut ffi::sqlite3, sql: &str) -> Result<()> {
    let c_sql = try!(CString::new(sql));
    let rc = unsafe { ffi::sqlite3_declare_vtab(db, c_sql.as_ptr()) };
    if rc == ffi::SQLITE_OK {
        Ok(())
    } else {
        Err(error_from_sqlite_code(rc, None))
    }
}

/// Escape double-quote (`"`) character occurences by doubling them (`""`).
pub fn escape_double_quote<'a>(identifier: &'a str) -> Cow<'a, str> {
    if identifier.contains('"') {
        // escape quote by doubling them
        Owned(identifier.replace("\"", "\"\""))
    } else {
        Borrowed(identifier)
    }
}

// FIXME copy/paste from function.rs
unsafe extern "C" fn free_boxed_value<T>(p: *mut libc::c_void) {
    let _: Box<T> = Box::from_raw(mem::transmute(p));
}

#[macro_export]
macro_rules! init_module {
    ($module_name: ident, $vtab: ident, $cursor: ty,
        $create: ident, $best_index: ident, $destroy: ident,
        $open: ident, $close: ident,
        $filter: ident, $next: ident, $eof: ident,
        $column: ident, $rowid: ident) => {

static $module_name: ffi::sqlite3_module = ffi::sqlite3_module {
    iVersion: 1,
    xCreate: Some($create),
    xConnect: Some($create), /* A virtual table is eponymous if its xCreate method is the exact same function as the xConnect method */
    xBestIndex: Some($best_index),
    xDisconnect: Some($destroy),
    xDestroy: Some($destroy),
    xOpen: Some($open),
    xClose: Some($close),
    xFilter: Some($filter),
    xNext: Some($next),
    xEof: Some($eof),
    xColumn: Some($column),
    xRowid: Some($rowid),
    xUpdate: None, // TODO
    xBegin: None,
    xSync: None,
    xCommit: None,
    xRollback: None,
    xFindFunction: None,
    xRename: None,
    xSavepoint: None,
    xRelease: None,
    xRollbackTo: None,
};

unsafe extern "C" fn $create(db: *mut ffi::sqlite3,
                              aux: *mut libc::c_void,
                              argc: libc::c_int,
                              argv: *const *const libc::c_char,
                              pp_vtab: *mut *mut ffi::sqlite3_vtab,
                              err_msg: *mut *mut libc::c_char)
                              -> libc::c_int {
    use std::error::Error as StdError;
    use std::slice;
    use vtab::mprintf;
    let args = slice::from_raw_parts(argv, argc as usize);
    match $vtab::create(db, aux, args) {
        Ok(vtab) => {
            let boxed_vtab: *mut $vtab = Box::into_raw(Box::new(vtab));
            *pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab;
            ffi::SQLITE_OK
        },
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(s) = s {
                *err_msg = mprintf(&s);
            }
            err.extended_code
        },
        Err(err) => {
            *err_msg = mprintf(err.description());
            ffi::SQLITE_ERROR
        }
    }
}
unsafe extern "C" fn $best_index(vtab: *mut ffi::sqlite3_vtab,
                                  info: *mut ffi::sqlite3_index_info)
                                  -> libc::c_int {
    let vtab = vtab as *mut $vtab;
    (*vtab).best_index(info);
    ffi::SQLITE_OK
}
unsafe extern "C" fn $destroy(vtab: *mut ffi::sqlite3_vtab) -> libc::c_int {
    let vtab = vtab as *mut $vtab;
    let _: Box<$vtab> = Box::from_raw(mem::transmute(vtab));
    ffi::SQLITE_OK
}

unsafe extern "C" fn $open(vtab: *mut ffi::sqlite3_vtab,
                            pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor)
                            -> libc::c_int {
    use std::error::Error as StdError;
    use vtab::set_err_msg;
    let vt = vtab as *mut $vtab;
    match (*vt).open() {
        Ok(cursor) => {
            let boxed_cursor: *mut $cursor = Box::into_raw(Box::new(cursor));
            *pp_cursor = boxed_cursor as *mut ffi::sqlite3_vtab_cursor;
            ffi::SQLITE_OK
        },
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg(vtab, &err_msg);
            }
            err.extended_code
        },
        Err(err) => {
            set_err_msg(vtab, err.description());
            ffi::SQLITE_ERROR
        }
    }
}
unsafe extern "C" fn $close(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
    let cr = cursor as *mut $cursor;
    let _: Box<$cursor> = Box::from_raw(mem::transmute(cr));
    ffi::SQLITE_OK
}

unsafe extern "C" fn $filter(cursor: *mut ffi::sqlite3_vtab_cursor,
                              idx_num: libc::c_int,
                              idx_str: *const libc::c_char,
                              argc: libc::c_int,
                              argv: *mut *mut ffi::sqlite3_value)
                              -> libc::c_int {
    use vtab::cursor_error;
    let cr = cursor as *mut $cursor;
    cursor_error(cursor, (*cr).filter(idx_num, idx_str, argc, argv))
}
unsafe extern "C" fn $next(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
    use vtab::cursor_error;
    let cr = cursor as *mut $cursor;
    cursor_error(cursor, (*cr).next())
}
unsafe extern "C" fn $eof(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
    let cr = cursor as *mut $cursor;
    (*cr).eof() as libc::c_int
}
unsafe extern "C" fn $column(cursor: *mut ffi::sqlite3_vtab_cursor,
                              ctx: *mut ffi::sqlite3_context,
                              i: libc::c_int)
                              -> libc::c_int {
    use vtab::result_error;
    let cr = cursor as *mut $cursor;
    result_error(ctx, (*cr).column(ctx, i))
}
unsafe extern "C" fn $rowid(cursor: *mut ffi::sqlite3_vtab_cursor,
                             p_rowid: *mut ffi::sqlite3_int64)
                             -> libc::c_int {
    use vtab::cursor_error;
    let cr = cursor as *mut $cursor;
    match (*cr).rowid() {
        Ok(rowid) => {
            *p_rowid = rowid;
            ffi::SQLITE_OK
        },
        err => cursor_error(cursor, err)
    }
}
    }
}

/// Virtual table cursors can set an error message by assigning a string to `zErrMsg`.
pub unsafe fn cursor_error<T>(cursor: *mut ffi::sqlite3_vtab_cursor,
                              result: Result<T>)
                              -> libc::c_int {
    use std::error::Error as StdError;
    match result {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg((*cursor).pVtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg((*cursor).pVtab, err.description());
            ffi::SQLITE_ERROR
        }
    }
}

/// Virtual tables methods can set an error message by assigning a string to `zErrMsg`.
pub unsafe fn set_err_msg(vtab: *mut ffi::sqlite3_vtab, err_msg: &str) {
    if !(*vtab).zErrMsg.is_null() {
        ffi::sqlite3_free((*vtab).zErrMsg as *mut libc::c_void);
    }
    (*vtab).zErrMsg = mprintf(err_msg);
}

/// To raise an error, the `column` method should use this method to set the error message and return the error code.
pub unsafe fn result_error<T>(ctx: *mut ffi::sqlite3_context, result: Result<T>) -> libc::c_int {
    use std::error::Error as StdError;
    match result {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            match err.extended_code {
                ffi::SQLITE_TOOBIG => {
                    ffi::sqlite3_result_error_toobig(ctx);
                }
                ffi::SQLITE_NOMEM => {
                    ffi::sqlite3_result_error_nomem(ctx);
                }
                code => {
                    ffi::sqlite3_result_error_code(ctx, code);
                    if let Some(Ok(cstr)) = s.map(|s| str_to_cstring(&s)) {
                        ffi::sqlite3_result_error(ctx, cstr.as_ptr(), -1);
                    }
                }
            };
            err.extended_code
        }
        Err(err) => {
            ffi::sqlite3_result_error_code(ctx, ffi::SQLITE_ERROR);
            if let Ok(cstr) = str_to_cstring(err.description()) {
                ffi::sqlite3_result_error(ctx, cstr.as_ptr(), -1);
            }
            ffi::SQLITE_ERROR
        }
    }
}

// Space to hold this error message string must be obtained from an SQLite memory allocation function.
pub fn mprintf(err_msg: &str) -> *mut ::libc::c_char {
    let c_format = CString::new("%s").unwrap();
    let c_err = CString::new(err_msg).unwrap();
    unsafe { ffi::sqlite3_mprintf(c_format.as_ptr(), c_err.as_ptr()) }
}

pub mod int_array;
#[cfg(feature = "csvtab")]pub mod csvtab;
<commit_msg>Fix warnings<commit_after>//! Create virtual tables.
//! (See http://sqlite.org/vtab.html)
use std::borrow::Cow;
use std::borrow::Cow::{Borrowed, Owned};
use std::ffi::CString;
use std::mem;
use std::ptr;
use libc;

use {Connection, Error, Result, InnerConnection, str_to_cstring};
use error::error_from_sqlite_code;
use ffi;

// let conn: Connection = ...;
// let mod: Module = ...; // VTab builder
// conn.create_module("module", mod);
//
// conn.execute("CREATE VIRTUAL TABLE foo USING module(...)");
// \-> Module::xcreate
//  |-> let vtab: VTab = ...; // on the heap
//  \-> conn.declare_vtab("CREATE TABLE foo (...)");
// conn = Connection::open(...);
// \-> Module::xconnect
//  |-> let vtab: VTab = ...; // on the heap
//  \-> conn.declare_vtab("CREATE TABLE foo (...)");
//
// conn.close();
// \-> vtab.xdisconnect
// conn.execute("DROP TABLE foo");
// \-> vtab.xDestroy
//
// let stmt = conn.prepare("SELECT ... FROM foo WHERE ...");
// \-> vtab.xbestindex
// stmt.query().next();
// \-> vtab.xopen
//  |-> let cursor: Cursor = ...; // on the heap
//  |-> cursor.xfilter or xnext
//  |-> cursor.xeof
//  \-> if not eof { cursor.column or xrowid } else { cursor.xclose }
//

/// Virtual table instance trait.
pub trait VTab<C: VTabCursor<Self>>: Sized {
    /// Create a new instance of a virtual table in response to a CREATE VIRTUAL TABLE statement.
    /// The `db` parameter is a pointer to the SQLite database connection that is executing the CREATE VIRTUAL TABLE statement.
    fn create(db: *mut ffi::sqlite3,
              aux: *mut libc::c_void,
              args: &[*const libc::c_char])
              -> Result<Self>;
    /// Determine the best way to access the virtual table.
    fn best_index(&self, info: *mut ffi::sqlite3_index_info);
    /// Create a new cursor used for accessing a virtual table.
    fn open(&self) -> Result<C>;
}

/// Virtual table cursor trait.
pub trait VTabCursor<V: VTab<Self>>: Sized {
    /// Accessor to the associated virtual table.
    fn vtab(&self) -> &mut V;
    /// Begin a search of a virtual table.
    fn filter(&mut self,
              idx_num: libc::c_int,
              idx_str: *const libc::c_char,
              argc: libc::c_int,
              argv: *mut *mut ffi::sqlite3_value)
              -> Result<()>;
    /// Advance cursor to the next row of a result set initiated by `filter`.
    fn next(&mut self) -> Result<()>;
    /// Must return `false` if the cursor currently points to a valid row of data, or `true` otherwise.
    fn eof(&self) -> bool;
    /// Find the value for the `i`-th column of the current row. `i` is zero-based so the first column is numbered 0.
    /// May return its result back to SQLite using one of the specified `ctx`.
    fn column(&self, ctx: *mut ffi::sqlite3_context, i: libc::c_int) -> Result<()>;
    /// Return the rowid of row that the cursor is currently pointing at.
    fn rowid(&self) -> Result<i64>;
}

impl Connection {
    /// Register a virtual table implementation.
    pub fn create_module<A>(&self,
                            module_name: &str,
                            module: *const ffi::sqlite3_module,
                            aux: Option<A>)
                            -> Result<()> {
        self.db
            .borrow_mut()
            .create_module(module_name, module, aux)
    }
}

impl InnerConnection {
    fn create_module<A>(&mut self,
                        module_name: &str,
                        module: *const ffi::sqlite3_module,
                        aux: Option<A>)
                        -> Result<()> {
        let c_name = try!(str_to_cstring(module_name));
        let r = match aux {
            Some(aux) => {
                let boxed_aux: *mut A = Box::into_raw(Box::new(aux));
                unsafe {
                    ffi::sqlite3_create_module_v2(self.db(),
                                                  c_name.as_ptr(),
                                                  module,
                                                  mem::transmute(boxed_aux),
                                                  Some(free_boxed_value::<A>))
                }
            }
            None => unsafe {
                ffi::sqlite3_create_module_v2(self.db(),
                                              c_name.as_ptr(),
                                              module,
                                              ptr::null_mut(),
                                              None)
            },
        };
        self.decode_result(r)
    }
}

/// Declare the schema of a virtual table.
pub fn declare_vtab(db: *mut ffi::sqlite3, sql: &str) -> Result<()> {
    let c_sql = try!(CString::new(sql));
    let rc = unsafe { ffi::sqlite3_declare_vtab(db, c_sql.as_ptr()) };
    if rc == ffi::SQLITE_OK {
        Ok(())
    } else {
        Err(error_from_sqlite_code(rc, None))
    }
}

/// Escape double-quote (`"`) character occurences by doubling them (`""`).
pub fn escape_double_quote<'a>(identifier: &'a str) -> Cow<'a, str> {
    if identifier.contains('"') {
        // escape quote by doubling them
        Owned(identifier.replace("\"", "\"\""))
    } else {
        Borrowed(identifier)
    }
}

// FIXME copy/paste from function.rs
unsafe extern "C" fn free_boxed_value<T>(p: *mut libc::c_void) {
    let _: Box<T> = Box::from_raw(mem::transmute(p));
}

#[macro_export]
macro_rules! init_module {
    ($module_name: ident, $vtab: ident, $cursor: ty,
        $create: ident, $best_index: ident, $destroy: ident,
        $open: ident, $close: ident,
        $filter: ident, $next: ident, $eof: ident,
        $column: ident, $rowid: ident) => {

static $module_name: ffi::sqlite3_module = ffi::sqlite3_module {
    iVersion: 1,
    xCreate: Some($create),
    xConnect: Some($create), /* A virtual table is eponymous if its xCreate method is the exact same function as the xConnect method */
    xBestIndex: Some($best_index),
    xDisconnect: Some($destroy),
    xDestroy: Some($destroy),
    xOpen: Some($open),
    xClose: Some($close),
    xFilter: Some($filter),
    xNext: Some($next),
    xEof: Some($eof),
    xColumn: Some($column),
    xRowid: Some($rowid),
    xUpdate: None, // TODO
    xBegin: None,
    xSync: None,
    xCommit: None,
    xRollback: None,
    xFindFunction: None,
    xRename: None,
    xSavepoint: None,
    xRelease: None,
    xRollbackTo: None,
};

unsafe extern "C" fn $create(db: *mut ffi::sqlite3,
                              aux: *mut libc::c_void,
                              argc: libc::c_int,
                              argv: *const *const libc::c_char,
                              pp_vtab: *mut *mut ffi::sqlite3_vtab,
                              err_msg: *mut *mut libc::c_char)
                              -> libc::c_int {
    use std::error::Error as StdError;
    use std::slice;
    use vtab::mprintf;
    let args = slice::from_raw_parts(argv, argc as usize);
    match $vtab::create(db, aux, args) {
        Ok(vtab) => {
            let boxed_vtab: *mut $vtab = Box::into_raw(Box::new(vtab));
            *pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab;
            ffi::SQLITE_OK
        },
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(s) = s {
                *err_msg = mprintf(&s);
            }
            err.extended_code
        },
        Err(err) => {
            *err_msg = mprintf(err.description());
            ffi::SQLITE_ERROR
        }
    }
}
unsafe extern "C" fn $best_index(vtab: *mut ffi::sqlite3_vtab,
                                  info: *mut ffi::sqlite3_index_info)
                                  -> libc::c_int {
    let vtab = vtab as *mut $vtab;
    (*vtab).best_index(info);
    ffi::SQLITE_OK
}
unsafe extern "C" fn $destroy(vtab: *mut ffi::sqlite3_vtab) -> libc::c_int {
    let vtab = vtab as *mut $vtab;
    let _: Box<$vtab> = Box::from_raw(mem::transmute(vtab));
    ffi::SQLITE_OK
}

unsafe extern "C" fn $open(vtab: *mut ffi::sqlite3_vtab,
                            pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor)
                            -> libc::c_int {
    use std::error::Error as StdError;
    use vtab::set_err_msg;
    let vt = vtab as *mut $vtab;
    match (*vt).open() {
        Ok(cursor) => {
            let boxed_cursor: *mut $cursor = Box::into_raw(Box::new(cursor));
            *pp_cursor = boxed_cursor as *mut ffi::sqlite3_vtab_cursor;
            ffi::SQLITE_OK
        },
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg(vtab, &err_msg);
            }
            err.extended_code
        },
        Err(err) => {
            set_err_msg(vtab, err.description());
            ffi::SQLITE_ERROR
        }
    }
}
unsafe extern "C" fn $close(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
    let cr = cursor as *mut $cursor;
    let _: Box<$cursor> = Box::from_raw(mem::transmute(cr));
    ffi::SQLITE_OK
}

unsafe extern "C" fn $filter(cursor: *mut ffi::sqlite3_vtab_cursor,
                              idx_num: libc::c_int,
                              idx_str: *const libc::c_char,
                              argc: libc::c_int,
                              argv: *mut *mut ffi::sqlite3_value)
                              -> libc::c_int {
    use vtab::cursor_error;
    let cr = cursor as *mut $cursor;
    cursor_error(cursor, (*cr).filter(idx_num, idx_str, argc, argv))
}
unsafe extern "C" fn $next(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
    use vtab::cursor_error;
    let cr = cursor as *mut $cursor;
    cursor_error(cursor, (*cr).next())
}
unsafe extern "C" fn $eof(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
    let cr = cursor as *mut $cursor;
    (*cr).eof() as libc::c_int
}
unsafe extern "C" fn $column(cursor: *mut ffi::sqlite3_vtab_cursor,
                              ctx: *mut ffi::sqlite3_context,
                              i: libc::c_int)
                              -> libc::c_int {
    use vtab::result_error;
    let cr = cursor as *mut $cursor;
    result_error(ctx, (*cr).column(ctx, i))
}
unsafe extern "C" fn $rowid(cursor: *mut ffi::sqlite3_vtab_cursor,
                             p_rowid: *mut ffi::sqlite3_int64)
                             -> libc::c_int {
    use vtab::cursor_error;
    let cr = cursor as *mut $cursor;
    match (*cr).rowid() {
        Ok(rowid) => {
            *p_rowid = rowid;
            ffi::SQLITE_OK
        },
        err => cursor_error(cursor, err)
    }
}
    }
}

/// Virtual table cursors can set an error message by assigning a string to `zErrMsg`.
pub unsafe fn cursor_error<T>(cursor: *mut ffi::sqlite3_vtab_cursor,
                              result: Result<T>)
                              -> libc::c_int {
    use std::error::Error as StdError;
    match result {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg((*cursor).pVtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg((*cursor).pVtab, err.description());
            ffi::SQLITE_ERROR
        }
    }
}

/// Virtual tables methods can set an error message by assigning a string to `zErrMsg`.
pub unsafe fn set_err_msg(vtab: *mut ffi::sqlite3_vtab, err_msg: &str) {
    if !(*vtab).zErrMsg.is_null() {
        ffi::sqlite3_free((*vtab).zErrMsg as *mut libc::c_void);
    }
    (*vtab).zErrMsg = mprintf(err_msg);
}

/// To raise an error, the `column` method should use this method to set the error message and return the error code.
pub unsafe fn result_error<T>(ctx: *mut ffi::sqlite3_context, result: Result<T>) -> libc::c_int {
    use std::error::Error as StdError;
    match result {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            match err.extended_code {
                ffi::SQLITE_TOOBIG => {
                    ffi::sqlite3_result_error_toobig(ctx);
                }
                ffi::SQLITE_NOMEM => {
                    ffi::sqlite3_result_error_nomem(ctx);
                }
                code => {
                    ffi::sqlite3_result_error_code(ctx, code);
                    if let Some(Ok(cstr)) = s.map(|s| str_to_cstring(&s)) {
                        ffi::sqlite3_result_error(ctx, cstr.as_ptr(), -1);
                    }
                }
            };
            err.extended_code
        }
        Err(err) => {
            ffi::sqlite3_result_error_code(ctx, ffi::SQLITE_ERROR);
            if let Ok(cstr) = str_to_cstring(err.description()) {
                ffi::sqlite3_result_error(ctx, cstr.as_ptr(), -1);
            }
            ffi::SQLITE_ERROR
        }
    }
}

// Space to hold this error message string must be obtained from an SQLite memory allocation function.
pub fn mprintf(err_msg: &str) -> *mut ::libc::c_char {
    let c_format = CString::new("%s").unwrap();
    let c_err = CString::new(err_msg).unwrap();
    unsafe { ffi::sqlite3_mprintf(c_format.as_ptr(), c_err.as_ptr()) }
}

pub mod int_array;
#[cfg(feature = "csvtab")]pub mod csvtab;
<|endoftext|>


<commit_before>extern crate clap;
extern crate dent;
extern crate term;
extern crate term_size;

use clap::{App, Arg};
use dent::plot;
use dent::summary::Summary;
use dent::t_test::{SigLevel, TTest, welch_t_test};

use std::error;
use std::fs::File;
use std::path::Path;
use std::io::{self, BufRead, BufReader};

mod fmt;
mod log;

macro_rules! ok {
    ($r: expr) => {
        match $r {
            Ok(t) => t,
            Err(e) => {
                log::error(&format!("{}", e));
                std::process::exit(1);
            }
        }
    }
}

fn print_summary(s: &Summary) {
    let width = 10;
    let size_width = 6;

    println!(
        "{n:>nw$}  {min:>w$}  {max:>w$}  {med:>w$}  {mean:>w$}  {sd:>w$}  {se:>w$}",
        w = width,
        nw = size_width,
        n = "N",
        min = "Min",
        max = "Max",
        med = "Median",
        mean = "Mean",
        sd= "StdDev",
        se = "StdErr",
    );
    println!(
        "{n:>nw$}  {min:>w$}  {max:>w$}  {med:>w$}  {mean:>w$}  {sd:>w$}  {se:>w$}",
        w = width,
        nw = size_width,
        n = fmt::f(s.size(), width),
        min = fmt::f(s.min(), width),
        max = fmt::f(s.max(), width),
        med = fmt::f(s.median(), width),
        mean = fmt::f(s.mean(), width),
        sd = fmt::f(s.standard_deviation(), width),
        se = fmt::f(s.standard_error(), width),
    );
}

fn print_t_test(t_test: &TTest) {
    let width = 12;
    let reject = if t_test.reject { "yes" } else { "no" };

    println!("{l:>w$} = {v}", w = width, l = "Reject H₀?", v = reject);
    println!("{l:>w$} = {v}", w = width, l = "α", v = t_test.alpha);
    println!("{l:>w$} = {v}", w = width, l = "t", v = t_test.t);
    println!("{l:>w$} = {v}", w = width, l = "Crit. v", v = t_test.crit);
    println!("{l:>w$} = {v}", w = width, l = "DF", v = t_test.df);
}

fn summarize_file(path: &str, lax_parsing: bool) -> Result<Summary, Box<error::Error>> {
    let p = Path::new(path);
    let f = File::open(p).or_else(|e| {
        log::error(&format!("Could not open file: {:?}", p));
        Err(e)
    })?;
    let reader = BufReader::new(f);

    let data = read_data(reader, lax_parsing)?;

    Ok(Summary::new(&data)?)
}

fn read_data<R>(reader: R, lax_parsing: bool) -> Result<Vec<f64>, Box<error::Error>>
    where R: BufRead {
    let mut data: Vec<f64> = vec![];

    for l in reader.lines() {
        let s = l?.trim().to_string();

        if s.is_empty() {
            continue;
        }

        match s.parse() {
            Ok(d) => data.push(d),
            err => if !lax_parsing { err?; }
        }
    }

    Ok(data)
}

fn parse_alpha(arg: &str) -> Result<SigLevel, String> {
    Ok(match arg {
        ".001" => SigLevel::Alpha001,
        ".005" => SigLevel::Alpha005,
        ".01"  => SigLevel::Alpha010,
        ".025" => SigLevel::Alpha025,
        ".05"  => SigLevel::Alpha050,
        ".1"   => SigLevel::Alpha100,
        _ => return Err(format!("Invalid value for α: {:?}", arg))
    })
}

fn summarize_stdin(lax_parsing: bool) -> Result<Summary, Box<error::Error>> {
    let stdin = io::stdin();
    let data = read_data(stdin.lock(), lax_parsing)?;

    Ok(Summary::new(&data)?)
}

fn display_t_test(
    summary1: &Summary,
    summary2: &Summary,
    alpha: SigLevel,
    draw_plot: bool,
    width: usize,
    ascii: bool,
) {
    let t_test = welch_t_test(&summary1, &summary2, alpha);

    if draw_plot {
        let p = plot::comparison_plot(&[summary1, summary2], width, ascii, true);
        println!("{}\n", p);
    }

    print_summary(&summary1);
    println!();
    print_summary(&summary2);
    println!();
    print_t_test(&t_test);
}

fn display_summaries(
    summaries: &[Summary],
    draw_plot: bool,
    width: usize,
    ascii: bool,
) {
    if draw_plot {
        let summary_refs: Vec<&Summary> = summaries
            .iter()
            .collect();

        let plot = plot::comparison_plot(&summary_refs, width, ascii, true);
        println!("{}\n", plot);
    }

    for i in 0..summaries.len() {
        if i > 0 {
            println!();
        }
        print_summary(&summaries[i]);
    }
}

fn main() {
    let matches = App::new("dent")
        .version("0.3.0")
        .author("Joe Ranweiler <joe@lemma.co>")
        .about("A tiny tool for t-tests &c.")
        .arg(Arg::with_name("stdin")
             .short("s")
             .long("stdin")
             .help("Read and summarize data from stdin"))
        .arg(Arg::with_name("files")
             .multiple(true)
             .value_name("FILES")
             .takes_value(true)
             .required_unless("stdin")
             .help("Path to one or more files of sample data"))
        .arg(Arg::with_name("alpha")
             .short("a")
             .long("alpha")
             .value_name("ALPHA")
             .help("Significance level α")
             .takes_value(true)
             .default_value(".05"))
        .arg(Arg::with_name("lax")
             .long("lax")
             .help("Ignore non-numeric input lines"))
        .arg(Arg::with_name("plot")
             .short("p")
             .long("plot")
             .help("Print standard boxplots"))
        .arg(Arg::with_name("ascii")
             .long("ascii")
             .help("Use only ASCII characters in boxplots"))
        .arg(Arg::with_name("width")
             .short("w")
             .long("width")
             .value_name("WIDTH")
             .takes_value(true)
             .help("Width of boxplot"))
        .get_matches();

    let ascii = matches.is_present("ascii");
    let lax_parsing = matches.is_present("lax");
    let draw_plot = matches.is_present("plot");
    let use_stdin = matches.is_present("stdin");

    let width = matches
        .value_of("width")
        .and_then(|w| w.parse::<usize>().ok())
        .or(term_size::dimensions().map(|(w, _)| w))
        .unwrap_or(80);

    let summaries = if use_stdin {
        vec![ok!(summarize_stdin(lax_parsing))]
    } else {
        // Required if `stdin` is not present, so we can unwrap.
        matches.values_of("files")
            .unwrap_or_else(|| unreachable!())
            .map(|f| ok!(summarize_file(f, lax_parsing)))
            .collect()
    };

    match summaries.len() {
        0 => unreachable!(),
        // We want match 1 with the case `len()` > 2.
        2 => {
            // Has a default value, so we can can unwrap.
            let alpha_arg = matches.value_of("alpha").unwrap_or_else(|| unreachable!());
            let alpha = ok!(parse_alpha(alpha_arg));

            display_t_test(
                &summaries[0],
                &summaries[1],
                alpha,
                draw_plot,
                width,
                ascii,
            );
        }
        _ => {
            display_summaries(&summaries, draw_plot, width, ascii);
        },
    };
}
<commit_msg>Rely on `AsRef` conversion when opening file<commit_after>extern crate clap;
extern crate dent;
extern crate term;
extern crate term_size;

use clap::{App, Arg};
use dent::plot;
use dent::summary::Summary;
use dent::t_test::{SigLevel, TTest, welch_t_test};

use std::error;
use std::fs::File;
use std::io::{self, BufRead, BufReader};

mod fmt;
mod log;

macro_rules! ok {
    ($r: expr) => {
        match $r {
            Ok(t) => t,
            Err(e) => {
                log::error(&format!("{}", e));
                std::process::exit(1);
            }
        }
    }
}

fn print_summary(s: &Summary) {
    let width = 10;
    let size_width = 6;

    println!(
        "{n:>nw$}  {min:>w$}  {max:>w$}  {med:>w$}  {mean:>w$}  {sd:>w$}  {se:>w$}",
        w = width,
        nw = size_width,
        n = "N",
        min = "Min",
        max = "Max",
        med = "Median",
        mean = "Mean",
        sd= "StdDev",
        se = "StdErr",
    );
    println!(
        "{n:>nw$}  {min:>w$}  {max:>w$}  {med:>w$}  {mean:>w$}  {sd:>w$}  {se:>w$}",
        w = width,
        nw = size_width,
        n = fmt::f(s.size(), width),
        min = fmt::f(s.min(), width),
        max = fmt::f(s.max(), width),
        med = fmt::f(s.median(), width),
        mean = fmt::f(s.mean(), width),
        sd = fmt::f(s.standard_deviation(), width),
        se = fmt::f(s.standard_error(), width),
    );
}

fn print_t_test(t_test: &TTest) {
    let width = 12;
    let reject = if t_test.reject { "yes" } else { "no" };

    println!("{l:>w$} = {v}", w = width, l = "Reject H₀?", v = reject);
    println!("{l:>w$} = {v}", w = width, l = "α", v = t_test.alpha);
    println!("{l:>w$} = {v}", w = width, l = "t", v = t_test.t);
    println!("{l:>w$} = {v}", w = width, l = "Crit. v", v = t_test.crit);
    println!("{l:>w$} = {v}", w = width, l = "DF", v = t_test.df);
}

fn summarize_file(path: &str, lax_parsing: bool) -> Result<Summary, Box<error::Error>> {
    let f = File::open(path).or_else(|e| {
        log::error(&format!("Could not open file: {:?}", path));
        Err(e)
    })?;
    let reader = BufReader::new(f);

    let data = read_data(reader, lax_parsing)?;

    Ok(Summary::new(&data)?)
}

fn read_data<R>(reader: R, lax_parsing: bool) -> Result<Vec<f64>, Box<error::Error>>
    where R: BufRead {
    let mut data: Vec<f64> = vec![];

    for l in reader.lines() {
        let s = l?.trim().to_string();

        if s.is_empty() {
            continue;
        }

        match s.parse() {
            Ok(d) => data.push(d),
            err => if !lax_parsing { err?; }
        }
    }

    Ok(data)
}

fn parse_alpha(arg: &str) -> Result<SigLevel, String> {
    Ok(match arg {
        ".001" => SigLevel::Alpha001,
        ".005" => SigLevel::Alpha005,
        ".01"  => SigLevel::Alpha010,
        ".025" => SigLevel::Alpha025,
        ".05"  => SigLevel::Alpha050,
        ".1"   => SigLevel::Alpha100,
        _ => return Err(format!("Invalid value for α: {:?}", arg))
    })
}

fn summarize_stdin(lax_parsing: bool) -> Result<Summary, Box<error::Error>> {
    let stdin = io::stdin();
    let data = read_data(stdin.lock(), lax_parsing)?;

    Ok(Summary::new(&data)?)
}

fn display_t_test(
    summary1: &Summary,
    summary2: &Summary,
    alpha: SigLevel,
    draw_plot: bool,
    width: usize,
    ascii: bool,
) {
    let t_test = welch_t_test(&summary1, &summary2, alpha);

    if draw_plot {
        let p = plot::comparison_plot(&[summary1, summary2], width, ascii, true);
        println!("{}\n", p);
    }

    print_summary(&summary1);
    println!();
    print_summary(&summary2);
    println!();
    print_t_test(&t_test);
}

fn display_summaries(
    summaries: &[Summary],
    draw_plot: bool,
    width: usize,
    ascii: bool,
) {
    if draw_plot {
        let summary_refs: Vec<&Summary> = summaries
            .iter()
            .collect();

        let plot = plot::comparison_plot(&summary_refs, width, ascii, true);
        println!("{}\n", plot);
    }

    for i in 0..summaries.len() {
        if i > 0 {
            println!();
        }
        print_summary(&summaries[i]);
    }
}

fn main() {
    let matches = App::new("dent")
        .version("0.3.0")
        .author("Joe Ranweiler <joe@lemma.co>")
        .about("A tiny tool for t-tests &c.")
        .arg(Arg::with_name("stdin")
             .short("s")
             .long("stdin")
             .help("Read and summarize data from stdin"))
        .arg(Arg::with_name("files")
             .multiple(true)
             .value_name("FILES")
             .takes_value(true)
             .required_unless("stdin")
             .help("Path to one or more files of sample data"))
        .arg(Arg::with_name("alpha")
             .short("a")
             .long("alpha")
             .value_name("ALPHA")
             .help("Significance level α")
             .takes_value(true)
             .default_value(".05"))
        .arg(Arg::with_name("lax")
             .long("lax")
             .help("Ignore non-numeric input lines"))
        .arg(Arg::with_name("plot")
             .short("p")
             .long("plot")
             .help("Print standard boxplots"))
        .arg(Arg::with_name("ascii")
             .long("ascii")
             .help("Use only ASCII characters in boxplots"))
        .arg(Arg::with_name("width")
             .short("w")
             .long("width")
             .value_name("WIDTH")
             .takes_value(true)
             .help("Width of boxplot"))
        .get_matches();

    let ascii = matches.is_present("ascii");
    let lax_parsing = matches.is_present("lax");
    let draw_plot = matches.is_present("plot");
    let use_stdin = matches.is_present("stdin");

    let width = matches
        .value_of("width")
        .and_then(|w| w.parse::<usize>().ok())
        .or(term_size::dimensions().map(|(w, _)| w))
        .unwrap_or(80);

    let summaries = if use_stdin {
        vec![ok!(summarize_stdin(lax_parsing))]
    } else {
        // Required if `stdin` is not present, so we can unwrap.
        matches.values_of("files")
            .unwrap_or_else(|| unreachable!())
            .map(|f| ok!(summarize_file(f, lax_parsing)))
            .collect()
    };

    match summaries.len() {
        0 => unreachable!(),
        // We want match 1 with the case `len()` > 2.
        2 => {
            // Has a default value, so we can can unwrap.
            let alpha_arg = matches.value_of("alpha").unwrap_or_else(|| unreachable!());
            let alpha = ok!(parse_alpha(alpha_arg));

            display_t_test(
                &summaries[0],
                &summaries[1],
                alpha,
                draw_plot,
                width,
                ascii,
            );
        }
        _ => {
            display_summaries(&summaries, draw_plot, width, ascii);
        },
    };
}
<|endoftext|>


<commit_before>//	MIT License
//
//  Copyright © 2017 Michael J Simms. All rights reserved.
//
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in all
//	copies or substantial portions of the Software.
//
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//	SOFTWARE.

/// Each feature has a name and value.
pub struct Feature {
    name: String,
    value: u64,
}

impl Feature {
    pub fn new (name: &str, value: u64) -> Feature {
        Feature { name: name.to_string(), value: value }
    }

    pub fn set_name(&mut self, name: String) {
        self.name = name;
    }

    pub fn get_name(&self) -> String {
        self.name
    }

    pub fn set_value(&mut self, value: u64) {
        self.value = value;
    }

    pub fn get_value(&self) -> u64 {
        self.value
    }
}

pub type FeatureList = Vec<Feature>;

/// This class represents a sample.
/// Each sample has a name and list of features.
pub struct Sample {
    name: String,
    features: FeatureList,
}

impl Sample {
    pub fn new (name: &str) -> Sample {
        Sample { name: name.to_string(), features: Sample::create_feature_list() }
    }

    fn create_feature_list() -> FeatureList {
        let mut v: FeatureList = vec![];
        v
    }

    pub fn add_features(&mut self, features: &mut FeatureList) {
        self.features.append(features);
    }

    pub fn add_feature(&mut self, feature: Feature) {
        self.features.push(feature);
    }

    pub fn features(&self) -> FeatureList {
        self.features
    }
}

pub type SampleList = Vec<Sample>;

/// Tree node, used internally.
struct Node {
    feature_name: String,
    left: Option<Box<Node>>,
    right: Option<Box<Node>>,
}

impl Node {
    pub fn new (feature_name: &str) -> Node {
        Node { feature_name: feature_name.to_string(), left: None, right: None }
    }

    fn get_feature_name(&self) -> String {
        self.feature_name
    }

	fn set_left_subtree(&mut self, subtree: NodeLink) {
		self.left = subtree;
	}

	fn set_right_subtree(&mut self, subtree: NodeLink) {
		self.right = subtree;
	}
}

pub type NodeLink = Option<Box<Node>>;
pub type NodeList = Vec<Node>;

/// Isolation Forest implementation.
pub struct Forest {
    //featureValues: FeatureNameToValueMap, // Lists each feature and maps it to all unique values in the training set
    trees: NodeList, // The decision trees that comprise the forest
    numTreesToCreate: u32, // The maximum number of trees to create
    subSamplingSize: u32, // The maximum depth of a tree
}

impl Forest {
    pub fn new (numTreesToCreate: u32, subSamplingSize: u32) -> Forest {
        Forest { numTreesToCreate: numTreesToCreate, subSamplingSize: subSamplingSize, trees: Forest::create_trees() }
    }

    fn create_trees() -> NodeList {
        let mut v: NodeList = vec![];
        v
    }

    pub fn add_sample(&self, sample: Sample) {
		// Add each of this sample's features to the list of known features
		// with the corresponding set of unique values.
		let mut features = sample.features();
        for feature in &features {
            let mut found_feature = false;
        }
    }

    pub fn create(&self) {
    }

    fn score_tree(&self, sample: Sample, tree: Node) -> f64 {
        let mut depth = 0.0;
        let mut current_node = tree;
        while !current_node.is_none() {
            let mut found_feature = false;
            let feature_name = current_node.get_feature_name();
            let features = sample.features();
            for feature in features {

            }
        }
        depth
    }

    pub fn score(&self, sample: Sample) -> f64 {
        let mut score = 0.0;

        if self.trees.len() > 0 {
            for tree in self.trees {
                score += self.score_tree(sample, tree);
            }
            score /= self.trees.len() as f64;
        }
        score
    }
}
<commit_msg>Backup commit.<commit_after>//	MIT License
//
//  Copyright © 2017 Michael J Simms. All rights reserved.
//
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in all
//	copies or substantial portions of the Software.
//
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//	SOFTWARE.

use std::collections::HashSet;
use std::collections::HashMap;

/// Each feature has a name and value.
pub struct Feature {
    name: String,
    value: u64,
}

impl Feature {
    pub fn new (name: &str, value: u64) -> Feature {
        Feature { name: name.to_string(), value: value }
    }

    pub fn set_name(&mut self, name: String) {
        self.name = name;
    }

    pub fn get_name(&self) -> String {
        self.name
    }

    pub fn set_value(&mut self, value: u64) {
        self.value = value;
    }

    pub fn get_value(&self) -> u64 {
        self.value
    }
}

pub type FeatureList = Vec<Feature>;
pub type Uint64Set = HashSet<u64>;
pub type FeatureNameToValuesMap<'a> = HashMap<&'a str, Uint64Set>;

/// This class represents a sample.
/// Each sample has a name and list of features.
pub struct Sample {
    name: String,
    features: FeatureList,
}

impl Sample {
    pub fn new (name: &str) -> Sample {
        Sample { name: name.to_string(), features: Sample::create_feature_list() }
    }

    fn create_feature_list() -> FeatureList {
        let mut v: FeatureList = vec![];
        v
    }

    pub fn add_features(&mut self, features: &mut FeatureList) {
        self.features.append(features);
    }

    pub fn add_feature(&mut self, feature: Feature) {
        self.features.push(feature);
    }

    pub fn features(&self) -> FeatureList {
        self.features
    }
}

pub type SampleList = Vec<Sample>;

/// Tree node, used internally.
struct Node {
    feature_name: String,
    left: Option<Box<Node>>,
    right: Option<Box<Node>>,
}

impl Node {
    pub fn new (feature_name: &str) -> Node {
        Node { feature_name: feature_name.to_string(), left: None, right: None }
    }

    fn get_feature_name(&self) -> String {
        self.feature_name
    }

	fn set_left_subtree(&mut self, subtree: NodeLink) {
		self.left = subtree;
	}

	fn set_right_subtree(&mut self, subtree: NodeLink) {
		self.right = subtree;
	}
}

type NodeLink = Option<Box<Node>>;
pub type NodeList = Vec<Node>;

/// Isolation Forest implementation.
pub struct Forest<'a> {
    featureValues: FeatureNameToValuesMap<'a>, // Lists each feature and maps it to all unique values in the training set
    trees: NodeList, // The decision trees that comprise the forest
    numTreesToCreate: u32, // The maximum number of trees to create
    subSamplingSize: u32, // The maximum depth of a tree
}

impl<'a> Forest<'a> {
    pub fn new (numTreesToCreate: u32, subSamplingSize: u32) -> Forest<'a> {
        Forest { numTreesToCreate: numTreesToCreate, subSamplingSize: subSamplingSize, trees: Forest::create_trees(), featureValues: Forest::create_feature_name_to_values_map() }
    }

    fn create_trees() -> NodeList {
        let mut v: NodeList = vec![];
        v
    }

    fn create_feature_name_to_values_map() -> FeatureNameToValuesMap<'a> {
        let mut m = HashMap::new();
        m
    }

    pub fn add_sample(&self, sample: Sample) {
		// Add each of this sample's features to the list of known features
		// with the corresponding set of unique values.
		let mut features = sample.features();
        for feature in &features {
            let mut found_feature = false;
        }
    }

    pub fn create(&self) {
    	for i in 0..self.numTreesToCreate {
            let tree = Forest::create_trees();
        }
    }

    fn score_tree(&self, sample: Sample, tree: Node) -> f64 {
        let mut depth = 0.0;
        let mut current_node = tree;
        let mut done = false;
        while !done {
            let mut found_feature = false;
            let feature_name = current_node.get_feature_name();
            let features = sample.features();
            for feature in features {

            }
        }
        depth
    }

    pub fn score(&self, sample: Sample) -> f64 {
        let mut score = 0.0;

        if self.trees.len() > 0 {
            for tree in self.trees {
                score += self.score_tree(sample, tree);
            }
            score /= self.trees.len() as f64;
        }
        score
    }
}
<|endoftext|>


<commit_before>extern crate lalrpop_util;

/// Utility macro to create an Err result with a WeldError.
#[macro_export]
macro_rules! weld_err {
    ( $($arg:tt)* ) => ({
        ::std::result::Result::Err($crate::error::WeldError(format!($($arg)*)))
    })
}

// TODO: Not all of these should be public
pub mod ast;
pub mod eval;
pub mod error;
pub mod parser;
pub mod grammar;
pub mod type_inference;
pub mod pretty_print;

#[cfg(test)]
mod tests;
<commit_msg>No need to export weld_err<commit_after>extern crate lalrpop_util;

/// Utility macro to create an Err result with a WeldError.
macro_rules! weld_err {
    ( $($arg:tt)* ) => ({
        ::std::result::Result::Err($crate::error::WeldError(format!($($arg)*)))
    })
}

// TODO: Not all of these should be public
pub mod ast;
pub mod eval;
pub mod error;
pub mod parser;
pub mod grammar;
pub mod type_inference;
pub mod pretty_print;

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before>//! Tools for wrapping devices.

use types::{AudioDevice, Sample, Time};

/// Bundles an AudioDevice with allocated input and output buffers.
///
/// To use the device, input samples must first be manually dropped into the
/// `inputs` buffer, then `tick` may be called to generate outputs. The output
/// samples can be found in the `outputs` buffer.
pub struct Buffered<D> where D: AudioDevice {
    /// The AudioDevice being wrapped
    pub device: D,
    /// The input buffer
    pub inputs: Vec<Sample>,
    /// The output buffer
    pub outputs: Vec<Sample>,
}

impl<D> Buffered<D> where D: AudioDevice {
    /// Calls the device's tick method using the wrapper's buffers.
    pub fn tick(&mut self, t: Time) {
        self.device.tick(t, &self.inputs, &mut self.outputs);
    }
}

impl<D> From<D> for Buffered<D> where D: AudioDevice {
    fn from(device: D) -> Self {
        let inputs = device.num_inputs();
        let outputs = device.num_outputs();
        Buffered {
            device: device,
            inputs: vec![0.0; inputs],
            outputs: vec![0.0; outputs],
        }
    }
}
<commit_msg>Implement deref for Buffered wrapper<commit_after>//! Tools for wrapping devices.

use std::ops::{Deref, DerefMut};

use types::{AudioDevice, Sample, Time};

/// Bundles an AudioDevice with allocated input and output buffers.
///
/// To use the device, input samples must first be manually dropped into the
/// `inputs` buffer, then `tick` may be called to generate outputs. The output
/// samples can be found in the `outputs` buffer.
pub struct Buffered<D> where D: AudioDevice {
    /// The AudioDevice being wrapped
    pub device: D,
    /// The input buffer
    pub inputs: Vec<Sample>,
    /// The output buffer
    pub outputs: Vec<Sample>,
}

impl<D> Buffered<D> where D: AudioDevice {
    /// Calls the device's tick method using the wrapper's buffers.
    pub fn tick(&mut self, t: Time) {
        self.device.tick(t, &self.inputs, &mut self.outputs);
    }
}

impl<D> From<D> for Buffered<D> where D: AudioDevice {
    fn from(device: D) -> Self {
        let inputs = device.num_inputs();
        let outputs = device.num_outputs();
        Buffered {
            device: device,
            inputs: vec![0.0; inputs],
            outputs: vec![0.0; outputs],
        }
    }
}

impl<D> Deref for Buffered<D> where D: AudioDevice {
    type Target = D;
    fn deref(&self) -> &D {
        &self.device
    }
}
impl<D> DerefMut for Buffered<D> where D: AudioDevice {
    fn deref_mut(&mut self) -> &mut D {
        &mut self.device
    }
}
<|endoftext|>