<commit_before>extern mod std;

use libc::c_char;
use libc::c_int;
use libc::size_t;
use libc::c_ulong;
use libc::c_void;
use num::from_int;
use ptr::null;
use ptr::addr_of;
use ptr::mut_addr_of;
use ptr::to_mut_unsafe_ptr;
use str::as_c_str;

struct mpz_struct {
  _mp_alloc: c_int,
  _mp_size: c_int,
  _mp_d: *c_void
}

type mpz_srcptr = *const mpz_struct;
type mpz_ptr = *mut mpz_struct;

extern mod gmp {
  fn __gmpz_init(x: mpz_ptr);
  fn __gmpz_init_set(rop: mpz_ptr, op: mpz_srcptr);
  fn __gmpz_init_set_str(rop: mpz_ptr, str: *c_char, base: c_int) -> c_int;
  fn __gmpz_clear(x: mpz_ptr);
  fn __gmpz_set(rop: mpz_ptr, op: mpz_srcptr);
  fn __gmpz_set_str(rop: mpz_ptr, str: *c_char, base: c_int) -> c_int;
  fn __gmpz_get_str(str: *c_char, base: c_int, op: mpz_srcptr) -> *c_char;
  pure fn __gmpz_sizeinbase(op: mpz_srcptr, base: c_int) -> size_t;
  pure fn __gmpz_cmp(op: mpz_srcptr, op2: mpz_srcptr) -> c_int;
  pure fn __gmpz_cmp_ui(op1: mpz_srcptr, op2: c_ulong) -> c_int;
  fn __gmpz_add(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_sub(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_mul(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_neg(rop: mpz_ptr, op: mpz_srcptr);
  fn __gmpz_abs(rop: mpz_ptr, op: mpz_srcptr);
  fn __gmpz_tdiv_q(r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
  fn __gmpz_mod(r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
}

use gmp::*;

pub struct Mpz {
  priv mpz: mpz_struct,

  drop {
    __gmpz_clear(mut_addr_of(&self.mpz));
  }
}

impl Mpz {
  fn set(&mut self, other: &Mpz) {
    __gmpz_set(mut_addr_of(&self.mpz), addr_of(&other.mpz));
  }

  fn set_str(&mut self, s: &str, base: int) -> bool {
    let mpz = to_mut_unsafe_ptr(&mut self.mpz);
    let r = as_c_str(s, { |s| __gmpz_set_str(mpz, s, base as c_int) });
    r == 0
  }

  pure fn to_str_radix(&self, base: int) -> ~str unsafe {
    let length = self.size_in_base(10) + 2;
    let dst = vec::to_mut(vec::from_elem(length, '0'));
    let pdst = vec::raw::to_ptr(dst);

    str::raw::from_c_str(__gmpz_get_str(pdst as *c_char, base as c_int,
                         addr_of(&self.mpz)))
  }

  pure fn size_in_base(&self, base: int) -> uint {
    __gmpz_sizeinbase(addr_of(&self.mpz), base as c_int) as uint
  }

  // TODO: implement the clone::Clone trait when 0.5 is released
  pure fn clone() -> Mpz unsafe {
    let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
    __gmpz_init_set(mut_addr_of(&mpz), addr_of(&self.mpz));
    Mpz { mpz: mpz }
  }

  pure fn abs() -> Mpz unsafe {
    let res = init();
    __gmpz_abs(mut_addr_of(&res.mpz), addr_of(&self.mpz));
    res
  }
}

impl Mpz: cmp::Eq {
  pure fn eq(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) == 0
  }
  pure fn ne(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) != 0
  }
}

impl Mpz: cmp::Ord {
  pure fn lt(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) < 0
  }
  pure fn le(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) <= 0
  }
  pure fn gt(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) > 0
  }
  pure fn ge(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) >= 0
  }
}

