<commit_before>// Many of my decisions were based off the following document
// https://web.archive.org/web/20140727185616/http://algs4.cs.princeton.edu/33balanced/

use std::cmp::Ord;
use std::option::{None, Option, Some};
use std::to_string::ToString;

/// Four
struct Four<V: ToString+Ord>(V, V, V, Option<(Box<Node<V>>, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>)>);

impl <V: ToString+Ord> Four<V> {

    /// Convert a Split into a TwoNode with the middle value as the value of the new parent node
    fn to_two(self) -> Two<V> {
        match self {
            Four(v1, v2, v3, None) =>
                Two(v2,
                    box LeafTwoNode(LeafTwo(v1)),
                    box LeafTwoNode(LeafTwo(v3))),
            Four(v1, v2, v3, Some((n1, n2, n3, n4))) =>
                Two(v2,
                    box TwoNode(Two(v1, n1, n2)),
                    box TwoNode(Two(v3, n3, n4))),
        }
    }
}

/// InsertResult
enum InsertResult<V: ToString+Ord> {
    Fit(Node<V>),  // box this node?
    Split(Four<V>),  // split should always contain a ThreeNode/LeafThreeNode. box this?
}

/// Direction
enum Direction {
    Left,
    Middle,
    Right,
    Leaf,
}

/// Two
pub struct Two<V: ToString+Ord>(pub V, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: ToString+Ord> Two<V> {
    fn to_node(self) -> Node<V> { TwoNode(self) }

    fn to_three(self, other_value: V, other_node: Box<Node<V>>) -> Three<V> {
        let Two(self_value, self_left, self_middle) = self;
        if self_value > other_value {
            Three(other_value, self_value, other_node, self_left, self_middle)
        } else {
            Three(self_value, other_value, self_left, self_middle, other_node)
        }
    }
}

/// Three
pub struct Three<V: ToString+Ord>(pub V, pub V, pub Box<Node<V>>, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: ToString+Ord> Three<V> {
    fn to_node(self) -> Node<V> { ThreeNode(self) }

    fn to_four(self, other_value: V, other_node: Box<Node<V>>) -> Four<V> {
        let Three(self_value1, self_value2, self_left, self_middle, self_right) = self;
        if other_value < self_value1 {
            Four(other_value, self_value1, self_value2, Some((other_node, self_left, self_middle, self_right)))
        } else {
            Four(self_value1, self_value2, other_value, Some((self_left, self_middle, self_right, other_node)))
        }
    }
}

/// LeafTwo
pub struct LeafTwo<V: ToString+Ord>(pub V);

/// LeafThree
pub struct LeafThree<V: ToString+Ord>(pub V, pub V);

impl <V: ToString+Ord> LeafThree<V> {
    fn to_four(self, value: V) -> Four<V> {
        let LeafThree(value1, value2) = self;
        if value > value2      { Four(value1, value2, value, None) }
        else if value < value1 { Four(value, value1, value2, None) }
        else                   { Four(value1, value, value2, None) }
    }
}

/// Node
pub enum Node<V: ToString+Ord> {
    LeafTwoNode(LeafTwo<V>),
    LeafThreeNode(LeafThree<V>),
    TwoNode(Two<V>),
    ThreeNode(Three<V>),
}

impl <V: ToString+Ord> ToString for Node<V> {
    fn to_string(&self) -> String {
        match *self {
            LeafTwoNode(LeafTwo(ref v)) => format!("LeafTwoNode({:s})", v.to_string()),
            LeafThreeNode(LeafThree(ref v1, ref v2)) => format!("LeafThreeNode({:s}, {:s})", v1.to_string(), v2.to_string()),
            TwoNode(Two(ref v, ref left, ref middle)) => format!("TwoNode({:s}, {:s}, {:s})", v.to_string(), left.to_string(), middle.to_string()),
            ThreeNode(Three(_, _, ref left, ref middle, ref right)) => format!("ThreeNode({:s}, {:s}, {:s})", left.to_string(), middle.to_string(), right.to_string()),
        }
    }
}

impl <V: ToString+Ord> Node<V> {
    // PRIVATE

    fn next_direction(&self, to_insert: &V) -> Direction {
        match self {
            &TwoNode(Two(ref value, _, _)) =>
                if to_insert < value { Left }
                else                 { Middle },
            &ThreeNode(Three(ref value1, ref value2, _, _, _)) =>
                if      to_insert < value1 { Left }
                else if to_insert > value2 { Right }
                else                       { Middle },
            _ => Leaf,
        }
    }

    fn contains_node(&self, to_check: &V) -> bool {
        match self {
            &TwoNode(Two(ref v, _, _)) |
                &LeafTwoNode(LeafTwo(ref v)) if to_check == v => true,

            &ThreeNode(Three(ref v1, ref v2, _, _, _)) |
                &LeafThreeNode(LeafThree(ref v1, ref v2)) if to_check == v1 || to_check == v2 => true,

            _ => false
        }
    }

    fn insert(self, to_insert: V) -> InsertResult<V> {
        // If value is already in this node, we're done (prevent duplicates)
        if self.contains_node(&to_insert) { return Fit(self); }

        let next_direction = self.next_direction(&to_insert);

        match self {
            // Insert if leaf TwoNode
            LeafTwoNode(LeafTwo(value)) => {
                let (smaller, larger) =
                    if value < to_insert { (value, to_insert) }
                    else                 { (to_insert, value) };
                let new_node = LeafThreeNode(LeafThree(smaller, larger));
                Fit(new_node)
            },

            // Split if leaf ThreeNode
            LeafThreeNode(leaf_three) => {
                let four_node = leaf_three.to_four(to_insert);
                Split(four_node)
            },

            // Recurse down if internal Node and handle results
            TwoNode(Two(value, box left, box middle)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node) = match next_direction {
                    Left => (left, middle),
                    Middle => (middle, left),
                    _ => fail!(""),
                };

                // Recurse, save the result of the insert
                let insert_result = next_node.insert(to_insert);

                // Handle the result of the insert
                let new_node = match insert_result {
                    Fit(returned_node) =>
                        match next_direction {
                            Left => Two(value, box returned_node, box other_node).to_node(),
                            Middle => Two(value, box other_node, box returned_node).to_node(),
                            _ => fail!(""),
                        },
                    Split(four_node) => four_node.to_two().to_three(value, box other_node).to_node(),
                };

                Fit(new_node)
            },

            // Recurse down if internal Node and handle results
            ThreeNode(Three(value1, value2, left, middle, right)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node1, other_node2) = match next_direction {
                    Left => (left, middle, right),
                    Middle => (middle, left, right),
                    Right => (right, left, middle),
                    _ => fail!(""),
                };

                let insert_result = next_node.insert(to_insert);

                match insert_result {
                    Fit(returned_node) => {
                        let new_node = match next_direction {
                            Left => ThreeNode(Three(value1, value2, box returned_node, other_node1, other_node2)),
                            Middle => ThreeNode(Three(value1, value2, other_node1, box returned_node, other_node2)),
                            Right => ThreeNode(Three(value1, value2, other_node1, other_node2, box returned_node)),
                            _ => fail!(""),
                        };
                        Fit(new_node)
                    },
                    Split(four_node) => {
                        let new_node: Four<V> = match next_direction {
                            Left => four_node.to_two().to_three(value1, other_node1).to_four(value2, other_node2),
                            Middle => four_node.to_two().to_three(value1, other_node1).to_four(value2, other_node2),
                            Right => four_node.to_two().to_three(value2, other_node2).to_four(value1, other_node1),
                            _ => fail!(""),
                        };
                        Split(new_node)
                    }
                }
            }
        }
    }
}

/// TTTree
pub struct TTTree<V: ToString+Ord> {
    pub root: Option<Node<V>>,
}

impl <V: ToString+Ord> ToString for TTTree<V> {
    fn to_string(&self) -> String {
        match self.root {
            Some(ref node) => node.to_string(),
            None => "TTTree(<empty>)".to_string(),
        }
    }
}

impl <V: ToString+Ord> TTTree<V> {
    pub fn new() -> TTTree<V> {
        TTTree { root: None }
    }

    pub fn insert(&mut self, value: V) -> () {
        let root: Option<Node<V>> = self.root.take();
        let new_root: Node<V> = match root {
            None => LeafTwoNode(LeafTwo(value)),
            Some(root) => {
                let result = root.insert(value);
                match result {
                    Fit(node) => node,
                    Split(node @ Four(..)) => node.to_two().to_node(),
                }
            }
        };
        self.root = Some(new_root);
    }
}

// TODO:
// Collection trait
// convert this to Key/Value K/V
// remove ToString debugging stuffs
<commit_msg>Simplify some logic<commit_after>// Many of my decisions were based off the following document
// https://web.archive.org/web/20140727185616/http://algs4.cs.princeton.edu/33balanced/

use std::cmp::Ord;
use std::option::{None, Option, Some};
use std::to_string::ToString;

/// Four
struct Four<V: ToString+Ord>(V, V, V, Option<(Box<Node<V>>, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>)>);

impl <V: ToString+Ord> Four<V> {

    /// Convert a Split into a TwoNode with the middle value as the value of the new parent node
    fn to_two(self) -> Two<V> {
        match self {
            Four(v1, v2, v3, None) =>
                Two(v2,
                    box LeafTwoNode(LeafTwo(v1)),
                    box LeafTwoNode(LeafTwo(v3))),
            Four(v1, v2, v3, Some((n1, n2, n3, n4))) =>
                Two(v2,
                    box TwoNode(Two(v1, n1, n2)),
                    box TwoNode(Two(v3, n3, n4))),
        }
    }
}

/// InsertResult
enum InsertResult<V: ToString+Ord> {
    Fit(Node<V>),  // box this node?
    Split(Four<V>),  // split should always contain a ThreeNode/LeafThreeNode. box this?
}

/// Direction
enum Direction {
    Left,
    Middle,
    Right,
    Leaf,
}

