<commit_before>use ast::node::Node;
use sass::rule::SassRule;
use error::Result;

use std::io::Write;

pub trait Streamable {
    fn stream(&self, output: &mut Write, style: &SassOutputStyle)
             -> Result<()>;
}

pub trait SassOutputStyle {
    fn rule_separator(&self) -> String {
        String::from("\n\n")
    }

    fn selector_separator(&self) -> String {
        String::from(", ")
    }

    fn selector_string(&self, rule: &SassRule, parents: &str) -> String {
        let separator = self.selector_separator();
        if parents.is_empty() {
            rule.selectors.iter()
                          .map(|s| s.token.to_string())
                          .collect::<Vec<_>>().join(&separator)
        } else {
            parents.split(",").map(|p| {
                rule.selectors.iter().map(|s| {
                    if s.token.to_string().contains("&") {
                        s.token.to_string().replace("&", p.trim())
                    } else {
                        format!("{} {}", p.trim(), s.token)
                    }
                }).collect::<Vec<_>>().join(&separator)
            }).collect::<Vec<_>>().join(&separator)
        }
    }

    fn selector_brace_separator(&self) -> String {
        String::from(" ")
    }

    fn brace_property_separator(&self) -> String {
        String::from("")
    }

    fn before_property(&self, _nesting: &str) -> String {
        String::from("\n")
    }

    fn after_property(&self) -> String {
        String::from("")
    }

    fn property_brace_separator(&self) -> String {
        String::from("")
    }

    fn rule_and_child_rules_separator(&self, _nesting: &str) -> String {
        String::from("")
    }

    fn child_rule_separator(&self, _has_properties: bool) -> String {
        String::from("\n")
    }

    fn property(&self, name: &str, value: &str) -> String {
        format!("  {}: {};", name, value)
    }

    fn before_comment(&self) -> String {
        String::new()
    }

    fn comment(&self, content: &str) -> String {
        String::from(content)
    }

    fn after_comment(&self) -> String {
        String::from("\n")
    }

