<commit_before>use super::{Upsert, Number, Integer};
use super::{Bson, Array, Object};
use std::borrow::Cow;

/* Add easy API for dot notation */

#[derive(Clone)]
pub struct Update<'a>(Object<'a>);

impl<'a> Update<'a> {
    pub fn new() -> Self {
        Update(Object::new())
    }

    pub fn field(&'a mut self, field: &'a str) -> UpdateField {
        UpdateField {
            root:   &mut self.0,
            field:  field,
        }
    }

    pub fn array(&'a mut self, array: &'a str) -> UpdateArray {
        UpdateArray {
            root:   &mut self.0,
            array:  array,
        }
    }
}

pub struct UpdateField<'a> {
    root:    &'a mut Object<'a>,
    field:   &'a str,
}

impl<'a> UpdateField<'a> {
    pub fn increment<N: Number<'a>>(self, amount: N) -> Self {
        self.add_modifier(INCREMENT, amount.to_bson_num())
    }

    #[inline]
    pub fn inc<N: Number<'a>>(self, amount: N) -> Self {
        self.increment(amount)
    }

    pub fn multiply<N: Number<'a>>(self, amount: N) -> Self {
        self.add_modifier(MULTIPLY, amount.to_bson_num())
    }

    #[inline]
    pub fn mul<N: Number<'a>>(self, amount: N) -> Self {
        self.multiply(amount)
    }

    pub fn min(self, value: Bson<'a>) -> Self {
        self.add_modifier(MIN, value)
    }

    pub fn max(self, value: Bson<'a>) -> Self {
        self.add_modifier(MAX, value)
    }

    pub fn and<I: Integer<'a>>(self, bits: I) -> Self {
        self.bit(AND, bits.to_bson_int())
    }

    pub fn or<I: Integer<'a>>(self, bits: I) -> Self {
        self.bit(OR, bits.to_bson_int())
    }

    pub fn xor<I: Integer<'a>>(self, bits: I) -> Self {
        self.bit(XOR, bits.to_bson_int())
    }

    pub fn set(self, value: Bson<'a>) -> Self {
        self.add_modifier(SET, value)
    }

    pub fn unset(self) -> Self {
        self.add_modifier(UNSET, Bson::Str(""))
    }

    pub fn rename(self, name: &'a str) -> Self {
        self.add_modifier(RENAME, Bson::Str(name))
    }

    pub fn set_on_insert(self, value: Bson<'a>) -> Self {
        self.add_modifier(SET_ON_INSERT, value)
    }

    pub fn set_date_now(self) -> Self {
        self.add_modifier(CURRENT_DATE, Bson::Str(DATE_TYPE))
    }

    pub fn set_timestamp_now(self) -> Self {
        self.add_modifier(CURRENT_DATE, Bson::Str(TIMESTAMP_TYPE))
    }

    #[inline]
    fn add_modifier(mut self, category: &'static str, value: Bson<'a>) -> Self {
        {
            let group = self.root.object(category);
            group.insert(self.field, value);
        }
        self
    }

    #[inline]
    fn bit(mut self, op: &'static str, bits: Bson<'a>) -> Self {
        {
	        let bits_update = self.root.object(BIT);
	        let field_ops = bits_update.object(self.field);
	        field_ops.insert(op, bits);
        }
        self
    }
}

pub struct UpdateArray<'a> {
    root:    &'a mut Object<'a>,
    array:   &'a str,
}

impl<'a> UpdateArray<'a> {
    /* TODO: Implement first-matching ( $ symbol )
     * and dot notation for arrays (including index)
     * .first_matching()
     * .index() | These can lead to either a field or another
     * .dot()   | array?
     */
    /* TODO: Refactor for less code bloat */

    pub fn push(self, value: Bson<'a>) -> Self {
        self.add_modifier(PUSH, value)
    }

    pub fn push_all(self, values: &'a Array<'a>) -> Self {
        {
	        let array = self.root.deep_object(PUSH, self.array);
	        array.insert(EACH, Bson::Array(Cow::Borrowed(values)));
        }
        self
    }

    pub fn slice(self, max: u32) -> Self {
        {
            let array = self.root.deep_object(PUSH, self.array);
            array.entry(EACH).or_insert_with(|| Bson::Array(Cow::Owned(Vec::new())));
            array.insert(SLICE, max.to_bson_int());
        }
        self
    }

    pub fn sort(self) -> Self {
        self.sort_array(1, None)
    }

    pub fn rev_sort(self) -> Self {
        self.sort_array(-1, None)
    }

    pub fn sort_by(self, field: &'a str) -> Self {
        self.sort_array(1, Some(field))
    }

    pub fn rev_sort_by(self, field: &'a str) -> Self {
        self.sort_array(-1, Some(field))
    }

    fn sort_array(mut self, direction: i32, spec: Option<&'a str>) -> Self {
        {
	        let array = self.root.deep_object(PUSH, self.array);
            array.entry(EACH).or_insert_with(|| Bson::Array(Cow::Owned(Vec::new())));
            if let Some(field) = spec {
                let sort = array.object(SORT);
                sort.insert(field, direction.to_bson_int());
            } else {
                array.insert(SORT, direction.to_bson_int());
            }
	    }
        self
    }

    pub fn pull(self, value: Bson<'a>) -> Self {
        self.add_modifier(PULL, value)
    }

    pub fn pull_all(self, values: &'a Array<'a>) -> Self {
        self.add_modifier(PULL_ALL, Bson::Array(Cow::Borrowed(values)))
    }

    /* TODO: Requires Query ops pub fn pull_if(self, condition: ) */

    pub fn pop_front(self) -> Self {
        // TODO: Check if we should be using FloatingPoint()
        // to avoid NumberInt("-1");
        self.add_modifier(POP, (-1).to_bson_int())
    }

    pub fn pop_back(self) -> Self {
        // TODO: Same as above
        self.add_modifier(POP, 1.to_bson_int())
    }

    pub fn add_to_set(self, value: Bson<'a>) -> Self {
        self.add_modifier(ADD_TO_SET, value)
    }

    pub fn add_all_to_set(self, values: &'a Array<'a>) -> Self {
        {
            let array = self.root.deep_object(ADD_TO_SET, self.array);
            array.insert(EACH, Bson::Array(Cow::Borrowed(values)));
        }
        self
    }

    #[inline]
    fn add_modifier(mut self, category: &'static str, value: Bson<'a>) -> Self {
        {
            let group = self.root.object(category);
            group.insert(self.array, value);
        }
        self
    }
}

/*****************
 * Update Fields *
 *****************/
const INCREMENT:      &'static str = "$inc";
const MULTIPLY:       &'static str = "$mul";
const RENAME:         &'static str = "$rename";
const SET_ON_INSERT:  &'static str = "$setOnInsert";
const SET:            &'static str = "$set";
const UNSET:          &'static str = "$unset";
const MIN:            &'static str = "$min";
const MAX:            &'static str = "$max";
const CURRENT_DATE:   &'static str = "$currentDate";
const DATE_TYPE:      &'static str = "{$type:\"date\"}";
const TIMESTAMP_TYPE: &'static str = "{$type:\"timestamp\"}";

/*****************
 * Update Arrays *
 *****************/
/* Operators */
const FIRST:      &'static str = "$";
const ADD_TO_SET: &'static str = "$addToSet";
const POP:        &'static str = "$pop";
const PULL_ALL:   &'static str = "$pullAll";
const PULL:       &'static str = "$pull";
const PUSH:       &'static str = "$push";
/* Modifiers */
const EACH:       &'static str = "$each";
const SLICE:      &'static str = "$slice";
const SORT:       &'static str = "$sort";
const POSITION:   &'static str = "$position";

/*********************
 * Bitwise Operation *
 *********************/
const BIT: &'static str = "$bit";
const AND: &'static str = "and";
const XOR: &'static str = "xor";
const OR:  &'static str = "or";

/*************
 * Isolation *
 *************/
const ISOLATED: &'static str = "$isolated";
<commit_msg>Added  op<commit_after>use super::{Upsert, Number, Integer};
use super::{Bson, Array, Object};
use std::borrow::Cow;

/* Add easy API for dot notation */

#[derive(Clone)]
pub struct Update<'a>(Object<'a>);

impl<'a> Update<'a> {
    pub fn new() -> Self {
        Update(Object::new())
    }

    pub fn field(&'a mut self, field: &'a str) -> UpdateField {
        UpdateField {
            root:   &mut self.0,
            field:  field,
        }
    }

    pub fn array(&'a mut self, array: &'a str) -> UpdateArray {
        UpdateArray {
            root:   &mut self.0,
            array:  array,
        }
    }
}

pub struct UpdateField<'a> {
    root:    &'a mut Object<'a>,
    field:   &'a str,
}

impl<'a> UpdateField<'a> {
    pub fn increment<N: Number<'a>>(self, amount: N) -> Self {
        self.add_modifier(INCREMENT, amount.to_bson_num())
    }

    #[inline]
    pub fn inc<N: Number<'a>>(self, amount: N) -> Self {
        self.increment(amount)
    }

    pub fn multiply<N: Number<'a>>(self, amount: N) -> Self {
        self.add_modifier(MULTIPLY, amount.to_bson_num())
    }

    #[inline]
    pub fn mul<N: Number<'a>>(self, amount: N) -> Self {
        self.multiply(amount)
    }

    pub fn min(self, value: Bson<'a>) -> Self {
        self.add_modifier(MIN, value)
    }

    pub fn max(self, value: Bson<'a>) -> Self {
        self.add_modifier(MAX, value)
    }

    pub fn and<I: Integer<'a>>(self, bits: I) -> Self {
        self.bit(AND, bits.to_bson_int())
    }

    pub fn or<I: Integer<'a>>(self, bits: I) -> Self {
        self.bit(OR, bits.to_bson_int())
    }

    pub fn xor<I: Integer<'a>>(self, bits: I) -> Self {
        self.bit(XOR, bits.to_bson_int())
    }

    pub fn set(self, value: Bson<'a>) -> Self {
        self.add_modifier(SET, value)
    }

    pub fn unset(self) -> Self {
        self.add_modifier(UNSET, Bson::Str(""))
    }

    pub fn rename(self, name: &'a str) -> Self {
        self.add_modifier(RENAME, Bson::Str(name))
    }

    pub fn set_on_insert(self, value: Bson<'a>) -> Self {
        self.add_modifier(SET_ON_INSERT, value)
    }

    pub fn set_date_now(self) -> Self {
        self.add_modifier(CURRENT_DATE, Bson::Str(DATE_TYPE))
    }

    pub fn set_timestamp_now(self) -> Self {
        self.add_modifier(CURRENT_DATE, Bson::Str(TIMESTAMP_TYPE))
    }

    #[inline]
    fn add_modifier(mut self, category: &'static str, value: Bson<'a>) -> Self {
        {
            let group = self.root.object(category);
            group.insert(self.field, value);
        }
        self
    }

    #[inline]
    fn bit(mut self, op: &'static str, bits: Bson<'a>) -> Self {
        {
	        let bits_update = self.root.object(BIT);
	        let field_ops = bits_update.object(self.field);
	        field_ops.insert(op, bits);
        }
        self
    }
}

pub struct UpdateArray<'a> {
    root:    &'a mut Object<'a>,
    array:   &'a str,
}

impl<'a> UpdateArray<'a> {
    /* TODO: Implement first-matching ( $ symbol )
     * and dot notation for arrays (including index)
     * .first_matching()
     * .index() | These can lead to either a field or another
     * .dot()   | array?
     */
    /* TODO: Refactor for less code bloat */

    pub fn push(self, value: Bson<'a>) -> Self {
        self.add_modifier(PUSH, value)
    }

    #[inline]
    pub fn push_at(self, value: Bson<'a>, position: u32) -> Self {
        self.push_pos_cow(Cow::Owned(vec![value]), position)
    }

    pub fn push_all(self, values: &'a Array<'a>) -> Self {
        {
	        let array = self.root.deep_object(PUSH, self.array);
	        array.insert(EACH, Bson::Array(Cow::Borrowed(values)));
        }
        self
    }

