<commit_before>use std::ops::Deref;
use r2d2;
use r2d2_redis::RedisConnectionManager;
use redis::Commands;
use redis::RedisError;
use serde_json;
use rocket::response::status;
use rocket::http;

use db::redis::RedisConnection;
use domain::{SessionId, Todo, TodoFilter, TodoId};

impl Deref for RedisConnection {
    type Target = r2d2::PooledConnection<RedisConnectionManager>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

#[derive(Debug)]
pub enum RepositoryError {
    RedisErr(String),
    JsonErr(String),
}

pub struct Repository {
    session_id: SessionId,
    connection: RedisConnection,
}

impl From<RepositoryError> for status::Custom<String> {
    fn from(err: RepositoryError) -> Self {
        let message = match err {
            RepositoryError::RedisErr(msg) => msg,
            RepositoryError::JsonErr(msg) => msg,
        };

        status::Custom(http::Status::ServiceUnavailable, message)
    }
}

impl From<RedisError> for RepositoryError {
    fn from(err: RedisError) -> Self {
        RepositoryError::RedisErr(err.category().into())
    }
}

impl From<serde_json::Error> for RepositoryError {
    fn from(err: serde_json::Error) -> Self {
        RepositoryError::JsonErr(err.to_string())
    }
}

impl Repository {
    pub fn new(session_id: SessionId, connection: RedisConnection) -> Self {
        Repository {
            session_id: session_id,
            connection: connection,
        }
    }

    //
    // Commands
    //

    pub fn create(&self, description: &str) -> Result<(), RepositoryError> {
        let sequence_key = format!("todo_id_sequence:{}", self.session_id);
        let todo_id: TodoId = self.connection.incr(sequence_key, 1)?;
        let todo = Todo {
            id: todo_id,
            completed: false,
            description: description.to_string(),
        };
        let payload = serde_json::to_string(&todo)?;

        let _: () = self.connection.hset(&self.session_key(), todo_id, payload)?;

        Ok(())
    }

    pub fn clear(&self, todo_id: TodoId) -> Result<(), RepositoryError> {
        let _: () = self.connection
            .hdel(&self.session_key(), hash_field(todo_id))?;

        Ok(())
    }

    pub fn update_description(
        &self,
        todo_id: TodoId,
        description: &String,
    ) -> Result<(), RepositoryError> {
        self.update_todo(todo_id, &|t: &mut Todo| t.description = description.clone())
    }

    pub fn complete(&self, todo_id: TodoId) -> Result<(), RepositoryError> {
        self.update_todo(todo_id, &|t: &mut Todo| t.completed = true)
    }

    pub fn activate(&self, todo_id: TodoId) -> Result<(), RepositoryError> {
        self.update_todo(todo_id, &|t: &mut Todo| t.completed = false)
    }

    pub fn complete_all(&self) -> Result<(), RepositoryError> {
        self.active()?
            .into_iter()
            .map(|t| self.complete(t.id))
            .collect::<Result<Vec<()>, _>>()?;

        Ok(())
    }

    pub fn activate_all(&self) -> Result<(), RepositoryError> {
        self.completed()?
            .into_iter()
            .map(|t| self.activate(t.id))
            .collect::<Result<Vec<()>, _>>()?;

        Ok(())
    }

    pub fn clear_completed(&self) -> Result<(), RepositoryError> {
        self.completed()?
            .into_iter()
            .map(|t| self.clear(t.id))
            .collect::<Result<Vec<()>, _>>()?;

        Ok(())
    }

    //
    // Queries
    //

    pub fn list(&self, filter: &TodoFilter) -> Result<Vec<Todo>, RepositoryError> {
        match *filter {
            TodoFilter::All => self.all(),
            TodoFilter::Active => self.active(),
            TodoFilter::Completed => self.completed(),
        }
    }

    pub fn active_count(&self) -> Result<usize, RepositoryError> {
        Ok(self.active()?.len())
    }

    pub fn is_all_completed(&self) -> Result<bool, RepositoryError> {
        Ok(self.all()?.iter().all(|t| t.completed))
    }

    pub fn is_any_completed(&self) -> Result<bool, RepositoryError> {
        Ok(self.all()?.iter().any(|t| t.completed))
    }

    pub fn todo_count(&self) -> Result<usize, RepositoryError> {
        Ok(self.connection.hlen(self.session_key())?)
    }

    //
    // Private functions
    //

    fn all(&self) -> Result<Vec<Todo>, RepositoryError> {
        let ids_and_payloads: Vec<(usize, String)> = self.connection.hgetall(self.session_key())?;

        let todos = ids_and_payloads
            .into_iter()
            .map(|(_, payload)| serde_json::from_str(&payload))
            .flat_map(|r| r)
            .collect();

        Ok(todos)
    }

    fn active(&self) -> Result<Vec<Todo>, RepositoryError> {
        self.all()
            .map(|todos| todos.into_iter().filter(|t| !t.completed).collect())
    }

    fn completed(&self) -> Result<Vec<Todo>, RepositoryError> {
        self.all()
            .map(|todos| todos.into_iter().filter(|t| t.completed).collect())
    }

    fn update_todo(
        &self,
        todo_id: TodoId,
        updater: &Fn(&mut Todo) -> (),
    ) -> Result<(), RepositoryError> {
        let json: String = self.connection.hget(&self.session_key(), todo_id)?;
        let mut todo: Todo = serde_json::from_str(&json)?;

        updater(&mut todo);

        let updated_json = serde_json::to_string(&todo)?;
        let _: () = self.connection
            .hset(&self.session_key(), hash_field(todo_id), updated_json)?;

        Ok(())
    }

    fn session_key(&self) -> String {
        format!("todos:{}", self.session_id)
    }
}

fn hash_field(todo_id: TodoId) -> String {
    format!("{}", todo_id)
}
<commit_msg>Sort todo list by creation order<commit_after>use std::ops::Deref;
use r2d2;
use r2d2_redis::RedisConnectionManager;
use redis::Commands;
use redis::RedisError;
use serde_json;
use rocket::response::status;
use rocket::http;

use db::redis::RedisConnection;
use domain::{SessionId, Todo, TodoFilter, TodoId};

impl Deref for RedisConnection {
    type Target = r2d2::PooledConnection<RedisConnectionManager>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

#[derive(Debug)]
pub enum RepositoryError {
    RedisErr(String),
    JsonErr(String),
}

pub struct Repository {
    session_id: SessionId,
    connection: RedisConnection,
}

impl From<RepositoryError> for status::Custom<String> {
    fn from(err: RepositoryError) -> Self {
        let message = match err {
            RepositoryError::RedisErr(msg) => msg,
            RepositoryError::JsonErr(msg) => msg,
        };

        status::Custom(http::Status::ServiceUnavailable, message)
    }
}

impl From<RedisError> for RepositoryError {
    fn from(err: RedisError) -> Self {
        RepositoryError::RedisErr(err.category().into())
    }
}

impl From<serde_json::Error> for RepositoryError {
    fn from(err: serde_json::Error) -> Self {
        RepositoryError::JsonErr(err.to_string())
    }
}

impl Repository {
    pub fn new(session_id: SessionId, connection: RedisConnection) -> Self {
        Repository {
            session_id: session_id,
            connection: connection,
        }
    }

    //
    // Commands
    //

    pub fn create(&self, description: &str) -> Result<(), RepositoryError> {
        let sequence_key = format!("todo_id_sequence:{}", self.session_id);
        let todo_id: TodoId = self.connection.incr(sequence_key, 1)?;
        let todo = Todo {
            id: todo_id,
            completed: false,
            description: description.to_string(),
        };
        let payload = serde_json::to_string(&todo)?;

        let _: () = self.connection.hset(&self.session_key(), todo_id, payload)?;

        Ok(())
    }

    pub fn clear(&self, todo_id: TodoId) -> Result<(), RepositoryError> {
        let _: () = self.connection
            .hdel(&self.session_key(), hash_field(todo_id))?;

        Ok(())
    }

    pub fn update_description(
        &self,
        todo_id: TodoId,
        description: &String,
    ) -> Result<(), RepositoryError> {
        self.update_todo(todo_id, &|t: &mut Todo| t.description = description.clone())
    }

    pub fn complete(&self, todo_id: TodoId) -> Result<(), RepositoryError> {
        self.update_todo(todo_id, &|t: &mut Todo| t.completed = true)
    }

    pub fn activate(&self, todo_id: TodoId) -> Result<(), RepositoryError> {
        self.update_todo(todo_id, &|t: &mut Todo| t.completed = false)
    }

    pub fn complete_all(&self) -> Result<(), RepositoryError> {
        self.active()?
            .into_iter()
            .map(|t| self.complete(t.id))
            .collect::<Result<Vec<()>, _>>()?;

        Ok(())
    }

    pub fn activate_all(&self) -> Result<(), RepositoryError> {
        self.completed()?
            .into_iter()
            .map(|t| self.activate(t.id))
            .collect::<Result<Vec<()>, _>>()?;

        Ok(())
    }

    pub fn clear_completed(&self) -> Result<(), RepositoryError> {
        self.completed()?
            .into_iter()
            .map(|t| self.clear(t.id))
            .collect::<Result<Vec<()>, _>>()?;

        Ok(())
    }

    //
    // Queries
    //

    pub fn list(&self, filter: &TodoFilter) -> Result<Vec<Todo>, RepositoryError> {
        match *filter {
            TodoFilter::All => self.all(),
            TodoFilter::Active => self.active(),
            TodoFilter::Completed => self.completed(),
        }
    }

    pub fn active_count(&self) -> Result<usize, RepositoryError> {
        Ok(self.active()?.len())
    }

    pub fn is_all_completed(&self) -> Result<bool, RepositoryError> {
        Ok(self.all()?.iter().all(|t| t.completed))
    }

    pub fn is_any_completed(&self) -> Result<bool, RepositoryError> {
        Ok(self.all()?.iter().any(|t| t.completed))
    }

    pub fn todo_count(&self) -> Result<usize, RepositoryError> {
        Ok(self.connection.hlen(self.session_key())?)
    }

    //
    // Private functions
    //

    fn all(&self) -> Result<Vec<Todo>, RepositoryError> {
        let ids_and_payloads: Vec<(usize, String)> = self.connection.hgetall(self.session_key())?;

        let mut todos: Vec<Todo> = ids_and_payloads
            .into_iter()
            .map(|(_, payload)| serde_json::from_str(&payload))
            .flat_map(|r| r)
            .collect();

        todos.sort_unstable_by_key(|t| t.id);

        Ok(todos)
    }

    fn active(&self) -> Result<Vec<Todo>, RepositoryError> {
        self.all()
            .map(|todos| todos.into_iter().filter(|t| !t.completed).collect())
    }

    fn completed(&self) -> Result<Vec<Todo>, RepositoryError> {
        self.all()
            .map(|todos| todos.into_iter().filter(|t| t.completed).collect())
    }

    fn update_todo(
        &self,
        todo_id: TodoId,
        updater: &Fn(&mut Todo) -> (),
    ) -> Result<(), RepositoryError> {
        let json: String = self.connection.hget(&self.session_key(), todo_id)?;
        let mut todo: Todo = serde_json::from_str(&json)?;

        updater(&mut todo);

        let updated_json = serde_json::to_string(&todo)?;
        let _: () = self.connection
            .hset(&self.session_key(), hash_field(todo_id), updated_json)?;

        Ok(())
    }

