<commit_before>use screen::*;
use piston_window;
use conrod::{self, Widget, Frameable, Positionable};
use conrod::color::Colorable;

pub struct MainMenuScreen {
    ui: conrod::Ui<piston_window::Glyphs>,
}

impl MainMenuScreen {
    pub fn new(window: &piston_window::PistonWindow, context: &mut Context) -> MainMenuScreen {
        MainMenuScreen { ui: create_ui(&window, &context.assets_path) }
    }
}

impl Screen for MainMenuScreen {
    fn on_input(&mut self,
                input: &piston_window::Input,
                window: &piston_window::PistonWindow,
                context: &mut Context)
                -> InputResults {
        use piston_window::{Input, Button, MouseButton};

        let mut result = Vec::new();

        match input {
            &Input::Press(Button::Mouse(MouseButton::Left)) => {
                result.push(InputResult::PopScreen);
                result.push(InputResult::PushScreen(Box::new(BattleScreen::new(&window, context))));
            }
            _ => {}
        }

        result
    }

    fn on_draw(&mut self, args: &piston_window::RenderArgs, window: &piston_window::PistonWindow) {
        self.ui.handle_event(window);
        window.draw_2d(|context, graphics| self.ui.draw_if_changed(context, graphics));
    }

    fn on_update(&mut self, args: &piston_window::UpdateArgs) {
        self.ui.set_widgets(|ui| {
            conrod::Canvas::new()
                .frame(200.)
                .pad(30.0)
                .color(conrod::color::rgb(0.2, 0.35, 0.45))
                .scroll_kids()
                .set(CANVAS, ui);

            conrod::Text::new("Main menu")
                .top_left_with_margins_on(CANVAS, 0.0, 350.0)
                .font_size(32)
                .color(conrod::color::rgb(0.2, 0.35, 0.45).plain_contrast())
                .set(TITLE, ui);
        });
    }
}

widget_ids! {
    CANVAS,
    TITLE,
    NEW_GAME_BUTTON,
    EXIT_BUTTON,
}

fn create_ui(window: &piston_window::PistonWindow,
             assets_path: &::std::path::Path)
             -> conrod::Ui<piston_window::Glyphs> {
    let font_path = assets_path.join("NotoSans-Regular.ttf");
    let theme = conrod::Theme::default();
    let glyph_cache = piston_window::Glyphs::new(&font_path, window.factory.borrow().clone());
    conrod::Ui::new(glyph_cache.unwrap(), theme)
}
<commit_msg>'New game' button<commit_after>use screen::*;
use piston_window;
use conrod::{self, Widget, Frameable, Positionable, Sizeable, Labelable};
use conrod::color::Colorable;
//use gif::traits::SetParameter;

pub struct MainMenuScreen {
    ui: conrod::Ui<piston_window::Glyphs>,
}

impl MainMenuScreen {
    pub fn new(window: &piston_window::PistonWindow, context: &mut Context) -> MainMenuScreen {
        MainMenuScreen { ui: create_ui(&window, &context.assets_path) }
    }
}

impl Screen for MainMenuScreen {
    fn on_input(&mut self,
                input: &piston_window::Input,
                window: &piston_window::PistonWindow,
                context: &mut Context)
                -> InputResults {
        use piston_window::{Input, Button, MouseButton};

        let mut result = Vec::new();

        match input {
            &Input::Press(Button::Mouse(MouseButton::Left)) => {
                result.push(InputResult::PopScreen);
                result.push(InputResult::PushScreen(Box::new(BattleScreen::new(&window, context))));
            }
            _ => {}
        }

        result
    }

    fn on_draw(&mut self, args: &piston_window::RenderArgs, window: &piston_window::PistonWindow) {
        self.ui.handle_event(window);
        window.draw_2d(|context, graphics| self.ui.draw_if_changed(context, graphics));
    }

    fn on_update(&mut self, args: &piston_window::UpdateArgs) {
        self.ui.set_widgets(|ui| {
            conrod::Canvas::new()
                .frame(200.)
                .pad(30.0)
                .color(conrod::color::rgb(0.2, 0.35, 0.45))
                .scroll_kids()
                .set(CANVAS, ui);

            conrod::Text::new("Main menu")
                .top_left_with_margins_on(CANVAS, 0.0, 350.0)
                .font_size(32)
                .color(conrod::color::rgb(0.2, 0.35, 0.45).plain_contrast())
                .set(TITLE, ui);

            conrod::Button::new()
//                .w_h(200.0, 50.0)
//                .mid_left_of(CANVAS)
//                .down_from(TITLE, 45.0)
                .rgb(0.4, 0.75, 0.6)
                .frame(100.)
                .label("New game")
//                .react(conrod::color::rgb(0.2, 0.35, 0.45))
                .react(|| ())
                .set(NEW_GAME_BUTTON, ui);
        });
    }
}

widget_ids! {
    CANVAS,
    TITLE,
    NEW_GAME_BUTTON,
    EXIT_BUTTON,
}

fn create_ui(window: &piston_window::PistonWindow,
             assets_path: &::std::path::Path)
             -> conrod::Ui<piston_window::Glyphs> {
    let font_path = assets_path.join("NotoSans-Regular.ttf");
    let theme = conrod::Theme::default();
    let glyph_cache = piston_window::Glyphs::new(&font_path, window.factory.borrow().clone());
    conrod::Ui::new(glyph_cache.unwrap(), theme)
}
<|endoftext|>


<commit_before>use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::io::stderr;
use std::path::Path;
use std::process;

struct Match {
    offset: usize,
    key: u8,
    preview: String,
}

fn main() {
    let args: Vec<String> = env::args().skip(1).collect();
    if args.len() < 2 {
        writeln!(stderr(), "usage: roxor <file> <crib>").unwrap();
        process::exit(1);
    }

    let path = Path::new(&args[0]);
    let crib: Vec<u8> = args[1].bytes().collect();

    if crib.len() < 2 {
        writeln!(stderr(), "error: crib too short").unwrap();
        process::exit(1);
    }

    let mut file = match File::open(&path) {
        Err(why) => panic!("couldn't open {}: {}", path.display(), why),
        Ok(file) => file,
    };

    let mut ciphertext: Vec<u8> = Vec::new();
    file.read_to_end(&mut ciphertext).unwrap();

    if ciphertext.len() < crib.len() {
        writeln!(stderr(), "error: ciphertext too short").unwrap();
        process::exit(1);
    }

    for m in attack_cipher(ciphertext, crib) {
        println!("Found text at 0x{:x} (XOR key 0x{:02x})", m.offset, m.key);
        println!("  preview: {}", m.preview);
    }
}

fn attack_cipher(ciphertext: Vec<u8>, crib: Vec<u8>) -> Vec<Match> {
    let mut matches: Vec<Match> = Vec::new();
    for (i, x) in ciphertext.iter().enumerate() {
        let mut old_key = x ^ crib[0];
        let mut j = 1;
        while j < crib.len() && (i+j) < ciphertext.len() {
            let key = ciphertext[i+j] ^ crib[j];
            if key != old_key { break; }
            old_key = key;
            j += 1;
            if j == crib.len() {
                let preview: String = ciphertext[i..i+50]
                    .iter()
                    .map(|x| x ^ key)
                    .map(|x| if x >= 32 && x <= 126 {x as char} else {'.'})
                    .collect();
                matches.push(Match { offset: i, key: key, preview: preview });
            }
        }
    }
    return matches;
}
<commit_msg>Pass data as slices<commit_after>use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::io::stderr;
use std::path::Path;
use std::process;

struct Match {
    offset: usize,
    key: u8,
    preview: String,
}

fn main() {
    let args: Vec<String> = env::args().skip(1).collect();
    if args.len() < 2 {
        writeln!(stderr(), "usage: roxor <file> <crib>").unwrap();
        process::exit(1);
    }

    let path = Path::new(&args[0]);
    let crib = args[1].as_bytes();

    if crib.len() < 2 {
        writeln!(stderr(), "error: crib too short").unwrap();
        process::exit(1);
    }

    let mut file = match File::open(&path) {
        Err(why) => panic!("couldn't open {}: {}", path.display(), why),
        Ok(file) => file,
    };

    let mut ciphertext: Vec<u8> = Vec::new();
    file.read_to_end(&mut ciphertext).unwrap();

    if ciphertext.len() < crib.len() {
        writeln!(stderr(), "error: ciphertext too short").unwrap();
        process::exit(1);
    }

    for m in attack_cipher(&ciphertext[..], crib) {
        println!("Found text at 0x{:x} (XOR key 0x{:02x})", m.offset, m.key);
        println!("  preview: {}", m.preview);
    }
}

fn attack_cipher(ciphertext: &[u8], crib: &[u8]) -> Vec<Match> {
    let mut matches: Vec<Match> = Vec::new();
    for (i, x) in ciphertext.iter().enumerate() {
        let mut old_key = x ^ crib[0];
        let mut j = 1;
        while j < crib.len() && (i+j) < ciphertext.len() {
            let key = ciphertext[i+j] ^ crib[j];
            if key != old_key { break; }
            old_key = key;
            j += 1;
            if j == crib.len() {
                let preview: String = ciphertext[i..i+50]
                    .iter()
                    .map(|x| x ^ key)
                    .map(|x| if x >= 32 && x <= 126 {x as char} else {'.'})
                    .collect();
                matches.push(Match { offset: i, key: key, preview: preview });
            }
        }
    }
    return matches;
}
<|endoftext|>


<commit_before>extern crate piston_meta;

use piston_meta::*;
use std::fs::File;
use std::path::Path;
use std::io::Read;

fn load_file<P: AsRef<Path>>(path: P) -> String {
    let mut file_h = File::open(path.as_ref()).unwrap();
    let mut source = String::new();
    file_h.read_to_string(&mut source).unwrap();
    source
}

fn main() {
    // Get the old syntax in the new syntax.
    let old = load_file("assets/old-syntax.txt");
    let old_syntax = stderr_unwrap(&old, syntax2(&old));

    let old_in_old = load_file("assets/old-self-syntax.txt");
    let old_in_old_syntax = stderr_unwrap(&old_in_old, syntax(&old_in_old));

    assert_eq!(old_syntax, old_in_old_syntax);
    println!("Bootstrap succeeded!");
}
<commit_msg>Fixed "bootstrap_old" example<commit_after>extern crate piston_meta;

use piston_meta::*;
use std::fs::File;
use std::path::Path;
use std::io::Read;

fn load_file<P: AsRef<Path>>(path: P) -> String {
    let mut file_h = File::open(path.as_ref()).unwrap();
    let mut source = String::new();
    file_h.read_to_string(&mut source).unwrap();
    source
}

fn main() {
    // Get the old syntax in the new syntax.
    let old = load_file("assets/old-syntax.txt");
    let old_syntax = stderr_unwrap(&old, syntax2(&old));

    let old_in_old = load_file("assets/old-self-syntax.txt");
    let old_in_old_syntax = stderr_unwrap(&old_in_old,
        parse(&old_syntax, &old_in_old));
    let old_in_old_syntax = bootstrap::convert(&old_in_old_syntax, &mut vec![])
        .unwrap();

    assert_eq!(old_syntax, old_in_old_syntax);
    println!("Bootstrap succeeded!");
}
<|endoftext|>


<commit_before>use std::iter::from_fn;

use turtle::{random, random_range, Color, Turtle};

fn main() {
    // Parameters to play around with for changing the character of the created drawing.
    let width = 800;
    let height = 600;
    let row_count = 3;
    let col_count = 4;
    let color_count = 7;

    let mut turtle = ArtisticTurtle::new(width, height, row_count, col_count, color_count);
    turtle.draw();
}

/// A special kind of turtle that is specialized in creating drawings of colorful triangles.
struct ArtisticTurtle {
    turtle: Turtle,
    row_count: u32,
    col_count: u32,
    row_height: f64,
    col_width: f64,
    colors: Vec<Color>,
}

