<commit_before>use super::Rope;
use std::iter;

#[test]
fn rebalance_test_1() {
    let mut r = Rope::from("This is a large string \
                        that will need to be rebalanced.".to_string());
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn rebalance_test_2() {
    let mut r =
        Rope::from("Lorem ipsum dolor sit amet, consectetur adipiscing eli\
                    t, sed do eiusmod tempor incididunt ut labore et dolor\
                    e magna aliqua. Ut enim ad minim veniam, quis nostrud \
                    exercitation ullamco laboris nisi ut aliquip ex ea com\
                    modo consequat. Duis aute irure dolor in reprehenderit\
                     in voluptate velit esse cillum dolore eu fugiat nulla\
                     pariatur. Excepteur sint occaecat cupidatat non proid\
                    ent, sunt in culpa qui officia deserunt mollit anim id\
                     est laborum.".to_string());
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn big_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn repeated_concat_left_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    for _ in 1..1000 {
        r = r + iter::repeat('a').take(100).collect::<String>();
    }
    assert!(r.is_balanced());
}

#[test]
fn repeated_concat_right_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    for _ in 1..1000 {
        let s2 = iter::repeat('a').take(100).collect::<String>();
        r = Rope::from(s2) + r;
    }
    assert!(r.is_balanced());
}

#[test]
fn merge_rebalance_test() {
    let s = "Lorem ipsum dolor sit amet, consectetur adipiscing eli\
             t, sed do eiusmod tempor incididunt ut labore et dolor\
             e magna aliqua. Ut enim ad minim veniam, quis nostrud \
             exercitation ullamco laboris nisi ut aliquip ex ea com\
             modo consequat. Duis aute irure dolor in reprehenderit\
              in voluptate velit esse cillum dolore eu fugiat nulla\
              pariatur. Excepteur sint occaecat cupidatat non proid\
             ent, sunt in culpa qui officia deserunt mollit anim id\
              est laborum.";

     let t = Rope::from(s.to_owned());
     let mut u = t + s;
     u.rebalance();
     assert!(u.is_balanced());
}

#[test]
fn with_insert_rope_balance_test() {
    let s: String = iter::repeat('a').take(10).collect();
    let mut r_1 = Rope::from(s);
    for _ in 0..99 {
        let t: String = iter::repeat('a').take(10).collect();
        r_1 = r_1.with_insert_rope(5, Rope::from(t));
    }
    //  this isn't necessary, with_insert_rope() will automatically rebalance
    //      - eliza, 12/18/2016
    // r_1.rebalance();
    assert!(r_1.is_balanced());
}

#[test]
fn with_insert_rope_test_1() {
    let s: String = iter::repeat('a').take(1_000).collect();
    let r_1 = Rope::from(s);
    let mut r_2 = Rope::new();
    for _ in 0..100 {
        let t: String = iter::repeat('a').take(10).collect();
        r_2.with_insert_rope(0, Rope::from(t));
    }
    assert_eq!(r_1, r_2);
}

#[test]
fn with_insert_rope_test_2() {
    let s: String = iter::repeat('a').take(10).collect();
    let mut r_1 = Rope::from(s);
    for _ in 0..99 {
        let t: String = iter::repeat('a').take(10).collect();
        r_1 = r_1.with_insert_rope(5, Rope::from(t));
    }

    let q: String = iter::repeat('a').take(1_000).collect();
    let r_2 = Rope::from(q);
    assert_eq!(r_1, r_2);
}

#[test]
fn mutable_insert_rope_test_1() {
    let mut s_1 = Rope::from(String::from("aaaaa"));
    let mut s_2 = Rope::from(String::from("bbbbb"));
    let s_3 = Rope::from(String::from("ccccc"));
    s_2.insert_rope(0, s_3);
    s_1.insert_rope(0, s_2);
    assert_eq!(&s_1, "cccccbbbbbaaaaa");
}

#[test]
fn mutable_insert_str_test_1() {
    let mut s = Rope::from("aaaaa");
    s.insert_str(0, "bbbbb");
    s.insert_str(10, "ccccc");
    assert_eq!(&s, "bbbbbaaaaaccccc");
}

#[test]
fn mutable_insert_char_test_1() {
    let mut s = Rope::from("aaaaa");
    for _ in 0..5 { s.insert(0, 'b')}
    for _ in 0..5 { s.insert(10, 'c')}
    assert_eq!(&s, "bbbbbaaaaaccccc");
}

#[test]
fn with_insert_char_test_1() {
    let s = Rope::from("aaaaa");
    let s_1 = s.with_insert(5, 'b');
    let s_2 = s_1.with_insert(4, 'b');
    let s_3 = s_2.with_insert(3, 'b');
    let s_4 = s_3.with_insert(2, 'b');
    let s_5 = s_4.with_insert(1, 'b');
    assert_eq!(&s, "aaaaa");
    assert_eq!(&s_1, "aaaaab");
    assert_eq!(&s_2, "aaaabab");
    assert_eq!(&s_3, "aaababab");
    assert_eq!(&s_4, "aabababab");
    assert_eq!(&s_5, "ababababab");

}

#[test]
fn with_insert_str_test_1() {
    let s = Rope::from("aaaaa");
    let s_1 = s.with_insert_str(5, "ccccc");
    let s_2 = s_1.with_insert_str(5, "bbbbb");
    assert_eq!(&s, "aaaaa");
    assert_eq!(&s_1, "aaaaaccccc");
    assert_eq!(&s_2, "aaaaabbbbbccccc");
}
<commit_msg>rope: fix incorrect Rope::test::with_insert_1 the rope was not reassigned<commit_after>use super::Rope;
use std::iter;

#[test]
fn rebalance_test_1() {
    let mut r = Rope::from("This is a large string \
                        that will need to be rebalanced.".to_string());
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn rebalance_test_2() {
    let mut r =
        Rope::from("Lorem ipsum dolor sit amet, consectetur adipiscing eli\
                    t, sed do eiusmod tempor incididunt ut labore et dolor\
                    e magna aliqua. Ut enim ad minim veniam, quis nostrud \
                    exercitation ullamco laboris nisi ut aliquip ex ea com\
                    modo consequat. Duis aute irure dolor in reprehenderit\
                     in voluptate velit esse cillum dolore eu fugiat nulla\
                     pariatur. Excepteur sint occaecat cupidatat non proid\
                    ent, sunt in culpa qui officia deserunt mollit anim id\
                     est laborum.".to_string());
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn big_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn repeated_concat_left_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    for _ in 1..1000 {
        r = r + iter::repeat('a').take(100).collect::<String>();
    }
    assert!(r.is_balanced());
}

#[test]
fn repeated_concat_right_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    for _ in 1..1000 {
        let s2 = iter::repeat('a').take(100).collect::<String>();
        r = Rope::from(s2) + r;
    }
    assert!(r.is_balanced());
}

#[test]
fn merge_rebalance_test() {
    let s = "Lorem ipsum dolor sit amet, consectetur adipiscing eli\
             t, sed do eiusmod tempor incididunt ut labore et dolor\
             e magna aliqua. Ut enim ad minim veniam, quis nostrud \
             exercitation ullamco laboris nisi ut aliquip ex ea com\
             modo consequat. Duis aute irure dolor in reprehenderit\
              in voluptate velit esse cillum dolore eu fugiat nulla\
              pariatur. Excepteur sint occaecat cupidatat non proid\
             ent, sunt in culpa qui officia deserunt mollit anim id\
              est laborum.";

     let t = Rope::from(s.to_owned());
     let mut u = t + s;
     u.rebalance();
     assert!(u.is_balanced());
}

#[test]
fn with_insert_rope_balance_test() {
    let s: String = iter::repeat('a').take(10).collect();
    let mut r_1 = Rope::from(s);
    for _ in 0..99 {
        let t: String = iter::repeat('a').take(10).collect();
        r_1 = r_1.with_insert_rope(5, Rope::from(t));
    }
    //  this isn't necessary, with_insert_rope() will automatically rebalance
    //      - eliza, 12/18/2016
    // r_1.rebalance();
    assert!(r_1.is_balanced());
}

#[test]
fn with_insert_rope_test_1() {
    let s: String = iter::repeat('a').take(1_000).collect();
    let r_1 = Rope::from(s);
    let mut r_2 = Rope::new();
    for _ in 0..100 {
        let t: String = iter::repeat('a').take(10).collect();
        r_2 = r_2.with_insert_rope(0, Rope::from(t));
    }
    assert_eq!(r_1, r_2);
}

#[test]
fn with_insert_rope_test_2() {
    let s: String = iter::repeat('a').take(10).collect();
    let mut r_1 = Rope::from(s);
    for _ in 0..99 {
        let t: String = iter::repeat('a').take(10).collect();
        r_1 = r_1.with_insert_rope(5, Rope::from(t));
    }

    let q: String = iter::repeat('a').take(1_000).collect();
    let r_2 = Rope::from(q);
    assert_eq!(r_1, r_2);
}

#[test]
fn mutable_insert_rope_test_1() {
    let mut s_1 = Rope::from(String::from("aaaaa"));
    let mut s_2 = Rope::from(String::from("bbbbb"));
    let s_3 = Rope::from(String::from("ccccc"));
    s_2.insert_rope(0, s_3);
    s_1.insert_rope(0, s_2);
    assert_eq!(&s_1, "cccccbbbbbaaaaa");
}

#[test]
fn mutable_insert_str_test_1() {
    let mut s = Rope::from("aaaaa");
    s.insert_str(0, "bbbbb");
    s.insert_str(10, "ccccc");
    assert_eq!(&s, "bbbbbaaaaaccccc");
}

#[test]
fn mutable_insert_char_test_1() {
    let mut s = Rope::from("aaaaa");
    for _ in 0..5 { s.insert(0, 'b')}
    for _ in 0..5 { s.insert(10, 'c')}
    assert_eq!(&s, "bbbbbaaaaaccccc");
}

#[test]
fn with_insert_char_test_1() {
    let s = Rope::from("aaaaa");
    let s_1 = s.with_insert(5, 'b');
    let s_2 = s_1.with_insert(4, 'b');
    let s_3 = s_2.with_insert(3, 'b');
    let s_4 = s_3.with_insert(2, 'b');
    let s_5 = s_4.with_insert(1, 'b');
    assert_eq!(&s, "aaaaa");
    assert_eq!(&s_1, "aaaaab");
    assert_eq!(&s_2, "aaaabab");
    assert_eq!(&s_3, "aaababab");
    assert_eq!(&s_4, "aabababab");
    assert_eq!(&s_5, "ababababab");

}

#[test]
fn with_insert_str_test_1() {
    let s = Rope::from("aaaaa");
    let s_1 = s.with_insert_str(5, "ccccc");
    let s_2 = s_1.with_insert_str(5, "bbbbb");
    assert_eq!(&s, "aaaaa");
    assert_eq!(&s_1, "aaaaaccccc");
    assert_eq!(&s_2, "aaaaabbbbbccccc");
}
<|endoftext|>


<commit_before>extern crate env_logger;

extern crate gluon;
#[macro_use]
extern crate gluon_codegen;

use std::io::{self, BufRead};

use gluon::vm::api::{FunctionRef, OpaqueValue};
use gluon::{new_vm, Compiler, RootedThread};

#[derive(VmType)]
#[gluon(vm_type = "examples.lisp.lisp.Expr")]
struct Expr;
type OpaqueExpr = OpaqueValue<RootedThread, Expr>;

#[derive(VmType)]
#[gluon(vm_type = "examples.lisp.lisp.LispState")]
struct LispState;
type OpaqueLispState = OpaqueValue<RootedThread, LispState>;

fn main() {
    if let Err(err) = main_() {
        eprintln!("{}", err);
    }
}

fn main_() -> gluon::Result<()> {
    env_logger::init();

    let thread = new_vm();
    Compiler::new().load_file(&thread, "examples/lisp/lisp.glu")?;

    let mut eval: FunctionRef<
        fn(String, OpaqueLispState) -> Result<(OpaqueExpr, OpaqueLispState), String>,
    > = thread.get_global("examples.lisp.lisp.eval_env_string")?;

    let mut show: FunctionRef<fn(OpaqueExpr) -> String> =
        thread.get_global("examples.lisp.lisp.show.show")?;

    let mut env: OpaqueLispState = thread.get_global("examples.lisp.lisp.default_env")?;

    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let line = line?;
        match eval.call(line, env.clone())? {
            Ok((msg, new_env)) => {
                println!("{}", show.call(msg.clone())?);
                env = new_env;
            }
            Err(err) => {
                eprintln!("{}", err);
            }
        }
    }
    Ok(())
}
<commit_msg>test: Test the lisp example<commit_after>extern crate env_logger;

