<commit_before>/**
 * At the moment, this is a partial hashmap implementation, not yet fit for
 * use, but useful as a stress test for rustboot.
 */

import std._int;
import std.sys;
import std.util;
import std._vec;

type hashfn[K] = fn(&K) -> uint;
type eqfn[K] = fn(&K, &K) -> bool;

state type hashmap[K, V] = state obj {
                                 fn size() -> uint;
                                 fn insert(&K key, &V val) -> bool;
                                 fn contains_key(&K key) -> bool;
                                 fn get(&K key) -> V;
                                 fn find(&K key) -> util.option[V];
                                 fn remove(&K key) -> util.option[V];
                                 fn rehash();
                                 iter items() -> tup(K,V);
};

fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {

    let uint initial_capacity = 32u; // 2^5
    let util.rational load_factor = rec(num=3, den=4);

    tag bucket[K, V] {
        nil;
        deleted;
        some(K, V);
    }

    fn make_buckets[K, V](uint nbkts) -> vec[mutable bucket[K, V]] {
        ret _vec.init_elt[mutable bucket[K, V]](nil[K, V], nbkts);
    }

    // Derive two hash functions from the one given by taking the upper
    // half and lower half of the uint bits.  Our bucket probing
    // sequence is then defined by
    //
    //   hash(key, i) := hashl(key) + i * hashr(key)   for i = 0, 1, 2, ...
    //
    // Tearing the hash function apart this way is kosher in practice
    // as, assuming 32-bit uints, the table would have to be at 2^32
    // buckets before the resulting pair of hash functions no longer
    // probes all buckets for a fixed key.  Note that hashr is made to
    // output odd numbers (hence coprime to the number of nbkts, which
    // is always a power of 2), so that all buckets are probed for a
    // fixed key.

    fn hashl[K](&hashfn[K] hasher, uint nbkts, &K key) -> uint {
        ret (hasher(key) >>> (sys.rustrt.size_of[uint]() * 8u / 2u));
    }

    fn hashr[K](&hashfn[K] hasher, uint nbkts, &K key) -> uint {
        ret ((((~ 0u) >>> (sys.rustrt.size_of[uint]() * 8u / 2u))
              & hasher(key)) * 2u + 1u);
    }

    fn hash[K](&hashfn[K] hasher, uint nbkts, &K key, uint i) -> uint {
        ret (hashl[K](hasher, nbkts, key)
             + i * hashr[K](hasher, nbkts, key)) % nbkts;
    }

    /**
     * We attempt to never call this with a full table.  If we do, it
     * will fail.
     */
    fn insert_common[K, V](&hashfn[K] hasher,
                           &eqfn[K] eqer,
                           vec[mutable bucket[K, V]] bkts,
                           uint nbkts,
                           &K key,
                           &V val)
        -> bool
        {
            let uint i = 0u;
            while (i < nbkts) {
                let uint j = hash[K](hasher, nbkts, key, i);
                alt (bkts.(j)) {
                    case (some[K, V](?k, _)) {
                        if (eqer(key, k)) {
                            bkts.(j) = some[K, V](k, val);
                            ret false;
                        }
                        i += 1u;
                    }
                    case (_) {
                        bkts.(j) = some[K, V](key, val);
                        ret true;
                    }
                }
            }
            fail; // full table
        }

    fn find_common[K, V](&hashfn[K] hasher,
                         &eqfn[K] eqer,
                         vec[mutable bucket[K, V]] bkts,
                         uint nbkts,
                         &K key)
        -> util.option[V]
        {
            let uint i = 0u;
            while (i < nbkts) {
                let uint j = (hash[K](hasher, nbkts, key, i));
                alt (bkts.(j)) {
                    case (some[K, V](?k, ?v)) {
                        if (eqer(key, k)) {
                            ret util.some[V](v);
                        }
                    }
                    case (nil[K, V]) {
                        ret util.none[V];
                    }
                    case (deleted[K, V]) { }
                }
                i += 1u;
            }
            ret util.none[V];
        }

    fn rehash[K, V](&hashfn[K] hasher,
                    &eqfn[K] eqer,
                    vec[mutable bucket[K, V]] oldbkts, uint noldbkts,
                    vec[mutable bucket[K, V]] newbkts, uint nnewbkts)
        {
            for (bucket[K, V] b in oldbkts) {
                alt (b) {
                    case (some[K, V](?k, ?v)) {
                        insert_common[K, V](hasher, eqer, newbkts,
                                            nnewbkts, k, v);
                    }
                    case (_) { }
                }
            }
        }

    state obj hashmap[K, V](hashfn[K] hasher,
                            eqfn[K] eqer,
                            mutable vec[mutable bucket[K, V]] bkts,
                            mutable uint nbkts,
                            mutable uint nelts,
                            util.rational lf)
        {
            fn size() -> uint { ret nelts; }

            fn insert(&K key, &V val) -> bool {
                let util.rational load = rec(num=(nelts + 1u) as int,
                                             den=nbkts as int);
                if (!util.rational_leq(load, lf)) {
                    let uint nnewbkts = _uint.next_power_of_two(nbkts + 1u);
                    let vec[mutable bucket[K, V]] newbkts =
                        make_buckets[K, V](nnewbkts);
                    rehash[K, V](hasher, eqer, bkts, nbkts,
                                 newbkts, nnewbkts);
                    bkts = newbkts;
                    nbkts = nnewbkts;
                }

                if (insert_common[K, V](hasher, eqer, bkts,
                                        nbkts, key, val)) {
                    nelts += 1u;
                    ret true;
                }
                ret false;
            }

            fn contains_key(&K key) -> bool {
                alt (find_common[K, V](hasher, eqer, bkts, nbkts, key)) {
                    case (util.some[V](_)) { ret true; }
                    case (_) { ret false; }
                }
            }

            fn get(&K key) -> V {
                alt (find_common[K, V](hasher, eqer, bkts, nbkts, key)) {
                    case (util.some[V](?val)) { ret val; }
                    case (_) { fail; }
                }
            }

            fn find(&K key) -> util.option[V] {
                be find_common[K, V](hasher, eqer, bkts, nbkts, key);
            }

            fn remove(&K key) -> util.option[V] {
                let uint i = 0u;
                while (i < nbkts) {
                    let uint j = (hash[K](hasher, nbkts, key, i));
                    alt (bkts.(j)) {
                        case (some[K, V](?k, ?v)) {
                            if (eqer(key, k)) {
                                bkts.(j) = deleted[K, V];
                                nelts -= 1u;
                                ret util.some[V](v);
                            }
                        }
                        case (deleted[K, V]) { }
                        case (nil[K, V]) {
                            ret util.none[V];
                        }
                    }
                    i += 1u;
                }
                ret util.none[V];
            }

            fn rehash() {
                let vec[mutable bucket[K, V]] newbkts =
                    make_buckets[K, V](nbkts);
                rehash[K, V](hasher, eqer, bkts, nbkts, newbkts, nbkts);
                bkts = newbkts;
            }

            iter items() -> tup(K,V) {
                for (bucket[K,V] b in bkts) {
                    alt (b) {
                        case(some[K,V](?k,?v)) {
                            put tup(k,v);
                        }
                        case (_) { }
                    }
                }
            }
        }

    let vec[mutable bucket[K, V]] bkts =
        make_buckets[K, V](initial_capacity);

    ret hashmap[K, V](hasher, eqer, bkts, initial_capacity, 0u, load_factor);
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>Disable use of parametric tail call in map.rs, they don't presently work.<commit_after>/**
 * At the moment, this is a partial hashmap implementation, not yet fit for
 * use, but useful as a stress test for rustboot.
 */

import std._int;
import std.sys;
import std.util;
import std._vec;

type hashfn[K] = fn(&K) -> uint;
type eqfn[K] = fn(&K, &K) -> bool;

state type hashmap[K, V] = state obj {
                                 fn size() -> uint;
                                 fn insert(&K key, &V val) -> bool;
                                 fn contains_key(&K key) -> bool;
                                 fn get(&K key) -> V;
                                 fn find(&K key) -> util.option[V];
                                 fn remove(&K key) -> util.option[V];
                                 fn rehash();
                                 iter items() -> tup(K,V);
};

fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {

    let uint initial_capacity = 32u; // 2^5
    let util.rational load_factor = rec(num=3, den=4);

    tag bucket[K, V] {
        nil;
        deleted;
        some(K, V);
    }

    fn make_buckets[K, V](uint nbkts) -> vec[mutable bucket[K, V]] {
        ret _vec.init_elt[mutable bucket[K, V]](nil[K, V], nbkts);
    }

    // Derive two hash functions from the one given by taking the upper
    // half and lower half of the uint bits.  Our bucket probing
    // sequence is then defined by
    //
    //   hash(key, i) := hashl(key) + i * hashr(key)   for i = 0, 1, 2, ...
    //
    // Tearing the hash function apart this way is kosher in practice
    // as, assuming 32-bit uints, the table would have to be at 2^32
    // buckets before the resulting pair of hash functions no longer
    // probes all buckets for a fixed key.  Note that hashr is made to
    // output odd numbers (hence coprime to the number of nbkts, which
    // is always a power of 2), so that all buckets are probed for a
    // fixed key.

    fn hashl[K](&hashfn[K] hasher, uint nbkts, &K key) -> uint {
        ret (hasher(key) >>> (sys.rustrt.size_of[uint]() * 8u / 2u));
    }

    fn hashr[K](&hashfn[K] hasher, uint nbkts, &K key) -> uint {
        ret ((((~ 0u) >>> (sys.rustrt.size_of[uint]() * 8u / 2u))
              & hasher(key)) * 2u + 1u);
    }

    fn hash[K](&hashfn[K] hasher, uint nbkts, &K key, uint i) -> uint {
        ret (hashl[K](hasher, nbkts, key)
             + i * hashr[K](hasher, nbkts, key)) % nbkts;
    }

    /**
     * We attempt to never call this with a full table.  If we do, it
     * will fail.
     */
    fn insert_common[K, V](&hashfn[K] hasher,
                           &eqfn[K] eqer,
                           vec[mutable bucket[K, V]] bkts,
                           uint nbkts,
                           &K key,
                           &V val)
        -> bool
        {
            let uint i = 0u;
            while (i < nbkts) {
                let uint j = hash[K](hasher, nbkts, key, i);
                alt (bkts.(j)) {
                    case (some[K, V](?k, _)) {
                        if (eqer(key, k)) {
                            bkts.(j) = some[K, V](k, val);
                            ret false;
                        }
                        i += 1u;
                    }
                    case (_) {
                        bkts.(j) = some[K, V](key, val);
                        ret true;
                    }
                }
            }
            fail; // full table
        }

    fn find_common[K, V](&hashfn[K] hasher,
                         &eqfn[K] eqer,
                         vec[mutable bucket[K, V]] bkts,
                         uint nbkts,
                         &K key)
        -> util.option[V]
        {
            let uint i = 0u;
            while (i < nbkts) {
                let uint j = (hash[K](hasher, nbkts, key, i));
                alt (bkts.(j)) {
                    case (some[K, V](?k, ?v)) {
                        if (eqer(key, k)) {
                            ret util.some[V](v);
                        }
                    }
                    case (nil[K, V]) {
                        ret util.none[V];
                    }
                    case (deleted[K, V]) { }
                }
                i += 1u;
            }
            ret util.none[V];
        }

    fn rehash[K, V](&hashfn[K] hasher,
                    &eqfn[K] eqer,
                    vec[mutable bucket[K, V]] oldbkts, uint noldbkts,
                    vec[mutable bucket[K, V]] newbkts, uint nnewbkts)
        {
            for (bucket[K, V] b in oldbkts) {
                alt (b) {
                    case (some[K, V](?k, ?v)) {
                        insert_common[K, V](hasher, eqer, newbkts,
                                            nnewbkts, k, v);
                    }
                    case (_) { }
                }
            }
        }

    state obj hashmap[K, V](hashfn[K] hasher,
                            eqfn[K] eqer,
                            mutable vec[mutable bucket[K, V]] bkts,
                            mutable uint nbkts,
                            mutable uint nelts,
                            util.rational lf)
        {
            fn size() -> uint { ret nelts; }

            fn insert(&K key, &V val) -> bool {
                let util.rational load = rec(num=(nelts + 1u) as int,
                                             den=nbkts as int);
                if (!util.rational_leq(load, lf)) {
                    let uint nnewbkts = _uint.next_power_of_two(nbkts + 1u);
                    let vec[mutable bucket[K, V]] newbkts =
                        make_buckets[K, V](nnewbkts);
                    rehash[K, V](hasher, eqer, bkts, nbkts,
                                 newbkts, nnewbkts);
                    bkts = newbkts;
                    nbkts = nnewbkts;
                }

                if (insert_common[K, V](hasher, eqer, bkts,
                                        nbkts, key, val)) {
                    nelts += 1u;
                    ret true;
                }
                ret false;
            }

            fn contains_key(&K key) -> bool {
                alt (find_common[K, V](hasher, eqer, bkts, nbkts, key)) {
                    case (util.some[V](_)) { ret true; }
                    case (_) { ret false; }
                }
            }

            fn get(&K key) -> V {
                alt (find_common[K, V](hasher, eqer, bkts, nbkts, key)) {
                    case (util.some[V](?val)) { ret val; }
                    case (_) { fail; }
                }
            }

            fn find(&K key) -> util.option[V] {
                // FIXME: should be 'be' but parametric tail-calls don't
                // work at the moment.
                ret find_common[K, V](hasher, eqer, bkts, nbkts, key);
            }

            fn remove(&K key) -> util.option[V] {
                let uint i = 0u;
                while (i < nbkts) {
                    let uint j = (hash[K](hasher, nbkts, key, i));
                    alt (bkts.(j)) {
                        case (some[K, V](?k, ?v)) {
                            if (eqer(key, k)) {
                                bkts.(j) = deleted[K, V];
                                nelts -= 1u;
                                ret util.some[V](v);
                            }
                        }
                        case (deleted[K, V]) { }
                        case (nil[K, V]) {
                            ret util.none[V];
                        }
                    }
                    i += 1u;
                }
                ret util.none[V];
            }

            fn rehash() {
                let vec[mutable bucket[K, V]] newbkts =
                    make_buckets[K, V](nbkts);
                rehash[K, V](hasher, eqer, bkts, nbkts, newbkts, nbkts);
                bkts = newbkts;
            }

            iter items() -> tup(K,V) {
                for (bucket[K,V] b in bkts) {
                    alt (b) {
                        case(some[K,V](?k,?v)) {
                            put tup(k,v);
                        }
                        case (_) { }
                    }
                }
            }
        }

    let vec[mutable bucket[K, V]] bkts =
        make_buckets[K, V](initial_capacity);

    ret hashmap[K, V](hasher, eqer, bkts, initial_capacity, 0u, load_factor);
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>More error handling<commit_after><|endoftext|>


<commit_before>//! AWS Regions and helper functions
//!
//! Mostly used for translating the Region enum to a string AWS accepts.
//!
//! EG: UsEast1 to "us-east-1"

use std::str::FromStr;

/// AWS Region
#[derive(Debug,PartialEq)]
pub enum Region {
    UsEast1,
    UsWest1,
    UsWest2,
    EuWest1,
    EuCentral1,
    ApSoutheast1,
    ApNortheast1,
    ApSoutheast2,
    SaEast1,
}

#[derive(Debug,PartialEq)]
pub struct ParseRegionError;

impl FromStr for Region {
    type Err = ParseRegionError;

    fn from_str(s: &str) -> Result<Region, ParseRegionError> {
        match s {
            "us-east-1" => Ok(Region::UsEast1),
            "us-west-1" => Ok(Region::UsWest1),
            "us-west-2" => Ok(Region::UsWest2),
            "eu-west-1" => Ok(Region::EuWest1),
            "eu-central-1" => Ok(Region::EuCentral1),
            "ap-southeast-1" => Ok(Region::ApSoutheast1),
            "ap-northeast-1" => Ok(Region::ApNortheast1),
            "ap-southeast-2" => Ok(Region::ApSoutheast2),
            "sa-east-1" => Ok(Region::SaEast1),
            _ => Err(ParseRegionError)
        }
    }
}

/// Translates region enum into AWS format.  EG: us-east-1
pub fn region_in_aws_format(region: &Region) -> String {
    match region {
        &Region::UsEast1 => "us-east-1".to_string(),
        &Region::UsWest1 => "us-west-1".to_string(),
        &Region::UsWest2 => "us-west-2".to_string(),
        &Region::EuWest1 => "eu-west-1".to_string(),
        &Region::EuCentral1 => "eu-central-1".to_string(),
        &Region::ApSoutheast1 => "ap-southeast-1".to_string(),
        &Region::ApNortheast1 => "ap-northeast-1".to_string(),
        &Region::ApSoutheast2 => "ap-southeast-2".to_string(),
        &Region::SaEast1 => "sa-east-1".to_string(),
    }
}

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

    #[test]
    fn from_str_for_region() {
        assert_eq!(FromStr::from_str("us-east-1"), Ok(Region::UsEast1));
        assert_eq!(FromStr::from_str("us-west-1"), Ok(Region::UsWest1));
        assert_eq!(FromStr::from_str("us-west-2"), Ok(Region::UsWest2));
        assert_eq!(FromStr::from_str("eu-west-1"), Ok(Region::EuWest1));
        assert_eq!(FromStr::from_str("eu-central-1"), Ok(Region::EuCentral1));
    }

	#[test]
	fn regions_correctly_map_to_aws_strings() {
        let mut region = Region::UsEast1;
        if region_in_aws_format(&region) != "us-east-1" {
            panic!("Couldn't map us-east-1 enum right.");
        }
        region = Region::UsWest1;
        if region_in_aws_format(&region) != "us-west-1" {
            panic!("Couldn't map us-west-1 enum right.");
        }
        region = Region::UsWest2;
        if region_in_aws_format(&region) != "us-west-2" {
            panic!("Couldn't map us-west-2 enum right.");
        }
        region = Region::EuWest1;
        if region_in_aws_format(&region) != "eu-west-1" {
            panic!("Couldn't map eu-west-1 enum right.");
        }
        region = Region::EuCentral1;
        if region_in_aws_format(&region) != "eu-central-1" {
            panic!("Couldn't map eu-central-1 enum right.");
        }
        region = Region::ApSoutheast1;
        if region_in_aws_format(&region) != "ap-southeast-1" {
            panic!("Couldn't map ap-southeast-1 enum right.");
        }
        region = Region::ApNortheast1;
        if region_in_aws_format(&region) != "ap-northeast-1" {
            panic!("Couldn't map ap-northeast-1 enum right.");
        }
        region = Region::ApSoutheast2;
        if region_in_aws_format(&region) != "ap-southeast-2" {
            panic!("Couldn't map ap-southeast-2 enum right.");
        }
        region = Region::SaEast1;
        if region_in_aws_format(&region) != "sa-east-1" {
            panic!("Couldn't map sa-east-1 enum right.");
        }
    }
}
<commit_msg>Add failing tests to FromStr for Region<commit_after>//! AWS Regions and helper functions
//!
//! Mostly used for translating the Region enum to a string AWS accepts.
//!
//! EG: UsEast1 to "us-east-1"

use std::str::FromStr;

/// AWS Region
#[derive(Debug,PartialEq)]
pub enum Region {
    UsEast1,
    UsWest1,
    UsWest2,
    EuWest1,
    EuCentral1,
    ApSoutheast1,
    ApNortheast1,
    ApSoutheast2,
    SaEast1,
}

#[derive(Debug,PartialEq)]
pub struct ParseRegionError;

impl FromStr for Region {
    type Err = ParseRegionError;

    fn from_str(s: &str) -> Result<Region, ParseRegionError> {
        match s {
            "us-east-1" => Ok(Region::UsEast1),
            "us-west-1" => Ok(Region::UsWest1),
            "us-west-2" => Ok(Region::UsWest2),
            "eu-west-1" => Ok(Region::EuWest1),
            "eu-central-1" => Ok(Region::EuCentral1),
            "ap-southeast-1" => Ok(Region::ApSoutheast1),
            "ap-northeast-1" => Ok(Region::ApNortheast1),
            "ap-southeast-2" => Ok(Region::ApSoutheast2),
            "sa-east-1" => Ok(Region::SaEast1),
            _ => Err(ParseRegionError)
        }
    }
}

/// Translates region enum into AWS format.  EG: us-east-1
pub fn region_in_aws_format(region: &Region) -> String {
    match region {
        &Region::UsEast1 => "us-east-1".to_string(),
        &Region::UsWest1 => "us-west-1".to_string(),
        &Region::UsWest2 => "us-west-2".to_string(),
        &Region::EuWest1 => "eu-west-1".to_string(),
        &Region::EuCentral1 => "eu-central-1".to_string(),
        &Region::ApSoutheast1 => "ap-southeast-1".to_string(),
        &Region::ApNortheast1 => "ap-northeast-1".to_string(),
        &Region::ApSoutheast2 => "ap-southeast-2".to_string(),
        &Region::SaEast1 => "sa-east-1".to_string(),
    }
}

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

    #[test]
    fn from_str_for_region() {
        assert_eq!(FromStr::from_str("us-east-1"), Ok(Region::UsEast1));
        assert_eq!(FromStr::from_str("us-west-1"), Ok(Region::UsWest1));
        assert_eq!(FromStr::from_str("us-west-2"), Ok(Region::UsWest2));
        assert_eq!(FromStr::from_str("eu-west-1"), Ok(Region::EuWest1));
        assert_eq!(FromStr::from_str("eu-central-1"), Ok(Region::EuCentral1));
        assert_eq!(FromStr::from_str("ap-southeast-1"), Ok(Region::ApSoutheast1));
    }

    #[test]
    fn from_str_errs_on_invalid_region() {
        assert_eq!(<Region as FromStr>::from_str("not an AWS region"), Err(ParseRegionError));
    }

    #[test]
	  fn regions_correctly_map_to_aws_strings() {
        let mut region = Region::UsEast1;
        if region_in_aws_format(&region) != "us-east-1" {
            panic!("Couldn't map us-east-1 enum right.");
        }
        region = Region::UsWest1;
        if region_in_aws_format(&region) != "us-west-1" {
            panic!("Couldn't map us-west-1 enum right.");
        }
        region = Region::UsWest2;
        if region_in_aws_format(&region) != "us-west-2" {
            panic!("Couldn't map us-west-2 enum right.");
        }
        region = Region::EuWest1;
        if region_in_aws_format(&region) != "eu-west-1" {
            panic!("Couldn't map eu-west-1 enum right.");
        }
        region = Region::EuCentral1;
        if region_in_aws_format(&region) != "eu-central-1" {
            panic!("Couldn't map eu-central-1 enum right.");
        }
        region = Region::ApSoutheast1;
        if region_in_aws_format(&region) != "ap-southeast-1" {
            panic!("Couldn't map ap-southeast-1 enum right.");
        }
        region = Region::ApNortheast1;
        if region_in_aws_format(&region) != "ap-northeast-1" {
            panic!("Couldn't map ap-northeast-1 enum right.");
        }
        region = Region::ApSoutheast2;
        if region_in_aws_format(&region) != "ap-southeast-2" {
            panic!("Couldn't map ap-southeast-2 enum right.");
        }
        region = Region::SaEast1;
        if region_in_aws_format(&region) != "sa-east-1" {
            panic!("Couldn't map sa-east-1 enum right.");
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add `to_u32` utility<commit_after>#[inline]
pub fn to_u32(bytes: &[u8]) -> u32 {
  let length = bytes.len();

  assert!(length <= 4);

  (0..length).fold(0, |result, i|
    result + ((bytes[i] as u32) << ((length - 1 - i) * 8))
  )
}
<|endoftext|>


<commit_before><commit_msg>Implement play control duration<commit_after><|endoftext|>


<commit_before><commit_msg>Add tests involving Rc, Arc, and Cell.<commit_after>#![feature(custom_attribute, box_syntax)]
#![allow(dead_code, unused_attributes)]

#[miri_run]
fn rc_cell() -> i32 {
    use std::rc::Rc;
    use std::cell::Cell;
    let r = Rc::new(Cell::new(42));
    let x = r.get();
    r.set(x + x);
    r.get()
}

#[miri_run]
fn arc() -> i32 {
    use std::sync::Arc;
    let a = Arc::new(42);
    *a
}
<|endoftext|>


<commit_before><commit_msg>Improved relay wait timeout tests.<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for ssqrt (not passed)<commit_after>
extern crate rand;
extern crate ndarray;
extern crate ndarray_rand;
extern crate ndarray_linalg as linalg;

use ndarray::prelude::*;
use linalg::SquareMatrix;
use rand::distributions::*;
use ndarray_rand::RandomExt;

fn all_close(a: &Array<f64, (Ix, Ix)>, b: &Array<f64, (Ix, Ix)>) {
    if !a.all_close(b, 1.0e-7) {
        panic!("\nTwo matrices are not equal:\na = \n{:?}\nb = \n{:?}\n",
               a,
               b);
    }
}

#[test]
fn ssqrt_random() {
    let r_dist = Range::new(0., 1.);
    let mut a = Array::<f64, _>::random((3, 3), r_dist);
    a = a.dot(&a.t());
    let ar = a.clone().ssqrt().unwrap();
    all_close(&ar.clone().reversed_axes(), &ar);
    all_close(&ar.dot(&ar), &a);
}
<|endoftext|>


<commit_before><commit_msg>test: Add test that aux2bib runs<commit_after>use std::env;
use std::process::Command;
use std::path::PathBuf;

fn get_bin_dir() -> PathBuf {
    env::current_exe()
        .expect("test bin's directory")
        .parent()
        .expect("test bin's parent directory")
        .parent()
        .expect("executable's directory")
        .to_path_buf()
}

fn cmd_aux2bib() -> Command {
    let path = get_bin_dir().join("aux2bib");
    if !path.is_file() {
        panic!("aux2bib binary not found");
    }
    let mut cmd = Command::new(path);

    cmd.env_clear();

    cmd
}

#[test]
fn aux2bib_runs() {
    let mut cmd = cmd_aux2bib().arg("--help").spawn().expect(
        "Failed to execute aux2bib",
    );

    let error_code = cmd.wait().expect("Failed to wait on aux2bib");

    assert!(error_code.success());

}
<|endoftext|>


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

//! Factory extension.
//!
//! This module serves as an extension to the `factory` module in the `gfx` crate. This module
//! exposes extension functions and shortcuts to aid with creating and managing graphics resources.
//! See the `FactoryExt` trait for more information.

use std::error::Error;
use std::fmt;
use core::{buffer, format, handle, texture, state};
use core::{Primitive, Resources, ShaderSet};
use core::factory::Factory;
use core::pso::{CreationError, Descriptor};
use core::memory::{self, Bind, Pod};
use slice::{Slice, IndexBuffer, IntoIndexBuffer};
use pso;
use shade::ProgramError;

/// Error creating a PipelineState
#[derive(Clone, PartialEq, Debug)]
pub enum PipelineStateError<S> {
    /// Shader program failed to link.
    Program(ProgramError),
    /// Unable to create PSO descriptor due to mismatched formats.
    DescriptorInit(pso::InitError<S>),
    /// Device failed to create the handle give the descriptor.
    DeviceCreate(CreationError),
}

impl<'a> From<PipelineStateError<&'a str>> for PipelineStateError<String> {
    fn from(pse: PipelineStateError<&'a str>) -> PipelineStateError<String> {
        match pse {
            PipelineStateError::Program(e) => PipelineStateError::Program(e),
            PipelineStateError::DescriptorInit(e) => PipelineStateError::DescriptorInit(e.into()),
            PipelineStateError::DeviceCreate(e) => PipelineStateError::DeviceCreate(e),
        }
    }
}

impl<S: fmt::Debug + fmt::Display> fmt::Display for PipelineStateError<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            PipelineStateError::Program(ref e) => write!(f, "{}: {}", self.description(), e),
            PipelineStateError::DescriptorInit(ref e) => write!(f, "{}: {}", self.description(), e),
            PipelineStateError::DeviceCreate(ref e) => write!(f, "{}: {}", self.description(), e),
        }
    }
}

