<commit_before>// Copyright 2014 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

pub use compile_error::*;
pub use syntax::parse::token::InternedString;
pub use syntax::ast::*;

use syntax::codemap::DUMMY_SP;
use std::rc::Rc;

pub struct AttributeValue<T>
{
  value: Option<T>,
  duplicate: DuplicateAttribute,
  span: Span
}

impl<T: Clone> AttributeValue<T>
{
  pub fn new(duplicate: DuplicateAttribute) -> AttributeValue<T>
  {
    AttributeValue {
      value: None,
      duplicate: duplicate,
      span: DUMMY_SP
    }
  }

  pub fn simple() -> AttributeValue<T>
  {
    AttributeValue::new(DuplicateAttribute::simple(Warn))
  }

  pub fn update(self, cx: &ExtCtxt, value: T, span: Span) -> AttributeValue<T>
  {
    let mut this = self;
    if this.value.is_some() {
      this.duplicate.issue(cx, this.span, span);
    } else {
      this.value = Some(value);
      this.span = span;
    }
    this
  }

  pub fn value_or(&self, default: T) -> T
  {
    match self.value {
      None => default,
      Some(ref value) => value.clone()
    }
  }
}

pub struct AttributeInfo
{
  pub name: InternedString,
  pub desc: &'static str,
  pub model: AttributeModel
}

impl AttributeInfo
{
  pub fn new(name: &'static str, desc: &'static str,
    model: AttributeModel) -> AttributeInfo
  {
    AttributeInfo {
      name: InternedString::new(name),
      desc: desc,
      model: model
    }
  }

  pub fn simple(name: &'static str, desc: &'static str) -> AttributeInfo
  {
    AttributeInfo::new(name, desc, NoProperty(AttributeValue::simple()))
  }

  pub fn update(self, model: AttributeModel) -> AttributeInfo
  {
    let mut this = self;
    this.model = model;
    this
  }

  pub fn plain_value<'a>(&'a self) -> &'a AttributeValue<bool>
  {
    match self.model {
      NoProperty(ref v) => v,
      _ => fail!("No plain value for the current attribute.")
    }
  }

  pub fn sub_model<'a>(&'a self) -> &'a AttributeDict
  {
    match self.model {
      SubAttribute(ref dict) => dict,
      _ => fail!("No sub value for the attribute.")
    }
  }
}

pub enum AttributeModel
{
  NoProperty(AttributeValue<bool>),
  KeyValue(AttributeLitModel),
  SubAttribute(AttributeDict)
}

pub enum AttributeLitModel
{
  MLitStr(AttributeValue<(InternedString, StrStyle)>),
  MLitBinary(AttributeValue<Rc<Vec<u8>>>),
  MLitByte(AttributeValue<u8>),
  MLitChar(AttributeValue<char>),
  MLitInt(AttributeValue<(u64, LitIntType)>),
  MLitFloat(AttributeValue<(InternedString, FloatTy)>),
  MLitFloatUnsuffixed(AttributeValue<InternedString>),
  MLitNil(AttributeValue<()>),
  MLitBool(AttributeValue<bool>)
}

pub struct AttributeDict
{
  dict: Vec<AttributeInfo>
}

impl AttributeDict
{
  pub fn new(dict: Vec<AttributeInfo>) -> AttributeDict
  {
    AttributeDict {
      dict: dict
    }
  }

  pub fn move_map(self, f: |AttributeInfo| -> AttributeInfo) -> AttributeDict
  {
    let mut this = self;
    this.dict = this.dict.move_iter().map(f).collect();
    this
  }

  pub fn push(&mut self, attr: AttributeInfo)
  {
    self.dict.push(attr);
  }

  pub fn get<'a>(&'a self, name: &'static str) -> &'a AttributeInfo
  {
    let interned = InternedString::new(name);
    for info in self.dict.iter() {
      if info.name == interned {
        return info;
      }
    }
    fail!("Try to get an attribute that doesn't exist.")
  }

  pub fn plain_value<'a>(&'a self, name: &'static str) -> &'a AttributeValue<bool>
  {
    self.get(name).plain_value()
  }

  pub fn sub_model<'a>(&'a self, name: &'static str) -> &'a AttributeDict
  {
    self.get(name).sub_model()
  }

  pub fn plain_value_or(&self, name: &'static str, def: bool) -> bool
  {
    self.plain_value(name).value_or(def)
  }

  // fn attribute_doc(&self)
  // {
  //   let mut doc = format!("Attribute `#[{}(<attribute list>)]`: {}\n",
  //       self.root_name.get(), self.root_desc);
  //   for info in self.infos.iter() {
  //     doc.add(format!("  * `#[{}({})]`: {}\n",
  //       self.root_name.get(), info.name, info.desc));
  //   }
  //   self.cx.parse_sess.span_diagnostic.handler.note(doc.as_slice());
  // }
}

impl AttributeLitModel
{
  pub fn to_lit_printer(&self) -> LitTypePrinter
  {
    match *self {
      MLitStr(_) => PLitStr,
      MLitBinary(_) => PLitBinary,
      MLitByte(_) => PLitByte,
      MLitChar(_) => PLitChar,
      MLitInt(_) => PLitInt,
      MLitFloat(_) => PLitFloat,
      MLitFloatUnsuffixed(_) => PLitFloatUnsuffixed,
      MLitNil(_) => PLitNil,
      MLitBool(_) => PLitBool
    }
  }
}

pub fn lit_to_lit_printer(lit: &Lit_) -> LitTypePrinter
{
  match *lit {
    LitStr(_, _) => PLitStr,
    LitBinary(_) => PLitBinary,
    LitByte(_) => PLitByte,
    LitChar(_) => PLitChar,
    LitInt(_, _) => PLitInt,
    LitFloat(_, _) => PLitFloat,
    LitFloatUnsuffixed(_) => PLitFloatUnsuffixed,
    LitNil => PLitNil,
    LitBool(_) => PLitBool
  }
}

pub enum LitTypePrinter
{
  PLitStr,
  PLitBinary,
  PLitByte,
  PLitChar,
  PLitInt,
  PLitFloat,
  PLitFloatUnsuffixed,
  PLitNil,
  PLitBool
}

impl LitTypePrinter
{
  pub fn type_to_str(&self) -> &'static str
  {
    match *self {
      PLitStr => "string",
      PLitBinary => "binary",
      PLitByte => "byte",
      PLitChar => "char",
      PLitInt => "int",
      PLitFloat => "float",
      PLitFloatUnsuffixed => "unsuffixed float",
      PLitNil => "nil",
      PLitBool => "boolean"
    }
  }

  pub fn type_example_to_str(&self) -> &'static str
  {
    match *self {
      PLitStr => "\"hello world\"",
      PLitBinary => "0b01010101",
      PLitByte => "b'9'",
      PLitChar => "'a'",
      PLitInt => "38",
      PLitFloat => "0.01f32",
      PLitFloatUnsuffixed => "0.1",
      PLitNil => "()",
      PLitBool => "true"
    }
  }
}
<commit_msg>[Extension] Add conveniency methods (span(), push_all(..)).<commit_after>// Copyright 2014 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

pub use compile_error::*;
pub use syntax::parse::token::InternedString;
pub use syntax::ast::*;

use syntax::codemap::DUMMY_SP;
use std::rc::Rc;

pub struct AttributeValue<T>
{
  value: Option<T>,
  duplicate: DuplicateAttribute,
  span: Span
}

impl<T: Clone> AttributeValue<T>
{
  pub fn new(duplicate: DuplicateAttribute) -> AttributeValue<T>
  {
    AttributeValue {
      value: None,
      duplicate: duplicate,
      span: DUMMY_SP
    }
  }

  pub fn simple() -> AttributeValue<T>
  {
    AttributeValue::new(DuplicateAttribute::simple(Warn))
  }

  pub fn update(self, cx: &ExtCtxt, value: T, span: Span) -> AttributeValue<T>
  {
    let mut this = self;
    if this.value.is_some() {
      this.duplicate.issue(cx, this.span, span);
    } else {
      this.value = Some(value);
      this.span = span;
    }
    this
  }

  pub fn value_or(&self, default: T) -> T
  {
    match self.value {
      None => default,
      Some(ref value) => value.clone()
    }
  }

  pub fn span(&self) -> Span
  {
    self.span.clone()
  }
}

pub struct AttributeInfo
{
  pub name: InternedString,
  pub desc: &'static str,
  pub model: AttributeModel
}

impl AttributeInfo
{
  pub fn new(name: &'static str, desc: &'static str,
    model: AttributeModel) -> AttributeInfo
  {
    AttributeInfo {
      name: InternedString::new(name),
      desc: desc,
      model: model
    }
  }

  pub fn simple(name: &'static str, desc: &'static str) -> AttributeInfo
  {
    AttributeInfo::new(name, desc, NoProperty(AttributeValue::simple()))
  }

  pub fn update(self, model: AttributeModel) -> AttributeInfo
  {
    let mut this = self;
    this.model = model;
    this
  }

  pub fn plain_value<'a>(&'a self) -> &'a AttributeValue<bool>
  {
    match self.model {
      NoProperty(ref v) => v,
      _ => fail!("No plain value for the current attribute.")
    }
  }

  pub fn sub_model<'a>(&'a self) -> &'a AttributeDict
  {
    match self.model {
      SubAttribute(ref dict) => dict,
      _ => fail!("No sub value for the attribute.")
    }
  }
}

pub enum AttributeModel
{
  NoProperty(AttributeValue<bool>),
  KeyValue(AttributeLitModel),
  SubAttribute(AttributeDict)
}

pub enum AttributeLitModel
{
  MLitStr(AttributeValue<(InternedString, StrStyle)>),
  MLitBinary(AttributeValue<Rc<Vec<u8>>>),
  MLitByte(AttributeValue<u8>),
  MLitChar(AttributeValue<char>),
  MLitInt(AttributeValue<(u64, LitIntType)>),
  MLitFloat(AttributeValue<(InternedString, FloatTy)>),
  MLitFloatUnsuffixed(AttributeValue<InternedString>),
  MLitNil(AttributeValue<()>),
  MLitBool(AttributeValue<bool>)
}