/// Two
pub struct Two<V: ToString+Ord>(pub V, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: ToString+Ord> Two<V> {
    fn to_node(self) -> Node<V> { TwoNode(self) }

    fn to_three(self, other_value: V, other_node: Box<Node<V>>) -> Three<V> {
        let Two(self_value, self_left, self_middle) = self;
        if self_value > other_value {
            Three(other_value, self_value, other_node, self_left, self_middle)
        } else {
            Three(self_value, other_value, self_left, self_middle, other_node)
        }
    }
}

/// Three
pub struct Three<V: ToString+Ord>(pub V, pub V, pub Box<Node<V>>, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: ToString+Ord> Three<V> {
    fn to_node(self) -> Node<V> { ThreeNode(self) }

    fn to_four(self, other_value: V, other_node: Box<Node<V>>) -> Four<V> {
        let Three(self_value1, self_value2, self_left, self_middle, self_right) = self;
        if other_value < self_value1 {
            Four(other_value, self_value1, self_value2, Some((other_node, self_left, self_middle, self_right)))
        } else {
            Four(self_value1, self_value2, other_value, Some((self_left, self_middle, self_right, other_node)))
        }
    }
}

/// LeafTwo
pub struct LeafTwo<V: ToString+Ord>(pub V);

/// LeafThree
pub struct LeafThree<V: ToString+Ord>(pub V, pub V);

impl <V: ToString+Ord> LeafThree<V> {
    fn to_four(self, value: V) -> Four<V> {
        let LeafThree(value1, value2) = self;
        if value > value2      { Four(value1, value2, value, None) }
        else if value < value1 { Four(value, value1, value2, None) }
        else                   { Four(value1, value, value2, None) }
    }
}

/// Node
pub enum Node<V: ToString+Ord> {
    LeafTwoNode(LeafTwo<V>),
    LeafThreeNode(LeafThree<V>),
    TwoNode(Two<V>),
    ThreeNode(Three<V>),
}

impl <V: ToString+Ord> ToString for Node<V> {
    fn to_string(&self) -> String {
        match *self {
            LeafTwoNode(LeafTwo(ref v)) => format!("LeafTwoNode({:s})", v.to_string()),
            LeafThreeNode(LeafThree(ref v1, ref v2)) => format!("LeafThreeNode({:s}, {:s})", v1.to_string(), v2.to_string()),
            TwoNode(Two(ref v, ref left, ref middle)) => format!("TwoNode({:s}, {:s}, {:s})", v.to_string(), left.to_string(), middle.to_string()),
            ThreeNode(Three(_, _, ref left, ref middle, ref right)) => format!("ThreeNode({:s}, {:s}, {:s})", left.to_string(), middle.to_string(), right.to_string()),
        }
    }
}

impl <V: ToString+Ord> Node<V> {
    // PRIVATE

    fn next_direction(&self, to_insert: &V) -> Direction {
        match self {
            &TwoNode(Two(ref value, _, _)) =>
                if to_insert < value { Left }
                else                 { Middle },
            &ThreeNode(Three(ref value1, ref value2, _, _, _)) =>
                if      to_insert < value1 { Left }
                else if to_insert > value2 { Right }
                else                       { Middle },
            _ => Leaf,
        }
    }

    fn contains_node(&self, to_check: &V) -> bool {
        match self {
            &TwoNode(Two(ref v, _, _)) |
                &LeafTwoNode(LeafTwo(ref v)) if to_check == v => true,

            &ThreeNode(Three(ref v1, ref v2, _, _, _)) |
                &LeafThreeNode(LeafThree(ref v1, ref v2)) if to_check == v1 || to_check == v2 => true,

            _ => false
        }
    }

    fn insert(self, to_insert: V) -> InsertResult<V> {
        // If value is already in this node, we're done (prevent duplicates)
        if self.contains_node(&to_insert) { return Fit(self); }

        let next_direction = self.next_direction(&to_insert);

        match self {
            // Insert if leaf TwoNode
            LeafTwoNode(LeafTwo(value)) => {
                let (smaller, larger) =
                    if value < to_insert { (value, to_insert) }
                    else                 { (to_insert, value) };
                let new_node = LeafThreeNode(LeafThree(smaller, larger));
                Fit(new_node)
            },

            // Split if leaf ThreeNode
            LeafThreeNode(leaf_three) => {
                let four_node = leaf_three.to_four(to_insert);
                Split(four_node)
            },

            // Recurse down if internal Node and handle results
            TwoNode(Two(value, box left, box middle)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node) = match next_direction {
                    Left => (left, middle),
                    Middle => (middle, left),
                    _ => fail!(""),
                };

                // Recurse, save the result of the insert
                let insert_result = next_node.insert(to_insert);

                // Handle the result of the insert
                let new_node = match insert_result {
                    Fit(returned_node) =>
                        match next_direction {
                            Left => Two(value, box returned_node, box other_node).to_node(),
                            Middle => Two(value, box other_node, box returned_node).to_node(),
                            _ => fail!(""),
                        },
                    Split(four_node) => four_node.to_two().to_three(value, box other_node).to_node(),
                };

                Fit(new_node)
            },

            // Recurse down if internal Node and handle results
            ThreeNode(Three(value1, value2, left, middle, right)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node1, other_node2) = match next_direction {
                    Left => (left, middle, right),
                    Middle => (middle, left, right),
                    Right => (right, left, middle),
                    _ => fail!(""),
                };

                let insert_result = next_node.insert(to_insert);

                match insert_result {
                    Fit(returned_node) => {
                        let three = match next_direction {
                            Left => Three(value1, value2, box returned_node, other_node1, other_node2),
                            Middle => Three(value1, value2, other_node1, box returned_node, other_node2),
                            Right => Three(value1, value2, other_node1, other_node2, box returned_node),
                            _ => fail!(""),
                        };
                        Fit(three.to_node())
                    },
                    Split(four_node) => {
                        let new_node: Four<V> = match next_direction {
                            Left => four_node.to_two().to_three(value1, other_node1).to_four(value2, other_node2),
                            Middle => four_node.to_two().to_three(value1, other_node1).to_four(value2, other_node2),
                            Right => four_node.to_two().to_three(value2, other_node2).to_four(value1, other_node1),
                            _ => fail!(""),
                        };
                        Split(new_node)
                    }
                }
            }
        }
    }
}

/// TTTree
pub struct TTTree<V: ToString+Ord> {
    pub root: Option<Node<V>>,
}

impl <V: ToString+Ord> ToString for TTTree<V> {
    fn to_string(&self) -> String {
        match self.root {
            Some(ref node) => node.to_string(),
            None => "TTTree(<empty>)".to_string(),
        }
    }
}

impl <V: ToString+Ord> TTTree<V> {
    pub fn new() -> TTTree<V> {
        TTTree { root: None }
    }

    pub fn insert(&mut self, value: V) -> () {
        let root: Option<Node<V>> = self.root.take();
        let new_root: Node<V> = match root {
            None => LeafTwoNode(LeafTwo(value)),
            Some(root) => {
                let result = root.insert(value);
                match result {
                    Fit(node) => node,
                    Split(node @ Four(..)) => node.to_two().to_node(),
                }
            }
        };
        self.root = Some(new_root);
    }
}

// TODO:
// Collection trait
// convert this to Key/Value K/V
// remove ToString debugging stuffs
<|endoftext|>


<commit_before>#![allow(dead_code)]
#[allow(non_camel_case_types)]
type float = f32;
fn ramer_douglas_peucker(v: Vec<(float, float)>, epsilon: float) -> Vec<(float, float)> {
    let length = v.len();
    if length < 3 {
        return v;
    }
    let mut stack = vec![(0, length - 1)];
    let mut result = Vec::new();
    let mut last_stack_index = -1;

    while let Some((start_index, end_index)) =  stack.pop() {
        // println!("start = {}, end = {}", start_index, end_index);
        let mut max_distance = 0.0 as float;
        let mut max_index = start_index;
        for i in start_index+1..end_index {
            let distance =
            distance_point_to_line(v[i], (v[start_index], v[end_index]));
            // println!("i = {}, distance = {}", i, distance);
            if distance > max_distance {
                max_distance = distance;
                max_index = i;
            }
        }
        if max_distance > epsilon {
            stack.push((max_index, end_index));
            stack.push((start_index, max_index));
        } else {
            if last_stack_index != start_index {
                result.push(v[start_index]);
            }
            result.push(v[end_index]);
            last_stack_index = end_index;
        }
    }
    result
}

fn distance_point_to_line(p: (float, float), l: ((float, float), (float, float))) -> float {
    if l.0 == l.1 {
        return distance_point_to_point(p, l.0);
    }
    let a = (l.0).1 - (l.1).1;
    let b = (l.1).0 - (l.0).0;
    let c = (l.0).0 * (l.1).1 - (l.1).0 * (l.0).1;
    let result = (a * p.0 + b * p.1 + c) / (a * a + b * b).sqrt();
    result.abs()
}

fn distance_point_to_point(x: (float, float), y: (float, float)) -> float {
    let a = y.0 - x.0;
    let b = y.1 - x.1;
    let result = (a * a + b * b).sqrt();
    result.abs()
}

#[test]
fn reduce_vector() {
    // Minimal cases:
    assert_eq!(vec![(1.0, 1.0)], ramer_douglas_peucker(vec![(1.0, 1.0)], 0.5));
    assert_eq!(vec![(1.0, 1.0), (2.0, 2.0)], ramer_douglas_peucker(vec![(1.0, 1.0), (2.0, 2.0)], 0.5));
    assert_eq!(vec![(1.0, 1.0), (3.0, 3.0)], ramer_douglas_peucker(vec![(1.0, 1.0), (2.0, 2.0), (3.0, 3.0)], 0.5));
    // Effect of varying epsilon:
    assert_eq!(vec![(0.0, 2.0), (1.0, 1.0), (3.0, 0.0), (5.0, 1.0)], ramer_douglas_peucker(vec![(0.0, 2.0), (1.0, 1.0), (3.0, 0.0), (5.0, 1.0)], 0.1));
    assert_eq!(vec![(0.0, 2.0), (3.0, 0.0), (5.0, 1.0)], ramer_douglas_peucker(vec![(0.0, 2.0), (1.0, 1.0), (3.0, 0.0), (5.0, 1.0)], 0.5));
    // Tests with vertical segments:
    assert_eq!(vec![(10.0, 35.0), (20.0, 29.0)], ramer_douglas_peucker(vec![(10.0, 35.0), (15.0, 34.0), (15.0, 30.0), (20.0, 29.0)], 10.0));
    assert_eq!(vec![(10.0, 35.0), (15.0, 34.0), (15.0, 30.0), (20.0, 29.0)], ramer_douglas_peucker(vec![(10.0, 35.0), (15.0, 34.0), (15.0, 30.0), (20.0, 29.0)], 1.0));
    // Tests with horizontal segments:
    assert_eq!(vec![(10.0, 35.0), (15.0, 35.0), (16.0, 30.0), (21.0, 30.0)], ramer_douglas_peucker(vec![(10.0, 35.0), (15.0, 35.0), (16.0, 30.0), (21.0, 30.0)], 1.0));
    assert_eq!(vec![(10.0, 35.0), (21.0, 30.0)], ramer_douglas_peucker(vec![(10.0, 35.0), (15.0, 35.0), (16.0, 30.0), (21.0, 30.0)], 10.0));
    // Tests with vertical and horizontal segments:
    assert_eq!(vec![(10.0, 30.0), (50.0, 10.0)], ramer_douglas_peucker(vec![(10.0, 30.0), (30.0, 30.0), (30.0, 10.0), (50.0, 10.0)], 10.0));
    assert_eq!(vec![(10.0, 30.0), (50.0, 10.0)], ramer_douglas_peucker(vec![(10.0, 30.0), (30.0, 30.0), (30.0, 10.0), (50.0, 10.0)], 15.0));
    // A more complex curve:
    assert_eq!(vec![(3.5, 21.25), (23.2, 3.1), (54.6, 18.15), (71.5, 9.7), (101.3, 21.1)], ramer_douglas_peucker(vec![(3.5, 21.25), (7.3, 12.0), (23.2, 3.1), (37.2, 12.07), (54.6, 18.15), (62.2, 16.45), (71.5, 9.7), (101.3, 21.1)], 5.0));
    assert_eq!(vec![(0.0, 0.0), (0.5, 0.5), (1.25, -0.25), (1.5, 0.5)], ramer_douglas_peucker(vec![(0.0,0.0),(0.5,0.5),(1.0,0.0),(1.25,-0.25),(1.5,0.5)], 0.25));
    // Start point == end point
    assert_eq!(vec![(0.0, 0.0), (2.0, 0.0), (2.0, 2.0), (0.0, 2.0), (0.0, 0.0)],ramer_douglas_peucker(vec![(0.0,0.0),(1.0,0.0),(2.0,0.0),(2.0,1.0),(2.0,2.0),(1.0,2.0),(0.0,2.0),(0.0,1.0),(0.0, 0.0)], 1.0));
}

#[test]
fn calculate_point_to_line_distance() {
    assert!((distance_point_to_line((3.0, 2.0), ((-2.0, 0.0),(0.0, 2.0))) - 2.12132).abs() < 0.00001);
    assert!(distance_point_to_line((0.0, 0.0), ((-1.0, 0.0),(1.0, 0.0))).abs() < 0.00001);
}

#[test]
fn calculate_point_to_point_distance() {
    assert!((distance_point_to_point((3.0, 2.0), (5.0, -1.0)) - 3.60555).abs() < 0.00001);
    assert!(distance_point_to_point((3.0, 2.0), (3.0, 2.0)).abs() < 0.00001);
}
<commit_msg>improve types<commit_after>#![allow(dead_code)]
#[allow(non_camel_case_types)]
type float = f32;
type Point = (float, float);
type Line = (Point, Point);

fn ramer_douglas_peucker(v: Vec<Point>, epsilon: float) -> Vec<Point> {
    let length = v.len();
    if length < 3 {
        return v;
    }
    let mut stack = vec![(0, length - 1)];
    let mut result = Vec::new();
    let mut last_stack_index = -1;

    while let Some((start_index, end_index)) =  stack.pop() {
        // println!("start = {}, end = {}", start_index, end_index);
        let mut max_distance = 0.0 as float;
        let mut max_index = start_index;
        for i in start_index+1..end_index {
            let distance =
            distance_point_to_line(v[i], (v[start_index], v[end_index]));
            // println!("i = {}, distance = {}", i, distance);
            if distance > max_distance {
                max_distance = distance;
                max_index = i;
            }
        }
        if max_distance > epsilon {
            stack.push((max_index, end_index));
            stack.push((start_index, max_index));
        } else {
            if last_stack_index != start_index {
                result.push(v[start_index]);
            }
            result.push(v[end_index]);
            last_stack_index = end_index;
        }
    }
    result
}

fn distance_point_to_line(p: Point, l: Line) -> float {
    if l.0 == l.1 {
        return distance_point_to_point(p, l.0);
    }
    let a = (l.0).1 - (l.1).1;
    let b = (l.1).0 - (l.0).0;
    let c = (l.0).0 * (l.1).1 - (l.1).0 * (l.0).1;
    let result = (a * p.0 + b * p.1 + c) / (a * a + b * b).sqrt();
    result.abs()
}

fn distance_point_to_point(x: Point, y: Point) -> float {
    let a = y.0 - x.0;
    let b = y.1 - x.1;
    let result = (a * a + b * b).sqrt();
    result.abs()
}