impl<S: fmt::Debug + fmt::Display> Error for PipelineStateError<S> {
    fn description(&self) -> &str {
        match *self {
            PipelineStateError::Program(_) => "Shader program failed to link",
            PipelineStateError::DescriptorInit(_) =>
                "Unable to create PSO descriptor due to mismatched formats",
            PipelineStateError::DeviceCreate(_) => "Device failed to create the handle give the descriptor",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            PipelineStateError::Program(ref program_error) => Some(program_error),
            PipelineStateError::DescriptorInit(ref init_error) => Some(init_error),
            PipelineStateError::DeviceCreate(ref creation_error) => Some(creation_error),
        }
    }
}

impl<S> From<ProgramError> for PipelineStateError<S> {
    fn from(e: ProgramError) -> Self {
        PipelineStateError::Program(e)
    }
}

impl<S> From<pso::InitError<S>> for PipelineStateError<S> {
    fn from(e: pso::InitError<S>) -> Self {
        PipelineStateError::DescriptorInit(e)
    }
}

impl<S> From<CreationError> for PipelineStateError<S> {
    fn from(e: CreationError) -> Self {
        PipelineStateError::DeviceCreate(e)
    }
}

/// This trait is responsible for creating and managing graphics resources, much like the `Factory`
/// trait in the `gfx` crate. Every `Factory` automatically implements `FactoryExt`.
pub trait FactoryExt<R: Resources>: Factory<R> {
    /// Creates an immutable vertex buffer from the supplied vertices.
    /// A `Slice` will have to manually be constructed.
    fn create_vertex_buffer<T>(&mut self, vertices: &[T])
                               -> handle::Buffer<R, T>
        where T: Pod + pso::buffer::Structure<format::Format>
    {
        //debug_assert!(nv <= self.get_capabilities().max_vertex_count);
        self.create_buffer_immutable(vertices, buffer::Role::Vertex, Bind::empty())
            .unwrap()
    }