    fn session_key(&self) -> String {
        format!("todos:{}", self.session_id)
    }
}

fn hash_field(todo_id: TodoId) -> String {
    format!("{}", todo_id)
}
<|endoftext|>


<commit_before>// #[cfg(test)]
// mod tests {
//     #[test]
//     fn it_works() {
//     }
// }

extern crate nalgebra;
extern crate smallvec;
use self::nalgebra::{Vector2, Point2, Dot, Norm};
use std::f32::consts::PI;
use self::smallvec::SmallVec;
pub type V2 = Vector2<f32>;
pub type P2 = Point2<f32>;
pub type IntersectionList = SmallVec<[Intersection; 2]>;

const THICKNESS: f32 = 0.0001;
const ROUGH_TOLERANCE: f32 = 0.0000001;

fn angle_between(a: V2, b: V2) -> f32 {
    let theta: f32 = a.dot(&b) / (a.norm() * b.norm());
    return theta.min(1.0).max(-1.0).acos();
}

fn angle_between_with_direction(a: V2, a_direction: V2, b: V2) -> f32 {
    let simple_angle = angle_between(a, b);
    let linear_direction = (b - a).normalize();

    if a_direction.dot(&linear_direction) >= 0.0 {
        return simple_angle;
    } else {
        return 2.0 * PI - simple_angle;
    };
}

trait RoughlyComparable {
    fn is_roughly(&self, other: Self) -> bool;
}

impl RoughlyComparable for f32 {
    fn is_roughly(&self, other: f32) -> bool {
        return (self - other).abs() <= ROUGH_TOLERANCE;
    }
}

trait Curve {
    fn offset_at(&self, point: P2) -> f32;
    fn contains(&self, point: P2) -> bool;
}

#[derive(Debug)]
pub struct Circle {
    pub center: P2,
    pub radius: f32,
}

impl Curve for Circle {
    fn offset_at(&self, point: P2) -> f32 {
        return angle_between_with_direction(V2::new(1.0, 0.0),
                                            V2::new(0.0, 1.0),
                                            (point - self.center) * self.radius);
    }

    fn contains(&self, point: P2) -> bool {
        return (point - self.center).norm() <= self.radius + THICKNESS / 2.0;
    }
}

#[derive(Debug)]
pub struct Line {
    pub start: P2,
    pub direction: V2,
}

#[derive(Debug)]
pub struct Intersection {
    pub along_a: f32,
    pub along_b: f32,
    pub position: P2,
}

impl Intersection {
	fn swapped(self) -> Intersection {
		return Intersection{
			along_a: self.along_b,
			along_b: self.along_a,
			position: self.position
		}
	}
}

pub trait Intersect {
    fn intersect(&self) -> IntersectionList;
}

impl<'a> Intersect for (&'a Line, &'a Line) {
    fn intersect(&self) -> IntersectionList {
        let (ref a, ref b) = *self;
        let mut intersection_list = SmallVec::new();

        let det = b.direction.x * a.direction.y - b.direction.y * a.direction.x;

        if !det.is_roughly(0.0) {
            let delta = b.start - a.start;
            let along_a = (delta.y * b.direction.x - delta.x * b.direction.y) / det;
            intersection_list.push(Intersection{
                along_a: along_a,
                along_b: (delta.y * a.direction.x - delta.x * a.direction.y) / det,
                position: a.start + a.direction * along_a
            });
        };

        return intersection_list;
    }
}

impl<'a> Intersect for (&'a Circle, &'a Line) {
    fn intersect(&self) -> IntersectionList {
        let (ref c, ref l) = *self;
        let mut intersection_list = SmallVec::new();

        let delta = l.start - c.center;
        let direction_dot_delta = l.direction.dot(&delta);
        let det = direction_dot_delta.powi(2) - (delta.norm_squared() - c.radius.powi(2));

        if det >= 0.0 {

            let t1 = -direction_dot_delta - det.sqrt();
            let solution1_position = l.start + t1 * l.direction;
            let solution1 = Intersection {
                along_a: t1,
                along_b: c.offset_at(solution1_position),
                position: solution1_position,
            };

            intersection_list.push(solution1);

            if det > 0.0 {
                let t2 = -direction_dot_delta + det.sqrt();
                let solution2_position = l.start + t2 * l.direction;
                let solution2 = Intersection {
                    along_a: t2,
                    along_b: c.offset_at(solution2_position),
                    position: solution2_position,
                };

                intersection_list.push(solution2);
            };
        }

        return intersection_list;
    }
}

impl<'a> Intersect for (&'a Line, &'a Circle) {
    fn intersect(&self) -> IntersectionList {
        let (l, c) = *self;
        let mut intersection_list = (c, l).intersect();
        return intersection_list.into_iter().map(|i| i.swapped()).collect::<IntersectionList>();
    }
}
<commit_msg>Early work on geometry primitives & operations, paths #3<commit_after>// #[cfg(test)]
// mod tests {
//     #[test]
//     fn it_works() {
//     }
// }

extern crate nalgebra;
extern crate smallvec;
use self::nalgebra::{Vector2, Point2, Dot, Norm};
use std::f32::consts::PI;
use self::smallvec::SmallVec;
pub type N = f32;
pub type V2 = Vector2<N>;
pub type P2 = Point2<N>;
pub type IntersectionList = SmallVec<[Intersection; 2]>;

// Thickness radius
const THICKNESS: N = 0.0001;
const ROUGH_TOLERANCE: N = 0.0000001;

fn angle_between(a: V2, b: V2) -> N {
    let theta: N = a.dot(&b) / (a.norm() * b.norm());
    return theta.min(1.0).max(-1.0).acos();
}

fn angle_between_with_direction(a: V2, a_direction: V2, b: V2) -> N {
    let simple_angle = angle_between(a, b);
    let linear_direction = (b - a).normalize();

    if a_direction.dot(&linear_direction) >= 0.0 {
        return simple_angle;
    } else {
        return 2.0 * PI - simple_angle;
    };
}

trait WithUniqueOrthogonal {
    fn orthogonal(&self) -> Self;
}

impl WithUniqueOrthogonal for V2 {
    fn orthogonal(&self) -> V2 {
        V2::new(self.y, -self.x)
    }
}

trait RoughlyComparable {
    fn is_roughly(&self, other: Self) -> bool;
}

impl RoughlyComparable for N {
    fn is_roughly(&self, other: N) -> bool {
        return (self - other).abs() <= ROUGH_TOLERANCE;
    }
}

trait Curve {
    fn project(&self, point: P2) -> Option<N>;
    fn contains(&self, point: P2) -> bool;
    fn distance_to(&self, point: P2) -> N;
}

#[derive(Debug)]
pub struct Circle {
    pub center: P2,
    pub radius: N,
}

impl Curve for Circle {
    fn project(&self, point: P2) -> Option<N> {
        Some(angle_between_with_direction(V2::new(1.0, 0.0),
                                            V2::new(0.0, 1.0),
                                            (point - self.center) * self.radius))
    }

    fn contains(&self, point: P2) -> bool {
        return (point - self.center).norm() <= self.radius + THICKNESS;
    }

    fn distance_to(&self, point: P2) -> N {
        0.0
    }
}

#[derive(Debug)]
pub struct Line {
    pub start: P2,
    pub direction: V2,
}

impl Curve for Line {
    fn project(&self, point: P2) -> Option<N> {
        Some((point - self.start).dot(&self.direction))
    }

    fn contains(&self, point: P2) -> bool {
        let distance = (point - self.start).dot(&self.direction.orthogonal());
        distance < THICKNESS
    }

    fn distance_to(&self, point: P2) -> N {
        0.0
    }
}

pub struct Ray {
    pub start: P2,
    pub direction: V2
}

impl Ray {
    fn as_line(&self) -> &Line {
        unsafe{::std::mem::transmute(self)}
    }
}

impl Curve for Ray {
    fn project(&self, point: P2) -> Option<N> {
        let line_offset = self.as_line().project(point).unwrap();
        if line_offset > -THICKNESS {Some(line_offset)} else {None}
    }

    fn contains(&self, point: P2) -> bool {
        self.as_line().contains(point) && match self.project(point) {
             Some(offset) => offset > -THICKNESS,
             None => false
        }
    }

    fn distance_to(&self, point: P2) -> N {
        0.0
    }
}

trait FiniteCurve : Curve {
    fn length(&self) -> N;
}

pub struct Segment {
    pub start: P2,
    pub center_or_direction: V2,
    pub end: P2,
    length: N,
    signed_radius: N
}

impl Segment {
    pub fn line(start: P2, end: P2) -> Segment {
        Segment{
            start: start,
            center_or_direction: (end - start).normalize(),
            end: end,
            length: (end - start).norm(),
            signed_radius: 0.0
        }
    }

    pub fn arc(start: P2, center: P2, end: P2) -> Segment {
        let start_to_center = center - start;
        let signed_radius = (start_to_center).norm() * start_to_center.dot(&(end - start)).signum();
        let direction = start_to_center.normalize().orthogonal() * -signed_radius.signum();
        let angle_span = angle_between_with_direction(start - center, direction, end - center);
        Segment{
            start: start,
            center_or_direction: center.to_vector(),
            end: end,
            length: angle_span * signed_radius.abs(),
            signed_radius: signed_radius
        }
    }

    pub fn arc_with_direction(start: P2, direction: V2, end: P2) -> Segment {
        let signed_radius = {
            let half_chord = (end - start) / 2.0;
            half_chord.norm_squared() / direction.orthogonal().dot(&half_chord)
        };
        let center = start + signed_radius * direction.orthogonal();
        let angle_span = angle_between_with_direction(start - center, direction, end - center);
        Segment{
            start: start,
            center_or_direction: center.to_vector(),
            end: end,
            length: angle_span * signed_radius.abs(),
            signed_radius: signed_radius
        }
    }

    pub fn is_linear(&self) -> bool {
        self.signed_radius == 0.0
    }

    fn center(&self) -> P2 {
        *self.center_or_direction.as_point()
    }

    fn radius(&self) -> N {
        self.signed_radius.abs()
    }

    fn start_direction_of_arc(&self) -> V2 {
        let start_to_center = self.center() - self.start;
        start_to_center.normalize().orthogonal() * -self.signed_radius.signum()
    }

    fn end_direction_of_arc(&self) -> V2 {
        let end_to_center = self.center() - self.end;
        end_to_center.normalize().orthogonal() * -self.signed_radius.signum()
    }
}

impl FiniteCurve for Segment {
    fn length(&self) -> N {
        self.length
    }
}

impl Curve for Segment {
    fn project(&self, point: P2) -> Option<N> {
        if self.is_linear() {
            let direction = self.center_or_direction;
            let line_offset = direction.dot(&(point - self.end));
            if line_offset > -THICKNESS && line_offset < self.length + THICKNESS {
                Some(line_offset)
            } else {None}
        } else {
            let angle_start_to_point = angle_between_with_direction(
                self.start - self.center(), self.start_direction_of_arc(), point - self.center());
            let angle_end_to_point = angle_between_with_direction(
                self.end - self.center(), -self.end_direction_of_arc(), point - self.center());

            let tolerance = THICKNESS / self.radius();
            let angle_span = self.length / self.radius();

            if angle_start_to_point <= angle_span + tolerance &&
                angle_end_to_point <= angle_span + tolerance {
                Some(angle_start_to_point.max(0.0).min(angle_span) * self.radius())
            } else {None}
        }
    }

    fn contains(&self, point: P2) -> bool {
        let primitive_contains_point = if self.is_linear() {
            Line{start: self.start, direction: self.center_or_direction}.contains(point)
        } else {
            Circle{center: self.center(), radius: self.radius()}.contains(point)
        };

        primitive_contains_point && self.project(point).is_some()
    }

    fn distance_to(&self, point: P2) -> N {
        0.0
    }
}

struct Path {
    segments: [Segment]
}

