<commit_before>//! Code for the 'normalization' query. This consists of a wrapper
//! which folds deeply, invoking the underlying
//! `normalize_projection_ty` query when it encounters projections.

use crate::infer::at::At;
use crate::infer::canonical::OriginalQueryValues;
use crate::infer::{InferCtxt, InferOk};
use crate::traits::error_reporting::InferCtxtExt;
use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use rustc_infer::traits::Normalized;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, Ty, TyCtxt};

use super::NoSolution;

pub use rustc_middle::traits::query::NormalizationResult;

pub trait AtExt<'tcx> {
    fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
    where
        T: TypeFoldable<'tcx>;
}

impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
    /// Normalize `value` in the context of the inference context,
    /// yielding a resulting type, or an error if `value` cannot be
    /// normalized. If you don't care about regions, you should prefer
    /// `normalize_erasing_regions`, which is more efficient.
    ///
    /// If the normalization succeeds and is unambiguous, returns back
    /// the normalized value along with various outlives relations (in
    /// the form of obligations that must be discharged).
    ///
    /// N.B., this will *eventually* be the main means of
    /// normalizing, but for now should be used only when we actually
    /// know that normalization will succeed, since error reporting
    /// and other details are still "under development".
    fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
    where
        T: TypeFoldable<'tcx>,
    {
        debug!(
            "normalize::<{}>(value={:?}, param_env={:?})",
            ::std::any::type_name::<T>(),
            value,
            self.param_env,
        );
        if !value.has_projections() {
            return Ok(Normalized { value: value.clone(), obligations: vec![] });
        }

        let mut normalizer = QueryNormalizer {
            infcx: self.infcx,
            cause: self.cause,
            param_env: self.param_env,
            obligations: vec![],
            error: false,
            anon_depth: 0,
        };

        let value1 = value.fold_with(&mut normalizer);
        if normalizer.error {
            Err(NoSolution)
        } else {
            Ok(Normalized { value: value1, obligations: normalizer.obligations })
        }
    }
}

struct QueryNormalizer<'cx, 'tcx> {
    infcx: &'cx InferCtxt<'cx, 'tcx>,
    cause: &'cx ObligationCause<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    obligations: Vec<PredicateObligation<'tcx>>,
    error: bool,
    anon_depth: usize,
}

impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
    fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
        self.infcx.tcx
    }

    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
        if !ty.has_projections() {
            return ty;
        }

        let ty = ty.super_fold_with(self);
        match ty.kind {
            ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
                // (*)
                // Only normalize `impl Trait` after type-checking, usually in codegen.
                match self.param_env.reveal {
                    Reveal::UserFacing => ty,

                    Reveal::All => {
                        let recursion_limit = *self.tcx().sess.recursion_limit.get();
                        if self.anon_depth >= recursion_limit {
                            let obligation = Obligation::with_depth(
                                self.cause.clone(),
                                recursion_limit,
                                self.param_env,
                                ty,
                            );
                            self.infcx.report_overflow_error(&obligation, true);
                        }

                        let generic_ty = self.tcx().type_of(def_id);
                        let concrete_ty = generic_ty.subst(self.tcx(), substs);
                        self.anon_depth += 1;
                        if concrete_ty == ty {
                            bug!(
                                "infinite recursion generic_ty: {:#?}, substs: {:#?}, \
                                 concrete_ty: {:#?}, ty: {:#?}",
                                generic_ty,
                                substs,
                                concrete_ty,
                                ty
                            );
                        }
                        let folded_ty = self.fold_ty(concrete_ty);
                        self.anon_depth -= 1;
                        folded_ty
                    }
                }
            }

            ty::Projection(ref data) if !data.has_escaping_bound_vars() => {
                // (*)
                // (*) This is kind of hacky -- we need to be able to
                // handle normalization within binders because
                // otherwise we wind up a need to normalize when doing
                // trait matching (since you can have a trait
                // obligation like `for<'a> T::B : Fn(&'a int)`), but
                // we can't normalize with bound regions in scope. So
                // far now we just ignore binders but only normalize
                // if all bound regions are gone (and then we still
                // have to renormalize whenever we instantiate a
                // binder). It would be better to normalize in a
                // binding-aware fashion.

                let tcx = self.infcx.tcx;

                let mut orig_values = OriginalQueryValues::default();
                // HACK(matthewjasper) `'static` is special-cased in selection,
                // so we cannot canonicalize it.
                let c_data = self
                    .infcx
                    .canonicalize_hr_query_hack(&self.param_env.and(*data), &mut orig_values);
                debug!("QueryNormalizer: c_data = {:#?}", c_data);
                debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
                match tcx.normalize_projection_ty(c_data) {
                    Ok(result) => {
                        // We don't expect ambiguity.
                        if result.is_ambiguous() {
                            self.error = true;
                            return ty;
                        }

                        match self.infcx.instantiate_query_response_and_region_obligations(
                            self.cause,
                            self.param_env,
                            &orig_values,
                            &result,
                        ) {
                            Ok(InferOk { value: result, obligations }) => {
                                debug!("QueryNormalizer: result = {:#?}", result);
                                debug!("QueryNormalizer: obligations = {:#?}", obligations);
                                self.obligations.extend(obligations);
                                result.normalized_ty
                            }

                            Err(_) => {
                                self.error = true;
                                ty
                            }
                        }
                    }

                    Err(NoSolution) => {
                        self.error = true;
                        ty
                    }
                }
            }

            _ => ty,
        }
    }

    fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
        let constant = constant.super_fold_with(self);
        constant.eval(self.infcx.tcx, self.param_env)
    }
}
<commit_msg>traits/query/normalize: add some `debug!` logging for the result.<commit_after>//! Code for the 'normalization' query. This consists of a wrapper
//! which folds deeply, invoking the underlying
//! `normalize_projection_ty` query when it encounters projections.

use crate::infer::at::At;
use crate::infer::canonical::OriginalQueryValues;
use crate::infer::{InferCtxt, InferOk};
use crate::traits::error_reporting::InferCtxtExt;
use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use rustc_infer::traits::Normalized;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, Ty, TyCtxt};

use super::NoSolution;

pub use rustc_middle::traits::query::NormalizationResult;

pub trait AtExt<'tcx> {
    fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
    where
        T: TypeFoldable<'tcx>;
}

impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
    /// Normalize `value` in the context of the inference context,
    /// yielding a resulting type, or an error if `value` cannot be
    /// normalized. If you don't care about regions, you should prefer
    /// `normalize_erasing_regions`, which is more efficient.
    ///
    /// If the normalization succeeds and is unambiguous, returns back
    /// the normalized value along with various outlives relations (in
    /// the form of obligations that must be discharged).
    ///
    /// N.B., this will *eventually* be the main means of
    /// normalizing, but for now should be used only when we actually
    /// know that normalization will succeed, since error reporting
    /// and other details are still "under development".
    fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
    where
        T: TypeFoldable<'tcx>,
    {
        debug!(
            "normalize::<{}>(value={:?}, param_env={:?})",
            ::std::any::type_name::<T>(),
            value,
            self.param_env,
        );
        if !value.has_projections() {
            return Ok(Normalized { value: value.clone(), obligations: vec![] });
        }

        let mut normalizer = QueryNormalizer {
            infcx: self.infcx,
            cause: self.cause,
            param_env: self.param_env,
            obligations: vec![],
            error: false,
            anon_depth: 0,
        };

        let result = value.fold_with(&mut normalizer);
        debug!(
            "normalize::<{}>: result={:?} with {} obligations",
            ::std::any::type_name::<T>(),
            result,
            normalizer.obligations.len(),
        );
        debug!(
            "normalize::<{}>: obligations={:?}",
            ::std::any::type_name::<T>(),
            normalizer.obligations,
        );
        if normalizer.error {
            Err(NoSolution)
        } else {
            Ok(Normalized { value: result, obligations: normalizer.obligations })
        }
    }
}

struct QueryNormalizer<'cx, 'tcx> {
    infcx: &'cx InferCtxt<'cx, 'tcx>,
    cause: &'cx ObligationCause<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    obligations: Vec<PredicateObligation<'tcx>>,
    error: bool,
    anon_depth: usize,
}

impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
    fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
        self.infcx.tcx
    }

    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
        if !ty.has_projections() {
            return ty;
        }

        let ty = ty.super_fold_with(self);
        match ty.kind {
            ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
                // (*)
                // Only normalize `impl Trait` after type-checking, usually in codegen.
                match self.param_env.reveal {
                    Reveal::UserFacing => ty,

                    Reveal::All => {
                        let recursion_limit = *self.tcx().sess.recursion_limit.get();
                        if self.anon_depth >= recursion_limit {
                            let obligation = Obligation::with_depth(
                                self.cause.clone(),
                                recursion_limit,
                                self.param_env,
                                ty,
                            );
                            self.infcx.report_overflow_error(&obligation, true);
                        }

                        let generic_ty = self.tcx().type_of(def_id);
                        let concrete_ty = generic_ty.subst(self.tcx(), substs);
                        self.anon_depth += 1;
                        if concrete_ty == ty {
                            bug!(
                                "infinite recursion generic_ty: {:#?}, substs: {:#?}, \
                                 concrete_ty: {:#?}, ty: {:#?}",
                                generic_ty,
                                substs,
                                concrete_ty,
                                ty
                            );
                        }
                        let folded_ty = self.fold_ty(concrete_ty);
                        self.anon_depth -= 1;
                        folded_ty
                    }
                }
            }

            ty::Projection(ref data) if !data.has_escaping_bound_vars() => {
                // (*)
                // (*) This is kind of hacky -- we need to be able to
                // handle normalization within binders because
                // otherwise we wind up a need to normalize when doing
                // trait matching (since you can have a trait
                // obligation like `for<'a> T::B : Fn(&'a int)`), but
                // we can't normalize with bound regions in scope. So
                // far now we just ignore binders but only normalize
                // if all bound regions are gone (and then we still
                // have to renormalize whenever we instantiate a
                // binder). It would be better to normalize in a
                // binding-aware fashion.

                let tcx = self.infcx.tcx;

                let mut orig_values = OriginalQueryValues::default();
                // HACK(matthewjasper) `'static` is special-cased in selection,
                // so we cannot canonicalize it.
                let c_data = self
                    .infcx
                    .canonicalize_hr_query_hack(&self.param_env.and(*data), &mut orig_values);
                debug!("QueryNormalizer: c_data = {:#?}", c_data);
                debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
                match tcx.normalize_projection_ty(c_data) {
                    Ok(result) => {
                        // We don't expect ambiguity.
                        if result.is_ambiguous() {
                            self.error = true;
                            return ty;
                        }

                        match self.infcx.instantiate_query_response_and_region_obligations(
                            self.cause,
                            self.param_env,
                            &orig_values,
                            &result,
                        ) {
                            Ok(InferOk { value: result, obligations }) => {
                                debug!("QueryNormalizer: result = {:#?}", result);
                                debug!("QueryNormalizer: obligations = {:#?}", obligations);
                                self.obligations.extend(obligations);
                                result.normalized_ty
                            }

                            Err(_) => {
                                self.error = true;
                                ty
                            }
                        }
                    }

                    Err(NoSolution) => {
                        self.error = true;
                        ty
                    }
                }
            }

            _ => ty,
        }
    }

    fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
        let constant = constant.super_fold_with(self);
        constant.eval(self.infcx.tcx, self.param_env)
    }
}
<|endoftext|>


<commit_before>trait GerberCode {
    fn to_code(&self) -> String;
}

#[derive(Debug)]
enum Command {
    FunctionCode(FunctionCode),
    ExtendedCode(ExtendedCode),
}

#[derive(Debug)]
enum FunctionCode {
    DCode(DCode),
    GCode(GCode),
    MCode(MCode),
}

#[derive(Debug)]
enum ExtendedCode {
    FS,
    MO,
    AD,
    AM,
    SR,
    LP,
    TF,
    TA,
    TD,
}

#[derive(Debug)]
enum DCode {
    Operation,
    SelectAperture,
}

#[derive(Debug)]
enum GCode {
    InterpolationMode,
    RegionMode,
    QuadrantMode,
    Comment(String),
}

#[derive(Debug)]
enum MCode {
    EndOfFile,
}

impl GerberCode for GCode {
    fn to_code(&self) -> String {
        match self {
            &GCode::InterpolationMode => format!("TODO InterpolationMode"),
            &GCode::RegionMode => format!("TODO RegionMode"),
            &GCode::QuadrantMode => format!("TODO QuadrantMode"),
            &GCode::Comment(ref comment) => format!("G04 {} *", comment),
        }
    }
}

impl<T: GerberCode> GerberCode for Vec<T> {
    fn to_code(&self) -> String {
        self.iter()
            .map(|g| g.to_code())
            .collect::<Vec<String>>()
            .join("\n")
    }
}

#[cfg(test)]
mod test {
    use super::{Command, FunctionCode, DCode, GCode};
    use super::GerberCode;

    #[test]
    fn test_gcode_debug() {
        let c = Command::FunctionCode(FunctionCode::GCode(GCode::Comment("test".to_string())));
        let debug = format!("{:?}", c);
        assert_eq!(debug, "FunctionCode(GCode(Comment(\"test\")))");
    }

    #[test]
    fn test_to_code() {
        let comment = GCode::Comment("testcomment".to_string());
        assert_eq!(comment.to_code(), "G04 testcomment *".to_string());
    }

    #[test]
    fn test_vec_to_code() {
        let mut v = Vec::new();
        v.push(GCode::Comment("comment 1".to_string()));
        v.push(GCode::Comment("another one".to_string()));
        assert_eq!(v.to_code(), "G04 comment 1 *\nG04 another one *".to_string());
    }

}
<commit_msg>Implement interpolation mode<commit_after>trait GerberCode {
    fn to_code(&self) -> String;
}

#[derive(Debug)]
enum Command {
    FunctionCode(FunctionCode),
    ExtendedCode(ExtendedCode),
}

#[derive(Debug)]
enum FunctionCode {
    DCode(DCode),
    GCode(GCode),
    MCode(MCode),
}

#[derive(Debug)]
enum ExtendedCode {
    FS,
    MO,
    AD,
    AM,
    SR,
    LP,
    TF,
    TA,
    TD,
}

#[derive(Debug)]
enum DCode {
    Operation,
    SelectAperture,
}

#[derive(Debug)]
enum InterpolationMode {
    Linear,
    ClockwiseCircular,
    CounterclockwiseCircular,
}

#[derive(Debug)]
enum GCode {
    InterpolationMode(InterpolationMode),
    RegionMode,
    QuadrantMode,
    Comment(String),
}

#[derive(Debug)]
enum MCode {
    EndOfFile,
}

impl GerberCode for GCode {
    fn to_code(&self) -> String {
        match self {
            &GCode::InterpolationMode(ref mode) => {
                match *mode {
                    InterpolationMode::Linear => "G01*".to_string(),
                    InterpolationMode::ClockwiseCircular => "G02*".to_string(),
                    InterpolationMode::CounterclockwiseCircular => "G03*".to_string(),
                }
            },
            &GCode::RegionMode => format!("TODO RegionMode"),
            &GCode::QuadrantMode => format!("TODO QuadrantMode"),
            &GCode::Comment(ref comment) => format!("G04 {} *", comment),
        }
    }
}

impl<T: GerberCode> GerberCode for Vec<T> {
    fn to_code(&self) -> String {
        self.iter()
            .map(|g| g.to_code())
            .collect::<Vec<String>>()
            .join("\n")
    }
}

#[cfg(test)]
mod test {
    use super::{Command, FunctionCode, DCode, GCode, InterpolationMode};
    use super::GerberCode;

    #[test]
    fn test_gcode_debug() {
        let c = Command::FunctionCode(FunctionCode::GCode(GCode::Comment("test".to_string())));
        let debug = format!("{:?}", c);
        assert_eq!(debug, "FunctionCode(GCode(Comment(\"test\")))");
    }

    #[test]
    fn test_to_code() {
        let comment = GCode::Comment("testcomment".to_string());
        assert_eq!(comment.to_code(), "G04 testcomment *".to_string());
    }

    #[test]
    fn test_vec_to_code() {
        let mut v = Vec::new();
        v.push(GCode::Comment("comment 1".to_string()));
        v.push(GCode::Comment("another one".to_string()));
        assert_eq!(v.to_code(), "G04 comment 1 *\nG04 another one *".to_string());
    }

    #[test]
    fn test_interpolation_mode() {
        let mut commands = Vec::new();
        let c1 = GCode::InterpolationMode(InterpolationMode::Linear);
        let c2 = GCode::InterpolationMode(InterpolationMode::ClockwiseCircular);
        let c3 = GCode::InterpolationMode(InterpolationMode::CounterclockwiseCircular);
        commands.push(c1);
        commands.push(c2);
        commands.push(c3);
        assert_eq!(commands.to_code(), "G01*\nG02*\nG03*".to_string());
    }

}
<|endoftext|>


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

use infer::at::At;
use infer::InferOk;
use infer::canonical::OriginalQueryValues;
use std::iter::FromIterator;
use syntax::source_map::Span;
use ty::subst::Kind;
use ty::{self, Ty, TyCtxt};

impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
    /// Given a type `ty` of some value being dropped, computes a set
    /// of "kinds" (types, regions) that must be outlive the execution
    /// of the destructor. These basically correspond to data that the
    /// destructor might access. This is used during regionck to
    /// impose "outlives" constraints on any lifetimes referenced
    /// within.
    ///
    /// The rules here are given by the "dropck" RFCs, notably [#1238]
    /// and [#1327]. This is a fixed-point computation, where we
    /// explore all the data that will be dropped (transitively) when
    /// a value of type `ty` is dropped. For each type T that will be
    /// dropped and which has a destructor, we must assume that all
    /// the types/regions of T are live during the destructor, unless
    /// they are marked with a special attribute (`#[may_dangle]`).
    ///
    /// [#1238]: https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md
    /// [#1327]: https://github.com/rust-lang/rfcs/blob/master/text/1327-dropck-param-eyepatch.md
    pub fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec<Kind<'tcx>>> {
        debug!(
            "dropck_outlives(ty={:?}, param_env={:?})",
            ty, self.param_env,
        );

        // Quick check: there are a number of cases that we know do not require
        // any destructor.
        let tcx = self.infcx.tcx;
        if trivial_dropck_outlives(tcx, ty) {
            return InferOk {
                value: vec![],
                obligations: vec![],
            };
        }

        let gcx = tcx.global_tcx();
        let mut orig_values = OriginalQueryValues::default();
        let c_ty = self.infcx.canonicalize_query(&self.param_env.and(ty), &mut orig_values);
        let span = self.cause.span;
        debug!("c_ty = {:?}", c_ty);
        if let Ok(result) = &gcx.dropck_outlives(c_ty) {
            if result.is_proven() {
                if let Ok(InferOk { value, obligations }) =
                    self.infcx.instantiate_query_response_and_region_obligations(
                    self.cause,
                    self.param_env,
                    &orig_values,
                    result)
                {
                    let ty = self.infcx.resolve_type_vars_if_possible(&ty);
                    let kinds = value.into_kinds_reporting_overflows(tcx, span, ty);
                    return InferOk {
                        value: kinds,
                        obligations,
                    };
                }
            }
        }

        // Errors and ambiuity in dropck occur in two cases:
        // - unresolved inference variables at the end of typeck
        // - non well-formed types where projections cannot be resolved
        // Either of these should have created an error before.
        tcx.sess
            .delay_span_bug(span, "dtorck encountered internal error");

        InferOk {
            value: vec![],
            obligations: vec![],
        }
    }
}

#[derive(Clone, Debug, Default)]
pub struct DropckOutlivesResult<'tcx> {
    pub kinds: Vec<Kind<'tcx>>,
    pub overflows: Vec<Ty<'tcx>>,
}

impl<'tcx> DropckOutlivesResult<'tcx> {
    pub fn report_overflows(
        &self,
        tcx: TyCtxt<'_, '_, 'tcx>,
        span: Span,
        ty: Ty<'tcx>,
    ) {
        if let Some(overflow_ty) = self.overflows.iter().next() {
            let mut err = struct_span_err!(
                tcx.sess,
                span,
                E0320,
                "overflow while adding drop-check rules for {}",
                ty,
            );
            err.note(&format!("overflowed on {}", overflow_ty));
            err.emit();
        }
    }

    pub fn into_kinds_reporting_overflows(
        self,
        tcx: TyCtxt<'_, '_, 'tcx>,
        span: Span,
        ty: Ty<'tcx>,
    ) -> Vec<Kind<'tcx>> {
        self.report_overflows(tcx, span, ty);
        let DropckOutlivesResult { kinds, overflows: _ } = self;
        kinds
    }
}

/// A set of constraints that need to be satisfied in order for
/// a type to be valid for destruction.
#[derive(Clone, Debug)]
pub struct DtorckConstraint<'tcx> {
    /// Types that are required to be alive in order for this
    /// type to be valid for destruction.
    pub outlives: Vec<ty::subst::Kind<'tcx>>,

    /// Types that could not be resolved: projections and params.
    pub dtorck_types: Vec<Ty<'tcx>>,

    /// If, during the computation of the dtorck constraint, we
    /// overflow, that gets recorded here. The caller is expected to
    /// report an error.
    pub overflows: Vec<Ty<'tcx>>,
}

impl<'tcx> DtorckConstraint<'tcx> {
    pub fn empty() -> DtorckConstraint<'tcx> {
        DtorckConstraint {
            outlives: vec![],
            dtorck_types: vec![],
            overflows: vec![],
        }
    }
}

impl<'tcx> FromIterator<DtorckConstraint<'tcx>> for DtorckConstraint<'tcx> {
    fn from_iter<I: IntoIterator<Item = DtorckConstraint<'tcx>>>(iter: I) -> Self {
        let mut result = Self::empty();

        for DtorckConstraint { outlives, dtorck_types, overflows } in iter {
            result.outlives.extend(outlives);
            result.dtorck_types.extend(dtorck_types);
            result.overflows.extend(overflows);
        }

        result
    }
}
BraceStructTypeFoldableImpl! {
    impl<'tcx> TypeFoldable<'tcx> for DropckOutlivesResult<'tcx> {
        kinds, overflows
    }
}

BraceStructLiftImpl! {
    impl<'a, 'tcx> Lift<'tcx> for DropckOutlivesResult<'a> {
        type Lifted = DropckOutlivesResult<'tcx>;
        kinds, overflows
    }
}

impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> {
    kinds, overflows
});

impl_stable_hash_for!(struct DtorckConstraint<'tcx> {
    outlives,
    dtorck_types,
    overflows
});

/// This returns true if the type `ty` is "trivial" for
/// dropck-outlives -- that is, if it doesn't require any types to
/// outlive. This is similar but not *quite* the same as the
/// `needs_drop` test in the compiler already -- that is, for every
/// type T for which this function return true, needs-drop would
/// return false. But the reverse does not hold: in particular,
/// `needs_drop` returns false for `PhantomData`, but it is not
/// trivial for dropck-outlives.
///
/// Note also that `needs_drop` requires a "global" type (i.e., one
/// with erased regions), but this function does not.
pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
    match ty.sty {
        // None of these types have a destructor and hence they do not
        // require anything in particular to outlive the dtor's
        // execution.
        ty::Infer(ty::FreshIntTy(_))
        | ty::Infer(ty::FreshFloatTy(_))
        | ty::Bool
        | ty::Int(_)
        | ty::Uint(_)
        | ty::Float(_)
        | ty::Never
        | ty::FnDef(..)
        | ty::FnPtr(_)
        | ty::Char
        | ty::GeneratorWitness(..)
        | ty::RawPtr(_)
        | ty::Ref(..)
        | ty::Str
        | ty::Foreign(..)
        | ty::Error => true,

        // [T; N] and [T] have same properties as T.
        ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty),

        // (T1..Tn) and closures have same properties as T1..Tn --
        // check if *any* of those are trivial.
        ty::Tuple(ref tys) => tys.iter().cloned().all(|t| trivial_dropck_outlives(tcx, t)),
        ty::Closure(def_id, ref substs) => substs
            .upvar_tys(def_id, tcx)
            .all(|t| trivial_dropck_outlives(tcx, t)),

        ty::Adt(def, _) => {
            if Some(def.did) == tcx.lang_items().manually_drop() {
                // `ManuallyDrop` never has a dtor.
                true
            } else {
                // Other types might. Moreover, PhantomData doesn't
                // have a dtor, but it is considered to own its
                // content, so it is non-trivial. Unions can have `impl Drop`,
                // and hence are non-trivial as well.
                false
            }
        }

        // The following *might* require a destructor: needs deeper inspection.
        ty::Dynamic(..)
        | ty::Projection(..)
        | ty::Param(_)
        | ty::Opaque(..)
        | ty::Placeholder(..)
        | ty::Infer(_)
        | ty::Bound(..)
        | ty::Generator(..) => false,

        ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
    }
}
<commit_msg>dropck: remove unnecessary call to cloned()<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use infer::at::At;
use infer::InferOk;
use infer::canonical::OriginalQueryValues;
use std::iter::FromIterator;
use syntax::source_map::Span;
use ty::subst::Kind;
use ty::{self, Ty, TyCtxt};

impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
    /// Given a type `ty` of some value being dropped, computes a set
    /// of "kinds" (types, regions) that must be outlive the execution
    /// of the destructor. These basically correspond to data that the
    /// destructor might access. This is used during regionck to
    /// impose "outlives" constraints on any lifetimes referenced
    /// within.
    ///
    /// The rules here are given by the "dropck" RFCs, notably [#1238]
    /// and [#1327]. This is a fixed-point computation, where we
    /// explore all the data that will be dropped (transitively) when
    /// a value of type `ty` is dropped. For each type T that will be
    /// dropped and which has a destructor, we must assume that all
    /// the types/regions of T are live during the destructor, unless
    /// they are marked with a special attribute (`#[may_dangle]`).
    ///
    /// [#1238]: https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md
    /// [#1327]: https://github.com/rust-lang/rfcs/blob/master/text/1327-dropck-param-eyepatch.md
    pub fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec<Kind<'tcx>>> {
        debug!(
            "dropck_outlives(ty={:?}, param_env={:?})",
            ty, self.param_env,
        );

        // Quick check: there are a number of cases that we know do not require
        // any destructor.
        let tcx = self.infcx.tcx;
        if trivial_dropck_outlives(tcx, ty) {
            return InferOk {
                value: vec![],
                obligations: vec![],
            };
        }

        let gcx = tcx.global_tcx();
        let mut orig_values = OriginalQueryValues::default();
        let c_ty = self.infcx.canonicalize_query(&self.param_env.and(ty), &mut orig_values);
        let span = self.cause.span;
        debug!("c_ty = {:?}", c_ty);
        if let Ok(result) = &gcx.dropck_outlives(c_ty) {
            if result.is_proven() {
                if let Ok(InferOk { value, obligations }) =
                    self.infcx.instantiate_query_response_and_region_obligations(
                    self.cause,
                    self.param_env,
                    &orig_values,
                    result)
                {
                    let ty = self.infcx.resolve_type_vars_if_possible(&ty);
                    let kinds = value.into_kinds_reporting_overflows(tcx, span, ty);
                    return InferOk {
                        value: kinds,
                        obligations,
                    };
                }
            }
        }

        // Errors and ambiuity in dropck occur in two cases:
        // - unresolved inference variables at the end of typeck
        // - non well-formed types where projections cannot be resolved
        // Either of these should have created an error before.
        tcx.sess
            .delay_span_bug(span, "dtorck encountered internal error");

        InferOk {
            value: vec![],
            obligations: vec![],
        }
    }
}

