<commit_before>#[cfg(all(feature = "std_rng", feature = "default_dictionary"))]
use petname::petname;
use petname::Petnames;
use rand::rngs::mock::StepRng;

#[test]
#[cfg(feature = "default_dictionary")]
fn default_petnames_has_adjectives() {
    let petnames = Petnames::default();
    assert_ne!(petnames.adjectives.len(), 0);
}

#[test]
#[cfg(feature = "default_dictionary")]
fn default_petnames_has_adverbs() {
    let petnames = Petnames::default();
    assert_ne!(petnames.adverbs.len(), 0);
}

#[test]
#[cfg(feature = "default_dictionary")]
fn default_petnames_has_names() {
    let petnames = Petnames::default();
    assert_ne!(petnames.names.len(), 0);
}

#[test]
fn retain_applies_given_predicate() {
    let petnames_expected = Petnames::init("bob", "bob", "bob jane");
    let mut petnames = Petnames::init("alice bob carol", "alice bob", "bob carol jane");
    petnames.retain(|word| word.len() < 5);
    assert_eq!(petnames_expected, petnames);
}

#[test]
#[cfg(feature = "default_dictionary")]
fn default_petnames_has_non_zero_cardinality() {
    let petnames = Petnames::default();
    // This test will need to be adjusted when word lists change.
    assert_eq!(0, petnames.cardinality(0));
    assert_eq!(456, petnames.cardinality(1));
    assert_eq!(204744, petnames.cardinality(2));
    assert_eq!(53438184, petnames.cardinality(3));
    assert_eq!(13947366024, petnames.cardinality(4));
}

#[test]
fn generate_uses_adverb_adjective_name() {
    let petnames = Petnames {
        adjectives: vec!["adjective"],
        adverbs: vec!["adverb"],
        names: vec!["name"],
    };
    assert_eq!(
        petnames.generate(&mut StepRng::new(0, 1), 3, "-"),
        "adverb-adjective-name"
    );
}

#[test]
#[cfg(all(feature = "std_rng", feature = "default_dictionary"))]
fn petname_renders_desired_number_of_words() {
    assert_eq!(petname(7, "-").split('-').count(), 7);
}

#[test]
#[cfg(all(feature = "std_rng", feature = "default_dictionary"))]
fn petname_renders_with_desired_separator() {
    assert_eq!(petname(7, "@").split('@').count(), 7);
}

#[test]
fn petnames_iter_has_cardinality() {
    let mut rng = StepRng::new(0, 1);
    let petnames = Petnames::init("a b", "c d e", "f g h i");
    let names = petnames.iter(&mut rng, 3, ".");
    assert_eq!(24u128, names.cardinality());
}

#[test]
fn petnames_iter_yields_names() {
    let mut rng = StepRng::new(0, 1);
    let petnames = Petnames::init("foo", "bar", "baz");
    let names = petnames.iter(&mut rng, 3, ".");
    // Definintely an Iterator...
    let mut iter: Box<dyn Iterator<Item = _>> = Box::new(names);
    assert_eq!(Some("bar.foo.baz".to_string()), iter.next());
}

#[test]
fn petnames_iter_unique_yields_unique_names() {
    let mut rng = StepRng::new(0, 1);
    let petnames = Petnames::init("a1 a2", "b1 b2 b3", "c1 c2");
    let names = petnames.iter_unique(&mut rng, 3, ".");
    // Definintely an Iterator...
    let iter: Box<dyn Iterator<Item = _>> = Box::new(names);
    let names: Vec<String> = iter.collect();
    assert_eq!(
        vec![
            "b2.a2.c2", "b3.a2.c2", "b1.a2.c2", "b2.a1.c2", "b3.a1.c2", "b1.a1.c2", "b2.a2.c1",
            "b3.a2.c1", "b1.a2.c1", "b2.a1.c1", "b3.a1.c1", "b1.a1.c1"
        ],
        names
    )
}

#[test]
fn petnames_iter_unique_yields_nothing_when_any_word_list_is_empty() {
    let mut rng = StepRng::new(0, 1);
    let petnames = Petnames::init("a1 a2", "", "c1 c2");
    let names = petnames.iter_unique(&mut rng, 3, ".");
    // Definintely an Iterator...
    let iter: Box<dyn Iterator<Item = _>> = Box::new(names);
    let names: Vec<String> = iter.collect();
    assert!(names.is_empty())
}
<commit_msg>Test when no words are requested<commit_after>#[cfg(all(feature = "std_rng", feature = "default_dictionary"))]
use petname::petname;
use petname::Petnames;
use rand::rngs::mock::StepRng;

#[test]
#[cfg(feature = "default_dictionary")]
fn default_petnames_has_adjectives() {
    let petnames = Petnames::default();
    assert_ne!(petnames.adjectives.len(), 0);
}

#[test]
#[cfg(feature = "default_dictionary")]
fn default_petnames_has_adverbs() {
    let petnames = Petnames::default();
    assert_ne!(petnames.adverbs.len(), 0);
}

#[test]
#[cfg(feature = "default_dictionary")]
fn default_petnames_has_names() {
    let petnames = Petnames::default();
    assert_ne!(petnames.names.len(), 0);
}

#[test]
fn retain_applies_given_predicate() {
    let petnames_expected = Petnames::init("bob", "bob", "bob jane");
    let mut petnames = Petnames::init("alice bob carol", "alice bob", "bob carol jane");
    petnames.retain(|word| word.len() < 5);
    assert_eq!(petnames_expected, petnames);
}

#[test]
#[cfg(feature = "default_dictionary")]
fn default_petnames_has_non_zero_cardinality() {
    let petnames = Petnames::default();
    // This test will need to be adjusted when word lists change.
    assert_eq!(0, petnames.cardinality(0));
    assert_eq!(456, petnames.cardinality(1));
    assert_eq!(204744, petnames.cardinality(2));
    assert_eq!(53438184, petnames.cardinality(3));
    assert_eq!(13947366024, petnames.cardinality(4));
}

#[test]
fn generate_uses_adverb_adjective_name() {
    let petnames = Petnames {
        adjectives: vec!["adjective"],
        adverbs: vec!["adverb"],
        names: vec!["name"],
    };
    assert_eq!(
        petnames.generate(&mut StepRng::new(0, 1), 3, "-"),
        "adverb-adjective-name"
    );
}

#[test]
#[cfg(all(feature = "std_rng", feature = "default_dictionary"))]
fn petname_renders_desired_number_of_words() {
    assert_eq!(petname(7, "-").split('-').count(), 7);
}

#[test]
#[cfg(all(feature = "std_rng", feature = "default_dictionary"))]
fn petname_renders_with_desired_separator() {
    assert_eq!(petname(7, "@").split('@').count(), 7);
}

#[test]
fn petnames_iter_has_cardinality() {
    let mut rng = StepRng::new(0, 1);
    let petnames = Petnames::init("a b", "c d e", "f g h i");
    let names = petnames.iter(&mut rng, 3, ".");
    assert_eq!(24u128, names.cardinality());
}

#[test]
fn petnames_iter_yields_names() {
    let mut rng = StepRng::new(0, 1);
    let petnames = Petnames::init("foo", "bar", "baz");
    let names = petnames.iter(&mut rng, 3, ".");
    // Definintely an Iterator...
    let mut iter: Box<dyn Iterator<Item = _>> = Box::new(names);
    assert_eq!(Some("bar.foo.baz".to_string()), iter.next());
}

#[test]
fn petnames_iter_unique_yields_unique_names() {
    let mut rng = StepRng::new(0, 1);
    let petnames = Petnames::init("a1 a2", "b1 b2 b3", "c1 c2");
    let names = petnames.iter_unique(&mut rng, 3, ".");
    // Definintely an Iterator...
    let iter: Box<dyn Iterator<Item = _>> = Box::new(names);
    let names: Vec<String> = iter.collect();
    assert_eq!(
        vec![
            "b2.a2.c2", "b3.a2.c2", "b1.a2.c2", "b2.a1.c2", "b3.a1.c2", "b1.a1.c2", "b2.a2.c1",
            "b3.a2.c1", "b1.a2.c1", "b2.a1.c1", "b3.a1.c1", "b1.a1.c1"
        ],
        names
    )
}

#[test]
fn petnames_iter_unique_yields_nothing_when_any_word_list_is_empty() {
    let mut rng = StepRng::new(0, 1);
    let petnames = Petnames::init("a1 a2", "", "c1 c2");
    let names = petnames.iter_unique(&mut rng, 3, ".");
    // Definintely an Iterator...
    let iter: Box<dyn Iterator<Item = _>> = Box::new(names);
    let names: Vec<String> = iter.collect();
    assert!(names.is_empty())
}

#[test]
fn petnames_iter_unique_yields_nothing_when_no_word_lists_are_given() {
    let mut rng = StepRng::new(0, 1);
    let petnames = Petnames::init("a1 a2", "b1 b2", "c1 c2");
    let names = petnames.iter_unique(&mut rng, 0, ".");
    // Definintely an Iterator...
    let iter: Box<dyn Iterator<Item = _>> = Box::new(names);
    let names: Vec<String> = iter.collect();
    assert!(names.is_empty())
}
<|endoftext|>


<commit_before>use criterion::*;
use std::hash::{Hash, Hasher, BuildHasher};
use std::collections::hash_map::DefaultHasher;
use ahash::{AHasher};
use fxhash::{FxHasher};
use t1ha::T1haBuildHasher;

#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
fn aeshash<H: Hash>(b: H) -> u64 {
    let mut hasher = AHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}
#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
fn aeshash<H: Hash>(_b: H) -> u64 {
    panic!("aes must be enabled")
}

#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
fn fallbackhash<H: Hash>(b: H) -> u64 {
    let mut hasher = AHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
fn fallbackhash<H: Hash>(_b: H) -> u64 {
    panic!("aes must be disabled")
}

fn fnvhash<H: Hash>(b: H) -> u64 {
    let mut hasher = fnv::FnvHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn t1ha<H: Hash>(b: H) -> u64 {
    let mut hasher = T1haBuildHasher::default().build_hasher();
    b.hash(&mut hasher);
    hasher.finish()
}

fn siphash<H: Hash>(b: H) -> u64 {
    let mut hasher = DefaultHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn fxhash<H: Hash>(b: H) -> u64 {
    let mut hasher = FxHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn seahash<H: Hash>(b: H) -> u64 {
    let mut hasher = seahash::SeaHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

const STRING_LENGTHS: [u32; 11] = [1, 3, 4, 7, 8, 15, 16, 24, 68, 132, 1024];

fn gen_strings() -> Vec<String> {
    STRING_LENGTHS.iter().map(|len| {
        let mut string = String::default();
        for pos in 1..=*len {
            let c = (48 + (pos % 10) as u8) as char;
            string.push(c);
        }
        string
    }).collect()

}

const U8_VALUES: [u8; 1] = [8];
const U16_VALUES: [u16; 1] = [16];
const U32_VALUES: [u32; 1] = [32];
const U64_VALUES: [u64; 1] = [64];
const U128_VALUES: [u128; 1] = [128];

fn bench_ahash(c: &mut Criterion) {
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(aeshash(&s))), &U8_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(aeshash(&s))), &U16_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(aeshash(&s))), &U32_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(aeshash(&s))), &U64_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(aeshash(&s))), &U128_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(aeshash(&s))), gen_strings()),
    );
}

fn bench_fallback(c: &mut Criterion) {
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U8_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U16_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U32_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U64_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U128_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fallbackhash(&s))), gen_strings()),
    );
}

