<commit_before>#[macro_use]
extern crate rswm;
extern crate x11;

use std::os::raw::{c_uchar, c_uint};
use x11::{keysym, xlib};

use rswm::client::ClientW;
use rswm::config::*;
use rswm::core;
use rswm::loggers;
use rswm::layout::{Tile, FullScreen, Overview, Layout};
use rswm::util::spawn;

const KEYS: &'static [(c_uint, c_uint, &'static Fn(&mut core::WindowManager))] =
    &[(MOD_MASK, keysym::XK_r, &|_| spawn("dmenu_run", &[])),
      (MOD_MASK, keysym::XK_t, &|_| spawn("urxvt", &[])),
      (MOD_MASK, keysym::XK_Print, &|_| spawn("scrot", &["-e", "mv $f ~/"])),
      (MOD_MASK | xlib::Mod1Mask,
       keysym::XK_Print,
       &|_| spawn("scrot", &["-s", "-e", "mv $f ~/"])),
      (MOD_MASK, keysym::XK_f, &|_| spawn("pcmanfm", &[])),
      (MOD_MASK, keysym::XK_l, &|_| spawn("i3lock", &["-c", "000000", "-n"])),
      (0, keysym::XF86XK_MonBrightnessUp, &|_| spawn("xbrightness", &["+10000"])),
      (0, keysym::XF86XK_MonBrightnessDown, &|_| spawn("xbrightness", &["-10000"])),
      (0, keysym::XF86XK_AudioRaiseVolume, &|_| spawn("amixer", &["set", "Master", "5000+"])),
      (0, keysym::XF86XK_AudioLowerVolume, &|_| spawn("amixer", &["set", "Master", "5000-"])),
      (0, keysym::XF86XK_AudioMute, &|_| spawn("amixer", &["set", "Master", "toggle"])),
      (0, keysym::XF86XK_AudioMicMute, &|_| spawn("amixer", &["set", "Capture", "toggle"]))];

const START_PROGRAMS: &'static [&'static Fn()] =
    &[&|| spawn("xcompmgr", &[]),
      &|| spawn("fcitx", &[]),
      &|| spawn("tilda", &["--hidden"]),
      &|| spawn("/usr/lib/polkit-kde/polkit-kde-authentication-agent-1", &[])];

const TAG_LAYOUT: &'static [(c_uchar, &'static str)] = &[('9' as c_uchar, "fullscreen"),
                                                         (TAG_OVERVIEW as c_uchar, "overview")];

const RULES: &'static [(&'static Fn(&ClientW) -> bool, &'static Fn(&mut ClientW))] =
    &[(&|c| c.get_class() == "Gimp", &|c| c.set_floating(true)),
      (&|c| c.is_dialog(), &|c| c.set_floating(true)),
      (&|c| c.get_class() == "VirtualBox", &|c| c.set_floating(true)),
      (&|c| c.get_class() == "Tilda",
       &|c| {
           c.set_floating(true);
           c.set_sticky(true);
       })];

const TAG_KEYS: &'static (&'static [(c_uint, c_uint, &'static Fn(&mut core::WindowManager))],
          &'static [c_uchar]) = &define_tags!(MOD_MASK,
                                              xlib::ShiftMask,
                                              ['1', '2', '3', '4', '5', '6', '7', '8', '9']);

const TAG_DESCRIPTION: &'static [(c_uchar, &'static str)] = &[('1' as c_uchar, "网页"),
                                                              ('2' as c_uchar, "代码")];

fn main() {
    let config = Config::default()
        .border_width(2)
        .bar_height(19)
        .addtional_keys(KEYS)
        .start_programs(START_PROGRAMS)
        .tag_keys(TAG_KEYS)
        .tag_default('1' as c_uchar)
        .rules(RULES)
        .tag_description(TAG_DESCRIPTION)
        .tag_layout(vec![('9' as c_uchar, Box::new(FullScreen)),
                         (TAG_OVERVIEW as c_uchar, Box::new(Overview))]);
    let xmobar_logger = loggers::XMobarLogger::new(loggers::LoggerConfig::default(), &[]);
    let mut window_manager = core::WindowManager::new(config);
    window_manager.set_logger(Box::new(xmobar_logger));
    window_manager.run();
}
<commit_msg>add dmenu to switch between windows.<commit_after>#[macro_use]
extern crate rswm;
extern crate x11;

use std::io;
use std::io::{Read, Write};
use std::os::raw::{c_uchar, c_uint};
use std::process;
use x11::{keysym, xlib};

use rswm::client::ClientW;
use rswm::config::*;
use rswm::core;
use rswm::loggers;
use rswm::layout::{Tile, FullScreen, Overview, Layout};
use rswm::util::spawn;

const KEYS: &'static [(c_uint, c_uint, &'static Fn(&mut core::WindowManager))] =
    &[(MOD_MASK, keysym::XK_r, &|_| spawn("dmenu_run", &[])),
      (MOD_MASK, keysym::XK_t, &|_| spawn("urxvt", &[])),
      (MOD_MASK, keysym::XK_Print, &|_| spawn("scrot", &["-e", "mv $f ~/"])),
      (MOD_MASK | xlib::Mod1Mask,
       keysym::XK_Print,
       &|_| spawn("scrot", &["-s", "-e", "mv $f ~/"])),
      (MOD_MASK, keysym::XK_f, &|_| spawn("pcmanfm", &[])),
      (MOD_MASK, keysym::XK_l, &|_| spawn("i3lock", &["-c", "000000", "-n"])),
      (0, keysym::XF86XK_MonBrightnessUp, &|_| spawn("xbrightness", &["+10000"])),
      (0, keysym::XF86XK_MonBrightnessDown, &|_| spawn("xbrightness", &["-10000"])),
      (0, keysym::XF86XK_AudioRaiseVolume, &|_| spawn("amixer", &["set", "Master", "5000+"])),
      (0, keysym::XF86XK_AudioLowerVolume, &|_| spawn("amixer", &["set", "Master", "5000-"])),
      (0, keysym::XF86XK_AudioMute, &|_| spawn("amixer", &["set", "Master", "toggle"])),
      (0, keysym::XF86XK_AudioMicMute, &|_| spawn("amixer", &["set", "Capture", "toggle"])),
      (MOD_MASK,
       keysym::XK_w,
       &|w| {
        let clients = w.all_clients();
        let contents: Vec<String> =
            clients.iter().map(|c| format!("[{}] {}", c.get_class(), c.get_title())).collect();
        match dmenu_helper(contents.iter(),
                           &["-p", "window", "-i", "-l", "7", "-sb", "#000000", "-sf",
                             "#00ff00", "-nb", "#000000", "-nf", "#dddddd"]) {
            Ok(result) => {
                if let Some(position) = contents.iter().position(|s| (*s).trim() == result.trim()) {
                    let c = clients[position].clone();
                    w.select_tag(c.tag());
                    w.set_focus(c);
                }
            }
            Err(_) => return,
        }
    })];

const START_PROGRAMS: &'static [&'static Fn()] =
    &[&|| spawn("xcompmgr", &[]),
      &|| spawn("fcitx", &[]),
      &|| spawn("tilda", &["--hidden"]),
      &|| spawn("/usr/lib/polkit-kde/polkit-kde-authentication-agent-1", &[])];

const TAG_LAYOUT: &'static [(c_uchar, &'static str)] = &[('9' as c_uchar, "fullscreen"),
                                                         (TAG_OVERVIEW as c_uchar, "overview")];

const RULES: &'static [(&'static Fn(&ClientW) -> bool, &'static Fn(&mut ClientW))] =
    &[(&|c| c.get_class() == "Gimp", &|c| c.set_floating(true)),
      (&|c| c.is_dialog(), &|c| c.set_floating(true)),
      (&|c| c.get_class() == "VirtualBox", &|c| c.set_floating(true)),
      (&|c| c.get_class() == "Tilda",
       &|c| {
           c.set_floating(true);
           c.set_sticky(true);
       })];

const TAG_KEYS: &'static (&'static [(c_uint, c_uint, &'static Fn(&mut core::WindowManager))],
          &'static [c_uchar]) = &define_tags!(MOD_MASK,
                                              xlib::ShiftMask,
                                              ['1', '2', '3', '4', '5', '6', '7', '8', '9']);

const TAG_DESCRIPTION: &'static [(c_uchar, &'static str)] = &[('1' as c_uchar, "网页"),
                                                              ('2' as c_uchar, "代码")];

fn main() {
    let config = Config::default()
        .border_width(2)
        .bar_height(19)
        .addtional_keys(KEYS)
        .start_programs(START_PROGRAMS)
        .tag_keys(TAG_KEYS)
        .tag_default('1' as c_uchar)
        .rules(RULES)
        .tag_description(TAG_DESCRIPTION)
        .tag_layout(vec![('9' as c_uchar, Box::new(FullScreen)),
                         (TAG_OVERVIEW as c_uchar, Box::new(Overview))]);
    let xmobar_logger = loggers::XMobarLogger::new(loggers::LoggerConfig::default(), &[]);
    let mut window_manager = core::WindowManager::new(config);
    window_manager.set_logger(Box::new(xmobar_logger));
    window_manager.run();
}

fn dmenu_helper<'a, I>(strings: I, args: &[&str]) -> Result<String, io::Error>
    where I: Iterator<Item = &'a String>
{
    let mut child = try!(process::Command::new("dmenu")
        .args(args)
        .stdin(process::Stdio::piped())
        .stdout(process::Stdio::piped())
        .spawn());
    for c in strings {
        try!(writeln!(child.stdin.as_mut().unwrap(), "{}", c));
    }
    try!(child.wait());
    let mut result = String::new();
    try!(child.stdout.unwrap().read_to_string(&mut result));
    Ok(result)
}<|endoftext|>


<commit_before>
// library
extern crate my_extern_lib;

// modules
mod simple_functions {
    pub fn print_hello_world() {
        println!("Hello, World! (from the simple_functions module)");
     }

    // nested modules
    pub mod simple_math {
        pub fn multiple_two_integers(a: i32, b: i32) -> i32 {
            a * b
        }
    }
}

use simple_functions::simple_math::multiple_two_integers;

fn print_some_msg() {
    println!("Modules: printing from the outer function");
}

mod sample_module {

    pub fn call_sample_module() {
        use second_module::print_some_msg as print_second;
        use self::second_module::print_some_msg as print_second_sample;
        use super::print_some_msg as print_outside;
        print_outside();
        print_second();
        print_some_msg();
        print_second_sample();
    }

    mod second_module {

        pub fn print_some_msg() {
            println!("Modules: printing from the second module inside the sample module");
        }

    }

    fn print_some_msg() {
        println!("Modules: printing from the inside of the sample module");
    }

}

mod second_module {
    pub fn print_some_msg() {
        println!("Modules: printing from the second module");
    }
}

mod modules;