    /// Creates an immutable vertex buffer from the supplied vertices,
    /// together with a `Slice` from the supplied indices.
    fn create_vertex_buffer_with_slice<B, V>(&mut self, vertices: &[V], indices: B)
                                             -> (handle::Buffer<R, V>, Slice<R>)
        where V: Pod + pso::buffer::Structure<format::Format>,
              B: IntoIndexBuffer<R>
    {
        let vertex_buffer = self.create_vertex_buffer(vertices);
        let index_buffer = indices.into_index_buffer(self);
        let buffer_length = match index_buffer {
            IndexBuffer::Auto => vertex_buffer.len(),
            IndexBuffer::Index16(ref ib) => ib.len(),
            IndexBuffer::Index32(ref ib) => ib.len(),
        };

        (vertex_buffer, Slice {
            start: 0,
            end: buffer_length as u32,
            base_vertex: 0,
            instances: None,
            buffer: index_buffer
        })
    }

    /// Creates a constant buffer for `num` identical elements of type `T`.
    fn create_constant_buffer<T>(&mut self, num: usize) -> handle::Buffer<R, T>
        where T: Copy
    {
        self.create_buffer(num,
                           buffer::Role::Constant,
                           memory::Usage::Dynamic,
                           Bind::empty()).unwrap()
    }

    /// Creates an upload buffer for `num` elements of type `T`.
    fn create_upload_buffer<T>(&mut self, num: usize)
                               -> Result<handle::Buffer<R, T>, buffer::CreationError>
    {
        self.create_buffer(num,
                           buffer::Role::Staging,
                           memory::Usage::Upload,
                           memory::TRANSFER_SRC)
    }

    /// Creates a download buffer for `num` elements of type `T`.
    fn create_download_buffer<T>(&mut self, num: usize)
                                 -> Result<handle::Buffer<R, T>, buffer::CreationError>
    {
        self.create_buffer(num,
                           buffer::Role::Staging,
                           memory::Usage::Download,
                           memory::TRANSFER_DST)
    }

    /// Creates a `ShaderSet` from the supplied vertex and pixel shader source code.
    fn create_shader_set(&mut self, vs_code: &[u8], ps_code: &[u8])
                         -> Result<ShaderSet<R>, ProgramError> {
        let vs = match self.create_shader_vertex(vs_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Vertex(e)),
        };
        let ps = match self.create_shader_pixel(ps_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Pixel(e)),
        };
        Ok(ShaderSet::Simple(vs, ps))
    }

    /// Mainly for testing
    fn create_shader_set_tessellation(&mut self, vs_code: &[u8], hs_code: &[u8], ds_code: &[u8], ps_code: &[u8])
                         -> Result<ShaderSet<R>, ProgramError> {
        let vs = match self.create_shader_vertex(vs_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Vertex(e)),
        };

        let hs = match self.create_shader_hull(hs_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Hull(e)),
        };

        let ds = match self.create_shader_domain(ds_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Domain(e)),
        };

        let ps = match self.create_shader_pixel(ps_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Pixel(e)),
        };
        Ok(ShaderSet::Tessellated(vs, hs, ds, ps))
    }

    /// Creates a basic shader `Program` from the supplied vertex and pixel shader source code.
    fn link_program(&mut self, vs_code: &[u8], ps_code: &[u8])
                    -> Result<handle::Program<R>, ProgramError> {

        let set = try!(self.create_shader_set(vs_code, ps_code));
        self.create_program(&set).map_err(|e| ProgramError::Link(e))
    }

    /// Similar to `create_pipeline_from_program(..)`, but takes a `ShaderSet` as opposed to a
    /// shader `Program`.
    fn create_pipeline_state<I: pso::PipelineInit>(&mut self, shaders: &ShaderSet<R>,
                             primitive: Primitive, rasterizer: state::Rasterizer, init: I)
                             -> Result<pso::PipelineState<R, I::Meta>, PipelineStateError<String>>
    {
        let program = try!(self.create_program(shaders).map_err(|e| ProgramError::Link(e)));
        self.create_pipeline_from_program(&program, primitive, rasterizer, init).map_err(|error| {
            use self::PipelineStateError::*;
            match error {
                Program(e) => Program(e),
                DescriptorInit(e) => DescriptorInit(e.into()),
                DeviceCreate(e) => DeviceCreate(e),
            }
        })
    }

    /// Creates a strongly typed `PipelineState` from its `Init` structure, a shader `Program`, a
    /// primitive type and a `Rasterizer`.
    fn create_pipeline_from_program<'a, I: pso::PipelineInit>(&mut self, program: &'a handle::Program<R>,
                                    primitive: Primitive, rasterizer: state::Rasterizer, init: I)
                                    -> Result<pso::PipelineState<R, I::Meta>, PipelineStateError<&'a str>>
    {
        let mut descriptor = Descriptor::new(primitive, rasterizer);
        let meta = try!(init.link_to(&mut descriptor, program.get_info()));
        let raw = try!(self.create_pipeline_state_raw(program, &descriptor));

        Ok(pso::PipelineState::new(raw, primitive, meta))
    }

    /// Creates a strongly typed `PipelineState` from its `Init` structure. Automatically creates a
    /// shader `Program` from a vertex and pixel shader source, as well as a `Rasterizer` capable
    /// of rendering triangle faces without culling.
    fn create_pipeline_simple<I: pso::PipelineInit>(&mut self, vs: &[u8], ps: &[u8], init: I)
                              -> Result<pso::PipelineState<R, I::Meta>, PipelineStateError<String>>
    {
        let set = try!(self.create_shader_set(vs, ps));
        self.create_pipeline_state(&set, Primitive::TriangleList, state::Rasterizer::new_fill(),
                                   init)
    }

    /// Create a linear sampler with clamping to border.
    fn create_sampler_linear(&mut self) -> handle::Sampler<R> {
        self.create_sampler(texture::SamplerInfo::new(
            texture::FilterMethod::Trilinear,
            texture::WrapMode::Clamp,
        ))
    }
}

