<commit_before>use std::f32;

use cgmath;
pub use cgmath::prelude::*;
pub use cgmath::{vec3, vec4};

use num_traits::clamp;

use collision;

pub type Vector2 = cgmath::Vector2<f32>;
pub type Vector3 = cgmath::Vector3<f32>;
pub type Vector4 = cgmath::Vector4<f32>;

pub type Point3 = cgmath::Point3<f32>;

pub type Matrix4 = cgmath::Matrix4<f32>;
pub type Quaternion = cgmath::Quaternion<f32>;

pub type Aabb3 = collision::Aabb3<f32>;

// A point's spherical coordinates, inspired by ThreeJS version
pub struct Spherical {
    pub radius: f32,
    pub phi: f32,
    pub theta: f32,
}

impl Default for Spherical {
    fn default() -> Self {
        Spherical { radius: 1.0, phi: 0.0, theta: 0.0 }
    }
}

impl Spherical {
    pub fn from_vec3(vec3: Vector3) -> Self {
        let radius = vec3.magnitude();
        let (theta, phi) = if radius == 0.0 {
            (0.0, 0.0)
        } else {
            (
                vec3.x.atan2(vec3.z), // equator angle around y-up axis
                clamp(vec3.y / radius, -1.0, 1.0).acos() // polar angle
            )
        };
        Self {
            radius,
            theta,
            phi
        }
    }

    pub fn to_vec3(&self) -> Vector3 {
        let sin_phi_radius = self.phi.sin() * self.radius;
        let x = sin_phi_radius * self.theta.sin();
        let y = self.phi.cos() * self.radius;
        let z = sin_phi_radius * self.theta.cos();
        vec3(x, y, z)
    }
}

use std::num::ParseFloatError;
pub fn parse_vec3(s: &str) -> Result<Vector3, ParseFloatError> {
    let coords: Vec<&str> = s.split(',').collect();
    coords.len() != 3 && panic!("Failed to parse Vector3 ({})", s);
    let x = coords[0].parse::<f32>()?;
    let y = coords[1].parse::<f32>()?;
    let z = coords[2].parse::<f32>()?;

    Ok(vec3(x, y, z))
}
<commit_msg>Use assert!(...) instead of an "unused" boolean expression<commit_after>use std::f32;

use cgmath;
pub use cgmath::prelude::*;
pub use cgmath::{vec3, vec4};

use num_traits::clamp;

use collision;

pub type Vector2 = cgmath::Vector2<f32>;
pub type Vector3 = cgmath::Vector3<f32>;
pub type Vector4 = cgmath::Vector4<f32>;

pub type Point3 = cgmath::Point3<f32>;

pub type Matrix4 = cgmath::Matrix4<f32>;
pub type Quaternion = cgmath::Quaternion<f32>;

pub type Aabb3 = collision::Aabb3<f32>;

// A point's spherical coordinates, inspired by ThreeJS version
pub struct Spherical {
    pub radius: f32,
    pub phi: f32,
    pub theta: f32,
}

impl Default for Spherical {
    fn default() -> Self {
        Spherical { radius: 1.0, phi: 0.0, theta: 0.0 }
    }
}

impl Spherical {
    pub fn from_vec3(vec3: Vector3) -> Self {
        let radius = vec3.magnitude();
        let (theta, phi) = if radius == 0.0 {
            (0.0, 0.0)
        } else {
            (
                vec3.x.atan2(vec3.z), // equator angle around y-up axis
                clamp(vec3.y / radius, -1.0, 1.0).acos() // polar angle
            )
        };
        Self {
            radius,
            theta,
            phi
        }
    }

    pub fn to_vec3(&self) -> Vector3 {
        let sin_phi_radius = self.phi.sin() * self.radius;
        let x = sin_phi_radius * self.theta.sin();
        let y = self.phi.cos() * self.radius;
        let z = sin_phi_radius * self.theta.cos();
        vec3(x, y, z)
    }
}

use std::num::ParseFloatError;
pub fn parse_vec3(s: &str) -> Result<Vector3, ParseFloatError> {
    let coords: Vec<&str> = s.split(',').collect();
    assert!(coords.len() == 3, "Failed to parse Vector3 ({})", s);
    let x = coords[0].parse::<f32>()?;
    let y = coords[1].parse::<f32>()?;
    let z = coords[2].parse::<f32>()?;

    Ok(vec3(x, y, z))
}
<|endoftext|>


<commit_before>use crate::events::get_document;
use chrono::Date;
use std::ops::DerefMut;
use std::sync::{Arc, Mutex};

use select::document::Document;
use select::predicate::Attr;
use select::predicate::Class;
use select::predicate::Predicate;

use std::fmt;

use chrono::offset::FixedOffset;
use chrono::prelude::Utc;
use chrono::DateTime;
use chrono::Datelike;
use chrono::Weekday;
use chrono::Weekday::*;

#[derive(Copy, Clone, Debug)]
pub enum Meal {
    Breakfast,
    Lunch,
    Dinner,
    LateNight,
    GrabAndGo,
}

type InternalFoodStore = (Date<FixedOffset>, DiningCommonsDocs);
pub type FoodStore = Arc<Mutex<InternalFoodStore>>;

use self::Meal::*;

pub fn get_store() -> FoodStore {
    Arc::new(Mutex::new((get_date(), get_menus_no_cache())))
}

pub fn get_date() -> Date<FixedOffset> {
    let current_time_utc = Utc::now();
    let current_time: DateTime<FixedOffset> = DateTime::from_utc(
        current_time_utc.naive_utc(),
        FixedOffset::west(4 * 60 * 60),
        // Four hours west of the date line
        // Four instead of five because 5am/6am is a better default than 6am/7am
    );

    current_time.date()
}

fn get_day_of_week() -> Weekday {
    get_date().weekday()
}

impl fmt::Display for Meal {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        formatter.write_str(match get_day_of_week() {
            Mon | Tue | Wed | Thu | Fri => match self {
                Breakfast => "Breakfast",
                Lunch => "Lunch",
                Dinner => "Dinner",
                LateNight => "Late Night",
                GrabAndGo => "Grab n' Go",
            },
            Sat | Sun => match self {
                Breakfast => "Breakfast",
                Lunch => "Brunch",
                Dinner => "Dinner",
                LateNight => "Late Night",
                GrabAndGo => "Grab n' Go",
            },
        })
    }
}

#[derive(Copy, Clone, Debug)]
pub enum DiningCommon {
    Berk,
    Hamp,
    Frank,
    Worcester,
}

pub struct DiningCommonsDocs {
    berk: String,
    hamp: String,
    frank: String,
    worcester: String,
}

use self::DiningCommon::*;

fn get_meal_code(meal: Meal) -> String {
    match meal {
        Breakfast => "breakfast_menu",
        Lunch => "lunch_menu",
        Dinner => "dinner_menu",
        LateNight => "latenight_menu",
        GrabAndGo => "grabngo",
    }
    .to_string()
}

fn get_dining_common_code(dining_common: DiningCommon) -> String {
    match dining_common {
        Worcester => "worcester",
        Frank => "franklin",
        Hamp => "hampshire",
        Berk => "berkshire",
    }
    .to_string()
}

pub fn get_menu_no_cache(dining_common: DiningCommon) -> String {
    let dining_common_id = get_dining_common_code(dining_common);

    let url: &str = &format!(
        "http://umassdining.com/locations-menus/{dining_common}/menu",
        dining_common = dining_common_id
    );

    println!("{}", url);

    get_document(url).unwrap()
}

pub fn get_menus_no_cache() -> DiningCommonsDocs {
    DiningCommonsDocs {
        berk: get_menu_no_cache(Berk),
        hamp: get_menu_no_cache(Hamp),
        frank: get_menu_no_cache(Frank),
        worcester: get_menu_no_cache(Worcester),
    }
}

fn get_menu_document(dining_common: DiningCommon, store: &FoodStore) -> Document {
    let mut unlocked_store = store.lock().unwrap();
    let store: &mut InternalFoodStore = unlocked_store.deref_mut();
    if store.0 != get_date() {
        store.0 = get_date();
        store.1 = get_menus_no_cache();
    }

    Document::from(&*match dining_common {
        Berk => store.1.berk.clone(),
        Hamp => store.1.hamp.clone(),
        Frank => store.1.frank.clone(),
        Worcester => store.1.worcester.clone(),
    })
}

pub fn get_on_menu(
    dining_common: DiningCommon,
    meal: Meal,
    item: &str,
    store: &FoodStore,
) -> Vec<String> {
    let nodes: Vec<String> = get_menu_document(dining_common, store)
        .find(Attr("id", &get_meal_code(meal)[..]).descendant(Attr("id", "content_text")))
        .nth(0)
        .expect("Couldn't find the menu items on page")
        .find(Class("lightbox-nutrition"))
        .map(|node| node.text())
        .collect();

    let filtered: Vec<String> = nodes
        .into_iter()
        .map(|text| text.to_lowercase())
        .filter(|text| text.contains(item.to_lowercase().as_str()))
        .collect();

    let found = filtered.join(" ");
    if found != String::new() {
        println!("{}", found);
    }

    filtered
}

fn which_meals(dc: DiningCommon) -> Vec<Meal> {
    match get_day_of_week() {
        Mon | Tue | Wed | Thu => match dc {
            Berk => vec![Lunch, Dinner, LateNight, GrabAndGo],
            Hamp | Frank => vec![Breakfast, Lunch, Dinner GrabAndGo],
            Worcester => vec![Breakfast, Lunch, Dinner, LateNight, GrabAndGo],
        },
        Fri => match dc {
            Berk => vec![Lunch, Dinner, LateNight, GrabAndGo],
            Hamp | Frank | Worcester => vec![Breakfast, Lunch, Dinner, GrabAndGo],
        },
        Sat => match dc {
            Berk => vec![Lunch, Dinner, LateNight],
            Hamp | Frank | Worcester => vec![Lunch, Dinner],
        },
        Sun => match dc {
            Berk => vec![Lunch, Dinner, LateNight],
            Worcester => vec![Lunch, Dinner, LateNight],
            Hamp | Frank => vec![Lunch, Dinner],
        },
    }
}

pub fn check_for(food: &str, store: &FoodStore) -> String {
    let mut places: Vec<String> = vec![];

    for dining_common in &[Berk, Hamp, Frank, Worcester] {
        let meals = which_meals(*dining_common);
        for meal in meals {
            let food_on_menu = get_on_menu(*dining_common, meal, food, &store);
            if !food_on_menu.is_empty() {
                places.push(
                    format!("{:?} {}: {}", dining_common, meal, food_on_menu.join(", "))
                        .to_string(),
                );
            }
        }
    }

    let to_return = match places.len() {
        0 => format!("{} not found", food).to_string(),
        _ => format!("{}: \n{}", food, places.join("\n")).to_string(),
    };

    println!("To return: {}", to_return);

    to_return
}
<commit_msg>Fix typo<commit_after>use crate::events::get_document;
use chrono::Date;
use std::ops::DerefMut;
use std::sync::{Arc, Mutex};

use select::document::Document;
use select::predicate::Attr;
use select::predicate::Class;
use select::predicate::Predicate;

use std::fmt;

use chrono::offset::FixedOffset;
use chrono::prelude::Utc;
use chrono::DateTime;
use chrono::Datelike;
use chrono::Weekday;
use chrono::Weekday::*;

#[derive(Copy, Clone, Debug)]
pub enum Meal {
    Breakfast,
    Lunch,
    Dinner,
    LateNight,
    GrabAndGo,
}

type InternalFoodStore = (Date<FixedOffset>, DiningCommonsDocs);
pub type FoodStore = Arc<Mutex<InternalFoodStore>>;

use self::Meal::*;

pub fn get_store() -> FoodStore {
    Arc::new(Mutex::new((get_date(), get_menus_no_cache())))
}

pub fn get_date() -> Date<FixedOffset> {
    let current_time_utc = Utc::now();
    let current_time: DateTime<FixedOffset> = DateTime::from_utc(
        current_time_utc.naive_utc(),
        FixedOffset::west(4 * 60 * 60),
        // Four hours west of the date line
        // Four instead of five because 5am/6am is a better default than 6am/7am
    );

    current_time.date()
}

fn get_day_of_week() -> Weekday {
    get_date().weekday()
}