pub struct AttributeDict
{
  dict: Vec<AttributeInfo>
}

impl AttributeDict
{
  pub fn new(dict: Vec<AttributeInfo>) -> AttributeDict
  {
    AttributeDict {
      dict: dict
    }
  }

  pub fn move_map(self, f: |AttributeInfo| -> AttributeInfo) -> AttributeDict
  {
    let mut this = self;
    this.dict = this.dict.move_iter().map(f).collect();
    this
  }

  pub fn push(&mut self, attr: AttributeInfo)
  {
    self.dict.push(attr);
  }

  pub fn push_all(&mut self, attrs: Vec<AttributeInfo>)
  {
    self.dict.push_all_move(attrs);
  }

  pub fn get<'a>(&'a self, name: &'static str) -> &'a AttributeInfo
  {
    let interned = InternedString::new(name);
    for info in self.dict.iter() {
      if info.name == interned {
        return info;
      }
    }
    fail!("Try to get an attribute that doesn't exist.")
  }

  pub fn plain_value<'a>(&'a self, name: &'static str) -> &'a AttributeValue<bool>
  {
    self.get(name).plain_value()
  }

  pub fn sub_model<'a>(&'a self, name: &'static str) -> &'a AttributeDict
  {
    self.get(name).sub_model()
  }

  pub fn plain_value_or(&self, name: &'static str, def: bool) -> bool
  {
    self.plain_value(name).value_or(def)
  }

  // fn attribute_doc(&self)
  // {
  //   let mut doc = format!("Attribute `#[{}(<attribute list>)]`: {}\n",
  //       self.root_name.get(), self.root_desc);
  //   for info in self.infos.iter() {
  //     doc.add(format!("  * `#[{}({})]`: {}\n",
  //       self.root_name.get(), info.name, info.desc));
  //   }
  //   self.cx.parse_sess.span_diagnostic.handler.note(doc.as_slice());
  // }
}

impl AttributeLitModel
{
  pub fn to_lit_printer(&self) -> LitTypePrinter
  {
    match *self {
      MLitStr(_) => PLitStr,
      MLitBinary(_) => PLitBinary,
      MLitByte(_) => PLitByte,
      MLitChar(_) => PLitChar,
      MLitInt(_) => PLitInt,
      MLitFloat(_) => PLitFloat,
      MLitFloatUnsuffixed(_) => PLitFloatUnsuffixed,
      MLitNil(_) => PLitNil,
      MLitBool(_) => PLitBool
    }
  }
}

pub fn lit_to_lit_printer(lit: &Lit_) -> LitTypePrinter
{
  match *lit {
    LitStr(_, _) => PLitStr,
    LitBinary(_) => PLitBinary,
    LitByte(_) => PLitByte,
    LitChar(_) => PLitChar,
    LitInt(_, _) => PLitInt,
    LitFloat(_, _) => PLitFloat,
    LitFloatUnsuffixed(_) => PLitFloatUnsuffixed,
    LitNil => PLitNil,
    LitBool(_) => PLitBool
  }
}

pub enum LitTypePrinter
{
  PLitStr,
  PLitBinary,
  PLitByte,
  PLitChar,
  PLitInt,
  PLitFloat,
  PLitFloatUnsuffixed,
  PLitNil,
  PLitBool
}

impl LitTypePrinter
{
  pub fn type_to_str(&self) -> &'static str
  {
    match *self {
      PLitStr => "string",
      PLitBinary => "binary",
      PLitByte => "byte",
      PLitChar => "char",
      PLitInt => "int",
      PLitFloat => "float",
      PLitFloatUnsuffixed => "unsuffixed float",
      PLitNil => "nil",
      PLitBool => "boolean"
    }
  }

  pub fn type_example_to_str(&self) -> &'static str
  {
    match *self {
      PLitStr => "\"hello world\"",
      PLitBinary => "0b01010101",
      PLitByte => "b'9'",
      PLitChar => "'a'",
      PLitInt => "38",
      PLitFloat => "0.01f32",
      PLitFloatUnsuffixed => "0.1",
      PLitNil => "()",
      PLitBool => "true"
    }
  }
}
<|endoftext|>


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

#![cfg(not(target_arch = "wasm32"))]

use std::i16;
use std::mem;
use std::str;

use core::num::flt2dec::MAX_SIG_DIGITS;
use core::num::flt2dec::strategy::grisu::format_exact_opt;
use core::num::flt2dec::strategy::grisu::format_shortest_opt;
use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};

use rand::{self, Rand, XorShiftRng};
use rand::distributions::{IndependentSample, Range};

pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
    match decode(v).1 {
        FullDecoded::Finite(decoded) => decoded,
        full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
    }
}

fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V) -> (usize, usize)
        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
              V: FnMut(usize) -> Decoded {
    assert!(k <= 1024);

    let mut npassed = 0; // f(x) = Some(g(x))
    let mut nignored = 0; // f(x) = None

    for i in 0..n {
        if (i & 0xfffff) == 0 {
            println!("in progress, {:x}/{:x} (ignored={} passed={} failed={})",
                     i, n, nignored, npassed, i - nignored - npassed);
        }

        let decoded = v(i);
        let mut buf1 = [0; 1024];
        if let Some((len1, e1)) = f(&decoded, &mut buf1[..k]) {
            let mut buf2 = [0; 1024];
            let (len2, e2) = g(&decoded, &mut buf2[..k]);
            if e1 == e2 && &buf1[..len1] == &buf2[..len2] {
                npassed += 1;
            } else {
                println!("equivalence test failed, {:x}/{:x}: {:?} f(i)={}e{} g(i)={}e{}",
                         i, n, decoded, str::from_utf8(&buf1[..len1]).unwrap(), e1,
                                        str::from_utf8(&buf2[..len2]).unwrap(), e2);
            }
        } else {
            nignored += 1;
        }
    }
    println!("{}({}): done, ignored={} passed={} failed={}",
             func, k, nignored, npassed, n - nignored - npassed);
    assert!(nignored + npassed == n,
            "{}({}): {} out of {} values returns an incorrect value!",
            func, k, n - nignored - npassed, n);
    (npassed, nignored)
}

pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
    let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng());
    let f32_range = Range::new(0x0000_0001u32, 0x7f80_0000);
    iterate("f32_random_equivalence_test", k, n, f, g, |_| {
        let i: u32 = f32_range.ind_sample(&mut rng);
        let x: f32 = unsafe {mem::transmute(i)};
        decode_finite(x)
    });
}

pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
    let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng());
    let f64_range = Range::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
    iterate("f64_random_equivalence_test", k, n, f, g, |_| {
        let i: u64 = f64_range.ind_sample(&mut rng);
        let x: f64 = unsafe {mem::transmute(i)};
        decode_finite(x)
    });
}

pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
    // we have only 2^23 * (2^8 - 1) - 1 = 2,139,095,039 positive finite f32 values,
    // so why not simply testing all of them?
    //
    // this is of course very stressful (and thus should be behind an `#[ignore]` attribute),
    // but with `-C opt-level=3 -C lto` this only takes about an hour or so.

    // iterate from 0x0000_0001 to 0x7f7f_ffff, i.e. all finite ranges
    let (npassed, nignored) = iterate("f32_exhaustive_equivalence_test",
                                      k, 0x7f7f_ffff, f, g, |i: usize| {
        let x: f32 = unsafe {mem::transmute(i as u32 + 1)};
        decode_finite(x)
    });
    assert_eq!((npassed, nignored), (2121451881, 17643158));
}

#[test]
fn shortest_random_equivalence_test() {
    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
    f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
    f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
}

#[test] #[ignore] // it is too expensive
fn shortest_f32_exhaustive_equivalence_test() {
    // it is hard to directly test the optimality of the output, but we can at least test if
    // two different algorithms agree to each other.
    //
    // this reports the progress and the number of f32 values returned `None`.
    // with `--nocapture` (and plenty of time and appropriate rustc flags), this should print:
    // `done, ignored=17643158 passed=2121451881 failed=0`.

    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
    f32_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
}

#[test] #[ignore] // it is too expensive
fn shortest_f64_hard_random_equivalence_test() {
    // this again probably has to use appropriate rustc flags.

    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
    f64_random_equivalence_test(format_shortest_opt, fallback,
                                         MAX_SIG_DIGITS, 100_000_000);
}

#[test]
fn exact_f32_random_equivalence_test() {
    use core::num::flt2dec::strategy::dragon::format_exact as fallback;
    for k in 1..21 {
        f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
    }
}

#[test]
fn exact_f64_random_equivalence_test() {
    use core::num::flt2dec::strategy::dragon::format_exact as fallback;
    for k in 1..21 {
        f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
    }
}

<commit_msg>Rollup merge of #50464 - est31:master, r=rkruppe<commit_after>// Copyright 2017 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.

#![cfg(not(target_arch = "wasm32"))]

use std::i16;
use std::str;

use core::num::flt2dec::MAX_SIG_DIGITS;
use core::num::flt2dec::strategy::grisu::format_exact_opt;
use core::num::flt2dec::strategy::grisu::format_shortest_opt;
use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};

use rand::{self, Rand, XorShiftRng};
use rand::distributions::{IndependentSample, Range};

pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
    match decode(v).1 {
        FullDecoded::Finite(decoded) => decoded,
        full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
    }
}

fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V) -> (usize, usize)
        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
              V: FnMut(usize) -> Decoded {
    assert!(k <= 1024);

    let mut npassed = 0; // f(x) = Some(g(x))
    let mut nignored = 0; // f(x) = None

    for i in 0..n {
        if (i & 0xfffff) == 0 {
            println!("in progress, {:x}/{:x} (ignored={} passed={} failed={})",
                     i, n, nignored, npassed, i - nignored - npassed);
        }

        let decoded = v(i);
        let mut buf1 = [0; 1024];
        if let Some((len1, e1)) = f(&decoded, &mut buf1[..k]) {
            let mut buf2 = [0; 1024];
            let (len2, e2) = g(&decoded, &mut buf2[..k]);
            if e1 == e2 && &buf1[..len1] == &buf2[..len2] {
                npassed += 1;
            } else {
                println!("equivalence test failed, {:x}/{:x}: {:?} f(i)={}e{} g(i)={}e{}",
                         i, n, decoded, str::from_utf8(&buf1[..len1]).unwrap(), e1,
                                        str::from_utf8(&buf2[..len2]).unwrap(), e2);
            }
        } else {
            nignored += 1;
        }
    }
    println!("{}({}): done, ignored={} passed={} failed={}",
             func, k, nignored, npassed, n - nignored - npassed);
    assert!(nignored + npassed == n,
            "{}({}): {} out of {} values returns an incorrect value!",
            func, k, n - nignored - npassed, n);
    (npassed, nignored)
}

pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
    let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng());
    let f32_range = Range::new(0x0000_0001u32, 0x7f80_0000);
    iterate("f32_random_equivalence_test", k, n, f, g, |_| {
        let x = f32::from_bits(f32_range.ind_sample(&mut rng));
        decode_finite(x)
    });
}

pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
    let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng());
    let f64_range = Range::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
    iterate("f64_random_equivalence_test", k, n, f, g, |_| {
        let x = f64::from_bits(f64_range.ind_sample(&mut rng));
        decode_finite(x)
    });
}

pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
    // we have only 2^23 * (2^8 - 1) - 1 = 2,139,095,039 positive finite f32 values,
    // so why not simply testing all of them?
    //
    // this is of course very stressful (and thus should be behind an `#[ignore]` attribute),
    // but with `-C opt-level=3 -C lto` this only takes about an hour or so.

    // iterate from 0x0000_0001 to 0x7f7f_ffff, i.e. all finite ranges
    let (npassed, nignored) = iterate("f32_exhaustive_equivalence_test",
                                      k, 0x7f7f_ffff, f, g, |i: usize| {

        let x = f32::from_bits(i as u32 + 1);
        decode_finite(x)
    });
    assert_eq!((npassed, nignored), (2121451881, 17643158));
}

#[test]
fn shortest_random_equivalence_test() {
    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
    f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
    f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
}

#[test] #[ignore] // it is too expensive
fn shortest_f32_exhaustive_equivalence_test() {
    // it is hard to directly test the optimality of the output, but we can at least test if
    // two different algorithms agree to each other.
    //
    // this reports the progress and the number of f32 values returned `None`.
    // with `--nocapture` (and plenty of time and appropriate rustc flags), this should print:
    // `done, ignored=17643158 passed=2121451881 failed=0`.

    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
    f32_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
}

#[test] #[ignore] // it is too expensive
fn shortest_f64_hard_random_equivalence_test() {
    // this again probably has to use appropriate rustc flags.

    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
    f64_random_equivalence_test(format_shortest_opt, fallback,
                                         MAX_SIG_DIGITS, 100_000_000);
}

#[test]
fn exact_f32_random_equivalence_test() {
    use core::num::flt2dec::strategy::dragon::format_exact as fallback;
    for k in 1..21 {
        f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
    }
}

#[test]
fn exact_f64_random_equivalence_test() {
    use core::num::flt2dec::strategy::dragon::format_exact as fallback;
    for k in 1..21 {
        f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
    }
}

<|endoftext|>


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

//! The Rust Prelude
//!
//! Because `std` is required by most serious Rust software, it is
//! imported at the topmost level of every crate by default, as if the
//! first line of each crate was
//!
//! ```ignore
//! extern crate std;
//! ```
//!
//! This means that the contents of std can be accessed from any context
//! with the `std::` path prefix, as in `use std::vec`, `use std::thread::spawn`,
//! etc.
//!
//! Additionally, `std` contains a versioned *prelude* that reexports many of the
//! most common traits, types and functions. *The contents of the prelude are
//! imported into every module by default*.  Implicitly, all modules behave as if
//! they contained the following [`use` statement][book-use]:
//!
//! [book-use]: ../../book/crates-and-modules.html#importing-modules-with-use
//!
//! ```ignore
//! use std::prelude::v1::*;
//! ```
//!
//! The prelude is primarily concerned with exporting *traits* that
//! are so pervasive that they would be onerous to import for every use,
//! particularly those that are commonly mentioned in [generic type
//! bounds][book-traits].
//!
//! The current version of the prelude (version 1) lives in
//! [`std::prelude::v1`](v1/index.html), and reexports the following.
//!
//! * `std::marker::`{
//!     [`Copy`](../marker/trait.Copy.html),
//!     [`Send`](../marker/trait.Send.html),
//!     [`Sized`](../marker/trait.Sized.html),
//!     [`Sync`](../marker/trait.Sync.html)
//!   }.
//!   The marker traits indicate fundamental properties of types.
//! * `std::ops::`{
//!     [`Drop`](../ops/trait.Drop.html),
//!     [`Fn`](../ops/trait.Fn.html),
//!     [`FnMut`](../ops/trait.FnMut.html),
//!     [`FnOnce`](../ops/trait.FnOnce.html)
//!   }.
//!   The [destructor][book-dtor] trait and the
//!   [closure][book-closures] traits, reexported from the same
//!   [module that also defines overloaded
//!   operators](../ops/index.html).
//! * `std::mem::`[`drop`](../mem/fn.drop.html).
//!   A convenience function for explicitly dropping a value.
//! * `std::boxed::`[`Box`](../boxed/struct.Box.html).
//!   The owned heap pointer.
//! * `std::borrow::`[`ToOwned`](../borrow/trait.ToOwned.html).
//!   The conversion trait that defines `to_owned`, the generic method
//!   for creating an owned type from a borrowed type.
//! * `std::clone::`[`Clone`](../clone/trait.Clone.html).
//!   The ubiquitous trait that defines `clone`, the method for
//!   producing copies of values that are consider expensive to copy.
//! * `std::cmp::`{
//!     [`PartialEq`](../cmp/trait.PartialEq.html),
//!     [`PartialOrd`](../cmp/trait.PartialOrd.html),
//!     [`Eq`](../cmp/trait.Eq.html),
//!     [`Ord`](../cmp/trait.Ord.html)
//!   }.
//!   The comparision traits, which implement the comparison operators
//!   and are often seen in trait bounds.
//! * `std::convert::`{
//!     [`AsRef`](../convert/trait.AsRef.html),
//!     [`AsMut`](../convert/trait.AsMut.html),
//!     [`Into`](../convert/trait.Into.html),
//!     [`From`](../convert/trait.From.html)
//!   }.
//!   Generic conversions, used by savvy API authors to create
//!   overloaded methods.
//! * `std::default::`[`Default`](../default/trait.Default).
//!   Types that have default values.
//! * `std::iter::`{
//!     [`Iterator`](../iter/trait.Iterator.html),
//!     [`Extend`](../iter/trait.Extend.html),
//!     [`IntoIterator`](../iter/trait.IntoIterator.html),
//!     [`DoubleEndedIterator`](../iter/trait.DoubleEndedIterator.html),
//!     [`ExactSizeIterator`](../iter/trait.ExactSizeIterator.html)
//!   }.
//!   [Iterators][book-iter].
//! * `std::option::Option::`{
//!     [`self`](../option/enum.Option.html),
//!     [`Some`](../option/enum.Option.html),
//!     [`None`](../option/enum.Option.html)
//!   }.
//!   The ubiquitous `Option` type and its two [variants][book-enums],
//!   `Some` and `None`.
//! * `std::result::Result::`{
//!     [`self`](../result/enum.Result.html),
//!     [`Some`](../result/enum.Result.html),
//!     [`None`](../result/enum.Result.html)
//!   }.
//!   The ubiquitous `Result` type and its two [variants][book-enums],
//!   `Ok` and `Err`.
//! * `std::slice::`[`SliceConcatExt`](../slice/trait.SliceConcatExt.html).
//!   An unstable extension to slices that shouldn't have to exist.
//! * `std::string::`{
//!     [`String`](../string/struct.String.html),
//!     [`ToString`](../string/trait.ToString.html)
//!   }.
//!   Heap allocated strings.
//! * `std::vec::`[`Vec`](../vec/struct.Vec.html).
//!   Heap allocated vectors.
//!
//! [book-traits]: ../../book/traits.html
//! [book-closures]: ../../book/closures.html
//! [book-dtor]: ../../book/drop.html
//! [book-iter]: ../../book/iterators.html
//! [book-enums]: ../../book/enums.html

#![stable(feature = "rust1", since = "1.0.0")]