impl<R: Resources, F: Factory<R>> FactoryExt<R> for F {}
<commit_msg>Auto merge of #1193 - nical:create_ibo, r=kvark<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Factory extension.
//!
//! This module serves as an extension to the `factory` module in the `gfx` crate. This module
//! exposes extension functions and shortcuts to aid with creating and managing graphics resources.
//! See the `FactoryExt` trait for more information.

use std::error::Error;
use std::fmt;
use core::{buffer, format, handle, texture, state};
use core::{Primitive, Resources, ShaderSet};
use core::factory::Factory;
use core::pso::{CreationError, Descriptor};
use core::memory::{self, Bind, Pod};
use slice::{Slice, IndexBuffer, IntoIndexBuffer};
use pso;
use shade::ProgramError;

/// Error creating a PipelineState
#[derive(Clone, PartialEq, Debug)]
pub enum PipelineStateError<S> {
    /// Shader program failed to link.
    Program(ProgramError),
    /// Unable to create PSO descriptor due to mismatched formats.
    DescriptorInit(pso::InitError<S>),
    /// Device failed to create the handle give the descriptor.
    DeviceCreate(CreationError),
}

impl<'a> From<PipelineStateError<&'a str>> for PipelineStateError<String> {
    fn from(pse: PipelineStateError<&'a str>) -> PipelineStateError<String> {
        match pse {
            PipelineStateError::Program(e) => PipelineStateError::Program(e),
            PipelineStateError::DescriptorInit(e) => PipelineStateError::DescriptorInit(e.into()),
            PipelineStateError::DeviceCreate(e) => PipelineStateError::DeviceCreate(e),
        }
    }
}

impl<S: fmt::Debug + fmt::Display> fmt::Display for PipelineStateError<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            PipelineStateError::Program(ref e) => write!(f, "{}: {}", self.description(), e),
            PipelineStateError::DescriptorInit(ref e) => write!(f, "{}: {}", self.description(), e),
            PipelineStateError::DeviceCreate(ref e) => write!(f, "{}: {}", self.description(), e),
        }
    }
}

impl<S: fmt::Debug + fmt::Display> Error for PipelineStateError<S> {
    fn description(&self) -> &str {
        match *self {
            PipelineStateError::Program(_) => "Shader program failed to link",
            PipelineStateError::DescriptorInit(_) =>
                "Unable to create PSO descriptor due to mismatched formats",
            PipelineStateError::DeviceCreate(_) => "Device failed to create the handle give the descriptor",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            PipelineStateError::Program(ref program_error) => Some(program_error),
            PipelineStateError::DescriptorInit(ref init_error) => Some(init_error),
            PipelineStateError::DeviceCreate(ref creation_error) => Some(creation_error),
        }
    }
}

impl<S> From<ProgramError> for PipelineStateError<S> {
    fn from(e: ProgramError) -> Self {
        PipelineStateError::Program(e)
    }
}

impl<S> From<pso::InitError<S>> for PipelineStateError<S> {
    fn from(e: pso::InitError<S>) -> Self {
        PipelineStateError::DescriptorInit(e)
    }
}

impl<S> From<CreationError> for PipelineStateError<S> {
    fn from(e: CreationError) -> Self {
        PipelineStateError::DeviceCreate(e)
    }
}

/// This trait is responsible for creating and managing graphics resources, much like the `Factory`
/// trait in the `gfx` crate. Every `Factory` automatically implements `FactoryExt`.
pub trait FactoryExt<R: Resources>: Factory<R> {
    /// Creates an immutable vertex buffer from the supplied vertices.
    /// A `Slice` will have to manually be constructed.
    fn create_vertex_buffer<T>(&mut self, vertices: &[T])
                               -> handle::Buffer<R, T>
        where T: Pod + pso::buffer::Structure<format::Format>
    {
        //debug_assert!(nv <= self.get_capabilities().max_vertex_count);
        self.create_buffer_immutable(vertices, buffer::Role::Vertex, Bind::empty())
            .unwrap()
    }

    /// Creates an immutable index buffer from the supplied vertices.
    ///
    /// The paramater `indices` is typically a &[u16] or &[u32] slice.
    fn create_index_buffer<T>(&mut self, indices: T)
                              -> IndexBuffer<R>
        where T: IntoIndexBuffer<R>
    {
        indices.into_index_buffer(self)
    }

    /// Creates an immutable vertex buffer from the supplied vertices,
    /// together with a `Slice` from the supplied indices.
    fn create_vertex_buffer_with_slice<B, V>(&mut self, vertices: &[V], indices: B)
                                             -> (handle::Buffer<R, V>, Slice<R>)
        where V: Pod + pso::buffer::Structure<format::Format>,
              B: IntoIndexBuffer<R>
    {
        let vertex_buffer = self.create_vertex_buffer(vertices);
        let index_buffer = self.create_index_buffer(indices);
        let buffer_length = match index_buffer {
            IndexBuffer::Auto => vertex_buffer.len(),
            IndexBuffer::Index16(ref ib) => ib.len(),
            IndexBuffer::Index32(ref ib) => ib.len(),
        };

        (vertex_buffer, Slice {
            start: 0,
            end: buffer_length as u32,
            base_vertex: 0,
            instances: None,
            buffer: index_buffer
        })
    }

    /// Creates a constant buffer for `num` identical elements of type `T`.
    fn create_constant_buffer<T>(&mut self, num: usize) -> handle::Buffer<R, T>
        where T: Copy
    {
        self.create_buffer(num,
                           buffer::Role::Constant,
                           memory::Usage::Dynamic,
                           Bind::empty()).unwrap()
    }

    /// Creates an upload buffer for `num` elements of type `T`.
    fn create_upload_buffer<T>(&mut self, num: usize)
                               -> Result<handle::Buffer<R, T>, buffer::CreationError>
    {
        self.create_buffer(num,
                           buffer::Role::Staging,
                           memory::Usage::Upload,
                           memory::TRANSFER_SRC)
    }

    /// Creates a download buffer for `num` elements of type `T`.
    fn create_download_buffer<T>(&mut self, num: usize)
                                 -> Result<handle::Buffer<R, T>, buffer::CreationError>
    {
        self.create_buffer(num,
                           buffer::Role::Staging,
                           memory::Usage::Download,
                           memory::TRANSFER_DST)
    }

    /// Creates a `ShaderSet` from the supplied vertex and pixel shader source code.
    fn create_shader_set(&mut self, vs_code: &[u8], ps_code: &[u8])
                         -> Result<ShaderSet<R>, ProgramError> {
        let vs = match self.create_shader_vertex(vs_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Vertex(e)),
        };
        let ps = match self.create_shader_pixel(ps_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Pixel(e)),
        };
        Ok(ShaderSet::Simple(vs, ps))
    }

    /// Mainly for testing
    fn create_shader_set_tessellation(&mut self, vs_code: &[u8], hs_code: &[u8], ds_code: &[u8], ps_code: &[u8])
                         -> Result<ShaderSet<R>, ProgramError> {
        let vs = match self.create_shader_vertex(vs_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Vertex(e)),
        };

        let hs = match self.create_shader_hull(hs_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Hull(e)),
        };

        let ds = match self.create_shader_domain(ds_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Domain(e)),
        };

        let ps = match self.create_shader_pixel(ps_code) {
            Ok(s) => s,
            Err(e) => return Err(ProgramError::Pixel(e)),
        };
        Ok(ShaderSet::Tessellated(vs, hs, ds, ps))
    }

    /// Creates a basic shader `Program` from the supplied vertex and pixel shader source code.
    fn link_program(&mut self, vs_code: &[u8], ps_code: &[u8])
                    -> Result<handle::Program<R>, ProgramError> {

        let set = try!(self.create_shader_set(vs_code, ps_code));
        self.create_program(&set).map_err(|e| ProgramError::Link(e))
    }

    /// Similar to `create_pipeline_from_program(..)`, but takes a `ShaderSet` as opposed to a
    /// shader `Program`.
    fn create_pipeline_state<I: pso::PipelineInit>(&mut self, shaders: &ShaderSet<R>,
                             primitive: Primitive, rasterizer: state::Rasterizer, init: I)
                             -> Result<pso::PipelineState<R, I::Meta>, PipelineStateError<String>>
    {
        let program = try!(self.create_program(shaders).map_err(|e| ProgramError::Link(e)));
        self.create_pipeline_from_program(&program, primitive, rasterizer, init).map_err(|error| {
            use self::PipelineStateError::*;
            match error {
                Program(e) => Program(e),
                DescriptorInit(e) => DescriptorInit(e.into()),
                DeviceCreate(e) => DeviceCreate(e),
            }
        })
    }

    /// Creates a strongly typed `PipelineState` from its `Init` structure, a shader `Program`, a
    /// primitive type and a `Rasterizer`.
    fn create_pipeline_from_program<'a, I: pso::PipelineInit>(&mut self, program: &'a handle::Program<R>,
                                    primitive: Primitive, rasterizer: state::Rasterizer, init: I)
                                    -> Result<pso::PipelineState<R, I::Meta>, PipelineStateError<&'a str>>
    {
        let mut descriptor = Descriptor::new(primitive, rasterizer);
        let meta = try!(init.link_to(&mut descriptor, program.get_info()));
        let raw = try!(self.create_pipeline_state_raw(program, &descriptor));

        Ok(pso::PipelineState::new(raw, primitive, meta))
    }

    /// Creates a strongly typed `PipelineState` from its `Init` structure. Automatically creates a
    /// shader `Program` from a vertex and pixel shader source, as well as a `Rasterizer` capable
    /// of rendering triangle faces without culling.
    fn create_pipeline_simple<I: pso::PipelineInit>(&mut self, vs: &[u8], ps: &[u8], init: I)
                              -> Result<pso::PipelineState<R, I::Meta>, PipelineStateError<String>>
    {
        let set = try!(self.create_shader_set(vs, ps));
        self.create_pipeline_state(&set, Primitive::TriangleList, state::Rasterizer::new_fill(),
                                   init)
    }

    /// Create a linear sampler with clamping to border.
    fn create_sampler_linear(&mut self) -> handle::Sampler<R> {
        self.create_sampler(texture::SamplerInfo::new(
            texture::FilterMethod::Trilinear,
            texture::WrapMode::Clamp,
        ))
    }
}