    #[inline]
    pub fn push_all_at(self, values: &'a Array<'a>, position: u32) -> Self {
        self.push_pos_cow(Cow::Borrowed(values), position)
    }

    pub fn slice(self, max: u32) -> Self {
        {
            let array = self.root.deep_object(PUSH, self.array);
            array.entry(EACH).or_insert_with(|| Bson::Array(Cow::Owned(Vec::new())));
            array.insert(SLICE, max.to_bson_int());
        }
        self
    }

    pub fn sort(self) -> Self {
        self.sort_array(1, None)
    }

    pub fn rev_sort(self) -> Self {
        self.sort_array(-1, None)
    }

    pub fn sort_by(self, field: &'a str) -> Self {
        self.sort_array(1, Some(field))
    }

    pub fn rev_sort_by(self, field: &'a str) -> Self {
        self.sort_array(-1, Some(field))
    }

    fn sort_array(mut self, direction: i32, spec: Option<&'a str>) -> Self {
        {
	        let array = self.root.deep_object(PUSH, self.array);
            array.entry(EACH).or_insert_with(|| Bson::Array(Cow::Owned(Vec::new())));
            if let Some(field) = spec {
                let sort = array.object(SORT);
                sort.insert(field, direction.to_bson_int());
            } else {
                array.insert(SORT, direction.to_bson_int());
            }
	    }
        self
    }

    pub fn pull(self, value: Bson<'a>) -> Self {
        self.add_modifier(PULL, value)
    }

    pub fn pull_all(self, values: &'a Array<'a>) -> Self {
        self.add_modifier(PULL_ALL, Bson::Array(Cow::Borrowed(values)))
    }

    /* TODO: Requires Query ops pub fn pull_if(self, condition: ) */

    pub fn pop_front(self) -> Self {
        // TODO: Check if we should be using FloatingPoint()
        // to avoid NumberInt("-1");
        self.add_modifier(POP, (-1).to_bson_int())
    }

    pub fn pop_back(self) -> Self {
        // TODO: Same as above
        self.add_modifier(POP, 1.to_bson_int())
    }

    pub fn add_to_set(self, value: Bson<'a>) -> Self {
        self.add_modifier(ADD_TO_SET, value)
    }

    pub fn add_all_to_set(self, values: &'a Array<'a>) -> Self {
        {
            let array = self.root.deep_object(ADD_TO_SET, self.array);
            array.insert(EACH, Bson::Array(Cow::Borrowed(values)));
        }
        self
    }

    #[inline]
    fn add_modifier(mut self, category: &'static str, value: Bson<'a>) -> Self {
        {
            let group = self.root.object(category);
            group.insert(self.array, value);
        }
        self
    }

    fn push_pos_cow(self, values: Cow<'a, Array<'a>>, position: u32) -> Self {
        {
            let array = self.root.deep_object(PUSH, self.array);
            array.insert(EACH, Bson::Array(values));
            array.insert(POSITION, position.to_bson_int());
        }
        self
    }
}

/*****************
 * Update Fields *
 *****************/
const INCREMENT:      &'static str = "$inc";
const MULTIPLY:       &'static str = "$mul";
const RENAME:         &'static str = "$rename";
const SET_ON_INSERT:  &'static str = "$setOnInsert";
const SET:            &'static str = "$set";
const UNSET:          &'static str = "$unset";
const MIN:            &'static str = "$min";
const MAX:            &'static str = "$max";
const CURRENT_DATE:   &'static str = "$currentDate";
const DATE_TYPE:      &'static str = "{$type:\"date\"}";
const TIMESTAMP_TYPE: &'static str = "{$type:\"timestamp\"}";

/*****************
 * Update Arrays *
 *****************/
/* Operators */
const FIRST:      &'static str = "$";
const ADD_TO_SET: &'static str = "$addToSet";
const POP:        &'static str = "$pop";
const PULL_ALL:   &'static str = "$pullAll";
const PULL:       &'static str = "$pull";
const PUSH:       &'static str = "$push";
/* Modifiers */
const EACH:       &'static str = "$each";
const SLICE:      &'static str = "$slice";
const SORT:       &'static str = "$sort";
const POSITION:   &'static str = "$position";

/*********************
 * Bitwise Operation *
 *********************/
const BIT: &'static str = "$bit";
const AND: &'static str = "and";
const XOR: &'static str = "xor";
const OR:  &'static str = "or";

/*************
 * Isolation *
 *************/
const ISOLATED: &'static str = "$isolated";
<|endoftext|>


<commit_before>use core::intrinsics;

// NOTE These functions are implemented using assembly because they using a custom
// calling convention which can't be implemented using a normal Rust function
#[cfg(windows)]
#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn ___chkstk_ms() {
    asm!("push   %rcx
          push   %rax
          cmp    $$0x1000,%rax
          lea    24(%rsp),%rcx
          jb     1f
          2:
          sub    $$0x1000,%rcx
          test   %rcx,(%rcx)
          sub    $$0x1000,%rax
          cmp    $$0x1000,%rax
          ja     2b
          1:
          sub    %rax,%rcx
          test   %rcx,(%rcx)
          pop    %rax
          pop    %rcx
          ret");
    intrinsics::unreachable();
}

#[cfg(windows)]
#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __alloca() {
    asm!("mov    %rcx,%rax  // x64 _alloca is a normal function with parameter in rcx");
    // The original behavior had __alloca fall through to ___chkstk here, but
    // I don't believe that this behavior is guaranteed, and a program that uses
    // only __alloca could have ___chkstk removed by --gc-sections. Call
    // ___chkstk here to guarantee that neither of those happen.
    ___chkstk();
}

#[cfg(windows)]
#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn ___chkstk() {
    asm!("push   %rcx
          cmp    $$0x1000,%rax
          lea    16(%rsp),%rcx  // rsp before calling this routine -> rcx
          jb     1f
          2:
          sub    $$0x1000,%rcx
          test   %rcx,(%rcx)
          sub    $$0x1000,%rax
          cmp    $$0x1000,%rax
          ja     2b
          1:
          sub    %rax,%rcx
          test   %rcx,(%rcx)

          lea    8(%rsp),%rax   // load pointer to the return address into rax
          mov    %rcx,%rsp      // install the new top of stack pointer into rsp
          mov    -8(%rax),%rcx  // restore rcx
          push   (%rax)         // push return address onto the stack
          sub    %rsp,%rax      // restore the original value in rax
          ret");
    intrinsics::unreachable();
}

<commit_msg>Use `jmp` to implement __alloca fallthrough<commit_after>use core::intrinsics;

// NOTE These functions are implemented using assembly because they using a custom
// calling convention which can't be implemented using a normal Rust function
#[cfg(windows)]
#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn ___chkstk_ms() {
    asm!("push   %rcx
          push   %rax
          cmp    $$0x1000,%rax
          lea    24(%rsp),%rcx
          jb     1f
          2:
          sub    $$0x1000,%rcx
          test   %rcx,(%rcx)
          sub    $$0x1000,%rax
          cmp    $$0x1000,%rax
          ja     2b
          1:
          sub    %rax,%rcx
          test   %rcx,(%rcx)
          pop    %rax
          pop    %rcx
          ret");
    intrinsics::unreachable();
}

#[cfg(windows)]
#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __alloca() {
    asm!("mov    %rcx,%rax  // x64 _alloca is a normal function with parameter in rcx
          jmp    ___chkstk  // Jump to ___chkstk since fallthrough may be unreliable");
    intrinsics::unreachable();
}

#[cfg(windows)]
#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn ___chkstk() {
    asm!("push   %rcx
          cmp    $$0x1000,%rax
          lea    16(%rsp),%rcx  // rsp before calling this routine -> rcx
          jb     1f
          2:
          sub    $$0x1000,%rcx
          test   %rcx,(%rcx)
          sub    $$0x1000,%rax
          cmp    $$0x1000,%rax
          ja     2b
          1:
          sub    %rax,%rcx
          test   %rcx,(%rcx)

          lea    8(%rsp),%rax   // load pointer to the return address into rax
          mov    %rcx,%rsp      // install the new top of stack pointer into rsp
          mov    -8(%rax),%rcx  // restore rcx
          push   (%rax)         // push return address onto the stack
          sub    %rsp,%rax      // restore the original value in rax
          ret");
    intrinsics::unreachable();
}

<|endoftext|>


<commit_before>
<commit_msg>Add tests for code generated by `quantity!` macro.<commit_after>#[macro_use]
mod length {
    quantity! {
        quantity: TLength; "length";
        dimension: Q<P1, Z0>;
        units {
            @kilometer: prefix!(kilo); "km", "kilometer", "kilometers";
            @meter: prefix!(none); "m", "meter", "meters";
        }
    }
}

#[macro_use]
mod mass {
    quantity! {
        quantity: TMass; "mass";
        dimension: Q<Z0, P1>;
        units {
            @kilogram: prefix!(kilo) / prefix!(kilo); "kg", "kilogram", "kilograms";
        }
    }
}

system! {
    quantities: Q {
        length: meter, L;
        mass: kilogram, M;
    }
    units: U {
        TLength,
        TMass,
    }
}

mod f32 {
    Q!(tests, f32);
}

mod quantity {
    use super::*;
    use super::f32::*;
    use super::length::{kilometer, meter};
    use super::mass::kilogram;

    #[test]
    fn description() {
        assert_eq!("length", length::description());
        assert_eq!("mass", mass::description());
    }

    #[test]
    fn abbreviation() {
        assert_eq!("km", kilometer::abbreviation());
        assert_eq!("m", meter::abbreviation());
        assert_eq!("kg", kilogram::abbreviation());
    }

    #[test]
    fn singular() {
        assert_eq!("kilometer", kilometer::singular());
        assert_eq!("meter", meter::singular());
        assert_eq!("kilogram", kilogram::singular());
    }

    #[test]
    fn plural() {
        assert_eq!("kilometers", kilometer::plural());
        assert_eq!("meters", meter::plural());
        assert_eq!("kilograms", kilogram::plural());
    }

    #[test]
    fn new() {
        let l1 = TLength::new::<kilometer>(1.0);
        let l2 = TLength::new::<meter>(1.0);
        let m1 = TMass::new::<kilogram>(1.0);

        assert_eq!(1000.0, l1.value);
        assert_eq!(1.0, l2.value);
        assert_eq!(1.0, m1.value);
    }

    #[test]
    fn get() {
        let l1 = TLength::new::<kilometer>(1.0);
        let l2 = TLength::new::<meter>(1.0);
        let m1 = TMass::new::<kilogram>(1.0);

        assert_eq!(1000.0, l1.get(meter));
        assert_eq!(1.0, l2.get(meter));
        assert_eq!(1.0, l1.get(kilometer));
        assert_eq!(0.001, l2.get(kilometer));
        assert_eq!(1.0, m1.get(kilogram));
    }

    #[test]
    fn conversion() {
        assert_eq!(1000.0, kilometer::conversion());
        assert_eq!(1.0, meter::conversion());
        assert_eq!(1.0, kilogram::conversion());
    }
}
<|endoftext|>


<commit_before>use quick_check::{
    quickcheck,
    quicktest
};

use property::{
    Property
};

use testable::{
    IntoTestable
};

#[test]
fn prop_reverse_reverse() {
    fn prop(input: Vec<u8>) -> bool {
        let mut revrev = input.clone();
        revrev.reverse();
        revrev.reverse();
        revrev == input
    }
    quickcheck(prop as fn(Vec<u8>) -> bool);
}

#[test]
#[should_panic]
fn prop_oob() {
    fn prop() -> bool {
        let zero: Vec<bool> = vec![];
        zero[0]
    }
    quicktest(prop as fn() -> bool);
    // match quicktest(prop as fn() -> bool) {
    //     Ok(n) => panic!("prop_oob should fail with a runtime error \
    //                      but instead it passed {} tests.", n),
    //     _ => return
    // }
}