fn bench_fx(c: &mut Criterion) {
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fxhash(&s))), &U8_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fxhash(&s))), &U16_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fxhash(&s))), &U32_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fxhash(&s))), &U64_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fxhash(&s))), &U128_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fxhash(&s))), gen_strings()),
    );
}

fn bench_fnv(c: &mut Criterion) {
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fnvhash(&s))), &U8_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fnvhash(&s))), &U16_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fnvhash(&s))), &U32_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fnvhash(&s))), &U64_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fnvhash(&s))), &U128_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fnvhash(&s))), gen_strings()),
    );
}

fn bench_sea(c: &mut Criterion) {
    c.bench(
        "sea",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(seahash(&s))), gen_strings()),
    );
}

fn bench_t1ha(c: &mut Criterion) {
    c.bench(
        "t1ha",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(t1ha(&s))), gen_strings()),
    );
}

fn bench_sip(c: &mut Criterion) {
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(siphash(&s))), &U8_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(siphash(&s))), &U16_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(siphash(&s))), &U32_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(siphash(&s))), &U64_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(siphash(&s))), &U128_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(siphash(&s))), gen_strings()),
    );
}

criterion_main!(benches);
criterion_group!(benches, bench_ahash, bench_fallback, bench_fx, bench_fnv, bench_sea, bench_t1ha, bench_sip);
<commit_msg>Remove unneeded ref<commit_after>use criterion::*;
use std::hash::{Hash, Hasher, BuildHasher};
use std::collections::hash_map::DefaultHasher;
use ahash::{AHasher};
use fxhash::{FxHasher};
use t1ha::T1haBuildHasher;

#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
fn aeshash<H: Hash>(b: H) -> u64 {
    let mut hasher = AHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}
#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
fn aeshash<H: Hash>(_b: H) -> u64 {
    panic!("aes must be enabled")
}

#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
fn fallbackhash<H: Hash>(b: H) -> u64 {
    let mut hasher = AHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
fn fallbackhash<H: Hash>(_b: H) -> u64 {
    panic!("aes must be disabled")
}

fn fnvhash<H: Hash>(b: H) -> u64 {
    let mut hasher = fnv::FnvHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn t1ha<H: Hash>(b: H) -> u64 {
    let mut hasher = T1haBuildHasher::default().build_hasher();
    b.hash(&mut hasher);
    hasher.finish()
}

fn siphash<H: Hash>(b: H) -> u64 {
    let mut hasher = DefaultHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn fxhash<H: Hash>(b: H) -> u64 {
    let mut hasher = FxHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn seahash<H: Hash>(b: H) -> u64 {
    let mut hasher = seahash::SeaHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

const STRING_LENGTHS: [u32; 11] = [1, 3, 4, 7, 8, 15, 16, 24, 68, 132, 1024];

fn gen_strings() -> Vec<String> {
    STRING_LENGTHS.iter().map(|len| {
        let mut string = String::default();
        for pos in 1..=*len {
            let c = (48 + (pos % 10) as u8) as char;
            string.push(c);
        }
        string
    }).collect()

}

const U8_VALUES: [u8; 1] = [8];
const U16_VALUES: [u16; 1] = [16];
const U32_VALUES: [u32; 1] = [32];
const U64_VALUES: [u64; 1] = [64];
const U128_VALUES: [u128; 1] = [128];

fn bench_ahash(c: &mut Criterion) {
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(aeshash(s))), &U8_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(aeshash(s))), &U16_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(aeshash(s))), &U32_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(aeshash(s))), &U64_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(aeshash(s))), &U128_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(aeshash(s))), gen_strings()),
    );
}

fn bench_fallback(c: &mut Criterion) {
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fallbackhash(s))), &U8_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fallbackhash(s))), &U16_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fallbackhash(s))), &U32_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fallbackhash(s))), &U64_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fallbackhash(s))), &U128_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fallbackhash(s))), gen_strings()),
    );
}

fn bench_fx(c: &mut Criterion) {
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fxhash(s))), &U8_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fxhash(s))), &U16_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fxhash(s))), &U32_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fxhash(s))), &U64_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fxhash(s))), &U128_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fxhash(s))), gen_strings()),
    );
}

fn bench_fnv(c: &mut Criterion) {
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fnvhash(s))), &U8_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fnvhash(s))), &U16_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fnvhash(s))), &U32_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fnvhash(s))), &U64_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fnvhash(s))), &U128_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fnvhash(s))), gen_strings()),
    );
}

fn bench_sea(c: &mut Criterion) {
    c.bench(
        "sea",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(seahash(s))), gen_strings()),
    );
}

fn bench_t1ha(c: &mut Criterion) {
    c.bench(
        "t1ha",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(t1ha(s))), gen_strings()),
    );
}

fn bench_sip(c: &mut Criterion) {
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(siphash(s))), &U8_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(siphash(s))), &U16_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(siphash(s))), &U32_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(siphash(s))), &U64_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(siphash(s))), &U128_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(siphash(s))), gen_strings()),
    );
}

criterion_main!(benches);
criterion_group!(benches, bench_ahash, bench_fallback, bench_fx, bench_fnv, bench_sea, bench_t1ha, bench_sip);
<|endoftext|>


<commit_before>#[macro_use]
extern crate sorted;

use sorted::*;

order_by_key!{ Key0AscOrder:
    fn (K: Ord + Copy, T)(entry: (K,T)) -> K { entry.0 }
}

order_by_key!{ KeySecondOrder:
    fn (K: Ord + Copy, T)(entry: (T,K)) -> K { entry.1 }
}

#[test]
fn sorted_array() {
    let arr = [7, 2, 9, 6];
    let v = AscendingOrder::by_sorting(arr);
    assert_eq!(*v.as_inner(), [2, 6, 7, 9]);
}

#[test]
fn ascending_order() {
    let arr = AscendingOrder::by_sorting([3, 4, 1, 2]);
    assert_eq!(*arr.as_inner(), [1, 2, 3, 4]);
}

#[test]
fn descending_order() {
    let arr = DescendingOrder::by_sorting([1, 3, 4, 2]);
    assert_eq!(*arr.as_inner(), [4, 3, 2, 1]);
}

#[test]
fn sorted_slice() {
    let mut arr = [3, 2, 4, 1];
    let s = AscendingOrder::by_sorting(&mut arr[..]);
    assert_eq!(s.as_inner(), &[1, 2, 3, 4]);
}

#[test]
fn sorted_vec() {
    let v = AscendingOrder::by_sorting(vec![4, 3, 1, 2]);
    assert_eq!(v.as_slice(), &[1, 2, 3, 4]);
}

#[test]
fn sort_by_first() {
    let s = vec![(5, 3), (2, 7), (3, 4)];
    let v = KeyOrder::<keys::Key0, AscendingOrder>::by_sorting(s);
    assert_eq!(&[(2, 7), (3, 4), (5, 3)], v.as_slice());
}

#[test]
fn sort_by_second() {
    let s = vec![(5, 3, 9), (2, 7, 2), (3, 4, 4)];
    let v = KeyOrder::<keys::Key2, DescendingOrder>::by_sorting(s);
    assert_eq!(&[(5, 3, 9), (3, 4, 4), (2, 7, 2)], v.as_slice());
}

#[test]
fn sort_with_property_key_type() {
    #[derive(Debug, Clone, Copy, PartialEq)]
    struct Record { stuff: i32, id: u32 };
    impl Record {
        pub fn new(n: u32) -> Self { Record{ stuff: 0, id: n} }
    }
    #[derive(Debug, Clone, Copy)]
    struct IdKey;
    impl Key<Record> for IdKey {
        type Key = u32;
        fn key(r: &Record) -> Self::Key { r.id }
    }

    let v = KeyOrder::<IdKey, AscendingOrder>::by_sorting(
        vec![Record::new(2), Record::new(3), Record::new(1)]
    );
    assert_eq!(
        &v.as_slice(),
        &[Record::new(1), Record::new(2), Record::new(3)]
    );
}

#[test]
fn sort_by_property_string() {
    use std::cmp::Ordering;
    #[derive(Debug, Clone, PartialEq)]
    struct Person { name: String, x: i32 };
    impl Person {
        pub fn new(n: &str) -> Self {
            Self { name: n.to_string(), x: 0 }
        }
    }
    #[derive(Debug, Clone, Copy)]
    struct OrderByName;
    impl SortOrder<Person> for OrderByName {
        fn cmp(a: &Person, b: &Person) -> Ordering {
            a.name.cmp(&b.name)
        }
    }
    let v = OrderByName::by_sorting(
        vec![Person::new("Bob"), Person::new("Cecil"), Person::new("Alice")]
    );
    assert_eq!(
        v.as_slice(),
        &[Person::new("Alice"), Person::new("Bob"), Person::new("Cecil")]
    );
}

#[test]
fn sorted_slice_from_sorted_vec() {
    fn take_sorted_slice<'a>(slice: Sorted<'a, &'a [i32], AscendingOrder>) {
        assert_eq!(&[1, 2, 4, 9, 33][..], *slice);
    }
    let vec = AscendingOrder::by_sorting(vec![4, 9, 2, 33, 1]);
    take_sorted_slice(vec.as_ref());
}

/// TODO: Can you get a Sorted<'a, &vec, O> from Sorted::as_ref?
#[test]
fn uhm() {
    let vec = AscendingOrder::by_sorting(vec![3,2,4,1]);
    let rvec: Sorted<&Vec<i32>, AscendingOrder> = vec.as_ref();
    rvec.as_slice();
}

#[test]
#[cfg(feature="unstable")]
fn sorted_vec_from_sorted_slice() {
    type SortedVec<'a, T, O> = Sorted<'a, Vec<T>, O>;
    let mut arr = [5, 3, 7, 9];
    let slice = AscendingOrder::by_sorting(&mut arr[..]);
    let vec = SortedVec::from(slice);
    assert_eq!([3, 5, 7, 9], vec.as_slice());
}

#[test]
fn take_sorted_iterator() {
    fn take_sorted<I>(sorted: I)
        where I: IntoIterator<Item = i32> + IsSorted
    {
        let v: Vec<_> = sorted.into_iter().collect();
        assert_eq!(vec![2, 3, 8, 10], v);
    }
    let vec = AscendingOrder::by_sorting(vec![3, 8, 2, 10]);
    take_sorted(vec);
}

#[test]
fn take_sorted_ref_iterator() {
    fn take_sorted_ref<'a,I>(sorted: I)
        where I: IntoIterator<Item = &'a i32> + IsSorted
    {
        let v: Vec<_> = sorted.into_iter().cloned().collect();
        assert_eq!([1,2,3,4], v.as_slice());
    }
    let vec = AscendingOrder::by_sorting(vec![3,4,1,2]);
    take_sorted_ref(vec.iter());
}

#[test]
fn sorted_insert() {
    let mut vec = AscendingOrder::by_sorting(vec![4, 8, 2, 0]);
    vec.insert(6);
    assert_eq!([0, 2, 4, 6, 8], vec.as_slice());
}

#[test]
fn sorted_vec_from_sorted_iterator() {
    type SortedVec<'a, T, O> = Sorted<'a, Vec<T>, O>;
    let v0 = AscendingOrder::by_sorting(vec![3,1,4,2]);
    let it = v0.into_iter();
    let v1 = SortedVec::from_iter(it);
    assert_eq!(
        &[1,2,3,4],
        v1.as_slice()
    );
}<commit_msg>Adding some clarifying comments to the usage tests.<commit_after>#[macro_use]
extern crate sorted;