pub mod v1;
<commit_msg>Rollup merge of #27398 - tshepang:patch-5, r=steveklabnik<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The Rust Prelude
//!
//! Because `std` is required by most serious Rust software, it is
//! imported at the topmost level of every crate by default, as if
//! each crate contains the following:
//!
//! ```ignore
//! extern crate std;
//! ```
//!
//! This means that the contents of std can be accessed from any context
//! with the `std::` path prefix, as in `use std::vec`, `use std::thread::spawn`,
//! etc.
//!
//! Additionally, `std` contains a versioned *prelude* that reexports many of the
//! most common traits, types, and functions. *The contents of the prelude are
//! imported into every module by default*.  Implicitly, all modules behave as if
//! they contained the following [`use` statement][book-use]:
//!
//! [book-use]: ../../book/crates-and-modules.html#importing-modules-with-use
//!
//! ```ignore
//! use std::prelude::v1::*;
//! ```
//!
//! The prelude is primarily concerned with exporting *traits* that
//! are so pervasive that they would be onerous to import for every use,
//! particularly those that are commonly mentioned in [generic type
//! bounds][book-traits].
//!
//! The current version of the prelude (version 1) lives in
//! [`std::prelude::v1`](v1/index.html), and reexports the following.
//!
//! * `std::marker::`{
//!     [`Copy`](../marker/trait.Copy.html),
//!     [`Send`](../marker/trait.Send.html),
//!     [`Sized`](../marker/trait.Sized.html),
//!     [`Sync`](../marker/trait.Sync.html)
//!   }.
//!   The marker traits indicate fundamental properties of types.
//! * `std::ops::`{
//!     [`Drop`](../ops/trait.Drop.html),
//!     [`Fn`](../ops/trait.Fn.html),
//!     [`FnMut`](../ops/trait.FnMut.html),
//!     [`FnOnce`](../ops/trait.FnOnce.html)
//!   }.
//!   The [destructor][book-dtor] trait and the
//!   [closure][book-closures] traits, reexported from the same
//!   [module that also defines overloaded
//!   operators](../ops/index.html).
//! * `std::mem::`[`drop`](../mem/fn.drop.html).
//!   A convenience function for explicitly dropping a value.
//! * `std::boxed::`[`Box`](../boxed/struct.Box.html).
//!   The owned heap pointer.
//! * `std::borrow::`[`ToOwned`](../borrow/trait.ToOwned.html).
//!   The conversion trait that defines `to_owned`, the generic method
//!   for creating an owned type from a borrowed type.
//! * `std::clone::`[`Clone`](../clone/trait.Clone.html).
//!   The ubiquitous trait that defines `clone`, the method for
//!   producing copies of values that are consider expensive to copy.
//! * `std::cmp::`{
//!     [`PartialEq`](../cmp/trait.PartialEq.html),
//!     [`PartialOrd`](../cmp/trait.PartialOrd.html),
//!     [`Eq`](../cmp/trait.Eq.html),
//!     [`Ord`](../cmp/trait.Ord.html)
//!   }.
//!   The comparision traits, which implement the comparison operators
//!   and are often seen in trait bounds.
//! * `std::convert::`{
//!     [`AsRef`](../convert/trait.AsRef.html),
//!     [`AsMut`](../convert/trait.AsMut.html),
//!     [`Into`](../convert/trait.Into.html),
//!     [`From`](../convert/trait.From.html)
//!   }.
//!   Generic conversions, used by savvy API authors to create
//!   overloaded methods.
//! * `std::default::`[`Default`](../default/trait.Default).
//!   Types that have default values.
//! * `std::iter::`{
//!     [`Iterator`](../iter/trait.Iterator.html),
//!     [`Extend`](../iter/trait.Extend.html),
//!     [`IntoIterator`](../iter/trait.IntoIterator.html),
//!     [`DoubleEndedIterator`](../iter/trait.DoubleEndedIterator.html),
//!     [`ExactSizeIterator`](../iter/trait.ExactSizeIterator.html)
//!   }.
//!   [Iterators][book-iter].
//! * `std::option::Option::`{
//!     [`self`](../option/enum.Option.html),
//!     [`Some`](../option/enum.Option.html),
//!     [`None`](../option/enum.Option.html)
//!   }.
//!   The ubiquitous `Option` type and its two [variants][book-enums],
//!   `Some` and `None`.
//! * `std::result::Result::`{
//!     [`self`](../result/enum.Result.html),
//!     [`Some`](../result/enum.Result.html),
//!     [`None`](../result/enum.Result.html)
//!   }.
//!   The ubiquitous `Result` type and its two [variants][book-enums],
//!   `Ok` and `Err`.
//! * `std::slice::`[`SliceConcatExt`](../slice/trait.SliceConcatExt.html).
//!   An unstable extension to slices that shouldn't have to exist.
//! * `std::string::`{
//!     [`String`](../string/struct.String.html),
//!     [`ToString`](../string/trait.ToString.html)
//!   }.
//!   Heap allocated strings.
//! * `std::vec::`[`Vec`](../vec/struct.Vec.html).
//!   Heap allocated vectors.
//!
//! [book-traits]: ../../book/traits.html
//! [book-closures]: ../../book/closures.html
//! [book-dtor]: ../../book/drop.html
//! [book-iter]: ../../book/iterators.html
//! [book-enums]: ../../book/enums.html

#![stable(feature = "rust1", since = "1.0.0")]

pub mod v1;
<|endoftext|>


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

use option::{Option, Some, None};
use result::{Ok, Err};
use rt::io::{io_error};
use rt::rtio::{IoFactory, IoFactoryObject,
               RtioTimer, RtioTimerObject};
use rt::local::Local;

pub struct Timer(~RtioTimerObject);

impl Timer {

    pub fn new() -> Option<Timer> {
        let timer = unsafe {
            rtdebug!("Timer::init: borrowing io to init timer");
            let io: *mut IoFactoryObject = Local::unsafe_borrow();
            rtdebug!("about to init timer");
            (*io).timer_init()
        };
        match timer {
            Ok(t) => Some(Timer(t)),
            Err(ioerr) => {
                rtdebug!("Timer::init: failed to init: %?", ioerr);
                io_error::cond.raise(ioerr);
                None
            }
        }
    }

    pub fn sleep(&mut self, msecs: u64) {
        (**self).sleep(msecs);
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use rt::test::*;
    #[test]
    fn test_io_timer_sleep_simple() {
        do run_in_mt_newsched_task {
            let timer = Timer::new();
            do timer.map_move |mut t| { t.sleep(1) };
        }
    }
}
<commit_msg>auto merge of #9191 : huonw/rust/are-you-tired, r=cmr<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use option::{Option, Some, None};
use result::{Ok, Err};
use rt::io::{io_error};
use rt::rtio::{IoFactory, IoFactoryObject,
               RtioTimer, RtioTimerObject};
use rt::local::Local;

pub struct Timer(~RtioTimerObject);

/// Sleep the current task for `msecs` milliseconds.
pub fn sleep(msecs: u64) {
    let mut timer = Timer::new().expect("timer::sleep: could not create a Timer");

    timer.sleep(msecs)
}

impl Timer {

    pub fn new() -> Option<Timer> {
        let timer = unsafe {
            rtdebug!("Timer::init: borrowing io to init timer");
            let io: *mut IoFactoryObject = Local::unsafe_borrow();
            rtdebug!("about to init timer");
            (*io).timer_init()
        };
        match timer {
            Ok(t) => Some(Timer(t)),
            Err(ioerr) => {
                rtdebug!("Timer::init: failed to init: %?", ioerr);
                io_error::cond.raise(ioerr);
                None
            }
        }
    }

    pub fn sleep(&mut self, msecs: u64) {
        (**self).sleep(msecs);
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use rt::test::*;
    #[test]
    fn test_io_timer_sleep_simple() {
        do run_in_mt_newsched_task {
            let timer = Timer::new();
            do timer.map_move |mut t| { t.sleep(1) };
        }
    }

    #[test]
    fn test_io_timer_sleep_standalone() {
        do run_in_mt_newsched_task {
            sleep(1)
        }
    }
}
<|endoftext|>


<commit_before>use luminance::{Dim2, Flat, Mode, RGBA32F, Unit};
use luminance_gl::gl33::{Framebuffer, Pipe, Pipeline, RenderCommand, ShadingCommand, Tessellation,
                         Texture, Uniform};

use compositor::{Compositor, Screen};
use id::Id;
use scene::Scene;
use shader::Program;

pub type Texture2D<A> = Texture<Flat, Dim2, A>;

const FORWARD_SOURCE: Uniform<Unit> = Uniform::new(0);

pub struct Forward<'a> {
  program: Id<'a, Program>,
  quad: Tessellation,
  w: u32,
  h: u32
}

impl<'a> Forward<'a> {
  pub fn new_from(w: u32, h: u32, scene: &mut Scene<'a>) -> Self {
    let program = get_id!(scene, "spectra/compositors/forward.glsl", vec![Uniform::<Unit>::sem("source")]).unwrap();

    // update the texture uniform once and for all
    {
      let program: &Program = &scene.get_by_id(&program).unwrap();
      program.update(&FORWARD_SOURCE, Unit::new(0));
    }

    Forward {
      program: program,
      quad: Tessellation::attributeless(Mode::TriangleStrip, 4),
      w: w,
      h: h
    }
  }
}

impl<'a, 'b> Compositor<'a, 'b, &'a Texture2D<RGBA32F>> for Forward<'b> {
  fn composite(&'a self, scene: &'a mut Scene<'b>, source: &'a Texture2D<RGBA32F>) -> Screen<'a> {
    let program = scene.get_by_id(&self.program).unwrap();
    let back_fb = Framebuffer::default((self.w, self.h));
    let textures = &[source.into()];

    Pipeline::new(&back_fb, [0., 0., 0., 0.], textures, &[], vec![
      Pipe::new(|_| {}, ShadingCommand::new(&program, vec![
        Pipe::new(|_| {}, RenderCommand::new(None, true, vec![
          Pipe::new(|_|{}, &self.quad)], 1, None))
        ]))
    ]).run();

    Screen::Display
  }
}
<commit_msg>Forward::new_from -> Forward::new.<commit_after>use luminance::{Dim2, Flat, Mode, RGBA32F, Unit};
use luminance_gl::gl33::{Framebuffer, Pipe, Pipeline, RenderCommand, ShadingCommand, Tessellation,
                         Texture, Uniform};

use compositor::{Compositor, Screen};
use id::Id;
use scene::Scene;
use shader::Program;

pub type Texture2D<A> = Texture<Flat, Dim2, A>;

const FORWARD_SOURCE: Uniform<Unit> = Uniform::new(0);

pub struct Forward<'a> {
  program: Id<'a, Program>,
  quad: Tessellation,
  w: u32,
  h: u32
}

impl<'a> Forward<'a> {
  pub fn new(w: u32, h: u32, scene: &mut Scene<'a>) -> Self {
    let program = get_id!(scene, "spectra/compositors/forward.glsl", vec![Uniform::<Unit>::sem("source")]).unwrap();

    // update the texture uniform once and for all
    {
      let program: &Program = &scene.get_by_id(&program).unwrap();
      program.update(&FORWARD_SOURCE, Unit::new(0));
    }

    Forward {
      program: program,
      quad: Tessellation::attributeless(Mode::TriangleStrip, 4),
      w: w,
      h: h
    }
  }
}

impl<'a, 'b> Compositor<'a, 'b, &'a Texture2D<RGBA32F>> for Forward<'b> {
  fn composite(&'a self, scene: &'a mut Scene<'b>, source: &'a Texture2D<RGBA32F>) -> Screen<'a> {
    let program = scene.get_by_id(&self.program).unwrap();
    let back_fb = Framebuffer::default((self.w, self.h));
    let textures = &[source.into()];

