<commit_before>use serde::{Deserialize, Serialize};
use yew::services::storage::{Area, StorageService};
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};

type Ref = i32;

pub struct Model {
    file: File,
    store: StorageService,
    selected: Option<Ref>,
}

impl Model {
    fn lookup(&self, reference: Ref) -> Option<&Node> {
        self.file.lookup(reference)
    }
    fn lookup_mut(&mut self, reference: Ref) -> Option<&mut Node> {
        self.file.lookup_mut(reference)
    }
}

#[derive(Clone)]
pub enum Msg {
    Select(Ref),
    Rename(Ref, String),

    Store,
    Load,

    AddArgument,
}

#[derive(Serialize, Deserialize)]
struct File {
    bindings: Vec<Ref>,
    nodes: Vec<Node>,
    next_reference: Ref,
}

impl File {
    fn lookup(&self, reference: Ref) -> Option<&Node> {
        self.nodes
            .iter()
            .filter(|v| v.reference == reference)
            .next()
    }

    fn lookup_mut(&mut self, reference: Ref) -> Option<&mut Node> {
        self.nodes
            .iter_mut()
            .filter(|v| v.reference == reference)
            .next()
    }

    fn add_node(&mut self, value: Value) -> Ref {
        let reference = self.next_reference();
        let node = Node {
            reference: reference,
            value: value,
        };
        self.nodes.push(node);
        reference
    }

    fn next_reference(&mut self) -> Ref {
        let reference = self.next_reference;
        self.next_reference += 1;
        reference
    }
}

#[derive(Serialize, Deserialize)]
struct Node {
    reference: Ref,
    value: Value,
}

const ERROR_NODE: Node = Node {
    reference: 1111111111,
    value: Value::Hole,
};

#[derive(Serialize, Deserialize)]
enum Value {
    Hole,

    Bool(bool),
    Int(i32),
    Float(f32),
    String(String),

    Ref(Ref),
    Binding(BindingValue),
    Pattern(PatternValue),

    Block(BlockValue),
    List(ListValue),
    If(IfValue),
    FunctionDefinition(FunctionDefinitionValue),
    FunctionCall(FunctionCallValue),
    BinaryOperator(BinaryOperatorValue),
}

impl Node {
    fn label(&self) -> Option<&Label> {
        match &self.value {
            Value::Binding(ref v) => Some(&v.label),
            Value::Pattern(ref v) => Some(&v.label),
            _ => None,
        }
    }
    fn rename(&mut self, name: String) {
        match &mut self.value {
            Value::Binding(ref mut v) => v.label.name = name,
            Value::Pattern(ref mut v) => v.label.name = name,
            _ => {}
        }
    }
}

#[derive(Serialize, Deserialize)]
struct BindingValue {
    label: Label,
    value: Ref,
}

#[derive(Serialize, Deserialize)]
struct PatternValue {
    label: Label,
}

#[derive(Serialize, Deserialize)]
struct BlockValue {
    expressions: Vec<Ref>,
}

#[derive(Serialize, Deserialize)]
struct ListValue {
    items: Vec<Ref>,
}

#[derive(Serialize, Deserialize)]
struct IfValue {
    conditional: Ref,
    true_body: Ref,
    false_body: Ref,
}

#[derive(Serialize, Deserialize)]
struct FunctionDefinitionValue {
    label: Label,
    arguments: Vec<Ref>,
    body: Ref,
}

#[derive(Serialize, Deserialize)]
struct FunctionCallValue {
    function: Ref,
    arguments: Vec<Ref>,
}

#[derive(Serialize, Deserialize)]
struct BinaryOperatorValue {
    operator: String,
    left: Ref,
    right: Ref,
}

#[derive(Serialize, Deserialize)]
struct Pattern {
    label: Label,
}

#[derive(Serialize, Deserialize)]
struct Label {
    name: String,
    colour: String,
}

impl Component for Model {
    type Message = Msg;
    type Properties = ();

    fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
        Model {
            store: StorageService::new(Area::Local),
            file: File {
                next_reference: 1000,
                nodes: vec![
                    Node {
                        reference: 111,
                        value: Value::FunctionDefinition(FunctionDefinitionValue {
                            label: Label {
                                name: "main".to_string(),
                                colour: "red".to_string(),
                            },
                            arguments: vec![],
                            body: 123,
                        }),
                    },
                    Node {
                        reference: 124,
                        value: Value::Int(123),
                    },
                    Node {
                        reference: 12,
                        value: Value::FunctionDefinition(FunctionDefinitionValue {
                            label: Label {
                                name: "factorial".to_string(),
                                colour: "red".to_string(),
                            },
                            arguments: vec![222],
                            body: 228,
                        }),
                    },
                    Node {
                        reference: 222,
                        value: Value::Pattern(PatternValue {
                            label: Label {
                                name: "x".to_string(),
                                colour: "".to_string(),
                            },
                        }),
                    },
                    Node {
                        reference: 228,
                        value: Value::BinaryOperator(BinaryOperatorValue {
                            operator: "*".to_string(),
                            left: 1231,
                            right: 1232,
                        }),
                    },
                    Node {
                        reference: 1231,
                        value: Value::Ref(222),
                    },
                    Node {
                        reference: 1232,
                        value: Value::FunctionCall(FunctionCallValue {
                            function: 12,
                            arguments: vec![229],
                        }),
                    },
                    Node {
                        reference: 229,
                        value: Value::BinaryOperator(BinaryOperatorValue {
                            operator: "-".to_string(),
                            left: 230,
                            right: 231,
                        }),
                    },
                    Node {
                        reference: 230,
                        value: Value::Ref(222),
                    },
                    Node {
                        reference: 231,
                        value: Value::Int(1),
                    },
                ],
                bindings: vec![111, 12],
            },
            selected: None,
        }
    }

    fn update(&mut self, msg: Self::Message) -> ShouldRender {
        const KEY: &str = "linc_file";
        match msg {
            Msg::Select(reference) => {
                self.selected = Some(reference);
            }
            Msg::Rename(reference, name) => {
                if let Some(node) = self.lookup_mut(reference) {
                    node.rename(name);
                }
            }

            Msg::Store => {
                self.store.store(KEY, yew::format::Json(&self.file));
            }
            Msg::Load => {
                if let yew::format::Json(Ok(file)) = self.store.restore(KEY) {
                    self.file = file;
                }
            }

            Msg::AddArgument => {
                let reference = self.file.add_node(Value::Pattern(PatternValue {
                    label: Label {
                        name: "xxx".to_string(),
                        colour: "red".to_string(),
                    },
                }));
                if let Some(node) = self
                    .selected
                    .and_then(|reference| self.lookup_mut(reference))
                {
                    if let Value::FunctionDefinition(ref mut v) = node.value {
                        v.arguments.push(reference);
                    }
                }
            }
        };
        true
    }
}

impl Renderable<Model> for Model {
    fn view(&self) -> Html<Self> {
        html! {

{ "LINC" }

{ format!("Selected: {:?}", self.selected) }

{ self.view_actions() }

{ self.view_file(&self.file) }

        }
    }
}

struct Action {
    text: String,
    msg: Msg,
}

impl Model {
    fn view_actions(&self) -> Html<Model> {
        let actions = vec![
            Action {
                text: "store".to_string(),
                msg: Msg::Store,
            },
            Action {
                text: "load".to_string(),
                msg: Msg::Load,
            },
            Action {
                text: "+arg".to_string(),
                msg: Msg::AddArgument,
            },
        ];
        let mut actions = actions.iter().map(|a| self.view_action(a));
        html! {

            { for actions }

        }
    }

    fn view_action(&self, action: &Action) -> Html<Model> {
        let m = action.msg.clone();
        html! {

                { &action.text }

        }
    }

    fn view_file(&self, file: &File) -> Html<Model> {
        let serialized = serde_json::to_string_pretty(file).expect("could not serialize to JSON");
        html! {

{ "file" }

{ for file.bindings.iter().map(|v| self.view_binding(*v)) }

{ "JSON" }

{ serialized }

        }
    }

    fn view_label(&self, label: &Label, reference: Ref) -> Html<Model> {
        html! {
            <input oninput=|e| Msg::Rename(reference, e.value)
                type="text"
                value=label.name/>
        }
    }

    fn view_binding(&self, reference: Ref) -> Html<Model> {
        let node = self.lookup(reference).unwrap_or(&ERROR_NODE);
        html! {

{ self.view_node(node) }

        }
    }

    fn view_node(&self, node: &Node) -> Html<Model> {
        let reference = node.reference;
        let selected = match self.selected {
            None => false,
            Some(selected_reference) => selected_reference == reference,
        };
        // TODO: Use Vec.
        let mut class = "node".to_string();
        if selected {
            class.push_str(" selected");
        }
        html! {

                { self.view_value(&node.value, reference) }

        }
    }

    fn view_value(&self, value: &Value, reference: Ref) -> Html<Model> {
        match value {
            Value::Hole => {
                html! { { "@" } }
            }
            Value::Bool(v) => {
                let v = if *v { "true" } else { "false" };
                html! { { v } }
            }
            Value::Int(v) => {
                let v = format!("{}", v);
                html! { { v } }
            }
            Value::Float(v) => {
                let v = format!("{}", v);
                html! { { v } }
            }
            Value::String(v) => {
                html! { { v } }
            }
            Value::Ref(reference) => {
                let node = self.lookup(*reference);
                let text = node
                    .and_then(|n| n.label())
                    .map(|l| l.name.clone())
                    .unwrap_or("<UNKNOWN>".to_string());
                html! { { text } }
            }
            Value::Binding(v) => {
                let label = self.view_label(&v.label, reference);
                let value = self.lookup(v.value).unwrap_or(&ERROR_NODE);
                html! {

                    { label }{ "=" }{ self.view_node(value) }

                }
            }
            Value::Pattern(v) => {
                html! {

                        { self.view_label(&v.label, reference) }

                }
            }
            Value::Block(_) => {
                html! { { "xxx" } }
            }
            Value::List(_) => {
                html! { { "xxx" } }
            }
            Value::If(_) => {
                html! { { "xxx" } }
            }
            Value::FunctionDefinition(v) => {
                let label = self.view_label(&v.label, reference);
                let mut args = v
                    .arguments
                    .iter()
                    // TODO: We should not filter out invalid nodes.
                    .filter_map(|r| self.lookup(*r))
                    .map(|n| self.view_node(n));
                let body = self.lookup(v.body).unwrap_or(&ERROR_NODE);
                html! {

                        { "fn" }{ label }
                        { "(" }{ for args }{ ")" }
                        { self.view_node(body) }

                }
            }
            Value::FunctionCall(v) => {
                let node = self.file.lookup(v.function);
                let function_name = node
                    .and_then(|n| n.label())
                    .map(|l| l.name.clone())
                    .unwrap_or("<UNKNOWN>".to_string());
                let mut args = v
                    .arguments
                    .iter()
                    // TODO: We should not filter out invalid nodes.
                    .filter_map(|r| self.lookup(*r))
                    .map(|n| self.view_node(n));
                html! {

                        { function_name }
                        { "(" }{ for args }{ ")" }

                }
            }
            Value::BinaryOperator(v) => {
                let left = self.lookup(v.left).unwrap_or(&ERROR_NODE);
                let right = self.lookup(v.right).unwrap_or(&ERROR_NODE);
                html! {

                        { self.view_node(left) }
                        { &v.operator }
                        { self.view_node(right) }

                }
            }
        }
    }
}
<commit_msg>FunctionDefinition<commit_after>use serde::{Deserialize, Serialize};
use yew::services::storage::{Area, StorageService};
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};