use sorted::*;

order_by_key!{ Key0AscOrder:
    fn (K: Ord + Copy, T)(entry: (K,T)) -> K { entry.0 }
}

order_by_key!{ KeySecondOrder:
    fn (K: Ord + Copy, T)(entry: (T,K)) -> K { entry.1 }
}

#[test]
fn sorted_array() {
    let arr = [7, 2, 9, 6];
    // Sort the array, resulting in a Sorted<[T;n], AscendingOrder>.
    let v = AscendingOrder::by_sorting(arr);
    // Retrieve a reference to the inner type with .as_inner.
    assert_eq!(v.as_inner(), &[2, 6, 7, 9]);
}

#[test]
fn ascending_order() {
    let arr = AscendingOrder::by_sorting([3, 4, 1, 2]);
    assert_eq!(arr.as_inner(), &[1, 2, 3, 4]);
}

#[test]
fn descending_order() {
    let arr = DescendingOrder::by_sorting([1, 3, 4, 2]);
    assert_eq!(arr.as_inner(), &[4, 3, 2, 1]);
}

#[test]
fn sorted_slice() {
    // You can also refer to a slice that should be sorted.
    // This leaves the ownership outside of the Sorted<> type.
    let mut arr = [3, 2, 4, 1];
    let s = AscendingOrder::by_sorting(&mut arr[..]);
    assert_eq!(s.as_inner(), &[1, 2, 3, 4]);
}

#[test]
fn sorted_vec() {
    let v = AscendingOrder::by_sorting(vec![4, 3, 1, 2]);
    assert_eq!(v.as_slice(), &[1, 2, 3, 4]);
}

#[test]
fn sort_by_first() {
    // It's easy to sort by a tuple key. Specifiy which key and in what order
    // it should be sorted.
    let s = vec![(5, 3), (2, 7), (3, 4)];
    let v = KeyOrder::<keys::Key0, AscendingOrder>::by_sorting(s);
    assert_eq!(&[(2, 7), (3, 4), (5, 3)], v.as_slice());
}

#[test]
fn sort_by_second() {
    let s = vec![(5, 3, 9), (2, 7, 2), (3, 4, 4)];
    let v = KeyOrder::<keys::Key2, DescendingOrder>::by_sorting(s);
    assert_eq!(&[(5, 3, 9), (3, 4, 4), (2, 7, 2)], v.as_slice());
}

#[test]
fn sort_with_property_key_type() {
    #[derive(Debug, Clone, Copy, PartialEq)]
    struct Record { stuff: i32, id: u32 };
    impl Record {
        pub fn new(n: u32) -> Self { Record{ stuff: 0, id: n} }
    }

    // Sorting via an arbitrary property takes a bit more work.
    // First define a tag type to identify what property we want to sort by.
    #[derive(Debug, Clone, Copy)]
    struct IdKey;
    // Then implement how to get that key from our Record type.
    impl Key<Record> for IdKey {
        type Key = u32;
        fn key(r: &Record) -> Self::Key { r.id }
    }

    // You can now sort the Records by a property in any order.
    let v = KeyOrder::<IdKey, AscendingOrder>::by_sorting(
        vec![Record::new(2), Record::new(3), Record::new(1)]
    );
    assert_eq!(
        &v.as_slice(),
        &[Record::new(1), Record::new(2), Record::new(3)]
    );
}

#[test]
fn sort_by_property_string() {
    use std::cmp::Ordering;
    // Using strings as keys has some lifetime issues with the previous key
    // pattern. It's however possible, just not as flexible.
    #[derive(Debug, Clone, PartialEq)]
    struct Person { name: String, x: i32 };
    impl Person {
        pub fn new(n: &str) -> Self {
            Self { name: n.to_string(), x: 0 }
        }
    }

    // We'll implement our own SortOrder type. Starting with a tag type.
    #[derive(Debug, Clone, Copy)]
    struct OrderByName;
    // Then implement the SortOrder trait, per struct supporting it.
    impl SortOrder<Person> for OrderByName {
        fn cmp(a: &Person, b: &Person) -> Ordering {
            a.name.cmp(&b.name)
        }
    }

    // It will only provide one ordering for what you define, so if you need to
    // support multiple ways of ordering by name it will result in a bit of
    // boilerplate.
    let v = OrderByName::by_sorting(
        vec![Person::new("Bob"), Person::new("Cecil"), Person::new("Alice")]
    );
    assert_eq!(
        v.as_slice(),
        &[Person::new("Alice"), Person::new("Bob"), Person::new("Cecil")]
    );
}

#[test]
fn sorted_slice_from_sorted_vec() {
    // The as_ref works like Option::as_ref; it returns a Sorted type with the
    // inner type being a reference to the original. If the inner type implements
    // the correct AsRef, it'll work.
    fn take_sorted_slice<'a>(slice: Sorted<'a, &'a [i32], AscendingOrder>) {
        assert_eq!(&[1, 2, 4, 9, 33][..], *slice);
    }
    let vec = AscendingOrder::by_sorting(vec![4, 9, 2, 33, 1]);
    take_sorted_slice(vec.as_ref());
}

#[test]
fn sorted_vec_ref() {
    fn take_sorted_vec<'a>(refvec: Sorted<'a, &'a Vec<i32>, AscendingOrder>) {
        assert_eq!(&[1,2,3,4], refvec.as_slice())
    }
    let vec = AscendingOrder::by_sorting(vec![3,2,4,1]);
    take_sorted_vec(vec.as_ref());
}

#[test]
#[cfg(feature="unstable")]
fn sorted_vec_from_sorted_slice() {
    type SortedVec<'a, T, O> = Sorted<'a, Vec<T>, O>;
    let mut arr = [5, 3, 7, 9];
    let slice = AscendingOrder::by_sorting(&mut arr[..]);
    // This is currently unstable as it doesn't seem possible to guarantee sortedness.
    let vec = SortedVec::from(slice);
    assert_eq!([3, 5, 7, 9], vec.as_slice());
}

#[test]
fn take_sorted_iterator() {
    // Sorted types can generate IsSorted iterators.
    fn take_sorted<I>(sorted: I)
        where I: IntoIterator<Item = i32> + IsSorted
    {
        let v: Vec<_> = sorted.into_iter().collect();
        assert_eq!(vec![2, 3, 8, 10], v);
    }
    let vec = AscendingOrder::by_sorting(vec![3, 8, 2, 10]);
    take_sorted(vec);
}

#[test]
fn take_sorted_ref_iterator() {
    // By-ref iterators can only be created via Sorted::iter() right now.
    // I.e there is no IntoIterator for &Sorted<>.
    fn take_sorted_ref<'a,I>(sorted: I)
        where I: IntoIterator<Item = &'a i32> + IsSorted
    {
        let v: Vec<_> = sorted.into_iter().cloned().collect();
        assert_eq!([1,2,3,4], v.as_slice());
    }
    let vec = AscendingOrder::by_sorting(vec![3,4,1,2]);
    take_sorted_ref(vec.iter());
}

#[test]
fn sorted_insert() {
    // The Sorted type only provides mutable operations that keep the collection
    // sorted.
    let mut vec = AscendingOrder::by_sorting(vec![4, 8, 2, 0]);
    vec.insert(6);
    assert_eq!([0, 2, 4, 6, 8], vec.as_slice());
}

#[test]
fn sorted_vec_from_sorted_iterator() {
    // You can create Sorted collections from Sorted iterators.
    type SortedVec<'a, T, O> = Sorted<'a, Vec<T>, O>;
    let v0 = AscendingOrder::by_sorting(vec![3,1,4,2]);
    let it = v0.into_iter();
    let v1 = SortedVec::from_iter(it);
    assert_eq!(
        &[1,2,3,4],
        v1.as_slice()
    );
}<|endoftext|>


<commit_before>use super::write_file;
use anyhow::{Context, Result};
use std::path::{Path, PathBuf};
use std::{fs, str};

const BINDING_CC_TEMPLATE: &'static str = include_str!("./templates/binding.cc");
const BINDING_GYP_TEMPLATE: &'static str = include_str!("./templates/binding.gyp");
const INDEX_JS_TEMPLATE: &'static str = include_str!("./templates/index.js");
const LIB_RS_TEMPLATE: &'static str = include_str!("./templates/lib.rs");
const BUILD_RS_TEMPLATE: &'static str = include_str!("./templates/build.rs");
const CARGO_TOML_TEMPLATE: &'static str = include_str!("./templates/cargo.toml");
const PACKAGE_JSON_TEMPLATE: &'static str = include_str!("./templates/package.json");
const PARSER_NAME_PLACEHOLDER: &'static str = "PARSER_NAME";
const CLI_VERSION_PLACEHOLDER: &'static str = "CLI_VERSION";
const CLI_VERSION: &'static str = env!("CARGO_PKG_VERSION");

pub fn generate_binding_files(repo_path: &Path, language_name: &str) -> Result<()> {
    let bindings_dir = repo_path.join("bindings");

    let dashed_language_name = language_name.replace("_", "-");
    let dashed_language_name = dashed_language_name.as_str();

    // Generate rust bindings if needed.
    let rust_binding_dir = bindings_dir.join("rust");
    create_path(&rust_binding_dir, |path| create_dir(path))?;

    create_path(&rust_binding_dir.join("lib.rs").to_owned(), |path| {
        generate_file(path, LIB_RS_TEMPLATE, language_name)
    })?;

    create_path(&rust_binding_dir.join("build.rs").to_owned(), |path| {
        generate_file(path, BUILD_RS_TEMPLATE, language_name)
    })?;

    create_path(&repo_path.join("Cargo.toml").to_owned(), |path| {
        generate_file(path, CARGO_TOML_TEMPLATE, dashed_language_name)
    })?;

    // Generate node bindings
    let node_binding_dir = bindings_dir.join("node");
    create_path(&node_binding_dir, |path| create_dir(path))?;

    create_path(&node_binding_dir.join("index.js").to_owned(), |path| {
        generate_file(path, INDEX_JS_TEMPLATE, language_name)
    })?;

    create_path(&node_binding_dir.join("binding.cc").to_owned(), |path| {
        generate_file(path, BINDING_CC_TEMPLATE, language_name)
    })?;

    // Create binding.gyp, or update it with new binding path.
    let binding_gyp_path = repo_path.join("binding.gyp");
    create_path_else(
        &binding_gyp_path,
        |path| generate_file(path, BINDING_GYP_TEMPLATE, language_name),
        |path| {
            eprintln!("Updating binding.gyp with new binding path");
            let binding_gyp =
                fs::read_to_string(path).with_context(|| "Failed to read binding.gyp")?;
            let binding_gyp = binding_gyp.replace("\"src/binding.cc\"", "\"bindings/node/binding.cc\"");
            write_file(path, binding_gyp)
        },
    )?;

    // Create package.json, or update it with new binding path.
    let package_json_path = repo_path.join("package.json");
    create_path_else(
        &package_json_path,
        |path| generate_file(path, PACKAGE_JSON_TEMPLATE, dashed_language_name),
        |path| {
            let package_json_str =
                fs::read_to_string(path).with_context(|| "Failed to read package.json")?;
            let mut package_json =
                serde_json::from_str::<serde_json::Map<String, serde_json::Value>>(
                    &package_json_str,
                )
                .with_context(|| "Failed to parse package.json")?;
            let package_json_main = package_json.get("main");
            let package_json_needs_update = package_json_main.map_or(true, |v| {
                let main_string = v.as_str();
                main_string == Some("index.js") || main_string == Some("./index.js")
            });
            if package_json_needs_update {
                eprintln!("Updating package.json with new binding path");

                package_json.insert(
                    "main".to_string(),
                    serde_json::Value::String("bindings/node".to_string()),
                );
                let mut package_json_str = serde_json::to_string_pretty(&package_json)?;
                package_json_str.push('\n');
                write_file(path, package_json_str)?;
            }
            Ok(())
        },
    )?;

    // Remove files from old node binding paths.
    let old_index_js_path = repo_path.join("index.js");
    let old_binding_cc_path = repo_path.join("src").join("binding.cc");
    if old_index_js_path.exists() {
        fs::remove_file(old_index_js_path).ok();
    }
    if old_binding_cc_path.exists() {
        fs::remove_file(old_binding_cc_path).ok();
    }

    Ok(())
}