    fn filter_child_properties<'a>(&self, children: &[Node])
       -> Vec<Node> {
        children.iter().filter(|c|
            match **c {
                Node::Rule(..)     => false,
                Node::Comment(..)  => true,
                Node::Property(..) => true,
                Node::Variable(..) => true,
            }
        ).cloned().collect()
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Expanded {}

impl SassOutputStyle for Expanded {
    fn brace_property_separator(&self) -> String {
        String::from("")
    }

    fn property_brace_separator(&self) -> String {
        String::from("\n")
    }

    fn rule_and_child_rules_separator(&self, _nesting: &str) -> String {
        String::from("\n")
    }

    fn before_comment(&self) -> String {
        String::from("  ")
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Nested {}

impl SassOutputStyle for Nested {
    fn brace_property_separator(&self) -> String {
        String::from("\n")
    }

    fn before_property(&self, nesting: &str) -> String {
        String::from(nesting)
    }

    fn after_property(&self) -> String {
        String::from("\n")
    }

    fn property_brace_separator(&self) -> String {
        String::from(" ")
    }

    fn rule_and_child_rules_separator(&self, nesting: &str) -> String {
        format!("\n{}", nesting)
    }

    fn child_rule_separator(&self, has_properties: bool) -> String {
        if has_properties {
            String::from("\n  ")
        } else {
            String::from("\n")
        }
    }

    fn before_comment(&self) -> String {
        String::from("  ")
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Compact {}

impl SassOutputStyle for Compact {
    fn brace_property_separator(&self) -> String {
        String::from(" ")
    }

    fn before_property(&self, _nesting: &str) -> String {
        String::from("")
    }

    fn after_property(&self) -> String {
        String::from(" ")
    }

    fn property_brace_separator(&self) -> String {
        String::from(" ")
    }

    fn rule_and_child_rules_separator(&self, _nesting: &str) -> String {
        String::from("\n")
    }

    fn property(&self, name: &str, value: &str) -> String {
        format!("{}: {};", name, value)
    }

    fn comment(&self, content: &str) -> String {
        String::from(content.lines()
                            .map(|s| s.trim())
                            .collect::<Vec<_>>()
                            .join(" "))
    }

}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Compressed {}

impl SassOutputStyle for Compressed {
    fn rule_separator(&self) -> String {
        String::from("")
    }

    fn selector_separator(&self) -> String {
        String::from(",")
    }

    fn selector_brace_separator(&self) -> String {
        String::from("")
    }

    fn before_property(&self, _nesting: &str) -> String {
        String::from("")
    }

    fn after_property(&self) -> String {
        String::from(";")
    }

    fn child_rule_separator(&self, _has_properties: bool) -> String {
        String::from("")
    }

    fn property(&self, name: &str, value: &str) -> String {
        format!("{}:{}", name, value)
    }

    fn comment(&self, _content: &str) -> String {
        String::new()
    }

    fn after_comment(&self) -> String {
        String::new()
    }

    fn selector_string(&self, rule: &SassRule, parents: &str) -> String {
        let separator: String = self.selector_separator();
        let s = if parents.is_empty() {
            rule.selectors.iter()
                          .map(|s| s.token.to_string())
                          .collect::<Vec<_>>().join(&separator)
        } else {
            parents.split(",").map(|p| {
                rule.selectors.iter().map(|s| {
                    if s.token.to_string().contains("&") {
                        s.token.to_string().replace("&", p.trim())
                    } else {
                        format!("{} {}", p.trim(), s.token)
                    }
                }).collect::<Vec<_>>().join(&separator)
            }).collect::<Vec<_>>().join(&separator)
        };
        self.compress_selectors(s)
    }

    fn filter_child_properties(&self, children: &[Node])
       -> Vec<Node> {
        children.iter().filter(|p|
            match **p {
                Node::Comment(..) => false,
                _ => true,
            }
        ).cloned().collect()
    }
}

impl Compressed {
    fn compress_selectors(&self, selector_string: String) -> String {
        selector_string.replace(" > ", ">").replace(" + ", "+")
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Debug {}

impl SassOutputStyle for Debug {
    fn property(&self, name: &str, value: &str) -> String {
        format!("Property({}, {})", name, value)
    }
}
<commit_msg>Back to the tests passing<commit_after>use ast::node::Node;
use sass::rule::SassRule;
use error::Result;

use std::io::Write;

pub trait Streamable {
    fn stream(&self, output: &mut Write, style: &SassOutputStyle)
             -> Result<()>;
}

pub trait SassOutputStyle {
    fn rule_separator(&self) -> String {
        String::from("\n\n")
    }

    fn selector_separator(&self) -> String {
        String::from(", ")
    }

    fn selector_string(&self, rule: &SassRule, parents: &str) -> String {
        let separator = self.selector_separator();
        if parents.is_empty() {
            rule.selectors.iter()
                          .map(|s| s.token.to_string())
                          .collect::<Vec<_>>().join(&separator)
        } else {
            parents.split(",").map(|p| {
                rule.selectors.iter().map(|s| {
                    if s.token.to_string().contains("&") {
                        s.token.to_string().replace("&", p.trim())
                    } else {
                        format!("{} {}", p.trim(), s.token)
                    }
                }).collect::<Vec<_>>().join(&separator)
            }).collect::<Vec<_>>().join(&separator)
        }
    }

    fn selector_brace_separator(&self) -> String {
        String::from(" ")
    }

    fn brace_property_separator(&self) -> String {
        String::from("")
    }

    fn before_property(&self, _nesting: &str) -> String {
        String::from("\n")
    }

    fn after_property(&self) -> String {
        String::from("")
    }

    fn property_brace_separator(&self) -> String {
        String::from("")
    }

    fn rule_and_child_rules_separator(&self, _nesting: &str) -> String {
        String::from("")
    }

    fn child_rule_separator(&self, _has_properties: bool) -> String {
        String::from("\n")
    }

    fn property(&self, name: &str, value: &str) -> String {
        format!("  {}: {};", name, value)
    }

    fn before_comment(&self) -> String {
        String::new()
    }

    fn comment(&self, content: &str) -> String {
        String::from(content)
    }

    fn after_comment(&self) -> String {
        String::from("\n")
    }

    fn filter_child_properties<'a>(&self, children: &[Node])
       -> Vec<Node> {
        children.iter().filter(|c|
            match **c {
                Node::Rule(..)     => false,
                Node::Comment(..)  => true,
                Node::Property(..) => true,
                Node::Variable(..) => true,
            }
        ).cloned().collect()
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Expanded {}

impl SassOutputStyle for Expanded {
    fn brace_property_separator(&self) -> String {
        String::from("")
    }

    fn property_brace_separator(&self) -> String {
        String::from("\n")
    }

    fn rule_and_child_rules_separator(&self, _nesting: &str) -> String {
        String::from("\n")
    }

    fn before_comment(&self) -> String {
        String::from("  ")
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Nested {}

impl SassOutputStyle for Nested {
    fn brace_property_separator(&self) -> String {
        String::from("\n")
    }

    fn before_property(&self, nesting: &str) -> String {
        String::from(nesting)
    }

    fn after_property(&self) -> String {
        String::from("\n")
    }

    fn property_brace_separator(&self) -> String {
        String::from(" ")
    }

    fn rule_and_child_rules_separator(&self, nesting: &str) -> String {
        format!("\n{}", nesting)
    }

    fn child_rule_separator(&self, has_properties: bool) -> String {
        if has_properties {
            String::from("\n  ")
        } else {
            String::from("\n")
        }
    }

    fn before_comment(&self) -> String {
        String::from("  ")
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Compact {}

impl SassOutputStyle for Compact {
    fn brace_property_separator(&self) -> String {
        String::from(" ")
    }

    fn before_property(&self, _nesting: &str) -> String {
        String::from("")
    }

    fn after_property(&self) -> String {
        String::from(" ")
    }

    fn property_brace_separator(&self) -> String {
        String::from(" ")
    }

    fn rule_and_child_rules_separator(&self, _nesting: &str) -> String {
        String::from("\n")
    }

    fn property(&self, name: &str, value: &str) -> String {
        format!("{}: {};", name, value)
    }

    fn comment(&self, content: &str) -> String {
        String::from(content.lines()
                            .map(|s| s.trim())
                            .collect::<Vec<_>>()
                            .join(" "))
    }

}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Compressed {}

impl SassOutputStyle for Compressed {
    fn rule_separator(&self) -> String {
        String::from("")
    }

    fn selector_separator(&self) -> String {
        String::from(",")
    }

    fn selector_brace_separator(&self) -> String {
        String::from("")
    }

    fn before_property(&self, _nesting: &str) -> String {
        String::from("")
    }

    fn after_property(&self) -> String {
        String::from(";")
    }

    fn child_rule_separator(&self, _has_properties: bool) -> String {
        String::from("")
    }

    fn property(&self, name: &str, value: &str) -> String {
        format!("{}:{}", name, value)
    }

    fn comment(&self, _content: &str) -> String {
        String::new()
    }

    fn after_comment(&self) -> String {
        String::new()
    }

    fn selector_string(&self, rule: &SassRule, parents: &str) -> String {
        let separator: String = self.selector_separator();
        let s = if parents.is_empty() {
            rule.selectors.iter()
                          .map(|s| s.token.to_string())
                          .collect::<Vec<_>>().join(&separator)
        } else {
            parents.split(",").map(|p| {
                rule.selectors.iter().map(|s| {
                    if s.token.to_string().contains("&") {
                        s.token.to_string().replace("&", p.trim())
                    } else {
                        format!("{} {}", p.trim(), s.token)
                    }
                }).collect::<Vec<_>>().join(&separator)
            }).collect::<Vec<_>>().join(&separator)
        };
        self.compress_selectors(s)
    }

    fn filter_child_properties(&self, children: &[Node])
       -> Vec<Node> {
        children.iter().filter(|c|
           match **c {
               Node::Rule(..)     => false,
               Node::Comment(..)  => false,
               Node::Property(..) => true,
               Node::Variable(..) => true,
           }
        ).cloned().collect()
    }
}

impl Compressed {
    fn compress_selectors(&self, selector_string: String) -> String {
        selector_string.replace(" > ", ">").replace(" + ", "+")
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Debug {}

impl SassOutputStyle for Debug {
    fn property(&self, name: &str, value: &str) -> String {
        format!("Property({}, {})", name, value)
    }
}
<|endoftext|>


<commit_before>fn repli<T: Clone>(list: &[T], n: uint) -> ~[T] {
    let mut r = ~[];
    for e in list.iter() {
        for _ in range(0, n) {
            r.push(e.clone());
        }
    }
    r
}

fn main() {
    let list = ~['a', 'b', 'c'];
    println!("{:?}", repli(list, 3));
}

<commit_msg>Cleanup Problem 15<commit_after>// The author of this work hereby waives all claim of copyright (economic and
// moral) in this work and immediately places it in the public domain; it may
// be used, distorted or destroyed in any manner whatsoever without further
// attribution or notice to the creator.

//! Problem 15: Vectors: replicate
//!
//! Replicate the elements of a vector a given number of times.
//!
//! Your function could have this signature:
//! `fn repli<T: Clone>(n: uint, vec: ~[T]) -> ~[T]`

fn repli<T: Clone>(n: uint, vec: ~[T]) -> ~[T] {
    vec.move_iter().flat_map(|e| Vec::from_elem(n, e).move_iter()).collect()
}

#[test]
fn dupli_0() {
    let vec = ~['a', 'b', 'c', 'c', 'd'];
    assert_eq!(repli(0, vec), ~[]);
}

#[test]
fn dupli_2() {
    let vec = ~['a', 'b', 'c', 'c', 'd'];
    assert_eq!(repli(2, vec), ~['a', 'a', 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd']);
}
<|endoftext|>


<commit_before>use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::utils::Fallible;
use dom::bindings::codegen::CanvasRenderingContext2DBinding;
use dom::window::Window;
use js::jsapi::{JSContext, JSObject};
use dom::bindings::utils::{ErrorResult};

pub struct CanvasRenderingContext2D {                           //struct containing Reflector object.
    reflector_: Reflector,
    window: @mut Window,
}

impl CanvasRenderingContext2D {                                 //CanvasRenderingContext2D interface.
    pub fn new_inherited(window: @mut Window) -> CanvasRenderingContext2D { //creating window and reflector objects.
        CanvasRenderingContext2D {
            reflector_: Reflector::new(),
            window: window,
        }
    }

    pub fn new(window: @mut Window) -> @mut CanvasRenderingContext2D {
        reflect_dom_object(@mut CanvasRenderingContext2D::new_inherited(window), window, CanvasRenderingContext2DBinding::Wrap)
    }

 pub fn Width(&self) -> u32 {                    //Width of the canvas
        0
    }

    pub fn SetWidth(&mut self, _width: u32) -> ErrorResult {
        Ok(())
    }

    pub fn Height(&self) -> u32 {                 //Height of the canvas
        0
    }

    pub fn SetHeight(&mut self, _height: u32) -> ErrorResult {
        Ok(())
    }

}

impl CanvasRenderingContext2D {
    pub fn Constructor(window: @mut Window) -> Fallible<@mut CanvasRenderingContext2D> {
        Ok(CanvasRenderingContext2D::new(window))
    }
}

impl Reflectable for CanvasRenderingContext2D {           //implementing the Reflectable.
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }

    fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
        unreachable!();
    }

    fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut Reflectable> {
        Some(self.window as @mut Reflectable)
    }

}
<commit_msg>Update canvasrenderingcontext2d.rs<commit_after>use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::utils::Fallible;
use dom::bindings::codegen::CanvasRenderingContext2DBinding;
use dom::window::Window;
use js::jsapi::{JSContext, JSObject};
use dom::bindings::utils::{ErrorResult};

pub struct CanvasRenderingContext2D {
    reflector_: Reflector,
    window: @mut Window,
}

impl CanvasRenderingContext2D {
    pub fn new_inherited(window: @mut Window) -> CanvasRenderingContext2D {
        CanvasRenderingContext2D {
            reflector_: Reflector::new(),
            window: window,
        }
    }

    pub fn new(window: @mut Window) -> @mut CanvasRenderingContext2D {
        reflect_dom_object(@mut CanvasRenderingContext2D::new_inherited(window), window, CanvasRenderingContext2DBinding::Wrap)
    }

 pub fn Width(&self) -> u32 {
        0
    }

    pub fn SetWidth(&mut self, _width: u32) -> ErrorResult {
        Ok(())
    }

    pub fn Height(&self) -> u32 {
        0
    }

    pub fn SetHeight(&mut self, _height: u32) -> ErrorResult {
        Ok(())
    }

}

impl CanvasRenderingContext2D {
    pub fn Constructor(window: @mut Window) -> Fallible<@mut CanvasRenderingContext2D> {
        Ok(CanvasRenderingContext2D::new(window))
    }
}

impl Reflectable for CanvasRenderingContext2D {           //implementing the Reflectable.
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }

    fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
        unreachable!();
    }

    fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut Reflectable> {
        Some(self.window as @mut Reflectable)
    }

}
<|endoftext|>


<commit_before>use num::{Signed, CheckedAdd, CheckedMul};
use array_ext::*;
use std::cmp::{min, max};

use super::*;

/// Evaluate all Taylor coefficients of a polynomial.
///
/// Returns None if any of the coefficients do not fit in the type.
pub trait AllTaylorCoefficients<Input>: Sized {
  fn all_taylor_coefficients(&self, input: Input)->Option<Self>;
}

macro_rules! impl_polynomials {
  ($($coefficients: expr),*) => {
$(
impl <Coefficient: DoubleSizedInteger> AllTaylorCoefficients<<Coefficient as DoubleSizedInteger>::Type> for [Coefficient; $coefficients] {
  fn all_taylor_coefficients(&self, input: <Coefficient as DoubleSizedInteger>::Type)->Option <Self> {
    let mut intermediates: [<Coefficient as DoubleSizedInteger>::Type; $coefficients] = self.map (| coefficient | coefficient.into());
    for first_source in (1..intermediates.len()).rev() {
      for source in first_source..intermediates.len() {
        intermediates[source - 1] = intermediates [source - 1].checked_add (&intermediates[source].checked_mul (&input)?)?;
      }
    }
    let mut output = [Coefficient::zero(); $coefficients];
    for (index, value) in intermediates.iter().enumerate() {
      output [index] = (*value).try_into().ok()?;
    }
    Some (output)
  }

}

)*

  }
}

impl_polynomials!(1,2,3,4,5);

#[cfg(test)]
mod tests {

//use super::*;
//use proptest::prelude::*;

macro_rules! test_polynomials {
  ($($coefficients: expr, $integer: ident, $double: ident, $uniform: ident, $name: ident,)*) => {
$(
  mod $name {
    use super::super::*;
    use proptest::prelude::*;
    proptest! {
      #[test]
      fn randomly_test_polynomial_translation_inverts (coefficients in prop::array::$uniform(-16 as i32..16), input in -16 as i32..16) {
        let translated = coefficients.all_taylor_coefficients (input as $double);
        prop_assume! (translated.is_some());
        let translated = translated.unwrap();
        let translated_back = translated.all_taylor_coefficients (-input as $double);
        prop_assert! (translated_back.is_some(), "we know that the original value was in bounds, so translating back should return some");
        prop_assert_eq! (coefficients, translated_back.unwrap());

      }
    }
  }
)*

  }
}

test_polynomials!(
  1, i32, i64, uniform1, polynomial_tests_1,
  2, i32, i64, uniform2, polynomial_tests_2,
  3, i32, i64, uniform3, polynomial_tests_3,
  4, i32, i64, uniform4, polynomial_tests_4,
  5, i32, i64, uniform5, polynomial_tests_5,
);

}
<commit_msg>Added another test<commit_after>use num::{Signed, CheckedAdd, CheckedMul};
use array_ext::*;
use std::cmp::{min, max};

use super::*;

/// Evaluate all Taylor coefficients of a polynomial.
///
/// Returns None if any of the coefficients do not fit in the type.
pub trait AllTaylorCoefficients<Input>: Sized {
  fn all_taylor_coefficients(&self, input: impl Into<Input>)->Option<Self>;
}

macro_rules! impl_polynomials {
  ($($coefficients: expr),*) => {
$(
impl <Coefficient: DoubleSizedInteger> AllTaylorCoefficients<<Coefficient as DoubleSizedInteger>::Type> for [Coefficient; $coefficients] {
  fn all_taylor_coefficients(&self, input: impl Into<<Coefficient as DoubleSizedInteger>::Type>)->Option <Self> {
    let input = input.into();
    let mut intermediates: [<Coefficient as DoubleSizedInteger>::Type; $coefficients] = self.map (| coefficient | coefficient.into());
    for first_source in (1..intermediates.len()).rev() {
      for source in first_source..intermediates.len() {
        intermediates[source - 1] = intermediates [source - 1].checked_add (&intermediates[source].checked_mul (&input)?)?;
      }
    }
    let mut output = [Coefficient::zero(); $coefficients];
    for (index, value) in intermediates.iter().enumerate() {
      output [index] = (*value).try_into().ok()?;
    }
    Some (output)
  }

}

)*

  }
}

impl_polynomials!(1,2,3,4,5);

#[cfg(test)]
mod tests {

use super::*;
//use proptest::prelude::*;
use num::BigInt;

fn naive_perfect_evaluate <Coefficient: Integer> (coefficients: & [Coefficient], input: Coefficient)->BigInt where BigInt: From<Coefficient> {
  let input = BigInt::from (input) ;
  let mut result = BigInt::zero();
  for (exponent, coefficient) in coefficients.iter().enumerate() {
    let mut term = BigInt::from(*coefficient);
    for _ in 0..exponent { term = term * &input; }
    result = result + term;
  }
  result
}

macro_rules! test_polynomials {
  ($($coefficients: expr, $integer: ident, $double: ident, $uniform: ident, $name: ident,)*) => {
$(
  mod $name {
    use super::*;
    use super::super::*;
    use proptest::prelude::*;
    proptest! {
      #[test]
      fn randomly_test_polynomial_translation_inverts (coefficients in prop::array::$uniform(-16 as i32..16), input in -16 as i32..16) {
        let translated = coefficients.all_taylor_coefficients (input);
        prop_assume! (translated.is_some());
        let translated = translated.unwrap();
        let translated_back = translated.all_taylor_coefficients (-input);
        prop_assert! (translated_back.is_some(), "we know that the original value was in bounds, so translating back should return some");
        prop_assert_eq! (coefficients, translated_back.unwrap());

      }

      #[test]
      fn randomly_test_taylor_coefficients_evaluates (coefficients in prop::array::$uniform(-16 as i32..16), input in -16 as i32..16) {
        let translated = coefficients.all_taylor_coefficients (input);
        prop_assume! (translated.is_some());
        let translated = translated.unwrap();
        let evaluated = naive_perfect_evaluate (&coefficients, input);
        prop_assert_eq! (BigInt::from(translated[0]), evaluated);

      }
    }
  }
)*

  }
}

test_polynomials!(
  1, i32, i64, uniform1, polynomial_tests_1,
  2, i32, i64, uniform2, polynomial_tests_2,
  3, i32, i64, uniform3, polynomial_tests_3,
  4, i32, i64, uniform4, polynomial_tests_4,
  5, i32, i64, uniform5, polynomial_tests_5,
);

}
<|endoftext|>


<commit_before>/**
 * Generic tokenizer used by the parser in the Syntax tool.
 *
 * https://www.npmjs.com/package/syntax-cli
 */

// ------------------------------------------------------------------
// Token.

#[derive(Debug, Clone, Copy)]
struct Token {
    kind: i32,
    value: &'static str,

    start_offset: i32,
    end_offset: i32,
    start_line: i32,
    end_line: i32,
    start_column: i32,
    end_column: i32,
}

// NOTE: LEX_RULES_BY_START_CONDITIONS, and TOKENS_MAP
// are defined in the lazy_static! block in lr.templates.rs

// ------------------------------------------------------------------
// Tokenizer.

lazy_static! {
    /**
     * Pre-parse the regex instead of parsing it every time when calling `get_next_token`.
     * This is really(and most) time consuming accodring to my test.
     */
    static ref REGEX_RULES: Vec<Regex> = LEX_RULES.iter().map(|rule| Regex::new(rule).unwrap()).collect();
}

struct Tokenizer {
    /**
     * Tokenizing string.
     */
    string: &'static str,

    /**
     * Cursor for current symbol.
     */
    cursor: i32,

    /**
     * States.
     */
    states: Vec<&'static str>,

    /**
     * Line-based location tracking.
     */
    current_line: i32,
    current_column: i32,
    current_line_begin_offset: i32,

    /**
     * Location data of a matched token.
     */
    token_start_offset: i32,
    token_end_offset: i32,
    token_start_line: i32,
    token_end_line: i32,
    token_start_column: i32,
    token_end_column: i32,

    /**
     * Matched text, and its length.
     */
    yytext: &'static str,
    yyleng: usize,

    handlers: [fn(&mut Tokenizer) -> &'static str; {{{LEX_RULE_HANDLERS_COUNT}}}],
}

impl Tokenizer {

    /**
     * Creates a new Tokenizer instance.
     *
     * The same instance can be then reused in parser
     * by calling `init_string`.
     */
    pub fn new() -> Tokenizer {
        let mut tokenizer = Tokenizer {
            string: "",
            cursor: 0,

            states: Vec::new(),

            current_line: 1,
            current_column: 0,
            current_line_begin_offset: 0,

            token_start_offset: 0,
            token_end_offset: 0,
            token_start_line: 0,
            token_end_line: 0,
            token_start_column: 0,
            token_end_column: 0,

            yytext: "",
            yyleng: 0,

            handlers: {{{LEX_RULE_HANDLERS_ARRAY}}}
        };

        tokenizer
    }

    /**
     * Initializes a parsing string.
     */
    pub fn init_string(&mut self, string: &'static str) -> &mut Tokenizer {
        self.string = string;

        // Initialize states.
        self.states.clear();
        self.states.push("INITIAL");

        self.cursor = 0;
        self.current_line = 1;
        self.current_column = 0;
        self.current_line_begin_offset = 0;

        self.token_start_offset = 0;
        self.token_end_offset = 0;
        self.token_start_line = 0;
        self.token_end_line = 0;
        self.token_start_column = 0;
        self.token_end_column = 0;

        self
    }

    /**
     * Returns next token.
     */
    pub fn get_next_token(&mut self) -> Token {
        if !self.has_more_tokens() {
            self.yytext = EOF;
            return self.to_token(EOF)
        }

        let str_slice = &self.string[self.cursor as usize..];

        let lex_rules_for_state = LEX_RULES_BY_START_CONDITIONS
            .get(self.get_current_state())
            .unwrap();

        let mut max_match_len = 0;
        let mut max_match_token: Option<&'static str> = None;

        for i in lex_rules_for_state {
            let i = *i as usize;

            // the previous author use this to generate a new regex expression
            // every time when `get_next_token` is called
            // now this variable is of no use, I leave it here for debug use
            let _lex_rule = LEX_RULES[i];

            if let Some(matched) = self._match(str_slice, &REGEX_RULES[i]) {

                // Manual handling of EOF token (the end of string). Return it
                // as `EOF` symbol.
                if matched.len() == 0 {
                    self.cursor = self.cursor + 1;
                }

                // find longest match
                if matched.len() > max_match_len {
                    self.yytext = matched;
                    self.yyleng = matched.len();
                    max_match_len = matched.len();
                    max_match_token = Some(self.handlers[i](self));
                }
            }
        }

        if let Some(token) = max_match_token {
            self.cursor = self.cursor + (self.yyleng as i32);
            // "" - no token (skip)
            if token.len() == 0 {
                return self.get_next_token();
            }
            return self.to_token(token);
        }

        if self.is_eof() {
            self.cursor = self.cursor + 1;
            self.yytext = EOF;
            return self.to_token(EOF);
        }

        self.panic_unexpected_token(
            &str_slice[0..1],
            self.current_line,
            self.current_column
        );

        unreachable!()
    }

    /**
     * Throws default "Unexpected token" exception, showing the actual
     * line from the source, pointing with the ^ marker to the bad token.
     * In addition, shows `line:column` location.
     */
    fn panic_unexpected_token(&self, string: &'static str, line: i32, column: i32) {
        let line_source = self.string
            .split('\n')
            .collect::<Vec<&str>>()
            [(line - 1) as usize];

        let pad = ::std::iter::repeat(" ")
            .take(column as usize)
            .collect::<String>();

        let line_data = format!("\n\n{}\n{}^\n", line_source, pad);

        panic!(
            "{} Unexpected token: \"{}\" at {}:{}.",
            line_data,
            string,
            line,
            column
        );
    }

    fn capture_location(&mut self, matched: &'static str) {
        let nl_re = Regex::new(r"\n").unwrap();

        // Absolute offsets.
        self.token_start_offset = self.cursor;

        // Line-based locations, start.
        self.token_start_line = self.current_line;
        self.token_start_column = self.token_start_offset - self.current_line_begin_offset;

        // Extract `\n` in the matched token.
        for cap in nl_re.captures_iter(matched) {
            self.current_line = self.current_line + 1;
            self.current_line_begin_offset = self.token_start_offset +
                cap.get(0).unwrap().start() as i32 + 1;
        }

        self.token_end_offset = self.cursor + matched.len() as i32;

        // Line-based locations, end.
        self.token_end_line = self.current_line;
        self.token_end_column = self.token_end_offset - self.current_line_begin_offset;
        self.current_column = self.token_end_column;
    }

    fn _match(&mut self, str_slice: &'static str, re: &Regex) -> Option<&'static str> {
        match re.captures(str_slice) {
            Some(caps) => {
                let matched = caps.get(0).unwrap().as_str();
                self.capture_location(matched);
                Some(matched)
            },
            None => None
        }
    }

    fn to_token(&self, token: &'static str) -> Token {
        Token {
            kind: *TOKENS_MAP.get(token).unwrap(),
            value: self.yytext,
            start_offset: self.token_start_offset,
            end_offset: self.token_end_offset,
            start_line: self.token_start_line,
            end_line: self.token_end_line,
            start_column: self.token_start_column,
            end_column: self.token_end_column,
        }
    }

    /**
     * Whether there are still tokens in the stream.
     */
    pub fn has_more_tokens(&mut self) -> bool {
        self.cursor <= self.string.len() as i32
    }

    /**
     * Whether the cursor is at the EOF.
     */
    pub fn is_eof(&mut self) -> bool {
        self.cursor == self.string.len() as i32
    }

    /**
     * Returns current tokenizing state.
     */
    pub fn get_current_state(&mut self) -> &'static str {
        match self.states.last() {
            Some(last) => last,
            None => "INITIAL"
        }
    }

    /**
     * Enters a new state pushing it on the states stack.
     */
    pub fn push_state(&mut self, state: &'static str) -> &mut Tokenizer {
        self.states.push(state);
        self
    }

    /**
     * Alias for `push_state`.
     */
    pub fn begin(&mut self, state: &'static str) -> &mut Tokenizer {
        self.push_state(state);
        self
    }

    /**
     * Exits a current state popping it from the states stack.
     */
    pub fn pop_state(&mut self) -> &'static str {
        match self.states.pop() {
            Some(top) => top,
            None => "INITIAL"
        }
    }

    /**
     * Lex rule handlers.
     */
    {{{LEX_RULE_HANDLERS}}}
}<commit_msg>Update tokenizer.template.rs<commit_after>/**
 * Generic tokenizer used by the parser in the Syntax tool.
 *
 * https://www.npmjs.com/package/syntax-cli
 */

// ------------------------------------------------------------------
// Token.

#[derive(Debug, Clone, Copy)]
struct Token {
    kind: i32,
    value: &'static str,

    start_offset: i32,
    end_offset: i32,
    start_line: i32,
    end_line: i32,
    start_column: i32,
    end_column: i32,
}

// NOTE: LEX_RULES_BY_START_CONDITIONS, and TOKENS_MAP
// are defined in the lazy_static! block in lr.templates.rs

// ------------------------------------------------------------------
// Tokenizer.

lazy_static! {
    /**
     * Pre-parse the regex instead of parsing it every time when calling `get_next_token`.
     */
    static ref REGEX_RULES: Vec<Regex> = LEX_RULES.iter().map(|rule| Regex::new(rule).unwrap()).collect();
}

struct Tokenizer {
    /**
     * Tokenizing string.
     */
    string: &'static str,

    /**
     * Cursor for current symbol.
     */
    cursor: i32,

    /**
     * States.
     */
    states: Vec<&'static str>,

    /**
     * Line-based location tracking.
     */
    current_line: i32,
    current_column: i32,
    current_line_begin_offset: i32,

    /**
     * Location data of a matched token.
     */
    token_start_offset: i32,
    token_end_offset: i32,
    token_start_line: i32,
    token_end_line: i32,
    token_start_column: i32,
    token_end_column: i32,

    /**
     * Matched text, and its length.
     */
    yytext: &'static str,
    yyleng: usize,

    handlers: [fn(&mut Tokenizer) -> &'static str; {{{LEX_RULE_HANDLERS_COUNT}}}],
}

impl Tokenizer {

    /**
     * Creates a new Tokenizer instance.
     *
     * The same instance can be then reused in parser
     * by calling `init_string`.
     */
    pub fn new() -> Tokenizer {
        let mut tokenizer = Tokenizer {
            string: "",
            cursor: 0,

            states: Vec::new(),

            current_line: 1,
            current_column: 0,
            current_line_begin_offset: 0,

            token_start_offset: 0,
            token_end_offset: 0,
            token_start_line: 0,
            token_end_line: 0,
            token_start_column: 0,
            token_end_column: 0,

            yytext: "",
            yyleng: 0,

            handlers: {{{LEX_RULE_HANDLERS_ARRAY}}}
        };

        tokenizer
    }

    /**
     * Initializes a parsing string.
     */
    pub fn init_string(&mut self, string: &'static str) -> &mut Tokenizer {
        self.string = string;

        // Initialize states.
        self.states.clear();
        self.states.push("INITIAL");

        self.cursor = 0;
        self.current_line = 1;
        self.current_column = 0;
        self.current_line_begin_offset = 0;

        self.token_start_offset = 0;
        self.token_end_offset = 0;
        self.token_start_line = 0;
        self.token_end_line = 0;
        self.token_start_column = 0;
        self.token_end_column = 0;

        self
    }

    /**
     * Returns next token.
     */
    pub fn get_next_token(&mut self) -> Token {
        if !self.has_more_tokens() {
            self.yytext = EOF;
            return self.to_token(EOF)
        }

        let str_slice = &self.string[self.cursor as usize..];

        let lex_rules_for_state = LEX_RULES_BY_START_CONDITIONS
            .get(self.get_current_state())
            .unwrap();

        let mut max_match_len = 0;
        let mut max_match_token: Option<&'static str> = None;

        for i in lex_rules_for_state {
            let i = *i as usize;

            if let Some(matched) = self._match(str_slice, &REGEX_RULES[i]) {

                // Manual handling of EOF token (the end of string). Return it
                // as `EOF` symbol.
                if matched.len() == 0 {
                    self.cursor = self.cursor + 1;
                }

                self.yytext = matched;
                self.yyleng = matched.len();

                let token_type = self.handlers[i](self);

                // "" - no token (skip)
                if token_type.len() == 0 {
                    return self.get_next_token();
                }

                return self.to_token(token_type)
            }
        }

        if self.is_eof() {
            self.cursor = self.cursor + 1;
            self.yytext = EOF;
            return self.to_token(EOF);
        }

        self.panic_unexpected_token(
            &str_slice[0..1],
            self.current_line,
            self.current_column
        );

        unreachable!()
    }

    /**
     * Throws default "Unexpected token" exception, showing the actual
     * line from the source, pointing with the ^ marker to the bad token.
     * In addition, shows `line:column` location.
     */
    fn panic_unexpected_token(&self, string: &'static str, line: i32, column: i32) {
        let line_source = self.string
            .split('\n')
            .collect::<Vec<&str>>()
            [(line - 1) as usize];

        let pad = ::std::iter::repeat(" ")
            .take(column as usize)
            .collect::<String>();

        let line_data = format!("\n\n{}\n{}^\n", line_source, pad);

        panic!(
            "{} Unexpected token: \"{}\" at {}:{}.",
            line_data,
            string,
            line,
            column
        );
    }

    fn capture_location(&mut self, matched: &'static str) {
        let nl_re = Regex::new(r"\n").unwrap();

        // Absolute offsets.
        self.token_start_offset = self.cursor;

        // Line-based locations, start.
        self.token_start_line = self.current_line;
        self.token_start_column = self.token_start_offset - self.current_line_begin_offset;

        // Extract `\n` in the matched token.
        for cap in nl_re.captures_iter(matched) {
            self.current_line = self.current_line + 1;
            self.current_line_begin_offset = self.token_start_offset +
                cap.get(0).unwrap().start() as i32 + 1;
        }

        self.token_end_offset = self.cursor + matched.len() as i32;

        // Line-based locations, end.
        self.token_end_line = self.current_line;
        self.token_end_column = self.token_end_offset - self.current_line_begin_offset;
        self.current_column = self.token_end_column;
    }

    fn _match(&mut self, str_slice: &'static str, re: &Regex) -> Option<&'static str> {
        match re.captures(str_slice) {
            Some(caps) => {
                let matched = caps.get(0).unwrap().as_str();
                self.capture_location(matched);
                self.cursor = self.cursor + (matched.len() as i32);
                Some(matched)
            },
            None => None
        }
    }

    fn to_token(&self, token: &'static str) -> Token {
        Token {
            kind: *TOKENS_MAP.get(token).unwrap(),
            value: self.yytext,
            start_offset: self.token_start_offset,
            end_offset: self.token_end_offset,
            start_line: self.token_start_line,
            end_line: self.token_end_line,
            start_column: self.token_start_column,
            end_column: self.token_end_column,
        }
    }

    /**
     * Whether there are still tokens in the stream.
     */
    pub fn has_more_tokens(&mut self) -> bool {
        self.cursor <= self.string.len() as i32
    }

    /**
     * Whether the cursor is at the EOF.
     */
    pub fn is_eof(&mut self) -> bool {
        self.cursor == self.string.len() as i32
    }

    /**
     * Returns current tokenizing state.
     */
    pub fn get_current_state(&mut self) -> &'static str {
        match self.states.last() {
            Some(last) => last,
            None => "INITIAL"
        }
    }

    /**
     * Enters a new state pushing it on the states stack.
     */
    pub fn push_state(&mut self, state: &'static str) -> &mut Tokenizer {
        self.states.push(state);
        self
    }

    /**
     * Alias for `push_state`.
     */
    pub fn begin(&mut self, state: &'static str) -> &mut Tokenizer {
        self.push_state(state);
        self
    }

    /**
     * Exits a current state popping it from the states stack.
     */
    pub fn pop_state(&mut self) -> &'static str {
        match self.states.pop() {
            Some(top) => top,
            None => "INITIAL"
        }
    }

    /**
     * Lex rule handlers.
     */
    {{{LEX_RULE_HANDLERS}}}
}
<|endoftext|>


<commit_before><commit_msg>Update compiler.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Add documentation examples for parallel iterator methods Closes #420<commit_after><|endoftext|>


<commit_before><commit_msg>Removed excess lock<commit_after><|endoftext|>


<commit_before>#![feature(test)]
#[cfg(test)]

extern crate jmespath;
extern crate test;
extern crate rustc_serialize;

use rustc_serialize::json::Json;
use test::Bencher;

#[bench]
fn bench_parsing_foo_bar_baz(b: &mut Bencher) {
    b.iter(|| jmespath::Expression::new("foo.bar.baz"));
}

#[bench]
fn bench_lexing_foo_bar_baz(b: &mut Bencher) {
    b.iter(|| for _ in jmespath::tokenize("foo.bar.baz") {});
}

#[bench]
fn bench_full_foo_bar_baz(b: &mut Bencher) {
    let json = Json::from_str("{\"foo\":{\"bar\":{\"baz\":true}}}").unwrap();
    b.iter(|| {
        let expr = jmespath::Expression::new("foo.bar.baz").unwrap();
        expr.search(json.clone()).unwrap();
    });
}

#[bench]
fn bench_full_or_branches(b: &mut Bencher) {
    let json = Json::from_str("{\"foo\":true}").unwrap();
    b.iter(|| {
        let expr = jmespath::Expression::new("bar || baz || bam || foo").unwrap();
        expr.search(json.clone()).unwrap();
    });
}

#[bench]
fn bench_deep_projection_104(b: &mut Bencher) {
    let deep = "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[*].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[*].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[*].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[*]";
    b.iter(|| jmespath::parse(deep));
}
<commit_msg>Fixing benches<commit_after>#![feature(test)]
#[cfg(test)]

extern crate jmespath;
extern crate test;
extern crate rustc_serialize;

use rustc_serialize::json::Json;
use test::Bencher;

#[bench]
fn bench_parsing_foo_bar_baz(b: &mut Bencher) {
    b.iter(|| jmespath::Expression::new("foo.bar.baz"));
}

#[bench]
fn bench_lexing_foo_bar_baz(b: &mut Bencher) {
    b.iter(|| for _ in jmespath::tokenize("foo.bar.baz") {});
}

#[bench]
fn bench_full_foo_bar_baz(b: &mut Bencher) {
    let json = Json::from_str("{\"foo\":{\"bar\":{\"baz\":true}}}").unwrap();
    b.iter(|| {
        let expr = jmespath::Expression::new("foo.bar.baz").unwrap();
        expr.search(json.clone()).unwrap();
    });
}

#[bench]
fn bench_full_or_branches(b: &mut Bencher) {
    let json = Json::from_str("{\"foo\":true}").unwrap();
    b.iter(|| {
        let expr = jmespath::Expression::new("bar || baz || bam || foo").unwrap();
        expr.search(json.clone()).unwrap();
    });
}

#[bench]
fn bench_expr_identifier(b: &mut Bencher) {
    let expr = "abcdefghijklmnopqrstuvwxyz";
    b.iter(|| jmespath::parse(expr));
}

#[bench]
fn bench_expr_subexpr(b: &mut Bencher) {
    let expr = "abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz";
    b.iter(|| jmespath::parse(expr));
}
<|endoftext|>


<commit_before>use std::collections::{HashMap, HashSet};
use std::hash::Hash;
use std::borrow::Borrow;

/// An associative map data structure for representing scopes.
///
/// A `ForkTable` functions similarly to a standard associative map
/// data structure (such as a `HashMap`), but with the ability to
/// fork children off of each level of the map. If a key exists in any
/// of a child's parents, the child will 'pass through' that key. If a
/// new value is bound to a key in a child level, that child will overwrite
/// the previous entry with the new one, but the previous `key` -> `value`
/// mapping will remain in the level it is defined. This means that the parent
/// level will still provide the previous value for that key.
///
/// This is an implementation of the ForkTable data structure for
/// representing scopes. The ForkTable was initially described by
/// Max Clive. This implemention is based primarily by the Scala
/// reference implementation written by Hawk Weisman for the Decaf
/// compiler, which is available [here](https://github.com/hawkw/decaf/blob/master/src/main/scala/com/meteorcode/common/ForkTable.scala).
#[derive(Debug)]
pub struct ForkTable<'a, K:'a +  Eq + Hash,V: 'a>  {
    table: HashMap<K, V>,
    whiteouts: HashSet<K>,
    parent: Option<&'a mut ForkTable<'a, K,V>>
}

impl<'a, K,V> ForkTable<'a, K, V> where K: Eq + Hash {

    /// Returns a reference to the value corresponding to the key.
    ///
    /// If the key is defined in this level of the table, or in any
    /// of its' parents, a reference to the associated value will be
    /// returned.
    ///
    /// The key may be any borrowed form of the map's key type, but
    /// `Hash` and `Eq` on the borrowed form *must* match those for
    /// the key type.
    ///
    pub fn get<Q: ?Sized>(&'a self, key: &Q) -> Option<&'a V>
        where K: Borrow<Q>, Q: Hash + Eq {
        if self.whiteouts.contains(key) {
            None
        } else {
            self.table
                .get(key)
                .or(match self.parent {
                        Some(ref parent) => parent.get(key),
                        None => None
                    })
        }
    }

    /// Returns a mutable reference to the value corresponding to the key.
    ///
    /// If the key is defined in this level of the table, or in any
    /// of its' parents, a reference to the associated value will be
    /// returned.
    ///
    /// The key may be any borrowed form of the map's key type, but
    /// `Hash` and `Eq` on the borrowed form *must* match those for
    /// the key type.
    ///
   pub fn get_mut<Q: ?Sized>(&'a mut self, key: &Q) -> Option<&mut V>
        where K: Borrow<Q>, Q: Hash + Eq {
        if self.whiteouts.contains(key) {
            None
        } else {
            self.table
                .get_mut(key)
                .or(match self.parent {
                        Some(ref mut parent) => parent.get_mut(key),
                        None => None
                    })
        }
    }

    /// Removes a key from the map, returning the value at the key if
    /// the key was previously in the map.
    ///
    /// If the removed value exists in a lower level of the table,
    /// it will be whited out at this level. This means that the entry
    /// will be 'removed' at this level and this table will not provide
    /// access to it, but the mapping will still exist in the level where
    /// it was defined.
    ///
    /// The key may be any borrowed form of the map's key type, but
    /// `Hash` and `Eq` on the borrowed form *must* match those for
    /// the key type.
    ///
    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
        where K: Borrow<Q>, Q: Hash + Eq {
            unimplemented!()
    }

    /// Inserts a key-value pair from the map.
    ///
    /// If the key already had a value present in the map, that
    /// value is returned. Otherwise, `None` is returned.
    ///
    /// If the key is currently whited out (i.e. it was defined
    /// in a lower level of the map and was removed) then it will
    /// be un-whited out and added at this level.
    ///
    /// # Arguments
    ///
    ///  + `k`  - the key
    ///  + `v`  - the value
    ///
    /// # Examples
    ///
    /// Simply inserting an entry:
    ///
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut table: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.get(&1isize), None);
    /// assert_eq!(table.insert(1isize, "One"), None);
    /// assert_eq!(table.get(&1isize), Some("One"));
    /// ```
    ///
    /// Overwriting the value associated with a key:
    ///
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut table: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.get(&1isize), None);
    /// assert_eq!(table.insert(1isize, "two"), None);
    /// assert_eq!(table.get(&1isize), Some("two"));
    ///
    /// assert_eq!(table.insert(2isize, "Two"), Some("two"));
    /// ssert_eq!(table.get(&2isize), Some("Two"));
    /// ```
    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
        if self.whiteouts.contains(&k) { self.whiteouts.remove(&k); };
        self.table.insert(k, v)
    }

    /// Returns true if this level contains a value for the specified key.
    ///
    /// The key may be any borrowed form of the map's key type, but
    /// `Hash` and `Eq` on the borrowed form *must* match those for
    /// the key type.
    ///
    /// # Examples
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut table: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.contains_key(&1isize), false);
    /// table.insert(1isize, "One");
    /// assert_eq!(table.contains_key(&1isize), true);
    /// ```
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut level_1: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.contains_key(&1isize), false);
    /// table.insert(1isize, "One");
    /// assert_eq!(level_1.contains_key(&1isize), true);
    ///
    /// let mut level_2: ForkTable<isize,String> = level_1.fork();
    /// assert_eq!(level_2.contains_key(&1isize), false);
    pub fn contains_key(&self, key: &K) -> bool  {
        self.table.contains_key(key)
    }

    /// Returns true if the key is defined in this level of the table, or
    /// in any of its' parents and is not whited out.
    ///
    /// The key may be any borrowed form of the map's key type, but
    /// `Hash` and `Eq` on the borrowed form *must* match those for
    /// the key type.
    ///
    /// # Examples
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut table: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.chain_contains_key(&1isize), false);
    /// table.insert(1isize, "One");
    /// assert_eq!(table.chain_contains_key(&1isize), true);
    /// ```
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut level_1: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.chain_contains_key(&1isize), false);
    /// table.insert(1isize, "One");
    /// assert_eq!(level_1.chain_contains_key(&1isize), true);
    ///
    /// let mut level_2: ForkTable<isize,String> = level_1.fork();
    /// assert_eq!(level_2.chain_contains_key(&1isize), true);
    /// ```
    pub fn chain_contains_key(&self, key: &K) -> bool {
        self.table.contains_key(key) ||
        (self.whiteouts.contains(key) &&
            match self.parent {
                Some(ref p) => p.chain_contains_key(key),
                None            => false
            })
    }

    /// Forks this table, returning a new `ForkTable<K,V>`.
    ///
    /// This level of the table will be set as the child's
    /// parent. The child will be created with an empty backing
    /// `HashMap` and no keys whited out.
    pub fn fork(&'a mut self) -> ForkTable<'a, K,V> {
        ForkTable {
            table: HashMap::new(),
            whiteouts: HashSet::new(),
            parent: Some(self)
        }
    }

    /// Constructs a new `ForkTable<K,V>`
    pub fn new() -> ForkTable<'a, K,V> {
        ForkTable {
            table: HashMap::new(),
            whiteouts: HashSet::new(),
            parent: None
        }
    }
}<commit_msg>Fix ForkTable doctests<commit_after>use std::collections::{HashMap, HashSet};
use std::hash::Hash;
use std::borrow::Borrow;

/// An associative map data structure for representing scopes.
///
/// A `ForkTable` functions similarly to a standard associative map
/// data structure (such as a `HashMap`), but with the ability to
/// fork children off of each level of the map. If a key exists in any
/// of a child's parents, the child will 'pass through' that key. If a
/// new value is bound to a key in a child level, that child will overwrite
/// the previous entry with the new one, but the previous `key` -> `value`
/// mapping will remain in the level it is defined. This means that the parent
/// level will still provide the previous value for that key.
///
/// This is an implementation of the ForkTable data structure for
/// representing scopes. The ForkTable was initially described by
/// Max Clive. This implemention is based primarily by the Scala
/// reference implementation written by Hawk Weisman for the Decaf
/// compiler, which is available [here](https://github.com/hawkw/decaf/blob/master/src/main/scala/com/meteorcode/common/ForkTable.scala).
#[derive(Debug)]
pub struct ForkTable<'a, K:'a +  Eq + Hash,V: 'a>  {
    table: HashMap<K, V>,
    whiteouts: HashSet<K>,
    parent: Option<&'a mut ForkTable<'a, K,V>>
}

impl<'a, K,V> ForkTable<'a, K, V> where K: Eq + Hash {

    /// Returns a reference to the value corresponding to the key.
    ///
    /// If the key is defined in this level of the table, or in any
    /// of its' parents, a reference to the associated value will be
    /// returned.
    ///
    /// The key may be any borrowed form of the map's key type, but
    /// `Hash` and `Eq` on the borrowed form *must* match those for
    /// the key type.
    ///
    pub fn get<Q: ?Sized>(&'a self, key: &Q) -> Option<&'a V>
        where K: Borrow<Q>, Q: Hash + Eq {
        if self.whiteouts.contains(key) {
            None
        } else {
            self.table
                .get(key)
                .or(match self.parent {
                        Some(ref parent) => parent.get(key),
                        None => None
                    })
        }
    }

    /// Returns a mutable reference to the value corresponding to the key.
    ///
    /// If the key is defined in this level of the table, or in any
    /// of its' parents, a reference to the associated value will be
    /// returned.
    ///
    /// The key may be any borrowed form of the map's key type, but
    /// `Hash` and `Eq` on the borrowed form *must* match those for
    /// the key type.
    ///
   pub fn get_mut<Q: ?Sized>(&'a mut self, key: &Q) -> Option<&mut V>
        where K: Borrow<Q>, Q: Hash + Eq {
        if self.whiteouts.contains(key) {
            None
        } else {
            self.table
                .get_mut(key)
                .or(match self.parent {
                        Some(ref mut parent) => parent.get_mut(key),
                        None => None
                    })
        }
    }

    /// Removes a key from the map, returning the value at the key if
    /// the key was previously in the map.
    ///
    /// If the removed value exists in a lower level of the table,
    /// it will be whited out at this level. This means that the entry
    /// will be 'removed' at this level and this table will not provide
    /// access to it, but the mapping will still exist in the level where
    /// it was defined.
    ///
    /// The key may be any borrowed form of the map's key type, but
    /// `Hash` and `Eq` on the borrowed form *must* match those for
    /// the key type.
    ///
    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
        where K: Borrow<Q>, Q: Hash + Eq {
            unimplemented!()
    }

    /// Inserts a key-value pair from the map.
    ///
    /// If the key already had a value present in the map, that
    /// value is returned. Otherwise, `None` is returned.
    ///
    /// If the key is currently whited out (i.e. it was defined
    /// in a lower level of the map and was removed) then it will
    /// be un-whited out and added at this level.
    ///
    /// # Arguments
    ///
    ///  + `k`  - the key
    ///  + `v`  - the value
    ///
    /// # Examples
    ///
    /// Simply inserting an entry:
    ///
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut table: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.get(&1isize), None);
    /// assert_eq!(table.insert(1isize, "One"), None);
    /// assert_eq!(table.get(&1isize), Some(&"One"));
    /// ```
    ///
    /// Overwriting the value associated with a key:
    ///
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut table: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.get(&1isize), None);
    /// assert_eq!(table.insert(1isize, "two"), None);
    /// assert_eq!(table.get(&1isize), Some("two"));
    ///
    /// assert_eq!(table.insert(2isize, "Two"), Some("two"));
    /// assert_eq!(table.get(&2isize), Some(&"Two"));
    /// ```
    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
        if self.whiteouts.contains(&k) { self.whiteouts.remove(&k); };
        self.table.insert(k, v)
    }

    /// Returns true if this level contains a value for the specified key.
    ///
    /// The key may be any borrowed form of the map's key type, but
    /// `Hash` and `Eq` on the borrowed form *must* match those for
    /// the key type.
    ///
    /// # Examples
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut table: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.contains_key(&1isize), false);
    /// table.insert(1isize, "One");
    /// assert_eq!(table.contains_key(&1isize), true);
    /// ```
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut level_1: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.contains_key(&1isize), false);
    /// table.insert(1isize, "One");
    /// assert_eq!(level_1.contains_key(&1isize), true);
    ///
    /// let mut level_2: ForkTable<isize,String> = level_1.fork();
    /// assert_eq!(level_2.contains_key(&1isize), false);
    pub fn contains_key(&self, key: &K) -> bool  {
        self.table.contains_key(key)
    }

    /// Returns true if the key is defined in this level of the table, or
    /// in any of its' parents and is not whited out.
    ///
    /// The key may be any borrowed form of the map's key type, but
    /// `Hash` and `Eq` on the borrowed form *must* match those for
    /// the key type.
    ///
    /// # Examples
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut table: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(table.chain_contains_key(&1isize), false);
    /// table.insert(1isize, "One");
    /// assert_eq!(table.chain_contains_key(&1isize), true);
    /// ```
    /// ```
    /// # use seax_scheme::ForkTable;
    /// let mut level_1: ForkTable<isize,&str> = ForkTable::new();
    /// assert_eq!(level_1.chain_contains_key(&1isize), false);
    /// table.insert(1isize, "One");
    /// assert_eq!(level_1.chain_contains_key(&1isize), true);
    ///
    /// let mut level_2: ForkTable<isize,String> = level_1.fork();
    /// assert_eq!(level_2.chain_contains_key(&1isize), true);
    /// ```
    pub fn chain_contains_key(&self, key: &K) -> bool {
        self.table.contains_key(key) ||
        (self.whiteouts.contains(key) &&
            match self.parent {
                Some(ref p) => p.chain_contains_key(key),
                None            => false
            })
    }

    /// Forks this table, returning a new `ForkTable<K,V>`.
    ///
    /// This level of the table will be set as the child's
    /// parent. The child will be created with an empty backing
    /// `HashMap` and no keys whited out.
    pub fn fork(&'a mut self) -> ForkTable<'a, K,V> {
        ForkTable {
            table: HashMap::new(),
            whiteouts: HashSet::new(),
            parent: Some(self)
        }
    }

    /// Constructs a new `ForkTable<K,V>`
    pub fn new() -> ForkTable<'a, K,V> {
        ForkTable {
            table: HashMap::new(),
            whiteouts: HashSet::new(),
            parent: None
        }
    }
}<|endoftext|>


<commit_before>extern crate teleborg;
extern crate reqwest;

#[cfg(test)]
mod tests {
    use teleborg::{Bot, ParseMode, ChatAction};
    use teleborg::objects::{Button, Markup, Contact};
    use reqwest::Client;

    use std::env;

    const BASE_URL: &'static str = "https://api.telegram.org/bot";

    fn setup() -> (String, i64) {
        let token = env::var("TELEGRAM_BOT_TOKEN")
            .ok()
            .expect("Can't find TELEGRAM_BOT_TOKEN env variable");
        let chat_id = env::var("TELEGRAM_CHAT_ID")
            .ok()
            .expect("Can't find TELEGRAM_CHAT_ID env variable")
            .parse::<i64>()
            .unwrap();
        (token, chat_id)
    }

    #[test]
    fn test_send_contact() {
        let (token, chat_id) = setup();
        let bot_url = [BASE_URL, &token].concat();
        let bot = Bot::new(bot_url).unwrap();

        let contact = Contact::new("0612345678".to_string(), "Voider".to_string(), Some("1".to_string()), Some(666));
        let message = bot.send_contact(&chat_id, &contact, None, None, None);
        println!("{:?}", &message);
        assert!(message.is_ok());
    }
}<commit_msg>removed Markup and Button imports<commit_after>extern crate teleborg;
extern crate reqwest;

#[cfg(test)]
mod tests {
    use teleborg::{Bot, ParseMode, ChatAction};
    use teleborg::objects::{Contact};
    use reqwest::Client;

    use std::env;

    const BASE_URL: &'static str = "https://api.telegram.org/bot";

    fn setup() -> (String, i64) {
        let token = env::var("TELEGRAM_BOT_TOKEN")
            .ok()
            .expect("Can't find TELEGRAM_BOT_TOKEN env variable");
        let chat_id = env::var("TELEGRAM_CHAT_ID")
            .ok()
            .expect("Can't find TELEGRAM_CHAT_ID env variable")
            .parse::<i64>()
            .unwrap();
        (token, chat_id)
    }

    #[test]
    fn test_send_contact() {
        let (token, chat_id) = setup();
        let bot_url = [BASE_URL, &token].concat();
        let bot = Bot::new(bot_url).unwrap();

        let contact = Contact::new("0612345678".to_string(), "Voider".to_string(), Some("1".to_string()), Some(666));
        let message = bot.send_contact(&chat_id, &contact, None, None, None);
        println!("{:?}", &message);
        assert!(message.is_ok());
    }
}<|endoftext|>


<commit_before><commit_msg>*Request fields are now public<commit_after><|endoftext|>


<commit_before>pub use telegram_bot_raw::{GetFile, GetMe, GetUpdates,  GetUserProfilePhotos, ForwardMessage};
pub use telegram_bot_raw::{SendLocation, SendMessage, SendContact, SendVenue};
pub use telegram_bot_raw::{GetChat, LeaveChat};
pub use telegram_bot_raw::SendChatAction;
pub use telegram_bot_raw::{GetChatAdministrators, GetChatMember, GetChatMembersCount};
pub use telegram_bot_raw::{KickChatMember, UnbanChatMember};
pub use telegram_bot_raw::{EditMessageText, EditMessageCaption, EditMessageReplyMarkup};
<commit_msg>typo: remove space<commit_after>pub use telegram_bot_raw::{GetFile, GetMe, GetUpdates, GetUserProfilePhotos, ForwardMessage};
pub use telegram_bot_raw::{SendLocation, SendMessage, SendContact, SendVenue};
pub use telegram_bot_raw::{GetChat, LeaveChat};
pub use telegram_bot_raw::SendChatAction;
pub use telegram_bot_raw::{GetChatAdministrators, GetChatMember, GetChatMembersCount};
pub use telegram_bot_raw::{KickChatMember, UnbanChatMember};
pub use telegram_bot_raw::{EditMessageText, EditMessageCaption, EditMessageReplyMarkup};
<|endoftext|>


<commit_before>//! OS-specific functionality.

#![stable(feature = "os", since = "1.0.0")]
#![allow(missing_docs, nonstandard_style, missing_debug_implementations)]

cfg_if::cfg_if! {
    if #[cfg(doc)] {

        // When documenting libstd we want to show unix/windows/linux modules as
        // these are the "main modules" that are used across platforms. This
        // should help show platform-specific functionality in a hopefully
        // cross-platform way in the documentation

        #[stable(feature = "rust1", since = "1.0.0")]
        pub use crate::sys::unix_ext as unix;

        #[stable(feature = "rust1", since = "1.0.0")]
        pub use crate::sys::windows_ext as windows;

        #[doc(cfg(target_os = "linux"))]
        pub mod linux;
    } else {

        // If we're not documenting libstd then we just expose the main modules
        // as we otherwise would.

        #[cfg(any(target_os = "redox", unix, target_os = "vxworks", target_os = "hermit"))]
        #[stable(feature = "rust1", since = "1.0.0")]
        pub use crate::sys::ext as unix;

        #[cfg(windows)]
        #[stable(feature = "rust1", since = "1.0.0")]
        pub use crate::sys::ext as windows;

        #[cfg(any(target_os = "linux", target_os = "l4re"))]
        pub mod linux;

    }
}

#[cfg(target_os = "android")]
pub mod android;
#[cfg(target_os = "dragonfly")]
pub mod dragonfly;
#[cfg(target_os = "emscripten")]
pub mod emscripten;
#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
pub mod fortanix_sgx;
#[cfg(target_os = "freebsd")]
pub mod freebsd;
#[cfg(target_os = "fuchsia")]
pub mod fuchsia;
#[cfg(target_os = "haiku")]
pub mod haiku;
#[cfg(target_os = "illumos")]
pub mod illumos;
#[cfg(target_os = "ios")]
pub mod ios;
#[cfg(target_os = "macos")]
pub mod macos;
#[cfg(target_os = "netbsd")]
pub mod netbsd;
#[cfg(target_os = "openbsd")]
pub mod openbsd;
#[cfg(target_os = "redox")]
pub mod redox;
#[cfg(target_os = "solaris")]
pub mod solaris;
#[cfg(target_os = "vxworks")]
pub mod vxworks;
#[cfg(target_os = "wasi")]
pub mod wasi;

pub mod raw;
<commit_msg>Avoid `cfg_if` in `std::os`<commit_after>//! OS-specific functionality.

#![stable(feature = "os", since = "1.0.0")]
#![allow(missing_docs, nonstandard_style, missing_debug_implementations)]

// When documenting libstd we want to show unix/windows/linux modules as these are the "main
// modules" that are used across platforms, so all modules are enabled when `cfg(doc)` is set.
// This should help show platform-specific functionality in a hopefully cross-platform way in the
// documentation.
// Note that we deliberately avoid `cfg_if!` here to work around a rust-analyzer bug that would make
// `std::os` submodules unusable: https://github.com/rust-analyzer/rust-analyzer/issues/6038

#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
pub use crate::sys::unix_ext as unix;

#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
pub use crate::sys::windows_ext as windows;

#[cfg(doc)]
#[doc(cfg(target_os = "linux"))]
pub mod linux;

// If we're not documenting libstd then we just expose the main modules as we otherwise would.

#[cfg(not(doc))]
#[cfg(any(target_os = "redox", unix, target_os = "vxworks", target_os = "hermit"))]
#[stable(feature = "rust1", since = "1.0.0")]
pub use crate::sys::ext as unix;

#[cfg(not(doc))]
#[cfg(windows)]
#[stable(feature = "rust1", since = "1.0.0")]
pub use crate::sys::ext as windows;

#[cfg(not(doc))]
#[cfg(any(target_os = "linux", target_os = "l4re"))]
pub mod linux;

#[cfg(target_os = "android")]
pub mod android;
#[cfg(target_os = "dragonfly")]
pub mod dragonfly;
#[cfg(target_os = "emscripten")]
pub mod emscripten;
#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
pub mod fortanix_sgx;
#[cfg(target_os = "freebsd")]
pub mod freebsd;
#[cfg(target_os = "fuchsia")]
pub mod fuchsia;
#[cfg(target_os = "haiku")]
pub mod haiku;
#[cfg(target_os = "illumos")]
pub mod illumos;
#[cfg(target_os = "ios")]
pub mod ios;
#[cfg(target_os = "macos")]
pub mod macos;
#[cfg(target_os = "netbsd")]
pub mod netbsd;
#[cfg(target_os = "openbsd")]
pub mod openbsd;
#[cfg(target_os = "redox")]
pub mod redox;
#[cfg(target_os = "solaris")]
pub mod solaris;
#[cfg(target_os = "vxworks")]
pub mod vxworks;
#[cfg(target_os = "wasi")]
pub mod wasi;

pub mod raw;
<|endoftext|>


<commit_before>//! This module pre-selects commenly used OrbTk crates and put them into scope.

// std
pub use std::rc::Rc;

// crates modules
pub use crate::application::*;
pub use crate::event::*;
pub use crate::layout::*;
pub use crate::localization::*;
pub use crate::macros::*;
pub use crate::properties::*;
pub use crate::render_object::*;
pub use crate::services::*;
pub use crate::systems::*;
pub use crate::theming::*;
pub use crate::tree::*;
pub use crate::widget_base::*;

pub use crate::{into_property_source, trigger_event, widget};
<commit_msg>orbtk_core: update lib documentation<commit_after>//! This module pre-selects commonly used OrbTk crates and put them into scope.

// std
pub use std::rc::Rc;

// crates modules
pub use crate::application::*;
pub use crate::event::*;
pub use crate::layout::*;
pub use crate::localization::*;
pub use crate::macros::*;
pub use crate::properties::*;
pub use crate::render_object::*;
pub use crate::services::*;
pub use crate::systems::*;
pub use crate::theming::*;
pub use crate::tree::*;
pub use crate::widget_base::*;

pub use crate::{into_property_source, trigger_event, widget};
<|endoftext|>


<commit_before>use log::{LevelFilter, Log, Metadata, Record};

struct Logger {
    pub filter: Option<String>,
}

impl Log for Logger {
    fn enabled(&self, _: &Metadata) -> bool {
        true
    }

    fn log(&self, record: &Record) {
        eprintln!(
            "[{}] {}",
            record
                .module_path()
                .unwrap_or_default()
                .trim_start_matches("rust_tree_sitter_cli::"),
            record.args()
        );
    }

    fn flush(&self) {}
}

pub fn init() {
    log::set_boxed_logger(Box::new(Logger { filter: None })).unwrap();
    log::set_max_level(LevelFilter::Info);
}
<commit_msg>fix(cli): allow dead code in Logger<commit_after>use log::{LevelFilter, Log, Metadata, Record};

#[allow(dead_code)]
struct Logger {
    pub filter: Option<String>,
}

impl Log for Logger {
    fn enabled(&self, _: &Metadata) -> bool {
        true
    }

    fn log(&self, record: &Record) {
        eprintln!(
            "[{}] {}",
            record
                .module_path()
                .unwrap_or_default()
                .trim_start_matches("rust_tree_sitter_cli::"),
            record.args()
        );
    }

    fn flush(&self) {}
}

pub fn init() {
    log::set_boxed_logger(Box::new(Logger { filter: None })).unwrap();
    log::set_max_level(LevelFilter::Info);
}
<|endoftext|>


<commit_before>//! GPU-visible memory allocation and management.
//!
//! When you create a buffer or a texture with Vulkan, you have to bind it to a chunk of allocated
//! memory. To do so, you have to pass a type that implements the `MemorySource` trait.
//!
//! There are several implementations of the trait, ie. several things that you can pass to the
//! constructors of buffers and textures:
//!
//! - `&Arc<Device>`, which will simply allocate a new chunk of memory every time (easy but not
//!   very efficient).
//! - `MemorySource`, which is the same as `&Arc<Device>` except that it will use the
//!   already-allocated block.
//! - ... needs more ...
//!
//! # Synchronization
//!
//! In Vulkan, it's the job of the programmer to enforce memory safety. In other words, the
//! programmer must take care that two chunks of memory are not read and written simultaneously.
//!
//! In this library, this is enforced by the implementation of `MemorySource` or
//! `MemorySourceChunk`.
//!
//! There are two mechanisms in Vulkan that can provide synchronization: fences and semaphores.
//! Fences provide synchronization between the CPU and the GPU, and semaphores provide
//! synchronization between multiple queues of the GPU. See the `sync` module for more info.
//!
//! # Sparse resources
//!
//! **Not yet implemented**.
//!
//! Instead of creating a buffer or an image with a single chunk of memory, you also have the
//! possibility to create resources with *sparse memory*.
//!
//! For example you can bind the first half of the buffer to a memory chunk, and the second half of
//! the buffer to another memory chunk.
//!
//! There is a hierarchy of three features related to sparse resources:
//!
//!  - The `sparseBinding` feature allows you to use sparse resources.
//!  - The `sparseResidency` feature is a superset of `sparseBinding` and allows you to leave some
//!    parts of the resource unbinded before using it.
//!  - The `sparseResidencyAliased` feature is a superset of `sparseResidency` and allows you to
//!    bind the same memory chunk to multiple different resources at once.
//!
use std::mem;
use std::os::raw::c_void;
use std::slice;
use std::sync::Arc;

use sync::Fence;
use sync::Semaphore;

use device::Device;
use device::Queue;

use OomError;

pub use self::device_memory::DeviceMemory;
pub use self::device_memory::MappedDeviceMemory;
pub use self::single::DeviceLocal;
pub use self::single::DeviceLocalChunk;
pub use self::single::HostVisible;
pub use self::single::HostVisibleChunk;

mod device_memory;
mod single;

/// Trait for memory objects that can be accessed from the CPU.
pub unsafe trait CpuAccessible<'a, T: ?Sized> {
    type Read;

    /// Gives a read access to the content of the buffer.
    ///
    /// If the buffer is in use by the GPU, blocks until it is available.
    // TODO: what happens if timeout is reached? a panic?
    fn read(&'a self, timeout_ns: u64) -> Self::Read;

    /// Tries to give a read access to the content of the buffer.
    ///
    /// If the buffer is in use by the GPU, returns `None`.
    fn try_read(&'a self) -> Option<Self::Read>;
}

/// Trait for memory objects that be mutably accessed from the CPU.
pub unsafe trait CpuWriteAccessible<'a, T: ?Sized>: CpuAccessible<'a, T> {
    type Write;

    /// Gives a write access to the content of the buffer.
    ///
    /// If the buffer is in use by the GPU, blocks until it is available.
    // TODO: what happens if timeout is reached? a panic?
    fn write(&'a self, timeout_ns: u64) -> Self::Write;

    /// Tries to give a write access to the content of the buffer.
    ///
    /// If the buffer is in use by the GPU, returns `None`.
    fn try_write(&'a self) -> Option<Self::Write>;
}

/// Trait for objects that can be used to fill the memory requirements of a buffer or an image.
pub unsafe trait MemorySource {
    /// An object that represents one block of allocation. Returned by `allocate`.
    type Chunk: MemorySourceChunk;

    /// Returns true if the chunks allocated by this source will use sparse memory.
    // TODO: should return the level of the required sparse feature
    fn is_sparse(&self) -> bool;

    /// Allocates a block of memory to be used.
    ///
    /// `memory_type_bits` is a bitsfield which indicates from which memory type the memory can
    /// be allocated. For example if the bit 2 is set (`memory_type_bits & (1 << 2) != 0`), that
    /// means that the memory type whose ID is 2 can be used.
    ///
    /// The implementation is allowed to return a chunk with a larger size or alignment.
    fn allocate(self, &Arc<Device>, size: usize, alignment: usize, memory_type_bits: u32)
                -> Result<Self::Chunk, OomError>;
}

/// A chunk of GPU-visible memory.
pub unsafe trait MemorySourceChunk {
    /// Returns the properties of this chunk.
    fn properties(&self) -> ChunkProperties;

    /// Returns true if the `gpu_access` function should be passed a fence.
    #[inline]
    fn requires_fence(&self) -> bool {
        true
    }

    /// Returns true if the `gpu_access` function should be passed a semaphore.
    #[inline]
    fn requires_semaphore(&self) -> bool {
        true
    }

    /// Instructs the manager that a part of this chunk of memory is going to be used by the
    /// GPU soon in the future. The function should block if the memory is currently being
    /// accessed by the CPU.
    ///
    /// `write` indicates whether the GPU will write to the memory. If `false`, then it will only
    /// be written.
    ///
    /// `range` indicates the part of the chunk that is concerned.
    ///
    /// `queue` is the queue where the command buffer that accesses the memory will be submitted.
    /// If the `gpu_access` function submits something to that queue, it will thus be submitted
    /// beforehand. This behavior can be used for example to submit sparse binding commands.
    ///
    /// `fence` is a fence that will be signaled when this GPU access will stop. It should be
    /// waited upon whenever the user wants to read this memory from the CPU. If `requires_fence`
    /// returned false, then this value will be `None`.
    ///
    /// `semaphore` is a semaphore that will be signaled when this GPU access will stop. This value
    /// is intended to be returned later, in a follow-up call to `gpu_access`. If
    /// `requires_semaphore` returned false, then this value will be `None`.
    ///
    /// The manager must track whether this chunk of memory is being accessed by the CPU/GPU and
    /// return a semaphore that must be waited upon by the GPU before the access can start. The
    /// semaphore being returned is usually one that has been previously passed to this function,
    /// but it doesn't need to be the case.
    unsafe fn gpu_access(&self, write: bool, range: ChunkRange, queue: &Arc<Queue>,
                         fence: Option<Arc<Fence>>, semaphore: Option<Arc<Semaphore>>)
                         -> Option<Arc<Semaphore>>;

    /// Returns true if this chunk of memory may be used, now or in the future, by multiple buffers
    /// or images (or a combination of both) simultaneously. If you're not sure, it's safer to
    /// return true.
    ///
    /// If this value is true, then the Vulkan implementation must be more conservative about
    /// reordering subpasses in a renderpass.
    fn may_alias(&self) -> bool;
}

pub enum ChunkRange {
    All,
    Range { offset: usize, size: usize }
}

pub enum ChunkProperties<'a> {
    Regular {
        memory: &'a DeviceMemory,
        offset: usize,
        size: usize,
    },

    Sparse,     // TODO: unimplemented
}

/// Trait for types of data that can be mapped.
pub unsafe trait Content {
    /// Builds a pointer to this type from a raw pointer.
    fn ref_from_ptr<'a>(ptr: *mut c_void, size: usize) -> Option<*mut Self>;

    /// Returns true if the size is suitable to store a type like this.
    fn is_size_suitable(usize) -> bool;
}

unsafe impl<T> Content for T {
    #[inline]
    fn ref_from_ptr<'a>(ptr: *mut c_void, size: usize) -> Option<*mut T> {
        if size != mem::size_of::<T>() {
            return None;
        }

        Some(ptr as *mut T)
    }

    #[inline]
    fn is_size_suitable(size: usize) -> bool {
        size == mem::size_of::<T>()
    }
}

unsafe impl<T> Content for [T] {
    #[inline]
    fn ref_from_ptr<'a>(ptr: *mut c_void, size: usize) -> Option<*mut [T]> {
        if size % mem::size_of::<T>() != 0 {
            return None;
        }

        let ptr = ptr as *mut T;
        let size = size / mem::size_of::<T>();
        Some(unsafe { slice::from_raw_parts_mut(&mut *ptr, size) as *mut [T] })
    }

    #[inline]
    fn is_size_suitable(size: usize) -> bool {
        size % mem::size_of::<T>() == 0
    }
}
<commit_msg>Minor cleanup in memory/mod.rs<commit_after>//! GPU-visible memory allocation and management.
//!
//! When you create a buffer or a texture with Vulkan, you have to bind it to a chunk of allocated
//! memory. To do so, you have to pass a type that implements the `MemorySource` trait.
//!
//! There are several implementations of the trait, ie. several things that you can pass to the
//! constructors of buffers and textures:
//!
//! - `&Arc<Device>`, which will simply allocate a new chunk of memory every time (easy but not
//!   very efficient).
//! - `MemorySource`, which is the same as `&Arc<Device>` except that it will use the
//!   already-allocated block.
//! - ... needs more ...
//!
//! # Synchronization
//!
//! In Vulkan, it's the job of the programmer to enforce memory safety. In other words, the
//! programmer must take care that two chunks of memory are not read and written simultaneously.
//!
//! In this library, this is enforced by the implementation of `MemorySource` or
//! `MemorySourceChunk`.
//!
//! There are two mechanisms in Vulkan that can provide synchronization: fences and semaphores.
//! Fences provide synchronization between the CPU and the GPU, and semaphores provide
//! synchronization between multiple queues of the GPU. See the `sync` module for more info.
//!
//! # Sparse resources
//!
//! **Not yet implemented**.
//!
//! Instead of creating a buffer or an image with a single chunk of memory, you also have the
//! possibility to create resources with *sparse memory*.
//!
//! For example you can bind the first half of the buffer to a memory chunk, and the second half of
//! the buffer to another memory chunk.
//!
//! There is a hierarchy of three features related to sparse resources:
//!
//!  - The `sparseBinding` feature allows you to use sparse resources.
//!  - The `sparseResidency` feature is a superset of `sparseBinding` and allows you to leave some
//!    parts of the resource unbinded before using it.
//!  - The `sparseResidencyAliased` feature is a superset of `sparseResidency` and allows you to
//!    bind the same memory chunk to multiple different resources at once.
//!
use std::mem;
use std::ops::Deref;
use std::ops::DerefMut;
use std::os::raw::c_void;
use std::slice;
use std::sync::Arc;

use sync::Fence;
use sync::Semaphore;

use device::Device;
use device::Queue;

use OomError;

pub use self::device_memory::DeviceMemory;
pub use self::device_memory::MappedDeviceMemory;
pub use self::single::DeviceLocal;
pub use self::single::DeviceLocalChunk;
pub use self::single::HostVisible;
pub use self::single::HostVisibleChunk;

mod device_memory;
mod single;

/// Trait for memory objects that can be accessed from the CPU.
pub unsafe trait CpuAccessible<'a, T: ?Sized> {
    /// The object that provides the access.
    type Read: Deref<Target = T>;

    /// Gives a read access to the content of the buffer.
    ///
    /// If the buffer is in use by the GPU, blocks until it is available.
    // TODO: what happens if timeout is reached? a panic?
    fn read(&'a self, timeout_ns: u64) -> Self::Read;

    /// Tries to give a read access to the content of the buffer.
    ///
    /// If the buffer is in use by the GPU, returns `None`.
    fn try_read(&'a self) -> Option<Self::Read>;
}

/// Trait for memory objects that can be mutably accessed from the CPU.
pub unsafe trait CpuWriteAccessible<'a, T: ?Sized>: CpuAccessible<'a, T> {
    /// The object that provides the access.
    type Write: DerefMut<Target = T>;

    /// Gives a write access to the content of the buffer.
    ///
    /// If the buffer is in use by the GPU, blocks until it is available.
    // TODO: what happens if timeout is reached? a panic?
    fn write(&'a self, timeout_ns: u64) -> Self::Write;

    /// Tries to give a write access to the content of the buffer.
    ///
    /// If the buffer is in use by the GPU, returns `None`.
    fn try_write(&'a self) -> Option<Self::Write>;
}

/// Trait for objects that can be used to fill the memory requirements of a buffer or an image.
pub unsafe trait MemorySource {
    /// An object that represents one block of allocation. Returned by `allocate`.
    type Chunk: MemorySourceChunk;

    /// Returns true if the chunks allocated by this source will use sparse memory.
    // TODO: should return the level of the required sparse feature
    fn is_sparse(&self) -> bool;

    /// Allocates a block of memory to be used.
    ///
    /// `memory_type_bits` is a bitsfield which indicates from which memory type the memory can
    /// be allocated. For example if the bit 2 is set (`memory_type_bits & (1 << 2) != 0`), that
    /// means that the memory type whose ID is 2 can be used.
    ///
    /// The implementation is allowed to return a chunk with a larger size or alignment.
    fn allocate(self, &Arc<Device>, size: usize, alignment: usize, memory_type_bits: u32)
                -> Result<Self::Chunk, OomError>;
}

/// A chunk of GPU-visible memory.
pub unsafe trait MemorySourceChunk {
    /// Returns the properties of this chunk.
    fn properties(&self) -> ChunkProperties;

    /// Returns true if the `gpu_access` function should be passed a fence.
    #[inline]
    fn requires_fence(&self) -> bool {
        true
    }

    /// Returns true if the `gpu_access` function should be passed a semaphore.
    #[inline]
    fn requires_semaphore(&self) -> bool {
        true
    }

    /// Instructs the manager that a part of this chunk of memory is going to be used by the
    /// GPU soon in the future. The function should block if the memory is currently being
    /// accessed by the CPU.
    ///
    /// `write` indicates whether the GPU will write to the memory. If `false`, then it will only
    /// be written.
    ///
    /// `range` indicates the part of the chunk that is concerned.
    ///
    /// `queue` is the queue where the command buffer that accesses the memory will be submitted.
    /// If the `gpu_access` function submits something to that queue, it will thus be submitted
    /// beforehand. This behavior can be used for example to submit sparse binding commands.
    ///
    /// `fence` is a fence that will be signaled when this GPU access will stop. It should be
    /// waited upon whenever the user wants to read this memory from the CPU. If `requires_fence`
    /// returned false, then this value will be `None`.
    ///
    /// `semaphore` is a semaphore that will be signaled when this GPU access will stop. This value
    /// is intended to be returned later, in a follow-up call to `gpu_access`. If
    /// `requires_semaphore` returned false, then this value will be `None`.
    ///
    /// The manager must track whether this chunk of memory is being accessed by the CPU/GPU and
    /// return a semaphore that must be waited upon by the GPU before the access can start. The
    /// semaphore being returned is usually one that has been previously passed to this function,
    /// but it doesn't need to be the case.
    unsafe fn gpu_access(&self, write: bool, range: ChunkRange, queue: &Arc<Queue>,
                         fence: Option<Arc<Fence>>, semaphore: Option<Arc<Semaphore>>)
                         -> Option<Arc<Semaphore>>;

    /// Returns true if this chunk of memory may be used, now or in the future, by multiple buffers
    /// or images (or a combination of both) simultaneously. If you're not sure, it's safer to
    /// return true.
    ///
    /// If this value is true, then the Vulkan implementation must be more conservative about
    /// reordering subpasses in a renderpass.
    fn may_alias(&self) -> bool;
}

/// Describes a range in a memory chunk.
pub enum ChunkRange {
    /// The whole chunk.
    All,

    /// A subpart of the chunk.
    Range {
        /// Number of bytes between the start of the chunk and the part we want.
        offset: usize,
        /// Size in bytes of the part we want.
        size: usize,
    }
}

pub enum ChunkProperties<'a> {
    Regular {
        memory: &'a DeviceMemory,
        offset: usize,
        size: usize,
    },

    Sparse,     // TODO: unimplemented
}

/// Trait for types of data that can be mapped.
pub unsafe trait Content {
    /// Builds a pointer to this type from a raw pointer.
    fn ref_from_ptr<'a>(ptr: *mut c_void, size: usize) -> Option<*mut Self>;

    /// Returns true if the size is suitable to store a type like this.
    fn is_size_suitable(usize) -> bool;
}

unsafe impl<T> Content for T {
    #[inline]
    fn ref_from_ptr<'a>(ptr: *mut c_void, size: usize) -> Option<*mut T> {
        if size != mem::size_of::<T>() {
            return None;
        }

        Some(ptr as *mut T)
    }

    #[inline]
    fn is_size_suitable(size: usize) -> bool {
        size == mem::size_of::<T>()
    }
}

unsafe impl<T> Content for [T] {
    #[inline]
    fn ref_from_ptr<'a>(ptr: *mut c_void, size: usize) -> Option<*mut [T]> {
        if size % mem::size_of::<T>() != 0 {
            return None;
        }

        let ptr = ptr as *mut T;
        let size = size / mem::size_of::<T>();
        Some(unsafe { slice::from_raw_parts_mut(&mut *ptr, size) as *mut [T] })
    }

    #[inline]
    fn is_size_suitable(size: usize) -> bool {
        size % mem::size_of::<T>() == 0
    }
}

/*
TODO: do this when it's possible
unsafe impl Content for .. {}
impl<'a, T> !Content for &'a T {}
impl<'a, T> !Content for &'a mut T {}
impl<T> !Content for *const T {}
impl<T> !Content for *mut T {}
impl<T> !Content for Box<T> {}
impl<T> !Content for UnsafeCell<T> {}

*/
<|endoftext|>