struct StartOffsetState(N);

impl<'a> Path {
    fn scan_segments (start_offset: &mut StartOffsetState, segment: &'a Segment) -> Option<(&'a Segment, N)> {
        let pair = (segment, start_offset.0);
        start_offset.0 += segment.length;
        Some(pair)
    }

    fn segments_with_start_offsets(&'a self)
    -> ::std::iter::Scan<
        ::std::slice::Iter<'a, Segment>,
        StartOffsetState,
        fn(&mut StartOffsetState, &'a Segment) -> Option<(&'a Segment, N)>
    > {
        return self.segments.into_iter().scan(StartOffsetState(0.0), Self::scan_segments);
    }
}

impl FiniteCurve for Path {
    fn length(&self) -> N {
        self.segments.into_iter().map(|segment| segment.length()).fold(0.0, ::std::ops::Add::add)
    }
}

impl Curve for Path {
    fn project(&self, point: P2) -> Option<N> {
        self.segments_with_start_offsets().filter_map(|pair: (&Segment, N)| {
            let (segment, start_offset) = pair;
            let offset_on_segment = segment.project(point);
            match offset_on_segment {
                Some(offset) => Some(start_offset + offset),
                None => None
            }
        }).next()
    }

    fn contains(&self, point: P2) -> bool {
        self.segments.into_iter().any(|segment| segment.contains(point))
    }

    fn distance_to(&self, point: P2) -> N {
        self.segments.into_iter().fold(None, |min, segment| {
            let distance = segment.distance_to(point);
            if min.is_some() && distance < min.unwrap() {Some(distance)} else {min}
        }).unwrap()
    }
}

#[derive(Debug)]
pub struct Intersection {
    pub along_a: N,
    pub along_b: N,
    pub position: P2,
}

impl Intersection {
	fn swapped(self) -> Intersection {
		return Intersection{
			along_a: self.along_b,
			along_b: self.along_a,
			position: self.position
		}
	}
}

pub trait Intersect {
    fn intersect(&self) -> IntersectionList;
}

impl<'a> Intersect for (&'a Line, &'a Line) {
    fn intersect(&self) -> IntersectionList {
        let (ref a, ref b) = *self;
        let mut intersection_list = SmallVec::new();

        let det = b.direction.x * a.direction.y - b.direction.y * a.direction.x;

        if !det.is_roughly(0.0) {
            let delta = b.start - a.start;
            let along_a = (delta.y * b.direction.x - delta.x * b.direction.y) / det;
            intersection_list.push(Intersection{
                along_a: along_a,
                along_b: (delta.y * a.direction.x - delta.x * a.direction.y) / det,
                position: a.start + a.direction * along_a
            });
        };

        return intersection_list;
    }
}

impl<'a> Intersect for (&'a Circle, &'a Line) {
    fn intersect(&self) -> IntersectionList {
        let (ref c, ref l) = *self;
        let mut intersection_list = SmallVec::new();

        let delta = l.start - c.center;
        let direction_dot_delta = l.direction.dot(&delta);
        let det = direction_dot_delta.powi(2) - (delta.norm_squared() - c.radius.powi(2));

        if det >= 0.0 {

            let t1 = -direction_dot_delta - det.sqrt();
            let solution1_position = l.start + t1 * l.direction;
            let solution1 = Intersection {
                along_a: t1,
                along_b: c.project(solution1_position).unwrap(),
                position: solution1_position,
            };

            intersection_list.push(solution1);

            if det > 0.0 {
                let t2 = -direction_dot_delta + det.sqrt();
                let solution2_position = l.start + t2 * l.direction;
                let solution2 = Intersection {
                    along_a: t2,
                    along_b: c.project(solution2_position).unwrap(),
                    position: solution2_position,
                };

                intersection_list.push(solution2);
            };
        }

        return intersection_list;
    }
}

impl<'a> Intersect for (&'a Line, &'a Circle) {
    fn intersect(&self) -> IntersectionList {
        let (l, c) = *self;
        let mut intersection_list = (c, l).intersect();
        return intersection_list.into_iter().map(|i| i.swapped()).collect::<IntersectionList>();
    }
}
<|endoftext|>


<commit_before>//! OpenTelemetry shared core date types
use std::borrow::Cow;

/// Key used for metric `LabelSet`s and trace `Span` attributes.
#[derive(Clone, Debug)]
pub struct Key(Cow<'static, str>);

impl Key {
    /// Create a new `Key`.
    pub fn new<S: Into<Cow<'static, str>>>(value: S) -> Self {
        Key(value.into())
    }

    /// Create a `KeyValue` pair for `bool` values.
    pub fn bool(&self, value: bool) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::Bool(value),
        }
    }

    /// Create a `KeyValue` pair for `i64` values.
    pub fn i64(&self, value: i64) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::I64(value),
        }
    }

    /// Create a `KeyValue` pair for `u64` values.
    pub fn u64(&self, value: u64) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::U64(value),
        }
    }

    /// Create a `KeyValue` pair for `f64` values.
    pub fn f64(&self, value: f64) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::F64(value),
        }
    }

    /// Create a `KeyValue` pair for `Into<String>` values.
    pub fn string<S: Into<String>>(&self, value: S) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::String(value.into()),
        }
    }

    /// Create a `KeyValue` pair for byte arrays.
    pub fn bytes(&self, value: Vec<u8>) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::Bytes(value),
        }
    }

    /// Returns a reference to the key's `Cow` type for use in `LabelSet`s.
    pub fn inner(&self) -> &Cow<'static, str> {
        &self.0
    }

    /// Returns the inner `Cow` type.
    pub fn into_inner(self) -> Cow<'static, str> {
        self.0
    }
}

impl Into<Cow<'static, str>> for Key {
    /// Converts `Key` instances into `Cow`
    fn into(self) -> Cow<'static, str> {
        self.0
    }
}

impl Into<String> for Key {
    /// Converts `Key` instances into `String`.
    fn into(self) -> String {
        self.0.to_string()
    }
}

/// Value types for use in `KeyValue` pairs.
#[derive(Clone, Debug)]
pub enum Value {
    /// bool values
    Bool(bool),
    /// i64 values
    I64(i64),
    /// u64 values
    U64(u64),
    /// f64 values
    F64(f64),
    /// String values
    String(String),
    /// Byte array values
    Bytes(Vec<u8>),
}

impl ToString for Value {
    /// Convert `Value` types to `String` for use by exporters that only use
    /// `String` values.
    fn to_string(&self) -> String {
        match self {
            Value::Bool(value) => value.to_string(),
            Value::I64(value) => value.to_string(),
            Value::U64(value) => value.to_string(),
            Value::F64(value) => value.to_string(),
            Value::String(value) => value.clone(),
            Value::Bytes(value) => {
                String::from_utf8(value.clone()).unwrap_or_else(|_| String::new())
            }
        }
    }
}

impl Into<Cow<'static, str>> for Value {
    /// Convert `Value` types into `Cow` for use in `LabelSet`s.
    fn into(self) -> Cow<'static, str> {
        self.to_string().into()
    }
}

/// `KeyValue` pairs are used by `LabelSet`s and `Span` attributes.
#[derive(Clone, Debug)]
pub struct KeyValue {
    /// Dimension or event key
    pub key: Key,
    /// Dimension or event value
    pub value: Value,
}

/// Units denote underlying data units tracked by `Meter`s.
#[derive(Default, Debug)]
pub struct Unit(String);

impl Unit {
    /// Create a new `Unit` from an `Into<String>`
    pub fn new<S: Into<String>>(value: S) -> Self {
        Unit(value.into())
    }
}
<commit_msg>Improve KeyValue ergonomics<commit_after>//! OpenTelemetry shared core date types
use std::borrow::Cow;

/// Key used for metric `LabelSet`s and trace `Span` attributes.
#[derive(Clone, Debug)]
pub struct Key(Cow<'static, str>);

impl Key {
    /// Create a new `Key`.
    pub fn new<S: Into<Cow<'static, str>>>(value: S) -> Self {
        Key(value.into())
    }

    /// Create a `KeyValue` pair for `bool` values.
    pub fn bool(&self, value: bool) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::Bool(value),
        }
    }

    /// Create a `KeyValue` pair for `i64` values.
    pub fn i64(&self, value: i64) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::I64(value),
        }
    }

    /// Create a `KeyValue` pair for `u64` values.
    pub fn u64(&self, value: u64) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::U64(value),
        }
    }

    /// Create a `KeyValue` pair for `f64` values.
    pub fn f64(&self, value: f64) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::F64(value),
        }
    }

    /// Create a `KeyValue` pair for `Into<String>` values.
    pub fn string<S: Into<String>>(&self, value: S) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::String(value.into()),
        }
    }

    /// Create a `KeyValue` pair for byte arrays.
    pub fn bytes(&self, value: Vec<u8>) -> KeyValue {
        KeyValue {
            key: self.clone(),
            value: Value::Bytes(value),
        }
    }

    /// Returns a reference to the key's `Cow` type for use in `LabelSet`s.
    pub fn inner(&self) -> &Cow<'static, str> {
        &self.0
    }

    /// Returns the inner `Cow` type.
    pub fn into_inner(self) -> Cow<'static, str> {
        self.0
    }
}

impl From<&'static str> for Key {
    /// Convert a `&str` to a `Key`.
    fn from(key_str: &'static str) -> Self {
        Key(Cow::from(key_str))
    }
}

impl Into<Cow<'static, str>> for Key {
    /// Converts `Key` instances into `Cow`
    fn into(self) -> Cow<'static, str> {
        self.0
    }
}

impl Into<String> for Key {
    /// Converts `Key` instances into `String`.
    fn into(self) -> String {
        self.0.to_string()
    }
}

/// Value types for use in `KeyValue` pairs.
#[derive(Clone, Debug)]
pub enum Value {
    /// bool values
    Bool(bool),
    /// i64 values
    I64(i64),
    /// u64 values
    U64(u64),
    /// f64 values
    F64(f64),
    /// String values
    String(String),
    /// Byte array values
    Bytes(Vec<u8>),
}

impl From<&str> for Value {
    /// Convenience method for creating a `Value` form a `&str`.
    fn from(value_str: &str) -> Self {
        Value::String(value_str.to_string())
    }
}

impl ToString for Value {
    /// Convert `Value` types to `String` for use by exporters that only use
    /// `String` values.
    fn to_string(&self) -> String {
        match self {
            Value::Bool(value) => value.to_string(),
            Value::I64(value) => value.to_string(),
            Value::U64(value) => value.to_string(),
            Value::F64(value) => value.to_string(),
            Value::String(value) => value.clone(),
            Value::Bytes(value) => {
                String::from_utf8(value.clone()).unwrap_or_else(|_| String::new())
            }
        }
    }
}

impl Into<Cow<'static, str>> for Value {
    /// Convert `Value` types into `Cow` for use in `LabelSet`s.
    fn into(self) -> Cow<'static, str> {
        self.to_string().into()
    }
}

/// `KeyValue` pairs are used by `LabelSet`s and `Span` attributes.
#[derive(Clone, Debug)]
pub struct KeyValue {
    /// Dimension or event key
    pub key: Key,
    /// Dimension or event value
    pub value: Value,
}

impl KeyValue {
    /// Create a new `KeyValue` pair.
    pub fn new<K, V>(key: K, value: V) -> Self where K: Into<Key>, V: Into<Value> {
        KeyValue { key: key.into(), value: value.into() }
    }
}

/// Units denote underlying data units tracked by `Meter`s.
#[derive(Default, Debug)]
pub struct Unit(String);