fn main() {

    // formatted output
    println!("Hello, Rust!");
    println!("Integer number = {}", 23);
    println!("Float number = {}", 1.012);
    println!("Repeat printing: {0}, {1}, {1}, {3}, {2}", 2, 1, 44, 9);
    println!("Named arguments: {name}, {age}, {occupation}", age="24", name="Ann", occupation="Designer");
    println!("{:08b} XOR {:08b} = {:08b}", 3i8, 32i8, 3i8 ^ 34i8);
    println!("Floating point number {:?}", 2.910210);
    println!("Hex: {:08X}, {:08x}", 131342112, 131342112);
    // TODO find out why this doesn't work:
    //println!("{0:08X}, {0:08x}", 7661);

    // variables
    let integer = 3i32;
    let floating_point = 2.1137;

    let mut u_integer = 3u32;
    //integer += 1; error: an immutable variable
    u_integer += 1;

    println!("{}, {}, {}", integer, floating_point, u_integer);
    // TODO find out why snake case instead of camel case

    // shadowing
    let first_var = 4;
    {
        let first_var = 51;
        println!("first_var = {}", first_var);
    }
    println!("first_var = {}", first_var);

    // unitialized variables
    let uninit_var;
    //println!("uninit_var = {}", uninit_var); error: use of an init variable
    uninit_var = 231.2;
    println!("already initialized uninit_var = {}", uninit_var);

    // type casting
    let a_integer = 0x40_u8;
    let a_char = a_integer as char;
    println!("char cast from integer {}: {}", a_integer, a_char);

    let a_float = 8.45511;
    println!("integer cast from float {}: {}", a_float, a_float as i32);

    println!("Binary represntation of {}: {:08b}", -1_i8, -1_i8);
    println!("Binary represntation of {}: {:08b}", -2_i8, -2_i8);

    // aliases
    type FloatingPoint32 = f32;
    let a_float_2 : FloatingPoint32 = 3 as f32;
    println!("Type alias: {}, size of var {}", a_float_2, std::mem::size_of_val(&a_float_2));

    // expressions
    let expr = {
        let x = 4.09;
        let y = 1.28;
        println!("x = {}, y = {}", x, y);
        x / y
    };
    println!("expr = {}", expr);

    // if-statement (every if-statement is an expression too, which is really a cool thing)
    let speed = 10;
    let mass = 890;
    let consumption =
        if speed < 0 {
            -1.0
        }
        else if speed == 0 {
            0.8
        }
        else if speed > 0 && speed < 10 {
            18.52
        }
        else if speed >= 10 && speed < 30 {
            let x = mass / speed;
            (x as f32) * 0.05
        }
        else {
            11.71
        };
        println!("Speed = {}, consumption = {}", speed, consumption);

        // loop
        let mut count = 0u32;
        loop {
            println!("loop iteration #{}", count);
            count += 1;
            if count > 9 {
            break;
            }
        }

        count = 0;
        while count < 10 {
            println!("while loop iteration #{}", count);
            count += 1;
        }

        for n in 0u32..10 {
            println!("for loop iteration #{}", n);
        }

        // matching
        let age = 19;
        match age {
            1  => println!("Seems like 1"),
            5  => println!("It's 5"),
            18 => println!("Exactly 18!"),
            _  => println!("I couldn't guess :("),
        }

        match age {
            a if a > 1 && a <= 9  => println!("The age is in range [1,9]"),
            a if a > 9 && a <= 19 => println!("The age is in range [10, 19]"),
            _                     => println!("Nothing, I don't know what range the age is in :("),
        }

        // the previous match is equivalent to the following:
        match age {
            a @ 1...9   => println!("The age is {} and in range [1,9]", a),
            a @ 10...19 => println!("The age is {} and in range [10, 19]", a),
            a           => println!("Nothing, I don't know what range the age {} is in :(", a),
        }

        // if let
        let a_some = Some(0.0008);
        if let Some(i) = a_some {
            println!("a_some is not None, {}", i);
            println!("result {}",  9.0 / i);
        }
        else {
            println!("None");
        }

        // while let
        let mut a_optional = Some(10);

        while let Some(i) = a_optional {
            if i == 20 {
                println!("while let: i equals 20, leave");
                a_optional = None;
            }
            else {
                a_optional = Some(i + 1);
            }
        }

        // functions, finally!
        let first_integer: i32 = -20;
        let second_integer: i32 = 8;
        let result_of_addition = add_two_integers(first_integer, second_integer);
        println!("{} + {} = {}", first_integer, second_integer, result_of_addition);

        simple_functions::print_hello_world();
        let mul_result = simple_functions::simple_math::multiple_two_integers(3, 15);
        println!("Modules: multiplication result = {}", mul_result);

        // this doesn't work.. why?
        println!("Modules: multiplication result 2 = {}", multiple_two_integers(-1, 8));

        // "super" and "self"
        sample_module::call_sample_module();

        // file hierarchy
        {
            let a : i32 = 4;
            let b : i32 = 15;
            println!("modules::math {} + {} = {}", a, b, modules::math::add_two_int(a, b));
        }

        // call external library
        my_extern_lib::run(5);

        // tuples
        let pair = ("key", 4);
        println!("tuple value: ({}, {})", pair.0, pair.1);
        println!("tuple value: {:?}", pair);

        // structs
        let bmw: Car = Car {color: "Blue".to_string(), weight: 940};
        println!("BMW: {} - {}", bmw.color, bmw.weight);

        // tuple structs
        let color_1: RgbColor = RgbColor(123, 33, 81);
        println!("RGB color: {}, {}, {}", color_1.0, color_1.1, color_1.2);

        // unit structs
        let _nil = Nil;

        // a struct with a constructor and getter
        let rabbit = my_extern_lib::Animal::new(2, 4, "The King");
        println!("Rabbit: {}, {}, {}", rabbit.age, rabbit.weight, rabbit.get_secret_info());

        // generics
        {
            struct ThreeValues<T, U, V> {
                first: T,
                second: U,
                third: V,
            }

            let three_values = ThreeValues { first: 4, second: 2.01, third: "hello" };
            println!("Generic data structure: {}, {}, {}", three_values.first, three_values.second, three_values.third);

            // generic function
            fn swap<U, V>(first_value: U, second_value: V) -> (V, U) {
                (second_value, first_value)
            }

            let random_tuple = swap(4, 2);
            println!("Use unused variables: {} {}", random_tuple.0, random_tuple.1);

        }

        // box (heap allocation)
        {

            let toyota: Car = Car {color: "Green".to_string(), weight: 1040,};
            let porche: Box<Car> = Box::new(Car {color: "Black".to_string(), weight: 876, });

            println!("Toyota's size on stack is {}", std::mem::size_of_val(&toyota));
            println!("Boxed porche's size on stack is {}", std::mem::size_of_val(&porche));

            let unboxed_porche: Car = *porche;
            println!("Unboxed porche's size on stack is {}", std::mem::size_of_val(&unboxed_porche));

            // ownership
            let bmw : Box<Car> = Box::new(Car {color: "Yellow".to_string(), weight: 1620});
            println!("Boxed BMW at {:p}: {}/{}", &bmw, bmw.color, bmw.weight);
            let moved_bmw: Box<Car> = bmw;
            println!("Moved BMW at {:p}: {}/{}", &moved_bmw, moved_bmw.color, moved_bmw.weight);
            // can't do the following, the ownership has been moved
            // println!("Boxed BMW at {:p}: {}/{}", &bmw, bmw.color, bmw.weight);

            // mutability
            let immutable_car = Box::new(Car {color: "Pink".to_string(), weight: 510});
            // can't do this
            // immutable_car.weight = 403;

            // but we can change mutability
            let mut mutable_car = immutable_car;
            mutable_car.weight = 401;

        }

        // ref
        {

            let mut bmw: Car = Car {color: "Green".to_string(), weight: 870};
            println!("Ref: bmw {},{}", bmw.color, bmw.weight);

            {
                let Car {color: _, weight: ref weight_reference} = bmw;

                println!("Ref: {}", *weight_reference);
            }

            {
                let Car {color: _, weight: ref mut weight_mut_ref} = bmw;

                *weight_mut_ref = 200;
            }

            println!("Ref: bmw {},{}", bmw.color, bmw.weight);

        }

        // try some enums
        {

            enum TwoValues {
                First(i8),
                Second(f32),
            }

            fn test_enum(some_number: i32) -> TwoValues {

                if some_number > 0 {
                    TwoValues::First(120)
                }
                else {
                    TwoValues::Second(3.09)
                }

            }

            match test_enum(-2) {
                TwoValues::First(value) => println!("TwoValues enum: {}", value),
                TwoValues::Second(value) => println!("TwoValues enum: {}", value),
            }

            let two_values_instance = TwoValues::First(9);
            println!("TwoValues enum: size of a variant {}", std::mem::size_of_val(&two_values_instance));

        }

        // closures
        {
            let say = |phrase: String| {println!("{}", phrase)};
            say("Hello, closure!".to_string()); // this is probably worse than just println!

            fn mutate_integer<F: Fn(i32) -> i32>(value: i32, mutator: F) -> i32 {
                mutator(value)
            }

            let modulo_three = |v: i32| {v % 3};

            let value: i32 = 23;
            println!("Closures: input value = {}, result = {}", value, mutate_integer(value, modulo_three));

            let add_five = |v: u32| {v + 5};
            let mul_ten = |v: u32| {v * 10};

            fn mutate_integer_2<F, G>(value: u32, mutator_1: F, mutator_2: G) -> u32
                where F: Fn(u32) -> u32, G: Fn(u32) -> u32 {

                mutator_2(mutator_1(value))

            }

            let value_2: u32 = 7194682;
            println!("Closures #2: input value = {}, result = {}", value_2, mutate_integer_2(value_2, add_five, mul_ten));
        }

        // threads
        {
            use std::io;
            use std::thread;
            use std::sync::mpsc;

            // without a guard
            thread::spawn(|| {
                println!("Very first thread EEEEEEYYYYYEEEECCCCAAAAAAATTTCCCHHHEEEERRR!!!");
            });
            thread::sleep_ms(50); // we need it because main terminates and kills all the threads

            // with a guard
            let thread_guard: thread::JoinGuard<()> = thread::scoped(|| {
                println!("Thread with a guard here!!");
            });
            println!("Thread guard: {:?}", thread_guard.thread().name());

            // another example
            for i in 0..16 {

                thread::spawn(move || {
                    println!("Thread #{} started", i);
                    thread::sleep_ms(500 % (i + 1));
                    println!("Thread #{} finished", i);
                });

            }
            thread::sleep_ms(2500);

            // channels

            let (tx, rx) = mpsc::channel();

            thread::spawn(move || {
                for _ in 10..20 {
                    let mut read_buffer: String = String::new();
                    io::stdin().read_line(&mut read_buffer).ok().expect("failed to read line");
                    tx.send(read_buffer).unwrap();
                }
            });

            for _ in 0..5 {
                println!("Got value {:?} from another thread", rx.recv().unwrap());
            }

        }
}

// a C-like struct
struct Car {
    color: String,
    weight: u32,
}

// a tuple struct s
struct RgbColor(i8, i8, i8);

// a unit struct
struct Nil;