extern crate gluon;
#[macro_use]
extern crate gluon_codegen;

use std::io::{self, BufRead};

use gluon::{
    new_vm,
    vm::api::{FunctionRef, OpaqueValue},
    Compiler, RootedThread,
};

#[derive(VmType)]
#[gluon(vm_type = "examples.lisp.lisp.Expr")]
struct ExprMarker;
type Expr = OpaqueValue<RootedThread, ExprMarker>;

#[derive(VmType)]
#[gluon(vm_type = "examples.lisp.lisp.LispState")]
struct LispStateMarker;
type LispState = OpaqueValue<RootedThread, LispStateMarker>;

fn main() {
    if let Err(err) = main_() {
        eprintln!("{}", err);
    }
}

fn main_() -> gluon::Result<()> {
    env_logger::init();

    let thread = new_vm();
    Compiler::new().load_file(&thread, "examples/lisp/lisp.glu")?;

    let mut eval: FunctionRef<fn(String, LispState) -> Result<(Expr, LispState), String>> =
        thread.get_global("examples.lisp.lisp.eval_env_string")?;

    let mut show: FunctionRef<fn(Expr) -> String> =
        thread.get_global("examples.lisp.lisp.show.show")?;

    let mut env: LispState = thread.get_global("examples.lisp.lisp.default_env")?;

    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let line = line?;
        match eval.call(line, env.clone())? {
            Ok((msg, new_env)) => {
                println!("{}", show.call(msg.clone())?);
                env = new_env;
            }
            Err(err) => {
                eprintln!("{}", err);
            }
        }
    }
    Ok(())
}

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

    use gluon::Error;

    fn eval_lisp(expr: &str) -> Result<String, Error> {
        let thread = new_vm();
        Compiler::new().load_file(&thread, "examples/lisp/lisp.glu")?;

        let mut eval: FunctionRef<fn(String, LispState) -> Result<(Expr, LispState), String>> =
            thread.get_global("examples.lisp.lisp.eval_env_string")?;

        let mut show: FunctionRef<fn(Expr) -> String> =
            thread.get_global("examples.lisp.lisp.show.show")?;

        let env: LispState = thread.get_global("examples.lisp.lisp.default_env")?;

        let (msg, _) = eval.call(expr.to_string(), env.clone())??;
        Ok(show.call(msg.clone())?)
    }

    #[test]
    fn basic() {
        assert_eq!(eval_lisp("(+ 1 2 3)").unwrap(), "6");
    }
}
<|endoftext|>


<commit_before><commit_msg>define JYInfo related wrappers<commit_after>use data_structs::JYInfo;
use jalali_bindings::*;

impl JYInfo {
  pub fn new() -> Self {
    JYInfo {
      lf: 0,
      y: 0,
      r: 0,
      p: 0,
      rl: 0,
      pl: 0,
      apl: 0,
    }
  }

  pub fn get_jalali_year_info(year: i32) -> Self {
    let mut result = Self::new();
    result.y = year;
    unsafe {
      jalali_get_jyear_info(&mut result);
    }
    result
  }
}
<|endoftext|>


<commit_before>use raw::{FunctionCallbackInfo, Isolate, Local};

extern "system" {

    #[link_name = "NeonSys_Call_SetReturn"]
    pub fn set_return(info: &FunctionCallbackInfo, value: Local);

    #[link_name = "NeonSys_Call_GetIsolate"]
    pub fn get_isolate(info: &FunctionCallbackInfo) -> *mut Isolate;

    #[link_name = "NeonSys_Call_CurrentIsolate"]
    pub fn current_isolate() -> *mut Isolate;

    #[link_name = "NeonSys_Call_IsConstruct"]
    pub fn is_construct(info: &FunctionCallbackInfo) -> bool;

    #[link_name = "NeonSys_Call_This"]
    pub fn this(info: &FunctionCallbackInfo, out: &mut Local);

    #[link_name = "NeonSys_Call_Callee"]
    pub fn callee(info: &FunctionCallbackInfo, out: &mut Local);

    #[link_name = "NeonSys_Call_Data"]
    pub fn data(info: &FunctionCallbackInfo, out: &mut Local);

    #[link_name = "NeonSys_Call_Length"]
    pub fn len(info: &FunctionCallbackInfo) -> i32;

    #[link_name = "NeonSys_Call_Get"]
    pub fn get(info: &FunctionCallbackInfo, i: i32, out: &mut Local);

}
<commit_msg>expand neon_sys::call mod documentation<commit_after>//! Facilities for working with `v8::FunctionCallbackInfo` and getting the current `v8::Isolate`.

use raw::{FunctionCallbackInfo, Isolate, Local};

extern "system" {

    /// Sets the return value of the function call.
    #[link_name = "NeonSys_Call_SetReturn"]
    pub fn set_return(info: &FunctionCallbackInfo, value: Local);

    /// Gets the isolate of the function call.
    #[link_name = "NeonSys_Call_GetIsolate"]
    pub fn get_isolate(info: &FunctionCallbackInfo) -> *mut Isolate;

    /// Gets the current `v8::Isolate`.
    #[link_name = "NeonSys_Call_CurrentIsolate"]
    pub fn current_isolate() -> *mut Isolate;

    /// Indicates if the function call was invoked as a constructor.
    #[link_name = "NeonSys_Call_IsConstruct"]
    pub fn is_construct(info: &FunctionCallbackInfo) -> bool;

    /// Mutates the `out` argument provided to refer to the `v8::Local` handle value of the object
    /// the function is bound to.
    #[link_name = "NeonSys_Call_This"]
    pub fn this(info: &FunctionCallbackInfo, out: &mut Local);

    /// Mutates the `out` argument provided to refer to the `v8::Local` handle value of the
    /// currently executing function.
    #[link_name = "NeonSys_Call_Callee"]
    pub fn callee(info: &FunctionCallbackInfo, out: &mut Local);

    /// Mutates the `out` argument provided to refer to the `v8::Local` handle value of the
    /// `v8::FunctionCallbackInfo` `Data`.
    #[link_name = "NeonSys_Call_Data"]
    pub fn data(info: &FunctionCallbackInfo, out: &mut Local);

    /// Gets the number of arguments passed to the function.
    #[link_name = "NeonSys_Call_Length"]
    pub fn len(info: &FunctionCallbackInfo) -> i32;

    /// Mutates the `out` argument provided to refer to the `v8::Local` handle value of the `i`th
    /// argument passed to the function.
    #[link_name = "NeonSys_Call_Get"]
    pub fn get(info: &FunctionCallbackInfo, i: i32, out: &mut Local);

}
<|endoftext|>


<commit_before>//! Input for the parser -- a sequence of tokens.
//!
//! As of now, parser doesn't have access to the *text* of the tokens, and makes
//! decisions based solely on their classification.

use crate::SyntaxKind;

#[allow(non_camel_case_types)]
type bits = u64;

/// Main input to the parser.
///
/// A sequence of tokens represented internally as a struct of arrays.
#[derive(Default)]
pub struct Tokens {
    kind: Vec<SyntaxKind>,
    joint: Vec<bits>,
    contextual_kw: Vec<SyntaxKind>,
}

impl Tokens {
    #[inline]
    pub fn push(&mut self, kind: SyntaxKind) {
        self.push_impl(kind, SyntaxKind::EOF)
    }
    /// Sets jointness for the last token we've pushed.
    ///
    /// This is a separate API rather than an argument to the `push` to make it
    /// convenient both for textual and mbe tokens. With text, you know whether
    /// the *previous* token was joint, with mbe, you know whether the *current*
    /// one is joint. This API allows for styles of usage:
    ///
    /// ```
    /// // In text:
    /// tokens.was_joint(prev_joint);
    /// tokens.push(curr);
    ///
    /// // In MBE:
    /// token.push(curr);
    /// tokens.push(curr_joint)
    /// ```
    #[inline]
    pub fn was_joint(&mut self) {
        self.set_joint(self.len() - 1);
    }
    #[inline]
    pub fn push_ident(&mut self, contextual_kw: SyntaxKind) {
        self.push_impl(SyntaxKind::IDENT, contextual_kw)
    }
    #[inline]
    fn push_impl(&mut self, kind: SyntaxKind, contextual_kw: SyntaxKind) {
        let idx = self.len();
        if idx % (bits::BITS as usize) == 0 {
            self.joint.push(0);
        }
        self.kind.push(kind);
        self.contextual_kw.push(contextual_kw);
    }
    fn set_joint(&mut self, n: usize) {
        let (idx, b_idx) = self.bit_index(n);
        self.joint[idx] |= 1 << b_idx;
    }
    fn bit_index(&self, n: usize) -> (usize, usize) {
        let idx = n / (bits::BITS as usize);
        let b_idx = n % (bits::BITS as usize);
        (idx, b_idx)
    }

    fn len(&self) -> usize {
        self.kind.len()
    }
}

/// pub(crate) impl used by the parser.
impl Tokens {
    pub(crate) fn kind(&self, idx: usize) -> SyntaxKind {
        self.kind.get(idx).copied().unwrap_or(SyntaxKind::EOF)
    }
    pub(crate) fn contextual_kind(&self, idx: usize) -> SyntaxKind {
        self.contextual_kw.get(idx).copied().unwrap_or(SyntaxKind::EOF)
    }
    pub(crate) fn is_joint(&self, n: usize) -> bool {
        let (idx, b_idx) = self.bit_index(n);
        self.joint[idx] & 1 << b_idx != 0
    }
}
<commit_msg>consistency<commit_after>//! Input for the parser -- a sequence of tokens.
//!
//! As of now, parser doesn't have access to the *text* of the tokens, and makes
//! decisions based solely on their classification.

use crate::SyntaxKind;

#[allow(non_camel_case_types)]
type bits = u64;

/// Main input to the parser.
///
/// A sequence of tokens represented internally as a struct of arrays.
#[derive(Default)]
pub struct Tokens {
    kind: Vec<SyntaxKind>,
    joint: Vec<bits>,
    contextual_kind: Vec<SyntaxKind>,
}

impl Tokens {
    #[inline]
    pub fn push(&mut self, kind: SyntaxKind) {
        self.push_impl(kind, SyntaxKind::EOF)
    }
    /// Sets jointness for the last token we've pushed.
    ///
    /// This is a separate API rather than an argument to the `push` to make it
    /// convenient both for textual and mbe tokens. With text, you know whether
    /// the *previous* token was joint, with mbe, you know whether the *current*
    /// one is joint. This API allows for styles of usage:
    ///
    /// ```
    /// // In text:
    /// tokens.was_joint(prev_joint);
    /// tokens.push(curr);
    ///
    /// // In MBE:
    /// token.push(curr);
    /// tokens.push(curr_joint)
    /// ```
    #[inline]
    pub fn was_joint(&mut self) {
        self.set_joint(self.len() - 1);
    }
    #[inline]
    pub fn push_ident(&mut self, contextual_kind: SyntaxKind) {
        self.push_impl(SyntaxKind::IDENT, contextual_kind)
    }
    #[inline]
    fn push_impl(&mut self, kind: SyntaxKind, contextual_kind: SyntaxKind) {
        let idx = self.len();
        if idx % (bits::BITS as usize) == 0 {
            self.joint.push(0);
        }
        self.kind.push(kind);
        self.contextual_kind.push(contextual_kind);
    }
    fn set_joint(&mut self, n: usize) {
        let (idx, b_idx) = self.bit_index(n);
        self.joint[idx] |= 1 << b_idx;
    }
    fn bit_index(&self, n: usize) -> (usize, usize) {
        let idx = n / (bits::BITS as usize);
        let b_idx = n % (bits::BITS as usize);
        (idx, b_idx)
    }

    fn len(&self) -> usize {
        self.kind.len()
    }
}

/// pub(crate) impl used by the parser.
impl Tokens {
    pub(crate) fn kind(&self, idx: usize) -> SyntaxKind {
        self.kind.get(idx).copied().unwrap_or(SyntaxKind::EOF)
    }
    pub(crate) fn contextual_kind(&self, idx: usize) -> SyntaxKind {
        self.contextual_kind.get(idx).copied().unwrap_or(SyntaxKind::EOF)
    }
    pub(crate) fn is_joint(&self, n: usize) -> bool {
        let (idx, b_idx) = self.bit_index(n);
        self.joint[idx] & 1 << b_idx != 0
    }
}
<|endoftext|>


