<commit_before>// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Handles syntax highlighting and other styling.
//!
//! Plugins provide syntax highlighting information in the form of 'scopes'.
//! Scope information originating from any number of plugins can be resolved
//! into styles using a theme, augmented with additional style definitions.

use std::collections::BTreeMap;
use syntect::parsing::Scope;
use syntect::highlighting::StyleModifier;

use xi_rope::interval::Interval;
use xi_rope::spans::{Spans, SpansBuilder};

use tabs::DocumentCtx;
use styles::Style;
use plugins::PluginPid;

/// A collection of layers containing scope information.
#[derive(Default)]
//TODO: rename. Probably to `Layers`
pub struct Scopes {
    layers: BTreeMap<PluginPid, ScopeLayer>,
    merged: Spans<Style>,
}

/// A collection of scope spans from a single source.
pub struct ScopeLayer {
    stack_lookup: Vec<Vec<Scope>>,
    style_lookup: Vec<Style>,
    // TODO: this might be efficient (in memory at least) if we use
    // a prefix tree.
    /// style state of existing scope spans, so we can more efficiently
    /// compute styles of child spans.
    style_cache: BTreeMap<Vec<Scope>, StyleModifier>,
    /// Human readable scope names, for debugging
    name_lookup: Vec<Vec<String>>,
    scope_spans: Spans<u32>,
    style_spans: Spans<Style>,
}

impl Scopes {

    pub fn get_merged(&self) -> &Spans<Style> {
        &self.merged
    }

    /// Adds the provided scopes to the layer's lookup table.
    pub fn add_scopes(&mut self, layer: PluginPid, scopes: Vec<Vec<String>>,
                                doc_ctx: &DocumentCtx) {
        self.create_if_missing(layer);
        self.layers.get_mut(&layer).unwrap().add_scopes(scopes, doc_ctx);
    }

    /// Inserts empty spans at the given interval for all layers.
    ///
    /// This is useful for clearing spans, and for updating spans
    /// as edits occur.
    pub fn update_all(&mut self, iv: Interval, len: usize) {
        self.merged.edit(iv, SpansBuilder::new(len).build());
        let empty_spans = SpansBuilder::new(len).build();
        for layer in self.layers.values_mut() {
            layer.update_scopes(iv, &empty_spans);
        }
        self.resolve_styles(iv);
    }

    /// Updates the scope spans for a given layer.
    pub fn update_layer(&mut self, layer: PluginPid, iv: Interval, spans: Spans<u32>) {
        self.create_if_missing(layer);
        self.layers.get_mut(&layer).unwrap().update_scopes(iv, &spans);
        self.resolve_styles(iv);
    }

    /// Removes a given layer. This will remove all styles derived from
    /// that layer's scopes.
    pub fn remove_layer(&mut self, layer: PluginPid) -> Option<ScopeLayer> {
        let layer = self.layers.remove(&layer);
        if layer.is_some() {
            let iv_all = Interval::new_closed_closed(0, self.merged.len());
            //TODO: should Spans<T> have a clear() method?
            self.merged = SpansBuilder::new(self.merged.len()).build();
            self.resolve_styles(iv_all);
        }
        layer
    }

    pub fn theme_changed(&mut self, doc_ctx: &DocumentCtx) {
        for layer in self.layers.values_mut() {
            layer.theme_changed(doc_ctx);
        }
        self.merged = SpansBuilder::new(self.merged.len()).build();
        let iv_all = Interval::new_closed_closed(0, self.merged.len());
        self.resolve_styles(iv_all);
    }

    /// Resolves styles from all layers for the given interval, updating
    /// the master style spans.
    fn resolve_styles(&mut self, iv: Interval) {
        if self.layers.is_empty() {
            return
        }
        let mut layer_iter = self.layers.values();
        let mut resolved = layer_iter.next().unwrap().style_spans.subseq(iv);

        for other in layer_iter {
            let spans = other.style_spans.subseq(iv);
            assert_eq!(resolved.len(), spans.len());
            resolved = resolved.merge(&spans, |a, b| {
                match b {
                    Some(b) => a.merge(b),
                    None => a.to_owned(),
                }
            });
        }
        self.merged.edit(iv, resolved);
    }

    /// Prints scopes and style information for the given `Interval`.
    pub fn debug_print_spans(&self, iv: Interval) {
        for (id, layer) in self.layers.iter() {
            let spans = layer.scope_spans.subseq(iv);
            let styles = layer.style_spans.subseq(iv);
            if spans.iter().next().is_some() {
                eprintln!("scopes for layer {:?}:", id);
                for (iv, val) in spans.iter() {
                    eprintln!("{}: {:?}", iv, layer.name_lookup[*val as usize]);
                }
                eprintln!("styles:");
                for (iv, val) in styles.iter() {
                    eprintln!("{}: {:?}", iv, val);
                }
            }
        }
    }

    fn create_if_missing(&mut self, layer_id: PluginPid) {
        if !self.layers.contains_key(&layer_id) {
            self.layers.insert(layer_id, ScopeLayer::new(self.merged.len()));
        }
    }
}

impl Default for ScopeLayer {
    fn default() -> Self {
        ScopeLayer {
            stack_lookup: Vec::new(),
            style_lookup: Vec::new(),
            name_lookup: Vec::new(),
            style_cache: BTreeMap::new(),
            scope_spans: Spans::default(),
            style_spans: Spans::default(),
        }
    }
}

impl ScopeLayer {

    pub fn new(len: usize) -> Self {
        ScopeLayer {
            stack_lookup: Vec::new(),
            style_lookup: Vec::new(),
            name_lookup: Vec::new(),
            style_cache: BTreeMap::new(),
            scope_spans: SpansBuilder::new(len).build(),
            style_spans: SpansBuilder::new(len).build(),
        }
    }

    fn theme_changed(&mut self, doc_ctx: &DocumentCtx) {
        // recompute styles with the new theme
        let cur_stacks = self.stack_lookup.clone();
        self.style_lookup = self.styles_for_stacks(&cur_stacks, doc_ctx);
        let iv_all = Interval::new_closed_closed(0, self.style_spans.len());
        self.style_spans = SpansBuilder::new(self.style_spans.len()).build();
        // this feels unnecessary but we can't pass in a reference to self
        // and I don't want to get fancy unless there's an actual perf problem
        let scopes = self.scope_spans.clone();
        self.update_styles(iv_all, &scopes)
    }

    fn add_scopes(&mut self, scopes: Vec<Vec<String>>,
                                doc_ctx: &DocumentCtx) {
        let mut stacks = Vec::with_capacity(scopes.len());
        for stack in scopes {
            let scopes = stack.iter().map(|s| Scope::new(&s))
                .filter(|result| match *result {
                    Err(ref err) => {
                        eprintln!("failed to resolve scope {}\nErr: {:?}",
                                   &stack.join(" "),
                                   err);
                        false
                    }
                    _ => true
                })
                .map(|s| s.unwrap())
                .collect::<Vec<_>>();
            stacks.push(scopes);
            self.name_lookup.push(stack);
        }

        let mut new_styles = self.styles_for_stacks(stacks.as_slice(), doc_ctx);
        self.stack_lookup.append(&mut stacks);
        self.style_lookup.append(&mut new_styles);
    }

    fn styles_for_stacks(&mut self, stacks: &[Vec<Scope>],
                         doc_ctx: &DocumentCtx) -> Vec<Style> {
        let style_map = doc_ctx.get_style_map().lock().unwrap();
        let highlighter = style_map.get_highlighter();
        let mut new_styles = Vec::new();

        for stack in stacks {
            let mut last_style: Option<StyleModifier> = None;
            let mut upper_bound_of_last = stack.len() as usize;

            // walk backwards through stack to see if we have an existing
            // style for any child stacks.
            for i in 0..stack.len()-1 {
                let prev_range = 0..stack.len() - (i + 1);
                if let Some(s) = self.style_cache.get(&stack[prev_range]) {
                    last_style = Some(*s);
                    upper_bound_of_last = stack.len() - (i + 1);
                    break
                }
            }
            let mut base_style_mod = last_style.unwrap_or_default();

            // apply the stack, generating children as needed.
            for i in upper_bound_of_last..stack.len() {
                let style_mod = highlighter.get_style(&stack[0..i+1]);
                base_style_mod = base_style_mod.apply(style_mod);
            }

            let style = Style::from_syntect_style_mod(&base_style_mod);
            self.style_cache.insert(stack.clone(), base_style_mod);

            new_styles.push(style);
        }
        new_styles
    }

    fn update_scopes(&mut self, iv: Interval, spans: &Spans<u32>) {
        self.scope_spans.edit(iv, spans.to_owned());
        self.update_styles(iv, spans);
    }

    /// Updates `self.style_spans`, mapping scopes to styles and combining
    /// adjacent and equal spans.
    fn update_styles(&mut self, iv: Interval, spans: &Spans<u32>) {

        // NOTE: This is a tradeoff. Keeping both u32 and Style spans for each
        // layer makes debugging simpler and reduces the total number of spans
        // on the wire (because we combine spans that resolve to the same style)
        // but it does require additional computation + memory up front.
        let mut sb = SpansBuilder::new(spans.len());
        let mut spans_iter = spans.iter();
        let mut prev = spans_iter.next();
        {
        // distinct adjacent scopes can often resolve to the same style,
        // so we combine them when building the styles.
        let style_eq = |i1: &u32, i2: &u32| {
            self.style_lookup[*i1 as usize] == self.style_lookup[*i2 as usize]
        };

        while let Some((p_iv, p_val)) = prev {
            match spans_iter.next() {
                Some((n_iv, n_val)) if n_iv.start() == p_iv.end() && style_eq(p_val, n_val) => {
                    prev = Some((p_iv.union(n_iv), p_val));
                }
                other => {
                    sb.add_span(p_iv, self.style_lookup[*p_val as usize].to_owned());
                    prev = other;
                }
            }
        }
        }
        self.style_spans.edit(iv, sb.build());
    }
}
<commit_msg>Remove redundant name lookup from ScopeLayer<commit_after>// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Handles syntax highlighting and other styling.
//!
//! Plugins provide syntax highlighting information in the form of 'scopes'.
//! Scope information originating from any number of plugins can be resolved
//! into styles using a theme, augmented with additional style definitions.

use std::collections::BTreeMap;
use syntect::parsing::Scope;
use syntect::highlighting::StyleModifier;

use xi_rope::interval::Interval;
use xi_rope::spans::{Spans, SpansBuilder};

use tabs::DocumentCtx;
use styles::Style;
use plugins::PluginPid;

/// A collection of layers containing scope information.
#[derive(Default)]
//TODO: rename. Probably to `Layers`
pub struct Scopes {
    layers: BTreeMap<PluginPid, ScopeLayer>,
    merged: Spans<Style>,
}