type Ref = i32;

pub struct Model {
    file: File,
    store: StorageService,
    selected: Option<Ref>,
}

impl Model {
    fn lookup(&self, reference: Ref) -> Option<&Node> {
        self.file.lookup(reference)
    }
    fn lookup_mut(&mut self, reference: Ref) -> Option<&mut Node> {
        self.file.lookup_mut(reference)
    }
}

#[derive(Clone)]
pub enum Msg {
    Select(Ref),
    Rename(Ref, String),

    Store,
    Load,

    AddArgument,
}

#[derive(Serialize, Deserialize)]
struct File {
    bindings: Vec<Ref>,
    nodes: Vec<Node>,
    next_reference: Ref,
}

impl File {
    fn lookup(&self, reference: Ref) -> Option<&Node> {
        self.nodes
            .iter()
            .filter(|v| v.reference == reference)
            .next()
    }

    fn lookup_mut(&mut self, reference: Ref) -> Option<&mut Node> {
        self.nodes
            .iter_mut()
            .filter(|v| v.reference == reference)
            .next()
    }

    fn add_node(&mut self, value: Value) -> Ref {
        let reference = self.next_reference();
        let node = Node {
            reference: reference,
            value: value,
        };
        self.nodes.push(node);
        reference
    }

    fn next_reference(&mut self) -> Ref {
        let reference = self.next_reference;
        self.next_reference += 1;
        reference
    }
}

#[derive(Serialize, Deserialize)]
struct Node {
    reference: Ref,
    value: Value,
}

const ERROR_NODE: Node = Node {
    reference: 1111111111,
    value: Value::Hole,
};

#[derive(Serialize, Deserialize)]
enum Value {
    Hole,

    Bool(bool),
    Int(i32),
    Float(f32),
    String(String),

    Ref(Ref),
    Binding(BindingValue),
    Pattern(PatternValue),

    Block(BlockValue),
    List(ListValue),
    If(IfValue),
    FunctionDefinition(FunctionDefinitionValue),
    FunctionCall(FunctionCallValue),
    BinaryOperator(BinaryOperatorValue),
}

impl Node {
    fn label(&self) -> Option<&Label> {
        match &self.value {
            Value::Binding(ref v) => Some(&v.label),
            Value::Pattern(ref v) => Some(&v.label),
            Value::FunctionDefinition(ref v) => Some(&v.label),
            _ => None,
        }
    }
    fn rename(&mut self, name: String) {
        match &mut self.value {
            Value::Binding(ref mut v) => v.label.name = name,
            Value::Pattern(ref mut v) => v.label.name = name,
            Value::FunctionDefinition(ref mut v) => v.label.name = name,
            _ => {}
        }
    }
}

#[derive(Serialize, Deserialize)]
struct BindingValue {
    label: Label,
    value: Ref,
}

#[derive(Serialize, Deserialize)]
struct PatternValue {
    label: Label,
}

#[derive(Serialize, Deserialize)]
struct BlockValue {
    expressions: Vec<Ref>,
}

#[derive(Serialize, Deserialize)]
struct ListValue {
    items: Vec<Ref>,
}

#[derive(Serialize, Deserialize)]
struct IfValue {
    conditional: Ref,
    true_body: Ref,
    false_body: Ref,
}

#[derive(Serialize, Deserialize)]
struct FunctionDefinitionValue {
    label: Label,
    arguments: Vec<Ref>,
    body: Ref,
}

#[derive(Serialize, Deserialize)]
struct FunctionCallValue {
    function: Ref,
    arguments: Vec<Ref>,
}

#[derive(Serialize, Deserialize)]
struct BinaryOperatorValue {
    operator: String,
    left: Ref,
    right: Ref,
}

#[derive(Serialize, Deserialize)]
struct Pattern {
    label: Label,
}

#[derive(Serialize, Deserialize)]
struct Label {
    name: String,
    colour: String,
}

impl Component for Model {
    type Message = Msg;
    type Properties = ();

    fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
        Model {
            store: StorageService::new(Area::Local),
            file: File {
                next_reference: 1000,
                nodes: vec![
                    Node {
                        reference: 111,
                        value: Value::FunctionDefinition(FunctionDefinitionValue {
                            label: Label {
                                name: "main".to_string(),
                                colour: "red".to_string(),
                            },
                            arguments: vec![],
                            body: 123,
                        }),
                    },
                    Node {
                        reference: 124,
                        value: Value::Int(123),
                    },
                    Node {
                        reference: 12,
                        value: Value::FunctionDefinition(FunctionDefinitionValue {
                            label: Label {
                                name: "factorial".to_string(),
                                colour: "red".to_string(),
                            },
                            arguments: vec![222],
                            body: 228,
                        }),
                    },
                    Node {
                        reference: 222,
                        value: Value::Pattern(PatternValue {
                            label: Label {
                                name: "x".to_string(),
                                colour: "".to_string(),
                            },
                        }),
                    },
                    Node {
                        reference: 228,
                        value: Value::BinaryOperator(BinaryOperatorValue {
                            operator: "*".to_string(),
                            left: 1231,
                            right: 1232,
                        }),
                    },
                    Node {
                        reference: 1231,
                        value: Value::Ref(222),
                    },
                    Node {
                        reference: 1232,
                        value: Value::FunctionCall(FunctionCallValue {
                            function: 12,
                            arguments: vec![229],
                        }),
                    },
                    Node {
                        reference: 229,
                        value: Value::BinaryOperator(BinaryOperatorValue {
                            operator: "-".to_string(),
                            left: 230,
                            right: 231,
                        }),
                    },
                    Node {
                        reference: 230,
                        value: Value::Ref(222),
                    },
                    Node {
                        reference: 231,
                        value: Value::Int(1),
                    },
                ],
                bindings: vec![111, 12],
            },
            selected: None,
        }
    }

    fn update(&mut self, msg: Self::Message) -> ShouldRender {
        const KEY: &str = "linc_file";
        match msg {
            Msg::Select(reference) => {
                self.selected = Some(reference);
            }
            Msg::Rename(reference, name) => {
                if let Some(node) = self.lookup_mut(reference) {
                    node.rename(name);
                }
            }

            Msg::Store => {
                self.store.store(KEY, yew::format::Json(&self.file));
            }
            Msg::Load => {
                if let yew::format::Json(Ok(file)) = self.store.restore(KEY) {
                    self.file = file;
                }
            }

            Msg::AddArgument => {
                let reference = self.file.add_node(Value::Pattern(PatternValue {
                    label: Label {
                        name: "xxx".to_string(),
                        colour: "red".to_string(),
                    },
                }));
                if let Some(node) = self
                    .selected
                    .and_then(|reference| self.lookup_mut(reference))
                {
                    if let Value::FunctionDefinition(ref mut v) = node.value {
                        v.arguments.push(reference);
                    }
                }
            }
        };
        true
    }
}

impl Renderable<Model> for Model {
    fn view(&self) -> Html<Self> {
        let selected_node = self
            .selected
            .and_then(|reference| self.lookup(reference))
            .unwrap_or(&ERROR_NODE);
        let serialized_node =
            serde_json::to_string_pretty(selected_node).expect("could not serialize to JSON");
        html! {

{ "LINC" }

{ format!("Selected: {:?}", self.selected) }

{ serialized_node }

{ self.view_actions() }

{ self.view_file(&self.file) }

        }
    }
}

struct Action {
    text: String,
    msg: Msg,
}

impl Model {
    fn view_actions(&self) -> Html<Model> {
        let actions = vec![
            Action {
                text: "store".to_string(),
                msg: Msg::Store,
            },
            Action {
                text: "load".to_string(),
                msg: Msg::Load,
            },
            Action {
                text: "+arg".to_string(),
                msg: Msg::AddArgument,
            },
        ];
        let mut actions = actions.iter().map(|a| self.view_action(a));
        html! {

            { for actions }

        }
    }

    fn view_action(&self, action: &Action) -> Html<Model> {
        let m = action.msg.clone();
        html! {

                { &action.text }

        }
    }

    fn view_file(&self, file: &File) -> Html<Model> {
        let serialized = serde_json::to_string_pretty(file).expect("could not serialize to JSON");
        html! {

{ "file" }

{ for file.bindings.iter().map(|v| self.view_binding(*v)) }

{ "JSON" }

{ serialized }

        }
    }

    fn view_label(&self, label: &Label, reference: Ref) -> Html<Model> {
        html! {
            <input oninput=|e| Msg::Rename(reference, e.value)
                type="text"
                value=label.name/>
        }
    }

    fn view_binding(&self, reference: Ref) -> Html<Model> {
        let node = self.lookup(reference).unwrap_or(&ERROR_NODE);
        html! {

{ self.view_node(node) }

        }
    }

    fn view_node(&self, node: &Node) -> Html<Model> {
        let reference = node.reference;
        let selected = match self.selected {
            None => false,
            Some(selected_reference) => selected_reference == reference,
        };
        // TODO: Use Vec.
        let mut class = "node".to_string();
        if selected {
            class.push_str(" selected");
        }
        html! {

                { self.view_value(&node.value, reference) }

        }
    }