#[test]
fn reverse_single() {
    let prop = Property::<(Vec<usize>,)>
        ::when(|xs| xs.len() == 1)
        .property(|xs| xs == xs.clone().into_iter().rev().collect::<Vec<_>>())
        // ::new(|xs| xs == xs.clone().into_iter().rev().collect::<Vec<_>>())
        .resize(|_| 1);

    quickcheck(prop);
}
<commit_msg>Adding some tests from quickcheck-rs.<commit_after>use quick_check::{
    quickcheck,
    quicktest
};

use property::{
    Property
};

use testable::{
    IntoTestable
};

#[test]
fn prop_reverse_reverse() {
    fn prop(input: Vec<u8>) -> bool {
        let mut revrev = input.clone();
        revrev.reverse();
        revrev.reverse();
        revrev == input
    }
    quickcheck(prop as fn(Vec<u8>) -> bool);
}

#[test]
#[should_panic]
fn prop_oob() {
    fn prop() -> bool {
        let zero: Vec<bool> = vec![];
        zero[0]
    }
    quicktest(prop as fn() -> bool);
    // match quicktest(prop as fn() -> bool) {
    //     Ok(n) => panic!("prop_oob should fail with a runtime error \
    //                      but instead it passed {} tests.", n),
    //     _ => return
    // }
}

#[test]
fn reverse_single() {
    let prop = Property::<(Vec<usize>,)>
        ::when(|xs| xs.len() == 1)
        .property(|xs| xs == xs.clone().into_iter().rev().collect::<Vec<_>>())
        .resize(|_| 5);

    quickcheck(prop);
}

#[test]
fn reverse_app() {
    fn prop(xs: Vec<usize>, ys: Vec<usize>) -> bool {
        let mut app = xs.clone();
        app.extend(ys.iter().cloned());
        let app_rev: Vec<usize> = app.into_iter().rev().collect();

        let rxs: Vec<usize> = xs.into_iter().rev().collect();
        let mut rev_app = ys.into_iter().rev().collect::<Vec<usize>>();
        rev_app.extend(rxs.into_iter());

        app_rev == rev_app
    }
    quickcheck(prop as fn(Vec<usize>, Vec<usize>) -> bool);
}

#[test]
fn max() {
    let prop = Property::<(isize, isize)>
        ::when(|x, y| x <= y)
        .property(|x, y| ::std::cmp::max(x, y) == y);

    quickcheck(prop);
}

#[test]
fn sort() {
    fn prop(mut xs: Vec<isize>) -> bool {
        xs.sort_by(|x, y| x.cmp(y));
        let upto = if xs.len() == 0 { 0 } else { xs.len()-1 };
        for i in 0..upto {
            if xs[i] > xs[i+1] {
                return false
            }
        }
        true
    }
    quickcheck(prop as fn(Vec<isize>) -> bool);
}

fn sieve(n: usize) -> Vec<usize> {
    if n <= 1 {
        return vec![];
    }

    let mut marked = vec![false; n+1];
    marked[0] = true;
    marked[1] = true;
    marked[2] = true;
    for p in 2..n {
        for i in (2*p..n).filter(|&n| n % p == 0) {
            marked[i] = true;
        }
    }
    marked.iter()
          .enumerate()
          .filter_map(|(i, &m)| if m { None } else { Some(i) })
          .collect()
}

fn is_prime(n: usize) -> bool {
    n != 0 && n != 1 && (2..).take_while(|i| i*i <= n).all(|i| n % i != 0)
}

#[test]
#[should_panic]
fn sieve_not_prime() {
    fn prop_all_prime(n: usize) -> bool {
        sieve(n).into_iter().all(is_prime)
    }
    quickcheck(prop_all_prime as fn(usize) -> bool);
}
<|endoftext|>


<commit_before>#![feature(globs)]
#![crate_type = "bin"]
extern crate rust_js;
extern crate test;
extern crate collections;
use rust_js::lexer::Lexer;
use rust_js::parser::{Parser, VerboseResult};
use rust_js::exec::{Executor, Interpreter};
use rust_js::js::value::{Value, ValueData, VNull, VNumber, VString, from_value};

fn run(script:&str) -> Value {
	let mut lexer = Lexer::new();
	lexer.lex_str(script.to_owned()).v_unwrap();
	let mut parser = Parser::new(lexer.tokens);
	let result = parser.parse_all().v_unwrap();
	let mut engine : ~Interpreter = Executor::new();
	let result : Result<Value, Value> = engine.run(result);
	return result.unwrap();
}
fn assert_eq(a:ValueData, b:Value) -> () {
	if a != *b.borrow() {
		fail!("Expected {}, got {}", a, b.borrow());
	}
}
#[test]
fn test_value_conversion() {
	let val:Vec<i32> = from_value(run("[0, 2, 34, 12]")).unwrap();
	if *val.get(0) != 0 || *val.get(1) != 2 || *val.get(2) != 34 || *val.get(3) != 12 {
		fail!("Bad value {}", val);
	}
}
#[test]
fn test_array_comma() {
	assert_eq(VNull, run("[ , 'home', , 'school'][0]"));
}
#[test]
fn test_escape() {
	assert_eq(VString(~"Newline:'"), run("'Newline:\\\''"));
}
#[test]
fn test_to_string() {
	assert_eq(VString(~"117"), run("117+''"));
	assert_eq(VString(~"0.12"), run("0.12+''"));
	assert_eq(VString(~"null"), run("null+''"));
	assert_eq(VString(~"undefined"), run("unexisty+''"));
}
#[test]
fn test_num_op() {
	assert_eq(VNumber(10.0), run("((4 + 2) / 3) * 5"));
}
#[test]
fn test_hello_world() {
	assert_eq(VString(~"Hello, world!"), run("'Hello, world!'"));
}
#[test]
fn test_function() {
	assert_eq(VString(~"Function!"), run("(function(a){return a + '!'})('Function')"))
}
#[test]
fn test_constructor() {
	assert_eq(VString(~"Hello"), run("function Text(phrase) { this.phrase = phrase; }; text = new Text('Hello'); text.phrase"));
}
#[test]
fn test_json() {
	assert_eq(VNumber(42.0), run("JSON.parse(JSON.stringify({num: 42})).num"))
}
#[test]
fn test_typeof() {
	assert_eq(VString(~"number"), run("typeof Math.PI"));
	assert_eq(VString(~"boolean"), run("typeof true"));
	assert_eq(VString(~"undefined"), run("typeof undefined"));
	assert_eq(VString(~"string"), run("typeof ''"));
	assert_eq(VString(~"function"), run("typeof Object.prototype.hasOwnProperty"));
}<commit_msg>Add test for Object.defineProperty<commit_after>#![feature(globs)]
#![crate_type = "bin"]
extern crate rust_js;
extern crate test;
extern crate collections;
use rust_js::lexer::Lexer;
use rust_js::parser::{Parser, VerboseResult};
use rust_js::exec::{Executor, Interpreter};
use rust_js::js::value::{Value, ValueData, VNull, VNumber, VString, VBoolean, from_value};

fn run(script:&str) -> Value {
	let mut lexer = Lexer::new();
	lexer.lex_str(script.to_owned()).v_unwrap();
	let mut parser = Parser::new(lexer.tokens);
	let result = parser.parse_all().v_unwrap();
	let mut engine : ~Interpreter = Executor::new();
	let result : Result<Value, Value> = engine.run(result);
	return result.unwrap();
}
fn assert_eq(a:ValueData, b:Value) -> () {
	if a != *b.borrow() {
		fail!("Expected {}, got {}", a, b.borrow());
	}
}
#[test]
fn test_value_conversion() {
	let val:Vec<i32> = from_value(run("[0, 2, 34, 12]")).unwrap();
	if *val.get(0) != 0 || *val.get(1) != 2 || *val.get(2) != 34 || *val.get(3) != 12 {
		fail!("Bad value {}", val);
	}
}
#[test]
fn test_array_comma() {
	assert_eq(VNull, run("[ , 'home', , 'school'][0]"));
}
#[test]
fn test_escape() {
	assert_eq(VString(~"Newline:'"), run("'Newline:\\\''"));
}
#[test]
fn test_to_string() {
	assert_eq(VString(~"117"), run("117+''"));
	assert_eq(VString(~"0.12"), run("0.12+''"));
	assert_eq(VString(~"null"), run("null+''"));
	assert_eq(VString(~"undefined"), run("unexisty+''"));
}
#[test]
fn test_num_op() {
	assert_eq(VNumber(10.0), run("((4 + 2) / 3) * 5"));
}
#[test]
fn test_hello_world() {
	assert_eq(VString(~"Hello, world!"), run("'Hello, world!'"));
}
#[test]
fn test_function() {
	assert_eq(VString(~"Function!"), run("(function(a){return a + '!'})('Function')"))
}
#[test]
fn test_constructor() {
	assert_eq(VString(~"Hello"), run("function Text(phrase) { this.phrase = phrase; }; text = new Text('Hello'); text.phrase"));
}
#[test]
fn test_json() {
	assert_eq(VNumber(42.0), run("JSON.parse(JSON.stringify({num: 42})).num"))
}
#[test]
fn test_typeof() {
	assert_eq(VString(~"number"), run("typeof Math.PI"));
	assert_eq(VString(~"boolean"), run("typeof true"));
	assert_eq(VString(~"undefined"), run("typeof undefined"));
	assert_eq(VString(~"string"), run("typeof ''"));
	assert_eq(VString(~"function"), run("typeof Object.prototype.hasOwnProperty"));
}
#[test]
fn test_define_prop() {
	assert_eq(VBoolean(true), run("{
		var obj = {};
		Object.defineProperty(obj, \"some_bool\", {
			value: true
		});
		obj.some_bool
	}"));
}<|endoftext|>


<commit_before>use super::Checked;

// Test a unary operator
macro_rules! test_unop {
    ($name:ident $t:ty: $op:tt $expr1:tt == $expr2:tt) => {
        #[test]
        fn $name() {
            let x = Checked::<$t>::from($expr1);
            let y = Checked::<$t>::from($expr2);
            assert_eq!($op x, y);
            assert_eq!($op &x, y);
        }
    };
}

// Test a binary operator
macro_rules! test_binop {
    ($name:ident $t:ty: $expr1:tt $op:tt $expr2:tt == $expr3:tt) => {
        #[test]
        fn $name() {
            let x1 = Checked::<$t>::from($expr1);
            let y1 = Checked::<$t>::from($expr2);
            let x2 = $expr1 as $t;
            let y2 = $expr2 as $t;
            let z = Checked::<$t>::from($expr3);
            assert_eq!(x1 $op y1, z);
            assert_eq!(x2 $op y1, z);
            assert_eq!(x1 $op y2, z);
            assert_eq!(&x1 $op y1, z);
            assert_eq!(&x2 $op y1, z);
            assert_eq!(&x1 $op y2, z);
            assert_eq!(x1 $op &y1, z);
            assert_eq!(x2 $op &y1, z);
            assert_eq!(x1 $op &y2, z);
            assert_eq!(&x1 $op &y1, z);
            assert_eq!(&x2 $op &y1, z);
            assert_eq!(&x1 $op &y2, z);
        }
    };

    ($name:ident $t:ty, $u:ty: $expr1:tt $op:tt $expr2:tt == $expr3:tt) => {
        #[test]
        fn $name() {
            let x1 = Checked::<$t>::from($expr1);
            let y1 = Checked::<$u>::from($expr2);
            let x2 = $expr1 as $t;
            let y2 = $expr2 as $u;
            let z = Checked::<$t>::from($expr3);
            assert_eq!(x1 $op y1, z);
            assert_eq!(x2 $op y1, z);
            assert_eq!(x1 $op y2, z);
            assert_eq!(&x1 $op y1, z);
            assert_eq!(&x2 $op y1, z);
            assert_eq!(&x1 $op y2, z);
            assert_eq!(x1 $op &y1, z);
            assert_eq!(x2 $op &y1, z);
            assert_eq!(x1 $op &y2, z);
            assert_eq!(&x1 $op &y1, z);
            assert_eq!(&x2 $op &y1, z);
            assert_eq!(&x1 $op &y2, z);
        }
    };

    ($name:ident $t:ty, $u:ty, $v:ty: $expr1:tt $op:tt $expr2:tt == $expr3:tt) => {
        #[test]
        fn $name() {
            let x1 = Checked::<$t>::from($expr1);
            let y1 = Checked::<$u>::from($expr2);
            let x2 = $expr1 as $t;
            let y2 = $expr2 as $u;
            let z = Checked::<$v>::from($expr3);
            assert_eq!(x1 $op y1, z);
            assert_eq!(x2 $op y1, z);
            assert_eq!(x1 $op y2, z);
            assert_eq!(&x1 $op y1, z);
            assert_eq!(&x2 $op y1, z);
            assert_eq!(&x1 $op y2, z);
            assert_eq!(x1 $op &y1, z);
            assert_eq!(x2 $op &y1, z);
            assert_eq!(x1 $op &y2, z);
            assert_eq!(&x1 $op &y1, z);
            assert_eq!(&x2 $op &y1, z);
            assert_eq!(&x1 $op &y2, z);
        }
    };
}