<commit_before>//! # Strum
//!
//! Strum is a set of macros and traits for working with
//! enums and strings easier in Rust.
//!
//! # Documentation
//!
//! The documentation for this crate is found in the `strum` crate.

extern crate syn;
#[macro_use]
extern crate quote;
extern crate proc_macro;

use proc_macro::TokenStream;
use syn::Attribute;
use std::env;

#[proc_macro_derive(EnumString,attributes(strum))]
pub fn from_string(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();

    let toks = from_string_inner(&ast);
    debug_print_generated(&ast, &toks);
    toks.parse().unwrap()
}

#[proc_macro_derive(EnumIter,attributes(strum))]
pub fn enum_iter(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();

    let toks = enum_iter_inner(&ast);
    debug_print_generated(&ast, &toks);
    toks.parse().unwrap()
}

#[proc_macro_derive(EnumMessage,attributes(strum))]
pub fn enum_messages(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();

    let toks = enum_message_inner(&ast);
    debug_print_generated(&ast, &toks);
    toks.parse().unwrap()
}

fn debug_print_generated(ast: &syn::DeriveInput, toks: &quote::Tokens) {
    let ident = ast.ident.as_ref();
    let debug = env::var("STRUM_DEBUG");
    if let Ok(s) = debug {
        if s == "1" {
            println!("{}", toks);
        }

        if s == ident {
            println!("{}", toks);
        }
    }
}

fn extract_attrs<'a>(attrs: &'a [Attribute], attr: &str, prop: &str) -> Vec<&'a str> {
    attrs.iter()
        // Get all the attributes with our tag on them.
        .filter_map(|attribute| {
            use syn::MetaItem::*;
            if let List(ref i, ref nested) = attribute.value {
                if i == attr { Some(nested) } else { None }
            } else {
                None
            }
        })
        .flat_map(|nested| nested)
        // Get all the inner elements as long as they start with ser.
        .filter_map(|attribute| {
            use syn::NestedMetaItem::*;
            use syn::MetaItem::*;
            if let &MetaItem(NameValue(ref i, syn::Lit::Str(ref s, ..))) = attribute {
                if i == prop { Some(&**s) } else { None }
            } else {
                None
            }
        }).collect()
}

fn unique_attr<'a>(attrs: &'a [Attribute], attr: &str, prop: &str) -> Option<&'a str> {
    let mut curr = extract_attrs(attrs, attr, prop);
    if curr.len() > 1 {
        panic!("More than one property: {} found on variant", prop);
    }

    curr.pop()
}

fn is_disabled(attrs: &[Attribute]) -> bool {
    let v = extract_attrs(attrs, "strum", "disabled");
    match v.len() {
        0 => false,
        1 => v[0] == "true",
        _ => panic!("Can't have multiple values for 'disabled'"),
    }
}

fn from_string_inner(ast: &syn::DeriveInput) -> quote::Tokens {
    let name = &ast.ident;
    let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
    let variants = match ast.body {
        syn::Body::Enum(ref v) => v,
        _ => panic!("FromString only works on Enums"),
    };

    let mut has_default = false;
    let mut default = quote! { _ => Err(strum::ParseError::VariantNotFound) };
    let mut arms = Vec::new();
    for variant in variants {
        use syn::VariantData::*;
        let ident = &variant.ident;

        // Look at all the serialize attributes.
        let mut attrs = extract_attrs(&variant.attrs, "strum", "serialize");
        if is_disabled(&variant.attrs) {
            continue;
        }

        if let Some("true") = unique_attr(&variant.attrs, "strum", "default") {
            if has_default {
                panic!("Can't have multiple default variants");
            }

            if let Tuple(ref fields) = variant.data {
                if fields.len() != 1 {
                    panic!("Default only works on unit structs with a single String parameter");
                }

                default = quote!{
                    default => Ok(#name::#ident (default.into()))
                };
            } else {
                panic!("Default only works on unit structs with a single String parameter");
            }

            has_default = true;
            continue;
        }

        // If we don't have any custom variants, add the default name.
        if attrs.len() == 0 {
            attrs.push(ident.as_ref());
        }

        let params = match variant.data {
            Unit => quote::Ident::from(""),
            Tuple(ref fields) => {
                let default = fields.iter()
                    .map(|_| "Default::default()")
                    .collect::<Vec<_>>()
                    .join(", ");

                quote::Ident::from(&*format!("({})", default))
            }
            Struct(ref fields) => {
                let default = fields.iter()
                    .map(|field| {
                        format!("{}:{}", field.ident.as_ref().unwrap(), "Default::default()")
                    })
                    .collect::<Vec<_>>()
                    .join(", ");

                quote::Ident::from(&*format!("{{{}}}", default))
            }
        };

        arms.push(quote!{ #(#attrs)|* => Ok(#name::#ident #params) });
    }

    arms.push(default);

    quote!{
        impl #impl_generics std::str::FromStr for #name #ty_generics #where_clause {
            type Err = strum::ParseError;
            fn from_str(s: &str) -> Result< #name #ty_generics , strum::ParseError> {
                match s {
                    #(#arms),*
                }
            }
        }
    }
}

fn enum_iter_inner(ast: &syn::DeriveInput) -> quote::Tokens {
    let name = &ast.ident;
    let gen = &ast.generics;
    let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
    let vis = &ast.vis;

    if gen.lifetimes.len() > 0 {
        panic!("Enum Iterator isn't supported on Enums with lifetimes. The resulting enums would \
                be unbounded.");
    }

    let phantom_data = if gen.ty_params.len() > 0 {
        quote!{ #ty_generics}
    } else {
        quote! { < () > }
    };

    let variants = match ast.body {
        syn::Body::Enum(ref v) => v,
        _ => panic!("EnumIter only works on Enums"),
    };

    let mut arms = Vec::new();
    let enabled = variants.iter().filter(|variant| !is_disabled(&variant.attrs));

    for (idx, variant) in enabled.enumerate() {
        use syn::VariantData::*;
        let ident = &variant.ident;
        let params = match variant.data {
            Unit => quote::Ident::from(""),
            Tuple(ref fields) => {
                let default = fields.iter()
                    .map(|_| "Default::default()")
                    .collect::<Vec<_>>()
                    .join(", ");

                quote::Ident::from(&*format!("({})", default))
            }
            Struct(ref fields) => {
                let default = fields.iter()
                    .map(|field| {
                        format!("{}:{}", field.ident.as_ref().unwrap(), "Default::default()")
                    })
                    .collect::<Vec<_>>()
                    .join(", ");

                quote::Ident::from(&*format!("{{{}}}", default))
            }
        };

        arms.push(quote!{#idx => Some(#name::#ident #params)});
    }

    arms.push(quote! { _ => None });
    let iter_name = quote::Ident::from(&*format!("{}Iter", name));
    quote!{
        #vis struct #iter_name #ty_generics {
            idx: usize,
            marker: std::marker::PhantomData #phantom_data,
        }

        impl #impl_generics strum::IntoEnumIterator for #name #ty_generics #where_clause {
            type Iterator = #iter_name #ty_generics;
            fn iter() -> #iter_name #ty_generics {
                #iter_name {
                    idx:0,
                    marker: std::marker::PhantomData,
                }
            }
        }

        impl #impl_generics Iterator for #iter_name #ty_generics #where_clause {
            type Item = #name #ty_generics;

            fn next(&mut self) -> Option<#name #ty_generics> {
                use std::default::Default;
                let output = match self.idx {
                    #(#arms),*
                };

                self.idx += 1;
                output
            }
        }
    }
}

fn enum_message_inner(ast: &syn::DeriveInput) -> quote::Tokens {
    let name = &ast.ident;
    let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
    let variants = match ast.body {
        syn::Body::Enum(ref v) => v,
        _ => panic!("EnumHelp only works on Enums"),
    };

    let mut arms = Vec::new();
    let mut detailed_arms = Vec::new();
    let mut serializations = Vec::new();

    for variant in variants {
        let messages = unique_attr(&variant.attrs, "strum", "message");
        let detailed_messages = unique_attr(&variant.attrs, "strum", "detailed_message");
        let ident = &variant.ident;

        use syn::VariantData::*;
        let params = match variant.data {
            Unit => quote::Ident::from(""),
            Tuple(..) => quote::Ident::from("(..)"),
            Struct(..) => quote::Ident::from("{..}"),
        };

        // You can't disable getting the serializations.
        {
            let mut serialization_variants = extract_attrs(&variant.attrs, "strum", "serialize");
            if serialization_variants.len() == 0 {
                serialization_variants.push(ident.as_ref());
            }

            let count = serialization_variants.len();
            serializations.push(quote!{
                &#name::#ident #params => {
                    static ARR: [&'static str; #count] = [#(#serialization_variants),*];
                    &ARR
                }
            });
        }

        // But you can disable the messages.
        if is_disabled(&variant.attrs) {
            continue;
        }

        if let Some(msg) = messages {
            let params = params.clone();

            // Push the simple message.
            let tokens = quote!{ &#name::#ident #params => Some(#msg) };
            arms.push(tokens.clone());

            if detailed_messages.is_none() {
                detailed_arms.push(tokens);
            }
        }

        if let Some(msg) = detailed_messages {
            let params = params.clone();
            // Push the simple message.
            detailed_arms.push(quote!{ &#name::#ident #params => Some(#msg) });
        }
    }

    if arms.len() < variants.len() {
        arms.push(quote!{ _ => None });
    }

    if detailed_arms.len() < variants.len() {
        detailed_arms.push(quote!{ _ => None });
    }

    quote!{
        impl #impl_generics strum::EnumMessage for #name #ty_generics #where_clause {
            fn get_message(&self) -> Option<&str> {
                match self {
                    #(#arms),*
                }
            }

            fn get_detailed_message(&self) -> Option<&str> {
                match self {
                    #(#detailed_arms),*
                }
            }

            fn get_serializations(&self) -> &[&str] {
                match self {
                    #(#serializations),*
                }
            }
        }
    }
}
<commit_msg>strum_macros: absolutize type paths<commit_after>//! # Strum
//!
//! Strum is a set of macros and traits for working with
//! enums and strings easier in Rust.
//!
//! # Documentation
//!
//! The documentation for this crate is found in the `strum` crate.

extern crate syn;
#[macro_use]
extern crate quote;
extern crate proc_macro;

use proc_macro::TokenStream;
use syn::Attribute;
use std::env;

#[proc_macro_derive(EnumString,attributes(strum))]
pub fn from_string(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();

    let toks = from_string_inner(&ast);
    debug_print_generated(&ast, &toks);
    toks.parse().unwrap()
}

#[proc_macro_derive(EnumIter,attributes(strum))]
pub fn enum_iter(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();

    let toks = enum_iter_inner(&ast);
    debug_print_generated(&ast, &toks);
    toks.parse().unwrap()
}

#[proc_macro_derive(EnumMessage,attributes(strum))]
pub fn enum_messages(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();

    let toks = enum_message_inner(&ast);
    debug_print_generated(&ast, &toks);
    toks.parse().unwrap()
}

fn debug_print_generated(ast: &syn::DeriveInput, toks: &quote::Tokens) {
    let ident = ast.ident.as_ref();
    let debug = env::var("STRUM_DEBUG");
    if let Ok(s) = debug {
        if s == "1" {
            println!("{}", toks);
        }

        if s == ident {
            println!("{}", toks);
        }
    }
}

fn extract_attrs<'a>(attrs: &'a [Attribute], attr: &str, prop: &str) -> Vec<&'a str> {
    attrs.iter()
        // Get all the attributes with our tag on them.
        .filter_map(|attribute| {
            use syn::MetaItem::*;
            if let List(ref i, ref nested) = attribute.value {
                if i == attr { Some(nested) } else { None }
            } else {
                None
            }
        })
        .flat_map(|nested| nested)
        // Get all the inner elements as long as they start with ser.
        .filter_map(|attribute| {
            use syn::NestedMetaItem::*;
            use syn::MetaItem::*;
            if let &MetaItem(NameValue(ref i, syn::Lit::Str(ref s, ..))) = attribute {
                if i == prop { Some(&**s) } else { None }
            } else {
                None
            }
        }).collect()
}