#[derive(Clone, Debug, Default)]
pub struct DropckOutlivesResult<'tcx> {
    pub kinds: Vec<Kind<'tcx>>,
    pub overflows: Vec<Ty<'tcx>>,
}

impl<'tcx> DropckOutlivesResult<'tcx> {
    pub fn report_overflows(
        &self,
        tcx: TyCtxt<'_, '_, 'tcx>,
        span: Span,
        ty: Ty<'tcx>,
    ) {
        if let Some(overflow_ty) = self.overflows.iter().next() {
            let mut err = struct_span_err!(
                tcx.sess,
                span,
                E0320,
                "overflow while adding drop-check rules for {}",
                ty,
            );
            err.note(&format!("overflowed on {}", overflow_ty));
            err.emit();
        }
    }

    pub fn into_kinds_reporting_overflows(
        self,
        tcx: TyCtxt<'_, '_, 'tcx>,
        span: Span,
        ty: Ty<'tcx>,
    ) -> Vec<Kind<'tcx>> {
        self.report_overflows(tcx, span, ty);
        let DropckOutlivesResult { kinds, overflows: _ } = self;
        kinds
    }
}

/// A set of constraints that need to be satisfied in order for
/// a type to be valid for destruction.
#[derive(Clone, Debug)]
pub struct DtorckConstraint<'tcx> {
    /// Types that are required to be alive in order for this
    /// type to be valid for destruction.
    pub outlives: Vec<ty::subst::Kind<'tcx>>,

    /// Types that could not be resolved: projections and params.
    pub dtorck_types: Vec<Ty<'tcx>>,

    /// If, during the computation of the dtorck constraint, we
    /// overflow, that gets recorded here. The caller is expected to
    /// report an error.
    pub overflows: Vec<Ty<'tcx>>,
}

impl<'tcx> DtorckConstraint<'tcx> {
    pub fn empty() -> DtorckConstraint<'tcx> {
        DtorckConstraint {
            outlives: vec![],
            dtorck_types: vec![],
            overflows: vec![],
        }
    }
}

impl<'tcx> FromIterator<DtorckConstraint<'tcx>> for DtorckConstraint<'tcx> {
    fn from_iter<I: IntoIterator<Item = DtorckConstraint<'tcx>>>(iter: I) -> Self {
        let mut result = Self::empty();

        for DtorckConstraint { outlives, dtorck_types, overflows } in iter {
            result.outlives.extend(outlives);
            result.dtorck_types.extend(dtorck_types);
            result.overflows.extend(overflows);
        }

        result
    }
}
BraceStructTypeFoldableImpl! {
    impl<'tcx> TypeFoldable<'tcx> for DropckOutlivesResult<'tcx> {
        kinds, overflows
    }
}

BraceStructLiftImpl! {
    impl<'a, 'tcx> Lift<'tcx> for DropckOutlivesResult<'a> {
        type Lifted = DropckOutlivesResult<'tcx>;
        kinds, overflows
    }
}

impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> {
    kinds, overflows
});

impl_stable_hash_for!(struct DtorckConstraint<'tcx> {
    outlives,
    dtorck_types,
    overflows
});

/// This returns true if the type `ty` is "trivial" for
/// dropck-outlives -- that is, if it doesn't require any types to
/// outlive. This is similar but not *quite* the same as the
/// `needs_drop` test in the compiler already -- that is, for every
/// type T for which this function return true, needs-drop would
/// return false. But the reverse does not hold: in particular,
/// `needs_drop` returns false for `PhantomData`, but it is not
/// trivial for dropck-outlives.
///
/// Note also that `needs_drop` requires a "global" type (i.e., one
/// with erased regions), but this function does not.
pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
    match ty.sty {
        // None of these types have a destructor and hence they do not
        // require anything in particular to outlive the dtor's
        // execution.
        ty::Infer(ty::FreshIntTy(_))
        | ty::Infer(ty::FreshFloatTy(_))
        | ty::Bool
        | ty::Int(_)
        | ty::Uint(_)
        | ty::Float(_)
        | ty::Never
        | ty::FnDef(..)
        | ty::FnPtr(_)
        | ty::Char
        | ty::GeneratorWitness(..)
        | ty::RawPtr(_)
        | ty::Ref(..)
        | ty::Str
        | ty::Foreign(..)
        | ty::Error => true,

        // [T; N] and [T] have same properties as T.
        ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty),

        // (T1..Tn) and closures have same properties as T1..Tn --
        // check if *any* of those are trivial.
        ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t)),
        ty::Closure(def_id, ref substs) => substs
            .upvar_tys(def_id, tcx)
            .all(|t| trivial_dropck_outlives(tcx, t)),

        ty::Adt(def, _) => {
            if Some(def.did) == tcx.lang_items().manually_drop() {
                // `ManuallyDrop` never has a dtor.
                true
            } else {
                // Other types might. Moreover, PhantomData doesn't
                // have a dtor, but it is considered to own its
                // content, so it is non-trivial. Unions can have `impl Drop`,
                // and hence are non-trivial as well.
                false
            }
        }

        // The following *might* require a destructor: needs deeper inspection.
        ty::Dynamic(..)
        | ty::Projection(..)
        | ty::Param(_)
        | ty::Opaque(..)
        | ty::Placeholder(..)
        | ty::Infer(_)
        | ty::Bound(..)
        | ty::Generator(..) => false,

        ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
    }
}
<|endoftext|>


<commit_before>//138
pub struct INITCOMMONCONTROLSEX {
	pub dwSize: ::DWORD,
	pub dwICC: ::DWORD,
}
pub type LPINITCOMMONCONTROLSEX = *const INITCOMMONCONTROLSEX;
pub const ICC_LISTVIEW_CLASSES: ::DWORD = 0x1;
pub const ICC_TREEVIEW_CLASSES: ::DWORD = 0x2;
pub const ICC_BAR_CLASSES: ::DWORD = 0x4;
pub const ICC_TAB_CLASSES: ::DWORD = 0x8;
pub const ICC_UPDOWN_CLASS: ::DWORD = 0x10;
pub const ICC_PROGRESS_CLASS: ::DWORD = 0x20;
pub const ICC_HOTKEY_CLASS: ::DWORD = 0x40;
pub const ICC_ANIMATE_CLASS: ::DWORD = 0x80;
pub const ICC_WIN95_CLASSES: ::DWORD = 0xFF;
pub const ICC_DATE_CLASSES: ::DWORD = 0x100;
pub const ICC_USEREX_CLASSES: ::DWORD = 0x200;
pub const ICC_COOL_CLASSES: ::DWORD = 0x400;
pub const ICC_INTERNET_CLASSES: ::DWORD = 0x800;
pub const ICC_PAGESCROLLER_CLASS: ::DWORD = 0x1000;
pub const ICC_NATIVEFNTCTL_CLASS: ::DWORD = 0x2000;
pub const ICC_STANDARD_CLASSES: ::DWORD = 0x4000;
pub const ICC_LINK_CLASS: ::DWORD = 0x8000;
<commit_msg>Change LPINITCOMMONCONTROLSEX to a *mut pointer.<commit_after>//138
pub struct INITCOMMONCONTROLSEX {
	pub dwSize: ::DWORD,
	pub dwICC: ::DWORD,
}
pub type LPINITCOMMONCONTROLSEX = *mut INITCOMMONCONTROLSEX;
pub const ICC_LISTVIEW_CLASSES: ::DWORD = 0x1;
pub const ICC_TREEVIEW_CLASSES: ::DWORD = 0x2;
pub const ICC_BAR_CLASSES: ::DWORD = 0x4;
pub const ICC_TAB_CLASSES: ::DWORD = 0x8;
pub const ICC_UPDOWN_CLASS: ::DWORD = 0x10;
pub const ICC_PROGRESS_CLASS: ::DWORD = 0x20;
pub const ICC_HOTKEY_CLASS: ::DWORD = 0x40;
pub const ICC_ANIMATE_CLASS: ::DWORD = 0x80;
pub const ICC_WIN95_CLASSES: ::DWORD = 0xFF;
pub const ICC_DATE_CLASSES: ::DWORD = 0x100;
pub const ICC_USEREX_CLASSES: ::DWORD = 0x200;
pub const ICC_COOL_CLASSES: ::DWORD = 0x400;
pub const ICC_INTERNET_CLASSES: ::DWORD = 0x800;
pub const ICC_PAGESCROLLER_CLASS: ::DWORD = 0x1000;
pub const ICC_NATIVEFNTCTL_CLASS: ::DWORD = 0x2000;
pub const ICC_STANDARD_CLASSES: ::DWORD = 0x4000;
pub const ICC_LINK_CLASS: ::DWORD = 0x8000;
<|endoftext|>


