<commit_before>#[doc = "Operations and constants for `float`"];

// Even though this module exports everything defined in it,
// because it contains re-exports, we also have to explicitly
// export locally defined things. That's a bit annoying.
export to_str_common, to_str_exact, to_str, from_str;
export add, sub, mul, div, rem, lt, le, gt, eq, eq, ne;
export is_positive, is_negative, is_nonpositive, is_nonnegative;
export is_zero, is_infinite, is_finite;
export NaN, is_NaN, infinity, neg_infinity;
export consts;
export logarithm;
export acos, asin, atan, atan2, cbrt, ceil, copysign, cos, cosh, floor;
export erf, erfc, exp, expm1, exp2, abs, abs_sub;
export mul_add, fmax, fmin, nextafter, frexp, hypot, ldexp;
export lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix;
export modf, pow, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc;
export signbit;
export pow_with_uint;

// export when m_float == c_double

export j0, j1, jn, y0, y1, yn;

// PORT this must match in width according to architecture

import m_float = f64;
import f64::*;

/**
 * Section: String Conversions
 */

#[doc = "
Converts a float to a string

# Arguments

* num - The float value
* digits - The number of significant digits
* exact - Whether to enforce the exact number of significant digits
"]
fn to_str_common(num: float, digits: uint, exact: bool) -> str {
    if is_NaN(num) { ret "NaN"; }
    let mut (num, accum) = if num < 0.0 { (-num, "-") } else { (num, "") };
    let trunc = num as uint;
    let mut frac = num - (trunc as float);
    accum += uint::str(trunc);
    if (frac < epsilon && !exact) || digits == 0u { ret accum; }
    accum += ".";
    let mut i = digits;
    let mut epsilon = 1. / pow_with_uint(10u, i);
    while i > 0u && (frac >= epsilon || exact) {
        frac *= 10.0;
        epsilon *= 10.0;
        let digit = frac as uint;
        accum += uint::str(digit);
        frac -= digit as float;
        i -= 1u;
    }
    ret accum;

}

#[doc = "
Converts a float to a string with exactly the number of
provided significant digits

# Arguments

* num - The float value
* digits - The number of significant digits
"]
fn to_str_exact(num: float, digits: uint) -> str {
    to_str_common(num, digits, true)
}

#[test]
fn test_to_str_exact_do_decimal() {
    let s = to_str_exact(5.0, 4u);
    assert s == "5.0000";
}

#[doc = "
Converts a float to a string with a maximum number of
significant digits

# Arguments

* num - The float value
* digits - The number of significant digits
"]
fn to_str(num: float, digits: uint) -> str {
    to_str_common(num, digits, false)
}

#[doc = "
Convert a string to a float

This function accepts strings such as

* '3.14'
* '+3.14', equivalent to '3.14'
* '-3.14'
* '2.5E10', or equivalently, '2.5e10'
* '2.5E-10'
* '', or, equivalently, '.' (understood as 0)
* '5.'
* '.5', or, equivalently,  '0.5'

Leading and trailing whitespace are ignored.

# Arguments

* num - A string

# Return value

`none` if the string did not represent a valid number.  Otherwise, `some(n)`
where `n` is the floating-point number represented by `[num]`.
"]
fn from_str(num: str) -> option<float> {
   let mut pos = 0u;               //Current byte position in the string.
                                   //Used to walk the string in O(n).
   let len = str::len(num);        //Length of the string, in bytes.

   if len == 0u { ret none; }
   let mut total = 0f;             //Accumulated result
   let mut c     = 'z';            //Latest char.

   //The string must start with one of the following characters.
   alt str::char_at(num, 0u) {
      '-' | '+' | '0' to '9' | '.' {}
      _ { ret none; }
   }

   //Determine if first char is '-'/'+'. Set [pos] and [neg] accordingly.
   let mut neg = false;               //Sign of the result
   alt str::char_at(num, 0u) {
      '-' {
          neg = true;
          pos = 1u;
      }
      '+' {
          pos = 1u;
      }
      _ {}
   }

   //Examine the following chars until '.', 'e', 'E'
   while(pos < len) {
       let char_range = str::char_range_at(num, pos);
       c   = char_range.ch;
       pos = char_range.next;
       alt c {
         '0' to '9' {
           total = total * 10f;
           total += ((c as int) - ('0' as int)) as float;
         }
         '.' | 'e' | 'E' {
           break;
         }
         _ {
           ret none;
         }
       }
   }

   if c == '.' {//Examine decimal part
      let mut decimal = 1f;
      while(pos < len) {
         let char_range = str::char_range_at(num, pos);
         c = char_range.ch;
         pos = char_range.next;
         alt c {
            '0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9'  {
                 decimal /= 10f;
                 total += (((c as int) - ('0' as int)) as float)*decimal;
             }
             'e' | 'E' {
                 break;
             }
             _ {
                 ret none;
             }
         }
      }
   }

   if (c == 'e') | (c == 'E') {//Examine exponent
      let mut exponent = 0u;
      let mut neg_exponent = false;
      if(pos < len) {
          let char_range = str::char_range_at(num, pos);
          c   = char_range.ch;
          alt c  {
             '+' {
                pos = char_range.next;
             }
             '-' {
                pos = char_range.next;
                neg_exponent = true;
             }
             _ {}
          }
          while(pos < len) {
             let char_range = str::char_range_at(num, pos);
             c = char_range.ch;
             alt c {
                 '0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9' {
                     exponent *= 10u;
                     exponent += ((c as uint) - ('0' as uint));
                 }
                 _ {
                     break;
                 }
             }
             pos = char_range.next;
          }
          let multiplier = pow_with_uint(10u, exponent);
              //Note: not [int::pow], otherwise, we'll quickly
              //end up with a nice overflow
          if neg_exponent {
             total = total / multiplier;
          } else {
             total = total * multiplier;
          }
      } else {
         ret none;
      }
   }

   if(pos < len) {
     ret none;
   } else {
     if(neg) {
        total *= -1f;
     }
     ret some(total);
   }
}

/**
 * Section: Arithmetics
 */

#[doc = "
Compute the exponentiation of an integer by another integer as a float

# Arguments

* x - The base
* pow - The exponent

# Return value

`NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
"]
fn pow_with_uint(base: uint, pow: uint) -> float {
   if base == 0u {
      if pow == 0u {
        ret NaN;
      }
       ret 0.;
   }
   let mut my_pow     = pow;
   let mut total      = 1f;
   let mut multiplier = base as float;
   while (my_pow > 0u) {
     if my_pow % 2u == 1u {
       total = total * multiplier;
     }
     my_pow     /= 2u;
     multiplier *= multiplier;
   }
   ret total;
}

#[test]
fn test_from_str() {
   assert from_str("3") == some(3.);
   assert from_str("3") == some(3.);
   assert from_str("3.14") == some(3.14);
   assert from_str("+3.14") == some(3.14);
   assert from_str("-3.14") == some(-3.14);
   assert from_str("2.5E10") == some(25000000000.);
   assert from_str("2.5e10") == some(25000000000.);
   assert from_str("25000000000.E-10") == some(2.5);
   assert from_str(".") == some(0.);
   assert from_str(".e1") == some(0.);
   assert from_str(".e-1") == some(0.);
   assert from_str("5.") == some(5.);
   assert from_str(".5") == some(0.5);
   assert from_str("0.5") == some(0.5);
   assert from_str("0.5") == some(0.5);
   assert from_str("0.5") == some(0.5);
   assert from_str("-.5") == some(-0.5);
   assert from_str("-.5") == some(-0.5);
   assert from_str("-5") == some(-5.);

   assert from_str("") == none;
   assert from_str("x") == none;
   assert from_str(" ") == none;
   assert from_str("   ") == none;
   assert from_str("e") == none;
   assert from_str("E") == none;
   assert from_str("E1") == none;
   assert from_str("1e1e1") == none;
   assert from_str("1e1.1") == none;
   assert from_str("1e1-1") == none;
}

#[test]
fn test_positive() {
  assert(is_positive(infinity));
  assert(is_positive(1.));
  assert(is_positive(0.));
  assert(!is_positive(-1.));
  assert(!is_positive(neg_infinity));
  assert(!is_positive(1./neg_infinity));
  assert(!is_positive(NaN));
}

#[test]
fn test_negative() {
  assert(!is_negative(infinity));
  assert(!is_negative(1.));
  assert(!is_negative(0.));
  assert(is_negative(-1.));
  assert(is_negative(neg_infinity));
  assert(is_negative(1./neg_infinity));
  assert(!is_negative(NaN));
}

#[test]
fn test_nonpositive() {
  assert(!is_nonpositive(infinity));
  assert(!is_nonpositive(1.));
  assert(!is_nonpositive(0.));
  assert(is_nonpositive(-1.));
  assert(is_nonpositive(neg_infinity));
  assert(is_nonpositive(1./neg_infinity));
  assert(!is_nonpositive(NaN));
}

#[test]
fn test_nonnegative() {
  assert(is_nonnegative(infinity));
  assert(is_nonnegative(1.));
  assert(is_nonnegative(0.));
  assert(!is_nonnegative(-1.));
  assert(!is_nonnegative(neg_infinity));
  assert(!is_nonnegative(1./neg_infinity));
  assert(!is_nonnegative(NaN));
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//

<commit_msg>write out "inf"/"-inf" in float::to_str_common<commit_after>#[doc = "Operations and constants for `float`"];

// Even though this module exports everything defined in it,
// because it contains re-exports, we also have to explicitly
// export locally defined things. That's a bit annoying.
export to_str_common, to_str_exact, to_str, from_str;
export add, sub, mul, div, rem, lt, le, gt, eq, eq, ne;
export is_positive, is_negative, is_nonpositive, is_nonnegative;
export is_zero, is_infinite, is_finite;
export NaN, is_NaN, infinity, neg_infinity;
export consts;
export logarithm;
export acos, asin, atan, atan2, cbrt, ceil, copysign, cos, cosh, floor;
export erf, erfc, exp, expm1, exp2, abs, abs_sub;
export mul_add, fmax, fmin, nextafter, frexp, hypot, ldexp;
export lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix;
export modf, pow, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc;
export signbit;
export pow_with_uint;

// export when m_float == c_double

export j0, j1, jn, y0, y1, yn;

// PORT this must match in width according to architecture

import m_float = f64;
import f64::*;

/**
 * Section: String Conversions
 */

#[doc = "
Converts a float to a string

# Arguments

* num - The float value
* digits - The number of significant digits
* exact - Whether to enforce the exact number of significant digits
"]
fn to_str_common(num: float, digits: uint, exact: bool) -> str {
    if is_NaN(num) { ret "NaN"; }
    if num == infinity { ret "inf"; }
    if num == neg_infinity { ret "-inf"; }
    let mut (num, accum) = if num < 0.0 { (-num, "-") } else { (num, "") };
    let trunc = num as uint;
    let mut frac = num - (trunc as float);
    accum += uint::str(trunc);
    if (frac < epsilon && !exact) || digits == 0u { ret accum; }
    accum += ".";
    let mut i = digits;
    let mut epsilon = 1. / pow_with_uint(10u, i);
    while i > 0u && (frac >= epsilon || exact) {
        frac *= 10.0;
        epsilon *= 10.0;
        let digit = frac as uint;
        accum += uint::str(digit);
        frac -= digit as float;
        i -= 1u;
    }
    ret accum;

}

#[doc = "
Converts a float to a string with exactly the number of
provided significant digits

# Arguments

* num - The float value
* digits - The number of significant digits
"]
fn to_str_exact(num: float, digits: uint) -> str {
    to_str_common(num, digits, true)
}

#[test]
fn test_to_str_exact_do_decimal() {
    let s = to_str_exact(5.0, 4u);
    assert s == "5.0000";
}

#[doc = "
Converts a float to a string with a maximum number of
significant digits

# Arguments

* num - The float value
* digits - The number of significant digits
"]
fn to_str(num: float, digits: uint) -> str {
    to_str_common(num, digits, false)
}

#[doc = "
Convert a string to a float

This function accepts strings such as

* '3.14'
* '+3.14', equivalent to '3.14'
* '-3.14'
* '2.5E10', or equivalently, '2.5e10'
* '2.5E-10'
* '', or, equivalently, '.' (understood as 0)
* '5.'
* '.5', or, equivalently,  '0.5'

Leading and trailing whitespace are ignored.

# Arguments

* num - A string

# Return value

`none` if the string did not represent a valid number.  Otherwise, `some(n)`
where `n` is the floating-point number represented by `[num]`.
"]
fn from_str(num: str) -> option<float> {
   let mut pos = 0u;               //Current byte position in the string.
                                   //Used to walk the string in O(n).
   let len = str::len(num);        //Length of the string, in bytes.

   if len == 0u { ret none; }
   let mut total = 0f;             //Accumulated result
   let mut c     = 'z';            //Latest char.

   //The string must start with one of the following characters.
   alt str::char_at(num, 0u) {
      '-' | '+' | '0' to '9' | '.' {}
      _ { ret none; }
   }

   //Determine if first char is '-'/'+'. Set [pos] and [neg] accordingly.
   let mut neg = false;               //Sign of the result
   alt str::char_at(num, 0u) {
      '-' {
          neg = true;
          pos = 1u;
      }
      '+' {
          pos = 1u;
      }
      _ {}
   }

   //Examine the following chars until '.', 'e', 'E'
   while(pos < len) {
       let char_range = str::char_range_at(num, pos);
       c   = char_range.ch;
       pos = char_range.next;
       alt c {
         '0' to '9' {
           total = total * 10f;
           total += ((c as int) - ('0' as int)) as float;
         }
         '.' | 'e' | 'E' {
           break;
         }
         _ {
           ret none;
         }
       }
   }

   if c == '.' {//Examine decimal part
      let mut decimal = 1f;
      while(pos < len) {
         let char_range = str::char_range_at(num, pos);
         c = char_range.ch;
         pos = char_range.next;
         alt c {
            '0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9'  {
                 decimal /= 10f;
                 total += (((c as int) - ('0' as int)) as float)*decimal;
             }
             'e' | 'E' {
                 break;
             }
             _ {
                 ret none;
             }
         }
      }
   }

   if (c == 'e') | (c == 'E') {//Examine exponent
      let mut exponent = 0u;
      let mut neg_exponent = false;
      if(pos < len) {
          let char_range = str::char_range_at(num, pos);
          c   = char_range.ch;
          alt c  {
             '+' {
                pos = char_range.next;
             }
             '-' {
                pos = char_range.next;
                neg_exponent = true;
             }
             _ {}
          }
          while(pos < len) {
             let char_range = str::char_range_at(num, pos);
             c = char_range.ch;
             alt c {
                 '0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9' {
                     exponent *= 10u;
                     exponent += ((c as uint) - ('0' as uint));
                 }
                 _ {
                     break;
                 }
             }
             pos = char_range.next;
          }
          let multiplier = pow_with_uint(10u, exponent);
              //Note: not [int::pow], otherwise, we'll quickly
              //end up with a nice overflow
          if neg_exponent {
             total = total / multiplier;
          } else {
             total = total * multiplier;
          }
      } else {
         ret none;
      }
   }

   if(pos < len) {
     ret none;
   } else {
     if(neg) {
        total *= -1f;
     }
     ret some(total);
   }
}

/**
 * Section: Arithmetics
 */

#[doc = "
Compute the exponentiation of an integer by another integer as a float

# Arguments

* x - The base
* pow - The exponent

# Return value

`NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
"]
fn pow_with_uint(base: uint, pow: uint) -> float {
   if base == 0u {
      if pow == 0u {
        ret NaN;
      }
       ret 0.;
   }
   let mut my_pow     = pow;
   let mut total      = 1f;
   let mut multiplier = base as float;
   while (my_pow > 0u) {
     if my_pow % 2u == 1u {
       total = total * multiplier;
     }
     my_pow     /= 2u;
     multiplier *= multiplier;
   }
   ret total;
}