/// A collection of scope spans from a single source.
pub struct ScopeLayer {
    stack_lookup: Vec<Vec<Scope>>,
    style_lookup: Vec<Style>,
    // TODO: this might be efficient (in memory at least) if we use
    // a prefix tree.
    /// style state of existing scope spans, so we can more efficiently
    /// compute styles of child spans.
    style_cache: BTreeMap<Vec<Scope>, StyleModifier>,
    /// Human readable scope names, for debugging
    scope_spans: Spans<u32>,
    style_spans: Spans<Style>,
}

impl Scopes {

    pub fn get_merged(&self) -> &Spans<Style> {
        &self.merged
    }

    /// Adds the provided scopes to the layer's lookup table.
    pub fn add_scopes(&mut self, layer: PluginPid, scopes: Vec<Vec<String>>,
                                doc_ctx: &DocumentCtx) {
        self.create_if_missing(layer);
        self.layers.get_mut(&layer).unwrap().add_scopes(scopes, doc_ctx);
    }

    /// Inserts empty spans at the given interval for all layers.
    ///
    /// This is useful for clearing spans, and for updating spans
    /// as edits occur.
    pub fn update_all(&mut self, iv: Interval, len: usize) {
        self.merged.edit(iv, SpansBuilder::new(len).build());
        let empty_spans = SpansBuilder::new(len).build();
        for layer in self.layers.values_mut() {
            layer.update_scopes(iv, &empty_spans);
        }
        self.resolve_styles(iv);
    }

    /// Updates the scope spans for a given layer.
    pub fn update_layer(&mut self, layer: PluginPid, iv: Interval, spans: Spans<u32>) {
        self.create_if_missing(layer);
        self.layers.get_mut(&layer).unwrap().update_scopes(iv, &spans);
        self.resolve_styles(iv);
    }

    /// Removes a given layer. This will remove all styles derived from
    /// that layer's scopes.
    pub fn remove_layer(&mut self, layer: PluginPid) -> Option<ScopeLayer> {
        let layer = self.layers.remove(&layer);
        if layer.is_some() {
            let iv_all = Interval::new_closed_closed(0, self.merged.len());
            //TODO: should Spans<T> have a clear() method?
            self.merged = SpansBuilder::new(self.merged.len()).build();
            self.resolve_styles(iv_all);
        }
        layer
    }

    pub fn theme_changed(&mut self, doc_ctx: &DocumentCtx) {
        for layer in self.layers.values_mut() {
            layer.theme_changed(doc_ctx);
        }
        self.merged = SpansBuilder::new(self.merged.len()).build();
        let iv_all = Interval::new_closed_closed(0, self.merged.len());
        self.resolve_styles(iv_all);
    }

    /// Resolves styles from all layers for the given interval, updating
    /// the master style spans.
    fn resolve_styles(&mut self, iv: Interval) {
        if self.layers.is_empty() {
            return
        }
        let mut layer_iter = self.layers.values();
        let mut resolved = layer_iter.next().unwrap().style_spans.subseq(iv);

        for other in layer_iter {
            let spans = other.style_spans.subseq(iv);
            assert_eq!(resolved.len(), spans.len());
            resolved = resolved.merge(&spans, |a, b| {
                match b {
                    Some(b) => a.merge(b),
                    None => a.to_owned(),
                }
            });
        }
        self.merged.edit(iv, resolved);
    }

    /// Prints scopes and style information for the given `Interval`.
    pub fn debug_print_spans(&self, iv: Interval) {
        for (id, layer) in self.layers.iter() {
            let spans = layer.scope_spans.subseq(iv);
            let styles = layer.style_spans.subseq(iv);
            if spans.iter().next().is_some() {
                eprintln!("scopes for layer {:?}:", id);
                for (iv, val) in spans.iter() {
                    eprintln!("{}: {:?}", iv, layer.stack_lookup[*val as usize]);
                }
                eprintln!("styles:");
                for (iv, val) in styles.iter() {
                    eprintln!("{}: {:?}", iv, val);
                }
            }
        }
    }

    fn create_if_missing(&mut self, layer_id: PluginPid) {
        if !self.layers.contains_key(&layer_id) {
            self.layers.insert(layer_id, ScopeLayer::new(self.merged.len()));
        }
    }
}

impl Default for ScopeLayer {
    fn default() -> Self {
        ScopeLayer {
            stack_lookup: Vec::new(),
            style_lookup: Vec::new(),
            style_cache: BTreeMap::new(),
            scope_spans: Spans::default(),
            style_spans: Spans::default(),
        }
    }
}

impl ScopeLayer {

    pub fn new(len: usize) -> Self {
        ScopeLayer {
            stack_lookup: Vec::new(),
            style_lookup: Vec::new(),
            style_cache: BTreeMap::new(),
            scope_spans: SpansBuilder::new(len).build(),
            style_spans: SpansBuilder::new(len).build(),
        }
    }

    fn theme_changed(&mut self, doc_ctx: &DocumentCtx) {
        // recompute styles with the new theme
        let cur_stacks = self.stack_lookup.clone();
        self.style_lookup = self.styles_for_stacks(&cur_stacks, doc_ctx);
        let iv_all = Interval::new_closed_closed(0, self.style_spans.len());
        self.style_spans = SpansBuilder::new(self.style_spans.len()).build();
        // this feels unnecessary but we can't pass in a reference to self
        // and I don't want to get fancy unless there's an actual perf problem
        let scopes = self.scope_spans.clone();
        self.update_styles(iv_all, &scopes)
    }

    fn add_scopes(&mut self, scopes: Vec<Vec<String>>,
                                doc_ctx: &DocumentCtx) {
        let mut stacks = Vec::with_capacity(scopes.len());
        for stack in scopes {
            let scopes = stack.iter().map(|s| Scope::new(&s))
                .filter(|result| match *result {
                    Err(ref err) => {
                        eprintln!("failed to resolve scope {}\nErr: {:?}",
                                   &stack.join(" "),
                                   err);
                        false
                    }
                    _ => true
                })
                .map(|s| s.unwrap())
                .collect::<Vec<_>>();
            stacks.push(scopes);
        }

        let mut new_styles = self.styles_for_stacks(stacks.as_slice(), doc_ctx);
        self.stack_lookup.append(&mut stacks);
        self.style_lookup.append(&mut new_styles);
    }

    fn styles_for_stacks(&mut self, stacks: &[Vec<Scope>],
                         doc_ctx: &DocumentCtx) -> Vec<Style> {
        let style_map = doc_ctx.get_style_map().lock().unwrap();
        let highlighter = style_map.get_highlighter();
        let mut new_styles = Vec::new();

        for stack in stacks {
            let mut last_style: Option<StyleModifier> = None;
            let mut upper_bound_of_last = stack.len() as usize;

            // walk backwards through stack to see if we have an existing
            // style for any child stacks.
            for i in 0..stack.len()-1 {
                let prev_range = 0..stack.len() - (i + 1);
                if let Some(s) = self.style_cache.get(&stack[prev_range]) {
                    last_style = Some(*s);
                    upper_bound_of_last = stack.len() - (i + 1);
                    break
                }
            }
            let mut base_style_mod = last_style.unwrap_or_default();

            // apply the stack, generating children as needed.
            for i in upper_bound_of_last..stack.len() {
                let style_mod = highlighter.get_style(&stack[0..i+1]);
                base_style_mod = base_style_mod.apply(style_mod);
            }

            let style = Style::from_syntect_style_mod(&base_style_mod);
            self.style_cache.insert(stack.clone(), base_style_mod);

            new_styles.push(style);
        }
        new_styles
    }

    fn update_scopes(&mut self, iv: Interval, spans: &Spans<u32>) {
        self.scope_spans.edit(iv, spans.to_owned());
        self.update_styles(iv, spans);
    }

    /// Updates `self.style_spans`, mapping scopes to styles and combining
    /// adjacent and equal spans.
    fn update_styles(&mut self, iv: Interval, spans: &Spans<u32>) {

        // NOTE: This is a tradeoff. Keeping both u32 and Style spans for each
        // layer makes debugging simpler and reduces the total number of spans
        // on the wire (because we combine spans that resolve to the same style)
        // but it does require additional computation + memory up front.
        let mut sb = SpansBuilder::new(spans.len());
        let mut spans_iter = spans.iter();
        let mut prev = spans_iter.next();
        {
        // distinct adjacent scopes can often resolve to the same style,
        // so we combine them when building the styles.
        let style_eq = |i1: &u32, i2: &u32| {
            self.style_lookup[*i1 as usize] == self.style_lookup[*i2 as usize]
        };

        while let Some((p_iv, p_val)) = prev {
            match spans_iter.next() {
                Some((n_iv, n_val)) if n_iv.start() == p_iv.end() && style_eq(p_val, n_val) => {
                    prev = Some((p_iv.union(n_iv), p_val));
                }
                other => {
                    sb.add_span(p_iv, self.style_lookup[*p_val as usize].to_owned());
                    prev = other;
                }
            }
        }
        }
        self.style_spans.edit(iv, sb.build());
    }
}
<|endoftext|>


<commit_before><commit_msg>how to read a file<commit_after>/*
 * How to read a file.
 * Future work: as a variant, we may use the C bindings to call mmap/munmap
 */

/* read the file path by calling the read_whole_file_str function */
fn read_file_whole(path: ~str) -> ~str {
   let res = io::read_whole_file_str(&Path(path));
   if result::is_err(&res) {
      fail ~"file_reader error: " + result::get_err(&res);
   }
   res.get()
}

/* read the file path line by line */
fn read_file_lines(path: ~str) -> ~str {
   let res = io::file_reader(&Path(path));
   if result::is_err(&res) {
      fail ~"file_reader error: " + result::get_err(&res);
   }

   let mut content = ~"";
   let reader = res.get();
   loop {
      let line = (reader as io::ReaderUtil).read_line();
      if reader.eof() {
         break;
      }
      // read_line does not return the '\n', so we add it
      content += line + ~"\n";
   }

   content
}

fn main() {
   let filename = ~"read_file.rs";
   //let content = read_file_whole(copy filename);
   let content = read_file_lines(copy filename);
   io::println(~"the content of " + filename + ~" is [\n" + content + ~"]");
}
<|endoftext|>


<commit_before><commit_msg>Added expression example<commit_after>fn main() {
    let x = 5u32;

    let y = {
        let x_squared = x * x;
        let x_cube = x_squared * x;

        // This expression will be assigned to `y`
        x_cube + x_squared + x
    };

    let z = {
        // The semicolon suppresses this expression and `()` is assigned to `z`
        2 * x;
    };

    println!("x is {:?}", x);
    println!("y is {:?}", y);
    println!("z is {:?}", z);
}
<|endoftext|>