fn unique_attr<'a>(attrs: &'a [Attribute], attr: &str, prop: &str) -> Option<&'a str> {
    let mut curr = extract_attrs(attrs, attr, prop);
    if curr.len() > 1 {
        panic!("More than one property: {} found on variant", prop);
    }

    curr.pop()
}

fn is_disabled(attrs: &[Attribute]) -> bool {
    let v = extract_attrs(attrs, "strum", "disabled");
    match v.len() {
        0 => false,
        1 => v[0] == "true",
        _ => panic!("Can't have multiple values for 'disabled'"),
    }
}

fn from_string_inner(ast: &syn::DeriveInput) -> quote::Tokens {
    let name = &ast.ident;
    let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
    let variants = match ast.body {
        syn::Body::Enum(ref v) => v,
        _ => panic!("FromString only works on Enums"),
    };

    let mut has_default = false;
    let mut default = quote! { _ => ::std::result::Result::Err(::strum::ParseError::VariantNotFound) };
    let mut arms = Vec::new();
    for variant in variants {
        use syn::VariantData::*;
        let ident = &variant.ident;

        // Look at all the serialize attributes.
        let mut attrs = extract_attrs(&variant.attrs, "strum", "serialize");
        if is_disabled(&variant.attrs) {
            continue;
        }

        if let Some("true") = unique_attr(&variant.attrs, "strum", "default") {
            if has_default {
                panic!("Can't have multiple default variants");
            }

            if let Tuple(ref fields) = variant.data {
                if fields.len() != 1 {
                    panic!("Default only works on unit structs with a single String parameter");
                }

                default = quote!{
                    default => ::std::result::Result::Ok(#name::#ident (default.into()))
                };
            } else {
                panic!("Default only works on unit structs with a single String parameter");
            }

            has_default = true;
            continue;
        }

        // If we don't have any custom variants, add the default name.
        if attrs.len() == 0 {
            attrs.push(ident.as_ref());
        }

        let params = match variant.data {
            Unit => quote::Ident::from(""),
            Tuple(ref fields) => {
                let default = fields.iter()
                    .map(|_| "Default::default()")
                    .collect::<Vec<_>>()
                    .join(", ");

                quote::Ident::from(&*format!("({})", default))
            }
            Struct(ref fields) => {
                let default = fields.iter()
                    .map(|field| {
                        format!("{}:{}", field.ident.as_ref().unwrap(), "Default::default()")
                    })
                    .collect::<Vec<_>>()
                    .join(", ");

                quote::Ident::from(&*format!("{{{}}}", default))
            }
        };

        arms.push(quote!{ #(#attrs)|* => ::std::result::Result::Ok(#name::#ident #params) });
    }

    arms.push(default);

    quote!{
        impl #impl_generics ::std::str::FromStr for #name #ty_generics #where_clause {
            type Err = ::strum::ParseError;
            fn from_str(s: &str) -> ::std::result::Result< #name #ty_generics , Self::Err> {
                match s {
                    #(#arms),*
                }
            }
        }
    }
}

fn enum_iter_inner(ast: &syn::DeriveInput) -> quote::Tokens {
    let name = &ast.ident;
    let gen = &ast.generics;
    let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
    let vis = &ast.vis;

    if gen.lifetimes.len() > 0 {
        panic!("Enum Iterator isn't supported on Enums with lifetimes. The resulting enums would \
                be unbounded.");
    }

    let phantom_data = if gen.ty_params.len() > 0 {
        quote!{ #ty_generics}
    } else {
        quote! { < () > }
    };

    let variants = match ast.body {
        syn::Body::Enum(ref v) => v,
        _ => panic!("EnumIter only works on Enums"),
    };

    let mut arms = Vec::new();
    let enabled = variants.iter().filter(|variant| !is_disabled(&variant.attrs));

    for (idx, variant) in enabled.enumerate() {
        use syn::VariantData::*;
        let ident = &variant.ident;
        let params = match variant.data {
            Unit => quote::Ident::from(""),
            Tuple(ref fields) => {
                let default = fields.iter()
                    .map(|_| "Default::default()")
                    .collect::<Vec<_>>()
                    .join(", ");

                quote::Ident::from(&*format!("({})", default))
            }
            Struct(ref fields) => {
                let default = fields.iter()
                    .map(|field| {
                        format!("{}:{}", field.ident.as_ref().unwrap(), "Default::default()")
                    })
                    .collect::<Vec<_>>()
                    .join(", ");

                quote::Ident::from(&*format!("{{{}}}", default))
            }
        };

        arms.push(quote!{#idx => ::std::option::Option::Some(#name::#ident #params)});
    }

    arms.push(quote! { _ => ::std::option::Option::None });
    let iter_name = quote::Ident::from(&*format!("{}Iter", name));
    quote!{
        #vis struct #iter_name #ty_generics {
            idx: usize,
            marker: ::std::marker::PhantomData #phantom_data,
        }

        impl #impl_generics strum::IntoEnumIterator for #name #ty_generics #where_clause {
            type Iterator = #iter_name #ty_generics;
            fn iter() -> #iter_name #ty_generics {
                #iter_name {
                    idx:0,
                    marker: std::marker::PhantomData,
                }
            }
        }

        impl #impl_generics Iterator for #iter_name #ty_generics #where_clause {
            type Item = #name #ty_generics;

            fn next(&mut self) -> Option<#name #ty_generics> {
                use std::default::Default;
                let output = match self.idx {
                    #(#arms),*
                };

                self.idx += 1;
                output
            }
        }
    }
}

fn enum_message_inner(ast: &syn::DeriveInput) -> quote::Tokens {
    let name = &ast.ident;
    let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
    let variants = match ast.body {
        syn::Body::Enum(ref v) => v,
        _ => panic!("EnumHelp only works on Enums"),
    };

    let mut arms = Vec::new();
    let mut detailed_arms = Vec::new();
    let mut serializations = Vec::new();

    for variant in variants {
        let messages = unique_attr(&variant.attrs, "strum", "message");
        let detailed_messages = unique_attr(&variant.attrs, "strum", "detailed_message");
        let ident = &variant.ident;

        use syn::VariantData::*;
        let params = match variant.data {
            Unit => quote::Ident::from(""),
            Tuple(..) => quote::Ident::from("(..)"),
            Struct(..) => quote::Ident::from("{..}"),
        };

        // You can't disable getting the serializations.
        {
            let mut serialization_variants = extract_attrs(&variant.attrs, "strum", "serialize");
            if serialization_variants.len() == 0 {
                serialization_variants.push(ident.as_ref());
            }

            let count = serialization_variants.len();
            serializations.push(quote!{
                &#name::#ident #params => {
                    static ARR: [&'static str; #count] = [#(#serialization_variants),*];
                    &ARR
                }
            });
        }

        // But you can disable the messages.
        if is_disabled(&variant.attrs) {
            continue;
        }

        if let Some(msg) = messages {
            let params = params.clone();

            // Push the simple message.
            let tokens = quote!{ &#name::#ident #params => ::std::option::Option::Some(#msg) };
            arms.push(tokens.clone());

            if detailed_messages.is_none() {
                detailed_arms.push(tokens);
            }
        }

        if let Some(msg) = detailed_messages {
            let params = params.clone();
            // Push the simple message.
            detailed_arms.push(quote!{ &#name::#ident #params => ::std::option::Option::Some(#msg) });
        }
    }

    if arms.len() < variants.len() {
        arms.push(quote!{ _ => ::std::option::Option::None });
    }

    if detailed_arms.len() < variants.len() {
        detailed_arms.push(quote!{ _ => ::std::option::Option::None });
    }

    quote!{
        impl #impl_generics ::strum::EnumMessage for #name #ty_generics #where_clause {
            fn get_message(&self) -> ::std::option::Option<&str> {
                match self {
                    #(#arms),*
                }
            }

            fn get_detailed_message(&self) -> ::std::option::Option<&str> {
                match self {
                    #(#detailed_arms),*
                }
            }

            fn get_serializations(&self) -> &[&str] {
                match self {
                    #(#serializations),*
                }
            }
        }
    }
}
<|endoftext|>


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

#[macro_use]
extern crate lazy_static;
pub fn get_number<P: AsRef<Path>>(filename: P) -> io::Result<u32> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"NUMBER=(\d+)").unwrap();
    }
    if let Ok(lines) = read_lines(filename) {
        for line in lines {
            if let Some(n) = RE.captures(&line) {
                return Ok(n.get(1).unwrap().as_str().parse().unwrap());
            }
        }
    }
    Ok(0)
}

fn read_lines<P: AsRef<Path>>(filename: P) -> io::Result<impl Iterator<Item = String>> {
    let file = File::open(filename)?;
    return Ok(io::BufReader::new(file).lines().map(|line|
        line.unwrap()
    ));
}

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

    #[test]
    fn get_test_number() {
        assert_eq!(get_number("../data/test.txt").unwrap() , 3);
    }
}
<commit_msg>Working with lifelimes. do not understand it yet<commit_after>use std::fs::File;
use std::io::{self, BufRead};
use std::path::Path;
use regex::Regex;

#[macro_use]
extern crate lazy_static;
pub fn get_number<P: AsRef<Path>>(filename: P) -> io::Result<u32> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"NUMBER=(\d+)").unwrap();
    }
    let mut matches = match_lines(filename, &RE)?;
    return Ok(matches.next().unwrap().parse().unwrap());
}

fn match_lines<P: AsRef<Path>>(filename: P, regex: &'static Regex) -> io::Result<impl Iterator<Item = String>> {
    let lines = read_lines(filename)?;
    let matches = lines.filter_map(move |line| regex.captures(&line).map(|captures| captures[1].to_string()));
    Ok(matches)
}

fn read_lines<P: AsRef<Path>>(filename: P) -> io::Result<impl Iterator<Item = String>> {
    let file = File::open(filename)?;
    return Ok(io::BufReader::new(file).lines().map(|line|
        line.unwrap()
    ));
}

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

    #[test]
    fn get_test_number() {
        assert_eq!(get_number("../data/test.txt").unwrap() , 3);
    }
}
<|endoftext|>


<commit_before>// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

//! Request boundary validator

use std::mem;

pub fn extract_requests(buf: &[u8]) -> (Vec<String>, usize) {
	let utf8 = match String::from_utf8(buf.to_vec()) {
		Ok(val) => val,
		Err(_) => { return (Vec::new(), 0) }
	};

	let mut str_buf = String::new();
	let mut depth = 0;
	let mut res = Vec::new();
	let mut last_req = 0;
	let mut in_str = false;
	let mut is_escaped = false;
	let mut ever_started = false;

	for (idx, char) in utf8.char_indices() {
		str_buf.push(char);

		if (char == '{' || char == '[') && !in_str {
			if depth == 0 {
				ever_started = true;
			}
			depth += 1;
		}
		else if (char == '}' || char == ']') && !in_str {
			depth -= 1;
		}
		else if char == '"' && !is_escaped {
			in_str = !in_str;
		}
		else if char == '\\' && is_escaped && !in_str {
			is_escaped = !is_escaped;
		}

		if depth == 0 && str_buf.len() > 0 {
			if ever_started {
				res.push(mem::replace(&mut str_buf, String::new()));
			}
			ever_started = false;
			last_req = idx;
		}
	}

	(res, last_req)
}

#[test]
fn can_extract_request() {
	let buf = b"{ \"val\" : 1 } ffuuu";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "{ \"val\" : 1 }");
}

#[test]
fn can_extract_requests() {
	let buf = b"{ \"val\" : 1 }{ \"val2\" : 2 }";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "{ \"val\" : 1 }");
	assert_eq!(res.0[1], "{ \"val2\" : 2 }");
}

#[test]
fn can_extract_requests_with_slash() {
	let buf = b"{ \"va\\l\" : 1 }{ \"va\\l2\" : 2 }";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "{ \"va\\l\" : 1 }");
	assert_eq!(res.0[1], "{ \"va\\l2\" : 2 }");
}

#[test]
fn can_extract_requests_with_brackets() {
	let buf = b"[{ \"val_s1\" : 10 }{ \"val_s2\" : 20 }]";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "[{ \"val_s1\" : 10 }{ \"val_s2\" : 20 }]");
}

#[test]
fn can_extract_requests_with_braces() {
	let buf = b"{ \"va{l\" : 1 }{ \"va}l2\" : 2 }";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "{ \"va{l\" : 1 }");
	assert_eq!(res.0[1], "{ \"va}l2\" : 2 }");
}