fn generate_file(path: &Path, template: &str, language_name: &str) -> Result<()> {
    write_file(
        path,
        template
            .replace(PARSER_NAME_PLACEHOLDER, language_name)
            .replace(CLI_VERSION_PLACEHOLDER, CLI_VERSION),
    )
}

fn create_dir(path: &Path) -> Result<()> {
    fs::create_dir_all(&path)
        .with_context(|| format!("Failed to create {:?}", path.to_string_lossy()))
}

fn create_path<F>(path: &PathBuf, action: F) -> Result<bool>
where
    F: Fn(&PathBuf) -> Result<()>,
{
    if !path.exists() {
        action(path)?;
        return Ok(true);
    }
    Ok(false)
}

fn create_path_else<T, F>(path: &PathBuf, action: T, else_action: F) -> Result<bool>
where
    T: Fn(&PathBuf) -> Result<()>,
    F: Fn(&PathBuf) -> Result<()>,
{
    if !path.exists() {
        action(path)?;
        return Ok(true);
    } else {
        else_action(path)?;
    }
    Ok(false)
}
<commit_msg>Updating of binding.gyp should depend on its content instead of bindings/node folder<commit_after>use super::write_file;
use anyhow::{Context, Result};
use std::path::{Path, PathBuf};
use std::{fs, str};

const BINDING_CC_TEMPLATE: &'static str = include_str!("./templates/binding.cc");
const BINDING_GYP_TEMPLATE: &'static str = include_str!("./templates/binding.gyp");
const INDEX_JS_TEMPLATE: &'static str = include_str!("./templates/index.js");
const LIB_RS_TEMPLATE: &'static str = include_str!("./templates/lib.rs");
const BUILD_RS_TEMPLATE: &'static str = include_str!("./templates/build.rs");
const CARGO_TOML_TEMPLATE: &'static str = include_str!("./templates/cargo.toml");
const PACKAGE_JSON_TEMPLATE: &'static str = include_str!("./templates/package.json");
const PARSER_NAME_PLACEHOLDER: &'static str = "PARSER_NAME";
const CLI_VERSION_PLACEHOLDER: &'static str = "CLI_VERSION";
const CLI_VERSION: &'static str = env!("CARGO_PKG_VERSION");

pub fn generate_binding_files(repo_path: &Path, language_name: &str) -> Result<()> {
    let bindings_dir = repo_path.join("bindings");

    let dashed_language_name = language_name.replace("_", "-");
    let dashed_language_name = dashed_language_name.as_str();

    // Generate rust bindings if needed.
    let rust_binding_dir = bindings_dir.join("rust");
    create_path(&rust_binding_dir, |path| create_dir(path))?;

    create_path(&rust_binding_dir.join("lib.rs").to_owned(), |path| {
        generate_file(path, LIB_RS_TEMPLATE, language_name)
    })?;

    create_path(&rust_binding_dir.join("build.rs").to_owned(), |path| {
        generate_file(path, BUILD_RS_TEMPLATE, language_name)
    })?;

    create_path(&repo_path.join("Cargo.toml").to_owned(), |path| {
        generate_file(path, CARGO_TOML_TEMPLATE, dashed_language_name)
    })?;

    // Generate node bindings
    let node_binding_dir = bindings_dir.join("node");
    create_path(&node_binding_dir, |path| create_dir(path))?;

    create_path(&node_binding_dir.join("index.js").to_owned(), |path| {
        generate_file(path, INDEX_JS_TEMPLATE, language_name)
    })?;

    create_path(&node_binding_dir.join("binding.cc").to_owned(), |path| {
        generate_file(path, BINDING_CC_TEMPLATE, language_name)
    })?;

    // Create binding.gyp, or update it with new binding path.
    let binding_gyp_path = repo_path.join("binding.gyp");
    create_path_else(
        &binding_gyp_path,
        |path| generate_file(path, BINDING_GYP_TEMPLATE, language_name),
        |path| {
            let binding_gyp =
                fs::read_to_string(path).with_context(|| "Failed to read binding.gyp")?;
            let old_path = "\"src/binding.cc\"";
            if binding_gyp.contains(old_path) {
                eprintln!("Updating binding.gyp with new binding path");
                let binding_gyp = binding_gyp.replace(old_path, "\"bindings/node/binding.cc\"");
                write_file(path, binding_gyp)?;
            }
            Ok(())
        },
    )?;

    // Create package.json, or update it with new binding path.
    let package_json_path = repo_path.join("package.json");
    create_path_else(
        &package_json_path,
        |path| generate_file(path, PACKAGE_JSON_TEMPLATE, dashed_language_name),
        |path| {
            let package_json_str =
                fs::read_to_string(path).with_context(|| "Failed to read package.json")?;
            let mut package_json =
                serde_json::from_str::<serde_json::Map<String, serde_json::Value>>(
                    &package_json_str,
                )
                .with_context(|| "Failed to parse package.json")?;
            let package_json_main = package_json.get("main");
            let package_json_needs_update = package_json_main.map_or(true, |v| {
                let main_string = v.as_str();
                main_string == Some("index.js") || main_string == Some("./index.js")
            });
            if package_json_needs_update {
                eprintln!("Updating package.json with new binding path");
                package_json.insert(
                    "main".to_string(),
                    serde_json::Value::String("bindings/node".to_string()),
                );
                let mut package_json_str = serde_json::to_string_pretty(&package_json)?;
                package_json_str.push('\n');
                write_file(path, package_json_str)?;
            }
            Ok(())
        },
    )?;

    // Remove files from old node binding paths.
    let old_index_js_path = repo_path.join("index.js");
    let old_binding_cc_path = repo_path.join("src").join("binding.cc");
    if old_index_js_path.exists() {
        fs::remove_file(old_index_js_path).ok();
    }
    if old_binding_cc_path.exists() {
        fs::remove_file(old_binding_cc_path).ok();
    }

    Ok(())
}

fn generate_file(path: &Path, template: &str, language_name: &str) -> Result<()> {
    write_file(
        path,
        template
            .replace(PARSER_NAME_PLACEHOLDER, language_name)
            .replace(CLI_VERSION_PLACEHOLDER, CLI_VERSION),
    )
}

fn create_dir(path: &Path) -> Result<()> {
    fs::create_dir_all(&path)
        .with_context(|| format!("Failed to create {:?}", path.to_string_lossy()))
}

fn create_path<F>(path: &PathBuf, action: F) -> Result<bool>
where
    F: Fn(&PathBuf) -> Result<()>,
{
    if !path.exists() {
        action(path)?;
        return Ok(true);
    }
    Ok(false)
}

fn create_path_else<T, F>(path: &PathBuf, action: T, else_action: F) -> Result<bool>
where
    T: Fn(&PathBuf) -> Result<()>,
    F: Fn(&PathBuf) -> Result<()>,
{
    if !path.exists() {
        action(path)?;
        return Ok(true);
    } else {
        else_action(path)?;
    }
    Ok(false)
}
<|endoftext|>


<commit_before>//! lint on enum variants that are prefixed or suffixed by the same characters

use rustc::lint::*;
use syntax::ast::*;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use utils::{span_help_and_lint, span_lint};
use utils::{camel_case_from, camel_case_until, in_macro};

/// **What it does:** Warns on enum variants that are prefixed or suffixed by the same characters
///
/// **Why is this bad?** Enum variant names should specify their variant, not the enum, too.
///
/// **Known problems:** None
///
/// **Example:** enum Cake { BlackForestCake, HummingbirdCake }
declare_lint! {
    pub ENUM_VARIANT_NAMES, Warn,
    "finds enums where all variants share a prefix/postfix"
}

#[derive(Default)]
pub struct EnumVariantNames {
    modules: Vec<String>,
}

impl LintPass for EnumVariantNames {
    fn get_lints(&self) -> LintArray {
        lint_array!(ENUM_VARIANT_NAMES)
    }
}

fn var2str(var: &Variant) -> InternedString {
    var.node.name.name.as_str()
}

/// Returns the number of chars that match from the start
fn partial_match(pre: &str, name: &str) -> usize {
    let mut name_iter = name.chars();
    let _ = name_iter.next_back(); // make sure the name is never fully matched
    pre.chars().zip(name_iter).take_while(|&(l, r)| l == r).count()
}

/// Returns the number of chars that match from the end
fn partial_rmatch(post: &str, name: &str) -> usize {
    let mut name_iter = name.chars();
    let _ = name_iter.next(); // make sure the name is never fully matched
    post.chars().rev().zip(name_iter.rev()).take_while(|&(l, r)| l == r).count()
}

// FIXME: #600
#[allow(while_let_on_iterator)]
fn check_variant(cx: &EarlyContext, def: &EnumDef, item_name: &str, item_name_chars: usize, span: Span) {
    for var in &def.variants {
        let name = var2str(var);
        if partial_match(item_name, &name) == item_name_chars {
            span_lint(cx, ENUM_VARIANT_NAMES, var.span, "Variant name starts with the enum's name");
        }
        if partial_rmatch(item_name, &name) == item_name_chars {
            span_lint(cx, ENUM_VARIANT_NAMES, var.span, "Variant name ends with the enum's name");
        }
    }
    if def.variants.len() < 2 {
        return;
    }
    let first = var2str(&def.variants[0]);
    let mut pre = &first[..camel_case_until(&*first)];
    let mut post = &first[camel_case_from(&*first)..];
    for var in &def.variants {
        let name = var2str(var);

        let pre_match = partial_match(pre, &name);
        pre = &pre[..pre_match];
        let pre_camel = camel_case_until(pre);
        pre = &pre[..pre_camel];
        while let Some((next, last)) = name[pre.len()..].chars().zip(pre.chars().rev()).next() {
            if next.is_lowercase() {
                let last = pre.len() - last.len_utf8();
                let last_camel = camel_case_until(&pre[..last]);
                pre = &pre[..last_camel];
            } else {
                break;
            }
        }

        let post_match = partial_rmatch(post, &name);
        let post_end = post.len() - post_match;
        post = &post[post_end..];
        let post_camel = camel_case_from(post);
        post = &post[post_camel..];
    }
    let (what, value) = match (pre.is_empty(), post.is_empty()) {
        (true, true) => return,
        (false, _) => ("pre", pre),
        (true, false) => ("post", post),
    };
    span_help_and_lint(cx,
                       ENUM_VARIANT_NAMES,
                       span,
                       &format!("All variants have the same {}fix: `{}`", what, value),
                       &format!("remove the {}fixes and use full paths to \
                                 the variants instead of glob imports",
                                what));
}