<commit_before><commit_msg>update<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test for a big enum<commit_after>#[macro_use]
extern crate enum_map;
#[macro_use]
extern crate enum_map_derive;

#[derive(EnumMap)]
enum Example {
    A,
    B,
    C,
    D,
    E,
    F,
    G,
    H,
    I,
    J,
    K,
    L,
    M,
    N,
    O,
    P,
    Q,
    R,
    S,
    T,
    U,
    V,
    W,
    X,
    Y,
    Z,
    Aa,
    Bb,
    Cc,
    Dd,
    Ee,
    Ff,
    Gg,
    Hh,
    Ii,
    Jj,
    Kk,
    Ll,
    Mm,
    Nn,
    Oo,
    Pp,
    Qq,
    Rr,
    Ss,
    Tt,
    Uu,
    Vv,
    Ww,
    Xx,
    Yy,
    Zz,
}

#[test]
fn huge_enum() {
    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}
<|endoftext|>


<commit_before><commit_msg>Add unit tests for mesh creation.<commit_after>use crate::tests;
use crate::*;

const TRIANGLE_VERTS: &[graphics::Vertex] = &[
    graphics::Vertex {
        pos: [0.0, 0.0],
        uv: [0.0, 0.0],
        color: [1.0, 1.0, 1.0, 1.0],
    },
    graphics::Vertex {
        pos: [0.0, 0.0],
        uv: [0.0, 0.0],
        color: [1.0, 1.0, 1.0, 1.0],
    },
    graphics::Vertex {
        pos: [0.0, 0.0],
        uv: [0.0, 0.0],
            color: [1.0, 1.0, 1.0, 1.0],
        },
    ];

/// Mesh creation fails if verts or indices are empty.
#[test]
fn test_mesh_verts_empty() {
    let (mut ctx, _ev) = tests::make_context();
    let verts: Vec<graphics::Vertex> = vec![
    ];
    let indices: Vec<u32> = vec![
    ];
    let m = graphics::Mesh::from_raw(&mut ctx, &verts, &indices, None);
    assert!(m.is_err());

    let m = graphics::Mesh::from_raw(&mut ctx, TRIANGLE_VERTS, &indices, None);
    assert!(m.is_err());

}

/// Mesh creation fails if not enough indices to make a triangle.
#[test]
fn test_mesh_verts_invalid_count() {
    let (mut ctx, _ev) = tests::make_context();
    let indices: Vec<u32> = vec![
        0, 1
    ];
    let m = graphics::Mesh::from_raw(&mut ctx, TRIANGLE_VERTS, &indices, None);
    assert!(m.is_err());

    let indices: Vec<u32> = vec![
        0, 1, 2, 0
    ];
    let m = graphics::Mesh::from_raw(&mut ctx, TRIANGLE_VERTS, &indices, None);
    assert!(m.is_err());
}

/// TODO: This is actually tricky to test for well...
#[test]
fn test_mesh_points_clockwise() {
    let (mut ctx, _ev) = tests::make_context();

    // Points in CCW order
    let points: Vec<graphics::Point2> = vec![
        graphics::Point2::new(0.0, 0.0),
        graphics::Point2::new(0.0, -1.0),
        graphics::Point2::new(-1.0, -1.0),
    ];

    let trapezoid_mesh = graphics::Mesh::new_polygon(
        &mut ctx,
        graphics::DrawMode::fill(),
        &points,
        [0.0, 0.0, 1.0, 1.0].into()
    );

    assert!(trapezoid_mesh.is_err());
}
<|endoftext|>


<commit_before>use std::fmt;
use std::io::{self, Read};
use std::sync::{Arc, Mutex};

use hyper::client::IntoUrl;
use hyper::header::{Headers, ContentType, Location, Referer, UserAgent, Accept};
use hyper::method::Method;
use hyper::status::StatusCode;
use hyper::version::HttpVersion;
use hyper::{Url};

use serde::{Deserialize, Serialize};
use serde_json;
use serde_urlencoded;

use ::body::{self, Body};
use ::redirect::{RedirectPolicy, check_redirect};

static DEFAULT_USER_AGENT: &'static str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));

/// A `Client` to make Requests with.
///
/// The Client has various configuration values to tweak, but the defaults
/// are set to what is usually the most commonly desired value.
///
/// The `Client` holds a connection pool internally, so it is advised that
/// you create one and reuse it.
#[derive(Clone)]
pub struct Client {
    inner: Arc<ClientRef>,  //::hyper::Client,
}

impl Client {
    /// Constructs a new `Client`.
    pub fn new() -> ::Result<Client> {
        let mut client = try!(new_hyper_client());
        client.set_redirect_policy(::hyper::client::RedirectPolicy::FollowNone);
        Ok(Client {
            inner: Arc::new(ClientRef {
                hyper: client,
                redirect_policy: Mutex::new(RedirectPolicy::default()),
            }),
        })
    }

    /// Set a `RedirectPolicy` for this client.
    pub fn redirect(&mut self, policy: RedirectPolicy) {
        *self.inner.redirect_policy.lock().unwrap() = policy;
    }

    /// Convenience method to make a `GET` request to a URL.
    pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Get, url)
    }

    /// Convenience method to make a `POST` request to a URL.
    pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Post, url)
    }

    /// Convenience method to make a `HEAD` request to a URL.
    pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Head, url)
    }

    /// Start building a `Request` with the `Method` and `Url`.
    ///
    /// Returns a `RequestBuilder`, which will allow setting headers and
    /// request body before sending.
    pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
        let url = url.into_url();
        RequestBuilder {
            client: self.inner.clone(),
            method: method,
            url: url,
            _version: HttpVersion::Http11,
            headers: Headers::new(),

            body: None,
        }
    }
}

impl fmt::Debug for Client {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Client")
            .field("redirect_policy", &self.inner.redirect_policy)
            .finish()
    }
}

struct ClientRef {
    hyper: ::hyper::Client,
    redirect_policy: Mutex<RedirectPolicy>,
}

fn new_hyper_client() -> ::Result<::hyper::Client> {
    use tls::TlsClient;
    Ok(::hyper::Client::with_connector(
        ::hyper::client::Pool::with_connector(
            Default::default(),
            ::hyper::net::HttpsConnector::new(try!(TlsClient::new()))
        )
    ))
}

/// A builder to construct the properties of a `Request`.
pub struct RequestBuilder {
    client: Arc<ClientRef>,

    method: Method,
    url: Result<Url, ::UrlError>,
    _version: HttpVersion,
    headers: Headers,

    body: Option<::Result<Body>>,
}

impl RequestBuilder {
    /// Add a `Header` to this Request.
    ///
    /// ```no_run
    /// use reqwest::header::UserAgent;
    /// let client = reqwest::Client::new().expect("client failed to construct");
    ///
    /// let res = client.get("https://www.rust-lang.org")
    ///     .header(UserAgent("foo".to_string()))
    ///     .send();
    /// ```
    pub fn header<H: ::header::Header + ::header::HeaderFormat>(mut self, header: H) -> RequestBuilder {
        self.headers.set(header);
        self
    }
    /// Add a set of Headers to the existing ones on this Request.
    ///
    /// The headers will be merged in to any already set.
    pub fn headers(mut self, headers: ::header::Headers) -> RequestBuilder {
        self.headers.extend(headers.iter());
        self
    }

    /// Set the request body.
    pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder {
        self.body = Some(Ok(body.into()));
        self
    }

    /// Send a form body.
    ///
    /// Sets the body to the url encoded serialization of the passed value,
    /// and also sets the `Content-Type: application/www-form-url-encoded`
    /// header.
    ///
    /// ```no_run
    /// # use std::collections::HashMap;
    /// let mut params = HashMap::new();
    /// params.insert("lang", "rust");
    ///
    /// let client = reqwest::Client::new().unwrap();
    /// let res = client.post("http://httpbin.org")
    ///     .form(&params)
    ///     .send();
    /// ```
    pub fn form<T: Serialize>(mut self, form: &T) -> RequestBuilder {
        let body = serde_urlencoded::to_string(form).map_err(::Error::from);
        self.headers.set(ContentType::form_url_encoded());
        self.body = Some(body.map(|b| b.into()));
        self
    }

    /// Send a JSON body.
    ///
    /// Sets the body to the JSON serialization of the passed value, and
    /// also sets the `Content-Type: application/json` header.
    ///
    /// ```no_run
    /// # use std::collections::HashMap;
    /// let mut map = HashMap::new();
    /// map.insert("lang", "rust");
    ///
    /// let client = reqwest::Client::new().unwrap();
    /// let res = client.post("http://httpbin.org")
    ///     .json(&map)
    ///     .send();
    /// ```
    pub fn json<T: Serialize>(mut self, json: &T) -> RequestBuilder {
        let body = serde_json::to_vec(json).expect("serde to_vec cannot fail");
        self.headers.set(ContentType::json());
        self.body = Some(Ok(body.into()));
        self
    }

    /// Constructs the Request and sends it the target URL, returning a Response.
    pub fn send(mut self) -> ::Result<Response> {
        if !self.headers.has::<UserAgent>() {
            self.headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned()));
        }

        if !self.headers.has::<Accept>() {
            self.headers.set(Accept::star());
        }

        let client = self.client;
        let mut method = self.method;
        let mut url = try!(self.url);
        let mut headers = self.headers;
        let mut body = match self.body {
            Some(b) => Some(try!(b)),
            None => None,
        };

        let mut urls = Vec::new();

        loop {
            let res = {
                debug!("request {:?} \"{}\"", method, url);
                let mut req = client.hyper.request(method.clone(), url.clone())
                    .headers(headers.clone());

                if let Some(ref mut b) = body {
                    let body = body::as_hyper_body(b);
                    req = req.body(body);
                }

                try!(req.send())
            };

            let should_redirect = match res.status {
                StatusCode::MovedPermanently |
                StatusCode::Found |
                StatusCode::SeeOther => {
                    body = None;
                    match method {
                        Method::Get | Method::Head => {},
                        _ => {
                            method = Method::Get;
                        }
                    }
                    true
                },
                StatusCode::TemporaryRedirect |
                StatusCode::PermanentRedirect => {
                    if let Some(ref body) = body {
                        body::can_reset(body)
                    } else {
                        true
                    }
                },
                _ => false,
            };

            if should_redirect {
                let loc = {
                    let loc = res.headers.get::<Location>().map(|loc| url.join(loc));
                    if let Some(loc) = loc {
                        loc
                    } else {
                        return Ok(Response {
                            inner: res
                        });
                    }
                };

                url = match loc {
                    Ok(loc) => {
                        headers.set(Referer(url.to_string()));
                        urls.push(url);
                        if check_redirect(&client.redirect_policy.lock().unwrap(), &loc, &urls)? {
                            loc
                        } else {
                            debug!("redirect_policy disallowed redirection to '{}'", loc);
                            return Ok(Response {
                                inner: res
                            })
                        }
                    },
                    Err(e) => {
                        debug!("Location header had invalid URI: {:?}", e);
                        return Ok(Response {
                            inner: res
                        })
                    }
                };

                debug!("redirecting to {:?} '{}'", method, url);

                //TODO: removeSensitiveHeaders(&mut headers, &url);
            } else {
                return Ok(Response {
                    inner: res
                });
            }
        }
    }
}