    fn view_value(&self, value: &Value, reference: Ref) -> Html<Model> {
        match value {
            Value::Hole => {
                html! { { "@" } }
            }
            Value::Bool(v) => {
                let v = if *v { "true" } else { "false" };
                html! { { v } }
            }
            Value::Int(v) => {
                let v = format!("{}", v);
                html! { { v } }
            }
            Value::Float(v) => {
                let v = format!("{}", v);
                html! { { v } }
            }
            Value::String(v) => {
                html! { { v } }
            }
            Value::Ref(reference) => {
                let node = self.lookup(*reference);
                let text = node
                    .and_then(|n| n.label())
                    .map(|l| l.name.clone())
                    .unwrap_or("<UNKNOWN>".to_string());
                html! { { text } }
            }
            Value::Binding(v) => {
                let label = self.view_label(&v.label, reference);
                let value = self.lookup(v.value).unwrap_or(&ERROR_NODE);
                html! {

                    { label }{ "=" }{ self.view_node(value) }

                }
            }
            Value::Pattern(v) => {
                html! {

                        { self.view_label(&v.label, reference) }

                }
            }
            Value::Block(_) => {
                html! { { "xxx" } }
            }
            Value::List(_) => {
                html! { { "xxx" } }
            }
            Value::If(_) => {
                html! { { "xxx" } }
            }
            Value::FunctionDefinition(v) => {
                let label = self.view_label(&v.label, reference);
                let mut args = v
                    .arguments
                    .iter()
                    // TODO: We should not filter out invalid nodes.
                    .filter_map(|r| self.lookup(*r))
                    .map(|n| self.view_node(n));
                let body = self.lookup(v.body).unwrap_or(&ERROR_NODE);
                html! {

                        { "fn" }{ label }
                        { "(" }{ for args }{ ")" }
                        { self.view_node(body) }

                }
            }
            Value::FunctionCall(v) => {
                let node = self.file.lookup(v.function);
                let function_name = node
                    .and_then(|n| n.label())
                    .map(|l| l.name.clone())
                    .unwrap_or("<UNKNOWN>".to_string());
                let mut args = v
                    .arguments
                    .iter()
                    // TODO: We should not filter out invalid nodes.
                    .filter_map(|r| self.lookup(*r))
                    .map(|n| self.view_node(n));
                html! {

                        { function_name }
                        { "(" }{ for args }{ ")" }

                }
            }
            Value::BinaryOperator(v) => {
                let left = self.lookup(v.left).unwrap_or(&ERROR_NODE);
                let right = self.lookup(v.right).unwrap_or(&ERROR_NODE);
                html! {

                        { self.view_node(left) }
                        { &v.operator }
                        { self.view_node(right) }

                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use regex::Regex;
use std::fs::File;
use std::io::{self, BufRead};
use std::str::FromStr;

#[macro_use]
extern crate lazy_static;
extern crate if_chain;

struct State<T>(Box<dyn Iterator<Item = T>>, Option<T>);
pub struct Merge<T> {
    count: usize,
    states: Vec<State<T>>,
}

impl<T: 'static + FromStr> Merge<T> {
    pub fn new(filename: &str) -> Self {
        let count = get_number(filename).unwrap();
        let states = (0..count).map(|i| {
            let collection = Box::new(get_collection(filename, i).unwrap());
            State(collection, None)
        }).collect();
        Merge {
            count: count,
            states: states,
        }
    }
}

impl<T: 'static + PartialOrd> Iterator for Merge<T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        let count = self.count;
        let states = &mut self.states;
        for i in 0..count {
            let state = &mut states[i];
            if state.1.is_none() {
                state.1 = state.0.next();
            }
        }
        let mut min_index: Option<usize> = None;
        for i in 0..count {
            if_chain::if_chain! {
                if let Some(_) = states[i].1.as_ref();
                then {
                    if min_index.is_none() {
                        min_index.replace(i);
                    }
                }
            }
            if_chain::if_chain! {
                if let Some(val) = states[i].1.as_ref();
                if let Some(m) = min_index;
                if let Some(min) = states[m].1.as_ref();
                then {
                    if val < min {
                        min_index.replace(i);
                    }
                }
            }
        }
        if let Some(m) = min_index {
            return states[m].1.take();
        }
        return None;
    }
}

pub fn get_number(filename: &str) -> io::Result<usize> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"NUMBER=(\d+)").unwrap();
    }
    let mut matches = match_lines(filename, &*RE)?;
    return Ok(matches.next().unwrap().parse().unwrap());
}

pub fn get_output<T: FromStr>(filename: &str) -> io::Result<impl Iterator<Item = T>> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"OUTPUT:(.*)").unwrap();
    }
    get_numbers(filename, &*RE)
}

pub fn get_collection<T: FromStr>(filename: &str, idx: usize) -> io::Result<impl Iterator<Item = T>> {
    let regex: Regex = {
        let r = format!("COLLECTION{}:(.*)", idx);
        Regex::new(&r).unwrap()
    };
    get_numbers(filename, &regex)
}

fn get_numbers<T: FromStr>(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = T>> {
    let matches = match_lines(filename, regex)?;
    let to_int = |v: &str| -> Option<T> {
        if let Ok(i) = v.parse::<T>() {
            Some(i)
        } else {
            None
        }
    };
    let values = matches
        .map(move |s| {
            let numbers = s.split(',').filter_map(|v| to_int(&v));
            numbers.collect::<Vec<_>>()
        })
        .flatten();
    Ok(values)
}

fn match_lines(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = String>> {
    let read_lines = move || -> io::Result<_> {
        let file = File::open(filename)?;
        Ok(io::BufReader::new(file).lines().map(|line| line.unwrap()))
    };
    let lines = read_lines()?;
    let r = regex.clone(); // TODO
    let matches =
        lines.filter_map(move |line| r.captures(&line).map(|captures| captures[1].to_string()));
    Ok(matches)
}

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

    #[test]
    fn test_number() {
        assert_eq!(get_number("../data/test.txt").unwrap(), 3);
    }

    #[test]
    fn test_output() {
        let output = [1, 1, 2, 2, 3, 4, 4, 6, 7, 9, 9, 20, 21];
        assert_eq!(
            get_output("../data/test.txt").unwrap().collect::<Vec<u32>>(),
            output
        );
    }

    #[test]
    fn test_collection() {
        let output = [2, 4, 6, 9, 20];
        assert_eq!(
            get_collection("../data/test.txt", 1)
                .unwrap()
                .collect::<Vec<u32>>(),
            output
        );
    }

    fn merge<T: 'static + FromStr + PartialOrd>(filename: &str) -> (impl Iterator<Item = T>, impl Iterator<Item = T>) {
        let result = Merge::new(filename);
        let output = get_output(filename).unwrap();
        (result, output)
    }

    fn assert_iterator<T: PartialEq>(
        iter1: &mut impl Iterator<Item = T>,
        iter2: &mut impl Iterator<Item = T>,
    ) -> bool {
        loop {
            match (iter1.next(), iter2.next()) {
                (None, None) => return true,
                (Some(v1), Some(v2)) if v1 == v2 => continue,
                _ => return false,
            }
        }
    }

    #[test]
    fn test_merge() {
        let filename = "../data/test.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(assert_iterator(&mut result, &mut output));
    }

    #[test]
    #[should_panic]
    fn test_bad_merge() {
        let filename = "../data/bad.txt";
        let (_result, _output) = merge::<u32>(filename);
    }

    #[test]
    fn test_zero_merge() {
        let filename = "../data/zero.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(result.next().is_none());
        assert!(output.next().is_none());
    }

    #[test]
    fn test_err() {
        let filename = "../data/err.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(!assert_iterator(&mut result, &mut output));
    }
}
<commit_msg>pretty elegant if_chain<commit_after>use regex::Regex;
use std::fs::File;
use std::io::{self, BufRead};
use std::str::FromStr;

#[macro_use]
extern crate lazy_static;
extern crate if_chain;

struct State<T>(Box<dyn Iterator<Item = T>>, Option<T>);
pub struct Merge<T> {
    count: usize,
    states: Vec<State<T>>,
}

impl<T: 'static + FromStr> Merge<T> {
    pub fn new(filename: &str) -> Self {
        let count = get_number(filename).unwrap();
        let states = (0..count).map(|i| {
            let collection = Box::new(get_collection(filename, i).unwrap());
            State(collection, None)
        }).collect();
        Merge {
            count: count,
            states: states,
        }
    }
}

impl<T: 'static + PartialOrd> Iterator for Merge<T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        let count = self.count;
        let states = &mut self.states;
        for i in 0..count {
            let state = &mut states[i];
            if state.1.is_none() {
                state.1 = state.0.next();
            }
        }
        let mut min_index: Option<usize> = None;
        for i in 0..count {
            if_chain::if_chain! {
                if let Some(_) = states[i].1.as_ref();
                if min_index.is_none();
                then {
                    min_index.replace(i);
                }
            }
            if_chain::if_chain! {
                if let Some(val) = states[i].1.as_ref();
                if let Some(m) = min_index;
                if let Some(min) = states[m].1.as_ref();
                if val < min;
                then {
                    min_index.replace(i);
                }
            }
        }
        if let Some(m) = min_index {
            return states[m].1.take();
        }
        return None;
    }
}

pub fn get_number(filename: &str) -> io::Result<usize> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"NUMBER=(\d+)").unwrap();
    }
    let mut matches = match_lines(filename, &*RE)?;
    return Ok(matches.next().unwrap().parse().unwrap());
}

pub fn get_output<T: FromStr>(filename: &str) -> io::Result<impl Iterator<Item = T>> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"OUTPUT:(.*)").unwrap();
    }
    get_numbers(filename, &*RE)
}

pub fn get_collection<T: FromStr>(filename: &str, idx: usize) -> io::Result<impl Iterator<Item = T>> {
    let regex: Regex = {
        let r = format!("COLLECTION{}:(.*)", idx);
        Regex::new(&r).unwrap()
    };
    get_numbers(filename, &regex)
}