// These tests use None to indicate over/underflow.
test_binop! (add1 u8: 5 + 6 == 11);
test_binop! (add2 u32: 3_000_000_000 + 2_000_000_000 == None);
test_binop! (add3 i32: (-2_000_000_000) + (-2_000_000_000) == None);
test_binop! (sub u8: 5 - 6 == None);
test_binop! (mul1 u8: 5 * 6 == 30);
test_binop! (mul2 i32: 2_000_000_000 * 3 == None);
test_binop! (div1 u8: 10 / 3 == 3);
test_binop! (div2 u8: 10 / 0 == None);
test_binop! (and u8: 5 & 6 == 4);
test_binop! (xor u8: 5 ^ 6 == 3);
test_binop! (or u8: 5 | 6 == 7);
test_binop! (rem u8: 10 % 3 == 1);
test_binop! (shl u8, u32: 10 << 3 == 80);
test_binop! (shr u8, u32: 80 >> 3 == 10);
test_unop! (neg1 u8: - 5 == None);
test_unop! (neg2 i8: - 5 == (-5));
test_unop! (not i8: ! 5 == (-6));
<commit_msg>add test for ordering<commit_after>use super::Checked;

// Test a unary operator
macro_rules! test_unop {
    ($name:ident $t:ty: $op:tt $expr1:tt == $expr2:tt) => {
        #[test]
        fn $name() {
            let x = Checked::<$t>::from($expr1);
            let y = Checked::<$t>::from($expr2);
            assert_eq!($op x, y);
            assert_eq!($op &x, y);
        }
    };
}

// Test a binary operator
macro_rules! test_binop {
    ($name:ident $t:ty: $expr1:tt $op:tt $expr2:tt == $expr3:tt) => {
        #[test]
        fn $name() {
            let x1 = Checked::<$t>::from($expr1);
            let y1 = Checked::<$t>::from($expr2);
            let x2 = $expr1 as $t;
            let y2 = $expr2 as $t;
            let z = Checked::<$t>::from($expr3);
            assert_eq!(x1 $op y1, z);
            assert_eq!(x2 $op y1, z);
            assert_eq!(x1 $op y2, z);
            assert_eq!(&x1 $op y1, z);
            assert_eq!(&x2 $op y1, z);
            assert_eq!(&x1 $op y2, z);
            assert_eq!(x1 $op &y1, z);
            assert_eq!(x2 $op &y1, z);
            assert_eq!(x1 $op &y2, z);
            assert_eq!(&x1 $op &y1, z);
            assert_eq!(&x2 $op &y1, z);
            assert_eq!(&x1 $op &y2, z);
        }
    };

    ($name:ident $t:ty, $u:ty: $expr1:tt $op:tt $expr2:tt == $expr3:tt) => {
        #[test]
        fn $name() {
            let x1 = Checked::<$t>::from($expr1);
            let y1 = Checked::<$u>::from($expr2);
            let x2 = $expr1 as $t;
            let y2 = $expr2 as $u;
            let z = Checked::<$t>::from($expr3);
            assert_eq!(x1 $op y1, z);
            assert_eq!(x2 $op y1, z);
            assert_eq!(x1 $op y2, z);
            assert_eq!(&x1 $op y1, z);
            assert_eq!(&x2 $op y1, z);
            assert_eq!(&x1 $op y2, z);
            assert_eq!(x1 $op &y1, z);
            assert_eq!(x2 $op &y1, z);
            assert_eq!(x1 $op &y2, z);
            assert_eq!(&x1 $op &y1, z);
            assert_eq!(&x2 $op &y1, z);
            assert_eq!(&x1 $op &y2, z);
        }
    };

    ($name:ident $t:ty, $u:ty, $v:ty: $expr1:tt $op:tt $expr2:tt == $expr3:tt) => {
        #[test]
        fn $name() {
            let x1 = Checked::<$t>::from($expr1);
            let y1 = Checked::<$u>::from($expr2);
            let x2 = $expr1 as $t;
            let y2 = $expr2 as $u;
            let z = Checked::<$v>::from($expr3);
            assert_eq!(x1 $op y1, z);
            assert_eq!(x2 $op y1, z);
            assert_eq!(x1 $op y2, z);
            assert_eq!(&x1 $op y1, z);
            assert_eq!(&x2 $op y1, z);
            assert_eq!(&x1 $op y2, z);
            assert_eq!(x1 $op &y1, z);
            assert_eq!(x2 $op &y1, z);
            assert_eq!(x1 $op &y2, z);
            assert_eq!(&x1 $op &y1, z);
            assert_eq!(&x2 $op &y1, z);
            assert_eq!(&x1 $op &y2, z);
        }
    };
}

// These tests use None to indicate over/underflow.
test_binop! (add1 u8: 5 + 6 == 11);
test_binop! (add2 u32: 3_000_000_000 + 2_000_000_000 == None);
test_binop! (add3 i32: (-2_000_000_000) + (-2_000_000_000) == None);
test_binop! (sub u8: 5 - 6 == None);
test_binop! (mul1 u8: 5 * 6 == 30);
test_binop! (mul2 i32: 2_000_000_000 * 3 == None);
test_binop! (div1 u8: 10 / 3 == 3);
test_binop! (div2 u8: 10 / 0 == None);
test_binop! (and u8: 5 & 6 == 4);
test_binop! (xor u8: 5 ^ 6 == 3);
test_binop! (or u8: 5 | 6 == 7);
test_binop! (rem u8: 10 % 3 == 1);
test_binop! (shl u8, u32: 10 << 3 == 80);
test_binop! (shr u8, u32: 80 >> 3 == 10);
test_unop! (neg1 u8: - 5 == None);
test_unop! (neg2 i8: - 5 == (-5));
test_unop! (not i8: ! 5 == (-6));

#[test]
fn order() {
    assert!(Checked::from(1_000_u32) <= Checked::from(10_000_u32));
    assert!(!(Checked::from(1_000_u32) <= Checked::from(None)));
    assert!((Checked::from(None) <= Checked::from(1_000_u32)));
}
<|endoftext|>


<commit_before>use std::fmt;
use std::ops;
use std::slice;
use std::vec;

use features::Features;

/// A sentence with the CoNLL-X annotation layers.
///
/// This data type is a small wrapper around `Vec<Token>` that provides some
/// extra convenience. For example, the implementation of the `Display` trait
/// outputs the sentence in CoNLL-X format.
#[derive(Clone, Debug, PartialEq)]
pub struct Sentence {
    tokens: Vec<Token>,
}

impl Sentence {
    /// Create a new `Sentence` from a vector of tokens.
    pub fn new<T>(tokens: T) -> Sentence
    where
        T: Into<Vec<Token>>,
    {
        Sentence {
            tokens: tokens.into(),
        }
    }

    /// Get the sentence tokens as a slice.
    pub fn as_tokens(&self) -> &[Token] {
        &self.tokens
    }

    /// Get the sentence tokens as a mutable slice.
    pub fn as_tokens_mut(&mut self) -> &mut [Token] {
        &mut self.tokens
    }

    /// Get an iterator over the sentence tokens.
    pub fn iter(&self) -> slice::Iter<Token> {
        self.tokens.iter()
    }

    /// Get a mutable iterator over the sentence tokens.
    pub fn iter_mut(&mut self) -> slice::IterMut<Token> {
        self.tokens.iter_mut()
    }
}

impl fmt::Display for Sentence {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let last_id = self.tokens.len() - 1;

        for (id, token) in self.iter().enumerate() {
            if id == last_id {
                write!(f, "{}\t{}", id + 1, token)?
            } else {
                write!(f, "{}\t{}\n", id + 1, token)?
            }
        }

        Ok(())
    }
}

impl From<Sentence> for Vec<Token> {
    fn from(sentence: Sentence) -> Self {
        sentence.tokens
    }
}

impl ops::Index<usize> for Sentence {
    type Output = Token;
    fn index(&self, index: usize) -> &Token {
        &self.tokens[index]
    }
}

impl ops::IndexMut<usize> for Sentence {
    fn index_mut(&mut self, index: usize) -> &mut Token {
        &mut self.tokens[index]
    }
}

impl IntoIterator for Sentence {
    type Item = Token;
    type IntoIter = vec::IntoIter<Token>;

    fn into_iter(self) -> vec::IntoIter<Token> {
        self.tokens.into_iter()
    }
}

impl<'a> IntoIterator for &'a Sentence {
    type Item = &'a Token;
    type IntoIter = slice::Iter<'a, Token>;

    fn into_iter(self) -> slice::Iter<'a, Token> {
        self.iter()
    }
}

impl<'a> IntoIterator for &'a mut Sentence {
    type Item = &'a mut Token;
    type IntoIter = slice::IterMut<'a, Token>;

    fn into_iter(self) -> slice::IterMut<'a, Token> {
        self.iter_mut()
    }
}

/// A builder for `Token`s.
///
/// The `Token` type stores a CoNLL-X token. However, since this format
/// permits a large number of fields, construction of a token can get
/// tedious. This builder provides a fluent interface for creating `Token`s.
pub struct TokenBuilder {
    token: Token,
}

impl TokenBuilder {
    /// Create a `Token` builder with all non-form fields set to absent.
    pub fn new<S>(form: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        TokenBuilder {
            token: Token::new(form),
        }
    }

    /// Set the word form or punctuation symbol.
    pub fn form<S>(mut self, form: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_form(form);
        self
    }

    /// Set the lemma or stem of the word form.
    pub fn lemma<S>(mut self, lemma: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_lemma(Some(lemma));
        self
    }

    /// Set the coarse-grained part-of-speech tag.
    pub fn cpos<S>(mut self, cpos: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_cpos(Some(cpos));
        self
    }

    /// Set the fine-grained part-of-speech tag.
    pub fn pos<S>(mut self, pos: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_pos(Some(pos));
        self
    }

    /// Set the syntactic and/or morphological features of the token.
    pub fn features(mut self, features: Features) -> TokenBuilder {
        self.token.set_features(Some(features));
        self
    }

    /// Set the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn head(mut self, head: usize) -> TokenBuilder {
        self.token.set_head(Some(head));
        self
    }

    /// Set the dependency relation to the head of this token.
    pub fn head_rel<S>(mut self, head_rel: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_head_rel(Some(head_rel));
        self
    }

    /// Set the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn p_head(mut self, p_head: usize) -> TokenBuilder {
        self.token.set_p_head(Some(p_head));
        self
    }

    /// Set the dependency relation to the projective head of this token.
    pub fn p_head_rel<S>(mut self, p_head_rel: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_p_head_rel(Some(p_head_rel));
        self
    }

    pub fn token(self) -> Token {
        self.token
    }
}