impl Mpz: num::Num {
  pure fn add(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_add(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn sub(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_sub(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn mul(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_mul(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn div(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_tdiv_q(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn modulo(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_mod(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn neg() -> Mpz unsafe {
    let res = init();
    __gmpz_neg(mut_addr_of(&res.mpz), addr_of(&self.mpz));
    res
  }
  pure fn to_int() -> int {
    fail ~"not implemented";
  }
  static pure fn from_int(other: int) -> Mpz {
    // the gmp functions dealing with longs aren't usable here - long is only
    // guaranteed to be at least 32-bit
    option::unwrap(from_str(other.to_str()))
  }
}

pub pure fn from_str_radix(s: &str, base: int) -> Option<Mpz> unsafe {
  let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
  let mpz_ptr = mut_addr_of(&mpz);
  let r = as_c_str(s, { |s| __gmpz_init_set_str(mpz_ptr, s, base as c_int) });
  if r == 0 {
    Some(Mpz { mpz: mpz })
  } else {
    __gmpz_clear(mpz_ptr);
    None
  }
}

pub pure fn from_str(s: &str) -> Option<Mpz> {
  from_str_radix(s, 10)
}

impl Mpz : from_str::FromStr {
  static fn from_str(s: &str) -> Option<Mpz> {
    from_str(s)
  }
}

impl Mpz : to_str::ToStr {
  pure fn to_str() -> ~str {
    self.to_str_radix(10)
  }
}

pub pure fn init() -> Mpz unsafe {
  let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
  __gmpz_init(mut_addr_of(&mpz));
  Mpz { mpz: mpz }
}

#[cfg(test)]
mod tests {
  #[test]
  fn test_set() {
    let mut x: Mpz = num::from_int(1000);
    let y: Mpz = num::from_int(5000);
    x.set(&y);
    assert(x == y);
  }

  #[test]
  fn size_in_base() {
    let x = option::unwrap(from_str("150000"));
    assert(x.size_in_base(10) == 6);
    assert(x == option::unwrap(from_str_radix("249f0", 16)));
    assert(x.size_in_base(16) == 5);
  }

  #[test]
  fn eq() {
    let x = option::unwrap(from_str("4242142195"));
    let y = option::unwrap(from_str("4242142195"));
    let z = option::unwrap(from_str("4242142196"));

    assert(x == y);
    assert(x != z);
    assert(y != z);
  }

  #[test]
  fn ord() {
    let x = option::unwrap(from_str("40000000000000000000000"));
    let y = option::unwrap(from_str("45000000000000000000000"));
    let z = option::unwrap(from_str("50000000000000000000000"));

    assert(x < y && x < z && y < z);
    assert(x <= x && x <= y && x <= z && y <= z);
    assert(z > y && z > x && y > x);
    assert(z >= z && z >= y && z >= x && y >= x);
  }

  #[test]
  #[should_fail]
  fn div_zero() {
    let x = init();
    x / x;
  }

  #[test]
  #[should_fail]
  fn modulo_zero() {
    let x = init();
    x % x;
  }

  #[test]
  fn test_div_round() {
    let x: Mpz = from_int(2);
    let y: Mpz = from_int(3);
    assert((x / y).to_str() == (2 / 3).to_str());
    assert((x / -y).to_str() == (2 / -3).to_str());
  }

  #[test]
  fn to_str_radix() {
    let x = option::unwrap(from_str("255"));
    assert(x.to_str_radix(16) == ~"ff");
  }

  #[test]
  fn to_str() {
    let x = option::unwrap(from_str("1234567890"));
    assert(x.to_str() == ~"1234567890");
  }

  #[test]
  fn invalid_str() {
    assert(from_str("foobar").is_none());
  }

  #[test]
  fn test_clone() {
    let a = option::unwrap(from_str("100"));
    let b = a.clone();
    assert(b == a);
    assert(a + b == option::unwrap(from_str("200")));
  }

  #[test]
  fn test_from_int() {
    let x: Mpz = from_int(150);
    assert(x.to_str() == ~"150");
    assert(x == option::unwrap(from_str("150")));
  }

  #[test]
  fn test_abs() {
    let x: Mpz = from_int(1000);
    let y: Mpz = from_int(-1000);
    assert(x.neg() == y);
    assert(x == y.neg());
    assert(x == y.abs());
    assert(x.abs() == y.abs());
  }
}
<commit_msg>add binary bitwise operators<commit_after>extern mod std;

use libc::c_char;
use libc::c_int;
use libc::size_t;
use libc::c_ulong;
use libc::c_void;
use num::from_int;
use ptr::null;
use ptr::addr_of;
use ptr::mut_addr_of;
use ptr::to_mut_unsafe_ptr;
use str::as_c_str;

struct mpz_struct {
  _mp_alloc: c_int,
  _mp_size: c_int,
  _mp_d: *c_void
}

type mpz_srcptr = *const mpz_struct;
type mpz_ptr = *mut mpz_struct;

extern mod gmp {
  fn __gmpz_init(x: mpz_ptr);
  fn __gmpz_init_set(rop: mpz_ptr, op: mpz_srcptr);
  fn __gmpz_init_set_str(rop: mpz_ptr, str: *c_char, base: c_int) -> c_int;
  fn __gmpz_clear(x: mpz_ptr);
  fn __gmpz_set(rop: mpz_ptr, op: mpz_srcptr);
  fn __gmpz_set_str(rop: mpz_ptr, str: *c_char, base: c_int) -> c_int;
  fn __gmpz_get_str(str: *c_char, base: c_int, op: mpz_srcptr) -> *c_char;
  pure fn __gmpz_sizeinbase(op: mpz_srcptr, base: c_int) -> size_t;
  pure fn __gmpz_cmp(op: mpz_srcptr, op2: mpz_srcptr) -> c_int;
  pure fn __gmpz_cmp_ui(op1: mpz_srcptr, op2: c_ulong) -> c_int;
  fn __gmpz_add(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_sub(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_mul(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_neg(rop: mpz_ptr, op: mpz_srcptr);
  fn __gmpz_abs(rop: mpz_ptr, op: mpz_srcptr);
  fn __gmpz_tdiv_q(r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
  fn __gmpz_mod(r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
  fn __gmpz_and(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_ior(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_xor(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
}

use gmp::*;

pub struct Mpz {
  priv mpz: mpz_struct,

  drop {
    __gmpz_clear(mut_addr_of(&self.mpz));
  }
}

impl Mpz {
  fn set(&mut self, other: &Mpz) {
    __gmpz_set(mut_addr_of(&self.mpz), addr_of(&other.mpz));
  }

  fn set_str(&mut self, s: &str, base: int) -> bool {
    let mpz = to_mut_unsafe_ptr(&mut self.mpz);
    let r = as_c_str(s, { |s| __gmpz_set_str(mpz, s, base as c_int) });
    r == 0
  }

  pure fn to_str_radix(&self, base: int) -> ~str unsafe {
    let length = self.size_in_base(10) + 2;
    let dst = vec::to_mut(vec::from_elem(length, '0'));
    let pdst = vec::raw::to_ptr(dst);

    str::raw::from_c_str(__gmpz_get_str(pdst as *c_char, base as c_int,
                         addr_of(&self.mpz)))
  }

  pure fn size_in_base(&self, base: int) -> uint {
    __gmpz_sizeinbase(addr_of(&self.mpz), base as c_int) as uint
  }

  // TODO: implement the clone::Clone trait when 0.5 is released
  pure fn clone() -> Mpz unsafe {
    let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
    __gmpz_init_set(mut_addr_of(&mpz), addr_of(&self.mpz));
    Mpz { mpz: mpz }
  }

  pure fn abs() -> Mpz unsafe {
    let res = init();
    __gmpz_abs(mut_addr_of(&res.mpz), addr_of(&self.mpz));
    res
  }
}

impl Mpz: cmp::Eq {
  pure fn eq(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) == 0
  }
  pure fn ne(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) != 0
  }
}

impl Mpz: cmp::Ord {
  pure fn lt(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) < 0
  }
  pure fn le(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) <= 0
  }
  pure fn gt(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) > 0
  }
  pure fn ge(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) >= 0
  }
}

impl Mpz: num::Num {
  pure fn add(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_add(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn sub(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_sub(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn mul(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_mul(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn div(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_tdiv_q(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn modulo(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_mod(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn neg() -> Mpz unsafe {
    let res = init();
    __gmpz_neg(mut_addr_of(&res.mpz), addr_of(&self.mpz));
    res
  }
  pure fn to_int() -> int {
    fail ~"not implemented";
  }
  static pure fn from_int(other: int) -> Mpz {
    // the gmp functions dealing with longs aren't usable here - long is only
    // guaranteed to be at least 32-bit
    option::unwrap(from_str(other.to_str()))
  }
}

impl Mpz: BitAnd<Mpz, Mpz> {
  pure fn bitand(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_and(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
}

impl Mpz: BitOr<Mpz, Mpz> {
  pure fn bitor(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_ior(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
}

impl Mpz: BitXor<Mpz, Mpz> {
  pure fn bitxor(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_xor(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
}

pub pure fn from_str_radix(s: &str, base: int) -> Option<Mpz> unsafe {
  let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
  let mpz_ptr = mut_addr_of(&mpz);
  let r = as_c_str(s, { |s| __gmpz_init_set_str(mpz_ptr, s, base as c_int) });
  if r == 0 {
    Some(Mpz { mpz: mpz })
  } else {
    __gmpz_clear(mpz_ptr);
    None
  }
}

pub pure fn from_str(s: &str) -> Option<Mpz> {
  from_str_radix(s, 10)
}

impl Mpz : from_str::FromStr {
  static fn from_str(s: &str) -> Option<Mpz> {
    from_str(s)
  }
}

impl Mpz : to_str::ToStr {
  pure fn to_str() -> ~str {
    self.to_str_radix(10)
  }
}

pub pure fn init() -> Mpz unsafe {
  let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
  __gmpz_init(mut_addr_of(&mpz));
  Mpz { mpz: mpz }
}

#[cfg(test)]
mod tests {
  #[test]
  fn test_set() {
    let mut x: Mpz = num::from_int(1000);
    let y: Mpz = num::from_int(5000);
    x.set(&y);
    assert(x == y);
  }

  #[test]
  fn size_in_base() {
    let x = option::unwrap(from_str("150000"));
    assert(x.size_in_base(10) == 6);
    assert(x == option::unwrap(from_str_radix("249f0", 16)));
    assert(x.size_in_base(16) == 5);
  }

  #[test]
  fn eq() {
    let x = option::unwrap(from_str("4242142195"));
    let y = option::unwrap(from_str("4242142195"));
    let z = option::unwrap(from_str("4242142196"));

    assert(x == y);
    assert(x != z);
    assert(y != z);
  }

  #[test]
  fn ord() {
    let x = option::unwrap(from_str("40000000000000000000000"));
    let y = option::unwrap(from_str("45000000000000000000000"));
    let z = option::unwrap(from_str("50000000000000000000000"));

    assert(x < y && x < z && y < z);
    assert(x <= x && x <= y && x <= z && y <= z);
    assert(z > y && z > x && y > x);
    assert(z >= z && z >= y && z >= x && y >= x);
  }

  #[test]
  #[should_fail]
  fn div_zero() {
    let x = init();
    x / x;
  }

  #[test]
  #[should_fail]
  fn modulo_zero() {
    let x = init();
    x % x;
  }

  #[test]
  fn test_div_round() {
    let x: Mpz = from_int(2);
    let y: Mpz = from_int(3);
    assert((x / y).to_str() == (2 / 3).to_str());
    assert((x / -y).to_str() == (2 / -3).to_str());
  }

  #[test]
  fn to_str_radix() {
    let x = option::unwrap(from_str("255"));
    assert(x.to_str_radix(16) == ~"ff");
  }

  #[test]
  fn to_str() {
    let x = option::unwrap(from_str("1234567890"));
    assert(x.to_str() == ~"1234567890");
  }

  #[test]
  fn invalid_str() {
    assert(from_str("foobar").is_none());
  }

  #[test]
  fn test_clone() {
    let a = option::unwrap(from_str("100"));
    let b = a.clone();
    assert(b == a);
    assert(a + b == option::unwrap(from_str("200")));
  }

  #[test]
  fn test_from_int() {
    let x: Mpz = from_int(150);
    assert(x.to_str() == ~"150");
    assert(x == option::unwrap(from_str("150")));
  }

  #[test]
  fn test_abs() {
    let x: Mpz = from_int(1000);
    let y: Mpz = from_int(-1000);
    assert(x.neg() == y);
    assert(x == y.neg());
    assert(x == y.abs());
    assert(x.abs() == y.abs());
  }

  #[test]
  fn test_bitand() {
    let a = 0b1001_0111;
    let b = 0b1100_0100;
    let c = a & b;

    let m_a: Mpz = from_int(a);
    let m_b: Mpz = from_int(b);
    let m_c: Mpz = from_int(c);

    assert(m_a & m_b == m_c);
  }

  #[test]
  fn test_bitor() {
    let a = 0b1001_0111;
    let b = 0b1100_0100;
    let c = a | b;

    let m_a: Mpz = from_int(a);
    let m_b: Mpz = from_int(b);
    let m_c: Mpz = from_int(c);

    assert(m_a | m_b == m_c);
  }

  #[test]
  fn test_bitxor() {
    let a = 0b1001_0111;
    let b = 0b1100_0100;
    let c = a ^ b;

    let m_a: Mpz = from_int(a);
    let m_b: Mpz = from_int(b);
    let m_c: Mpz = from_int(c);

    assert(m_a ^ m_b == m_c);
  }
}
<|endoftext|>


<commit_before>extern crate acronym;

#[test]
fn basic() {
  assert_eq!(acronym::abbreviate("Portable Network Graphics"), "PNG");
}

#[test]
#[ignore]
fn lowercase_words() {
  assert_eq!(acronym::abbreviate("Ruby on Rails"), "ROR");
}

#[test]
#[ignore]
fn camelcase() {
    assert_eq!(acronym::abbreviate("HyperText Markup Language"), "HTML");
}

#[test]
#[ignore]
fn punctuation() {
    assert_eq!(acronym::abbreviate("First In, First Out"), "FIFO");
}

#[test]
#[ignore]
fn all_caps_words() {
    assert_eq!(acronym::abbreviate("PHP: Hypertext Preprocessor"), "PHP");
}

#[test]
#[ignore]
fn hyphenated() {
    assert_eq!(acronym::abbreviate("Complementary metal-oxide semiconductor"),
               "CMOS");
}
<commit_msg>acronym: Add GIMP case<commit_after>extern crate acronym;

#[test]
fn basic() {
  assert_eq!(acronym::abbreviate("Portable Network Graphics"), "PNG");
}

#[test]
#[ignore]
fn lowercase_words() {
  assert_eq!(acronym::abbreviate("Ruby on Rails"), "ROR");
}

#[test]
#[ignore]
fn camelcase() {
    assert_eq!(acronym::abbreviate("HyperText Markup Language"), "HTML");
}

#[test]
#[ignore]
fn punctuation() {
    assert_eq!(acronym::abbreviate("First In, First Out"), "FIFO");
}

#[test]
#[ignore]
fn all_caps_words() {
    assert_eq!(acronym::abbreviate("PHP: Hypertext Preprocessor"), "PHP");
}

#[test]
#[ignore]
fn non_acronym_all_caps_word() {
    assert_eq!(acronym::abbreviate("GNU Image Manipulation Program"), "GIMP");
}

#[test]
#[ignore]
fn hyphenated() {
    assert_eq!(acronym::abbreviate("Complementary metal-oxide semiconductor"),
               "CMOS");
}
<|endoftext|>


<commit_before>#[packed]
#[allow(dead_code)]
pub struct Gdtr {
    limit : u16,
    base : uint,
}
#[packed]
pub struct Idtr {
    limit : u16,
    base : uint,
}

// FIXME Would like to use "m", but it seems to be impossible to get the right
// thing sent.
pub unsafe fn lgdt(gdtr : &Gdtr) {
    asm!("lgdt ($0)" :: "r" (gdtr));
}
pub unsafe fn lidt(idtr : &Idtr) {
    asm!("lidt ($0)" :: "r" (idtr));
}
pub unsafe fn ltr(tr : uint) {
    asm!("ltr %ax" :: "{ax}"(tr));
}

pub fn cr2() -> uint {
    let mut cr2 : uint;
    unsafe { asm!("mov %cr2, $0": "=r" (cr2)); }
    return cr2;
}

pub mod seg {
    #![allow(dead_code)]
    pub static code32 : uint = 8;
    pub static data32 : uint = 16;
    pub static code : uint = 24;
    pub static data : uint = 32;
    pub static tss64 : uint = 40;
    pub static user_code32_base : uint = 56;
    pub static user_data32_base : uint = 64;
    pub static user_code64_base : uint = user_code32_base + 16;
    pub static user_data64_base : uint = user_code64_base + 8;
    pub static user_cs : uint = user_code64_base | 3;
    pub static user_ds : uint = user_cs + 8;
}

pub mod idt {

use core::prelude::*;

use x86::seg;
use x86::Idtr;
use x86::lidt;

static GatePresent : uint = 0x80;
static GateTypeInterrupt : uint = 0x0e;

pub fn entry(handler_ptr : *const u8) -> Entry {
    let handler = handler_ptr as uint;
    let low = (handler & 0xffff) | (seg::code << 16);
    let flags = GatePresent | GateTypeInterrupt;
    let high = (((handler >> 16) & 0xffff) << 16) | (flags << 8);

    (low as u64 | (high as u64 << 32), handler as u64 >> 32)
}

pub static null_entry : Entry = (0,0);

pub type Entry = (u64,u64);
pub type Table = [Entry, ..49];

pub fn limit(_table : &[Entry, ..49]) -> u16 {
    return 49 * 16 - 1;
}

pub unsafe fn load(table: *const [Entry, ..49]) {
    static mut idtr : Idtr = Idtr { base : 0, limit : 0 };
    idtr.base = (table as *const u8) as uint;
    idtr.limit = limit(&*table);
    lidt(&idtr);
}

#[no_mangle]
pub fn irq_entry(vec : u8, err : uint) -> ! {
    use page_fault;
    use handler_NM;
    use generic_irq_handler;
    use cpu;
    cpu().leave_proc();
    let p = cpu().get_process();
    if vec == 7 {
        handler_NM();
    } else if vec == 14 {
        page_fault(p.unwrap(), err);
    } else if vec >= 32 {
        match p {
            Some(p) => cpu().queue(p),
            None => (),
        }
        generic_irq_handler(vec);
    }
    unsafe { cpu().run(); }
}

pub unsafe fn init() {
    extern {
        fn handler_PF_stub();
        fn handler_NM_stub();
        // We can generate this, probably in less than 68 bytes?
        static irq_handlers : [u32, ..17];
    }
    static mut idt_table : [Entry, ..49] = [null_entry, ..49];
    idt_table[7] = entry(handler_NM_stub as *const u8);
    idt_table[14] = entry(handler_PF_stub as *const u8);
    for i in range(32 as uint,49) {
        idt_table[i] = entry((&irq_handlers[i - 32]) as *const u32 as *const u8);
    }
    load(&idt_table);
}

} // mod idt

pub mod msr {
    pub enum MSR {
        EFER = 0xc000_0080,
        STAR = 0xc000_0081,
        LSTAR = 0xc000_0082,
        CSTAR = 0xc000_0083,
        FMASK = 0xc000_0084,
        GSBASE = 0xc000_0101
    }

    pub unsafe fn wrmsr(msr : MSR, val : uint) {
        asm!("wrmsr":
        : "{ecx}" (msr as u32),
          "{edx}" ((val >> 32) as u32),
          "{eax}" (val as u32)
        :
        : "volatile");
    }

    pub unsafe fn rdmsr(msr : MSR) -> uint {
        let mut h : uint;
        let mut l : uint;
        asm!("rdmsr"
        : "={edx}" (h),
          "={eax}" (l)
        : "{ecx}" (msr as u32));
        return (h << 32) | l;
    }

}

pub mod rflags {
    pub static IF : uint = 1 << 9;
    pub static VM : uint = 1 << 17;
}

pub mod efer {
    pub static SCE : uint = 1;
    pub static NXE : uint = 1 << 11;
}

pub unsafe fn set_cr3(cr3 : uint) {
    let mut old_cr3 : uint;
    asm!("movq %cr3, $0" : "=r"(old_cr3));
    if old_cr3 != cr3 {
        asm!("movq $0, %cr3" :: "r"(cr3));
    }
}
<commit_msg>Fix idtr/gdtr structs and lidt/lgdt functions<commit_after>#[repr(packed)]
#[allow(dead_code)]
pub struct Gdtr {
    limit : u16,
    base : uint,
}
pub unsafe fn lgdt(gdtr : &Gdtr) {
    asm!("lgdt $0" :: "*m" (*gdtr));
}
pub unsafe fn ltr(tr : uint) {
    asm!("ltr %ax" :: "{ax}"(tr));
}

pub fn cr2() -> uint {
    let mut cr2 : uint;
    unsafe { asm!("mov %cr2, $0": "=r" (cr2)); }
    return cr2;
}

pub mod seg {
    #![allow(dead_code)]
    pub static code32 : uint = 8;
    pub static data32 : uint = 16;
    pub static code : uint = 24;
    pub static data : uint = 32;
    pub static tss64 : uint = 40;
    pub static user_code32_base : uint = 56;
    pub static user_data32_base : uint = 64;
    pub static user_code64_base : uint = user_code32_base + 16;
    pub static user_data64_base : uint = user_code64_base + 8;
    pub static user_cs : uint = user_code64_base | 3;
    pub static user_ds : uint = user_cs + 8;
}

pub mod idt {

use core::prelude::*;

use x86::seg;

static GatePresent : uint = 0x80;
static GateTypeInterrupt : uint = 0x0e;

pub fn entry(handler_ptr : *const u8) -> Entry {
    let handler = handler_ptr as uint;
    let low = (handler & 0xffff) | (seg::code << 16);
    let flags = GatePresent | GateTypeInterrupt;
    let high = (((handler >> 16) & 0xffff) << 16) | (flags << 8);

    (low as u64 | (high as u64 << 32), handler as u64 >> 32)
}

pub static null_entry : Entry = (0,0);

pub type Entry = (u64,u64);
pub type Table = [Entry, ..49];

#[repr(packed)]
#[allow(dead_code)]
pub struct Idtr {
    limit : u16,
    base : *const Table,
}

pub unsafe fn lidt(idtr : &Idtr) {
    asm!("lidt $0" :: "*m" (*idtr));
}
pub fn limit(_table : &[Entry, ..49]) -> u16 {
    return 49 * 16 - 1;
}

pub unsafe fn load(table: *const [Entry, ..49]) {
    let idtr = Idtr {
        limit : limit(&*table),
        base : table,
    };
    lidt(&idtr);
}

#[no_mangle]
pub fn irq_entry(vec : u8, err : uint) -> ! {
    use page_fault;
    use handler_NM;
    use generic_irq_handler;
    use cpu;
    cpu().leave_proc();
    let p = cpu().get_process();
    if vec == 7 {
        handler_NM();
    } else if vec == 14 {
        page_fault(p.unwrap(), err);
    } else if vec >= 32 {
        match p {
            Some(p) => cpu().queue(p),
            None => (),
        }
        generic_irq_handler(vec);
    }
    unsafe { cpu().run(); }
}

pub unsafe fn init() {
    extern {
        fn handler_PF_stub();
        fn handler_NM_stub();
        // We can generate this, probably in less than 68 bytes?
        static irq_handlers : [u32, ..17];
    }
    static mut idt_table : [Entry, ..49] = [null_entry, ..49];
    idt_table[7] = entry(handler_NM_stub as *const u8);
    idt_table[14] = entry(handler_PF_stub as *const u8);
    for i in range(32 as uint,49) {
        idt_table[i] = entry((&irq_handlers[i - 32]) as *const u32 as *const u8);
    }
    load(&idt_table);
}

} // mod idt

pub mod msr {
    pub enum MSR {
        EFER = 0xc000_0080,
        STAR = 0xc000_0081,
        LSTAR = 0xc000_0082,
        CSTAR = 0xc000_0083,
        FMASK = 0xc000_0084,
        GSBASE = 0xc000_0101
    }

    pub unsafe fn wrmsr(msr : MSR, val : uint) {
        asm!("wrmsr":
        : "{ecx}" (msr as u32),
          "{edx}" ((val >> 32) as u32),
          "{eax}" (val as u32)
        :
        : "volatile");
    }

    pub unsafe fn rdmsr(msr : MSR) -> uint {
        let mut h : uint;
        let mut l : uint;
        asm!("rdmsr"
        : "={edx}" (h),
          "={eax}" (l)
        : "{ecx}" (msr as u32));
        return (h << 32) | l;
    }

}

pub mod rflags {
    pub static IF : uint = 1 << 9;
    pub static VM : uint = 1 << 17;
}

pub mod efer {
    pub static SCE : uint = 1;
    pub static NXE : uint = 1 << 11;
}

pub unsafe fn set_cr3(cr3 : uint) {
    let mut old_cr3 : uint;
    asm!("movq %cr3, $0" : "=r"(old_cr3));
    if old_cr3 != cr3 {
        asm!("movq $0, %cr3" :: "r"(cr3));
    }
}
<|endoftext|>


<commit_before>//! Compile time optimized maps
#[crate_id="github.com/sfackler/rust-phf/phf"];
#[doc(html_root_url="http://www.rust-ci.org/sfackler/rust-phf/doc")];
#[crate_type="lib"];
#[warn(missing_doc)];

use std::iter;
use std::vec;

/// An immutable map constructed at compile time.
///
/// `PhfMap`s may be created with the `phf_map` macro:
///
/// ```rust
/// static my_map: PhfMap<int> = phf_map!(
///    "hello" => 10,
///    "world" => 11,
/// );
/// ```
///
/// # Note
///
/// The fields of this struct are public so that they may be initialized by the
/// `phf_map` macro. They are subject to change at any time and should never
/// be accessed directly.
pub struct PhfMap<T> {
    #[doc(hidden)]
    len: uint,
    #[doc(hidden)]
    keys: Keys,
    #[doc(hidden)]
    disps: &'static [(uint, uint)],
    #[doc(hidden)]
    entries: &'static [Option<(&'static str, T)>],
}

#[doc(hidden)]
pub struct Keys {
    k1: u64,
    k2_g: u64,
    k2_f1: u64,
    k2_f2: u64,
}

impl Keys {
    #[doc(hidden)]
    pub fn hash1(&self, s: &str) -> uint {
        s.hash_keyed(self.k1, self.k2_g) as uint
    }

    #[doc(hidden)]
    pub fn hash2(&self, s: &str, d1: uint, d2: uint) -> uint {
        let f1 = s.hash_keyed(self.k1, self.k2_f1) as uint;
        let f2 = s.hash_keyed(self.k1, self.k2_f2) as uint;
        d2 + f1 * d1 + f2
    }
}

impl<T> Container for PhfMap<T> {
    #[inline]
    fn len(&self) -> uint {
        self.len
    }
}

impl<'a, T> Map<&'a str, T> for PhfMap<T> {
    #[inline]
    fn find<'a>(&'a self, key: & &str) -> Option<&'a T> {
        let hash1 = self.keys.hash1(*key);
        let (d1, d2) = self.disps[hash1 % self.disps.len()];
        let hash2 = self.keys.hash2(*key, d1, d2);
        match self.entries[hash2 % self.entries.len()] {
            Some((s, ref value)) if s == *key => Some(value),
            _ => None
        }
    }
}

impl<T> PhfMap<T> {
    /// Returns an iterator over the key/value pairs in the map. Entries are
    /// retuned in an arbitrary order.
    #[inline]
    pub fn entries<'a>(&'a self) -> PhfMapEntries<'a, T> {
        PhfMapEntries {
            iter: self.entries.iter().filter_map(|e| {
                match *e {
                    Some((key, ref value)) => Some((key, value)),
                    None => None
                }
            })
        }
    }

    /// Returns an iterator over the keys in the map. Keys are returned in an
    /// arbitrary order.
    #[inline]
    pub fn keys<'a>(&'a self) -> PhfMapKeys<'a, T> {
        PhfMapKeys { iter: self.entries() }
    }

    /// Returns an iterator over the values in the map. Values are returned in
    /// an arbitrary order.
    #[inline]
    pub fn values<'a>(&'a self) -> PhfMapValues<'a, T> {
        PhfMapValues { iter: self.entries() }
    }
}

/// An iterator over the key/value pairs in a `PhfMap`.
pub struct PhfMapEntries<'a, T> {
    priv iter: iter::FilterMap<'a,
                               &'a Option<(&'static str, T)>,
                               (&'static str, &'a T),
                               vec::Items<'a, Option<(&'static str, T)>>>,
}

impl<'a, T> Iterator<(&'static str, &'a T)> for PhfMapEntries<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<(&'static str, &'a T)> {
        self.iter.next()
    }
}

/// An iterator over the keys in a `PhfMap`.
pub struct PhfMapKeys<'a, T> {
    priv iter: PhfMapEntries<'a, T>,
}

impl<'a, T> Iterator<&'static str> for PhfMapKeys<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<&'static str> {
        self.iter.next().map(|(key, _)| key)
    }
}

/// An iterator over the values in a `PhfMap`.
pub struct PhfMapValues<'a, T> {
    priv iter: PhfMapEntries<'a, T>,
}

impl<'a, T> Iterator<&'a T> for PhfMapValues<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<&'a T> {
        self.iter.next().map(|(_, value)| value)
    }
}
<commit_msg>Add size_hint to iterators<commit_after>//! Compile time optimized maps
#[crate_id="github.com/sfackler/rust-phf/phf"];
#[doc(html_root_url="http://www.rust-ci.org/sfackler/rust-phf/doc")];
#[crate_type="lib"];
#[warn(missing_doc)];

use std::iter;
use std::vec;

/// An immutable map constructed at compile time.
///
/// `PhfMap`s may be created with the `phf_map` macro:
///
/// ```rust
/// static my_map: PhfMap<int> = phf_map!(
///    "hello" => 10,
///    "world" => 11,
/// );
/// ```
///
/// # Note
///
/// The fields of this struct are public so that they may be initialized by the
/// `phf_map` macro. They are subject to change at any time and should never
/// be accessed directly.
pub struct PhfMap<T> {
    #[doc(hidden)]
    len: uint,
    #[doc(hidden)]
    keys: Keys,
    #[doc(hidden)]
    disps: &'static [(uint, uint)],
    #[doc(hidden)]
    entries: &'static [Option<(&'static str, T)>],
}

#[doc(hidden)]
pub struct Keys {
    k1: u64,
    k2_g: u64,
    k2_f1: u64,
    k2_f2: u64,
}

impl Keys {
    #[doc(hidden)]
    pub fn hash1(&self, s: &str) -> uint {
        s.hash_keyed(self.k1, self.k2_g) as uint
    }

    #[doc(hidden)]
    pub fn hash2(&self, s: &str, d1: uint, d2: uint) -> uint {
        let f1 = s.hash_keyed(self.k1, self.k2_f1) as uint;
        let f2 = s.hash_keyed(self.k1, self.k2_f2) as uint;
        d2 + f1 * d1 + f2
    }
}

impl<T> Container for PhfMap<T> {
    #[inline]
    fn len(&self) -> uint {
        self.len
    }
}

impl<'a, T> Map<&'a str, T> for PhfMap<T> {
    #[inline]
    fn find<'a>(&'a self, key: & &str) -> Option<&'a T> {
        let hash1 = self.keys.hash1(*key);
        let (d1, d2) = self.disps[hash1 % self.disps.len()];
        let hash2 = self.keys.hash2(*key, d1, d2);
        match self.entries[hash2 % self.entries.len()] {
            Some((s, ref value)) if s == *key => Some(value),
            _ => None
        }
    }
}

impl<T> PhfMap<T> {
    /// Returns an iterator over the key/value pairs in the map. Entries are
    /// retuned in an arbitrary order.
    #[inline]
    pub fn entries<'a>(&'a self) -> PhfMapEntries<'a, T> {
        PhfMapEntries {
            iter: self.entries.iter().filter_map(|e| {
                match *e {
                    Some((key, ref value)) => Some((key, value)),
                    None => None
                }
            })
        }
    }

    /// Returns an iterator over the keys in the map. Keys are returned in an
    /// arbitrary order.
    #[inline]
    pub fn keys<'a>(&'a self) -> PhfMapKeys<'a, T> {
        PhfMapKeys { iter: self.entries() }
    }

    /// Returns an iterator over the values in the map. Values are returned in
    /// an arbitrary order.
    #[inline]
    pub fn values<'a>(&'a self) -> PhfMapValues<'a, T> {
        PhfMapValues { iter: self.entries() }
    }
}