fn get_numbers<T: FromStr>(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = T>> {
    let matches = match_lines(filename, regex)?;
    let to_int = |v: &str| -> Option<T> {
        if let Ok(i) = v.parse::<T>() {
            Some(i)
        } else {
            None
        }
    };
    let values = matches
        .map(move |s| {
            let numbers = s.split(',').filter_map(|v| to_int(&v));
            numbers.collect::<Vec<_>>()
        })
        .flatten();
    Ok(values)
}

fn match_lines(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = String>> {
    let read_lines = move || -> io::Result<_> {
        let file = File::open(filename)?;
        Ok(io::BufReader::new(file).lines().map(|line| line.unwrap()))
    };
    let lines = read_lines()?;
    let r = regex.clone(); // TODO
    let matches =
        lines.filter_map(move |line| r.captures(&line).map(|captures| captures[1].to_string()));
    Ok(matches)
}

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

    #[test]
    fn test_number() {
        assert_eq!(get_number("../data/test.txt").unwrap(), 3);
    }

    #[test]
    fn test_output() {
        let output = [1, 1, 2, 2, 3, 4, 4, 6, 7, 9, 9, 20, 21];
        assert_eq!(
            get_output("../data/test.txt").unwrap().collect::<Vec<u32>>(),
            output
        );
    }

    #[test]
    fn test_collection() {
        let output = [2, 4, 6, 9, 20];
        assert_eq!(
            get_collection("../data/test.txt", 1)
                .unwrap()
                .collect::<Vec<u32>>(),
            output
        );
    }

    fn merge<T: 'static + FromStr + PartialOrd>(filename: &str) -> (impl Iterator<Item = T>, impl Iterator<Item = T>) {
        let result = Merge::new(filename);
        let output = get_output(filename).unwrap();
        (result, output)
    }

    fn assert_iterator<T: PartialEq>(
        iter1: &mut impl Iterator<Item = T>,
        iter2: &mut impl Iterator<Item = T>,
    ) -> bool {
        loop {
            match (iter1.next(), iter2.next()) {
                (None, None) => return true,
                (Some(v1), Some(v2)) if v1 == v2 => continue,
                _ => return false,
            }
        }
    }

    #[test]
    fn test_merge() {
        let filename = "../data/test.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(assert_iterator(&mut result, &mut output));
    }

    #[test]
    #[should_panic]
    fn test_bad_merge() {
        let filename = "../data/bad.txt";
        let (_result, _output) = merge::<u32>(filename);
    }

    #[test]
    fn test_zero_merge() {
        let filename = "../data/zero.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(result.next().is_none());
        assert!(output.next().is_none());
    }

    #[test]
    fn test_err() {
        let filename = "../data/err.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(!assert_iterator(&mut result, &mut output));
    }
}
<|endoftext|>


<commit_before>//! This module defines all the service-level metrics of crates.io.
//!
//! Service-level metrics are collected for the whole service, without querying the individual
//! instances of the application. They're not suited for instance-level metrics (like "how many
//! requests were processed" or "how many connections are left in the database pool").
//!
//! Service-level metrics should **never** be updated around the codebase: instead all the updates
//! should happen inside the `gather` method. A database connection is available inside the method.
//!
//! As a rule of thumb, if the metric is not straight up fetched from the database it's probably an
//! instance-level metric, and you should add it to `src/metrics/instance.rs`.

use crate::schema::{crates, versions};
use crate::util::errors::AppResult;
use diesel::{dsl::count_star, prelude::*, PgConnection};
use prometheus::{proto::MetricFamily, IntGauge};

metrics! {
    pub struct ServiceMetrics {
        /// Number of crates ever published
        crates_total: IntGauge,
        /// Number of versions ever published
        versions_total: IntGauge,
    }

    // All service metrics will be prefixed with this namespace.
    namespace: "cratesio_service",
}

impl ServiceMetrics {
    pub(crate) fn gather(&self, conn: &PgConnection) -> AppResult<Vec<MetricFamily>> {
        self.crates_total
            .set(crates::table.select(count_star()).first(conn)?);
        self.versions_total
            .set(versions::table.select(count_star()).first(conn)?);

        Ok(self.registry.gather())
    }
}
<commit_msg>Auto merge of #4121 - Turbo87:background-job-metrics, r=pietroalbini<commit_after>//! This module defines all the service-level metrics of crates.io.
//!
//! Service-level metrics are collected for the whole service, without querying the individual
//! instances of the application. They're not suited for instance-level metrics (like "how many
//! requests were processed" or "how many connections are left in the database pool").
//!
//! Service-level metrics should **never** be updated around the codebase: instead all the updates
//! should happen inside the `gather` method. A database connection is available inside the method.
//!
//! As a rule of thumb, if the metric is not straight up fetched from the database it's probably an
//! instance-level metric, and you should add it to `src/metrics/instance.rs`.

use crate::schema::{background_jobs, crates, versions};
use crate::util::errors::AppResult;
use diesel::{dsl::count_star, prelude::*, PgConnection};
use prometheus::{proto::MetricFamily, IntGauge};

metrics! {
    pub struct ServiceMetrics {
        /// Number of crates ever published
        crates_total: IntGauge,
        /// Number of versions ever published
        versions_total: IntGauge,
        /// Number of queued up background jobs
        background_jobs: IntGauge,
    }

    // All service metrics will be prefixed with this namespace.
    namespace: "cratesio_service",
}

impl ServiceMetrics {
    pub(crate) fn gather(&self, conn: &PgConnection) -> AppResult<Vec<MetricFamily>> {
        self.crates_total
            .set(crates::table.select(count_star()).first(conn)?);
        self.versions_total
            .set(versions::table.select(count_star()).first(conn)?);
        self.background_jobs
            .set(background_jobs::table.select(count_star()).first(conn)?);

        Ok(self.registry.gather())
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Jeremy Letang.
// 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.

use iron::{BeforeMiddleware, Request, IronResult};
use iron::status::Status;
use iron::error::IronError;
use iron::headers::ContentType;
use iron::headers::AccessControlAllowOrigin;
use iron::headers::AccessControlAllowMethods;
use iron::headers::AccessControlAllowHeaders;
use iron::modifiers::Header;
use std::error::Error;
use std::fmt;
use unicase::UniCase;

pub struct SimpleCors;

#[derive(Debug)]
pub struct FakeError;

impl Error for FakeError {
    fn description(&self) -> &str { "" }

    fn cause(&self) -> Option<&Error> { None }
}

impl fmt::Display for FakeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "")
    }
}

impl BeforeMiddleware for SimpleCors {
    fn before(&self, _: &mut Request) -> IronResult<()> {
        use iron::method::Method::*;
        let content_type = Header(ContentType::json());
        let allow_origin = Header(AccessControlAllowOrigin::Any);
        let allow_method = Header(AccessControlAllowMethods(vec![Get, Post, Put, Delete, Options]));
        let allow_headers = Header(AccessControlAllowHeaders(vec![
            UniCase("x-github-token".to_owned()),
            UniCase("content-type".to_owned())
        ]));
        let modifiers = (Status::Ok, content_type, allow_origin, allow_method, allow_headers);
        Err(IronError::new(FakeError, modifiers))
    }
}
<commit_msg>so, do not apply cors and return nothing OK when method is not options<commit_after>// Copyright 2016 Jeremy Letang.
// 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.

use iron::{BeforeMiddleware, Request, IronResult};
use iron::status::Status;
use iron::error::IronError;
use iron::headers::ContentType;
use iron::headers::AccessControlAllowOrigin;
use iron::headers::AccessControlAllowMethods;
use iron::headers::AccessControlAllowHeaders;
use iron::modifiers::Header;
use std::error::Error;
use std::fmt;
use unicase::UniCase;

pub struct SimpleCors;

#[derive(Debug)]
pub struct FakeError;

impl Error for FakeError {
    fn description(&self) -> &str { "" }

    fn cause(&self) -> Option<&Error> { None }
}

impl fmt::Display for FakeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "")
    }
}

impl BeforeMiddleware for SimpleCors {
    fn before(&self, req : &mut Request) -> IronResult<()> {
        use iron::method::Method::*;
        match req.method {
            Options => {
                let content_type = Header(ContentType::json());
                let allow_origin = Header(AccessControlAllowOrigin::Any);
                let allow_method = Header(AccessControlAllowMethods(vec![Get, Post, Put, Delete, Options]));
                let allow_headers = Header(AccessControlAllowHeaders(vec![
                    UniCase("x-github-token".to_owned()),
                    UniCase("content-type".to_owned())
                ]));
                let modifiers = (Status::Ok, content_type, allow_origin, allow_method, allow_headers);
                Err(IronError::new(FakeError, modifiers))
            },
            _ => Ok(()),
        }
    }
}
<|endoftext|>


<commit_before>//! [GET /_matrix/client/r0/user/{userId}/filter/{filterId}](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-user-userid-filter-filterid)

use ruma_api_macros::ruma_api;
use ruma_identifiers::UserId;
use serde::{Deserialize, Serialize};

use super::FilterDefinition;

ruma_api! {
    metadata {
        description: "Retrieve a previously created filter.",
        method: GET,
        name: "get_filter",
        path: "/_matrix/client/r0/user/:user_id/filter/:filter_id",
        rate_limited: false,
        requires_authentication: false,
    }

    request {
        /// The ID of the filter to download.
        #[ruma_api(path)]
        pub filter_id: String,
        /// The user ID to download a filter for.
        #[ruma_api(path)]
        pub user_id: UserId,
    }

    response {
        /// The filter definition.
        #[ruma_api(body)]
        pub filter: FilterDefinition,
    }
}
<commit_msg>Update get_filter endpoint to r0.4.0<commit_after>//! [GET /_matrix/client/r0/user/{userId}/filter/{filterId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-user-userid-filter-filterid)

use ruma_api_macros::ruma_api;
use ruma_identifiers::UserId;
use serde::{Deserialize, Serialize};

use super::FilterDefinition;

ruma_api! {
    metadata {
        description: "Retrieve a previously created filter.",
        method: GET,
        name: "get_filter",
        path: "/_matrix/client/r0/user/:user_id/filter/:filter_id",
        rate_limited: false,
        requires_authentication: true,
    }

    request {
        /// The ID of the filter to download.
        #[ruma_api(path)]
        pub filter_id: String,
        /// The user ID to download a filter for.
        #[ruma_api(path)]
        pub user_id: UserId,
    }

    response {
        /// The filter definition.
        #[ruma_api(body)]
        pub filter: FilterDefinition,
    }
}
<|endoftext|>


<commit_before>use output::Colours;

use options::{flags, Vars, Misfire};
use options::parser::MatchedFlags;

/// Under what circumstances we should display coloured, rather than plain,
/// output to the terminal.
///
/// By default, we want to display the colours when stdout can display them.
/// Turning them on when output is going to, say, a pipe, would make programs
/// such as `grep` or `more` not work properly. So the `Automatic` mode does
/// this check and only displays colours when they can be truly appreciated.
#[derive(PartialEq, Debug)]
enum TerminalColours {