impl fmt::Debug for RequestBuilder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("RequestBuilder")
            .field("method", &self.method)
            .field("url", &self.url)
            .field("headers", &self.headers)
            .finish()
    }
}

/// A Response to a submitted `Request`.
pub struct Response {
    inner: ::hyper::client::Response,
}

impl Response {
    /// Get the `StatusCode`.
    #[inline]
    pub fn status(&self) -> &StatusCode {
        &self.inner.status
    }

    /// Get the `Headers`.
    #[inline]
    pub fn headers(&self) -> &Headers {
        &self.inner.headers
    }

    /// Get the `HttpVersion`.
    #[inline]
    pub fn version(&self) -> &HttpVersion {
        &self.inner.version
    }

    /// Try and deserialize the response body as JSON.
    #[inline]
    pub fn json<T: Deserialize>(&mut self) -> ::Result<T> {
        serde_json::from_reader(self).map_err(::Error::from)
    }
}

/// Read the body of the Response.
impl Read for Response {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl fmt::Debug for Response {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Response")
            .field("status", self.status())
            .field("headers", self.headers())
            .field("version", self.version())
            .finish()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use ::body;
    use hyper::method::Method;
    use hyper::Url;
    use hyper::header::{Host, Headers, ContentType};
    use std::collections::HashMap;
    use serde_urlencoded;
    use serde_json;

    #[test]
    fn basic_get_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.get(some_url);

        assert_eq!(r.method, Method::Get);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn basic_head_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.head(some_url);

        assert_eq!(r.method, Method::Head);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn basic_post_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.post(some_url);

        assert_eq!(r.method, Method::Post);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn add_header() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let header = Host {
            hostname: "google.com".to_string(),
            port: None,
        };

        // Add a copy of the header to the request builder
        r = r.header(header.clone());

        // then check it was actually added
        assert_eq!(r.headers.get::<Host>(), Some(&header));
    }

    #[test]
    fn add_headers() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let header = Host {
            hostname: "google.com".to_string(),
            port: None,
        };

        let mut headers = Headers::new();
        headers.set(header);

        // Add a copy of the headers to the request builder
        r = r.headers(headers.clone());

        // then make sure they were added correctly
        assert_eq!(r.headers, headers);
    }

    #[test]
    fn add_body() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let body = "Some interesting content";

        r = r.body(body);

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        assert_eq!(buf, body);
    }

    #[test]
    fn add_form() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let mut form_data = HashMap::new();
        form_data.insert("foo", "bar");

        r = r.form(&form_data);

        // Make sure the content type was set
        assert_eq!(r.headers.get::<ContentType>(), Some(&ContentType::form_url_encoded()));

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        let body_should_be = serde_urlencoded::to_string(&form_data).unwrap();
        assert_eq!(buf, body_should_be);
    }

    #[test]
    fn add_json() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let mut json_data = HashMap::new();
        json_data.insert("foo", "bar");

        r = r.json(&json_data);

        // Make sure the content type was set
        assert_eq!(r.headers.get::<ContentType>(), Some(&ContentType::json()));

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        let body_should_be = serde_json::to_string(&json_data).unwrap();
        assert_eq!(buf, body_should_be);
    }
}
<commit_msg>remove Clone impl from Client<commit_after>use std::fmt;
use std::io::{self, Read};
use std::sync::{Arc, Mutex};

use hyper::client::IntoUrl;
use hyper::header::{Headers, ContentType, Location, Referer, UserAgent, Accept};
use hyper::method::Method;
use hyper::status::StatusCode;
use hyper::version::HttpVersion;
use hyper::{Url};

use serde::{Deserialize, Serialize};
use serde_json;
use serde_urlencoded;

use ::body::{self, Body};
use ::redirect::{RedirectPolicy, check_redirect};

static DEFAULT_USER_AGENT: &'static str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));

/// A `Client` to make Requests with.
///
/// The Client has various configuration values to tweak, but the defaults
/// are set to what is usually the most commonly desired value.
///
/// The `Client` holds a connection pool internally, so it is advised that
/// you create one and reuse it.
pub struct Client {
    inner: Arc<ClientRef>,  //::hyper::Client,
}

impl Client {
    /// Constructs a new `Client`.
    pub fn new() -> ::Result<Client> {
        let mut client = try!(new_hyper_client());
        client.set_redirect_policy(::hyper::client::RedirectPolicy::FollowNone);
        Ok(Client {
            inner: Arc::new(ClientRef {
                hyper: client,
                redirect_policy: Mutex::new(RedirectPolicy::default()),
            }),
        })
    }

    /// Set a `RedirectPolicy` for this client.
    pub fn redirect(&mut self, policy: RedirectPolicy) {
        *self.inner.redirect_policy.lock().unwrap() = policy;
    }

    /// Convenience method to make a `GET` request to a URL.
    pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Get, url)
    }

    /// Convenience method to make a `POST` request to a URL.
    pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Post, url)
    }

    /// Convenience method to make a `HEAD` request to a URL.
    pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Head, url)
    }

    /// Start building a `Request` with the `Method` and `Url`.
    ///
    /// Returns a `RequestBuilder`, which will allow setting headers and
    /// request body before sending.
    pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
        let url = url.into_url();
        RequestBuilder {
            client: self.inner.clone(),
            method: method,
            url: url,
            _version: HttpVersion::Http11,
            headers: Headers::new(),

            body: None,
        }
    }
}

impl fmt::Debug for Client {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Client")
            .field("redirect_policy", &self.inner.redirect_policy)
            .finish()
    }
}

struct ClientRef {
    hyper: ::hyper::Client,
    redirect_policy: Mutex<RedirectPolicy>,
}

fn new_hyper_client() -> ::Result<::hyper::Client> {
    use tls::TlsClient;
    Ok(::hyper::Client::with_connector(
        ::hyper::client::Pool::with_connector(
            Default::default(),
            ::hyper::net::HttpsConnector::new(try!(TlsClient::new()))
        )
    ))
}

/// A builder to construct the properties of a `Request`.
pub struct RequestBuilder {
    client: Arc<ClientRef>,

    method: Method,
    url: Result<Url, ::UrlError>,
    _version: HttpVersion,
    headers: Headers,

    body: Option<::Result<Body>>,
}

impl RequestBuilder {
    /// Add a `Header` to this Request.
    ///
    /// ```no_run
    /// use reqwest::header::UserAgent;
    /// let client = reqwest::Client::new().expect("client failed to construct");
    ///
    /// let res = client.get("https://www.rust-lang.org")
    ///     .header(UserAgent("foo".to_string()))
    ///     .send();
    /// ```
    pub fn header<H: ::header::Header + ::header::HeaderFormat>(mut self, header: H) -> RequestBuilder {
        self.headers.set(header);
        self
    }
    /// Add a set of Headers to the existing ones on this Request.
    ///
    /// The headers will be merged in to any already set.
    pub fn headers(mut self, headers: ::header::Headers) -> RequestBuilder {
        self.headers.extend(headers.iter());
        self
    }

    /// Set the request body.
    pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder {
        self.body = Some(Ok(body.into()));
        self
    }

    /// Send a form body.
    ///
    /// Sets the body to the url encoded serialization of the passed value,
    /// and also sets the `Content-Type: application/www-form-url-encoded`
    /// header.
    ///
    /// ```no_run
    /// # use std::collections::HashMap;
    /// let mut params = HashMap::new();
    /// params.insert("lang", "rust");
    ///
    /// let client = reqwest::Client::new().unwrap();
    /// let res = client.post("http://httpbin.org")
    ///     .form(&params)
    ///     .send();
    /// ```
    pub fn form<T: Serialize>(mut self, form: &T) -> RequestBuilder {
        let body = serde_urlencoded::to_string(form).map_err(::Error::from);
        self.headers.set(ContentType::form_url_encoded());
        self.body = Some(body.map(|b| b.into()));
        self
    }

    /// Send a JSON body.
    ///
    /// Sets the body to the JSON serialization of the passed value, and
    /// also sets the `Content-Type: application/json` header.
    ///
    /// ```no_run
    /// # use std::collections::HashMap;
    /// let mut map = HashMap::new();
    /// map.insert("lang", "rust");
    ///
    /// let client = reqwest::Client::new().unwrap();
    /// let res = client.post("http://httpbin.org")
    ///     .json(&map)
    ///     .send();
    /// ```
    pub fn json<T: Serialize>(mut self, json: &T) -> RequestBuilder {
        let body = serde_json::to_vec(json).expect("serde to_vec cannot fail");
        self.headers.set(ContentType::json());
        self.body = Some(Ok(body.into()));
        self
    }

    /// Constructs the Request and sends it the target URL, returning a Response.
    pub fn send(mut self) -> ::Result<Response> {
        if !self.headers.has::<UserAgent>() {
            self.headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned()));
        }

        if !self.headers.has::<Accept>() {
            self.headers.set(Accept::star());
        }

        let client = self.client;
        let mut method = self.method;
        let mut url = try!(self.url);
        let mut headers = self.headers;
        let mut body = match self.body {
            Some(b) => Some(try!(b)),
            None => None,
        };

        let mut urls = Vec::new();

        loop {
            let res = {
                debug!("request {:?} \"{}\"", method, url);
                let mut req = client.hyper.request(method.clone(), url.clone())
                    .headers(headers.clone());

                if let Some(ref mut b) = body {
                    let body = body::as_hyper_body(b);
                    req = req.body(body);
                }

                try!(req.send())
            };

            let should_redirect = match res.status {
                StatusCode::MovedPermanently |
                StatusCode::Found |
                StatusCode::SeeOther => {
                    body = None;
                    match method {
                        Method::Get | Method::Head => {},
                        _ => {
                            method = Method::Get;
                        }
                    }
                    true
                },
                StatusCode::TemporaryRedirect |
                StatusCode::PermanentRedirect => {
                    if let Some(ref body) = body {
                        body::can_reset(body)
                    } else {
                        true
                    }
                },
                _ => false,
            };

            if should_redirect {
                let loc = {
                    let loc = res.headers.get::<Location>().map(|loc| url.join(loc));
                    if let Some(loc) = loc {
                        loc
                    } else {
                        return Ok(Response {
                            inner: res
                        });
                    }
                };

                url = match loc {
                    Ok(loc) => {
                        headers.set(Referer(url.to_string()));
                        urls.push(url);
                        if check_redirect(&client.redirect_policy.lock().unwrap(), &loc, &urls)? {
                            loc
                        } else {
                            debug!("redirect_policy disallowed redirection to '{}'", loc);
                            return Ok(Response {
                                inner: res
                            })
                        }
                    },
                    Err(e) => {
                        debug!("Location header had invalid URI: {:?}", e);
                        return Ok(Response {
                            inner: res
                        })
                    }
                };

                debug!("redirecting to {:?} '{}'", method, url);

                //TODO: removeSensitiveHeaders(&mut headers, &url);
            } else {
                return Ok(Response {
                    inner: res
                });
            }
        }
    }
}