/// A token with the CoNLL-X annotation layers.
///
/// The fields of CoNLLX tokens are described at:
///
/// http://ilk.uvt.nl/conll/
///
/// This type provides exactly the same fields, except for the ID field
/// (since it can be derived from the sentence position of the token).
/// If a particular field is absent (*_* in the CoNLL-X format), its
/// value is `None`.
#[derive(Clone, Debug, PartialEq)]
pub struct Token {
    form: String,
    lemma: Option<String>,
    cpos: Option<String>,
    pos: Option<String>,
    features: Option<Features>,
    head: Option<usize>,
    head_rel: Option<String>,
    p_head: Option<usize>,
    p_head_rel: Option<String>,
}

impl Token {
    /// Create a new token where all the non-form fields are absent.
    pub fn new<S>(form: S) -> Token
    where
        S: Into<String>,
    {
        Token {
            form: form.into(),
            lemma: None,
            cpos: None,
            pos: None,
            features: None,
            head: None,
            head_rel: None,
            p_head: None,
            p_head_rel: None,
        }
    }

    /// Get the word form or punctuation symbol.
    pub fn form(&self) -> &str {
        self.form.as_ref()
    }

    /// Get the lemma or stem of the word form.
    pub fn lemma(&self) -> Option<&str> {
        self.lemma.as_ref().map(String::as_ref)
    }

    /// Get the coarse-grained part-of-speech tag.
    pub fn cpos(&self) -> Option<&str> {
        self.cpos.as_ref().map(String::as_ref)
    }

    /// Get the fine-grained part-of-speech tag.
    pub fn pos(&self) -> Option<&str> {
        self.pos.as_ref().map(String::as_ref)
    }

    /// Get the syntactic and/or morphological features of the token.
    pub fn features(&self) -> Option<&Features> {
        self.features.as_ref()
    }

    /// Get the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn head(&self) -> Option<usize> {
        self.head
    }

    /// Get the dependency relation to the head of this token.
    pub fn head_rel(&self) -> Option<&str> {
        self.head_rel.as_ref().map(String::as_ref)
    }

    /// Get the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn p_head(&self) -> Option<usize> {
        self.p_head
    }

    /// Get the dependency relation to the projective head of this token.
    pub fn p_head_rel(&self) -> Option<&str> {
        self.p_head_rel.as_ref().map(String::as_ref)
    }

    /// Set the word form or punctuation symbol.
    pub fn set_form<S>(&mut self, form: S)
    where
        S: Into<String>,
    {
        self.form = form.into()
    }

    /// Set the lemma or stem of the word form.
    pub fn set_lemma<S>(&mut self, lemma: Option<S>)
    where
        S: Into<String>,
    {
        self.lemma = lemma.map(|i| i.into())
    }

    /// Set the coarse-grained part-of-speech tag.
    pub fn set_cpos<S>(&mut self, cpos: Option<S>)
    where
        S: Into<String>,
    {
        self.cpos = cpos.map(|i| i.into())
    }

    /// Set the fine-grained part-of-speech tag.
    pub fn set_pos<S>(&mut self, pos: Option<S>)
    where
        S: Into<String>,
    {
        self.pos = pos.map(|i| i.into())
    }

    /// Set the syntactic and/or morphological features of the token.
    pub fn set_features(&mut self, features: Option<Features>) {
        self.features = features
    }

    /// Set the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn set_head(&mut self, head: Option<usize>) {
        self.head = head
    }

    /// Set the dependency relation to the head of this token.
    pub fn set_head_rel<S>(&mut self, head_rel: Option<S>)
    where
        S: Into<String>,
    {
        self.head_rel = head_rel.map(|i| i.into())
    }

    /// Set the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn set_p_head(&mut self, p_head: Option<usize>) {
        self.p_head = p_head
    }

    /// Set the dependency relation to the projective head of this token.
    pub fn set_p_head_rel<S>(&mut self, p_head_rel: Option<S>)
    where
        S: Into<String>,
    {
        self.p_head_rel = p_head_rel.map(|i| i.into())
    }
}

pub const EMPTY_TOKEN: &'static str = "_";

impl fmt::Display for Token {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let head_str = self.head.as_ref().map(|n| n.to_string());
        let p_head_str = self.p_head.as_ref().map(|n| n.to_string());

        write!(
            f,
            "{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}",
            self.form.as_str(),
            self.lemma
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.cpos
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.pos.as_ref().map(|s| s.as_ref()).unwrap_or(EMPTY_TOKEN),
            self.features
                .as_ref()
                .map(|s| s.as_str())
                .unwrap_or(EMPTY_TOKEN),
            head_str.as_ref().map(|s| s.as_ref()).unwrap_or(EMPTY_TOKEN),
            self.head_rel
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            p_head_str
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.p_head_rel
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
        )
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeMap;

    use super::{Features, Token, TokenBuilder};

    fn token_with_features() -> Vec<Token> {
        vec![
            TokenBuilder::new("Gilles")
                .lemma("Gilles")
                .cpos("N")
                .pos("NE")
                .features(Features::from_string(
                    "case:nominative|number:singular|gender:masculine",
                ))
                .head(0)
                .head_rel("ROOT")
                .token(),
            TokenBuilder::new("Deleuze")
                .lemma("Deleuze")
                .cpos("N")
                .pos("NE")
                .features(Features::from_string("nominative|singular|masculine"))
                .head(1)
                .head_rel("APP")
                .token(),
        ]
    }

    fn features_correct() -> Vec<BTreeMap<String, Option<String>>> {
        let mut correct1 = BTreeMap::new();
        correct1.insert("case".to_owned(), Some("nominative".to_owned()));
        correct1.insert("number".to_owned(), Some("singular".to_owned()));
        correct1.insert("gender".to_owned(), Some("masculine".to_owned()));

        let mut correct2 = BTreeMap::new();
        correct2.insert("nominative".to_owned(), None);
        correct2.insert("singular".to_owned(), None);
        correct2.insert("masculine".to_owned(), None);

        vec![correct1, correct2]
    }

    #[test]
    fn features() {
        let tokens = token_with_features();
        let features = features_correct();

        for (token, correct) in tokens.iter().zip(features) {
            let kv = token.features().as_ref().unwrap().as_map();
            assert_eq!(&correct, kv);
        }
    }
}
<commit_msg>Roundtrip conversions from/to &[Token]/Vec[Token].<commit_after>use std::fmt;
use std::ops;
use std::slice;
use std::vec;

use features::Features;

/// A sentence with the CoNLL-X annotation layers.
///
/// This data type is a small wrapper around `Vec<Token>` that provides some
/// extra convenience. For example, the implementation of the `Display` trait
/// outputs the sentence in CoNLL-X format.
#[derive(Clone, Debug, PartialEq)]
pub struct Sentence {
    tokens: Vec<Token>,
}

impl Sentence {
    /// Create a new `Sentence` from a vector of tokens.
    pub fn new<T>(tokens: T) -> Sentence
    where
        T: Into<Vec<Token>>,
    {
        Sentence {
            tokens: tokens.into(),
        }
    }

    /// Get the sentence tokens as a slice.
    pub fn as_tokens(&self) -> &[Token] {
        &self.tokens
    }

    /// Get the sentence tokens as a mutable slice.
    pub fn as_tokens_mut(&mut self) -> &mut [Token] {
        &mut self.tokens
    }

    /// Get an iterator over the sentence tokens.
    pub fn iter(&self) -> slice::Iter<Token> {
        self.tokens.iter()
    }

    /// Get a mutable iterator over the sentence tokens.
    pub fn iter_mut(&mut self) -> slice::IterMut<Token> {
        self.tokens.iter_mut()
    }
}

impl fmt::Display for Sentence {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let last_id = self.tokens.len() - 1;

        for (id, token) in self.iter().enumerate() {
            if id == last_id {
                write!(f, "{}\t{}", id + 1, token)?
            } else {
                write!(f, "{}\t{}\n", id + 1, token)?
            }
        }

        Ok(())
    }
}

impl From<Sentence> for Vec<Token> {
    fn from(sentence: Sentence) -> Self {
        sentence.tokens
    }
}

impl<'a> From<&'a Sentence> for &'a [Token] {
    fn from(sentence: &'a Sentence) -> Self {
        &sentence.tokens
    }
}

impl From<Vec<Token>> for Sentence {
    fn from(tokens: Vec<Token>) -> Self {
        Sentence { tokens }
    }
}

impl<'a> From<&'a [Token]> for Sentence {
    fn from(tokens: &'a [Token]) -> Self {
        Sentence { tokens: tokens.to_owned() }
    }
}

impl ops::Index<usize> for Sentence {
    type Output = Token;
    fn index(&self, index: usize) -> &Token {
        &self.tokens[index]
    }
}

impl ops::IndexMut<usize> for Sentence {
    fn index_mut(&mut self, index: usize) -> &mut Token {
        &mut self.tokens[index]
    }
}

impl IntoIterator for Sentence {
    type Item = Token;
    type IntoIter = vec::IntoIter<Token>;

    fn into_iter(self) -> vec::IntoIter<Token> {
        self.tokens.into_iter()
    }
}

impl<'a> IntoIterator for &'a Sentence {
    type Item = &'a Token;
    type IntoIter = slice::Iter<'a, Token>;

    fn into_iter(self) -> slice::Iter<'a, Token> {
        self.iter()
    }
}

impl<'a> IntoIterator for &'a mut Sentence {
    type Item = &'a mut Token;
    type IntoIter = slice::IterMut<'a, Token>;

    fn into_iter(self) -> slice::IterMut<'a, Token> {
        self.iter_mut()
    }
}

/// A builder for `Token`s.
///
/// The `Token` type stores a CoNLL-X token. However, since this format
/// permits a large number of fields, construction of a token can get
/// tedious. This builder provides a fluent interface for creating `Token`s.
pub struct TokenBuilder {
    token: Token,
}

impl TokenBuilder {
    /// Create a `Token` builder with all non-form fields set to absent.
    pub fn new<S>(form: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        TokenBuilder {
            token: Token::new(form),
        }
    }

    /// Set the word form or punctuation symbol.
    pub fn form<S>(mut self, form: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_form(form);
        self
    }

    /// Set the lemma or stem of the word form.
    pub fn lemma<S>(mut self, lemma: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_lemma(Some(lemma));
        self
    }

    /// Set the coarse-grained part-of-speech tag.
    pub fn cpos<S>(mut self, cpos: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_cpos(Some(cpos));
        self
    }

    /// Set the fine-grained part-of-speech tag.
    pub fn pos<S>(mut self, pos: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_pos(Some(pos));
        self
    }

    /// Set the syntactic and/or morphological features of the token.
    pub fn features(mut self, features: Features) -> TokenBuilder {
        self.token.set_features(Some(features));
        self
    }

    /// Set the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn head(mut self, head: usize) -> TokenBuilder {
        self.token.set_head(Some(head));
        self
    }

    /// Set the dependency relation to the head of this token.
    pub fn head_rel<S>(mut self, head_rel: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_head_rel(Some(head_rel));
        self
    }

    /// Set the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn p_head(mut self, p_head: usize) -> TokenBuilder {
        self.token.set_p_head(Some(p_head));
        self
    }

    /// Set the dependency relation to the projective head of this token.
    pub fn p_head_rel<S>(mut self, p_head_rel: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_p_head_rel(Some(p_head_rel));
        self
    }

    pub fn token(self) -> Token {
        self.token
    }
}

/// A token with the CoNLL-X annotation layers.
///
/// The fields of CoNLLX tokens are described at:
///
/// http://ilk.uvt.nl/conll/
///
/// This type provides exactly the same fields, except for the ID field
/// (since it can be derived from the sentence position of the token).
/// If a particular field is absent (*_* in the CoNLL-X format), its
/// value is `None`.
#[derive(Clone, Debug, PartialEq)]
pub struct Token {
    form: String,
    lemma: Option<String>,
    cpos: Option<String>,
    pos: Option<String>,
    features: Option<Features>,
    head: Option<usize>,
    head_rel: Option<String>,
    p_head: Option<usize>,
    p_head_rel: Option<String>,
}