fn add_two_integers(a: i32, b: i32) -> i32 {
    a + b
}
<commit_msg>Comment the use of scoped threads (see #24292)<commit_after>
// library
extern crate my_extern_lib;

// modules
mod simple_functions {
    pub fn print_hello_world() {
        println!("Hello, World! (from the simple_functions module)");
     }

    // nested modules
    pub mod simple_math {
        pub fn multiple_two_integers(a: i32, b: i32) -> i32 {
            a * b
        }
    }
}

use simple_functions::simple_math::multiple_two_integers;

fn print_some_msg() {
    println!("Modules: printing from the outer function");
}

mod sample_module {

    pub fn call_sample_module() {
        use second_module::print_some_msg as print_second;
        use self::second_module::print_some_msg as print_second_sample;
        use super::print_some_msg as print_outside;
        print_outside();
        print_second();
        print_some_msg();
        print_second_sample();
    }

    mod second_module {

        pub fn print_some_msg() {
            println!("Modules: printing from the second module inside the sample module");
        }

    }

    fn print_some_msg() {
        println!("Modules: printing from the inside of the sample module");
    }

}

mod second_module {
    pub fn print_some_msg() {
        println!("Modules: printing from the second module");
    }
}

mod modules;

fn main() {

    // formatted output
    println!("Hello, Rust!");
    println!("Integer number = {}", 23);
    println!("Float number = {}", 1.012);
    println!("Repeat printing: {0}, {1}, {1}, {3}, {2}", 2, 1, 44, 9);
    println!("Named arguments: {name}, {age}, {occupation}", age="24", name="Ann", occupation="Designer");
    println!("{:08b} XOR {:08b} = {:08b}", 3i8, 32i8, 3i8 ^ 34i8);
    println!("Floating point number {:?}", 2.910210);
    println!("Hex: {:08X}, {:08x}", 131342112, 131342112);
    // TODO find out why this doesn't work:
    //println!("{0:08X}, {0:08x}", 7661);

    // variables
    let integer = 3i32;
    let floating_point = 2.1137;

    let mut u_integer = 3u32;
    //integer += 1; error: an immutable variable
    u_integer += 1;

    println!("{}, {}, {}", integer, floating_point, u_integer);
    // TODO find out why snake case instead of camel case

    // shadowing
    let first_var = 4;
    {
        let first_var = 51;
        println!("first_var = {}", first_var);
    }
    println!("first_var = {}", first_var);

    // unitialized variables
    let uninit_var;
    //println!("uninit_var = {}", uninit_var); error: use of an init variable
    uninit_var = 231.2;
    println!("already initialized uninit_var = {}", uninit_var);

    // type casting
    let a_integer = 0x40_u8;
    let a_char = a_integer as char;
    println!("char cast from integer {}: {}", a_integer, a_char);

    let a_float = 8.45511;
    println!("integer cast from float {}: {}", a_float, a_float as i32);

    println!("Binary represntation of {}: {:08b}", -1_i8, -1_i8);
    println!("Binary represntation of {}: {:08b}", -2_i8, -2_i8);

    // aliases
    type FloatingPoint32 = f32;
    let a_float_2 : FloatingPoint32 = 3 as f32;
    println!("Type alias: {}, size of var {}", a_float_2, std::mem::size_of_val(&a_float_2));

    // expressions
    let expr = {
        let x = 4.09;
        let y = 1.28;
        println!("x = {}, y = {}", x, y);
        x / y
    };
    println!("expr = {}", expr);

    // if-statement (every if-statement is an expression too, which is really a cool thing)
    let speed = 10;
    let mass = 890;
    let consumption =
        if speed < 0 {
            -1.0
        }
        else if speed == 0 {
            0.8
        }
        else if speed > 0 && speed < 10 {
            18.52
        }
        else if speed >= 10 && speed < 30 {
            let x = mass / speed;
            (x as f32) * 0.05
        }
        else {
            11.71
        };
        println!("Speed = {}, consumption = {}", speed, consumption);

        // loop
        let mut count = 0u32;
        loop {
            println!("loop iteration #{}", count);
            count += 1;
            if count > 9 {
            break;
            }
        }

        count = 0;
        while count < 10 {
            println!("while loop iteration #{}", count);
            count += 1;
        }

        for n in 0u32..10 {
            println!("for loop iteration #{}", n);
        }

        // matching
        let age = 19;
        match age {
            1  => println!("Seems like 1"),
            5  => println!("It's 5"),
            18 => println!("Exactly 18!"),
            _  => println!("I couldn't guess :("),
        }

        match age {
            a if a > 1 && a <= 9  => println!("The age is in range [1,9]"),
            a if a > 9 && a <= 19 => println!("The age is in range [10, 19]"),
            _                     => println!("Nothing, I don't know what range the age is in :("),
        }

        // the previous match is equivalent to the following:
        match age {
            a @ 1...9   => println!("The age is {} and in range [1,9]", a),
            a @ 10...19 => println!("The age is {} and in range [10, 19]", a),
            a           => println!("Nothing, I don't know what range the age {} is in :(", a),
        }

        // if let
        let a_some = Some(0.0008);
        if let Some(i) = a_some {
            println!("a_some is not None, {}", i);
            println!("result {}",  9.0 / i);
        }
        else {
            println!("None");
        }

        // while let
        let mut a_optional = Some(10);

        while let Some(i) = a_optional {
            if i == 20 {
                println!("while let: i equals 20, leave");
                a_optional = None;
            }
            else {
                a_optional = Some(i + 1);
            }
        }

        // functions, finally!
        let first_integer: i32 = -20;
        let second_integer: i32 = 8;
        let result_of_addition = add_two_integers(first_integer, second_integer);
        println!("{} + {} = {}", first_integer, second_integer, result_of_addition);

        simple_functions::print_hello_world();
        let mul_result = simple_functions::simple_math::multiple_two_integers(3, 15);
        println!("Modules: multiplication result = {}", mul_result);

        // this doesn't work.. why?
        println!("Modules: multiplication result 2 = {}", multiple_two_integers(-1, 8));

        // "super" and "self"
        sample_module::call_sample_module();

        // file hierarchy
        {
            let a : i32 = 4;
            let b : i32 = 15;
            println!("modules::math {} + {} = {}", a, b, modules::math::add_two_int(a, b));
        }

        // call external library
        my_extern_lib::run(5);

        // tuples
        let pair = ("key", 4);
        println!("tuple value: ({}, {})", pair.0, pair.1);
        println!("tuple value: {:?}", pair);

        // structs
        let bmw: Car = Car {color: "Blue".to_string(), weight: 940};
        println!("BMW: {} - {}", bmw.color, bmw.weight);

        // tuple structs
        let color_1: RgbColor = RgbColor(123, 33, 81);
        println!("RGB color: {}, {}, {}", color_1.0, color_1.1, color_1.2);

        // unit structs
        let _nil = Nil;

        // a struct with a constructor and getter
        let rabbit = my_extern_lib::Animal::new(2, 4, "The King");
        println!("Rabbit: {}, {}, {}", rabbit.age, rabbit.weight, rabbit.get_secret_info());

        // generics
        {
            struct ThreeValues<T, U, V> {
                first: T,
                second: U,
                third: V,
            }

            let three_values = ThreeValues { first: 4, second: 2.01, third: "hello" };
            println!("Generic data structure: {}, {}, {}", three_values.first, three_values.second, three_values.third);

            // generic function
            fn swap<U, V>(first_value: U, second_value: V) -> (V, U) {
                (second_value, first_value)
            }

            let random_tuple = swap(4, 2);
            println!("Use unused variables: {} {}", random_tuple.0, random_tuple.1);

        }

        // box (heap allocation)
        {

            let toyota: Car = Car {color: "Green".to_string(), weight: 1040,};
            let porche: Box<Car> = Box::new(Car {color: "Black".to_string(), weight: 876, });

            println!("Toyota's size on stack is {}", std::mem::size_of_val(&toyota));
            println!("Boxed porche's size on stack is {}", std::mem::size_of_val(&porche));

            let unboxed_porche: Car = *porche;
            println!("Unboxed porche's size on stack is {}", std::mem::size_of_val(&unboxed_porche));

            // ownership
            let bmw : Box<Car> = Box::new(Car {color: "Yellow".to_string(), weight: 1620});
            println!("Boxed BMW at {:p}: {}/{}", &bmw, bmw.color, bmw.weight);
            let moved_bmw: Box<Car> = bmw;
            println!("Moved BMW at {:p}: {}/{}", &moved_bmw, moved_bmw.color, moved_bmw.weight);
            // can't do the following, the ownership has been moved
            // println!("Boxed BMW at {:p}: {}/{}", &bmw, bmw.color, bmw.weight);

            // mutability
            let immutable_car = Box::new(Car {color: "Pink".to_string(), weight: 510});
            // can't do this
            // immutable_car.weight = 403;

            // but we can change mutability
            let mut mutable_car = immutable_car;
            mutable_car.weight = 401;

        }

        // ref
        {

            let mut bmw: Car = Car {color: "Green".to_string(), weight: 870};
            println!("Ref: bmw {},{}", bmw.color, bmw.weight);

            {
                let Car {color: _, weight: ref weight_reference} = bmw;

                println!("Ref: {}", *weight_reference);
            }

            {
                let Car {color: _, weight: ref mut weight_mut_ref} = bmw;

                *weight_mut_ref = 200;
            }

            println!("Ref: bmw {},{}", bmw.color, bmw.weight);

        }

        // try some enums
        {

            enum TwoValues {
                First(i8),
                Second(f32),
            }

            fn test_enum(some_number: i32) -> TwoValues {

                if some_number > 0 {
                    TwoValues::First(120)
                }
                else {
                    TwoValues::Second(3.09)
                }

            }

            match test_enum(-2) {
                TwoValues::First(value) => println!("TwoValues enum: {}", value),
                TwoValues::Second(value) => println!("TwoValues enum: {}", value),
            }

            let two_values_instance = TwoValues::First(9);
            println!("TwoValues enum: size of a variant {}", std::mem::size_of_val(&two_values_instance));

        }

        // closures
        {
            let say = |phrase: String| {println!("{}", phrase)};
            say("Hello, closure!".to_string()); // this is probably worse than just println!

            fn mutate_integer<F: Fn(i32) -> i32>(value: i32, mutator: F) -> i32 {
                mutator(value)
            }

            let modulo_three = |v: i32| {v % 3};

            let value: i32 = 23;
            println!("Closures: input value = {}, result = {}", value, mutate_integer(value, modulo_three));

            let add_five = |v: u32| {v + 5};
            let mul_ten = |v: u32| {v * 10};

            fn mutate_integer_2<F, G>(value: u32, mutator_1: F, mutator_2: G) -> u32
                where F: Fn(u32) -> u32, G: Fn(u32) -> u32 {

                mutator_2(mutator_1(value))

            }

            let value_2: u32 = 7194682;
            println!("Closures #2: input value = {}, result = {}", value_2, mutate_integer_2(value_2, add_five, mul_ten));
        }

        // threads
        {
            use std::io;
            use std::thread;
            use std::sync::mpsc;

            // without a guard
            thread::spawn(|| {
                println!("Very first thread EEEEEEYYYYYEEEECCCCAAAAAAATTTCCCHHHEEEERRR!!!");
            });
            thread::sleep_ms(50); // we need it because main terminates and kills all the threads

            // with a guard (got unstable because of the memory leak issue #24292)
            /*
            let thread_guard: thread::JoinGuard<()> = thread::scoped(|| {
                println!("Thread with a guard here!!");
            });
            println!("Thread guard: {:?}", thread_guard.thread().name());
            */

            // another example
            for i in 0..16 {

                thread::spawn(move || {
                    println!("Thread #{} started", i);
                    thread::sleep_ms(500 % (i + 1));
                    println!("Thread #{} finished", i);
                });

            }
            thread::sleep_ms(2500);

            // channels

            let (tx, rx) = mpsc::channel();

            thread::spawn(move || {
                for _ in 10..20 {
                    let mut read_buffer: String = String::new();
                    io::stdin().read_line(&mut read_buffer).ok().expect("failed to read line");
                    tx.send(read_buffer).unwrap();
                }
            });

            for _ in 0..5 {
                println!("Got value {:?} from another thread", rx.recv().unwrap());
            }

        }
}

// a C-like struct
struct Car {
    color: String,
    weight: u32,
}

// a tuple struct s
struct RgbColor(i8, i8, i8);

// a unit struct
struct Nil;

fn add_two_integers(a: i32, b: i32) -> i32 {
    a + b
}
<|endoftext|>


<commit_before>
extern crate hyper_native_tls;
extern crate imageflow_helpers;

use std;
use std::fmt;
use reqwest::blocking;
use hyper;
use reqwest::Certificate;
use ::imageflow_helpers::filesystem::read_file_bytes;
use std::path::PathBuf;
use std::io::Read;

#[derive(Debug)]
pub enum FetchError {
    ReqwestError(reqwest::Error),
    HyperError(hyper::Error),
    IoError(std::io::Error),
    UpstreamResponseError(reqwest::StatusCode),

    UpstreamResponseErrorWithResponse{ status: reqwest::StatusCode, response: FetchedResponse},
}

impl fmt::Display for FetchError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FetchError::ReqwestError(ref e) => e.fmt(f),
            FetchError::HyperError(ref e) => e.fmt(f),
            FetchError::IoError(ref e) => e.fmt(f),
            FetchError::UpstreamResponseError(ref status) |
            FetchError::UpstreamResponseErrorWithResponse {ref status, ..} => {
                write!(f, "Response status {}", status)
            },
        }
    }
}

pub type FetchResult = ::std::result::Result<FetchedResponse,FetchError>;

pub struct FetchedResponse {
    pub code: reqwest::StatusCode,
    pub bytes: Vec<u8>,
    pub content_type: reqwest::header:: HeaderValue,
}

impl fmt::Debug for FetchedResponse {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // If there is a second key/value, we're assuming it is 'charset'
        if !self.content_type.is_empty() || self.content_type.to_str().unwrap() == "text/plain"{
            write!(f, "FetchedResponse {{ content_type: {:?}, length: {}, as_string: {:?} }}", self.content_type, self.bytes.len(), std::str::from_utf8(&self.bytes))
        }else{
            write!(f, "FetchedResponse {{ content_type: {:?}, length: {} }}", self.content_type, self.bytes.len())
        }
    }
}

pub fn fetch_bytes(url: &str) -> std::result::Result<Vec<u8>, FetchError> {
    fetch(url, Default::default()).map(|r| r.bytes)
}

#[derive(Default, Clone, Debug)]
pub struct FetchConfig{
    /// Only honored on linux (maybe outdated?)
    /// PEM format
    pub custom_ca_trust_file: Option<PathBuf>,
    pub read_error_body: Option<bool>
}