impl Unit {
    /// Create a new `Unit` from an `Into<String>`
    pub fn new<S: Into<String>>(value: S) -> Self {
        Unit(value.into())
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;
use graphics::{ Context, DrawState, Graphics, Viewport };
use graphics::BACK_END_MAX_VERTEX_COUNT as BUFFER_SIZE;
use { gfx, Texture };

const POS_COMPONENTS: usize = 2;
const UV_COMPONENTS: usize = 2;

// Boiler plate for automatic attribute construction.
// Needs to be improved on gfx-rs side.
// For some reason, using ``*_COMPONENT` triggers some macros errors.

#[vertex_format]
struct PositionFormat { pos: [f32; 2] }

#[vertex_format]
struct ColorFormat { color: [f32; 4] }

#[vertex_format]
struct TexCoordsFormat { uv: [f32; 2] }

#[shader_param]
struct Params<R: gfx::Resources> {
    color: [f32; 4],
    _dummy: PhantomData<R>,
}

#[shader_param]
struct ParamsUV<R: gfx::Resources> {
    color: [f32; 4],
    s_texture: gfx::shade::TextureParam<R>,
}

/// The data used for drawing 2D graphics.
pub struct Gfx2d<R: gfx::Resources> {
    buffer_pos: gfx::BufferHandle<R, f32>,
    buffer_uv: gfx::BufferHandle<R, f32>,
    batch: gfx::batch::OwnedBatch<Params<R>>,
    batch_uv: gfx::batch::OwnedBatch<ParamsUV<R>>,
}

impl<R: gfx::Resources> Gfx2d<R> {
    /// Creates a new G2D object.
    pub fn new<D, F>(device: &mut D, factory: &mut F) -> Self
        where D: gfx::Device,
              F: gfx::Factory<R>
    {
        use gfx::traits::*;
        use gfx::VertexFormat;
        use shaders::{ colored, textured };

        let ref capabilities = device.get_capabilities();

        let program = {
            let vertex = gfx::ShaderSource {
                glsl_120: Some(colored::VERTEX_GLSL_120),
                glsl_150: Some(colored::VERTEX_GLSL_150_CORE),
                .. gfx::ShaderSource::empty()
            };
            let fragment = gfx::ShaderSource {
                glsl_120: Some(colored::FRAGMENT_GLSL_120),
                glsl_150: Some(colored::FRAGMENT_GLSL_150_CORE),
                .. gfx::ShaderSource::empty()
            };
            factory.link_program_source(
                vertex,
                fragment,
                capabilities
            ).unwrap()
        };

        let program_uv = {
            let vertex = gfx::ShaderSource {
                glsl_120: Some(textured::VERTEX_GLSL_120),
                glsl_150: Some(textured::VERTEX_GLSL_150_CORE),
                .. gfx::ShaderSource::empty()
            };
            let fragment = gfx::ShaderSource {
                glsl_120: Some(textured::FRAGMENT_GLSL_120),
                glsl_150: Some(textured::FRAGMENT_GLSL_150_CORE),
                .. gfx::ShaderSource::empty()
            };
            factory.link_program_source(
                vertex,
                fragment,
                capabilities
            ).unwrap()
        };

        let buffer_pos = factory.create_buffer(
            POS_COMPONENTS * BUFFER_SIZE,
            gfx::BufferUsage::Dynamic
        );
        let buffer_uv = factory.create_buffer(
            UV_COMPONENTS * BUFFER_SIZE,
            gfx::BufferUsage::Dynamic
        );

        let mut mesh = gfx::Mesh::new(BUFFER_SIZE as u32);
        mesh.attributes.extend(
            PositionFormat::generate(
                buffer_pos.raw().clone()
            )
        );

        // Reuse parameters from `mesh`.
        let mut mesh_uv = mesh.clone();
        mesh_uv.attributes.extend(
            TexCoordsFormat::generate(
                buffer_uv.raw().clone()
            )
        );

        let params = Params {
            color: [1.0; 4],
            _dummy: PhantomData,
        };
        let mut batch = gfx::batch::OwnedBatch::new(
            mesh,
            program,
            params
        ).unwrap();

        let sampler = factory.create_sampler(
            gfx::tex::SamplerInfo::new(
                gfx::tex::FilterMethod::Trilinear,
                gfx::tex::WrapMode::Clamp
            )
        );

        // Create a dummy texture
        let texture_info = gfx::tex::TextureInfo {
            width: 1,
            height: 1,
            depth: 1,
            levels: 1,
            kind: gfx::tex::TextureKind::Texture2D,
            format: gfx::tex::RGBA8,
        };
        let image_info = texture_info.to_image_info();
        let texture = factory.create_texture(texture_info).unwrap();

        factory.update_texture(
            &texture,
            &image_info,
            &[0x20u8, 0xA0, 0xC0, 0x00],
            Some(gfx::tex::TextureKind::Texture2D)
        ).unwrap();

        let params_uv = ParamsUV {
            color: [1.0; 4],
            s_texture: (texture, Some(sampler))
        };
        let mut batch_uv = gfx::batch::OwnedBatch::new(
            mesh_uv,
            program_uv,
            params_uv
        ).unwrap();

        // Disable culling.
        batch.state.primitive.method =
            gfx::state::RasterMethod::Fill(gfx::state::CullFace::Nothing);
        batch_uv.state.primitive.method =
            gfx::state::RasterMethod::Fill(gfx::state::CullFace::Nothing);

        Gfx2d {
            buffer_pos: buffer_pos,
            buffer_uv: buffer_uv,
            batch: batch,
            batch_uv: batch_uv,
        }
    }

    /// Renders graphics to a Gfx renderer.
    pub fn draw<C, O, F>(
        &mut self,
        renderer: &mut gfx::Renderer<R, C>,
        output: &O,
        viewport: Viewport,
        mut f: F
    )
        where C: gfx::CommandBuffer<R>,
              O: gfx::Output<R>,
              F: FnMut(Context, &mut GfxGraphics<R, C, O>)
    {
        let ref mut g = GfxGraphics::new(
            renderer,
            output,
            self
        );
        let c = Context::new_viewport(viewport);
        f(c, g);
    }
}

/// Used for rendering 2D graphics.
pub struct GfxGraphics<'a, R, C, O>
    where R: gfx::Resources + 'a,
          C: gfx::CommandBuffer<R> + 'a,
          O: gfx::Output<R> + 'a,
          R::Buffer: 'a,
          R::ArrayBuffer: 'a,
          R::Shader: 'a,
          R::Program: 'a,
          R::FrameBuffer: 'a,
          R::Surface: 'a,
          R::Texture: 'a,
          R::Sampler: 'a
{
    renderer: &'a mut gfx::Renderer<R, C>,
    output: &'a O,
    g2d: &'a mut Gfx2d<R>,
}

impl<'a, R, C, O> GfxGraphics<'a, R, C, O>
    where R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
          O: gfx::Output<R>
{
    /// Creates a new object for rendering 2D graphics.
    pub fn new(renderer: &'a mut gfx::Renderer<R, C>,
               output: &'a O,
               g2d: &'a mut Gfx2d<R>) -> Self {
        GfxGraphics {
            renderer: renderer,
            output: output,
            g2d: g2d,
        }
    }

    /// Returns true if texture has alpha channel.
    pub fn has_texture_alpha(&self, texture: &Texture<R>) -> bool {
        use gfx::tex::Components::RGBA;

        texture.handle().get_info().format.get_components() == Some(RGBA)
    }
}

impl<'a, R, C, O> Graphics for GfxGraphics<'a, R, C, O>
    where R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
          O: gfx::Output<R>,
          R::Buffer: 'a,
          R::ArrayBuffer: 'a,
          R::Shader: 'a,
          R::Program: 'a,
          R::FrameBuffer: 'a,
          R::Surface: 'a,
          R::Texture: 'a,
          R::Sampler: 'a
{
    type Texture = Texture<R>;

    fn clear_color(&mut self, color: [f32; 4]) {
        let &mut GfxGraphics {
            ref mut renderer,
            output,
            ..
        } = self;
        renderer.clear(
            gfx::ClearData {
                color: color,
                depth: 0.0,
                stencil: 0,
            },
            gfx::COLOR,
            output
        );
    }

    fn clear_stencil(&mut self, value: u8) {
        let &mut GfxGraphics {
            ref mut renderer,
            output,
            ..
        } = self;
        renderer.clear(
            gfx::ClearData {
                color: [0.0; 4],
                depth: 0.0,
                stencil: value,
            },
            gfx::STENCIL,
            output
        );
    }

    fn tri_list<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32]))
    {
        let &mut GfxGraphics {
            ref mut renderer,
            ref output,
            g2d: &mut Gfx2d {
                ref mut buffer_pos,
                ref mut batch,
                ..
            },
        } = self;

        batch.state = *draw_state;
        batch.param.color = *color;

        f(&mut |vertices: &[f32]| {
            renderer.update_buffer_vec(&buffer_pos, vertices, 0);

            let n = vertices.len() / POS_COMPONENTS;
            batch.slice = gfx::Slice {
                    prim_type: gfx::PrimitiveType::TriangleList,
                    start: 0,
                    end: n as u32,
                    kind: gfx::SliceKind::Vertex
            };
            let _ = renderer.draw(batch, *output);
        })
    }

    fn tri_list_uv<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        texture: &<Self as Graphics>::Texture,
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32], &[f32]))
    {
        let &mut GfxGraphics {
            ref mut renderer,
            ref output,
            g2d: &mut Gfx2d {
                ref mut buffer_pos,
                ref mut buffer_uv,
                ref mut batch_uv,
                ..
            },
        } = self;

        batch_uv.state = *draw_state;
        batch_uv.param.s_texture.0 = texture.handle();
        batch_uv.param.color = *color;

        f(&mut |vertices: &[f32], texture_coords: &[f32]| {
            assert_eq!(
                vertices.len() * UV_COMPONENTS,
                texture_coords.len() * POS_COMPONENTS
            );
            renderer.update_buffer_vec(&buffer_pos, vertices, 0);
            renderer.update_buffer_vec(&buffer_uv, texture_coords, 0);

            let n = vertices.len() / POS_COMPONENTS;
            batch_uv.slice = gfx::Slice {
                    prim_type: gfx::PrimitiveType::TriangleList,
                    start: 0,
                    end: n as u32,
                    kind: gfx::SliceKind::Vertex
            };
            let _ = renderer.draw(batch_uv, *output);
        })
    }
}
<commit_msg>Use Texture::empty in back_end<commit_after>use std::marker::PhantomData;
use graphics::{ Context, DrawState, Graphics, Viewport };
use graphics::BACK_END_MAX_VERTEX_COUNT as BUFFER_SIZE;
use { gfx, Texture };

const POS_COMPONENTS: usize = 2;
const UV_COMPONENTS: usize = 2;

// Boiler plate for automatic attribute construction.
// Needs to be improved on gfx-rs side.
// For some reason, using ``*_COMPONENT` triggers some macros errors.

#[vertex_format]
struct PositionFormat { pos: [f32; 2] }

#[vertex_format]
struct ColorFormat { color: [f32; 4] }

#[vertex_format]
struct TexCoordsFormat { uv: [f32; 2] }

#[shader_param]
struct Params<R: gfx::Resources> {
    color: [f32; 4],
    _dummy: PhantomData<R>,
}

#[shader_param]
struct ParamsUV<R: gfx::Resources> {
    color: [f32; 4],
    s_texture: gfx::shade::TextureParam<R>,
}

/// The data used for drawing 2D graphics.
pub struct Gfx2d<R: gfx::Resources> {
    buffer_pos: gfx::BufferHandle<R, f32>,
    buffer_uv: gfx::BufferHandle<R, f32>,
    batch: gfx::batch::OwnedBatch<Params<R>>,
    batch_uv: gfx::batch::OwnedBatch<ParamsUV<R>>,
}