#[test]
fn can_extract_vitro1() {
	let buf = b"[{\"jsonrpc\":\"2.0\",\"id\":\"3a3472c0-c7be-4070-a05c-8042c0a94892\",\"method\":\"eth_accounts\",\"params\":[]}][{\"jsonrpc\":\"2.0\",\"id\":\"a7329aff-888e-4aa7-a925-651c9545f356\",\"method\":\"net_peerCount\",\"params\":[]}]";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "[{\"jsonrpc\":\"2.0\",\"id\":\"3a3472c0-c7be-4070-a05c-8042c0a94892\",\"method\":\"eth_accounts\",\"params\":[]}]");
	assert_eq!(res.0[1], "[{\"jsonrpc\":\"2.0\",\"id\":\"a7329aff-888e-4aa7-a925-651c9545f356\",\"method\":\"net_peerCount\",\"params\":[]}]");
}
<commit_msg>Faster validator (#52)<commit_after>// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

//! Request boundary validator

pub fn extract_requests(buf: &[u8]) -> (Vec<String>, usize) {
	let mut depth = 0;
	let mut res = Vec::new();
	let mut last_req = 0;
	let mut in_str = false;
	let mut is_escaped = false;
	let mut start_idx = 0;

	for (idx, &byte) in buf.iter().enumerate() {
		if (byte == b'{' || byte == b'[') && !in_str {
			if depth == 0 {
				start_idx = idx;
			}
			depth += 1;
		}
		else if (byte == b'}' || byte == b']') && !in_str {
			depth -= 1;
		}
		else if byte == b'"' && !is_escaped {
			in_str = !in_str;
		}
		else if byte == b'\\' && is_escaped && !in_str {
			is_escaped = !is_escaped;
		}

		if depth == 0 && idx != start_idx {
			let slice = &buf[start_idx .. idx + 1];
			let req = match String::from_utf8(slice.to_vec()) {
				Ok(val) => val,
				Err(_) => return (res, last_req)
			};

			res.push(req);

			last_req = idx;
		}
	}

	(res, last_req)
}

#[test]
fn can_extract_request() {
	let buf = b"{ \"val\" : 1 } ffuuu";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "{ \"val\" : 1 }");
}

#[test]
fn can_extract_requests() {
	let buf = b"{ \"val\" : 1 }{ \"val2\" : 2 }";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "{ \"val\" : 1 }");
	assert_eq!(res.0[1], "{ \"val2\" : 2 }");
}

#[test]
fn can_extract_requests_with_slash() {
	let buf = b"{ \"va\\l\" : 1 }{ \"va\\l2\" : 2 }";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "{ \"va\\l\" : 1 }");
	assert_eq!(res.0[1], "{ \"va\\l2\" : 2 }");
}

#[test]
fn can_extract_requests_with_brackets() {
	let buf = b"[{ \"val_s1\" : 10 }{ \"val_s2\" : 20 }]";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "[{ \"val_s1\" : 10 }{ \"val_s2\" : 20 }]");
}

#[test]
fn can_extract_requests_with_braces() {
	let buf = b"{ \"va{l\" : 1 }{ \"va}l2\" : 2 }";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "{ \"va{l\" : 1 }");
	assert_eq!(res.0[1], "{ \"va}l2\" : 2 }");
}

#[test]
fn can_extract_vitro1() {
	let buf = b"[{\"jsonrpc\":\"2.0\",\"id\":\"3a3472c0-c7be-4070-a05c-8042c0a94892\",\"method\":\"eth_accounts\",\"params\":[]}][{\"jsonrpc\":\"2.0\",\"id\":\"a7329aff-888e-4aa7-a925-651c9545f356\",\"method\":\"net_peerCount\",\"params\":[]}]";
	let res = extract_requests(buf);
	assert_eq!(res.0[0], "[{\"jsonrpc\":\"2.0\",\"id\":\"3a3472c0-c7be-4070-a05c-8042c0a94892\",\"method\":\"eth_accounts\",\"params\":[]}]");
	assert_eq!(res.0[1], "[{\"jsonrpc\":\"2.0\",\"id\":\"a7329aff-888e-4aa7-a925-651c9545f356\",\"method\":\"net_peerCount\",\"params\":[]}]");
}
<|endoftext|>


<commit_before>use std::fmt;
use std::cmp::{max, min};
use world::{HEX_INNER_RADIUS, HEX_OUTER_RADIUS};
use super::{AxialType, DefaultFloat, Point2f};
use std::ops::{Add, Div, Index, IndexMut, Mul, Rem, Sub};
use math::cgmath::{Array, EuclideanSpace, MetricSpace};
use super::AxialVector;
/// A 2-dimensional point in axial coordinates. See [here][hex-blog] for more
/// information.
///
/// [hex-blog]: http://www.redblobgames.com/grids/hexagons/#coordinates
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[repr(C, packed)]
pub struct AxialPoint {
    pub q: AxialType,
    pub r: AxialType,
}
// TODO: implement cgmath::Array
// TODO: implement cgmath::MatricSpace
// TODO: implement cgmath::EuclideanSpace
// TODO: implement ops::{ ... }
// For all of the above, see
// http://bjz.github.io/cgmath/cgmath/struct.Point2.html
//
impl AxialPoint {
    pub fn new(q: AxialType, r: AxialType) -> Self {
        AxialPoint { q: q, r: r }
    }
    /// Returns the position of the hexagons center in the standard coordinate
    /// system using `world::{HEX_INNER_RADIUS, HEX_OUTER_RADIUS}`.
    pub fn to_real(&self) -> Point2f {
        Point2f {
            x: ((2 * self.q + self.r) as DefaultFloat) * HEX_INNER_RADIUS,
            y: (self.r as DefaultFloat) * (3.0 / 2.0) * HEX_OUTER_RADIUS,
        }
    }
    /// Return the AxailPoint from a Point2f
    pub fn from_real(real: Point2f) -> Self {
        let q: f32 = (real.x * ::math::SQRT_3 / 3.0 - real.y / 3.0) / HEX_OUTER_RADIUS;
        let r: f32 = (real.y * 2.0 / 3.0) / HEX_OUTER_RADIUS;

        let y: f32 = -q - r;

        // Rounding
        let mut rx: i32 = (q + 0.5) as i32;
        let ry: i32 = (y + 0.5) as i32;
        let mut rz: i32 = (r + 0.5) as i32;

        // To test the right rounding
        let x_diff = (rx as f32 - q).abs();
        let y_diff = (ry as f32 - y).abs();
        let z_diff = (rz as f32 - r).abs();
        if x_diff > y_diff && x_diff > z_diff {
            rx = -ry - rz;
        } else if !(y_diff > z_diff) {
            rz = -rx - ry;
        }

        AxialPoint { q: rx, r: rz }
    }
    /// Returns the `s` component of corresponding cube coordinates. In cube
    /// coordinates 'q + r + s = 0', so saving `s` is redundant and can be
    /// calculated on the fly when needed.
    pub fn s(&self) -> AxialType {
        -self.q - self.r
    }
}
impl fmt::Debug for AxialPoint {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_tuple("")
            .field(&self.q)
            .field(&self.r)
            .finish()
    }
}
/// ********************Basic Arithmetics************
impl Add<AxialVector> for AxialPoint {
    type Output = AxialPoint;
    fn add(self, rhs: AxialVector) -> AxialPoint {
        AxialPoint {
            q: self.q + rhs.q,
            r: self.r + rhs.r,
        }
    }
}
impl Sub<AxialPoint> for AxialPoint {
    type Output = AxialVector;
    fn sub(self, rhs: AxialPoint) -> AxialVector {
        AxialVector {
            q: self.q - rhs.q,
            r: self.r - rhs.r,
        }
    }
}
impl Mul<AxialType> for AxialPoint {
    type Output = AxialPoint;
    fn mul(self, rhs: AxialType) -> AxialPoint {
        AxialPoint {
            q: self.q * rhs,
            r: self.r * rhs,
        }
    }
}
impl Div<AxialType> for AxialPoint {
    type Output = AxialPoint;
    fn div(self, rhs: AxialType) -> AxialPoint {
        AxialPoint {
            q: self.q / rhs,
            r: self.r / rhs,
        }
    }
}
impl Rem<AxialType> for AxialPoint {
    type Output = AxialPoint;
    fn rem(self, d: AxialType) -> AxialPoint {
        AxialPoint {
            q: self.q % d,
            r: self.r % d,
        }
    }
}
/// ********************Index************
impl Index<usize> for AxialPoint {
    type Output = AxialType;
    fn index(&self, index: usize) -> &AxialType {
        match index {
            0 => &self.q,
            1 => &self.r,
            _ => panic!("Index out of bounds!"),
        }
    }
}
impl IndexMut<usize> for AxialPoint {
    fn index_mut(&mut self, index: usize) -> &mut AxialType {
        match index {
            0 => &mut self.q,
            1 => &mut self.r,
            _ => panic!("Index out of bounds!"),
        }
    }
}
/// ********************Array************
impl Array for AxialPoint {
    type Element = AxialType;
    fn from_value(x: AxialType) -> AxialPoint {
        AxialPoint { q: x, r: x }
    }
    fn sum(self) -> AxialType {
        self.q + self.r
    }
    fn product(self) -> AxialType {
        self.q * self.r
    }
    fn min(self) -> AxialType {
        min(self.q, self.r)
    }
    fn max(self) -> AxialType {
        max(self.q, self.r)
    }
}
/// ******************* Metric-Space************************
impl MetricSpace for AxialPoint {
    type Metric = f32;
    fn distance2(self, other: AxialPoint) -> Self::Metric {
        (((self.q - other.q) * (self.q - other.q)) +
         ((self.r - other.r) * (self.r - other.r))) as f32
    }
}
/// ******************* EuclideanSpace**********************
impl EuclideanSpace for AxialPoint {
    type Scalar = i32;
    type Diff = AxialVector;
    fn origin() -> Self {
        AxialPoint { q: 0, r: 0 }
    }
    fn from_vec(v: Self::Diff) -> Self {
        AxialPoint { q: v.q, r: v.r }
    }
    fn to_vec(self) -> Self::Diff {
        AxialVector {
            q: self.q,
            r: self.r,
        }
    }
    fn dot(self, v: Self::Diff) -> Self::Scalar {
        (self.q * v.q) + (self.r * v.r)
    }
}

#[test]
fn arithmetic_test_point() {
    let a: AxialPoint = AxialPoint { q: 5, r: 7 };
    let b: AxialPoint = AxialPoint { q: -2, r: 0 };
    let v: AxialVector = AxialVector { q: 8, r: 1 };
    assert!(a.add(v) == AxialPoint { q: 13, r: 8 });
    assert!(a.sub(b) == AxialVector { q: 7, r: 7 });
    assert!(b.mul(4) == AxialPoint { q: -8, r: 0 });
    assert!(b.div(2) == AxialPoint { q: -1, r: 0 });
    assert!(a.rem(3) == AxialPoint { q: 2, r: 1 });
}
#[test]
fn index_test_point() {
    let a: AxialPoint = AxialPoint { q: 5, r: 7 };
    let mut b: AxialPoint = AxialPoint { q: -2, r: 0 };
    assert!(a[0] == 5);
    assert!(a[1] == 7);
    b[0] = 5;
    b[1] = 5;
    assert!(b.q == 5 && b.r == 5);
}
#[test]
fn array_test_point() {
    let a = AxialPoint::from_value(7);
    let b: AxialPoint = AxialPoint { q: 5, r: 7 };
    assert!(a.q == 7 && a.r == 7);
    assert!(a.sum() == 14);
    assert!(a.product() == 49);
    assert!(b.min() == 5);
    assert!(b.max() == 7);
}
#[test]
fn meticspace_test_point() {
    let a = AxialPoint { q: 0, r: 0 };
    let b = AxialPoint { q: 1, r: 1 };
    assert!(a.distance2(b) == 2.0);
}
#[test]
fn euclideanspace_test_point() {
    let v: AxialVector = AxialVector { q: 8, r: 1 };
    let a = AxialPoint { q: 1, r: 1 };
    assert!(AxialPoint::from_vec(v) == AxialPoint { q: 8, r: 1 });
    assert!(a.to_vec() == AxialVector { q: 1, r: 1 });
    assert!(a.dot(v) == 9);
}
<commit_msg>fixed<commit_after>use std::fmt;
use std::cmp::{max, min};
use world::{HEX_INNER_RADIUS, HEX_OUTER_RADIUS};
use super::{AxialType, DefaultFloat, Point2f};
use std::ops::{Add, Div, Index, IndexMut, Mul, Rem, Sub};
use math::cgmath::{Array, EuclideanSpace, MetricSpace};
use super::AxialVector;
/// A 2-dimensional point in axial coordinates. See [here][hex-blog] for more
/// information.
///
/// [hex-blog]: http://www.redblobgames.com/grids/hexagons/#coordinates
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[repr(C, packed)]
pub struct AxialPoint {
    pub q: AxialType,
    pub r: AxialType,
}
// TODO: implement cgmath::Array
// TODO: implement cgmath::MatricSpace
// TODO: implement cgmath::EuclideanSpace
// TODO: implement ops::{ ... }
// For all of the above, see
// http://bjz.github.io/cgmath/cgmath/struct.Point2.html
//
impl AxialPoint {
    pub fn new(q: AxialType, r: AxialType) -> Self {
        AxialPoint { q: q, r: r }
    }