impl FetchConfig {
//    #[cfg(not(any(target_os = "windows", target_os = "macos")))]
//    pub fn supports_custom_ca() -> bool{
//        true
//    }
//    #[cfg(any(target_os = "windows", target_os = "macos"))]
//    pub fn supports_custom_ca() -> bool{
//        false
//    }
//    #[cfg(not(any(target_os = "windows", target_os = "macos")))]
//    pub fn build_client(&self) -> Client{
//        let mut ssl = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
//        if let Some(ref path) = self.custom_ca_trust_file{
//            ssl.set_ca_file(path).unwrap();
//        }
//        let ssl = OpensslClient::from(ssl.build());
//        let connector = HttpsConnector::new(ssl);
//        Client::with_connector(connector)
//    }
//
//    #[cfg(any(target_os = "windows", target_os = "macos"))]
//    pub fn build_client(&self) -> Client{
//        let ssl = NativeTlsClient::new().unwrap();
//        let connector = HttpsConnector::new(ssl);
//        Client::with_connector(connector)
//    }

    pub fn build_client(&self) -> blocking::Client{
        let builder = if let Some(ref cert) = self.custom_ca_trust_file{
            let bytes = read_file_bytes(cert).unwrap();
            reqwest::blocking::ClientBuilder::new().add_root_certificate(Certificate::from_pem(&bytes).unwrap())
        } else{
            reqwest::blocking::ClientBuilder::new()
        };
        builder.build().unwrap()
    }
}

pub fn fetch(url: &str, config: Option<FetchConfig>) -> std::result::Result<FetchedResponse, FetchError> {
    let conf = config.unwrap_or_default();
    let client = conf.build_client();

    let mut res = client.get(url).send()?;

    let response = if res.status().is_success() || conf.read_error_body.unwrap_or(false) {
        let mut source_bytes = Vec::new();
        let _ = res.read_to_end(&mut source_bytes)?;
        Some(FetchedResponse {
            code: res.status(),
            bytes: source_bytes,
            content_type: res.headers().get(reqwest::header::CONTENT_TYPE).expect("content type required").clone()
        })
    } else {
        None
    };

    if res.status().is_success() && response.is_some(){
        Ok(response.unwrap())
    }else {
        match (response, res.status()) {
            (Some(r),
                _) =>
                Err(FetchError::UpstreamResponseErrorWithResponse { status: res.status(), response: r }),
            (None, _) => Err(FetchError::UpstreamResponseError(res.status()))
        }
    }
}

pub fn get_status_code_for(url: &str) -> std::result::Result<reqwest::StatusCode, FetchError> {

    let client = reqwest::blocking::ClientBuilder::new().build().unwrap();

    let res = client.get(url).send()?;
    Ok(res.status())

    //Ok(*reqwest::get(url)?.status())
}

impl From<reqwest::Error> for FetchError {
    fn from(e: reqwest::Error) -> FetchError {
        FetchError::ReqwestError(e)
    }
}

impl From<hyper::Error> for FetchError {
    fn from(e: hyper::Error) -> FetchError {
        FetchError::HyperError(e)
    }
}

impl From<std::io::Error> for FetchError {
    fn from(e: std::io::Error) -> FetchError {
        FetchError::IoError(e)
    }
}
<commit_msg>Try to make HTTP fetching more resilient; verify content-length is correct and use .bytes() instead of .read_to_end()<commit_after>
extern crate hyper_native_tls;
extern crate imageflow_helpers;

use std;
use std::fmt;
use reqwest::blocking;
use hyper;
use reqwest::Certificate;
use ::imageflow_helpers::filesystem::read_file_bytes;
use std::path::PathBuf;

#[derive(Debug)]
pub enum FetchError {
    ReqwestError(reqwest::Error),
    HyperError(hyper::Error),
    IoError(std::io::Error),
    UpstreamResponseError(reqwest::StatusCode),
    ContentLengthMismatch,

    UpstreamResponseErrorWithResponse{ status: reqwest::StatusCode, response: FetchedResponse},
}

impl fmt::Display for FetchError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FetchError::ReqwestError(ref e) => e.fmt(f),
            FetchError::HyperError(ref e) => e.fmt(f),
            FetchError::IoError(ref e) => e.fmt(f),
            FetchError::UpstreamResponseError(ref status) |
            FetchError::UpstreamResponseErrorWithResponse {ref status, ..} => {
                write!(f, "Response status {}", status)
            },
            FetchError::ContentLengthMismatch => write!(f, "Content-Length value did not match bytes recieved.")
        }
    }
}

pub type FetchResult = ::std::result::Result<FetchedResponse,FetchError>;

pub struct FetchedResponse {
    pub code: reqwest::StatusCode,
    pub bytes: Vec<u8>,
    pub content_type: reqwest::header:: HeaderValue,
}

impl fmt::Debug for FetchedResponse {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // If there is a second key/value, we're assuming it is 'charset'
        if !self.content_type.is_empty() || self.content_type.to_str().unwrap() == "text/plain"{
            write!(f, "FetchedResponse {{ content_type: {:?}, length: {}, as_string: {:?} }}", self.content_type, self.bytes.len(), std::str::from_utf8(&self.bytes))
        }else{
            write!(f, "FetchedResponse {{ content_type: {:?}, length: {} }}", self.content_type, self.bytes.len())
        }
    }
}

pub fn fetch_bytes(url: &str) -> std::result::Result<Vec<u8>, FetchError> {
    fetch(url, Default::default()).map(|r| r.bytes)
}

#[derive(Default, Clone, Debug)]
pub struct FetchConfig{
    /// Only honored on linux (maybe outdated?)
    /// PEM format
    pub custom_ca_trust_file: Option<PathBuf>,
    pub read_error_body: Option<bool>
}

impl FetchConfig {
//    #[cfg(not(any(target_os = "windows", target_os = "macos")))]
//    pub fn supports_custom_ca() -> bool{
//        true
//    }
//    #[cfg(any(target_os = "windows", target_os = "macos"))]
//    pub fn supports_custom_ca() -> bool{
//        false
//    }
//    #[cfg(not(any(target_os = "windows", target_os = "macos")))]
//    pub fn build_client(&self) -> Client{
//        let mut ssl = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
//        if let Some(ref path) = self.custom_ca_trust_file{
//            ssl.set_ca_file(path).unwrap();
//        }
//        let ssl = OpensslClient::from(ssl.build());
//        let connector = HttpsConnector::new(ssl);
//        Client::with_connector(connector)
//    }
//
//    #[cfg(any(target_os = "windows", target_os = "macos"))]
//    pub fn build_client(&self) -> Client{
//        let ssl = NativeTlsClient::new().unwrap();
//        let connector = HttpsConnector::new(ssl);
//        Client::with_connector(connector)
//    }

    pub fn build_client(&self) -> blocking::Client{
        let builder = if let Some(ref cert) = self.custom_ca_trust_file{
            let bytes = read_file_bytes(cert).unwrap();
            reqwest::blocking::ClientBuilder::new().add_root_certificate(Certificate::from_pem(&bytes).unwrap())
        } else{
            reqwest::blocking::ClientBuilder::new()
        };
        builder.build().unwrap()
    }
}

pub fn fetch(url: &str, config: Option<FetchConfig>) -> std::result::Result<FetchedResponse, FetchError> {
    let conf = config.unwrap_or_default();
    let client = conf.build_client();

    let res = client.get(url).send()?;
    let status = res.status().to_owned();

    let response = if status.is_success() || conf.read_error_body.unwrap_or(false) {

        let content_length =  res.content_length();
        let code = status;
        let content_type = res.headers().get(reqwest::header::CONTENT_TYPE).expect("content type required").clone();
        let bytes = res.bytes()?.to_vec();
        if content_length.is_some() && content_length.unwrap() != bytes.len() as u64{
            return Err(FetchError::ContentLengthMismatch);
        }
        Some(FetchedResponse {
            code: code,
            content_type: content_type,
            bytes: bytes,
        })
    } else {
        None
    };

    if status.is_success() && response.is_some(){
        Ok(response.unwrap())
    }else {
        match (response, status) {
            (Some(r),
                _) =>
                Err(FetchError::UpstreamResponseErrorWithResponse { status: status, response: r }),
            (None, _) => Err(FetchError::UpstreamResponseError(status))
        }
    }
}

pub fn get_status_code_for(url: &str) -> std::result::Result<reqwest::StatusCode, FetchError> {

    let client = reqwest::blocking::ClientBuilder::new().build().unwrap();

    let res = client.get(url).send()?;
    Ok(res.status())

    //Ok(*reqwest::get(url)?.status())
}

impl From<reqwest::Error> for FetchError {
    fn from(e: reqwest::Error) -> FetchError {
        FetchError::ReqwestError(e)
    }
}

impl From<hyper::Error> for FetchError {
    fn from(e: hyper::Error) -> FetchError {
        FetchError::HyperError(e)
    }
}

impl From<std::io::Error> for FetchError {
    fn from(e: std::io::Error) -> FetchError {
        FetchError::IoError(e)
    }
}
<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::{io, env};
use std::collections::{BTreeMap, HashSet};

macro_rules! errln {
    ($($fmt: tt)*) => {
        (writeln!(&mut io::stderr(), $($fmt)*).unwrap())
    }
}

fn div_up(x: usize, y: usize) -> usize {
    (x + y - 1) / y
}

fn gcd(x: usize, y: usize) -> usize {
    if y == 0 { x }
    else { gcd(y, x % y) }
}
fn coprime_to(x: usize, upto: usize) -> Vec<usize> {
    (1..upto).filter(|&n| gcd(n, x) == 1).collect()
}

fn bit_index(x: usize) -> usize {
    let wheel = x / BYTE_WHEEL * BYTE_COUNT;
    let rem = x % BYTE_WHEEL;
    let bits = (1..rem).filter(|y| gcd(*y, BYTE_WHEEL) == 1).count();
    wheel + bits
}
fn from_bit_index(x: usize, byte_coprime: &Vec<usize>) -> usize {
    let (byte, bit) = (x / BYTE_COUNT, x % BYTE_COUNT);
    byte * BYTE_WHEEL + byte_coprime[bit]
}

const BYTE_WHEEL: usize = 2 * 3 * 5;
const BYTE_COUNT: usize = 1 * 2 * 4;

const SMALL_LIMIT: usize = 10_000;