fn to_camel_case(item_name: &str) -> String {
    let mut s = String::new();
    let mut up = true;
    for c in item_name.chars() {
        if c.is_uppercase() {
            // we only turn snake case text into CamelCase
            return item_name.to_string();
        }
        if c == '_' {
            up = true;
            continue;
        }
        if up {
            up = false;
            s.extend(c.to_uppercase());
        } else {
            s.push(c);
        }
    }
    s
}

impl EarlyLintPass for EnumVariantNames {
    fn check_item_post(&mut self, _cx: &EarlyContext, _item: &Item) {
        let last = self.modules.pop();
        assert!(last.is_some());
    }

    fn check_item(&mut self, cx: &EarlyContext, item: &Item) {
        let item_name = item.ident.name.as_str();
        let item_name_chars = item_name.chars().count();
        let item_camel = to_camel_case(&item_name);
        if item.vis == Visibility::Public {
            if !in_macro(cx, item.span) {
                if let Some(mod_camel) = self.modules.last() {
                    // constants don't have surrounding modules
                    if !mod_camel.is_empty() {
                        let matching = partial_match(mod_camel, &item_camel);
                        let rmatching = partial_rmatch(mod_camel, &item_camel);
                        let nchars = mod_camel.chars().count();
                        if matching == nchars {
                            span_lint(cx, ENUM_VARIANT_NAMES, item.span, &format!("Item name ({}) starts with its containing module's name ({})", item_camel, mod_camel));
                        }
                        if rmatching == nchars {
                            span_lint(cx, ENUM_VARIANT_NAMES, item.span, &format!("Item name ({}) ends with its containing module's name ({})", item_camel, mod_camel));
                        }
                    }
                }
            }
        }
        if let ItemKind::Enum(ref def, _) = item.node {
            check_variant(cx, def, &item_name, item_name_chars, item.span);
        }
        self.modules.push(item_camel);
    }
}
<commit_msg>round 3<commit_after>//! lint on enum variants that are prefixed or suffixed by the same characters

use rustc::lint::*;
use syntax::ast::*;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use utils::{span_help_and_lint, span_lint};
use utils::{camel_case_from, camel_case_until, in_macro};

/// **What it does:** Warns on enum variants that are prefixed or suffixed by the same characters
///
/// **Why is this bad?** Enum variant names should specify their variant, not the enum, too.
///
/// **Known problems:** None
///
/// **Example:** enum Cake { BlackForestCake, HummingbirdCake }
declare_lint! {
    pub ENUM_VARIANT_NAMES, Warn,
    "finds enums where all variants share a prefix/postfix"
}

#[derive(Default)]
pub struct EnumVariantNames {
    modules: Vec<String>,
}

impl LintPass for EnumVariantNames {
    fn get_lints(&self) -> LintArray {
        lint_array!(ENUM_VARIANT_NAMES)
    }
}

fn var2str(var: &Variant) -> InternedString {
    var.node.name.name.as_str()
}

/// Returns the number of chars that match from the start
fn partial_match(pre: &str, name: &str) -> usize {
    let mut name_iter = name.chars();
    let _ = name_iter.next_back(); // make sure the name is never fully matched
    pre.chars().zip(name_iter).take_while(|&(l, r)| l == r).count()
}

/// Returns the number of chars that match from the end
fn partial_rmatch(post: &str, name: &str) -> usize {
    let mut name_iter = name.chars();
    let _ = name_iter.next(); // make sure the name is never fully matched
    post.chars().rev().zip(name_iter.rev()).take_while(|&(l, r)| l == r).count()
}

// FIXME: #600
#[allow(while_let_on_iterator)]
fn check_variant(cx: &EarlyContext, def: &EnumDef, item_name: &str, item_name_chars: usize, span: Span) {
    for var in &def.variants {
        let name = var2str(var);
        if partial_match(item_name, &name) == item_name_chars {
            span_lint(cx, ENUM_VARIANT_NAMES, var.span, "Variant name starts with the enum's name");
        }
        if partial_rmatch(item_name, &name) == item_name_chars {
            span_lint(cx, ENUM_VARIANT_NAMES, var.span, "Variant name ends with the enum's name");
        }
    }
    if def.variants.len() < 2 {
        return;
    }
    let first = var2str(&def.variants[0]);
    let mut pre = &first[..camel_case_until(&*first)];
    let mut post = &first[camel_case_from(&*first)..];
    for var in &def.variants {
        let name = var2str(var);

        let pre_match = partial_match(pre, &name);
        pre = &pre[..pre_match];
        let pre_camel = camel_case_until(pre);
        pre = &pre[..pre_camel];
        while let Some((next, last)) = name[pre.len()..].chars().zip(pre.chars().rev()).next() {
            if next.is_lowercase() {
                let last = pre.len() - last.len_utf8();
                let last_camel = camel_case_until(&pre[..last]);
                pre = &pre[..last_camel];
            } else {
                break;
            }
        }

        let post_match = partial_rmatch(post, &name);
        let post_end = post.len() - post_match;
        post = &post[post_end..];
        let post_camel = camel_case_from(post);
        post = &post[post_camel..];
    }
    let (what, value) = match (pre.is_empty(), post.is_empty()) {
        (true, true) => return,
        (false, _) => ("pre", pre),
        (true, false) => ("post", post),
    };
    span_help_and_lint(cx,
                       ENUM_VARIANT_NAMES,
                       span,
                       &format!("All variants have the same {}fix: `{}`", what, value),
                       &format!("remove the {}fixes and use full paths to \
                                 the variants instead of glob imports",
                                what));
}

fn to_camel_case(item_name: &str) -> String {
    let mut s = String::new();
    let mut up = true;
    for c in item_name.chars() {
        if c.is_uppercase() {
            // we only turn snake case text into CamelCase
            return item_name.to_string();
        }
        if c == '_' {
            up = true;
            continue;
        }
        if up {
            up = false;
            s.extend(c.to_uppercase());
        } else {
            s.push(c);
        }
    }
    s
}

impl EarlyLintPass for EnumVariantNames {
    fn check_item_post(&mut self, _cx: &EarlyContext, _item: &Item) {
        let last = self.modules.pop();
        assert!(last.is_some());
    }

    fn check_item(&mut self, cx: &EarlyContext, item: &Item) {
        let item_name = item.ident.name.as_str();
        let item_name_chars = item_name.chars().count();
        let item_camel = to_camel_case(&item_name);
        if item.vis == Visibility::Public && !in_macro(cx, item.span) {
            if let Some(mod_camel) = self.modules.last() {
                // constants don't have surrounding modules
                if !mod_camel.is_empty() {
                    let matching = partial_match(mod_camel, &item_camel);
                    let rmatching = partial_rmatch(mod_camel, &item_camel);
                    let nchars = mod_camel.chars().count();
                    if matching == nchars {
                        span_lint(cx, ENUM_VARIANT_NAMES, item.span, &format!("Item name ({}) starts with its containing module's name ({})", item_camel, mod_camel));
                    }
                    if rmatching == nchars {
                        span_lint(cx, ENUM_VARIANT_NAMES, item.span, &format!("Item name ({}) ends with its containing module's name ({})", item_camel, mod_camel));
                    }
                }
            }
        }
        if let ItemKind::Enum(ref def, _) = item.node {
            check_variant(cx, def, &item_name, item_name_chars, item.span);
        }
        self.modules.push(item_camel);
    }
}
<|endoftext|>


<commit_before>use prodbg_api::read_write::{Reader, Writer};
use prodbg_api::backend::{CBackendCallbacks};
use plugins::PluginHandler;
use reader_wrapper::{ReaderWrapper, WriterWrapper};
use backend_plugin::{BackendHandle, BackendPlugins};
use libc::{c_void};

#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct SessionHandle(pub u64);

///! Session is a major part of ProDBG. There can be several sessions active at the same time
///! and each session has exactly one backend. There are only communication internally in a session
///! sessions can't (at least now) not talk to eachother.
///!
///! A backend can have several views at the same time. Data can be sent between the backend and
///| views using the PDReader/PDWriter APIs (prodbg::Writer prodbg::Reader in Rust) and this is the
///| only way for views and backends to talk with each other. There are several reasons for this
///| approach:
///!
///| 1. No "hacks" on trying to share memory. Plugins can be over a socket/webview/etc.
///! 2. Views and backends makes no assumetions on the inner workings of the others.
///! 3. Backends and views can post messages which anyone can decide to (optionally) act on.
///!
pub struct Session {
    pub handle: SessionHandle,
    pub reader: Reader,

    //current_writer: usize,
    writers: [Writer; 2],
    action: i32,

    backend: Option<BackendHandle>,
}

///! Connection options for Remote connections. Currently just one Ip adderss
///!
pub struct ConnectionSettings<'a> {
    pub address: &'a str,
}

impl Session {
    pub fn new(handle: SessionHandle) -> Session {
        Session {
            handle: handle,
            writers: [
                WriterWrapper::create_writer(),
                WriterWrapper::create_writer(),
            ],
            reader: ReaderWrapper::create_reader(),
            action: 0,
            //current_writer: 0,
            backend: None,
        }
    }

    pub fn get_current_writer(&mut self) -> &mut Writer {
        &mut self.writers[0]
    }

    pub fn start_remote(_plugin_handler: &PluginHandler, _settings: &ConnectionSettings) {}

    pub fn start_local(_: &str, _: usize) {}

    pub fn set_backend(&mut self, backend: Option<BackendHandle>) {
        self.backend = backend
    }

    pub fn action_step(&mut self) {
        println!("do step");
        self.action = 4;
    }

    pub fn update(&mut self, backend_plugins: &mut BackendPlugins) {
        // swap the writers
        //let c_writer = self.current_writer;
        //let n_writer = (self.current_writer + 1) & 1;

        ReaderWrapper::init_from_writer(&mut self.reader, &self.writers[0]);
        ReaderWrapper::reset_writer(&mut self.writers[1]);

        if let Some(backend) = backend_plugins.get_backend(self.backend) {
            unsafe {
                let plugin_funcs = backend.plugin_type.plugin_funcs as *mut CBackendCallbacks;
                ((*plugin_funcs).update.unwrap())(backend.plugin_data,
                                                  self.action,
                                                  self.reader.api as *mut c_void,
                                                  self.writers[1].api as *mut c_void);
            }
        }

        self.action = 0;

        ReaderWrapper::init_from_writer(&mut self.reader, &self.writers[1]);
        ReaderWrapper::reset_writer(&mut self.writers[0]);
    }
}

///
/// Sessions handler
///
pub struct Sessions {
    instances: Vec<Session>,
    current: usize,
    session_counter: SessionHandle,
}

impl Sessions {
    pub fn new() -> Sessions {
        Sessions {
            instances: Vec::new(),
            current: 0,
            session_counter: SessionHandle(0),
        }
    }

    pub fn create_instance(&mut self) -> SessionHandle {
        let s = Session::new(self.session_counter);
        let handle = s.handle;
        self.instances.push(s);
        self.session_counter.0 += 1;
        handle
    }

    pub fn update(&mut self, backend_plugins: &mut BackendPlugins) {
        for session in self.instances.iter_mut() {
            session.update(backend_plugins);
        }
    }

    pub fn get_current(&mut self) -> &mut Session {
        let current = self.current;
        &mut self.instances[current]
    }

    pub fn get_session(&mut self, handle: SessionHandle) -> Option<&mut Session> {
        for i in 0..self.instances.len() {
            if self.instances[i].handle == handle {
                return Some(&mut self.instances[i]);
            }
        }

        None
    }
}

#[cfg(test)]
mod tests {
    use core::reader_wrapper::{ReaderWrapper};
    use super::*;

    #[test]
    fn create_session() {
        let _session = Session::new();
    }