    /// Returns the position of the hexagons center in the standard coordinate
    /// system using `world::{HEX_INNER_RADIUS, HEX_OUTER_RADIUS}`.
    pub fn to_real(&self) -> Point2f {
        Point2f {
            x: ((2 * self.q + self.r) as DefaultFloat) * HEX_INNER_RADIUS,
            y: (self.r as DefaultFloat) * (3.0 / 2.0) * HEX_OUTER_RADIUS,
        }
    }

    /// Return the `AxailPoint´ from a Point2f
    pub fn from_real(real: Point2f) -> Self {
        let q: f32 = (real.x * ::math::SQRT_3 / 3.0 - real.y / 3.0) / HEX_OUTER_RADIUS;
        let r: f32 = (real.y * 2.0 / 3.0) / HEX_OUTER_RADIUS;

        let y: f32 = -q - r;

        // Rounding
        let mut rx: i32 = (q + 0.5) as i32;
        let ry: i32 = (y + 0.5) as i32;
        let mut rz: i32 = (r + 0.5) as i32;

        // To test the right rounding
        let x_diff = (rx as f32 - q).abs();
        let y_diff = (ry as f32 - y).abs();
        let z_diff = (rz as f32 - r).abs();
        if x_diff > y_diff && x_diff > z_diff {
            rx = -ry - rz;
        } else if y_diff <= z_diff {
            rz = -rx - ry;
        }

        AxialPoint { q: rx, r: rz }
    }

    /// Returns the `s` component of corresponding cube coordinates. In cube
    /// coordinates 'q + r + s = 0', so saving `s` is redundant and can be
    /// calculated on the fly when needed.
    pub fn s(&self) -> AxialType {
        -self.q - self.r
    }
}
impl fmt::Debug for AxialPoint {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_tuple("")
            .field(&self.q)
            .field(&self.r)
            .finish()
    }
}
/// ********************Basic Arithmetics************
impl Add<AxialVector> for AxialPoint {
    type Output = AxialPoint;
    fn add(self, rhs: AxialVector) -> AxialPoint {
        AxialPoint {
            q: self.q + rhs.q,
            r: self.r + rhs.r,
        }
    }
}
impl Sub<AxialPoint> for AxialPoint {
    type Output = AxialVector;
    fn sub(self, rhs: AxialPoint) -> AxialVector {
        AxialVector {
            q: self.q - rhs.q,
            r: self.r - rhs.r,
        }
    }
}
impl Mul<AxialType> for AxialPoint {
    type Output = AxialPoint;
    fn mul(self, rhs: AxialType) -> AxialPoint {
        AxialPoint {
            q: self.q * rhs,
            r: self.r * rhs,
        }
    }
}
impl Div<AxialType> for AxialPoint {
    type Output = AxialPoint;
    fn div(self, rhs: AxialType) -> AxialPoint {
        AxialPoint {
            q: self.q / rhs,
            r: self.r / rhs,
        }
    }
}
impl Rem<AxialType> for AxialPoint {
    type Output = AxialPoint;
    fn rem(self, d: AxialType) -> AxialPoint {
        AxialPoint {
            q: self.q % d,
            r: self.r % d,
        }
    }
}
/// ********************Index************
impl Index<usize> for AxialPoint {
    type Output = AxialType;
    fn index(&self, index: usize) -> &AxialType {
        match index {
            0 => &self.q,
            1 => &self.r,
            _ => panic!("Index out of bounds!"),
        }
    }
}
impl IndexMut<usize> for AxialPoint {
    fn index_mut(&mut self, index: usize) -> &mut AxialType {
        match index {
            0 => &mut self.q,
            1 => &mut self.r,
            _ => panic!("Index out of bounds!"),
        }
    }
}
/// ********************Array************
impl Array for AxialPoint {
    type Element = AxialType;
    fn from_value(x: AxialType) -> AxialPoint {
        AxialPoint { q: x, r: x }
    }
    fn sum(self) -> AxialType {
        self.q + self.r
    }
    fn product(self) -> AxialType {
        self.q * self.r
    }
    fn min(self) -> AxialType {
        min(self.q, self.r)
    }
    fn max(self) -> AxialType {
        max(self.q, self.r)
    }
}
/// ******************* Metric-Space************************
impl MetricSpace for AxialPoint {
    type Metric = f32;
    fn distance2(self, other: AxialPoint) -> Self::Metric {
        (((self.q - other.q) * (self.q - other.q)) +
         ((self.r - other.r) * (self.r - other.r))) as f32
    }
}
/// ******************* EuclideanSpace**********************
impl EuclideanSpace for AxialPoint {
    type Scalar = i32;
    type Diff = AxialVector;
    fn origin() -> Self {
        AxialPoint { q: 0, r: 0 }
    }
    fn from_vec(v: Self::Diff) -> Self {
        AxialPoint { q: v.q, r: v.r }
    }
    fn to_vec(self) -> Self::Diff {
        AxialVector {
            q: self.q,
            r: self.r,
        }
    }
    fn dot(self, v: Self::Diff) -> Self::Scalar {
        (self.q * v.q) + (self.r * v.r)
    }
}

#[test]
fn arithmetic_test_point() {
    let a: AxialPoint = AxialPoint { q: 5, r: 7 };
    let b: AxialPoint = AxialPoint { q: -2, r: 0 };
    let v: AxialVector = AxialVector { q: 8, r: 1 };
    assert!(a.add(v) == AxialPoint { q: 13, r: 8 });
    assert!(a.sub(b) == AxialVector { q: 7, r: 7 });
    assert!(b.mul(4) == AxialPoint { q: -8, r: 0 });
    assert!(b.div(2) == AxialPoint { q: -1, r: 0 });
    assert!(a.rem(3) == AxialPoint { q: 2, r: 1 });
}
#[test]
fn index_test_point() {
    let a: AxialPoint = AxialPoint { q: 5, r: 7 };
    let mut b: AxialPoint = AxialPoint { q: -2, r: 0 };
    assert!(a[0] == 5);
    assert!(a[1] == 7);
    b[0] = 5;
    b[1] = 5;
    assert!(b.q == 5 && b.r == 5);
}
#[test]
fn array_test_point() {
    let a = AxialPoint::from_value(7);
    let b: AxialPoint = AxialPoint { q: 5, r: 7 };
    assert!(a.q == 7 && a.r == 7);
    assert!(a.sum() == 14);
    assert!(a.product() == 49);
    assert!(b.min() == 5);
    assert!(b.max() == 7);
}
#[test]
fn meticspace_test_point() {
    let a = AxialPoint { q: 0, r: 0 };
    let b = AxialPoint { q: 1, r: 1 };
    assert!(a.distance2(b) == 2.0);
}
#[test]
fn euclideanspace_test_point() {
    let v: AxialVector = AxialVector { q: 8, r: 1 };
    let a = AxialPoint { q: 1, r: 1 };
    assert!(AxialPoint::from_vec(v) == AxialPoint { q: 8, r: 1 });
    assert!(a.to_vec() == AxialVector { q: 1, r: 1 });
    assert!(a.dot(v) == 9);
}
<|endoftext|>


<commit_before>//! Asynchronous I/O.
//!
//! This module is the asynchronous version of `std::io`. Primarily, it
//! defines two traits, [`AsyncRead`] and [`AsyncWrite`], which extend the
//! `Read` and `Write` traits of the standard library.
//!
//! # AsyncRead and AsyncWrite
//!
//! [`AsyncRead`] and [`AsyncWrite`] must only be implemented for
//! non-blocking I/O types that integrate with the futures type system. In
//! other words, these types must never block the thread, and instead the
//! current task is notified when the I/O resource is ready.
//!
//! # Standard input and output
//!
//! Tokio provides asynchronous APIs to standard [input], [output], and [error].
//! These APIs are very similar to the ones provided by `std`, but they also
//! implement [`AsyncRead`] and [`AsyncWrite`].
//!
//! Unlike *most* other Tokio APIs, the standard input / output APIs
//! **must** be used from the context of the Tokio runtime as they require
//! Tokio specific features to function.
//!
//! [input]: fn.stdin.html
//! [output]: fn.stdout.html
//! [error]: fn.stderr.html
//!
//! # `std` re-exports
//!
//! Additionally, [`Error`], [`ErrorKind`], and [`Result`] are re-exported
//! from `std::io` for ease of use.
//!
//! [`AsyncRead`]: trait.AsyncRead.html
//! [`AsyncWrite`]: trait.AsyncWrite.html
//! [`Error`]: struct.Error.html
//! [`ErrorKind`]: enum.ErrorKind.html
//! [`Result`]: type.Result.html

cfg_io_blocking! {
    pub(crate) mod blocking;
}

mod async_buf_read;
pub use self::async_buf_read::AsyncBufRead;

mod async_read;
pub use self::async_read::AsyncRead;

mod async_write;
pub use self::async_write::AsyncWrite;

cfg_io_driver! {
    pub(crate) mod driver;

    mod poll_evented;
    pub use poll_evented::PollEvented;

    mod registration;
    pub use registration::Registration;
}

cfg_io_std! {
    mod stderr;
    pub use stderr::{stderr, Stderr};

    mod stdin;
    pub use stdin::{stdin, Stdin};

    mod stdout;
    pub use stdout::{stdout, Stdout};
}

cfg_io_util! {
    mod split;
    pub use split::{split, ReadHalf, WriteHalf};

    pub(crate) mod util;
    pub use util::{
        copy, empty, repeat, sink, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufStream,
        BufWriter, Copy, Empty, Lines, Repeat, Sink, Split, Take,
    };

    // Re-export io::Error so that users don't have to deal with conflicts when
    // `use`ing `tokio::io` and `std::io`.
    pub use std::io::{Error, ErrorKind, Result};
}

cfg_not_io_util! {
    cfg_process! {
        pub(crate) mod util;
    }
}