    /// Display them even when output isn’t going to a terminal.
    Always,

    /// Display them when output is going to a terminal, but not otherwise.
    Automatic,

    /// Never display them, even when output is going to a terminal.
    Never,
}

impl Default for TerminalColours {
    fn default() -> TerminalColours {
        TerminalColours::Automatic
    }
}

const COLOURS: &[&str] = &["always", "auto", "never"];

impl TerminalColours {

    /// Determine which terminal colour conditions to use.
    fn deduce(matches: &MatchedFlags) -> Result<TerminalColours, Misfire> {

        let word = match matches.get_where(|f| f.matches(&flags::COLOR) || f.matches(&flags::COLOUR))? {
            Some(w) => w,
            None    => return Ok(TerminalColours::default()),
        };

        if word == "always" {
            Ok(TerminalColours::Always)
        }
        else if word == "auto" || word == "automatic" {
            Ok(TerminalColours::Automatic)
        }
        else if word == "never" {
            Ok(TerminalColours::Never)
        }
        else {
            Err(Misfire::bad_argument(&flags::COLOR, word, COLOURS))
        }
    }
}

impl Colours {
    pub fn deduce<V, TW>(matches: &MatchedFlags, vars: &V, widther: TW) -> Result<Colours, Misfire>
    where TW: Fn() -> Option<usize>, V: Vars {
        use self::TerminalColours::*;
        use output::lsc::LSColors;

        let tc = TerminalColours::deduce(matches)?;
        if tc == Never || (tc == Automatic && widther().is_none()) {
            return Ok(Colours::plain());
        }

        let scale = matches.has_where(|f| f.matches(&flags::COLOR_SCALE) || f.matches(&flags::COLOUR_SCALE))?;
        let mut c = Colours::colourful(scale.is_some());

        if let Some(lsc) = vars.get("LS_COLORS") {
            let lsc = lsc.to_string_lossy();
            let lsc = LSColors::parse(lsc.as_ref());

            if let Some(dir) = lsc.get("di") {
                c.filekinds.directory = dir;
            }
        }

        Ok(c)
    }
}

#[cfg(test)]
mod terminal_test {
    use super::*;
    use std::ffi::OsString;
    use options::flags;
    use options::parser::{Flag, Arg};

    use options::test::parse_for_test;
    use options::test::Strictnesses::*;

    pub fn os(input: &'static str) -> OsString {
        let mut os = OsString::new();
        os.push(input);
        os
    }

    static TEST_ARGS: &[&Arg] = &[ &flags::COLOR, &flags::COLOUR ];

    macro_rules! test {
        ($name:ident:  $inputs:expr;  $stricts:expr => $result:expr) => {
            #[test]
            fn $name() {
                for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| TerminalColours::deduce(mf)) {
                    assert_eq!(result, $result);
                }
            }
        };

        ($name:ident:  $inputs:expr;  $stricts:expr => err $result:expr) => {
            #[test]
            fn $name() {
                for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| TerminalColours::deduce(mf)) {
                    assert_eq!(result.unwrap_err(), $result);
                }
            }
        };
    }

    // Default
    test!(empty:         [];                     Both => Ok(TerminalColours::default()));

    // --colour
    test!(u_always:      ["--colour=always"];    Both => Ok(TerminalColours::Always));
    test!(u_auto:        ["--colour", "auto"];   Both => Ok(TerminalColours::Automatic));
    test!(u_never:       ["--colour=never"];     Both => Ok(TerminalColours::Never));

    // --color
    test!(no_u_always:   ["--color", "always"];  Both => Ok(TerminalColours::Always));
    test!(no_u_auto:     ["--color=auto"];       Both => Ok(TerminalColours::Automatic));
    test!(no_u_never:    ["--color", "never"];   Both => Ok(TerminalColours::Never));

    // Errors
    test!(no_u_error:    ["--color=upstream"];   Both => err Misfire::bad_argument(&flags::COLOR, &os("upstream"), super::COLOURS));  // the error is for --color
    test!(u_error:       ["--colour=lovers"];    Both => err Misfire::bad_argument(&flags::COLOR, &os("lovers"),   super::COLOURS));  // and so is this one!

    // Overriding
    test!(overridden_1:  ["--colour=auto", "--colour=never"];  Last => Ok(TerminalColours::Never));
    test!(overridden_2:  ["--color=auto",  "--colour=never"];  Last => Ok(TerminalColours::Never));
    test!(overridden_3:  ["--colour=auto", "--color=never"];   Last => Ok(TerminalColours::Never));
    test!(overridden_4:  ["--color=auto",  "--color=never"];   Last => Ok(TerminalColours::Never));

    test!(overridden_5:  ["--colour=auto", "--colour=never"];  Complain => err Misfire::Duplicate(Flag::Long("colour"), Flag::Long("colour")));
    test!(overridden_6:  ["--color=auto",  "--colour=never"];  Complain => err Misfire::Duplicate(Flag::Long("color"),  Flag::Long("colour")));
    test!(overridden_7:  ["--colour=auto", "--color=never"];   Complain => err Misfire::Duplicate(Flag::Long("colour"), Flag::Long("color")));
    test!(overridden_8:  ["--color=auto",  "--color=never"];   Complain => err Misfire::Duplicate(Flag::Long("color"),  Flag::Long("color")));
}

#[cfg(test)]
mod colour_test {
    use super::*;
    use options::flags;
    use options::parser::{Flag, Arg};

    use options::test::parse_for_test;
    use options::test::Strictnesses::*;

    static TEST_ARGS: &[&Arg] = &[ &flags::COLOR,       &flags::COLOUR,
                                   &flags::COLOR_SCALE, &flags::COLOUR_SCALE ];

    macro_rules! test {
        ($name:ident:  $inputs:expr, $widther:expr;  $stricts:expr => $result:expr) => {
            #[test]
            fn $name() {
                for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| Colours::deduce(mf, &None, &$widther)) {
                    assert_eq!(result, $result);
                }
            }
        };

        ($name:ident:  $inputs:expr, $widther:expr;  $stricts:expr => err $result:expr) => {
            #[test]
            fn $name() {
                for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| Colours::deduce(mf, &None, &$widther)) {
                    assert_eq!(result.unwrap_err(), $result);
                }
            }
        };

        ($name:ident:  $inputs:expr, $widther:expr;  $stricts:expr => like $pat:pat) => {
            #[test]
            fn $name() {
                for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| Colours::deduce(mf, &None, &$widther)) {
                    println!("Testing {:?}", result);
                    match result {
                        $pat => assert!(true),
                        _    => assert!(false),
                    }
                }
            }
        };
    }

    test!(width_1:  ["--colour", "always"],    || Some(80);  Both => Ok(Colours::colourful(false)));
    test!(width_2:  ["--colour", "always"],    || None;      Both => Ok(Colours::colourful(false)));
    test!(width_3:  ["--colour", "never"],     || Some(80);  Both => Ok(Colours::plain()));
    test!(width_4:  ["--colour", "never"],     || None;      Both => Ok(Colours::plain()));
    test!(width_5:  ["--colour", "automatic"], || Some(80);  Both => Ok(Colours::colourful(false)));
    test!(width_6:  ["--colour", "automatic"], || None;      Both => Ok(Colours::plain()));
    test!(width_7:  [],                        || Some(80);  Both => Ok(Colours::colourful(false)));
    test!(width_8:  [],                        || None;      Both => Ok(Colours::plain()));

    test!(scale_1:  ["--color=always", "--color-scale", "--colour-scale"], || None;   Last => like Ok(Colours { scale: true,  .. }));
    test!(scale_2:  ["--color=always", "--color-scale",                 ], || None;   Last => like Ok(Colours { scale: true,  .. }));
    test!(scale_3:  ["--color=always",                  "--colour-scale"], || None;   Last => like Ok(Colours { scale: true,  .. }));
    test!(scale_4:  ["--color=always",                                  ], || None;   Last => like Ok(Colours { scale: false, .. }));

    test!(scale_5:  ["--color=always", "--color-scale", "--colour-scale"], || None;   Complain => err Misfire::Duplicate(Flag::Long("color-scale"),  Flag::Long("colour-scale")));
    test!(scale_6:  ["--color=always", "--color-scale",                 ], || None;   Complain => like Ok(Colours { scale: true,  .. }));
    test!(scale_7:  ["--color=always",                  "--colour-scale"], || None;   Complain => like Ok(Colours { scale: true,  .. }));
    test!(scale_8:  ["--color=always",                                  ], || None;   Complain => like Ok(Colours { scale: false, .. }));
}

#[cfg(test)]
mod customs_test {
    use std::ffi::OsString;

    use super::*;
    use options::Vars;
    use options::test::parse_for_test;
    use options::test::Strictnesses::Both;

    use ansi_term::Colour::*;

    macro_rules! test {
        ($name:ident:  ls $ls:expr, exa $exa:expr  =>  $resulter:expr) => {
            #[test]
            fn $name() {
                let mut c = Colours::colourful(false);
                $resulter(&mut c);

                let vars = MockVars { ls: $ls, exa: $exa };

                for result in parse_for_test(&[], &[], Both, |mf| Colours::deduce(mf, &vars, || Some(80))) {
                    assert_eq!(result, Ok(c));
                }
            }
        };
    }

    struct MockVars {
        ls: &'static str,
        exa: &'static str,
    }

    // Test impl that just returns the value it has.
    impl Vars for MockVars {
        fn get(&self, name: &'static str) -> Option<OsString> {
            if name == "LS_COLORS" && !self.ls.is_empty() {
                OsString::from(self.ls.clone()).into()
            }
            else if name == "EXA_COLORS" && !self.exa.is_empty() {
                OsString::from(self.exa.clone()).into()
            }
            else {
                None
            }
        }
    }

    test!(override_1:  ls "di=34", exa ""  =>  |c: &mut Colours| { c.filekinds.directory = Blue.normal(); });
}
<commit_msg>Add more ls_colors colours<commit_after>use output::Colours;

use options::{flags, Vars, Misfire};
use options::parser::MatchedFlags;

/// Under what circumstances we should display coloured, rather than plain,
/// output to the terminal.
///
/// By default, we want to display the colours when stdout can display them.
/// Turning them on when output is going to, say, a pipe, would make programs
/// such as `grep` or `more` not work properly. So the `Automatic` mode does
/// this check and only displays colours when they can be truly appreciated.
#[derive(PartialEq, Debug)]
enum TerminalColours {