impl ArtisticTurtle {
    /// Create a new turtle using the given parameters.
    /// `width`: total width of the drawing
    /// `height`: total height of the drawing
    /// `row_count`: number of rows of triangles to be created
    /// `col_count`: number of columns per row to be created
    /// `color_count`: number of different colors to use
    fn new(width: u32, height: u32, row_count: u32, col_count: u32, color_count: usize) -> Self {
        // Create and prepare the turtle.
        let mut turtle = Turtle::new();
        turtle.set_speed("instant");
        turtle.pen_up();
        turtle.drawing_mut().set_size([width, height]);

        // Move turtle to the upper left corner of the drawing.
        let size = turtle.drawing().size();
        let x_start = size.width / 2;
        let y_start = size.height / 2;
        turtle.go_to([f64::from(x_start) * -1.0, f64::from(y_start)]);
        turtle.set_speed(20);

        // Calculate height and width of the triangles.
        let row_height = f64::from(size.height) / f64::from(row_count);
        let col_width = f64::from(size.width) / f64::from(col_count);

        // Prepare a set of random colors to randomly choose from when drawing.
        let colors: Vec<Color> = from_fn(|| Some(random())).take(color_count).collect();

        Self {
            turtle,
            row_count,
            col_count,
            row_height,
            col_width,
            colors,
        }
    }

    /// Randomly choose a color from the previously specified set of colors.
    fn get_color(&self) -> Color {
        let index: usize = random_range(0, self.colors.len() - 1);
        self.colors[index]
    }

    /// Draw a single triangle by drawing two sides and filling them with a random color
    /// which creates the third side of the triangle along the way.
    /// Note: Even though the turtle is always turning right in this method, this movement
    /// can also result in a left turn (depending on the angle chosen).
    fn draw_triangle(&mut self, angle: f64) {
        self.turtle.set_fill_color(self.get_color());
        self.turtle.begin_fill();

        self.turtle.right(angle);
        self.turtle.forward(self.col_width);

        self.turtle.right(angle);
        self.turtle.forward(self.row_height);

        self.turtle.end_fill();
    }

    /// Draw a single row of triangles in two runs:
    /// 1. Create triangles from left to right.
    /// 2. Turn around and fill in triangles from right to left.
    fn draw_row(&mut self) {
        // Create an endless loop over the angles of 90 and 270 degrees
        // (corresponds to moving right and left, respectively).
        let angles = vec![90.0, 270.0];
        let mut angle_cycle = angles.iter().cycle();

        // Create triangles from left to right.
        for _ in 0..self.col_count {
            let angle = angle_cycle.next().unwrap();
            self.draw_triangle(*angle);
        }

        // Skip one angle so that we have the correct angle when turning around.
        angle_cycle.next();

        // Fill in triangles from right to left to complete the row.
        for _ in 0..self.col_count {
            let angle = angle_cycle.next().unwrap();
            self.draw_triangle(*angle);
        }

        // Reset position to prepare for the next row.
        self.turtle.right(180.0);
        self.turtle.forward(self.row_height);
        self.turtle.left(180.0);
    }

    /// Create a drawing consisting of rows of triangles in different colors.
    fn draw(&mut self) {
        for _ in 0..self.row_count {
            self.draw_row();
        }
        self.turtle.hide();
    }
}
<commit_msg>Replace get_color with the new choose function<commit_after>use std::iter::from_fn;

use turtle::{choose, random, Color, Turtle};

fn main() {
    // Parameters to play around with for changing the character of the created drawing.
    let width = 800;
    let height = 600;
    let row_count = 3;
    let col_count = 4;
    let color_count = 7;

    let mut turtle = ArtisticTurtle::new(width, height, row_count, col_count, color_count);
    turtle.draw();
}

/// A special kind of turtle that is specialized in creating drawings of colorful triangles.
struct ArtisticTurtle {
    turtle: Turtle,
    row_count: u32,
    col_count: u32,
    row_height: f64,
    col_width: f64,
    colors: Vec<Color>,
}

impl ArtisticTurtle {
    /// Create a new turtle using the given parameters.
    /// `width`: total width of the drawing
    /// `height`: total height of the drawing
    /// `row_count`: number of rows of triangles to be created
    /// `col_count`: number of columns per row to be created
    /// `color_count`: number of different colors to use
    fn new(width: u32, height: u32, row_count: u32, col_count: u32, color_count: usize) -> Self {
        // Create and prepare the turtle.
        let mut turtle = Turtle::new();
        turtle.set_speed("instant");
        turtle.pen_up();
        turtle.drawing_mut().set_size([width, height]);

        // Move turtle to the upper left corner of the drawing.
        let size = turtle.drawing().size();
        let x_start = size.width / 2;
        let y_start = size.height / 2;
        turtle.go_to([f64::from(x_start) * -1.0, f64::from(y_start)]);
        turtle.set_speed(20);

        // Calculate height and width of the triangles.
        let row_height = f64::from(size.height) / f64::from(row_count);
        let col_width = f64::from(size.width) / f64::from(col_count);

        // Prepare a set of random colors to randomly choose from when drawing.
        let colors: Vec<Color> = from_fn(|| Some(random())).take(color_count).collect();

        Self {
            turtle,
            row_count,
            col_count,
            row_height,
            col_width,
            colors,
        }
    }

    /// Draw a single triangle by drawing two sides and filling them with a random color
    /// which creates the third side of the triangle along the way.
    /// Note: Even though the turtle is always turning right in this method, this movement
    /// can also result in a left turn (depending on the angle chosen).
    fn draw_triangle(&mut self, angle: f64) {
        // This call to unwrap() is always safe because the color slice will always be non-empty.
        let color = choose(&self.colors).cloned().unwrap();
        self.turtle.set_fill_color(color);
        self.turtle.begin_fill();

        self.turtle.right(angle);
        self.turtle.forward(self.col_width);

        self.turtle.right(angle);
        self.turtle.forward(self.row_height);

        self.turtle.end_fill();
    }

    /// Draw a single row of triangles in two runs:
    /// 1. Create triangles from left to right.
    /// 2. Turn around and fill in triangles from right to left.
    fn draw_row(&mut self) {
        // Create an endless loop over the angles of 90 and 270 degrees
        // (corresponds to moving right and left, respectively).
        let angles = vec![90.0, 270.0];
        let mut angle_cycle = angles.iter().cycle();

        // Create triangles from left to right.
        for _ in 0..self.col_count {
            let angle = angle_cycle.next().unwrap();
            self.draw_triangle(*angle);
        }

        // Skip one angle so that we have the correct angle when turning around.
        angle_cycle.next();

        // Fill in triangles from right to left to complete the row.
        for _ in 0..self.col_count {
            let angle = angle_cycle.next().unwrap();
            self.draw_triangle(*angle);
        }

        // Reset position to prepare for the next row.
        self.turtle.right(180.0);
        self.turtle.forward(self.row_height);
        self.turtle.left(180.0);
    }

    /// Create a drawing consisting of rows of triangles in different colors.
    fn draw(&mut self) {
        for _ in 0..self.row_count {
            self.draw_row();
        }
        self.turtle.hide();
    }
}
<|endoftext|>


<commit_before>extern crate nalgebra as na;

use na::{Point3, Vector3, Isometry3};
use ncollide3d::shape::{Cuboid, ShapeHandle};
use nphysics3d::object::{Ground, BodyStatus, FEMVolumeDesc, ColliderDesc, RigidBodyDesc, DefaultBodySet, DefaultColliderSet, BodyPartHandle};
use nphysics3d::force_generator::DefaultForceGeneratorSet;
use nphysics3d::joint::DefaultJointConstraintSet;
use nphysics3d::world::{DefaultMechanicalWorld, DefaultGeometricalWorld};
use nphysics_testbed3d::Testbed;

pub fn init_world(testbed: &mut Testbed) {
    /*
     * World
     */
    let mechanical_world = DefaultMechanicalWorld::new(Vector3::zeros());
    let geometrical_world = DefaultGeometricalWorld::new();
    let mut bodies = DefaultBodySet::new();
    let mut colliders = DefaultColliderSet::new();
    let joint_constraints = DefaultJointConstraintSet::new();
    let force_generators = DefaultForceGeneratorSet::new();

    /*
     * Ground.
     */
    let platform_height = 0.4;
    let platform_size = 0.6;
    let platform_shape =
        ShapeHandle::new(Cuboid::new(Vector3::new(0.03, 0.03, platform_size)));

    let positions = [
        Isometry3::new(Vector3::new(0.4, platform_height, 0.0), na::zero()),
        Isometry3::new(Vector3::new(0.2, -platform_height, 0.0), na::zero()),
        Isometry3::new(Vector3::new(0.0, platform_height, 0.0), na::zero()),
        Isometry3::new(Vector3::new(-0.2, -platform_height, 0.0), na::zero()),
        Isometry3::new(Vector3::new(-0.4, platform_height, 0.0), na::zero()),
    ];

    let mut platforms = Vec::new();

    for (i, pos) in positions.iter().enumerate() {
        let platform = RigidBodyDesc::new()
            .position(*pos)
            .status(BodyStatus::Kinematic)
            .build();
        platforms.push(bodies.insert(platform));

        let co = ColliderDesc::new(platform_shape.clone())
            .build(BodyPartHandle(platforms[i], 0));
        colliders.insert(co);
    }

    /*
     * Create the deformable body and a collider for its contour.
     */
    let mut deformable = FEMVolumeDesc::cube(20, 1, 1)
        .scale(Vector3::new(1.1, 0.1, 0.1))
        .density(1.0)
        .young_modulus(1.0e2)
        .mass_damping(0.2)
        .plasticity(0.1, 5.0, 10.0)
        .build();
    let collider_desc = deformable.boundary_collider_desc();
    let deformable_surface_handle = bodies.insert(deformable);
    let co = collider_desc.build(deformable_surface_handle);
    colliders.insert(co);

    /*
     * Set up the testbed.
     */
    testbed.set_body_color(deformable_surface_handle, Point3::new(0.0, 0.0, 1.0));

    for platform in &platforms {
        testbed.set_body_color(*platform, Point3::new(0.5, 0.5, 0.5));
    }

    testbed.add_callback(move |_, _, bodies, _, _, _| {
        for (i, handle) in platforms.iter().enumerate() {
            let platform = bodies.rigid_body_mut(*handle).unwrap();
            let platform_y = platform.position().translation.vector.y;

            let mut vel = *platform.velocity();
            let vel_magnitude = 0.1;
            let max_traversal = 0.005;

            if i % 2 == 0 {
                if platform_y <= -max_traversal {
                    vel.linear.y = vel_magnitude;
                } else if platform_y >= platform_height {
                    vel.linear.y = -vel_magnitude;
                }
            } else {
                if platform_y >= max_traversal {
                    vel.linear.y = -vel_magnitude;
                } else if platform_y <= -platform_height {
                    vel.linear.y = vel_magnitude;
                }
            }

            platform.set_velocity(vel);
        }
    });

    // NOTE: we add another static body to the scene. It is not necessary for our simulation
    // but this is required so that we can call `testbed.set_ground_handle` which will
    // enable the testbed's feature that lets us grab an object with the mouse.
    let ground_handle = bodies.insert(Ground::new());
    testbed.set_ground_handle(Some(ground_handle));
    testbed.set_world(mechanical_world, geometrical_world, bodies, colliders, joint_constraints, force_generators);
    testbed.look_at(Point3::new(0.0, 0.0, 2.0), Point3::new(0.0, 0.0, 0.0));
    testbed.show_performance_counters();
}

fn main() {
    let testbed = Testbed::from_builders(0, vec![
        ("Plasticity", init_world),
    ]);
    testbed.run()
}
<commit_msg>Plasticity 3D demo: don't show performance counters.<commit_after>extern crate nalgebra as na;