    #[test]
    fn write_simple_event() {
        let mut session = Session::new();

        session.writers[0].event_begin(0x44);
        session.writers[0].event_end();

        ReaderWrapper::init_from_writer(&mut session.reader, &session.writers[0]);

        assert_eq!(session.reader.get_event().unwrap(), 0x44);
    }
}

<commit_msg>Views can now send messages between.<commit_after>use prodbg_api::read_write::{Reader, Writer};
use prodbg_api::backend::{CBackendCallbacks};
use plugins::PluginHandler;
use reader_wrapper::{ReaderWrapper, WriterWrapper};
use backend_plugin::{BackendHandle, BackendPlugins};
use libc::{c_void};

#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct SessionHandle(pub u64);

///! Session is a major part of ProDBG. There can be several sessions active at the same time
///! and each session has exactly one backend. There are only communication internally in a session
///! sessions can't (at least now) not talk to eachother.
///!
///! A backend can have several views at the same time. Data can be sent between the backend and
///| views using the PDReader/PDWriter APIs (prodbg::Writer prodbg::Reader in Rust) and this is the
///| only way for views and backends to talk with each other. There are several reasons for this
///| approach:
///!
///| 1. No "hacks" on trying to share memory. Plugins can be over a socket/webview/etc.
///! 2. Views and backends makes no assumetions on the inner workings of the others.
///! 3. Backends and views can post messages which anyone can decide to (optionally) act on.
///!
pub struct Session {
    pub handle: SessionHandle,
    pub reader: Reader,

    current_writer: usize,
    writers: [Writer; 2],
    action: i32,

    backend: Option<BackendHandle>,
}

///! Connection options for Remote connections. Currently just one Ip adderss
///!
pub struct ConnectionSettings<'a> {
    pub address: &'a str,
}

impl Session {
    pub fn new(handle: SessionHandle) -> Session {
        Session {
            handle: handle,
            writers: [
                WriterWrapper::create_writer(),
                WriterWrapper::create_writer(),
            ],
            reader: ReaderWrapper::create_reader(),
            action: 0,
            current_writer: 0,
            backend: None,
        }
    }

    pub fn get_current_writer(&mut self) -> &mut Writer {
        &mut self.writers[0]
    }

    pub fn start_remote(_plugin_handler: &PluginHandler, _settings: &ConnectionSettings) {}

    pub fn start_local(_: &str, _: usize) {}

    pub fn set_backend(&mut self, backend: Option<BackendHandle>) {
        self.backend = backend
    }

    pub fn action_step(&mut self) {
        println!("do step");
        self.action = 4;
    }

    // The way this code works is to allow the view plugins to have "two rounds" of updates.
    // That is to allow the view plugins to send things that other view plugins can listen
    // to and not only get data from the backend.
    pub fn update(&mut self, backend_plugins: &mut BackendPlugins) {
        // swap the writers
        let c_writer = self.current_writer;
        let n_writer = (self.current_writer + 1) & 1;

        ReaderWrapper::init_from_writer(&mut self.reader, &self.writers[c_writer]);
        ReaderWrapper::reset_writer(&mut self.writers[n_writer]);

        if let Some(backend) = backend_plugins.get_backend(self.backend) {
            unsafe {
                let plugin_funcs = backend.plugin_type.plugin_funcs as *mut CBackendCallbacks;
                ((*plugin_funcs).update.unwrap())(backend.plugin_data,
                                                  self.action,
                                                  self.reader.api as *mut c_void,
                                                  self.writers[n_writer].api as *mut c_void);
            }
        }

        self.action = 0;
        self.current_writer = n_writer;

        //ReaderWrapper::init_from_writer(&mut self.reader, &self.writers[1]);
        //ReaderWrapper::reset_writer(&mut self.writers[0]);
    }
}

///
/// Sessions handler
///
pub struct Sessions {
    instances: Vec<Session>,
    current: usize,
    session_counter: SessionHandle,
}

impl Sessions {
    pub fn new() -> Sessions {
        Sessions {
            instances: Vec::new(),
            current: 0,
            session_counter: SessionHandle(0),
        }
    }

    pub fn create_instance(&mut self) -> SessionHandle {
        let s = Session::new(self.session_counter);
        let handle = s.handle;
        self.instances.push(s);
        self.session_counter.0 += 1;
        handle
    }

    pub fn update(&mut self, backend_plugins: &mut BackendPlugins) {
        for session in self.instances.iter_mut() {
            session.update(backend_plugins);
        }
    }

    pub fn get_current(&mut self) -> &mut Session {
        let current = self.current;
        &mut self.instances[current]
    }

    pub fn get_session(&mut self, handle: SessionHandle) -> Option<&mut Session> {
        for i in 0..self.instances.len() {
            if self.instances[i].handle == handle {
                return Some(&mut self.instances[i]);
            }
        }

        None
    }
}

#[cfg(test)]
mod tests {
    use core::reader_wrapper::{ReaderWrapper};
    use super::*;

    #[test]
    fn create_session() {
        let _session = Session::new();
    }

    #[test]
    fn write_simple_event() {
        let mut session = Session::new();

        session.writers[0].event_begin(0x44);
        session.writers[0].event_end();

        ReaderWrapper::init_from_writer(&mut session.reader, &session.writers[0]);

        assert_eq!(session.reader.get_event().unwrap(), 0x44);
    }
}

<|endoftext|>


<commit_before>extern crate indicatif;

use std::thread;
use std::time::Duration;
use std::sync::Arc;

use indicatif::{ProgressBar, MultiProgress, ProgressStyle};

fn main() {
    let m = Arc::new(MultiProgress::new());
    let sty = ProgressStyle::default_bar()
        .template("{bar:40.green/yellow} {pos:>7}/{len:7}")
        .progress_chars("##-");

    let pb = m.add(ProgressBar::new(5));
    pb.set_style(sty.clone());

    let m2 = m.clone();
    let _ = thread::spawn(move || {
        // make sure we show up at all.  otherwise no rendering
        // event.
        pb.tick();
        for _ in 0..5 {
            let pb2 = m2.add(ProgressBar::new(128));
            pb2.set_style(sty.clone());
            for _ in 0..128 {
                pb2.inc(1);
                thread::sleep(Duration::from_millis(5));
            }
            pb2.finish();
            pb.inc(1);
        }
        pb.finish_with_message("done");
    });

    m.join().unwrap();
}
<commit_msg>Leave default style for an example<commit_after>extern crate indicatif;

use std::thread;
use std::time::Duration;
use std::sync::Arc;

use indicatif::{ProgressBar, MultiProgress, ProgressStyle};

fn main() {
    let m = Arc::new(MultiProgress::new());
    let sty = ProgressStyle::default_bar()
        .template("{bar:40.green/yellow} {pos:>7}/{len:7}");

    let pb = m.add(ProgressBar::new(5));
    pb.set_style(sty.clone());

    let m2 = m.clone();
    let _ = thread::spawn(move || {
        // make sure we show up at all.  otherwise no rendering
        // event.
        pb.tick();
        for _ in 0..5 {
            let pb2 = m2.add(ProgressBar::new(128));
            pb2.set_style(sty.clone());
            for _ in 0..128 {
                pb2.inc(1);
                thread::sleep(Duration::from_millis(5));
            }
            pb2.finish();
            pb.inc(1);
        }
        pb.finish_with_message("done");
    });

    m.join().unwrap();
}
<|endoftext|>


<commit_before>/* Copyright 2016 Jordan Miner
 *
 * Licensed under the MIT license <LICENSE or
 * http://opensource.org/licenses/MIT>. This file may not be copied,
 * modified, or distributed except according to those terms.
 */

#[macro_use]
extern crate clear_coat;
extern crate iup_sys;
extern crate smallvec;

use std::rc::Rc;
use iup_sys::*;
use smallvec::SmallVec;

use clear_coat::*;
use clear_coat::common_attrs_cbs::*;

struct CursorsCanvas {
    canvas: Canvas,
}

impl CursorsCanvas {
    pub fn new() -> Self {
        CursorsCanvas {
            canvas: Canvas::new(),
        }
    }
}

impl CursorAttribute for CursorsCanvas {}

unsafe impl Control for CursorsCanvas {
    fn handle(&self) -> *mut Ihandle {
        self.canvas.handle()
    }
}

fn create_cursors_page() -> Box<Control> {
    let cursors_canvas = Rc::new(CursorsCanvas::new());

    let radios_info = [
        ("None", Cursor::None),
        ("Arrow", Cursor::Arrow),
        ("Busy", Cursor::Busy),
        ("Cross", Cursor::Cross),
        ("Hand", Cursor::Hand),
        ("Help", Cursor::Help),
        ("Move", Cursor::Move),
        ("ResizeN", Cursor::ResizeN),
        ("ResizeS", Cursor::ResizeS),
        ("ResizeNS", Cursor::ResizeNS),
        ("ResizeW", Cursor::ResizeW),
        ("ResizeE", Cursor::ResizeE),
        ("ResizeWE", Cursor::ResizeWE),
        ("ResizeNE", Cursor::ResizeNE),
        ("ResizeSW", Cursor::ResizeSW),
        ("ResizeNW", Cursor::ResizeNW),
        ("ResizeSE", Cursor::ResizeSE),
        ("Text", Cursor::Text),
    ];

    let mut radios = SmallVec::<[Toggle; 32]>::new();
    for &(text, cur) in radios_info.iter() {
        let toggle = Toggle::new();
        toggle.set_title(text);
        let cursors_canvas2 = cursors_canvas.clone();
        toggle.action_event().add(move |checked| {
            if checked { cursors_canvas2.set_cursor(cur); }
        });
        radios.push(toggle);
    }
    // The arrow cursor is the default.
    radios[1].set_on(true);

    let grid = grid_box!(
        &radios[0],
        &radios[1],
        &radios[2],
        &radios[3],
        &radios[4],
        &radios[5],
        &radios[6],
        &radios[7],
        &radios[8],
        &radios[9],
        &radios[10],
        &radios[11],
        &radios[12],
        &radios[13],
        &radios[14],
        &radios[15],
        &radios[16],
        &radios[17],
    );
    grid.set_num_div(NumDiv::Fixed(2));
    grid.fit_all_to_children();
    let page = vbox!(
        &cursors_canvas,
        hbox!(
            fill!(),
            Radio::with_child(&grid),
            fill!(),
        ),
    );
    Box::new(page)
}

fn create_file_dialog_page() -> Box<Control> {
    let type_check_box = Toggle::new();
    type_check_box.set_title("Dialog Type:");

    let open_radio = Toggle::new();
    open_radio.set_title("Open");
    let save_radio = Toggle::new();
    save_radio.set_title("Save");
    let dir_radio = Toggle::new();
    dir_radio.set_title("Directory");
    let type_radio = Radio::with_child(&vbox!(
        &open_radio,
        &save_radio,
        &dir_radio,
    ));

    let dir_check_box = Toggle::new();
    dir_check_box.set_title("Directory:");

    let dir_text_box = Text::new();

    let multiple_files_check_box = Toggle::new();
    multiple_files_check_box.set_title("Multiple Files");

    let show_dialog = Button::with_title("Show Dialog");

    let type_check_box_capt = type_check_box.clone();
    let open_radio_capt = open_radio.clone();
    let save_radio_capt = save_radio.clone();
    let dir_check_box_capt = dir_check_box.clone();
    let dir_text_box_capt = dir_text_box.clone();
    let multiple_files_check_box_capt = multiple_files_check_box.clone();
    show_dialog.action_event().add(move || {
        let dialog = FileDlg::new();
        if type_check_box_capt.is_on() {
            dialog.set_dialog_type(if open_radio_capt.is_on() {
                FileDialogType::Open
            } else if save_radio_capt.is_on() {
                FileDialogType::Save
            } else {
                FileDialogType::Dir
            })
        }
        if dir_check_box_capt.is_on() {
            dialog.set_directory(&dir_text_box_capt.value());
        }
        if multiple_files_check_box_capt.is_on() {
            dialog.set_multiple_files(true);
        }
        dialog.popup(ScreenPosition::CenterParent, ScreenPosition::CenterParent)
              .expect("couldn't show file dialog");
    });

    let grid = grid_box!(
        type_check_box, type_radio,
        dir_check_box, dir_text_box,
        multiple_files_check_box, fill!(),
        fill!(), show_dialog,
    );
    grid.set_num_div(NumDiv::Fixed(2));
    grid.set_size_col(1);
    grid.fit_all_to_children();
    Box::new(grid)
}