    /// Display them even when output isn’t going to a terminal.
    Always,

    /// Display them when output is going to a terminal, but not otherwise.
    Automatic,

    /// Never display them, even when output is going to a terminal.
    Never,
}

impl Default for TerminalColours {
    fn default() -> TerminalColours {
        TerminalColours::Automatic
    }
}

const COLOURS: &[&str] = &["always", "auto", "never"];

impl TerminalColours {

    /// Determine which terminal colour conditions to use.
    fn deduce(matches: &MatchedFlags) -> Result<TerminalColours, Misfire> {

        let word = match matches.get_where(|f| f.matches(&flags::COLOR) || f.matches(&flags::COLOUR))? {
            Some(w) => w,
            None    => return Ok(TerminalColours::default()),
        };

        if word == "always" {
            Ok(TerminalColours::Always)
        }
        else if word == "auto" || word == "automatic" {
            Ok(TerminalColours::Automatic)
        }
        else if word == "never" {
            Ok(TerminalColours::Never)
        }
        else {
            Err(Misfire::bad_argument(&flags::COLOR, word, COLOURS))
        }
    }
}

impl Colours {
    pub fn deduce<V, TW>(matches: &MatchedFlags, vars: &V, widther: TW) -> Result<Colours, Misfire>
    where TW: Fn() -> Option<usize>, V: Vars {
        use self::TerminalColours::*;
        use output::lsc::LSColors;

        let tc = TerminalColours::deduce(matches)?;
        if tc == Never || (tc == Automatic && widther().is_none()) {
            return Ok(Colours::plain());
        }

        let scale = matches.has_where(|f| f.matches(&flags::COLOR_SCALE) || f.matches(&flags::COLOUR_SCALE))?;
        let mut colours = Colours::colourful(scale.is_some());

        if let Some(lsc) = vars.get("LS_COLORS") {
            let lsc = lsc.to_string_lossy();
            let lsc = LSColors::parse(lsc.as_ref());

            if let Some(c) = lsc.get("di") { colours.filekinds.directory  = c; }
            if let Some(c) = lsc.get("ex") { colours.filekinds.executable = c; }
            if let Some(c) = lsc.get("fi") { colours.filekinds.normal     = c; }
            if let Some(c) = lsc.get("pi") { colours.filekinds.pipe       = c; }
            if let Some(c) = lsc.get("so") { colours.filekinds.socket     = c; }
            if let Some(c) = lsc.get("bd") { colours.filekinds.device     = c; }
            if let Some(c) = lsc.get("cd") { colours.filekinds.device     = c; }
            if let Some(c) = lsc.get("ln") { colours.filekinds.symlink    = c; }
            if let Some(c) = lsc.get("or") { colours.broken_arrow         = c; }
            if let Some(c) = lsc.get("mi") { colours.broken_filename      = c; }
        }

        Ok(colours)
    }
}

#[cfg(test)]
mod terminal_test {
    use super::*;
    use std::ffi::OsString;
    use options::flags;
    use options::parser::{Flag, Arg};

    use options::test::parse_for_test;
    use options::test::Strictnesses::*;

    pub fn os(input: &'static str) -> OsString {
        let mut os = OsString::new();
        os.push(input);
        os
    }

    static TEST_ARGS: &[&Arg] = &[ &flags::COLOR, &flags::COLOUR ];

    macro_rules! test {
        ($name:ident:  $inputs:expr;  $stricts:expr => $result:expr) => {
            #[test]
            fn $name() {
                for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| TerminalColours::deduce(mf)) {
                    assert_eq!(result, $result);
                }
            }
        };

        ($name:ident:  $inputs:expr;  $stricts:expr => err $result:expr) => {
            #[test]
            fn $name() {
                for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| TerminalColours::deduce(mf)) {
                    assert_eq!(result.unwrap_err(), $result);
                }
            }
        };
    }

    // Default
    test!(empty:         [];                     Both => Ok(TerminalColours::default()));

    // --colour
    test!(u_always:      ["--colour=always"];    Both => Ok(TerminalColours::Always));
    test!(u_auto:        ["--colour", "auto"];   Both => Ok(TerminalColours::Automatic));
    test!(u_never:       ["--colour=never"];     Both => Ok(TerminalColours::Never));

    // --color
    test!(no_u_always:   ["--color", "always"];  Both => Ok(TerminalColours::Always));
    test!(no_u_auto:     ["--color=auto"];       Both => Ok(TerminalColours::Automatic));
    test!(no_u_never:    ["--color", "never"];   Both => Ok(TerminalColours::Never));

    // Errors
    test!(no_u_error:    ["--color=upstream"];   Both => err Misfire::bad_argument(&flags::COLOR, &os("upstream"), super::COLOURS));  // the error is for --color
    test!(u_error:       ["--colour=lovers"];    Both => err Misfire::bad_argument(&flags::COLOR, &os("lovers"),   super::COLOURS));  // and so is this one!

    // Overriding
    test!(overridden_1:  ["--colour=auto", "--colour=never"];  Last => Ok(TerminalColours::Never));
    test!(overridden_2:  ["--color=auto",  "--colour=never"];  Last => Ok(TerminalColours::Never));
    test!(overridden_3:  ["--colour=auto", "--color=never"];   Last => Ok(TerminalColours::Never));
    test!(overridden_4:  ["--color=auto",  "--color=never"];   Last => Ok(TerminalColours::Never));

    test!(overridden_5:  ["--colour=auto", "--colour=never"];  Complain => err Misfire::Duplicate(Flag::Long("colour"), Flag::Long("colour")));
    test!(overridden_6:  ["--color=auto",  "--colour=never"];  Complain => err Misfire::Duplicate(Flag::Long("color"),  Flag::Long("colour")));
    test!(overridden_7:  ["--colour=auto", "--color=never"];   Complain => err Misfire::Duplicate(Flag::Long("colour"), Flag::Long("color")));
    test!(overridden_8:  ["--color=auto",  "--color=never"];   Complain => err Misfire::Duplicate(Flag::Long("color"),  Flag::Long("color")));
}

#[cfg(test)]
mod colour_test {
    use super::*;
    use options::flags;
    use options::parser::{Flag, Arg};

    use options::test::parse_for_test;
    use options::test::Strictnesses::*;

    static TEST_ARGS: &[&Arg] = &[ &flags::COLOR,       &flags::COLOUR,
                                   &flags::COLOR_SCALE, &flags::COLOUR_SCALE ];

    macro_rules! test {
        ($name:ident:  $inputs:expr, $widther:expr;  $stricts:expr => $result:expr) => {
            #[test]
            fn $name() {
                for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| Colours::deduce(mf, &None, &$widther)) {
                    assert_eq!(result, $result);
                }
            }
        };

        ($name:ident:  $inputs:expr, $widther:expr;  $stricts:expr => err $result:expr) => {
            #[test]
            fn $name() {
                for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| Colours::deduce(mf, &None, &$widther)) {
                    assert_eq!(result.unwrap_err(), $result);
                }
            }
        };

        ($name:ident:  $inputs:expr, $widther:expr;  $stricts:expr => like $pat:pat) => {
            #[test]
            fn $name() {
                for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| Colours::deduce(mf, &None, &$widther)) {
                    println!("Testing {:?}", result);
                    match result {
                        $pat => assert!(true),
                        _    => assert!(false),
                    }
                }
            }
        };
    }

    test!(width_1:  ["--colour", "always"],    || Some(80);  Both => Ok(Colours::colourful(false)));
    test!(width_2:  ["--colour", "always"],    || None;      Both => Ok(Colours::colourful(false)));
    test!(width_3:  ["--colour", "never"],     || Some(80);  Both => Ok(Colours::plain()));
    test!(width_4:  ["--colour", "never"],     || None;      Both => Ok(Colours::plain()));
    test!(width_5:  ["--colour", "automatic"], || Some(80);  Both => Ok(Colours::colourful(false)));
    test!(width_6:  ["--colour", "automatic"], || None;      Both => Ok(Colours::plain()));
    test!(width_7:  [],                        || Some(80);  Both => Ok(Colours::colourful(false)));
    test!(width_8:  [],                        || None;      Both => Ok(Colours::plain()));

    test!(scale_1:  ["--color=always", "--color-scale", "--colour-scale"], || None;   Last => like Ok(Colours { scale: true,  .. }));
    test!(scale_2:  ["--color=always", "--color-scale",                 ], || None;   Last => like Ok(Colours { scale: true,  .. }));
    test!(scale_3:  ["--color=always",                  "--colour-scale"], || None;   Last => like Ok(Colours { scale: true,  .. }));
    test!(scale_4:  ["--color=always",                                  ], || None;   Last => like Ok(Colours { scale: false, .. }));

    test!(scale_5:  ["--color=always", "--color-scale", "--colour-scale"], || None;   Complain => err Misfire::Duplicate(Flag::Long("color-scale"),  Flag::Long("colour-scale")));
    test!(scale_6:  ["--color=always", "--color-scale",                 ], || None;   Complain => like Ok(Colours { scale: true,  .. }));
    test!(scale_7:  ["--color=always",                  "--colour-scale"], || None;   Complain => like Ok(Colours { scale: true,  .. }));
    test!(scale_8:  ["--color=always",                                  ], || None;   Complain => like Ok(Colours { scale: false, .. }));
}

#[cfg(test)]
mod customs_test {
    use std::ffi::OsString;

    use super::*;
    use options::Vars;
    use options::test::parse_for_test;
    use options::test::Strictnesses::Both;

    use ansi_term::Colour::*;

    macro_rules! test {
        ($name:ident:  ls $ls:expr, exa $exa:expr  =>  $resulter:expr) => {
            #[test]
            fn $name() {
                let mut c = Colours::colourful(false);
                $resulter(&mut c);

                let vars = MockVars { ls: $ls, exa: $exa };

                for result in parse_for_test(&[], &[], Both, |mf| Colours::deduce(mf, &vars, || Some(80))) {
                    assert_eq!(result, Ok(c));
                }
            }
        };
    }

    struct MockVars {
        ls: &'static str,
        exa: &'static str,
    }

    // Test impl that just returns the value it has.
    impl Vars for MockVars {
        fn get(&self, name: &'static str) -> Option<OsString> {
            if name == "LS_COLORS" && !self.ls.is_empty() {
                OsString::from(self.ls.clone()).into()
            }
            else if name == "EXA_COLORS" && !self.exa.is_empty() {
                OsString::from(self.exa.clone()).into()
            }
            else {
                None
            }
        }
    }