use na::{Point3, Vector3, Isometry3};
use ncollide3d::shape::{Cuboid, ShapeHandle};
use nphysics3d::object::{Ground, BodyStatus, FEMVolumeDesc, ColliderDesc, RigidBodyDesc, DefaultBodySet, DefaultColliderSet, BodyPartHandle};
use nphysics3d::force_generator::DefaultForceGeneratorSet;
use nphysics3d::joint::DefaultJointConstraintSet;
use nphysics3d::world::{DefaultMechanicalWorld, DefaultGeometricalWorld};
use nphysics_testbed3d::Testbed;

pub fn init_world(testbed: &mut Testbed) {
    /*
     * World
     */
    let mechanical_world = DefaultMechanicalWorld::new(Vector3::zeros());
    let geometrical_world = DefaultGeometricalWorld::new();
    let mut bodies = DefaultBodySet::new();
    let mut colliders = DefaultColliderSet::new();
    let joint_constraints = DefaultJointConstraintSet::new();
    let force_generators = DefaultForceGeneratorSet::new();

    /*
     * Ground.
     */
    let platform_height = 0.4;
    let platform_size = 0.6;
    let platform_shape =
        ShapeHandle::new(Cuboid::new(Vector3::new(0.03, 0.03, platform_size)));

    let positions = [
        Isometry3::new(Vector3::new(0.4, platform_height, 0.0), na::zero()),
        Isometry3::new(Vector3::new(0.2, -platform_height, 0.0), na::zero()),
        Isometry3::new(Vector3::new(0.0, platform_height, 0.0), na::zero()),
        Isometry3::new(Vector3::new(-0.2, -platform_height, 0.0), na::zero()),
        Isometry3::new(Vector3::new(-0.4, platform_height, 0.0), na::zero()),
    ];

    let mut platforms = Vec::new();

    for (i, pos) in positions.iter().enumerate() {
        let platform = RigidBodyDesc::new()
            .position(*pos)
            .status(BodyStatus::Kinematic)
            .build();
        platforms.push(bodies.insert(platform));

        let co = ColliderDesc::new(platform_shape.clone())
            .build(BodyPartHandle(platforms[i], 0));
        colliders.insert(co);
    }

    /*
     * Create the deformable body and a collider for its contour.
     */
    let mut deformable = FEMVolumeDesc::cube(20, 1, 1)
        .scale(Vector3::new(1.1, 0.1, 0.1))
        .density(1.0)
        .young_modulus(1.0e2)
        .mass_damping(0.2)
        .plasticity(0.1, 5.0, 10.0)
        .build();
    let collider_desc = deformable.boundary_collider_desc();
    let deformable_surface_handle = bodies.insert(deformable);
    let co = collider_desc.build(deformable_surface_handle);
    colliders.insert(co);

    /*
     * Set up the testbed.
     */
    testbed.set_body_color(deformable_surface_handle, Point3::new(0.0, 0.0, 1.0));

    for platform in &platforms {
        testbed.set_body_color(*platform, Point3::new(0.5, 0.5, 0.5));
    }

    testbed.add_callback(move |_, _, bodies, _, _, _| {
        for (i, handle) in platforms.iter().enumerate() {
            let platform = bodies.rigid_body_mut(*handle).unwrap();
            let platform_y = platform.position().translation.vector.y;

            let mut vel = *platform.velocity();
            let vel_magnitude = 0.1;
            let max_traversal = 0.005;

            if i % 2 == 0 {
                if platform_y <= -max_traversal {
                    vel.linear.y = vel_magnitude;
                } else if platform_y >= platform_height {
                    vel.linear.y = -vel_magnitude;
                }
            } else {
                if platform_y >= max_traversal {
                    vel.linear.y = -vel_magnitude;
                } else if platform_y <= -platform_height {
                    vel.linear.y = vel_magnitude;
                }
            }

            platform.set_velocity(vel);
        }
    });

    // NOTE: we add another static body to the scene. It is not necessary for our simulation
    // but this is required so that we can call `testbed.set_ground_handle` which will
    // enable the testbed's feature that lets us grab an object with the mouse.
    let ground_handle = bodies.insert(Ground::new());
    testbed.set_ground_handle(Some(ground_handle));
    testbed.set_world(mechanical_world, geometrical_world, bodies, colliders, joint_constraints, force_generators);
    testbed.look_at(Point3::new(0.0, 0.0, 2.0), Point3::new(0.0, 0.0, 0.0));
}

fn main() {
    let testbed = Testbed::from_builders(0, vec![
        ("Plasticity", init_world),
    ]);
    testbed.run()
}
<|endoftext|>


<commit_before>use rand::{SeedableRng, Rng, rngs::SmallRng};

// Having more than 1 test does seem to make a difference
// (i.e., this calls ptr::swap which having just one test does not).
#[test]
fn simple1() {
    assert_eq!(4, 4);
}

#[test]
fn simple2() {
    assert_ne!(42, 24);
}

// A test that won't work on miri (tests disabling tests).
#[test]
#[cfg_attr(miri, ignore)]
fn does_not_work_on_miri() {
    let x = 0u8;
    assert!(&x as *const _ as usize % 4 < 4);
}

// We also use this to test some external crates, that we cannot depend on in the compiletest suite.

#[test]
fn entropy_rng() {
    // Try seeding with "real" entropy.
    let mut rng = SmallRng::from_entropy();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();

    // Also try per-thread RNG.
    let mut rng = rand::thread_rng();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();
}

#[test]
fn num_cpus() {
    assert_eq!(num_cpus::get(), 1);
}

// FIXME: Remove this `cfg` once we fix https://github.com/rust-lang/miri/issues/1059.
// We cfg-gate the `should_panic` attribute and the `panic!` itself, so that the test
// stdout does not depend on the platform.
#[test]
#[cfg_attr(not(windows), should_panic(expected="Explicit panic"))]
fn do_panic() { // In large, friendly letters :)
    #[cfg(not(windows))]
    panic!("Explicit panic from test!");
}

// FIXME: see above
#[test]
#[allow(const_err)]
#[cfg_attr(not(windows), should_panic(expected="the len is 0 but the index is 42"))]
fn fail_index_check() {
    #[cfg(not(windows))]
    [][42]
}
<commit_msg>fix test-cargo-miri<commit_after>use rand::{SeedableRng, Rng, rngs::SmallRng};

// Having more than 1 test does seem to make a difference
// (i.e., this calls ptr::swap which having just one test does not).
#[test]
fn simple1() {
    assert_eq!(4, 4);
}

#[test]
fn simple2() {
    assert_ne!(42, 24);
}

// A test that won't work on miri (tests disabling tests).
#[test]
#[cfg_attr(miri, ignore)]
fn does_not_work_on_miri() {
    let x = 0u8;
    assert!(&x as *const _ as usize % 4 < 4);
}

// We also use this to test some external crates, that we cannot depend on in the compiletest suite.

#[test]
fn entropy_rng() {
    // Try seeding with "real" entropy.
    let mut rng = SmallRng::from_entropy();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();

    // Also try per-thread RNG.
    let mut rng = rand::thread_rng();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();
}

#[test]
fn num_cpus() {
    assert_eq!(num_cpus::get(), 1);
}

// FIXME: Remove this `cfg` once we fix https://github.com/rust-lang/miri/issues/1059.
// We cfg-gate the `should_panic` attribute and the `panic!` itself, so that the test
// stdout does not depend on the platform.
#[test]
#[cfg_attr(not(windows), should_panic(expected="Explicit panic"))]
fn do_panic() { // In large, friendly letters :)
    #[cfg(not(windows))]
    panic!("Explicit panic from test!");
}

// FIXME: see above
#[test]
#[allow(unconditional_panic)]
#[cfg_attr(not(windows), should_panic(expected="the len is 0 but the index is 42"))]
fn fail_index_check() {
    #[cfg(not(windows))]
    [][42]
}
<|endoftext|>


<commit_before>use std::fmt::Debug;
use std::f64::consts::PI;

pub trait ActivationFunction: Clone + Debug + Send + Sized + PartialEq + Eq {
    fn formula_gnuplot(&self, x: String) -> String;
    fn name(&self) -> String;
    fn calculate(&self, x: f64) -> f64;
}

#[inline(always)]
fn bipolar_debug_check(x: f64) -> f64 {
    debug_assert!(x >= -1.0 && x <= 1.0);
    x
}