#[test]
fn test_from_str() {
   assert from_str("3") == some(3.);
   assert from_str("3") == some(3.);
   assert from_str("3.14") == some(3.14);
   assert from_str("+3.14") == some(3.14);
   assert from_str("-3.14") == some(-3.14);
   assert from_str("2.5E10") == some(25000000000.);
   assert from_str("2.5e10") == some(25000000000.);
   assert from_str("25000000000.E-10") == some(2.5);
   assert from_str(".") == some(0.);
   assert from_str(".e1") == some(0.);
   assert from_str(".e-1") == some(0.);
   assert from_str("5.") == some(5.);
   assert from_str(".5") == some(0.5);
   assert from_str("0.5") == some(0.5);
   assert from_str("0.5") == some(0.5);
   assert from_str("0.5") == some(0.5);
   assert from_str("-.5") == some(-0.5);
   assert from_str("-.5") == some(-0.5);
   assert from_str("-5") == some(-5.);

   assert from_str("") == none;
   assert from_str("x") == none;
   assert from_str(" ") == none;
   assert from_str("   ") == none;
   assert from_str("e") == none;
   assert from_str("E") == none;
   assert from_str("E1") == none;
   assert from_str("1e1e1") == none;
   assert from_str("1e1.1") == none;
   assert from_str("1e1-1") == none;
}

#[test]
fn test_positive() {
  assert(is_positive(infinity));
  assert(is_positive(1.));
  assert(is_positive(0.));
  assert(!is_positive(-1.));
  assert(!is_positive(neg_infinity));
  assert(!is_positive(1./neg_infinity));
  assert(!is_positive(NaN));
}

#[test]
fn test_negative() {
  assert(!is_negative(infinity));
  assert(!is_negative(1.));
  assert(!is_negative(0.));
  assert(is_negative(-1.));
  assert(is_negative(neg_infinity));
  assert(is_negative(1./neg_infinity));
  assert(!is_negative(NaN));
}

#[test]
fn test_nonpositive() {
  assert(!is_nonpositive(infinity));
  assert(!is_nonpositive(1.));
  assert(!is_nonpositive(0.));
  assert(is_nonpositive(-1.));
  assert(is_nonpositive(neg_infinity));
  assert(is_nonpositive(1./neg_infinity));
  assert(!is_nonpositive(NaN));
}

#[test]
fn test_nonnegative() {
  assert(is_nonnegative(infinity));
  assert(is_nonnegative(1.));
  assert(is_nonnegative(0.));
  assert(!is_nonnegative(-1.));
  assert(!is_nonnegative(neg_infinity));
  assert(!is_nonnegative(1./neg_infinity));
  assert(!is_nonnegative(NaN));
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//

<|endoftext|>


<commit_before><commit_msg>genet-abi: remove ExecType::SerialAsync<commit_after><|endoftext|>


<commit_before><commit_msg>Initial commit for find.rs<commit_after><|endoftext|>


<commit_before><commit_msg>:art: Make it possible to use Attachment and Basic format<commit_after><|endoftext|>


<commit_before>// Copyright 2018 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::{self, ImplPolarity};
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc::ty::{self, Slice, TyCtxt};
use rustc::ty::subst::Substs;
use rustc::traits::{WhereClauseAtom, PolyDomainGoal, DomainGoal, ProgramClause, Clause, Goal};
use syntax::ast;
use rustc_data_structures::sync::Lrc;

use std::iter;

trait Lower<T> {
    /// Lower a rustc construction (e.g. `ty::TraitPredicate`) to a chalk-like type.
    fn lower(&self) -> T;
}

impl<T, U> Lower<Vec<U>> for Vec<T> where T: Lower<U> {
    fn lower(&self) -> Vec<U> {
        self.iter().map(|item| item.lower()).collect()
    }
}

impl<'tcx> Lower<WhereClauseAtom<'tcx>> for ty::TraitPredicate<'tcx> {
    fn lower(&self) -> WhereClauseAtom<'tcx> {
        WhereClauseAtom::Implemented(*self)
    }
}

impl<'tcx> Lower<WhereClauseAtom<'tcx>> for ty::ProjectionPredicate<'tcx> {
    fn lower(&self) -> WhereClauseAtom<'tcx> {
        WhereClauseAtom::ProjectionEq(*self)
    }
}

impl<'tcx, T> Lower<DomainGoal<'tcx>> for T where T: Lower<WhereClauseAtom<'tcx>> {
    fn lower(&self) -> DomainGoal<'tcx> {
        DomainGoal::Holds(self.lower())
    }
}

impl<'tcx> Lower<DomainGoal<'tcx>> for ty::RegionOutlivesPredicate<'tcx> {
    fn lower(&self) -> DomainGoal<'tcx> {
        DomainGoal::RegionOutlives(*self)
    }
}

impl<'tcx> Lower<DomainGoal<'tcx>> for ty::TypeOutlivesPredicate<'tcx> {
    fn lower(&self) -> DomainGoal<'tcx> {
        DomainGoal::TypeOutlives(*self)
    }
}

/// `ty::Binder` is used for wrapping a rustc construction possibly containing generic
/// lifetimes, e.g. `for<'a> T: Fn(&'a i32)`. Instead of representing higher-ranked things
/// in that leaf-form (i.e. `Holds(Implemented(Binder<TraitPredicate>))` in the previous
/// example), we model them with quantified domain goals, e.g. as for the previous example:
/// `forall<'a> { T: Fn(&'a i32) }` which corresponds to something like
/// `Binder<Holds(Implemented(TraitPredicate))>`.
impl<'tcx, T> Lower<PolyDomainGoal<'tcx>> for ty::Binder<T>
    where T: Lower<DomainGoal<'tcx>> + ty::fold::TypeFoldable<'tcx>
{
    fn lower(&self) -> PolyDomainGoal<'tcx> {
        self.map_bound_ref(|p| p.lower())
    }
}

impl<'tcx> Lower<PolyDomainGoal<'tcx>> for ty::Predicate<'tcx> {
    fn lower(&self) -> PolyDomainGoal<'tcx> {
        use rustc::ty::Predicate::*;

        match self {
            Trait(predicate) => predicate.lower(),
            RegionOutlives(predicate) => predicate.lower(),
            TypeOutlives(predicate) => predicate.lower(),
            Projection(predicate) => predicate.lower(),
            WellFormed(ty) => ty::Binder::dummy(DomainGoal::WellFormedTy(*ty)),
            ObjectSafe(..) |
            ClosureKind(..) |
            Subtype(..) |
            ConstEvaluatable(..) => unimplemented!(),
        }
    }
}

/// Transforms an existing goal into a FromEnv goal.
///
/// Used for lowered where clauses (see rustc guide).
trait IntoFromEnvGoal {
    fn into_from_env_goal(self) -> Self;
}

impl<'tcx> IntoFromEnvGoal for DomainGoal<'tcx> {
    fn into_from_env_goal(self) -> DomainGoal<'tcx> {
        use self::DomainGoal::*;
        match self {
            Holds(wc_atom) => FromEnv(wc_atom),
            WellFormed(..) |
            FromEnv(..) |
            WellFormedTy(..) |
            FromEnvTy(..) |
            RegionOutlives(..) |
            TypeOutlives(..) => self,
        }
    }
}

crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                       -> Lrc<&'tcx Slice<Clause<'tcx>>>
{
    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
    let node = tcx.hir.find(node_id).unwrap();
    match node {
        hir::map::Node::NodeItem(item) => match item.node {
            hir::ItemTrait(..) => program_clauses_for_trait(tcx, def_id),
            hir::ItemImpl(..) => program_clauses_for_impl(tcx, def_id),
            _ => Lrc::new(vec![]),
        }
        hir::map::Node::NodeImplItem(item) => {
            if let hir::ImplItemKind::Type(..) = item.node {
                program_clauses_for_associated_type(tcx, def_id)
            } else {
                Lrc::new(vec![])
            }
        },

        // FIXME: other constructions e.g. traits, associated types...
        _ => Lrc::new(tcx.mk_clauses(iter::empty::<Clause>())),
    }
}

fn program_clauses_for_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                       -> Lrc<&'tcx Slice<Clause<'tcx>>>
{
    // `trait Trait<P1..Pn> where WC { .. } // P0 == Self`

    // Rule Implemented-From-Env (see rustc guide)
    //
    // ```
    // forall<Self, P1..Pn> {
    //   Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)
    // }
    // ```

    // `Self: Trait<P1..Pn>`
    let trait_pred = ty::TraitPredicate {
        trait_ref: ty::TraitRef {
            def_id,
            substs: Substs::identity_for_item(tcx, def_id)
        }
    };
    // `FromEnv(Self: Trait<P1..Pn>)`
    let from_env = Goal::from(DomainGoal::FromEnv(trait_pred.lower()));
    // `Implemented(Self: Trait<P1..Pn>)`
    let impl_trait = DomainGoal::Holds(WhereClauseAtom::Implemented(trait_pred));

    // `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
    let implemented_from_env = ProgramClause {
        goal: impl_trait,
        hypotheses: tcx.mk_goals(iter::once(from_env)),
    };
    let clauses = iter::once(
        Clause::ForAll(ty::Binder::dummy(implemented_from_env))
    );

    // Rule Implied-Bound-From-Trait
    //
    // For each where clause WC:
    // ```
    // forall<Self, P1..Pn> {
    //   FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn)
    // }
    // ```

    // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`, for each where clause WC
    // FIXME: Remove the [1..] slice; this is a hack because the query
    // predicates_of currently includes the trait itself (`Self: Trait<P1..Pn>`).
    let where_clauses = &tcx.predicates_of(def_id).predicates;
    let implied_bound_clauses =
        where_clauses[1..].into_iter()
        .map(|wc| implied_bound_from_trait(tcx, trait_pred, wc));

    Lrc::new(tcx.mk_clauses(clauses.chain(implied_bound_clauses)))
}

/// For a given `where_clause`, returns a clause `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`.
fn implied_bound_from_trait<'a, 'tcx>(
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    trait_pred: ty::TraitPredicate<'tcx>,
    where_clause: &ty::Predicate<'tcx>,
) -> Clause<'tcx> {
    // `FromEnv(Self: Trait<P1..Pn>)`
    let impl_trait = DomainGoal::FromEnv(WhereClauseAtom::Implemented(trait_pred));

    // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`
    Clause::ForAll(
        where_clause.lower().map_bound(|goal| ProgramClause {
            goal: goal.into_from_env_goal(),
            hypotheses: tcx.mk_goals(iter::once(Goal::from(impl_trait))),
        })
    )
}

fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                      -> Lrc<&'tcx Slice<Clause<'tcx>>>
{
    if let ImplPolarity::Negative = tcx.impl_polarity(def_id) {
        return Lrc::new(tcx.mk_clauses(iter::empty::<Clause>()));
    }

    // Rule Implemented-From-Impl (see rustc guide)
    //
    // `impl<P0..Pn> Trait<A1..An> for A0 where WC { .. }`
    //
    // ```
    // forall<P0..Pn> {
    //   Implemented(A0: Trait<A1..An>) :- WC
    // }
    // ```

    let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
    // `Implemented(A0: Trait<A1..An>)`
    let trait_pred = ty::TraitPredicate { trait_ref }.lower();
     // `WC`
    let where_clauses = tcx.predicates_of(def_id).predicates.lower();

     // `Implemented(A0: Trait<A1..An>) :- WC`
    let clause = ProgramClause {
        goal: trait_pred,
        hypotheses: tcx.mk_goals(
            where_clauses.into_iter().map(|wc| Goal::from_poly_domain_goal(wc, tcx))
        )
    };
    Lrc::new(tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause)))))
}

pub fn program_clauses_for_associated_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: DefId)
    -> Lrc<Vec<Clause<'tcx>>> {
    // Rule Normalize-From-Impl (see rustc guide)
    //
    // ```impl<P0..Pn> Trait<A1..An> for A0
    // where WC
    // {
    //     type AssocType<Pn+1..Pm> where WC1 = T;
    // }```
    //
    // ```
    // forall<P0..Pm> {
    //   forall<Pn+1..Pm> {
    //     Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T) :-
    //       WC && WC1
    //   }
    // }
    // ```

    let item = tcx.associated_item(item_id);
    debug_assert_eq!(item.kind, ty::AssociatedKind::Type);
    let impl_id = if let ty::AssociatedItemContainer::ImplContainer(impl_id) = item.container {
        impl_id
    } else {
        bug!()
    };
    // `A0 as Trait<A1..An>`
    let trait_ref = tcx.impl_trait_ref(impl_id).unwrap();
    // `T`
    let ty = tcx.type_of(item_id);
    // `WC`
    let impl_where_clauses = tcx.predicates_of(impl_id).predicates.lower();
    // `WC1`
    let item_where_clauses = tcx.predicates_of(item_id).predicates.lower();
    // `WC && WC1`
    let mut where_clauses = vec![];
    where_clauses.extend(impl_where_clauses);
    where_clauses.extend(item_where_clauses);
    // `<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm>`
    let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.name);
    // `Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T)`
    let normalize_goal = DomainGoal::Normalize(ty::ProjectionPredicate { projection_ty, ty });
    // `Normalize(... -> T) :- WC && WC1`
    let clause = Clause::Implies(where_clauses, normalize_goal);
    Lrc::new(vec![clause])
}

pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
    if !tcx.features().rustc_attrs {
        return;
    }

    let mut visitor = ClauseDumper { tcx };
    tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
}

struct ClauseDumper<'a, 'tcx: 'a> {
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
}

impl<'a, 'tcx> ClauseDumper<'a, 'tcx > {
    fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) {
        let def_id = self.tcx.hir.local_def_id(node_id);
        for attr in attrs {
            if attr.check_name("rustc_dump_program_clauses") {
                let clauses = self.tcx.program_clauses_for(def_id);
                for clause in *clauses {
                    // Skip the top-level binder for a less verbose output
                    let program_clause = match clause {
                        Clause::Implies(program_clause) => program_clause,
                        Clause::ForAll(program_clause) => program_clause.skip_binder(),
                    };
                    self.tcx.sess.struct_span_err(attr.span, &format!("{}", program_clause)).emit();
                }
            }
        }
    }
}

impl<'a, 'tcx> Visitor<'tcx> for ClauseDumper<'a, 'tcx> {
    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
    }

    fn visit_item(&mut self, item: &'tcx hir::Item) {
        self.process_attrs(item.id, &item.attrs);
        intravisit::walk_item(self, item);
    }

    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
        self.process_attrs(trait_item.id, &trait_item.attrs);
        intravisit::walk_trait_item(self, trait_item);
    }

    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
        self.process_attrs(impl_item.id, &impl_item.attrs);
        intravisit::walk_impl_item(self, impl_item);
    }

    fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
        self.process_attrs(s.id, &s.attrs);
        intravisit::walk_struct_field(self, s);
    }
}
<commit_msg>Improve function name.<commit_after>// Copyright 2018 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::{self, ImplPolarity};
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc::ty::{self, Slice, TyCtxt};
use rustc::ty::subst::Substs;
use rustc::traits::{WhereClauseAtom, PolyDomainGoal, DomainGoal, ProgramClause, Clause, Goal};
use syntax::ast;
use rustc_data_structures::sync::Lrc;

use std::iter;

trait Lower<T> {
    /// Lower a rustc construction (e.g. `ty::TraitPredicate`) to a chalk-like type.
    fn lower(&self) -> T;
}

impl<T, U> Lower<Vec<U>> for Vec<T> where T: Lower<U> {
    fn lower(&self) -> Vec<U> {
        self.iter().map(|item| item.lower()).collect()
    }
}

impl<'tcx> Lower<WhereClauseAtom<'tcx>> for ty::TraitPredicate<'tcx> {
    fn lower(&self) -> WhereClauseAtom<'tcx> {
        WhereClauseAtom::Implemented(*self)
    }
}

impl<'tcx> Lower<WhereClauseAtom<'tcx>> for ty::ProjectionPredicate<'tcx> {
    fn lower(&self) -> WhereClauseAtom<'tcx> {
        WhereClauseAtom::ProjectionEq(*self)
    }
}

impl<'tcx, T> Lower<DomainGoal<'tcx>> for T where T: Lower<WhereClauseAtom<'tcx>> {
    fn lower(&self) -> DomainGoal<'tcx> {
        DomainGoal::Holds(self.lower())
    }
}

impl<'tcx> Lower<DomainGoal<'tcx>> for ty::RegionOutlivesPredicate<'tcx> {
    fn lower(&self) -> DomainGoal<'tcx> {
        DomainGoal::RegionOutlives(*self)
    }
}

impl<'tcx> Lower<DomainGoal<'tcx>> for ty::TypeOutlivesPredicate<'tcx> {
    fn lower(&self) -> DomainGoal<'tcx> {
        DomainGoal::TypeOutlives(*self)
    }
}

/// `ty::Binder` is used for wrapping a rustc construction possibly containing generic
/// lifetimes, e.g. `for<'a> T: Fn(&'a i32)`. Instead of representing higher-ranked things
/// in that leaf-form (i.e. `Holds(Implemented(Binder<TraitPredicate>))` in the previous
/// example), we model them with quantified domain goals, e.g. as for the previous example:
/// `forall<'a> { T: Fn(&'a i32) }` which corresponds to something like
/// `Binder<Holds(Implemented(TraitPredicate))>`.
impl<'tcx, T> Lower<PolyDomainGoal<'tcx>> for ty::Binder<T>
    where T: Lower<DomainGoal<'tcx>> + ty::fold::TypeFoldable<'tcx>
{
    fn lower(&self) -> PolyDomainGoal<'tcx> {
        self.map_bound_ref(|p| p.lower())
    }
}

impl<'tcx> Lower<PolyDomainGoal<'tcx>> for ty::Predicate<'tcx> {
    fn lower(&self) -> PolyDomainGoal<'tcx> {
        use rustc::ty::Predicate::*;

        match self {
            Trait(predicate) => predicate.lower(),
            RegionOutlives(predicate) => predicate.lower(),
            TypeOutlives(predicate) => predicate.lower(),
            Projection(predicate) => predicate.lower(),
            WellFormed(ty) => ty::Binder::dummy(DomainGoal::WellFormedTy(*ty)),
            ObjectSafe(..) |
            ClosureKind(..) |
            Subtype(..) |
            ConstEvaluatable(..) => unimplemented!(),
        }
    }
}

/// Transforms an existing goal into a FromEnv goal.
///
/// Used for lowered where clauses (see rustc guide).
trait IntoFromEnvGoal {
    fn into_from_env_goal(self) -> Self;
}