<commit_before>use std::vec::Vec;
use std::string::String;

struct Compiler {
    pub lines: Vec<String>,
}

impl Compiler {
    pub fn new() -> Self {
        Compiler { lines: Vec::new() }
    }

    pub fn parse(&mut self, assembly: &str) {
        let mut line = String::new();
        let mut chars = assembly.chars();

        while let Some(c) = chars.next() {
            match c {
                // Line Feed
                '\u{000A}' => {
                    self.lines.push(line);
                    line = String::new();
                }
                _ => {
                    line.push(c);
                }
            }
        }

        if !line.is_empty() {
            self.lines.push(line);
        }
    }
}

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

    #[test]
    fn it_splits_lines_by_line_feed() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\n0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_ignors_trailing_separators() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\n0 0 0 0\n");

        assert_eq!(compiler.lines.len(), 2);
    }
}
<commit_msg>Splits assembly on vertical tabs.<commit_after>use std::vec::Vec;
use std::string::String;

struct Compiler {
    pub lines: Vec<String>,
}

impl Compiler {
    pub fn new() -> Self {
        Compiler { lines: Vec::new() }
    }

    pub fn parse(&mut self, assembly: &str) {
        let mut line = String::new();
        let mut chars = assembly.chars();

        while let Some(c) = chars.next() {
            match c {
                // Line Feed
                // Vertical Tab
                '\u{000A}' | '\u{000B}' => {
                    self.lines.push(line);
                    line = String::new();
                }

                _ => {
                    line.push(c);
                }
            }
        }

        if !line.is_empty() {
            self.lines.push(line);
        }
    }
}

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

    #[test]
    fn it_splits_lines_by_line_feed() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\n0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_vertical_tab() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\x0B0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_ignors_trailing_separators() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\n0 0 0 0\n");

        assert_eq!(compiler.lines.len(), 2);
    }
}
<|endoftext|>


<commit_before>//! Directory module for managing Algorithmia Data Directories
//!
//! # Examples
//!
//! ```no_run
//! use algorithmia::Algorithmia;
//! use std::fs::File;
//!
//! let client = Algorithmia::client("111112222233333444445555566");
//! let my_dir = client.dir(".my/my_dir");
//!
//! my_dir.create();
//! my_dir.put_file("/path/to/file");
//! ```

extern crate hyper;
extern crate chrono;

use {Algorithmia, AlgorithmiaError, ApiErrorResponse};
use hyper::Url;
use hyper::status::StatusCode;
use rustc_serialize::{json, Decoder};
use std::io::Read;
use std::fs::File;
use std::path::Path;
use hyper::header::ContentType;
use hyper::mime::{Mime, TopLevel, SubLevel};
use self::chrono::{DateTime, UTC};
use super::{DataObject, FileAddedResult, FileAdded};
use std::ops::Deref;

/// Algorithmia Data Directory
pub struct DataDir {
    data_object: DataObject,
}

impl Deref for DataDir {
    type Target = DataObject;
    fn deref(&self) -> &DataObject {&self.data_object}
}

pub type DirectoryShowResult = Result<DirectoryShow, AlgorithmiaError>;
pub type DirectoryCreatedResult = Result<(), AlgorithmiaError>;
pub type DirectoryDeletedResult = Result<DirectoryDeleted, AlgorithmiaError>;

#[derive(RustcDecodable, Debug)]
pub struct DirectoryUpdated {
    pub acl: Option<DataAcl>,
}

#[derive(RustcDecodable, Debug)]
pub struct DeletedResult {
    pub deleted: u64,
}

/// Response when deleting a new Directory
#[derive(RustcDecodable, Debug)]
pub struct DirectoryDeleted {
    // Omitting deleted.number and error.number for now
    pub result: DeletedResult,
}

#[derive(RustcDecodable, RustcEncodable, Debug)]
pub struct DataFolder {
    pub name: String,
    pub acl: Option<DataAcl>,
}

#[derive(RustcDecodable, Debug)]
pub struct DataFile {
    pub filename: String,
    pub last_modified: DateTime<UTC>,
    pub size: u64,
}

#[derive(RustcDecodable, RustcEncodable, Debug)]
pub struct DataAcl {
    pub read: Vec<String>
}

/// Response when querying an existing Directory
#[derive(RustcDecodable, Debug)]
pub struct DirectoryShow {
    pub folders: Option<Vec<DataFolder>>,
    pub files: Option<Vec<DataFile>>,
    pub marker: Option<String>,
    pub acl: Option<DataAcl>,
}

impl DataDir {
    pub fn new(client: Algorithmia, data_uri: &str) -> DataDir {
        DataDir {
            data_object: DataObject::new(client, data_uri),
        }
    }

    /// Display Directory details if it exists
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let my_dir = client.dir(".my/my_dir");
    /// match my_dir.show() {
    ///   Ok(dir) => println!("Files: {}", dir.files.unwrap().iter().map(|f| f.filename.clone()).collect::<Vec<_>>().connect(", ")),
    ///   Err(e) => println!("ERROR: {:?}", e),
    /// };
    /// ```
    pub fn show(&self) -> DirectoryShowResult {
        let http_client = self.client.http_client();
        let req = http_client.get(self.to_url());

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        match json::decode::<DirectoryShow>(&res_json) {
            Ok(result) => Ok(result),
            Err(why) => match json::decode::<ApiErrorResponse>(&res_json) {
                Ok(err_res) => Err(AlgorithmiaError::AlgorithmiaApiError(err_res.error)),
                Err(_) => Err(AlgorithmiaError::DecoderErrorWithContext(why, res_json)),
            }
        }
    }

    /// Create a Directory
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let my_dir = client.dir(".my/my_dir");
    /// match my_dir.create() {
    ///   Ok(_) => println!("Successfully created Directory"),
    ///   Err(e) => println!("ERROR creating Directory: {:?}", e),
    /// };
    /// ```
    pub fn create(&self) -> DirectoryCreatedResult {
        let url = self.parent().unwrap().to_url(); //TODO: don't unwrap this

        let input_data = DataFolder {
            name: self.basename().unwrap().to_string(), //TODO: don't unwrap this
            acl: Some(DataAcl { read: vec![] }),
        };
        let raw_input = try!(json::encode(&input_data));

        // POST request
        let http_client = self.client.http_client();
        let req = http_client.post(url)
            .header(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])))
            .body(&raw_input);

        // Parse response
        let mut res = try!(req.send());

        match res.status {
            StatusCode::Ok | StatusCode::Created => Ok(()),
            _ => {
                let mut res_json = String::new();
                try!(res.read_to_string(&mut res_json));
                Err(Algorithmia::decode_to_error(res_json))
            }
        }
    }

    /// Delete a Directory
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let my_dir = client.dir(".my/my_dir");
    /// match my_dir.delete() {
    ///   Ok(_) => println!("Successfully deleted Directory"),
    ///   Err(e) => println!("ERROR deleting Directory: {:?}", e),
    /// };
    /// ```
    pub fn delete(&self) -> DirectoryDeletedResult {
        // DELETE request
        let http_client = self.client.http_client();
        let req = http_client.delete(self.to_url());

        // Parse response
        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Algorithmia::decode_to_result::<DirectoryDeleted>(res_json)
    }

    /// Upload a file to an existing Directory
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let my_dir = client.dir(".my/my_dir");
    ///
    /// match my_dir.put_file("/path/to/file") {
    ///   Ok(response) => println!("Successfully uploaded to: {}", response.result),
    ///   Err(e) => println!("ERROR uploading file: {:?}", e),
    /// };
    /// ```
    pub fn put_file<P: AsRef<Path>>(&self, file_path: P) -> FileAddedResult {
        // FIXME: A whole lot of unwrap going on here...
        let path_ref = file_path.as_ref();
        let url_string = format!("{}/{}",
            self.to_url(),
            path_ref.file_name().unwrap().to_str().unwrap()
        );
        let url = Url::parse(&url_string).unwrap();

        let mut file = File::open(path_ref).unwrap();
        let http_client = self.client.http_client();
        let req = http_client.post(url).body(&mut file);

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Algorithmia::decode_to_result::<FileAdded>(res_json)
    }

}

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

    fn mock_client() -> Algorithmia { Algorithmia::client("") }

    #[test]
    fn test_to_url() {
        let mock_client = mock_client();
        let dir = DataDir::new(mock_client, "data://anowell/foo");
        assert_eq!(dir.to_url().serialize(), format!("{}/v1/data/anowell/foo", dir.client.base_url));
    }

    #[test]
    fn test_to_data_uri() {
        let dir = DataDir::new(mock_client(), "/anowell/foo");
        assert_eq!(dir.to_data_uri(), "data://anowell/foo".to_string());
    }

    #[test]
    fn test_parent() {
        let dir = DataDir::new(mock_client(), "data://anowell/foo");
        let expected = DataDir::new(mock_client(), "data://anowell");
        assert_eq!(dir.parent().unwrap().path, expected.path);
    }
}<commit_msg>temporary rename of name collision<commit_after>//! Directory module for managing Algorithmia Data Directories
//!
//! # Examples
//!
//! ```no_run
//! use algorithmia::Algorithmia;
//! use std::fs::File;
//!
//! let client = Algorithmia::client("111112222233333444445555566");
//! let my_dir = client.dir(".my/my_dir");
//!
//! my_dir.create();
//! my_dir.put_file("/path/to/file");
//! ```