impl<R: Resources, F: Factory<R>> FactoryExt<R> for F {}
<|endoftext|>


<commit_before><commit_msg>Put examples in a mod<commit_after><|endoftext|>


<commit_before><commit_msg>Removed testing binary.<commit_after><|endoftext|>


<commit_before><commit_msg>Trim console output<commit_after><|endoftext|>


<commit_before>//! Matrix event identifiers.

use std::{
    convert::TryFrom,
    fmt::{Display, Formatter, Result as FmtResult},
};

#[cfg(feature = "diesel")]
use diesel::sql_types::Text;
use serde::{
    de::{Error as SerdeError, Unexpected, Visitor},
    Deserialize, Deserializer, Serialize, Serializer,
};
use url::Host;

use crate::{display, error::Error, generate_localpart, parse_id};

/// A Matrix event ID.
///
/// An `EventId` is generated randomly or converted from a string slice, and can be converted back
/// into a string as needed.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::EventId;
/// assert_eq!(
///     EventId::try_from("$h29iv0s8:example.com").unwrap().to_string(),
///     "$h29iv0s8:example.com"
/// );
/// ```
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "diesel", derive(FromSqlRow, QueryId, AsExpression, SqlType))]
#[cfg_attr(feature = "diesel", sql_type = "Text")]
pub struct EventId {
    /// The hostname of the homeserver.
    hostname: Host,
    /// The event's unique ID.
    opaque_id: String,
    /// The network port of the homeserver.
    port: u16,
}

/// A serde visitor for `EventId`.
struct EventIdVisitor;

impl EventId {
    /// Attempts to generate an `EventId` for the given origin server with a localpart consisting
    /// of 18 random ASCII characters.
    ///
    /// Fails if the given origin server name cannot be parsed as a valid host.
    pub fn new(server_name: &str) -> Result<Self, Error> {
        let event_id = format!("${}:{}", generate_localpart(18), server_name);
        let (opaque_id, host, port) = parse_id('$', &event_id)?;

        Ok(Self {
            hostname: host,
            opaque_id: opaque_id.to_string(),
            port,
        })
    }

    /// Returns a `Host` for the event ID, containing the server name (minus the port) of the
    /// originating homeserver.
    ///
    /// The host can be either a domain name, an IPv4 address, or an IPv6 address.
    pub fn hostname(&self) -> &Host {
        &self.hostname
    }

    /// Returns the event's opaque ID.
    pub fn opaque_id(&self) -> &str {
        &self.opaque_id
    }

    /// Returns the port the originating homeserver can be accessed on.
    pub fn port(&self) -> u16 {
        self.port
    }
}

impl Display for EventId {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        display(f, '$', &self.opaque_id, &self.hostname, self.port)
    }
}

impl Serialize for EventId {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl<'de> Deserialize<'de> for EventId {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(EventIdVisitor)
    }
}

impl<'a> TryFrom<&'a str> for EventId {
    type Error = Error;

    /// Attempts to create a new Matrix event ID from a string representation.
    ///
    /// The string must include the leading $ sigil, the opaque ID, a literal colon, and a valid
    /// server name.
    fn try_from(event_id: &'a str) -> Result<Self, Self::Error> {
        let (opaque_id, host, port) = parse_id('$', event_id)?;

        Ok(Self {
            hostname: host,
            opaque_id: opaque_id.to_owned(),
            port,
        })
    }
}

impl<'de> Visitor<'de> for EventIdVisitor {
    type Value = EventId;

    fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult {
        write!(formatter, "a Matrix event ID as a string")
    }

    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
    where
        E: SerdeError,
    {
        match EventId::try_from(v) {
            Ok(event_id) => Ok(event_id),
            Err(_) => Err(SerdeError::invalid_value(Unexpected::Str(v), &self)),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use serde_json::{from_str, to_string};

    use super::EventId;
    use crate::error::Error;

    #[test]
    fn valid_event_id() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne:example.com")
                .expect("Failed to create EventId.")
                .to_string(),
            "$39hvsi03hlne:example.com"
        );
    }

    #[test]
    fn generate_random_valid_event_id() {
        let event_id = EventId::new("example.com")
            .expect("Failed to generate EventId.")
            .to_string();

        assert!(event_id.to_string().starts_with('$'));
        assert_eq!(event_id.len(), 31);
    }

    #[test]
    fn generate_random_invalid_event_id() {
        assert!(EventId::new("").is_err());
    }

    #[test]
    fn serialize_valid_event_id() {
        assert_eq!(
            to_string(
                &EventId::try_from("$39hvsi03hlne:example.com").expect("Failed to create EventId.")
            )
            .expect("Failed to convert EventId to JSON."),
            r#""$39hvsi03hlne:example.com""#
        );
    }

    #[test]
    fn deserialize_valid_event_id() {
        assert_eq!(
            from_str::<EventId>(r#""$39hvsi03hlne:example.com""#)
                .expect("Failed to convert JSON to EventId"),
            EventId::try_from("$39hvsi03hlne:example.com").expect("Failed to create EventId.")
        );
    }

    #[test]
    fn valid_event_id_with_explicit_standard_port() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne:example.com:443")
                .expect("Failed to create EventId.")
                .to_string(),
            "$39hvsi03hlne:example.com"
        );
    }

    #[test]
    fn valid_event_id_with_non_standard_port() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne:example.com:5000")
                .expect("Failed to create EventId.")
                .to_string(),
            "$39hvsi03hlne:example.com:5000"
        );
    }

    #[test]
    fn missing_event_id_sigil() {
        assert_eq!(
            EventId::try_from("39hvsi03hlne:example.com").err().unwrap(),
            Error::MissingSigil
        );
    }

    #[test]
    fn missing_event_id_delimiter() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne").err().unwrap(),
            Error::MissingDelimiter
        );
    }

    #[test]
    fn invalid_event_id_host() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne:-").err().unwrap(),
            Error::InvalidHost
        );
    }

    #[test]
    fn invalid_event_id_port() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne:example.com:notaport")
                .err()
                .unwrap(),
            Error::InvalidHost
        );
    }
}
<commit_msg>Support event ID formats for all room versions.<commit_after>//! Matrix event identifiers.

use std::{
    convert::TryFrom,
    fmt::{Display, Formatter, Result as FmtResult},
};

#[cfg(feature = "diesel")]
use diesel::sql_types::Text;
use serde::{
    de::{Error as SerdeError, Unexpected, Visitor},
    Deserialize, Deserializer, Serialize, Serializer,
};
use url::Host;

use crate::{display, error::Error, generate_localpart, parse_id};

/// A Matrix event ID.
///
/// An `EventId` is generated randomly or converted from a string slice, and can be converted back
/// into a string as needed.
///
/// # Room versions
///
/// Matrix specifies multiple [room versions](https://matrix.org/docs/spec/#room-versions) and the
/// format of event identifiers differ between them. The original format used by room versions 1
/// and 2 uses a short pseudorandom "localpart" followed by the hostname and port of the
/// originating homeserver. Later room versions change event identifiers to be a hash of the event
/// encoded with Base64. Some of the methods provided by `EventId` are only relevant to the
/// original event format.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::EventId;
/// // Original format
/// assert_eq!(
///     EventId::try_from("$h29iv0s8:example.com").unwrap().to_string(),
///     "$h29iv0s8:example.com"
/// );
/// // Room version 3 format
/// assert_eq!(
///     EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk").unwrap().to_string(),
///     "$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk"
/// );
/// // Room version 4 format
/// assert_eq!(
///     EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg").unwrap().to_string(),
///     "$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg"
/// );
/// ```
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "diesel", derive(FromSqlRow, QueryId, AsExpression, SqlType))]
#[cfg_attr(feature = "diesel", sql_type = "Text")]
pub struct EventId(Format);

/// Different event ID formats from the different Matrix room versions.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
enum Format {
    /// The original format as used by Matrix room versions 1 and 2.
    Original(Original),
    /// The format used by Matrix room version 3.
    Base64(String),
    /// The format used by Matrix room version 4.
    UrlSafeBase64(String),
}

/// An event in the original format as used by Matrix room versions 1 and 2.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
struct Original {
    /// The hostname of the homeserver.
    pub hostname: Host,
    /// The event's unique ID.
    pub localpart: String,
    /// The network port of the homeserver.
    pub port: u16,
}

/// A serde visitor for `EventId`.
struct EventIdVisitor;

impl EventId {
    /// Attempts to generate an `EventId` for the given origin server with a localpart consisting
    /// of 18 random ASCII characters. This should only be used for events in the original format
    /// as used by Matrix room versions 1 and 2.
    ///
    /// Fails if the given origin server name cannot be parsed as a valid host.
    pub fn new(server_name: &str) -> Result<Self, Error> {
        let event_id = format!("${}:{}", generate_localpart(18), server_name);
        let (localpart, host, port) = parse_id('$', &event_id)?;

        Ok(Self(Format::Original(Original {
            hostname: host,
            localpart: localpart.to_string(),
            port,
        })))
    }

    /// Returns a `Host` for the event ID, containing the server name (minus the port) of the
    /// originating homeserver. Only applicable to events in the original format as used by Matrix
    /// room versions 1 and 2.
    ///
    /// The host can be either a domain name, an IPv4 address, or an IPv6 address.
    pub fn hostname(&self) -> Option<&Host> {
        if let Format::Original(original) = &self.0 {
            Some(&original.hostname)
        } else {
            None
        }
    }

    /// Returns the event's unique ID. For the original event format as used by Matrix room
    /// versions 1 and 2, this is the "localpart" that precedes the homeserver. For later formats,
    /// this is the entire ID without the leading $ sigil.
    pub fn localpart(&self) -> &str {
        match &self.0 {
            Format::Original(original) => &original.localpart,
            Format::Base64(id) | Format::UrlSafeBase64(id) => id,
        }
    }

    /// Returns the port the originating homeserver can be accessed on. Only applicable to events
    /// in the original format as used by Matrix room versions 1 and 2.
    pub fn port(&self) -> Option<u16> {
        if let Format::Original(original) = &self.0 {
            Some(original.port)
        } else {
            None
        }
    }
}

impl Display for EventId {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        match &self.0 {
            Format::Original(original) => display(
                f,
                '$',
                &original.localpart,
                &original.hostname,
                original.port,
            ),
            Format::Base64(id) | Format::UrlSafeBase64(id) => write!(f, "${}", id),
        }
    }
}

impl Serialize for EventId {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl<'de> Deserialize<'de> for EventId {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(EventIdVisitor)
    }
}

impl<'a> TryFrom<&'a str> for EventId {
    type Error = Error;

    /// Attempts to create a new Matrix event ID from a string representation.
    ///
    /// If using the original event format as used by Matrix room versions 1 and 2, the string must
    /// include the leading $ sigil, the localpart, a literal colon, and a valid homeserver
    /// hostname.
    fn try_from(event_id: &'a str) -> Result<Self, Self::Error> {
        if event_id.contains(':') {
            let (localpart, host, port) = parse_id('$', event_id)?;

            Ok(Self(Format::Original(Original {
                hostname: host,
                localpart: localpart.to_owned(),
                port,
            })))
        } else if !event_id.starts_with('$') {
            Err(Error::MissingSigil)
        } else if event_id.contains(|chr| chr == '+' || chr == '/') {
            Ok(Self(Format::Base64(event_id[1..].to_string())))
        } else {
            Ok(Self(Format::UrlSafeBase64(event_id[1..].to_string())))
        }
    }
}