/// Clips the value of `x` into the range [-1, 1].
fn bipolar_clip(x: f64) -> f64 {
    if x > 1.0 {
        1.0
    } else if x < -1.0 {
        -1.0
    } else {
        x
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GeometricActivationFunction {
    Linear,
    LinearBipolarClipped,
    Absolute,
    Gaussian,
    BipolarGaussian,
    BipolarSigmoid,
    Sine,
    Cosine,
    Constant1,
}

impl ActivationFunction for GeometricActivationFunction {
    fn calculate(&self, x: f64) -> f64 {
        match *self {
            GeometricActivationFunction::Linear => x,
            GeometricActivationFunction::LinearBipolarClipped => bipolar_debug_check(bipolar_clip(x)),
            GeometricActivationFunction::Absolute => x.abs(),
            GeometricActivationFunction::Gaussian => {
                (-((x * 2.5).powi(2))).exp()
            }
            GeometricActivationFunction::BipolarGaussian => {
                bipolar_debug_check(2.0 * (-((x * 2.5).powi(2))).exp() - 1.0)
            }
            GeometricActivationFunction::BipolarSigmoid => {
                bipolar_debug_check((2.0 / (1.0 + (-4.9 * x).exp())) - 1.0)
            }
            GeometricActivationFunction::Sine => bipolar_debug_check((2.0*PI*x).sin()),
            GeometricActivationFunction::Cosine => bipolar_debug_check(2.0*PI*x.cos()),
            GeometricActivationFunction::Constant1 => 1.0,
        }
    }

    fn formula_gnuplot(&self, x: String) -> String {
        match *self {
            GeometricActivationFunction::Linear => format!("{}", x),
            GeometricActivationFunction::LinearBipolarClipped => format!("max(-1.0, min(1.0, {}))", x),
            GeometricActivationFunction::Absolute => format!("abs({})", x),
            GeometricActivationFunction::Gaussian => format!("(exp(-((({}) * 2.5)**2.0))", x),
            GeometricActivationFunction::BipolarGaussian => format!("2.0 * exp(-((({}) * 2.5)**2.0)) - 1.0", x),
            GeometricActivationFunction::BipolarSigmoid => format!("2.0 / (1.0 + exp(-4.9 * ({}))) - 1.0", x),
            GeometricActivationFunction::Sine => format!("sin({})", x),
            GeometricActivationFunction::Cosine => format!("cos({})", x),
            GeometricActivationFunction::Constant1 => format!("1.0"),
        }
    }

    fn name(&self) -> String {
        match *self {
            GeometricActivationFunction::Linear => "Linear",
            GeometricActivationFunction::LinearBipolarClipped => "LinearBipolarClipped",
            GeometricActivationFunction::Absolute => "Absolute",
            GeometricActivationFunction::Gaussian => "Gaussian",
            GeometricActivationFunction::BipolarGaussian => "BipolarGaussian",
            GeometricActivationFunction::BipolarSigmoid =>  "BipolarSigmoid",
            GeometricActivationFunction::Sine => "Sine",
            GeometricActivationFunction::Cosine => "Consine",
            GeometricActivationFunction::Constant1 => "1.0",
        }.to_string()
    }
}

#[test]
fn test_bipolar_linear_clipped() {
    assert_eq!(0.0, GeometricActivationFunction::LinearBipolarClipped.calculate(0.0));
    assert_eq!(1.0, GeometricActivationFunction::LinearBipolarClipped.calculate(1.0));
    assert_eq!(-1.0, GeometricActivationFunction::LinearBipolarClipped.calculate(-1.0));
    assert_eq!(0.5, GeometricActivationFunction::LinearBipolarClipped.calculate(0.5));
    assert_eq!(-0.5, GeometricActivationFunction::LinearBipolarClipped.calculate(-0.5));
    assert_eq!(1.0, GeometricActivationFunction::LinearBipolarClipped.calculate(1.1));
    assert_eq!(-1.0, GeometricActivationFunction::LinearBipolarClipped.calculate(-1.1));
}

#[test]
fn test_constant1() {
    assert_eq!(1.0, GeometricActivationFunction::Constant1.calculate(0.0));
    assert_eq!(1.0, GeometricActivationFunction::Constant1.calculate(-1.0));
    assert_eq!(1.0, GeometricActivationFunction::Constant1.calculate(1.0));
}
<commit_msg>Add LinearClipped<commit_after>use std::fmt::Debug;
use std::f64::consts::PI;

pub trait ActivationFunction: Clone + Debug + Send + Sized + PartialEq + Eq {
    fn formula_gnuplot(&self, x: String) -> String;
    fn name(&self) -> String;
    fn calculate(&self, x: f64) -> f64;
}

#[inline(always)]
fn bipolar_debug_check(x: f64) -> f64 {
    debug_assert!(x >= -1.0 && x <= 1.0);
    x
}

/// Clips the value of `x` into the range [-1, 1].
fn bipolar_clip(x: f64) -> f64 {
    if x > 1.0 {
        1.0
    } else if x < -1.0 {
        -1.0
    } else {
        x
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GeometricActivationFunction {
    Linear,
    LinearBipolarClipped,
    LinearClipped,
    Absolute,
    Gaussian,
    BipolarGaussian,
    BipolarSigmoid,
    Sine,
    Cosine,
    Constant1,
}

impl ActivationFunction for GeometricActivationFunction {
    fn calculate(&self, x: f64) -> f64 {
        match *self {
            GeometricActivationFunction::Linear => x,
            GeometricActivationFunction::LinearBipolarClipped => bipolar_debug_check(bipolar_clip(x)),
            GeometricActivationFunction::LinearClipped => x.min(1.0).max(0.0),
            GeometricActivationFunction::Absolute => x.abs(),
            GeometricActivationFunction::Gaussian => {
                (-((x * 2.5).powi(2))).exp()
            }
            GeometricActivationFunction::BipolarGaussian => {
                bipolar_debug_check(2.0 * (-((x * 2.5).powi(2))).exp() - 1.0)
            }
            GeometricActivationFunction::BipolarSigmoid => {
                bipolar_debug_check((2.0 / (1.0 + (-4.9 * x).exp())) - 1.0)
            }
            GeometricActivationFunction::Sine => bipolar_debug_check((2.0*PI*x).sin()),
            GeometricActivationFunction::Cosine => bipolar_debug_check(2.0*PI*x.cos()),
            GeometricActivationFunction::Constant1 => 1.0,
        }
    }

    fn formula_gnuplot(&self, x: String) -> String {
        match *self {
            GeometricActivationFunction::Linear => format!("{}", x),
            GeometricActivationFunction::LinearBipolarClipped => format!("max(-1.0, min(1.0, {}))", x),
            GeometricActivationFunction::LinearClipped => format!("max(0.0, min(1.0, {}))", x),
            GeometricActivationFunction::Absolute => format!("abs({})", x),
            GeometricActivationFunction::Gaussian => format!("(exp(-((({}) * 2.5)**2.0))", x),
            GeometricActivationFunction::BipolarGaussian => format!("2.0 * exp(-((({}) * 2.5)**2.0)) - 1.0", x),
            GeometricActivationFunction::BipolarSigmoid => format!("2.0 / (1.0 + exp(-4.9 * ({}))) - 1.0", x),
            GeometricActivationFunction::Sine => format!("sin({})", x),
            GeometricActivationFunction::Cosine => format!("cos({})", x),
            GeometricActivationFunction::Constant1 => format!("1.0"),
        }
    }

    fn name(&self) -> String {
        match *self {
            GeometricActivationFunction::Linear => "Linear",
            GeometricActivationFunction::LinearBipolarClipped => "LinearBipolarClipped",
            GeometricActivationFunction::LinearClipped => "LinearClipped",
            GeometricActivationFunction::Absolute => "Absolute",
            GeometricActivationFunction::Gaussian => "Gaussian",
            GeometricActivationFunction::BipolarGaussian => "BipolarGaussian",
            GeometricActivationFunction::BipolarSigmoid =>  "BipolarSigmoid",
            GeometricActivationFunction::Sine => "Sine",
            GeometricActivationFunction::Cosine => "Consine",
            GeometricActivationFunction::Constant1 => "1.0",
        }.to_string()
    }
}

#[test]
fn test_bipolar_linear_clipped() {
    assert_eq!(0.0, GeometricActivationFunction::LinearBipolarClipped.calculate(0.0));
    assert_eq!(1.0, GeometricActivationFunction::LinearBipolarClipped.calculate(1.0));
    assert_eq!(-1.0, GeometricActivationFunction::LinearBipolarClipped.calculate(-1.0));
    assert_eq!(0.5, GeometricActivationFunction::LinearBipolarClipped.calculate(0.5));
    assert_eq!(-0.5, GeometricActivationFunction::LinearBipolarClipped.calculate(-0.5));
    assert_eq!(1.0, GeometricActivationFunction::LinearBipolarClipped.calculate(1.1));
    assert_eq!(-1.0, GeometricActivationFunction::LinearBipolarClipped.calculate(-1.1));
}

#[test]
fn test_linear_clipped() {
    assert_eq!(0.0, GeometricActivationFunction::LinearClipped.calculate(0.0));
    assert_eq!(1.0, GeometricActivationFunction::LinearClipped.calculate(1.0));
    assert_eq!(0.0, GeometricActivationFunction::LinearClipped.calculate(-1.0));
    assert_eq!(0.5, GeometricActivationFunction::LinearClipped.calculate(0.5));
    assert_eq!(0.0, GeometricActivationFunction::LinearClipped.calculate(-0.5));
    assert_eq!(1.0, GeometricActivationFunction::LinearClipped.calculate(1.1));
    assert_eq!(0.0, GeometricActivationFunction::LinearClipped.calculate(-1.1));
}

#[test]
fn test_constant1() {
    assert_eq!(1.0, GeometricActivationFunction::Constant1.calculate(0.0));
    assert_eq!(1.0, GeometricActivationFunction::Constant1.calculate(-1.0));
    assert_eq!(1.0, GeometricActivationFunction::Constant1.calculate(1.0));
}
<|endoftext|>


<commit_before>use analysis::bounds::Bound;
use analysis::imports::Imports;
use analysis::ref_mode::RefMode;
use analysis::rust_type::*;
use analysis::signatures::{Signature, Signatures};
use config;
use config::gobjects::GObject;
use env::Env;
use library;
use nameutil;
use traits::*;
use version::Version;

#[derive(Debug)]
pub struct Property {
    pub name: String,
    pub var_name: String,
    pub typ: library::TypeId,
    pub is_get: bool,
    pub func_name: String,
    pub nullable: library::Nullable,
    pub conversion: PropertyConversion,
    pub default_value: Option<String>, //for getter
    pub get_out_ref_mode: RefMode,
    pub set_in_ref_mode: RefMode,
    pub version: Option<Version>,
    pub deprecated_version: Option<Version>,
    pub bound: Option<Bound>,
}

pub fn analyze(env: &Env, props: &[library::Property], type_tid: library::TypeId,
               obj: &GObject, imports: &mut Imports, signatures: &Signatures,
               deps: &[library::TypeId]) -> Vec<Property> {
    let mut properties = Vec::new();

    for prop in props {
        let configured_properties = obj.properties.matched(&prop.name);
        if configured_properties.iter().any(|f| f.ignore) {
            continue;
        }

        if env.is_totally_deprecated(prop.deprecated_version) { continue; }

        let (getter, setter) = analyze_property(env, prop, type_tid, &configured_properties,
                                                signatures, deps);
        if getter.is_none() && setter.is_none() {
            continue;
        }

        let type_string = rust_type(env, prop.typ);
        let used_type_string = used_rust_type(env, prop.typ);
        if let Some(prop) = getter {
            if let Ok(ref s) = used_type_string {
                imports.add_used_type(s, prop.version);
            }
            if prop.conversion != PropertyConversion::Direct {
                imports.add("std::mem::transmute", prop.version);
            }
            if type_string.is_ok() && prop.default_value.is_some() {
                imports.add("glib::Value", prop.version);
                imports.add("gobject_ffi", prop.version);
            }

            properties.push(prop);
        }
        if let Some(prop) = setter {
            if let Ok(ref s) = used_type_string {
                imports.add_used_type(s, prop.version);
            }
            if type_string.is_ok() {
                imports.add("glib::Value", prop.version);
                imports.add("gobject_ffi", prop.version);
                if prop.bound.is_some() {
                    imports.add("glib::object::IsA", prop.version);
                    imports.add("Object", prop.version);
                }
            }

            properties.push(prop);
        }
    }

    properties
}

fn analyze_property(env: &Env, prop: &library::Property, type_tid: library::TypeId,
                    configured_properties: &[&config::properties::Property],
                    signatures: &Signatures, deps: &[library::TypeId]) -> (Option<Property>, Option<Property>) {
    let name = prop.name.clone();
    let type_ = env.type_(prop.typ);

    let prop_version = configured_properties.iter().filter_map(|f| f.version).min()
        .or(prop.version);
    let name_for_func = nameutil::signal_to_snake(&name);
    let var_name = nameutil::mangle_keywords(&*name_for_func).into_owned();
    let get_func_name = format!("get_property_{}", name_for_func);
    let set_func_name = format!("set_property_{}", name_for_func);
    let check_get_func_name = format!("get_{}", name_for_func);
    let check_set_func_name = format!("set_{}", name_for_func);

    let mut readable = prop.readable;
    let mut writable = prop.writable;
    if prop.construct_only { writable = false; }

    if readable {
        let (has, version) = Signature::has_by_name_and_in_deps(env, &check_get_func_name,
                                                                signatures, deps);
        if has && (env.is_totally_deprecated(version) || version <= prop_version) {
            readable = false;
        }
    }
    if writable {
        let (has, version) = Signature::has_by_name_and_in_deps(env, &check_set_func_name,
                                                                signatures, deps);
        if has && (env.is_totally_deprecated(version) || version <= prop_version) {
            writable = false;
        }
    }

    let default_value = get_type_default_value(env, prop.typ, type_);
    if default_value.is_none() && readable {
        readable = false;
        let owner_name = rust_type(env, type_tid).into_string();
        error!("No default value for getter of property `{}` for `{}`", name, owner_name);
    }
    let conversion = PropertyConversion::of(type_);
    let get_out_ref_mode = RefMode::of(&env.library, prop.typ, library::ParameterDirection::Return);
    let mut set_in_ref_mode = RefMode::of(&env.library, prop.typ, library::ParameterDirection::In);
    if set_in_ref_mode == RefMode::ByRefMut {
        set_in_ref_mode = RefMode::ByRef;
    }
    let nullable = library::Nullable(set_in_ref_mode.is_ref());
    let getter = if readable {
        Some(Property{
            name: name.clone(),
            var_name: String::new(),
            typ: prop.typ,
            is_get: true,
            func_name: get_func_name,
            nullable: nullable,
            conversion: conversion,
            default_value: default_value,
            get_out_ref_mode: get_out_ref_mode,
            set_in_ref_mode: set_in_ref_mode,
            version: prop_version,
            deprecated_version: prop.deprecated_version,
            bound: None,
        })
    } else { None };

    let setter = if writable {
        let bound = Bound::get_for_property_setter(env, &var_name, prop.typ, nullable);
        Some(Property{
            name: name.clone(),
            var_name: var_name,
            typ: prop.typ,
            is_get: false,
            func_name: set_func_name,
            nullable: nullable,
            conversion: conversion,
            default_value: None,
            get_out_ref_mode: get_out_ref_mode,
            set_in_ref_mode: set_in_ref_mode,
            version: prop_version,
            deprecated_version: prop.deprecated_version,
            bound: bound,
        })
    } else { None };

    (getter, setter)
}

pub fn get_type_default_value(env: &Env, type_tid: library::TypeId, type_: &library::Type)
                          -> Option<String> {
    use library::Type;
    use library::Fundamental;
    let some = |s: &str| Some(s.to_string());
    match *type_ {
        Type::Fundamental(fund) => {
            match fund {
                Fundamental::Boolean => some("&false"),
                Fundamental::Int => some("&0"),
                Fundamental::UInt => some("&0u32"),
                Fundamental::Utf8 => some("None::<&str>"),
                Fundamental::Float => some("&0f32"),
                Fundamental::Double => some("&0f64"),
                _ => None,
            }
        }
        Type::Bitfield(_) => some("&0u32"),
        Type::Enumeration(_) => some("&0"),
        Type::Class(..) |
        Type::Interface(..) => {
            let type_str = rust_type(env, type_tid).into_string();
            Some(format!("None::<&{}>", type_str))
        }
        _ => None,
    }
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PropertyConversion {
    Direct,
    AsI32,
    Bitflag,
}

impl PropertyConversion {
    pub fn of(type_: &library::Type) -> PropertyConversion {
        use library::Type;
        use self::PropertyConversion::*;
        match *type_ {
            Type::Bitfield(_) => Bitflag,
            Type::Enumeration(_) => AsI32,
            _ => Direct,
        }
    }
}

impl Default for PropertyConversion {
    fn default() -> Self {
        PropertyConversion::Direct
    }
}
<commit_msg>Add default values for fundamental types and Records<commit_after>use analysis::bounds::Bound;
use analysis::imports::Imports;
use analysis::ref_mode::RefMode;
use analysis::rust_type::*;
use analysis::signatures::{Signature, Signatures};
use config;
use config::gobjects::GObject;
use env::Env;
use library;
use nameutil;
use traits::*;
use version::Version;

#[derive(Debug)]
pub struct Property {
    pub name: String,
    pub var_name: String,
    pub typ: library::TypeId,
    pub is_get: bool,
    pub func_name: String,
    pub nullable: library::Nullable,
    pub conversion: PropertyConversion,
    pub default_value: Option<String>, //for getter
    pub get_out_ref_mode: RefMode,
    pub set_in_ref_mode: RefMode,
    pub version: Option<Version>,
    pub deprecated_version: Option<Version>,
    pub bound: Option<Bound>,
}

pub fn analyze(env: &Env, props: &[library::Property], type_tid: library::TypeId,
               obj: &GObject, imports: &mut Imports, signatures: &Signatures,
               deps: &[library::TypeId]) -> Vec<Property> {
    let mut properties = Vec::new();

    for prop in props {
        let configured_properties = obj.properties.matched(&prop.name);
        if configured_properties.iter().any(|f| f.ignore) {
            continue;
        }

        if env.is_totally_deprecated(prop.deprecated_version) { continue; }

        let (getter, setter) = analyze_property(env, prop, type_tid, &configured_properties,
                                                signatures, deps);
        if getter.is_none() && setter.is_none() {
            continue;
        }

        let type_string = rust_type(env, prop.typ);
        let used_type_string = used_rust_type(env, prop.typ);
        if let Some(prop) = getter {
            if let Ok(ref s) = used_type_string {
                imports.add_used_type(s, prop.version);
            }
            if prop.conversion != PropertyConversion::Direct {
                imports.add("std::mem::transmute", prop.version);
            }
            if type_string.is_ok() && prop.default_value.is_some() {
                imports.add("glib::Value", prop.version);
                imports.add("gobject_ffi", prop.version);
            }

            properties.push(prop);
        }
        if let Some(prop) = setter {
            if let Ok(ref s) = used_type_string {
                imports.add_used_type(s, prop.version);
            }
            if type_string.is_ok() {
                imports.add("glib::Value", prop.version);
                imports.add("gobject_ffi", prop.version);
                if prop.bound.is_some() {
                    imports.add("glib::object::IsA", prop.version);
                    imports.add("Object", prop.version);
                }
            }

            properties.push(prop);
        }
    }

    properties
}

fn analyze_property(env: &Env, prop: &library::Property, type_tid: library::TypeId,
                    configured_properties: &[&config::properties::Property],
                    signatures: &Signatures, deps: &[library::TypeId]) -> (Option<Property>, Option<Property>) {
    let name = prop.name.clone();
    let type_ = env.type_(prop.typ);

    let prop_version = configured_properties.iter().filter_map(|f| f.version).min()
        .or(prop.version);
    let name_for_func = nameutil::signal_to_snake(&name);
    let var_name = nameutil::mangle_keywords(&*name_for_func).into_owned();
    let get_func_name = format!("get_property_{}", name_for_func);
    let set_func_name = format!("set_property_{}", name_for_func);
    let check_get_func_name = format!("get_{}", name_for_func);
    let check_set_func_name = format!("set_{}", name_for_func);

    let mut readable = prop.readable;
    let mut writable = prop.writable;
    if prop.construct_only { writable = false; }

    if readable {
        let (has, version) = Signature::has_by_name_and_in_deps(env, &check_get_func_name,
                                                                signatures, deps);
        if has && (env.is_totally_deprecated(version) || version <= prop_version) {
            readable = false;
        }
    }
    if writable {
        let (has, version) = Signature::has_by_name_and_in_deps(env, &check_set_func_name,
                                                                signatures, deps);
        if has && (env.is_totally_deprecated(version) || version <= prop_version) {
            writable = false;
        }
    }

    let default_value = get_type_default_value(env, prop.typ, type_);
    if default_value.is_none() && readable {
        readable = false;
        let owner_name = rust_type(env, type_tid).into_string();
        error!("No default value for getter of property `{}` for `{}`", name, owner_name);
    }
    let conversion = PropertyConversion::of(type_);
    let get_out_ref_mode = RefMode::of(&env.library, prop.typ, library::ParameterDirection::Return);
    let mut set_in_ref_mode = RefMode::of(&env.library, prop.typ, library::ParameterDirection::In);
    if set_in_ref_mode == RefMode::ByRefMut {
        set_in_ref_mode = RefMode::ByRef;
    }
    let nullable = library::Nullable(set_in_ref_mode.is_ref());
    let getter = if readable {
        Some(Property{
            name: name.clone(),
            var_name: String::new(),
            typ: prop.typ,
            is_get: true,
            func_name: get_func_name,
            nullable: nullable,
            conversion: conversion,
            default_value: default_value,
            get_out_ref_mode: get_out_ref_mode,
            set_in_ref_mode: set_in_ref_mode,
            version: prop_version,
            deprecated_version: prop.deprecated_version,
            bound: None,
        })
    } else { None };

    let setter = if writable {
        let bound = Bound::get_for_property_setter(env, &var_name, prop.typ, nullable);
        Some(Property{
            name: name.clone(),
            var_name: var_name,
            typ: prop.typ,
            is_get: false,
            func_name: set_func_name,
            nullable: nullable,
            conversion: conversion,
            default_value: None,
            get_out_ref_mode: get_out_ref_mode,
            set_in_ref_mode: set_in_ref_mode,
            version: prop_version,
            deprecated_version: prop.deprecated_version,
            bound: bound,
        })
    } else { None };

    (getter, setter)
}

pub fn get_type_default_value(env: &Env, type_tid: library::TypeId, type_: &library::Type)
                          -> Option<String> {
    use library::Type;
    use library::Fundamental;
    let some = |s: &str| Some(s.to_string());
    match *type_ {
        Type::Fundamental(fund) => {
            match fund {
                Fundamental::Boolean => some("&false"),
                Fundamental::Int => some("&0"),
                Fundamental::UInt => some("&0u32"),
                Fundamental::Utf8 => some("None::<&str>"),
                Fundamental::Float => some("&0f32"),
                Fundamental::Double => some("&0f64"),
                Fundamental::Int8 => some("&0i8"),
                Fundamental::UInt8 => some("&0u8"),
                Fundamental::Int16 => some("&0i16"),
                Fundamental::UInt16 => some("&0u16"),
                Fundamental::Int32 => some("&0i32"),
                Fundamental::UInt32 => some("&0u32"),
                Fundamental::Int64 => some("&0i64"),
                Fundamental::UInt64 => some("&0u64"),
                Fundamental::Char => some("&0i8"),
                Fundamental::UChar => some("&0u8"),
                Fundamental::Size => some("&0isize"),
                Fundamental::SSize => some("&0usize"),
                Fundamental::Pointer => some("::std::ptr::null_mut()"),
                Fundamental::Type => some("&gobject_sys::G_TYPE_NONE"),
                _ => None,
            }
        }
        Type::Bitfield(_) => some("&0u32"),
        Type::Enumeration(_) => some("&0"),
        Type::Class(..) |
        Type::Record(..) |
        Type::Interface(..) => {
            let type_str = rust_type(env, type_tid).into_string();
            Some(format!("None::<&{}>", type_str))
        }
        _ => None,
    }
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PropertyConversion {
    Direct,
    AsI32,
    Bitflag,
}

impl PropertyConversion {
    pub fn of(type_: &library::Type) -> PropertyConversion {
        use library::Type;
        use self::PropertyConversion::*;
        match *type_ {
            Type::Bitfield(_) => Bitflag,
            Type::Enumeration(_) => AsI32,
            _ => Direct,
        }
    }
}

impl Default for PropertyConversion {
    fn default() -> Self {
        PropertyConversion::Direct
    }
}
<|endoftext|>


<commit_before>use webapi::event_target::{IEventTarget, EventTarget};
use webcore::unsafe_typed_array::UnsafeTypedArray;
use webcore::value::{
    Reference,
    Value,
};
use webcore::try_from::TryInto;

/// Use XMLHttpRequest (XHR) objects to interact with servers.
/// You can retrieve data from a URL without having to do a full page refresh.
/// This enables a Web page to update just part of a page without disrupting
/// what the user is doing. XMLHttpRequest is used heavily in Ajax programming.
///
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
pub struct XMLHttpRequest( Reference );

reference_boilerplate! {
    XMLHttpRequest,
    instanceof XMLHttpRequest
    convertible to EventTarget
}

/// An enum indicating the state of the `XMLHttpRequest`.
///
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState)
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum ReadyState {
    /// Client has been created. [open()](struct.XMLHttpRequest.html#method.open) not called yet.
    Unsent,
    /// [open()](struct.XMLHttpRequest.html#method.open) has been called.
    Opened,
    /// [send()](struct.XMLHttpRequest.html#method.send) has been called, and headers and [status()](struct.XMLHttpRequest.html#method.status) are available.
    HeadersReceived,
    /// Downloading; [reponse_text()](struct.XMLHttpRequest.html#method.reponse_text) holds partial data.
    Loading,
    /// The operation is complete.
    Done,
}

impl IEventTarget for XMLHttpRequest {}

impl XMLHttpRequest {
    /// Creates new `XMLHttpRequest`.
    pub fn new() -> XMLHttpRequest {
        js!( return new XMLHttpRequest(); ).try_into().unwrap()
    }

    /// Returns the current state of the request as a [ReadyState](enum.ReadyState.html).
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState)
    pub fn ready_state(&self) -> ReadyState {
        use self::ReadyState::*;
        let state: u16 = js!( return @{self}.readyState; ).try_into().unwrap();
        match state {
            0 => Unsent,
            1 => Opened,
            2 => HeadersReceived,
            3 => Loading,
            4 => Done,
            _ => unreachable!( "Unexpected value of XMLHttpRequest::readyState: {}", state )
        }
    }

    /// Returns a string that contains the response to the request as text, or None
    /// if the request was unsuccessful or has not yet been sent.
    ///
    ///[(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText)
    pub fn response_text(&self) -> Option<String> {
        let response = js!(return @{self}.responseText;);
        match response {
            Value::Null => None,
            Value::String(resp) => Some(resp),
            _ => unreachable!(),
        }
    }

    /// Returns an unsigned short with the status of the response of the request.
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/status)
    pub fn status(&self) -> u16 {
        js!(return @{self}.status;).try_into().unwrap()
    }

    /// Open connection with given method (ie GET or POST), and the url to hit
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open)
    pub fn open(&self, method: &str, url: &str) {
        js! {
            @{self}.open(@{method}, @{url}, true);
        };
    }

    /// Send request on an open connection with no data
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send)
    pub fn send(&self) {
        js! {
            @{self}.send();
        };
    }

    /// Send request on an open connection with string body
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send)
    pub fn send_with_string(&self, body: &str) {
        js! {
            @{self}.send(@{body});
        };
    }

    /// Send request on an open connection with a byte array body
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send)
    pub fn send_with_bytes(&self, body: &[u8]) {
        js! {
            @{self}.send(@{UnsafeTypedArray(body)});
        };
    }

    /// Aborts the request if it has already been sent.
    /// When a request is aborted, its [ready_state](struct.XMLHttpRequest.html#method.ready_state) is changed to [Done](enum.ReadyState.html#variant.Done)
    /// and the [status](struct.XMLHttpRequest.html#method.status) code is set to
    /// [Unsent](enum.ReadyState.html#variant.Unsent).
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/abort)
    pub fn abort(&self) {
        js! {
            @{self}.abort();
        };
    }
}
<commit_msg>Implement set and get headers for XMLHttpRequest (#66)<commit_after>use webapi::event_target::{IEventTarget, EventTarget};
use webcore::unsafe_typed_array::UnsafeTypedArray;
use webcore::value::{
    Reference,
    Value,
};
use webcore::try_from::TryInto;

/// Use XMLHttpRequest (XHR) objects to interact with servers.
/// You can retrieve data from a URL without having to do a full page refresh.
/// This enables a Web page to update just part of a page without disrupting
/// what the user is doing. XMLHttpRequest is used heavily in Ajax programming.
///
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
pub struct XMLHttpRequest( Reference );

reference_boilerplate! {
    XMLHttpRequest,
    instanceof XMLHttpRequest
    convertible to EventTarget
}

/// An enum indicating the state of the `XMLHttpRequest`.
///
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState)
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum ReadyState {
    /// Client has been created. [open()](struct.XMLHttpRequest.html#method.open) not called yet.
    Unsent,
    /// [open()](struct.XMLHttpRequest.html#method.open) has been called.
    Opened,
    /// [send()](struct.XMLHttpRequest.html#method.send) has been called, and headers and [status()](struct.XMLHttpRequest.html#method.status) are available.
    HeadersReceived,
    /// Downloading; [reponse_text()](struct.XMLHttpRequest.html#method.reponse_text) holds partial data.
    Loading,
    /// The operation is complete.
    Done,
}