extern crate hyper;
extern crate chrono;

use {Algorithmia, AlgorithmiaError, ApiErrorResponse};
use hyper::Url;
use hyper::status::StatusCode;
use rustc_serialize::{json, Decoder};
use std::io::Read;
use std::fs::File;
use std::path::Path;
use hyper::header::ContentType;
use hyper::mime::{Mime, TopLevel, SubLevel};
use self::chrono::{DateTime, UTC};
use super::{DataObject, FileAddedResult, FileAdded};
use std::ops::Deref;

/// Algorithmia Data Directory
pub struct DataDir {
    data_object: DataObject,
}

impl Deref for DataDir {
    type Target = DataObject;
    fn deref(&self) -> &DataObject {&self.data_object}
}

pub type DirectoryShowResult = Result<DirectoryShow, AlgorithmiaError>;
pub type DirectoryCreatedResult = Result<(), AlgorithmiaError>;
pub type DirectoryDeletedResult = Result<DirectoryDeleted, AlgorithmiaError>;

#[derive(RustcDecodable, Debug)]
pub struct DirectoryUpdated {
    pub acl: Option<DataAcl>,
}

#[derive(RustcDecodable, Debug)]
pub struct DeletedResult {
    pub deleted: u64,
}

/// Response when deleting a new Directory
#[derive(RustcDecodable, Debug)]
pub struct DirectoryDeleted {
    // Omitting deleted.number and error.number for now
    pub result: DeletedResult,
}

#[derive(RustcDecodable, RustcEncodable, Debug)]
pub struct FolderListing {
    pub name: String,
    pub acl: Option<DataAcl>,
}

#[derive(RustcDecodable, Debug)]
pub struct FileListing {
    pub filename: String,
    pub last_modified: DateTime<UTC>,
    pub size: u64,
}

#[derive(RustcDecodable, RustcEncodable, Debug)]
pub struct DataAcl {
    pub read: Vec<String>
}

/// Response when querying an existing Directory
#[derive(RustcDecodable, Debug)]
pub struct DirectoryShow {
    pub folders: Option<Vec<FolderListing>>,
    pub files: Option<Vec<FileListing>>,
    pub marker: Option<String>,
    pub acl: Option<DataAcl>,
}

impl DataDir {
    pub fn new(client: Algorithmia, data_uri: &str) -> DataDir {
        DataDir {
            data_object: DataObject::new(client, data_uri),
        }
    }

    /// Display Directory details if it exists
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let my_dir = client.dir(".my/my_dir");
    /// match my_dir.show() {
    ///   Ok(dir) => println!("Files: {}", dir.files.unwrap().iter().map(|f| f.filename.clone()).collect::<Vec<_>>().connect(", ")),
    ///   Err(e) => println!("ERROR: {:?}", e),
    /// };
    /// ```
    pub fn show(&self) -> DirectoryShowResult {
        let http_client = self.client.http_client();
        let req = http_client.get(self.to_url());

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        match json::decode::<DirectoryShow>(&res_json) {
            Ok(result) => Ok(result),
            Err(why) => match json::decode::<ApiErrorResponse>(&res_json) {
                Ok(err_res) => Err(AlgorithmiaError::AlgorithmiaApiError(err_res.error)),
                Err(_) => Err(AlgorithmiaError::DecoderErrorWithContext(why, res_json)),
            }
        }
    }

    /// Create a Directory
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let my_dir = client.dir(".my/my_dir");
    /// match my_dir.create() {
    ///   Ok(_) => println!("Successfully created Directory"),
    ///   Err(e) => println!("ERROR creating Directory: {:?}", e),
    /// };
    /// ```
    pub fn create(&self) -> DirectoryCreatedResult {
        let url = self.parent().unwrap().to_url(); //TODO: don't unwrap this

        // TODO: complete abuse of this structure
        let input_data = FolderListing {
            name: self.basename().unwrap().to_string(), //TODO: don't unwrap this
            acl: Some(DataAcl { read: vec![] }),
        };
        let raw_input = try!(json::encode(&input_data));

        // POST request
        let http_client = self.client.http_client();
        let req = http_client.post(url)
            .header(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])))
            .body(&raw_input);

        // Parse response
        let mut res = try!(req.send());

        match res.status {
            StatusCode::Ok | StatusCode::Created => Ok(()),
            _ => {
                let mut res_json = String::new();
                try!(res.read_to_string(&mut res_json));
                Err(Algorithmia::decode_to_error(res_json))
            }
        }
    }

    /// Delete a Directory
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let my_dir = client.dir(".my/my_dir");
    /// match my_dir.delete() {
    ///   Ok(_) => println!("Successfully deleted Directory"),
    ///   Err(e) => println!("ERROR deleting Directory: {:?}", e),
    /// };
    /// ```
    pub fn delete(&self) -> DirectoryDeletedResult {
        // DELETE request
        let http_client = self.client.http_client();
        let req = http_client.delete(self.to_url());

        // Parse response
        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Algorithmia::decode_to_result::<DirectoryDeleted>(res_json)
    }

    /// Upload a file to an existing Directory
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let my_dir = client.dir(".my/my_dir");
    ///
    /// match my_dir.put_file("/path/to/file") {
    ///   Ok(response) => println!("Successfully uploaded to: {}", response.result),
    ///   Err(e) => println!("ERROR uploading file: {:?}", e),
    /// };
    /// ```
    pub fn put_file<P: AsRef<Path>>(&self, file_path: P) -> FileAddedResult {
        // FIXME: A whole lot of unwrap going on here...
        let path_ref = file_path.as_ref();
        let url_string = format!("{}/{}",
            self.to_url(),
            path_ref.file_name().unwrap().to_str().unwrap()
        );
        let url = Url::parse(&url_string).unwrap();

        let mut file = File::open(path_ref).unwrap();
        let http_client = self.client.http_client();
        let req = http_client.post(url).body(&mut file);

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Algorithmia::decode_to_result::<FileAdded>(res_json)
    }

}

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

    fn mock_client() -> Algorithmia { Algorithmia::client("") }

    #[test]
    fn test_to_url() {
        let mock_client = mock_client();
        let dir = DataDir::new(mock_client, "data://anowell/foo");
        assert_eq!(dir.to_url().serialize(), format!("{}/v1/data/anowell/foo", dir.client.base_url));
    }

    #[test]
    fn test_to_data_uri() {
        let dir = DataDir::new(mock_client(), "/anowell/foo");
        assert_eq!(dir.to_data_uri(), "data://anowell/foo".to_string());
    }

    #[test]
    fn test_parent() {
        let dir = DataDir::new(mock_client(), "data://anowell/foo");
        let expected = DataDir::new(mock_client(), "data://anowell");
        assert_eq!(dir.parent().unwrap().path, expected.path);
    }
}<|endoftext|>


<commit_before>/// entiti:es.rs
/// data structures for the mastodon api
///
use std::fmt;

#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct StatusId(u64);

impl fmt::Display for StatusId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct UserId(u64);

impl fmt::Display for UserId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct NotificationId(u64);

impl fmt::Display for NotificationId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Status {
    pub id: StatusId,
    uri: String,
    url: String,
    account: Account,
    in_reply_to_id: Option<StatusId>,
    reblog: Option<Box<Status>>,
    content: String,
    created_at: String,
    reblogs_count: u64,
    favourites_count: u64,
    reblogged: bool,
    favourited: bool,
    media_attachments: Vec<MediaAttachment>,
    mentions: Vec<Mention>
}