cfg_io_blocking! {
    /// Types in this module can be mocked out in tests.
    mod sys {
        // TODO: don't rename
        pub(crate) use crate::blocking::spawn_blocking as run;
        pub(crate) use crate::task::JoinHandle as Blocking;
    }
}
<commit_msg>docs: refresh `tokio::io` API docs (#1803)<commit_after>//! Asynchronous I/O.
//!
//! This module is the asynchronous version of `std::io`. Primarily, it
//! defines two traits, [`AsyncRead`] and [`AsyncWrite`], which are asynchronous
//! versions of the [`Read`] and [`Write`] traits in the standard library.
//!
//! # AsyncRead and AsyncWrite
//!
//! Like the standard library's [`Read`] and [`Write`] traits, [`AsyncRead`] and
//! [`AsyncWrite`] provide the most general interface for reading and writing
//! input and output. Unlike the standard library's traits, however, they are
//! _asynchronous_ — meaning that reading from or writing to a `tokio::io`
//! type will _yield_ to the Tokio scheduler when IO is not ready, rather than
//! blocking. This allows other tasks to run while waiting on IO.
//!
//! In asynchronous programs, Tokio's [`AsyncRead`] and [`AsyncWrite`] traits
//! can be used in almost exactly the same manner as the standard library's
//! `Read` and `Write`. Most types in the standard library that implement `Read`
//! and `Write` have asynchronous equivalents in `tokio` that implement
//! `AsyncRead` and `AsyncWrite`, such as [`File`] and [`TcpStream`].
//!
//! For example, the standard library documentation introduces `Read` by
//! [demonstrating][std_example] reading some bytes from a [`std::fs::File`]. We
//! can do the same with [`tokio::fs::File`][`File`]:
//!
//! ```no_run
//! use tokio::io;
//! use tokio::prelude::*;
//! use tokio::fs::File;
//!
//! #[tokio::main]
//! async fn main() -> io::Result<()> {
//!     let mut f = File::open("foo.txt").await?;
//!     let mut buffer = [0; 10];
//!
//!     // read up to 10 bytes
//!     let n = f.read(&mut buffer).await?;
//!
//!     println!("The bytes: {:?}", &buffer[..n]);
//!     Ok(())
//! }
//! ```
//!
//! [`File`]: crate::fs::File
//! [`TcpStream`]: crate::net::TcpStream
//! [`std::fs::File`]: std::fs::File
//! [std_example]: https://doc.rust-lang.org/std/io/index.html#read-and-write
//!
//! ## Buffered Readers and Writers
//!
//! Byte-based interfaces are unwieldy and can be inefficient, as we'd need to be
//! making near-constant calls to the operating system. To help with this,
//! `std::io` comes with [support for _buffered_ readers and writers][stdbuf],
//! and therefore, `tokio::io` does as well.
//!
//! Tokio provides an async version of the [`std::io::BufRead`] trait,
//! [`AsyncBufRead`]; and async [`BufReader`] and [`BufWriter`] structs, which
//! wrap readers and writers. These wrappers use a buffer, reducing the number
//! of calls and providing nicer methods for accessing exactly what you want.
//!
//! For example, [`BufReader`] works with the [`AsyncBufRead`] trait to add
//! extra methods to any async reader:
//!
//! ```no_run
//! use tokio::io;
//! use tokio::io::BufReader;
//! use tokio::fs::File;
//! use tokio::prelude::*;
//!
//! #[tokio::main]
//! async fn main() -> io::Result<()> {
//!     let f = File::open("foo.txt").await?;
//!     let mut reader = BufReader::new(f);
//!     let mut buffer = String::new();
//!
//!     // read a line into buffer
//!     reader.read_line(&mut buffer).await?;
//!
//!     println!("{}", buffer);
//!     Ok(())
//! }
//! ```
//!
//! [`BufWriter`] doesn't add any new ways of writing; it just buffers every call
//! to [`write`](crate::io::AsyncWriteExt::write):
//!
//! ```no_run
//! use tokio::io;
//! use tokio::io::BufWriter;
//! use tokio::fs::File;
//! use tokio::prelude::*;
//!
//! #[tokio::main]
//! async fn main() -> io::Result<()> {
//!     let f = File::create("foo.txt").await?;
//!     {
//!         let mut writer = BufWriter::new(f);
//!
//!         // write a byte to the buffer
//!         writer.write(&[42u8]).await?;
//!
//!     } // the buffer is flushed once writer goes out of scope
//!
//!     Ok(())
//! }
//! ```
//!
//! [stdbuf]: https://doc.rust-lang.org/std/io/index.html#bufreader-and-bufwriter
//! [`std::io::BufRead`]: std::io::BufRead
//! [`AsyncBufRead`]: crate::io::AsyncBufRead
//! [`BufReader`]: crate::io::BufReader
//! [`BufWriter`]: crate::io::BufWriter
//!
//! ## Implementing AsyncRead and AsyncWrite
//!
//! Because they are traits, we can implement `AsyncRead` and `AsyncWrite` for
//! our own types, as well. Note that these traits must only be implemented for
//! non-blocking I/O types that integrate with the futures type system. In
//! other words, these types must never block the thread, and instead the
//! current task is notified when the I/O resource is ready.
//!
//! # Standard input and output
//!
//! Tokio provides asynchronous APIs to standard [input], [output], and [error].
//! These APIs are very similar to the ones provided by `std`, but they also
//! implement [`AsyncRead`] and [`AsyncWrite`].
//!
//! Note that the standard input / output APIs  **must** be used from the
//! context of the Tokio runtime, as they require Tokio-specific features to
//! function. Calling these functions outside of a Tokio runtime will panic.
//!
//! [input]: fn.stdin.html
//! [output]: fn.stdout.html
//! [error]: fn.stderr.html
//!
//! # `std` re-exports
//!
//! Additionally, [`Error`], [`ErrorKind`], and [`Result`] are re-exported
//! from `std::io` for ease of use.
//!
//! [`AsyncRead`]: trait.AsyncRead.html
//! [`AsyncWrite`]: trait.AsyncWrite.html
//! [`Error`]: struct.Error.html
//! [`ErrorKind`]: enum.ErrorKind.html
//! [`Result`]: type.Result.html
//! [`Read`]: std::io::Read
//! [`Write`]: std::io::Write
cfg_io_blocking! {
    pub(crate) mod blocking;
}

mod async_buf_read;
pub use self::async_buf_read::AsyncBufRead;

mod async_read;
pub use self::async_read::AsyncRead;

mod async_write;
pub use self::async_write::AsyncWrite;

cfg_io_driver! {
    pub(crate) mod driver;

    mod poll_evented;
    pub use poll_evented::PollEvented;

    mod registration;
    pub use registration::Registration;
}

cfg_io_std! {
    mod stderr;
    pub use stderr::{stderr, Stderr};

    mod stdin;
    pub use stdin::{stdin, Stdin};

    mod stdout;
    pub use stdout::{stdout, Stdout};
}

cfg_io_util! {
    mod split;
    pub use split::{split, ReadHalf, WriteHalf};

    pub(crate) mod util;
    pub use util::{
        copy, empty, repeat, sink, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufStream,
        BufWriter, Copy, Empty, Lines, Repeat, Sink, Split, Take,
    };

    // Re-export io::Error so that users don't have to deal with conflicts when
    // `use`ing `tokio::io` and `std::io`.
    pub use std::io::{Error, ErrorKind, Result};
}

cfg_not_io_util! {
    cfg_process! {
        pub(crate) mod util;
    }
}

cfg_io_blocking! {
    /// Types in this module can be mocked out in tests.
    mod sys {
        // TODO: don't rename
        pub(crate) use crate::blocking::spawn_blocking as run;
        pub(crate) use crate::task::JoinHandle as Blocking;
    }
}
<|endoftext|>


<commit_before>use cocoa::base::{class, id};
use cocoa::foundation::NSUInteger;
use core_foundation::base::CFRange;
use libc::c_void;
use objc::runtime::BOOL;
use {MTLPixelFormat, MTLRegion};

#[cfg(target_os = "macos")]
macro_rules! texture_platform_methods_impl {
    () => {
        unsafe fn ioSurface(self) -> id {
            msg_send![self, ioSurface]
        }
        unsafe fn ioSurfacePlane(self) -> NSUInteger {
            msg_send![self, ioSurfacePlane]
        }
    }
}

#[cfg(target_os = "ios")]
macro_rules! texture_platform_methods_impl {
    () => {
        unsafe fn buffer(self) -> id {
            msg_send![self, buffer]
        }

        unsafe fn bufferOffset(self) -> NSUInteger {
            msg_send![self, bufferOffset]
        }

        unsafe fn bufferBytesPerRow(self) -> id {
            msg_send![self, bufferBytesPerRow]
        }
    }
}

#[cfg(target_os = "macos")]
pub trait MTLTexture {
    unsafe fn replaceRegion_mipmapLevel_slice_withBytes_bytesPerRow_bytesPerImage(
        self, region: MTLRegion, level: NSUInteger, slice: NSUInteger,
        pixelBytes: *const c_void, bytesPerRow: NSUInteger,
        bytesPerImage: NSUInteger);

    unsafe fn replaceRegion_mipmapLevel_withBytes_bytesPerRow(self, region: MTLRegion,
                                                              level: NSUInteger,
                                                              pixelBytes: *const c_void,
                                                              bytesPerRow: NSUInteger);

    unsafe fn getBytes_bytesPerRow_bytesPerImage_fromRegion_mipmapLevel_slice(
        self, pixel_bytes: *mut c_void, bytesPerRow: NSUInteger,
        bytesPerImage: NSUInteger, region: MTLRegion, mipmapLevel: NSUInteger,
        slice: NSUInteger);

    unsafe fn getBytes_bytesPerRow_fromRegion_mipmapLevel(self, pixel_bytes: *mut c_void,
                                                          bytesPerRow: NSUInteger,
                                                          region: MTLRegion,
                                                          mipmapLevel: NSUInteger);

    unsafe fn newTextureViewWithPixelFormat(_: Self, format: MTLPixelFormat) -> id {
        msg_send![class("MTLTexture"), newTextureViewWithPixelFormat:format]
    }

    unsafe fn newTextureViewWithPixelFormat_textureType_levels_slices(
        _: Self, format: MTLPixelFormat, textureType: MTLTextureType,
        levels: CFRange, slices: NSUInteger) -> id {
        msg_send![class("MTLTexture"), newTextureViewWithPixelFormat:format
                                                         textureType:textureType
                                                              levels:levels
                                                              slices:slices]
    }

    unsafe fn textureType(self) -> MTLTextureType;
    unsafe fn pixelFormat(self) -> MTLPixelFormat;
    unsafe fn width(self) -> NSUInteger;
    unsafe fn height(self) -> NSUInteger;
    unsafe fn depth(self) -> NSUInteger;
    unsafe fn mipmapLevelCount(self) -> NSUInteger;
    unsafe fn arrayLength(self) -> NSUInteger;
    unsafe fn sampleCount(self) -> NSUInteger;
    unsafe fn frameBufferOnly(self) -> BOOL;
    unsafe fn rootResource(self) -> id;
    unsafe fn usage(self) -> MTLTextureUsage;

    unsafe fn ioSurface(self) -> id;
    unsafe fn ioSurfacePlane(self) -> NSUInteger;

    unsafe fn parentTexture(self) -> id;
    unsafe fn parentRelativeLevel(self) -> NSUInteger;
    unsafe fn parentRelativeSlice(self) -> NSUInteger;
}

#[cfg(target_os = "ios")]
pub trait MTLTexture {
    unsafe fn replaceRegion_mipmapLevel_slice_withBytes_bytesPerRow_bytesPerImage(
        self, region: MTLRegion, level: NSUInteger, slice: NSUInteger,
        pixelBytes: *const c_void, bytesPerRow: NSUInteger,
        bytesPerImage: NSUInteger);

    unsafe fn replaceRegion_mipmapLevel_withBytes_bytesPerRow(self, region: MTLRegion,
                                                              level: NSUInteger,
                                                              pixelBytes: *mut c_void,
                                                              bytesPerRow: NSUInteger);

    unsafe fn getBytes_bytesPerRow_bytesPerImage_fromRegion_mipmapLevel_slice(
        self, pixel_bytes: *mut c_void, bytesPerRow: NSUInteger,
        bytesPerImage: NSUInteger, region: MTLRegion, mipmapLevel: NSUInteger,
        slice: NSUInteger);

    unsafe fn getBytes_bytesPerRow_fromRegion_mipmapLevel(self, pixel_bytes: *mut c_void,
                                                          bytesPerRow: NSUInteger,
                                                          region: MTLRegion,
                                                          mipmapLevel: NSUInteger);

    unsafe fn newTextureViewWithPixelFormat(format: MTLPixelFormat) -> id {
        msg_send![class("MTLTexture"), newTextureViewWithPixelFormat:format]
    }

    unsafe fn newTextureViewWithPixelFormat_textureType_levels_slices(format: MTLPixelFormat,
                                                                      textureType: MTLTextureType,
                                                                      levels: CFRange,
                                                                      slices: NSUInteger)
                                                                      -> id {
        msg_send![class("MTLTexture"), newTextureViewWithPixelFormat:format
                                                         textureType:textureType
                                                              levels:levels
                                                              slices:slices]
    }

    unsafe fn textureType(self) -> MTLTextureType;
    unsafe fn pixelFormat(self) -> MTLPixelFormat;
    unsafe fn width(self) -> NSUInteger;
    unsafe fn height(self) -> NSUInteger;
    unsafe fn depth(self) -> NSUInteger;
    unsafe fn mipmapLevelCount(self) -> NSUInteger;
    unsafe fn arrayLength(self) -> NSUInteger;
    unsafe fn sampleCount(self) -> NSUInteger;
    unsafe fn frameBufferOnly(self) -> BOOL;
    unsafe fn rootResource(self) -> id;
    unsafe fn usage(self) -> MTLTextureUsage;

    unsafe fn buffer(self) -> id;
    unsafe fn bufferOffset(self) -> NSUInteger;
    unsafe fn bufferBytesPerRow(self) -> NSUInteger;

    unsafe fn parentTexture(self) -> id;
    unsafe fn parentRelativeLevel(self) -> NSUInteger;
    unsafe fn parentRelativeSlice(self) -> NSUInteger;
}

impl MTLTexture for id {
    unsafe fn replaceRegion_mipmapLevel_slice_withBytes_bytesPerRow_bytesPerImage(
        self, region: MTLRegion, level: NSUInteger, slice: NSUInteger,
        pixelBytes: *const c_void, bytesPerRow: NSUInteger,
        bytesPerImage: NSUInteger) {
        msg_send![self, replaceRegion:region
                          mipmapLevel:level
                                slice:slice
                            withBytes:pixelBytes
                          bytesPerRow:bytesPerRow
                        bytesPerImage:bytesPerImage]
    }
    unsafe fn replaceRegion_mipmapLevel_withBytes_bytesPerRow(self, region: MTLRegion,
                                                              level: NSUInteger,
                                                              pixelBytes: *const c_void,
                                                              bytesPerRow: NSUInteger) {
        msg_send![self, replaceRegion:region
                          mipmapLevel:level
                            withBytes:pixelBytes
                          bytesPerRow:bytesPerRow]
    }

    unsafe fn getBytes_bytesPerRow_bytesPerImage_fromRegion_mipmapLevel_slice(
        self, pixelBytes: *mut c_void, bytesPerRow: NSUInteger,
        bytesPerImage: NSUInteger, region: MTLRegion, level: NSUInteger,
        slice: NSUInteger) {
        msg_send![self, getBytes:pixelBytes
                     bytesPerRow:bytesPerRow
                   bytesPerImage:bytesPerImage
                          region:region
                     mipmapLevel:level
                           slice:slice]
    }

    unsafe fn getBytes_bytesPerRow_fromRegion_mipmapLevel(self, pixelBytes: *mut c_void,
                                                          bytesPerRow: NSUInteger,
                                                          region: MTLRegion, level: NSUInteger) {
        msg_send![self, getBytes:pixelBytes
                     bytesPerRow:bytesPerRow
                          region:region
                     mipmapLevel:level]
    }

    unsafe fn textureType(self) -> MTLTextureType {
        msg_send![self, textureType]
    }

    unsafe fn pixelFormat(self) -> MTLPixelFormat {
        msg_send![self, pixelFormat]
    }

    unsafe fn width(self) -> NSUInteger {
        msg_send![self, width]
    }

    unsafe fn height(self) -> NSUInteger {
        msg_send![self, height]
    }

    unsafe fn depth(self) -> NSUInteger {
        msg_send![self, depth]
    }

    unsafe fn mipmapLevelCount(self) -> NSUInteger {
        msg_send![self, mipmapLevelCount]
    }

    unsafe fn arrayLength(self) -> NSUInteger {
        msg_send![self, arrayLength]
    }

    unsafe fn sampleCount(self) -> NSUInteger {
        msg_send![self, sampleCount]
    }

    unsafe fn frameBufferOnly(self) -> BOOL {
        msg_send![self, frameBufferOnly]
    }

    unsafe fn rootResource(self) -> id {
        msg_send![self, rootResource]
    }

    unsafe fn usage(self) -> MTLTextureUsage {
        msg_send![self, usage]
    }

    unsafe fn parentTexture(self) -> id {
        msg_send![self, parentTexture]
    }

    unsafe fn parentRelativeLevel(self) -> NSUInteger {
        msg_send![self, parentRelativeLevel]
    }

    unsafe fn parentRelativeSlice(self) -> NSUInteger {
        msg_send![self, parentRelativeSlice]
    }

    texture_platform_methods_impl!{}
}

#[repr(usize)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum MTLTextureType {
    MTLTextureType1D = 0,
    MTLTextureType1DArray = 1,
    MTLTextureType2D = 2,
    MTLTextureType2DArray = 3,
    MTLTextureType2DMultisample = 4,
    MTLTextureTypeCube = 5,
    MTLTextureType3D = 7
}