impl IEventTarget for XMLHttpRequest {}

impl XMLHttpRequest {
    /// Creates new `XMLHttpRequest`.
    pub fn new() -> XMLHttpRequest {
        js!( return new XMLHttpRequest(); ).try_into().unwrap()
    }

    /// Returns the current state of the request as a [ReadyState](enum.ReadyState.html).
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState)
    pub fn ready_state(&self) -> ReadyState {
        use self::ReadyState::*;
        let state: u16 = js!( return @{self}.readyState; ).try_into().unwrap();
        match state {
            0 => Unsent,
            1 => Opened,
            2 => HeadersReceived,
            3 => Loading,
            4 => Done,
            _ => unreachable!( "Unexpected value of XMLHttpRequest::readyState: {}", state )
        }
    }

    /// Returns a string that contains the response to the request as text, or None
    /// if the request was unsuccessful or has not yet been sent.
    ///
    ///[(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText)
    pub fn response_text(&self) -> Option<String> {
        let response = js!(return @{self}.responseText;);
        match response {
            Value::Null => None,
            Value::String(resp) => Some(resp),
            _ => unreachable!(),
        }
    }

    /// Returns an unsigned short with the status of the response of the request.
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/status)
    pub fn status(&self) -> u16 {
        js!(return @{self}.status;).try_into().unwrap()
    }

    /// Open connection with given method (ie GET or POST), and the url to hit.
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open)
    pub fn open(&self, method: &str, url: &str) {
        js! { @(no_return)
            @{self}.open(@{method}, @{url}, true);
        };
    }

    /// Returns the string containing the text of the specified header. If there
    /// are multiple response headers with the same name, then their values are
    /// returned as a single concatenated string.
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/getResponseHeader)
    pub fn get_response_header(&self, header: &str) -> Option<String> {
        let header = js!( return @{self}.getResponseHeader(@{header}); );
        match header {
            Value::Null => None,
            Value::String(text) => Some(text),
            _ => unreachable!(),
        }
    }

    /// Sets the value of an HTTP request header. Must be called after `open()`,
    /// but before `send()`. If this method is called several times with the same
    /// header, the values are merged into one single request header.
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader)
    pub fn set_request_header(&self, header: &str, value: &str) {
        // TODO: Handle InvalidStateError and SyntaxError exceptions.
        // https://xhr.spec.whatwg.org/#the-setrequestheader()-method
        js! { @(no_return)
            @{self}.setRequestHeader(@{header}, @{value});
        };
    }

    /// Send request on an open connection with no data
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send)
    pub fn send(&self) {
        js! { @(no_return)
            @{self}.send();
        };
    }

    /// Send request on an open connection with string body
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send)
    pub fn send_with_string(&self, body: &str) {
        js! { @(no_return)
            @{self}.send(@{body});
        };
    }

    /// Send request on an open connection with a byte array body
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send)
    pub fn send_with_bytes(&self, body: &[u8]) {
        js! { @(no_return)
            @{self}.send(@{UnsafeTypedArray(body)});
        };
    }

    /// Aborts the request if it has already been sent.
    /// When a request is aborted, its [ready_state](struct.XMLHttpRequest.html#method.ready_state) is changed to [Done](enum.ReadyState.html#variant.Done)
    /// and the [status](struct.XMLHttpRequest.html#method.status) code is set to
    /// [Unsent](enum.ReadyState.html#variant.Unsent).
    ///
    /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/abort)
    pub fn abort(&self) {
        js! { @(no_return)
            @{self}.abort();
        };
    }
}
<|endoftext|>