impl<'tcx> IntoFromEnvGoal for DomainGoal<'tcx> {
    fn into_from_env_goal(self) -> DomainGoal<'tcx> {
        use self::DomainGoal::*;
        match self {
            Holds(wc_atom) => FromEnv(wc_atom),
            WellFormed(..) |
            FromEnv(..) |
            WellFormedTy(..) |
            FromEnvTy(..) |
            RegionOutlives(..) |
            TypeOutlives(..) => self,
        }
    }
}

crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                       -> Lrc<&'tcx Slice<Clause<'tcx>>>
{
    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
    let node = tcx.hir.find(node_id).unwrap();
    match node {
        hir::map::Node::NodeItem(item) => match item.node {
            hir::ItemTrait(..) => program_clauses_for_trait(tcx, def_id),
            hir::ItemImpl(..) => program_clauses_for_impl(tcx, def_id),
            _ => Lrc::new(vec![]),
        }
        hir::map::Node::NodeImplItem(item) => {
            if let hir::ImplItemKind::Type(..) = item.node {
                program_clauses_for_associated_type_value(tcx, def_id)
            } else {
                Lrc::new(vec![])
            }
        },

        // FIXME: other constructions e.g. traits, associated types...
        _ => Lrc::new(tcx.mk_clauses(iter::empty::<Clause>())),
    }
}

fn program_clauses_for_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                       -> Lrc<&'tcx Slice<Clause<'tcx>>>
{
    // `trait Trait<P1..Pn> where WC { .. } // P0 == Self`

    // Rule Implemented-From-Env (see rustc guide)
    //
    // ```
    // forall<Self, P1..Pn> {
    //   Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)
    // }
    // ```

    // `Self: Trait<P1..Pn>`
    let trait_pred = ty::TraitPredicate {
        trait_ref: ty::TraitRef {
            def_id,
            substs: Substs::identity_for_item(tcx, def_id)
        }
    };
    // `FromEnv(Self: Trait<P1..Pn>)`
    let from_env = Goal::from(DomainGoal::FromEnv(trait_pred.lower()));
    // `Implemented(Self: Trait<P1..Pn>)`
    let impl_trait = DomainGoal::Holds(WhereClauseAtom::Implemented(trait_pred));

    // `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
    let implemented_from_env = ProgramClause {
        goal: impl_trait,
        hypotheses: tcx.mk_goals(iter::once(from_env)),
    };
    let clauses = iter::once(
        Clause::ForAll(ty::Binder::dummy(implemented_from_env))
    );

    // Rule Implied-Bound-From-Trait
    //
    // For each where clause WC:
    // ```
    // forall<Self, P1..Pn> {
    //   FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn)
    // }
    // ```

    // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`, for each where clause WC
    // FIXME: Remove the [1..] slice; this is a hack because the query
    // predicates_of currently includes the trait itself (`Self: Trait<P1..Pn>`).
    let where_clauses = &tcx.predicates_of(def_id).predicates;
    let implied_bound_clauses =
        where_clauses[1..].into_iter()
        .map(|wc| implied_bound_from_trait(tcx, trait_pred, wc));

    Lrc::new(tcx.mk_clauses(clauses.chain(implied_bound_clauses)))
}

/// For a given `where_clause`, returns a clause `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`.
fn implied_bound_from_trait<'a, 'tcx>(
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    trait_pred: ty::TraitPredicate<'tcx>,
    where_clause: &ty::Predicate<'tcx>,
) -> Clause<'tcx> {
    // `FromEnv(Self: Trait<P1..Pn>)`
    let impl_trait = DomainGoal::FromEnv(WhereClauseAtom::Implemented(trait_pred));

    // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`
    Clause::ForAll(
        where_clause.lower().map_bound(|goal| ProgramClause {
            goal: goal.into_from_env_goal(),
            hypotheses: tcx.mk_goals(iter::once(Goal::from(impl_trait))),
        })
    )
}

fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                      -> Lrc<&'tcx Slice<Clause<'tcx>>>
{
    if let ImplPolarity::Negative = tcx.impl_polarity(def_id) {
        return Lrc::new(tcx.mk_clauses(iter::empty::<Clause>()));
    }

    // Rule Implemented-From-Impl (see rustc guide)
    //
    // `impl<P0..Pn> Trait<A1..An> for A0 where WC { .. }`
    //
    // ```
    // forall<P0..Pn> {
    //   Implemented(A0: Trait<A1..An>) :- WC
    // }
    // ```

    let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
    // `Implemented(A0: Trait<A1..An>)`
    let trait_pred = ty::TraitPredicate { trait_ref }.lower();
     // `WC`
    let where_clauses = tcx.predicates_of(def_id).predicates.lower();

     // `Implemented(A0: Trait<A1..An>) :- WC`
    let clause = ProgramClause {
        goal: trait_pred,
        hypotheses: tcx.mk_goals(
            where_clauses.into_iter().map(|wc| Goal::from_poly_domain_goal(wc, tcx))
        )
    };
    Lrc::new(tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause)))))
}

pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    item_id: DefId,
) -> Lrc<Vec<Clause<'tcx>>> {
    // Rule Normalize-From-Impl (see rustc guide)
    //
    // ```impl<P0..Pn> Trait<A1..An> for A0
    // where WC
    // {
    //     type AssocType<Pn+1..Pm> where WC1 = T;
    // }```
    //
    // ```
    // forall<P0..Pm> {
    //   forall<Pn+1..Pm> {
    //     Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T) :-
    //       WC && WC1
    //   }
    // }
    // ```

    let item = tcx.associated_item(item_id);
    debug_assert_eq!(item.kind, ty::AssociatedKind::Type);
    let impl_id = if let ty::AssociatedItemContainer::ImplContainer(impl_id) = item.container {
        impl_id
    } else {
        bug!()
    };
    // `A0 as Trait<A1..An>`
    let trait_ref = tcx.impl_trait_ref(impl_id).unwrap();
    // `T`
    let ty = tcx.type_of(item_id);
    // `WC`
    let impl_where_clauses = tcx.predicates_of(impl_id).predicates.lower();
    // `WC1`
    let item_where_clauses = tcx.predicates_of(item_id).predicates.lower();
    // `WC && WC1`
    let mut where_clauses = vec![];
    where_clauses.extend(impl_where_clauses);
    where_clauses.extend(item_where_clauses);
    // `<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm>`
    let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.name);
    // `Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T)`
    let normalize_goal = DomainGoal::Normalize(ty::ProjectionPredicate { projection_ty, ty });
    // `Normalize(... -> T) :- WC && WC1`
    let clause = Clause::Implies(where_clauses, normalize_goal);
    Lrc::new(vec![clause])
}

pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
    if !tcx.features().rustc_attrs {
        return;
    }

    let mut visitor = ClauseDumper { tcx };
    tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
}

struct ClauseDumper<'a, 'tcx: 'a> {
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
}

impl<'a, 'tcx> ClauseDumper<'a, 'tcx > {
    fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) {
        let def_id = self.tcx.hir.local_def_id(node_id);
        for attr in attrs {
            if attr.check_name("rustc_dump_program_clauses") {
                let clauses = self.tcx.program_clauses_for(def_id);
                for clause in *clauses {
                    // Skip the top-level binder for a less verbose output
                    let program_clause = match clause {
                        Clause::Implies(program_clause) => program_clause,
                        Clause::ForAll(program_clause) => program_clause.skip_binder(),
                    };
                    self.tcx.sess.struct_span_err(attr.span, &format!("{}", program_clause)).emit();
                }
            }
        }
    }
}

impl<'a, 'tcx> Visitor<'tcx> for ClauseDumper<'a, 'tcx> {
    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
    }

    fn visit_item(&mut self, item: &'tcx hir::Item) {
        self.process_attrs(item.id, &item.attrs);
        intravisit::walk_item(self, item);
    }

    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
        self.process_attrs(trait_item.id, &trait_item.attrs);
        intravisit::walk_trait_item(self, trait_item);
    }

    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
        self.process_attrs(impl_item.id, &impl_item.attrs);
        intravisit::walk_impl_item(self, impl_item);
    }

    fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
        self.process_attrs(s.id, &s.attrs);
        intravisit::walk_struct_field(self, s);
    }
}
<|endoftext|>


<commit_before><commit_msg>structs example<commit_after>
struct User {
    username: String,
    email: String,
    isactive: bool,
    sign_in_count: u32,
}

fn main() {

    let rk = User {
        username: String::from("rkgade"),
        email: String::from("rkgade@email.com"),
        isactive: true,
        sign_in_count: 1,
    };

    let someone_like_rk = User {
        username: String::from("someone"),
        email: String::from("someone@something.com"),
        ..rk
    };

    println!("{}", rk.email );
    println!("",someone_like_rk );

    // Don't use references as values for struct fields.
    // This can be done using lifetimes, but that comes later

}
<|endoftext|>


<commit_before><commit_msg>Simplify implementation of add_tag()<commit_after><|endoftext|>


<commit_before><commit_msg>Replaced oldschool type for struct<commit_after><|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Code to handle initial setup steps for a pool.
// Initial setup steps are steps that do not alter the environment.

use std::collections::{HashMap, HashSet};
use std::io::ErrorKind;
use std::fs::{OpenOptions, read_dir};
use std::os::linux::fs::MetadataExt;
use std::path::PathBuf;
use std::str::FromStr;

use nix::Errno;
use nix::sys::stat::{S_IFBLK, S_IFMT};
use serde_json;

use devicemapper::Device;

use super::super::errors::{EngineResult, EngineError, ErrorEnum};
use super::super::types::PoolUuid;

use super::blockdev::BlockDev;
use super::device::blkdev_size;
use super::engine::DevOwnership;
use super::metadata::{BDA, StaticHeader};
use super::range_alloc::RangeAllocator;
use super::serde_structs::PoolSave;

/// Find all Stratis devices.
///
/// Returns a map of pool uuids to a vector of devices for each pool.
pub fn find_all() -> EngineResult<HashMap<PoolUuid, Vec<PathBuf>>> {

    let mut pool_map = HashMap::new();
    for dir_e in try!(read_dir("/dev")) {
        let dir_e = try!(dir_e);
        let mode = try!(dir_e.metadata()).st_mode();

        // Device node can't belong to Stratis if it is not a block device
        if mode & S_IFMT.bits() != S_IFBLK.bits() {
            continue;
        }

        let devnode = dir_e.path();

        let f = OpenOptions::new().read(true).open(&devnode);

        // There are some reasons for OpenOptions::open() to return an error
        // which are not reasons for this method to return an error.
        // Try to distinguish. Non-error conditions are:
        //
        // 1. ENXIO: The device does not exist anymore. This means that the device
        // was volatile for some reason; in that case it can not belong to
        // Stratis so it is safe to ignore it.
        //
        // 2. ENOMEDIUM: The device has no medium. An example of this case is an
        // empty optical drive.
        //
        // Note that it is better to be conservative and return with an
        // error in any case where failure to read the device could result
        // in bad data for Stratis. Additional exceptions may be added,
        // but only with a complete justification.
        if f.is_err() {
            let err = f.unwrap_err();
            match err.kind() {
                ErrorKind::NotFound => {
                    continue;
                }
                _ => {
                    if let Some(errno) = err.raw_os_error() {
                        match Errno::from_i32(errno) {
                            Errno::ENXIO | Errno::ENOMEDIUM => continue,
                            _ => return Err(EngineError::Io(err)),
                        };
                    } else {
                        return Err(EngineError::Io(err));
                    }
                }
            }
        }

        let mut f = f.expect("unreachable if f is err");
        if let DevOwnership::Ours(uuid) = try!(StaticHeader::determine_ownership(&mut f)) {
            pool_map
                .entry(uuid)
                .or_insert_with(Vec::new)
                .push(devnode)
        };
    }

    Ok(pool_map)
}