impl fmt::Debug for RequestBuilder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("RequestBuilder")
            .field("method", &self.method)
            .field("url", &self.url)
            .field("headers", &self.headers)
            .finish()
    }
}

/// A Response to a submitted `Request`.
pub struct Response {
    inner: ::hyper::client::Response,
}

impl Response {
    /// Get the `StatusCode`.
    #[inline]
    pub fn status(&self) -> &StatusCode {
        &self.inner.status
    }

    /// Get the `Headers`.
    #[inline]
    pub fn headers(&self) -> &Headers {
        &self.inner.headers
    }

    /// Get the `HttpVersion`.
    #[inline]
    pub fn version(&self) -> &HttpVersion {
        &self.inner.version
    }

    /// Try and deserialize the response body as JSON.
    #[inline]
    pub fn json<T: Deserialize>(&mut self) -> ::Result<T> {
        serde_json::from_reader(self).map_err(::Error::from)
    }
}

/// Read the body of the Response.
impl Read for Response {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl fmt::Debug for Response {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Response")
            .field("status", self.status())
            .field("headers", self.headers())
            .field("version", self.version())
            .finish()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use ::body;
    use hyper::method::Method;
    use hyper::Url;
    use hyper::header::{Host, Headers, ContentType};
    use std::collections::HashMap;
    use serde_urlencoded;
    use serde_json;

    #[test]
    fn basic_get_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.get(some_url);

        assert_eq!(r.method, Method::Get);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn basic_head_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.head(some_url);

        assert_eq!(r.method, Method::Head);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn basic_post_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.post(some_url);

        assert_eq!(r.method, Method::Post);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn add_header() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let header = Host {
            hostname: "google.com".to_string(),
            port: None,
        };

        // Add a copy of the header to the request builder
        r = r.header(header.clone());

        // then check it was actually added
        assert_eq!(r.headers.get::<Host>(), Some(&header));
    }

    #[test]
    fn add_headers() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let header = Host {
            hostname: "google.com".to_string(),
            port: None,
        };

        let mut headers = Headers::new();
        headers.set(header);

        // Add a copy of the headers to the request builder
        r = r.headers(headers.clone());

        // then make sure they were added correctly
        assert_eq!(r.headers, headers);
    }

    #[test]
    fn add_body() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let body = "Some interesting content";

        r = r.body(body);

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        assert_eq!(buf, body);
    }

    #[test]
    fn add_form() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let mut form_data = HashMap::new();
        form_data.insert("foo", "bar");

        r = r.form(&form_data);

        // Make sure the content type was set
        assert_eq!(r.headers.get::<ContentType>(), Some(&ContentType::form_url_encoded()));

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        let body_should_be = serde_urlencoded::to_string(&form_data).unwrap();
        assert_eq!(buf, body_should_be);
    }

    #[test]
    fn add_json() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let mut json_data = HashMap::new();
        json_data.insert("foo", "bar");

        r = r.json(&json_data);

        // Make sure the content type was set
        assert_eq!(r.headers.get::<ContentType>(), Some(&ContentType::json()));

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        let body_should_be = serde_json::to_string(&json_data).unwrap();
        assert_eq!(buf, body_should_be);
    }
}
<|endoftext|>


<commit_before><commit_msg>Basic logging<commit_after>
#[macro_export]
macro_rules! debug {
	($fm:expr) => ({
		println!("[DEBUG]: {}", format!($fm))
	});
	($fm:expr, $($arg:expr),*) => ({
		println!("[DEBUG]: {}", format!($fm, $($arg,)* ))
	});
}

#[macro_export]
macro_rules! info {
	($fm:expr) => ({
		println!("[INFO]: {}", format!($fm))
	});
	($fm:expr, $($arg:expr)*) => ({
		println!("[INFO]: {}", format!($fm, $($arg,)* ))
	});
}

#[macro_export]
macro_rules! warn {
	($fm:expr) => ({
		println!("[WARN]: {}", format!($fm))
	});
	($fm:expr, $($arg:expr),*) => ({
		println!("[WARN]: {}", format!($fm, $($arg,)* ))
	});
}

#[macro_export]
macro_rules! error {
	($fm:expr) => ({
		println!("[ERROR]: {}", format!($fm))
	});
	($fm:expr, $($arg:expr)*) => ({
		panic!("[ERROR]: {}", format!($fm, $($arg,)* ))
	});
}
<|endoftext|>


<commit_before><commit_msg>Added whitespace to `src/macros.rs` so that `rustfmt` doesn't trash the opening comment<commit_after><|endoftext|>


<commit_before><commit_msg>Add parser.rs file<commit_after>/// For some reason, Pest cannot find the grammar file if listed in parser/mod.rs, so I listed it here
use pest::Parser;

use ast::Expression;

use std::f64;

const _GRAMMAR: &'static str = include_str!("grammar/grammar.pest");

#[derive(Parser)]
#[grammar = "grammar/grammar.pest"]
pub struct ExpressionParser;

pub fn parse(input: &'static str) -> Expression {
    // TODO: Remove unwrap
    let mut pairs = ExpressionParser::parse_str(Rule::expression_literal, input).unwrap();

    let first = pairs.nth(0).unwrap().into_inner().nth(0).unwrap();

    match first.as_rule() {
        Rule::boolean_literal =>
            Expression::Boolean(
                first.into_span().as_str().parse::<bool>().unwrap()
            ),

        Rule::identifier_literal =>
            Expression::Identifier(first.into_span().as_str().to_string()),

        // TODO: For now, just conver the value into a normal f64. No formatting!
        Rule::decimal_digits_literal =>
            Expression::Number(
                first.into_span().as_str().parse::<f64>().unwrap()
            ),

        Rule::binary_digits_literal =>
            // The parse function does not support binary digits, so do it the hard way
            Expression::Number(
                f64::from(i32::from_str_radix(&first.into_span().as_str()[2..], 2).unwrap())
            ),

        Rule::oct_digits_literal =>
            // The parse function does not support octal digits, so do it the hard way
            Expression::Number(
                f64::from(i32::from_str_radix(&first.into_span().as_str()[2..], 8).unwrap())
            ),

        Rule::hex_digits_literal =>
            // The parse function does not support hexadecimal digits, so do it the hard way
            Expression::Number(
                f64::from(i32::from_str_radix(&first.into_span().as_str()[2..], 16).unwrap())
            ),

        // Temporary
        _ => unreachable!()
    }
}<|endoftext|>


<commit_before><commit_msg>Remove use of std::num::ToPrimitive<commit_after><|endoftext|>


<commit_before><commit_msg>First tranche of SPIR-V reflection -- read uniform offsets and binding points, then update uniform offsets<commit_after><|endoftext|>


<commit_before><commit_msg>Add tests for network<commit_after>//
// Sysinfo
//
// Copyright (c) 2020 Guillaume Gomez
//

// This test is used to ensure that the processors are loaded whatever the method
// used to initialize `System`.

extern crate sysinfo;

#[test]
fn test_processor() {
    use sysinfo::{NetworksExt, SystemExt};

    let s = sysinfo::System::new();
    assert_eq!(s.get_networks().iter().count(), 0);
    let s = sysinfo::System::new_all();
    assert!(s.get_networks().iter().count() > 0);
}
<|endoftext|>


<commit_before>use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::result::HookResult;

generate_error_module!(
    generate_error_types!(GitHookError, GitHookErrorKind,
        ConfigError => "Configuration Error",
        NoConfigError => "No Configuration",
        ConfigTypeError => "Configuration value type wrong",
        RuntimeInformationSetupError => "Couldn't setup runtime information for git hook",
        RepositoryError                   => "Error while interacting with git repository",
        RepositoryBranchError             => "Error while interacting with git branch(es)",
        RepositoryBranchNameFetchingError => "Error while fetching branch name",
        RepositorySignatureFetchingError  => "Error while fetching Authors/Committers signature",
        RepositoryIndexFetchingError      => "Error while fetching Repository Index",
        RepositoryPathAddingError         => "Error while adding Path to Index",
        RepositoryTreeWritingError        => "Error while writing repository tree",
        RepositoryTreeFindingError        => "Error while finding repository tree",
        RepositoryCommitFindingError      => "Error while finding commit",
        RepositoryCommittingError         => "Error while committing",
        HeadFetchError                    => "Error while getting HEAD",
        NotOnBranch                       => "No Branch is checked out",
        MkRepo => "Repository creation error",
        MkSignature => "Error while building Signature object"
    );
);

impl GitHookError {

    pub fn inside_of<T>(self, h: HEK) -> HookResult<T> {
        Err(HE::new(h, Some(Box::new(self))))
    }

}

impl From<GitHookError> for HE {

    fn from(he: GitHookError) -> HE {
        HE::new(HEK::HookExecutionError, Some(Box::new(he)))
    }

}

pub use self::error::GitHookError;
pub use self::error::GitHookErrorKind;
pub use self::error::MapErrInto;

<commit_msg>Add error kind and impl From<Git2Error> for HE<commit_after>use git2::Error as Git2Error;

use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::result::HookResult;

generate_error_module!(
    generate_error_types!(GitHookError, GitHookErrorKind,
        ConfigError => "Configuration Error",
        NoConfigError => "No Configuration",
        ConfigTypeError => "Configuration value type wrong",
        RuntimeInformationSetupError => "Couldn't setup runtime information for git hook",
        RepositoryBackendError            => "Error in the git library",
        RepositoryError                   => "Error while interacting with git repository",
        RepositoryBranchError             => "Error while interacting with git branch(es)",
        RepositoryBranchNameFetchingError => "Error while fetching branch name",
        RepositorySignatureFetchingError  => "Error while fetching Authors/Committers signature",
        RepositoryIndexFetchingError      => "Error while fetching Repository Index",
        RepositoryPathAddingError         => "Error while adding Path to Index",
        RepositoryTreeWritingError        => "Error while writing repository tree",
        RepositoryTreeFindingError        => "Error while finding repository tree",
        RepositoryCommitFindingError      => "Error while finding commit",
        RepositoryCommittingError         => "Error while committing",
        HeadFetchError                    => "Error while getting HEAD",
        NotOnBranch                       => "No Branch is checked out",
        MkRepo => "Repository creation error",
        MkSignature => "Error while building Signature object"
    );
);