/// An iterator over the key/value pairs in a `PhfMap`.
pub struct PhfMapEntries<'a, T> {
    priv iter: iter::FilterMap<'a,
                               &'a Option<(&'static str, T)>,
                               (&'static str, &'a T),
                               vec::Items<'a, Option<(&'static str, T)>>>,
}

impl<'a, T> Iterator<(&'static str, &'a T)> for PhfMapEntries<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<(&'static str, &'a T)> {
        self.iter.next()
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        self.iter.size_hint()
    }
}

/// An iterator over the keys in a `PhfMap`.
pub struct PhfMapKeys<'a, T> {
    priv iter: PhfMapEntries<'a, T>,
}

impl<'a, T> Iterator<&'static str> for PhfMapKeys<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<&'static str> {
        self.iter.next().map(|(key, _)| key)
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        self.iter.size_hint()
    }
}

/// An iterator over the values in a `PhfMap`.
pub struct PhfMapValues<'a, T> {
    priv iter: PhfMapEntries<'a, T>,
}

impl<'a, T> Iterator<&'a T> for PhfMapValues<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<&'a T> {
        self.iter.next().map(|(_, value)| value)
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        self.iter.size_hint()
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "no_std")]
use core::prelude::*;
use libc::{c_int, c_uint, c_void, uint8_t, uint32_t};
use libc::{uint16_t, c_double, c_char};
use super::rwops::SDL_RWops;