impl<'de> Visitor<'de> for EventIdVisitor {
    type Value = EventId;

    fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult {
        write!(formatter, "a Matrix event ID as a string")
    }

    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
    where
        E: SerdeError,
    {
        match EventId::try_from(v) {
            Ok(event_id) => Ok(event_id),
            Err(_) => Err(SerdeError::invalid_value(Unexpected::Str(v), &self)),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use serde_json::{from_str, to_string};

    use super::EventId;
    use crate::error::Error;

    #[test]
    fn valid_original_event_id() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne:example.com")
                .expect("Failed to create EventId.")
                .to_string(),
            "$39hvsi03hlne:example.com"
        );
    }

    #[test]
    fn valid_base64_event_id() {
        assert_eq!(
            EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
                .expect("Failed to create EventId.")
                .to_string(),
            "$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk"
        )
    }

    #[test]
    fn valid_url_safe_base64_event_id() {
        assert_eq!(
            EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
                .expect("Failed to create EventId.")
                .to_string(),
            "$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg"
        )
    }

    #[test]
    fn generate_random_valid_event_id() {
        let event_id = EventId::new("example.com")
            .expect("Failed to generate EventId.")
            .to_string();

        assert!(event_id.to_string().starts_with('$'));
        assert_eq!(event_id.len(), 31);
    }

    #[test]
    fn generate_random_invalid_event_id() {
        assert!(EventId::new("").is_err());
    }

    #[test]
    fn serialize_valid_original_event_id() {
        assert_eq!(
            to_string(
                &EventId::try_from("$39hvsi03hlne:example.com").expect("Failed to create EventId.")
            )
            .expect("Failed to convert EventId to JSON."),
            r#""$39hvsi03hlne:example.com""#
        );
    }

    #[test]
    fn serialize_valid_base64_event_id() {
        assert_eq!(
            to_string(
                &EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
                    .expect("Failed to create EventId.")
            )
            .expect("Failed to convert EventId to JSON."),
            r#""$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk""#
        );
    }

    #[test]
    fn serialize_valid_url_safe_base64_event_id() {
        assert_eq!(
            to_string(
                &EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
                    .expect("Failed to create EventId.")
            )
            .expect("Failed to convert EventId to JSON."),
            r#""$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg""#
        );
    }