impl GitHookError {

    pub fn inside_of<T>(self, h: HEK) -> HookResult<T> {
        Err(HE::new(h, Some(Box::new(self))))
    }

}

impl From<GitHookError> for HE {

    fn from(he: GitHookError) -> HE {
        HE::new(HEK::HookExecutionError, Some(Box::new(he)))
    }

}

impl From<Git2Error> for GitHookError {

    fn from(ge: Git2Error) -> GitHookError {
        GitHookError::new(GitHookErrorKind::RepositoryBackendError, Some(Box::new(ge)))
    }

}

pub use self::error::GitHookError;
pub use self::error::GitHookErrorKind;
pub use self::error::MapErrInto;

<|endoftext|>


<commit_before>use std::fmt::{Debug, Formatter};
use std::fmt;
use std::ops::Deref;

use clap::ArgMatches;

use runtime::Runtime;
use module::Module;

use storage::parser::FileHeaderParser;
use storage::parser::Parser;
use storage::json::parser::JsonHeaderParser;
use module::helpers::cli::create_tag_filter;
use module::helpers::cli::create_hash_filter;
use module::helpers::cli::create_text_header_field_grep_filter;
use module::helpers::cli::CliFileFilter;

mod header;

use self::header::get_url_from_header;
use self::header::get_tags_from_header;

pub struct BM<'a> {
    rt: &'a Runtime<'a>,
}

impl<'a> BM<'a> {

    pub fn new(rt: &'a Runtime<'a>) -> BM<'a> {
        BM {
            rt: rt,
        }
    }

    /**
     * Subcommand: add
     */
    fn command_add(&self, matches: &ArgMatches) -> bool {
        use ansi_term::Colour::{Green, Yellow, Red};
        use std::process::exit;
        use self::header::build_header;

        let parser = Parser::new(JsonHeaderParser::new(None));

        let url    = matches.value_of("url").map(String::from).unwrap(); // clap ensures this is present

        if !self.validate_url(&url, &parser) {
            error!("URL validation failed, exiting.");
            exit(1);
        } else {
            debug!("Verification succeeded");
        }

        let tags   = matches.value_of("tags").and_then(|s| {
            Some(s.split(",").map(String::from).collect())
        }).unwrap_or(vec![]);

        debug!("Building header with");
        debug!("    url  = '{:?}'", url);
        debug!("    tags = '{:?}'", tags);
        let header = build_header(url, tags);

        let fileid = self.rt
                         .store()
                         .new_file_with_header(self, header);

        let result = self.rt
            .store()
            .load(self, &parser, &fileid)
            .map(|file| {
                info!("{}", Yellow.paint(format!("Created file in memory: {}", fileid)));
                self.rt
                    .store()
                    .persist(&parser, file)
            })
            .unwrap_or(false);

        if result {
            info!("{}", Red.paint("Adding worked"));
        } else {
            info!("{}", Green.paint("Adding failed"));
        }

        result
    }

    fn validate_url<HP>(&self, url: &String, parser: &Parser<HP>) -> bool
        where HP: FileHeaderParser
    {
        use util::is_url;

        if !is_url(url) {
            error!("Url '{}' is not a valid URL. Will not store.", url);
            return false;
        }

        let is_in_store = self.rt
            .store()
            .load_for_module(self, parser)
            .iter()
            .any(|file| {
                let f = file.deref().borrow();
                get_url_from_header(f.header()).map(|url_in_store| {
                    &url_in_store == url
                }).unwrap_or(false)
            });

        if is_in_store {
            error!("URL '{}' seems to be in the store already", url);
            return false;
        }

        return true;
    }

    /**
     * Subcommand: list
     */
    fn command_list(&self, matches: &ArgMatches) -> bool {
        use ui::file::{FilePrinter, TablePrinter};
        use std::ops::Deref;

        let parser = Parser::new(JsonHeaderParser::new(None));
        let filter = {
            let hash_filter = create_hash_filter(matches, "id", true);
            let text_filter = create_text_header_field_grep_filter(matches, "match", "URL", true);
            let tags_filter = create_tag_filter(matches, "tags", true);
            hash_filter.and(Box::new(text_filter)).and(Box::new(tags_filter))
        };

        let files  = self.rt
            .store()
            .load_for_module(self, &parser)
            .into_iter()
            .filter(|file| filter.filter_file(file));
        let printer = TablePrinter::new(self.rt.is_verbose(), self.rt.is_debugging());

        printer.print_files_custom(files,
            &|file| {
                let fl = file.deref().borrow();
                let hdr = fl.header();
                let url = get_url_from_header(hdr).unwrap_or(String::from("Parser error"));
                let tags = get_tags_from_header(hdr);

                debug!("Custom printer field: url  = '{:?}'", url);
                debug!("Custom printer field: tags = '{:?}'", tags);

                vec![url, tags.join(", ")]
            }
        );
        true
    }

    /**
     * Subcommand: open
     */
    fn command_open(&self, matches: &ArgMatches) -> bool {
        use ansi_term::Colour::{Green, Red};
        use open;

        let parser = Parser::new(JsonHeaderParser::new(None));
        let filter : Box<CliFileFilter> = {
            let hash_filter = create_hash_filter(matches, "id", true);
            let text_filter = create_text_header_field_grep_filter(matches, "match", "URL", true);
            let tags_filter = create_tag_filter(matches, "tags", true);
            Box::new(hash_filter.and(Box::new(text_filter)).and(Box::new(tags_filter)))
        };
        let result = self.rt
            .store()
            .load_for_module(self, &parser)
            .iter()
            .filter(|file| filter.filter_file(file))
            .map(|file| {
                debug!("File loaded, can open now: {:?}", file);
                let f = file.deref().borrow();
                get_url_from_header(f.header()).map(|url| {
                    if open::that(&url[..]).is_ok() {
                        info!("{}", Green.paint(format!("open({})", url)));
                        true
                    } else {
                        info!("{}", Red.paint(format!("could not open({})", url)));
                        false
                    }
                })
                .unwrap_or(false)
            })
            .fold((0, 0), |acc, succeeded| {
                let (worked, failed) = acc;
                if succeeded {
                    (worked + 1, failed)
                } else {
                    (worked, failed + 1)
                }
            });

        let (succ, fail) = result;
        info!("{}", Green.paint(format!("open() succeeded for {} files", succ)));
        info!("{}", Red.paint(format!(  "open() failed    for {} files", fail)));
        return fail == 0;
    }

    /**
     * Subcommand: remove
     */
    fn command_remove(&self, matches: &ArgMatches) -> bool {
        use ansi_term::Colour::{Green, Red};

        let parser = Parser::new(JsonHeaderParser::new(None));

        let filter = {
            let hash_filter = create_hash_filter(matches, "id", false);
            let text_filter = create_text_header_field_grep_filter(matches, "match", "URL", false);
            let tags_filter = create_tag_filter(matches, "tags", false);
            hash_filter.or(Box::new(text_filter)).or(Box::new(tags_filter))
        };

        let result = self.rt
            .store()
            .load_for_module(self, &parser)
            .iter()
            .filter(|file| filter.filter_file(file))
            .map(|file| {
                debug!("File loaded, can remove now: {:?}", file);
                let f = file.deref().borrow();
                self.rt.store().remove(f.id().clone())
            })
            .fold((0, 0), |acc, succeeded| {
                let (worked, failed) = acc;
                if succeeded {
                    (worked + 1, failed)
                } else {
                    (worked, failed + 1)
                }
            });

        let (worked, failed) = result;

        info!("{}", Green.paint(format!("Removing succeeded for {} files", worked)));
        info!("{}", Red.paint(format!(  "Removing failed for {} files", failed)));

        return failed == 0;
    }

    /**
     * Subcommand: add_tags
     */
    fn command_add_tags(&self, matches: &ArgMatches) -> bool {
        use module::helpers::header::tags::data::alter_tags_in_files;
        use self::header::rebuild_header_with_tags;

        let parser = Parser::new(JsonHeaderParser::new(None));
        alter_tags_in_files(self, matches, &parser, |old_tags, cli_tags| {
            let mut new_tags = old_tags.clone();
            new_tags.append(&mut cli_tags.clone());
            new_tags
        }, rebuild_header_with_tags)
    }

    /**
     * Subcommand: rm_tags
     */
    fn command_rm_tags(&self, matches: &ArgMatches) -> bool {
        use module::helpers::header::tags::data::alter_tags_in_files;
        use self::header::rebuild_header_with_tags;

        let parser = Parser::new(JsonHeaderParser::new(None));
        alter_tags_in_files(self, matches, &parser, |old_tags, cli_tags| {
            old_tags.clone()
                .into_iter()
                .filter(|tag| !cli_tags.contains(tag))
                .collect()
        }, rebuild_header_with_tags)
    }

    /**
     * Subcommand: set_tags
     */
    fn command_set_tags(&self, matches: &ArgMatches) -> bool {
        use module::helpers::header::tags::data::alter_tags_in_files;
        use self::header::rebuild_header_with_tags;

        let parser = Parser::new(JsonHeaderParser::new(None));
        alter_tags_in_files(self, matches, &parser, |_, cli_tags| {
            cli_tags.clone()
        }, rebuild_header_with_tags)
    }

}

/**
 * Trait implementation for BM module
 */
impl<'a> Module<'a> for BM<'a> {

    fn exec(&self, matches: &ArgMatches) -> bool {
        use ansi_term::Colour::{Yellow, Red};

        match matches.subcommand_name() {
            Some("add") => {
                self.command_add(matches.subcommand_matches("add").unwrap())
            },

            Some("list") => {
                self.command_list(matches.subcommand_matches("list").unwrap())
            },

            Some("open") => {
                self.command_open(matches.subcommand_matches("open").unwrap())
            },

            Some("remove") => {
                self.command_remove(matches.subcommand_matches("remove").unwrap())
            },

            Some("add_tags") => {
                self.command_add_tags(matches.subcommand_matches("add_tags").unwrap())
            },

            Some("rm_tags") => {
                self.command_rm_tags(matches.subcommand_matches("rm_tags").unwrap())
            },

            Some("set_tags") => {
                self.command_set_tags(matches.subcommand_matches("set_tags").unwrap())
            },

            Some(_) | None => {
                info!("{}", Red.bold().paint("No command given, doing nothing"));
                false
            },
        }
    }

    fn name(&self) -> &'static str {
        "bookmark"
    }

    fn runtime(&self) -> &Runtime {
        self.rt
    }
}

impl<'a> Debug for BM<'a> {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "BM"));
        Ok(())
    }

}