fn main() {
    let primes = env::args()
        .skip(1)
        .map(|x| x.parse::<usize>().expect(&format!("could not parse `{}` as a positive integer", x)))
        .collect::<Vec<_>>();

    assert!(primes.len() > 0, "need at least one prime to make a wheel");
    for p in &primes {
        assert!(primal_check::miller_rabin(*p as u64), "{} is not prime", p);
    }
    assert!(primes.len() == primes.iter().collect::<HashSet<_>>().len(),
            "some primes were non-unique");

    let wheel = primes.iter().fold(1, |x, y| x * *y);
    let count = primes.iter().fold(1, |x, y| x * (*y - 1));

    errln!("wheel for {} (count {})", wheel, count);
    let byte_coprime = coprime_to(BYTE_WHEEL, BYTE_WHEEL);
    let coprime = coprime_to(wheel, wheel);
    let mut diff_to_next = BTreeMap::new();
    for (i, &c) in coprime.iter().enumerate() {
        let next = coprime[(i + 1) % coprime.len()];
        diff_to_next.insert(c, ((wheel + next) - c) % wheel);
    }

    // The main workhorse.
    //
    // The sieve is driven by crossing off things that are definitely
    // not prime, and performance is driven by minimising how much
    // crossing off happens.
    //
    // Suppose we have a wheel of size 30 = 2 * 3 * 5. Given a prime p
    // = 30n + i, there's only 8 possible values of i: C = {1, 7, 11,
    // 13, 17, 19, 23, 29}. As is standard, we know that all values
    // below p * p will have already been crossed off by the time
    // we're crossing off with p, so we only need to start
    // there... but we can do better. The idea behind the wheel also
    // implies that {p * (30k + 0), p * (30k + 2), p * (30k + 3), ...,
    // (30k + 28)} will have been crossed off already (for all k), in
    // particular, we only need to consider multiplication by 30k + j
    // for j in C.
    //
    // If we have some multiple m = q * p, we need to work out how to
    // get to the next one, m'. One possibility would be to literally
    // store q and then find the next q' (next number congruent mod 30
    // to an element of C), but we can do better (common theme, huh?):
    // m' = m + (j' - j) * p, so just the difference between
    // successive j's is needed (this difference is diff_mult_factor
    // in the following table). These differences are of course cycle
    // with period |C| = 8, conveniently.
    //
    // The last really tricky part is we want to address and
    // manipulate individual bits efficiently, which means storing
    // byte indices and precomputing appropriate bitmasks. This
    // essentially means we divide p and m by 30, rounding down, and
    // hence lose information in two ways: we don't know were to
    // write, nor can we compute the exact right byte
    // automatically. The former is managed by bitmasks that change
    // with j, and the latter is managed by "corrections". Corrections
    // are additive factors that are used like [m'/30] = [m/30] + (j'
    // - j) *[p/30] + correction, where [x] == floor(x). Both these
    // management tools are cyclic with period 8.
    //
    // (Another slight complication is that we can use a computation
    // wheel that is different to the in-memory wheel, which means we
    // skip over more writes by taking bigger steps, but don't get the
    // memory savings.)
    #[derive(Debug)]
    struct Info {
        total_mult_factor: usize,
        diff_mult_factor: usize,
        total_add_factor: usize,
        correction: usize,
        unset_bit: u8,
    }
    let infos = byte_coprime.iter()
        .map(|c| {
            coprime.iter()
                .map(|&cc| {
                    let total_add_factor = c * cc;
                    let diff = diff_to_next[&cc];
                    Info {
                        total_mult_factor: cc,
                        total_add_factor,
                        diff_mult_factor: diff,
                        correction: (total_add_factor + diff * c) / BYTE_WHEEL - total_add_factor / BYTE_WHEEL,
                        unset_bit: !(1 << (bit_index(total_add_factor) % 8))
                    }
                })
                .collect::<Vec<_>>()
        })
        .collect::<Vec<_>>();

    println!("// automatically generated
use crate::wheel::{{WheelInit, Wheel, WheelElem}};

#[derive(Debug, Clone)]
pub struct Wheel{modulo};
impl Wheel for Wheel{modulo} {{
    #[inline(always)]
    fn modulo(&self) -> usize {{ MODULO }}

    #[inline(always)]
    fn size(&self) -> usize {{ SIZE }}

    #[inline(always)]
    fn wheel(&self) -> &'static [WheelElem] {{ WHEEL }}

    #[inline(always)]
    fn init(&self) -> &'static [WheelInit] {{ INIT }}

    #[inline(always)]
    unsafe fn hardcoded_sieve(&self,
                              bytes: &mut [u8], si_: &mut usize, wi_: &mut usize, prime: usize) {{
        hardcoded_sieve(bytes, si_, wi_, prime)
    }}
}}

pub const SIZE: usize = {size};

pub const MODULO: usize = {modulo};
",
             size = count,
             modulo = wheel);

    let length_bytes = div_up(SMALL_LIMIT * count, wheel * 8);
    let length_bits = length_bytes * 8;
    let sieve = primal_slowsieve::Primes::sieve(length_bits * wheel / count);
    print!("\
#[allow(dead_code)]
pub const SMALL_BITS: usize = {};
#[allow(dead_code)]
pub const SMALL: &'static [u8; SMALL_BITS / 8] = &[", length_bits);
    let mut bit = 0;
    // precompute the sieve for a little while.
    for byte in 0..length_bytes {
        let mut val = 0;
        for i in 0..8 {
            val |= (sieve.is_prime(from_bit_index(bit, &byte_coprime)) as u8) << i;
            bit += 1;
        }
        if byte % 8 == 0 {
            print!("\n    0b{:08b},", val);
        } else {
            print!(" 0b{:08b},", val);
        }
    }
    println!();
    println!("];");

    // compute the initialisers: push an arbitrary number up to the
    // next one that isn't eliminated by the wheel, indicating which
    // multiple it is (for indexing into the next one, which is
    // ordered by multiple)
    println!("const INIT: &'static [WheelInit; {}] = &[", wheel);
    let mut next = 0;
    for (i, &y) in coprime_to(wheel, wheel).iter().enumerate() {
        for x in next..y + 1 {
            println!("    WheelInit {{ next_mult_factor: {}, wheel_index: {} }}, // {}",
                     y - x, i, x)
        }
        next = y + 1;
    }
    println!("];");

    // now print the full wheel!
    println!("const WHEEL: &'static [WheelElem; {}] = &[", BYTE_COUNT * count);
    for (c, cur_infos) in byte_coprime.iter().zip(&infos) {
        println!("    // remainder {}", c);

        for (i, info) in cur_infos.iter().enumerate() {
            println!("    WheelElem {{ unset_bit: {}, next_mult_factor: {}, correction: {}, next: {} }},",
                     info.unset_bit,
                     info.diff_mult_factor,
                     info.correction,
                     if i == count - 1 { -(i as isize) } else { 1 })
        }
    }
    println!("];");

    // the hard-coded sieve is a code version of WHEEL, designed for
    // cases when `prime` is small and hence a lot of writes are
    // peformed: loops can be unrolled.
    //
    // this (ab)uses labelled breaks to jump around more efficiently ala goto.
    println!("\
pub unsafe fn hardcoded_sieve(bytes: &mut [u8], si_: &mut usize, wi_: &mut usize, prime: usize) {{
    let bytes = bytes;
    let start = bytes.as_mut_ptr();
    let len = bytes.len() as isize;
    let largest_step = ::std::cmp::min(len, {wheel} * (prime as isize + 1) - 1);
    let loop_len = len - largest_step;
    let loop_end = start.offset(loop_len);
    let end = start.offset(len);
    let si = *si_ as isize;
    let mut p = start.offset(si);
    let mut wi = *wi_;
    let prime_ = prime as isize;

    'outer: loop {{
    match wi {{",
             wheel = wheel);
    for (i, (&c, cur_infos)) in coprime.iter().zip(&infos).enumerate() {
        let wheel_start = i * count;
        let wheel_end = (i + 1) * count;
        println!("        {}..={} => {{ // {} * x + {}",
                 wheel_start, wheel_end - 1,
                 BYTE_WHEEL, c);
        let mut indent: String = "            ".into();
        println!("\
{indent}loop {{",
                     indent = indent);
        for j in (0..count).rev() {
            indent.push_str(" ");
            println!("{}'label{}: loop {{", indent, wheel_start + j);
        }

        println!("\
{indent} match wi {{", indent = indent);
        for j in 0..count - 1 {
            println!("{}  {1} => break 'label{1},", indent, wheel_start + j);
        }
        println!("{}  _ => break 'label{},", indent, wheel_start + count - 1);
        println!("{} }}", indent);
        println!("{}}}", indent);
        println!("\
{indent}while p < loop_end {{
{indent}    p = crate::b(p);",
                 indent = indent);

        for info in cur_infos {
            println!("\
{indent}    safe_assert!(start <= p.offset(prime_ * {sl} + {off}) &&
{indent}                 p.offset(prime_ * {sl} + {off}) < end);
{indent}    *p.offset(prime_ * {sl} + {off}) &= {bit};",
                     // p starts at offset 1 * prime_, so strip off
                     // that factor.
                     sl = info.total_mult_factor - 1,
                     off = info.total_add_factor / wheel,
                     bit = info.unset_bit, indent = indent);
        }
        println!("
{indent}    p = p.offset(prime_ * {} + {})
{indent}}}",
                 wheel, c,
                 indent = indent);

        for (j, info) in cur_infos.iter().enumerate() {
            indent.pop();
            let end = if j + 1 == count {
                format!("wi = {}", wheel_start)
            } else {
                format!("break 'label{}", wheel_start + j + 1)
            };
            println!("\
{indent} if p >= end {{ wi = {val}; break 'outer; }}
{indent} safe_assert!(start <= p && p < end);
{indent} *p &= {}; p = p.offset(prime_ * {} + {});
{indent} {}
{indent}}}",

                     info.unset_bit, info.diff_mult_factor, info.correction,
                     end,
                     val = wheel_start + j,
                     indent = indent);
        }
        println!("        }}");
    }
    println!("        _ => unreachable!(\"{{}}\", wi),
    }}
    }}
    *si_ = (p as usize).wrapping_sub(end as usize);
    *wi_ = wi;
}}")
}
<commit_msg>Replace own errln! with eprintln!<commit_after>use std::collections::{BTreeMap, HashSet};
use std::env;

fn div_up(x: usize, y: usize) -> usize {
    (x + y - 1) / y
}

fn gcd(x: usize, y: usize) -> usize {
    if y == 0 { x }
    else { gcd(y, x % y) }
}
fn coprime_to(x: usize, upto: usize) -> Vec<usize> {
    (1..upto).filter(|&n| gcd(n, x) == 1).collect()
}

fn bit_index(x: usize) -> usize {
    let wheel = x / BYTE_WHEEL * BYTE_COUNT;
    let rem = x % BYTE_WHEEL;
    let bits = (1..rem).filter(|y| gcd(*y, BYTE_WHEEL) == 1).count();
    wheel + bits
}
fn from_bit_index(x: usize, byte_coprime: &Vec<usize>) -> usize {
    let (byte, bit) = (x / BYTE_COUNT, x % BYTE_COUNT);
    byte * BYTE_WHEEL + byte_coprime[bit]
}

const BYTE_WHEEL: usize = 2 * 3 * 5;
const BYTE_COUNT: usize = 1 * 2 * 4;

const SMALL_LIMIT: usize = 10_000;