impl Token {
    /// Create a new token where all the non-form fields are absent.
    pub fn new<S>(form: S) -> Token
    where
        S: Into<String>,
    {
        Token {
            form: form.into(),
            lemma: None,
            cpos: None,
            pos: None,
            features: None,
            head: None,
            head_rel: None,
            p_head: None,
            p_head_rel: None,
        }
    }

    /// Get the word form or punctuation symbol.
    pub fn form(&self) -> &str {
        self.form.as_ref()
    }

    /// Get the lemma or stem of the word form.
    pub fn lemma(&self) -> Option<&str> {
        self.lemma.as_ref().map(String::as_ref)
    }

    /// Get the coarse-grained part-of-speech tag.
    pub fn cpos(&self) -> Option<&str> {
        self.cpos.as_ref().map(String::as_ref)
    }

    /// Get the fine-grained part-of-speech tag.
    pub fn pos(&self) -> Option<&str> {
        self.pos.as_ref().map(String::as_ref)
    }

    /// Get the syntactic and/or morphological features of the token.
    pub fn features(&self) -> Option<&Features> {
        self.features.as_ref()
    }

    /// Get the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn head(&self) -> Option<usize> {
        self.head
    }

    /// Get the dependency relation to the head of this token.
    pub fn head_rel(&self) -> Option<&str> {
        self.head_rel.as_ref().map(String::as_ref)
    }

    /// Get the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn p_head(&self) -> Option<usize> {
        self.p_head
    }

    /// Get the dependency relation to the projective head of this token.
    pub fn p_head_rel(&self) -> Option<&str> {
        self.p_head_rel.as_ref().map(String::as_ref)
    }

    /// Set the word form or punctuation symbol.
    pub fn set_form<S>(&mut self, form: S)
    where
        S: Into<String>,
    {
        self.form = form.into()
    }

    /// Set the lemma or stem of the word form.
    pub fn set_lemma<S>(&mut self, lemma: Option<S>)
    where
        S: Into<String>,
    {
        self.lemma = lemma.map(|i| i.into())
    }

    /// Set the coarse-grained part-of-speech tag.
    pub fn set_cpos<S>(&mut self, cpos: Option<S>)
    where
        S: Into<String>,
    {
        self.cpos = cpos.map(|i| i.into())
    }

    /// Set the fine-grained part-of-speech tag.
    pub fn set_pos<S>(&mut self, pos: Option<S>)
    where
        S: Into<String>,
    {
        self.pos = pos.map(|i| i.into())
    }

    /// Set the syntactic and/or morphological features of the token.
    pub fn set_features(&mut self, features: Option<Features>) {
        self.features = features
    }

    /// Set the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn set_head(&mut self, head: Option<usize>) {
        self.head = head
    }

    /// Set the dependency relation to the head of this token.
    pub fn set_head_rel<S>(&mut self, head_rel: Option<S>)
    where
        S: Into<String>,
    {
        self.head_rel = head_rel.map(|i| i.into())
    }

    /// Set the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn set_p_head(&mut self, p_head: Option<usize>) {
        self.p_head = p_head
    }

    /// Set the dependency relation to the projective head of this token.
    pub fn set_p_head_rel<S>(&mut self, p_head_rel: Option<S>)
    where
        S: Into<String>,
    {
        self.p_head_rel = p_head_rel.map(|i| i.into())
    }
}

pub const EMPTY_TOKEN: &'static str = "_";

impl fmt::Display for Token {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let head_str = self.head.as_ref().map(|n| n.to_string());
        let p_head_str = self.p_head.as_ref().map(|n| n.to_string());

        write!(
            f,
            "{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}",
            self.form.as_str(),
            self.lemma
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.cpos
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.pos.as_ref().map(|s| s.as_ref()).unwrap_or(EMPTY_TOKEN),
            self.features
                .as_ref()
                .map(|s| s.as_str())
                .unwrap_or(EMPTY_TOKEN),
            head_str.as_ref().map(|s| s.as_ref()).unwrap_or(EMPTY_TOKEN),
            self.head_rel
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            p_head_str
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.p_head_rel
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
        )
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeMap;

    use super::{Features, Sentence, Token, TokenBuilder};

    fn token_with_features() -> Vec<Token> {
        vec![
            TokenBuilder::new("Gilles")
                .lemma("Gilles")
                .cpos("N")
                .pos("NE")
                .features(Features::from_string(
                    "case:nominative|number:singular|gender:masculine",
                ))
                .head(0)
                .head_rel("ROOT")
                .token(),
            TokenBuilder::new("Deleuze")
                .lemma("Deleuze")
                .cpos("N")
                .pos("NE")
                .features(Features::from_string("nominative|singular|masculine"))
                .head(1)
                .head_rel("APP")
                .token(),
        ]
    }

    fn features_correct() -> Vec<BTreeMap<String, Option<String>>> {
        let mut correct1 = BTreeMap::new();
        correct1.insert("case".to_owned(), Some("nominative".to_owned()));
        correct1.insert("number".to_owned(), Some("singular".to_owned()));
        correct1.insert("gender".to_owned(), Some("masculine".to_owned()));

        let mut correct2 = BTreeMap::new();
        correct2.insert("nominative".to_owned(), None);
        correct2.insert("singular".to_owned(), None);
        correct2.insert("masculine".to_owned(), None);

        vec![correct1, correct2]
    }

    #[test]
    fn features() {
        let tokens = token_with_features();
        let features = features_correct();

        for (token, correct) in tokens.iter().zip(features) {
            let kv = token.features().as_ref().unwrap().as_map();
            assert_eq!(&correct, kv);
        }
    }

    #[test]
    fn from_test() {
        let tokens = token_with_features();
        let sent: Sentence = tokens.as_slice().into();
        let into_token_slice: &[Token] = (&sent).into();
        assert_eq!(tokens.as_slice(), into_token_slice);

        let sent: Sentence = tokens.clone().into();
        let into_tokens: Vec<Token> = sent.into();
        assert_eq!(tokens, into_tokens);
    }
}
<|endoftext|>


<commit_before>
use std::cmp;

type Rgba = [u8; 4];

fn minf(a: f32, b: f32) -> f32 { if a < b { a } else { b } }
fn maxf(a: f32, b: f32) -> f32 { if a > b { a } else { b } }
fn saturate(a: f32) -> f32 { maxf(minf(a, 1.0), 0.0) }
fn fnorm(a: u8) -> f32 { a as f32 / 255.0 }
fn bnorm(a: f32) -> u8 { (saturate(a) * 255.0) as u8 }

/*type Hsva = [u8; 4];

fn to_hsva(rgba: &Rgba) -> Hsva {
	let (r, g, b) = (fnorm(rgba[0]), fnorm(rgba[1]), fnorm(rgba[2]));
	let max = maxf(maxf(r , g), b);
	let min = minf(minf(r , g), b);
	let c = max - min;
	let h =
		if c == 0.0 {
			0.0
		} else {
			(if max == r {
				(g - b) / c
			} else if max == g {
				(b - r) / c + 2.0
			} else {
				(r - g) / c + 4.0
			}) / 6.0
		};

	let s = if max == 0.0 { 0.0 } else { c / max };
	[bnorm(h), bnorm(s), bnorm(max), rgba[3]]
}

fn to_rgba(hsva: &Hsva) -> Rgba {
	let v = fnorm(hsva[2]);
	let c = v * fnorm(hsva[3]);
	let h = fnorm(hsva[0]) * 6.0;
	let x = c * (1.0 - (h % 2.0 - 1.0).abs());
	let rgb1 =
		if h < 1.0 {
			(c, x, 0.0)
		} else if h < 2.0 {
			(x, c, 0.0)
		} else if h < 3.0 {
			(0.0, c, x)
		} else if h < 4.0 {
			(0.0, x, c)
		} else if h < 5.0 {
			(x, 0.0, c)
		} else {
			(c, 0.0, x)
		};
	let m = v - c;
	[bnorm(rgb1.0 + m),
	bnorm(rgb1.1 + m),
	bnorm(rgb1.2 + m),
	hsva[3]]
}*/

fn bc1_dist(a: &Rgba, b: &Rgba) -> u32 {
	fn bc1_dist_one(a: u8, b: u8) -> u32 {
		let x = a as i32 - b as i32;
		(x * x) as u32
	}
	bc1_dist_one(a[0], b[0]) +
	bc1_dist_one(a[1], b[1]) +
	bc1_dist_one(a[2], b[2])
}

fn bc1_total_dist(table: &[Rgba; 4], pixels: &[Rgba; 16]) -> u32 {
	let mut sum = 0u32;
	let mut max = 0u32;
	for pix in pixels.into_iter().rev() {
		let e = (0..4).into_iter().map(|x| bc1_dist(&table[x], pix)).min().unwrap();
		sum += e;
		max = cmp::max(max, e);
	}
	sum + max * 16
}

fn bc1_build_entry(min: &Rgba, max: &Rgba, index: usize) -> Rgba {
	let coefs = match index {
		0x0 => (3, 0),
		0x1 => (0, 3),
		0x2 => (2 ,1),
		_ => (1, 2)
	};
	[((coefs.1 * min[0] as u16 + coefs.0 * max[0] as u16) / 3) as u8,
	 ((coefs.1 * min[1] as u16 + coefs.0 * max[1] as u16) / 3) as u8,
	 ((coefs.1 * min[2] as u16 + coefs.0 * max[2] as u16) / 3) as u8,
	 ((coefs.1 * min[3] as u16 + coefs.0 * max[3] as u16) / 3) as u8]
}

fn bc1_build_table(min: &Rgba, max: &Rgba) -> [Rgba; 4] {
	let mut interps = [[0u8; 4]; 4];
	for i in 0..4 {
		interps[i] = bc1_build_entry(&min, &max, i);
	}
	interps
}

fn bc1_minmax(pixels: &[Rgba; 16]) -> (Rgba, Rgba) {
	let mut min = [u8::max_value(); 4];
	let mut max = [0u8; 4];
	for p in pixels.into_iter() {
		for i in 0..4 {
			min[i] = cmp::min(min[i], p[i]);
			max[i] = cmp::max(max[i], p[i]);
		}
	}
	(min, max)
}

fn bc1_extrapolate_endpoints(e: &(Rgba, Rgba)) -> (Rgba, Rgba) {
	let mut a = e.0;
	let mut b = e.1;
	for i in 0..3 {
		let f = (fnorm(e.0[i]) - fnorm(e.1[i])) * 1.5;
		a[i] = bnorm(fnorm(e.0[i]) - f);
		b[i] = bnorm(fnorm(e.1[i]) + f);
	}
	(a, b)
}

fn bc1_sort_endpoints(e: &(Rgba, Rgba)) -> (Rgba, Rgba) {
	if bc1_encode_endpoint(&e.0) > bc1_encode_endpoint(&e.1) {
		(e.1, e.0)
	} else {
		(e.0, e.1)
	}
}

fn bc1_build_endpoints(pixels: &[Rgba; 16], quality: u8) -> Vec<(Rgba, Rgba)> {
	let (min, max) = bc1_minmax(pixels);

	let mut out = Vec::new();
	out.push((min, max));

	if quality > 0 && min != max {
		for i in 0..15 {
			for j in (i + 1)..16 {
				let px = (pixels[i], pixels[j]);
				out.push(bc1_sort_endpoints(&px));
				if quality > 1 {
					out.push(bc1_sort_endpoints(&bc1_extrapolate_endpoints(&px)));
				}
			}
		}
	}
	out
}

fn bc1_encode_endpoint(pix: &Rgba) -> u16 {
	((pix[0] as u16 >> 3) << 11) |
	((pix[1] as u16 >> 2) << 5) |
	(pix[2] as u16 >> 3)
}

fn bc1_encode_pixel(table: &[Rgba; 4], pixels: &[Rgba; 16]) -> u32 {
	let mut mask = 0u32;
	for pix in pixels.into_iter().rev() {
		let best = (0..4).into_iter().min_by_key(|x| bc1_dist(&table[*x], pix)).unwrap() as u32;
		mask = (mask << 2) | (best & 0x03);
	}
	mask
}