<commit_msg>Remove unused import<commit_after>use std::fmt::{Debug, Formatter};
use std::fmt;
use std::ops::Deref;

use clap::ArgMatches;

use runtime::Runtime;
use module::Module;

use storage::parser::FileHeaderParser;
use storage::parser::Parser;
use storage::json::parser::JsonHeaderParser;
use module::helpers::cli::create_tag_filter;
use module::helpers::cli::create_hash_filter;
use module::helpers::cli::create_text_header_field_grep_filter;
use module::helpers::cli::CliFileFilter;

mod header;

use self::header::get_url_from_header;
use self::header::get_tags_from_header;

pub struct BM<'a> {
    rt: &'a Runtime<'a>,
}

impl<'a> BM<'a> {

    pub fn new(rt: &'a Runtime<'a>) -> BM<'a> {
        BM {
            rt: rt,
        }
    }

    /**
     * Subcommand: add
     */
    fn command_add(&self, matches: &ArgMatches) -> bool {
        use ansi_term::Colour::{Green, Yellow, Red};
        use std::process::exit;
        use self::header::build_header;

        let parser = Parser::new(JsonHeaderParser::new(None));

        let url    = matches.value_of("url").map(String::from).unwrap(); // clap ensures this is present

        if !self.validate_url(&url, &parser) {
            error!("URL validation failed, exiting.");
            exit(1);
        } else {
            debug!("Verification succeeded");
        }

        let tags   = matches.value_of("tags").and_then(|s| {
            Some(s.split(",").map(String::from).collect())
        }).unwrap_or(vec![]);

        debug!("Building header with");
        debug!("    url  = '{:?}'", url);
        debug!("    tags = '{:?}'", tags);
        let header = build_header(url, tags);

        let fileid = self.rt
                         .store()
                         .new_file_with_header(self, header);

        let result = self.rt
            .store()
            .load(self, &parser, &fileid)
            .map(|file| {
                info!("{}", Yellow.paint(format!("Created file in memory: {}", fileid)));
                self.rt
                    .store()
                    .persist(&parser, file)
            })
            .unwrap_or(false);

        if result {
            info!("{}", Red.paint("Adding worked"));
        } else {
            info!("{}", Green.paint("Adding failed"));
        }

        result
    }

    fn validate_url<HP>(&self, url: &String, parser: &Parser<HP>) -> bool
        where HP: FileHeaderParser
    {
        use util::is_url;

        if !is_url(url) {
            error!("Url '{}' is not a valid URL. Will not store.", url);
            return false;
        }

        let is_in_store = self.rt
            .store()
            .load_for_module(self, parser)
            .iter()
            .any(|file| {
                let f = file.deref().borrow();
                get_url_from_header(f.header()).map(|url_in_store| {
                    &url_in_store == url
                }).unwrap_or(false)
            });

        if is_in_store {
            error!("URL '{}' seems to be in the store already", url);
            return false;
        }

        return true;
    }

    /**
     * Subcommand: list
     */
    fn command_list(&self, matches: &ArgMatches) -> bool {
        use ui::file::{FilePrinter, TablePrinter};
        use std::ops::Deref;

        let parser = Parser::new(JsonHeaderParser::new(None));
        let filter = {
            let hash_filter = create_hash_filter(matches, "id", true);
            let text_filter = create_text_header_field_grep_filter(matches, "match", "URL", true);
            let tags_filter = create_tag_filter(matches, "tags", true);
            hash_filter.and(Box::new(text_filter)).and(Box::new(tags_filter))
        };

        let files  = self.rt
            .store()
            .load_for_module(self, &parser)
            .into_iter()
            .filter(|file| filter.filter_file(file));
        let printer = TablePrinter::new(self.rt.is_verbose(), self.rt.is_debugging());

        printer.print_files_custom(files,
            &|file| {
                let fl = file.deref().borrow();
                let hdr = fl.header();
                let url = get_url_from_header(hdr).unwrap_or(String::from("Parser error"));
                let tags = get_tags_from_header(hdr);

                debug!("Custom printer field: url  = '{:?}'", url);
                debug!("Custom printer field: tags = '{:?}'", tags);

                vec![url, tags.join(", ")]
            }
        );
        true
    }

    /**
     * Subcommand: open
     */
    fn command_open(&self, matches: &ArgMatches) -> bool {
        use ansi_term::Colour::{Green, Red};
        use open;

        let parser = Parser::new(JsonHeaderParser::new(None));
        let filter : Box<CliFileFilter> = {
            let hash_filter = create_hash_filter(matches, "id", true);
            let text_filter = create_text_header_field_grep_filter(matches, "match", "URL", true);
            let tags_filter = create_tag_filter(matches, "tags", true);
            Box::new(hash_filter.and(Box::new(text_filter)).and(Box::new(tags_filter)))
        };
        let result = self.rt
            .store()
            .load_for_module(self, &parser)
            .iter()
            .filter(|file| filter.filter_file(file))
            .map(|file| {
                debug!("File loaded, can open now: {:?}", file);
                let f = file.deref().borrow();
                get_url_from_header(f.header()).map(|url| {
                    if open::that(&url[..]).is_ok() {
                        info!("{}", Green.paint(format!("open({})", url)));
                        true
                    } else {
                        info!("{}", Red.paint(format!("could not open({})", url)));
                        false
                    }
                })
                .unwrap_or(false)
            })
            .fold((0, 0), |acc, succeeded| {
                let (worked, failed) = acc;
                if succeeded {
                    (worked + 1, failed)
                } else {
                    (worked, failed + 1)
                }
            });

        let (succ, fail) = result;
        info!("{}", Green.paint(format!("open() succeeded for {} files", succ)));
        info!("{}", Red.paint(format!(  "open() failed    for {} files", fail)));
        return fail == 0;
    }

    /**
     * Subcommand: remove
     */
    fn command_remove(&self, matches: &ArgMatches) -> bool {
        use ansi_term::Colour::{Green, Red};

        let parser = Parser::new(JsonHeaderParser::new(None));

        let filter = {
            let hash_filter = create_hash_filter(matches, "id", false);
            let text_filter = create_text_header_field_grep_filter(matches, "match", "URL", false);
            let tags_filter = create_tag_filter(matches, "tags", false);
            hash_filter.or(Box::new(text_filter)).or(Box::new(tags_filter))
        };

        let result = self.rt
            .store()
            .load_for_module(self, &parser)
            .iter()
            .filter(|file| filter.filter_file(file))
            .map(|file| {
                debug!("File loaded, can remove now: {:?}", file);
                let f = file.deref().borrow();
                self.rt.store().remove(f.id().clone())
            })
            .fold((0, 0), |acc, succeeded| {
                let (worked, failed) = acc;
                if succeeded {
                    (worked + 1, failed)
                } else {
                    (worked, failed + 1)
                }
            });

        let (worked, failed) = result;

        info!("{}", Green.paint(format!("Removing succeeded for {} files", worked)));
        info!("{}", Red.paint(format!(  "Removing failed for {} files", failed)));

        return failed == 0;
    }

    /**
     * Subcommand: add_tags
     */
    fn command_add_tags(&self, matches: &ArgMatches) -> bool {
        use module::helpers::header::tags::data::alter_tags_in_files;
        use self::header::rebuild_header_with_tags;

        let parser = Parser::new(JsonHeaderParser::new(None));
        alter_tags_in_files(self, matches, &parser, |old_tags, cli_tags| {
            let mut new_tags = old_tags.clone();
            new_tags.append(&mut cli_tags.clone());
            new_tags
        }, rebuild_header_with_tags)
    }

    /**
     * Subcommand: rm_tags
     */
    fn command_rm_tags(&self, matches: &ArgMatches) -> bool {
        use module::helpers::header::tags::data::alter_tags_in_files;
        use self::header::rebuild_header_with_tags;

        let parser = Parser::new(JsonHeaderParser::new(None));
        alter_tags_in_files(self, matches, &parser, |old_tags, cli_tags| {
            old_tags.clone()
                .into_iter()
                .filter(|tag| !cli_tags.contains(tag))
                .collect()
        }, rebuild_header_with_tags)
    }

    /**
     * Subcommand: set_tags
     */
    fn command_set_tags(&self, matches: &ArgMatches) -> bool {
        use module::helpers::header::tags::data::alter_tags_in_files;
        use self::header::rebuild_header_with_tags;

        let parser = Parser::new(JsonHeaderParser::new(None));
        alter_tags_in_files(self, matches, &parser, |_, cli_tags| {
            cli_tags.clone()
        }, rebuild_header_with_tags)
    }

}

/**
 * Trait implementation for BM module
 */
impl<'a> Module<'a> for BM<'a> {

    fn exec(&self, matches: &ArgMatches) -> bool {
        use ansi_term::Colour::Red;

        match matches.subcommand_name() {
            Some("add") => {
                self.command_add(matches.subcommand_matches("add").unwrap())
            },

            Some("list") => {
                self.command_list(matches.subcommand_matches("list").unwrap())
            },

            Some("open") => {
                self.command_open(matches.subcommand_matches("open").unwrap())
            },

            Some("remove") => {
                self.command_remove(matches.subcommand_matches("remove").unwrap())
            },

            Some("add_tags") => {
                self.command_add_tags(matches.subcommand_matches("add_tags").unwrap())
            },

            Some("rm_tags") => {
                self.command_rm_tags(matches.subcommand_matches("rm_tags").unwrap())
            },

            Some("set_tags") => {
                self.command_set_tags(matches.subcommand_matches("set_tags").unwrap())
            },

            Some(_) | None => {
                info!("{}", Red.bold().paint("No command given, doing nothing"));
                false
            },
        }
    }

    fn name(&self) -> &'static str {
        "bookmark"
    }

    fn runtime(&self) -> &Runtime {
        self.rt
    }
}

impl<'a> Debug for BM<'a> {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "BM"));
        Ok(())
    }

}

<|endoftext|>


<commit_before><commit_msg>add numeral sign<commit_after><|endoftext|>


<commit_before><commit_msg>Add actual trait -.-<commit_after><|endoftext|>


<commit_before><commit_msg>test: simple globals<commit_after>#[macro_use]
extern crate wayland_client as wayc;
extern crate wayland_server as ways;

mod helpers;

mod server_utils {
    use ways::{Client, EventLoop, EventLoopHandle, GlobalHandler};
    use ways::protocol::wl_compositor::WlCompositor;

    struct CompositorHandler;

    impl GlobalHandler<WlCompositor> for CompositorHandler {
        fn bind(&mut self, evlh: &mut EventLoopHandle, client: &Client, global: WlCompositor) {}
    }

    // max supported version: 4
    pub fn insert_compositor(event_loop: &mut EventLoop, v: i32) {
        let hid = event_loop.add_handler(CompositorHandler);
        let _ = event_loop.register_global::<WlCompositor, CompositorHandler>(hid, v);
    }
}