<commit_before>fn main()
{
    let x = true;

    let y:bool = false;

    let xx = 'x';

    //Unlike some other languages, this means that Rust’s char is not a single byte, but four.
    let two_hearts = '💕';

    let a = 10; // x has type i32

    let b = 1.0; // y has type f64

}
<commit_msg>examples of arrays added<commit_after>fn main()
{
    let x = true;

    let y:bool = false;

    let xx = 'x';

    //Unlike some other languages, this means that Rust’s char is not a single byte, but four.
    let two_hearts = '💕';

    let a = 10; // x has type i32

    let b = 1.0; // y has type f64

    // arrays
    let a = [1, 2, 3]; // a: [i32; 3]
    let mut m = [1, 2, 3]; // m: [i32; 3]

    let a1 = [0; 20]; // a: [i32; 20]

    println!("a1 has {} elements", a1.len());

    let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3]

    println!("The second name is: {}", names[1]);

    //slices
    let middle = &a1[1..4];

}
<|endoftext|>


<commit_before>use super::{
    device::Device,
    devices_manager::DevicesManager,
    integration::{Integration, IntegrationId},
};
use crate::integrations::dummy::Dummy;
use std::{
    collections::HashMap,
    error::Error,
    sync::{Arc, Mutex},
};

pub type DeviceId = String;

pub type ThreadsafeIntegration = Box<dyn Integration + Send + Sync>;

pub struct ManagedIntegration {
    pub integration: ThreadsafeIntegration,
    pub devices: HashMap<DeviceId, Device>,
}

pub type IntegrationsTree = HashMap<IntegrationId, ManagedIntegration>;
pub type Integrations = Arc<Mutex<IntegrationsTree>>;

pub struct IntegrationsManager {
    integrations: Integrations,
    devices_manager: DevicesManager,
}

pub type SharedIntegrationsManager = Arc<Mutex<IntegrationsManager>>;

impl IntegrationsManager {
    pub fn new() -> Self {
        let integrations: Integrations = Arc::new(Mutex::new(HashMap::new()));
        let devices_manager = DevicesManager::new(integrations.clone());

        IntegrationsManager {
            integrations,
            devices_manager,
        }
    }

    pub fn load_integration(
        &self,
        module_name: &String,
        integration_id: &IntegrationId,
        shared_integrations_manager: SharedIntegrationsManager,
    ) -> Result<(), String> {
        println!("loading integration with module_name {}", module_name);

        let integration = load_integration(
            module_name,
            integration_id,
            &"".into(),
            shared_integrations_manager,
        )?;

        let devices = HashMap::new();
        let managed = ManagedIntegration {
            integration,
            devices,
        };

        {
            let mut integrations = self.integrations.lock().unwrap();
            integrations.insert(integration_id.clone(), managed);
        }

        Ok(())
    }

    pub async fn run_register_pass(&self) -> Result<(), Box<dyn Error>> {
        let integrations = self.integrations.lock().unwrap();

        for (_integration_id, managed) in integrations.iter() {
            managed.integration.register().await?;
        }

        Ok(())
    }

    pub async fn run_start_pass(&self) -> Result<(), Box<dyn Error>> {
        let integrations = self.integrations.lock().unwrap();

        for (_integration_id, managed) in integrations.iter() {
            managed.integration.start().await?;
        }

        Ok(())
    }
}

fn load_integration(
    module_name: &String,
    id: &IntegrationId,
    config: &String,
    integrations_manager: SharedIntegrationsManager,
) -> Result<ThreadsafeIntegration, String> {
    match module_name.as_str() {
        "dummy" => Ok(Box::new(Dummy::new(id, config, integrations_manager))),
        _ => Err(format!("Unknown module name {}!", module_name)),
    }
}
<commit_msg>add comment on dynamic plugins<commit_after>use super::{
    device::Device,
    devices_manager::DevicesManager,
    integration::{Integration, IntegrationId},
};
use crate::integrations::dummy::Dummy;
use std::{
    collections::HashMap,
    error::Error,
    sync::{Arc, Mutex},
};

pub type DeviceId = String;

pub type ThreadsafeIntegration = Box<dyn Integration + Send + Sync>;

pub struct ManagedIntegration {
    pub integration: ThreadsafeIntegration,
    pub devices: HashMap<DeviceId, Device>,
}

pub type IntegrationsTree = HashMap<IntegrationId, ManagedIntegration>;
pub type Integrations = Arc<Mutex<IntegrationsTree>>;

pub struct IntegrationsManager {
    integrations: Integrations,
    devices_manager: DevicesManager,
}

pub type SharedIntegrationsManager = Arc<Mutex<IntegrationsManager>>;

impl IntegrationsManager {
    pub fn new() -> Self {
        let integrations: Integrations = Arc::new(Mutex::new(HashMap::new()));
        let devices_manager = DevicesManager::new(integrations.clone());

        IntegrationsManager {
            integrations,
            devices_manager,
        }
    }

    pub fn load_integration(
        &self,
        module_name: &String,
        integration_id: &IntegrationId,
        shared_integrations_manager: SharedIntegrationsManager,
    ) -> Result<(), String> {
        println!("loading integration with module_name {}", module_name);

        let integration = load_integration(
            module_name,
            integration_id,
            &"".into(),
            shared_integrations_manager,
        )?;

        let devices = HashMap::new();
        let managed = ManagedIntegration {
            integration,
            devices,
        };

        {
            let mut integrations = self.integrations.lock().unwrap();
            integrations.insert(integration_id.clone(), managed);
        }

        Ok(())
    }