// assume LSB
pub type SDL_AudioFormat = uint16_t;
pub const AUDIO_U8 : SDL_AudioFormat =         0x0008;
pub const AUDIO_S8 : SDL_AudioFormat =         0x8008;
pub const AUDIO_U16LSB : SDL_AudioFormat =     0x0010;
pub const AUDIO_S16LSB : SDL_AudioFormat =     0x8010;
pub const AUDIO_U16MSB : SDL_AudioFormat =     0x1010;
pub const AUDIO_S16MSB : SDL_AudioFormat =     0x9010;
pub const AUDIO_U16 : SDL_AudioFormat =        AUDIO_U16LSB;
pub const AUDIO_S16 : SDL_AudioFormat =        AUDIO_S16LSB;
pub const AUDIO_S32LSB : SDL_AudioFormat =     0x8020;
pub const AUDIO_S32MSB : SDL_AudioFormat =     0x9020;
pub const AUDIO_S32 : SDL_AudioFormat =        AUDIO_S32LSB;
pub const AUDIO_F32LSB : SDL_AudioFormat =     0x8120;
pub const AUDIO_F32MSB : SDL_AudioFormat =     0x9120;
pub const AUDIO_F32 : SDL_AudioFormat =        AUDIO_F32LSB;
pub const AUDIO_U16SYS : SDL_AudioFormat =     AUDIO_U16LSB;
pub const AUDIO_S16SYS : SDL_AudioFormat =     AUDIO_S16LSB;
pub const AUDIO_S32SYS : SDL_AudioFormat =     AUDIO_S32LSB;
pub const AUDIO_F32SYS : SDL_AudioFormat =     AUDIO_F32LSB;

pub type SDL_AudioCallback =
    Option<extern "C" fn (arg1: *mut c_void, arg2: *mut uint8_t, arg3: c_int)>;
#[allow(missing_copy_implementations)]
#[repr(C)]
pub struct SDL_AudioSpec {
    pub freq: c_int,
    pub format: SDL_AudioFormat,
    pub channels: uint8_t,
    pub silence: uint8_t,
    pub samples: uint16_t,
    pub padding: uint16_t,
    pub size: uint32_t,
    pub callback: SDL_AudioCallback,
    pub userdata: *mut c_void,
}
pub type SDL_AudioFilter =
    Option<extern "C" fn (arg1: *mut SDL_AudioCVT, arg2: SDL_AudioFormat)>;
#[allow(dead_code, missing_copy_implementations)]
#[derive(Copy, Clone)]
#[repr(C)]
pub struct SDL_AudioCVT {
    pub needed: c_int,
    pub src_format: SDL_AudioFormat,
    pub dst_format: SDL_AudioFormat,
    pub rate_incr: c_double,
    pub buf: *mut uint8_t,
    pub len: c_int,
    pub len_cvt: c_int,
    pub len_mult: c_int,
    pub len_ratio: c_double,
    filters: [SDL_AudioFilter; 10],
    filter_index: c_int,
}
pub type SDL_AudioDeviceID = uint32_t;
pub type SDL_AudioStatus = c_uint;
pub const SDL_AUDIO_STOPPED: c_uint = 0;
pub const SDL_AUDIO_PLAYING: c_uint = 1;
pub const SDL_AUDIO_PAUSED: c_uint = 2;
extern "C" {
    pub fn SDL_GetNumAudioDrivers() -> c_int;
    pub fn SDL_GetAudioDriver(index: c_int) -> *const c_char;
    pub fn SDL_AudioInit(driver_name: *const c_char) -> c_int;
    pub fn SDL_AudioQuit();
    pub fn SDL_GetCurrentAudioDriver() -> *const c_char;
    pub fn SDL_OpenAudio(desired: *const SDL_AudioSpec,
                         obtained: *mut SDL_AudioSpec) -> c_int;
    pub fn SDL_GetNumAudioDevices(iscapture: c_int) -> c_int;
    pub fn SDL_GetAudioDeviceName(index: c_int, iscapture: c_int) -> *const c_char;
    pub fn SDL_OpenAudioDevice(device: *const c_char, iscapture: c_int,
                               desired: *const SDL_AudioSpec,
                               obtained: *mut SDL_AudioSpec,
                               allowed_changes: c_int) -> SDL_AudioDeviceID;
    pub fn SDL_GetAudioStatus() -> SDL_AudioStatus;
    pub fn SDL_GetAudioDeviceStatus(dev: SDL_AudioDeviceID) ->
        SDL_AudioStatus;
    pub fn SDL_PauseAudio(pause_on: c_int);
    pub fn SDL_PauseAudioDevice(dev: SDL_AudioDeviceID, pause_on: c_int);
    pub fn SDL_LoadWAV_RW(src: *mut SDL_RWops, freesrc: c_int,
                          spec: *mut SDL_AudioSpec,
                          audio_buf: *mut *mut uint8_t, audio_len: *mut uint32_t) -> *mut SDL_AudioSpec;
    pub fn SDL_FreeWAV(audio_buf: *mut uint8_t);
    pub fn SDL_BuildAudioCVT(cvt: *mut SDL_AudioCVT,
                             src_format: SDL_AudioFormat, src_channels: uint8_t,
                             src_rate: c_int, dst_format: SDL_AudioFormat,
                             dst_channels: uint8_t, dst_rate: c_int) -> c_int;
    pub fn SDL_ConvertAudio(cvt: *mut SDL_AudioCVT) -> c_int;
    pub fn SDL_MixAudio(dst: *mut uint8_t, src: *const uint8_t, len: uint32_t,
                        volume: c_int);
    pub fn SDL_MixAudioFormat(dst: *mut uint8_t, src: *const uint8_t,
                              format: SDL_AudioFormat, len: uint32_t,
                              volume: c_int);
    pub fn SDL_LockAudio();
    pub fn SDL_LockAudioDevice(dev: SDL_AudioDeviceID);
    pub fn SDL_UnlockAudio();
    pub fn SDL_UnlockAudioDevice(dev: SDL_AudioDeviceID);
    pub fn SDL_CloseAudio();
    pub fn SDL_CloseAudioDevice(dev: SDL_AudioDeviceID);
}
<commit_msg>Added Audio Queue functions to sdl2-sys<commit_after>#[cfg(feature = "no_std")]
use core::prelude::*;
use libc::{c_int, c_uint, c_void, uint8_t, uint32_t};
use libc::{uint16_t, c_double, c_char};
use super::rwops::SDL_RWops;