    #[test]
    fn deserialize_valid_original_event_id() {
        assert_eq!(
            from_str::<EventId>(r#""$39hvsi03hlne:example.com""#)
                .expect("Failed to convert JSON to EventId"),
            EventId::try_from("$39hvsi03hlne:example.com").expect("Failed to create EventId.")
        );
    }

    #[test]
    fn deserialize_valid_base64_event_id() {
        assert_eq!(
            from_str::<EventId>(r#""$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk""#)
                .expect("Failed to convert JSON to EventId"),
            EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
                .expect("Failed to create EventId.")
        );
    }

    #[test]
    fn deserialize_valid_url_safe_base64_event_id() {
        assert_eq!(
            from_str::<EventId>(r#""$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg""#)
                .expect("Failed to convert JSON to EventId"),
            EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
                .expect("Failed to create EventId.")
        );
    }

    #[test]
    fn valid_original_event_id_with_explicit_standard_port() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne:example.com:443")
                .expect("Failed to create EventId.")
                .to_string(),
            "$39hvsi03hlne:example.com"
        );
    }

    #[test]
    fn valid_original_event_id_with_non_standard_port() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne:example.com:5000")
                .expect("Failed to create EventId.")
                .to_string(),
            "$39hvsi03hlne:example.com:5000"
        );
    }

    #[test]
    fn missing_original_event_id_sigil() {
        assert_eq!(
            EventId::try_from("39hvsi03hlne:example.com").err().unwrap(),
            Error::MissingSigil
        );
    }

    #[test]
    fn missing_base64_event_id_sigil() {
        assert_eq!(
            EventId::try_from("acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
                .err()
                .unwrap(),
            Error::MissingSigil
        );
    }

    #[test]
    fn missing_url_safe_base64_event_id_sigil() {
        assert_eq!(
            EventId::try_from("Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
                .err()
                .unwrap(),
            Error::MissingSigil
        );
    }

    #[test]
    fn invalid_event_id_host() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne:-").err().unwrap(),
            Error::InvalidHost
        );
    }

    #[test]
    fn invalid_event_id_port() {
        assert_eq!(
            EventId::try_from("$39hvsi03hlne:example.com:notaport")
                .err()
                .unwrap(),
            Error::InvalidHost
        );
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove Chain<Chain<Chain<Chain ...<commit_after><|endoftext|>


<commit_before><commit_msg>SyncFile: minor cleanup in get_sync_id<commit_after><|endoftext|>


<commit_before>/*
Module: task

Task management.

An executing Rust program consists of a tree of tasks, each with their own
stack, and sole ownership of their allocated heap data. Tasks communicate
with each other using ports and channels.

When a task fails, that failure will propagate to its parent (the task
that spawned it) and the parent will fail as well. The reverse is not
true: when a parent task fails its children will continue executing. When
the root (main) task fails, all tasks fail, and then so does the entire
process.

A task may remove itself from this failure propagation mechanism by
calling the <unsupervise> function, after which failure will only
result in the termination of that task.

Tasks may execute in parallel and are scheduled automatically by the runtime.

Example:

> spawn("Hello, World", fn (&&msg: str) {
>   log msg;
> });

*/
import cast = unsafe::reinterpret_cast;
import comm;
import option::{some, none};
import option = option::t;
import ptr;

export task;
export joinable_task;
export sleep;
export yield;
export task_notification;
export join;
export unsupervise;
export pin;
export unpin;
export set_min_stack;
export task_result;
export tr_success;
export tr_failure;
export get_task;
export spawn;
export spawn_notify;
export spawn_joinable;

#[abi = "rust-intrinsic"]
native mod rusti {
    // these must run on the Rust stack so that they can swap stacks etc:
    fn task_sleep(time_in_us: uint);
}

#[link_name = "rustrt"]
#[abi = "cdecl"]
native mod rustrt {
    // these can run on the C stack:
    fn pin_task();
    fn unpin_task();
    fn get_task_id() -> task_id;

    fn set_min_stack(stack_size: uint);

    fn new_task() -> task_id;
    fn drop_task(task_id: *rust_task);
    fn get_task_pointer(id: task_id) -> *rust_task;

    fn migrate_alloc(alloc: *u8, target: task_id);

    fn start_task(id: task, closure: *u8);

}

/* Section: Types */

type rust_task =
    {id: task,
     mutable notify_enabled: u32,
     mutable notify_chan: comm::chan<task_notification>,
     mutable stack_ptr: *u8};

resource rust_task_ptr(task: *rust_task) { rustrt::drop_task(task); }

type task_id = int;

/*
Type: task

A handle to a task
*/
type task = task_id;

/*
Type: joinable_task

A task that sends notification upon termination
*/
type joinable_task = (task, comm::port<task_notification>);

/*
Tag: task_result

Indicates the manner in which a task exited
*/
tag task_result {
    /* Variant: tr_success */
    tr_success;
    /* Variant: tr_failure */
    tr_failure;
}

/*
Tag: task_notification

Message sent upon task exit to indicate normal or abnormal termination
*/
tag task_notification {
    /* Variant: exit */
    exit(task, task_result);
}

/* Section: Operations */

/*
Type: get_task

Retreives a handle to the currently executing task
*/
fn get_task() -> task { rustrt::get_task_id() }

/*
Function: sleep

Hints the scheduler to yield this task for a specified ammount of time.

Parameters:

time_in_us - maximum number of microseconds to yield control for
*/
fn sleep(time_in_us: uint) { ret rusti::task_sleep(time_in_us); }

/*
Function: yield

Yield control to the task scheduler

The scheduler may schedule another task to execute.
*/
fn yield() { sleep(1u) }

/*
Function: join

Wait for a child task to exit

The child task must have been spawned with <spawn_joinable>, which
produces a notification port that the child uses to communicate its
exit status.

Returns:

A task_result indicating whether the task terminated normally or failed
*/
fn join(task_port: joinable_task) -> task_result {
    let (id, port) = task_port;
    alt comm::recv::<task_notification>(port) {
      exit(_id, res) {
        if _id == id {
            ret res
        } else { fail #fmt["join received id %d, expected %d", _id, id] }
      }
    }
}

/*
Function: unsupervise

Detaches this task from its parent in the task tree

An unsupervised task will not propagate its failure up the task tree
*/
fn unsupervise() { ret sys::unsupervise(); }

/*
Function: pin

Pins the current task and future child tasks to a single scheduler thread
*/
fn pin() { rustrt::pin_task(); }

/*
Function: unpin

Unpin the current task and future child tasks
*/
fn unpin() { rustrt::unpin_task(); }

/*
Function: set_min_stack

Set the minimum stack size (in bytes) for tasks spawned in the future.

This function has global effect and should probably not be used.
*/
fn set_min_stack(stack_size: uint) { rustrt::set_min_stack(stack_size); }

/*
Function: spawn

Creates and executes a new child task

Sets up a new task with its own call stack and schedules it to be executed.
Upon execution the new task will call function `f` with the provided
argument `data`.

Function `f` is a bare function, meaning it may not close over any data, as do
shared functions (fn@) and lambda blocks. `data` must be a uniquely owned
type; it is moved into the new task and thus can no longer be accessed
locally.

Parameters:

data - A unique-type value to pass to the new task
f - A function to execute in the new task

Returns:

A handle to the new task
*/
fn spawn<uniq T>(-data: T, f: fn(T)) -> task {
    spawn_inner(data, f, none)
}

/*
Function: spawn_notify

Create and execute a new child task, requesting notification upon its
termination

Immediately before termination, either on success or failure, the spawned
task will send a <task_notification> message on the provided channel.
*/
fn spawn_notify<uniq T>(-data: T, f: fn(T),
                         notify: comm::chan<task_notification>) -> task {
    spawn_inner(data, f, some(notify))
}

/*
Function: spawn_joinable

Create and execute a task which can later be joined with the <join> function

This is a convenience wrapper around spawn_notify which, when paired
with <join> can be easily used to spawn a task then wait for it to
complete.
*/
fn spawn_joinable<uniq T>(-data: T, f: fn(T)) -> joinable_task {
    let p = comm::port::<task_notification>();
    let id = spawn_notify(data, f, comm::chan::<task_notification>(p));
    ret (id, p);
}

// FIXME: To transition from the unsafe spawn that spawns a shared closure to
// the safe spawn that spawns a bare function we're going to write
// barefunc-spawn on top of unsafe-spawn.  Sadly, bind does not work reliably
// enough to suite our needs (#1034, probably others yet to be discovered), so
// we're going to copy the bootstrap data into a unique pointer, cast it to an
// unsafe pointer then wrap up the bare function and the unsafe pointer in a
// shared closure to spawn.
//
// After the transition this should all be rewritten.

fn spawn_inner<uniq T>(-data: T, f: fn(T),
                          notify: option<comm::chan<task_notification>>)
    -> task unsafe {

    fn wrapper<uniq T>(-data: *u8, f: fn(T)) unsafe {
        let data: ~T = unsafe::reinterpret_cast(data);
        f(*data);
    }

    let data = ~data;
    let dataptr: *u8 = unsafe::reinterpret_cast(data);
    unsafe::leak(data);
    let wrapped = bind wrapper(dataptr, f);
    ret unsafe_spawn_inner(wrapped, notify);
}

// FIXME: This is the old spawn function that spawns a shared closure.
// It is a hack and needs to be rewritten.
fn unsafe_spawn_inner(-thunk: fn@(),
                      notify: option<comm::chan<task_notification>>) ->
   task unsafe {
    let id = rustrt::new_task();

    let raw_thunk: {code: u32, env: u32} = cast(thunk);

    // set up the task pointer
    let task_ptr <- rust_task_ptr(rustrt::get_task_pointer(id));

    assert (ptr::null() != (**task_ptr).stack_ptr);

    // copy the thunk from our stack to the new stack
    let sp: uint = cast((**task_ptr).stack_ptr);
    let ptrsize = sys::size_of::<*u8>();
    let thunkfn: *mutable uint = cast(sp - ptrsize * 2u);
    let thunkenv: *mutable uint = cast(sp - ptrsize);
    *thunkfn = cast(raw_thunk.code);;
    *thunkenv = cast(raw_thunk.env);;
    // align the stack to 16 bytes
    (**task_ptr).stack_ptr = cast(sp - ptrsize * 4u);

    // set up notifications if they are enabled.
    alt notify {
      some(c) {
        (**task_ptr).notify_enabled = 1u32;;
        (**task_ptr).notify_chan = c;
      }
      none { }
    }

    // give the thunk environment's allocation to the new task
    rustrt::migrate_alloc(cast(raw_thunk.env), id);
    rustrt::start_task(id, cast(thunkfn));
    // don't cleanup the thunk in this task
    unsafe::leak(thunk);
    ret id;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>change u32 to uint.  maybe we want an intptr_t built-in type.<commit_after>/*
Module: task

Task management.

An executing Rust program consists of a tree of tasks, each with their own
stack, and sole ownership of their allocated heap data. Tasks communicate
with each other using ports and channels.

When a task fails, that failure will propagate to its parent (the task
that spawned it) and the parent will fail as well. The reverse is not
true: when a parent task fails its children will continue executing. When
the root (main) task fails, all tasks fail, and then so does the entire
process.

A task may remove itself from this failure propagation mechanism by
calling the <unsupervise> function, after which failure will only
result in the termination of that task.

Tasks may execute in parallel and are scheduled automatically by the runtime.

Example:

> spawn("Hello, World", fn (&&msg: str) {
>   log msg;
> });

*/
import cast = unsafe::reinterpret_cast;
import comm;
import option::{some, none};
import option = option::t;
import ptr;

export task;
export joinable_task;
export sleep;
export yield;
export task_notification;
export join;
export unsupervise;
export pin;
export unpin;
export set_min_stack;
export task_result;
export tr_success;
export tr_failure;
export get_task;
export spawn;
export spawn_notify;
export spawn_joinable;

#[abi = "rust-intrinsic"]
native mod rusti {
    // these must run on the Rust stack so that they can swap stacks etc:
    fn task_sleep(time_in_us: uint);
}

#[link_name = "rustrt"]
#[abi = "cdecl"]
native mod rustrt {
    // these can run on the C stack:
    fn pin_task();
    fn unpin_task();
    fn get_task_id() -> task_id;

    fn set_min_stack(stack_size: uint);

    fn new_task() -> task_id;
    fn drop_task(task_id: *rust_task);
    fn get_task_pointer(id: task_id) -> *rust_task;

    fn migrate_alloc(alloc: *u8, target: task_id);

    fn start_task(id: task, closure: *u8);

}

/* Section: Types */

type rust_task =
    {id: task,
     mutable notify_enabled: u32,
     mutable notify_chan: comm::chan<task_notification>,
     mutable stack_ptr: *u8};

resource rust_task_ptr(task: *rust_task) { rustrt::drop_task(task); }

type task_id = int;

/*
Type: task

A handle to a task
*/
type task = task_id;

/*
Type: joinable_task

A task that sends notification upon termination
*/
type joinable_task = (task, comm::port<task_notification>);

/*
Tag: task_result

Indicates the manner in which a task exited
*/
tag task_result {
    /* Variant: tr_success */
    tr_success;
    /* Variant: tr_failure */
    tr_failure;
}

/*
Tag: task_notification

Message sent upon task exit to indicate normal or abnormal termination
*/
tag task_notification {
    /* Variant: exit */
    exit(task, task_result);
}

/* Section: Operations */

/*
Type: get_task

Retreives a handle to the currently executing task
*/
fn get_task() -> task { rustrt::get_task_id() }

/*
Function: sleep

Hints the scheduler to yield this task for a specified ammount of time.

Parameters:

time_in_us - maximum number of microseconds to yield control for
*/
fn sleep(time_in_us: uint) { ret rusti::task_sleep(time_in_us); }

/*
Function: yield

Yield control to the task scheduler

The scheduler may schedule another task to execute.
*/
fn yield() { sleep(1u) }

/*
Function: join

Wait for a child task to exit

The child task must have been spawned with <spawn_joinable>, which
produces a notification port that the child uses to communicate its
exit status.

Returns:

A task_result indicating whether the task terminated normally or failed
*/
fn join(task_port: joinable_task) -> task_result {
    let (id, port) = task_port;
    alt comm::recv::<task_notification>(port) {
      exit(_id, res) {
        if _id == id {
            ret res
        } else { fail #fmt["join received id %d, expected %d", _id, id] }
      }
    }
}

/*
Function: unsupervise

Detaches this task from its parent in the task tree

An unsupervised task will not propagate its failure up the task tree
*/
fn unsupervise() { ret sys::unsupervise(); }

/*
Function: pin

Pins the current task and future child tasks to a single scheduler thread
*/
fn pin() { rustrt::pin_task(); }

/*
Function: unpin

Unpin the current task and future child tasks
*/
fn unpin() { rustrt::unpin_task(); }

/*
Function: set_min_stack

Set the minimum stack size (in bytes) for tasks spawned in the future.

This function has global effect and should probably not be used.
*/
fn set_min_stack(stack_size: uint) { rustrt::set_min_stack(stack_size); }

/*
Function: spawn

Creates and executes a new child task

Sets up a new task with its own call stack and schedules it to be executed.
Upon execution the new task will call function `f` with the provided
argument `data`.

Function `f` is a bare function, meaning it may not close over any data, as do
shared functions (fn@) and lambda blocks. `data` must be a uniquely owned
type; it is moved into the new task and thus can no longer be accessed
locally.

Parameters:

data - A unique-type value to pass to the new task
f - A function to execute in the new task

Returns:

A handle to the new task
*/
fn spawn<uniq T>(-data: T, f: fn(T)) -> task {
    spawn_inner(data, f, none)
}

/*
Function: spawn_notify

Create and execute a new child task, requesting notification upon its
termination

Immediately before termination, either on success or failure, the spawned
task will send a <task_notification> message on the provided channel.
*/
fn spawn_notify<uniq T>(-data: T, f: fn(T),
                         notify: comm::chan<task_notification>) -> task {
    spawn_inner(data, f, some(notify))
}

/*
Function: spawn_joinable

Create and execute a task which can later be joined with the <join> function

This is a convenience wrapper around spawn_notify which, when paired
with <join> can be easily used to spawn a task then wait for it to
complete.
*/
fn spawn_joinable<uniq T>(-data: T, f: fn(T)) -> joinable_task {
    let p = comm::port::<task_notification>();
    let id = spawn_notify(data, f, comm::chan::<task_notification>(p));
    ret (id, p);
}

// FIXME: To transition from the unsafe spawn that spawns a shared closure to
// the safe spawn that spawns a bare function we're going to write
// barefunc-spawn on top of unsafe-spawn.  Sadly, bind does not work reliably
// enough to suite our needs (#1034, probably others yet to be discovered), so
// we're going to copy the bootstrap data into a unique pointer, cast it to an
// unsafe pointer then wrap up the bare function and the unsafe pointer in a
// shared closure to spawn.
//
// After the transition this should all be rewritten.

fn spawn_inner<uniq T>(-data: T, f: fn(T),
                          notify: option<comm::chan<task_notification>>)
    -> task unsafe {

    fn wrapper<uniq T>(-data: *u8, f: fn(T)) unsafe {
        let data: ~T = unsafe::reinterpret_cast(data);
        f(*data);
    }

    let data = ~data;
    let dataptr: *u8 = unsafe::reinterpret_cast(data);
    unsafe::leak(data);
    let wrapped = bind wrapper(dataptr, f);
    ret unsafe_spawn_inner(wrapped, notify);
}

// FIXME: This is the old spawn function that spawns a shared closure.
// It is a hack and needs to be rewritten.
fn unsafe_spawn_inner(-thunk: fn@(),
                      notify: option<comm::chan<task_notification>>) ->
   task unsafe {
    let id = rustrt::new_task();

    let raw_thunk: {code: uint, env: uint} = cast(thunk);

    // set up the task pointer
    let task_ptr <- rust_task_ptr(rustrt::get_task_pointer(id));

    assert (ptr::null() != (**task_ptr).stack_ptr);

    // copy the thunk from our stack to the new stack
    let sp: uint = cast((**task_ptr).stack_ptr);
    let ptrsize = sys::size_of::<*u8>();
    let thunkfn: *mutable uint = cast(sp - ptrsize * 2u);
    let thunkenv: *mutable uint = cast(sp - ptrsize);
    *thunkfn = cast(raw_thunk.code);;
    *thunkenv = cast(raw_thunk.env);;
    // align the stack to 16 bytes
    (**task_ptr).stack_ptr = cast(sp - ptrsize * 4u);

    // set up notifications if they are enabled.
    alt notify {
      some(c) {
        (**task_ptr).notify_enabled = 1u32;;
        (**task_ptr).notify_chan = c;
      }
      none { }
    }

    // give the thunk environment's allocation to the new task
    rustrt::migrate_alloc(cast(raw_thunk.env), id);
    rustrt::start_task(id, cast(thunkfn));
    // don't cleanup the thunk in this task
    unsafe::leak(thunk);
    ret id;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>[Rust] impl trait in the same expression can mean the other type<commit_after>trait T {
}

struct S0 {
}
struct S1 {
}
struct S2 {
}

impl T for S0 {
}
impl T for S1 {
}
impl T for S2 {
}

fn a(_: impl T) -> impl T {
    S0{}
}

fn main() {
    a(S0{});
    a(S1{});
    a(S2{});
}
<|endoftext|>


<commit_before><commit_msg>new API darft<commit_after>
mod api {

    pub type Target = u32;

    pub enum FeatureType {
        Boolean,
        Category,
        Number
    }

    pub trait RecordMeta {

        fn some_record_meta(&self) -> bool;

    }

    pub struct DataSetMeta {
        pub target_count: usize,
        pub features: Vec<(usize, FeatureType)>
    }

    pub struct DataSet<T: RecordMeta> {
        records: Vec<(T, Target)>,
        meta: DataSetMeta,
    }

    pub struct DataSetIterator<'a, T: 'a> {
        records: &'a Vec<(T, Target)>,
        current: usize,
        max: usize
    }

    impl<T: RecordMeta> DataSet<T> {

        pub fn new(meta: DataSetMeta, records: Vec<(T, Target)>) -> DataSet<T> {
            // here we should check that all records has the same meta
            DataSet{records: records, meta: meta}
        }

        pub fn is_empty(&self) -> bool {
            self.records.is_empty()
        }

        pub fn target_count(&self) -> usize {
            self.meta.target_count
        }

        pub fn records(&self) -> DataSetIterator<T> {
            DataSetIterator{records: &self.records, current: 0, max: self.records.len()}
        }

    }

    impl<'a, T: RecordMeta> Iterator for DataSetIterator<'a, T> {

        type Item = &'a (T, Target);

        fn next(&mut self) -> Option<&'a (T, Target)> {
            if self.current < self.max {
                let result = Some(&self.records[self.current]);
                self.current = self.current + 1;
                return result
            } else {
                return None
            }
        }

    }

}

mod data {

    use ::api;

    #[derive(Debug)]
    pub struct Record {
        pub zopa: u32
    }

    impl api::RecordMeta for Record {

        fn some_record_meta(&self) -> bool {
            true
        }

    }

    pub fn get_data() -> api::DataSet<Record> {
        api::DataSet::new(
            api::DataSetMeta {
                target_count: 2,
                features: vec![
                    (0, api::FeatureType::Number),
                    (1, api::FeatureType::Boolean)
                ]
            },
            vec![
                (Record{zopa: 0}, 0),
                (Record{zopa: 1}, 1)
            ]
        )
    }

}

fn test<T: api::RecordMeta>(ds: &api::DataSet<T>) {
    println!("{}", ds.target_count());
    for record in ds.records() {
        println!("{}", record.0.some_record_meta());
    }
}

fn main() {
    use data;
    println!("Hello, API!");
    let ds = data::get_data();
    println!("is_empty = {}, target_count = {}", ds.is_empty(), ds.target_count());
    for record in ds.records() {
        println!("{:?}", record);
    }
    test(&ds);
}<|endoftext|>


<commit_before><commit_msg>Minor cleanup<commit_after><|endoftext|>


<commit_before><commit_msg>examples<commit_after><|endoftext|>


<commit_before><commit_msg>Add type of mio messages<commit_after><|endoftext|>


<commit_before><commit_msg>Fix negative number handling.<commit_after><|endoftext|>


<commit_before><commit_msg>Added test explicitly testing that this PR continues to handle empty arrays in same manner as before.<commit_after>// Pre-existing behavior has been to reject patterns with consts
// denoting non-empty arrays of non-`Eq` types, but *accept* empty
// arrays of such types.
//
// See rust-lang/rust#62336.

// run-pass

#[derive(PartialEq, Debug)]
struct B(i32);

fn main() {
    const FOO: [B; 0] = [];
    match [] {
        FOO => { }
    }
}
<|endoftext|>


<commit_before><commit_msg>Replace the Vulkan API call result checks with a macro to reduce repeated code<commit_after><|endoftext|>


<commit_before><commit_msg>Tidy up the comments around the array of C-style strings for layer and extension names<commit_after><|endoftext|>


<commit_before><commit_msg>Remove debug.<commit_after><|endoftext|>


<commit_before><commit_msg>clean feature should be ready for use :)<commit_after>#![allow(unused_mut)]
#![allow(unused_imports)]
#![allow(unused_variables)]

#[macro_use]
extern crate clap;

use clap::Shell;
use clap::App;

fn main() {

    // load configuration
    #[cfg(feature = "english")]
    let yaml = load_yaml!("src/cli/options-en.yml");
    #[cfg(feature = "francais")]
    let yaml = load_yaml!("src/cli/options-fr.yml");
    #[cfg(feature = "deutsch")]
    let yaml = load_yaml!("src/cli/options-de.yml");
    let mut app = App::from_yaml(yaml).version(crate_version!());

    // generate bash completions if desired
    #[cfg(feature = "bash")]
    app.gen_completions("sn", Shell::Bash, env!("BASH_COMPLETIONS_DIR"));

    // generate fish completions if desired
    let mut app_snd = App::from_yaml(yaml).version(crate_version!());
    #[cfg(feature = "fish")]
    app_snd.gen_completions("sn", Shell::Fish, env!("FISH_COMPLETIONS_DIR"));

}
<|endoftext|>


<commit_before><commit_msg>Added FileIndex to FileWatcher.<commit_after><|endoftext|>


<commit_before><commit_msg>Delete .#chip8.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Fix the build of Colossal<commit_after><|endoftext|>


<commit_before><commit_msg>Clarify the result of the 'panda' command<commit_after><|endoftext|>


<commit_before><commit_msg>2017 day 15 both parts<commit_after>extern crate structopt;
#[macro_use]
extern crate structopt_derive;

use structopt::StructOpt;

#[derive(Debug)]
struct Generator {
    current: usize,
    factor: usize,
}

impl Iterator for Generator {
    type Item = usize;
    fn next(&mut self) -> Option<Self::Item> {
        self.current = self.current * self.factor % 2_147_483_647;
        Some(self.current)
    }
}

fn part1(a: usize, b: usize) -> usize {
    let gen_a = Generator {
        current: a,
        factor: 16_807,
    };
    let gen_b = Generator {
        current: b,
        factor: 48_271,
    };
    gen_a
        .zip(gen_b)
        .take(40_000_000)
        .filter(|&(a, b)| a & 0xffff == b & 0xffff)
        .count()
}

fn part2(a: usize, b: usize) -> usize {
    let gen_a = Generator {
        current: a,
        factor: 16_807,
    };
    let gen_b = Generator {
        current: b,
        factor: 48_271,
    };
    gen_a
        .filter(|x| x % 4 == 0)
        .zip(gen_b.filter(|x| x % 8 == 0))
        .take(5_000_000)
        .filter(|&(a, b)| a & 0xffff == b & 0xffff)
        .count()
}

fn main() {
    let opt = Opt::from_args();
    let a = opt.a
        .parse::<usize>()
        .expect(&format!("Could not parse {} as usize", opt.a));
    let b = opt.b
        .parse::<usize>()
        .expect(&format!("Could not parse {} as usize", opt.b));
    println!("Part 1: {}", part1(a, b));
    println!("Part 2: {}", part2(a, b));
}

#[derive(StructOpt, Debug)]
#[structopt(name = "day13", about = "Advent of code 2017 day 13")]
struct Opt {
    #[structopt(help = "input for generator a")] a: String,
    #[structopt(help = "input for generator b")] b: String,
}

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

    #[test]
    fn generator_test() {
        let gen_a = Generator {
            current: 65,
            factor: 16_807,
        };
        let gen_b = Generator {
            current: 8921,
            factor: 48271,
        };
        let results: Vec<_> = gen_a.zip(gen_b).take(5).collect();
        assert_eq!(
            &results,
            &[
                (1_092_455, 430_625_591),
                (1_181_022_009, 1_233_683_848),
                (245_556_042, 1_431_495_498),
                (1_744_312_007, 137_874_439),
                (1_352_636_452, 285_222_916),
            ]
        );
    }

    #[test]
    fn part1_test() {
        assert_eq!(part1(65, 8921), 588);
    }

    #[test]
    fn part2_test() {
        assert_eq!(part2(65, 8921), 309);
    }
}
<|endoftext|>


<commit_before><commit_msg>Use closure instead of always constructing object<commit_after><|endoftext|>


<commit_before><commit_msg>Tidy up ModMult trait implementations with macro.<commit_after><|endoftext|>


<commit_before><commit_msg>Implement NetworkTransmittable for Vec<T> and NetworkReceivable for Vec<u8><commit_after><|endoftext|>


<commit_before><commit_msg>FromIterator impl for ByteString<commit_after><|endoftext|>


<commit_before><commit_msg>Remove duplication of dummy packet and PacketSet test declaration.<commit_after><|endoftext|>


<commit_before>#![deny(unused_must_use)]
#![feature(futures_api, pin, arbitrary_self_types)]

use std::iter::Iterator;
use std::future::Future;

use std::task::{Poll, LocalWaker};
use std::pin::Pin;
use std::unimplemented;

struct MyFuture;

impl Future for MyFuture {
   type Output = u32;

   fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<u32> {
      Poll::Pending
   }
}

fn iterator() -> impl Iterator {
   std::iter::empty::<u32>()
}

fn future() -> impl Future {
   MyFuture
}

fn square_fn_once() -> impl FnOnce(u32) -> u32 {
   |x| x * x
}

fn square_fn_mut() -> impl FnMut(u32) -> u32 {
   |x| x * x
}

fn square_fn() -> impl Fn(u32) -> u32 {
   |x| x * x
}

fn main() {
   iterator(); //~ ERROR unused implementer of `std::iter::Iterator` that must be used
   future(); //~ ERROR unused implementer of `std::future::Future` that must be used
   square_fn_once(); //~ ERROR unused implementer of `std::ops::FnOnce` that must be used
   square_fn_mut(); //~ ERROR unused implementer of `std::ops::FnMut` that must be used
   square_fn(); //~ ERROR unused implementer of `std::ops::Fn` that must be used
}<commit_msg>Add trailing newline<commit_after>#![deny(unused_must_use)]
#![feature(futures_api, pin, arbitrary_self_types)]

use std::iter::Iterator;
use std::future::Future;

use std::task::{Poll, LocalWaker};
use std::pin::Pin;
use std::unimplemented;

struct MyFuture;

impl Future for MyFuture {
   type Output = u32;

   fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<u32> {
      Poll::Pending
   }
}

fn iterator() -> impl Iterator {
   std::iter::empty::<u32>()
}

fn future() -> impl Future {
   MyFuture
}

fn square_fn_once() -> impl FnOnce(u32) -> u32 {
   |x| x * x
}

fn square_fn_mut() -> impl FnMut(u32) -> u32 {
   |x| x * x
}

fn square_fn() -> impl Fn(u32) -> u32 {
   |x| x * x
}

fn main() {
   iterator(); //~ ERROR unused implementer of `std::iter::Iterator` that must be used
   future(); //~ ERROR unused implementer of `std::future::Future` that must be used
   square_fn_once(); //~ ERROR unused implementer of `std::ops::FnOnce` that must be used
   square_fn_mut(); //~ ERROR unused implementer of `std::ops::FnMut` that must be used
   square_fn(); //~ ERROR unused implementer of `std::ops::Fn` that must be used
}
<|endoftext|>


<commit_before><commit_msg>Added some boilerplate for map<commit_after>//! This module defines the map to link the keys and values

extern crate time;

use mod key;
use mod value;

struct Map {
    created: time::Tm
}
<|endoftext|>


<commit_before><commit_msg>Rename *{Start,End} posititons to {Before,After}*<commit_after><|endoftext|>


<commit_before><commit_msg>adds postings and decimal type<commit_after>use amount::MixedAmount;

#[derive(Clone, PartialEq, Eq)]
enum ClearedStatus {
    Uncleared,
    Pending,
    Cleared
}

#[derive(Clone, PartialEq, Eq)]
enum PostingType {
    Regular,
    Virtual,
    BalancedVirtual
}

#[derive(Clone, PartialEq, Eq)]
struct Posting {
    status: ClearedStatus,
    amount: MixedAmount,
    posting_type: PostingType,
    balance_assertion: Option<MixedAmount>
}

impl Posting {
    pub fn is_real(&self) -> bool {
        self.posting_type == PostingType::Regular
    }

    pub fn is_virtual(&self) -> bool {
        self.posting_type == PostingType::Virtual
    }

    pub fn related_postings(&self) -> Vec<Posting> {
        vec!()
    }

    pub fn sum_postings(postings: Vec<Posting>) -> MixedAmount {
        postings.iter().map(|x| x.amount).sum()
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix timeline.events type in sync_events response<commit_after><|endoftext|>


<commit_before><commit_msg>ComponentStore trait can be downcasted<commit_after><|endoftext|>