#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum MediaAttachment {
    Image {
        url: String,
        preview_url: String,
    },
    Video {
        url: String,
        preview_url: String,
    }
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Mention {
    pub id: UserId,
    url: String,
    acct: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Account {
    pub id: UserId,
    username: String,
    acct: String,
    display_name: String,
    note: String,
    url: String,
    avatar: String,
    header: String,
    followers_count: u64,
    following_count: u64,
    statuses_count: u64,
}

#[derive(Debug, Serialize, Deserialize)]
struct RawNotification {
    #[serde(rename = "type")]
    tag: String,
    id: NotificationId,
    account: Account,
    status: Option<Status>,
}

#[derive(Debug)]
pub enum Notification {
    Mention {
        id: NotificationId,
        account: Account,
    },
    Follow {
        id: NotificationId,
        account: Account,
    },
    Favourite {
        id: NotificationId,
        account: Account,
        status: Status,
    },
    Reblog {
        id: NotificationId,
        account: Account,
        status: Status,
    },
    Unknown {
        id: NotificationId,
    }
}

impl From<RawNotification> for Notification {
    fn from(rn: RawNotification) -> Self {
        match rn.tag.as_str() {
            "mention" => Notification::Mention {
                id: rn.id,
                account: rn.account,
            },
            "follow" => Notification::Follow {
                id: rn.id,
                account: rn.account,
            },
            "favourite" => Notification::Favourite {
                id: rn.id,
                account: rn.account,
                status: rn.status.unwrap(),
            },
            "reblog" => Notification::Reblog {
                id: rn.id,
                account: rn.account,
                status: rn.status.unwrap(),
            },
            _ => Notification::Unknown {
                id: rn.id,
            }
        }
    }
}

<commit_msg>updated several entities to match current mastodon docs<commit_after>/// entiti:es.rs
/// data structures for the mastodon api
///
use std::fmt;

#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct StatusId(u64);

impl fmt::Display for StatusId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct UserId(u64);

impl fmt::Display for UserId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct NotificationId(u64);

impl fmt::Display for NotificationId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Status {
    pub id: StatusId,
    uri: String,
    url: String,
    account: Account,
    in_reply_to_id: Option<StatusId>,
    in_reply_to_account_id: Option<UserId>,
    reblog: Option<Box<Status>>,
    content: String,
    created_at: String,
    reblogs_count: u64,
    favourites_count: u64,
    reblogged: bool,
    favourited: bool,
    sensitive: bool,
    spoiler_text: bool,
    visibility: Visibility,
    media_attachments: Vec<MediaAttachment>,
    mentions: Vec<Mention>,
    tags: Vec<Tag>,
    application: Application
}

#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum Visibility {
    Public,
    Unlisted,
    Private,
    Direct,
}

#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum MediaAttachment {
    Image {
        url: String,
        preview_url: String,
    },
    Video {
        url: String,
        preview_url: String,
    },
    GifV {
        url: String,
        preview_url: String,
    }
}

#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct Tag {
    name: String,
    url: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Mention {
    pub id: UserId,
    url: String,
    username: String,
    acct: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Account {
    pub id: UserId,
    username: String,
    acct: String,
    display_name: String,
    note: String,
    url: String,
    avatar: String,
    header: String,
    locked: bool,
    created_at: String,
    followers_count: u64,
    following_count: u64,
    statuses_count: u64,
}

#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct Application {
    name: String,
    website: String,
}

#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct Instance {
    uri: String,
    title: String,
    description: String,
    email: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct RawNotification {
    #[serde(rename = "type")]
    tag: String,
    id: NotificationId,
    created_at: String,
    account: Account,
    status: Option<Status>,
}

#[derive(Debug)]
pub enum Notification {
    Mention {
        id: NotificationId,
        created_at: String,
        account: Account,
    },
    Follow {
        id: NotificationId,
        created_at: String,
        account: Account,
    },
    Favourite {
        id: NotificationId,
        created_at: String,
        account: Account,
        status: Status,
    },
    Reblog {
        id: NotificationId,
        created_at: String,
        account: Account,
        status: Status,
    },
    Unknown {
        id: NotificationId,
        created_at: String,
    }
}

impl From<RawNotification> for Notification {
    fn from(rn: RawNotification) -> Self {
        match rn.tag.as_str() {
            "mention" => Notification::Mention {
                id: rn.id,
                created_at: rn.created_at,
                account: rn.account,
            },
            "follow" => Notification::Follow {
                id: rn.id,
                created_at: rn.created_at,
                account: rn.account,
            },
            "favourite" => Notification::Favourite {
                id: rn.id,
                created_at: rn.created_at,
                account: rn.account,
                status: rn.status.unwrap(),
            },
            "reblog" => Notification::Reblog {
                id: rn.id,
                created_at: rn.created_at,
                account: rn.account,
                status: rn.status.unwrap(),
            },
            _ => Notification::Unknown {
                id: rn.id,
                created_at: rn.created_at,
            }
        }
    }
}

#[derive(Debug, Serialize, Deserialize)]
/// a server sent error
/// in most cases these will be translated into results
pub struct ServerError {
    error: String
}<|endoftext|>


<commit_before>// Rx -- Reactive programming for Rust
// Copyright 2016 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

use observable::Observable;
use observer::Observer;
use std::marker::PhantomData;

/// An observable that produces an error when subscribed to.
pub struct ErrorObservable<T: Clone, E: Clone> {
    _phantom_t: PhantomData<T>,
    error: E,
}

impl<T: Clone, E: Clone> Observable for ErrorObservable<T, E> {
    type Item = T;
    type Error = E;
    type Subscription = super::UncancellableSubscription;

    fn subscribe<O>(&mut self, observer: O) -> Self::Subscription
        where O: Observer<Self::Item, Self::Error> {
        observer.on_error(self.error.clone());
        super::UncancellableSubscription
    }
}

/// Returns an observable that fails with the given error when subscribed to.
///
/// On its own an observable that always fails has limited use, but it can be
/// convenient when combining observables.
///
/// TODO: Add example once `continue_with` has been implemented.
pub fn error<T: Clone, E: Clone>(error: E) -> ErrorObservable<T, E> {
    ErrorObservable {
        _phantom_t: PhantomData,
        error: error,
    }
}
<commit_msg>Note that rx::error() is obsolete<commit_after>// Rx -- Reactive programming for Rust
// Copyright 2016 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

use observable::Observable;
use observer::Observer;
use std::marker::PhantomData;

/// An observable that produces an error when subscribed to.
pub struct ErrorObservable<T: Clone, E: Clone> {
    _phantom_t: PhantomData<T>,
    error: E,
}

impl<T: Clone, E: Clone> Observable for ErrorObservable<T, E> {
    type Item = T;
    type Error = E;
    type Subscription = super::UncancellableSubscription;

    fn subscribe<O>(&mut self, observer: O) -> Self::Subscription
        where O: Observer<Self::Item, Self::Error> {
        observer.on_error(self.error.clone());
        super::UncancellableSubscription
    }
}