#[test]
fn reduce_vector() {
    // Minimal cases:
    assert_eq!(vec![(1.0, 1.0)], ramer_douglas_peucker(vec![(1.0, 1.0)], 0.5));
    assert_eq!(vec![(1.0, 1.0), (2.0, 2.0)], ramer_douglas_peucker(vec![(1.0, 1.0), (2.0, 2.0)], 0.5));
    assert_eq!(vec![(1.0, 1.0), (3.0, 3.0)], ramer_douglas_peucker(vec![(1.0, 1.0), (2.0, 2.0), (3.0, 3.0)], 0.5));
    // Effect of varying epsilon:
    assert_eq!(vec![(0.0, 2.0), (1.0, 1.0), (3.0, 0.0), (5.0, 1.0)], ramer_douglas_peucker(vec![(0.0, 2.0), (1.0, 1.0), (3.0, 0.0), (5.0, 1.0)], 0.1));
    assert_eq!(vec![(0.0, 2.0), (3.0, 0.0), (5.0, 1.0)], ramer_douglas_peucker(vec![(0.0, 2.0), (1.0, 1.0), (3.0, 0.0), (5.0, 1.0)], 0.5));
    // Tests with vertical segments:
    assert_eq!(vec![(10.0, 35.0), (20.0, 29.0)], ramer_douglas_peucker(vec![(10.0, 35.0), (15.0, 34.0), (15.0, 30.0), (20.0, 29.0)], 10.0));
    assert_eq!(vec![(10.0, 35.0), (15.0, 34.0), (15.0, 30.0), (20.0, 29.0)], ramer_douglas_peucker(vec![(10.0, 35.0), (15.0, 34.0), (15.0, 30.0), (20.0, 29.0)], 1.0));
    // Tests with horizontal segments:
    assert_eq!(vec![(10.0, 35.0), (15.0, 35.0), (16.0, 30.0), (21.0, 30.0)], ramer_douglas_peucker(vec![(10.0, 35.0), (15.0, 35.0), (16.0, 30.0), (21.0, 30.0)], 1.0));
    assert_eq!(vec![(10.0, 35.0), (21.0, 30.0)], ramer_douglas_peucker(vec![(10.0, 35.0), (15.0, 35.0), (16.0, 30.0), (21.0, 30.0)], 10.0));
    // Tests with vertical and horizontal segments:
    assert_eq!(vec![(10.0, 30.0), (50.0, 10.0)], ramer_douglas_peucker(vec![(10.0, 30.0), (30.0, 30.0), (30.0, 10.0), (50.0, 10.0)], 10.0));
    assert_eq!(vec![(10.0, 30.0), (50.0, 10.0)], ramer_douglas_peucker(vec![(10.0, 30.0), (30.0, 30.0), (30.0, 10.0), (50.0, 10.0)], 15.0));
    // A more complex curve:
    assert_eq!(vec![(3.5, 21.25), (23.2, 3.1), (54.6, 18.15), (71.5, 9.7), (101.3, 21.1)], ramer_douglas_peucker(vec![(3.5, 21.25), (7.3, 12.0), (23.2, 3.1), (37.2, 12.07), (54.6, 18.15), (62.2, 16.45), (71.5, 9.7), (101.3, 21.1)], 5.0));
    assert_eq!(vec![(0.0, 0.0), (0.5, 0.5), (1.25, -0.25), (1.5, 0.5)], ramer_douglas_peucker(vec![(0.0,0.0),(0.5,0.5),(1.0,0.0),(1.25,-0.25),(1.5,0.5)], 0.25));
    // Start point == end point
    assert_eq!(vec![(0.0, 0.0), (2.0, 0.0), (2.0, 2.0), (0.0, 2.0), (0.0, 0.0)],ramer_douglas_peucker(vec![(0.0,0.0),(1.0,0.0),(2.0,0.0),(2.0,1.0),(2.0,2.0),(1.0,2.0),(0.0,2.0),(0.0,1.0),(0.0, 0.0)], 1.0));
}

#[test]
fn calculate_point_to_line_distance() {
    assert!((distance_point_to_line((3.0, 2.0), ((-2.0, 0.0),(0.0, 2.0))) - 2.12132).abs() < 0.00001);
    assert!(distance_point_to_line((0.0, 0.0), ((-1.0, 0.0),(1.0, 0.0))).abs() < 0.00001);
}

#[test]
fn calculate_point_to_point_distance() {
    assert!((distance_point_to_point((3.0, 2.0), (5.0, -1.0)) - 3.60555).abs() < 0.00001);
    assert!(distance_point_to_point((3.0, 2.0), (3.0, 2.0)).abs() < 0.00001);
}
<|endoftext|>


<commit_before>//! # `derive_more`
//!
//! [![Build Status](https://api.travis-ci.org/JelteF/derive_more.svg?branch=master)](https://travis-ci.org/JelteF/derive_more)
//! [![Latest Version](https://img.shields.io/crates/v/derive_more.svg)](https://crates.io/crates/derive_more)
//! [![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://jeltef.github.io/derive_more/derive_more/)
//! [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/JelteF/derive_more/master/LICENSE)
//!
//! Rust has lots of builtin traits that are implemented for its basic types, such
//! as `Add`, `Not`, `From` or `Display`.
//! However, when wrapping these types inside your own structs or enums you lose the
//! implementations of these traits and are required to recreate them.
//! This is especially annoying when your own structures are very simple, such as
//! when using the commonly advised newtype pattern (e.g. `MyInt(i32)`).
//!
//! This library tries to remove these annoyances and the corresponding boilerplate code.
//! It does this by allowing you to derive lots of commonly used traits for both structs and enums.
//!
//! ## Example code
//!
//! By using this library the following code just works:
//!
//! ```rust
//! extern crate derive_more;
//! use derive_more::{Add, Display, From, Into};
//!
//! #[derive(PartialEq, From, Add)]
//! struct MyInt(i32);
//!
//! #[derive(PartialEq, From, Into)]
//! struct Point2D {
//!     x: i32,
//!     y: i32,
//! }
//!
//! #[derive(PartialEq, From, Add, Display)]
//! enum MyEnum {
//!     #[display(fmt = "int: {}", _0)]
//!     Int(i32),
//!     Uint(u32),
//!     #[display(fmt = "nothing")]
//!     Nothing,
//! }
//!
//! assert!(MyInt(11) == MyInt(5) + 6.into());
//! assert!((5, 6) == Point2D { x: 5, y: 6 }.into());
//! assert!(MyEnum::Int(15) == (MyEnum::Int(8) + 7.into()).unwrap());
//! assert!(MyEnum::Int(15).to_string() == "int: 15");
//! assert!(MyEnum::Uint(42).to_string() == "42");
//! assert!(MyEnum::Nothing.to_string() == "nothing");
//! ```
//!
//! ## The derivable traits
//!
//! Below are all the traits that you can derive using this library.
//! Some trait derivations are so similar that the further documentation will only show a single one
//! of them.
//! You can recognize these by the "-like" suffix in their name.
//! The trait name before that will be the only one that is used throughout the further
//! documentation.
//!
//! It is important to understand what code gets generated when using one of the
//! derives from this crate.
//! That is why the links below explain what code gets generated for a trait for
//! each group from before.
//!
//! You can use the [`cargo-expand`] utility to see the exact code that is generated
//! for your specific type.
//! This will show you your code with all macros and derives expanded.
//!
//! **NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't
//! automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]`
//!
//! ### Conversion traits
//!
//! These are traits that are used to convert automatically between types.
//!
//! 1. [`From`]
//! 2. [`Into`]
//! 3. [`FromStr`]
//! 4. [`TryInto`]
//! 5. [`IntoIterator`]
//! 6. [`AsRef`]
//! 7. [`AsMut`]
//!
//! ### Formatting traits
//!
//! These traits are used for converting a struct to a string in different ways.
//!
//! 1. [`Display`-like], contains `Display`, `Binary`, `Octal`, `LowerHex`,
//!    `UpperHex`, `LowerExp`, `UpperExp`, `Pointer`
//!
//! ### Operators
//!
//! These are traits that can be used for operator overloading.
//!
//! 1. [`Index`]
//! 2. [`Deref`]
//! 3. [`Not`-like], contains `Not` and `Neg`
//! 4. [`Add`-like], contains `Add`, `Sub`, `BitAnd`, `BitOr`, `BitXor`, `MulSelf`,
//!    `DivSelf`, `RemSelf`, `ShrSelf` and `ShlSelf`
//! 5. [`Mul`-like], contains `Mul`, `Div`, `Rem`, `Shr` and `Shl`
//! 3. [`Sum`-like], contains `Sum` and `Product`
//! 6. [`IndexMut`]
//! 7. [`DerefMut`]
//! 8. [`AddAssign`-like], contains `AddAssign`, `SubAssign`, `BitAndAssign`,
//!    `BitOrAssign` and `BitXorAssign`
//! 9. [`MulAssign`-like], contains `MulAssign`, `DivAssign`, `RemAssign`,
//!    `ShrAssign` and `ShlAssign`
//!
//! ### Static methods
//!
//! These don't derive traits, but derive static methods instead.
//!
//! 1. [`Constructor`], this derives a `new` method that can be used as a constructor.
//!    This is very basic if you need more customization for your constructor, check
//!    out the [`derive-new`] crate.
//!
//! ## Generated code
//!
//! ## Installation
//!
//! This library requires Rust 1.15 or higher, so this needs to be installed.
//! Then add the following to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! derive_more = "0.15.0"
//! ```
//!
//! And this to the top of your Rust file:
//!
//! ```rust
//! extern crate derive_more;
//! // Only needed when using the Rust 2015, for 2018 you can skip this line
//! extern crate core;
//! ```
//!
//! This crate supports `no_std` out of the box.
//!
//! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
//! [`derive-new`]: https://github.com/nrc/derive-new
//!
//! [`From`]: from.html
//! [`Into`]: into.html
//! [`FromStr`]: from_str.html
//! [`TryInto`]: try_into.html
//! [`IntoIterator`]: into_iterator.html
//! [`AsRef`]: as_ref.html
//! [`AsMut`]: as_mut.html
//!
//! [`Display`-like]: display.html
//!
//! [`Index`]: index_op.html
//! [`Deref`]: deref.html
//! [`Not`-like]: not.html
//! [`Add`-like]: add.html
//! [`Mul`-like]: mul.html
//! [`Sum`-like]: sum.html
//! [`IndexMut`]: index_mut.html
//! [`DerefMut`]: deref_mut.html
//! [`AddAssign`-like]: add_assign.html
//! [`MulAssign`-like]: mul_assign.html
//!
//! [`Constructor`]: constructor.html

#![recursion_limit = "128"]

extern crate proc_macro;
use proc_macro2;
use syn;

use proc_macro::TokenStream;
use syn::parse::Error as ParseError;

mod utils;

#[cfg(feature = "add_assign_like")]
mod add_assign_like;
#[cfg(any(
    feature = "add_like",
    feature = "add_assign_like",
    feature = "mul_like"
))]
mod add_helpers;
#[cfg(any(feature = "add_like", feature = "mul_like"))]
mod add_like;
#[cfg(feature = "as_mut")]
mod as_mut;
#[cfg(feature = "as_ref")]
mod as_ref;
#[cfg(feature = "constructor")]
mod constructor;
#[cfg(feature = "deref")]
mod deref;
#[cfg(feature = "deref_mut")]
mod deref_mut;
#[cfg(feature = "display")]
mod display;
#[cfg(feature = "from")]
mod from;
#[cfg(feature = "from_str")]
mod from_str;
#[cfg(feature = "index")]
mod index;
#[cfg(feature = "index_mut")]
mod index_mut;
#[cfg(feature = "into")]
mod into;
#[cfg(feature = "into_iterator")]
mod into_iterator;
#[cfg(feature = "iterator")]
mod iterator;
#[cfg(feature = "mul_assign_like")]
mod mul_assign_like;
#[cfg(any(feature = "mul_like", feature = "mul_assign_like"))]
mod mul_helpers;
#[cfg(feature = "mul_like")]
mod mul_like;
#[cfg(feature = "not_like")]
mod not_like;
#[cfg(feature = "display")]
#[allow(ellipsis_inclusive_range_patterns)]
#[allow(clippy::all)]
mod parsing;
#[cfg(feature = "sum_like")]
mod sum_like;
#[cfg(feature = "try_into")]
mod try_into;

// This trait describes the possible return types of
// the derives. A derive can generally be infallible and
// return a TokenStream, or it can be fallible and return
// a Result<TokenStream, syn::parse::Error>.
trait Output {
    fn process(self) -> TokenStream;
}

impl Output for proc_macro2::TokenStream {
    fn process(self) -> TokenStream {
        self.into()
    }
}

impl Output for Result<proc_macro2::TokenStream, ParseError> {
    fn process(self) -> TokenStream {
        match self {
            Ok(ts) => ts.into(),
            Err(e) => e.to_compile_error().into(),
        }
    }
}

macro_rules! create_derive(
    ($feature:literal, $mod_:ident, $trait_:ident, $fn_name: ident $(,$attribute:ident)*) => {
        #[cfg(feature = $feature)]
        #[proc_macro_derive($trait_, attributes($($attribute),*))]
        #[doc(hidden)]
        pub fn $fn_name(input: TokenStream) -> TokenStream {
            let ast = syn::parse(input).unwrap();
            Output::process($mod_::expand(&ast, stringify!($trait_)))
        }
    }
);