    pub async fn run_register_pass(&self) -> Result<(), Box<dyn Error>> {
        let integrations = self.integrations.lock().unwrap();

        for (_integration_id, managed) in integrations.iter() {
            managed.integration.register().await?;
        }

        Ok(())
    }

    pub async fn run_start_pass(&self) -> Result<(), Box<dyn Error>> {
        let integrations = self.integrations.lock().unwrap();

        for (_integration_id, managed) in integrations.iter() {
            managed.integration.start().await?;
        }

        Ok(())
    }
}

// integrations will perhaps one day be loaded dynamically:
// https://michael-f-bryan.github.io/rust-ffi-guide/dynamic_loading.html
fn load_integration(
    module_name: &String,
    id: &IntegrationId,
    config: &String,
    integrations_manager: SharedIntegrationsManager,
) -> Result<ThreadsafeIntegration, String> {
    match module_name.as_str() {
        "dummy" => Ok(Box::new(Dummy::new(id, config, integrations_manager))),
        _ => Err(format!("Unknown module name {}!", module_name)),
    }
}
<|endoftext|>


<commit_before>/// Comparisons against SCCS.
///
/// The weave algorithm used comes from the the SCCS program.  This can be installed on most Linux
/// distros by installing the package "cssc".
extern crate env_logger;
#[macro_use]
extern crate log;
extern crate rand;
extern crate tempdir;
extern crate weave;

use rand::{rngs::StdRng, Rng, SeedableRng};
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::env;
use std::fs::{remove_file, File};
use std::io::{BufRead, BufReader, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus, Stdio};
use std::rc::Rc;
use tempdir::TempDir;
use weave::{DeltaWriter, Entry, NewWeave, Parser, PullParser, Result, SimpleNaming, Sink};

/// Number of iterations to make.  Note that the default check is greater than O(n^2) so the test
/// will run very long if this is increased too much.
const ITERATION_COUNT: usize = 100;

/// Number of lines in the files.  Affects how convoluted the diffs are.
const FILE_SIZE: usize = 100;

/// Set to true to verify all previous deltas, not just the most recent.
const VERIFY_ALL_DELTAS: bool = true;

#[test]
fn sccs() {
    let _ = env_logger::init();

    // Normally, detect the SCCS command being present, and use it for additional tests.  It can be
    // ignored by setting NO_SCCS=1 in the environment.
    let use_sccs = has_sccs() && env::var("NO_SCCS").is_err();

    let tdir = TempDir::new("sccstest").unwrap();
    let mut gen = Gen::new(tdir.path(), use_sccs).unwrap();

    // For debugging, this will cause the directory to not be removed.
    if env::var("KEEPTEMP").is_ok() {
        tdir.into_path();
    }

    gen.new_sccs();
    gen.new_weave();
    gen.next_delta();
    gen.weave_check();

    for i in 0..ITERATION_COUNT {
        gen.shuffle();
        gen.add_sccs_delta();
        gen.add_weave_delta(i + 1);
        gen.next_delta();

        // Checking with sccs is very slow.  Do we want to do it?
        // gen.sccs_check();
        gen.weave_check();
    }
}

/// Determine if we have the sccs command available.  If not, show an error, and return false.
fn has_sccs() -> bool {
    match Command::new("sccs").arg("-V").output() {
        Ok(_) => true,
        Err(_) => {
            error!("'sccs' not found in path, skipping some tests, install 'cssc' to fix");
            false
        }
    }
}

/// Gen synthesizes a series of deltas, and can add them using SCCS to make a weave file, and later
/// to this weave implementation to compare the results.
struct Gen {
    /// The directory to write the files into.
    tdir: PathBuf,

    /// The name of the plain file related to it.
    sccs_plain: PathBuf,

    /// The current lines.
    nums: Vec<usize>,

    /// Each delta.  Sccs numbers the deltas from 1, so these are off by one.
    deltas: Vec<Vec<usize>>,

    /// A Rng for generating the shuffles.
    rand: StdRng,

    /// Is sccs enabled.
    use_sccs: bool,
}

impl Gen {
    fn new<P: AsRef<Path>>(tdir: P, use_sccs: bool) -> Result<Gen> {
        let tdir = tdir.as_ref();
        let mut seed: [u8; 32] = [0; 32];
        seed[0] = 1;
        seed[0] = 2;
        seed[0] = 3;
        seed[0] = 4;
        Ok(Gen {
            tdir: tdir.to_owned(),
            sccs_plain: tdir.join("tfile"),
            nums: (1..FILE_SIZE + 1).collect(),
            rand: SeedableRng::from_seed(seed),
            deltas: vec![],
            use_sccs: use_sccs,
        })
    }

    /// Perform a somewhat random modification of the data.  Choose some range of the numbers and
    /// reverse them.
    fn shuffle(&mut self) {
        let a = self.rand.gen_range(0, self.nums.len());
        let b = self.rand.gen_range(0, self.nums.len());

        let (a, b) = if a <= b { (a, b) } else { (b, a) };
        self.nums[a..b].reverse();
    }

    fn next_delta(&mut self) {
        self.deltas.push(self.nums.clone())
    }

    /// Write to a new sccs file, resulting in delta 1.
    fn new_sccs(&mut self) {
        if !self.use_sccs {
            return;
        }

        self.emit_to(&self.sccs_plain);
        Command::new("sccs")
            .args(&["admin", "-itfile", "-n", "s.tfile"])
            .current_dir(&self.tdir)
            .status()
            .expect("Unable to run sccs admin")
            .expect_success("Sccs command returned error");
        remove_file(&self.sccs_plain).expect("Unable to remove data file");
    }

    /// Add a new delta to the sccs file.
    fn add_sccs_delta(&mut self) {
        if !self.use_sccs {
            return;
        }

        Command::new("sccs")
            .args(&["get", "-e", "s.tfile"])
            .current_dir(&self.tdir)
            .stderr(Stdio::null())
            .stdout(Stdio::null())
            .status()
            .expect("Unable to run sccs get")
            .expect_success("sccs get failed");
        self.emit_to(&self.sccs_plain);
        Command::new("sccs")
            .args(&["delta", "-yMessage", "s.tfile"])
            .current_dir(&self.tdir)
            .stderr(Stdio::null())
            .stdout(Stdio::null())
            .status()
            .expect("Unable to run sccs delta")
            .expect_success("sccs delta failed");
    }

    /// Emit the current numbers to the given name (in the temp dir).
    fn emit_to<P: AsRef<Path>>(&self, name: P) {
        let mut fd = File::create(self.tdir.join(name)).unwrap();
        for i in &self.nums {
            writeln!(&mut fd, "{}", i).unwrap();
        }
    }

    /// Check the output of "sccs get".  This is more of a sanity check.
    #[allow(dead_code)]
    fn sccs_check(&self) {
        for (i, del) in self.deltas.iter().enumerate() {
            self.sccs_check_one(i, del);
        }
    }

    #[allow(dead_code)]
    fn sccs_check_one(&self, num: usize, data: &[usize]) {
        if !self.use_sccs {
            return;
        }

        let out = Command::new("sccs")
            .args(&["get", &format!("-r1.{}", num + 1), "-p", "s.tfile"])
            .current_dir(&self.tdir)
            .output()
            .expect("Unable to run sccs get");
        out.status.expect_success("Error running sccs get");
        let mut onums: Vec<usize> = vec![];
        for line in BufReader::new(&out.stdout[..]).lines() {
            let line = line.unwrap();
            onums.push(line.as_str().parse::<usize>().unwrap());
        }

        assert_eq!(data, &onums[..]);
    }

    /// Check that weave decodes all of the sccs files properly.
    fn weave_check(&self) {
        if VERIFY_ALL_DELTAS {
            // Verify all of the previous deltas.
            for (i, del) in self.deltas.iter().enumerate() {
                self.weave_sccs_check_one(i, del);
                self.weave_check_one(i, del);
                self.weave_check_pull(i, del);
            }
        } else {
            // This only checks the last delta for each one.  It will miss any bugs that result in
            // earlier deltas being unreadable.
            let del = self.deltas.iter().last().unwrap();
            self.weave_sccs_check_one(self.deltas.len() - 1, del);
            self.weave_check_one(self.deltas.len() - 1, del);
            self.weave_check_pull(self.deltas.len() - 1, del);
        }
    }

    fn weave_sccs_check_one(&self, num: usize, data: &[usize]) {
        if !self.use_sccs {
            return;
        }

        let fd = File::open(self.tdir.join("s.tfile")).unwrap();
        let lines = BufReader::new(fd).lines();
        let dsink = Rc::new(RefCell::new(DeltaSink { nums: vec![] }));
        {
            let mut parser = Parser::new_raw(lines, dsink.clone(), num + 1).unwrap();
            match parser.parse_to(0) {
                Ok(0) => (),
                Ok(_) => panic!("Unexpected stop of parser"),
                Err(e) => panic!("Parser error: {:?}", e),
            }
        }

        assert_eq!(data, &dsink.borrow().nums[..]);
    }

    fn weave_check_one(&self, num: usize, data: &[usize]) {
        let fd = File::open(self.tdir.join("sample.weave")).unwrap();
        let lines = BufReader::new(fd).lines();
        let dsink = Rc::new(RefCell::new(DeltaSink { nums: vec![] }));
        {
            let mut parser = Parser::new_raw(lines, dsink.clone(), num + 1).unwrap();
            match parser.parse_to(0) {
                Ok(0) => (),
                Ok(_) => panic!("Unexpected stop of parser"),
                Err(e) => panic!("Parser error: {:?}", e),
            }
        }

        assert_eq!(data, &dsink.borrow().nums[..]);
    }

    fn weave_check_pull(&self, num: usize, data: &[usize]) {
        let fd = File::open(self.tdir.join("sample.weave")).unwrap();
        let lines = BufReader::new(fd).lines();
        let mut nums = vec![];
        for line in PullParser::new_raw(lines, num + 1).unwrap() {
            let line = line.unwrap();
            match line {
                Entry::Plain { keep, text } if keep => {
                    nums.push(text.parse::<usize>().unwrap());
                }
                _ => (),
            }
        }

        assert_eq!(data, &nums[..]);
    }

    fn new_weave(&mut self) {
        let mut tags = BTreeMap::new();
        tags.insert("name", "initial");
        let nc = SimpleNaming::new(&self.tdir, "sample", "weave", false);
        let mut nw = NewWeave::new(&nc, tags.into_iter()).unwrap();
        for i in &self.nums {
            writeln!(&mut nw, "{}", i).unwrap();
        }
        nw.close().unwrap();
    }

    fn add_weave_delta(&mut self, base: usize) {
        let name_value = format!("{}", base + 1);
        let mut tags = BTreeMap::new();
        tags.insert("name", name_value.as_str());
        let nc = SimpleNaming::new(&self.tdir, "sample", "weave", false);
        let mut delta = DeltaWriter::new(&nc, tags.into_iter(), base).unwrap();
        for i in &self.nums {
            writeln!(&mut delta, "{}", i).unwrap();
        }
        delta.close().unwrap();
    }
}

/// A Weave Sink that just collects the numbers in the given delta.
struct DeltaSink {
    nums: Vec<usize>,
}

impl Sink for DeltaSink {
    fn plain(&mut self, text: &str, keep: bool) -> Result<()> {
        if !keep {
            return Ok(());
        }

        self.nums.push(text.parse::<usize>()?);
        Ok(())
    }
}

/// A small utility to make asserting success easier.
trait Successful {
    fn expect_success(&self, msg: &str);
}