// assume LSB
pub type SDL_AudioFormat = uint16_t;
pub const AUDIO_U8 : SDL_AudioFormat =         0x0008;
pub const AUDIO_S8 : SDL_AudioFormat =         0x8008;
pub const AUDIO_U16LSB : SDL_AudioFormat =     0x0010;
pub const AUDIO_S16LSB : SDL_AudioFormat =     0x8010;
pub const AUDIO_U16MSB : SDL_AudioFormat =     0x1010;
pub const AUDIO_S16MSB : SDL_AudioFormat =     0x9010;
pub const AUDIO_U16 : SDL_AudioFormat =        AUDIO_U16LSB;
pub const AUDIO_S16 : SDL_AudioFormat =        AUDIO_S16LSB;
pub const AUDIO_S32LSB : SDL_AudioFormat =     0x8020;
pub const AUDIO_S32MSB : SDL_AudioFormat =     0x9020;
pub const AUDIO_S32 : SDL_AudioFormat =        AUDIO_S32LSB;
pub const AUDIO_F32LSB : SDL_AudioFormat =     0x8120;
pub const AUDIO_F32MSB : SDL_AudioFormat =     0x9120;
pub const AUDIO_F32 : SDL_AudioFormat =        AUDIO_F32LSB;
pub const AUDIO_U16SYS : SDL_AudioFormat =     AUDIO_U16LSB;
pub const AUDIO_S16SYS : SDL_AudioFormat =     AUDIO_S16LSB;
pub const AUDIO_S32SYS : SDL_AudioFormat =     AUDIO_S32LSB;
pub const AUDIO_F32SYS : SDL_AudioFormat =     AUDIO_F32LSB;

pub type SDL_AudioCallback =
    Option<extern "C" fn (arg1: *mut c_void, arg2: *mut uint8_t, arg3: c_int)>;
#[allow(missing_copy_implementations)]
#[repr(C)]
pub struct SDL_AudioSpec {
    pub freq: c_int,
    pub format: SDL_AudioFormat,
    pub channels: uint8_t,
    pub silence: uint8_t,
    pub samples: uint16_t,
    pub padding: uint16_t,
    pub size: uint32_t,
    pub callback: SDL_AudioCallback,
    pub userdata: *mut c_void,
}
pub type SDL_AudioFilter =
    Option<extern "C" fn (arg1: *mut SDL_AudioCVT, arg2: SDL_AudioFormat)>;
#[allow(dead_code, missing_copy_implementations)]
#[derive(Copy, Clone)]
#[repr(C)]
pub struct SDL_AudioCVT {
    pub needed: c_int,
    pub src_format: SDL_AudioFormat,
    pub dst_format: SDL_AudioFormat,
    pub rate_incr: c_double,
    pub buf: *mut uint8_t,
    pub len: c_int,
    pub len_cvt: c_int,
    pub len_mult: c_int,
    pub len_ratio: c_double,
    filters: [SDL_AudioFilter; 10],
    filter_index: c_int,
}
pub type SDL_AudioDeviceID = uint32_t;
pub type SDL_AudioStatus = c_uint;
pub const SDL_AUDIO_STOPPED: c_uint = 0;
pub const SDL_AUDIO_PLAYING: c_uint = 1;
pub const SDL_AUDIO_PAUSED: c_uint = 2;
extern "C" {
    pub fn SDL_GetNumAudioDrivers() -> c_int;
    pub fn SDL_GetAudioDriver(index: c_int) -> *const c_char;
    pub fn SDL_AudioInit(driver_name: *const c_char) -> c_int;
    pub fn SDL_AudioQuit();
    pub fn SDL_GetCurrentAudioDriver() -> *const c_char;
    pub fn SDL_OpenAudio(desired: *const SDL_AudioSpec,
                         obtained: *mut SDL_AudioSpec) -> c_int;
    pub fn SDL_GetNumAudioDevices(iscapture: c_int) -> c_int;
    pub fn SDL_GetAudioDeviceName(index: c_int, iscapture: c_int) -> *const c_char;
    pub fn SDL_OpenAudioDevice(device: *const c_char, iscapture: c_int,
                               desired: *const SDL_AudioSpec,
                               obtained: *mut SDL_AudioSpec,
                               allowed_changes: c_int) -> SDL_AudioDeviceID;
    pub fn SDL_GetAudioStatus() -> SDL_AudioStatus;
    pub fn SDL_GetAudioDeviceStatus(dev: SDL_AudioDeviceID) ->
        SDL_AudioStatus;
    pub fn SDL_PauseAudio(pause_on: c_int);
    pub fn SDL_PauseAudioDevice(dev: SDL_AudioDeviceID, pause_on: c_int);
    pub fn SDL_LoadWAV_RW(src: *mut SDL_RWops, freesrc: c_int,
                          spec: *mut SDL_AudioSpec,
                          audio_buf: *mut *mut uint8_t, audio_len: *mut uint32_t) -> *mut SDL_AudioSpec;
    pub fn SDL_FreeWAV(audio_buf: *mut uint8_t);
    pub fn SDL_BuildAudioCVT(cvt: *mut SDL_AudioCVT,
                             src_format: SDL_AudioFormat, src_channels: uint8_t,
                             src_rate: c_int, dst_format: SDL_AudioFormat,
                             dst_channels: uint8_t, dst_rate: c_int) -> c_int;
    pub fn SDL_ConvertAudio(cvt: *mut SDL_AudioCVT) -> c_int;
    pub fn SDL_MixAudio(dst: *mut uint8_t, src: *const uint8_t, len: uint32_t,
                        volume: c_int);
    pub fn SDL_MixAudioFormat(dst: *mut uint8_t, src: *const uint8_t,
                              format: SDL_AudioFormat, len: uint32_t,
                              volume: c_int);
    pub fn SDL_QueueAudio(dev: SDL_AudioDeviceID, data: *const c_void, len: uint32_t) -> c_int;
    pub fn SDL_GetQueuedAudioSize(dev: SDL_AudioDeviceID) -> uint32_t;
    pub fn SDL_ClearQueuedAudio(dev: SDL_AudioDeviceID);
    pub fn SDL_LockAudio();
    pub fn SDL_LockAudioDevice(dev: SDL_AudioDeviceID);
    pub fn SDL_UnlockAudio();
    pub fn SDL_UnlockAudioDevice(dev: SDL_AudioDeviceID);
    pub fn SDL_CloseAudio();
    pub fn SDL_CloseAudioDevice(dev: SDL_AudioDeviceID);
}
<|endoftext|>


<commit_before>use std::sync::atomic::{AtomicBool, Ordering};
use std::cmp::max;

use game::{Position, Move, Score, ScoreUnit, NumPlies};
use types::{Data};

// TODO put more parameters here
#[derive(Clone)]
pub struct Param {
    pub draw_val: ScoreUnit,
    pub depth: NumPlies,
}

pub fn negamax(pos: &mut Position,
               alpha: Option<Score>,
               beta: Option<Score>,
               param: Param,
               is_killed: &AtomicBool) -> (Score, Data) {
    negamax_generic(pos, alpha, beta, param, is_killed,
                    &mut |x| Box::new(x.legal_iter()),
                    &mut |x, draw_val| {
                        let quiescence_param = Param {
                            draw_val: draw_val,
                            depth: NumPlies(20)
                        };
                        quiescence(x, alpha, beta, quiescence_param, is_killed)
                    },
                    &mut |_, _| None)
}

fn quiescence(pos: &mut Position,
              alpha: Option<Score>,
              beta: Option<Score>,
              param: Param,
              is_killed: &AtomicBool) -> (Score, Data) {
    negamax_generic(pos, alpha, beta, param, is_killed,
                    &mut |x| Box::new(x.legal_noisy_iter()),
                    &mut |x, draw_val| (x.eval(draw_val), Data::one_node()),
                    &mut |x, draw_val| Some(x.eval(draw_val)))
}

// TODO somehow eliminate the Box
fn negamax_generic<F, G, H>(pos: &mut Position,
                            alpha: Option<Score>,
                            beta: Option<Score>,
                            param: Param,
                            is_killed: &AtomicBool,
                            move_gen_fn: &mut F,
                            eval_fn: &mut G,
                            stand_pat_fn: &mut H) -> (Score, Data) where
for<'a> F: FnMut(&'a Position) -> Box<Iterator<Item = Move> + 'a>,
for<'b> G: FnMut(&'b mut Position, ScoreUnit) -> (Score, Data),
for<'c> H: FnMut(&'c mut Position, ScoreUnit) -> Option<Score> {
    if is_killed.load(Ordering::Relaxed) {
        return (Score::Value(ScoreUnit(0)), Data::one_node());
    }
    if param.depth == NumPlies(0) {
        return eval_fn(pos, param.draw_val);
    }

    let (has_legal, score_opt, data): (bool, Option<Score>, Data) = (|| {
        let temp = pos.clone();
        let move_iter = move_gen_fn(&temp);

        let mut has_legal = false;
        let mut prev_score_opt: Option<Score> = alpha;

        if let Some(stand_pat_score) = stand_pat_fn(pos, param.draw_val) {
            let new_score = match prev_score_opt {
                None => stand_pat_score,
                Some(prev_score) => max(prev_score, stand_pat_score),
            };

            has_legal = true;
            prev_score_opt = Some(new_score);

            if let Some(beta_val) = beta {
                if new_score >= beta_val {
                    return (true, beta, Data::one_node());
                }
            }
        }

        let mut prev_data = Data::one_node();

        for curr_move in move_iter {

            let new_alpha = beta.map(|x| x.decrement());
            let new_beta = prev_score_opt.map(|x| x.decrement());
            let new_param = Param {
                draw_val: -param.draw_val,
                depth: NumPlies(param.depth.0 - 1)
            };
            let (temp_score, temp_data) = pos.with_move(&curr_move, |new_pos|
                negamax_generic(new_pos,
                                new_alpha,
                                new_beta,
                                new_param,
                                is_killed,
                                move_gen_fn,
                                eval_fn,
                                stand_pat_fn));
            let curr_score = temp_score.increment();
            let curr_data = temp_data.increment();

            let new_score = match prev_score_opt {
                None => curr_score,
                Some(prev_score) => max(prev_score, curr_score),
            };
            let new_data = prev_data.combine(curr_data);

            has_legal = true;
            prev_score_opt = Some(new_score);
            prev_data = new_data;

            if let Some(beta_val) = beta {
                if new_score >= beta_val {
                    prev_score_opt = beta;
                    break;
                }
            }
        }

        (has_legal, prev_score_opt, prev_data)
    })();

    if has_legal {
        (score_opt.unwrap(), data)
    } else {
        eval_fn(pos, param.draw_val)
    }
}
<commit_msg>Fix bug by allowing eval_fn to take alpha and beta<commit_after>use std::sync::atomic::{AtomicBool, Ordering};
use std::cmp::max;

use game::{Position, Move, Score, ScoreUnit, NumPlies};
use types::{Data};

// TODO put more parameters here
#[derive(Clone)]
pub struct Param {
    pub draw_val: ScoreUnit,
    pub depth: NumPlies,
}