create_derive!("from", from, From, from_derive, from);

create_derive!("into", into, Into, into_derive, into);

create_derive!("constructor", constructor, Constructor, constructor_derive);

create_derive!("not_like", not_like, Not, not_derive);
create_derive!("not_like", not_like, Neg, neg_derive);

create_derive!("add_like", add_like, Add, add_derive);
create_derive!("add_like", add_like, Sub, sub_derive);
create_derive!("add_like", add_like, BitAnd, bit_and_derive);
create_derive!("add_like", add_like, BitOr, bit_or_derive);
create_derive!("add_like", add_like, BitXor, bit_xor_derive);

create_derive!("mul_like", mul_like, Mul, mul_derive, mul);
create_derive!("mul_like", mul_like, Div, div_derive, div);
create_derive!("mul_like", mul_like, Rem, rem_derive, rem);
create_derive!("mul_like", mul_like, Shr, shr_derive, shr);
create_derive!("mul_like", mul_like, Shl, shl_derive, shl);

create_derive!(
    "add_assign_like",
    add_assign_like,
    AddAssign,
    add_assign_derive
);
create_derive!(
    "add_assign_like",
    add_assign_like,
    SubAssign,
    sub_assign_derive
);
create_derive!(
    "add_assign_like",
    add_assign_like,
    BitAndAssign,
    bit_and_assign_derive
);
create_derive!(
    "add_assign_like",
    add_assign_like,
    BitOrAssign,
    bit_or_assign_derive
);
create_derive!(
    "add_assign_like",
    add_assign_like,
    BitXorAssign,
    bit_xor_assign_derive
);

create_derive!(
    "mul_assign_like",
    mul_assign_like,
    MulAssign,
    mul_assign_derive,
    mul_assign
);
create_derive!(
    "mul_assign_like",
    mul_assign_like,
    DivAssign,
    div_assign_derive,
    div_assign
);
create_derive!(
    "mul_assign_like",
    mul_assign_like,
    RemAssign,
    rem_assign_derive,
    rem_assign
);
create_derive!(
    "mul_assign_like",
    mul_assign_like,
    ShrAssign,
    shr_assign_derive,
    shr_assign
);
create_derive!(
    "mul_assign_like",
    mul_assign_like,
    ShlAssign,
    shl_assign_derive,
    shl_assign
);

create_derive!("sum_like", sum_like, Sum, sum_derive);
create_derive!("sum_like", sum_like, Product, product_derive);

create_derive!("from_str", from_str, FromStr, from_str_derive);

create_derive!("display", display, Display, display_derive, display);
create_derive!("display", display, Binary, binary_derive, binary);
create_derive!("display", display, Octal, octal_derive, octal);
create_derive!("display", display, LowerHex, lower_hex_derive, lower_hex);
create_derive!("display", display, UpperHex, upper_hex_derive, upper_hex);
create_derive!("display", display, LowerExp, lower_exp_derive, lower_exp);
create_derive!("display", display, UpperExp, upper_exp_derive, upper_exp);
create_derive!("display", display, Pointer, pointer_derive, pointer);
create_derive!("display", display, DebugCustom, debug_custom_derive, debug);

create_derive!("index", index, Index, index_derive, index);
create_derive!(
    "index_mut",
    index_mut,
    IndexMut,
    index_mut_derive,
    index_mut
);

create_derive!(
    "into_iterator",
    into_iterator,
    IntoIterator,
    into_iterator_derive,
    into_iterator
);
create_derive!("iterator", iterator, Iterator, iterator_derive, iterator);

create_derive!("try_into", try_into, TryInto, try_into_derive, try_into);

create_derive!("deref", deref, Deref, deref_derive, deref);
create_derive!(
    "deref_mut",
    deref_mut,
    DerefMut,
    deref_mut_derive,
    deref_mut
);

create_derive!("as_ref", as_ref, AsRef, as_ref_derive, as_ref);
create_derive!("as_mut", as_mut, AsMut, as_mut_derive, as_mut);
<commit_msg>Support trailing space in create_derive macro<commit_after>//! # `derive_more`
//!
//! [![Build Status](https://api.travis-ci.org/JelteF/derive_more.svg?branch=master)](https://travis-ci.org/JelteF/derive_more)
//! [![Latest Version](https://img.shields.io/crates/v/derive_more.svg)](https://crates.io/crates/derive_more)
//! [![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://jeltef.github.io/derive_more/derive_more/)
//! [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/JelteF/derive_more/master/LICENSE)
//!
//! Rust has lots of builtin traits that are implemented for its basic types, such
//! as `Add`, `Not`, `From` or `Display`.
//! However, when wrapping these types inside your own structs or enums you lose the
//! implementations of these traits and are required to recreate them.
//! This is especially annoying when your own structures are very simple, such as
//! when using the commonly advised newtype pattern (e.g. `MyInt(i32)`).
//!
//! This library tries to remove these annoyances and the corresponding boilerplate code.
//! It does this by allowing you to derive lots of commonly used traits for both structs and enums.
//!
//! ## Example code
//!
//! By using this library the following code just works:
//!
//! ```rust
//! extern crate derive_more;
//! use derive_more::{Add, Display, From, Into};
//!
//! #[derive(PartialEq, From, Add)]
//! struct MyInt(i32);
//!
//! #[derive(PartialEq, From, Into)]
//! struct Point2D {
//!     x: i32,
//!     y: i32,
//! }
//!
//! #[derive(PartialEq, From, Add, Display)]
//! enum MyEnum {
//!     #[display(fmt = "int: {}", _0)]
//!     Int(i32),
//!     Uint(u32),
//!     #[display(fmt = "nothing")]
//!     Nothing,
//! }
//!
//! assert!(MyInt(11) == MyInt(5) + 6.into());
//! assert!((5, 6) == Point2D { x: 5, y: 6 }.into());
//! assert!(MyEnum::Int(15) == (MyEnum::Int(8) + 7.into()).unwrap());
//! assert!(MyEnum::Int(15).to_string() == "int: 15");
//! assert!(MyEnum::Uint(42).to_string() == "42");
//! assert!(MyEnum::Nothing.to_string() == "nothing");
//! ```
//!
//! ## The derivable traits
//!
//! Below are all the traits that you can derive using this library.
//! Some trait derivations are so similar that the further documentation will only show a single one
//! of them.
//! You can recognize these by the "-like" suffix in their name.
//! The trait name before that will be the only one that is used throughout the further
//! documentation.
//!
//! It is important to understand what code gets generated when using one of the
//! derives from this crate.
//! That is why the links below explain what code gets generated for a trait for
//! each group from before.
//!
//! You can use the [`cargo-expand`] utility to see the exact code that is generated
//! for your specific type.
//! This will show you your code with all macros and derives expanded.
//!
//! **NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't
//! automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]`
//!
//! ### Conversion traits
//!
//! These are traits that are used to convert automatically between types.
//!
//! 1. [`From`]
//! 2. [`Into`]
//! 3. [`FromStr`]
//! 4. [`TryInto`]
//! 5. [`IntoIterator`]
//! 6. [`AsRef`]
//! 7. [`AsMut`]
//!
//! ### Formatting traits
//!
//! These traits are used for converting a struct to a string in different ways.
//!
//! 1. [`Display`-like], contains `Display`, `Binary`, `Octal`, `LowerHex`,
//!    `UpperHex`, `LowerExp`, `UpperExp`, `Pointer`
//!
//! ### Operators
//!
//! These are traits that can be used for operator overloading.
//!
//! 1. [`Index`]
//! 2. [`Deref`]
//! 3. [`Not`-like], contains `Not` and `Neg`
//! 4. [`Add`-like], contains `Add`, `Sub`, `BitAnd`, `BitOr`, `BitXor`, `MulSelf`,
//!    `DivSelf`, `RemSelf`, `ShrSelf` and `ShlSelf`
//! 5. [`Mul`-like], contains `Mul`, `Div`, `Rem`, `Shr` and `Shl`
//! 3. [`Sum`-like], contains `Sum` and `Product`
//! 6. [`IndexMut`]
//! 7. [`DerefMut`]
//! 8. [`AddAssign`-like], contains `AddAssign`, `SubAssign`, `BitAndAssign`,
//!    `BitOrAssign` and `BitXorAssign`
//! 9. [`MulAssign`-like], contains `MulAssign`, `DivAssign`, `RemAssign`,
//!    `ShrAssign` and `ShlAssign`
//!
//! ### Static methods
//!
//! These don't derive traits, but derive static methods instead.
//!
//! 1. [`Constructor`], this derives a `new` method that can be used as a constructor.
//!    This is very basic if you need more customization for your constructor, check
//!    out the [`derive-new`] crate.
//!
//! ## Generated code
//!
//! ## Installation
//!
//! This library requires Rust 1.15 or higher, so this needs to be installed.
//! Then add the following to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! derive_more = "0.15.0"
//! ```
//!
//! And this to the top of your Rust file:
//!
//! ```rust
//! extern crate derive_more;
//! // Only needed when using the Rust 2015, for 2018 you can skip this line
//! extern crate core;
//! ```
//!
//! This crate supports `no_std` out of the box.
//!
//! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
//! [`derive-new`]: https://github.com/nrc/derive-new
//!
//! [`From`]: from.html
//! [`Into`]: into.html
//! [`FromStr`]: from_str.html
//! [`TryInto`]: try_into.html
//! [`IntoIterator`]: into_iterator.html
//! [`AsRef`]: as_ref.html
//! [`AsMut`]: as_mut.html
//!
//! [`Display`-like]: display.html
//!
//! [`Index`]: index_op.html
//! [`Deref`]: deref.html
//! [`Not`-like]: not.html
//! [`Add`-like]: add.html
//! [`Mul`-like]: mul.html
//! [`Sum`-like]: sum.html
//! [`IndexMut`]: index_mut.html
//! [`DerefMut`]: deref_mut.html
//! [`AddAssign`-like]: add_assign.html
//! [`MulAssign`-like]: mul_assign.html
//!
//! [`Constructor`]: constructor.html

#![recursion_limit = "128"]

extern crate proc_macro;
use proc_macro2;
use syn;

use proc_macro::TokenStream;
use syn::parse::Error as ParseError;

mod utils;

#[cfg(feature = "add_assign_like")]
mod add_assign_like;
#[cfg(any(
    feature = "add_like",
    feature = "add_assign_like",
    feature = "mul_like"
))]
mod add_helpers;
#[cfg(any(feature = "add_like", feature = "mul_like"))]
mod add_like;
#[cfg(feature = "as_mut")]
mod as_mut;
#[cfg(feature = "as_ref")]
mod as_ref;
#[cfg(feature = "constructor")]
mod constructor;
#[cfg(feature = "deref")]
mod deref;
#[cfg(feature = "deref_mut")]
mod deref_mut;
#[cfg(feature = "display")]
mod display;
#[cfg(feature = "from")]
mod from;
#[cfg(feature = "from_str")]
mod from_str;
#[cfg(feature = "index")]
mod index;
#[cfg(feature = "index_mut")]
mod index_mut;
#[cfg(feature = "into")]
mod into;
#[cfg(feature = "into_iterator")]
mod into_iterator;
#[cfg(feature = "iterator")]
mod iterator;
#[cfg(feature = "mul_assign_like")]
mod mul_assign_like;
#[cfg(any(feature = "mul_like", feature = "mul_assign_like"))]
mod mul_helpers;
#[cfg(feature = "mul_like")]
mod mul_like;
#[cfg(feature = "not_like")]
mod not_like;
#[cfg(feature = "display")]
#[allow(ellipsis_inclusive_range_patterns)]
#[allow(clippy::all)]
mod parsing;
#[cfg(feature = "sum_like")]
mod sum_like;
#[cfg(feature = "try_into")]
mod try_into;

// This trait describes the possible return types of
// the derives. A derive can generally be infallible and
// return a TokenStream, or it can be fallible and return
// a Result<TokenStream, syn::parse::Error>.
trait Output {
    fn process(self) -> TokenStream;
}

impl Output for proc_macro2::TokenStream {
    fn process(self) -> TokenStream {
        self.into()
    }
}

impl Output for Result<proc_macro2::TokenStream, ParseError> {
    fn process(self) -> TokenStream {
        match self {
            Ok(ts) => ts.into(),
            Err(e) => e.to_compile_error().into(),
        }
    }
}

macro_rules! create_derive(
    ($feature:literal, $mod_:ident, $trait_:ident, $fn_name: ident $(,$attribute:ident)* $(,)?) => {
        #[cfg(feature = $feature)]
        #[proc_macro_derive($trait_, attributes($($attribute),*))]
        #[doc(hidden)]
        pub fn $fn_name(input: TokenStream) -> TokenStream {
            let ast = syn::parse(input).unwrap();
            Output::process($mod_::expand(&ast, stringify!($trait_)))
        }
    }
);