    Pipeline::new(&back_fb, [0., 0., 0., 0.], textures, &[], vec![
      Pipe::new(|_| {}, ShadingCommand::new(&program, vec![
        Pipe::new(|_| {}, RenderCommand::new(None, true, vec![
          Pipe::new(|_|{}, &self.quad)], 1, None))
        ]))
    ]).run();

    Screen::Display
  }
}
<|endoftext|>


<commit_before>// main.rs
#![feature(plugin)]
#![plugin(docopt_macros)]

extern crate rustc_serialize;
extern crate docopt;
extern crate regex;

use std::fmt::{ Display, Formatter };
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::OpenOptions;
use std::io::BufWriter;
use std::path::Path;
// https://github.com/docopt/docopt.rs
use docopt::Docopt;

// https://doc.rust-lang.org/regex/regex/index.html
use regex::Regex;

docopt!(Args derive Debug, "
Alexey Mekhanoshin

Usage:
	rus_fritz -e <engfile>  -r <rusfile> ( -o <outfile> | --stdout )
	rus_fritz (-h | --help)
	rus_fritz --version
Options:
  -h --help		Show this screen.
  --version		Show version.
");

struct EnglishName {
    name: String,
    opis: String,
}

struct RussianName {
    name: String,
    opis: String,
    using: bool,
}

impl EnglishName {
    fn new<S: Into<String>>(name: S, opis: S) -> EnglishName {
        EnglishName {
            name: name.into(),
            opis: opis.into(),
        }
    }
}

impl RussianName {
    fn new<S: Into<String>>(name: S, opis: S) -> RussianName {
        RussianName {
            name: name.into(),
            opis: opis.into(),
            using: false,
        }
    }
}

impl std::fmt::Display for EnglishName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(f, "Display Eng: {},\t\t\t{}", self.name, self.opis)
    }
}

impl std::fmt::Display for RussianName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(f, "Display Rus: {},\t\t\t{}", self.name, self.opis)
    }
}

fn open_any_file(file_name: &String) -> BufReader<File> {
    let path = Path::new(file_name);
    let display = path.display();
    let file = match File::open(path) {
        Ok(f) => f,
        Err(why) => panic!("Not open file {}: {}", display, Error::description(&why) ),
    };
    let reader = BufReader::new(file);
    return reader;
}

fn create_out_file(file_name: &String) -> BufWriter<File> {
    let path = Path::new(file_name);
    let display = path.display();
    let mut options = OpenOptions::new();
    let file = match options.create(true).write(true).truncate(true).open(path) {
	    Ok(file) => file,
	    Err(why) => panic!("Not create/open file {}: {}", display, Error::description(&why)),
	};
    let writer = BufWriter::new(file);
    return writer;
}

fn main() {

    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
    if args.flag_stdout {
        println!("{:?}", args);
        if args.flag_h { println!("Print Help coming soon ..." ); return; }
        if args.flag_version { println!("Print Version coming soon ..." ); return; }
    }

    let mut engvec: Vec<EnglishName> = Vec::new();
    let mut rusvec: Vec<RussianName> = Vec::new();
/*
    open_eng_file(&mut engvec, &args.arg_engfile.to_string());
    assert!( !engvec.is_empty() );
    open_rus_file(&mut rusvec, &args.arg_rusfile.to_string());
    assert!( !rusvec.is_empty() );
*/
    let re = Regex::new(r"(.*)(,)(.*)(\x22.*\x22)").unwrap();
    // Create English Vector
    for line in open_any_file(&args.arg_engfile.to_string()).lines() {
        let s = line.unwrap();
        for cap in re.captures_iter(&s) {
            let ubs = EnglishName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
            engvec.push(ubs);
        }
    }
    assert!( !engvec.is_empty() );
    // Create Russian Vector
    for line in open_any_file(&args.arg_rusfile.to_string()).lines() {
        let s = line.unwrap();
        for cap in re.captures_iter(&s) {
            let ubs = RussianName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
            rusvec.push(ubs);
        }
    }
    assert!( !rusvec.is_empty() );

	//  Подготовка закончилась, начинаем работу.

    if args.flag_stdout {
        println!("/*\n\tRecreated by RusFritz project\n*/");
    } else {
		// Write to file
    }

    let mut i=0;
    let mut found = false;
    let mut outstr = String::new();

    for e in &mut engvec {
        i = i+1;
        for r in &mut rusvec {
            if e.name == r.name {
                e.opis = r.opis.clone();
                found = true;
                r.using = true;
                if args.flag_stdout {
                    println!("{},\t\t{};", r.name, r.opis);
                } else {
                    let s = String::from( format!("{},\t\t{};\n", r.name, r.opis) );
                    outstr.push_str(&s);
                }
            }
        }
        if !found {
            //println!("ERR: {} - не найдено соответствие", e.name );
            if args.flag_stdout {
                println!("{},\t\t{};",e.name, e.opis);
            } else {
                // Wite output to file
            }
        }
        found = false;
    }
    // Print if not using from Russian Names
    println!("------ Not using Found from Russian File --------");
    for r in rusvec {
        if r.using == false {
            println!("{},\t\t{}",r.name,r.opis);
        }
    }

    // File write, if needed
    if args.flag_stdout == false {
        let mut wr = create_out_file(&args.arg_outfile.to_string());
        if outstr.len() > 0 {
            match wr.write_all(&outstr.as_bytes()) {
                Err(why) => {
                    panic!("couldn't write to{}: {}",
                        &args.arg_outfile.to_string(),
                        Error::description(&why))
                },
                Ok(_) => println!("Good write file"),
            };
            wr.flush();
        }
    }
    //println!("Обработано {} строк из {}",i, engvec.len());
    //let writer = std::io::file_writer(&Path(std::os::args()[2]), [io::Append, io::Create]).unwrap();
}
<commit_msg>Add AskMe Translate for stdin input<commit_after>// main.rs
#![feature(plugin)]
#![plugin(docopt_macros)]

extern crate rustc_serialize;
extern crate docopt;
extern crate regex;

use std::io;
use std::fmt::{ Display, Formatter };
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::OpenOptions;
use std::io::BufWriter;
use std::path::Path;
// https://github.com/docopt/docopt.rs
use docopt::Docopt;

// https://doc.rust-lang.org/regex/regex/index.html
use regex::Regex;

docopt!(Args derive Debug, "
Alexey Mekhanoshin

Usage:
	rus_fritz -e <engfile>  -r <rusfile> ( -o <outfile> | --stdout ) [--askme]
	rus_fritz (-h | --help)
	rus_fritz --version
Options:
  -h --help		Show this screen.
  --version		Show version.
  --askme		Ask Me for translate
");

struct EnglishName {
    name: String,
    opis: String,
}

struct RussianName {
    name: String,
    opis: String,
    using: bool,
}

impl EnglishName {
    fn new<S: Into<String>>(name: S, opis: S) -> EnglishName {
        EnglishName {
            name: name.into(),
            opis: opis.into(),
        }
    }
}

impl RussianName {
    fn new<S: Into<String>>(name: S, opis: S) -> RussianName {
        RussianName {
            name: name.into(),
            opis: opis.into(),
            using: false,
        }
    }
}

impl std::fmt::Display for EnglishName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(f, "Display Eng: {},\t\t\t{}", self.name, self.opis)
    }
}

impl std::fmt::Display for RussianName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(f, "Display Rus: {},\t\t\t{}", self.name, self.opis)
    }
}

fn open_any_file(file_name: &String) -> BufReader<File> {
    let path = Path::new(file_name);
    let display = path.display();
    let file = match File::open(path) {
        Ok(f) => f,
        Err(why) => panic!("Not open file {}: {}", display, Error::description(&why) ),
    };
    let reader = BufReader::new(file);
    return reader;
}

fn create_out_file(file_name: &String) -> BufWriter<File> {
    let path = Path::new(file_name);
    let display = path.display();
    let mut options = OpenOptions::new();
    let file = match options.create(true).write(true).truncate(true).open(path) {
	    Ok(file) => file,
	    Err(why) => panic!("Not create/open file {}: {}", display, Error::description(&why)),
	};
    let writer = BufWriter::new(file);
    return writer;
}

fn ask_me_trans(name: &str, opis: &str) -> String {

    let mut guess = String::new();

    // Debug print:
    println!("Переведите: {}", opis);
        let innum = io::stdin()
                  .read_line(&mut guess)
                  .ok()
                  .expect("Failed to read line");
    // If User input chars
    if innum > 1 {
        let output = format!("\"{}\"", guess.trim() );
        return output;
    } else { // Using English translating
        let output = opis.trim();
        return output.to_string();
    }
}

// ----------------------------------------------------------------------
fn main() {

    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
    if args.flag_stdout {
        println!("{:?}", args);
        if args.flag_h { println!("Print Help coming soon ..." ); return; }
        if args.flag_version { println!("Print Version coming soon ..." ); return; }
    }

    let mut engvec: Vec<EnglishName> = Vec::new();
    let mut rusvec: Vec<RussianName> = Vec::new();

    let re = Regex::new(r"(.*)(,)(.*)(\x22.*\x22)").unwrap();
    // Create English Vector
    for line in open_any_file(&args.arg_engfile.to_string()).lines() {
        let s = line.unwrap();
        for cap in re.captures_iter(&s) {
            let ubs = EnglishName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
            engvec.push(ubs);
        }
    }
    assert!( !engvec.is_empty() );
    // Create Russian Vector
    for line in open_any_file(&args.arg_rusfile.to_string()).lines() {
        let s = line.unwrap();
        for cap in re.captures_iter(&s) {
            let ubs = RussianName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
            rusvec.push(ubs);
        }
    }
    assert!( !rusvec.is_empty() );

	//  Подготовка закончилась, начинаем работу.

    if args.flag_stdout {
        println!("/*\n\tRecreated by RusFritz project\n*/");
    } else {
		// Write to file
    }

    let mut i=0;
    let mut found = false;
    let mut outstr = String::new();

    for e in &mut engvec {
        i = i+1;
        for r in &mut rusvec {
            if e.name == r.name {
                e.opis = r.opis.clone();
                found = true;
                r.using = true;
                if args.flag_stdout {
                    println!("{},\t\t{};", r.name, r.opis);
                } else {
                    let s = String::from( format!("{},\t\t{};\n", r.name, r.opis) );
                    outstr.push_str(&s);
                }
            }
        }
        if !found {
            //println!("myERR: {} - не найдено соответствие", e.name );
            if args.flag_stdout {
                if  args.flag_askme {
                    let rs = ask_me_trans(&e.name, &e.opis);
                    // Debug
                    println!("{},\t\t{};", e.name, rs );
                    //outstr.push_str(&s);
                } else {
                    println!("{},\t\t{};",e.name, e.opis);
                }
            }
        }
        found = false;
    }
    // Print if not using from Russian Names
    println!("------ Not using Found from Russian File --------");
    for r in rusvec {
        if r.using == false {
            println!("{},\t\t{}",r.name,r.opis);
        }
    }

    // File write, if needed
    if args.flag_stdout == false {
        let mut wr = create_out_file(&args.arg_outfile.to_string());
        if outstr.len() > 0 {
            match wr.write_all(&outstr.as_bytes()) {
                Err(why) => {
                    panic!("couldn't write to{}: {}",
                        &args.arg_outfile.to_string(),
                        Error::description(&why))
                },
                Ok(_) => println!("Good write file"),
            };
            wr.flush();
        }
    }
    //println!("Обработано {} строк из {}",i, engvec.len());
    //let writer = std::io::file_writer(&Path(std::os::args()[2]), [io::Append, io::Create]).unwrap();
}
<|endoftext|>