fn main() {
    let primes = env::args()
        .skip(1)
        .map(|x| x.parse::<usize>().expect(&format!("could not parse `{}` as a positive integer", x)))
        .collect::<Vec<_>>();

    assert!(primes.len() > 0, "need at least one prime to make a wheel");
    for p in &primes {
        assert!(primal_check::miller_rabin(*p as u64), "{} is not prime", p);
    }
    assert!(primes.len() == primes.iter().collect::<HashSet<_>>().len(),
            "some primes were non-unique");

    let wheel = primes.iter().fold(1, |x, y| x * *y);
    let count = primes.iter().fold(1, |x, y| x * (*y - 1));

    eprintln!("wheel for {} (count {})", wheel, count);
    let byte_coprime = coprime_to(BYTE_WHEEL, BYTE_WHEEL);
    let coprime = coprime_to(wheel, wheel);
    let mut diff_to_next = BTreeMap::new();
    for (i, &c) in coprime.iter().enumerate() {
        let next = coprime[(i + 1) % coprime.len()];
        diff_to_next.insert(c, ((wheel + next) - c) % wheel);
    }

    // The main workhorse.
    //
    // The sieve is driven by crossing off things that are definitely
    // not prime, and performance is driven by minimising how much
    // crossing off happens.
    //
    // Suppose we have a wheel of size 30 = 2 * 3 * 5. Given a prime p
    // = 30n + i, there's only 8 possible values of i: C = {1, 7, 11,
    // 13, 17, 19, 23, 29}. As is standard, we know that all values
    // below p * p will have already been crossed off by the time
    // we're crossing off with p, so we only need to start
    // there... but we can do better. The idea behind the wheel also
    // implies that {p * (30k + 0), p * (30k + 2), p * (30k + 3), ...,
    // (30k + 28)} will have been crossed off already (for all k), in
    // particular, we only need to consider multiplication by 30k + j
    // for j in C.
    //
    // If we have some multiple m = q * p, we need to work out how to
    // get to the next one, m'. One possibility would be to literally
    // store q and then find the next q' (next number congruent mod 30
    // to an element of C), but we can do better (common theme, huh?):
    // m' = m + (j' - j) * p, so just the difference between
    // successive j's is needed (this difference is diff_mult_factor
    // in the following table). These differences are of course cycle
    // with period |C| = 8, conveniently.
    //
    // The last really tricky part is we want to address and
    // manipulate individual bits efficiently, which means storing
    // byte indices and precomputing appropriate bitmasks. This
    // essentially means we divide p and m by 30, rounding down, and
    // hence lose information in two ways: we don't know were to
    // write, nor can we compute the exact right byte
    // automatically. The former is managed by bitmasks that change
    // with j, and the latter is managed by "corrections". Corrections
    // are additive factors that are used like [m'/30] = [m/30] + (j'
    // - j) *[p/30] + correction, where [x] == floor(x). Both these
    // management tools are cyclic with period 8.
    //
    // (Another slight complication is that we can use a computation
    // wheel that is different to the in-memory wheel, which means we
    // skip over more writes by taking bigger steps, but don't get the
    // memory savings.)
    #[derive(Debug)]
    struct Info {
        total_mult_factor: usize,
        diff_mult_factor: usize,
        total_add_factor: usize,
        correction: usize,
        unset_bit: u8,
    }
    let infos = byte_coprime.iter()
        .map(|c| {
            coprime.iter()
                .map(|&cc| {
                    let total_add_factor = c * cc;
                    let diff = diff_to_next[&cc];
                    Info {
                        total_mult_factor: cc,
                        total_add_factor,
                        diff_mult_factor: diff,
                        correction: (total_add_factor + diff * c) / BYTE_WHEEL - total_add_factor / BYTE_WHEEL,
                        unset_bit: !(1 << (bit_index(total_add_factor) % 8))
                    }
                })
                .collect::<Vec<_>>()
        })
        .collect::<Vec<_>>();

    println!("// automatically generated
use crate::wheel::{{WheelInit, Wheel, WheelElem}};

#[derive(Debug, Clone)]
pub struct Wheel{modulo};
impl Wheel for Wheel{modulo} {{
    #[inline(always)]
    fn modulo(&self) -> usize {{ MODULO }}

    #[inline(always)]
    fn size(&self) -> usize {{ SIZE }}

    #[inline(always)]
    fn wheel(&self) -> &'static [WheelElem] {{ WHEEL }}

    #[inline(always)]
    fn init(&self) -> &'static [WheelInit] {{ INIT }}

    #[inline(always)]
    unsafe fn hardcoded_sieve(&self,
                              bytes: &mut [u8], si_: &mut usize, wi_: &mut usize, prime: usize) {{
        hardcoded_sieve(bytes, si_, wi_, prime)
    }}
}}

pub const SIZE: usize = {size};

pub const MODULO: usize = {modulo};
",
             size = count,
             modulo = wheel);

    let length_bytes = div_up(SMALL_LIMIT * count, wheel * 8);
    let length_bits = length_bytes * 8;
    let sieve = primal_slowsieve::Primes::sieve(length_bits * wheel / count);
    print!("\
#[allow(dead_code)]
pub const SMALL_BITS: usize = {};
#[allow(dead_code)]
pub const SMALL: &'static [u8; SMALL_BITS / 8] = &[", length_bits);
    let mut bit = 0;
    // precompute the sieve for a little while.
    for byte in 0..length_bytes {
        let mut val = 0;
        for i in 0..8 {
            val |= (sieve.is_prime(from_bit_index(bit, &byte_coprime)) as u8) << i;
            bit += 1;
        }
        if byte % 8 == 0 {
            print!("\n    0b{:08b},", val);
        } else {
            print!(" 0b{:08b},", val);
        }
    }
    println!();
    println!("];");

    // compute the initialisers: push an arbitrary number up to the
    // next one that isn't eliminated by the wheel, indicating which
    // multiple it is (for indexing into the next one, which is
    // ordered by multiple)
    println!("const INIT: &'static [WheelInit; {}] = &[", wheel);
    let mut next = 0;
    for (i, &y) in coprime_to(wheel, wheel).iter().enumerate() {
        for x in next..y + 1 {
            println!("    WheelInit {{ next_mult_factor: {}, wheel_index: {} }}, // {}",
                     y - x, i, x)
        }
        next = y + 1;
    }
    println!("];");

    // now print the full wheel!
    println!("const WHEEL: &'static [WheelElem; {}] = &[", BYTE_COUNT * count);
    for (c, cur_infos) in byte_coprime.iter().zip(&infos) {
        println!("    // remainder {}", c);

        for (i, info) in cur_infos.iter().enumerate() {
            println!("    WheelElem {{ unset_bit: {}, next_mult_factor: {}, correction: {}, next: {} }},",
                     info.unset_bit,
                     info.diff_mult_factor,
                     info.correction,
                     if i == count - 1 { -(i as isize) } else { 1 })
        }
    }
    println!("];");

    // the hard-coded sieve is a code version of WHEEL, designed for
    // cases when `prime` is small and hence a lot of writes are
    // peformed: loops can be unrolled.
    //
    // this (ab)uses labelled breaks to jump around more efficiently ala goto.
    println!("\
pub unsafe fn hardcoded_sieve(bytes: &mut [u8], si_: &mut usize, wi_: &mut usize, prime: usize) {{
    let bytes = bytes;
    let start = bytes.as_mut_ptr();
    let len = bytes.len() as isize;
    let largest_step = ::std::cmp::min(len, {wheel} * (prime as isize + 1) - 1);
    let loop_len = len - largest_step;
    let loop_end = start.offset(loop_len);
    let end = start.offset(len);
    let si = *si_ as isize;
    let mut p = start.offset(si);
    let mut wi = *wi_;
    let prime_ = prime as isize;

    'outer: loop {{
    match wi {{",
             wheel = wheel);
    for (i, (&c, cur_infos)) in coprime.iter().zip(&infos).enumerate() {
        let wheel_start = i * count;
        let wheel_end = (i + 1) * count;
        println!("        {}..={} => {{ // {} * x + {}",
                 wheel_start, wheel_end - 1,
                 BYTE_WHEEL, c);
        let mut indent: String = "            ".into();
        println!("\
{indent}loop {{",
                     indent = indent);
        for j in (0..count).rev() {
            indent.push_str(" ");
            println!("{}'label{}: loop {{", indent, wheel_start + j);
        }

        println!("\
{indent} match wi {{", indent = indent);
        for j in 0..count - 1 {
            println!("{}  {1} => break 'label{1},", indent, wheel_start + j);
        }
        println!("{}  _ => break 'label{},", indent, wheel_start + count - 1);
        println!("{} }}", indent);
        println!("{}}}", indent);
        println!("\
{indent}while p < loop_end {{
{indent}    p = crate::b(p);",
                 indent = indent);

        for info in cur_infos {
            println!("\
{indent}    safe_assert!(start <= p.offset(prime_ * {sl} + {off}) &&
{indent}                 p.offset(prime_ * {sl} + {off}) < end);
{indent}    *p.offset(prime_ * {sl} + {off}) &= {bit};",
                     // p starts at offset 1 * prime_, so strip off
                     // that factor.
                     sl = info.total_mult_factor - 1,
                     off = info.total_add_factor / wheel,
                     bit = info.unset_bit, indent = indent);
        }
        println!("
{indent}    p = p.offset(prime_ * {} + {})
{indent}}}",
                 wheel, c,
                 indent = indent);

        for (j, info) in cur_infos.iter().enumerate() {
            indent.pop();
            let end = if j + 1 == count {
                format!("wi = {}", wheel_start)
            } else {
                format!("break 'label{}", wheel_start + j + 1)
            };
            println!("\
{indent} if p >= end {{ wi = {val}; break 'outer; }}
{indent} safe_assert!(start <= p && p < end);
{indent} *p &= {}; p = p.offset(prime_ * {} + {});
{indent} {}
{indent}}}",

                     info.unset_bit, info.diff_mult_factor, info.correction,
                     end,
                     val = wheel_start + j,
                     indent = indent);
        }
        println!("        }}");
    }
    println!("        _ => unreachable!(\"{{}}\", wi),
    }}
    }}
    *si_ = (p as usize).wrapping_sub(end as usize);
    *wi_ = wi;
}}")
}
<|endoftext|>


<commit_before>use card_strategy::CardStrategy;

use card::Card;
use game_status::GameStatus;
use player::PlayerName;

use std::collections::BTreeMap;

#[derive(Debug)]
pub struct MyCardStrategy;

impl MyCardStrategy {
    fn score_card<'a>(card: &'a Card, game_status: &'a GameStatus, player_name: &PlayerName) -> (i32, i32, i32, i32) {
        let card_penalty_to_me = MyCardStrategy::card_penalty_to_me(card, game_status, player_name);
        let card_penalty = 0 - MyCardStrategy::card_penalty(card, game_status);
        let trouble = MyCardStrategy::trouble_score(card, game_status);
        let card_rank = 0 - (u32::from(card.rank) as i32);
        (card_penalty_to_me, card_penalty, trouble, card_rank)
    }

    fn card_penalty(card: &Card, game_status: &GameStatus) -> i32 {
        game_status.round_parameters.card_points.get(card).map(|penalty| penalty.clone()).unwrap_or_default()
    }

    fn card_penalty_to_me(card: &Card, game_status: &GameStatus, player_name: &PlayerName) -> i32 {
        if MyCardStrategy::will_win_deal(card, game_status) {
            MyCardStrategy::card_penalty(card, game_status)
        } else {
            0
        }
    }

    fn trouble_score(card: &Card, game_status: &GameStatus) -> i32 {
        if MyCardStrategy::will_win_deal(card, game_status) {
            u32::from(card.rank) as i32
        } else {
            0
        }
    }

    fn will_win_deal(card: &Card, game_status: &GameStatus) -> bool {
        game_status.my_in_progress_deal.as_ref().and_then(|deal|
            deal.suit.and_then(|suit|
                deal.deal_cards.iter()
                    .map(|deal_card| deal_card.card)
                    .filter(|card| card.suit == suit)
                    .max()
                    .map(|winning_card| card.suit == suit && card.rank > winning_card.rank))).unwrap_or(true)
    }
}

impl CardStrategy for MyCardStrategy {

    fn pass_cards<'a>(&mut self, game_status: &'a GameStatus) -> Vec<&'a Card> {
        // Need to order cards by potential to win lowest penalty hands
        let mut initial_hand: Vec<&'a Card> = game_status.my_initial_hand.iter().collect();
        initial_hand.reverse();
        initial_hand.into_iter().take(3).collect()
    }

    fn play_card<'a>(&mut self, game_status: &'a GameStatus, player_name: &PlayerName) -> &'a Card {
        let current_suit = game_status.my_in_progress_deal.as_ref().and_then(|deal| deal.suit);
        let mut valid_cards: Vec<&'a Card> = game_status.my_current_hand.iter().filter(|card| Some(card.suit) == current_suit).collect();

        if valid_cards.is_empty() {
            valid_cards.extend(&game_status.my_current_hand);
        }

        let scored_cards = valid_cards.into_iter()
            .map(|card| ((MyCardStrategy::score_card(card, game_status, player_name), card), card)).collect::<BTreeMap<((i32, i32, i32, i32), &Card), &Card>>();

        scored_cards.values().next().expect("No valid cards to play!")
    }

}<commit_msg>cleanup<commit_after>use card_strategy::CardStrategy;

use card::Card;
use game_status::GameStatus;
use player::PlayerName;

use std::collections::BTreeMap;

#[derive(Debug)]
pub struct MyCardStrategy;

impl MyCardStrategy {
    fn score_card<'a>(card: &'a Card, game_status: &'a GameStatus, player_name: &PlayerName) -> (i32, i32, i32, i32) {
        let card_penalty_to_me = MyCardStrategy::card_penalty_to_me(card, game_status, player_name);
        let card_penalty = 0 - MyCardStrategy::card_penalty(card, game_status);
        let trouble = MyCardStrategy::trouble_score(card, game_status);
        let card_rank = 0 - (u32::from(card.rank) as i32);
        (card_penalty_to_me, card_penalty, trouble, card_rank)
    }

    fn card_penalty(card: &Card, game_status: &GameStatus) -> i32 {
        game_status.round_parameters.card_points.get(card)
            .map(|penalty| penalty.clone())
            .unwrap_or_default()
    }

    fn card_penalty_to_me(card: &Card, game_status: &GameStatus, player_name: &PlayerName) -> i32 {
        if MyCardStrategy::will_win_deal(card, game_status) {
            MyCardStrategy::card_penalty(card, game_status)
        } else {
            0
        }
    }

    fn trouble_score(card: &Card, game_status: &GameStatus) -> i32 {
        if MyCardStrategy::will_win_deal(card, game_status) {
            u32::from(card.rank) as i32
        } else {
            0
        }
    }

    fn will_win_deal(card: &Card, game_status: &GameStatus) -> bool {
        game_status.my_in_progress_deal.as_ref().and_then(|deal|
            deal.suit.and_then(|suit|
                deal.deal_cards.iter()
                    .map(|deal_card| deal_card.card)
                    .filter(|card| card.suit == suit)
                    .max()
                    .map(|winning_card| card.suit == suit && card.rank > winning_card.rank))).unwrap_or(true)
    }
}

impl CardStrategy for MyCardStrategy {