create_derive!("from", from, From, from_derive, from);

create_derive!("into", into, Into, into_derive, into);

create_derive!("constructor", constructor, Constructor, constructor_derive);

create_derive!("not_like", not_like, Not, not_derive);
create_derive!("not_like", not_like, Neg, neg_derive);

create_derive!("add_like", add_like, Add, add_derive);
create_derive!("add_like", add_like, Sub, sub_derive);
create_derive!("add_like", add_like, BitAnd, bit_and_derive);
create_derive!("add_like", add_like, BitOr, bit_or_derive);
create_derive!("add_like", add_like, BitXor, bit_xor_derive);

create_derive!("mul_like", mul_like, Mul, mul_derive, mul);
create_derive!("mul_like", mul_like, Div, div_derive, div);
create_derive!("mul_like", mul_like, Rem, rem_derive, rem);
create_derive!("mul_like", mul_like, Shr, shr_derive, shr);
create_derive!("mul_like", mul_like, Shl, shl_derive, shl);

create_derive!(
    "add_assign_like",
    add_assign_like,
    AddAssign,
    add_assign_derive,
);
create_derive!(
    "add_assign_like",
    add_assign_like,
    SubAssign,
    sub_assign_derive,
);
create_derive!(
    "add_assign_like",
    add_assign_like,
    BitAndAssign,
    bit_and_assign_derive,
);
create_derive!(
    "add_assign_like",
    add_assign_like,
    BitOrAssign,
    bit_or_assign_derive,
);
create_derive!(
    "add_assign_like",
    add_assign_like,
    BitXorAssign,
    bit_xor_assign_derive,
);

create_derive!(
    "mul_assign_like",
    mul_assign_like,
    MulAssign,
    mul_assign_derive,
    mul_assign,
);
create_derive!(
    "mul_assign_like",
    mul_assign_like,
    DivAssign,
    div_assign_derive,
    div_assign,
);
create_derive!(
    "mul_assign_like",
    mul_assign_like,
    RemAssign,
    rem_assign_derive,
    rem_assign,
);
create_derive!(
    "mul_assign_like",
    mul_assign_like,
    ShrAssign,
    shr_assign_derive,
    shr_assign,
);
create_derive!(
    "mul_assign_like",
    mul_assign_like,
    ShlAssign,
    shl_assign_derive,
    shl_assign,
);

create_derive!("sum_like", sum_like, Sum, sum_derive);
create_derive!("sum_like", sum_like, Product, product_derive);

create_derive!("from_str", from_str, FromStr, from_str_derive);

create_derive!("display", display, Display, display_derive, display);
create_derive!("display", display, Binary, binary_derive, binary);
create_derive!("display", display, Octal, octal_derive, octal);
create_derive!("display", display, LowerHex, lower_hex_derive, lower_hex);
create_derive!("display", display, UpperHex, upper_hex_derive, upper_hex);
create_derive!("display", display, LowerExp, lower_exp_derive, lower_exp);
create_derive!("display", display, UpperExp, upper_exp_derive, upper_exp);
create_derive!("display", display, Pointer, pointer_derive, pointer);
create_derive!("display", display, DebugCustom, debug_custom_derive, debug);

create_derive!("index", index, Index, index_derive, index);
create_derive!(
    "index_mut",
    index_mut,
    IndexMut,
    index_mut_derive,
    index_mut,
);

create_derive!(
    "into_iterator",
    into_iterator,
    IntoIterator,
    into_iterator_derive,
    into_iterator,
);
create_derive!("iterator", iterator, Iterator, iterator_derive, iterator);

create_derive!("try_into", try_into, TryInto, try_into_derive, try_into);

create_derive!("deref", deref, Deref, deref_derive, deref);
create_derive!(
    "deref_mut",
    deref_mut,
    DerefMut,
    deref_mut_derive,
    deref_mut,
);

create_derive!("as_ref", as_ref, AsRef, as_ref_derive, as_ref);
create_derive!("as_mut", as_mut, AsMut, as_mut_derive, as_mut);
<|endoftext|>


<commit_before>//! # Console progress bar for Rust
//!
//! Console progress bar for Rust Inspired from [pb](http://github.com/cheggaaa/pb).
//! support and tested on MacOS and Linux(should work on Windows too, but not tested yet).
//!
//! ![Screenshot](https://raw.githubusercontent.com/a8m/pb/master/gif/rec.gif)
//!
//! ### Examples
//! 1. simple example
//!
//! ```no_run
//! extern crate pbr;
//!
//! use pbr::ProgressBar;
//! use std::thread;
//!
//! fn main() {
//!     let count = 1000;
//!     let mut pb = ProgressBar::new(count);
//!     for _ in 0..count {
//!         pb.inc();
//!         thread::sleep_ms(200);
//!     }
//!     println!("done!");
//! }
//! ```
//!
//! 2. Broadcast writing(simple file copying)
//!
//! ```ignore
//! #![feature(io)]
//! extern crate pbr;
//!
//! use std::io::copy;
//! use std::io::prelude::*;
//! use std::fs::File;
//! use pbr::{ProgressBar, Units};
//!
//! fn main() {
//!     let mut file = File::open("/usr/share/dict/words").unwrap();
//!     let n_bytes = file.metadata().unwrap().len() as usize;
//!     let mut pb = ProgressBar::new(n_bytes);
//!     pb.set_units(Units::Bytes);
//!     let mut handle = File::create("copy-words").unwrap().broadcast(&mut pb);
//!     copy(&mut file, &mut handle).unwrap();
//!     println!("done!");
//! }
//! ```
extern crate time;
mod tty;
mod pb;
pub use pb::{ProgressBar, Units};

pub struct PbIter<I>
    where I: Iterator
{
    iter: I,
    progress_bar: ProgressBar,
}

impl<I> PbIter<I>
    where I: Iterator
{
    pub fn new(iter: I) -> Self {
        let size = iter.size_hint().0;
        PbIter {
            iter: iter,
            progress_bar: ProgressBar::new(size as u64),
        }
    }
}