<commit_before>//! TODO
//! replace all constants with fields of gol!!
#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
extern crate sdl2;
extern crate rand;
extern crate rayon;
#[macro_use]
extern crate clap;

use std::{thread, time};

use rayon::prelude::*;

use rand::Rng;

use sdl2::rect::Rect;
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::render::Renderer;
use sdl2::EventPump;

#[derive(Debug, Copy, Clone)]
struct Gol {
    max_x: usize,
    max_y: usize,
    cell_width: isize,
    cell_height: isize,
    ncells: usize,
    frametime: u64,
    verbose: bool,
}

fn init<'a>(gol: Gol) -> (Renderer<'a>, EventPump) {
    let sdl_context = sdl2::init().unwrap();
    let video_subsystem = sdl_context.video().unwrap();

    let window = video_subsystem.window("Conway's Game of Life",
                ((gol.max_x + 1) * gol.cell_width as usize) as u32,
                ((gol.max_y + 1) * gol.cell_height as usize) as u32)
        .position_centered()
        .opengl()
        .build()
        .unwrap();

    let mut renderer = window.renderer().build().unwrap();

    let event_pump = sdl_context.event_pump().unwrap();

    renderer.set_draw_color(Color::RGB(255, 255, 255));
    renderer.clear();
    renderer.present();

    (renderer, event_pump)
}

fn get_cell(cells: &[bool], i: usize, gol: Gol) -> Option<bool> {
    let (x, y) = get_coords(i, gol);
    if let Some(i) = get_index(x, y, gol) {
        Some(cells[i])
    } else {
        None
    }
}

fn count_neighbors(cells: &[bool], i: usize, gol: Gol) -> i32 {
    let mut counter = 0;
    let (origx, origy) = get_coords(i, gol);
    for ty in -1isize..2isize {
        for tx in (-1isize..2isize).filter(|tx| *tx != 0 || ty != 0) {
            if let Some(i) = get_index((origx as isize + tx), origy as isize + ty, gol) {
                if let Some(x) = get_cell(cells, i, gol) {
                    if x {
                        counter += 1;
                    }
                }
            }
        }
    }
    counter
}

fn toggle_field(x: isize, y: isize, cells: &mut Vec<bool>, gol: Gol) {
    let cell_x = x / gol.cell_width;
    let cell_y = y / gol.cell_height;
    cells[get_index(cell_x, cell_y, gol).unwrap()] = !cells[get_index(cell_x, cell_y, gol).unwrap()]
}

fn get_index(x: isize, y: isize, gol: Gol) -> Option<usize> {
    if x < 0 || y < 0 || x > gol.max_x as isize || y > gol.max_y as isize {
        None
    } else {
        Some((x + (y * (gol.max_x + 1) as isize)) as usize)
    }
}

fn get_coords(i: usize, gol: Gol) -> (isize, isize) {
    ((i % (gol.max_x + 1)) as isize, (i / (gol.max_x + 1)) as isize)
}

fn main() {
    let matches = clap_app!(gol =>
        (version: "0.1")
        (author: "Lars Mühmel <larsmuehmel@web.de")
        (about: "Conway's Game of Life in Rust")
        (@arg max_x: -x +takes_value "Sets the amount of horizontall cells")
        (@arg max_y: -y +takes_value "Sets the amount of verticall cells")
        (@arg cell_width: -w --width +takes_value "Sets the width of a single cell")
        (@arg cell_height: -h --height +takes_value "Sets the height of a single cell")
        (@arg framerate: -f --framerate +takes_value "Sets the number of generations per second")
        (@arg verbose: -v --verbose "Sets, wether or not the actual framerate should be printed to stdout")
        ).get_matches();

    println!("{:?}", matches);
    // create a settings struct
    let mut gol: Gol = Gol {
        max_x: 199,
        max_y: 199,
        frametime: 1000 / 30,
        ncells: 200 * 200,
        cell_width: 5,
        cell_height: 5,
        verbose: false,
    };

    if let Some(Ok(x)) = matches.value_of("max_x").map(str::parse::<usize>) {
        gol.max_x = x - 1;
    }
    if let Some(Ok(x)) = matches.value_of("max_y").map(str::parse::<usize>) {
        gol.max_y = x - 1;
    }
    gol.ncells = (gol.max_x + 1) * (gol.max_y + 1);
    if let Some(Ok(x)) = matches.value_of("frametime").map(str::parse::<u64>) {
        if x == 0 {
            gol.frametime = 0;
        } else {
            gol.frametime = 1000 / x;
        }
    }
    if let Some(Ok(x)) = matches.value_of("cell_width").map(str::parse) {
        gol.cell_width = x;
    }
    if let Some(Ok(x)) = matches.value_of("cell_height").map(str::parse) {
        gol.cell_height = x;
    }
    if matches.occurrences_of("verbose") != 0 {
        gol.verbose = true;
    }
    let mut rng = rand::thread_rng();
    let (mut r, mut events) = init(gol);
    let bg = Color::RGB(0xff, 0xff, 0xff);
    let fg = Color::RGB(0, 0, 0);
    let mut cells: Vec<bool> = Vec::with_capacity(gol.ncells as usize);
    let mut paused: bool = false;

    for _ in 0..gol.ncells {
        cells.push(rng.gen());
    }

    'running: loop {
        let frametimer = time::Instant::now();
        let timer =
            thread::spawn(move || thread::sleep(time::Duration::from_millis(gol.frametime)));
        for event in events.poll_iter() {
            match event {
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } |
                Event::Quit { .. } => break 'running,
                Event::KeyDown { keycode: Some(Keycode::Space), .. } => paused = !paused,
                Event::KeyDown { keycode: Some(Keycode::F), .. } => {
                    cells.par_iter_mut().for_each(|cell| {
                        *cell = true;
                    });
                }
                Event::KeyDown { keycode: Some(Keycode::C), .. } => {
                    cells.par_iter_mut().for_each(|cell| {
                        *cell = false;
                    });
                }
                Event::MouseButtonDown { x, y, .. } => {
                    if paused {
                        toggle_field(x as isize, y as isize, &mut cells, gol);
                    }
                }
                _ => {}
            }
        }

        r.set_draw_color(bg);
        r.clear();
        r.set_draw_color(fg);
        for (cell, i) in cells.iter().zip(0..gol.ncells) {
            if *cell {
                let (x, y) = get_coords(i, gol);
                r.fill_rect(Rect::new((x * gol.cell_width) as i32,
                                         (y * gol.cell_height) as i32,
                                         gol.cell_width as u32,
                                         gol.cell_height as u32))
                    .unwrap();
            }
        }

        r.present();

        if !paused {
            let old_cells = cells.clone();
            cells.par_iter_mut().enumerate().for_each(|(i, cell)| {
                let neighbors = count_neighbors(&old_cells, i, gol);
                if old_cells[i] {
                    if neighbors < 2 || neighbors > 3 {
                        *cell = false;
                    } else {
                        *cell = true;
                    }
                } else if neighbors == 3 {
                    *cell = true;
                } else {
                    *cell = false;

                }
            });
        }
        timer.join().unwrap();
        if gol.verbose {
            println!("Framerate:\t{:5}",
                     1_000_000_000 / frametimer.elapsed().subsec_nanos());
        }

    }
}
<commit_msg>Changed typo ("frametime" to "framerate"<commit_after>//! TODO
//! replace all constants with fields of gol!!
#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
extern crate sdl2;
extern crate rand;
extern crate rayon;
#[macro_use]
extern crate clap;

use std::{thread, time};

use rayon::prelude::*;

use rand::Rng;

use sdl2::rect::Rect;
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::render::Renderer;
use sdl2::EventPump;

#[derive(Debug, Copy, Clone)]
struct Gol {
    max_x: usize,
    max_y: usize,
    cell_width: isize,
    cell_height: isize,
    ncells: usize,
    frametime: u64,
    verbose: bool,
}

fn init<'a>(gol: Gol) -> (Renderer<'a>, EventPump) {
    let sdl_context = sdl2::init().unwrap();
    let video_subsystem = sdl_context.video().unwrap();

    let window = video_subsystem.window("Conway's Game of Life",
                ((gol.max_x + 1) * gol.cell_width as usize) as u32,
                ((gol.max_y + 1) * gol.cell_height as usize) as u32)
        .position_centered()
        .opengl()
        .build()
        .unwrap();

    let mut renderer = window.renderer().build().unwrap();

    let event_pump = sdl_context.event_pump().unwrap();

    renderer.set_draw_color(Color::RGB(255, 255, 255));
    renderer.clear();
    renderer.present();

    (renderer, event_pump)
}