/// Get the most recent metadata from a set of Devices for a given pool UUID.
/// Returns None if no metadata found for this pool.
pub fn get_metadata(pool_uuid: PoolUuid, devnodes: &[PathBuf]) -> EngineResult<Option<PoolSave>> {

    // No device nodes means no metadata
    if devnodes.is_empty() {
        return Ok(None);
    }

    // Get pairs of device nodes and matching BDAs
    // If no BDA, or BDA UUID does not match pool UUID, skip.
    // If there is an error reading the BDA, error. There could have been
    // vital information on that BDA, for example, it may have contained
    // the newest metadata.
    let mut bdas = Vec::new();
    for devnode in devnodes {
        let bda = try!(BDA::load(&mut try!(OpenOptions::new().read(true).open(devnode))));
        if bda.is_none() {
            continue;
        }
        let bda = bda.expect("unreachable if bda is None");

        if *bda.pool_uuid() != pool_uuid {
            continue;
        }
        bdas.push((devnode, bda));
    }

    // We may have had no devices with BDAs for this pool, so return if no BDAs.
    if bdas.is_empty() {
        return Ok(None);
    }

    // Get a most recent BDA
    let &(_, ref most_recent_bda) = bdas.iter()
        .max_by_key(|p| p.1.last_update_time())
        .expect("bdas is not empty, must have a max");

    // Most recent time should never be None if this was a properly
    // created pool; this allows for the method to be called in other
    // circumstances.
    let most_recent_time = most_recent_bda.last_update_time();
    if most_recent_time.is_none() {
        return Ok(None);
    }

    // Try to read from all available devnodes that could contain most
    // recent metadata. In the event of errors, continue to try until all are
    // exhausted.
    for &(devnode, ref bda) in
        bdas.iter()
            .filter(|p| p.1.last_update_time() == most_recent_time) {

        let f = OpenOptions::new().read(true).open(devnode);
        if f.is_err() {
            continue;
        }
        let mut f = f.expect("f is not err");

        if let Ok(Some(data)) = bda.load_state(&mut f) {
            let json: serde_json::Result<PoolSave> = serde_json::from_slice(&data);
            if let Ok(pool) = json {
                return Ok(Some(pool));
            } else {
                continue;
            }
        } else {
            continue;
        }
    }

    // If no data has yet returned, we have an error. That is, we should have
    // some metadata, because we have a most recent time, but we failed to
    // get any.
    let err_str = "timestamp indicates data was written, but no data succesfully read";
    Err(EngineError::Engine(ErrorEnum::NotFound, err_str.into()))
}