fn bc1_encode_block(pixels: &[Rgba; 16], quality: u8) -> (u64, u32) {
	/*let (min, max) = bc1_build_endpoints(&pixels)[0];
	let table = bc1_build_table(&min, &max);*/

	let ((min, max), table) = bc1_build_endpoints(pixels, quality).iter()
		.map(|pts| (*pts, bc1_build_table(&pts.0, &pts.1)))
		.min_by_key(|tbl| bc1_total_dist(&tbl.1, pixels)).unwrap();

	let dist = bc1_total_dist(&table, pixels);

	let min = bc1_encode_endpoint(&min) as u64;
	let max = bc1_encode_endpoint(&max) as u64;

	let encoded = bc1_encode_pixel(&table, &pixels) as u64;

	((encoded << 32) | (min << 16) | max, dist)
}

pub fn bc1(image: &Vec<u8>, size: (usize, usize), quality: u8) -> Result<Vec<u8>, ()> {
	if size.0 % 4 != 0 || size.1 % 4 != 0 || image.len() != size.0 * size.1 * 4 {
		return Err(());
	}

    let mut out = Vec::with_capacity(image.len() / 8);
    let mut total_dist = 0u32;

    let block_size = 4;
    let blk_count = (size.0 / block_size, size.1 / block_size);

   	for x in 0..blk_count.0 {
   		for y in 0..blk_count.1 {

   			let mut pixels = [[0u8; 4]; 16]; // No compile time constants
   			for px in 0..block_size {
   				for py in 0..block_size {
   					let x = x * block_size + px;
   					let y = y * block_size + py;

   					let pi = (x * size.1 + y) * 4; // in bytes
   					let pix = [image[pi], image[pi + 1], image[pi + 2], image[pi + 3]];

   					pixels[px * block_size + py] = pix;
   				}
   			}

   			let (mut encoded, dist) = bc1_encode_block(&pixels, quality);
   			total_dist += dist;

   			for _ in 0..8 {
   				out.push((encoded & 0xFF) as u8);
   				encoded >>= 8;
   			}
		}
	}
	//println!("per-pixel dist = {:?}", total_dist / (size.0 * size.1) as u32);
	Ok(out)
}
<commit_msg>fixed non square image not being encoded correctly.<commit_after>
use std::cmp;

type Rgba = [u8; 4];

fn minf(a: f32, b: f32) -> f32 { if a < b { a } else { b } }
fn maxf(a: f32, b: f32) -> f32 { if a > b { a } else { b } }
fn saturate(a: f32) -> f32 { maxf(minf(a, 1.0), 0.0) }
fn fnorm(a: u8) -> f32 { a as f32 / 255.0 }
fn bnorm(a: f32) -> u8 { (saturate(a) * 255.0) as u8 }

/*type Hsva = [u8; 4];

fn to_hsva(rgba: &Rgba) -> Hsva {
	let (r, g, b) = (fnorm(rgba[0]), fnorm(rgba[1]), fnorm(rgba[2]));
	let max = maxf(maxf(r , g), b);
	let min = minf(minf(r , g), b);
	let c = max - min;
	let h =
		if c == 0.0 {
			0.0
		} else {
			(if max == r {
				(g - b) / c
			} else if max == g {
				(b - r) / c + 2.0
			} else {
				(r - g) / c + 4.0
			}) / 6.0
		};

	let s = if max == 0.0 { 0.0 } else { c / max };
	[bnorm(h), bnorm(s), bnorm(max), rgba[3]]
}

fn to_rgba(hsva: &Hsva) -> Rgba {
	let v = fnorm(hsva[2]);
	let c = v * fnorm(hsva[3]);
	let h = fnorm(hsva[0]) * 6.0;
	let x = c * (1.0 - (h % 2.0 - 1.0).abs());
	let rgb1 =
		if h < 1.0 {
			(c, x, 0.0)
		} else if h < 2.0 {
			(x, c, 0.0)
		} else if h < 3.0 {
			(0.0, c, x)
		} else if h < 4.0 {
			(0.0, x, c)
		} else if h < 5.0 {
			(x, 0.0, c)
		} else {
			(c, 0.0, x)
		};
	let m = v - c;
	[bnorm(rgb1.0 + m),
	bnorm(rgb1.1 + m),
	bnorm(rgb1.2 + m),
	hsva[3]]
}*/

fn bc1_dist(a: &Rgba, b: &Rgba) -> u32 {
	fn bc1_dist_one(a: u8, b: u8) -> u32 {
		let x = a as i32 - b as i32;
		(x * x) as u32
	}
	bc1_dist_one(a[0], b[0]) +
	bc1_dist_one(a[1], b[1]) +
	bc1_dist_one(a[2], b[2])
}

fn bc1_total_dist(table: &[Rgba; 4], pixels: &[Rgba; 16]) -> u32 {
	let mut sum = 0u32;
	let mut max = 0u32;
	for pix in pixels.into_iter().rev() {
		let e = (0..4).into_iter().map(|x| bc1_dist(&table[x], pix)).min().unwrap();
		sum += e;
		max = cmp::max(max, e);
	}
	sum + max * 16
}

fn bc1_build_entry(min: &Rgba, max: &Rgba, index: usize) -> Rgba {
	let coefs = match index {
		0x0 => (3, 0),
		0x1 => (0, 3),
		0x2 => (2 ,1),
		_ => (1, 2)
	};
	[((coefs.1 * min[0] as u16 + coefs.0 * max[0] as u16) / 3) as u8,
	 ((coefs.1 * min[1] as u16 + coefs.0 * max[1] as u16) / 3) as u8,
	 ((coefs.1 * min[2] as u16 + coefs.0 * max[2] as u16) / 3) as u8,
	 ((coefs.1 * min[3] as u16 + coefs.0 * max[3] as u16) / 3) as u8]
}

fn bc1_build_table(min: &Rgba, max: &Rgba) -> [Rgba; 4] {
	let mut interps = [[0u8; 4]; 4];
	for i in 0..4 {
		interps[i] = bc1_build_entry(&min, &max, i);
	}
	interps
}

fn bc1_minmax(pixels: &[Rgba; 16]) -> (Rgba, Rgba) {
	let mut min = [u8::max_value(); 4];
	let mut max = [0u8; 4];
	for p in pixels.into_iter() {
		for i in 0..4 {
			min[i] = cmp::min(min[i], p[i]);
			max[i] = cmp::max(max[i], p[i]);
		}
	}
	(min, max)
}

fn bc1_extrapolate_endpoints(e: &(Rgba, Rgba)) -> (Rgba, Rgba) {
	let mut a = e.0;
	let mut b = e.1;
	for i in 0..3 {
		let f = (fnorm(e.0[i]) - fnorm(e.1[i])) * 1.5;
		a[i] = bnorm(fnorm(e.0[i]) - f);
		b[i] = bnorm(fnorm(e.1[i]) + f);
	}
	(a, b)
}

fn bc1_sort_endpoints(e: &(Rgba, Rgba)) -> (Rgba, Rgba) {
	if bc1_encode_endpoint(&e.0) > bc1_encode_endpoint(&e.1) {
		(e.1, e.0)
	} else {
		(e.0, e.1)
	}
}

fn bc1_build_endpoints(pixels: &[Rgba; 16], quality: u8) -> Vec<(Rgba, Rgba)> {
	let (min, max) = bc1_minmax(pixels);

	let mut out = Vec::new();
	out.push((min, max));

	if quality > 0 && min != max {
		for i in 0..15 {
			for j in (i + 1)..16 {
				let px = (pixels[i], pixels[j]);
				out.push(bc1_sort_endpoints(&px));
				if quality > 1 {
					out.push(bc1_sort_endpoints(&bc1_extrapolate_endpoints(&px)));
				}
			}
		}
	}
	out
}

fn bc1_encode_endpoint(pix: &Rgba) -> u16 {
	((pix[0] as u16 >> 3) << 11) |
	((pix[1] as u16 >> 2) << 5) |
	(pix[2] as u16 >> 3)
}

fn bc1_encode_pixel(table: &[Rgba; 4], pixels: &[Rgba; 16]) -> u32 {
	let mut mask = 0u32;
	for pix in pixels.into_iter().rev() {
		let best = (0..4).into_iter().min_by_key(|x| bc1_dist(&table[*x], pix)).unwrap() as u32;
		mask = (mask << 2) | (best & 0x03);
	}
	mask
}

fn bc1_encode_block(pixels: &[Rgba; 16], quality: u8) -> (u64, u32) {
	/*let (min, max) = bc1_build_endpoints(&pixels)[0];
	let table = bc1_build_table(&min, &max);*/

	let ((min, max), table) = bc1_build_endpoints(pixels, quality).iter()
		.map(|pts| (*pts, bc1_build_table(&pts.0, &pts.1)))
		.min_by_key(|tbl| bc1_total_dist(&tbl.1, pixels)).unwrap();

	let dist = bc1_total_dist(&table, pixels);

	let min = bc1_encode_endpoint(&min) as u64;
	let max = bc1_encode_endpoint(&max) as u64;

	let encoded = bc1_encode_pixel(&table, &pixels) as u64;

	((encoded << 32) | (min << 16) | max, dist)
}

pub fn bc1(image: &Vec<u8>, size: (usize, usize), quality: u8) -> Result<Vec<u8>, ()> {
	if size.0 % 4 != 0 || size.1 % 4 != 0 || image.len() != size.0 * size.1 * 4 {
		return Err(());
	}

    let mut out = Vec::with_capacity(image.len() / 8);
    let mut total_dist = 0u32;

    let block_size = 4;
    let blk_count = (size.0 / block_size, size.1 / block_size);

   	for by in 0..blk_count.1 {
   		for bx in 0..blk_count.0 {

   			let mut pixels = [[0u8; 4]; 16]; // No compile time constants
   			for py in 0..block_size {
   				for px in 0..block_size {
   					let x = bx * block_size + px;
   					let y = by * block_size + py;

   					//println!("{:?} of {:?}", (x, y), size);

   					let pi = (x + y * size.0) * 4; // in bytes
   					let pix = [image[pi], image[pi + 1], image[pi + 2], image[pi + 3]];

   					pixels[px + py * block_size] = pix;
   				}
   			}

   			let (mut encoded, dist) = bc1_encode_block(&pixels, quality);
   			total_dist += dist;

   			for _ in 0..8 {
   				out.push((encoded & 0xFF) as u8);
   				encoded >>= 8;
   			}
		}
	}
	//println!("per-pixel dist = {:?}", total_dist / (size.0 * size.1) as u32);
	Ok(out)
}
<|endoftext|>


<commit_before>use std::result;
use error;

pub type Result<T> = result::Result<T, error::HesError>;

pub enum ExpectedVersion {
    NoConflict, // -2 states that this write should never conflict with anything and should always succeed.
    NotExist,   // -1 states that the stream should not exist at the time of the writing (this write will create it)
    Empty,      //  0 states that the stream should exist but should be empty
    Number(u64)
}

//impl std::convert::From<types::ExpectedVersion> for std::string::String {
//
//}

impl From<ExpectedVersion> for String {
    fn from(version: ExpectedVersion) -> String {
        match version {
            ExpectedVersion::NoConflict => "-2".to_string(),
            ExpectedVersion::NotExist => "-1".to_string(),
            ExpectedVersion::Empty => "0".to_string(),
            ExpectedVersion::Number(n) => n.to_string()
        }
    }
}

<commit_msg>Do cleanup.<commit_after>use std::result;
use error;

pub type Result<T> = result::Result<T, error::HesError>;
<|endoftext|>


<commit_before>use crate::error::{AuthErrorOr, Error};

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

/// Represents an access token returned by oauth2 servers. All access tokens are
/// Bearer tokens. Other types of tokens are not supported.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
pub struct AccessToken {
    value: String,
    expires_at: Option<DateTime<Utc>>,
}