#[repr(usize)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum MTLTextureUsage {
    MTLTextureUsageUnknown = 0x0000,
    MTLTextureUsageShaderRead = 0x0001,
    MTLTextureUsageShaderWrite = 0x0002,
    MTLTextureUsageRenderTarget = 0x0004,
    MTLTextureUsagePixelFormatView = 0x0010
}
<commit_msg>Unify MTLTexture trait definition<commit_after>use cocoa::base::{class, id};
use cocoa::foundation::NSUInteger;
use core_foundation::base::CFRange;
use libc::c_void;
use objc::runtime::BOOL;
use {MTLPixelFormat, MTLRegion};

pub trait MTLTexture {
    unsafe fn replaceRegion_mipmapLevel_slice_withBytes_bytesPerRow_bytesPerImage(
        self, region: MTLRegion, level: NSUInteger, slice: NSUInteger,
        pixelBytes: *const c_void, bytesPerRow: NSUInteger,
        bytesPerImage: NSUInteger);

    unsafe fn replaceRegion_mipmapLevel_withBytes_bytesPerRow(self, region: MTLRegion,
                                                              level: NSUInteger,
                                                              pixelBytes: *const c_void,
                                                              bytesPerRow: NSUInteger);

    unsafe fn getBytes_bytesPerRow_bytesPerImage_fromRegion_mipmapLevel_slice(
        self, pixel_bytes: *mut c_void, bytesPerRow: NSUInteger,
        bytesPerImage: NSUInteger, region: MTLRegion, mipmapLevel: NSUInteger,
        slice: NSUInteger);

    unsafe fn getBytes_bytesPerRow_fromRegion_mipmapLevel(self, pixel_bytes: *mut c_void,
                                                          bytesPerRow: NSUInteger,
                                                          region: MTLRegion,
                                                          mipmapLevel: NSUInteger);

    unsafe fn newTextureViewWithPixelFormat(_: Self, format: MTLPixelFormat) -> id {
        msg_send![class("MTLTexture"), newTextureViewWithPixelFormat:format]
    }

    unsafe fn newTextureViewWithPixelFormat_textureType_levels_slices(_: Self,
                                                                      format: MTLPixelFormat,
                                                                      textureType: MTLTextureType,
                                                                      levels: CFRange,
                                                                      slices: NSUInteger)
                                                                      -> id {
        msg_send![class("MTLTexture"), newTextureViewWithPixelFormat:format
                                                         textureType:textureType
                                                              levels:levels
                                                              slices:slices]
    }

    unsafe fn textureType(self) -> MTLTextureType;
    unsafe fn pixelFormat(self) -> MTLPixelFormat;
    unsafe fn width(self) -> NSUInteger;
    unsafe fn height(self) -> NSUInteger;
    unsafe fn depth(self) -> NSUInteger;
    unsafe fn mipmapLevelCount(self) -> NSUInteger;
    unsafe fn arrayLength(self) -> NSUInteger;
    unsafe fn sampleCount(self) -> NSUInteger;
    unsafe fn frameBufferOnly(self) -> BOOL;
    unsafe fn rootResource(self) -> id;
    unsafe fn usage(self) -> MTLTextureUsage;

    #[cfg(target_os = "ios")]
    unsafe fn buffer(self) -> id;
    #[cfg(target_os = "ios")]
    unsafe fn bufferOffset(self) -> NSUInteger;
    #[cfg(target_os = "ios")]
    unsafe fn bufferBytesPerRow(self) -> NSUInteger;

    #[cfg(target_os = "macos")]
    unsafe fn ioSurface(self) -> id;
    #[cfg(target_os = "macos")]
    unsafe fn ioSurfacePlane(self) -> NSUInteger;

    unsafe fn parentTexture(self) -> id;
    unsafe fn parentRelativeLevel(self) -> NSUInteger;
    unsafe fn parentRelativeSlice(self) -> NSUInteger;
}

impl MTLTexture for id {
    unsafe fn replaceRegion_mipmapLevel_slice_withBytes_bytesPerRow_bytesPerImage(
        self, region: MTLRegion, level: NSUInteger, slice: NSUInteger,
        pixelBytes: *const c_void, bytesPerRow: NSUInteger,
        bytesPerImage: NSUInteger) {
        msg_send![self, replaceRegion:region
                          mipmapLevel:level
                                slice:slice
                            withBytes:pixelBytes
                          bytesPerRow:bytesPerRow
                        bytesPerImage:bytesPerImage]
    }
    unsafe fn replaceRegion_mipmapLevel_withBytes_bytesPerRow(self, region: MTLRegion,
                                                              level: NSUInteger,
                                                              pixelBytes: *const c_void,
                                                              bytesPerRow: NSUInteger) {
        msg_send![self, replaceRegion:region
                          mipmapLevel:level
                            withBytes:pixelBytes
                          bytesPerRow:bytesPerRow]
    }

    unsafe fn getBytes_bytesPerRow_bytesPerImage_fromRegion_mipmapLevel_slice(
        self, pixelBytes: *mut c_void, bytesPerRow: NSUInteger,
        bytesPerImage: NSUInteger, region: MTLRegion, level: NSUInteger,
        slice: NSUInteger) {
        msg_send![self, getBytes:pixelBytes
                     bytesPerRow:bytesPerRow
                   bytesPerImage:bytesPerImage
                          region:region
                     mipmapLevel:level
                           slice:slice]
    }

    unsafe fn getBytes_bytesPerRow_fromRegion_mipmapLevel(self, pixelBytes: *mut c_void,
                                                          bytesPerRow: NSUInteger,
                                                          region: MTLRegion, level: NSUInteger) {
        msg_send![self, getBytes:pixelBytes
                     bytesPerRow:bytesPerRow
                          region:region
                     mipmapLevel:level]
    }

    unsafe fn textureType(self) -> MTLTextureType {
        msg_send![self, textureType]
    }

    unsafe fn pixelFormat(self) -> MTLPixelFormat {
        msg_send![self, pixelFormat]
    }

    unsafe fn width(self) -> NSUInteger {
        msg_send![self, width]
    }

    unsafe fn height(self) -> NSUInteger {
        msg_send![self, height]
    }

    unsafe fn depth(self) -> NSUInteger {
        msg_send![self, depth]
    }

    unsafe fn mipmapLevelCount(self) -> NSUInteger {
        msg_send![self, mipmapLevelCount]
    }

    unsafe fn arrayLength(self) -> NSUInteger {
        msg_send![self, arrayLength]
    }

    unsafe fn sampleCount(self) -> NSUInteger {
        msg_send![self, sampleCount]
    }

    unsafe fn frameBufferOnly(self) -> BOOL {
        msg_send![self, frameBufferOnly]
    }

    unsafe fn rootResource(self) -> id {
        msg_send![self, rootResource]
    }

    unsafe fn usage(self) -> MTLTextureUsage {
        msg_send![self, usage]
    }

    #[cfg(target_os = "ios")]
    unsafe fn buffer(self) -> id {
        msg_send![self, buffer]
    }

    #[cfg(target_os = "ios")]
    unsafe fn bufferOffset(self) -> NSUInteger {
        msg_send![self, bufferOffset]
    }

    #[cfg(target_os = "ios")]
    unsafe fn bufferBytesPerRow(self) -> id {
        msg_send![self, bufferBytesPerRow]
    }

    #[cfg(target_os = "macos")]
    unsafe fn ioSurface(self) -> id {
        msg_send![self, ioSurface]
    }

    #[cfg(target_os = "macos")]
    unsafe fn ioSurfacePlane(self) -> NSUInteger {
        msg_send![self, ioSurfacePlane]
    }

    unsafe fn parentTexture(self) -> id {
        msg_send![self, parentTexture]
    }

    unsafe fn parentRelativeLevel(self) -> NSUInteger {
        msg_send![self, parentRelativeLevel]
    }

    unsafe fn parentRelativeSlice(self) -> NSUInteger {
        msg_send![self, parentRelativeSlice]
    }
}

#[repr(usize)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum MTLTextureType {
    MTLTextureType1D = 0,
    MTLTextureType1DArray = 1,
    MTLTextureType2D = 2,
    MTLTextureType2DArray = 3,
    MTLTextureType2DMultisample = 4,
    MTLTextureTypeCube = 5,
    MTLTextureType3D = 7
}

#[repr(usize)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum MTLTextureUsage {
    MTLTextureUsageUnknown = 0x0000,
    MTLTextureUsageShaderRead = 0x0001,
    MTLTextureUsageShaderWrite = 0x0002,
    MTLTextureUsageRenderTarget = 0x0004,
    MTLTextureUsagePixelFormatView = 0x0010
}
<|endoftext|>