    test!(ls_di:  ls "di=31", exa ""  =>  |c: &mut Colours| { c.filekinds.directory  = Red.normal();    });  // Directory
    test!(ls_ex:  ls "ex=32", exa ""  =>  |c: &mut Colours| { c.filekinds.executable = Green.normal();  });  // Executable file
    test!(ls_fi:  ls "fi=33", exa ""  =>  |c: &mut Colours| { c.filekinds.normal     = Yellow.normal(); });  // Regular file
    test!(ls_pi:  ls "pi=34", exa ""  =>  |c: &mut Colours| { c.filekinds.pipe       = Blue.normal();   });  // FIFO
    test!(ls_so:  ls "so=35", exa ""  =>  |c: &mut Colours| { c.filekinds.socket     = Purple.normal(); });  // Socket
    test!(ls_bd:  ls "bd=36", exa ""  =>  |c: &mut Colours| { c.filekinds.device     = Cyan.normal();   });  // Block device
    test!(ls_cd:  ls "cd=35", exa ""  =>  |c: &mut Colours| { c.filekinds.device     = Purple.normal(); });  // Character device
    test!(ls_ln:  ls "ln=34", exa ""  =>  |c: &mut Colours| { c.filekinds.symlink    = Blue.normal();   });  // Symlink
    test!(ls_or:  ls "or=33", exa ""  =>  |c: &mut Colours| { c.broken_arrow         = Yellow.normal(); });  // Broken link
    test!(ls_mi:  ls "mi=32", exa ""  =>  |c: &mut Colours| { c.broken_filename      = Green.normal();  });  // Broken link target
}
<|endoftext|>


<commit_before>use std::env;
use std::fs::File;
use std::io::Write;
use std::iter;
use std::path::Path;

/*
#[doc(hidden)]
#[macro_export]
macro_rules! count {
    () => { proc_macro_call_0!() };
    (!) => { proc_macro_call_1!() };
    (!!) => { proc_macro_call_2!() };
    ...
}
*/

fn main() {
    // Tell Cargo not to rerun on src/lib.rs changes.
    println!("cargo:rerun-if-changed=build.rs");

    let out_dir = env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("count.rs");
    let mut f = File::create(&dest_path).unwrap();

    let mut content = String::new();
    content += "
        #[doc(hidden)]
        #[macro_export]
        macro_rules! count {
    ";
    for i in 0..=64 {
        let bangs = iter::repeat("!").take(i).collect::<String>();
        content += &format!("({}) => {{ proc_macro_call_{}!() }};", bangs, i);
    }
    content += "
            ($(!)+) => {
                compile_error!(\"this macro does not support >64 nested macro invocations\")
            };
        }
    ";

    f.write_all(content.as_bytes()).unwrap();
}
<commit_msg>Simplify build script using fs::write<commit_after>use std::env;
use std::fs;
use std::iter;
use std::path::Path;

/*
#[doc(hidden)]
#[macro_export]
macro_rules! count {
    () => { proc_macro_call_0!() };
    (!) => { proc_macro_call_1!() };
    (!!) => { proc_macro_call_2!() };
    ...
}
*/

fn main() {
    // Tell Cargo not to rerun on src/lib.rs changes.
    println!("cargo:rerun-if-changed=build.rs");

    let out_dir = env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("count.rs");

    let mut content = String::new();
    content += "
        #[doc(hidden)]
        #[macro_export]
        macro_rules! count {
    ";
    for i in 0..=64 {
        let bangs = iter::repeat("!").take(i).collect::<String>();
        content += &format!("({}) => {{ proc_macro_call_{}!() }};", bangs, i);
    }
    content += "
            ($(!)+) => {
                compile_error!(\"this macro does not support >64 nested macro invocations\")
            };
        }
    ";

    fs::write(dest_path, content).unwrap();
}
<|endoftext|>


<commit_before>//! N-cube or hypercube partitioning scheme

use std::ops::{Index, IndexMut};
use std::num::{Int, cast};
use std::cmp::PartialOrd;
use std::iter::AdditiveIterator;
use nalgebra::{Dim, BaseFloat, Zero, zero};
#[cfg(any(test, feature = "arbitrary"))]
use quickcheck::{Arbitrary, Gen};
use partition::{Partition, Subdivide};

/// An N-cube based partitioning scheme
#[derive(Copy, Clone, Debug)]
pub struct Ncube<P, S> {
    center: P,
    width: S,
}

impl<P, S: PartialOrd + Zero> Ncube<P, S> {
    /// Create a new N-cube given its center and width
    pub fn new(center: P, width: S) -> Ncube<P, S> {
        assert!(width > zero());
        Ncube { center: center, width: width }
    }
}

impl<P, S: Clone> Ncube<P, S> {
    /// The width of the N-cube
    pub fn width(&self) -> S { self.width.clone() }
}

impl<P: Clone, S> Ncube<P, S> {
    /// The center of the N-cube
    pub fn center(&self) -> P { self.center.clone() }
}

impl<P, S> Subdivide for Ncube<P, S>
    where P: Dim + Index<usize, Output=S> + IndexMut<usize, Output=S> + Copy,
          S: BaseFloat + PartialOrd,
{
    fn subdivide(&self) -> Vec<Ncube<P, S>> {
        let _2 = cast(2.0f64).unwrap();
        let dim = Dim::dim(None::<P>);
        let new_width = self.width / _2;
        (0..2.pow(dim as u32))
            .map(|n: i32| {
                let mut new_center = self.center;
                let dx = new_width / _2;
                for i in 0..dim {
                    new_center[i] = new_center[i] + match n / 2.pow(i as u32) % 2 {
                        0 => -dx,
                        1 => dx,
                        _ => unreachable!(),
                    };
                }
                Ncube {
                    center: new_center,
                    width: new_width,
                }
            })
        .collect()
    }
}

impl<P, S> Partition<P> for Ncube<P, S>
    where P: Dim + Index<usize, Output=S> + IndexMut<usize, Output=S> + Copy,
          S: BaseFloat + PartialOrd,
{
    fn contains(&self, elem: &P) -> bool {
        let _2 = cast(2.0f64).unwrap();
        (0..Dim::dim(None::<P>))
            .all(|i| {
                let off = (self.center[i] - elem[i]) * _2;
                (-self.width <= off) && (off < self.width)
            })
    }

    fn dispatch(&self, elem: &P) -> usize {
        range(0, Dim::dim(None::<P>))
            .map(|k| if elem[k] < self.center[k] {0} else {1 << k})
            .sum()
    }
}

#[cfg(any(test, feature = "arbitrary"))]
impl<P: Arbitrary, S: PartialOrd + Zero + Arbitrary> Arbitrary for Ncube<P, S> {
    fn arbitrary<G: Gen>(g: &mut G) -> Ncube<P, S> {
        use std::iter::repeat;
        Ncube::new(
            Arbitrary::arbitrary(g),
            repeat(())
                .map(|_| Arbitrary::arbitrary(g))
                .filter(|w: &S| w > &zero())
                .next()
                .unwrap()
        )
    }
}

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

    partition_quickcheck!(ncube_pnt2_f32_partition, Ncube<Pnt2<f32>, f32>, Pnt2<f32>);
}
<commit_msg>Replace last occurence of range(…) function<commit_after>//! N-cube or hypercube partitioning scheme

use std::ops::{Index, IndexMut};
use std::num::{Int, cast};
use std::cmp::PartialOrd;
use std::iter::AdditiveIterator;
use nalgebra::{Dim, BaseFloat, Zero, zero};
#[cfg(any(test, feature = "arbitrary"))]
use quickcheck::{Arbitrary, Gen};
use partition::{Partition, Subdivide};

/// An N-cube based partitioning scheme
#[derive(Copy, Clone, Debug)]
pub struct Ncube<P, S> {
    center: P,
    width: S,
}

impl<P, S: PartialOrd + Zero> Ncube<P, S> {
    /// Create a new N-cube given its center and width
    pub fn new(center: P, width: S) -> Ncube<P, S> {
        assert!(width > zero());
        Ncube { center: center, width: width }
    }
}

impl<P, S: Clone> Ncube<P, S> {
    /// The width of the N-cube
    pub fn width(&self) -> S { self.width.clone() }
}

impl<P: Clone, S> Ncube<P, S> {
    /// The center of the N-cube
    pub fn center(&self) -> P { self.center.clone() }
}

impl<P, S> Subdivide for Ncube<P, S>
    where P: Dim + Index<usize, Output=S> + IndexMut<usize, Output=S> + Copy,
          S: BaseFloat + PartialOrd,
{
    fn subdivide(&self) -> Vec<Ncube<P, S>> {
        let _2 = cast(2.0f64).unwrap();
        let dim = Dim::dim(None::<P>);
        let new_width = self.width / _2;
        (0..2.pow(dim as u32))
            .map(|n: i32| {
                let mut new_center = self.center;
                let dx = new_width / _2;
                for i in 0..dim {
                    new_center[i] = new_center[i] + match n / 2.pow(i as u32) % 2 {
                        0 => -dx,
                        1 => dx,
                        _ => unreachable!(),
                    };
                }
                Ncube {
                    center: new_center,
                    width: new_width,
                }
            })
        .collect()
    }
}

impl<P, S> Partition<P> for Ncube<P, S>
    where P: Dim + Index<usize, Output=S> + IndexMut<usize, Output=S> + Copy,
          S: BaseFloat + PartialOrd,
{
    fn contains(&self, elem: &P) -> bool {
        let _2 = cast(2.0f64).unwrap();
        (0..Dim::dim(None::<P>))
            .all(|i| {
                let off = (self.center[i] - elem[i]) * _2;
                (-self.width <= off) && (off < self.width)
            })
    }

    fn dispatch(&self, elem: &P) -> usize {
        (0..Dim::dim(None::<P>))
            .map(|k| if elem[k] < self.center[k] {0} else {1 << k})
            .sum()
    }
}

#[cfg(any(test, feature = "arbitrary"))]
impl<P: Arbitrary, S: PartialOrd + Zero + Arbitrary> Arbitrary for Ncube<P, S> {
    fn arbitrary<G: Gen>(g: &mut G) -> Ncube<P, S> {
        use std::iter::repeat;
        Ncube::new(
            Arbitrary::arbitrary(g),
            repeat(())
                .map(|_| Arbitrary::arbitrary(g))
                .filter(|w: &S| w > &zero())
                .next()
                .unwrap()
        )
    }
}

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

    partition_quickcheck!(ncube_pnt2_f32_partition, Ncube<Pnt2<f32>, f32>, Pnt2<f32>);
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate complex;
extern crate fft;
extern crate test;

use complex::c64;
use test::{Bencher, black_box};

#[bench] fn complex_forward_0004(bencher: &mut Bencher) { complex_forward(   4, bencher); }
#[bench] fn complex_forward_0016(bencher: &mut Bencher) { complex_forward(  16, bencher); }
#[bench] fn complex_forward_0064(bencher: &mut Bencher) { complex_forward(  64, bencher); }
#[bench] fn complex_forward_0256(bencher: &mut Bencher) { complex_forward( 256, bencher); }
#[bench] fn complex_forward_1024(bencher: &mut Bencher) { complex_forward(1024, bencher); }
#[bench] fn complex_forward_4096(bencher: &mut Bencher) { complex_forward(4096, bencher); }

fn complex_forward(size: usize, bencher: &mut Bencher) {
    let mut data = vec![c64(42.0, 0.0); size];
    bencher.iter(|| black_box(fft::complex::forward(&mut data)));
}
<commit_msg>Add benchmarks for the real part<commit_after>#![feature(test)]

extern crate complex;
extern crate fft;
extern crate test;

use complex::c64;
use test::{Bencher, black_box};

#[bench] fn complex_forward_0004(bencher: &mut Bencher) { complex_forward(   4, bencher); }
#[bench] fn complex_forward_0016(bencher: &mut Bencher) { complex_forward(  16, bencher); }
#[bench] fn complex_forward_0064(bencher: &mut Bencher) { complex_forward(  64, bencher); }
#[bench] fn complex_forward_0256(bencher: &mut Bencher) { complex_forward( 256, bencher); }
#[bench] fn complex_forward_1024(bencher: &mut Bencher) { complex_forward(1024, bencher); }
#[bench] fn complex_forward_4096(bencher: &mut Bencher) { complex_forward(4096, bencher); }

#[bench] fn real_forward_0004(bencher: &mut Bencher) { real_forward(   4, bencher); }
#[bench] fn real_forward_0016(bencher: &mut Bencher) { real_forward(  16, bencher); }
#[bench] fn real_forward_0064(bencher: &mut Bencher) { real_forward(  64, bencher); }
#[bench] fn real_forward_0256(bencher: &mut Bencher) { real_forward( 256, bencher); }
#[bench] fn real_forward_1024(bencher: &mut Bencher) { real_forward(1024, bencher); }
#[bench] fn real_forward_4096(bencher: &mut Bencher) { real_forward(4096, bencher); }

fn complex_forward(size: usize, bencher: &mut Bencher) {
    let mut data = vec![c64(42.0, 69.0); size];
    bencher.iter(|| black_box(fft::complex::forward(&mut data)));
}

fn real_forward(size: usize, bencher: &mut Bencher) {
    let mut data = vec![42.0; 2 * size];
    bencher.iter(|| black_box(fft::real::forward(&mut data)));
}
<|endoftext|>


<commit_before>use errors::Result;
use std::fmt;
use std::fs::File;
use std::io::{self, Cursor, Read};
use std::path::{Path, PathBuf};
use std::sync::Arc;

#[derive(Debug, Clone)]
pub enum Readable {
    Empty,
    Bytes(Arc<Vec<u8>>),
    Path(Arc<PathBuf>),
    Stdin,
}

impl Readable {
    /// Open a reader for this readable.
    fn read(&self) -> Result<Box<Read>> {
        use self::Readable::*;

        let out: Box<Read> = match *self {
            Empty => Box::new(Cursor::new(&[])),
            Bytes(ref bytes) => Box::new(Cursor::new(ArcCursor(Arc::clone(&bytes)))),
            Path(ref path) => Box::new(File::open(path.as_ref())?),
            Stdin => Box::new(io::stdin()),
        };

        Ok(out)
    }
}

impl fmt::Display for Readable {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        use self::Readable::*;

        match *self {
            Empty => "empty".fmt(fmt),
            Bytes(ref bytes) => write!(fmt, "bytes:{}", bytes.len()),
            Path(ref path) => write!(fmt, "path:{}", path.display()),
            Stdin => "stdin".fmt(fmt),
        }
    }
}