impl fmt::Display for Meal {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        formatter.write_str(match get_day_of_week() {
            Mon | Tue | Wed | Thu | Fri => match self {
                Breakfast => "Breakfast",
                Lunch => "Lunch",
                Dinner => "Dinner",
                LateNight => "Late Night",
                GrabAndGo => "Grab n' Go",
            },
            Sat | Sun => match self {
                Breakfast => "Breakfast",
                Lunch => "Brunch",
                Dinner => "Dinner",
                LateNight => "Late Night",
                GrabAndGo => "Grab n' Go",
            },
        })
    }
}

#[derive(Copy, Clone, Debug)]
pub enum DiningCommon {
    Berk,
    Hamp,
    Frank,
    Worcester,
}

pub struct DiningCommonsDocs {
    berk: String,
    hamp: String,
    frank: String,
    worcester: String,
}

use self::DiningCommon::*;

fn get_meal_code(meal: Meal) -> String {
    match meal {
        Breakfast => "breakfast_menu",
        Lunch => "lunch_menu",
        Dinner => "dinner_menu",
        LateNight => "latenight_menu",
        GrabAndGo => "grabngo",
    }
    .to_string()
}

fn get_dining_common_code(dining_common: DiningCommon) -> String {
    match dining_common {
        Worcester => "worcester",
        Frank => "franklin",
        Hamp => "hampshire",
        Berk => "berkshire",
    }
    .to_string()
}

pub fn get_menu_no_cache(dining_common: DiningCommon) -> String {
    let dining_common_id = get_dining_common_code(dining_common);

    let url: &str = &format!(
        "http://umassdining.com/locations-menus/{dining_common}/menu",
        dining_common = dining_common_id
    );

    println!("{}", url);

    get_document(url).unwrap()
}

pub fn get_menus_no_cache() -> DiningCommonsDocs {
    DiningCommonsDocs {
        berk: get_menu_no_cache(Berk),
        hamp: get_menu_no_cache(Hamp),
        frank: get_menu_no_cache(Frank),
        worcester: get_menu_no_cache(Worcester),
    }
}

fn get_menu_document(dining_common: DiningCommon, store: &FoodStore) -> Document {
    let mut unlocked_store = store.lock().unwrap();
    let store: &mut InternalFoodStore = unlocked_store.deref_mut();
    if store.0 != get_date() {
        store.0 = get_date();
        store.1 = get_menus_no_cache();
    }

    Document::from(&*match dining_common {
        Berk => store.1.berk.clone(),
        Hamp => store.1.hamp.clone(),
        Frank => store.1.frank.clone(),
        Worcester => store.1.worcester.clone(),
    })
}

pub fn get_on_menu(
    dining_common: DiningCommon,
    meal: Meal,
    item: &str,
    store: &FoodStore,
) -> Vec<String> {
    let nodes: Vec<String> = get_menu_document(dining_common, store)
        .find(Attr("id", &get_meal_code(meal)[..]).descendant(Attr("id", "content_text")))
        .nth(0)
        .expect("Couldn't find the menu items on page")
        .find(Class("lightbox-nutrition"))
        .map(|node| node.text())
        .collect();

    let filtered: Vec<String> = nodes
        .into_iter()
        .map(|text| text.to_lowercase())
        .filter(|text| text.contains(item.to_lowercase().as_str()))
        .collect();

    let found = filtered.join(" ");
    if found != String::new() {
        println!("{}", found);
    }

    filtered
}

fn which_meals(dc: DiningCommon) -> Vec<Meal> {
    match get_day_of_week() {
        Mon | Tue | Wed | Thu => match dc {
            Berk => vec![Lunch, Dinner, LateNight, GrabAndGo],
            Hamp | Frank => vec![Breakfast, Lunch, Dinner, GrabAndGo],
            Worcester => vec![Breakfast, Lunch, Dinner, LateNight, GrabAndGo],
        },
        Fri => match dc {
            Berk => vec![Lunch, Dinner, LateNight, GrabAndGo],
            Hamp | Frank | Worcester => vec![Breakfast, Lunch, Dinner, GrabAndGo],
        },
        Sat => match dc {
            Berk => vec![Lunch, Dinner, LateNight],
            Hamp | Frank | Worcester => vec![Lunch, Dinner],
        },
        Sun => match dc {
            Berk => vec![Lunch, Dinner, LateNight],
            Worcester => vec![Lunch, Dinner, LateNight],
            Hamp | Frank => vec![Lunch, Dinner],
        },
    }
}

pub fn check_for(food: &str, store: &FoodStore) -> String {
    let mut places: Vec<String> = vec![];

    for dining_common in &[Berk, Hamp, Frank, Worcester] {
        let meals = which_meals(*dining_common);
        for meal in meals {
            let food_on_menu = get_on_menu(*dining_common, meal, food, &store);
            if !food_on_menu.is_empty() {
                places.push(
                    format!("{:?} {}: {}", dining_common, meal, food_on_menu.join(", "))
                        .to_string(),
                );
            }
        }
    }

    let to_return = match places.len() {
        0 => format!("{} not found", food).to_string(),
        _ => format!("{}: \n{}", food, places.join("\n")).to_string(),
    };

    println!("To return: {}", to_return);

    to_return
}
<|endoftext|>


<commit_before>use russell_lab::{Matrix, Vector};

/// Defines a line (segment) with 5 nodes (quartic functions)
///
/// The reference coordinates range from -1 to +1 with the geometry centred @ 0
///
/// # Local IDs of nodes
///
/// ```text
/// -1  -0.5    0    0.5  +1
///  @----@-----@-----@----@  --> r
///  0    3     2     4    1
/// ```
pub struct Lin5 {}

impl Lin5 {
    pub const GEO_NDIM: usize = 1;
    pub const NNODE: usize = 5;
    pub const NEDGE: usize = 0;
    pub const NFACE: usize = 0;
    pub const EDGE_NNODE: usize = 0;
    pub const FACE_NNODE: usize = 0;
    pub const FACE_NEDGE: usize = 0;

    #[rustfmt::skip]
    pub const NODE_REFERENCE_COORDS: [[f64; Lin5::GEO_NDIM]; Lin5::NNODE] = [
        [-1.0],
        [ 1.0],
        [ 0.0],
        [-0.5],
        [ 0.5],
    ];

    /// Computes the interpolation functions
    ///
    /// # Output
    ///
    /// * `interp` -- interpolation function evaluated at ksi (nnode)
    ///
    /// # Input
    ///
    /// * `ksi` -- reference coordinates with length ≥ geo_ndim
    pub fn calc_interp(interp: &mut Vector, ksi: &[f64]) {
        let r = ksi[0];

        interp[0] = (r - 1.0) * (1.0 - 2.0 * r) * r * (-1.0 - 2.0 * r) / 6.0;
        interp[1] = (1.0 - 2.0 * r) * r * (-1.0 - 2.0 * r) * (1.0 + r) / 6.0;
        interp[2] = (1.0 - r) * (1.0 - 2.0 * r) * (-1.0 - 2.0 * r) * (-1.0 - r);
        interp[3] = 4.0 * (1.0 - r) * (1.0 - 2.0 * r) * r * (-1.0 - r) / 3.0;
        interp[4] = 4.0 * (1.0 - r) * r * (-1.0 - 2.0 * r) * (-1.0 - r) / 3.0;
    }

    /// Computes the derivatives of interpolation functions with respect to the reference coordinates
    ///
    /// # Output
    ///
    /// * `deriv` -- derivatives of the interpolation function with respect to
    ///   the reference coordinates ksi, evaluated at ksi (nnode,geo_ndim)
    ///
    /// # Input
    ///
    /// * `ksi` -- reference coordinates with length ≥ geo_ndim
    pub fn calc_deriv(deriv: &mut Matrix, ksi: &[f64]) {
        let r = ksi[0];

        deriv[0][0] = -((1.0 - 2.0 * r) * (r - 1.0) * r) / 3.0 - ((-2.0 * r - 1.0) * (r - 1.0) * r) / 3.0
            + ((-2.0 * r - 1.0) * (1.0 - 2.0 * r) * r) / 6.0
            + ((-2.0 * r - 1.0) * (1.0 - 2.0 * r) * (r - 1.0)) / 6.0;

        deriv[1][0] = -((1.0 - 2.0 * r) * r * (r + 1.0)) / 3.0 - ((-2.0 * r - 1.0) * r * (r + 1.0)) / 3.0
            + ((-2.0 * r - 1.0) * (1.0 - 2.0 * r) * (r + 1.0)) / 6.0
            + ((-2.0 * r - 1.0) * (1.0 - 2.0 * r) * r) / 6.0;

        deriv[2][0] = -2.0 * (1.0 - 2.0 * r) * (-r - 1.0) * (1.0 - r)
            - 2.0 * (-2.0 * r - 1.0) * (-r - 1.0) * (1.0 - r)
            - (-2.0 * r - 1.0) * (1.0 - 2.0 * r) * (1.0 - r)
            - (-2.0 * r - 1.0) * (1.0 - 2.0 * r) * (-r - 1.0);

        deriv[3][0] = -(8.0 * (-r - 1.0) * (1.0 - r) * r) / 3.0
            - (4.0 * (1.0 - 2.0 * r) * (1.0 - r) * r) / 3.0
            - (4.0 * (1.0 - 2.0 * r) * (-r - 1.0) * r) / 3.0
            + (4.0 * (1.0 - 2.0 * r) * (-r - 1.0) * (1.0 - r)) / 3.0;

        deriv[4][0] = -(8.0 * (-r - 1.0) * (1.0 - r) * r) / 3.0
            - (4.0 * (-2.0 * r - 1.0) * (1.0 - r) * r) / 3.0
            - (4.0 * (-2.0 * r - 1.0) * (-r - 1.0) * r) / 3.0
            + (4.0 * (-2.0 * r - 1.0) * (-r - 1.0) * (1.0 - r)) / 3.0;
    }
}
<commit_msg>Improve comment figure in Lin5<commit_after>use russell_lab::{Matrix, Vector};

/// Defines a line (segment) with 5 nodes (quartic functions)
///
/// The reference coordinates range from -1 to +1 with the geometry centred @ 0
///
/// # Local IDs of nodes
///
/// ```text
/// -1   -0.5    0    0.5   +1
///  @-----@-----@-----@-----@  --> r
///  0     3     2     4     1
/// ```
pub struct Lin5 {}

impl Lin5 {
    pub const GEO_NDIM: usize = 1;
    pub const NNODE: usize = 5;
    pub const NEDGE: usize = 0;
    pub const NFACE: usize = 0;
    pub const EDGE_NNODE: usize = 0;
    pub const FACE_NNODE: usize = 0;
    pub const FACE_NEDGE: usize = 0;

    #[rustfmt::skip]
    pub const NODE_REFERENCE_COORDS: [[f64; Lin5::GEO_NDIM]; Lin5::NNODE] = [
        [-1.0],
        [ 1.0],
        [ 0.0],
        [-0.5],
        [ 0.5],
    ];

    /// Computes the interpolation functions
    ///
    /// # Output
    ///
    /// * `interp` -- interpolation function evaluated at ksi (nnode)
    ///
    /// # Input
    ///
    /// * `ksi` -- reference coordinates with length ≥ geo_ndim
    pub fn calc_interp(interp: &mut Vector, ksi: &[f64]) {
        let r = ksi[0];

        interp[0] = (r - 1.0) * (1.0 - 2.0 * r) * r * (-1.0 - 2.0 * r) / 6.0;
        interp[1] = (1.0 - 2.0 * r) * r * (-1.0 - 2.0 * r) * (1.0 + r) / 6.0;
        interp[2] = (1.0 - r) * (1.0 - 2.0 * r) * (-1.0 - 2.0 * r) * (-1.0 - r);
        interp[3] = 4.0 * (1.0 - r) * (1.0 - 2.0 * r) * r * (-1.0 - r) / 3.0;
        interp[4] = 4.0 * (1.0 - r) * r * (-1.0 - 2.0 * r) * (-1.0 - r) / 3.0;
    }