fn get_cell(cells: &[bool], i: usize, gol: Gol) -> Option<bool> {
    let (x, y) = get_coords(i, gol);
    if let Some(i) = get_index(x, y, gol) {
        Some(cells[i])
    } else {
        None
    }
}

fn count_neighbors(cells: &[bool], i: usize, gol: Gol) -> i32 {
    let mut counter = 0;
    let (origx, origy) = get_coords(i, gol);
    for ty in -1isize..2isize {
        for tx in (-1isize..2isize).filter(|tx| *tx != 0 || ty != 0) {
            if let Some(i) = get_index((origx as isize + tx), origy as isize + ty, gol) {
                if let Some(x) = get_cell(cells, i, gol) {
                    if x {
                        counter += 1;
                    }
                }
            }
        }
    }
    counter
}

fn toggle_field(x: isize, y: isize, cells: &mut Vec<bool>, gol: Gol) {
    let cell_x = x / gol.cell_width;
    let cell_y = y / gol.cell_height;
    cells[get_index(cell_x, cell_y, gol).unwrap()] = !cells[get_index(cell_x, cell_y, gol).unwrap()]
}

fn get_index(x: isize, y: isize, gol: Gol) -> Option<usize> {
    if x < 0 || y < 0 || x > gol.max_x as isize || y > gol.max_y as isize {
        None
    } else {
        Some((x + (y * (gol.max_x + 1) as isize)) as usize)
    }
}

fn get_coords(i: usize, gol: Gol) -> (isize, isize) {
    ((i % (gol.max_x + 1)) as isize, (i / (gol.max_x + 1)) as isize)
}

fn main() {
    let matches = clap_app!(gol =>
        (version: "0.1")
        (author: "Lars Mühmel <larsmuehmel@web.de")
        (about: "Conway's Game of Life in Rust")
        (@arg max_x: -x +takes_value "Sets the amount of horizontall cells")
        (@arg max_y: -y +takes_value "Sets the amount of verticall cells")
        (@arg cell_width: -w --width +takes_value "Sets the width of a single cell")
        (@arg cell_height: -h --height +takes_value "Sets the height of a single cell")
        (@arg framerate: -f --framerate +takes_value "Sets the number of generations per second")
        (@arg verbose: -v --verbose "Sets, wether or not the actual framerate should be printed to stdout")
        ).get_matches();

    println!("{:?}", matches);
    // create a settings struct
    let mut gol: Gol = Gol {
        max_x: 199,
        max_y: 199,
        frametime: 1000 / 30,
        ncells: 200 * 200,
        cell_width: 5,
        cell_height: 5,
        verbose: false,
    };

    if let Some(Ok(x)) = matches.value_of("max_x").map(str::parse::<usize>) {
        gol.max_x = x - 1;
    }
    if let Some(Ok(x)) = matches.value_of("max_y").map(str::parse::<usize>) {
        gol.max_y = x - 1;
    }
    gol.ncells = (gol.max_x + 1) * (gol.max_y + 1);
    if let Some(Ok(x)) = matches.value_of("framerate").map(str::parse::<u64>) {
        if x == 0 {
            gol.frametime = 0;
        } else {
            gol.frametime = 1000 / x;
        }
    }
    if let Some(Ok(x)) = matches.value_of("cell_width").map(str::parse) {
        gol.cell_width = x;
    }
    if let Some(Ok(x)) = matches.value_of("cell_height").map(str::parse) {
        gol.cell_height = x;
    }
    if matches.occurrences_of("verbose") != 0 {
        gol.verbose = true;
    }
    let mut rng = rand::thread_rng();
    let (mut r, mut events) = init(gol);
    let bg = Color::RGB(0xff, 0xff, 0xff);
    let fg = Color::RGB(0, 0, 0);
    let mut cells: Vec<bool> = Vec::with_capacity(gol.ncells as usize);
    let mut paused: bool = false;

    for _ in 0..gol.ncells {
        cells.push(rng.gen());
    }

    'running: loop {
        let frametimer = time::Instant::now();
        let timer =
            thread::spawn(move || thread::sleep(time::Duration::from_millis(gol.frametime)));
        for event in events.poll_iter() {
            match event {
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } |
                Event::Quit { .. } => break 'running,
                Event::KeyDown { keycode: Some(Keycode::Space), .. } => paused = !paused,
                Event::KeyDown { keycode: Some(Keycode::F), .. } => {
                    cells.par_iter_mut().for_each(|cell| {
                        *cell = true;
                    });
                }
                Event::KeyDown { keycode: Some(Keycode::C), .. } => {
                    cells.par_iter_mut().for_each(|cell| {
                        *cell = false;
                    });
                }
                Event::MouseButtonDown { x, y, .. } => {
                    if paused {
                        toggle_field(x as isize, y as isize, &mut cells, gol);
                    }
                }
                _ => {}
            }
        }

        r.set_draw_color(bg);
        r.clear();
        r.set_draw_color(fg);
        for (cell, i) in cells.iter().zip(0..gol.ncells) {
            if *cell {
                let (x, y) = get_coords(i, gol);
                r.fill_rect(Rect::new((x * gol.cell_width) as i32,
                                         (y * gol.cell_height) as i32,
                                         gol.cell_width as u32,
                                         gol.cell_height as u32))
                    .unwrap();
            }
        }

        r.present();

        if !paused {
            let old_cells = cells.clone();
            cells.par_iter_mut().enumerate().for_each(|(i, cell)| {
                let neighbors = count_neighbors(&old_cells, i, gol);
                if old_cells[i] {
                    if neighbors < 2 || neighbors > 3 {
                        *cell = false;
                    } else {
                        *cell = true;
                    }
                } else if neighbors == 3 {
                    *cell = true;
                } else {
                    *cell = false;

                }
            });
        }
        timer.join().unwrap();
        if gol.verbose {
            println!("Framerate:\t{:5}",
                     1_000_000_000 / frametimer.elapsed().subsec_nanos());
        }

    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate env_logger;
extern crate rustc_serialize;
extern crate docopt;
extern crate glob;
extern crate toml;

use docopt::Docopt;
use std::path::Path;
use std::fs::File;
use std::fs::metadata;
use std::io::prelude::*;
use glob::Pattern;

const USAGE: &'static str = "
enforcer for code rules

Usage:
  enforcer <glob> [-c|--clean]
  enforcer (-h | --help)
  enforcer --version

Options:
  -h --help     Show this screen.
  -v --version  Show version.
  --count       only count found entries
  -c --clean    clean up trailing whitespaces
";
const VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_count: bool,
    flag_clean: bool,
    arg_glob: String,
    flag_version: bool,
}
const HAS_TABS: u8               = 1 << 0;
const TRAILING_SPACES: u8        = 1 << 1;
const HAS_ILLEGAL_CHARACTERS: u8 = 1 << 2;

fn check_content<'a>(input: &'a str) -> std::io::Result<u8> {
    let mut result = 0;
    for line in input.lines_any() {
        if line.ends_with(' ') {
            result |= TRAILING_SPACES;
        }
        if line.contains("\t") {
            result |= HAS_TABS;
        }
        if line.as_bytes().iter().any(|x| *x > 127) {
            result |= HAS_ILLEGAL_CHARACTERS;
        }
    }
    Ok(result)
}

fn clean_string(input: &str) -> String {
    let v: Vec<&str> = input
        .lines_any()
        .map(|line| line.trim_right())
        .collect();

    if input.ends_with("\n") {
        v.join("\n") + "\n"
    }
    else {
        v.join("\n")
    }
}

fn is_dir(path: &Path) -> bool {
    if let Ok(result) = metadata(&path) {
        result.is_dir()
    } else {
        false
    }
}

fn check_path(path: &Path, clean: bool) -> std::io::Result<()> {
    use std::io::ErrorKind;

    let mut f = try!(File::open(path));
    let mut buffer = String::new();
    let mut check = 0;
    if let Err(e) = f.read_to_string(&mut buffer) {
        match e.kind() {
            ErrorKind::InvalidData => check = check | HAS_ILLEGAL_CHARACTERS,
            _ => return Err(e),
        }
    }
    // only check content if we could read the file
    if check == 0 { check = try!(check_content(&buffer)); }
    if (check & HAS_ILLEGAL_CHARACTERS) > 0 {
        println!("HAS_ILLEGAL_CHARACTERS:[{}]", path.display());
    }
    if (check & HAS_TABS) > 0 {
        println!("HAS_TABS:[{}]", path.display());
    }
    if (check & TRAILING_SPACES) > 0 {
        println!("TRAILING_SPACES:[{}]", path.display());
        if clean {
            println!("cleaning trailing whitespaces");
            let res_string = clean_string(&buffer);
            let mut file = try!(File::create(path));
            try!(file.write_all(res_string.as_bytes()));
        }
    }
    Ok(())
}

struct EnforcerCfg {
    unwanted: Vec<String>,
}
impl std::fmt::Debug for EnforcerCfg {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "[unwanted]: {:?}", self.unwanted)
    }
}
fn default_cfg() -> EnforcerCfg {
    EnforcerCfg { unwanted: vec![".git".to_string(), ".bake".to_string()]}
}

fn is_unwanted(path_elem: &str, unwanted_cfg: &EnforcerCfg) -> bool {
    unwanted_cfg.unwanted.iter()
        .any(|x| Pattern::new(x)
            .ok()
            .expect(&format!("{} seems not to be a valid pattern", x)[..])
            .matches(path_elem))
}

fn load_config<'a>(input: &'a str) -> std::io::Result<EnforcerCfg> {
    use std::io::{Error, ErrorKind};
    let mut parser = toml::Parser::new(input);
    let default_err = Err(Error::new(ErrorKind::InvalidData, "could not parse the config"));
    parser.parse().map_or(default_err, |toml_|
            toml_.get("ignore").map_or(Ok(default_cfg()), |entry|
                entry.as_slice().map_or(Ok(default_cfg()), |val| {
                    let xs = val.iter()
                        .filter_map(|x| x.as_str())
                        .map(|v| v.to_string())
                        .collect();
                    Ok(EnforcerCfg { unwanted: xs })
                })))
}