fn create_list_page() -> Box<Control> {
    let list = List::new();
    list.set_items(&["A", "B", "C"]);
    let list_label = Label::new();

    let dropdown = List::new();
    dropdown.set_dropdown(true);
    dropdown.set_items(&["apple", "banana", "grape"]);

    let grid = grid_box!(
        &list,
        &list_label,
        &dropdown,
    );

    let list_label_capt = list_label.clone();
    let grid_capt = grid.clone();
    list.action_event().add(move |args: &ListActionArgs| {
        if !args.selected {
            return;
        }
        list_label_capt.set_title(&format!("Selected {}", args.item_index));
        grid_capt.refresh_children();
    });

    Box::new(grid)
}

fn main() {

    let dialog = Dialog::new();

    let tabs = Tabs::new();

    tabs.append_tabs(&[
        TabInfo::new(&*create_cursors_page()).title("Cursors"),
        TabInfo::new(&*create_file_dialog_page()).title("File Dialog"),
        TabInfo::new(&*create_list_page()).title("List"),
    ]);

    dialog.append(&tabs).expect("failed to build the window");
    dialog.set_title("Showcase");

    dialog.show_xy(ScreenPosition::Center, ScreenPosition::Center)
          .expect("failed to show the window");
    main_loop();
}
<commit_msg>Implement dropdown and combo box examples in Showcase<commit_after>/* Copyright 2016 Jordan Miner
 *
 * Licensed under the MIT license <LICENSE or
 * http://opensource.org/licenses/MIT>. This file may not be copied,
 * modified, or distributed except according to those terms.
 */

#[macro_use]
extern crate clear_coat;
extern crate iup_sys;
extern crate smallvec;

use std::rc::Rc;
use iup_sys::*;
use smallvec::SmallVec;

use clear_coat::*;
use clear_coat::common_attrs_cbs::*;

struct CursorsCanvas {
    canvas: Canvas,
}

impl CursorsCanvas {
    pub fn new() -> Self {
        CursorsCanvas {
            canvas: Canvas::new(),
        }
    }
}

impl CursorAttribute for CursorsCanvas {}

unsafe impl Control for CursorsCanvas {
    fn handle(&self) -> *mut Ihandle {
        self.canvas.handle()
    }
}

fn create_cursors_page() -> Box<Control> {
    let cursors_canvas = Rc::new(CursorsCanvas::new());

    let radios_info = [
        ("None", Cursor::None),
        ("Arrow", Cursor::Arrow),
        ("Busy", Cursor::Busy),
        ("Cross", Cursor::Cross),
        ("Hand", Cursor::Hand),
        ("Help", Cursor::Help),
        ("Move", Cursor::Move),
        ("ResizeN", Cursor::ResizeN),
        ("ResizeS", Cursor::ResizeS),
        ("ResizeNS", Cursor::ResizeNS),
        ("ResizeW", Cursor::ResizeW),
        ("ResizeE", Cursor::ResizeE),
        ("ResizeWE", Cursor::ResizeWE),
        ("ResizeNE", Cursor::ResizeNE),
        ("ResizeSW", Cursor::ResizeSW),
        ("ResizeNW", Cursor::ResizeNW),
        ("ResizeSE", Cursor::ResizeSE),
        ("Text", Cursor::Text),
    ];

    let mut radios = SmallVec::<[Toggle; 32]>::new();
    for &(text, cur) in radios_info.iter() {
        let toggle = Toggle::new();
        toggle.set_title(text);
        let cursors_canvas2 = cursors_canvas.clone();
        toggle.action_event().add(move |checked| {
            if checked { cursors_canvas2.set_cursor(cur); }
        });
        radios.push(toggle);
    }
    // The arrow cursor is the default.
    radios[1].set_on(true);

    let grid = grid_box!(
        &radios[0],
        &radios[1],
        &radios[2],
        &radios[3],
        &radios[4],
        &radios[5],
        &radios[6],
        &radios[7],
        &radios[8],
        &radios[9],
        &radios[10],
        &radios[11],
        &radios[12],
        &radios[13],
        &radios[14],
        &radios[15],
        &radios[16],
        &radios[17],
    );
    grid.set_num_div(NumDiv::Fixed(2));
    grid.fit_all_to_children();
    let page = vbox!(
        &cursors_canvas,
        hbox!(
            fill!(),
            Radio::with_child(&grid),
            fill!(),
        ),
    );
    Box::new(page)
}

fn create_file_dialog_page() -> Box<Control> {
    let type_check_box = Toggle::new();
    type_check_box.set_title("Dialog Type:");

    let open_radio = Toggle::new();
    open_radio.set_title("Open");
    let save_radio = Toggle::new();
    save_radio.set_title("Save");
    let dir_radio = Toggle::new();
    dir_radio.set_title("Directory");
    let type_radio = Radio::with_child(&vbox!(
        &open_radio,
        &save_radio,
        &dir_radio,
    ));

    let dir_check_box = Toggle::new();
    dir_check_box.set_title("Directory:");

    let dir_text_box = Text::new();

    let multiple_files_check_box = Toggle::new();
    multiple_files_check_box.set_title("Multiple Files");

    let show_dialog = Button::with_title("Show Dialog");

    let type_check_box_capt = type_check_box.clone();
    let open_radio_capt = open_radio.clone();
    let save_radio_capt = save_radio.clone();
    let dir_check_box_capt = dir_check_box.clone();
    let dir_text_box_capt = dir_text_box.clone();
    let multiple_files_check_box_capt = multiple_files_check_box.clone();
    show_dialog.action_event().add(move || {
        let dialog = FileDlg::new();
        if type_check_box_capt.is_on() {
            dialog.set_dialog_type(if open_radio_capt.is_on() {
                FileDialogType::Open
            } else if save_radio_capt.is_on() {
                FileDialogType::Save
            } else {
                FileDialogType::Dir
            })
        }
        if dir_check_box_capt.is_on() {
            dialog.set_directory(&dir_text_box_capt.value());
        }
        if multiple_files_check_box_capt.is_on() {
            dialog.set_multiple_files(true);
        }
        dialog.popup(ScreenPosition::CenterParent, ScreenPosition::CenterParent)
              .expect("couldn't show file dialog");
    });

    let grid = grid_box!(
        type_check_box, type_radio,
        dir_check_box, dir_text_box,
        multiple_files_check_box, fill!(),
        fill!(), show_dialog,
    );
    grid.set_num_div(NumDiv::Fixed(2));
    grid.set_size_col(1);
    grid.fit_all_to_children();
    Box::new(grid)
}