pub fn negamax(pos: &mut Position,
               alpha: Option<Score>,
               beta: Option<Score>,
               param: Param,
               is_killed: &AtomicBool) -> (Score, Data) {
    negamax_generic(pos, alpha, beta, param, is_killed,
                    &mut |x| Box::new(x.legal_iter()),
                    &mut |x, draw_val, inner_alpha, inner_beta| {
                        let quiescence_param = Param {
                            draw_val: draw_val,
                            depth: NumPlies(20)
                        };
                        quiescence(x, inner_alpha, inner_beta, quiescence_param, is_killed)
                    },
                    &mut |_, _| None)
}

fn quiescence(pos: &mut Position,
              alpha: Option<Score>,
              beta: Option<Score>,
              param: Param,
              is_killed: &AtomicBool) -> (Score, Data) {
    negamax_generic(pos, alpha, beta, param, is_killed,
                    &mut |x| Box::new(x.legal_noisy_iter()),
                    &mut |x, draw_val, _, _| (x.eval(draw_val), Data::one_node()),
                    &mut |x, draw_val| Some(x.eval(draw_val)))
}

// TODO somehow eliminate the Box
fn negamax_generic<F, G, H>(pos: &mut Position,
                            alpha: Option<Score>,
                            beta: Option<Score>,
                            param: Param,
                            is_killed: &AtomicBool,
                            move_gen_fn: &mut F,
                            eval_fn: &mut G,
                            stand_pat_fn: &mut H) -> (Score, Data) where
for<'a> F: FnMut(&'a Position) -> Box<Iterator<Item = Move> + 'a>,
for<'b> G: FnMut(&'b mut Position, ScoreUnit, Option<Score>, Option<Score>) -> (Score, Data),
for<'c> H: FnMut(&'c mut Position, ScoreUnit) -> Option<Score> {
    if is_killed.load(Ordering::Relaxed) {
        return (Score::Value(ScoreUnit(0)), Data::one_node());
    }
    if param.depth == NumPlies(0) {
        return eval_fn(pos, param.draw_val, alpha, beta);
    }

    let (has_legal, score_opt, data): (bool, Option<Score>, Data) = (|| {
        let temp = pos.clone();
        let move_iter = move_gen_fn(&temp);

        let mut has_legal = false;
        let mut prev_score_opt: Option<Score> = alpha;

        if let Some(stand_pat_score) = stand_pat_fn(pos, param.draw_val) {
            let new_score = match prev_score_opt {
                None => stand_pat_score,
                Some(prev_score) => max(prev_score, stand_pat_score),
            };

            has_legal = true;
            prev_score_opt = Some(new_score);

            if let Some(beta_val) = beta {
                if new_score >= beta_val {
                    return (true, beta, Data::one_node());
                }
            }
        }

        let mut prev_data = Data::one_node();

        for curr_move in move_iter {

            let new_alpha = beta.map(|x| x.decrement());
            let new_beta = prev_score_opt.map(|x| x.decrement());
            let new_param = Param {
                draw_val: -param.draw_val,
                depth: NumPlies(param.depth.0 - 1)
            };
            let (temp_score, temp_data) = pos.with_move(&curr_move, |new_pos|
                negamax_generic(new_pos,
                                new_alpha,
                                new_beta,
                                new_param,
                                is_killed,
                                move_gen_fn,
                                eval_fn,
                                stand_pat_fn));
            let curr_score = temp_score.increment();
            let curr_data = temp_data.increment();

            let new_score = match prev_score_opt {
                None => curr_score,
                Some(prev_score) => max(prev_score, curr_score),
            };
            let new_data = prev_data.combine(curr_data);

            has_legal = true;
            prev_score_opt = Some(new_score);
            prev_data = new_data;

            if let Some(beta_val) = beta {
                if new_score >= beta_val {
                    prev_score_opt = beta;
                    break;
                }
            }
        }

        (has_legal, prev_score_opt, prev_data)
    })();

    if has_legal {
        (score_opt.unwrap(), data)
    } else {
        eval_fn(pos, param.draw_val, alpha, beta)
    }
}
<|endoftext|>


<commit_before>use super::*;
use redox::*;

#[derive(Copy, Clone)]
/// An instruction
pub struct Inst(pub Repeat, pub Key);

/// Repeatation
#[derive(Copy, Clone)]
pub enum Repeat {
    /// An integer
    Int(usize),
    /// Not given
    Null,
}
impl Repeat {
    /// Either unwrap the Int(n) or fallback to a given value
    #[inline]
    pub fn or(self, fallback: usize) -> usize {
        if let Repeat::Int(n) = self {
            n
        } else {
            fallback
        }
    }
    /// Fallback to one (default)
    #[inline]
    pub fn d(self) -> usize {
        self.or(1)
    }
}

/// Get the next instruction
impl Editor {
    pub fn next_inst(&mut self) -> Inst {
        let mut n = 0;
        let mut shifted = false;

        // TODO: Make the switch to normal mode shift more well-coded.
        loop {
            if let EventOption::Key(k) = self.window.poll().unwrap_or(Event::new()).to_option() {
                let c = k.character;
                match c {
                    '\0' => {
                        return Inst(Repeat::Null, match k.scancode {
                            K_ALT => Key::Alt(k.pressed),
                            K_CTRL => Key::Ctrl(k.pressed),
                            K_LEFT_SHIFT | K_RIGHT_SHIFT => Key::Shift(k.pressed),
                            s if k.pressed => match s {
                                K_BKSP => Key::Backspace,
                                K_LEFT => Key::Left,
                                K_RIGHT => Key::Right,
                                K_UP => Key::Up,
                                K_DOWN => Key::Down,
                                K_TAB => Key::Tab,
                                K_ESC => Key::Escape,
                                _ => Key::Unknown(s),
                            },
                            s => Key::Unknown(s),
                        })
                    }
                    _ => if k.pressed {
                        match self.cursor().mode {
                            Mode::Primitive(_) => {
                                return Inst(Repeat::Null, Key::Char(c));
                            },
                            Mode::Command(_) => {
                                n = match c {
                                    '0' if n != 0 => n * 10,
                                    '1'           => n * 10 + 1,
                                    '2'           => n * 10 + 2,
                                    '3'           => n * 10 + 3,
                                    '4'           => n * 10 + 4,
                                    '5'           => n * 10 + 5,
                                    '6'           => n * 10 + 6,
                                    '7'           => n * 10 + 7,
                                    '8'           => n * 10 + 8,
                                    '9'           => n * 10 + 9,
                                    _             => {

                                        return Inst(if n == 0 { Repeat::Null } else { Repeat::Int(n) }, Key::Char(c));
                                    }
                                }
                            }
                        }

                    },
                }
            }
        }

        unreachable!()
    }
}
<commit_msg>Fix doc msg<commit_after>use super::*;
use redox::*;

#[derive(Copy, Clone)]
/// An instruction
pub struct Inst(pub Repeat, pub Key);

/// Repeatation
#[derive(Copy, Clone)]
pub enum Repeat {
    /// An integer
    Int(usize),
    /// Not given
    Null,
}
impl Repeat {
    /// Either unwrap the Int(n) or fallback to a given value
    #[inline]
    pub fn or(self, fallback: usize) -> usize {
        if let Repeat::Int(n) = self {
            n
        } else {
            fallback
        }
    }
    /// Fallback to one (default)
    #[inline]
    pub fn d(self) -> usize {
        self.or(1)
    }
}