/// Returns an observable that fails with the given error when subscribed to.
///
/// On its own an observable that always fails has limited use, but it can be
/// convenient when combining observables.
///
/// TODO: Add example once `continue_with` has been implemented.
/// TODO: Actually, `Err(error)` can already be used for this. This should be removed.
pub fn error<T: Clone, E: Clone>(error: E) -> ErrorObservable<T, E> {
    ErrorObservable {
        _phantom_t: PhantomData,
        error: error,
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The rust-glib authors.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod extra;
extern mod rustc;
extern mod rustpkg;

use extra::time;
use rustpkg::api;
use std::io;
use std::os;
use std::run;
use std::str;
use std::util;
use std::vec;

fn cd(path: &Path) {
    if !os::change_dir(path) {
        fail2!("Package script error: Failed to `cd` into `{}`", path.to_str());
    }
}

fn do_install(args: ~[~str]) {
    let sysroot_arg = args[1].clone();
    let sysroot_path = Path(sysroot_arg);

    let glib_libs = match os::getenv("GLIB_LIBS") {
        None => {
            let pkg_config_output = run::process_output("pkg-config", [~"--libs", ~"glib-2.0"]);
            if pkg_config_output.status != 0 {
                fail!("Package script error: `pkg-config --libs glib-2.0` failed");
            }
            let output_ptr = vec::raw::to_ptr(pkg_config_output.output);
            let output_len = pkg_config_output.output.len();
            let libs_str = unsafe { str::raw::from_buf_len(output_ptr, output_len) };
            os::setenv("GLIB_LIBS", libs_str);
            libs_str
        },
        Some(glib_libs) => glib_libs
    };
    // `pkg-config` adds a newline to the end, which we need to trim away because newlines
    // in link_args cause build issues.
    let trimmed_glib_libs = glib_libs.trim();
    debug!("GLIB_LIBS=\"%s\"", trimmed_glib_libs);

    let workspace_path = os::getcwd();

    let src_path = workspace_path.push("src");
    let native_detail_src_path = src_path.push("glib").push("detail").push("native");
    let paths_to_substitute = [
        native_detail_src_path.push("error.rs.in"),
        native_detail_src_path.push("mem.rs.in"),
        native_detail_src_path.push("strfuncs.rs.in"),
        native_detail_src_path.push("string.rs.in")
    ];
    for path_to_substitute in paths_to_substitute.iter() {
        if !os::path_exists(path_to_substitute) {
            fail2!("Package script error: Source file `{}` does not exist.", path_to_substitute.to_str());
        }
        match path_to_substitute.filestem() {
            None => fail2!("Package script error: `{}` is a directory.", path_to_substitute.to_str()),
            Some(filestem) => {
                let output_path = path_to_substitute.with_filename(filestem);
                let r = match io::file_reader(path_to_substitute) {
                    Err(err_str) => fail2!("Package script error: Failed to open `{}` for reading: {}", path_to_substitute.to_str(), err_str),
                    Ok(r) => r
                };
                let w = match io::file_writer(&output_path, [io::Create]) {
                    Err(err_str) => fail2!("Package script error: Failed to open `{}` for writing: {}", output_path.to_str(), err_str),
                    Ok(w) => w
                };
                w.write_line("// -*- buffer-read-only: t -*-");
                w.write_line("// Generated by " + args[0] + " on " + time::now().rfc822());
                w.write_char('\n');

                do r.each_line |line| -> bool {
                    let substituted_line = str::replace(line, "@GLIB_LIBS@", trimmed_glib_libs);
                    w.write_line(substituted_line);
                    true
                };
            }
        }
    }

    api::build_lib(sysroot_path, workspace_path, ~"glib", rustpkg::version::ExactRevision(~"0.1"), Path("mod.rs"));
}

fn do_configs(args: ~[~str]) {
    util::ignore(args);
}

fn main() {
    let args = os::args();
    let args_len = args.len();

    if args_len < 2 {
        fail!("Package script requires a directory where rustc libraries live as the first argument");
    } else if args_len < 3 {
        fail!("Package script requires a command as the second argument");
    }

    if args[2] == ~"install" {
        do_install(args);
    } else if args[2] == ~"configs" {
        do_configs(args);
    } else {
        fail2!("Package script error: Unsupported command `{}`", args[2]);
    }
}
<commit_msg>Use the Truncate flag when outputting files<commit_after>// Copyright 2013 The rust-glib authors.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod extra;
extern mod rustc;
extern mod rustpkg;

use extra::time;
use rustpkg::api;
use std::io;
use std::os;
use std::run;
use std::str;
use std::util;
use std::vec;

fn cd(path: &Path) {
    if !os::change_dir(path) {
        fail2!("Package script error: Failed to `cd` into `{}`", path.to_str());
    }
}

fn do_install(args: ~[~str]) {
    let sysroot_arg = args[1].clone();
    let sysroot_path = Path(sysroot_arg);

    let glib_libs = match os::getenv("GLIB_LIBS") {
        None => {
            let pkg_config_output = run::process_output("pkg-config", [~"--libs", ~"glib-2.0"]);
            if pkg_config_output.status != 0 {
                fail!("Package script error: `pkg-config --libs glib-2.0` failed");
            }
            let output_ptr = vec::raw::to_ptr(pkg_config_output.output);
            let output_len = pkg_config_output.output.len();
            let libs_str = unsafe { str::raw::from_buf_len(output_ptr, output_len) };
            os::setenv("GLIB_LIBS", libs_str);
            libs_str
        },
        Some(glib_libs) => glib_libs
    };
    // `pkg-config` adds a newline to the end, which we need to trim away because newlines
    // in link_args cause build issues.
    let trimmed_glib_libs = glib_libs.trim();
    debug!("GLIB_LIBS=\"%s\"", trimmed_glib_libs);

    let workspace_path = os::getcwd();

    let src_path = workspace_path.push("src");
    let native_detail_src_path = src_path.push("glib").push("detail").push("native");
    let paths_to_substitute = [
        native_detail_src_path.push("error.rs.in"),
        native_detail_src_path.push("mem.rs.in"),
        native_detail_src_path.push("strfuncs.rs.in"),
        native_detail_src_path.push("string.rs.in")
    ];
    for path_to_substitute in paths_to_substitute.iter() {
        if !os::path_exists(path_to_substitute) {
            fail2!("Package script error: Source file `{}` does not exist.", path_to_substitute.to_str());
        }
        match path_to_substitute.filestem() {
            None => fail2!("Package script error: `{}` is a directory.", path_to_substitute.to_str()),
            Some(filestem) => {
                let output_path = path_to_substitute.with_filename(filestem);
                let r = match io::file_reader(path_to_substitute) {
                    Err(err_str) => fail2!("Package script error: Failed to open `{}` for reading: {}", path_to_substitute.to_str(), err_str),
                    Ok(r) => r
                };
                let w = match io::file_writer(&output_path, [io::Create, io::Truncate]) {
                    Err(err_str) => fail2!("Package script error: Failed to open `{}` for writing: {}", output_path.to_str(), err_str),
                    Ok(w) => w
                };
                w.write_line("// -*- buffer-read-only: t -*-");
                w.write_line("// Generated by " + args[0] + " on " + time::now().rfc822());
                w.write_char('\n');

                do r.each_line |line| -> bool {
                    let substituted_line = str::replace(line, "@GLIB_LIBS@", trimmed_glib_libs);
                    w.write_line(substituted_line);
                    true
                };
            }
        }
    }

    api::build_lib(sysroot_path, workspace_path, ~"glib", rustpkg::version::ExactRevision(~"0.1"), Path("mod.rs"));
}

fn do_configs(args: ~[~str]) {
    util::ignore(args);
}

fn main() {
    let args = os::args();
    let args_len = args.len();

    if args_len < 2 {
        fail!("Package script requires a directory where rustc libraries live as the first argument");
    } else if args_len < 3 {
        fail!("Package script requires a command as the second argument");
    }

    if args[2] == ~"install" {
        do_install(args);
    } else if args[2] == ~"configs" {
        do_configs(args);
    } else {
        fail2!("Package script error: Unsupported command `{}`", args[2]);
    }
}
<|endoftext|>


<commit_before>use card;
use std::fmt;

mod tests;

pub struct Hand {
    pub cards: Vec<card::Card>
}

impl Hand {
    pub fn new(cards: Vec<card::Card>) -> Hand {
        Hand {
            cards: cards
        }
    }
}

impl fmt::Display for Hand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}{}{}{}", self.cards.get(0).unwrap(),
                                self.cards.get(1).unwrap(),
                                self.cards.get(2).unwrap(),
                                self.cards.get(3).unwrap(),
                                self.cards.get(4).unwrap())
    }
}

#[derive(Debug, PartialEq)]
pub enum PokerHand {
    HighCard      = 0,
    OnePair       = 1,
    TwoPair       = 2,
    Trips         = 3,
    Straight      = 4,
    Flush         = 5,
    FullHouse     = 6,
    Quads         = 7,
    StraightFlush = 8,
}
<commit_msg>Added spaces in Hand Display output<commit_after>use card;
use std::fmt;

mod tests;

pub struct Hand {
    pub cards: Vec<card::Card>
}

impl Hand {
    pub fn new(cards: Vec<card::Card>) -> Hand {
        Hand {
            cards: cards
        }
    }
}

impl fmt::Display for Hand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {} {} {} {}", self.cards.get(0).unwrap(),
                                    self.cards.get(1).unwrap(),
                                    self.cards.get(2).unwrap(),
                                    self.cards.get(3).unwrap(),
                                    self.cards.get(4).unwrap())
    }
}

#[derive(Debug, PartialEq)]
pub enum PokerHand {
    HighCard      = 0,
    OnePair       = 1,
    TwoPair       = 2,
    Trips         = 3,
    Straight      = 4,
    Flush         = 5,
    FullHouse     = 6,
    Quads         = 7,
    StraightFlush = 8,
}
<|endoftext|>


<commit_before>//! The module implements the client side of the HTTP/2 protocol and exposes
//! an API for using it.
use std::io;

pub mod frame;
pub mod transport;
pub mod connection;

/// An alias for the type that represents the ID of an HTTP/2 stream
pub type StreamId = u32;

/// An enum representing errors that can arise when performing operations
/// involving an HTTP/2 connection.
pub enum HttpError {
    IoError(io::Error),
    UnknownFrameType,
    InvalidFrame,
}

/// A convenience `Result` type that has the `HttpError` type as the error
/// type and a generic Ok result type.
pub type HttpResult<T> = Result<T, HttpError>;
<commit_msg>Add the Header typedef<commit_after>//! The module implements the client side of the HTTP/2 protocol and exposes
//! an API for using it.
use std::io;

pub mod frame;
pub mod transport;
pub mod connection;

/// An alias for the type that represents the ID of an HTTP/2 stream
pub type StreamId = u32;
/// An alias for the type that represents HTTP/2 haders. For now we only alias
/// the tuple of byte vectors instead of going with a full struct representation.
pub type Header = (Vec<u8>, Vec<u8>);

/// An enum representing errors that can arise when performing operations
/// involving an HTTP/2 connection.
pub enum HttpError {
    IoError(io::Error),
    UnknownFrameType,
    InvalidFrame,
}

/// A convenience `Result` type that has the `HttpError` type as the error
/// type and a generic Ok result type.
pub type HttpResult<T> = Result<T, HttpError>;
<|endoftext|>