    /// Computes the derivatives of interpolation functions with respect to the reference coordinates
    ///
    /// # Output
    ///
    /// * `deriv` -- derivatives of the interpolation function with respect to
    ///   the reference coordinates ksi, evaluated at ksi (nnode,geo_ndim)
    ///
    /// # Input
    ///
    /// * `ksi` -- reference coordinates with length ≥ geo_ndim
    pub fn calc_deriv(deriv: &mut Matrix, ksi: &[f64]) {
        let r = ksi[0];

        deriv[0][0] = -((1.0 - 2.0 * r) * (r - 1.0) * r) / 3.0 - ((-2.0 * r - 1.0) * (r - 1.0) * r) / 3.0
            + ((-2.0 * r - 1.0) * (1.0 - 2.0 * r) * r) / 6.0
            + ((-2.0 * r - 1.0) * (1.0 - 2.0 * r) * (r - 1.0)) / 6.0;

        deriv[1][0] = -((1.0 - 2.0 * r) * r * (r + 1.0)) / 3.0 - ((-2.0 * r - 1.0) * r * (r + 1.0)) / 3.0
            + ((-2.0 * r - 1.0) * (1.0 - 2.0 * r) * (r + 1.0)) / 6.0
            + ((-2.0 * r - 1.0) * (1.0 - 2.0 * r) * r) / 6.0;

        deriv[2][0] = -2.0 * (1.0 - 2.0 * r) * (-r - 1.0) * (1.0 - r)
            - 2.0 * (-2.0 * r - 1.0) * (-r - 1.0) * (1.0 - r)
            - (-2.0 * r - 1.0) * (1.0 - 2.0 * r) * (1.0 - r)
            - (-2.0 * r - 1.0) * (1.0 - 2.0 * r) * (-r - 1.0);

        deriv[3][0] = -(8.0 * (-r - 1.0) * (1.0 - r) * r) / 3.0
            - (4.0 * (1.0 - 2.0 * r) * (1.0 - r) * r) / 3.0
            - (4.0 * (1.0 - 2.0 * r) * (-r - 1.0) * r) / 3.0
            + (4.0 * (1.0 - 2.0 * r) * (-r - 1.0) * (1.0 - r)) / 3.0;

        deriv[4][0] = -(8.0 * (-r - 1.0) * (1.0 - r) * r) / 3.0
            - (4.0 * (-2.0 * r - 1.0) * (1.0 - r) * r) / 3.0
            - (4.0 * (-2.0 * r - 1.0) * (-r - 1.0) * r) / 3.0
            + (4.0 * (-2.0 * r - 1.0) * (-r - 1.0) * (1.0 - r)) / 3.0;
    }
}
<|endoftext|>


<commit_before>// Originally from https://github.com/rust-lang/crates.io/blob/master/src/s3/lib.rs
//#![deny(warnings)]

#[allow(unused_imports, deprecated)]
use std::ascii::AsciiExt;
use std::fmt;

use crate::simples3::credential::*;
use crypto::digest::Digest;
use crypto::hmac::Hmac;
use crypto::mac::Mac;
use crypto::sha1::Sha1;
use futures::{Future, Stream};
use hyper::header::HeaderValue;
use hyper::Method;
use hyperx::header;
use reqwest::r#async::{Client, Request};

use crate::errors::*;
use crate::util::HeadersExt;

#[derive(Debug, Copy, Clone)]
#[allow(dead_code)]
/// Whether or not to use SSL.
pub enum Ssl {
    /// Use SSL.
    Yes,
    /// Do not use SSL.
    No,
}

fn base_url(endpoint: &str, ssl: Ssl) -> String {
    format!(
        "{}://{}/",
        match ssl {
            Ssl::Yes => "https",
            Ssl::No => "http",
        },
        endpoint
    )
}

fn hmac<D: Digest>(d: D, key: &[u8], data: &[u8]) -> Vec<u8> {
    let mut hmac = Hmac::new(d, key);
    hmac.input(data);
    hmac.result().code().iter().map(|b| *b).collect::<Vec<u8>>()
}

fn signature(string_to_sign: &str, signing_key: &str) -> String {
    let s = hmac(
        Sha1::new(),
        signing_key.as_bytes(),
        string_to_sign.as_bytes(),
    );
    base64::encode_config::<Vec<u8>>(&s, base64::STANDARD)
}

/// An S3 bucket.
pub struct Bucket {
    name: String,
    base_url: String,
    client: Client,
}

impl fmt::Display for Bucket {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Bucket(name={}, base_url={})", self.name, self.base_url)
    }
}

impl Bucket {
    pub fn new(name: &str, endpoint: &str, ssl: Ssl) -> Result<Bucket> {
        let base_url = base_url(&endpoint, ssl);
        Ok(Bucket {
            name: name.to_owned(),
            base_url: base_url,
            client: Client::new(),
        })
    }

    pub fn get(&self, key: &str, creds: Option<&AwsCredentials>) -> SFuture<Vec<u8>> {
        let url = format!("{}{}", self.base_url, key);
        debug!("GET {}", url);
        let url2 = url.clone();
        let mut request = Request::new(Method::GET, url.parse().unwrap());
        match creds {
            Some(creds) => {
                let mut canonical_headers = String::new();

                if let Some(token) = creds.token().as_ref().map(|s| s.as_str()) {
                    request.headers_mut().insert(
                        "x-amz-security-token",
                        HeaderValue::from_str(token)
                            .expect("Invalid `x-amz-security-token` header"),
                    );
                    canonical_headers
                        .push_str(format!("{}:{}\n", "x-amz-security-token", token).as_ref());
                }
                let date = time::now_utc().rfc822().to_string();
                let auth = self.auth("GET", &date, key, "", &canonical_headers, "", creds);
                request.headers_mut().insert(
                    "Date",
                    HeaderValue::from_str(&date).expect("Invalid date header"),
                );
                request.headers_mut().insert(
                    "Authorization",
                    HeaderValue::from_str(&auth).expect("Invalid authentication"),
                );
            }
            // request is fine as-is
            None => {}
        }

        Box::new(
            self.client
                .execute(request)
                .chain_err(move || format!("failed GET: {}", url))
                .and_then(|res| {
                    if res.status().is_success() {
                        let content_length = res
                            .headers()
                            .get_hyperx::<header::ContentLength>()
                            .map(|header::ContentLength(len)| len);
                        Ok((res.into_body(), content_length))
                    } else {
                        Err(ErrorKind::BadHTTPStatus(res.status().clone()).into())
                    }
                })
                .and_then(|(body, content_length)| {
                    body.fold(Vec::new(), |mut body, chunk| {
                        body.extend_from_slice(&chunk);
                        Ok::<_, reqwest::Error>(body)
                    })
                    .chain_err(|| "failed to read HTTP body")
                    .and_then(move |bytes| {
                        if let Some(len) = content_length {
                            if len != bytes.len() as u64 {
                                bail!(format!(
                                    "Bad HTTP body size read: {}, expected {}",
                                    bytes.len(),
                                    len
                                ));
                            } else {
                                info!("Read {} bytes from {}", bytes.len(), url2);
                            }
                        }
                        Ok(bytes)
                    })
                }),
        )
    }

    pub fn put(&self, key: &str, content: Vec<u8>, creds: &AwsCredentials) -> SFuture<()> {
        let url = format!("{}{}", self.base_url, key);
        debug!("PUT {}", url);
        let mut request = Request::new(Method::PUT, url.parse().unwrap());

        let content_type = "application/octet-stream";
        let date = time::now_utc().rfc822().to_string();
        let mut canonical_headers = String::new();
        let token = creds.token().as_ref().map(|s| s.as_str());
        // Keep the list of header values sorted!
        for (header, maybe_value) in vec![("x-amz-security-token", token)] {
            if let Some(ref value) = maybe_value {
                request.headers_mut().insert(
                    header,
                    HeaderValue::from_str(value)
                        .unwrap_or_else(|_| panic!("Invalid `{}` header", header)),
                );
                canonical_headers
                    .push_str(format!("{}:{}\n", header.to_ascii_lowercase(), value).as_ref());
            }
        }
        let auth = self.auth(
            "PUT",
            &date,
            key,
            "",
            &canonical_headers,
            content_type,
            creds,
        );
        request.headers_mut().insert(
            "Date",
            HeaderValue::from_str(&date).expect("Invalid date header"),
        );
        request
            .headers_mut()
            .set(header::ContentType(content_type.parse().unwrap()));
        request
            .headers_mut()
            .set(header::ContentLength(content.len() as u64));
        request.headers_mut().set(header::CacheControl(vec![
            // Two weeks
            header::CacheDirective::MaxAge(1296000),
        ]));
        request.headers_mut().insert(
            "Authorization",
            HeaderValue::from_str(&auth).expect("Invalid authentication"),
        );
        *request.body_mut() = Some(content.into());

        Box::new(self.client.execute(request).then(|result| match result {
            Ok(res) => {
                if res.status().is_success() {
                    trace!("PUT succeeded");
                    Ok(())
                } else {
                    trace!("PUT failed with HTTP status: {}", res.status());
                    Err(ErrorKind::BadHTTPStatus(res.status().clone()).into())
                }
            }
            Err(e) => {
                trace!("PUT failed with error: {:?}", e);
                Err(e.into())
            }
        }))
    }

    // http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
    fn auth(
        &self,
        verb: &str,
        date: &str,
        path: &str,
        md5: &str,
        headers: &str,
        content_type: &str,
        creds: &AwsCredentials,
    ) -> String {
        let string = format!(
            "{verb}\n{md5}\n{ty}\n{date}\n{headers}{resource}",
            verb = verb,
            md5 = md5,
            ty = content_type,
            date = date,
            headers = headers,
            resource = format!("/{}/{}", self.name, path)
        );
        let signature = signature(&string, creds.aws_secret_access_key());
        format!("AWS {}:{}", creds.aws_access_key_id(), signature)
    }
}
<commit_msg>Add test<commit_after>// Originally from https://github.com/rust-lang/crates.io/blob/master/src/s3/lib.rs
//#![deny(warnings)]

#[allow(unused_imports, deprecated)]
use std::ascii::AsciiExt;
use std::fmt;

use crate::simples3::credential::*;
use crypto::digest::Digest;
use crypto::hmac::Hmac;
use crypto::mac::Mac;
use crypto::sha1::Sha1;
use futures::{Future, Stream};
use hyper::header::HeaderValue;
use hyper::Method;
use hyperx::header;
use reqwest::r#async::{Client, Request};

use crate::errors::*;
use crate::util::HeadersExt;

#[derive(Debug, Copy, Clone)]
#[allow(dead_code)]
/// Whether or not to use SSL.
pub enum Ssl {
    /// Use SSL.
    Yes,
    /// Do not use SSL.
    No,
}

fn base_url(endpoint: &str, ssl: Ssl) -> String {
    format!(
        "{}://{}/",
        match ssl {
            Ssl::Yes => "https",
            Ssl::No => "http",
        },
        endpoint
    )
}

fn hmac<D: Digest>(d: D, key: &[u8], data: &[u8]) -> Vec<u8> {
    let mut hmac = Hmac::new(d, key);
    hmac.input(data);
    hmac.result().code().iter().map(|b| *b).collect::<Vec<u8>>()
}

fn signature(string_to_sign: &str, signing_key: &str) -> String {
    let s = hmac(
        Sha1::new(),
        signing_key.as_bytes(),
        string_to_sign.as_bytes(),
    );
    base64::encode_config::<Vec<u8>>(&s, base64::STANDARD)
}

/// An S3 bucket.
pub struct Bucket {
    name: String,
    base_url: String,
    client: Client,
}

impl fmt::Display for Bucket {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Bucket(name={}, base_url={})", self.name, self.base_url)
    }
}

impl Bucket {
    pub fn new(name: &str, endpoint: &str, ssl: Ssl) -> Result<Bucket> {
        let base_url = base_url(&endpoint, ssl);
        Ok(Bucket {
            name: name.to_owned(),
            base_url: base_url,
            client: Client::new(),
        })
    }