#[allow(dead_code)]
fn main() {
    use glob::glob;
    env_logger::init().unwrap();

    fn get_cfg() -> EnforcerCfg {
        fn read_unwanted() -> std::io::Result<EnforcerCfg> {
            let mut cfg_file = try!(File::open(".enforcer"));
            let mut buffer = String::new();
            try!(cfg_file.read_to_string(&mut buffer));
            load_config(&buffer[..])
        }
        let unwanted_cfg = read_unwanted()
            .unwrap_or(default_cfg());
        println!("loaded ignores: {:?}", unwanted_cfg.unwanted);
        unwanted_cfg
    }

    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());

    if args.flag_version {
        println!("  Version: {}", VERSION);
    }
    let pat = args.arg_glob.to_string();

    let unwanted_cfg = get_cfg();
    for path in glob(&*pat)
        .ok()
        .expect(&format!("glob has problems with {}", pat)[..])
        .filter_map(Result::ok)
        .filter(|x| !x.components()
                        .any(|y| is_unwanted(y.as_os_str()
                                                .to_str()
                                                .expect("blablalblalbla"), &unwanted_cfg))) {
            if !is_dir(path.as_path()) {
                check_path(path.as_path(), args.flag_clean)
                    .ok()
                    .expect(&format!("check_path for {:?} should work", path));
            }
    }
}

#[cfg(test)]
mod tests {
    use super::clean_string;
    use super::load_config;
    use super::is_unwanted;
    use glob::Pattern;
    use super::EnforcerCfg;
    use super::default_cfg;

    #[test]
    fn test_clean_does_not_remove_trailing_newline() {
        let content = "1\n2\n3\n4\n5\n";
        let cleaned = clean_string(content);
        assert!(cleaned.eq(content));
    }
    #[test]
    fn test_clean_trailing_whitespace() {
        let content = "1 \n2";
        let cleaned = clean_string(content);
        println!("{:?}", cleaned);
        assert!(cleaned.eq("1\n2"));
    }
    #[test]
    fn test_load_simple_config() {
        let c = include_str!("../samples/.enforcer");
        let cfg = load_config(c).unwrap();
        assert_eq!(cfg.unwanted.len(), 2);
    }
    #[test]
    fn test_load_broken_config() {
        let c = include_str!("../samples/.enforcer_broken");
        let cfg = load_config(c).unwrap();
        assert_eq!(default_cfg().unwanted, cfg.unwanted);
    }
    #[test]
    fn test_glob() {
        assert!(Pattern::new("build_*").unwrap().matches("build_Debug"));
    }
    #[test]
    fn test_is_unwanted() {
        let cfg = EnforcerCfg { unwanted: vec!["build_*".to_string(), ".git".to_string()]};
        assert!(is_unwanted("build_Debug", &cfg));
        assert!(is_unwanted(".git", &cfg));
        assert!(!is_unwanted("bla", &cfg));
    }
}

<commit_msg>change signature of is_unwanted to take path components<commit_after>#[macro_use]
extern crate log;
extern crate env_logger;
extern crate rustc_serialize;
extern crate docopt;
extern crate glob;
extern crate toml;

use docopt::Docopt;
use std::path::Path;
use std::fs::File;
use std::fs::metadata;
use std::io::prelude::*;
use glob::Pattern;

const USAGE: &'static str = "
enforcer for code rules

Usage:
  enforcer <glob> [-c|--clean]
  enforcer (-h | --help)
  enforcer (-v | --version)

Options:
  -h --help     Show this screen.
  -v --version  Show version.
  --count       only count found entries
  -c --clean    clean up trailing whitespaces
";
const VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_count: bool,
    flag_clean: bool,
    arg_glob: String,
    flag_version: bool,
}
const HAS_TABS: u8               = 1 << 0;
const TRAILING_SPACES: u8        = 1 << 1;
const HAS_ILLEGAL_CHARACTERS: u8 = 1 << 2;

fn check_content<'a>(input: &'a str) -> std::io::Result<u8> {
    let mut result = 0;
    for line in input.lines_any() {
        if line.ends_with(' ') {
            result |= TRAILING_SPACES;
        }
        if line.contains("\t") {
            result |= HAS_TABS;
        }
        if line.as_bytes().iter().any(|x| *x > 127) {
            result |= HAS_ILLEGAL_CHARACTERS;
        }
    }
    Ok(result)
}

fn clean_string(input: &str) -> String {
    let v: Vec<&str> = input
        .lines_any()
        .map(|line| line.trim_right())
        .collect();

    if input.ends_with("\n") {
        v.join("\n") + "\n"
    }
    else {
        v.join("\n")
    }
}

fn is_dir(path: &Path) -> bool {
    if let Ok(result) = metadata(&path) {
        result.is_dir()
    } else {
        false
    }
}

fn check_path(path: &Path, clean: bool) -> std::io::Result<()> {
    use std::io::ErrorKind;

    let mut f = try!(File::open(path));
    let mut buffer = String::new();
    let mut check = 0;
    if let Err(e) = f.read_to_string(&mut buffer) {
        match e.kind() {
            ErrorKind::InvalidData => check = check | HAS_ILLEGAL_CHARACTERS,
            _ => return Err(e),
        }
    }
    // only check content if we could read the file
    if check == 0 { check = try!(check_content(&buffer)); }
    if (check & HAS_ILLEGAL_CHARACTERS) > 0 {
        println!("HAS_ILLEGAL_CHARACTERS:[{}]", path.display());
    }
    if (check & HAS_TABS) > 0 {
        println!("HAS_TABS:[{}]", path.display());
    }
    if (check & TRAILING_SPACES) > 0 {
        println!("TRAILING_SPACES:[{}]", path.display());
        if clean {
            println!("cleaning trailing whitespaces");
            let res_string = clean_string(&buffer);
            let mut file = try!(File::create(path));
            try!(file.write_all(res_string.as_bytes()));
        }
    }
    Ok(())
}

struct EnforcerCfg {
    unwanted: Vec<String>,
}
impl std::fmt::Debug for EnforcerCfg {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "[unwanted]: {:?}", self.unwanted)
    }
}
fn default_cfg() -> EnforcerCfg {
    EnforcerCfg { unwanted: vec![".git".to_string(), ".bake".to_string()]}
}

fn is_unwanted(comp: std::path::Component, unwanted_cfg: &EnforcerCfg) -> bool {
    let path_elem = comp.as_os_str()
                        .to_str()
                        .expect(&format!("illegal path component {:?}", comp)[..]);
    unwanted_cfg.unwanted.iter()
        .any(|x| Pattern::new(x)
            .ok()
            .expect(&format!("{} seems not to be a valid pattern", x)[..])
            .matches(path_elem))
}

fn load_config<'a>(input: &'a str) -> std::io::Result<EnforcerCfg> {
    use std::io::{Error, ErrorKind};
    let mut parser = toml::Parser::new(input);
    let default_err = Err(Error::new(ErrorKind::InvalidData, "could not parse the config"));
    parser.parse().map_or(default_err, |toml_|
            toml_.get("ignore").map_or(Ok(default_cfg()), |entry|
                entry.as_slice().map_or(Ok(default_cfg()), |val| {
                    let xs = val.iter()
                        .filter_map(|x| x.as_str())
                        .map(|v| v.to_string())
                        .collect();
                    Ok(EnforcerCfg { unwanted: xs })
                })))
}

#[allow(dead_code)]
fn main() {
    use glob::glob;
    env_logger::init().unwrap();

    fn get_cfg() -> EnforcerCfg {
        fn read_unwanted() -> std::io::Result<EnforcerCfg> {
            let mut cfg_file = try!(File::open(".enforcer"));
            let mut buffer = String::new();
            try!(cfg_file.read_to_string(&mut buffer));
            load_config(&buffer[..])
        }
        let unwanted_cfg = read_unwanted()
            .unwrap_or(default_cfg());
        println!("loaded ignores: {:?}", unwanted_cfg.unwanted);
        unwanted_cfg
    }

    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());

    if args.flag_version {
        println!("  Version: {}", VERSION);
    }
    let pat = args.arg_glob.to_string();

    let unwanted_cfg = get_cfg();
    for path in glob(&*pat)
        .ok()
        .expect(&format!("glob has problems with {}", pat)[..])
        .filter_map(Result::ok)
        .filter(|x| !x.components()
                        .any(|y| is_unwanted(y, &unwanted_cfg))) {
            if !is_dir(path.as_path()) {
                check_path(path.as_path(), args.flag_clean)
                    .ok()
                    .expect(&format!("check_path for {:?} should work", path));
            }
    }
}

#[cfg(test)]
mod tests {
    use super::clean_string;
    use super::load_config;
    use super::is_unwanted;
    use glob::Pattern;
    use super::EnforcerCfg;
    use super::default_cfg;
    use std::ffi::OsStr;
    use std::path::Component::Normal;

    #[test]
    fn test_clean_does_not_remove_trailing_newline() {
        let content = "1\n2\n3\n4\n5\n";
        let cleaned = clean_string(content);
        assert!(cleaned.eq(content));
    }
    #[test]
    fn test_clean_trailing_whitespace() {
        let content = "1 \n2";
        let cleaned = clean_string(content);
        println!("{:?}", cleaned);
        assert!(cleaned.eq("1\n2"));
    }
    #[test]
    fn test_load_simple_config() {
        let c = include_str!("../samples/.enforcer");
        let cfg = load_config(c).unwrap();
        assert_eq!(cfg.unwanted.len(), 2);
    }
    #[test]
    fn test_load_broken_config() {
        let c = include_str!("../samples/.enforcer_broken");
        let cfg = load_config(c).unwrap();
        assert_eq!(default_cfg().unwanted, cfg.unwanted);
    }
    #[test]
    fn test_glob() {
        assert!(Pattern::new("build_*").unwrap().matches("build_Debug"));
    }
    #[test]
    fn test_is_unwanted() {
        let cfg = EnforcerCfg { unwanted: vec!["build_*".to_string(), ".git".to_string()]};
        assert!(is_unwanted(Normal(OsStr::new("build_Debug")), &cfg));
        assert!(is_unwanted(Normal(OsStr::new(".git")), &cfg));
        assert!(!is_unwanted(Normal(OsStr::new("bla")), &cfg));
    }
}

<|endoftext|>