impl AccessToken {
    /// A string representation of the access token.
    pub fn as_str(&self) -> &str {
        &self.value
    }

    /// The time the access token will expire, if any.
    pub fn expiration_time(&self) -> Option<DateTime<Utc>> {
        self.expires_at
    }

    /// Determine if the access token is expired.
    /// This will report that the token is expired 1 minute prior to the
    /// expiration time to ensure that when the token is actually sent to the
    /// server it's still valid.
    pub fn is_expired(&self) -> bool {
        // Consider the token expired if it's within 1 minute of it's expiration
        // time.
        self.expires_at
            .map(|expiration_time| expiration_time - chrono::Duration::minutes(1) <= Utc::now())
            .unwrap_or(false)
    }
}

impl AsRef<str> for AccessToken {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl From<TokenInfo> for AccessToken {
    fn from(value: TokenInfo) -> Self {
        AccessToken {
            value: value.access_token,
            expires_at: value.expires_at,
        }
    }
}

/// Represents a token as returned by OAuth2 servers.
///
/// It is produced by all authentication flows.
/// It authenticates certain operations, and must be refreshed once
/// it reached it's expiry date.
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct TokenInfo {
    /// used when authenticating calls to oauth2 enabled services.
    pub(crate) access_token: String,
    /// used to refresh an expired access_token.
    pub(crate) refresh_token: Option<String>,
    /// The time when the token expires.
    pub(crate) expires_at: Option<DateTime<Utc>>,
}

impl TokenInfo {
    pub(crate) fn from_json(json_data: &[u8]) -> Result<TokenInfo, Error> {
        #[derive(Deserialize)]
        struct RawToken {
            access_token: String,
            refresh_token: Option<String>,
            token_type: String,
            expires_in: Option<i64>,
        }

        let RawToken {
            access_token,
            refresh_token,
            token_type,
            expires_in,
        } = serde_json::from_slice::<AuthErrorOr<RawToken>>(json_data)?.into_result()?;

        if token_type.to_lowercase().as_str() != "bearer" {
            use std::io;
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    r#"unknown token type returned; expected "bearer" found {}"#,
                    token_type
                ),
            )
            .into());
        }

        let expires_at = expires_in
            .map(|seconds_from_now| Utc::now() + chrono::Duration::seconds(seconds_from_now));

        Ok(TokenInfo {
            access_token,
            refresh_token,
            expires_at,
        })
    }

    /// Returns true if we are expired.
    pub fn is_expired(&self) -> bool {
        self.expires_at
            .map(|expiration_time| expiration_time - chrono::Duration::minutes(1) <= Utc::now())
            .unwrap_or(false)
    }
}

/// Represents either 'installed' or 'web' applications in a json secrets file.
/// See `ConsoleApplicationSecret` for more information
#[derive(Deserialize, Serialize, Clone, Default, Debug)]
pub struct ApplicationSecret {
    /// The client ID.
    pub client_id: String,
    /// The client secret.
    pub client_secret: String,
    /// The token server endpoint URI.
    pub token_uri: String,
    /// The authorization server endpoint URI.
    pub auth_uri: String,
    /// The redirect uris.
    pub redirect_uris: Vec<String>,
    /// Name of the google project the credentials are associated with
    pub project_id: Option<String>,
    /// The service account email associated with the client.
    pub client_email: Option<String>,
    /// The URL of the public x509 certificate, used to verify the signature on JWTs, such
    /// as ID tokens, signed by the authentication provider.
    pub auth_provider_x509_cert_url: Option<String>,
    ///  The URL of the public x509 certificate, used to verify JWTs signed by the client.
    pub client_x509_cert_url: Option<String>,
}

/// A type to facilitate reading and writing the json secret file
/// as returned by the [google developer console](https://code.google.com/apis/console)
#[derive(Deserialize, Serialize, Default, Debug)]
pub struct ConsoleApplicationSecret {
    /// web app secret
    pub web: Option<ApplicationSecret>,
    /// installed app secret
    pub installed: Option<ApplicationSecret>,
}

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

    pub const SECRET: &'static str =
        "{\"installed\":{\"auth_uri\":\"https://accounts.google.com/o/oauth2/auth\",\
         \"client_secret\":\"UqkDJd5RFwnHoiG5x5Rub8SI\",\"token_uri\":\"https://accounts.google.\
         com/o/oauth2/token\",\"client_email\":\"\",\"redirect_uris\":[\"urn:ietf:wg:oauth:2.0:\
         oob\",\"oob\"],\"client_x509_cert_url\":\"\",\"client_id\":\
         \"14070749909-vgip2f1okm7bkvajhi9jugan6126io9v.apps.googleusercontent.com\",\
         \"auth_provider_x509_cert_url\":\"https://www.googleapis.com/oauth2/v1/certs\"}}";

    #[test]
    fn console_secret() {
        use serde_json as json;
        match json::from_str::<ConsoleApplicationSecret>(SECRET) {
            Ok(s) => assert!(s.installed.is_some() && s.web.is_none()),
            Err(err) => panic!(err),
        }
    }
}
<commit_msg>Expose TokenInfo fields publically<commit_after>use crate::error::{AuthErrorOr, Error};

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

/// Represents an access token returned by oauth2 servers. All access tokens are
/// Bearer tokens. Other types of tokens are not supported.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
pub struct AccessToken {
    value: String,
    expires_at: Option<DateTime<Utc>>,
}

impl AccessToken {
    /// A string representation of the access token.
    pub fn as_str(&self) -> &str {
        &self.value
    }

    /// The time the access token will expire, if any.
    pub fn expiration_time(&self) -> Option<DateTime<Utc>> {
        self.expires_at
    }

    /// Determine if the access token is expired.
    /// This will report that the token is expired 1 minute prior to the
    /// expiration time to ensure that when the token is actually sent to the
    /// server it's still valid.
    pub fn is_expired(&self) -> bool {
        // Consider the token expired if it's within 1 minute of it's expiration
        // time.
        self.expires_at
            .map(|expiration_time| expiration_time - chrono::Duration::minutes(1) <= Utc::now())
            .unwrap_or(false)
    }
}

impl AsRef<str> for AccessToken {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl From<TokenInfo> for AccessToken {
    fn from(value: TokenInfo) -> Self {
        AccessToken {
            value: value.access_token,
            expires_at: value.expires_at,
        }
    }
}

/// Represents a token as returned by OAuth2 servers.
///
/// It is produced by all authentication flows.
/// It authenticates certain operations, and must be refreshed once
/// it reached it's expiry date.
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct TokenInfo {
    /// used when authenticating calls to oauth2 enabled services.
    pub access_token: String,
    /// used to refresh an expired access_token.
    pub refresh_token: Option<String>,
    /// The time when the token expires.
    pub expires_at: Option<DateTime<Utc>>,
}

impl TokenInfo {
    pub(crate) fn from_json(json_data: &[u8]) -> Result<TokenInfo, Error> {
        #[derive(Deserialize)]
        struct RawToken {
            access_token: String,
            refresh_token: Option<String>,
            token_type: String,
            expires_in: Option<i64>,
        }

        let RawToken {
            access_token,
            refresh_token,
            token_type,
            expires_in,
        } = serde_json::from_slice::<AuthErrorOr<RawToken>>(json_data)?.into_result()?;

        if token_type.to_lowercase().as_str() != "bearer" {
            use std::io;
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    r#"unknown token type returned; expected "bearer" found {}"#,
                    token_type
                ),
            )
            .into());
        }

        let expires_at = expires_in
            .map(|seconds_from_now| Utc::now() + chrono::Duration::seconds(seconds_from_now));

        Ok(TokenInfo {
            access_token,
            refresh_token,
            expires_at,
        })
    }

    /// Returns true if we are expired.
    pub fn is_expired(&self) -> bool {
        self.expires_at
            .map(|expiration_time| expiration_time - chrono::Duration::minutes(1) <= Utc::now())
            .unwrap_or(false)
    }
}

/// Represents either 'installed' or 'web' applications in a json secrets file.
/// See `ConsoleApplicationSecret` for more information
#[derive(Deserialize, Serialize, Clone, Default, Debug)]
pub struct ApplicationSecret {
    /// The client ID.
    pub client_id: String,
    /// The client secret.
    pub client_secret: String,
    /// The token server endpoint URI.
    pub token_uri: String,
    /// The authorization server endpoint URI.
    pub auth_uri: String,
    /// The redirect uris.
    pub redirect_uris: Vec<String>,
    /// Name of the google project the credentials are associated with
    pub project_id: Option<String>,
    /// The service account email associated with the client.
    pub client_email: Option<String>,
    /// The URL of the public x509 certificate, used to verify the signature on JWTs, such
    /// as ID tokens, signed by the authentication provider.
    pub auth_provider_x509_cert_url: Option<String>,
    ///  The URL of the public x509 certificate, used to verify JWTs signed by the client.
    pub client_x509_cert_url: Option<String>,
}

/// A type to facilitate reading and writing the json secret file
/// as returned by the [google developer console](https://code.google.com/apis/console)
#[derive(Deserialize, Serialize, Default, Debug)]
pub struct ConsoleApplicationSecret {
    /// web app secret
    pub web: Option<ApplicationSecret>,
    /// installed app secret
    pub installed: Option<ApplicationSecret>,
}

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

    pub const SECRET: &'static str =
        "{\"installed\":{\"auth_uri\":\"https://accounts.google.com/o/oauth2/auth\",\
         \"client_secret\":\"UqkDJd5RFwnHoiG5x5Rub8SI\",\"token_uri\":\"https://accounts.google.\
         com/o/oauth2/token\",\"client_email\":\"\",\"redirect_uris\":[\"urn:ietf:wg:oauth:2.0:\
         oob\",\"oob\"],\"client_x509_cert_url\":\"\",\"client_id\":\
         \"14070749909-vgip2f1okm7bkvajhi9jugan6126io9v.apps.googleusercontent.com\",\
         \"auth_provider_x509_cert_url\":\"https://www.googleapis.com/oauth2/v1/certs\"}}";

    #[test]
    fn console_secret() {
        use serde_json as json;
        match json::from_str::<ConsoleApplicationSecret>(SECRET) {
            Ok(s) => assert!(s.installed.is_some() && s.web.is_none()),
            Err(err) => panic!(err),
        }
    }
}
<|endoftext|>


<commit_before>// FIXME: Should be bindgenned

import libc::{c_void, c_char, size_t};

#[nolink]
native mod cg {
    fn CGDataProviderCreateWithFilename(filename: *c_char) -> CGDataProviderRef;
    fn CGDataProviderCreateWithData(info: *c_void,
                                    data: *c_void,
                                    size: size_t,
                                    releaseData: CGDataProviderReleaseDataCallback
                                   ) -> CGDataProviderRef;
    fn CGDataProviderRelease(provider: CGDataProviderRef);
    fn CGFontCreateWithDataProvider(provider: CGDataProviderRef) -> CGFontRef;
}

type CGFontRef = *c_void;
type CGDataProviderRef = *c_void;
type CGDataProviderReleaseDataCallback = *c_void;<commit_msg>Add binding for CGFontRelease<commit_after>// FIXME: Should be bindgenned

import libc::{c_void, c_char, size_t};

#[nolink]
native mod cg {
    fn CGDataProviderCreateWithFilename(filename: *c_char) -> CGDataProviderRef;
    fn CGDataProviderCreateWithData(info: *c_void,
                                    data: *c_void,
                                    size: size_t,
                                    releaseData: CGDataProviderReleaseDataCallback
                                   ) -> CGDataProviderRef;
    fn CGDataProviderRelease(provider: CGDataProviderRef);
    fn CGFontCreateWithDataProvider(provider: CGDataProviderRef) -> CGFontRef;
    fn CGFontRelease(font: CGFontRef);
}

type CGFontRef = *c_void;
type CGDataProviderRef = *c_void;
type CGDataProviderReleaseDataCallback = *c_void;<|endoftext|>