/// Get the blockdevs corresponding to this pool.
pub fn get_blockdevs(pool_save: &PoolSave, devnodes: &[PathBuf]) -> EngineResult<Vec<BlockDev>> {
    let segments = pool_save
        .flex_devs
        .meta_dev
        .iter()
        .chain(pool_save.flex_devs.thin_meta_dev.iter())
        .chain(pool_save.flex_devs.thin_data_dev.iter());

    let mut segment_table = HashMap::new();
    for seg in segments {
        segment_table
            .entry(seg.0.clone())
            .or_insert(vec![])
            .push((seg.1, seg.2))
    }

    let mut blockdevs = vec![];
    let mut devices = HashSet::new();
    for dev in devnodes {
        let device = try!(Device::from_str(&dev.to_string_lossy()));

        // If we've seen this device already, skip it.
        if devices.contains(&device) {
            continue;
        } else {
            devices.insert(device);
        }

        let bda = try!(BDA::load(&mut try!(OpenOptions::new().read(true).open(dev))));
        let bda = try!(bda.ok_or(EngineError::Engine(ErrorEnum::NotFound,
                                                     "no BDA found for Stratis device".into())));

        let actual_size = try!(blkdev_size(&try!(OpenOptions::new().read(true).open(dev))))
            .sectors();

        // If size of device has changed and is less, then it is possible
        // that the segments previously allocated for this blockdev no
        // longer exist. If that is the case, RangeAllocator::new() will
        // return an error.
        let allocator =
            try!(RangeAllocator::new(actual_size,
                                     segment_table.get(bda.dev_uuid()).unwrap_or(&vec![])));

        blockdevs.push(BlockDev::new(device, dev.clone(), bda, allocator));
    }

    // Verify that blockdevs found match blockdevs recorded.
    let current_uuids: HashSet<_> = blockdevs.iter().map(|b| *b.uuid()).collect();
    let recorded_uuids: HashSet<_> = pool_save.block_devs.keys().map(|u| *u).collect();

    if current_uuids != recorded_uuids {
        let err_msg = "Recorded block dev UUIDs != discovered blockdev UUIDs";
        return Err(EngineError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    if blockdevs.len() != current_uuids.len() {
        let err_msg = "Duplicate block devices found in environment";
        return Err(EngineError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    Ok(blockdevs)
}
<commit_msg>Avoid unnecessary else branch<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Code to handle initial setup steps for a pool.
// Initial setup steps are steps that do not alter the environment.

use std::collections::{HashMap, HashSet};
use std::io::ErrorKind;
use std::fs::{OpenOptions, read_dir};
use std::os::linux::fs::MetadataExt;
use std::path::PathBuf;
use std::str::FromStr;

use nix::Errno;
use nix::sys::stat::{S_IFBLK, S_IFMT};
use serde_json;

use devicemapper::Device;

use super::super::errors::{EngineResult, EngineError, ErrorEnum};
use super::super::types::PoolUuid;

use super::blockdev::BlockDev;
use super::device::blkdev_size;
use super::engine::DevOwnership;
use super::metadata::{BDA, StaticHeader};
use super::range_alloc::RangeAllocator;
use super::serde_structs::PoolSave;

/// Find all Stratis devices.
///
/// Returns a map of pool uuids to a vector of devices for each pool.
pub fn find_all() -> EngineResult<HashMap<PoolUuid, Vec<PathBuf>>> {

    let mut pool_map = HashMap::new();
    for dir_e in try!(read_dir("/dev")) {
        let dir_e = try!(dir_e);
        let mode = try!(dir_e.metadata()).st_mode();

        // Device node can't belong to Stratis if it is not a block device
        if mode & S_IFMT.bits() != S_IFBLK.bits() {
            continue;
        }

        let devnode = dir_e.path();

        let f = OpenOptions::new().read(true).open(&devnode);

        // There are some reasons for OpenOptions::open() to return an error
        // which are not reasons for this method to return an error.
        // Try to distinguish. Non-error conditions are:
        //
        // 1. ENXIO: The device does not exist anymore. This means that the device
        // was volatile for some reason; in that case it can not belong to
        // Stratis so it is safe to ignore it.
        //
        // 2. ENOMEDIUM: The device has no medium. An example of this case is an
        // empty optical drive.
        //
        // Note that it is better to be conservative and return with an
        // error in any case where failure to read the device could result
        // in bad data for Stratis. Additional exceptions may be added,
        // but only with a complete justification.
        if f.is_err() {
            let err = f.unwrap_err();
            match err.kind() {
                ErrorKind::NotFound => {
                    continue;
                }
                _ => {
                    if let Some(errno) = err.raw_os_error() {
                        match Errno::from_i32(errno) {
                            Errno::ENXIO | Errno::ENOMEDIUM => continue,
                            _ => return Err(EngineError::Io(err)),
                        };
                    } else {
                        return Err(EngineError::Io(err));
                    }
                }
            }
        }

        let mut f = f.expect("unreachable if f is err");
        if let DevOwnership::Ours(uuid) = try!(StaticHeader::determine_ownership(&mut f)) {
            pool_map
                .entry(uuid)
                .or_insert_with(Vec::new)
                .push(devnode)
        };
    }

    Ok(pool_map)
}

/// Get the most recent metadata from a set of Devices for a given pool UUID.
/// Returns None if no metadata found for this pool.
pub fn get_metadata(pool_uuid: PoolUuid, devnodes: &[PathBuf]) -> EngineResult<Option<PoolSave>> {

    // No device nodes means no metadata
    if devnodes.is_empty() {
        return Ok(None);
    }

    // Get pairs of device nodes and matching BDAs
    // If no BDA, or BDA UUID does not match pool UUID, skip.
    // If there is an error reading the BDA, error. There could have been
    // vital information on that BDA, for example, it may have contained
    // the newest metadata.
    let mut bdas = Vec::new();
    for devnode in devnodes {
        let bda = try!(BDA::load(&mut try!(OpenOptions::new().read(true).open(devnode))));
        if bda.is_none() {
            continue;
        }
        let bda = bda.expect("unreachable if bda is None");

        if *bda.pool_uuid() != pool_uuid {
            continue;
        }
        bdas.push((devnode, bda));
    }

    // We may have had no devices with BDAs for this pool, so return if no BDAs.
    if bdas.is_empty() {
        return Ok(None);
    }

    // Get a most recent BDA
    let &(_, ref most_recent_bda) = bdas.iter()
        .max_by_key(|p| p.1.last_update_time())
        .expect("bdas is not empty, must have a max");

    // Most recent time should never be None if this was a properly
    // created pool; this allows for the method to be called in other
    // circumstances.
    let most_recent_time = most_recent_bda.last_update_time();
    if most_recent_time.is_none() {
        return Ok(None);
    }

    // Try to read from all available devnodes that could contain most
    // recent metadata. In the event of errors, continue to try until all are
    // exhausted.
    for &(devnode, ref bda) in
        bdas.iter()
            .filter(|p| p.1.last_update_time() == most_recent_time) {

        let f = OpenOptions::new().read(true).open(devnode);
        if f.is_err() {
            continue;
        }
        let mut f = f.expect("f is not err");

        if let Ok(Some(data)) = bda.load_state(&mut f) {
            let json: serde_json::Result<PoolSave> = serde_json::from_slice(&data);
            if let Ok(pool) = json {
                return Ok(Some(pool));
            } else {
                continue;
            }
        } else {
            continue;
        }
    }

    // If no data has yet returned, we have an error. That is, we should have
    // some metadata, because we have a most recent time, but we failed to
    // get any.
    let err_str = "timestamp indicates data was written, but no data succesfully read";
    Err(EngineError::Engine(ErrorEnum::NotFound, err_str.into()))
}

/// Get the blockdevs corresponding to this pool.
pub fn get_blockdevs(pool_save: &PoolSave, devnodes: &[PathBuf]) -> EngineResult<Vec<BlockDev>> {
    let segments = pool_save
        .flex_devs
        .meta_dev
        .iter()
        .chain(pool_save.flex_devs.thin_meta_dev.iter())
        .chain(pool_save.flex_devs.thin_data_dev.iter());

    let mut segment_table = HashMap::new();
    for seg in segments {
        segment_table
            .entry(seg.0.clone())
            .or_insert(vec![])
            .push((seg.1, seg.2))
    }

    let mut blockdevs = vec![];
    let mut devices = HashSet::new();
    for dev in devnodes {
        let device = try!(Device::from_str(&dev.to_string_lossy()));

        // If we've seen this device already, skip it.
        if devices.contains(&device) {
            continue;
        }
        devices.insert(device);

        let bda = try!(BDA::load(&mut try!(OpenOptions::new().read(true).open(dev))));
        let bda = try!(bda.ok_or(EngineError::Engine(ErrorEnum::NotFound,
                                                     "no BDA found for Stratis device".into())));

        let actual_size = try!(blkdev_size(&try!(OpenOptions::new().read(true).open(dev))))
            .sectors();

        // If size of device has changed and is less, then it is possible
        // that the segments previously allocated for this blockdev no
        // longer exist. If that is the case, RangeAllocator::new() will
        // return an error.
        let allocator =
            try!(RangeAllocator::new(actual_size,
                                     segment_table.get(bda.dev_uuid()).unwrap_or(&vec![])));

        blockdevs.push(BlockDev::new(device, dev.clone(), bda, allocator));
    }

    // Verify that blockdevs found match blockdevs recorded.
    let current_uuids: HashSet<_> = blockdevs.iter().map(|b| *b.uuid()).collect();
    let recorded_uuids: HashSet<_> = pool_save.block_devs.keys().map(|u| *u).collect();

    if current_uuids != recorded_uuids {
        let err_msg = "Recorded block dev UUIDs != discovered blockdev UUIDs";
        return Err(EngineError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    if blockdevs.len() != current_uuids.len() {
        let err_msg = "Duplicate block devices found in environment";
        return Err(EngineError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    Ok(blockdevs)
}
<|endoftext|>


<commit_before>// Copyright 2012-2015 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.

// ignore-android needs extra network permissions
// ignore-bitrig system ulimit (Too many open files)
// ignore-netbsd system ulimit (Too many open files)
// ignore-openbsd system ulimit (Too many open files)
// ignore-emscripten no threads or sockets support

use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
use std::process;
use std::sync::mpsc::channel;
use std::thread::{self, Builder};

fn main() {
    // This test has a chance to time out, try to not let it time out
    thread::spawn(move|| -> () {
        thread::sleep_ms(30 * 1000);
        process::exit(1);
    });

    let mut listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let addr = listener.local_addr().unwrap();
    thread::spawn(move || -> () {
        loop {
            let mut stream = match listener.accept() {
                Ok(stream) => stream.0,
                Err(error) => continue,
            };
            stream.read(&mut [0]);
            stream.write(&[2]);
        }
    });

    let (tx, rx) = channel();
    let mut spawned_cnt = 0;
    for _ in 0..1000 {
        let tx = tx.clone();
        let res = Builder::new().stack_size(64 * 1024).spawn(move|| {
            match TcpStream::connect(addr) {
                Ok(mut stream) => {
                    stream.write(&[1]);
                    stream.read(&mut [0]);
                },
                Err(..) => {}
            }
            tx.send(()).unwrap();
        });
        if let Ok(_) = res {
            spawned_cnt += 1;
        };
    }

    // Wait for all clients to exit, but don't wait for the server to exit. The
    // server just runs infinitely.
    drop(tx);
    for _ in 0..spawned_cnt {
        rx.recv().unwrap();
    }
    assert_eq!(spawned_cnt, 1000);
    process::exit(0);
}
<commit_msg>test: clear deprecation warnings in tcp-stress<commit_after>// Copyright 2012-2015 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.

// ignore-android needs extra network permissions
// ignore-bitrig system ulimit (Too many open files)
// ignore-netbsd system ulimit (Too many open files)
// ignore-openbsd system ulimit (Too many open files)
// ignore-emscripten no threads or sockets support

use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
use std::process;
use std::sync::mpsc::channel;
use std::time::Duration;
use std::thread::{self, Builder};

fn main() {
    // This test has a chance to time out, try to not let it time out
    thread::spawn(move|| -> () {
        thread::sleep(Duration::from_secs(30));
        process::exit(1);
    });

    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let addr = listener.local_addr().unwrap();
    thread::spawn(move || -> () {
        loop {
            let mut stream = match listener.accept() {
                Ok(stream) => stream.0,
                Err(_) => continue,
            };
            let _ = stream.read(&mut [0]);
            let _ = stream.write(&[2]);
        }
    });

    let (tx, rx) = channel();
    let mut spawned_cnt = 0;
    for _ in 0..1000 {
        let tx = tx.clone();
        let res = Builder::new().stack_size(64 * 1024).spawn(move|| {
            match TcpStream::connect(addr) {
                Ok(mut stream) => {
                    let _ = stream.write(&[1]);
                    let _ = stream.read(&mut [0]);
                },
                Err(..) => {}
            }
            tx.send(()).unwrap();
        });
        if let Ok(_) = res {
            spawned_cnt += 1;
        };
    }

    // Wait for all clients to exit, but don't wait for the server to exit. The
    // server just runs infinitely.
    drop(tx);
    for _ in 0..spawned_cnt {
        rx.recv().unwrap();
    }
    assert_eq!(spawned_cnt, 1000);
    process::exit(0);
}
<|endoftext|>


<commit_before><commit_msg>Add run-pass test for #44005<commit_after>// Copyright 2018 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.

pub trait Foo<'a> {
    type Bar;
    fn foo(&'a self) -> Self::Bar;
}

impl<'a, 'b, T: 'a> Foo<'a> for &'b T {
    type Bar = &'a T;
    fn foo(&'a self) -> &'a T {
        self
    }
}

pub fn uncallable<T, F>(x: T, f: F)
    where T: for<'a> Foo<'a>,
          F: for<'a> Fn(<T as Foo<'a>>::Bar)
{
    f(x.foo());
}

pub fn catalyst(x: &i32) {
    broken(x, |_| {})
}

pub fn broken<F: Fn(&i32)>(x: &i32, f: F) {
    uncallable(x, |y| f(y));
}

fn main() { }

<|endoftext|>


<commit_before>// Support code for rustc's built in test runner generator. Currently,
// none of this is meant for users. It is intended to support the
// simplest interface possible for representing and running tests
// while providing a base that other test frameworks may build off of.

export test_name;
export test_fn;
export test_desc;
export test_main;
export test_result;
export test_opts;
export tr_ok;
export tr_failed;
export tr_ignored;
export run_test;
export filter_tests;
export parse_opts;

// The name of a test. By convention this follows the rules for rust
// paths, i.e it should be a series of identifiers seperated by double
// colons. This way if some test runner wants to arrange the tests
// heirarchically it may.
type test_name = str;

// A function that runs a test. If the function returns successfully,
// the test succeeds; if the function fails then the test fails. We
// may need to come up with a more clever definition of test in order
// to support isolation of tests into tasks.
type test_fn = fn();

// The definition of a single test. A test runner will run a list of
// these.
type test_desc = rec(test_name name,
                     test_fn fn,
                     bool ignore);

// The default console test runner. It accepts the command line
// arguments and a vector of test_descs (generated at compile time).
fn test_main(&vec[str] args, &test_desc[] tests) {
    auto ivec_args = {
        auto iargs = ~[];
        for (str arg in args) {
            iargs += ~[arg]
        }
        iargs
    };
    check ivec::is_not_empty(ivec_args);
    auto opts = alt (parse_opts(ivec_args)) {
        either::left(?o) { o }
        either::right(?m) { fail m }
    };
    if (!run_tests(opts, tests)) {
        fail "Some tests failed";
    }
}

type test_opts = rec(option::t[str] filter,
                     bool run_ignored);

type opt_res = either::t[test_opts, str];

// Parses command line arguments into test options
fn parse_opts(&str[] args) : ivec::is_not_empty(args) -> opt_res {

    // FIXME (#649): Shouldn't have to check here
    check ivec::is_not_empty(args);
    auto args_ = ivec::tail(args);
    auto opts = ~[getopts::optflag("ignored")];
    auto match = alt (getopts::getopts_ivec(args_, opts)) {
        getopts::success(?m) { m }
        getopts::failure(?f) { ret either::right(getopts::fail_str(f)) }
    };

    auto filter = if (vec::len(match.free) > 0u) {
        option::some(match.free.(0))
    } else {
        option::none
    };

    auto run_ignored = getopts::opt_present(match, "ignored");

    auto test_opts = rec(filter = filter,
                         run_ignored = run_ignored);

    ret either::left(test_opts);
}

tag test_result {
    tr_ok;
    tr_failed;
    tr_ignored;
}

// A simple console test runner
fn run_tests(&test_opts opts, &test_desc[] tests) -> bool {

    auto filtered_tests = filter_tests(opts, tests);

    auto out = io::stdout();

    auto total = ivec::len(filtered_tests);
    out.write_line(#fmt("running %u tests", total));

    auto passed = 0u;
    auto failed = 0u;
    auto ignored = 0u;

    for (test_desc test in filtered_tests) {
        out.write_str(#fmt("running %s ... ", test.name));
        alt (run_test(test)) {
            tr_ok {
                passed += 1u;
                write_ok(out);
                out.write_line("");
            }
            tr_failed {
                failed += 1u;
                write_failed(out);
                out.write_line("");
            }
            tr_ignored {
                ignored += 1u;
                write_ignored(out);
                out.write_line("");
            }
        }
    }

    assert passed + failed + ignored == total;

    out.write_str(#fmt("\nresult: "));
    if (failed == 0u) {
        write_ok(out);
    } else {
        write_failed(out);
    }
    out.write_str(#fmt(". %u passed; %u failed; %u ignored\n\n",
                       passed, failed, ignored));

    ret true;

    fn write_ok(&io::writer out) {
        if (term::color_supported()) {
            term::fg(out.get_buf_writer(), term::color_green);
        }
        out.write_str("ok");
        if (term::color_supported()) {
            term::reset(out.get_buf_writer());
        }
     }

    fn write_failed(&io::writer out) {
        if (term::color_supported()) {
            term::fg(out.get_buf_writer(), term::color_red);
        }
        out.write_str("FAILED");
        if (term::color_supported()) {
            term::reset(out.get_buf_writer());
        }
    }

    fn write_ignored(&io::writer out) {
        if (term::color_supported()) {
            term::fg(out.get_buf_writer(), term::color_yellow);
        }
        out.write_str("ignored");
        if (term::color_supported()) {
            term::reset(out.get_buf_writer());
        }
    }
}

fn filter_tests(&test_opts opts, &test_desc[] tests) -> test_desc[] {
    auto filtered = tests;

    filtered = if (option::is_none(opts.filter)) {
        filtered
    } else {
        auto filter_str = alt opts.filter { option::some(?f) { f }
                                            option::none { "" } };

        auto filter = bind fn(&test_desc test,
                              str filter_str) -> option::t[test_desc] {
            if (str::find(test.name, filter_str) >= 0) {
                ret option::some(test);
            } else {
                ret option::none;
            }
        } (_, filter_str);

        ivec::filter_map(filter, filtered)
    };

    filtered = if (!opts.run_ignored) {
        filtered
    } else {
        auto filter = fn(&test_desc test) -> option::t[test_desc] {
            if (test.ignore) {
                ret option::some(rec(name = test.name,
                                     fn = test.fn,
                                     ignore = false));
            } else {
                ret option::none;
            }
        };

        ivec::filter_map(filter, filtered)
    };

    ret filtered;
}

fn run_test(&test_desc test) -> test_result {
    if (!test.ignore) {
        test.fn();
        ret tr_ok;
    } else {
        ret tr_ignored;
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>Run test functions in isolated tasks. Issue #428<commit_after>// Support code for rustc's built in test runner generator. Currently,
// none of this is meant for users. It is intended to support the
// simplest interface possible for representing and running tests
// while providing a base that other test frameworks may build off of.

export test_name;
export test_fn;
export test_desc;
export test_main;
export test_result;
export test_opts;
export tr_ok;
export tr_failed;
export tr_ignored;
export run_test;
export filter_tests;
export parse_opts;

// The name of a test. By convention this follows the rules for rust
// paths, i.e it should be a series of identifiers seperated by double
// colons. This way if some test runner wants to arrange the tests
// heirarchically it may.
type test_name = str;

// A function that runs a test. If the function returns successfully,
// the test succeeds; if the function fails then the test fails. We
// may need to come up with a more clever definition of test in order
// to support isolation of tests into tasks.
type test_fn = fn();

// The definition of a single test. A test runner will run a list of
// these.
type test_desc = rec(test_name name,
                     test_fn fn,
                     bool ignore);

// The default console test runner. It accepts the command line
// arguments and a vector of test_descs (generated at compile time).
fn test_main(&vec[str] args, &test_desc[] tests) {
    auto ivec_args = {
        auto iargs = ~[];
        for (str arg in args) {
            iargs += ~[arg]
        }
        iargs
    };
    check ivec::is_not_empty(ivec_args);
    auto opts = alt (parse_opts(ivec_args)) {
        either::left(?o) { o }
        either::right(?m) { fail m }
    };
    if (!run_tests(opts, tests)) {
        fail "Some tests failed";
    }
}

type test_opts = rec(option::t[str] filter,
                     bool run_ignored);

type opt_res = either::t[test_opts, str];

// Parses command line arguments into test options
fn parse_opts(&str[] args) : ivec::is_not_empty(args) -> opt_res {

    // FIXME (#649): Shouldn't have to check here
    check ivec::is_not_empty(args);
    auto args_ = ivec::tail(args);
    auto opts = ~[getopts::optflag("ignored")];
    auto match = alt (getopts::getopts_ivec(args_, opts)) {
        getopts::success(?m) { m }
        getopts::failure(?f) { ret either::right(getopts::fail_str(f)) }
    };

    auto filter = if (vec::len(match.free) > 0u) {
        option::some(match.free.(0))
    } else {
        option::none
    };

    auto run_ignored = getopts::opt_present(match, "ignored");

    auto test_opts = rec(filter = filter,
                         run_ignored = run_ignored);

    ret either::left(test_opts);
}

tag test_result {
    tr_ok;
    tr_failed;
    tr_ignored;
}

// A simple console test runner
fn run_tests(&test_opts opts, &test_desc[] tests) -> bool {

    auto filtered_tests = filter_tests(opts, tests);

    auto out = io::stdout();

    auto total = ivec::len(filtered_tests);
    out.write_line(#fmt("running %u tests", total));

    auto passed = 0u;
    auto failed = 0u;
    auto ignored = 0u;

    for (test_desc test in filtered_tests) {
        out.write_str(#fmt("running %s ... ", test.name));
        alt (run_test(test)) {
            tr_ok {
                passed += 1u;
                write_ok(out);
                out.write_line("");
            }
            tr_failed {
                failed += 1u;
                write_failed(out);
                out.write_line("");
            }
            tr_ignored {
                ignored += 1u;
                write_ignored(out);
                out.write_line("");
            }
        }
    }

    assert passed + failed + ignored == total;

    out.write_str(#fmt("\nresult: "));
    if (failed == 0u) {
        write_ok(out);
    } else {
        write_failed(out);
    }
    out.write_str(#fmt(". %u passed; %u failed; %u ignored\n\n",
                       passed, failed, ignored));

    ret true;

    fn write_ok(&io::writer out) {
        if (term::color_supported()) {
            term::fg(out.get_buf_writer(), term::color_green);
        }
        out.write_str("ok");
        if (term::color_supported()) {
            term::reset(out.get_buf_writer());
        }
     }

    fn write_failed(&io::writer out) {
        if (term::color_supported()) {
            term::fg(out.get_buf_writer(), term::color_red);
        }
        out.write_str("FAILED");
        if (term::color_supported()) {
            term::reset(out.get_buf_writer());
        }
    }

    fn write_ignored(&io::writer out) {
        if (term::color_supported()) {
            term::fg(out.get_buf_writer(), term::color_yellow);
        }
        out.write_str("ignored");
        if (term::color_supported()) {
            term::reset(out.get_buf_writer());
        }
    }
}

fn filter_tests(&test_opts opts, &test_desc[] tests) -> test_desc[] {
    auto filtered = tests;

    filtered = if (option::is_none(opts.filter)) {
        filtered
    } else {
        auto filter_str = alt opts.filter { option::some(?f) { f }
                                            option::none { "" } };

        auto filter = bind fn(&test_desc test,
                              str filter_str) -> option::t[test_desc] {
            if (str::find(test.name, filter_str) >= 0) {
                ret option::some(test);
            } else {
                ret option::none;
            }
        } (_, filter_str);

        ivec::filter_map(filter, filtered)
    };

    filtered = if (!opts.run_ignored) {
        filtered
    } else {
        auto filter = fn(&test_desc test) -> option::t[test_desc] {
            if (test.ignore) {
                ret option::some(rec(name = test.name,
                                     fn = test.fn,
                                     ignore = false));
            } else {
                ret option::none;
            }
        };

        ivec::filter_map(filter, filtered)
    };

    ret filtered;
}

fn run_test(&test_desc test) -> test_result {
    if (!test.ignore) {
        if (run_test_fn_in_task(test.fn)) {
            ret tr_ok;
        } else {
            ret tr_failed;
        }
    } else {
        ret tr_ignored;
    }
}

// We need to run our tests in another task in order to trap test failures.
// But, at least currently, functions can't be used as spawn arguments so
// we've got to treat our test functions as unsafe pointers.
fn run_test_fn_in_task(&fn() f) -> bool {
    fn run_task(*mutable fn() fptr) {
        task::unsupervise();
        (*fptr)()
    }
    auto fptr = ptr::addr_of(f);
    auto test_task = spawn run_task(fptr);
    ret alt (task::join(test_task)) {
        task::tr_success { true }
        task::tr_failure { false }
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>Improved readability<commit_after><|endoftext|>


<commit_before>// 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.
//
// Simple Prometheus support. Still a work in progress.
// The goal here is to develop a prometheus client that
// is fully designed for prometheus with the minimal
// dependencies and overhead.
//
// We currently provide no abstraction around collecting metrics.
// This Reporter eventually needs to handle the multiplexing and
// organization of metrics.

extern crate iron;
extern crate router;
extern crate persistent;
extern crate protobuf; // depend on rust-protobuf runtime
extern crate lru_cache;
extern crate time;

pub mod promo_proto;
use router::Router;
use iron::typemap::Key;
use iron::prelude::*;
use iron::status;
use persistent::Read;
use lru_cache::LruCache;
use protobuf::Message;
use std::sync::{Arc, RwLock};
use std::thread;

// http handler storage
#[derive(Copy, Clone)]
struct HandlerStorage;

// refer to https://prometheus.io/docs/instrumenting/exposition_formats/
const CONTENT_TYPE: &'static str = "application/vnd.google.protobuf; \
                                    proto=io.prometheus.client.MetricFamily;
                                    encoding=delimited";

impl Key for HandlerStorage {
    type Value = Arc<RwLock<LruCache<i64, promo_proto::MetricFamily>>>;
}

fn get_seconds() -> i64 {
    time::now().to_timespec().sec
}

fn families_to_u8(metric_families: Vec<(&i64, &promo_proto::MetricFamily)>) -> Vec<u8> {
    let mut buf = Vec::new();
    for (_, family) in metric_families {
        family.write_length_delimited_to_writer(&mut buf).unwrap();
    }
    buf
}

fn handler(req: &mut Request) -> IronResult<Response> {
    match req.get::<Read<HandlerStorage>>() {
        Ok(ts_and_metrics) => {
            // TODO catch unwrap
            let serialized: Vec<u8> =
                families_to_u8((*ts_and_metrics).read().unwrap().iter().collect());
            // TODO lifecycle out the metrics we sent up
            Ok(Response::with((CONTENT_TYPE, status::Ok, serialized)))
        }
        Err(_) => Ok(Response::with((status::InternalServerError, "ERROR"))),
    }
}

// TODO perhaps we autodiscover the host and port
pub struct PrometheusReporter {
    cache: Arc<RwLock<LruCache<i64, promo_proto::MetricFamily>>>,
    host_and_port: &'static str,
}

impl PrometheusReporter {
    pub fn new(host_and_port: &'static str) -> Self {
        PrometheusReporter {
            // TODO make it configurable
            cache: Arc::new(RwLock::new(LruCache::new(86400))),
            host_and_port: host_and_port,
        }
    }
    // TODO require start before add
    pub fn add(&mut self, metric_families: Vec<promo_proto::MetricFamily>) -> Result<i64, String> {
        let ts = get_seconds();
        match self.cache.write() {
            Ok(mut cache) => {
                let mut counter = 0;
                for metric_family in metric_families {
                    cache.insert(ts, metric_family);
                    counter = counter + 1;
                }
                Ok(counter)
            }
            Err(y) => Err(format!("Unable to add {}", y)),
        }
    }

    pub fn start(&self) -> Result<&str, String> {
        let mut router = Router::new();
        router.get("/metrics", handler);
        let mut chain = Chain::new(router);
        chain.link_before(Read::<HandlerStorage>::one(self.cache.clone()));
        // TODO get rid of the unwrap

        match Iron::new(chain).http(self.host_and_port) {
            Ok(iron) => {
                thread::spawn(move || iron);
                Ok("go")
            }
            Err(y) => Err(format!("Unable to start iron: {}", y)),
        }
    }
}

#[cfg(test)]
mod test {

    extern crate hyper;
    extern crate lru_cache;
    use std::thread;
    use std::time::Duration;
    use protobuf::repeated::RepeatedField;
    use super::*;

    fn a_metric_family() -> promo_proto::MetricFamily {
        let mut family = promo_proto::MetricFamily::new();
        family.set_name("MetricFamily".to_string());
        family.set_help("Help".to_string());
        family.set_field_type(promo_proto::MetricType::GAUGE);

        let mut metric = promo_proto::Metric::new();
        metric.set_timestamp_ms(a_ts());
        metric.set_gauge(a_gauge());
        metric.set_label(a_label_pair());
        family.set_metric(RepeatedField::from_vec(vec![metric]));

        family
    }

    fn a_label_pair() -> RepeatedField<promo_proto::LabelPair> {
        let mut label_pair = promo_proto::LabelPair::new();
        // The name and value alas are the names of the
        // protobuf fields in the pair in prometheus protobuf spec
        // Thes undescriptive names are part of the protocol alas.
        label_pair.set_name("name".to_string());
        label_pair.set_value("value".to_string());
        RepeatedField::from_vec(vec![label_pair])
    }

    fn a_gauge() -> promo_proto::Gauge {
        let mut gauge = promo_proto::Gauge::new();
        gauge.set_value(0.1);
        gauge
    }

    fn a_ts() -> i64 {
        0
    }

    #[test]
    fn add_some_stats_and_slurp_them_with_http() {
        let mut reporter = PrometheusReporter::new("0.0.0.0:8080");
        reporter.start().unwrap();
        thread::sleep(Duration::from_millis(1024));
        reporter.add(vec![]);
        let client = hyper::client::Client::new();
        let foo = client.get("http://127.0.0.1:8080").send().unwrap();
    }

}
<commit_msg>Actually check the results of the metrics protobufs<commit_after>// 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.
//
// Simple Prometheus support. Still a work in progress.
// The goal here is to develop a prometheus client that
// is fully designed for prometheus with the minimal
// dependencies and overhead.
//
// We currently provide no abstraction around collecting metrics.
// This Reporter eventually needs to handle the multiplexing and
// organization of metrics.

extern crate iron;
extern crate router;
extern crate persistent;
extern crate protobuf; // depend on rust-protobuf runtime
extern crate lru_cache;
extern crate time;

pub mod promo_proto;
use router::Router;
use iron::typemap::Key;
use iron::prelude::*;
use iron::status;
use lru_cache::LruCache;
use protobuf::Message;
use std::sync::{Arc, RwLock};
use std::thread;

// http handler storage
#[derive(Copy, Clone)]
struct HandlerStorage;

// refer to https://prometheus.io/docs/instrumenting/exposition_formats/
const CONTENT_TYPE: &'static str = "application/vnd.google.protobuf; \
                                    proto=io.prometheus.client.MetricFamily;
                                    encoding=delimited";

impl Key for HandlerStorage {
    type Value = Arc<RwLock<LruCache<i64, promo_proto::MetricFamily>>>;
}

fn get_seconds() -> i64 {
    time::now().to_timespec().sec
}

fn families_to_u8(metric_families: Vec<(&i64, &promo_proto::MetricFamily)>) -> Vec<u8> {
    let mut buf = Vec::new();
    for (_, family) in metric_families {
        family.write_length_delimited_to_writer(&mut buf).unwrap();
    }
    buf
}

fn handler(req: &mut Request) -> IronResult<Response> {
    match req.get::<persistent::Read<HandlerStorage>>() {
        Ok(ts_and_metrics) => {
            // TODO catch unwrap
            let serialized: Vec<u8> =
                families_to_u8((*ts_and_metrics).read().unwrap().iter().collect());
            // TODO lifecycle out the metrics we sent up
            Ok(Response::with((CONTENT_TYPE, status::Ok, serialized)))
        }
        Err(_) => Ok(Response::with((status::InternalServerError, "ERROR"))),
    }
}

// TODO perhaps we autodiscover the host and port
pub struct PrometheusReporter {
    cache: Arc<RwLock<LruCache<i64, promo_proto::MetricFamily>>>,
    host_and_port: &'static str,
}

impl PrometheusReporter {
    pub fn new(host_and_port: &'static str) -> Self {
        PrometheusReporter {
            // TODO make it configurable
            cache: Arc::new(RwLock::new(LruCache::new(86400))),
            host_and_port: host_and_port,
        }
    }
    // TODO require start before add
    pub fn add(&mut self, metric_families: Vec<promo_proto::MetricFamily>) -> Result<i64, String> {
        let ts = get_seconds();
        match self.cache.write() {
            Ok(mut cache) => {
                let mut counter = 0;
                for metric_family in metric_families {
                    cache.insert(ts, metric_family);
                    counter = counter + 1;
                }
                Ok(counter)
            }
            Err(y) => Err(format!("Unable to add {}", y)),
        }
    }

    pub fn start(&self) -> Result<&str, String> {
        let mut router = Router::new();
        router.get("/metrics", handler);
        let mut chain = Chain::new(router);
        chain.link_before(persistent::Read::<HandlerStorage>::one(self.cache.clone()));
        // TODO get rid of the unwrap

        match Iron::new(chain).http(self.host_and_port) {
            Ok(iron) => {
                thread::spawn(move || iron);
                Ok("go")
            }
            Err(y) => Err(format!("Unable to start iron: {}", y)),
        }
    }
}

#[cfg(test)]
mod test {

    extern crate hyper;
    extern crate lru_cache;
    use std::thread;
    use std::time::Duration;
    use protobuf::repeated::RepeatedField;
    use std::io::Read;
    use super::*;

    fn a_metric_family() -> promo_proto::MetricFamily {
        let mut family = promo_proto::MetricFamily::new();
        family.set_name("MetricFamily".to_string());
        family.set_help("Help".to_string());
        family.set_field_type(promo_proto::MetricType::GAUGE);

        let mut metric = promo_proto::Metric::new();
        metric.set_timestamp_ms(a_ts());
        metric.set_gauge(a_gauge());
        metric.set_label(a_label_pair());
        family.set_metric(RepeatedField::from_vec(vec![metric]));

        family
    }

    fn a_label_pair() -> RepeatedField<promo_proto::LabelPair> {
        let mut label_pair = promo_proto::LabelPair::new();
        // The name and value alas are the names of the
        // protobuf fields in the pair in prometheus protobuf spec
        // Thes undescriptive names are part of the protocol alas.
        label_pair.set_name("name".to_string());
        label_pair.set_value("value".to_string());
        RepeatedField::from_vec(vec![label_pair])
    }

    fn a_gauge() -> promo_proto::Gauge {
        let mut gauge = promo_proto::Gauge::new();
        gauge.set_value(0.1);
        gauge
    }

    fn a_ts() -> i64 {
        0
    }

    #[test]
    fn add_some_stats_and_slurp_them_with_http() {
        let mut reporter = PrometheusReporter::new("0.0.0.0:8080");
        reporter.start().unwrap();
        thread::sleep(Duration::from_millis(1024));
        reporter.add(vec![a_metric_family()]);
        let client = hyper::client::Client::new();
        let mut res = client.get("http://127.0.0.1:8080/metrics").send().unwrap();
        assert_eq!(res.status, hyper::Ok);
        let mut buffer = Vec::new();
        let size_of_buffer = res.read_to_end(&mut buffer).unwrap();
        println!("{:?} size:{} ", buffer, size_of_buffer);
        assert_eq!(size_of_buffer, 53);
    }
}
<|endoftext|>


<commit_before><commit_msg>solved 0006 with Rust<commit_after>use std::io::prelude::*;

fn main() {
    let stdin = std::io::stdin();

    let l = stdin.lock().lines().next().unwrap().unwrap();
    let a = l.chars().rev().collect::<String>();

    println!("{}",a);
}
<|endoftext|>


<commit_before><commit_msg>Chore(syncfile): tiny cleanup<commit_after><|endoftext|>


<commit_before><commit_msg>Add getters and setters for headers.<commit_after><|endoftext|>


<commit_before><commit_msg>day 16 solved.<commit_after>use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use std::collections::HashMap;

#[derive(Clone)]
struct Aunt {
    id   : usize,
    items: HashMap<String, u32>
}

impl Aunt {
    fn new(id: usize, items: HashMap<String, u32>) -> Aunt {
        Aunt {
            id   : id,
            items: items
        }
    }

    fn equal(&self, a: Aunt) -> bool {
        for prop in self.items.keys() {
            if a.items.contains_key(prop) {
                if self.items[prop] != a.items[prop] {
                    return false;
                }
            }
        }
        return true;
    }

    fn equal_2(&self, a: Aunt) -> bool {
        for prop in self.items.keys() {
            if a.items.contains_key(prop) {
                if (prop == "cats" && self.items[prop] >= a.items[prop])
                || (prop == "trees" && self.items[prop] >= a.items[prop])
                || (prop == "pomeranians" && self.items[prop] <= a.items[prop])
                || (prop == "goldfish" && self.items[prop] <= a.items[prop])
                || (prop != "cats" && prop != "trees" && prop != "pomeranians" && prop != "goldfish" && self.items[prop] != a.items[prop]) {
                    return false;
                }
            }
        }
        return true;
    }
}

fn main() {
    let mut f = File::open(Path::new("/Users/PetarV/rust-proj/advent-of-rust/target/input.txt"))
    	.ok()
    	.expect("Failed to open the input file!");

	let mut input = String::new();
	f.read_to_string(&mut input)
		.ok()
		.expect("Failed to read from the input file!");

    let mut ref_map = HashMap::new();
    ref_map.insert("children".to_string()   , 3);
    ref_map.insert("cats".to_string()       , 7);
    ref_map.insert("samoyeds".to_string()   , 2);
    ref_map.insert("pomeranians".to_string(), 3);
    ref_map.insert("akitas".to_string()     , 0);
    ref_map.insert("vizslas".to_string()    , 0);
    ref_map.insert("goldfish".to_string()   , 5);
    ref_map.insert("trees".to_string()      , 3);
    ref_map.insert("cars".to_string()       , 2);
    ref_map.insert("perfumes".to_string()   , 1);

    let ref_sue = Aunt::new(0, ref_map);

    let mut ret = 0;

    let mut aunts = Vec::new();

    for line in input.lines() {
        let mut parts: Vec<_> = line.split_whitespace().collect();

        let mut id_str = parts[1].to_string().clone(); id_str.pop();
        let id = id_str.parse().ok().expect("Could not parse into an integer!");

        let properties = parts.split_off(2);

        let mut map = HashMap::new();

        for elem in properties.chunks(2) {
            let mut prop = elem[0].to_string().clone(); prop.pop();
            let mut val_str = elem[1].to_string().clone();
            if let Some(ch) = val_str.pop() {
                if ch != ',' {
                   val_str.push(ch);
                }
            }
            let val = val_str.parse().ok().expect("Could not parse into an integer!");
            map.insert(prop.clone(), val);
        }

        let curr_aunt = Aunt::new(id, map);

        aunts.push(curr_aunt.clone());

        if ref_sue.equal(curr_aunt) {
            ret = id;
        }

    }

    println!("Sue #{} has sent the gift.", ret);

    for aunt in aunts.iter() {
        if ref_sue.equal_2(aunt.clone()) {
            ret = aunt.id;
            break;
        }
    }

    println!("Sue #{} has really sent the gift.", ret);
}<|endoftext|>


<commit_before><commit_msg>tests(macros): added integration tests<commit_after>extern crate hyper;
#[macro_use]
extern crate yup_hyper_mock;
#[macro_use]
extern crate log;

mock_connector_in_order! (MockSequential {
                                  "HTTP/1.1 200 OK\r\n\
                                 Server: BOGUS\r\n\
                                 \r\n\
                                 1"

                                 "HTTP/1.1 200 OK\r\n\
                                 Server: BOGUS\r\n\
                                 \r\n\
                                 2"
                                  });

mock_connector!(MockRedirectPolicy {
    "http://127.0.0.1" =>       "HTTP/1.1 301 Redirect\r\n\
                                 Location: http://127.0.0.2\r\n\
                                 Server: mock1\r\n\
                                 \r\n\
                                "
    "http://127.0.0.2" =>       "HTTP/1.1 302 Found\r\n\
                                 Location: https://127.0.0.3\r\n\
                                 Server: mock2\r\n\
                                 \r\n\
                                "
    "https://127.0.0.3" =>      "HTTP/1.1 200 OK\r\n\
                                 Server: mock3\r\n\
                                 \r\n\
                                "
});

/// Just to test the result of `mock_connector!` - this test was copied from hyper.
#[test]
fn test_redirect_followall() {
    let mut client = hyper::client::Client::with_connector(MockRedirectPolicy);
    client.set_redirect_policy(hyper::client::RedirectPolicy::FollowAll);

    let res = client.get("http://127.0.0.1").send().unwrap();
    assert_eq!(res.headers.get(), Some(&hyper::header::Server("mock3".to_owned())));
}

#[test]
fn test_sequential_mock() {
    use std::io::Read;

    let mut client = hyper::client::Client::with_connector(MockSequential::default());

    let res = client.get("http://127.0.0.1").send().unwrap();
    assert_eq!(res.bytes().next().unwrap().unwrap(), b'1');

    let res = client.get("http://127.0.0.1").send().unwrap();
    assert_eq!(res.bytes().next().unwrap().unwrap(), b'2');
}
<|endoftext|>


<commit_before><commit_msg>Added missing file.<commit_after>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

// pub use self::blosum62::blosum62;
// pub use self::pam40::pam40;
// pub use self::pam120::pam120;
// pub use self::pam200::pam200;
// pub use self::pam250::pam250;
//
// pub mod blosum62;
// pub mod pam40;
// pub mod pam120;
// pub mod pam200;
// pub mod pam250;
<|endoftext|>


<commit_before><commit_msg>Fix the variance of Input/Output<commit_after><|endoftext|>


<commit_before><commit_msg>add a `cmp` convenience method to `Ord`<commit_after><|endoftext|>


<commit_before><commit_msg>modified shell output line to show cwd, and implemented internal cd command.<commit_after><|endoftext|>


<commit_before><commit_msg>Derive Serialize for types in room::encrypted<commit_after><|endoftext|>


<commit_before><commit_msg>Expand Globs In For Expression<commit_after><|endoftext|>