    fn pass_cards<'a>(&mut self, game_status: &'a GameStatus) -> Vec<&'a Card> {
        // Need to order cards by potential to win lowest penalty hands
        let mut initial_hand: Vec<&'a Card> = game_status.my_initial_hand.iter().collect();
        initial_hand.reverse();
        initial_hand.into_iter().take(3).collect()
    }

    fn play_card<'a>(&mut self, game_status: &'a GameStatus, player_name: &PlayerName) -> &'a Card {
        let current_suit = game_status.my_in_progress_deal.as_ref().and_then(|deal| deal.suit);
        let mut valid_cards: Vec<&'a Card> = game_status.my_current_hand.iter().filter(|card| Some(card.suit) == current_suit).collect();

        if valid_cards.is_empty() {
            valid_cards.extend(&game_status.my_current_hand);
        }

        let scored_cards = valid_cards.into_iter()
            .map(|card| ((MyCardStrategy::score_card(card, game_status, player_name), card), card))
            .collect::<BTreeMap<((i32, i32, i32, i32), &Card), &Card>>();

        scored_cards.values().next().expect("No valid cards to play!")
    }

}<|endoftext|>


<commit_before>// Functions used by generated protobuf code.
// Should not be used by programs written by hands.

use std::iter::AdditiveIterator;

use core::*;
use zigzag::*;

use unknown::UnknownFields;

pub fn compute_raw_varint64_size(value: u64) -> u32 {
    if (value & (0xffffffffffffffffu64 <<  7)) == 0 { return 1; }
    if (value & (0xffffffffffffffffu64 << 14)) == 0 { return 2; }
    if (value & (0xffffffffffffffffu64 << 21)) == 0 { return 3; }
    if (value & (0xffffffffffffffffu64 << 28)) == 0 { return 4; }
    if (value & (0xffffffffffffffffu64 << 35)) == 0 { return 5; }
    if (value & (0xffffffffffffffffu64 << 42)) == 0 { return 6; }
    if (value & (0xffffffffffffffffu64 << 49)) == 0 { return 7; }
    if (value & (0xffffffffffffffffu64 << 56)) == 0 { return 8; }
    if (value & (0xffffffffffffffffu64 << 63)) == 0 { return 9; }
    10
}

pub fn compute_raw_varint32_size(value: u32) -> u32 {
    compute_raw_varint64_size(value as u64)
}

trait ProtobufVarint {
    // size of self when written as varint
    fn len_varint(&self) -> u32;
}

trait ProtobufVarintZigzag {
    fn len_varint_zigzag(&self) -> u32;
}

impl ProtobufVarint for u64 {
    fn len_varint(&self) -> u32 {
        compute_raw_varint64_size(*self)
    }
}

impl ProtobufVarint for u32 {
    fn len_varint(&self) -> u32 {
        (*self as u64).len_varint()
    }
}

impl ProtobufVarint for i64 {
    fn len_varint(&self) -> u32 {
        // same as length of u64
        (*self as u64).len_varint()
    }
}

impl ProtobufVarintZigzag for i64 {
    fn len_varint_zigzag(&self) -> u32 {
        compute_raw_varint64_size(encode_zig_zag_64(*self))
    }
}

impl ProtobufVarint for i32 {
    fn len_varint(&self) -> u32 {
        // sign-extend and then compute
        (*self as i64).len_varint()
    }
}

impl ProtobufVarintZigzag for i32 {
    fn len_varint_zigzag(&self) -> u32 {
        compute_raw_varint32_size(encode_zig_zag_32(*self))
    }
}

impl ProtobufVarint for bool {
    fn len_varint(&self) -> u32 {
        1
    }
}

/* Commented out due to https://github.com/mozilla/rust/issues/8075
impl<E:ProtobufEnum> ProtobufVarint for E {
    fn len_varint(&self) -> u32 {
        self.value().len_varint()
    }
}
*/

// Size of serialized data, excluding length and tag
pub fn vec_packed_varint_data_size<T : ProtobufVarint>(vec: &[T]) -> u32 {
    vec.iter().map(|v| v.len_varint()).sum()
}

// Size of serialized data, excluding length and tag
pub fn vec_packed_varint_zigzag_data_size<T : ProtobufVarintZigzag>(vec: &[T]) -> u32 {
    vec.iter().map(|v| v.len_varint_zigzag()).sum()
}