impl<R: gfx::Resources> Gfx2d<R> {
    /// Creates a new G2D object.
    pub fn new<D, F>(device: &mut D, factory: &mut F) -> Self
        where D: gfx::Device,
              F: gfx::Factory<R>
    {
        use gfx::traits::*;
        use gfx::VertexFormat;
        use shaders::{ colored, textured };

        let ref capabilities = device.get_capabilities();

        let program = {
            let vertex = gfx::ShaderSource {
                glsl_120: Some(colored::VERTEX_GLSL_120),
                glsl_150: Some(colored::VERTEX_GLSL_150_CORE),
                .. gfx::ShaderSource::empty()
            };
            let fragment = gfx::ShaderSource {
                glsl_120: Some(colored::FRAGMENT_GLSL_120),
                glsl_150: Some(colored::FRAGMENT_GLSL_150_CORE),
                .. gfx::ShaderSource::empty()
            };
            factory.link_program_source(
                vertex,
                fragment,
                capabilities
            ).unwrap()
        };

        let program_uv = {
            let vertex = gfx::ShaderSource {
                glsl_120: Some(textured::VERTEX_GLSL_120),
                glsl_150: Some(textured::VERTEX_GLSL_150_CORE),
                .. gfx::ShaderSource::empty()
            };
            let fragment = gfx::ShaderSource {
                glsl_120: Some(textured::FRAGMENT_GLSL_120),
                glsl_150: Some(textured::FRAGMENT_GLSL_150_CORE),
                .. gfx::ShaderSource::empty()
            };
            factory.link_program_source(
                vertex,
                fragment,
                capabilities
            ).unwrap()
        };

        let buffer_pos = factory.create_buffer(
            POS_COMPONENTS * BUFFER_SIZE,
            gfx::BufferUsage::Dynamic
        );
        let buffer_uv = factory.create_buffer(
            UV_COMPONENTS * BUFFER_SIZE,
            gfx::BufferUsage::Dynamic
        );

        let mut mesh = gfx::Mesh::new(BUFFER_SIZE as u32);
        mesh.attributes.extend(
            PositionFormat::generate(
                buffer_pos.raw().clone()
            )
        );

        // Reuse parameters from `mesh`.
        let mut mesh_uv = mesh.clone();
        mesh_uv.attributes.extend(
            TexCoordsFormat::generate(
                buffer_uv.raw().clone()
            )
        );

        let params = Params {
            color: [1.0; 4],
            _dummy: PhantomData,
        };
        let mut batch = gfx::batch::OwnedBatch::new(
            mesh,
            program,
            params
        ).unwrap();

        let sampler = factory.create_sampler(
            gfx::tex::SamplerInfo::new(
                gfx::tex::FilterMethod::Trilinear,
                gfx::tex::WrapMode::Clamp
            )
        );

        let tex_handle = Texture::empty(factory).unwrap().handle();

        let params_uv = ParamsUV {
            color: [1.0; 4],
            s_texture: (tex_handle, Some(sampler))
        };
        let mut batch_uv = gfx::batch::OwnedBatch::new(
            mesh_uv,
            program_uv,
            params_uv
        ).unwrap();

        // Disable culling.
        batch.state.primitive.method =
            gfx::state::RasterMethod::Fill(gfx::state::CullFace::Nothing);
        batch_uv.state.primitive.method =
            gfx::state::RasterMethod::Fill(gfx::state::CullFace::Nothing);

        Gfx2d {
            buffer_pos: buffer_pos,
            buffer_uv: buffer_uv,
            batch: batch,
            batch_uv: batch_uv,
        }
    }

    /// Renders graphics to a Gfx renderer.
    pub fn draw<C, O, F>(
        &mut self,
        renderer: &mut gfx::Renderer<R, C>,
        output: &O,
        viewport: Viewport,
        mut f: F
    )
        where C: gfx::CommandBuffer<R>,
              O: gfx::Output<R>,
              F: FnMut(Context, &mut GfxGraphics<R, C, O>)
    {
        let ref mut g = GfxGraphics::new(
            renderer,
            output,
            self
        );
        let c = Context::new_viewport(viewport);
        f(c, g);
    }
}

/// Used for rendering 2D graphics.
pub struct GfxGraphics<'a, R, C, O>
    where R: gfx::Resources + 'a,
          C: gfx::CommandBuffer<R> + 'a,
          O: gfx::Output<R> + 'a,
          R::Buffer: 'a,
          R::ArrayBuffer: 'a,
          R::Shader: 'a,
          R::Program: 'a,
          R::FrameBuffer: 'a,
          R::Surface: 'a,
          R::Texture: 'a,
          R::Sampler: 'a
{
    renderer: &'a mut gfx::Renderer<R, C>,
    output: &'a O,
    g2d: &'a mut Gfx2d<R>,
}

impl<'a, R, C, O> GfxGraphics<'a, R, C, O>
    where R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
          O: gfx::Output<R>
{
    /// Creates a new object for rendering 2D graphics.
    pub fn new(renderer: &'a mut gfx::Renderer<R, C>,
               output: &'a O,
               g2d: &'a mut Gfx2d<R>) -> Self {
        GfxGraphics {
            renderer: renderer,
            output: output,
            g2d: g2d,
        }
    }

    /// Returns true if texture has alpha channel.
    pub fn has_texture_alpha(&self, texture: &Texture<R>) -> bool {
        use gfx::tex::Components::RGBA;

        texture.handle().get_info().format.get_components() == Some(RGBA)
    }
}

impl<'a, R, C, O> Graphics for GfxGraphics<'a, R, C, O>
    where R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
          O: gfx::Output<R>,
          R::Buffer: 'a,
          R::ArrayBuffer: 'a,
          R::Shader: 'a,
          R::Program: 'a,
          R::FrameBuffer: 'a,
          R::Surface: 'a,
          R::Texture: 'a,
          R::Sampler: 'a
{
    type Texture = Texture<R>;

    fn clear_color(&mut self, color: [f32; 4]) {
        let &mut GfxGraphics {
            ref mut renderer,
            output,
            ..
        } = self;
        renderer.clear(
            gfx::ClearData {
                color: color,
                depth: 0.0,
                stencil: 0,
            },
            gfx::COLOR,
            output
        );
    }

    fn clear_stencil(&mut self, value: u8) {
        let &mut GfxGraphics {
            ref mut renderer,
            output,
            ..
        } = self;
        renderer.clear(
            gfx::ClearData {
                color: [0.0; 4],
                depth: 0.0,
                stencil: value,
            },
            gfx::STENCIL,
            output
        );
    }

    fn tri_list<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32]))
    {
        let &mut GfxGraphics {
            ref mut renderer,
            ref output,
            g2d: &mut Gfx2d {
                ref mut buffer_pos,
                ref mut batch,
                ..
            },
        } = self;

        batch.state = *draw_state;
        batch.param.color = *color;

        f(&mut |vertices: &[f32]| {
            renderer.update_buffer_vec(&buffer_pos, vertices, 0);

            let n = vertices.len() / POS_COMPONENTS;
            batch.slice = gfx::Slice {
                    prim_type: gfx::PrimitiveType::TriangleList,
                    start: 0,
                    end: n as u32,
                    kind: gfx::SliceKind::Vertex
            };
            let _ = renderer.draw(batch, *output);
        })
    }

    fn tri_list_uv<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        texture: &<Self as Graphics>::Texture,
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32], &[f32]))
    {
        let &mut GfxGraphics {
            ref mut renderer,
            ref output,
            g2d: &mut Gfx2d {
                ref mut buffer_pos,
                ref mut buffer_uv,
                ref mut batch_uv,
                ..
            },
        } = self;

        batch_uv.state = *draw_state;
        batch_uv.param.s_texture.0 = texture.handle();
        batch_uv.param.color = *color;

        f(&mut |vertices: &[f32], texture_coords: &[f32]| {
            assert_eq!(
                vertices.len() * UV_COMPONENTS,
                texture_coords.len() * POS_COMPONENTS
            );
            renderer.update_buffer_vec(&buffer_pos, vertices, 0);
            renderer.update_buffer_vec(&buffer_uv, texture_coords, 0);

            let n = vertices.len() / POS_COMPONENTS;
            batch_uv.slice = gfx::Slice {
                    prim_type: gfx::PrimitiveType::TriangleList,
                    start: 0,
                    end: n as u32,
                    kind: gfx::SliceKind::Vertex
            };
            let _ = renderer.draw(batch_uv, *output);
        })
    }
}
<|endoftext|>


<commit_before>extern crate gtk;

// make moving clones into closures more convenient
macro_rules! clone {
    (@param _) => ( _ );
    (@param $x:ident) => ( $x );
    ($($n:ident),+ => move || $body:expr) => (
        {
            $( let $n = $n.clone(); )+
                move || $body
        }
    );
    ($($n:ident),+ => move |$($p:tt),+| $body:expr) => (
        {
            $( let $n = $n.clone(); )+
                move |$(clone!(@param $p),)+| $body
        }
    );
}

#[cfg(feature = "gtk_3_10")]
mod example {
    use gtk;
    use gtk::prelude::*;
    use gtk::{
        Builder, Button, Grid, Window,
    };

    pub fn main() {
        if gtk::init().is_err() {
            println!("Failed to initialize GTK.");
            return;
        }
        let glade_src = include_str!("grid.glade");
        let builder = Builder::new_from_string(glade_src);

        let window: Window = builder.get_object("window").unwrap();
        let grid: Grid = builder.get_object("grid").unwrap();
        let button6: Button = builder.get_object("button6").unwrap();
        button6.connect_clicked(clone!(grid, button6 => move |_| {
            let height = grid.get_cell_height(&button6);
            let new_height = if height == 2 { 1 } else { 2 };
            grid.set_cell_height(&button6, new_height);
        }));
        let button7: Button = builder.get_object("button7").unwrap();
        button7.connect_clicked(clone!(grid, button7 => move |_| {
            let left_attach = grid.get_cell_left_attach(&button7);
            let new_left_attach = if left_attach == 2 { 0 } else { left_attach + 1 };
            grid.set_cell_left_attach(&button7, new_left_attach);
        }));

        window.connect_delete_event(|_, _| {
            gtk::main_quit();
            Inhibit(false)
        });

        window.show_all();
        gtk::main();
    }
}

#[cfg(feature = "gtk_3_10")]
fn main() {
    example::main()
}

#[cfg(not(feature = "gtk_3_10"))]
fn main() {
    println!("This example only work with GTK 3.10 and later");
    println!("Did you forget to build with `--features gtk_3_10`?");
}
<commit_msg>Remove unused macro warning<commit_after>extern crate gtk;

// make moving clones into closures more convenient
#[cfg(feature = "gtk_3_10")]
macro_rules! clone {
    (@param _) => ( _ );
    (@param $x:ident) => ( $x );
    ($($n:ident),+ => move || $body:expr) => (
        {
            $( let $n = $n.clone(); )+
                move || $body
        }
    );
    ($($n:ident),+ => move |$($p:tt),+| $body:expr) => (
        {
            $( let $n = $n.clone(); )+
                move |$(clone!(@param $p),)+| $body
        }
    );
}

#[cfg(feature = "gtk_3_10")]
mod example {
    use gtk;
    use gtk::prelude::*;
    use gtk::{
        Builder, Button, Grid, Window,
    };