    pub fn get(&self, key: &str, creds: Option<&AwsCredentials>) -> SFuture<Vec<u8>> {
        let url = format!("{}{}", self.base_url, key);
        debug!("GET {}", url);
        let url2 = url.clone();
        let mut request = Request::new(Method::GET, url.parse().unwrap());
        match creds {
            Some(creds) => {
                let mut canonical_headers = String::new();

                if let Some(token) = creds.token().as_ref().map(|s| s.as_str()) {
                    request.headers_mut().insert(
                        "x-amz-security-token",
                        HeaderValue::from_str(token)
                            .expect("Invalid `x-amz-security-token` header"),
                    );
                    canonical_headers
                        .push_str(format!("{}:{}\n", "x-amz-security-token", token).as_ref());
                }
                let date = time::now_utc().rfc822().to_string();
                let auth = self.auth("GET", &date, key, "", &canonical_headers, "", creds);
                request.headers_mut().insert(
                    "Date",
                    HeaderValue::from_str(&date).expect("Invalid date header"),
                );
                request.headers_mut().insert(
                    "Authorization",
                    HeaderValue::from_str(&auth).expect("Invalid authentication"),
                );
            }
            // request is fine as-is
            None => {}
        }

        Box::new(
            self.client
                .execute(request)
                .chain_err(move || format!("failed GET: {}", url))
                .and_then(|res| {
                    if res.status().is_success() {
                        let content_length = res
                            .headers()
                            .get_hyperx::<header::ContentLength>()
                            .map(|header::ContentLength(len)| len);
                        Ok((res.into_body(), content_length))
                    } else {
                        Err(ErrorKind::BadHTTPStatus(res.status().clone()).into())
                    }
                })
                .and_then(|(body, content_length)| {
                    body.fold(Vec::new(), |mut body, chunk| {
                        body.extend_from_slice(&chunk);
                        Ok::<_, reqwest::Error>(body)
                    })
                    .chain_err(|| "failed to read HTTP body")
                    .and_then(move |bytes| {
                        if let Some(len) = content_length {
                            if len != bytes.len() as u64 {
                                bail!(format!(
                                    "Bad HTTP body size read: {}, expected {}",
                                    bytes.len(),
                                    len
                                ));
                            } else {
                                info!("Read {} bytes from {}", bytes.len(), url2);
                            }
                        }
                        Ok(bytes)
                    })
                }),
        )
    }

    pub fn put(&self, key: &str, content: Vec<u8>, creds: &AwsCredentials) -> SFuture<()> {
        let url = format!("{}{}", self.base_url, key);
        debug!("PUT {}", url);
        let mut request = Request::new(Method::PUT, url.parse().unwrap());

        let content_type = "application/octet-stream";
        let date = time::now_utc().rfc822().to_string();
        let mut canonical_headers = String::new();
        let token = creds.token().as_ref().map(|s| s.as_str());
        // Keep the list of header values sorted!
        for (header, maybe_value) in vec![("x-amz-security-token", token)] {
            if let Some(ref value) = maybe_value {
                request.headers_mut().insert(
                    header,
                    HeaderValue::from_str(value)
                        .unwrap_or_else(|_| panic!("Invalid `{}` header", header)),
                );
                canonical_headers
                    .push_str(format!("{}:{}\n", header.to_ascii_lowercase(), value).as_ref());
            }
        }
        let auth = self.auth(
            "PUT",
            &date,
            key,
            "",
            &canonical_headers,
            content_type,
            creds,
        );
        request.headers_mut().insert(
            "Date",
            HeaderValue::from_str(&date).expect("Invalid date header"),
        );
        request
            .headers_mut()
            .set(header::ContentType(content_type.parse().unwrap()));
        request
            .headers_mut()
            .set(header::ContentLength(content.len() as u64));
        request.headers_mut().set(header::CacheControl(vec![
            // Two weeks
            header::CacheDirective::MaxAge(1296000),
        ]));
        request.headers_mut().insert(
            "Authorization",
            HeaderValue::from_str(&auth).expect("Invalid authentication"),
        );
        *request.body_mut() = Some(content.into());

        Box::new(self.client.execute(request).then(|result| match result {
            Ok(res) => {
                if res.status().is_success() {
                    trace!("PUT succeeded");
                    Ok(())
                } else {
                    trace!("PUT failed with HTTP status: {}", res.status());
                    Err(ErrorKind::BadHTTPStatus(res.status().clone()).into())
                }
            }
            Err(e) => {
                trace!("PUT failed with error: {:?}", e);
                Err(e.into())
            }
        }))
    }