wayland_env!(ClientEnv);

mod client_utils {
    use super::ClientEnv;
    use wayc::{EnvHandler, EventQueue};
    use wayc::protocol::wl_registry::WlRegistry;

    pub fn insert_handler(event_queue: &mut EventQueue, registry: &WlRegistry) -> usize {
        let hid = event_queue.add_handler(EnvHandler::<ClientEnv>::new());
        event_queue.register::<_, EnvHandler<ClientEnv>>(registry, hid);
        hid
    }
}

#[test]
fn simple_global() {
    // server setup
    //
    let (mut server_display, mut server_event_loop) = ways::create_display();
    let socket_name = server_display
        .add_socket_auto()
        .expect("Failed to create a server socket.");
    println!("{:?}", socket_name);
    self::server_utils::insert_compositor(&mut server_event_loop, 1);

    // client setup
    //
    let (mut client_display, mut client_event_queue) =
        wayc::connect_to(&socket_name).expect("Failed to connect to server.");
    let client_registry = client_display.get_registry();
    let client_handler_hid = self::client_utils::insert_handler(&mut client_event_queue, &client_registry);

    // message passing
    //
    client_display.flush().unwrap();
    // for some reason, two dispatches are needed
    server_event_loop.dispatch(Some(10)).unwrap();
    server_event_loop.dispatch(Some(10)).unwrap();
    server_display.flush_clients();
    client_event_queue.dispatch().unwrap();

    // result assertions
    //
    let state = client_event_queue.state();
    let env = state.get_handler::<wayc::EnvHandler<ClientEnv>>(client_handler_hid);
    let globals = env.globals();
    assert!(globals.len() == 1);
    assert_eq!(globals[0], (1, "wl_compositor".into(), 1));
}

#[test]
fn multi_versions() {
    // server setup
    //
    let (mut server_display, mut server_event_loop) = ways::create_display();
    let socket_name = server_display
        .add_socket_auto()
        .expect("Failed to create a server socket.");
    println!("{:?}", socket_name);
    self::server_utils::insert_compositor(&mut server_event_loop, 4);
    self::server_utils::insert_compositor(&mut server_event_loop, 2);
    self::server_utils::insert_compositor(&mut server_event_loop, 3);
    self::server_utils::insert_compositor(&mut server_event_loop, 1);

    // client setup
    //
    let (mut client_display, mut client_event_queue) =
        wayc::connect_to(&socket_name).expect("Failed to connect to server.");
    let client_registry = client_display.get_registry();
    let client_handler_hid = self::client_utils::insert_handler(&mut client_event_queue, &client_registry);

    // message passing
    //
    client_display.flush().unwrap();
    // for some reason, two dispatches are needed
    server_event_loop.dispatch(Some(10)).unwrap();
    server_event_loop.dispatch(Some(10)).unwrap();
    server_display.flush_clients();
    client_event_queue.dispatch().unwrap();

    // result assertions
    //
    let state = client_event_queue.state();
    let env = state.get_handler::<wayc::EnvHandler<ClientEnv>>(client_handler_hid);
    let globals = env.globals();
    assert!(globals.len() == 4);
    let mut seen = [false; 4];
    for &(id, ref interface, version) in globals {
        assert!(interface == "wl_compositor");
        seen[version as usize - 1] = true;
    }
    assert_eq!(seen, [true, true, true, true]);
}
<|endoftext|>


<commit_before><commit_msg>fetch/git: remove unused, pointless variable<commit_after><|endoftext|>


<commit_before><commit_msg>Added a 'main.rs' file as example.<commit_after>
extern crate "xor-rs" as xorfn;
extern crate collections;

fn main() {
    let source = [95, 80, 96, 71, 120, 25, 44, 92, 120, 71, 96, 79, 54];
    let result = xorfn::xor(source, [23, 53, 12, 43]);

    match collections::str::from_utf8(result.as_slice()) {
        Some(string) => println!("{}", string),
        _ => {}
    }
}
<|endoftext|>


<commit_before><commit_msg>DRY fix - UI text<commit_after><|endoftext|>


<commit_before><commit_msg>Corrected implementation of FlattenedEmoji PartialEq<commit_after><|endoftext|>


<commit_before><commit_msg>style(Typo): Correct a spelling mistake<commit_after><|endoftext|>


<commit_before><commit_msg>Added dual-buffer for AqDataDesc as well as the data vec.<commit_after><|endoftext|>


<commit_before><commit_msg>Better level management<commit_after><|endoftext|>


<commit_before><commit_msg>split up functions instead of chaining them, replace returns with prints<commit_after><|endoftext|>


<commit_before><commit_msg>Quit closes AgMD1 driver<commit_after><|endoftext|>


<commit_before><commit_msg>Add unit tests for math module<commit_after><|endoftext|>


<commit_before><commit_msg>examples: Make example for SureNode code<commit_after>/// Walking example.

use naming::Naming;
use rsure::{
    Estimate,
    Result,
    node::{
        self,
        fs,
        load,
        HashUpdater,
        NodeWriter,
        Source,
        SureNode,
    },
};
use std::{
    path::Path,
};

fn main() -> Result<()> {
    rsure::log_init();

    let base = ".";

    let mut naming = Naming::new(".", "haha", "dat", true);

    let mut estimate = Estimate { files: 0, bytes: 0 };
    let tmp_name = {
        let mut nf = naming.new_temp(true)?;
        naming.add_cleanup(nf.name.clone());
        let src = fs::scan_fs(base)?
            .inspect(|node| {
                match node {
                    Ok(n @ SureNode::File { .. }) => {
                        if n.needs_hash() {
                            estimate.files += 1;
                            estimate.bytes += n.size();
                        }
                    }
                    _ => (),
                }
            });
        node::save_to(&mut nf.writer, src)?;
        nf.name
    };
    println!("name: {:?}", tmp_name);

    // Update the hashes.
    let loader = Loader { name: &tmp_name };
    let hu = HashUpdater::new(loader, &mut naming);
    let hm = hu.compute(base, &estimate)?;
    let nf = naming.new_temp(true)?;
    hm.merge(&mut NodeWriter::new(nf.writer)?)?;

    naming.rename_to_main(&nf.name)?;

    Ok(())
}

struct Loader<'a> {
    name: &'a Path,
}

impl<'a> Source for Loader<'a> {
    fn iter(&mut self) -> Result<Box<dyn Iterator<Item = Result<SureNode>> + Send>> {
        Ok(Box::new(load(self.name)?))
    }
}
<|endoftext|>


<commit_before><commit_msg>tests/mcfg.rs: added test_example_mcfg_to_negra()<commit_after>extern crate log_domain;
extern crate rustomata;

use log_domain::LogDomain;
use std::fs::File;
use std::io::Read;

use rustomata::pmcfg::{PMCFG, PMCFGRule, separate_terminal_rules};
use rustomata::pmcfg::negra::to_negra;
use rustomata::recognisable::Recognisable;
use rustomata::tree_stack_automaton::*;
use rustomata::tree_stack_automaton::{PosState, TreeStackAutomaton};

fn example_tree_stack_automaton()
        -> TreeStackAutomaton<PosState<PMCFGRule<String, String, LogDomain<f64>>>, String, LogDomain<f64>>
{
    let mut grammar_file = File::open("examples/example.mcfg").unwrap();
    let mut grammar_string = String::new();
    let _ = grammar_file.read_to_string(&mut grammar_string);
    let grammar: PMCFG<String, String, _> = grammar_string.parse().unwrap();

    let automaton = TreeStackAutomaton::from(grammar);
    automaton
}

#[test]
fn test_example_mcfg_to_negra() {
    let automaton = example_tree_stack_automaton();
    let tree_stack = automaton.recognise(vec![
        String::from("a"), String::from("a"), String::from("b"),
        String::from("c"), String::from("c"), String::from("d")
    ]).next().unwrap().0;

    let syntax_tree = to_abstract_syntax_tree(tree_stack.storage.to_tree());
    let separated_syntax_tree = separate_terminal_rules(&syntax_tree);

    let negra_string = to_negra(&separated_syntax_tree, 0);
    let negra_control_string = String::from(
        "#BOS 0\n\
         a\ta\t--\t--\t1\n\
         a\ta\t--\t--\t2\n\
         b\tb\t--\t--\t3\n\
         c\tc\t--\t--\t1\n\
         c\tc\t--\t--\t2\n\
         d\td\t--\t--\t3\n\
         #1\tA\t--\t--\t4\n\
         #2\tA\t--\t--\t1\n\
         #3\tB\t--\t--\t4\n\
         #4\tS\t--\t--\t0\n\
         #EOS 0"
    );

    assert_eq!(negra_control_string, negra_string);
}
<|endoftext|>


<commit_before><commit_msg>Add test: xkcd knapsack problem.<commit_after>//! xkcd Knapsack Problem.
//!
//! https://en.wikipedia.org/wiki/Knapsack_problem
//! https://xkcd.com/287/

extern crate num_rational;
extern crate num_traits;
extern crate puzzle_solver;

use num_rational::Ratio;
use num_traits::ToPrimitive;
use puzzle_solver::{LinExpr,Puzzle,Val};

#[test]
fn xkcd_knapsack() {
    let menu = [
        (Ratio::new(2_15, 100), "Mixed Fruit"),
        (Ratio::new(2_75, 100), "French Fries"),
        (Ratio::new(3_35, 100), "Side Salad"),
        (Ratio::new(3_55, 100), "Hot Wings"),
        (Ratio::new(4_20, 100), "Mozzarella Sticks"),
        (Ratio::new(5_80, 100), "Sampler Plate") ];

    let mut sys = Puzzle::new();
    let mut vars = Vec::with_capacity(menu.len());
    let total = Ratio::new(15_05, 100);

    for &(cost, _) in menu.iter() {
        let num = (total / cost).floor().to_integer();
        let var = sys.new_var_with_candidates(&(0..(num + 1)).collect::<Vec<Val>>());
        vars.push(var)
    }

    sys.equals(total, vars.iter().zip(menu.iter()).fold(LinExpr::from(0),
            |sum, (&var, &(cost, _))| sum + var * cost));

    let solutions = sys.solve_all();
    assert_eq!(solutions.len(), 2);

    for dict in solutions.iter() {
        println!("");
        for (&var, &(cost, string)) in vars.iter().zip(menu.iter()) {
            let numer = cost.numer().to_f32().unwrap();
            let denom = cost.denom().to_f32().unwrap();
            println!(" {} x {:.2} {}", dict[var], numer / denom, string);
        }
    }

    println!("xkcd_knapsack: {} guesses", sys.num_guesses());
}
<|endoftext|>


<commit_before><commit_msg>Added 7b<commit_after><|endoftext|>