// Size of serialized data with length prefix and tag
pub fn vec_packed_varint_size<T : ProtobufVarint>(field_number: u32, vec: &[T]) -> u32 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_varint_data_size(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

// Size of serialized data with length prefix and tag
pub fn vec_packed_varint_zigzag_size<T : ProtobufVarintZigzag>(field_number: u32, vec: &[T]) -> u32 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_varint_zigzag_data_size(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

// Size of tag does not depend on wire type
pub fn tag_size(field_number: u32) -> u32 {
    wire_format::Tag::make(field_number, wire_format::WireTypeFixed64).value().len_varint()
}

pub fn value_size_no_tag<T : ProtobufVarint>(value: T, wt: wire_format::WireType) -> u32 {
    match wt {
        wire_format::WireTypeFixed64 => 8,
        wire_format::WireTypeFixed32 => 4,
        wire_format::WireTypeVarint => value.len_varint(),
        _ => fail!()
    }
}

pub fn value_size<T : ProtobufVarint>(field_number: u32, value: T, wt: wire_format::WireType) -> u32 {
    tag_size(field_number) + value_size_no_tag(value, wt)
}

fn enum_size_no_tag<E : ProtobufEnum>(value: E) -> u32 {
    value.value().len_varint()
}

pub fn enum_size<E : ProtobufEnum>(field_number: u32, value: E) -> u32 {
    tag_size(field_number) + enum_size_no_tag(value)
}

fn bytes_size_no_tag(bytes: &[u8]) -> u32 {
    compute_raw_varint64_size(bytes.len() as u64) + bytes.len() as u32
}

pub fn bytes_size(field_number: u32, bytes: &[u8]) -> u32 {
    tag_size(field_number) + bytes_size_no_tag(bytes)
}

fn string_size_no_tag(s: &str) -> u32 {
    bytes_size_no_tag(s.as_bytes())
}

pub fn string_size(field_number: u32, s: &str) -> u32 {
    tag_size(field_number) + string_size_no_tag(s)
}

pub fn unknown_fields_size(unknown_fields: &UnknownFields) -> u32 {
    let mut r = 0;
    for (number, values) in unknown_fields.iter() {
        r += (tag_size(number) + 4) * values.fixed32.len() as u32;
        r += (tag_size(number) + 8) * values.fixed64.len() as u32;

        r += tag_size(number) * values.varint.len() as u32;
        for varint in values.varint.iter() {
            r += varint.len_varint();
        }

        r += tag_size(number) * values.length_delimited.len() as u32;
        for bytes in values.length_delimited.iter() {
            r += bytes_size_no_tag(bytes.as_slice());
        }
    }
    r
}

<commit_msg>Fix private type in exported type paramater bound.<commit_after>// Functions used by generated protobuf code.
// Should not be used by programs written by hands.

use std::iter::AdditiveIterator;

use core::*;
use zigzag::*;

use unknown::UnknownFields;

pub fn compute_raw_varint64_size(value: u64) -> u32 {
    if (value & (0xffffffffffffffffu64 <<  7)) == 0 { return 1; }
    if (value & (0xffffffffffffffffu64 << 14)) == 0 { return 2; }
    if (value & (0xffffffffffffffffu64 << 21)) == 0 { return 3; }
    if (value & (0xffffffffffffffffu64 << 28)) == 0 { return 4; }
    if (value & (0xffffffffffffffffu64 << 35)) == 0 { return 5; }
    if (value & (0xffffffffffffffffu64 << 42)) == 0 { return 6; }
    if (value & (0xffffffffffffffffu64 << 49)) == 0 { return 7; }
    if (value & (0xffffffffffffffffu64 << 56)) == 0 { return 8; }
    if (value & (0xffffffffffffffffu64 << 63)) == 0 { return 9; }
    10
}

pub fn compute_raw_varint32_size(value: u32) -> u32 {
    compute_raw_varint64_size(value as u64)
}

pub trait ProtobufVarint {
    // size of self when written as varint
    fn len_varint(&self) -> u32;
}

pub trait ProtobufVarintZigzag {
    fn len_varint_zigzag(&self) -> u32;
}

impl ProtobufVarint for u64 {
    fn len_varint(&self) -> u32 {
        compute_raw_varint64_size(*self)
    }
}

impl ProtobufVarint for u32 {
    fn len_varint(&self) -> u32 {
        (*self as u64).len_varint()
    }
}

impl ProtobufVarint for i64 {
    fn len_varint(&self) -> u32 {
        // same as length of u64
        (*self as u64).len_varint()
    }
}

impl ProtobufVarintZigzag for i64 {
    fn len_varint_zigzag(&self) -> u32 {
        compute_raw_varint64_size(encode_zig_zag_64(*self))
    }
}

impl ProtobufVarint for i32 {
    fn len_varint(&self) -> u32 {
        // sign-extend and then compute
        (*self as i64).len_varint()
    }
}

impl ProtobufVarintZigzag for i32 {
    fn len_varint_zigzag(&self) -> u32 {
        compute_raw_varint32_size(encode_zig_zag_32(*self))
    }
}

impl ProtobufVarint for bool {
    fn len_varint(&self) -> u32 {
        1
    }
}

/* Commented out due to https://github.com/mozilla/rust/issues/8075
impl<E:ProtobufEnum> ProtobufVarint for E {
    fn len_varint(&self) -> u32 {
        self.value().len_varint()
    }
}
*/

// Size of serialized data, excluding length and tag
pub fn vec_packed_varint_data_size<T : ProtobufVarint>(vec: &[T]) -> u32 {
    vec.iter().map(|v| v.len_varint()).sum()
}

// Size of serialized data, excluding length and tag
pub fn vec_packed_varint_zigzag_data_size<T : ProtobufVarintZigzag>(vec: &[T]) -> u32 {
    vec.iter().map(|v| v.len_varint_zigzag()).sum()
}

// Size of serialized data with length prefix and tag
pub fn vec_packed_varint_size<T : ProtobufVarint>(field_number: u32, vec: &[T]) -> u32 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_varint_data_size(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

// Size of serialized data with length prefix and tag
pub fn vec_packed_varint_zigzag_size<T : ProtobufVarintZigzag>(field_number: u32, vec: &[T]) -> u32 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_varint_zigzag_data_size(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

// Size of tag does not depend on wire type
pub fn tag_size(field_number: u32) -> u32 {
    wire_format::Tag::make(field_number, wire_format::WireTypeFixed64).value().len_varint()
}

pub fn value_size_no_tag<T : ProtobufVarint>(value: T, wt: wire_format::WireType) -> u32 {
    match wt {
        wire_format::WireTypeFixed64 => 8,
        wire_format::WireTypeFixed32 => 4,
        wire_format::WireTypeVarint => value.len_varint(),
        _ => fail!()
    }
}

pub fn value_size<T : ProtobufVarint>(field_number: u32, value: T, wt: wire_format::WireType) -> u32 {
    tag_size(field_number) + value_size_no_tag(value, wt)
}

fn enum_size_no_tag<E : ProtobufEnum>(value: E) -> u32 {
    value.value().len_varint()
}

pub fn enum_size<E : ProtobufEnum>(field_number: u32, value: E) -> u32 {
    tag_size(field_number) + enum_size_no_tag(value)
}

fn bytes_size_no_tag(bytes: &[u8]) -> u32 {
    compute_raw_varint64_size(bytes.len() as u64) + bytes.len() as u32
}

pub fn bytes_size(field_number: u32, bytes: &[u8]) -> u32 {
    tag_size(field_number) + bytes_size_no_tag(bytes)
}

fn string_size_no_tag(s: &str) -> u32 {
    bytes_size_no_tag(s.as_bytes())
}

pub fn string_size(field_number: u32, s: &str) -> u32 {
    tag_size(field_number) + string_size_no_tag(s)
}

pub fn unknown_fields_size(unknown_fields: &UnknownFields) -> u32 {
    let mut r = 0;
    for (number, values) in unknown_fields.iter() {
        r += (tag_size(number) + 4) * values.fixed32.len() as u32;
        r += (tag_size(number) + 8) * values.fixed64.len() as u32;

        r += tag_size(number) * values.varint.len() as u32;
        for varint in values.varint.iter() {
            r += varint.len_varint();
        }

        r += tag_size(number) * values.length_delimited.len() as u32;
        for bytes in values.length_delimited.iter() {
            r += bytes_size_no_tag(bytes.as_slice());
        }
    }
    r
}

<|endoftext|>


<commit_before>use std::cmp::Ordering;

use ll;
use ll::limb::Limb;

pub unsafe fn gcd(gp: *mut Limb, mut ap: *mut Limb, mut an: i32, mut bp: *mut Limb, mut bn: i32) -> i32 {
    assert!(an >= bn);

    let mut gc = 0;
    while *ap == 0 && !ll::is_zero(ap, an) && *bp == 0 && !ll::is_zero(bp, bn){
        ap = ap.offset(1);
        bp = bp.offset(1);
        an -= 1;
        bn -= 1;
        gc += Limb::BITS as u32;
    }

    let a_trailing = (*ap).trailing_zeros() as u32;
    let b_trailing = (*bp).trailing_zeros() as u32;

    let trailing = if a_trailing < b_trailing {
        a_trailing
    } else {
        b_trailing
    };

    if trailing > 0 {
        ll::shr(ap, ap, an, trailing);
        ll::shr(bp, bp, bn, trailing);
        gc += trailing;
    }

    ll::copy_incr(bp, gp, bn);
    bp = gp;

    while !ll::is_zero(ap, an) {

        while *ap == 0 && !ll::is_zero(ap, an) {
            ap = ap.offset(1);
            an -= 1;
        }

        let at = (*ap).trailing_zeros() as u32;
        if at > 0 {
            ll::shr(ap, ap, an, at);
        }

        while *bp == 0 && !ll::is_zero(bp, bn) {
            bp = bp.offset(1);
            bn -= 1;
        }

        let bt = (*bp).trailing_zeros() as u32;
        if bt > 0 {
            ll::shr(bp, bp, bn, bt);
        }

        let c = ll::cmp(ap, bp, an);
        if an >= bn && (c == Ordering::Equal || c == Ordering::Greater) {
            ll::sub(ap, ap, an, bp, bn);
            ll::shr(ap, ap, an, 1);
        } else {
            // TODO: an for bp?
            ll::sub(gp, bp, an, ap, an);
            ll::shr(gp, gp, an, 1);
            bp = gp;
        }
    }

    let gn = ((gc / Limb::BITS as u32) + 1) as i32;

    for _ in 0..(gc / (Limb::BITS - 1) as u32) {
        ll::shl(gp, gp, gn, (Limb::BITS - 1) as u32);
    }
    let gc_mod = gc % (Limb::BITS - 1) as u32;
    if gc_mod > 0 {
        ll::shl(gp, gp, gn, gc_mod);
    }

    gn
}
<commit_msg>Cleanup left shift<commit_after>use std::cmp::Ordering;

use ll;
use ll::limb::Limb;

pub unsafe fn gcd(gp: *mut Limb, mut ap: *mut Limb, mut an: i32, mut bp: *mut Limb, mut bn: i32) -> i32 {
    assert!(an >= bn);

    let mut gc = 0;
    while *ap == 0 && !ll::is_zero(ap, an) && *bp == 0 && !ll::is_zero(bp, bn){
        ap = ap.offset(1);
        bp = bp.offset(1);
        an -= 1;
        bn -= 1;
        gc += 1;
    }

    let a_trailing = (*ap).trailing_zeros() as u32;
    let b_trailing = (*bp).trailing_zeros() as u32;

    let trailing = if a_trailing < b_trailing {
        a_trailing
    } else {
        b_trailing
    };

    if trailing > 0 {
        ll::shr(ap, ap, an, trailing);
        ll::shr(bp, bp, bn, trailing);
    }

    ll::copy_incr(bp, gp, bn);
    bp = gp;

    while !ll::is_zero(ap, an) {

        while *ap == 0 && !ll::is_zero(ap, an) {
            ap = ap.offset(1);
            an -= 1;
        }

        let at = (*ap).trailing_zeros() as u32;
        if at > 0 {
            ll::shr(ap, ap, an, at);
        }

        while *bp == 0 && !ll::is_zero(bp, bn) {
            bp = bp.offset(1);
            bn -= 1;
        }

        let bt = (*bp).trailing_zeros() as u32;
        if bt > 0 {
            ll::shr(bp, bp, bn, bt);
        }

        let c = ll::cmp(ap, bp, an);

        // FIXME find better way to compute |ap - bp| / 2
        if c == Ordering::Equal || c == Ordering::Greater {
            ll::sub(ap, ap, an, bp, bn);
            ll::shr(ap, ap, an, 1);
        } else {
            ll::sub(gp, bp, an, ap, an);
            ll::shr(gp, gp, an, 1);
            bp = gp;
        }
    }

    // FIXME what's the best way for the left shift, using offset
    let gn = (gc + 1) as i32;
    for _ in 0..gc {
        ll::shl(gp, gp, gn, (Limb::BITS - 1) as u32);
        ll::shl(gp, gp, gn, 1);
    }
    if trailing > 0 {
        ll::shl(gp, gp, gn, trailing);
    }

    gn
}
<|endoftext|>


<commit_before>use std::fs::{File, OpenOptions};
use std::io::{self, Write};

pub struct Logger {
    logfile: Option<File>,
}

impl Logger {
    pub fn new() -> Logger {
        Logger {
            logfile: None,
        }
    }

    pub fn set_logfile(&mut self, filename: &str) {
        let file = OpenOptions::new()
            .create(true)
            .append(true)
            .open(filename);

        match file {
            Ok(file) => self.logfile = Some(file),
            Err(error) => eprintln!("Couldn't open `{}' as a logfile: {}", filename, error),
        }
    }

    pub fn log(&mut self, message: &str) -> io::Result<()> {
        if let Some(ref mut logfile) = self.logfile {
            logfile.write_all(message.as_bytes())?;
            logfile.write_all("\n".as_bytes())?;
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    extern crate tempfile;

    use super::*;

    use self::tempfile::TempDir;
    use std::io::{self, Read};
    use std::path;

    fn setup_logger() -> io::Result<(TempDir, path::PathBuf, Logger)> {
        let tmp = TempDir::new()?;
        let logfile = {
            let mut logfile = tmp.path().to_owned();
            logfile.push("example.log");
            logfile
        };
        assert!(!logfile.exists());

        let mut logger = Logger::new();
        logger.set_logfile(logfile.to_str().unwrap());

        Ok((tmp, logfile, logger))
    }

    #[test]
    fn t_set_logfile() -> io::Result<()> {
        let (_tmp, logfile, _logger) = setup_logger()?;

        assert!(logfile.exists());

        Ok(())
    }

    #[test]
    fn t_log_writes_message_to_the_file() -> io::Result<()> {
        let (_tmp, logfile, mut logger) = setup_logger()?;

        let message = "Hello, world!";
        logger.log(message)?;

        // Dropping logger to force it to flush the log and close the file
        drop(logger);

        let mut file = File::open(logfile)?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;

        assert_eq!(contents, message.to_owned() + "\n");

        Ok(())
    }
}
<commit_msg>Test Logger::log on multiple strings<commit_after>use std::fs::{File, OpenOptions};
use std::io::{self, Write};

pub struct Logger {
    logfile: Option<File>,
}

impl Logger {
    pub fn new() -> Logger {
        Logger {
            logfile: None,
        }
    }

    pub fn set_logfile(&mut self, filename: &str) {
        let file = OpenOptions::new()
            .create(true)
            .append(true)
            .open(filename);

        match file {
            Ok(file) => self.logfile = Some(file),
            Err(error) => eprintln!("Couldn't open `{}' as a logfile: {}", filename, error),
        }
    }

    pub fn log(&mut self, message: &str) -> io::Result<()> {
        if let Some(ref mut logfile) = self.logfile {
            logfile.write_all(message.as_bytes())?;
            logfile.write_all("\n".as_bytes())?;
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    extern crate tempfile;

    use super::*;

    use self::tempfile::TempDir;
    use std::io::{self, BufReader, BufRead};
    use std::path;

    fn setup_logger() -> io::Result<(TempDir, path::PathBuf, Logger)> {
        let tmp = TempDir::new()?;
        let logfile = {
            let mut logfile = tmp.path().to_owned();
            logfile.push("example.log");
            logfile
        };
        assert!(!logfile.exists());

        let mut logger = Logger::new();
        logger.set_logfile(logfile.to_str().unwrap());

        Ok((tmp, logfile, logger))
    }

    #[test]
    fn t_set_logfile() -> io::Result<()> {
        let (_tmp, logfile, _logger) = setup_logger()?;

        assert!(logfile.exists());

        Ok(())
    }

    #[test]
    fn t_log_writes_message_to_the_file() -> io::Result<()> {
        let (_tmp, logfile, mut logger) = setup_logger()?;

        let messages = {
            let mut messages = vec![];
            messages.push("Hello, world!");
            messages.push("I'm doing fine, how are you?");
            messages.push("Time to wrap up, see ya!");
            messages
        };
        for msg in &messages {
            logger.log(msg)?;
        }

        // Dropping logger to force it to flush the log and close the file
        drop(logger);

        let file = File::open(logfile)?;
        let reader = BufReader::new(file);
        for (line, expected) in reader.lines().zip(messages) {
            match line {
                Ok(line) => assert_eq!(line, expected),
                Err(e) => return Err(e),
            }
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>macro_rules! vec_from_params {
  ($params:expr, $param:expr) => {
    match $params.find(&[$param]) {
      Some(val) => Vec::from_value(val)
                       .unwrap_or(vec![]),
      None => vec![],
    }
  }
}

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

  #[test]
  fn test_vec_from_params() {
    {
      let mut params = Map::new();
      params.assign("work_roles[]", Value::String("Fullstack".into())).unwrap();
      params.assign("work_roles[]", Value::String("DevOps".into())).unwrap();

      let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
      assert_eq!(work_roles, vec!["Fullstack", "DevOps"]);
    }

    {
      let mut params = Map::new();
      params.assign("work_roles[]", Value::String("".into())).unwrap();

      let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
      assert_eq!(work_roles, vec![""]); // vec![]?
    }

    {
      let work_roles: Vec<String> = vec_from_params!(Map::new(), "work_roles");
      assert_eq!(work_roles, Vec::<String>::new());
    }
  }
}
<commit_msg>macros: document vec_from_params!<commit_after>/// Given a `BTreeMap<String, Value>`, return a `Vec<_>` that
/// contains all the items wrapped inside the `Value`s.
///
/// Since `iron/params` returns `Result<Map, ParamsError>` (where
/// `Map` is defined as `BTreeMap<String, Value>`) and we're asked to
/// provide `VectorOfTerms<String>::build_terms()` a `Vec<String>`,
/// we need to assert that it `is_ok()` and eventually retrieving
/// its value using the convertion trait `FromValue`.
///
/// Either if the convertion result `is_none()` because of an error
/// or we originally got a `ParamsError`, an empty `Vec<String>` will
/// be returned.
///
/// Otherwise, the output will be a `Vec<String>` fill with all the
/// returned `String`s found inside the query string.
///
/// ```
/// use params::*;
///
/// let mut params = Map::new();
/// params.assign("work_roles[]", Value::String("Fullstack".into())).unwrap();
/// params.assign("work_roles[]", Value::String("DevOps".into())).unwrap();
///
/// let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
/// assert_eq!(work_roles, vec!["Fullstack", "DevOps"]);
/// ```
///
/// ```
/// use params::*;
///
/// let work_roles: Vec<String> = vec_from_params!(Map::new(), "work_roles");
/// assert_eq!(work_roles, Vec::<String>::new());
/// ```
#[macro_export]
macro_rules! vec_from_params {
  ($params:expr, $param:expr) => {
    match $params.find(&[$param]) {
      Some(val) => Vec::from_value(val)
                       .unwrap_or(vec![]),
      None => vec![],
    }
  }
}

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

  #[test]
  fn test_vec_from_params() {
    {
      let mut params = Map::new();
      params.assign("work_roles[]", Value::String("Fullstack".into())).unwrap();
      params.assign("work_roles[]", Value::String("DevOps".into())).unwrap();

      let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
      assert_eq!(work_roles, vec!["Fullstack", "DevOps"]);
    }

    {
      let mut params = Map::new();
      params.assign("work_roles[]", Value::String("".into())).unwrap();

      let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
      assert_eq!(work_roles, vec![""]); // TODO: `vec![]`?
    }

    {
      let work_roles: Vec<String> = vec_from_params!(Map::new(), "work_roles");
      assert_eq!(work_roles, Vec::<String>::new());
    }
  }
}
<|endoftext|>