    // http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
    fn auth(
        &self,
        verb: &str,
        date: &str,
        path: &str,
        md5: &str,
        headers: &str,
        content_type: &str,
        creds: &AwsCredentials,
    ) -> String {
        let string = format!(
            "{verb}\n{md5}\n{ty}\n{date}\n{headers}{resource}",
            verb = verb,
            md5 = md5,
            ty = content_type,
            date = date,
            headers = headers,
            resource = format!("/{}/{}", self.name, path)
        );
        let signature = signature(&string, creds.aws_secret_access_key());
        format!("AWS {}:{}", creds.aws_access_key_id(), signature)
    }
}

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

    #[test]
    fn test_signature() {
        assert_eq!(
            signature("/foo/bar\nbar", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"),
            "mwbstmHPMEJjTe2ksXi5H5f0c8U="
        );

        assert_eq!(
            signature("/bar/foo\nbaz", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"),
            "F9gZMso3+P+QTEyRKQ6qhZ1YM6o="
        );
    }
}
<|endoftext|>


<commit_before>extern crate capstone;

#[macro_use]
extern crate clap;

#[macro_use]
extern crate log;

extern crate stderrlog;

use capstone::{Arch, Endian, ExtraMode, Mode};
use capstone::prelude::*;
use clap::{App, Arg, ArgGroup};
use std::fs::File;
use std::io::prelude::*;
use std::process::exit;
use std::str::FromStr;

const DEFAULT_CAPACITY: usize = 1024;

trait ExpectExit<T> {
    fn expect_exit(self) -> T;
}

impl<T, E> ExpectExit<T> for Result<T, E>
where
    E: ::std::error::Error,
{
    fn expect_exit(self) -> T {
        match self {
            Ok(t) => t,
            Err(e) => {
                eprintln!("error: {}", e.description());
                exit(1);
            }
        }
    }
}

/// We can't iterate over enums declared in another crate, so we declare a private enum that
/// shadows the values
macro_rules! arch_conversions {
    (
        $arg_struct:ident = $cs_struct:ident
        [ $( $name:ident, )* ]
    ) => {
        arg_enum!{
            #[derive(PartialEq, Debug)]
            pub enum $arg_struct {
                $( $name, )*
            }
        }

        impl From<$arg_struct> for $cs_struct {
            fn from(arch_arg: $arg_struct) -> $cs_struct {
                match arch_arg {
                    $( $arg_struct::$name => $cs_struct::$name, )*
                }
            }
        }

        impl From<$cs_struct> for $arg_struct {
            fn from(arch_arg: $cs_struct) -> $arg_struct {
                match arch_arg {
                    $( $cs_struct::$name => $arg_struct::$name, )*
                }
            }
        }
    }
}

arch_conversions!(
    ArchArg = Arch
    [
        ARM,
        ARM64,
        MIPS,
        X86,
        PPC,
        SPARC,
        SYSZ,
        XCORE,
    ]
);

arch_conversions!(
    ModeArg = Mode
    [
        Arm,
        Mode16,
        Mode32,
        Mode64,
        Thumb,
        Mips3,
        Mips32R6,
        MipsGP64,
        V9,
        Default,
    ]
);

arch_conversions!(
    ExtraModeArg = ExtraMode
    [
        MClass,
        V8,
        Micro,
    ]
);

fn disasm<T: Iterator<Item = ExtraMode>>(
    arch: Arch,
    mode: Mode,
    extra_mode: T,
    endian: Option<Endian>,
    code: &[u8],
    addr: u64,
) {
    let mut cs = Capstone::new_raw(arch, mode, extra_mode, endian).expect_exit();

    for i in cs.disasm_all(code, addr).expect_exit().iter() {
        let bytes: Vec<_> = i.bytes().iter().map(|x| format!("{:02x}", x)).collect();
        let bytes = bytes.join(" ");
        println!(
            "{:-10x}:  {:35} {:7} {}",
            i.address(),
            bytes,
            i.mnemonic().unwrap(),
            i.op_str().unwrap_or("")
        );
    }
}

fn main() {
    // Lowercase arches
    let _arches: Vec<String> = ArchArg::variants()
        .iter()
        .map(|x| x.to_lowercase())
        .collect();
    let arches: Vec<&str> = _arches.iter().map(|x| x.as_str()).collect();

    // Lowercase modes
    let _modes: Vec<String> = ModeArg::variants()
        .iter()
        .map(|x| x.to_lowercase())
        .collect();
    let modes: Vec<&str> = _modes.iter().map(|x| x.as_str()).collect();

    // Lowercase extra modes
    let _extra_modes: Vec<String> = ExtraModeArg::variants()
        .iter()
        .map(|x| x.to_lowercase())
        .collect();
    let extra_modes: Vec<&str> = _extra_modes.iter().map(|x| x.as_str()).collect();

    let matches = App::new("capstone-rs disassembler tool")
        .about("Disassembles binary file")
        .arg(
            Arg::with_name("file")
                .short("f")
                .long("file")
                .help("input file with binary instructions")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("stdin")
                .short("s")
                .long("stdin")
                .help("read binary instructions from stdin")
                .takes_value(false),
        )
        .arg(
            Arg::with_name("address")
                .short("r")
                .long("addr")
                .help("address of code")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("v")
                .short("v")
                .multiple(true)
                .help("Sets the level of verbosity"),
        )
        .arg(
            Arg::with_name("ARCH")
                .short("a")
                .long("arch")
                .help("Architecture")
                .takes_value(true)
                .required(true)
                .possible_values(arches.as_slice())
                .case_insensitive(true),
        )
        .arg(
            Arg::with_name("MODE")
                .short("m")
                .long("mode")
                .help("Mode")
                .takes_value(true)
                .required(true)
                .possible_values(modes.as_slice())
                .case_insensitive(true),
        )
        .arg(
            Arg::with_name("EXTRA_MODE")
                .short("e")
                .long("extra")
                .help("Extra Mode")
                .takes_value(true)
                .required(false)
                .possible_values(extra_modes.as_slice())
                .case_insensitive(true)
                .multiple(true),
        )
        .group(
            ArgGroup::with_name("INPUT")
                .arg("file")
                .arg("stdin")
                .required(true),
        )
        .get_matches();

    let input_bytes: Vec<u8> = match matches.value_of("INPUT") {
        Some(file_path) => {
            let mut file = File::open(file_path).expect_exit();
            let capacity = match file.metadata() {
                Err(_) => DEFAULT_CAPACITY,
                Ok(metadata) => metadata.len() as usize,
            };
            let mut buf = Vec::with_capacity(capacity as usize);
            file.read_to_end(&mut buf).expect_exit();
            buf
        }
        None => {
            let mut buf = Vec::with_capacity(DEFAULT_CAPACITY);
            let mut stdin = std::io::stdin();
            let mut stdin = stdin.lock();
            stdin.read_to_end(&mut buf).expect_exit();
            buf
        }
    };

    stderrlog::new()
        .verbosity(matches.occurrences_of("v") as usize)
        .init()
        .unwrap();

    let arch: Arch = ArchArg::from_str(matches.value_of("ARCH").unwrap())
        .unwrap()
        .into();
    info!("Arch = {:?}", arch);

    let mode: Mode = ModeArg::from_str(matches.value_of("MODE").unwrap())
        .unwrap()
        .into();
    info!("Mode = {:?}", mode);

    let extra_mode: Vec<_> = match matches.values_of("EXTRA_MODE") {
        None => Vec::with_capacity(0),
        Some(x) => x.map(|x| ExtraMode::from(ExtraModeArg::from_str(x).unwrap()))
            .collect(),
    };
    info!("ExtraMode = {:?}", extra_mode);

    let address =
        u64::from_str_radix(matches.value_of("address").unwrap_or("1000"), 16).expect_exit();
    info!("Address = 0x{:x}", address);

    disasm(
        arch,
        mode,
        extra_mode.iter().map(|x| *x),
        None,
        input_bytes.as_slice(),
        address,
    );
}
<commit_msg>cstool: process hex input and show detail output<commit_after>extern crate capstone;

#[macro_use]
extern crate clap;

#[macro_use]
extern crate log;

extern crate stderrlog;

use capstone::{Arch, Endian, ExtraMode, Mode};
use capstone::prelude::*;
use clap::{App, Arg, ArgGroup};
use std::fs::File;
use std::io::prelude::*;
use std::process::exit;
use std::str::FromStr;

const DEFAULT_CAPACITY: usize = 1024;

trait ExpectExit<T> {
    fn expect_exit(self) -> T;
}

impl<T, E> ExpectExit<T> for Result<T, E>
where
    E: ::std::error::Error,
{
    fn expect_exit(self) -> T {
        match self {
            Ok(t) => t,
            Err(e) => {
                eprintln!("error: {}", e.description());
                exit(1);
            }
        }
    }
}

/// We can't iterate over enums declared in another crate, so we declare a private enum that
/// shadows the values
macro_rules! arch_conversions {
    (
        $arg_struct:ident = $cs_struct:ident
        [ $( $name:ident, )* ]
    ) => {
        arg_enum!{
            #[derive(PartialEq, Debug)]
            pub enum $arg_struct {
                $( $name, )*
            }
        }

        impl From<$arg_struct> for $cs_struct {
            fn from(arch_arg: $arg_struct) -> $cs_struct {
                match arch_arg {
                    $( $arg_struct::$name => $cs_struct::$name, )*
                }
            }
        }

        impl From<$cs_struct> for $arg_struct {
            fn from(arch_arg: $cs_struct) -> $arg_struct {
                match arch_arg {
                    $( $cs_struct::$name => $arg_struct::$name, )*
                }
            }
        }
    }
}

arch_conversions!(
    ArchArg = Arch
    [
        ARM,
        ARM64,
        MIPS,
        X86,
        PPC,
        SPARC,
        SYSZ,
        XCORE,
    ]
);

arch_conversions!(
    ModeArg = Mode
    [
        Arm,
        Mode16,
        Mode32,
        Mode64,
        Thumb,
        Mips3,
        Mips32R6,
        MipsGP64,
        V9,
        Default,
    ]
);

arch_conversions!(
    ExtraModeArg = ExtraMode
    [
        MClass,
        V8,
        Micro,
    ]
);

/// Print register names
fn reg_names<T, I>(cs: &Capstone, regs: T) -> String
where
    T: Iterator<Item = I>,
    I: Into<RegId>,
{
    let names: Vec<String> = regs.map(|x| cs.reg_name(x.into()).unwrap()).collect();
    names.join(", ")
}

/// Print instruction group names
fn group_names<T, I>(cs: &Capstone, regs: T) -> String
where
    T: Iterator<Item = I>,
    I: Into<InsnGroupId>,
{
    let names: Vec<String> = regs.map(|x| cs.group_name(x.into()).unwrap()).collect();
    names.join(", ")
}

/// Select only hex bytes from input
fn unhexed_bytes(input: Vec<u8>) -> Vec<u8> {
    let mut output: Vec<u8> = Vec::new();
    let mut curr_byte_str = String::with_capacity(2);
    for b_u8 in input {
        let b = char::from(b_u8);
        if ('0' <= b && b <= '9') || ('a' <= b && b <= 'f') || ('A' <= b && b <= 'F') {
            curr_byte_str.push(b);
        }

        if curr_byte_str.len() == 2 {
            debug!("  curr_byte_str={:?}", curr_byte_str);
            let byte = u8::from_str_radix(&curr_byte_str, 16)
                .expect("Unexpect hex parse error");
            output.push(byte);
            curr_byte_str.clear();
        }
    }

    if log::max_level() >= log::LevelFilter::Info {
        let output_hex: Vec<String> = output.iter().map(|x| format!("{:02x}", x)).collect();
        info!("unhexed_output = {:?}", output_hex);
    }

    output
}

fn disasm<T: Iterator<Item = ExtraMode>>(
    arch: Arch,
    mode: Mode,
    extra_mode: T,
    endian: Option<Endian>,
    code: &[u8],
    addr: u64,
    show_detail: bool,
) {
    let mut cs = Capstone::new_raw(arch, mode, extra_mode, endian).expect_exit();

    if show_detail {
        cs.set_detail(true).expect("Failed to set detail");
    }

    for i in cs.disasm_all(code, addr).expect_exit().iter() {
        let bytes: Vec<_> = i.bytes().iter().map(|x| format!("{:02x}", x)).collect();
        let bytes = bytes.join(" ");
        println!(
            "{:-10x}:  {:35} {:7} {}",
            i.address(),
            bytes,
            i.mnemonic().unwrap(),
            i.op_str().unwrap_or("")
        );

        if show_detail {
            let detail = cs.insn_detail(&i).expect("Failed to get insn detail");
            let arch_detail: ArchDetail = detail.arch_detail();

            let output: &[(&str, String)] = &[
                ("insn id:", format!("{:?}", i.id().0)),
                ("read regs:", reg_names(&cs, detail.regs_read())),
                ("write regs:", reg_names(&cs, detail.regs_write())),
                ("insn groups:", group_names(&cs, detail.groups())),
            ];

            for &(ref name, ref message) in output.iter() {
                println!("{:13}{:12} {}", "", name, message);
            }
        }
    }
}

fn main() {
    // Lowercase arches
    let _arches: Vec<String> = ArchArg::variants()
        .iter()
        .map(|x| x.to_lowercase())
        .collect();
    let arches: Vec<&str> = _arches.iter().map(|x| x.as_str()).collect();

    // Lowercase modes
    let _modes: Vec<String> = ModeArg::variants()
        .iter()
        .map(|x| x.to_lowercase())
        .collect();
    let modes: Vec<&str> = _modes.iter().map(|x| x.as_str()).collect();

    // Lowercase extra modes
    let _extra_modes: Vec<String> = ExtraModeArg::variants()
        .iter()
        .map(|x| x.to_lowercase())
        .collect();
    let extra_modes: Vec<&str> = _extra_modes.iter().map(|x| x.as_str()).collect();

    let matches = App::new("capstone-rs disassembler tool")
        .about("Disassembles binary file")
        .arg(
            Arg::with_name("file")
                .short("f")
                .long("file")
                .help("input file with binary instructions")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("stdin")
                .short("s")
                .long("stdin")
                .help("read binary instructions from stdin")
                .takes_value(false),
        )
        .arg(
            Arg::with_name("address")
                .short("r")
                .long("addr")
                .help("address of code")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("v")
                .short("v")
                .multiple(true)
                .help("Sets the level of verbosity"),
        )
        .arg(
            Arg::with_name("hex")
                .short("x")
                .long("hex")
                .help("Treat input has hex; only select characters that are [a-fA-F0-9]")
                .takes_value(false)
        )
        .arg(
            Arg::with_name("DETAIL")
                .short("d")
                .long("detail")
                .help("Print details about instructions")
                .takes_value(false)
        )
        .arg(
            Arg::with_name("ARCH")
                .short("a")
                .long("arch")
                .help("Architecture")
                .takes_value(true)
                .required(true)
                .possible_values(arches.as_slice())
                .case_insensitive(true),
        )
        .arg(
            Arg::with_name("MODE")
                .short("m")
                .long("mode")
                .help("Mode")
                .takes_value(true)
                .required(true)
                .possible_values(modes.as_slice())
                .case_insensitive(true),
        )
        .arg(
            Arg::with_name("EXTRA_MODE")
                .short("e")
                .long("extra")
                .help("Extra Mode")
                .takes_value(true)
                .required(false)
                .possible_values(extra_modes.as_slice())
                .case_insensitive(true)
                .multiple(true),
        )
        .group(
            ArgGroup::with_name("INPUT")
                .arg("file")
                .arg("stdin")
                .required(true),
        )
        .get_matches();

    let direct_input_bytes: Vec<u8> = match matches.value_of("INPUT") {
        Some(file_path) => {
            let mut file = File::open(file_path).expect_exit();
            let capacity = match file.metadata() {
                Err(_) => DEFAULT_CAPACITY,
                Ok(metadata) => metadata.len() as usize,
            };
            let mut buf = Vec::with_capacity(capacity as usize);
            file.read_to_end(&mut buf).expect_exit();
            buf
        }
        None => {
            let mut buf = Vec::with_capacity(DEFAULT_CAPACITY);
            let mut stdin = std::io::stdin();
            let mut stdin = stdin.lock();
            stdin.read_to_end(&mut buf).expect_exit();
            buf
        }
    };

    stderrlog::new()
        .verbosity(matches.occurrences_of("v") as usize)
        .init()
        .unwrap();

    let is_hex = matches.is_present("hex");
    info!("is_hex = {:?}", is_hex);

    let show_detail = matches.is_present("DETAIL");
    info!("show_detail = {:?}", show_detail);

    let arch: Arch = ArchArg::from_str(matches.value_of("ARCH").unwrap())
        .unwrap()
        .into();
    info!("Arch = {:?}", arch);

    let mode: Mode = ModeArg::from_str(matches.value_of("MODE").unwrap())
        .unwrap()
        .into();
    info!("Mode = {:?}", mode);

    let extra_mode: Vec<_> = match matches.values_of("EXTRA_MODE") {
        None => Vec::with_capacity(0),
        Some(x) => x.map(|x| ExtraMode::from(ExtraModeArg::from_str(x).unwrap()))
            .collect(),
    };
    info!("ExtraMode = {:?}", extra_mode);

    let address =
        u64::from_str_radix(matches.value_of("address").unwrap_or("1000"), 16).expect_exit();
    info!("Address = 0x{:x}", address);

    let input_bytes = if is_hex {
        unhexed_bytes(direct_input_bytes)
    } else {
        direct_input_bytes
    };

    disasm(
        arch,
        mode,
        extra_mode.iter().map(|x| *x),
        None,
        input_bytes.as_slice(),
        address,
        show_detail,
    );
}
<|endoftext|>


<commit_before>extern crate ggez;
extern crate specs;

use ggez::{Game, State, GameError};
use std::time::Duration;
use specs::{Join, World};

struct Transform {
    position: (u32, u32),
    rotation: f32,
}

impl specs::Component for Transform {
    type Storage = specs::VecStorage<Transform>;
}

struct MainState {
    planner: specs::Planner<()>,
}

impl MainState {
    fn new() -> MainState {
        let mut world = specs::World::new();
        world.register::<Transform>();
        world.create_now()
             .with(Transform {
                 position: (50, 50),
                 rotation: 0f32,
             })
             .build();
        MainState { planner: specs::Planner::new(world, 4) }
    }
}

impl State for MainState {
    fn load(&mut self) -> Result<(), GameError> {
        println!("load");
        Ok(())
    }

    fn update(&mut self, dt: Duration) -> Result<(), GameError> {
        println!("update");
        Ok(())
    }

    fn draw(&mut self) -> Result<(), GameError> {
        println!("draw");
        Ok(())
    }
}

pub fn main() {
    let mut g = MainState::new();
    let mut e: Game<MainState> = Game::new(g);
    e.run();
}
<commit_msg>Run a system in update<commit_after>extern crate ggez;
extern crate specs;

use ggez::{Game, State, GameError};
use std::time::Duration;
use specs::{Join, World};

struct Transform {
    position: (u32, u32),
    rotation: f32,
}

impl specs::Component for Transform {
    type Storage = specs::VecStorage<Transform>;
}

struct MainState {
    planner: specs::Planner<()>,
}

impl MainState {
    fn new() -> MainState {
        let mut world = specs::World::new();
        world.register::<Transform>();
        world.create_now()
             .with(Transform {
                 position: (50, 50),
                 rotation: 0f32,
             })
             .build();
        MainState { planner: specs::Planner::new(world, 4) }
    }
}

impl State for MainState {
    fn load(&mut self) -> Result<(), GameError> {
        println!("load");
        Ok(())
    }

    fn update(&mut self, dt: Duration) -> Result<(), GameError> {
        self.planner.run1w0r(|t: &mut Transform| {
            t.position.0 += 1;
            t.position.1 += 1;
        });
        Ok(())
    }

    fn draw(&mut self) -> Result<(), GameError> {
        println!("draw");
        Ok(())
    }
}

pub fn main() {
    let mut g = MainState::new();
    let mut e: Game<MainState> = Game::new(g);
    e.run();
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate hyperlocal;

use hyper::server::{Request, Response};
use hyperlocal::UnixSocketServer;

fn main() {
    let path = "test.sock";
    let server = UnixSocketServer::new(path).unwrap();
    server.handle(|_: Request, res: Response| {
        let _ = res.send(b"It's a Unix system. I know this.");
    }).unwrap();
    println!("listening @ {}", path);

}
<commit_msg>spacing<commit_after>extern crate hyper;
extern crate hyperlocal;

use hyper::server::{Request, Response};
use hyperlocal::UnixSocketServer;

fn main() {
    let path = "test.sock";
    let server = UnixSocketServer::new(path).unwrap();
    server.handle(|_: Request, res: Response| {
        let _ = res.send(b"It's a Unix system. I know this.");
    }).unwrap();
    println!("listening @ {}", path);
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]

extern crate civet;
extern crate conduit;
extern crate green;
extern crate rustuv;

use std::io::{IoResult,MemReader,MemWriter};
use std::collections::HashMap;

use civet::{Config, Server, response};
use conduit::{Request, Response};

macro_rules! http_write(
    ($dst:expr, $fmt:expr $($arg:tt)*) => (
        try!(write!($dst, concat!($fmt, "\r\n") $($arg)*))
    )
)

fn main() {
    let _a = Server::start(Config { port: 8888, threads: 50 }, handler);
    wait_for_sigint();
}

// libnative doesn't have signal handling yet
fn wait_for_sigint() {
    use green::{SchedPool, PoolConfig, GreenTaskBuilder};
    use std::io::signal::{Listener, Interrupt};
    use std::task::TaskBuilder;

    let mut config = PoolConfig::new();
    config.event_loop_factory = rustuv::event_loop;

    let mut pool = SchedPool::new(config);
    TaskBuilder::new().green(&mut pool).spawn(proc() {
        let mut l = Listener::new();
        l.register(Interrupt).unwrap();
        l.rx.recv();
    });
    pool.shutdown();
}

fn handler(req: &mut Request) -> IoResult<Response> {
    let mut res = MemWriter::with_capacity(10000);

    http_write!(res, "");
    http_write!(res, "
HTTP {}
", req.http_version());
    http_write!(res, "
Method: {}
", req.method());
    http_write!(res, "
Scheme: {}
", req.scheme());
    http_write!(res, "
Host: {}
", req.host());
    http_write!(res, "
Path: {}
", req.path());
    http_write!(res, "
Query String: {}
", req.query_string());
    http_write!(res, "
Remote IP: {}
", req.remote_ip());
    http_write!(res, "
Content Length: {}
", req.content_length());

    http_write!(res, "
Input: {}", req.body().read_to_str());

    http_write!(res, "
Headers

");

    for (key, value) in req.headers().iter() {
        http_write!(res, "
{} = {}
", key, value);
    }

    http_write!(res, "
");

    let mut headers = HashMap::new();
    headers.insert("Content-Type".to_str(), vec!("text/html".to_str()));

    let body = MemReader::new(res.unwrap());

    Ok(response(200, headers, body))
}
<commit_msg>Update to latest conduit<commit_after>#![feature(macro_rules)]

extern crate civet;
extern crate conduit;
extern crate green;
extern crate rustuv;

use std::io::{MemReader,MemWriter};
use std::collections::HashMap;
use std::fmt::Show;

use civet::{Config, Server, response};
use conduit::{Request, Response};

macro_rules! http_write(
    ($dst:expr, $fmt:expr $($arg:tt)*) => (
        try!(write!($dst, concat!($fmt, "\r\n") $($arg)*).map_err(|e| box e as Box<Show>))
    )
)

fn main() {
    let _a = Server::start(Config { port: 8888, threads: 50 }, handler);
    wait_for_sigint();
}

// libnative doesn't have signal handling yet
fn wait_for_sigint() {
    use green::{SchedPool, PoolConfig, GreenTaskBuilder};
    use std::io::signal::{Listener, Interrupt};
    use std::task::TaskBuilder;

    let mut config = PoolConfig::new();
    config.event_loop_factory = rustuv::event_loop;

    let mut pool = SchedPool::new(config);
    TaskBuilder::new().green(&mut pool).spawn(proc() {
        let mut l = Listener::new();
        l.register(Interrupt).unwrap();
        l.rx.recv();
    });
    pool.shutdown();
}

fn handler(req: &mut Request) -> Result<Response, Box<Show>> {
    let mut res = MemWriter::with_capacity(10000);

    http_write!(res, "");
    http_write!(res, "
HTTP {}
", req.http_version());
    http_write!(res, "
Method: {}
", req.method());
    http_write!(res, "
Scheme: {}
", req.scheme());
    http_write!(res, "
Host: {}
", req.host());
    http_write!(res, "
Path: {}
", req.path());
    http_write!(res, "
Query String: {}
", req.query_string());
    http_write!(res, "
Remote IP: {}
", req.remote_ip());
    http_write!(res, "
Content Length: {}
", req.content_length());

    http_write!(res, "
Input: {}", req.body().read_to_str());

    http_write!(res, "
Headers

");

    for (key, value) in req.headers().iter() {
        http_write!(res, "
{} = {}
", key, value);
    }

    http_write!(res, "
");

    let mut headers = HashMap::new();
    headers.insert("Content-Type".to_str(), vec!("text/html".to_str()));

    let body = MemReader::new(res.unwrap());

    Ok(response(200, headers, body))
}
<|endoftext|>


<commit_before>extern crate par;

fn main() {
    let mut bar = par::Bar::new(
        100
   );
    bar.prefix = String::from("dl ");
    for _ in 1..101 {
        bar.incr();
        std::thread::sleep_ms(10);
    }
    bar.finish_print("done");
}
<commit_msg>codestyle<commit_after>extern crate par;

fn main() {
    let mut bar = par::Bar::new(100);
    bar.prefix = String::from("dl ");
    for _ in 1..101 {
        bar.incr();
        std::thread::sleep_ms(10);
    }
    bar.finish_print("done");
}
<|endoftext|>


<commit_before>extern crate syscall;

use std::{env, mem, slice, thread};
use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::{AsRawFd, RawFd};
use std::cell::Cell;

use color::Color;
use event::{Event, EVENT_RESIZE};
use renderer::Renderer;
use WindowFlag;
use Mode;

pub fn get_display_size() -> Result<(u32, u32), String> {
    let display_path = try!(env::var("DISPLAY").or(Err("DISPLAY not set")));
    match File::open(&display_path) {
        Ok(display) => {
            let mut buf: [u8; 4096] = [0; 4096];
            let count = syscall::fpath(display.as_raw_fd() as usize, &mut buf).map_err(|err| format!("{}", err))?;
            let path = unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) };
            let res = path.split(":").nth(1).unwrap_or("");
            let width = res.split("/").nth(1).unwrap_or("").parse::<u32>().unwrap_or(0);
            let height = res.split("/").nth(2).unwrap_or("").parse::<u32>().unwrap_or(0);
            Ok((width, height))
        },
        Err(err) => Err(format!("{}", err))
    }
}

/// A window
pub struct Window {
    /// The x coordinate of the window
    x: i32,
    /// The y coordinate of the window
    y: i32,
    /// The width of the window
    w: u32,
    /// The height of the window
    h: u32,
    /// The title of the window
    t: String,
    /// True if the window should not wait for events
    async: bool,
    /// True if the window can be resized
    resizable: bool,
    /// Drawing mode
    mode: Cell<Mode>,
    /// The input scheme
    file: File,
    /// Window data
    data: &'static mut [Color],
}

impl Renderer for Window {
    /// Get width
    fn width(&self) -> u32 {
        self.w
    }

    /// Get height
    fn height(&self) -> u32 {
        self.h
    }

    /// Access pixel buffer
    fn data(&self) -> &[Color] {
        &self.data
    }

    /// Access pixel buffer mutably
    fn data_mut(&mut self) -> &mut [Color] {
        &mut self.data
    }

    /// Flip the buffer
    fn sync(&mut self) -> bool {
        self.file.sync_data().is_ok()
    }

    /// Set/get mode
    fn mode(&self) -> &Cell<Mode> {
        &self.mode
    }
}

impl Window {
    /// Create a new window
    pub fn new(x: i32, y: i32, w: u32, h: u32, title: &str) -> Option<Self> {
        Window::new_flags(x, y, w, h, title, &[])
    }

    /// Create a new window with flags
    pub fn new_flags(x: i32, y: i32, w: u32, h: u32, title: &str, flags: &[WindowFlag]) -> Option<Self> {
        let mut flag_str = String::new();

        let mut async = false;
        let mut resizable = false;
        for &flag in flags.iter() {
            match flag {
                WindowFlag::Async => {
                    async = true;
                    flag_str.push('a');
                },
                WindowFlag::Back => flag_str.push('b'),
                WindowFlag::Front => flag_str.push('f'),
                WindowFlag::Borderless => flag_str.push('l'),
                WindowFlag::Resizable => {
                    resizable = true;
                    flag_str.push('r');
                },
                WindowFlag::Unclosable => flag_str.push('u'),
            }
        }

        if let Ok(file) = File::open(&format!(
            "orbital:{}/{}/{}/{}/{}/{}",
            flag_str, x, y, w, h, title
        )) {
            if let Ok(address) = unsafe { syscall::fmap(file.as_raw_fd(), 0, (w * h * 4) as usize) } {
                Some(Window {
                    x: x,
                    y: y,
                    w: w,
                    h: h,
                    t: title.to_string(),
                    async: async,
                    resizable: resizable,
                    mode: Cell::new(Mode::Blend),
                    file: file,
                    data: unsafe { slice::from_raw_parts_mut(address as *mut Color, (w * h) as usize) },
                })
            } else {
                None
            }
        } else {
            None
        }
    }

    // TODO: Replace with smarter mechanism, maybe a move event?
    pub fn sync_path(&mut self) {
        let mut buf: [u8; 4096] = [0; 4096];
        if let Ok(count) = syscall::fpath(self.file.as_raw_fd() as usize, &mut buf) {
            let path = unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) };
            // orbital:/x/y/w/h/t
            let mut parts = path.split('/').skip(1);
            if let Some(x) = parts.next() {
                self.x = x.parse::<i32>().unwrap_or(0);
            }
            if let Some(y) = parts.next() {
                self.y = y.parse::<i32>().unwrap_or(0);
            }
            if let Some(w) = parts.next() {
                self.w = w.parse::<u32>().unwrap_or(0);
            }
            if let Some(h) = parts.next() {
                self.h = h.parse::<u32>().unwrap_or(0);
            }
        }
    }

    /// Get x
    // TODO: Sync with window movements
    pub fn x(&self) -> i32 {
        self.x
    }

    /// Get y
    // TODO: Sync with window movements
    pub fn y(&self) -> i32 {
        self.y
    }

    /// Get title
    pub fn title(&self) -> String {
        self.t.clone()
    }

    // Set position
    pub fn set_pos(&mut self, x: i32, y: i32) {
        let _ = self.file.write(&format!("P,{},{}", x, y).as_bytes());
        self.sync_path();
    }

    // Set size
    pub fn set_size(&mut self, width: u32, height: u32) {
        //TODO: Improve safety and reliability
        unsafe {
            syscall::funmap(self.data.as_ptr() as usize).expect("orbclient: failed to unmap memory in resize");
        }
        let _ = self.file.write(&format!("S,{},{}", width, height).as_bytes());
        self.sync_path();
        unsafe {
            let address = syscall::fmap(self.file.as_raw_fd(), 0, (self.w * self.h * 4) as usize).expect("orbclient: failed to map memory in resize");
            self.data = slice::from_raw_parts_mut(address as *mut Color, (self.w * self.h) as usize);
        }
    }

    /// Set title
    pub fn set_title(&mut self, title: &str) {
        let _ = self.file.write(&format!("T,{}", title).as_bytes());
        self.sync_path();
    }

    /// Blocking iterator over events
    pub fn events(&mut self) -> EventIter {
        let mut iter = EventIter {
            events: [Event::new(); 16],
            i: 0,
            count: 0,
        };

        'blocking: loop {
            //Should it be cleared? iter.events = [Event::new(); 128];
            match self.file.read(unsafe {
                slice::from_raw_parts_mut(iter.events.as_mut_ptr() as *mut u8, iter.events.len() * mem::size_of::<Event>())
            }){
                Ok(0) => if ! self.async {
                    thread::yield_now();
                } else {
                    break 'blocking;
                },
                Ok(count) => {
                    iter.count = count/mem::size_of::<Event>();
                    if self.resizable {
                        let mut resize = None;
                        for i in 0..iter.count {
                            let event = &iter.events[i];
                            if event.code == EVENT_RESIZE {
                                resize = Some((event.a as u32, event.b as u32));
                            }
                        }
                        if let Some((w, h)) = resize {
                            self.set_size(w, h);
                        }
                    }
                    break 'blocking;
                },
                Err(_) => break 'blocking,
            }
        }

        iter
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        let _ = unsafe { syscall::funmap(self.data.as_ptr() as usize) };
    }
}

impl AsRawFd for Window {
    fn as_raw_fd(&self) -> RawFd {
        self.file.as_raw_fd()
    }
}

/// Event iterator
pub struct EventIter {
    events: [Event; 16],
    i: usize,
    count: usize,
}

impl Iterator for EventIter {
    type Item = Event;
    fn next(&mut self) -> Option<Event> {
        if self.i < self.count {
            if let Some(event) = self.events.get(self.i) {
                self.i += 1;
                Some(*event)
            } else {
                None
            }
        } else {
            None
        }
    }
}
<commit_msg>Fix issue with edge-triggered orbital<commit_after>extern crate syscall;

use std::{env, mem, slice, thread};
use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::{AsRawFd, RawFd};
use std::cell::Cell;

use color::Color;
use event::{Event, EVENT_RESIZE};
use renderer::Renderer;
use WindowFlag;
use Mode;

pub fn get_display_size() -> Result<(u32, u32), String> {
    let display_path = try!(env::var("DISPLAY").or(Err("DISPLAY not set")));
    match File::open(&display_path) {
        Ok(display) => {
            let mut buf: [u8; 4096] = [0; 4096];
            let count = syscall::fpath(display.as_raw_fd() as usize, &mut buf).map_err(|err| format!("{}", err))?;
            let path = unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) };
            let res = path.split(":").nth(1).unwrap_or("");
            let width = res.split("/").nth(1).unwrap_or("").parse::<u32>().unwrap_or(0);
            let height = res.split("/").nth(2).unwrap_or("").parse::<u32>().unwrap_or(0);
            Ok((width, height))
        },
        Err(err) => Err(format!("{}", err))
    }
}

/// A window
pub struct Window {
    /// The x coordinate of the window
    x: i32,
    /// The y coordinate of the window
    y: i32,
    /// The width of the window
    w: u32,
    /// The height of the window
    h: u32,
    /// The title of the window
    t: String,
    /// True if the window should not wait for events
    async: bool,
    /// True if the window can be resized
    resizable: bool,
    /// Drawing mode
    mode: Cell<Mode>,
    /// The input scheme
    file: File,
    /// Window data
    data: &'static mut [Color],
}

impl Renderer for Window {
    /// Get width
    fn width(&self) -> u32 {
        self.w
    }

    /// Get height
    fn height(&self) -> u32 {
        self.h
    }

    /// Access pixel buffer
    fn data(&self) -> &[Color] {
        &self.data
    }

    /// Access pixel buffer mutably
    fn data_mut(&mut self) -> &mut [Color] {
        &mut self.data
    }

    /// Flip the buffer
    fn sync(&mut self) -> bool {
        self.file.sync_data().is_ok()
    }

    /// Set/get mode
    fn mode(&self) -> &Cell<Mode> {
        &self.mode
    }
}

impl Window {
    /// Create a new window
    pub fn new(x: i32, y: i32, w: u32, h: u32, title: &str) -> Option<Self> {
        Window::new_flags(x, y, w, h, title, &[])
    }

    /// Create a new window with flags
    pub fn new_flags(x: i32, y: i32, w: u32, h: u32, title: &str, flags: &[WindowFlag]) -> Option<Self> {
        let mut flag_str = String::new();

        let mut async = false;
        let mut resizable = false;
        for &flag in flags.iter() {
            match flag {
                WindowFlag::Async => {
                    async = true;
                    flag_str.push('a');
                },
                WindowFlag::Back => flag_str.push('b'),
                WindowFlag::Front => flag_str.push('f'),
                WindowFlag::Borderless => flag_str.push('l'),
                WindowFlag::Resizable => {
                    resizable = true;
                    flag_str.push('r');
                },
                WindowFlag::Unclosable => flag_str.push('u'),
            }
        }

        if let Ok(file) = File::open(&format!(
            "orbital:{}/{}/{}/{}/{}/{}",
            flag_str, x, y, w, h, title
        )) {
            if let Ok(address) = unsafe { syscall::fmap(file.as_raw_fd(), 0, (w * h * 4) as usize) } {
                Some(Window {
                    x: x,
                    y: y,
                    w: w,
                    h: h,
                    t: title.to_string(),
                    async: async,
                    resizable: resizable,
                    mode: Cell::new(Mode::Blend),
                    file: file,
                    data: unsafe { slice::from_raw_parts_mut(address as *mut Color, (w * h) as usize) },
                })
            } else {
                None
            }
        } else {
            None
        }
    }

    // TODO: Replace with smarter mechanism, maybe a move event?
    pub fn sync_path(&mut self) {
        let mut buf: [u8; 4096] = [0; 4096];
        if let Ok(count) = syscall::fpath(self.file.as_raw_fd() as usize, &mut buf) {
            let path = unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) };
            // orbital:/x/y/w/h/t
            let mut parts = path.split('/').skip(1);
            if let Some(x) = parts.next() {
                self.x = x.parse::<i32>().unwrap_or(0);
            }
            if let Some(y) = parts.next() {
                self.y = y.parse::<i32>().unwrap_or(0);
            }
            if let Some(w) = parts.next() {
                self.w = w.parse::<u32>().unwrap_or(0);
            }
            if let Some(h) = parts.next() {
                self.h = h.parse::<u32>().unwrap_or(0);
            }
        }
    }

    /// Get x
    // TODO: Sync with window movements
    pub fn x(&self) -> i32 {
        self.x
    }

    /// Get y
    // TODO: Sync with window movements
    pub fn y(&self) -> i32 {
        self.y
    }

    /// Get title
    pub fn title(&self) -> String {
        self.t.clone()
    }

    // Set position
    pub fn set_pos(&mut self, x: i32, y: i32) {
        let _ = self.file.write(&format!("P,{},{}", x, y).as_bytes());
        self.sync_path();
    }

    // Set size
    pub fn set_size(&mut self, width: u32, height: u32) {
        //TODO: Improve safety and reliability
        unsafe {
            syscall::funmap(self.data.as_ptr() as usize).expect("orbclient: failed to unmap memory in resize");
        }
        let _ = self.file.write(&format!("S,{},{}", width, height).as_bytes());
        self.sync_path();
        unsafe {
            let address = syscall::fmap(self.file.as_raw_fd(), 0, (self.w * self.h * 4) as usize).expect("orbclient: failed to map memory in resize");
            self.data = slice::from_raw_parts_mut(address as *mut Color, (self.w * self.h) as usize);
        }
    }

    /// Set title
    pub fn set_title(&mut self, title: &str) {
        let _ = self.file.write(&format!("T,{}", title).as_bytes());
        self.sync_path();
    }

    /// Blocking iterator over events
    pub fn events(&mut self) -> EventIter {
        let mut iter = EventIter {
            extra: None,
            events: [Event::new(); 16],
            i: 0,
            count: 0
        };

        'blocking: loop {
            if iter.events.len() - iter.count == 0 {
                if iter.extra.is_none() {
                    iter.extra = Some(Vec::with_capacity(32));
                }
                iter.extra.as_mut().unwrap().extend(&iter.events);
                iter.count = 0;
            }
            let bytes = unsafe { slice::from_raw_parts_mut(
                iter.events[iter.count..].as_mut_ptr() as *mut u8,
                iter.events[iter.count..].len() * mem::size_of::<Event>()
            ) };
            match self.file.read(bytes) {
                Ok(0) => if !self.async
                        && iter.extra.is_none()
                        && iter.events.len() == 0 {
                    thread::yield_now();
                } else {
                    break 'blocking;
                },
                Ok(count) => {
                    let count = count / mem::size_of::<Event>();
                    let events = &iter.events[iter.count..][..count];
                    iter.count += count;

                    if self.resizable {
                        let mut resize = None;
                        for event in events {
                            let event = *event;
                            if event.code == EVENT_RESIZE {
                                resize = Some((event.a as u32, event.b as u32));
                            }
                        }
                        if let Some((w, h)) = resize {
                            self.set_size(w, h);
                        }
                    }
                },
                Err(_) => break 'blocking,
            }
        }

        iter
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        let _ = unsafe { syscall::funmap(self.data.as_ptr() as usize) };
    }
}

impl AsRawFd for Window {
    fn as_raw_fd(&self) -> RawFd {
        self.file.as_raw_fd()
    }
}

/// Event iterator
pub struct EventIter {
    extra: Option<Vec<Event>>,
    events: [Event; 16],
    i: usize,
    count: usize
}

impl Iterator for EventIter {
    type Item = Event;
    fn next(&mut self) -> Option<Event> {
        let mut i = self.i;
        if let Some(ref mut extra) = self.extra {
            if i < extra.len() {
                if let Some(event) = extra.get(i) {
                    self.i += 1;
                    return Some(*event);
                }
            }
            i -= extra.len();
        }
        if i < self.count {
            if let Some(event) = self.events.get(i) {
                self.i += 1;
                return Some(*event);
            }
        }
        None
    }
}
<|endoftext|>


<commit_before>#![crate_type = "lib"]
#![crate_name = "bit-ops"]

pub mod algebra;

#[test]
fn test_adding () {
    let a = 3i8;
    let b = 6i8;
    assert!(a + b == algebra::add(a, b));
}

#[test]
fn test_subtracting () {
    let a = 9i8;
    let b = 3i8;

    let result = a - b == algebra::subtract(a, b);
    assert!(result);

    for minuend in range(0i8, 128) {
        for subtrahend in range(0i8, 128) {
            let result = minuend - subtrahend == algebra::subtract(minuend, subtrahend);
            assert!(result);
        }
    }

}

#[test]
fn test_gt () {
     for a in range(-10i8, 20i8) {
        for b in range (-10i8, 20i8) {
            assert!(a > b == algebra::gt(a, b), format!("{} > {} == a > b", a, b));
        }
    }
}

#[test]
fn test_lt () {
     for a in range(-10i8, 20i8) {
        for b in range (-10i8, 20i8) {
            assert!(a < b == algebra::lt(a, b), format!("{} < {} == {} ", a, b, a < b));
        }
    }
}

#[test]
fn test_hemming () {
    use algebra::hemming;

    let result = hemming(1i8);
    assert!(result == 1i8);

    let result = hemming(2i8);
    assert!(result == 1i8);

    let result = hemming(3i8);
    assert!(result == 2i8);

    let result = hemming(4i8);
    assert!(result == 1i8);

    let result = hemming(5i8);
    assert!(result == 2i8);

}
<commit_msg>better clearer tests for hemming<commit_after>#![crate_type = "lib"]
#![crate_name = "bit-ops"]

pub mod algebra;

#[test]
fn test_adding () {
    let a = 3i8;
    let b = 6i8;
    assert!(a + b == algebra::add(a, b));
}

#[test]
fn test_subtracting () {
    let a = 9i8;
    let b = 3i8;

    let result = a - b == algebra::subtract(a, b);
    assert!(result);

    for minuend in range(0i8, 128) {
        for subtrahend in range(0i8, 128) {
            let result = minuend - subtrahend == algebra::subtract(minuend, subtrahend);
            assert!(result);
        }
    }

}

#[test]
fn test_gt () {
     for a in range(-10i8, 20i8) {
        for b in range (-10i8, 20i8) {
            assert!(a > b == algebra::gt(a, b), format!("{} > {} == a > b", a, b));
        }
    }
}

#[test]
fn test_lt () {
     for a in range(-10i8, 20i8) {
        for b in range (-10i8, 20i8) {
            assert!(a < b == algebra::lt(a, b), format!("{} < {} == {} ", a, b, a < b));
        }
    }
}

#[test]
fn test_hemming () {
    use algebra::hemming;

    let result = hemming(1i8);
    assert!(result == 1i8);

    let result = hemming(2i8);
    assert!(result == 1i8);

    let result = hemming(3i8);
    assert!(result == 2i8);

    let result = hemming(4i8);
    assert!(result == 1i8);

    let result = hemming(5i8);
    assert!(result == 2i8);

    let result = hemming(6i8);
    assert!(result == 2i8);

    let result = hemming(0b0101_1100 as i8);
    assert!(result == 4i8);

    let result = hemming(0b0101_1101 as i8);
    assert!(result == 5i8);
}
<|endoftext|>


<commit_before>use banko::Row;
use combinations::Combination;
use std::u8;
use typenum::consts::*;

pub struct RowTable {
    table: [[[[[[[[[u8; 2]; 2]; 2]; 2]; 2]; 2]; 2]; 2]; 2],
}

impl RowTable {
    #[inline]
    pub fn get(&self, index: Row) -> Option<u8> {
        let result = self.table[index[0].is_some() as usize][index[1].is_some() as usize]
            [index[2].is_some() as usize][index[3].is_some() as usize][index[4].is_some() as usize]
            [index[5].is_some() as usize][index[6].is_some() as usize][index[7].is_some() as usize]
            [index[8].is_some() as usize];

        if result == u8::MAX {
            None
        } else {
            Some(result)
        }
    }
}

impl Default for RowTable {
    #[inline]
    fn default() -> RowTable {
        let mut table = [[[[[[[[[u8::MAX; 2]; 2]; 2]; 2]; 2]; 2]; 2]; 2]; 2];

        for (ndx, comb) in Combination::<U8, U5>::new().enumerate() {
            let mut pos = [0; 9];
            for c in comb {
                pos[c as usize] = 1;
            }

            table[pos[0]][pos[1]][pos[2]][pos[3]][pos[4]][pos[5]][pos[6]][pos[7]][pos[8]] =
                ndx as u8;
        }

        RowTable { table }
    }
}

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

    #[test]
    fn test_row_table() {
        let row_table = RowTable::default();
        let mut seen = 0;
        for n in 0..=0b111111111 {
            let mut index = [None; 9];
            let mut count = 0;
            for k in 0..9 {
                if n & (1 << k) != 0 {
                    index[k] = NonZeroU8::new(1);
                    count += 1;
                }
            }

            if count != 5 {
                assert!(row_table.get(index).is_none());
            } else {
                assert_eq!(row_table.get(index), Some(seen));
                seen += 1;
            }
        }
    }
}
<commit_msg>Fix a test<commit_after>use banko::Row;
use combinations::Combination;
use std::u8;
use typenum::consts::*;

pub struct RowTable {
    table: [[[[[[[[[u8; 2]; 2]; 2]; 2]; 2]; 2]; 2]; 2]; 2],
}

impl RowTable {
    #[inline]
    pub fn get(&self, index: Row) -> Option<u8> {
        let result = self.table[index[0].is_some() as usize][index[1].is_some() as usize]
            [index[2].is_some() as usize][index[3].is_some() as usize][index[4].is_some() as usize]
            [index[5].is_some() as usize][index[6].is_some() as usize][index[7].is_some() as usize]
            [index[8].is_some() as usize];

        if result == u8::MAX {
            None
        } else {
            Some(result)
        }
    }
}

impl Default for RowTable {
    #[inline]
    fn default() -> RowTable {
        let mut table = [[[[[[[[[u8::MAX; 2]; 2]; 2]; 2]; 2]; 2]; 2]; 2]; 2];

        for (ndx, comb) in Combination::<U8, U5>::new().enumerate() {
            let mut pos = [0; 9];
            for c in comb {
                pos[c as usize] = 1;
            }

            table[pos[0]][pos[1]][pos[2]][pos[3]][pos[4]][pos[5]][pos[6]][pos[7]][pos[8]] =
                ndx as u8;
        }

        RowTable { table }
    }
}

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

    #[test]
    fn test_row_table() {
        let row_table = RowTable::default();
        let mut seen = 0;
        for n in 0..=0b111111111 {
            let mut index = [None; 9];
            let mut count = 0;
            for k in 0..9 {
                if n & (1 << k) != 0 {
                    index[k] = NonZeroU8::new(1);
                    count += 1;
                }
            }

            if count != 5 {
                assert!(row_table.get(index).is_none());
            } else {
                assert_eq!(row_table.get(index), Some(seen));
                seen += 1;
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::convert::From;
use std::io;
use std::error::Error as StdError;
use std::result;

use nix;

pub type Result<T> = result::Result<T, Error>;

/// An error arising from terminal operations.
///
/// The lower-level cause of the error, if any, will be returned by calling `cause()`.
///
/// **Note:** Errors arising from system calls will return `None` when calling `cause()` as `nix`
/// errors do not implement `Error`. In this case, `description()` will return the standard `errno`
/// description.
#[derive(Debug)]
pub struct Error {
    err: Box<StdError + Send + Sync>,
}

impl Error {
    pub fn new<E>(error: E) -> Error
        where E: Into<Box<StdError + Send + Sync>>
    {
        let err = error.into();
        Error {
            err: err,
        }
    }
}

impl StdError for Error {
    fn description(&self) -> &str {
        self.err.description()
    }

    fn cause(&self) -> Option<&StdError> {
        self.err.cause()
    }
}

impl From<nix::Error> for Error {
    fn from(err: nix::Error) -> Self {
        Error::new(err.errno().desc())
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Self {
        Error::new(err)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.err.fmt(f)
    }
}

<commit_msg>small docs change in errors.rs<commit_after>use std::fmt;
use std::convert::From;
use std::io;
use std::error::Error as StdError;
use std::result;

use nix;

pub type Result<T> = result::Result<T, Error>;

/// An error arising from terminal operations.
///
/// The lower-level cause of the error, if any, will be returned by calling `cause()`.
#[derive(Debug)]
pub struct Error {
    err: Box<StdError + Send + Sync>,
}

impl Error {
    pub fn new<E>(error: E) -> Error
        where E: Into<Box<StdError + Send + Sync>>
    {
        let err = error.into();
        Error {
            err: err,
        }
    }
}

impl StdError for Error {
    fn description(&self) -> &str {
        self.err.description()
    }

    fn cause(&self) -> Option<&StdError> {
        self.err.cause()
    }
}

impl From<nix::Error> for Error {
    fn from(err: nix::Error) -> Self {
        Error::new(err.errno().desc())
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Self {
        Error::new(err)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.err.fmt(f)
    }
}

<|endoftext|>


<commit_before>use criterion::BenchmarkId;
use criterion::Criterion;
use criterion::{criterion_group, criterion_main};

// The benchmarks here verify that the complexity grows as O(*n*)
// where *n* is the number of characters in the text to be wrapped.

use lipsum::lipsum_words_from_seed;

const LINE_LENGTH: usize = 60;

/// Generate a lorem ipsum text with the given number of characters.
fn lorem_ipsum(length: usize) -> String {
    // The average word length in the lorem ipsum text is somewhere
    // between 6 and 7. So we conservatively divide by 5 to have a
    // long enough text that we can truncate below.
    let mut text = lipsum_words_from_seed(length / 5, 42);
    text.truncate(length);
    text
}

pub fn benchmark(c: &mut Criterion) {
    let mut group = c.benchmark_group("String lengths");
    for length in [200, 300, 400, 600, 800, 1200, 1600, 2400, 3200, 4800, 6400].iter() {
        let text = lorem_ipsum(*length);

        #[cfg(feature = "smawk")]
        {
            #[cfg(feature = "unicode-linebreak")]
            {
                let options = textwrap::Options::new(LINE_LENGTH)
                    .wrap_algorithm(textwrap::core::WrapAlgorithm::OptimalFit)
                    .word_separator(textwrap::UnicodeBreakProperties);
                group.bench_with_input(
                    BenchmarkId::new("fill_optimal_fit_unicode", length),
                    &text,
                    |b, text| {
                        b.iter(|| textwrap::fill(text, &options));
                    },
                );
            }

            let options = textwrap::Options::new(LINE_LENGTH)
                .wrap_algorithm(textwrap::core::WrapAlgorithm::OptimalFit)
                .word_separator(textwrap::AsciiSpace);
            group.bench_with_input(
                BenchmarkId::new("fill_optimal_fit_ascii", length),
                &text,
                |b, text| {
                    b.iter(|| textwrap::fill(text, &options));
                },
            );
        }

        let options = textwrap::Options::new(LINE_LENGTH)
            .wrap_algorithm(textwrap::core::WrapAlgorithm::FirstFit)
            .word_separator(textwrap::AsciiSpace);
        group.bench_with_input(
            BenchmarkId::new("fill_first_fit", length),
            &text,
            |b, text| {
                b.iter(|| textwrap::fill(text, &options));
            },
        );

        group.bench_function(BenchmarkId::new("fill_inplace", length), |b| {
            b.iter_batched(
                || text.clone(),
                |mut text| textwrap::fill_inplace(&mut text, LINE_LENGTH),
                criterion::BatchSize::SmallInput,
            );
        });

        #[cfg(feature = "hyphenation")]
        {
            use hyphenation::{Language, Load, Standard};
            let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
                .join("benches")
                .join("la.standard.bincode");
            let dictionary = Standard::from_path(Language::Latin, &path).unwrap();
            let options = options.splitter(dictionary);
            group.bench_with_input(BenchmarkId::new("hyphenation", length), &text, |b, text| {
                b.iter(|| textwrap::fill(text, &options));
            });
        };
    }
    group.finish();
}

criterion_group!(benches, benchmark);
criterion_main!(benches);
<commit_msg>Shorten benchmark warm-up time<commit_after>use std::time::Duration;

use criterion::BenchmarkId;
use criterion::Criterion;
use criterion::{criterion_group, criterion_main};

// The benchmarks here verify that the complexity grows as O(*n*)
// where *n* is the number of characters in the text to be wrapped.

use lipsum::lipsum_words_from_seed;

const LINE_LENGTH: usize = 60;

/// Generate a lorem ipsum text with the given number of characters.
fn lorem_ipsum(length: usize) -> String {
    // The average word length in the lorem ipsum text is somewhere
    // between 6 and 7. So we conservatively divide by 5 to have a
    // long enough text that we can truncate below.
    let mut text = lipsum_words_from_seed(length / 5, 42);
    text.truncate(length);
    text
}

pub fn benchmark(c: &mut Criterion) {
    let mut group = c.benchmark_group("String lengths");
    for length in [200, 300, 400, 600, 800, 1200, 1600, 2400, 3200, 4800, 6400].iter() {
        let text = lorem_ipsum(*length);

        #[cfg(feature = "smawk")]
        {
            #[cfg(feature = "unicode-linebreak")]
            {
                let options = textwrap::Options::new(LINE_LENGTH)
                    .wrap_algorithm(textwrap::core::WrapAlgorithm::OptimalFit)
                    .word_separator(textwrap::UnicodeBreakProperties);
                group.bench_with_input(
                    BenchmarkId::new("fill_optimal_fit_unicode", length),
                    &text,
                    |b, text| {
                        b.iter(|| textwrap::fill(text, &options));
                    },
                );
            }

            let options = textwrap::Options::new(LINE_LENGTH)
                .wrap_algorithm(textwrap::core::WrapAlgorithm::OptimalFit)
                .word_separator(textwrap::AsciiSpace);
            group.bench_with_input(
                BenchmarkId::new("fill_optimal_fit_ascii", length),
                &text,
                |b, text| {
                    b.iter(|| textwrap::fill(text, &options));
                },
            );
        }

        let options = textwrap::Options::new(LINE_LENGTH)
            .wrap_algorithm(textwrap::core::WrapAlgorithm::FirstFit)
            .word_separator(textwrap::AsciiSpace);
        group.bench_with_input(
            BenchmarkId::new("fill_first_fit", length),
            &text,
            |b, text| {
                b.iter(|| textwrap::fill(text, &options));
            },
        );

        group.bench_function(BenchmarkId::new("fill_inplace", length), |b| {
            b.iter_batched(
                || text.clone(),
                |mut text| textwrap::fill_inplace(&mut text, LINE_LENGTH),
                criterion::BatchSize::SmallInput,
            );
        });

        #[cfg(feature = "hyphenation")]
        {
            use hyphenation::{Language, Load, Standard};
            let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
                .join("benches")
                .join("la.standard.bincode");
            let dictionary = Standard::from_path(Language::Latin, &path).unwrap();
            let options = options.splitter(dictionary);
            group.bench_with_input(BenchmarkId::new("hyphenation", length), &text, |b, text| {
                b.iter(|| textwrap::fill(text, &options));
            });
        };
    }
    group.finish();
}

criterion_group!(
    name = benches;
    config = Criterion::default().warm_up_time(Duration::from_millis(500));
    targets = benchmark
);
criterion_main!(benches);
<|endoftext|>