impl Successful for ExitStatus {
    fn expect_success(&self, msg: &str) {
        if !self.success() {
            panic!(msg.to_string());
        }
    }
}
<commit_msg>weave: Fix panic for recent rustc<commit_after>/// Comparisons against SCCS.
///
/// The weave algorithm used comes from the the SCCS program.  This can be installed on most Linux
/// distros by installing the package "cssc".
extern crate env_logger;
#[macro_use]
extern crate log;
extern crate rand;
extern crate tempdir;
extern crate weave;

use rand::{rngs::StdRng, Rng, SeedableRng};
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::env;
use std::fs::{remove_file, File};
use std::io::{BufRead, BufReader, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus, Stdio};
use std::rc::Rc;
use tempdir::TempDir;
use weave::{DeltaWriter, Entry, NewWeave, Parser, PullParser, Result, SimpleNaming, Sink};

/// Number of iterations to make.  Note that the default check is greater than O(n^2) so the test
/// will run very long if this is increased too much.
const ITERATION_COUNT: usize = 100;

/// Number of lines in the files.  Affects how convoluted the diffs are.
const FILE_SIZE: usize = 100;

/// Set to true to verify all previous deltas, not just the most recent.
const VERIFY_ALL_DELTAS: bool = true;

#[test]
fn sccs() {
    let _ = env_logger::init();

    // Normally, detect the SCCS command being present, and use it for additional tests.  It can be
    // ignored by setting NO_SCCS=1 in the environment.
    let use_sccs = has_sccs() && env::var("NO_SCCS").is_err();

    let tdir = TempDir::new("sccstest").unwrap();
    let mut gen = Gen::new(tdir.path(), use_sccs).unwrap();

    // For debugging, this will cause the directory to not be removed.
    if env::var("KEEPTEMP").is_ok() {
        tdir.into_path();
    }

    gen.new_sccs();
    gen.new_weave();
    gen.next_delta();
    gen.weave_check();

    for i in 0..ITERATION_COUNT {
        gen.shuffle();
        gen.add_sccs_delta();
        gen.add_weave_delta(i + 1);
        gen.next_delta();

        // Checking with sccs is very slow.  Do we want to do it?
        // gen.sccs_check();
        gen.weave_check();
    }
}

/// Determine if we have the sccs command available.  If not, show an error, and return false.
fn has_sccs() -> bool {
    match Command::new("sccs").arg("-V").output() {
        Ok(_) => true,
        Err(_) => {
            error!("'sccs' not found in path, skipping some tests, install 'cssc' to fix");
            false
        }
    }
}

/// Gen synthesizes a series of deltas, and can add them using SCCS to make a weave file, and later
/// to this weave implementation to compare the results.
struct Gen {
    /// The directory to write the files into.
    tdir: PathBuf,

    /// The name of the plain file related to it.
    sccs_plain: PathBuf,

    /// The current lines.
    nums: Vec<usize>,

    /// Each delta.  Sccs numbers the deltas from 1, so these are off by one.
    deltas: Vec<Vec<usize>>,

    /// A Rng for generating the shuffles.
    rand: StdRng,

    /// Is sccs enabled.
    use_sccs: bool,
}

impl Gen {
    fn new<P: AsRef<Path>>(tdir: P, use_sccs: bool) -> Result<Gen> {
        let tdir = tdir.as_ref();
        let mut seed: [u8; 32] = [0; 32];
        seed[0] = 1;
        seed[0] = 2;
        seed[0] = 3;
        seed[0] = 4;
        Ok(Gen {
            tdir: tdir.to_owned(),
            sccs_plain: tdir.join("tfile"),
            nums: (1..FILE_SIZE + 1).collect(),
            rand: SeedableRng::from_seed(seed),
            deltas: vec![],
            use_sccs: use_sccs,
        })
    }

    /// Perform a somewhat random modification of the data.  Choose some range of the numbers and
    /// reverse them.
    fn shuffle(&mut self) {
        let a = self.rand.gen_range(0, self.nums.len());
        let b = self.rand.gen_range(0, self.nums.len());

        let (a, b) = if a <= b { (a, b) } else { (b, a) };
        self.nums[a..b].reverse();
    }

    fn next_delta(&mut self) {
        self.deltas.push(self.nums.clone())
    }

    /// Write to a new sccs file, resulting in delta 1.
    fn new_sccs(&mut self) {
        if !self.use_sccs {
            return;
        }

        self.emit_to(&self.sccs_plain);
        Command::new("sccs")
            .args(&["admin", "-itfile", "-n", "s.tfile"])
            .current_dir(&self.tdir)
            .status()
            .expect("Unable to run sccs admin")
            .expect_success("Sccs command returned error");
        remove_file(&self.sccs_plain).expect("Unable to remove data file");
    }

    /// Add a new delta to the sccs file.
    fn add_sccs_delta(&mut self) {
        if !self.use_sccs {
            return;
        }

        Command::new("sccs")
            .args(&["get", "-e", "s.tfile"])
            .current_dir(&self.tdir)
            .stderr(Stdio::null())
            .stdout(Stdio::null())
            .status()
            .expect("Unable to run sccs get")
            .expect_success("sccs get failed");
        self.emit_to(&self.sccs_plain);
        Command::new("sccs")
            .args(&["delta", "-yMessage", "s.tfile"])
            .current_dir(&self.tdir)
            .stderr(Stdio::null())
            .stdout(Stdio::null())
            .status()
            .expect("Unable to run sccs delta")
            .expect_success("sccs delta failed");
    }

    /// Emit the current numbers to the given name (in the temp dir).
    fn emit_to<P: AsRef<Path>>(&self, name: P) {
        let mut fd = File::create(self.tdir.join(name)).unwrap();
        for i in &self.nums {
            writeln!(&mut fd, "{}", i).unwrap();
        }
    }

    /// Check the output of "sccs get".  This is more of a sanity check.
    #[allow(dead_code)]
    fn sccs_check(&self) {
        for (i, del) in self.deltas.iter().enumerate() {
            self.sccs_check_one(i, del);
        }
    }

    #[allow(dead_code)]
    fn sccs_check_one(&self, num: usize, data: &[usize]) {
        if !self.use_sccs {
            return;
        }

        let out = Command::new("sccs")
            .args(&["get", &format!("-r1.{}", num + 1), "-p", "s.tfile"])
            .current_dir(&self.tdir)
            .output()
            .expect("Unable to run sccs get");
        out.status.expect_success("Error running sccs get");
        let mut onums: Vec<usize> = vec![];
        for line in BufReader::new(&out.stdout[..]).lines() {
            let line = line.unwrap();
            onums.push(line.as_str().parse::<usize>().unwrap());
        }

        assert_eq!(data, &onums[..]);
    }

    /// Check that weave decodes all of the sccs files properly.
    fn weave_check(&self) {
        if VERIFY_ALL_DELTAS {
            // Verify all of the previous deltas.
            for (i, del) in self.deltas.iter().enumerate() {
                self.weave_sccs_check_one(i, del);
                self.weave_check_one(i, del);
                self.weave_check_pull(i, del);
            }
        } else {
            // This only checks the last delta for each one.  It will miss any bugs that result in
            // earlier deltas being unreadable.
            let del = self.deltas.iter().last().unwrap();
            self.weave_sccs_check_one(self.deltas.len() - 1, del);
            self.weave_check_one(self.deltas.len() - 1, del);
            self.weave_check_pull(self.deltas.len() - 1, del);
        }
    }

    fn weave_sccs_check_one(&self, num: usize, data: &[usize]) {
        if !self.use_sccs {
            return;
        }

        let fd = File::open(self.tdir.join("s.tfile")).unwrap();
        let lines = BufReader::new(fd).lines();
        let dsink = Rc::new(RefCell::new(DeltaSink { nums: vec![] }));
        {
            let mut parser = Parser::new_raw(lines, dsink.clone(), num + 1).unwrap();
            match parser.parse_to(0) {
                Ok(0) => (),
                Ok(_) => panic!("Unexpected stop of parser"),
                Err(e) => panic!("Parser error: {:?}", e),
            }
        }

        assert_eq!(data, &dsink.borrow().nums[..]);
    }

    fn weave_check_one(&self, num: usize, data: &[usize]) {
        let fd = File::open(self.tdir.join("sample.weave")).unwrap();
        let lines = BufReader::new(fd).lines();
        let dsink = Rc::new(RefCell::new(DeltaSink { nums: vec![] }));
        {
            let mut parser = Parser::new_raw(lines, dsink.clone(), num + 1).unwrap();
            match parser.parse_to(0) {
                Ok(0) => (),
                Ok(_) => panic!("Unexpected stop of parser"),
                Err(e) => panic!("Parser error: {:?}", e),
            }
        }

        assert_eq!(data, &dsink.borrow().nums[..]);
    }

    fn weave_check_pull(&self, num: usize, data: &[usize]) {
        let fd = File::open(self.tdir.join("sample.weave")).unwrap();
        let lines = BufReader::new(fd).lines();
        let mut nums = vec![];
        for line in PullParser::new_raw(lines, num + 1).unwrap() {
            let line = line.unwrap();
            match line {
                Entry::Plain { keep, text } if keep => {
                    nums.push(text.parse::<usize>().unwrap());
                }
                _ => (),
            }
        }

        assert_eq!(data, &nums[..]);
    }

    fn new_weave(&mut self) {
        let mut tags = BTreeMap::new();
        tags.insert("name", "initial");
        let nc = SimpleNaming::new(&self.tdir, "sample", "weave", false);
        let mut nw = NewWeave::new(&nc, tags.into_iter()).unwrap();
        for i in &self.nums {
            writeln!(&mut nw, "{}", i).unwrap();
        }
        nw.close().unwrap();
    }

    fn add_weave_delta(&mut self, base: usize) {
        let name_value = format!("{}", base + 1);
        let mut tags = BTreeMap::new();
        tags.insert("name", name_value.as_str());
        let nc = SimpleNaming::new(&self.tdir, "sample", "weave", false);
        let mut delta = DeltaWriter::new(&nc, tags.into_iter(), base).unwrap();
        for i in &self.nums {
            writeln!(&mut delta, "{}", i).unwrap();
        }
        delta.close().unwrap();
    }
}

/// A Weave Sink that just collects the numbers in the given delta.
struct DeltaSink {
    nums: Vec<usize>,
}

impl Sink for DeltaSink {
    fn plain(&mut self, text: &str, keep: bool) -> Result<()> {
        if !keep {
            return Ok(());
        }

        self.nums.push(text.parse::<usize>()?);
        Ok(())
    }
}

/// A small utility to make asserting success easier.
trait Successful {
    fn expect_success(&self, msg: &str);
}

impl Successful for ExitStatus {
    fn expect_success(&self, msg: &str) {
        if !self.success() {
            panic!("{}", msg.to_string());
        }
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(clippy)]

#[deny(zero_width_space)]
fn zero() {
    print!("Here >< is a ZWS, and another");
               //~^ ERROR zero-width space detected
}

#[deny(unicode_not_nfc)]
fn canon() {
    print!("̀àh?"); //~ERROR non-nfc unicode sequence detected
}

#[deny(non_ascii_literal)]
fn uni() {
    print!("Üben!"); //~ERROR literal non-ASCII character detected
}

fn main() {
    zero();
    uni();
    canon();
}
<commit_msg>Add false positive checks to unicode test<commit_after>#![feature(plugin)]
#![plugin(clippy)]

#[deny(zero_width_space)]
fn zero() {
    print!("Here >< is a ZWS, and another");
               //~^ ERROR zero-width space detected
    print!("This\u{200B}is\u{200B}fine");
}

#[deny(unicode_not_nfc)]
fn canon() {
    print!("̀àh?"); //~ERROR non-nfc unicode sequence detected
    print!("a\u{0300}h?"); // also okay
}

#[deny(non_ascii_literal)]
fn uni() {
    print!("Üben!"); //~ERROR literal non-ASCII character detected
    print!("\u{DC}ben!"); // this is okay
}

fn main() {
    zero();
    uni();
    canon();
}
<|endoftext|>