    pub fn main() {
        if gtk::init().is_err() {
            println!("Failed to initialize GTK.");
            return;
        }
        let glade_src = include_str!("grid.glade");
        let builder = Builder::new_from_string(glade_src);

        let window: Window = builder.get_object("window").unwrap();
        let grid: Grid = builder.get_object("grid").unwrap();
        let button6: Button = builder.get_object("button6").unwrap();
        button6.connect_clicked(clone!(grid, button6 => move |_| {
            let height = grid.get_cell_height(&button6);
            let new_height = if height == 2 { 1 } else { 2 };
            grid.set_cell_height(&button6, new_height);
        }));
        let button7: Button = builder.get_object("button7").unwrap();
        button7.connect_clicked(clone!(grid, button7 => move |_| {
            let left_attach = grid.get_cell_left_attach(&button7);
            let new_left_attach = if left_attach == 2 { 0 } else { left_attach + 1 };
            grid.set_cell_left_attach(&button7, new_left_attach);
        }));

        window.connect_delete_event(|_, _| {
            gtk::main_quit();
            Inhibit(false)
        });

        window.show_all();
        gtk::main();
    }
}

#[cfg(feature = "gtk_3_10")]
fn main() {
    example::main()
}

#[cfg(not(feature = "gtk_3_10"))]
fn main() {
    println!("This example only work with GTK 3.10 and later");
    println!("Did you forget to build with `--features gtk_3_10`?");
}
<|endoftext|>


<commit_before>#![cfg_attr(not(feature = "gtk_3_10"), allow(unused_variables, unused_mut))]

extern crate gio;
extern crate gtk;

#[cfg(feature = "gtk_3_10")]
mod example {
    // make moving clones into closures more convenient
    #[cfg(feature = "gtk_3_10")]
    macro_rules! clone {
        (@param _) => ( _ );
        (@param $x:ident) => ( $x );
        ($($n:ident),+ => move || $body:expr) => (
            {
                $( let $n = $n.clone(); )+
                    move || $body
            }
        );
        ($($n:ident),+ => move |$($p:tt),+| $body:expr) => (
            {
                $( let $n = $n.clone(); )+
                    move |$(clone!(@param $p),)+| $body
            }
        );
    }

    use gio;
    use gtk;
    use gio::prelude::*;
    use gtk::prelude::*;
    use gtk::{
        ApplicationWindow, Builder, Button, Grid,
    };

    use std::env::args;

    pub fn build_ui(application: &gtk::Application) {
        let glade_src = include_str!("grid.glade");
        let builder = Builder::new_from_string(glade_src);

        let window: ApplicationWindow = builder.get_object("window").expect("Couldn't get window");
        window.set_application(application);
        let grid: Grid = builder.get_object("grid").expect("Couldn't get grid");
        let button6: Button = builder.get_object("button6").expect("Couldn't get button6");
        button6.connect_clicked(clone!(grid => move |button| {
            let height = grid.get_cell_height(button);
            let new_height = if height == 2 { 1 } else { 2 };
            grid.set_cell_height(button, new_height);
        }));
        let button7: Button = builder.get_object("button7").expect("Couldn't get button7");
        button7.connect_clicked(clone!(grid => move |button| {
            let left_attach = grid.get_cell_left_attach(button);
            let new_left_attach = if left_attach == 2 { 0 } else { left_attach + 1 };
            grid.set_cell_left_attach(button, new_left_attach);
        }));

        window.connect_delete_event(move |win, _| {
            win.destroy();
            Inhibit(false)
        });

        window.show_all();
    }

    pub fn main() {
        let application = gtk::Application::new("com.github.grid",
                                                gio::ApplicationFlags::empty())
                                           .expect("Initialization failed...");

        application.connect_startup(move |app| {
            build_ui(app);
        });
        application.connect_activate(|_| {});

        application.run(&args().collect::<Vec<_>>());
    }
}

#[cfg(feature = "gtk_3_10")]
fn main() {
    example::main()
}

#[cfg(not(feature = "gtk_3_10"))]
fn main() {
    println!("This example requires GTK 3.10 or later");
    println!("Did you forget to build with `--features gtk_3_10`?");
}
<commit_msg>Add weak reference<commit_after>#![cfg_attr(not(feature = "gtk_3_10"), allow(unused_variables, unused_mut))]

extern crate gio;
extern crate gtk;

#[cfg(feature = "gtk_3_10")]
mod example {
    use gio;
    use gtk;
    use gio::prelude::*;
    use gtk::prelude::*;
    use gtk::{
        ApplicationWindow, Builder, Button, Grid,
    };

    use std::env::args;

    pub fn build_ui(application: &gtk::Application) {
        let glade_src = include_str!("grid.glade");
        let builder = Builder::new_from_string(glade_src);

        let window: ApplicationWindow = builder.get_object("window").expect("Couldn't get window");
        window.set_application(application);
        let grid: Grid = builder.get_object("grid").expect("Couldn't get grid");
        let button6: Button = builder.get_object("button6").expect("Couldn't get button6");
        let weak_grid = grid.downgrade();
        button6.connect_clicked(move |button| {
            let grid = match weak_grid.upgrade() {
                Some(grid) => grid,
                None => return,
            };
            let height = grid.get_cell_height(button);
            let new_height = if height == 2 { 1 } else { 2 };
            grid.set_cell_height(button, new_height);
        });
        let button7: Button = builder.get_object("button7").expect("Couldn't get button7");
        let weak_grid = grid.downgrade();
        button7.connect_clicked(move |button| {
            let grid = match weak_grid.upgrade() {
                Some(grid) => grid,
                None => return,
            };
            let left_attach = grid.get_cell_left_attach(button);
            let new_left_attach = if left_attach == 2 { 0 } else { left_attach + 1 };
            grid.set_cell_left_attach(button, new_left_attach);
        });

        window.connect_delete_event(move |win, _| {
            win.destroy();
            Inhibit(false)
        });

        window.show_all();
    }

    pub fn main() {
        let application = gtk::Application::new("com.github.grid",
                                                gio::ApplicationFlags::empty())
                                           .expect("Initialization failed...");

        application.connect_startup(move |app| {
            build_ui(app);
        });
        application.connect_activate(|_| {});

        application.run(&args().collect::<Vec<_>>());
    }
}

#[cfg(feature = "gtk_3_10")]
fn main() {
    example::main()
}

#[cfg(not(feature = "gtk_3_10"))]
fn main() {
    println!("This example requires GTK 3.10 or later");
    println!("Did you forget to build with `--features gtk_3_10`?");
}
<|endoftext|>


<commit_before>
extern crate mprovision;
extern crate docopt;
#[macro_use(version)]
extern crate version;
extern crate chrono;

use std::io::{self, Write};
use std::process;
use docopt::Docopt;

const USAGE: &'static str = "
mprovision
A tool that helps iOS developers to manage mobileprovision files.

Usage:
  mprovision search <text> [<directory>]
  mprovision remove <uuid> [<directory>]
  mprovision show-xml <uuid> [<directory>]
  mprovision show-expired [<directory>]
  mprovision (-h | --help)
  mprovision --version

Options:
  -h --help     Show this help message.
  --version     Show version.
";

fn main() {
    let args = Docopt::new(USAGE)
                   .and_then(|d| {
                       d.options_first(true)
                        .version(Some(format!("mprovision {}", version!())))
                        .parse()
                   })
                   .unwrap_or_else(|e| e.exit());

    if let Some(cmd) = Command::from_args(&args) {
        let result = match cmd {
            Command::Search => search(&args),
            Command::Remove => remove(&args),
            Command::ShowXml => show_xml(&args),
            Command::ShowExpired => show_expired(&args),
        };
        match result {
            Ok(_) => process::exit(0),
            Err(e) => {
                writeln!(&mut io::stderr(), "{}", e).unwrap();
                process::exit(1);
            }
        }
    }
}

enum Command {
    Search,
    Remove,
    ShowXml,
    ShowExpired,
}

impl Command {
    fn from_args(args: &::docopt::ArgvMap) -> Option<Command> {
        if args.get_bool("search") {
            Some(Command::Search)
        } else if args.get_bool("remove") {
            Some(Command::Remove)
        } else if args.get_bool("show-xml") {
            Some(Command::ShowXml)
        } else if args.get_bool("show-expired") {
            Some(Command::ShowExpired)
        } else {
            None
        }
    }
}

fn search(args: &::docopt::ArgvMap) -> Result<(), String> {
    let text = args.get_str("<text>");
    if text.is_empty() {
        return Err("<text> should not be empty.".to_owned());
    }
    let dir_name = args.get_str("<directory>");
    let dir_name = if dir_name.is_empty() {
        None
    } else {
        Some(dir_name.as_ref())
    };

    mprovision::with_path(dir_name, |path| mprovision::search(path, text))
        .and_then(|info| {
            if info.profiles.len() == 0 {
                println!("Nothing found for '{}'", text);
            } else {
                println!("Found {} of {} profiles.\n",
                         info.profiles.len(),
                         info.total);
                for profile in &info.profiles {
                    println!("{}\n", profile.description());
                }
            }
            Ok(())
        })
        .map_err(|e| e.to_string())
}

fn remove(args: &::docopt::ArgvMap) -> Result<(), String> {
    let uuid = args.get_str("<uuid>");
    if uuid.is_empty() {
        return Err("<uuid> should not be empty.".to_owned());
    }
    let dir_name = args.get_str("<directory>");
    let dir_name = if dir_name.is_empty() {
        None
    } else {
        Some(dir_name.as_ref())
    };

    mprovision::with_path(dir_name, |path| mprovision::remove(path, uuid))
        .and_then(|_| Ok(println!("Profile '{}' was removed.", uuid)))
        .map_err(|e| e.to_string())
}

fn show_xml(args: &::docopt::ArgvMap) -> Result<(), String> {
    let uuid = args.get_str("<uuid>");
    if uuid.is_empty() {
        return Err("<uuid> should not be empty.".to_owned());
    }
    let dir_name = args.get_str("<directory>");
    let dir_name = if dir_name.is_empty() {
        None
    } else {
        Some(dir_name.as_ref())
    };

    mprovision::with_path(dir_name, |path| mprovision::xml(path, uuid))
        .and_then(|xml| Ok(println!("{}", xml)))
        .map_err(|e| e.to_string())
}

fn show_expired(args: &::docopt::ArgvMap) -> Result<(), String> {
    use chrono::*;

    let dir_name = args.get_str("<directory>");
    let dir_name = if dir_name.is_empty() {
        None
    } else {
        Some(dir_name.as_ref())
    };

    mprovision::with_path(dir_name, |path| mprovision::expired_profiles(path, UTC::now()))
        .and_then(|info| {
            if info.profiles.len() == 0 {
                println!("All profiles are valid.");
            } else {
                println!("Found {} of {} profiles.\n",
                         info.profiles.len(),
                         info.total);
                for profile in &info.profiles {
                    println!("{}\n", profile.description());
                }
            }
            Ok(())
        })
        .map_err(|e| e.to_string())
}
<commit_msg>Refactor usage of <directory> parameter.<commit_after>
extern crate mprovision;
extern crate docopt;
#[macro_use(version)]
extern crate version;
extern crate chrono;

use std::io::{self, Write};
use std::process;
use std::path::Path;
use docopt::Docopt;

const USAGE: &'static str = "
mprovision
A tool that helps iOS developers to manage mobileprovision files.

Usage:
  mprovision search <text> [<directory>]
  mprovision remove <uuid> [<directory>]
  mprovision show-xml <uuid> [<directory>]
  mprovision show-expired [<directory>]
  mprovision (-h | --help)
  mprovision --version

Options:
  -h --help     Show this help message.
  --version     Show version.
";