#[derive(Debug, Clone)]
pub struct Source {
    name: Option<Arc<String>>,
    path: Option<Arc<PathBuf>>,
    readable: Readable,
}

impl Source {
    /// Create a new empty source.
    pub fn empty<S: AsRef<str>>(name: S) -> Self {
        Self {
            name: Some(Arc::new(name.as_ref().to_string())),
            path: None,
            readable: Readable::Empty,
        }
    }

    /// Create a new bytes source.
    pub fn bytes<S: AsRef<str>>(name: S, bytes: Vec<u8>) -> Self {
        Self {
            name: Some(Arc::new(name.as_ref().to_string())),
            path: None,
            readable: Readable::Bytes(Arc::new(bytes)),
        }
    }

    /// Create a new path source.
    pub fn from_path<P: AsRef<Path>>(path: P) -> Self {
        Self {
            name: None,
            path: None,
            readable: Readable::Path(Arc::new(path.as_ref().to_owned())),
        }
    }

    /// Create an source from stdin.
    pub fn stdin() -> Self {
        Self {
            name: None,
            path: None,
            readable: Readable::Stdin,
        }
    }

    /// Access the path of the source.
    pub fn path(&self) -> Option<&Path> {
        if let Some(path) = self.path.as_ref() {
            return Some(path.as_ref());
        }

        if let Readable::Path(ref path) = self.readable {
            return Some(path.as_ref());
        }

        None
    }

    /// Open up a readable.
    pub fn read(&self) -> Result<Box<Read>> {
        self.readable.read()
    }

    /// Create a copy of this source that has a different name.
    pub fn with_name(&self, name: String) -> Self {
        Self {
            name: Some(Arc::new(name)),
            path: self.path.as_ref().map(Arc::clone),
            readable: self.readable.clone(),
        }
    }
}

impl fmt::Display for Source {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        if let Readable::Path(ref path) = self.readable {
            return path.display().fmt(fmt);
        }

        match self.name {
            Some(ref name) => write!(fmt, "<{} {}>", name, self.readable),
            None => write!(fmt, "<{}>", self.readable),
        }
    }
}

/// Adapt a vector in an Arc to be used in a Cursor.
struct ArcCursor(Arc<Vec<u8>>);

impl AsRef<[u8]> for ArcCursor {
    fn as_ref(&self) -> &[u8] {
        self.0.as_ref()
    }
}
<commit_msg>platform-neutral path formatting for source<commit_after>use errors::Result;
use std::fmt;
use std::fs::File;
use std::io::{self, Cursor, Read};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use RelativePathBuf;

#[derive(Debug, Clone)]
pub enum Readable {
    Empty,
    Bytes(Arc<Vec<u8>>),
    Path(Arc<PathBuf>),
    Stdin,
}

impl Readable {
    /// Open a reader for this readable.
    fn read(&self) -> Result<Box<Read>> {
        use self::Readable::*;

        let out: Box<Read> = match *self {
            Empty => Box::new(Cursor::new(&[])),
            Bytes(ref bytes) => Box::new(Cursor::new(ArcCursor(Arc::clone(&bytes)))),
            Path(ref path) => Box::new(File::open(path.as_ref())?),
            Stdin => Box::new(io::stdin()),
        };

        Ok(out)
    }
}

impl fmt::Display for Readable {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        use self::Readable::*;

        match *self {
            Empty => "empty".fmt(fmt),
            Bytes(ref bytes) => write!(fmt, "bytes:{}", bytes.len()),
            Path(ref path) => write!(fmt, "path:{}", path.display()),
            Stdin => "stdin".fmt(fmt),
        }
    }
}

#[derive(Debug, Clone)]
pub struct Source {
    name: Option<Arc<String>>,
    path: Option<Arc<PathBuf>>,
    readable: Readable,
}

impl Source {
    /// Create a new empty source.
    pub fn empty<S: AsRef<str>>(name: S) -> Self {
        Self {
            name: Some(Arc::new(name.as_ref().to_string())),
            path: None,
            readable: Readable::Empty,
        }
    }

    /// Create a new bytes source.
    pub fn bytes<S: AsRef<str>>(name: S, bytes: Vec<u8>) -> Self {
        Self {
            name: Some(Arc::new(name.as_ref().to_string())),
            path: None,
            readable: Readable::Bytes(Arc::new(bytes)),
        }
    }

    /// Create a new path source.
    pub fn from_path<P: AsRef<Path>>(path: P) -> Self {
        Self {
            name: None,
            path: None,
            readable: Readable::Path(Arc::new(path.as_ref().to_owned())),
        }
    }

    /// Create an source from stdin.
    pub fn stdin() -> Self {
        Self {
            name: None,
            path: None,
            readable: Readable::Stdin,
        }
    }

    /// Access the path of the source.
    pub fn path(&self) -> Option<&Path> {
        if let Some(path) = self.path.as_ref() {
            return Some(path.as_ref());
        }

        if let Readable::Path(ref path) = self.readable {
            return Some(path.as_ref());
        }

        None
    }

    /// Open up a readable.
    pub fn read(&self) -> Result<Box<Read>> {
        self.readable.read()
    }

    /// Create a copy of this source that has a different name.
    pub fn with_name(&self, name: String) -> Self {
        Self {
            name: Some(Arc::new(name)),
            path: self.path.as_ref().map(Arc::clone),
            readable: self.readable.clone(),
        }
    }
}

impl fmt::Display for Source {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        if let Readable::Path(ref path) = self.readable {
            if path.is_absolute() {
                return path.display().fmt(fmt);
            }

            // platform-neutral formatting
            return RelativePathBuf::from_path(path.as_ref())
                .map_err(|_| fmt::Error)?
                .display()
                .fmt(fmt);
        }

        match self.name {
            Some(ref name) => write!(fmt, "<{} {}>", name, self.readable),
            None => write!(fmt, "<{}>", self.readable),
        }
    }
}

/// Adapt a vector in an Arc to be used in a Cursor.
struct ArcCursor(Arc<Vec<u8>>);

impl AsRef<[u8]> for ArcCursor {
    fn as_ref(&self) -> &[u8] {
        self.0.as_ref()
    }
}
<|endoftext|>