impl Editor {
    /// Get the next instruction
    pub fn next_inst(&mut self) -> Inst {
        let mut n = 0;
        let mut shifted = false;

        // TODO: Make the switch to normal mode shift more well-coded.
        loop {
            if let EventOption::Key(k) = self.window.poll().unwrap_or(Event::new()).to_option() {
                let c = k.character;
                match c {
                    '\0' => {
                        return Inst(Repeat::Null, match k.scancode {
                            K_ALT => Key::Alt(k.pressed),
                            K_CTRL => Key::Ctrl(k.pressed),
                            K_LEFT_SHIFT | K_RIGHT_SHIFT => Key::Shift(k.pressed),
                            s if k.pressed => match s {
                                K_BKSP => Key::Backspace,
                                K_LEFT => Key::Left,
                                K_RIGHT => Key::Right,
                                K_UP => Key::Up,
                                K_DOWN => Key::Down,
                                K_TAB => Key::Tab,
                                K_ESC => Key::Escape,
                                _ => Key::Unknown(s),
                            },
                            s => Key::Unknown(s),
                        })
                    }
                    _ => if k.pressed {
                        match self.cursor().mode {
                            Mode::Primitive(_) => {
                                return Inst(Repeat::Null, Key::Char(c));
                            },
                            Mode::Command(_) => {
                                n = match c {
                                    '0' if n != 0 => n * 10,
                                    '1'           => n * 10 + 1,
                                    '2'           => n * 10 + 2,
                                    '3'           => n * 10 + 3,
                                    '4'           => n * 10 + 4,
                                    '5'           => n * 10 + 5,
                                    '6'           => n * 10 + 6,
                                    '7'           => n * 10 + 7,
                                    '8'           => n * 10 + 8,
                                    '9'           => n * 10 + 9,
                                    _             => {

                                        return Inst(if n == 0 { Repeat::Null } else { Repeat::Int(n) }, Key::Char(c));
                                    }
                                }
                            }
                        }

                    },
                }
            }
        }

        unreachable!()
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::str;

use crate::wire_format::WireType;

/// `Result` alias for `ProtobufError`
pub type Result<T> = std::result::Result<T, crate::Error>;

/// Enum values added here for diagnostic purposes.
/// Users should not depend on specific values.
#[derive(Debug, thiserror::Error)]
pub(crate) enum WireError {
    #[error("Unexpected EOF")]
    UnexpectedEof,
    #[error("Unexpected wire type")]
    UnexpectedWireType(WireType),
    #[error("Incorrect tag")]
    IncorrectTag(u32),
    #[error("Incorrect varint")]
    IncorrectVarint,
    #[error("Invalid UTF-8 sequence")]
    Utf8Error,
    #[error("Invalid enum value: {}", .0)]
    InvalidEnumValue(i32),
    #[error("Over recursion limit")]
    OverRecursionLimit,
    #[error("Truncated message")]
    TruncatedMessage,
    // not really possible
    #[error("Limit overflow")]
    LimitOverflow,
    #[error("New limit must not be greater than current limit")]
    LimitIncrease,
}

/// Generic protobuf error
#[derive(Debug, thiserror::Error)]
pub(crate) enum ProtobufError {
    /// I/O error when reading or writing
    #[error(transparent)]
    IoError(#[from] io::Error),
    /// Malformed input
    #[error(transparent)]
    WireError(#[from] WireError),
    /// Protocol contains a string which is not valid UTF-8 string
    #[error("UTF-8 decode error")]
    Utf8(
        #[source]
        #[from]
        str::Utf8Error,
    ),
    /// Not all required fields of message set.
    #[error("Message `{}` is missing required fields", .0)]
    MessageNotInitialized(String),
    /// Protobuf type and runtime types mismatch.
    #[error("Protobuf type and runtime types are not compatible")]
    IncompatibleProtobufTypeAndRuntimeType,
    /// Group field type not implemented.
    #[error("Group field is not supported")]
    GroupIsNotImplemented,
}

/// Error type for protobuf operations.
#[derive(Debug, thiserror::Error)]
#[error(transparent)]
pub struct Error(#[from] pub(crate) ProtobufError);

impl From<Error> for io::Error {
    #[cold]
    fn from(err: Error) -> Self {
        match err.0 {
            ProtobufError::IoError(e) => e,
            ProtobufError::WireError(e) => {
                io::Error::new(io::ErrorKind::InvalidData, ProtobufError::WireError(e))
            }
            ProtobufError::MessageNotInitialized(message) => io::Error::new(
                io::ErrorKind::InvalidInput,
                ProtobufError::MessageNotInitialized(message),
            ),
            e => io::Error::new(io::ErrorKind::Other, Box::new(e)),
        }
    }
}

impl From<io::Error> for Error {
    #[cold]
    fn from(err: io::Error) -> Self {
        Error(ProtobufError::IoError(err))
    }
}
<commit_msg>Make protobuf error one word size<commit_after>use std::io;
use std::str;

use crate::wire_format::WireType;

/// `Result` alias for `ProtobufError`
pub type Result<T> = std::result::Result<T, crate::Error>;

/// Enum values added here for diagnostic purposes.
/// Users should not depend on specific values.
#[derive(Debug, thiserror::Error)]
pub(crate) enum WireError {
    #[error("Unexpected EOF")]
    UnexpectedEof,
    #[error("Unexpected wire type")]
    UnexpectedWireType(WireType),
    #[error("Incorrect tag")]
    IncorrectTag(u32),
    #[error("Incorrect varint")]
    IncorrectVarint,
    #[error("Invalid UTF-8 sequence")]
    Utf8Error,
    #[error("Invalid enum value: {}", .0)]
    InvalidEnumValue(i32),
    #[error("Over recursion limit")]
    OverRecursionLimit,
    #[error("Truncated message")]
    TruncatedMessage,
    // not really possible
    #[error("Limit overflow")]
    LimitOverflow,
    #[error("New limit must not be greater than current limit")]
    LimitIncrease,
}

/// Generic protobuf error
#[derive(Debug, thiserror::Error)]
pub(crate) enum ProtobufError {
    /// I/O error when reading or writing
    #[error(transparent)]
    IoError(#[from] io::Error),
    /// Malformed input
    #[error(transparent)]
    WireError(#[from] WireError),
    /// Protocol contains a string which is not valid UTF-8 string
    #[error("UTF-8 decode error")]
    Utf8(
        #[source]
        #[from]
        str::Utf8Error,
    ),
    /// Not all required fields of message set.
    #[error("Message `{}` is missing required fields", .0)]
    MessageNotInitialized(String),
    /// Protobuf type and runtime types mismatch.
    #[error("Protobuf type and runtime types are not compatible")]
    IncompatibleProtobufTypeAndRuntimeType,
    /// Group field type not implemented.
    #[error("Group field is not supported")]
    GroupIsNotImplemented,
}

/// Error type for protobuf operations.
#[derive(Debug, thiserror::Error)]
#[error(transparent)]
pub struct Error(pub(crate) Box<ProtobufError>);

impl From<ProtobufError> for Error {
    #[cold]
    fn from(e: ProtobufError) -> Self {
        Self(Box::new(e))
    }
}

impl From<Error> for io::Error {
    #[cold]
    fn from(err: Error) -> Self {
        match *err.0 {
            ProtobufError::IoError(e) => e,
            ProtobufError::WireError(e) => {
                io::Error::new(io::ErrorKind::InvalidData, ProtobufError::WireError(e))
            }
            ProtobufError::MessageNotInitialized(message) => io::Error::new(
                io::ErrorKind::InvalidInput,
                ProtobufError::MessageNotInitialized(message),
            ),
            e => io::Error::new(io::ErrorKind::Other, Box::new(e)),
        }
    }
}

impl From<io::Error> for Error {
    #[cold]
    fn from(err: io::Error) -> Self {
        Error(Box::new(ProtobufError::IoError(err)))
    }
}
<|endoftext|>


<commit_before>// http://stackoverflow.com/questions/25877285/how-to-disable-unused-code-warnings-in-rust
// https://users.rust-lang.org/t/turning-off-compiler-warning-messages/4975/2
#![allow(non_snake_case)]

use postgres::{Connection, TlsMode};

use std::env;

use actix_web::{HttpRequest, HttpResponse};
use futures::future::{result, FutureResult};

#[derive(Serialize, Deserialize)]
struct UserInformation {
    userId: i32,
    name: String,
    surname: String,
    magicUrl: String,
    notifications: Vec<Notification>,
}

#[derive(Serialize, Deserialize)]
struct Notification {
    context: String,
    status: bool,
}

fn connection() -> Connection {
    Connection::connect(
        "postgres://".to_owned()
            + &env::var("PGUSER").unwrap()
            + "@localhost/"
            + &env::var("PGDATABASE").unwrap(),
        TlsMode::None,
    )
    .unwrap()
}

pub fn user_information(req: &HttpRequest) -> FutureResult<HttpResponse, actix_web::error::Error> {
    let conn = connection();
    let user_id = 1;
    let rows = &conn.query(
    "SELECT \"userId\", name, surname, \"magicUrl\" FROM user_information where \"userId\" = $1",
                           &[&user_id])
                    .unwrap();
    let row = rows.into_iter().next().unwrap();

    let mut notifications = Vec::new();
    for row in &conn.query(
        "select context, status from user_information as u join notifications as n on n.\"userId\" \
         = u.\"userId\" and u.\"userId\" = $1",
                           &[&user_id])
                    .unwrap() {
        let notification = Notification {
            context: row.get(0),
            status: row.get(1),
        };
        notifications.push(notification);
    }

    let s = UserInformation {
        userId: row.get(0),
        name: row.get(1),
        surname: row.get(2),
        magicUrl: row.get(3),
        notifications: notifications,
    };
    result(Ok(HttpResponse::Ok().json(s)))
}
/*
#[derive(Serialize, Deserialize)]
struct DataSet {
    id: i32,
    name: String,
}

#[get("/dataSets")]
fn data_sets() -> CORS<JSON<Vec<DataSet>>> {
    let conn = connection();
    let mut data_sets = Vec::new();

    for row in &conn.query("SELECT id, name FROM data_sets", &[]).unwrap() {
        let data_set = DataSet {
            id: row.get(0),
            name: row.get(1),
        };
        // note: move occurs because `data_set` has type `DataSet`,
        // which does not implement the `Copy` trait
        println!("Found DataSet {}", &data_set.name);
        data_sets.push(data_set);
    }
    CORS::any(JSON(data_sets))
}

#[derive(Serialize, Deserialize)]
struct DataSetWithComments {
    id: i32,
    name: String,
    comments: Vec<Comment>,
}

#[derive(Serialize, Deserialize)]
struct Comment {
    id: i32,
    content: String,
    userName: String,
    userPhotoUrl: String,
    date: String,
}

#[get("/dataSets/<url>")]
fn data_set(url: &str) -> CORS<JSON<DataSetWithComments>> {
    let conn = connection();
    let url2 = "dataSets/".to_owned() + url;
    let rows = &conn
        .query("SELECT id, name FROM data_sets where url = $1", &[&url2])
        .unwrap();
    let row = rows.into_iter().next().unwrap();
    let data_set_id: i32 = row.get(0);

    let mut comments = Vec::new();
    for row in &conn
        .query(
            "select c.id, content, \"userName\", \"userPhotoUrl\", date from comments as c \
             join data_sets as d on c.data_set_id = d.id and d.id = $1",
            &[&data_set_id],
        )
        .unwrap()
    {
        let comment = Comment {
            id: row.get(0),
            content: row.get(1),
            userName: row.get(2),
            userPhotoUrl: row.get(3),
            date: row.get(4),
        };
        comments.push(comment);
    }

    CORS::any(JSON(DataSetWithComments {
        id: row.get(0),
        name: row.get(1),
        comments: comments,
    }))
}

#[derive(Serialize, Deserialize)]
struct DataSetShort {
    id: i32,
    name: String,
    description: String,
    owner: String,
    releaseDate: String,
    rating: f32,
    favourite: bool,
    url: String,
}

#[get("/dataSetsCategories/<url>")]
fn data_set_category(url: &str) -> CORS<JSON<DataSetShort>> {
    let conn = connection();
    let url2 = "dataSetsCategories/".to_owned() + url;
    let rows = &conn
        .query(
            "select id from categories where \"contentUrl\" = $1",
            &[&url2],
        )
        .unwrap();
    let row = rows.into_iter().next().unwrap();
    let category_id: i32 = row.get(0);

    let dataSetShortRows = &conn.query("select d.id, name, SUBSTRING(description,0,100) as description, owner, \"releaseDate\", \
        rating, favourite, url from data_sets d join data_sets_in_categories di on d.id = di.data_sets_id \
        and di.categories_id = $1",
                    &[&category_id])
             .unwrap();
    let dataSetShortRow = dataSetShortRows.into_iter().next().unwrap();

    CORS::any(JSON(DataSetShort {
        id: dataSetShortRow.get(0),
        name: dataSetShortRow.get(1),
        description: dataSetShortRow.get(2),
        owner: dataSetShortRow.get(3),
        releaseDate: dataSetShortRow.get(4),
        rating: dataSetShortRow.get(5),
        favourite: dataSetShortRow.get(6),
        url: dataSetShortRow.get(7),
    }))
}

#[derive(Serialize, Deserialize)]
struct Category {
    id: i32,
    title: String,
    route: String,
    count: i32,
    contentUrl: String,
    subcategories: Vec<Subcategory>,
}

#[derive(Serialize, Deserialize)]
struct Subcategory {
    id: i32,
    title: String,
    route: String,
    count: i32,
    contentUrl: String,
}

#[get("/dataSetsCategories")]
fn data_sets_categories() -> CORS<JSON<Vec<Category>>> {
    let conn = connection();
    let mut categories = Vec::new();
    for row in &conn
        .query(
            "SELECT id, title, route, count, \"contentUrl\" FROM categories \
             where type = 'dataSet' and \"parentId\" is null",
            &[],
        )
        .unwrap()
    {
        let row_id: i32 = row.get(0);

        let mut subcategories = Vec::new();
        for subcategoryRow in &conn
            .query(
                "SELECT id, title, route, count, \"contentUrl\" FROM categories \
                 where type = 'dataSet' and \"parentId\" = $1",
                &[&row_id],
            )
            .unwrap()
        {
            let subcategory = Subcategory {
                id: subcategoryRow.get(0),
                title: subcategoryRow.get(1),
                route: subcategoryRow.get(2),
                count: subcategoryRow.get(3),
                contentUrl: subcategoryRow.get(4),
            };

            subcategories.push(subcategory);
        }

        let category = Category {
            id: row.get(0),
            title: row.get(1),
            route: row.get(2),
            count: row.get(3),
            contentUrl: row.get(4),
            subcategories: subcategories,
        };
        println!("Found Category {}", &category.title);
        categories.push(category);
    }
    CORS::any(JSON(categories))
}

use std::fs::File;
use std::io::{BufWriter, Write};

#[post("/dataSets/new", data = "<upload>")]
fn data_sets_new(upload: DataSetMultipart) -> CORS<String> {
    let f = File::create("plik").expect("Unable to create file");
    let mut f = BufWriter::new(f);
    f.write_all(&*upload.metadata)
        .expect("Unable to write data");
    CORS::any(format!("I read this: {:?}", upload))
}

#[derive(Debug)]
struct DataSetMultipart {
    name: String,
    description: String,
    categoryId: i32,
    metadata: Vec<u8>,
}

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

impl FromData for DataSetMultipart {
    type Error = ();

    fn from_data(request: &Request, data: Data) -> data::Outcome<Self, Self::Error> {
        // All of these errors should be reported
        let ct = request
            .headers()
            .get_one("Content-Type")
            .expect("no content-type");
        let idx = ct.find("boundary=").expect("no boundary");
        let boundary = &ct[(idx + "boundary=".len())..];

        let mut d = Vec::new();
        data.stream_to(&mut d).expect("Unable to read");

        let mut mp = Multipart::with_body(Cursor::new(d), boundary);

        // Custom implementation parts

        let mut name = None;
        let mut description = None;
        let mut categoryId = None;
        let mut metadata = None;

        mp.foreach_entry(|mut entry| match entry.name.as_str() {
            "name" => {
                let t = entry.data.as_text().expect("not text");
                name = Some(t.into());
            }
            "description" => {
                let t = entry.data.as_text().expect("not text");
                description = Some(t.into());
            }
            "categoryId" => {
                let t = entry.data.as_text().expect("not text");
                let n = t.parse().expect("not number");
                categoryId = Some(n);
            }
            "metadata" => {
                let mut d = Vec::new();
                let f = entry.data.as_file().expect("not file");
                f.read_to_end(&mut d).expect("can't read");
                metadata = Some(d);
            }
            other => panic!("No known key {}", other),
        })
        .expect("Unable to iterate");

        let v = DataSetMultipart {
            name: name.expect("name not set"),
            description: description.expect("description not set"),
            categoryId: categoryId.expect("categoryId not set"),
            metadata: metadata.expect("file not set"),
        };

        // End custom

        Outcome::Success(v)
    }
}
*/
<commit_msg>unsed<commit_after>// http://stackoverflow.com/questions/25877285/how-to-disable-unused-code-warnings-in-rust
// https://users.rust-lang.org/t/turning-off-compiler-warning-messages/4975/2
#![allow(non_snake_case)]

use postgres::{Connection, TlsMode};

use std::env;

use actix_web::{HttpRequest, HttpResponse};
use futures::future::{result, FutureResult};

#[derive(Serialize, Deserialize)]
struct UserInformation {
    userId: i32,
    name: String,
    surname: String,
    magicUrl: String,
    notifications: Vec<Notification>,
}

#[derive(Serialize, Deserialize)]
struct Notification {
    context: String,
    status: bool,
}

fn connection() -> Connection {
    Connection::connect(
        "postgres://".to_owned()
            + &env::var("PGUSER").unwrap()
            + "@localhost/"
            + &env::var("PGDATABASE").unwrap(),
        TlsMode::None,
    )
    .unwrap()
}

pub fn user_information(_req: &HttpRequest) -> FutureResult<HttpResponse, actix_web::error::Error> {
    let conn = connection();
    let user_id = 1;
    let rows = &conn.query(
    "SELECT \"userId\", name, surname, \"magicUrl\" FROM user_information where \"userId\" = $1",
                           &[&user_id])
                    .unwrap();
    let row = rows.into_iter().next().unwrap();

    let mut notifications = Vec::new();
    for row in &conn.query(
        "select context, status from user_information as u join notifications as n on n.\"userId\" \
         = u.\"userId\" and u.\"userId\" = $1",
                           &[&user_id])
                    .unwrap() {
        let notification = Notification {
            context: row.get(0),
            status: row.get(1),
        };
        notifications.push(notification);
    }

    let s = UserInformation {
        userId: row.get(0),
        name: row.get(1),
        surname: row.get(2),
        magicUrl: row.get(3),
        notifications: notifications,
    };
    result(Ok(HttpResponse::Ok().json(s)))
}
/*
#[derive(Serialize, Deserialize)]
struct DataSet {
    id: i32,
    name: String,
}

#[get("/dataSets")]
fn data_sets() -> CORS<JSON<Vec<DataSet>>> {
    let conn = connection();
    let mut data_sets = Vec::new();

    for row in &conn.query("SELECT id, name FROM data_sets", &[]).unwrap() {
        let data_set = DataSet {
            id: row.get(0),
            name: row.get(1),
        };
        // note: move occurs because `data_set` has type `DataSet`,
        // which does not implement the `Copy` trait
        println!("Found DataSet {}", &data_set.name);
        data_sets.push(data_set);
    }
    CORS::any(JSON(data_sets))
}

#[derive(Serialize, Deserialize)]
struct DataSetWithComments {
    id: i32,
    name: String,
    comments: Vec<Comment>,
}

#[derive(Serialize, Deserialize)]
struct Comment {
    id: i32,
    content: String,
    userName: String,
    userPhotoUrl: String,
    date: String,
}

#[get("/dataSets/<url>")]
fn data_set(url: &str) -> CORS<JSON<DataSetWithComments>> {
    let conn = connection();
    let url2 = "dataSets/".to_owned() + url;
    let rows = &conn
        .query("SELECT id, name FROM data_sets where url = $1", &[&url2])
        .unwrap();
    let row = rows.into_iter().next().unwrap();
    let data_set_id: i32 = row.get(0);

    let mut comments = Vec::new();
    for row in &conn
        .query(
            "select c.id, content, \"userName\", \"userPhotoUrl\", date from comments as c \
             join data_sets as d on c.data_set_id = d.id and d.id = $1",
            &[&data_set_id],
        )
        .unwrap()
    {
        let comment = Comment {
            id: row.get(0),
            content: row.get(1),
            userName: row.get(2),
            userPhotoUrl: row.get(3),
            date: row.get(4),
        };
        comments.push(comment);
    }

    CORS::any(JSON(DataSetWithComments {
        id: row.get(0),
        name: row.get(1),
        comments: comments,
    }))
}

#[derive(Serialize, Deserialize)]
struct DataSetShort {
    id: i32,
    name: String,
    description: String,
    owner: String,
    releaseDate: String,
    rating: f32,
    favourite: bool,
    url: String,
}

#[get("/dataSetsCategories/<url>")]
fn data_set_category(url: &str) -> CORS<JSON<DataSetShort>> {
    let conn = connection();
    let url2 = "dataSetsCategories/".to_owned() + url;
    let rows = &conn
        .query(
            "select id from categories where \"contentUrl\" = $1",
            &[&url2],
        )
        .unwrap();
    let row = rows.into_iter().next().unwrap();
    let category_id: i32 = row.get(0);

    let dataSetShortRows = &conn.query("select d.id, name, SUBSTRING(description,0,100) as description, owner, \"releaseDate\", \
        rating, favourite, url from data_sets d join data_sets_in_categories di on d.id = di.data_sets_id \
        and di.categories_id = $1",
                    &[&category_id])
             .unwrap();
    let dataSetShortRow = dataSetShortRows.into_iter().next().unwrap();

    CORS::any(JSON(DataSetShort {
        id: dataSetShortRow.get(0),
        name: dataSetShortRow.get(1),
        description: dataSetShortRow.get(2),
        owner: dataSetShortRow.get(3),
        releaseDate: dataSetShortRow.get(4),
        rating: dataSetShortRow.get(5),
        favourite: dataSetShortRow.get(6),
        url: dataSetShortRow.get(7),
    }))
}

#[derive(Serialize, Deserialize)]
struct Category {
    id: i32,
    title: String,
    route: String,
    count: i32,
    contentUrl: String,
    subcategories: Vec<Subcategory>,
}

#[derive(Serialize, Deserialize)]
struct Subcategory {
    id: i32,
    title: String,
    route: String,
    count: i32,
    contentUrl: String,
}

#[get("/dataSetsCategories")]
fn data_sets_categories() -> CORS<JSON<Vec<Category>>> {
    let conn = connection();
    let mut categories = Vec::new();
    for row in &conn
        .query(
            "SELECT id, title, route, count, \"contentUrl\" FROM categories \
             where type = 'dataSet' and \"parentId\" is null",
            &[],
        )
        .unwrap()
    {
        let row_id: i32 = row.get(0);

        let mut subcategories = Vec::new();
        for subcategoryRow in &conn
            .query(
                "SELECT id, title, route, count, \"contentUrl\" FROM categories \
                 where type = 'dataSet' and \"parentId\" = $1",
                &[&row_id],
            )
            .unwrap()
        {
            let subcategory = Subcategory {
                id: subcategoryRow.get(0),
                title: subcategoryRow.get(1),
                route: subcategoryRow.get(2),
                count: subcategoryRow.get(3),
                contentUrl: subcategoryRow.get(4),
            };

            subcategories.push(subcategory);
        }

        let category = Category {
            id: row.get(0),
            title: row.get(1),
            route: row.get(2),
            count: row.get(3),
            contentUrl: row.get(4),
            subcategories: subcategories,
        };
        println!("Found Category {}", &category.title);
        categories.push(category);
    }
    CORS::any(JSON(categories))
}

use std::fs::File;
use std::io::{BufWriter, Write};

#[post("/dataSets/new", data = "<upload>")]
fn data_sets_new(upload: DataSetMultipart) -> CORS<String> {
    let f = File::create("plik").expect("Unable to create file");
    let mut f = BufWriter::new(f);
    f.write_all(&*upload.metadata)
        .expect("Unable to write data");
    CORS::any(format!("I read this: {:?}", upload))
}

#[derive(Debug)]
struct DataSetMultipart {
    name: String,
    description: String,
    categoryId: i32,
    metadata: Vec<u8>,
}

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

impl FromData for DataSetMultipart {
    type Error = ();

    fn from_data(request: &Request, data: Data) -> data::Outcome<Self, Self::Error> {
        // All of these errors should be reported
        let ct = request
            .headers()
            .get_one("Content-Type")
            .expect("no content-type");
        let idx = ct.find("boundary=").expect("no boundary");
        let boundary = &ct[(idx + "boundary=".len())..];

        let mut d = Vec::new();
        data.stream_to(&mut d).expect("Unable to read");

        let mut mp = Multipart::with_body(Cursor::new(d), boundary);

        // Custom implementation parts

        let mut name = None;
        let mut description = None;
        let mut categoryId = None;
        let mut metadata = None;

        mp.foreach_entry(|mut entry| match entry.name.as_str() {
            "name" => {
                let t = entry.data.as_text().expect("not text");
                name = Some(t.into());
            }
            "description" => {
                let t = entry.data.as_text().expect("not text");
                description = Some(t.into());
            }
            "categoryId" => {
                let t = entry.data.as_text().expect("not text");
                let n = t.parse().expect("not number");
                categoryId = Some(n);
            }
            "metadata" => {
                let mut d = Vec::new();
                let f = entry.data.as_file().expect("not file");
                f.read_to_end(&mut d).expect("can't read");
                metadata = Some(d);
            }
            other => panic!("No known key {}", other),
        })
        .expect("Unable to iterate");

        let v = DataSetMultipart {
            name: name.expect("name not set"),
            description: description.expect("description not set"),
            categoryId: categoryId.expect("categoryId not set"),
            metadata: metadata.expect("file not set"),
        };

        // End custom

        Outcome::Success(v)
    }
}
*/
<|endoftext|>