fn main() {
    let args = Docopt::new(USAGE)
                   .and_then(|d| {
                       d.options_first(true)
                        .version(Some(format!("mprovision {}", version!())))
                        .parse()
                   })
                   .unwrap_or_else(|e| e.exit());

    if let Some(cmd) = Command::from_args(&args) {
        let result = match cmd {
            Command::Search => search(&args),
            Command::Remove => remove(&args),
            Command::ShowXml => show_xml(&args),
            Command::ShowExpired => show_expired(&args),
        };
        match result {
            Ok(_) => process::exit(0),
            Err(e) => {
                writeln!(&mut io::stderr(), "{}", e).unwrap();
                process::exit(1);
            }
        }
    }
}

enum Command {
    Search,
    Remove,
    ShowXml,
    ShowExpired,
}

impl Command {
    fn from_args(args: &::docopt::ArgvMap) -> Option<Command> {
        if args.get_bool("search") {
            Some(Command::Search)
        } else if args.get_bool("remove") {
            Some(Command::Remove)
        } else if args.get_bool("show-xml") {
            Some(Command::ShowXml)
        } else if args.get_bool("show-expired") {
            Some(Command::ShowExpired)
        } else {
            None
        }
    }
}

fn search(args: &::docopt::ArgvMap) -> Result<(), String> {
    let text = args.get_str("<text>");
    if text.is_empty() {
        return Err("<text> should not be empty.".to_owned());
    }

    mprovision::with_path(directory(args), |path| mprovision::search(path, text))
        .and_then(|info| {
            if info.profiles.len() == 0 {
                println!("Nothing found for '{}'", text);
            } else {
                println!("Found {} of {} profiles.\n",
                         info.profiles.len(),
                         info.total);
                for profile in &info.profiles {
                    println!("{}\n", profile.description());
                }
            }
            Ok(())
        })
        .map_err(|e| e.to_string())
}

fn remove(args: &::docopt::ArgvMap) -> Result<(), String> {
    let uuid = args.get_str("<uuid>");
    if uuid.is_empty() {
        return Err("<uuid> should not be empty.".to_owned());
    }

    mprovision::with_path(directory(args), |path| mprovision::remove(path, uuid))
        .and_then(|_| Ok(println!("Profile '{}' was removed.", uuid)))
        .map_err(|e| e.to_string())
}

fn show_xml(args: &::docopt::ArgvMap) -> Result<(), String> {
    let uuid = args.get_str("<uuid>");
    if uuid.is_empty() {
        return Err("<uuid> should not be empty.".to_owned());
    }

    mprovision::with_path(directory(args), |path| mprovision::xml(path, uuid))
        .and_then(|xml| Ok(println!("{}", xml)))
        .map_err(|e| e.to_string())
}

fn show_expired(args: &::docopt::ArgvMap) -> Result<(), String> {
    use chrono::*;

    mprovision::with_path(directory(args),
                          |path| mprovision::expired_profiles(path, UTC::now()))
        .and_then(|info| {
            if info.profiles.len() == 0 {
                println!("All profiles are valid.");
            } else {
                println!("Found {} of {} profiles.\n",
                         info.profiles.len(),
                         info.total);
                for profile in &info.profiles {
                    println!("{}\n", profile.description());
                }
            }
            Ok(())
        })
        .map_err(|e| e.to_string())
}

fn directory(args: &::docopt::ArgvMap) -> Option<&Path> {
    let dir_name = args.get_str("<directory>");
    if dir_name.is_empty() {
        None
    } else {
        Some(dir_name.as_ref())
    }
}
<|endoftext|>


<commit_before> #![warn(unused, bad_style,
        unnecessary_qualification, unnecessary_typecast, unused_result)]

#![feature(slicing_syntax)]

extern crate num;

extern crate common;
extern crate seq;

use num::BigUint;
use common::Solver;
use seq::Fibonacci;

fn compute(limit_len: uint) -> uint {
    let limit = from_str("9".repeat(limit_len - 1)[]).unwrap();
    Fibonacci::<BigUint>::new()
        .take_while(|n| *n <= limit)
        .count() + 1
}

fn solve() -> String {
    compute(1000).to_string()
}

fn main() { Solver::new("2783915460", solve).run(); }

#[cfg(test)]
mod tests {
    #[test]
    fn three() {
        assert_eq!(12, super::compute(3));
    }
}
<commit_msg>Fix p025<commit_after> #![warn(unused, bad_style,
        unnecessary_qualification, unnecessary_typecast, unused_result)]

#![feature(slicing_syntax)]

extern crate num;

extern crate common;
extern crate seq;

use num::BigUint;
use common::Solver;
use seq::Fibonacci;

fn compute(limit_len: uint) -> uint {
    let limit = from_str("9".repeat(limit_len - 1)[]).unwrap();
    Fibonacci::<BigUint>::new()
        .take_while(|n| *n <= limit)
        .count() + 1
}

fn solve() -> String {
    compute(1000).to_string()
}

fn main() { Solver::new("4782", solve).run(); }

#[cfg(test)]
mod tests {
    #[test]
    fn three() {
        assert_eq!(12, super::compute(3));
    }
}
<|endoftext|>


<commit_before>use rustc::lint::*;
use rustc_front::hir::*;
use rustc_front::intravisit::*;
use syntax::ast::LitKind;
use utils::{span_lint_and_then, in_macro, snippet_opt, SpanlessEq};

/// **What it does:** This lint checks for boolean expressions that can be written more concisely
///
/// **Why is this bad?** Readability of boolean expressions suffers from unnecesessary duplication
///
/// **Known problems:** Ignores short circuting behavior, bitwise and/or and xor. Ends up suggesting things like !(a == b)
///
/// **Example:** `if a && true` should be `if a`
declare_lint! {
    pub NONMINIMAL_BOOL, Allow,
    "checks for boolean expressions that can be written more concisely"
}

/// **What it does:** This lint checks for boolean expressions that contain terminals that can be eliminated
///
/// **Why is this bad?** This is most likely a logic bug
///
/// **Known problems:** Ignores short circuiting behavior
///
/// **Example:** The `b` in `if a && b || a` is unnecessary because the expression is equivalent to `if a`
declare_lint! {
    pub LOGIC_BUG, Warn,
    "checks for boolean expressions that contain terminals which can be eliminated"
}

#[derive(Copy,Clone)]
pub struct NonminimalBool;

impl LintPass for NonminimalBool {
    fn get_lints(&self) -> LintArray {
        lint_array!(NONMINIMAL_BOOL, LOGIC_BUG)
    }
}

impl LateLintPass for NonminimalBool {
    fn check_item(&mut self, cx: &LateContext, item: &Item) {
        NonminimalBoolVisitor(cx).visit_item(item)
    }
}

struct NonminimalBoolVisitor<'a, 'tcx: 'a>(&'a LateContext<'a, 'tcx>);

use quine_mc_cluskey::Bool;
struct Hir2Qmm<'a, 'tcx: 'a, 'v> {
    terminals: Vec<&'v Expr>,
    cx: &'a LateContext<'a, 'tcx>
}

impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
    fn extract(&mut self, op: BinOp_, a: &[&'v Expr], mut v: Vec<Bool>) -> Result<Vec<Bool>, String> {
        for a in a {
            if let ExprBinary(binop, ref lhs, ref rhs) = a.node {
                if binop.node == op {
                    v = self.extract(op, &[lhs, rhs], v)?;
                    continue;
                }
            }
            v.push(self.run(a)?);
        }
        Ok(v)
    }

    fn run(&mut self, e: &'v Expr) -> Result<Bool, String> {
        // prevent folding of `cfg!` macros and the like
        if !in_macro(self.cx, e.span) {
            match e.node {
                ExprUnary(UnNot, ref inner) => return Ok(Bool::Not(box self.run(inner)?)),
                ExprBinary(binop, ref lhs, ref rhs) => {
                    match binop.node {
                        BiOr => return Ok(Bool::Or(self.extract(BiOr, &[lhs, rhs], Vec::new())?)),
                        BiAnd => return Ok(Bool::And(self.extract(BiAnd, &[lhs, rhs], Vec::new())?)),
                        _ => {},
                    }
                },
                ExprLit(ref lit) => {
                    match lit.node {
                        LitKind::Bool(true) => return Ok(Bool::True),
                        LitKind::Bool(false) => return Ok(Bool::False),
                        _ => {},
                    }
                },
                _ => {},
            }
        }
        if let Some((n, _)) = self.terminals
                                  .iter()
                                  .enumerate()
                                  .find(|&(_, expr)| SpanlessEq::new(self.cx).ignore_fn().eq_expr(e, expr)) {
            #[allow(cast_possible_truncation)]
            return Ok(Bool::Term(n as u8));
        }
        let n = self.terminals.len();
        self.terminals.push(e);
        if n < 32 {
            #[allow(cast_possible_truncation)]
            Ok(Bool::Term(n as u8))
        } else {
            Err("too many literals".to_owned())
        }
    }
}

fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
    fn recurse(brackets: bool, cx: &LateContext, suggestion: &Bool, terminals: &[&Expr], mut s: String) -> String {
        use quine_mc_cluskey::Bool::*;
        match *suggestion {
            True => {
                s.extend("true".chars());
                s
            },
            False => {
                s.extend("false".chars());
                s
            },
            Not(ref inner) => {
                s.push('!');
                recurse(true, cx, inner, terminals, s)
            },
            And(ref v) => {
                if brackets {
                    s.push('(');
                }
                s = recurse(true, cx, &v[0], terminals, s);
                for inner in &v[1..] {
                    s.extend(" && ".chars());
                    s = recurse(true, cx, inner, terminals, s);
                }
                if brackets {
                    s.push(')');
                }
                s
            },
            Or(ref v) => {
                if brackets {
                    s.push('(');
                }
                s = recurse(true, cx, &v[0], terminals, s);
                for inner in &v[1..] {
                    s.extend(" || ".chars());
                    s = recurse(true, cx, inner, terminals, s);
                }
                if brackets {
                    s.push(')');
                }
                s
            },
            Term(n) => {
                s.extend(snippet_opt(cx, terminals[n as usize].span).expect("don't try to improve booleans created by macros").chars());
                s
            }
        }
    }
    recurse(false, cx, suggestion, terminals, String::new())
}

fn simple_negate(b: Bool) -> Bool {
    use quine_mc_cluskey::Bool::*;
    match b {
        True => False,
        False => True,
        t @ Term(_) => Not(Box::new(t)),
        And(mut v) => {
            for el in &mut v {
                *el = simple_negate(::std::mem::replace(el, True));
            }
            Or(v)
        },
        Or(mut v) => {
            for el in &mut v {
                *el = simple_negate(::std::mem::replace(el, True));
            }
            And(v)
        },
        Not(inner) => *inner,
    }
}

fn terminal_stats(b: &Bool) -> [usize; 32] {
    fn recurse(b: &Bool, stats: &mut [usize; 32]) {
        match *b {
            True | False => {},
            Not(ref inner) => recurse(inner, stats),
            And(ref v) | Or(ref v) => for inner in v {
                recurse(inner, stats)
            },
            Term(n) => stats[n as usize] += 1,
        }
    }
    use quine_mc_cluskey::Bool::*;
    let mut stats = [0; 32];
    recurse(b, &mut stats);
    stats
}

impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
    fn bool_expr(&self, e: &Expr) {
        let mut h2q = Hir2Qmm {
            terminals: Vec::new(),
            cx: self.0,
        };
        if let Ok(expr) = h2q.run(e) {
            let stats = terminal_stats(&expr);
            let mut simplified = expr.simplify();
            for simple in Bool::Not(Box::new(expr.clone())).simplify() {
                match simple {
                    Bool::Not(_) | Bool::True | Bool::False => {},
                    _ => simplified.push(Bool::Not(Box::new(simple.clone()))),
                }
                let simple_negated = simple_negate(simple);
                if simplified.iter().any(|s| *s == simple_negated) {
                    continue;
                }
                simplified.push(simple_negated);
            }
            if !simplified.iter().any(|s| *s == expr) {
                let mut improvements = Vec::new();
                'simplified: for suggestion in &simplified {
                    let simplified_stats = terminal_stats(&suggestion);
                    let mut improvement = false;
                    for i in 0..32 {
                        // ignore any "simplifications" that end up requiring a terminal more often than in the original expression
                        if stats[i] < simplified_stats[i] {
                            continue 'simplified;
                        }
                        // if the number of occurrences of a terminal decreases, this expression is a candidate for improvement
                        if stats[i] >= simplified_stats[i] {
                            improvement = true;
                        }
                        if stats[i] != 0 && simplified_stats[i] == 0 {
                            span_lint_and_then(self.0, LOGIC_BUG, e.span, "this boolean expression contains a logic bug", |db| {
                                db.span_help(h2q.terminals[i].span, "this expression can be optimized out by applying boolean operations to the outer expression");
                                db.span_suggestion(e.span, "it would look like the following", suggest(self.0, suggestion, &h2q.terminals));
                            });
                            // don't also lint `NONMINIMAL_BOOL`
                            improvements.clear();
                            break 'simplified;
                        }
                    }
                    if improvement {
                        improvements.push(suggestion);
                    }
                }
                if !improvements.is_empty() {
                    span_lint_and_then(self.0, NONMINIMAL_BOOL, e.span, "this boolean expression can be simplified", |db| {
                        for suggestion in &improvements {
                            db.span_suggestion(e.span, "try", suggest(self.0, suggestion, &h2q.terminals));
                        }
                    });
                }
            }
        }
    }
}

impl<'a, 'v, 'tcx> Visitor<'v> for NonminimalBoolVisitor<'a, 'tcx> {
    fn visit_expr(&mut self, e: &'v Expr) {
        if in_macro(self.0, e.span) { return }
        match e.node {
            ExprBinary(binop, _, _) if binop.node == BiOr || binop.node == BiAnd => self.bool_expr(e),
            ExprUnary(UnNot, ref inner) => {
                if self.0.tcx.node_types()[&inner.id].is_bool() {
                    self.bool_expr(e);
                } else {
                    walk_expr(self, e);
                }
            },
            _ => walk_expr(self, e),
        }
    }
}
<commit_msg>if a < b { ... } if a >= b { ... } what am I doing?<commit_after>use rustc::lint::*;
use rustc_front::hir::*;
use rustc_front::intravisit::*;
use syntax::ast::LitKind;
use utils::{span_lint_and_then, in_macro, snippet_opt, SpanlessEq};

/// **What it does:** This lint checks for boolean expressions that can be written more concisely
///
/// **Why is this bad?** Readability of boolean expressions suffers from unnecesessary duplication
///
/// **Known problems:** Ignores short circuting behavior, bitwise and/or and xor. Ends up suggesting things like !(a == b)
///
/// **Example:** `if a && true` should be `if a`
declare_lint! {
    pub NONMINIMAL_BOOL, Allow,
    "checks for boolean expressions that can be written more concisely"
}

/// **What it does:** This lint checks for boolean expressions that contain terminals that can be eliminated
///
/// **Why is this bad?** This is most likely a logic bug
///
/// **Known problems:** Ignores short circuiting behavior
///
/// **Example:** The `b` in `if a && b || a` is unnecessary because the expression is equivalent to `if a`
declare_lint! {
    pub LOGIC_BUG, Warn,
    "checks for boolean expressions that contain terminals which can be eliminated"
}

#[derive(Copy,Clone)]
pub struct NonminimalBool;

impl LintPass for NonminimalBool {
    fn get_lints(&self) -> LintArray {
        lint_array!(NONMINIMAL_BOOL, LOGIC_BUG)
    }
}

impl LateLintPass for NonminimalBool {
    fn check_item(&mut self, cx: &LateContext, item: &Item) {
        NonminimalBoolVisitor(cx).visit_item(item)
    }
}

struct NonminimalBoolVisitor<'a, 'tcx: 'a>(&'a LateContext<'a, 'tcx>);

use quine_mc_cluskey::Bool;
struct Hir2Qmm<'a, 'tcx: 'a, 'v> {
    terminals: Vec<&'v Expr>,
    cx: &'a LateContext<'a, 'tcx>
}

impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
    fn extract(&mut self, op: BinOp_, a: &[&'v Expr], mut v: Vec<Bool>) -> Result<Vec<Bool>, String> {
        for a in a {
            if let ExprBinary(binop, ref lhs, ref rhs) = a.node {
                if binop.node == op {
                    v = self.extract(op, &[lhs, rhs], v)?;
                    continue;
                }
            }
            v.push(self.run(a)?);
        }
        Ok(v)
    }

    fn run(&mut self, e: &'v Expr) -> Result<Bool, String> {
        // prevent folding of `cfg!` macros and the like
        if !in_macro(self.cx, e.span) {
            match e.node {
                ExprUnary(UnNot, ref inner) => return Ok(Bool::Not(box self.run(inner)?)),
                ExprBinary(binop, ref lhs, ref rhs) => {
                    match binop.node {
                        BiOr => return Ok(Bool::Or(self.extract(BiOr, &[lhs, rhs], Vec::new())?)),
                        BiAnd => return Ok(Bool::And(self.extract(BiAnd, &[lhs, rhs], Vec::new())?)),
                        _ => {},
                    }
                },
                ExprLit(ref lit) => {
                    match lit.node {
                        LitKind::Bool(true) => return Ok(Bool::True),
                        LitKind::Bool(false) => return Ok(Bool::False),
                        _ => {},
                    }
                },
                _ => {},
            }
        }
        if let Some((n, _)) = self.terminals
                                  .iter()
                                  .enumerate()
                                  .find(|&(_, expr)| SpanlessEq::new(self.cx).ignore_fn().eq_expr(e, expr)) {
            #[allow(cast_possible_truncation)]
            return Ok(Bool::Term(n as u8));
        }
        let n = self.terminals.len();
        self.terminals.push(e);
        if n < 32 {
            #[allow(cast_possible_truncation)]
            Ok(Bool::Term(n as u8))
        } else {
            Err("too many literals".to_owned())
        }
    }
}

fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
    fn recurse(brackets: bool, cx: &LateContext, suggestion: &Bool, terminals: &[&Expr], mut s: String) -> String {
        use quine_mc_cluskey::Bool::*;
        match *suggestion {
            True => {
                s.extend("true".chars());
                s
            },
            False => {
                s.extend("false".chars());
                s
            },
            Not(ref inner) => {
                s.push('!');
                recurse(true, cx, inner, terminals, s)
            },
            And(ref v) => {
                if brackets {
                    s.push('(');
                }
                s = recurse(true, cx, &v[0], terminals, s);
                for inner in &v[1..] {
                    s.extend(" && ".chars());
                    s = recurse(true, cx, inner, terminals, s);
                }
                if brackets {
                    s.push(')');
                }
                s
            },
            Or(ref v) => {
                if brackets {
                    s.push('(');
                }
                s = recurse(true, cx, &v[0], terminals, s);
                for inner in &v[1..] {
                    s.extend(" || ".chars());
                    s = recurse(true, cx, inner, terminals, s);
                }
                if brackets {
                    s.push(')');
                }
                s
            },
            Term(n) => {
                s.extend(snippet_opt(cx, terminals[n as usize].span).expect("don't try to improve booleans created by macros").chars());
                s
            }
        }
    }
    recurse(false, cx, suggestion, terminals, String::new())
}

fn simple_negate(b: Bool) -> Bool {
    use quine_mc_cluskey::Bool::*;
    match b {
        True => False,
        False => True,
        t @ Term(_) => Not(Box::new(t)),
        And(mut v) => {
            for el in &mut v {
                *el = simple_negate(::std::mem::replace(el, True));
            }
            Or(v)
        },
        Or(mut v) => {
            for el in &mut v {
                *el = simple_negate(::std::mem::replace(el, True));
            }
            And(v)
        },
        Not(inner) => *inner,
    }
}

fn terminal_stats(b: &Bool) -> [usize; 32] {
    fn recurse(b: &Bool, stats: &mut [usize; 32]) {
        match *b {
            True | False => {},
            Not(ref inner) => recurse(inner, stats),
            And(ref v) | Or(ref v) => for inner in v {
                recurse(inner, stats)
            },
            Term(n) => stats[n as usize] += 1,
        }
    }
    use quine_mc_cluskey::Bool::*;
    let mut stats = [0; 32];
    recurse(b, &mut stats);
    stats
}

impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
    fn bool_expr(&self, e: &Expr) {
        let mut h2q = Hir2Qmm {
            terminals: Vec::new(),
            cx: self.0,
        };
        if let Ok(expr) = h2q.run(e) {
            let stats = terminal_stats(&expr);
            let mut simplified = expr.simplify();
            for simple in Bool::Not(Box::new(expr.clone())).simplify() {
                match simple {
                    Bool::Not(_) | Bool::True | Bool::False => {},
                    _ => simplified.push(Bool::Not(Box::new(simple.clone()))),
                }
                let simple_negated = simple_negate(simple);
                if simplified.iter().any(|s| *s == simple_negated) {
                    continue;
                }
                simplified.push(simple_negated);
            }
            if !simplified.iter().any(|s| *s == expr) {
                let mut improvements = Vec::new();
                'simplified: for suggestion in &simplified {
                    let simplified_stats = terminal_stats(&suggestion);
                    let mut improvement = false;
                    for i in 0..32 {
                        // ignore any "simplifications" that end up requiring a terminal more often than in the original expression
                        if stats[i] < simplified_stats[i] {
                            continue 'simplified;
                        }
                        // if the number of occurrences of a terminal doesn't increase, this expression is a candidate for improvement
                        improvement = true;
                        if stats[i] != 0 && simplified_stats[i] == 0 {
                            span_lint_and_then(self.0, LOGIC_BUG, e.span, "this boolean expression contains a logic bug", |db| {
                                db.span_help(h2q.terminals[i].span, "this expression can be optimized out by applying boolean operations to the outer expression");
                                db.span_suggestion(e.span, "it would look like the following", suggest(self.0, suggestion, &h2q.terminals));
                            });
                            // don't also lint `NONMINIMAL_BOOL`
                            improvements.clear();
                            break 'simplified;
                        }
                    }
                    if improvement {
                        improvements.push(suggestion);
                    }
                }
                if !improvements.is_empty() {
                    span_lint_and_then(self.0, NONMINIMAL_BOOL, e.span, "this boolean expression can be simplified", |db| {
                        for suggestion in &improvements {
                            db.span_suggestion(e.span, "try", suggest(self.0, suggestion, &h2q.terminals));
                        }
                    });
                }
            }
        }
    }
}

impl<'a, 'v, 'tcx> Visitor<'v> for NonminimalBoolVisitor<'a, 'tcx> {
    fn visit_expr(&mut self, e: &'v Expr) {
        if in_macro(self.0, e.span) { return }
        match e.node {
            ExprBinary(binop, _, _) if binop.node == BiOr || binop.node == BiAnd => self.bool_expr(e),
            ExprUnary(UnNot, ref inner) => {
                if self.0.tcx.node_types()[&inner.id].is_bool() {
                    self.bool_expr(e);
                } else {
                    walk_expr(self, e);
                }
            },
            _ => walk_expr(self, e),
        }
    }
}
<|endoftext|>