impl<I> Iterator for PbIter<I>
    where I: Iterator
{
    type Item = I::Item;

    fn next(&mut self) -> Option<I::Item> {
        match self.iter.next() {
            Some(i) => {
                self.progress_bar.inc();
                Some(i)
            }
            None => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}
<commit_msg>docs(src): update link to gif<commit_after>//! # Console progress bar for Rust
//!
//! Console progress bar for Rust Inspired from [pb](http://github.com/cheggaaa/pb).
//! support and tested on MacOS and Linux(should work on Windows too, but not tested yet).
//!
//! ![Screenshot](https://raw.githubusercontent.com/a8m/pb/master/gif/rec_v2.gif)
//!
//! ### Examples
//! 1. simple example
//!
//! ```no_run
//! extern crate pbr;
//!
//! use pbr::ProgressBar;
//! use std::thread;
//!
//! fn main() {
//!     let count = 1000;
//!     let mut pb = ProgressBar::new(count);
//!     for _ in 0..count {
//!         pb.inc();
//!         thread::sleep_ms(200);
//!     }
//!     println!("done!");
//! }
//! ```
//!
//! 2. Broadcast writing(simple file copying)
//!
//! ```ignore
//! #![feature(io)]
//! extern crate pbr;
//!
//! use std::io::copy;
//! use std::io::prelude::*;
//! use std::fs::File;
//! use pbr::{ProgressBar, Units};
//!
//! fn main() {
//!     let mut file = File::open("/usr/share/dict/words").unwrap();
//!     let n_bytes = file.metadata().unwrap().len() as usize;
//!     let mut pb = ProgressBar::new(n_bytes);
//!     pb.set_units(Units::Bytes);
//!     let mut handle = File::create("copy-words").unwrap().broadcast(&mut pb);
//!     copy(&mut file, &mut handle).unwrap();
//!     println!("done!");
//! }
//! ```
extern crate time;
mod tty;
mod pb;
pub use pb::{ProgressBar, Units};

pub struct PbIter<I>
    where I: Iterator
{
    iter: I,
    progress_bar: ProgressBar,
}

impl<I> PbIter<I>
    where I: Iterator
{
    pub fn new(iter: I) -> Self {
        let size = iter.size_hint().0;
        PbIter {
            iter: iter,
            progress_bar: ProgressBar::new(size as u64),
        }
    }
}

impl<I> Iterator for PbIter<I>
    where I: Iterator
{
    type Item = I::Item;

    fn next(&mut self) -> Option<I::Item> {
        match self.iter.next() {
            Some(i) => {
                self.progress_bar.inc();
                Some(i)
            }
            None => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}
<|endoftext|>


<commit_before>extern crate glib_2_0_sys as glib;
extern crate gobject_2_0_sys as gobject;
extern crate gtypes;

use std::os::raw::c_char;
use gtypes::gboolean;
use gobject::GObject;

use glib::{GList, GError};

enum NotifyNotificationPrivate {}

#[repr(C)]
pub struct NotifyNotification {
    _parent_object: GObject,
    _priv_: NotifyNotificationPrivate
}

extern "C" {
    pub fn notify_init(app_name: *const c_char) -> gboolean;
    pub fn notify_uninit();
    pub fn notify_is_initted() -> gboolean;

    pub fn notify_get_app_name() -> *const c_char;
    pub fn notify_set_app_name(app_name: *const c_char);

    pub fn notify_get_server_caps() -> *mut GList;

    pub fn notify_get_server_info(ret_name: *mut *mut c_char,
                                  ret_vendor: *mut *mut c_char,
                                  ret_version: *mut *mut c_char,
                                  ret_spec_version: *mut *mut c_char);

    pub fn notify_notification_new(summary: *const c_char,
                                   body: *const c_char,
                                   icon: *const c_char)
                                   -> *mut NotifyNotification;

    pub fn notify_notification_show(notification: *mut NotifyNotification,
                                    error: *mut *mut GError);
}
<commit_msg>Rustfmt shenanigans<commit_after>extern crate glib_2_0_sys as glib;
extern crate gobject_2_0_sys as gobject;
extern crate gtypes;

use std::os::raw::c_char;
use gtypes::gboolean;
use gobject::GObject;

use glib::{GList, GError};

enum NotifyNotificationPrivate {}

#[repr(C)]
pub struct NotifyNotification {
    _parent_object: GObject,
    _priv_: NotifyNotificationPrivate,
}

extern "C" {
    pub fn notify_init(app_name: *const c_char) -> gboolean;
    pub fn notify_uninit();
    pub fn notify_is_initted() -> gboolean;

    pub fn notify_get_app_name() -> *const c_char;
    pub fn notify_set_app_name(app_name: *const c_char);

    pub fn notify_get_server_caps() -> *mut GList;

    pub fn notify_get_server_info(ret_name: *mut *mut c_char,
                                  ret_vendor: *mut *mut c_char,
                                  ret_version: *mut *mut c_char,
                                  ret_spec_version: *mut *mut c_char);

    pub fn notify_notification_new(summary: *const c_char,
                                   body: *const c_char,
                                   icon: *const c_char)
                                   -> *mut NotifyNotification;

    pub fn notify_notification_show(notification: *mut NotifyNotification,
                                    error: *mut *mut GError);
}
<|endoftext|>


<commit_before>//============================================================================
//
//  A Tagged Image File Format (TIFF) Library for Rust
//
//  Based on the TIFF 6.0 specification:
//
//      https://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
//
//  Copyright (c) 2014 by Gavin Baker <gavinb@antonym.org>
//  Published under the MIT License
//
//============================================================================

#![allow(dead_code)]

//----------------------------------------------------------------------------
// Dependencies

// For binary file I/O
extern crate byteorder;

//----------------------------------------------------------------------------
// Module imports

use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian};

use std::io::{Read, Seek};

//----------------------------------------------------------------------------
// Reexports

pub use reader::TIFFReader;

pub mod reader;
//mod writer;

//----------------------------------------------------------------------------
// Types

pub type BYTE = u8;
pub type SHORT = u16;
pub type LONG = u32;
pub type ASCII = String;
pub type RATIONAL = (u32, u32);
pub type SBYTE = i8;
pub type SSHORT = i16;
pub type SLONG = i32;
pub type SRATIONAL = (i32, i32);
pub type FLOAT = f32;
pub type DOUBLE = f64;

//----------------------------------------------------------------------------
// Enums

#[repr(u16)]
#[derive(Debug)]
pub enum TIFFByteOrder {
    LittleEndian = 0x4949,
    BigEndian = 0x4d4d,
}

#[repr(u16)]
#[derive(Debug)]
pub enum HeaderMagic {
    LittleEndian = 0x002a,
    BigEndian = 0x2a00,
}

#[repr(u16)]
#[derive(Debug)]
pub enum TagType {
    ByteTag = 1,
    ASCIITag = 2,
    ShortTag = 3,
    LongTag = 4,
    RationalTag = 5,
    SignedByteTag = 6,
    UndefinedTag = 7,
    SignedShortTag = 8,
    SignedLongTag = 9,
    SignedRationalTag = 10,
    FloatTag = 11,
    DoubleTag = 12,
}

#[repr(u16)]
#[derive(Debug)]
pub enum PhotometricInterpretation {
    WhiteIsZero = 0,
    BlackIsZero = 1,
}

#[repr(u16)]
#[derive(Debug)]
pub enum Compression {
    None = 1,
    Huffman = 2,
    PackBits = 32773,
}

#[repr(u16)]
#[derive(Debug)]
pub enum ResolutionUnit {
    None = 1,
    Inch = 2,
    Centimetre = 3,
}

//----------------------------------------------------------------------------
// Structs

#[derive(Debug)]
pub struct TIFFHeader {
    pub byte_order: TIFFByteOrder,
    pub magic: HeaderMagic,
    pub ifd_offset: LONG,
}

pub struct IFDEntry {
    tag: TIFFTag,
    typ: TagType,
    count: LONG,
    value_offset: LONG,
}

pub struct IFD {
    count: u16,
    entries: Vec<IFDEntry>,
}

//----------------------------------------------------------------------------
// Baseline Tags

#[repr(u16)]
#[derive(Debug)]
pub enum TIFFTag {

    // Baseline Tags

    ArtistTag = 0x013b,
    BitsPerSampleTag = 0x0102,
    CellLengthTag = 0x0109,
    CellWidthTag = 0x0108,
    ColorMapTag = 0x0140,
    CompressionTag = 0x0103,
    CopyrightTag = 0x8298,
    DateTimeTag = 0x0132,
    ExtraSamplesTag = 0x0152,
    FillOrderTag = 0x010a,
    FreeByteCountsTag = 0x0121,
    FreeOffsetsTag = 0x0120,
    GrayResponseCurveTag = 0x0123,
    GrayResponseUnitTag = 0x0122,
    HostComputerTag = 0x013c,
    ImageDescriptionTag = 0x010e,
    ImageLengthTag = 0x0101,
    ImageWidthTag = 0x0100,
    MakeTag = 0x010f,
    MaxSampleValueTag = 0x0119,
    MinSampleValueTag = 0x0118,
    ModelTag = 0x0110,
    NewSubfileTypeTag = 0x00fe,
    OrientationTag = 0x0112,
    PhotometricInterpretationTag = 0x0106,
    PlanarConfigurationTag = 0x011c,
    Predictor = 0x013d,
    ResolutionUnitTag = 0x0128,
    RowsPerStripTag = 0x0116,
    SampleFormat = 0x0153,
    SamplesPerPixel = 0x0115,
    SoftwareTag = 0x0131,
    StripByteCountsTag = 0x0117,
    StripOffsetsTag = 0x0111,
    SubfileTypeTag = 0x00ff,
    ThresholdingTag = 0x0107,
    XResolutionTag = 0x011a,
    YResolutionTag = 0x011b,

    // TIFF/EP Tags

    SubIFDsTag = 0x014a,
    JPEGTablesTag = 0x015b,
    CFARepeatPatternDimTag = 0x828d,
    BatteryLevelTag = 0x828f,
    IPTCTag = 0x83BB,
    InterColorProfileTag = 0x8773,
    InterlaceTag = 0x8829,
    TimeZoneOffsetTag = 0x882a,
    SelfTimerModeTag = 0x882b,
    NoiseTag = 0x920d,
    ImageNumberTag = 0x9211,
    SecurityClassificationTag = 0x9212,
    ImageHistoryTag = 0x9213,
    EPStandardIdTag = 0x9216,

    // Extension TIFF Tags
    // See http://www.awaresystems.be/imaging/tiff/tifftags/extension.html
    XMPTag = 0x02bc,

    // Private Tags
    PhotoshopTag = 0x8649,
    EXIFTag = 0x8769,
}

//----------------------------------------------------------------------------
// Default Values

static PHOTOMETRIC_INTERPRETATION_SHORT_DEFAULT: SHORT = 1;
static PHOTOMETRIC_INTERPRETATION_LONG_DEFAULT: LONG = 1;

//----------------------------------------------------------------------------

// Section 6: Required Fields for RGB Images

fn validate_rgb_image() {
    // ImageWidth
    // ImageLength
    // BitsPerSample
    // Compression
    // PhotometricInterpretation
    // StripOffsets
    // SamplesPerPixel
    // RowsPerStrip
    // StripByteCounts
    // XResolution
    // YResolution
    // ResolutionUnit
}

//----------------------------------------------------------------------------

pub trait SeekableReader: Seek + Read {}
impl<T: Seek + Read> SeekableReader for T {}

pub fn decode_tag(value: u16) -> Option<TIFFTag> {
    match value {
        0x013b => Some(TIFFTag::ArtistTag),
        0x0102 => Some(TIFFTag::BitsPerSampleTag),
        0x0109 => Some(TIFFTag::CellLengthTag),
        0x0108 => Some(TIFFTag::CellWidthTag),
        0x0140 => Some(TIFFTag::ColorMapTag),
        0x0103 => Some(TIFFTag::CompressionTag),
        0x8298 => Some(TIFFTag::CopyrightTag),
        0x0132 => Some(TIFFTag::DateTimeTag),
        0x0152 => Some(TIFFTag::ExtraSamplesTag),
        0x010a => Some(TIFFTag::FillOrderTag),
        0x0121 => Some(TIFFTag::FreeByteCountsTag),
        0x0120 => Some(TIFFTag::FreeOffsetsTag),
        0x0123 => Some(TIFFTag::GrayResponseCurveTag),
        0x0122 => Some(TIFFTag::GrayResponseUnitTag),
        0x013c => Some(TIFFTag::HostComputerTag),
        0x010e => Some(TIFFTag::ImageDescriptionTag),
        0x0101 => Some(TIFFTag::ImageLengthTag),
        0x0100 => Some(TIFFTag::ImageWidthTag),
        0x010f => Some(TIFFTag::MakeTag),
        0x0119 => Some(TIFFTag::MaxSampleValueTag),
        0x0118 => Some(TIFFTag::MinSampleValueTag),
        0x0110 => Some(TIFFTag::ModelTag),
        0x00fe => Some(TIFFTag::NewSubfileTypeTag),
        0x0112 => Some(TIFFTag::OrientationTag),
        0x0106 => Some(TIFFTag::PhotometricInterpretationTag),
        0x011c => Some(TIFFTag::PlanarConfigurationTag),
        0x013d => Some(TIFFTag::Predictor),
        0x0128 => Some(TIFFTag::ResolutionUnitTag),
        0x0116 => Some(TIFFTag::RowsPerStripTag),
        0x0115 => Some(TIFFTag::SamplesPerPixel),
        0x0153 => Some(TIFFTag::SampleFormat),
        0x0131 => Some(TIFFTag::SoftwareTag),
        0x0117 => Some(TIFFTag::StripByteCountsTag),
        0x0111 => Some(TIFFTag::StripOffsetsTag),
        0x00ff => Some(TIFFTag::SubfileTypeTag),
        0x0107 => Some(TIFFTag::ThresholdingTag),
        0x011a => Some(TIFFTag::XResolutionTag),
        0x011b => Some(TIFFTag::YResolutionTag),

        0x014a => Some(TIFFTag::SubIFDsTag),
        0x015b => Some(TIFFTag::JPEGTablesTag),
        0x828d => Some(TIFFTag::CFARepeatPatternDimTag),
        0x828f => Some(TIFFTag::BatteryLevelTag),
        0x83BB => Some(TIFFTag::IPTCTag),
        0x8773 => Some(TIFFTag::InterColorProfileTag),
        0x8829 => Some(TIFFTag::InterlaceTag),
        0x882a => Some(TIFFTag::TimeZoneOffsetTag),
        0x882b => Some(TIFFTag::SelfTimerModeTag),
        0x920d => Some(TIFFTag::NoiseTag),
        0x9211 => Some(TIFFTag::ImageNumberTag),
        0x9212 => Some(TIFFTag::SecurityClassificationTag),
        0x9213 => Some(TIFFTag::ImageHistoryTag),
        0x9216 => Some(TIFFTag::EPStandardIdTag),

        0x02bc => Some(TIFFTag::XMPTag),
        0x8649 => Some(TIFFTag::PhotoshopTag),
        0x8769 => Some(TIFFTag::EXIFTag),
        _ => None,
    }
}

pub fn decode_tag_type(typ: u16) -> Option<TagType> {

    match typ {
        1 => Some(TagType::ByteTag),
        2 => Some(TagType::ASCIITag),
        3 => Some(TagType::ShortTag),
        4 => Some(TagType::LongTag),
        5 => Some(TagType::RationalTag),
        6 => Some(TagType::SignedByteTag),
        7 => Some(TagType::UndefinedTag),
        8 => Some(TagType::SignedShortTag),
        9 => Some(TagType::SignedLongTag),
        10 => Some(TagType::SignedRationalTag),
        11 => Some(TagType::FloatTag),
        12 => Some(TagType::DoubleTag),
        _ => None,
    }
}

/*
    Required Fields for Bilevel Images

    - ImageWidth
    - ImageLength
    - Compression
    - PhotometricInterpretation
    - StripOffsets
    - RowsPerStrip
    - StripByteCounts
    - XResolution
    - YResolution
    - ResolutionUnit
 */

/*
    Required Fields for Grayscale Images

    - ImageWidth
    - ImageLength
    - BitsPerSample
    - Compression
    - PhotometricInterpretation
    - StripOffsets
    - RowsPerStrip
    - StripByteCounts
    - XResolution
    - YResolution
    - ResolutionUnit
 */

/*
    Required Fields for Palette Colour Images

    - ImageWidth
    - ImageLength
    - BitsPerSample
    - Compression
    - PhotometricInterpretation
    - StripOffsets
    - RowsPerStrip
    - StripByteCounts
    - XResolution
    - YResolution
    - ResolutionUnit
    - ColorMap
 */

/*
    Required Fields for RGB Images

    - ImageWidth
    - ImageLength
    - BitsPerSample
    - Compression
    - PhotometricInterpretation
    - StripOffsets
    - SamplesPerPixel
    - RowsPerStrip
    - StripByteCounts
    - XResolution
    - YResolution
    - ResolutionUnit
 */
<commit_msg>Add YCbCr tags and sample types from spec<commit_after>//============================================================================
//
//  A Tagged Image File Format (TIFF) Library for Rust
//
//  Based on the TIFF 6.0 specification:
//
//      https://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
//
//  Copyright (c) 2014 by Gavin Baker <gavinb@antonym.org>
//  Published under the MIT License
//
//============================================================================

#![allow(dead_code)]

//----------------------------------------------------------------------------
// Dependencies

// For binary file I/O
extern crate byteorder;

//----------------------------------------------------------------------------
// Module imports

use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian};

use std::io::{Read, Seek};

//----------------------------------------------------------------------------
// Reexports

pub use reader::TIFFReader;

pub mod reader;
//mod writer;

//----------------------------------------------------------------------------
// Types

pub type BYTE = u8;
pub type SHORT = u16;
pub type LONG = u32;
pub type ASCII = String;
pub type RATIONAL = (u32, u32);
pub type SBYTE = i8;
pub type SSHORT = i16;
pub type SLONG = i32;
pub type SRATIONAL = (i32, i32);
pub type FLOAT = f32;
pub type DOUBLE = f64;

//----------------------------------------------------------------------------
// Enums

#[repr(u16)]
#[derive(Debug)]
pub enum TIFFByteOrder {
    LittleEndian = 0x4949,
    BigEndian = 0x4d4d,
}

#[repr(u16)]
#[derive(Debug)]
pub enum HeaderMagic {
    LittleEndian = 0x002a,
    BigEndian = 0x2a00,
}

#[repr(u16)]
#[derive(Debug)]
pub enum TagType {
    ByteTag = 1,
    ASCIITag = 2,
    ShortTag = 3,
    LongTag = 4,
    RationalTag = 5,
    SignedByteTag = 6,
    UndefinedTag = 7,
    SignedShortTag = 8,
    SignedLongTag = 9,
    SignedRationalTag = 10,
    FloatTag = 11,
    DoubleTag = 12,
}

#[repr(u16)]
#[derive(Debug)]
pub enum PhotometricInterpretation {
    WhiteIsZero = 0,
    BlackIsZero = 1,
}

#[repr(u16)]
#[derive(Debug)]
pub enum Compression {
    None = 1,
    Huffman = 2,
    PackBits = 32773,
}

#[repr(u16)]
#[derive(Debug)]
pub enum ResolutionUnit {
    None = 1,
    Inch = 2,
    Centimetre = 3,
}

#[repr(u16)]
#[derive(Debug)]
pub enum SampleFormat {
    UnsignedInteger = 1,
    TwosComplementSignedInteger = 2,
    IEEEFloatingPoint = 3,
    Undefined = 4,
}

//----------------------------------------------------------------------------
// Structs

#[derive(Debug)]
pub struct TIFFHeader {
    pub byte_order: TIFFByteOrder,
    pub magic: HeaderMagic,
    pub ifd_offset: LONG,
}

pub struct IFDEntry {
    tag: TIFFTag,
    typ: TagType,
    count: LONG,
    value_offset: LONG,
}

pub struct IFD {
    count: u16,
    entries: Vec<IFDEntry>,
}

//----------------------------------------------------------------------------
// Baseline Tags

#[repr(u16)]
#[derive(Debug)]
pub enum TIFFTag {

    // Baseline Tags

    ArtistTag = 0x013b,
    BitsPerSampleTag = 0x0102,
    CellLengthTag = 0x0109,
    CellWidthTag = 0x0108,
    ColorMapTag = 0x0140,
    CompressionTag = 0x0103,
    CopyrightTag = 0x8298,
    DateTimeTag = 0x0132,
    ExtraSamplesTag = 0x0152,
    FillOrderTag = 0x010a,
    FreeByteCountsTag = 0x0121,
    FreeOffsetsTag = 0x0120,
    GrayResponseCurveTag = 0x0123,
    GrayResponseUnitTag = 0x0122,
    HostComputerTag = 0x013c,
    ImageDescriptionTag = 0x010e,
    ImageLengthTag = 0x0101,
    ImageWidthTag = 0x0100,
    MakeTag = 0x010f,
    MaxSampleValueTag = 0x0119,
    MinSampleValueTag = 0x0118,
    ModelTag = 0x0110,
    NewSubfileTypeTag = 0x00fe,
    OrientationTag = 0x0112,
    PhotometricInterpretationTag = 0x0106,
    PlanarConfigurationTag = 0x011c,
    Predictor = 0x013d,
    ResolutionUnitTag = 0x0128,
    RowsPerStripTag = 0x0116,
    SampleFormat = 0x0153,
    SamplesPerPixel = 0x0115,
    SoftwareTag = 0x0131,
    StripByteCountsTag = 0x0117,
    StripOffsetsTag = 0x0111,
    SubfileTypeTag = 0x00ff,
    ThresholdingTag = 0x0107,
    XResolutionTag = 0x011a,
    YResolutionTag = 0x011b,

    // Section 20: Colorimetry

    WhitePointTag = 0x013e,
    PrimaryChromaticities = 0x013f,
    TransferFunction = 0x012d,
    TransferRange = 0x0156,
    ReferenceBlackWhite = 0x0214,

    // Section 21: YCbCr Images

    YCbCrCoefficients = 0x0211,
    YCbCrSubsampling = 0x0212,
    YCbCrPositioning = 0x0213,

    // TIFF/EP Tags

    SubIFDsTag = 0x014a,
    JPEGTablesTag = 0x015b,
    CFARepeatPatternDimTag = 0x828d,
    BatteryLevelTag = 0x828f,
    IPTCTag = 0x83BB,
    InterColorProfileTag = 0x8773,
    InterlaceTag = 0x8829,
    TimeZoneOffsetTag = 0x882a,
    SelfTimerModeTag = 0x882b,
    NoiseTag = 0x920d,
    ImageNumberTag = 0x9211,
    SecurityClassificationTag = 0x9212,
    ImageHistoryTag = 0x9213,
    EPStandardIdTag = 0x9216,

    // Extension TIFF Tags
    // See http://www.awaresystems.be/imaging/tiff/tifftags/extension.html
    XMPTag = 0x02bc,

    // Private Tags
    PhotoshopTag = 0x8649,
    EXIFTag = 0x8769,
}

//----------------------------------------------------------------------------
// Default Values

static PHOTOMETRIC_INTERPRETATION_SHORT_DEFAULT: SHORT = 1;
static PHOTOMETRIC_INTERPRETATION_LONG_DEFAULT: LONG = 1;

//----------------------------------------------------------------------------

// Section 6: Required Fields for RGB Images

fn validate_rgb_image() {
    // ImageWidth
    // ImageLength
    // BitsPerSample
    // Compression
    // PhotometricInterpretation
    // StripOffsets
    // SamplesPerPixel
    // RowsPerStrip
    // StripByteCounts
    // XResolution
    // YResolution
    // ResolutionUnit
}

//----------------------------------------------------------------------------

pub trait SeekableReader: Seek + Read {}
impl<T: Seek + Read> SeekableReader for T {}

pub fn decode_tag(value: u16) -> Option<TIFFTag> {
    match value {
        0x013b => Some(TIFFTag::ArtistTag),
        0x0102 => Some(TIFFTag::BitsPerSampleTag),
        0x0109 => Some(TIFFTag::CellLengthTag),
        0x0108 => Some(TIFFTag::CellWidthTag),
        0x0140 => Some(TIFFTag::ColorMapTag),
        0x0103 => Some(TIFFTag::CompressionTag),
        0x8298 => Some(TIFFTag::CopyrightTag),
        0x0132 => Some(TIFFTag::DateTimeTag),
        0x0152 => Some(TIFFTag::ExtraSamplesTag),
        0x010a => Some(TIFFTag::FillOrderTag),
        0x0121 => Some(TIFFTag::FreeByteCountsTag),
        0x0120 => Some(TIFFTag::FreeOffsetsTag),
        0x0123 => Some(TIFFTag::GrayResponseCurveTag),
        0x0122 => Some(TIFFTag::GrayResponseUnitTag),
        0x013c => Some(TIFFTag::HostComputerTag),
        0x010e => Some(TIFFTag::ImageDescriptionTag),
        0x0101 => Some(TIFFTag::ImageLengthTag),
        0x0100 => Some(TIFFTag::ImageWidthTag),
        0x010f => Some(TIFFTag::MakeTag),
        0x0119 => Some(TIFFTag::MaxSampleValueTag),
        0x0118 => Some(TIFFTag::MinSampleValueTag),
        0x0110 => Some(TIFFTag::ModelTag),
        0x00fe => Some(TIFFTag::NewSubfileTypeTag),
        0x0112 => Some(TIFFTag::OrientationTag),
        0x0106 => Some(TIFFTag::PhotometricInterpretationTag),
        0x011c => Some(TIFFTag::PlanarConfigurationTag),
        0x013d => Some(TIFFTag::Predictor),
        0x0128 => Some(TIFFTag::ResolutionUnitTag),
        0x0116 => Some(TIFFTag::RowsPerStripTag),
        0x0115 => Some(TIFFTag::SamplesPerPixel),
        0x0153 => Some(TIFFTag::SampleFormat),
        0x0131 => Some(TIFFTag::SoftwareTag),
        0x0117 => Some(TIFFTag::StripByteCountsTag),
        0x0111 => Some(TIFFTag::StripOffsetsTag),
        0x00ff => Some(TIFFTag::SubfileTypeTag),
        0x0107 => Some(TIFFTag::ThresholdingTag),
        0x011a => Some(TIFFTag::XResolutionTag),
        0x011b => Some(TIFFTag::YResolutionTag),

        0x014a => Some(TIFFTag::SubIFDsTag),
        0x015b => Some(TIFFTag::JPEGTablesTag),
        0x828d => Some(TIFFTag::CFARepeatPatternDimTag),
        0x828f => Some(TIFFTag::BatteryLevelTag),
        0x83BB => Some(TIFFTag::IPTCTag),
        0x8773 => Some(TIFFTag::InterColorProfileTag),
        0x8829 => Some(TIFFTag::InterlaceTag),
        0x882a => Some(TIFFTag::TimeZoneOffsetTag),
        0x882b => Some(TIFFTag::SelfTimerModeTag),
        0x920d => Some(TIFFTag::NoiseTag),
        0x9211 => Some(TIFFTag::ImageNumberTag),
        0x9212 => Some(TIFFTag::SecurityClassificationTag),
        0x9213 => Some(TIFFTag::ImageHistoryTag),
        0x9216 => Some(TIFFTag::EPStandardIdTag),

        0x02bc => Some(TIFFTag::XMPTag),
        0x8649 => Some(TIFFTag::PhotoshopTag),
        0x8769 => Some(TIFFTag::EXIFTag),
        _ => None,
    }
}

pub fn decode_tag_type(typ: u16) -> Option<TagType> {

    match typ {
        1 => Some(TagType::ByteTag),
        2 => Some(TagType::ASCIITag),
        3 => Some(TagType::ShortTag),
        4 => Some(TagType::LongTag),
        5 => Some(TagType::RationalTag),
        6 => Some(TagType::SignedByteTag),
        7 => Some(TagType::UndefinedTag),
        8 => Some(TagType::SignedShortTag),
        9 => Some(TagType::SignedLongTag),
        10 => Some(TagType::SignedRationalTag),
        11 => Some(TagType::FloatTag),
        12 => Some(TagType::DoubleTag),
        _ => None,
    }
}

/*
    Required Fields for Bilevel Images

    - ImageWidth
    - ImageLength
    - Compression
    - PhotometricInterpretation
    - StripOffsets
    - RowsPerStrip
    - StripByteCounts
    - XResolution
    - YResolution
    - ResolutionUnit
 */

/*
    Required Fields for Grayscale Images

    - ImageWidth
    - ImageLength
    - BitsPerSample
    - Compression
    - PhotometricInterpretation
    - StripOffsets
    - RowsPerStrip
    - StripByteCounts
    - XResolution
    - YResolution
    - ResolutionUnit
 */

/*
    Required Fields for Palette Colour Images

    - ImageWidth
    - ImageLength
    - BitsPerSample
    - Compression
    - PhotometricInterpretation
    - StripOffsets
    - RowsPerStrip
    - StripByteCounts
    - XResolution
    - YResolution
    - ResolutionUnit
    - ColorMap
 */

/*
    Required Fields for RGB Images

    - ImageWidth
    - ImageLength
    - BitsPerSample
    - Compression
    - PhotometricInterpretation
    - StripOffsets
    - SamplesPerPixel
    - RowsPerStrip
    - StripByteCounts
    - XResolution
    - YResolution
    - ResolutionUnit
 */
<|endoftext|>


<commit_before>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was not
// distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.

//! The simple-stream crate provides simple abstraction building blocks over any type that
//! implements [`std::io::Read`][std-io-read] + [`std::io::Write`][std-io-write].
//! Coupled with a [`FrameBuilder`][framebuilder], it provides built-in types for plain text
//! and secured streams with help from [rust-openssl][rust-openssl-repo]. It supports both
//! blocking and non-blocking modes.
//!
//! It works by handling all of the I/O on a frame based level. It includes a built-in framing
//! pattern and WebSocket based framing. The `simple_stream::frame` module includes traits for
//! using custom frames.
//!
//! ## Example Usage
//!
//! ~~~rust
//! extern crate simple_stream as ss;
//!
//! use ss::frame::Frame;
//! use ss::frame::simple::{SimpleFrame, SimpleFrameBuilder};
//! use ss::{Socket, Plain, NonBlocking, SocketOptions};
//!
//!
//! fn main() {
//!     // tcp_stream is some connection established std::net::TcpStream
//!     //
//!     // Take ownership of the underlying fd to remove TcpStream's Drop being called now
//!     // that we're switching types.
//!     let fd = tcp_stream.into_raw_fd();
//!
//!     // Create a socket and set any POSIX based TCP/SOL_SOCKET options
//!     let mut socket = Socket::new(fd);
//!     socket.set_keepalive(true);
//!     socket.set_nonblocking();
//!
//!     // Create a plain text based stream that reads messages with SimpleFrame type
//!     let mut plain_stream = Plain::<Socket, SimpleFrameBuilder>::new(socket);
//!
//!     // Perform non-blocking read
//!     match plain_stream.nb_recv() {
//!         Ok(frames) => {
//!             // msgs is a Vec<Box<Frame>>
//!             for frame in frames.iter() {
//!                 // Do stuff with received things
//!             }
//!         }
//!         Err(e) => {
//!             // Error handling here
//!         }
//!     }
//!
//!     // Perform non-blocking write
//!     let frame = SimpleFrame::new(&some_buf[..]);
//!     plain_stream.nb_send(&frame).map_err(|e| {
//!         // Error handling here
//!     });
//! }
//! ~~~

#[macro_use]
extern crate log;
extern crate libc;
extern crate errno;
extern crate openssl;
#[macro_use]
extern crate bitflags;

use std::io::Error;

use frame::Frame;

pub use plain::*;
pub use socket::*;
pub use secure::*;

pub mod frame;
mod socket;
mod plain;
mod secure;

/// The `Blocking` trait provides method definitions for use with blocking streams.
pub trait Blocking {
    /// Performs a blocking read on the underlying stream until a complete Frame has been read
    /// or an `std::io::Error` has occurred.
    fn b_recv(&mut self) -> Result<Box<Frame>, Error>;
    /// Performs a blocking send on the underlying stream until a complete frame has been sent
    /// or an `std::io::Error` has occurred.
    fn b_send(&mut self, frame: &Frame) -> Result<(), Error>;
}

/// THe `NonBlocking` trait provides method definitions for use with non-blocking streams.
pub trait NonBlocking {
    /// Performs a non-blocking read on the underlying stream until `ErrorKind::WouldBlock` or an
    /// `std::io::Error` has occurred.
    ///
    /// # `simple_stream::Secure` notes
    ///
    /// Unlike its blocking counterpart, errors received on the OpenSSL level will be returned as
    /// `ErrorKind::Other` with various OpenSSL error information as strings in the description
    /// field of the `std::io::Error`.
    fn nb_recv(&mut self) -> Result<Vec<Box<Frame>>, Error>;
    /// Performs a non-blocking send on the underlying stream until `ErrorKind::WouldBlock` or an
    /// `std::io::Error` has occurred.
    ///
    /// # `simple_stream::Secure` notes
    ///
    /// Unlike its blocking counterpart, errors received on the OpenSSL level will be returned as
    /// `ErrorKind::Other` with various OpenSSL error information as strings in the description
    /// field of the `std::io::Error`.
    fn nb_send(&mut self, frame: &Frame) -> Result<(), Error>;
}
<commit_msg>Removed doc test from compiling examples.<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was not
// distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.

//! The simple-stream crate provides simple abstraction building blocks over any type that
//! implements [`std::io::Read`][std-io-read] + [`std::io::Write`][std-io-write].
//! Coupled with a [`FrameBuilder`][framebuilder], it provides built-in types for plain text
//! and secured streams with help from [rust-openssl][rust-openssl-repo]. It supports both
//! blocking and non-blocking modes.
//!
//! It works by handling all of the I/O on a frame based level. It includes a built-in framing
//! pattern and WebSocket based framing. The `simple_stream::frame` module includes traits for
//! using custom frames.
//!
//! ## Example Usage
//!
//! ```ignore
//! extern crate simple_stream as ss;
//!
//! use ss::frame::Frame;
//! use ss::frame::simple::{SimpleFrame, SimpleFrameBuilder};
//! use ss::{Socket, Plain, NonBlocking, SocketOptions};
//!
//!
//! fn main() {
//!     // tcp_stream is some connection established std::net::TcpStream
//!     //
//!     // Take ownership of the underlying fd to remove TcpStream's Drop being called now
//!     // that we're switching types.
//!     let fd = tcp_stream.into_raw_fd();
//!
//!     // Create a socket and set any POSIX based TCP/SOL_SOCKET options
//!     let mut socket = Socket::new(fd);
//!     socket.set_keepalive(true);
//!     socket.set_nonblocking();
//!
//!     // Create a plain text based stream that reads messages with SimpleFrame type
//!     let mut plain_stream = Plain::<Socket, SimpleFrameBuilder>::new(socket);
//!
//!     // Perform non-blocking read
//!     match plain_stream.nb_recv() {
//!         Ok(frames) => {
//!             // msgs is a Vec<Box<Frame>>
//!             for frame in frames.iter() {
//!                 // Do stuff with received things
//!             }
//!         }
//!         Err(e) => {
//!             // Error handling here
//!         }
//!     }
//!
//!     // Perform non-blocking write
//!     let frame = SimpleFrame::new(&some_buf[..]);
//!     plain_stream.nb_send(&frame).map_err(|e| {
//!         // Error handling here
//!     });
//! }
//! ```

#[macro_use]
extern crate log;
extern crate libc;
extern crate errno;
extern crate openssl;
#[macro_use]
extern crate bitflags;

use std::io::Error;

use frame::Frame;

pub use plain::*;
pub use socket::*;
pub use secure::*;

pub mod frame;
mod socket;
mod plain;
mod secure;

/// The `Blocking` trait provides method definitions for use with blocking streams.
pub trait Blocking {
    /// Performs a blocking read on the underlying stream until a complete Frame has been read
    /// or an `std::io::Error` has occurred.
    fn b_recv(&mut self) -> Result<Box<Frame>, Error>;
    /// Performs a blocking send on the underlying stream until a complete frame has been sent
    /// or an `std::io::Error` has occurred.
    fn b_send(&mut self, frame: &Frame) -> Result<(), Error>;
}

/// THe `NonBlocking` trait provides method definitions for use with non-blocking streams.
pub trait NonBlocking {
    /// Performs a non-blocking read on the underlying stream until `ErrorKind::WouldBlock` or an
    /// `std::io::Error` has occurred.
    ///
    /// # `simple_stream::Secure` notes
    ///
    /// Unlike its blocking counterpart, errors received on the OpenSSL level will be returned as
    /// `ErrorKind::Other` with various OpenSSL error information as strings in the description
    /// field of the `std::io::Error`.
    fn nb_recv(&mut self) -> Result<Vec<Box<Frame>>, Error>;
    /// Performs a non-blocking send on the underlying stream until `ErrorKind::WouldBlock` or an
    /// `std::io::Error` has occurred.
    ///
    /// # `simple_stream::Secure` notes
    ///
    /// Unlike its blocking counterpart, errors received on the OpenSSL level will be returned as
    /// `ErrorKind::Other` with various OpenSSL error information as strings in the description
    /// field of the `std::io::Error`.
    fn nb_send(&mut self, frame: &Frame) -> Result<(), Error>;
}
<|endoftext|>


<commit_before>// Copyright 2015 Jan Likar.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub mod ops {
    use std::env;
    use std::fs;
    use std::path::{Path, PathBuf};

    use cargo::core::dependency::Dependency;
    use cargo::core::source::{Source, SourceId};
    use cargo::core::Package;
    use cargo::sources::{GitSource, PathSource, SourceConfigMap};
    use cargo::util::to_semver::ToSemver;
    use cargo::util::{CargoResult, Config};

    use failure::bail;

    use walkdir::WalkDir;

    pub fn clone(
        krate: Option<&str>,
        srcid: &SourceId,
        prefix: Option<&str>,
        vers: Option<&str>,
        config: &Config,
    ) -> CargoResult<()> {
        let _lock = config.acquire_package_cache_lock()?;

        let map = SourceConfigMap::new(config)?;
        let pkg = if srcid.is_path() {
            let path = srcid.url().to_file_path().ok().expect("path must be valid");
            let mut src = PathSource::new(&path, srcid.clone(), config);
            src.update()?;

            select_pkg(config, src, krate, vers, &mut |path| path.read_packages())?
        } else if srcid.is_git() {
            select_pkg(
                config,
                GitSource::new(srcid.clone(), config)?,
                krate,
                vers,
                &mut |git| git.read_packages(),
            )?
        } else {
            select_pkg(
                config,
                map.load(srcid.clone(), &Default::default())?,
                krate,
                vers,
                &mut |_| {
                    bail!(
                        "must specify a crate to clone from \
                         crates.io, or use --path or --git to \
                         specify alternate source"
                    )
                },
            )?
        };

        // If prefix was not supplied, clone into current dir
        let mut dest_path = match prefix {
            Some(path) => PathBuf::from(path),
            None => r#try!(env::current_dir()),
        };

        dest_path.push(format!("{}", pkg.name()));

        r#try!(clone_directory(&pkg.root(), &dest_path));

        Ok(())
    }

    fn select_pkg<'a, T>(
        config: &Config,
        mut src: T,
        name: Option<&str>,
        vers: Option<&str>,
        list_all: &mut dyn FnMut(&mut T) -> CargoResult<Vec<Package>>,
    ) -> CargoResult<Package>
    where
        T: Source + 'a,
    {
        src.update()?;

        match name {
            Some(name) => {
                let vers = match vers {
                    Some(v) => match v.to_semver() {
                        Ok(v) => Some(v.to_string()),
                        Err(e) => bail!("{}", e),
                    },
                    None => None,
                };
                let vers = vers.as_ref().map(|s| &**s);
                let dep = r#try!(Dependency::parse_no_deprecated(name, vers, src.source_id()));
                let mut summaries = vec![];
                r#try!(src.query(&dep, &mut |summary| summaries.push(summary.clone())));

                let latest = summaries.iter().max_by_key(|s| s.version());

                match latest {
                    Some(l) => {
                        let pkg = Box::new(src).download_now(l.package_id(), config)?;
                        Ok(pkg)
                    }
                    None => bail!("package '{}' not found", name),
                }
            }
            None => {
                let candidates = list_all(&mut src)?;
                Ok(candidates[0].clone())
            }
        }
    }

    fn clone_directory(from: &Path, to: &Path) -> CargoResult<()> {
        for entry in WalkDir::new(from) {
            let entry = entry.unwrap();
            let file_type = entry.file_type();
            let mut to = to.to_owned();
            to.push(entry.path().strip_prefix(from).unwrap());

            if file_type.is_file() && entry.file_name() != ".cargo-ok" {
                // .cargo-ok is not wanted in this context
                r#try!(fs::copy(&entry.path(), &to));
            } else if file_type.is_dir() {
                r#try!(fs::create_dir(&to));
            }
        }

        Ok(())
    }
}
<commit_msg>chore: replace `try` macro invocations with try operator (`?`)<commit_after>// Copyright 2015 Jan Likar.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub mod ops {
    use std::env;
    use std::fs;
    use std::path::{Path, PathBuf};

    use cargo::core::dependency::Dependency;
    use cargo::core::source::{Source, SourceId};
    use cargo::core::Package;
    use cargo::sources::{GitSource, PathSource, SourceConfigMap};
    use cargo::util::to_semver::ToSemver;
    use cargo::util::{CargoResult, Config};

    use failure::bail;

    use walkdir::WalkDir;

    pub fn clone(
        krate: Option<&str>,
        srcid: &SourceId,
        prefix: Option<&str>,
        vers: Option<&str>,
        config: &Config,
    ) -> CargoResult<()> {
        let _lock = config.acquire_package_cache_lock()?;

        let map = SourceConfigMap::new(config)?;
        let pkg = if srcid.is_path() {
            let path = srcid.url().to_file_path().ok().expect("path must be valid");
            let mut src = PathSource::new(&path, srcid.clone(), config);
            src.update()?;

            select_pkg(config, src, krate, vers, &mut |path| path.read_packages())?
        } else if srcid.is_git() {
            select_pkg(
                config,
                GitSource::new(srcid.clone(), config)?,
                krate,
                vers,
                &mut |git| git.read_packages(),
            )?
        } else {
            select_pkg(
                config,
                map.load(srcid.clone(), &Default::default())?,
                krate,
                vers,
                &mut |_| {
                    bail!(
                        "must specify a crate to clone from \
                         crates.io, or use --path or --git to \
                         specify alternate source"
                    )
                },
            )?
        };

        // If prefix was not supplied, clone into current dir
        let mut dest_path = match prefix {
            Some(path) => PathBuf::from(path),
            None => env::current_dir()?,
        };

        dest_path.push(format!("{}", pkg.name()));

        clone_directory(&pkg.root(), &dest_path)?;

        Ok(())
    }

    fn select_pkg<'a, T>(
        config: &Config,
        mut src: T,
        name: Option<&str>,
        vers: Option<&str>,
        list_all: &mut dyn FnMut(&mut T) -> CargoResult<Vec<Package>>,
    ) -> CargoResult<Package>
    where
        T: Source + 'a,
    {
        src.update()?;

        match name {
            Some(name) => {
                let vers = match vers {
                    Some(v) => match v.to_semver() {
                        Ok(v) => Some(v.to_string()),
                        Err(e) => bail!("{}", e),
                    },
                    None => None,
                };
                let vers = vers.as_ref().map(|s| &**s);
                let dep = Dependency::parse_no_deprecated(name, vers, src.source_id())?;
                let mut summaries = vec![];
                src.query(&dep, &mut |summary| summaries.push(summary.clone()))?;

                let latest = summaries.iter().max_by_key(|s| s.version());

                match latest {
                    Some(l) => {
                        let pkg = Box::new(src).download_now(l.package_id(), config)?;
                        Ok(pkg)
                    }
                    None => bail!("package '{}' not found", name),
                }
            }
            None => {
                let candidates = list_all(&mut src)?;
                Ok(candidates[0].clone())
            }
        }
    }

    fn clone_directory(from: &Path, to: &Path) -> CargoResult<()> {
        for entry in WalkDir::new(from) {
            let entry = entry.unwrap();
            let file_type = entry.file_type();
            let mut to = to.to_owned();
            to.push(entry.path().strip_prefix(from).unwrap());

            if file_type.is_file() && entry.file_name() != ".cargo-ok" {
                // .cargo-ok is not wanted in this context
                fs::copy(&entry.path(), &to)?;
            } else if file_type.is_dir() {
                fs::create_dir(&to)?;
            }
        }

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