fn create_list_page() -> Box<Control> {
    let list = List::new();
    list.set_items(&["A", "B", "C"]);
    let list_label = Label::new();

    let multiple_list = List::new();
    multiple_list.set_multiple(true);
    multiple_list.set_items(&["D", "E", "F"]);
    let multiple_list_label = Label::new();

    let dropdown = List::new();
    dropdown.set_dropdown(true);
    dropdown.set_items(&["Apple", "Grape", "Orange"]);
    let dropdown_label = Label::new();

    let edit_box = List::new();
    edit_box.set_dropdown(true);
    edit_box.set_edit_box(true);
    edit_box.set_items(&["Cherry", "Peach", "Pumpkin", "Rhubarb"]);
    let edit_box_label = Label::new();

    let grid = grid_box!(
        &list,
        &multiple_list,
        &list_label,
        &multiple_list_label,
        &dropdown,
        &edit_box,
        &dropdown_label,
        &edit_box_label,
    );
    grid.set_num_div(NumDiv::Fixed(2));
    grid.fit_all_to_children();

    let list_label_capt = list_label.clone();
    let grid_capt = grid.clone();
    list.action_event().add(move |args: &ListActionArgs| {
        if !args.selected {
            return;
        }
        list_label_capt.set_title(&format!("Selected {}", args.item_index));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    let multiple_list_capt = multiple_list.clone();
    let grid_capt = grid.clone();
    multiple_list.action_event().add(move |_: &ListActionArgs| {
        let mut s = String::with_capacity(32);
        for (i, index) in multiple_list_capt.value_multiple().into_iter().enumerate() {
            if i > 0 {
                s += ", ";
            }
            s += &*index.to_string();
        }
        multiple_list_label.set_title(&format!("Selected {}", &s));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    let dropdown_capt = dropdown.clone();
    let grid_capt = grid.clone();
    dropdown.action_event().add(move |_: &ListActionArgs| {
        use std::borrow::Cow;
        let s = dropdown_capt.value_single().map(|i| Cow::Owned(dropdown_capt.item(i))).unwrap_or("No".into());
        dropdown_label.set_title(&format!("{} Juice", &s));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    let grid_capt = grid.clone();
    edit_box.action_event().add(move |args: &ListActionArgs| {
        edit_box_label.set_title(&format!("{} Pie", &args.text));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    Box::new(grid)
}

fn main() {

    let dialog = Dialog::new();

    let tabs = Tabs::new();

    tabs.append_tabs(&[
        TabInfo::new(&*create_cursors_page()).title("Cursors"),
        TabInfo::new(&*create_file_dialog_page()).title("File Dialog"),
        TabInfo::new(&*create_list_page()).title("List"),
    ]);

    dialog.append(&tabs).expect("failed to build the window");
    dialog.set_title("Showcase");

    dialog.show_xy(ScreenPosition::Center, ScreenPosition::Center)
          .expect("failed to show the window");
    main_loop();
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate milagro_crypto;
use self::milagro_crypto::randapi::Random;
use self::milagro_crypto::big::wrappers::MODBYTES;
use self::milagro_crypto::ff::FF;
use self::milagro_crypto::hash::wrappers::hash256;
use self::rand::os::OsRng;
use self::rand::Rng;
use services::crypto::constants::{
    BIG_SIZE,
    BN_MASK,
    PRIMES,
    NUM_PRIMES,
    LARGE_PRIME
};
use services::crypto::types::{ByteOrder};

pub fn generate_random_seed() -> [u8; 32] {
    let mut seed: [u8; 32] = [0; 32];
    let mut rng = OsRng::new().unwrap();
    rng.fill_bytes(&mut seed);
    seed
}

pub fn generate_big_random(size: usize) -> FF {
    let seed = generate_random_seed();
    let mut rng = Random::new(seed);

    let b_size: usize = size / 8 + 1; // number of bytes for mod value
    let big_size: usize = (b_size + MODBYTES - 1) / MODBYTES; // number of BIGs for mod value

    // init mod bytes with 0 and set 1 in proper place
    let mut bytes = vec![0; big_size * MODBYTES];
    bytes[big_size * MODBYTES - b_size] = (1 as u8).wrapping_shl((size - (b_size - 1) * 8) as u32);

    let bv = FF::from_bytes(&bytes[0..], big_size * MODBYTES, BIG_SIZE);
    let r = FF::randomnum(&bv, &mut rng);
    r
}

pub fn generate_prime(size: usize) -> FF {
    let seed = generate_random_seed();
    let mut rng = Random::new(seed);
    let mut iteration = 0;
    let mut is_prime = false;

    let mut prime = generate_big_random(size);
    let mut prime_bytes = prime.to_bytes();
    let length = prime_bytes.len();
    let last_byte = prime_bytes[length - 1];
    prime_bytes[length - 1] = last_byte | 3;
    prime = FF::from_bytes(&prime_bytes, length, BIG_SIZE);
    while !is_prime {
        prime.inc(4);
        iteration += 1;
        is_prime = FF::is_prime(&prime, &mut rng);
    }
    debug!("Iteration: {}\nFound prime: {}", iteration, prime);

    prime
}

pub fn generate_prime_2p_plus_1(size: usize) -> FF {
    let seed = generate_random_seed();
    let mut rng = Random::new(seed);
    let (mut is_prime, mut iteration) = (false, 0);
    let mut prime = FF::new(BIG_SIZE);

    while !is_prime {
        iteration += 1;
        prime = generate_prime(size);
        let mut prime_for_check = FF::mul(&prime, &FF::from_hex("2", BIG_SIZE));
        prime_for_check.inc(1);
        is_prime = FF::is_prime(&prime_for_check, &mut rng);
        debug!("Iteration: {}\nFound prime: {}\nis_prime: {}\n", iteration, prime, is_prime);
    }
    prime
}

pub fn random_qr(n: &FF){

}

fn random_in_range(start: &FF, end: &FF) -> FF {
    let sub = end - start;
    let size = significant_bits(&sub);
    let mut random_number = generate_big_random(size);

    while (&random_number + start) > *end {
        random_number = generate_big_random(size);
    }

    random_number = &random_number + start;
    debug!("start: {}\nend: {}\nsub: {}\nrandom: {}", start, end, sub, random_number);
    random_number
}

pub fn encode_attribute(attribute: &str, byte_order: ByteOrder) {
    //    let mut result = hash(MessageDigest::sha256(), attribute.as_bytes()).unwrap();
    //    let index = result.iter().position(|&value| value == 0);
    //    if let Some(position) = index {
    //        result.truncate(position);
    //    }
    //    if let ByteOrder::Little = byte_order {
    //        result.reverse();
    //    }
    //    let encoded_attribute = AnoncredsService::transform_byte_array_to_big_integer(&result);
    //    encoded_attribute.to_dec_str().unwrap().to_string()
}

fn significant_bytes(n: &FF) -> Vec<u8> {
    let mut bytes = n.to_bytes();
    let length = bytes.len();
    let index = bytes.iter().position(|&value| value != 0);
    if let Some(index) = index {
        bytes.reverse();
        bytes.truncate(length - index);
        bytes.reverse();
    }
    bytes
}

fn significant_bits(n: &FF) -> usize {
    let bytes = significant_bytes(n);
    let mut result = (bytes.len() - 1) * 8;
    result += format!("{:b}", bytes[0]).len();
    result
}

fn generate_probable_prime(size: usize) {
    let mut random_number = generate_big_random(size);
    let mut mods: Vec<FF> = Vec::new();
    for i in 1..NUM_PRIMES {
        debug!("{}", i);
        let bytes = random_number.to_bytes();
        let mut new_random = FF::from_bytes(&bytes, size, BIG_SIZE);
        let prime = FF::from_hex(&format!("{:x}", PRIMES[i])[..], BIG_SIZE);
        FF::modulus(&mut new_random, &prime);
        mods.push(new_random);
    }
    //TODO loop for mods check
}

pub fn get_hash_as_int(num: FF) -> FF {
    let array_bytes: Vec<u8> = num.to_bytes();

    let index = array_bytes.iter().position(|&value| value != 0).unwrap_or(array_bytes.len());

    let mut sha256: hash256 = hash256::new();

    for byte in array_bytes[index..].iter() {
        sha256.process(*byte);
    }

    let mut hashed_array: Vec<u8> =
        sha256.hash().iter()
            .map(|v| *v as u8)
            .collect();

    hashed_array.reverse();

    FF::from_bytes(&hashed_array[..], hashed_array.len(), 2)
}

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

    #[test]
    fn random_in_range_works() {
        ::env_logger::init().unwrap();

        let start = generate_big_random(100);
        let mut end = generate_big_random(120);

        while end < start {
            end = generate_big_random(30);
        }

        let random = random_in_range(&start, &end);
        assert!((random > start) && (random < end));
    }
}<commit_msg>added random_qr<commit_after>extern crate rand;
extern crate milagro_crypto;
use self::milagro_crypto::randapi::Random;
use self::milagro_crypto::big::wrappers::MODBYTES;
use self::milagro_crypto::ff::FF;
use self::milagro_crypto::hash::wrappers::hash256;
use self::rand::os::OsRng;
use self::rand::Rng;
use services::crypto::constants::{
    BIG_SIZE,
    BN_MASK,
    PRIMES,
    NUM_PRIMES,
    LARGE_PRIME
};
use services::crypto::types::{ByteOrder};

pub fn generate_random_seed() -> [u8; 32] {
    let mut seed: [u8; 32] = [0; 32];
    let mut rng = OsRng::new().unwrap();
    rng.fill_bytes(&mut seed);
    seed
}

pub fn generate_big_random(size: usize) -> FF {
    let seed = generate_random_seed();
    let mut rng = Random::new(seed);

    let b_size: usize = size / 8 + 1; // number of bytes for mod value
    let big_size: usize = (b_size + MODBYTES - 1) / MODBYTES; // number of BIGs for mod value

    // init mod bytes with 0 and set 1 in proper place
    let mut bytes = vec![0; big_size * MODBYTES];
    bytes[big_size * MODBYTES - b_size] = (1 as u8).wrapping_shl((size - (b_size - 1) * 8) as u32);

    let bv = FF::from_bytes(&bytes[0..], big_size * MODBYTES, BIG_SIZE);
    let r = FF::randomnum(&bv, &mut rng);
    r
}

pub fn generate_prime(size: usize) -> FF {
    let seed = generate_random_seed();
    let mut rng = Random::new(seed);
    let mut iteration = 0;
    let mut is_prime = false;

    let mut prime = generate_big_random(size);
    let mut prime_bytes = prime.to_bytes();
    let length = prime_bytes.len();
    let last_byte = prime_bytes[length - 1];
    prime_bytes[length - 1] = last_byte | 3;
    prime = FF::from_bytes(&prime_bytes, length, BIG_SIZE);
    while !is_prime {
        prime.inc(4);
        iteration += 1;
        is_prime = FF::is_prime(&prime, &mut rng);
    }
    debug!("Iteration: {}\nFound prime: {}", iteration, prime);

    prime
}

pub fn generate_prime_2p_plus_1(size: usize) -> FF {
    let seed = generate_random_seed();
    let mut rng = Random::new(seed);
    let (mut is_prime, mut iteration) = (false, 0);
    let mut prime = FF::new(BIG_SIZE);

    while !is_prime {
        iteration += 1;
        prime = generate_prime(size);
        let mut prime_for_check = FF::mul(&prime, &FF::from_hex("2", BIG_SIZE));
        prime_for_check.inc(1);
        is_prime = FF::is_prime(&prime_for_check, &mut rng);
        debug!("Iteration: {}\nFound prime: {}\nis_prime: {}\n", iteration, prime, is_prime);
    }
    prime
}

pub fn random_qr(n: &FF){
    println!("n :{}", n);
    let mut random = random_in_range(&FF::from_hex("0", BIG_SIZE), n);
    println!("random :{}", random);
    random = FF::sqr(&random);
    println!("random sqr :{}", random);
//    let mut nn = n.clone();
//    nn.set_size(32);
//    random.set_size(32);
    let random1 = FF::modulus(&random, &n);
    println!("random1 :{}", random1);
//    let (mut ctx, mut random_qr) = (BigNumContext::new().unwrap(), BigNum::new().unwrap());
//    random_qr.sqr(&AnoncredsService::random_in_range(&BigNum::from_u32(0).unwrap(), &n), &mut ctx);
//    random_qr
}

fn random_in_range(start: &FF, end: &FF) -> FF {
    let sub = end - start;
    let size = significant_bits(&sub);
    let mut random_number = generate_big_random(size);

    while (&random_number + start) > *end {
        random_number = generate_big_random(size);
    }

    random_number = &random_number + start;
    debug!("start: {}\nend: {}\nsub: {}\nrandom: {}", start, end, sub, random_number);
    random_number
}

pub fn encode_attribute(attribute: &str, byte_order: ByteOrder) {
    //    let mut result = hash(MessageDigest::sha256(), attribute.as_bytes()).unwrap();
    //    let index = result.iter().position(|&value| value == 0);
    //    if let Some(position) = index {
    //        result.truncate(position);
    //    }
    //    if let ByteOrder::Little = byte_order {
    //        result.reverse();
    //    }
    //    let encoded_attribute = AnoncredsService::transform_byte_array_to_big_integer(&result);
    //    encoded_attribute.to_dec_str().unwrap().to_string()
}

fn significant_bytes(n: &FF) -> Vec<u8> {
    let mut bytes = n.to_bytes();
    let length = bytes.len();
    let index = bytes.iter().position(|&value| value != 0);
    if let Some(index) = index {
        bytes.reverse();
        bytes.truncate(length - index);
        bytes.reverse();
    }
    bytes
}

fn significant_bits(n: &FF) -> usize {
    let bytes = significant_bytes(n);
    let mut result = (bytes.len() - 1) * 8;
    result += format!("{:b}", bytes[0]).len();
    result
}

fn generate_probable_prime(size: usize) {
    let mut random_number = generate_big_random(size);
    let mut mods: Vec<FF> = Vec::new();
    for i in 1..NUM_PRIMES {
        debug!("{}", i);
        let bytes = random_number.to_bytes();
        let mut new_random = FF::from_bytes(&bytes, size, BIG_SIZE);
        let prime = FF::from_hex(&format!("{:x}", PRIMES[i])[..], BIG_SIZE);
        FF::modulus(&mut new_random, &prime);
        mods.push(new_random);
    }
    //TODO loop for mods check
}

pub fn get_hash_as_int(num: FF) -> FF {
    let array_bytes: Vec<u8> = num.to_bytes();

    let index = array_bytes.iter().position(|&value| value != 0).unwrap_or(array_bytes.len());

    let mut sha256: hash256 = hash256::new();

    for byte in array_bytes[index..].iter() {
        sha256.process(*byte);
    }

    let mut hashed_array: Vec<u8> =
        sha256.hash().iter()
            .map(|v| *v as u8)
            .collect();

    hashed_array.reverse();

    FF::from_bytes(&hashed_array[..], hashed_array.len(), 2)
}

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

    #[test]
    fn random_in_range_works() {
        ::env_logger::init().unwrap();

        let start = generate_big_random(100);
        let mut end = generate_big_random(120);

        while end < start {
            end = generate_big_random(30);
        }

        let random = random_in_range(&start, &end);
        assert!((random > start) && (random < end));
    }

    #[test]
    fn test_random_qr() {
        let n = generate_big_random(10);
        random_qr(&n);
    }
}<|endoftext|>