<commit_before>#![feature(core, io, std_misc)]
use std::collections::HashMap;
use std::sync::mpsc::{Sender, Receiver, channel};
use std::thread::Thread;
use std::old_io::timer;
use std::time::Duration;

pub mod messages;
pub mod market;
pub mod actor;
pub mod teller;
pub mod corporate_actor;
pub mod smarter_actor;
pub mod scripted_actor;

use messages::*;
use market::*;
use actor::*;
use corporate_actor::*;
use smarter_actor::*;
use scripted_actor::*;

fn main() {
  //tx: clone for actors        rx: owned by market
  let (tx_market, rx_market): (Sender<MarketMessages>, Receiver<MarketMessages>) = channel();

  //TODO: with spawning multiple markets make this a for loop.
  let tx_market_clone = tx_market.clone();
  Thread::spawn(move || {
    market::start_market(0, tx_market_clone, rx_market);});

  let mut markets = HashMap::new();
  markets.insert(0, tx_market.clone());

  let mut actors_with_timers = vec![];

  let standard_actor_count = 5;
  let corporate_actor_count = 1;
  let scripted_actor_count = 2;
  let smarter_actor_count = 5;

  let mut current_id = 0;
  //TODO make more stocks and add history so actors can query on it.
  for _ in 0..standard_actor_count {
    let m = markets.clone();
    let (actor_tx, actor_rx): (Sender<ActorMessages>, Receiver<ActorMessages>) = channel();
    actors_with_timers.push(actor_tx.clone());
    Thread::spawn(move || {start_actor(current_id, m, actor_tx, actor_rx);});
    current_id += 1;
  }

  for _ in 0..corporate_actor_count {
    let m = markets.clone();
    Thread::spawn(move || {start_corporate_actor(current_id, m, 0, 100);});//start a corporate actor with 100 of stock 0
    current_id += 1;
  }

  for _ in 0..scripted_actor_count {
    let m = markets.clone();
    let (actor_tx, actor_rx): (Sender<ActorMessages>, Receiver<ActorMessages>) = channel();
    actors_with_timers.push(actor_tx.clone());
    Thread::spawn(move || {start_scripted_actor(current_id, m, actor_tx, actor_rx);});
    current_id += 1;
  }

  for _ in 0..smarter_actor_count{
    let m = markets.clone();
    let (actor_tx, actor_rx): (Sender<ActorMessages>, Receiver<ActorMessages>) = channel();
    actors_with_timers.push(actor_tx.clone());
    Thread::spawn(move || {start_smarter_actor(current_id, m, actor_tx, actor_rx);});
    current_id += 1;
  }

  let tick = 100;
  for t in 0..248 {
    for tx in actors_with_timers.iter() {
      tx.send(ActorMessages::Time(t * tick, 247 * tick)).unwrap();
    }
    timer::sleep(Duration::milliseconds(tick as i64));
  }
}
<commit_msg>Adding dummy actor to Main<commit_after>#![feature(core, io, std_misc)]
use std::collections::HashMap;
use std::sync::mpsc::{Sender, Receiver, channel};
use std::thread::Thread;
use std::old_io::timer;
use std::time::Duration;

pub mod messages;
pub mod market;
pub mod actor;
pub mod teller;
pub mod corporate_actor;
pub mod smarter_actor;
pub mod scripted_actor;
pub mod dummy_actor_1;

use messages::*;
use market::*;
use actor::*;
use corporate_actor::*;
use smarter_actor::*;
use scripted_actor::*;
use dummy_actor_1::*;

fn main() {
  //tx: clone for actors        rx: owned by market
  let (tx_market, rx_market): (Sender<MarketMessages>, Receiver<MarketMessages>) = channel();

  //TODO: with spawning multiple markets make this a for loop.
  let tx_market_clone = tx_market.clone();
  Thread::spawn(move || {
    market::start_market(0, tx_market_clone, rx_market);});

  let mut markets = HashMap::new();
  markets.insert(0, tx_market.clone());

  let mut actors_with_timers = vec![];

  let standard_actor_count = 5;
  let corporate_actor_count = 1;
  let scripted_actor_count = 2;
  let smarter_actor_count = 5;

  let mut current_id = 0;
  //TODO make more stocks and add history so actors can query on it.
  for _ in 0..standard_actor_count {
    let m = markets.clone();
    let (actor_tx, actor_rx): (Sender<ActorMessages>, Receiver<ActorMessages>) = channel();
    actors_with_timers.push(actor_tx.clone());
    Thread::spawn(move || {start_actor(current_id, m, actor_tx, actor_rx);});
    current_id += 1;
  }

  for _ in 0..corporate_actor_count {
    let m = markets.clone();
    Thread::spawn(move || {start_corporate_actor(current_id, m, 0, 100);});//start a corporate actor with 100 of stock 0
    current_id += 1;
  }

  for _ in 0..scripted_actor_count {
    let m = markets.clone();
    let (actor_tx, actor_rx): (Sender<ActorMessages>, Receiver<ActorMessages>) = channel();
    actors_with_timers.push(actor_tx.clone());
    Thread::spawn(move || {start_scripted_actor(current_id, m, actor_tx, actor_rx);});
    current_id += 1;
  }

  for _ in 0..smarter_actor_count{
    let m = markets.clone();
    let (actor_tx, actor_rx): (Sender<ActorMessages>, Receiver<ActorMessages>) = channel();
    actors_with_timers.push(actor_tx.clone());
    Thread::spawn(move || {start_smarter_actor(current_id, m, actor_tx, actor_rx);});
    current_id += 1;
  }

  let tick = 100;
  for t in 0..248 {
    for tx in actors_with_timers.iter() {
      tx.send(ActorMessages::Time(t * tick, 247 * tick)).unwrap();
    }
    timer::sleep(Duration::milliseconds(tick as i64));
  }
}
<|endoftext|>


<commit_before>/// Benchmarks game nbody code
/// Taken from the  `packed_simd` crate
/// Run this benchmark with `cargo test --example body`
use core_simd::*;

use std::f64::consts::PI;
const SOLAR_MASS: f64 = 4.0 * PI * PI;
const DAYS_PER_YEAR: f64 = 365.24;

#[derive(Debug, Clone, Copy)]
pub struct Body {
    pub x: f64x4,
    pub v: f64x4,
    pub mass: f64,
}

const N_BODIES: usize = 5;
const BODIES: [Body; N_BODIES] = [
    // sun:
    Body {
        x: f64x4::from_array([0., 0., 0., 0.]),
        v: f64x4::from_array([0., 0., 0., 0.]),
        mass: SOLAR_MASS,
    },
    // jupiter:
    Body {
        x: f64x4::from_array([
            4.84143144246472090e+00,
            -1.16032004402742839e+00,
            -1.03622044471123109e-01,
            0.,
        ]),
        v: f64x4::from_array([
            1.66007664274403694e-03 * DAYS_PER_YEAR,
            7.69901118419740425e-03 * DAYS_PER_YEAR,
            -6.90460016972063023e-05 * DAYS_PER_YEAR,
            0.,
        ]),
        mass: 9.54791938424326609e-04 * SOLAR_MASS,
    },
    // saturn:
    Body {
        x: f64x4::from_array([
            8.34336671824457987e+00,
            4.12479856412430479e+00,
            -4.03523417114321381e-01,
            0.,
        ]),
        v: f64x4::from_array([
            -2.76742510726862411e-03 * DAYS_PER_YEAR,
            4.99852801234917238e-03 * DAYS_PER_YEAR,
            2.30417297573763929e-05 * DAYS_PER_YEAR,
            0.,
        ]),
        mass: 2.85885980666130812e-04 * SOLAR_MASS,
    },
    // uranus:
    Body {
        x: f64x4::from_array([
            1.28943695621391310e+01,
            -1.51111514016986312e+01,
            -2.23307578892655734e-01,
            0.,
        ]),
        v: f64x4::from_array([
            2.96460137564761618e-03 * DAYS_PER_YEAR,
            2.37847173959480950e-03 * DAYS_PER_YEAR,
            -2.96589568540237556e-05 * DAYS_PER_YEAR,
            0.,
        ]),
        mass: 4.36624404335156298e-05 * SOLAR_MASS,
    },
    // neptune:
    Body {
        x: f64x4::from_array([
            1.53796971148509165e+01,
            -2.59193146099879641e+01,
            1.79258772950371181e-01,
            0.,
        ]),
        v: f64x4::from_array([
            2.68067772490389322e-03 * DAYS_PER_YEAR,
            1.62824170038242295e-03 * DAYS_PER_YEAR,
            -9.51592254519715870e-05 * DAYS_PER_YEAR,
            0.,
        ]),
        mass: 5.15138902046611451e-05 * SOLAR_MASS,
    },
];

pub fn offset_momentum(bodies: &mut [Body; N_BODIES]) {
    let (sun, rest) = bodies.split_at_mut(1);
    let sun = &mut sun[0];
    for body in rest {
        let m_ratio = body.mass / SOLAR_MASS;
        sun.v -= body.v * m_ratio;
    }
}

pub fn energy(bodies: &[Body; N_BODIES]) -> f64 {
    let mut e = 0.;
    for i in 0..N_BODIES {
        let bi = &bodies[i];
        e += bi.mass * (bi.v * bi.v).horizontal_sum() * 0.5;
        for bj in bodies.iter().take(N_BODIES).skip(i + 1) {
            let dx = bi.x - bj.x;
            e -= bi.mass * bj.mass / (dx * dx).horizontal_sum().sqrt()
        }
    }
    e
}

pub fn advance(bodies: &mut [Body; N_BODIES], dt: f64) {
    const N: usize = N_BODIES * (N_BODIES - 1) / 2;

    // compute distance between bodies:
    let mut r = [f64x4::splat(0.); N];
    {
        let mut i = 0;
        for j in 0..N_BODIES {
            for k in j + 1..N_BODIES {
                r[i] = bodies[j].x - bodies[k].x;
                i += 1;
            }
        }
    }

    let mut mag = [0.0; N];
    let mut i = 0;
    while i < N {
        let d2s = f64x2::from_array([
            (r[i] * r[i]).horizontal_sum(),
            (r[i + 1] * r[i + 1]).horizontal_sum(),
        ]);
        let dmags = f64x2::splat(dt) / (d2s * d2s.sqrt());
        mag[i] = dmags[0];
        mag[i + 1] = dmags[1];
        i += 2;
    }

    i = 0;
    for j in 0..N_BODIES {
        for k in j + 1..N_BODIES {
            let f = r[i] * mag[i];
            bodies[j].v -= f * bodies[k].mass;
            bodies[k].v += f * bodies[j].mass;
            i += 1
        }
    }
    for body in bodies {
        body.x += dt * body.v
    }
}

pub fn run(n: usize) -> (f64, f64) {
    let mut bodies = BODIES;
    offset_momentum(&mut bodies);
    let energy_before = energy(&bodies);
    for _ in 0..n {
        advance(&mut bodies, 0.01);
    }
    let energy_after = energy(&bodies);

    (energy_before, energy_after)
}

// Good enough for demonstration purposes, not going for strictness here.
fn approx_eq_f64(a: f64, b: f64) -> bool {
    (a - b).abs() < 0.00001
}

#[cfg(test)]
mod tests {
    #[test]
    fn test() {
        use super::*;
        const OUTPUT: [f64; 2] = [-0.169075164, -0.169087605];
        let (energy_before, energy_after) = super::run(1000);
        assert!(approx_eq_f64(energy_before, OUTPUT[0]));
        assert!(approx_eq_f64(energy_after, OUTPUT[1]));
    }
}

fn main () {
    // empty main to pass CI
}
<commit_msg>Update crates/core_simd/examples/nbody.rs<commit_after>/// Benchmarks game nbody code
/// Taken from the `packed_simd` crate
/// Run this benchmark with `cargo test --example nbody`
use core_simd::*;

use std::f64::consts::PI;
const SOLAR_MASS: f64 = 4.0 * PI * PI;
const DAYS_PER_YEAR: f64 = 365.24;

#[derive(Debug, Clone, Copy)]
pub struct Body {
    pub x: f64x4,
    pub v: f64x4,
    pub mass: f64,
}

const N_BODIES: usize = 5;
const BODIES: [Body; N_BODIES] = [
    // sun:
    Body {
        x: f64x4::from_array([0., 0., 0., 0.]),
        v: f64x4::from_array([0., 0., 0., 0.]),
        mass: SOLAR_MASS,
    },
    // jupiter:
    Body {
        x: f64x4::from_array([
            4.84143144246472090e+00,
            -1.16032004402742839e+00,
            -1.03622044471123109e-01,
            0.,
        ]),
        v: f64x4::from_array([
            1.66007664274403694e-03 * DAYS_PER_YEAR,
            7.69901118419740425e-03 * DAYS_PER_YEAR,
            -6.90460016972063023e-05 * DAYS_PER_YEAR,
            0.,
        ]),
        mass: 9.54791938424326609e-04 * SOLAR_MASS,
    },
    // saturn:
    Body {
        x: f64x4::from_array([
            8.34336671824457987e+00,
            4.12479856412430479e+00,
            -4.03523417114321381e-01,
            0.,
        ]),
        v: f64x4::from_array([
            -2.76742510726862411e-03 * DAYS_PER_YEAR,
            4.99852801234917238e-03 * DAYS_PER_YEAR,
            2.30417297573763929e-05 * DAYS_PER_YEAR,
            0.,
        ]),
        mass: 2.85885980666130812e-04 * SOLAR_MASS,
    },
    // uranus:
    Body {
        x: f64x4::from_array([
            1.28943695621391310e+01,
            -1.51111514016986312e+01,
            -2.23307578892655734e-01,
            0.,
        ]),
        v: f64x4::from_array([
            2.96460137564761618e-03 * DAYS_PER_YEAR,
            2.37847173959480950e-03 * DAYS_PER_YEAR,
            -2.96589568540237556e-05 * DAYS_PER_YEAR,
            0.,
        ]),
        mass: 4.36624404335156298e-05 * SOLAR_MASS,
    },
    // neptune:
    Body {
        x: f64x4::from_array([
            1.53796971148509165e+01,
            -2.59193146099879641e+01,
            1.79258772950371181e-01,
            0.,
        ]),
        v: f64x4::from_array([
            2.68067772490389322e-03 * DAYS_PER_YEAR,
            1.62824170038242295e-03 * DAYS_PER_YEAR,
            -9.51592254519715870e-05 * DAYS_PER_YEAR,
            0.,
        ]),
        mass: 5.15138902046611451e-05 * SOLAR_MASS,
    },
];

pub fn offset_momentum(bodies: &mut [Body; N_BODIES]) {
    let (sun, rest) = bodies.split_at_mut(1);
    let sun = &mut sun[0];
    for body in rest {
        let m_ratio = body.mass / SOLAR_MASS;
        sun.v -= body.v * m_ratio;
    }
}

pub fn energy(bodies: &[Body; N_BODIES]) -> f64 {
    let mut e = 0.;
    for i in 0..N_BODIES {
        let bi = &bodies[i];
        e += bi.mass * (bi.v * bi.v).horizontal_sum() * 0.5;
        for bj in bodies.iter().take(N_BODIES).skip(i + 1) {
            let dx = bi.x - bj.x;
            e -= bi.mass * bj.mass / (dx * dx).horizontal_sum().sqrt()
        }
    }
    e
}

pub fn advance(bodies: &mut [Body; N_BODIES], dt: f64) {
    const N: usize = N_BODIES * (N_BODIES - 1) / 2;

    // compute distance between bodies:
    let mut r = [f64x4::splat(0.); N];
    {
        let mut i = 0;
        for j in 0..N_BODIES {
            for k in j + 1..N_BODIES {
                r[i] = bodies[j].x - bodies[k].x;
                i += 1;
            }
        }
    }

    let mut mag = [0.0; N];
    let mut i = 0;
    while i < N {
        let d2s = f64x2::from_array([
            (r[i] * r[i]).horizontal_sum(),
            (r[i + 1] * r[i + 1]).horizontal_sum(),
        ]);
        let dmags = f64x2::splat(dt) / (d2s * d2s.sqrt());
        mag[i] = dmags[0];
        mag[i + 1] = dmags[1];
        i += 2;
    }

    i = 0;
    for j in 0..N_BODIES {
        for k in j + 1..N_BODIES {
            let f = r[i] * mag[i];
            bodies[j].v -= f * bodies[k].mass;
            bodies[k].v += f * bodies[j].mass;
            i += 1
        }
    }
    for body in bodies {
        body.x += dt * body.v
    }
}

pub fn run(n: usize) -> (f64, f64) {
    let mut bodies = BODIES;
    offset_momentum(&mut bodies);
    let energy_before = energy(&bodies);
    for _ in 0..n {
        advance(&mut bodies, 0.01);
    }
    let energy_after = energy(&bodies);

    (energy_before, energy_after)
}

// Good enough for demonstration purposes, not going for strictness here.
fn approx_eq_f64(a: f64, b: f64) -> bool {
    (a - b).abs() < 0.00001
}

#[cfg(test)]
mod tests {
    #[test]
    fn test() {
        use super::*;
        const OUTPUT: [f64; 2] = [-0.169075164, -0.169087605];
        let (energy_before, energy_after) = super::run(1000);
        assert!(approx_eq_f64(energy_before, OUTPUT[0]));
        assert!(approx_eq_f64(energy_after, OUTPUT[1]));
    }
}

fn main () {
    // empty main to pass CI
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

fn char_frequency(string: String) -> HashMap<char, usize> {
    let mut frequency = HashMap::new();

    for c in string.chars() {
        if !c.is_whitespace() {
            let counter = frequency.entry(c).or_insert(0);
            *counter += 1;
        }
    }

    return frequency;
}

pub fn is_permutation_of_palindrome(string: &str) -> bool {
    let string = string.to_lowercase();
    let char_frequency = char_frequency(string);

    println!("char_frequency {:?}", char_frequency);

    let mut odd_found = false;

    for (_, i) in char_frequency {
        if i % 2 == 1 {
            if odd_found {
                return false;
            }
            odd_found = true;
        }
    }

    return true;
}

#[test]
fn example_is_permutation_of_palindrome() {
    assert!(is_permutation_of_palindrome("Tact Coa"));
}

#[test]
fn one_character_is_permutation_of_palindrome() {
    assert!(is_permutation_of_palindrome("a"));
}

#[test]
fn a_palindrome_is_a_permutation_of_palindrome() {
    assert!(is_permutation_of_palindrome("abba"));
}

#[test]
#[should_panic]
fn my_name_is_not_a_permutation_of_palindrome() {
    assert!(is_permutation_of_palindrome("Julio"));
}
<commit_msg>Remove debugging code<commit_after>use std::collections::HashMap;

fn char_frequency(string: String) -> HashMap<char, usize> {
    let mut frequency = HashMap::new();

    for c in string.chars() {
        if !c.is_whitespace() {
            let counter = frequency.entry(c).or_insert(0);
            *counter += 1;
        }
    }

    return frequency;
}

pub fn is_permutation_of_palindrome(string: &str) -> bool {
    let string = string.to_lowercase();
    let char_frequency = char_frequency(string);

    let mut odd_found = false;

    for (_, i) in char_frequency {
        if i % 2 == 1 {
            if odd_found {
                return false;
            }
            odd_found = true;
        }
    }

    return true;
}

#[test]
fn example_is_permutation_of_palindrome() {
    assert!(is_permutation_of_palindrome("Tact Coa"));
}

#[test]
fn one_character_is_permutation_of_palindrome() {
    assert!(is_permutation_of_palindrome("a"));
}

#[test]
fn a_palindrome_is_a_permutation_of_palindrome() {
    assert!(is_permutation_of_palindrome("abba"));
}

#[test]
#[should_panic]
fn my_name_is_not_a_permutation_of_palindrome() {
    assert!(is_permutation_of_palindrome("Julio"));
}
<|endoftext|>


<commit_before>// Copyright 2014-2015 Johannes Köster, Peer Aramillo Irizar.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of alphabets and useful utilities.
//!
//! # Example
//!
//! ```rust
//! use bio::alphabets;
//! let alphabet = alphabets::dna::alphabet();
//! assert!(alphabet.is_word(b"AACCTgga"));
//! assert!(!alphabet.is_word(b"AXYZ"));
//! ```

use std::mem;

use bit_set::BitSet;
use vec_map::VecMap;

use utils::{IntoTextIterator, TextIterator};

pub mod dna;
pub mod protein;

pub type SymbolRanks = VecMap<u8>;

/// Representation of an alphabet.
pub struct Alphabet {
    pub symbols: BitSet,
}

impl Alphabet {
    /// Create new alphabet from given symbols.
    pub fn new<'a, T: IntoTextIterator<'a>>(symbols: T) -> Self {
        let mut s = BitSet::new();
        s.extend(symbols.into_iter().map(|&c| c as usize));

        Alphabet { symbols: s }
    }

    /// Insert symbol into alphabet.
    pub fn insert(&mut self, a: u8) {
        self.symbols.insert(a as usize);
    }

    /// Check if given text is a word over the alphabet.
    pub fn is_word<'a, T: IntoTextIterator<'a>>(&self, text: T) -> bool {
        text.into_iter()
            .all(|&c| self.symbols.contains(c as usize))
    }

    /// Return lexicographically maximal symbol.
    pub fn max_symbol(&self) -> Option<u8> {
        self.symbols.iter().max().map(|a| a as u8)
    }

    /// Return size of the alphabet.
    pub fn len(&self) -> usize {
        self.symbols.len()
    }

    /// Is this alphabet empty?
    pub fn is_empty(&self) -> bool {
        self.symbols.is_empty()
    }
}

/// Tools based on transforming the alphabet symbols to their lexicographical ranks.
#[derive(Serialize, Deserialize)]
pub struct RankTransform {
    pub ranks: SymbolRanks,
}

impl RankTransform {
    /// Construct a new `RankTransform`.
    pub fn new(alphabet: &Alphabet) -> Self {
        let mut ranks = VecMap::new();
        for (r, c) in alphabet.symbols.iter().enumerate() {
            ranks.insert(c, r as u8);
        }

        RankTransform { ranks: ranks }
    }

    /// Get the rank of symbol `a`.
    pub fn get(&self, a: u8) -> u8 {
        *self.ranks
             .get(a as usize)
             .expect("Unexpected character.")
    }

    /// Transform a given `text`.
    pub fn transform<'a, T: IntoTextIterator<'a>>(&self, text: T) -> Vec<u8> {
        text.into_iter()
            .map(|&c| {
                     *self.ranks
                          .get(c as usize)
                          .expect("Unexpected character in text.")
                 })
            .collect()
    }

    /// Iterate over q-grams (substrings of length q) of given `text`. The q-grams are encoded
    /// as `usize` by storing the symbol ranks in log2(|A|) bits (with |A| being the alphabet size).
    ///
    /// If q is larger than usize::BITS / log2(|A|), this method fails with an assertion.
    pub fn qgrams<'a, T: IntoTextIterator<'a>>(&'a self, q: u32, text: T) -> QGrams<T::IntoIter> {
        let bits = (self.ranks.len() as f32).log2().ceil() as u32;
        assert!((bits * q) as usize <= mem::size_of::<usize>() * 8,
                "Expecting q to be smaller than usize / log2(|A|)");

        let mut qgrams = QGrams {
            text: text.into_iter(),
            ranks: self,
            bits: bits,
            mask: (1 << (q * bits)) - 1,
            qgram: 0,
        };

        for _ in 0..q - 1 {
            qgrams.next();
        }

        qgrams
    }

    /// Restore alphabet from transform.
    pub fn alphabet(&self) -> Alphabet {
        let mut symbols = BitSet::with_capacity(self.ranks.len());
        symbols.extend(self.ranks.keys());
        Alphabet { symbols: symbols }
    }
}

/// Iterator over q-grams.
pub struct QGrams<'a, T: TextIterator<'a>> {
    text: T,
    ranks: &'a RankTransform,
    bits: u32,
    mask: usize,
    qgram: usize,
}

impl<'a, T: TextIterator<'a>> QGrams<'a, T> {
    fn qgram_push(&mut self, a: u8) {
        self.qgram <<= self.bits;
        self.qgram |= a as usize;
        self.qgram &= self.mask;
    }
}

impl<'a, T: TextIterator<'a>> Iterator for QGrams<'a, T> {
    type Item = usize;

    fn next(&mut self) -> Option<usize> {
        match self.text.next() {
            Some(a) => {
                let b = self.ranks.get(*a);
                self.qgram_push(b);
                Some(self.qgram)
            }
            None => None,
        }
    }
}

#[cfg(tests)]
mod tests {
    #[test]
    fn test_serde() {
        use serde::{Serialize, Deserialize};
        fn impls_serde_traits<S: Serialize + Deserialize>() {}

        impls_serde_traits::<RankTransform>();
    }
}
<commit_msg>Add rna module and format with rustfmt<commit_after>// Copyright 2014-2015 Johannes Köster, Peer Aramillo Irizar.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of alphabets and useful utilities.
//!
//! # Example
//!
//! ```rust
//! use bio::alphabets;
//! let alphabet = alphabets::dna::alphabet();
//! assert!(alphabet.is_word(b"AACCTgga"));
//! assert!(!alphabet.is_word(b"AXYZ"));
//! ```

use std::mem;

use bit_set::BitSet;
use vec_map::VecMap;

use utils::{IntoTextIterator, TextIterator};

pub mod dna;
pub mod rna;
pub mod protein;

pub type SymbolRanks = VecMap<u8>;

/// Representation of an alphabet.
pub struct Alphabet {
    pub symbols: BitSet,
}

impl Alphabet {
    /// Create new alphabet from given symbols.
    pub fn new<'a, T: IntoTextIterator<'a>>(symbols: T) -> Self {
        let mut s = BitSet::new();
        s.extend(symbols.into_iter().map(|&c| c as usize));

        Alphabet { symbols: s }
    }

    /// Insert symbol into alphabet.
    pub fn insert(&mut self, a: u8) {
        self.symbols.insert(a as usize);
    }

    /// Check if given text is a word over the alphabet.
    pub fn is_word<'a, T: IntoTextIterator<'a>>(&self, text: T) -> bool {
        text.into_iter().all(|&c| self.symbols.contains(c as usize))
    }

    /// Return lexicographically maximal symbol.
    pub fn max_symbol(&self) -> Option<u8> {
        self.symbols.iter().max().map(|a| a as u8)
    }

    /// Return size of the alphabet.
    pub fn len(&self) -> usize {
        self.symbols.len()
    }

    /// Is this alphabet empty?
    pub fn is_empty(&self) -> bool {
        self.symbols.is_empty()
    }
}

/// Tools based on transforming the alphabet symbols to their lexicographical ranks.
#[derive(Serialize, Deserialize)]
pub struct RankTransform {
    pub ranks: SymbolRanks,
}

impl RankTransform {
    /// Construct a new `RankTransform`.
    pub fn new(alphabet: &Alphabet) -> Self {
        let mut ranks = VecMap::new();
        for (r, c) in alphabet.symbols.iter().enumerate() {
            ranks.insert(c, r as u8);
        }

        RankTransform { ranks: ranks }
    }

    /// Get the rank of symbol `a`.
    pub fn get(&self, a: u8) -> u8 {
        *self.ranks.get(a as usize).expect("Unexpected character.")
    }

    /// Transform a given `text`.
    pub fn transform<'a, T: IntoTextIterator<'a>>(&self, text: T) -> Vec<u8> {
        text.into_iter()
            .map(|&c| {
                     *self.ranks
                          .get(c as usize)
                          .expect("Unexpected character in text.")
                 })
            .collect()
    }

    /// Iterate over q-grams (substrings of length q) of given `text`. The q-grams are encoded
    /// as `usize` by storing the symbol ranks in log2(|A|) bits (with |A| being the alphabet size).
    ///
    /// If q is larger than usize::BITS / log2(|A|), this method fails with an assertion.
    pub fn qgrams<'a, T: IntoTextIterator<'a>>(&'a self, q: u32, text: T) -> QGrams<T::IntoIter> {
        let bits = (self.ranks.len() as f32).log2().ceil() as u32;
        assert!((bits * q) as usize <= mem::size_of::<usize>() * 8,
                "Expecting q to be smaller than usize / log2(|A|)");

        let mut qgrams = QGrams {
            text: text.into_iter(),
            ranks: self,
            bits: bits,
            mask: (1 << (q * bits)) - 1,
            qgram: 0,
        };

        for _ in 0..q - 1 {
            qgrams.next();
        }

        qgrams
    }

    /// Restore alphabet from transform.
    pub fn alphabet(&self) -> Alphabet {
        let mut symbols = BitSet::with_capacity(self.ranks.len());
        symbols.extend(self.ranks.keys());
        Alphabet { symbols: symbols }
    }
}

/// Iterator over q-grams.
pub struct QGrams<'a, T: TextIterator<'a>> {
    text: T,
    ranks: &'a RankTransform,
    bits: u32,
    mask: usize,
    qgram: usize,
}

impl<'a, T: TextIterator<'a>> QGrams<'a, T> {
    fn qgram_push(&mut self, a: u8) {
        self.qgram <<= self.bits;
        self.qgram |= a as usize;
        self.qgram &= self.mask;
    }
}

impl<'a, T: TextIterator<'a>> Iterator for QGrams<'a, T> {
    type Item = usize;

    fn next(&mut self) -> Option<usize> {
        match self.text.next() {
            Some(a) => {
                let b = self.ranks.get(*a);
                self.qgram_push(b);
                Some(self.qgram)
            }
            None => None,
        }
    }
}

#[cfg(tests)]
mod tests {
    #[test]
    fn test_serde() {
        use serde::{Serialize, Deserialize};
        fn impls_serde_traits<S: Serialize + Deserialize>() {}

        impls_serde_traits::<RankTransform>();
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate rand;
extern crate presort;

use test::Bencher;
use rand::Rng;

use presort::PresortedVec;
use presort::inc_tree::{Tree, IncTree, dump, update};

const NODES: usize = 10000;
const BINARY_DEPTH: usize = 13;
const DEEP_DEPTH: usize = 150;
const WIDE_DEPTH: usize = 6;
const DEPTH: usize = BINARY_DEPTH;

//creates a random tree with the requested parameters
fn build_tree(max_depth: usize, nodes: usize) -> Tree<usize> {
    let mut rng = rand::thread_rng();

    let tree = Tree::new_node(rng.gen());

    for _ in 0..nodes {
        let mut branch = tree.clone();
        let depth = rng.gen::<usize>() % max_depth;
        for _ in 0..depth {
            let num = branch.num_children();
            if num <= 0 {break};
            branch = branch.get_child(rng.gen::<usize>() % num);
        }
        branch.push_child(Tree::new_node(rng.gen()));
    }

    tree
}
// mutates `edits` number of values of `tree`,
// at no more than a max depth of `high_depth`
// shorter branches may have the ends updated more often
fn mutate_vals(tree: &Tree<usize>, high_depth: usize, edits: usize) {
    let mut rng = rand::thread_rng();

    for _ in 0..edits {
        let mut branch = tree.clone();
        let depth = rng.gen::<usize>() % high_depth;
        for _ in 0..depth {
            let num = branch.num_children();
            if num <= 0 {break};
            branch = branch.get_child(rng.gen::<usize>() % num);
        }
        branch.set_data(rng.gen());
        //branch.set_data(branch.get_data()+1);
    }
}

fn add_branches(tree: &Tree<usize>, high_depth: usize, adds: usize) {
    let mut rng = rand::thread_rng();

    for _ in 0..adds {
        let mut branch = tree.clone();
        let depth = rng.gen::<usize>() % high_depth;
        for _ in 0..depth {
            let num = branch.num_children();
            if num <= 0 {break};
            branch = branch.get_child(rng.gen::<usize>() % num);
        }
        branch.push_child(Tree::new_node(rng.gen()));
    }
}

#[bench]
fn edit_50_batch(b: &mut Bencher) {
    let mut vec = PresortedVec::new();
    let tree = build_tree(DEPTH, NODES);
    dump(&tree, &mut vec);
    b.iter(|| {
        mutate_vals(&tree, DEPTH, 50);
        update(&tree, 0, &mut vec);
    })
}

#[bench]
fn edit_50_seperate(b: &mut Bencher) {
    let mut vec = PresortedVec::new();
    let tree = build_tree(DEPTH, NODES);
    dump(&tree, &mut vec);
    b.iter(|| {
        for _ in 0..50 {
            mutate_vals(&tree, DEPTH, 1);
            update(&tree, 0, &mut vec);
        }
    })
}

#[bench]
fn add_50_batch(b: &mut Bencher) {
    let mut vec = PresortedVec::new();
    let tree = build_tree(DEPTH, NODES);
    dump(&tree, &mut vec);
    b.iter(|| {
        add_branches(&tree, DEPTH, 50);
        update(&tree, 0, &mut vec);
    })
}

#[bench]
fn add_50_seperate(b: &mut Bencher) {
    let mut vec = PresortedVec::new();
    let tree = build_tree(DEPTH, NODES);
    dump(&tree, &mut vec);
    b.iter(|| {
        for _ in 0..50 {
            add_branches(&tree, DEPTH, 50);
            update(&tree, 0, &mut vec);
        }
    })
}

<commit_msg>Factored out random_subtree.<commit_after>#![feature(test)]

extern crate test;
extern crate rand;
extern crate presort;

use test::Bencher;
use rand::Rng;

use presort::PresortedVec;
use presort::inc_tree::{Tree, IncTree, dump, update};

const NODES: usize = 10000;
const BINARY_DEPTH: usize = 13;
const DEEP_DEPTH: usize = 150;
const WIDE_DEPTH: usize = 6;
const DEPTH: usize = BINARY_DEPTH;

//creates a random tree with the requested parameters
fn build_tree(max_depth: usize, nodes: usize) -> Tree<usize> {
    let mut rng = rand::thread_rng();

    let tree = Tree::new_node(rng.gen());

    for _ in 0..nodes {
        let mut branch = tree.clone();
        let depth = rng.gen::<usize>() % max_depth;
        for _ in 0..depth {
            let num = branch.num_children();
            if num <= 0 {break};
            branch = branch.get_child(rng.gen::<usize>() % num);
        }
        branch.push_child(Tree::new_node(rng.gen()));
    }

    tree
}

// Pick a random subtree from the tree
fn random_subtree(tree: &Tree<usize>, high_depth: usize) -> Tree<usize> {
    let mut rng = rand::thread_rng();
    let mut subtree = tree.clone();
    let depth = rng.gen::<usize>() % high_depth;
    for _ in 0..depth {
        let num = subtree.num_children();
        if num <= 0 { return subtree; }
        subtree = subtree.get_child(rng.gen::<usize>() % num);
    }
    return subtree;
}

// mutates `edits` number of values of `tree`,
// at no more than a max depth of `high_depth`
// shorter branches may have the ends updated more often
fn mutate_vals(tree: &Tree<usize>, high_depth: usize, edits: usize) {
    let mut rng = rand::thread_rng();
    for _ in 0..edits {
        random_subtree(tree, high_depth).set_data(rng.gen());
    }
}

fn add_branches(tree: &Tree<usize>, high_depth: usize, adds: usize) {
    let mut rng = rand::thread_rng();
    for _ in 0..adds {
        random_subtree(tree, high_depth).push_child(Tree::new_node(rng.gen()));
    }
}

#[bench]
fn edit_50_batch(b: &mut Bencher) {
    let mut vec = PresortedVec::new();
    let tree = build_tree(DEPTH, NODES);
    dump(&tree, &mut vec);
    b.iter(|| {
        mutate_vals(&tree, DEPTH, 50);
        update(&tree, 0, &mut vec);
    })
}

#[bench]
fn edit_50_seperate(b: &mut Bencher) {
    let mut vec = PresortedVec::new();
    let tree = build_tree(DEPTH, NODES);
    dump(&tree, &mut vec);
    b.iter(|| {
        for _ in 0..50 {
            mutate_vals(&tree, DEPTH, 1);
            update(&tree, 0, &mut vec);
        }
    })
}

#[bench]
fn add_50_batch(b: &mut Bencher) {
    let mut vec = PresortedVec::new();
    let tree = build_tree(DEPTH, NODES);
    dump(&tree, &mut vec);
    b.iter(|| {
        add_branches(&tree, DEPTH, 50);
        update(&tree, 0, &mut vec);
    })
}

#[bench]
fn add_50_seperate(b: &mut Bencher) {
    let mut vec = PresortedVec::new();
    let tree = build_tree(DEPTH, NODES);
    dump(&tree, &mut vec);
    b.iter(|| {
        for _ in 0..50 {
            add_branches(&tree, DEPTH, 50);
            update(&tree, 0, &mut vec);
        }
    })
}

<|endoftext|>


<commit_before><commit_msg>Add missing FromGlibBorrow implementation<commit_after><|endoftext|>


<commit_before>use std::cmp::Ordering;

#[derive(Debug, PartialEq, Eq)]
pub enum Alignment<T> {
    Match(T, T),
    ExcessLeftHead(T),
    ExcessRightHead(T),
    ExcessLeftTail(T),
    ExcessRightTail(T),
    DisjointLeft(T),
    DisjointRight(T),
}

impl<T> Alignment<T> {
    pub fn is_match(&self) -> bool {
        match *self {
            Alignment::Match(..) => true,
            _ => false,
        }
    }

    pub fn get_left(&self) -> Option<&T> {
        match *self {
            Alignment::Match(..) => None,

            Alignment::ExcessLeftHead(ref a) |
            Alignment::ExcessLeftTail(ref a) |
            Alignment::DisjointLeft(ref a) => Some(a),

            Alignment::ExcessRightHead(..) |
            Alignment::ExcessRightTail(..) |
            Alignment::DisjointRight(..) => None,
        }
    }

    pub fn get_right(&self) -> Option<&T> {
        match *self {
            Alignment::Match(..) => None,

            Alignment::ExcessLeftHead(..) |
            Alignment::ExcessLeftTail(..) |
            Alignment::DisjointLeft(..) => None,

            Alignment::ExcessRightHead(ref a) |
            Alignment::ExcessRightTail(ref a) |
            Alignment::DisjointRight(ref a) => Some(a),
        }
    }

    pub fn is_left(&self) -> bool {
        match *self {
            Alignment::Match(..) => false,

            Alignment::ExcessLeftHead(..) |
            Alignment::ExcessLeftTail(..) |
            Alignment::DisjointLeft(..) => true,

            Alignment::ExcessRightHead(..) |
            Alignment::ExcessRightTail(..) |
            Alignment::DisjointRight(..) => false
        }
    }

    pub fn is_right(&self) -> bool {
        match *self {
            Alignment::Match(..) => false,

            Alignment::ExcessLeftHead(..) |
            Alignment::ExcessLeftTail(..) |
            Alignment::DisjointLeft(..) => false,

            Alignment::ExcessRightHead(..) |
            Alignment::ExcessRightTail(..) |
            Alignment::DisjointRight(..) => true
        }
    }

    pub fn is_disjoint_left(&self) -> bool {
        match *self {
            Alignment::DisjointLeft(..) => true,
            _ => false,
        }
    }

    pub fn is_disjoint_right(&self) -> bool {
        match *self {
            Alignment::DisjointRight(..) => true,
            _ => false,
        }
    }

    pub fn is_disjoint(&self) -> bool {
        match *self {
            Alignment::DisjointLeft(..) |
            Alignment::DisjointRight(..) => true,
            _ => false,
        }
    }

    pub fn is_excess_left(&self) -> bool {
        match *self {
            Alignment::ExcessLeftHead(..) |
            Alignment::ExcessLeftTail(..) => true,
            _ => false,
        }
    }

    pub fn is_excess_right(&self) -> bool {
        match *self {
            Alignment::ExcessRightHead(..) |
            Alignment::ExcessRightTail(..) => true,
            _ => false,
        }
    }

    pub fn is_excess(&self) -> bool {
        match *self {
            Alignment::ExcessLeftHead(..) |
            Alignment::ExcessLeftTail(..) |
            Alignment::ExcessRightHead(..) |
            Alignment::ExcessRightTail(..) => true,
            _ => false,
        }
    }
}

/// Align the items of two sorted (unique) iterators.
pub fn align_sorted_iterators<CMP, F, I>(a: I, b: I, mut cmp: CMP, mut f: F)
    where
          CMP: Fn(&I::Item, &I::Item) -> Ordering,
          F: FnMut(Alignment<I::Item>),
          I: Iterator,
{
    let mut left_iter = a.peekable();
    let mut right_iter = b.peekable();
    let mut left_count = 0;
    let mut right_count = 0;

    enum Take {
        OneLeft,
        OneRight,
        Both,
        AllLeft,
        AllRight,
    };

    loop {
        let take;

        match (left_iter.peek(), right_iter.peek()) {
            (Some(ref l), Some(ref r)) => {
                take = match cmp(l, r) {
                    Ordering::Less => Take::OneLeft,
                    Ordering::Greater => Take::OneRight,
                    Ordering::Equal => Take::Both,
                };
            }
            (Some(_), None) => {
                take = Take::AllLeft;
            }
            (None, Some(_)) => {
                take = Take::AllRight;
            }
            (None, None) => {
                break;
            }
        }

        match take {
            Take::OneLeft => {
                let value = left_iter.next().unwrap();

                if right_count == 0 {
                    f(Alignment::ExcessLeftHead(value));
                } else {
                    f(Alignment::DisjointLeft(value));
                }

                left_count += 1;
            }
            Take::OneRight => {
                let value = right_iter.next().unwrap();

                if left_count == 0 {
                    f(Alignment::ExcessRightHead(value));
                } else {
                    f(Alignment::DisjointRight(value));
                }

                right_count += 1;
            }
            Take::Both => {
                // two equal values
                let left_value = left_iter.next().unwrap();
                let right_value = right_iter.next().unwrap();
                debug_assert!(cmp(&left_value, &right_value) == Ordering::Equal);

                f(Alignment::Match(left_value, right_value));

                left_count += 1;
                right_count += 1;
            }
            Take::AllLeft => {
                // There are no items left on the right side, so all items are ExcessLeftTail.
                for item in left_iter {
                    f(Alignment::ExcessLeftTail(item));
                }
                break;
            }
            Take::AllRight => {
                // There are no items left on the right side, so all items are ExcessRightTail.
                for item in right_iter {
                    f(Alignment::ExcessRightTail(item));
                }
                break;
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeSet;
    use super::{Alignment, align_sorted_iterators};

    fn align_as_vec<I>(a: I, b: I) -> Vec<Alignment<I::Item>>
        where I::Item: Ord + Clone,
              I: Iterator,
    {
        let mut c = Vec::new();
        align_sorted_iterators(a, b, Ord::cmp, |alignment| c.push(alignment));
        c
    }

    #[test]
    fn test_align_sorted_iterators() {
        let mut s1 = BTreeSet::<usize>::new();
        s1.insert(0);
        s1.insert(1);
        s1.insert(5);
        s1.insert(8);

        let mut s2 = BTreeSet::<usize>::new();
        s2.insert(1);
        s2.insert(5);
        s2.insert(7);
        s2.insert(9);
        s2.insert(55);

        let mut r = Vec::new();
        super::align_sorted_iterators(s1.iter().cloned(),
        s2.iter().cloned(),
        Ord::cmp,
        |alignment| {
            match alignment {
                Alignment::Match(a, _b) => r.push(a),
                Alignment::ExcessLeftHead(a) |
                    Alignment::ExcessRightHead(a) |
                    Alignment::ExcessLeftTail(a) |
                    Alignment::ExcessRightTail(a) |
                    Alignment::DisjointLeft(a) |
                    Alignment::DisjointRight(a) => r.push(a),
            }
        });

        assert_eq!(vec![0, 1, 5, 7, 8, 9, 55], r);
    }

    #[test]
    fn test_align_as_vec() {
        let mut left = BTreeSet::<usize>::new();
        let mut right = BTreeSet::<usize>::new();

        // 40, 46, 50
        left.insert(50);
        left.insert(46);
        left.insert(40);

        // 45, 50, 51, 52
        right.insert(50);
        right.insert(45);
        right.insert(51);
        right.insert(52);

        let c = align_as_vec(left.iter().cloned(), right.iter().cloned());
        assert_eq!(6, c.len());
        assert_eq!(Alignment::ExcessLeftHead(40), c[0]);
        assert_eq!(Alignment::DisjointRight(45), c[1]);
        assert_eq!(Alignment::DisjointLeft(46), c[2]);
        assert_eq!(Alignment::Match(50, 50), c[3]);
        assert_eq!(Alignment::ExcessRightTail(51), c[4]);
        assert_eq!(Alignment::ExcessRightTail(52), c[5]);
    }
}
<commit_msg>Simplify alignment<commit_after>use std::cmp::Ordering;

#[derive(Debug, PartialEq, Eq)]
pub enum LeftOrRight {
    Left,
    Right,
}

#[derive(Debug, PartialEq, Eq)]
pub enum Alignment<T> {
    Match(T, T),
    Excess(T, LeftOrRight),
    Disjoint(T, LeftOrRight),
}

impl<T> Alignment<T> {
    pub fn is_match(&self) -> bool {
        match *self {
            Alignment::Match(..) => true,
            _ => false,
        }
    }

    pub fn get_left(&self) -> Option<&T> {
        match *self {
            Alignment::Excess(ref a, LeftOrRight::Left) => Some(a),
            Alignment::Disjoint(ref a, LeftOrRight::Left) => Some(a),
            _ => None,
        }
    }

    pub fn get_right(&self) -> Option<&T> {
        match *self {
            Alignment::Excess(ref a, LeftOrRight::Right) => Some(a),
            Alignment::Disjoint(ref a, LeftOrRight::Right) => Some(a),
            _ => None,
        }
    }

    pub fn is_left(&self) -> bool {
        self.get_left().is_some()
    }

    pub fn is_right(&self) -> bool {
        self.get_right().is_some()
    }

    pub fn is_disjoint_left(&self) -> bool {
        match *self {
            Alignment::Disjoint(_, LeftOrRight::Left) => true,
            _ => false,
        }
    }

    pub fn is_disjoint_right(&self) -> bool {
        match *self {
            Alignment::Disjoint(_, LeftOrRight::Right) => true,
            _ => false,
        }
    }

    pub fn is_disjoint(&self) -> bool {
        match *self {
            Alignment::Disjoint(..) => true,
            _ => false,
        }
    }

    pub fn is_excess_left(&self) -> bool {
        match *self {
            Alignment::Excess(_, LeftOrRight::Left) => true,
            _ => false,
        }
    }

    pub fn is_excess_right(&self) -> bool {
        match *self {
            Alignment::Excess(_, LeftOrRight::Right) => true,
            _ => false,
        }
    }

    pub fn is_excess(&self) -> bool {
        match *self {
            Alignment::Excess(..) => true,
            _ => false,
        }
    }
}

/// Align the items of two sorted (unique) iterators.
pub fn align_sorted_iterators<CMP, F, I>(a: I, b: I, cmp: CMP, mut f: F)
    where
          CMP: Fn(&I::Item, &I::Item) -> Ordering,
          F: FnMut(Alignment<I::Item>),
          I: Iterator,
{
    let mut left_iter = a.peekable();
    let mut right_iter = b.peekable();
    let mut left_count = 0;
    let mut right_count = 0;

    enum Take {
        OneLeft,
        OneRight,
        Both,
        AllLeft,
        AllRight,
    };

    loop {
        let take;

        match (left_iter.peek(), right_iter.peek()) {
            (Some(ref l), Some(ref r)) => {
                take = match cmp(l, r) {
                    Ordering::Less => Take::OneLeft,
                    Ordering::Greater => Take::OneRight,
                    Ordering::Equal => Take::Both,
                };
            }
            (Some(_), None) => {
                take = Take::AllLeft;
            }
            (None, Some(_)) => {
                take = Take::AllRight;
            }
            (None, None) => {
                break;
            }
        }

        match take {
            Take::OneLeft => {
                let value = left_iter.next().unwrap();

                if right_count == 0 {
                    // left head
                    f(Alignment::Excess(value, LeftOrRight::Left));
                } else {
                    f(Alignment::Disjoint(value, LeftOrRight::Left));
                }

                left_count += 1;
            }
            Take::OneRight => {
                let value = right_iter.next().unwrap();

                if left_count == 0 {
                    // right head
                    f(Alignment::Excess(value, LeftOrRight::Right));
                } else {
                    f(Alignment::Disjoint(value, LeftOrRight::Right));
                }

                right_count += 1;
            }
            Take::Both => {
                // two equal values
                let left_value = left_iter.next().unwrap();
                let right_value = right_iter.next().unwrap();
                debug_assert!(cmp(&left_value, &right_value) == Ordering::Equal);

                f(Alignment::Match(left_value, right_value));

                left_count += 1;
                right_count += 1;
            }
            Take::AllLeft => {
                // There are no items left on the right side, so all items are ExcessLeftTail.
                for item in left_iter {
                    // left tail
                    f(Alignment::Excess(item, LeftOrRight::Left));
                }
                break;
            }
            Take::AllRight => {
                // There are no items left on the right side, so all items are ExcessRightTail.
                for item in right_iter {
                    f(Alignment::Excess(item, LeftOrRight::Right));
                }
                break;
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeSet;
    use super::{Alignment, align_sorted_iterators, LeftOrRight};

    fn align_as_vec<I>(a: I, b: I) -> Vec<Alignment<I::Item>>
        where I::Item: Ord + Clone,
              I: Iterator,
    {
        let mut c = Vec::new();
        align_sorted_iterators(a, b, Ord::cmp, |alignment| c.push(alignment));
        c
    }

    #[test]
    fn test_align_sorted_iterators() {
        let mut s1 = BTreeSet::<usize>::new();
        s1.insert(0);
        s1.insert(1);
        s1.insert(5);
        s1.insert(8);

        let mut s2 = BTreeSet::<usize>::new();
        s2.insert(1);
        s2.insert(5);
        s2.insert(7);
        s2.insert(9);
        s2.insert(55);

        let mut r = Vec::new();
        super::align_sorted_iterators(s1.iter().cloned(),
        s2.iter().cloned(),
        Ord::cmp,
        |alignment| {
            match alignment {
                Alignment::Match(a, _b) => r.push(a),
                Alignment::Excess(a, _) => r.push(a),
                Alignment::Disjoint(a, _) => r.push(a),
            }
        });

        assert_eq!(vec![0, 1, 5, 7, 8, 9, 55], r);
    }

    #[test]
    fn test_align_as_vec() {
        let mut left = BTreeSet::<usize>::new();
        let mut right = BTreeSet::<usize>::new();

        // 40, 46, 50
        left.insert(50);
        left.insert(46);
        left.insert(40);

        // 45, 50, 51, 52
        right.insert(50);
        right.insert(45);
        right.insert(51);
        right.insert(52);

        let c = align_as_vec(left.iter().cloned(), right.iter().cloned());
        assert_eq!(6, c.len());
        assert_eq!(Alignment::Excess(40, LeftOrRight::Left), c[0]);
        assert_eq!(Alignment::Disjoint(45, LeftOrRight::Right), c[1]);
        assert_eq!(Alignment::Disjoint(46, LeftOrRight::Left), c[2]);
        assert_eq!(Alignment::Match(50, 50), c[3]);
        assert_eq!(Alignment::Excess(51, LeftOrRight::Right), c[4]);
        assert_eq!(Alignment::Excess(52, LeftOrRight::Right), c[5]);
    }
}
<|endoftext|>


<commit_before>use quote::{ToTokens};

const TOP_LEVEL: &'static [&'static str] = &[
    "Window", "CanvasWindow", "TabsContainer", "Tab", "MessageWindow"
];

#[derive(Debug)]
pub struct NwgItem<'a> {
    id: &'a syn::Ident,
    parent_id: Option<String>,
    ty: &'a syn::Ident,

    names: Vec<syn::Ident>,
    values: Vec<syn::Expr>,

    weight: u32,
}

impl<'a> NwgItem<'a> {

    fn valid(field: &syn::Field) -> bool {
        field.attrs.iter().any(|attr|
            attr.path.get_ident()
                .map(|ident| ident == "nwg_control" || ident == "nwg_partial" )
                .unwrap_or(false)
        )
    }

    fn extract_type(field: &syn::Field) -> &syn::Ident {
        // TODO: extract type from nwg_control first

        match &field.ty {
            syn::Type::Path(p) => match p.path.segments.last() {
                Some(seg) => &seg.ident,
                None => panic!("Impossible to parse type for field {:?}. Try specifying it in the nwg_control attribute.", field.ident)
            },
            _ => panic!("Impossible to parse type for field {:?}. Try specifying it in the nwg_control attribute.", field.ident)
        }
    }

    fn expand_flags(&mut self) {
        let flags_index = self.names.iter().position(|n| n == "flags");
        if let Some(i) = flags_index {
            let old_flags = self.values[i].clone();
            self.values[i] = crate::controls::expand_flags(&self.id, &self.ty, old_flags);
        }
    }

    fn expand_parent(&mut self) {
        let parent_index = self.names.iter().position(|n| n == "parent");
        if parent_index.is_none() {
            return;
        }

        let i = parent_index.unwrap();
        let parent_expr: syn::Expr = match &self.values[i] {
            syn::Expr::Path(p) => {
                let id = &p.path.segments.last().unwrap().ident;
                self.parent_id = Some(id.to_string());
                syn::parse_str(&format!("&data.{}", id)).unwrap()
            },
            _ => { panic!("Bad expression type for parent of field {}", self.id); }
        };

        self.values[i] = parent_expr;
    }

}

pub struct NwgUiControls<'a>(&'a NwgUi<'a>);

impl<'a> ToTokens for NwgUiControls<'a> {

    fn to_tokens(&self, tokens: &mut pm2::TokenStream) {

        struct ControlGen<'b> {
            item: &'b NwgItem<'b>
        }

        impl<'b> ToTokens for ControlGen<'b> {
            fn to_tokens(&self, tokens: &mut pm2::TokenStream) {
                let item = &self.item;
                let ty = item.ty;
                let member = item.id;
                let names = &item.names;
                let values = &item.values;
                let control_tk = quote! {
                    nwg::#ty::builder()
                        #(.#names(#values))*
                        .build(&mut data.#member)?;
                };

                control_tk.to_tokens(tokens);
            }
        }

        let ui = &self.0;
        let controls: Vec<ControlGen> = ui.controls.iter()
            .map(|item| ControlGen { item })
            .collect();

        let controls_tk = quote! {
            #(#controls)*
        };

        controls_tk.to_tokens(tokens);
    }

}

pub struct NwgUiEvents<'a>(&'a NwgUi<'a>);

impl<'a> ToTokens for NwgUiEvents<'a> {

    fn to_tokens(&self, tokens: &mut pm2::TokenStream) {
        let events_tk = quote! {
        };

        events_tk.to_tokens(tokens);
    }

}

pub struct NwgUiLayouts<'a>(&'a NwgUi<'a>);

impl<'a> ToTokens for NwgUiLayouts<'a> {

    fn to_tokens(&self, tokens: &mut pm2::TokenStream) {
        let layouts_tk = quote! {

        };

        layouts_tk.to_tokens(tokens);
    }

}

pub struct NwgUi<'a> {
    pub data: &'a syn::DataStruct,
    pub controls: Vec<NwgItem<'a>>,
}

impl<'a> NwgUi<'a> {

    pub fn build(data: &'a syn::DataStruct) -> NwgUi<'a> {
        let named_fields = match &data.fields {
            syn::Fields::Named(n) => &n.named,
            _ => panic!("Ui structure must have named fields")
        };

        let mut controls: Vec<NwgItem> = Vec::with_capacity(named_fields.len());

        // First pass: names & default values
        for field in named_fields {
            if !NwgItem::valid(field) { continue; }

            let (names, values) = crate::controls::control_parameters(field);

            let f = NwgItem {
                id: field.ident.as_ref().unwrap(),
                parent_id: None,
                ty: NwgItem::extract_type(field),
                names,
                values,
                weight: 0,
            };

            controls.push(f);
        }

        // Second pass: parent stuff
        for i in 0..(controls.len()) {
            let has_attr_parent = controls[i].names.iter().any(|n| n == "parent");
            if has_attr_parent {
                controls[i].expand_parent();
            } else {
                let parent = controls[0..i]
                    .iter().rev()
                    .find(|i| TOP_LEVEL.iter().any(|top| i.ty == top) );

                if let Some(parent) = parent {
                    let parent_id = Some(parent.id.to_string());
                    let parent_expr: syn::Expr = syn::parse_str(&format!("&data.{}", parent.id)).unwrap();
                    controls[i].names.push(syn::Ident::new("parent", pm2::Span::call_site()));
                    controls[i].values.push(parent_expr);
                    controls[i].parent_id = parent_id;
                }
            }
        }

        // Third pass: Parent Weight
        fn compute_weight(controls: &[NwgItem], index: usize, weight: &mut u32) {
            match &controls[index].parent_id {
                Some(p) =>
                    if let Some(parent_index) = controls.iter().position(|c| &c.id == &p) {
                        compute_weight(controls, parent_index, weight);
                        *weight += 1;
                    },
                None => {}
            }
        };

        for i in 0..(controls.len()) {
            let mut weight = 0;
            compute_weight(&controls, i, &mut weight);
            controls[i].weight = weight;
        }

        // Fourth pass: Helpers
        for control in controls.iter_mut() {
            control.expand_flags();
        }

        // Fifth pass: sort by weight
        controls.sort_unstable_by(|a, b| a.weight.cmp(&b.weight));

        //println!("{:#?}", controls);

        NwgUi { data, controls }
    }

    pub fn controls(&self) -> NwgUiControls {
        NwgUiControls(self)
    }

    pub fn events(&self) -> NwgUiEvents {
        NwgUiEvents(self)
    }

    pub fn layouts(&self) -> NwgUiLayouts {
        NwgUiLayouts(self)
    }

}
<commit_msg>plug in events<commit_after>use quote::{ToTokens};

const TOP_LEVEL: &'static [&'static str] = &[
    "Window", "CanvasWindow", "TabsContainer", "Tab", "MessageWindow"
];

#[derive(Debug)]
pub struct NwgItem<'a> {
    id: &'a syn::Ident,
    parent_id: Option<String>,
    ty: &'a syn::Ident,

    names: Vec<syn::Ident>,
    values: Vec<syn::Expr>,

    weight: u32,
}

impl<'a> NwgItem<'a> {

    fn valid(field: &syn::Field) -> bool {
        field.attrs.iter().any(|attr|
            attr.path.get_ident()
                .map(|ident| ident == "nwg_control" || ident == "nwg_partial" )
                .unwrap_or(false)
        )
    }

    fn extract_type(field: &syn::Field) -> &syn::Ident {
        // TODO: extract type from nwg_control first

        match &field.ty {
            syn::Type::Path(p) => match p.path.segments.last() {
                Some(seg) => &seg.ident,
                None => panic!("Impossible to parse type for field {:?}. Try specifying it in the nwg_control attribute.", field.ident)
            },
            _ => panic!("Impossible to parse type for field {:?}. Try specifying it in the nwg_control attribute.", field.ident)
        }
    }

    fn expand_flags(&mut self) {
        let flags_index = self.names.iter().position(|n| n == "flags");
        if let Some(i) = flags_index {
            let old_flags = self.values[i].clone();
            self.values[i] = crate::controls::expand_flags(&self.id, &self.ty, old_flags);
        }
    }

    fn expand_parent(&mut self) {
        let parent_index = self.names.iter().position(|n| n == "parent");
        if parent_index.is_none() {
            return;
        }

        let i = parent_index.unwrap();
        let parent_expr: syn::Expr = match &self.values[i] {
            syn::Expr::Path(p) => {
                let id = &p.path.segments.last().unwrap().ident;
                self.parent_id = Some(id.to_string());
                syn::parse_str(&format!("&data.{}", id)).unwrap()
            },
            _ => { panic!("Bad expression type for parent of field {}", self.id); }
        };

        self.values[i] = parent_expr;
    }

}

pub struct NwgUiControls<'a>(&'a NwgUi<'a>);

impl<'a> ToTokens for NwgUiControls<'a> {

    fn to_tokens(&self, tokens: &mut pm2::TokenStream) {

        struct ControlGen<'b> {
            item: &'b NwgItem<'b>
        }

        impl<'b> ToTokens for ControlGen<'b> {
            fn to_tokens(&self, tokens: &mut pm2::TokenStream) {
                let item = &self.item;
                let ty = item.ty;
                let member = item.id;
                let names = &item.names;
                let values = &item.values;
                let control_tk = quote! {
                    nwg::#ty::builder()
                        #(.#names(#values))*
                        .build(&mut data.#member)?;
                };

                control_tk.to_tokens(tokens);
            }
        }

        let ui = &self.0;
        let controls: Vec<ControlGen> = ui.controls.iter()
            .map(|item| ControlGen { item })
            .collect();

        let controls_tk = quote! {
            #(#controls)*
        };

        controls_tk.to_tokens(tokens);
    }

}

pub struct NwgUiEvents<'a>(&'a NwgUi<'a>);

impl<'a> ToTokens for NwgUiEvents<'a> {

    fn to_tokens(&self, tokens: &mut pm2::TokenStream) {
        self.0.events.to_tokens(tokens);
    }

}

pub struct NwgUiLayouts<'a>(&'a NwgUi<'a>);

impl<'a> ToTokens for NwgUiLayouts<'a> {

    fn to_tokens(&self, tokens: &mut pm2::TokenStream) {
        let layouts_tk = quote! {

        };

        layouts_tk.to_tokens(tokens);
    }

}

pub struct NwgUi<'a> {
    pub data: &'a syn::DataStruct,
    pub controls: Vec<NwgItem<'a>>,
    pub events: crate::events::ControlEvents,
}

impl<'a> NwgUi<'a> {

    pub fn build(data: &'a syn::DataStruct) -> NwgUi<'a> {
        let named_fields = match &data.fields {
            syn::Fields::Named(n) => &n.named,
            _ => panic!("Ui structure must have named fields")
        };

        let mut controls: Vec<NwgItem> = Vec::with_capacity(named_fields.len());
        let mut events = crate::events::ControlEvents::with_capacity(named_fields.len());

        // First pass: names & default values
        for field in named_fields {
            if !NwgItem::valid(field) { continue; }

            let (names, values) = crate::controls::control_parameters(field);

            let f = NwgItem {
                id: field.ident.as_ref().unwrap(),
                parent_id: None,
                ty: NwgItem::extract_type(field),
                names,
                values,
                weight: 0,
            };

            events.generate_events(field);
            controls.push(f);
        }

        // Second pass: parent stuff
        for i in 0..(controls.len()) {
            let has_attr_parent = controls[i].names.iter().any(|n| n == "parent");
            if has_attr_parent {
                controls[i].expand_parent();
            } else {
                let parent = controls[0..i]
                    .iter().rev()
                    .find(|i| TOP_LEVEL.iter().any(|top| i.ty == top) );

                if let Some(parent) = parent {
                    let parent_id = Some(parent.id.to_string());
                    let parent_expr: syn::Expr = syn::parse_str(&format!("&data.{}", parent.id)).unwrap();
                    controls[i].names.push(syn::Ident::new("parent", pm2::Span::call_site()));
                    controls[i].values.push(parent_expr);
                    controls[i].parent_id = parent_id;
                }
            }
        }

        // Third pass: Parent Weight
        fn compute_weight(controls: &[NwgItem], index: usize, weight: &mut u32) {
            match &controls[index].parent_id {
                Some(p) =>
                    if let Some(parent_index) = controls.iter().position(|c| &c.id == &p) {
                        compute_weight(controls, parent_index, weight);
                        *weight += 1;
                    },
                None => {}
            }
        };

        for i in 0..(controls.len()) {
            let mut weight = 0;
            compute_weight(&controls, i, &mut weight);
            controls[i].weight = weight;
        }

        // Fourth pass: Helpers
        for control in controls.iter_mut() {
            control.expand_flags();
        }

        // Fifth pass: sort by weight
        controls.sort_unstable_by(|a, b| a.weight.cmp(&b.weight));

        NwgUi { data, controls, events }
    }

    pub fn controls(&self) -> NwgUiControls {
        NwgUiControls(self)
    }

    pub fn events(&self) -> NwgUiEvents {
        NwgUiEvents(self)
    }

    pub fn layouts(&self) -> NwgUiLayouts {
        NwgUiLayouts(self)
    }

}
<|endoftext|>


<commit_before>extern crate sdl2;
extern crate glm;
extern crate moho;

use std::time::{Instant, Duration};

use self::moho::resource_manager::ResourceManager;
use self::moho::resource_manager::Renderer;
use self::moho::resource_manager::TextureData;

pub struct Animation<R: Renderer> {
    texture: TextureData<R::Texture>,
    num_frames: u32,
    current_frame: u32,
    frame_duration: Duration,
    frame_instant: Option<Instant>,
    repeat: bool,
}

impl<R: Renderer> Animation<R> {
    pub fn new(texture: TextureData<R::Texture>,
               num_frames: u32,
               repeat: bool,
               frame_duration_ms: u16)
               -> Self {
        Animation {
            texture: texture,
            num_frames: num_frames,
            repeat: repeat,
            frame_duration: Duration::from_millis(frame_duration_ms as u64),
            current_frame: 0,
            frame_instant: None,
        }
    }

    pub fn update(&mut self) -> bool {
        self.current_frame = match self.frame_instant {
            None => {
                self.frame_instant = Some(Instant::now());
                0
            }
            Some(instant) => {
                if instant.elapsed() >= self.frame_duration {
                    self.frame_instant = Some(instant + self.frame_duration);
                    self.current_frame + 1
                } else {
                    self.current_frame
                }
            }
        };

        if self.current_frame >= self.num_frames {
            if self.repeat {
                self.current_frame -= self.num_frames;
                true
            } else {
                self.frame_instant = None;
                false
            }
        } else {
            true
        }
    }

    pub fn draw(&self,
                renderer: &mut ResourceManager<R>,
                center: glm::IVec2,
                dims: glm::UVec2)
                -> Result<(), String> {
        let texture_width = (self.texture.width / self.num_frames) as i32;
        let src = glm::ivec4(texture_width * self.current_frame as i32,
                             0,
                             texture_width,
                             self.texture.height as i32);
        renderer.draw_from_center(&*self.texture.texture, Some(src), center, dims, None)
    }
}
<commit_msg>split big update function in animation onto small private methods<commit_after>extern crate sdl2;
extern crate glm;
extern crate moho;

use std::time::{Instant, Duration};

use self::moho::resource_manager::ResourceManager;
use self::moho::resource_manager::Renderer;
use self::moho::resource_manager::TextureData;

pub struct Animation<R: Renderer> {
    texture: TextureData<R::Texture>,
    num_frames: u32,
    current_frame: u32,
    frame_duration: Duration,
    frame_instant: Option<Instant>,
    repeat: bool,
}

impl<R: Renderer> Animation<R> {
    pub fn new(texture: TextureData<R::Texture>,
               num_frames: u32,
               repeat: bool,
               frame_duration_ms: u16)
               -> Self {
        Animation {
            texture: texture,
            num_frames: num_frames,
            repeat: repeat,
            frame_duration: Duration::from_millis(frame_duration_ms as u64),
            current_frame: 0,
            frame_instant: None,
        }
    }

    pub fn update(&mut self) -> bool {
        self.current_frame = self.calculate_frame();
        self.is_active()
    }

    pub fn draw(&self,
                renderer: &mut ResourceManager<R>,
                center: glm::IVec2,
                dims: glm::UVec2)
                -> Result<(), String> {
        let texture_width = (self.texture.width / self.num_frames) as i32;
        let texture_height = self.texture.height as i32;
        let uv_left = texture_width * self.current_frame as i32;
        let src = glm::ivec4(uv_left, 0, texture_width, texture_height);
        renderer.draw_from_center(&*self.texture.texture, Some(src), center, dims, None)
    }

    fn is_active(&mut self) -> bool {
        if self.current_frame >= self.num_frames {
            if self.repeat {
                self.current_frame -= self.num_frames;
                true
            } else {
                self.frame_instant = None;
                false
            }
        } else {
            true
        }
    }

    fn calculate_frame(&mut self) -> u32 {
        match self.frame_instant {
            None => {
                self.frame_instant = Some(Instant::now());
                0
            }
            Some(instant) => {
                if instant.elapsed() >= self.frame_duration {
                    self.frame_instant = Some(instant + self.frame_duration);
                    self.current_frame + 1
                } else {
                    self.current_frame
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![feature(old_impl_check, plugin, core, std_misc)]

//! Computer graphics-centric math.
//!
//! This crate provides useful mathematical primitives and operations on them.
//! It is organized into one module per primitive. The core structures are
//! vectors and matrices. A strongly-typed interface is provided, to prevent
//! mixing units or violating mathematical invariants.
//!
//! Transformations are not usually done directly on matrices, but go through
//! transformation objects that can be converted to matrices. Rotations go
//! through the `Basis` types, which are guaranteed to be orthogonal matrices.
//! Despite this, one can directly create a limited rotation matrix using the
//! `look_at`, `from_angle`, `from_euler`, and `from_axis_angle` methods.
//! These are provided for convenience.

extern crate "rustc-serialize" as rustc_serialize;
extern crate rand;
#[plugin]
extern crate rand_macros;

// Re-exports

pub use array::{Array1, Array2, FixedArray};

pub use matrix::Matrix;
pub use matrix::{Matrix2, Matrix3, Matrix4};
pub use matrix::{ToMatrix2, ToMatrix3, ToMatrix4};
pub use quaternion::{Quaternion, ToQuaternion};
pub use vector::{Vector, EuclideanVector};
pub use vector::{Vector2, Vector3, Vector4};
pub use vector::{dot, vec2, vec3, vec4};

pub use angle::{rad, deg};
pub use angle::{Angle, Rad, Deg};
pub use angle::{ToRad, ToDeg};
pub use angle::bisect;
pub use angle::{sin, cos, tan, sin_cos};
pub use angle::{cot, sec, csc};
pub use angle::{acos, asin, atan, atan2};
pub use plane::Plane;
pub use point::{Point, Point2, Point3};
pub use line::{Line, Line2, Line3};
pub use ray::{Ray, Ray2, Ray3};
pub use rotation::{Rotation, Rotation2, Rotation3};
pub use rotation::{Basis3, Basis2};
pub use rotation::{ToBasis2, ToBasis3};
pub use transform::{Transform, Transform3};
pub use transform::{Decomposed, AffineMatrix3};

pub use projection::{perspective, frustum, ortho};
pub use projection::{Projection, PerspectiveFov, Perspective, Ortho};

pub use aabb::{Aabb, Aabb2, Aabb3};
pub use cylinder::Cylinder;
pub use frustum::{Frustum, FrustumPoints};
pub use intersect::Intersect;
pub use obb::{Obb2, Obb3};
pub use sphere::Sphere;

pub use approx::ApproxEq;
pub use num::{PartialOrd, BaseNum, BaseInt, BaseFloat, One, one, Zero, zero};

// Modules

mod array;

mod matrix;
mod quaternion;
mod vector;

mod angle;
mod plane;
mod point;
mod line;
mod ray;
mod rotation;
mod transform;

mod projection;

mod aabb;
mod cylinder;
mod frustum;
mod intersect;
mod obb;
mod sphere;

mod approx;
mod num;
<commit_msg>Fixed android build: added [no_link] to rand_macros<commit_after>// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![feature(old_impl_check, plugin, core, std_misc)]

//! Computer graphics-centric math.
//!
//! This crate provides useful mathematical primitives and operations on them.
//! It is organized into one module per primitive. The core structures are
//! vectors and matrices. A strongly-typed interface is provided, to prevent
//! mixing units or violating mathematical invariants.
//!
//! Transformations are not usually done directly on matrices, but go through
//! transformation objects that can be converted to matrices. Rotations go
//! through the `Basis` types, which are guaranteed to be orthogonal matrices.
//! Despite this, one can directly create a limited rotation matrix using the
//! `look_at`, `from_angle`, `from_euler`, and `from_axis_angle` methods.
//! These are provided for convenience.

extern crate "rustc-serialize" as rustc_serialize;
extern crate rand;
#[plugin]
#[no_link]
extern crate rand_macros;

// Re-exports

pub use array::{Array1, Array2, FixedArray};

pub use matrix::Matrix;
pub use matrix::{Matrix2, Matrix3, Matrix4};
pub use matrix::{ToMatrix2, ToMatrix3, ToMatrix4};
pub use quaternion::{Quaternion, ToQuaternion};
pub use vector::{Vector, EuclideanVector};
pub use vector::{Vector2, Vector3, Vector4};
pub use vector::{dot, vec2, vec3, vec4};

pub use angle::{rad, deg};
pub use angle::{Angle, Rad, Deg};
pub use angle::{ToRad, ToDeg};
pub use angle::bisect;
pub use angle::{sin, cos, tan, sin_cos};
pub use angle::{cot, sec, csc};
pub use angle::{acos, asin, atan, atan2};
pub use plane::Plane;
pub use point::{Point, Point2, Point3};
pub use line::{Line, Line2, Line3};
pub use ray::{Ray, Ray2, Ray3};
pub use rotation::{Rotation, Rotation2, Rotation3};
pub use rotation::{Basis3, Basis2};
pub use rotation::{ToBasis2, ToBasis3};
pub use transform::{Transform, Transform3};
pub use transform::{Decomposed, AffineMatrix3};

pub use projection::{perspective, frustum, ortho};
pub use projection::{Projection, PerspectiveFov, Perspective, Ortho};

pub use aabb::{Aabb, Aabb2, Aabb3};
pub use cylinder::Cylinder;
pub use frustum::{Frustum, FrustumPoints};
pub use intersect::Intersect;
pub use obb::{Obb2, Obb3};
pub use sphere::Sphere;

pub use approx::ApproxEq;
pub use num::{PartialOrd, BaseNum, BaseInt, BaseFloat, One, one, Zero, zero};

// Modules

mod array;

mod matrix;
mod quaternion;
mod vector;

mod angle;
mod plane;
mod point;
mod line;
mod ray;
mod rotation;
mod transform;

mod projection;

mod aabb;
mod cylinder;
mod frustum;
mod intersect;
mod obb;
mod sphere;

mod approx;
mod num;
<|endoftext|>


<commit_before>//! This module is concerned with finding methods that a given type provides.
//! For details about how this works in rustc, see the method lookup page in the
//! [rustc guide](https://rust-lang.github.io/rustc-guide/method-lookup.html)
//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs.
use std::sync::Arc;

use rustc_hash::FxHashMap;

use crate::{
    HirDatabase, Module, Crate, Name, Function, Trait,
    impl_block::{ImplId, ImplBlock, ImplItem},
    ty::{Ty, TypeCtor},
    nameres::CrateModuleId,
    resolve::Resolver,
    traits::TraitItem,
    generics::HasGenericParams,
    ty::primitive::{UncertainIntTy, UncertainFloatTy}
};
use super::{TraitRef, Canonical, autoderef};

/// This is used as a key for indexing impls.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum TyFingerprint {
    Apply(TypeCtor),
}

impl TyFingerprint {
    /// Creates a TyFingerprint for looking up an impl. Only certain types can
    /// have impls: if we have some `struct S`, we can have an `impl S`, but not
    /// `impl &S`. Hence, this will return `None` for reference types and such.
    fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
        match ty {
            Ty::Apply(a_ty) => Some(TyFingerprint::Apply(a_ty.ctor)),
            _ => None,
        }
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct CrateImplBlocks {
    /// To make sense of the CrateModuleIds, we need the source root.
    krate: Crate,
    impls: FxHashMap<TyFingerprint, Vec<(CrateModuleId, ImplId)>>,
    impls_by_trait: FxHashMap<Trait, Vec<(CrateModuleId, ImplId)>>,
}

impl CrateImplBlocks {
    pub fn lookup_impl_blocks<'a>(&'a self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + 'a {
        let fingerprint = TyFingerprint::for_impl(ty);
        fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flat_map(|i| i.iter()).map(
            move |(module_id, impl_id)| {
                let module = Module { krate: self.krate, module_id: *module_id };
                ImplBlock::from_id(module, *impl_id)
            },
        )
    }

    pub fn lookup_impl_blocks_for_trait<'a>(
        &'a self,
        tr: &Trait,
    ) -> impl Iterator<Item = ImplBlock> + 'a {
        self.impls_by_trait.get(&tr).into_iter().flat_map(|i| i.iter()).map(
            move |(module_id, impl_id)| {
                let module = Module { krate: self.krate, module_id: *module_id };
                ImplBlock::from_id(module, *impl_id)
            },
        )
    }

    fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) {
        let module_impl_blocks = db.impls_in_module(module.clone());

        for (impl_id, _) in module_impl_blocks.impls.iter() {
            let impl_block = ImplBlock::from_id(module_impl_blocks.module, impl_id);

            let target_ty = impl_block.target_ty(db);

            if impl_block.target_trait(db).is_some() {
                if let Some(tr) = impl_block.target_trait_ref(db) {
                    self.impls_by_trait
                        .entry(tr.trait_)
                        .or_insert_with(Vec::new)
                        .push((module.module_id, impl_id));
                }
            } else {
                if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
                    self.impls
                        .entry(target_ty_fp)
                        .or_insert_with(Vec::new)
                        .push((module.module_id, impl_id));
                }
            }
        }

        for child in module.children(db) {
            self.collect_recursive(db, &child);
        }
    }

    pub(crate) fn impls_in_crate_query(
        db: &impl HirDatabase,
        krate: Crate,
    ) -> Arc<CrateImplBlocks> {
        let mut crate_impl_blocks = CrateImplBlocks {
            krate,
            impls: FxHashMap::default(),
            impls_by_trait: FxHashMap::default(),
        };
        if let Some(module) = krate.root_module(db) {
            crate_impl_blocks.collect_recursive(db, &module);
        }
        Arc::new(crate_impl_blocks)
    }
}

fn def_crate(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<Crate> {
    match ty {
        Ty::Apply(a_ty) => match a_ty.ctor {
            TypeCtor::Adt(def_id) => def_id.krate(db),
            TypeCtor::Bool => db.lang_item(cur_crate, "bool".into())?.krate(db),
            TypeCtor::Char => db.lang_item(cur_crate, "char".into())?.krate(db),
            TypeCtor::Float(UncertainFloatTy::Known(f)) => {
                db.lang_item(cur_crate, f.ty_to_string().into())?.krate(db)
            }
            TypeCtor::Int(UncertainIntTy::Known(i)) => {
                db.lang_item(cur_crate, i.ty_to_string().into())?.krate(db)
            }
            TypeCtor::Str => db.lang_item(cur_crate, "str".into())?.krate(db),
            _ => None,
        },
        _ => None,
    }
}

/// Look up the method with the given name, returning the actual autoderefed
/// receiver type (but without autoref applied yet).
pub(crate) fn lookup_method(
    ty: &Canonical<Ty>,
    db: &impl HirDatabase,
    name: &Name,
    resolver: &Resolver,
) -> Option<(Ty, Function)> {
    iterate_method_candidates(ty, db, resolver, Some(name), |ty, f| Some((ty.clone(), f)))
}

// This would be nicer if it just returned an iterator, but that runs into
// lifetime problems, because we need to borrow temp `CrateImplBlocks`.
pub(crate) fn iterate_method_candidates<T>(
    ty: &Canonical<Ty>,
    db: &impl HirDatabase,
    resolver: &Resolver,
    name: Option<&Name>,
    mut callback: impl FnMut(&Ty, Function) -> Option<T>,
) -> Option<T> {
    // For method calls, rust first does any number of autoderef, and then one
    // autoref (i.e. when the method takes &self or &mut self). We just ignore
    // the autoref currently -- when we find a method matching the given name,
    // we assume it fits.

    // Also note that when we've got a receiver like &S, even if the method we
    // find in the end takes &self, we still do the autoderef step (just as
    // rustc does an autoderef and then autoref again).

    let krate = resolver.krate()?;
    for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) {
        if let Some(result) = iterate_inherent_methods(&derefed_ty, db, name, krate, &mut callback)
        {
            return Some(result);
        }
        if let Some(result) =
            iterate_trait_method_candidates(&derefed_ty, db, resolver, name, &mut callback)
        {
            return Some(result);
        }
    }
    None
}

fn iterate_trait_method_candidates<T>(
    ty: &Canonical<Ty>,
    db: &impl HirDatabase,
    resolver: &Resolver,
    name: Option<&Name>,
    mut callback: impl FnMut(&Ty, Function) -> Option<T>,
) -> Option<T> {
    let krate = resolver.krate()?;
    'traits: for t in resolver.traits_in_scope(db) {
        let data = t.trait_data(db);
        // we'll be lazy about checking whether the type implements the
        // trait, but if we find out it doesn't, we'll skip the rest of the
        // iteration
        let mut known_implemented = false;
        for item in data.items() {
            if let TraitItem::Function(m) = *item {
                let data = m.data(db);
                if name.map_or(true, |name| data.name() == name) && data.has_self_param() {
                    if !known_implemented {
                        let trait_ref = canonical_trait_ref(db, t, ty.clone());
                        if db.implements(krate, trait_ref).is_none() {
                            continue 'traits;
                        }
                    }
                    known_implemented = true;
                    if let Some(result) = callback(&ty.value, m) {
                        return Some(result);
                    }
                }
            }
        }
    }
    None
}

fn iterate_inherent_methods<T>(
    ty: &Canonical<Ty>,
    db: &impl HirDatabase,
    name: Option<&Name>,
    krate: Crate,
    mut callback: impl FnMut(&Ty, Function) -> Option<T>,
) -> Option<T> {
    let krate = match def_crate(db, krate, &ty.value) {
        Some(krate) => krate,
        None => return None,
    };
    let impls = db.impls_in_crate(krate);

    for impl_block in impls.lookup_impl_blocks(&ty.value) {
        for item in impl_block.items(db) {
            if let ImplItem::Method(f) = item {
                let data = f.data(db);
                if name.map_or(true, |name| data.name() == name) && data.has_self_param() {
                    if let Some(result) = callback(&ty.value, f) {
                        return Some(result);
                    }
                }
            }
        }
    }
    None
}

impl Ty {
    // This would be nicer if it just returned an iterator, but that runs into
    // lifetime problems, because we need to borrow temp `CrateImplBlocks`.
    pub fn iterate_impl_items<T>(
        self,
        db: &impl HirDatabase,
        krate: Crate,
        mut callback: impl FnMut(ImplItem) -> Option<T>,
    ) -> Option<T> {
        let krate = def_crate(db, krate, &self)?;
        let impls = db.impls_in_crate(krate);

        for impl_block in impls.lookup_impl_blocks(&self) {
            for item in impl_block.items(db) {
                if let Some(result) = callback(item) {
                    return Some(result);
                }
            }
        }
        None
    }
}

/// This creates Substs for a trait with the given Self type and type variables
/// for all other parameters, to query Chalk with it.
fn canonical_trait_ref(
    db: &impl HirDatabase,
    trait_: Trait,
    self_ty: Canonical<Ty>,
) -> Canonical<TraitRef> {
    let mut substs = Vec::new();
    let generics = trait_.generic_params(db);
    let num_vars = self_ty.num_vars;
    substs.push(self_ty.value);
    substs.extend(
        generics
            .params_including_parent()
            .into_iter()
            .skip(1)
            .enumerate()
            .map(|(i, _p)| Ty::Bound((i + num_vars) as u32)),
    );
    Canonical {
        num_vars: substs.len() - 1 + self_ty.num_vars,
        value: TraitRef { trait_, substs: substs.into() },
    }
}
<commit_msg>Method resolution for slices<commit_after>//! This module is concerned with finding methods that a given type provides.
//! For details about how this works in rustc, see the method lookup page in the
//! [rustc guide](https://rust-lang.github.io/rustc-guide/method-lookup.html)
//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs.
use std::sync::Arc;

use arrayvec::ArrayVec;
use rustc_hash::FxHashMap;

use crate::{
    HirDatabase, Module, Crate, Name, Function, Trait,
    impl_block::{ImplId, ImplBlock, ImplItem},
    ty::{Ty, TypeCtor},
    nameres::CrateModuleId,
    resolve::Resolver,
    traits::TraitItem,
    generics::HasGenericParams,
    ty::primitive::{UncertainIntTy, UncertainFloatTy}
};
use super::{TraitRef, Canonical, autoderef};

/// This is used as a key for indexing impls.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum TyFingerprint {
    Apply(TypeCtor),
}

impl TyFingerprint {
    /// Creates a TyFingerprint for looking up an impl. Only certain types can
    /// have impls: if we have some `struct S`, we can have an `impl S`, but not
    /// `impl &S`. Hence, this will return `None` for reference types and such.
    fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
        match ty {
            Ty::Apply(a_ty) => Some(TyFingerprint::Apply(a_ty.ctor)),
            _ => None,
        }
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct CrateImplBlocks {
    /// To make sense of the CrateModuleIds, we need the source root.
    krate: Crate,
    impls: FxHashMap<TyFingerprint, Vec<(CrateModuleId, ImplId)>>,
    impls_by_trait: FxHashMap<Trait, Vec<(CrateModuleId, ImplId)>>,
}

impl CrateImplBlocks {
    pub fn lookup_impl_blocks<'a>(&'a self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + 'a {
        let fingerprint = TyFingerprint::for_impl(ty);
        fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flat_map(|i| i.iter()).map(
            move |(module_id, impl_id)| {
                let module = Module { krate: self.krate, module_id: *module_id };
                ImplBlock::from_id(module, *impl_id)
            },
        )
    }

    pub fn lookup_impl_blocks_for_trait<'a>(
        &'a self,
        tr: &Trait,
    ) -> impl Iterator<Item = ImplBlock> + 'a {
        self.impls_by_trait.get(&tr).into_iter().flat_map(|i| i.iter()).map(
            move |(module_id, impl_id)| {
                let module = Module { krate: self.krate, module_id: *module_id };
                ImplBlock::from_id(module, *impl_id)
            },
        )
    }

    fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) {
        let module_impl_blocks = db.impls_in_module(module.clone());

        for (impl_id, _) in module_impl_blocks.impls.iter() {
            let impl_block = ImplBlock::from_id(module_impl_blocks.module, impl_id);

            let target_ty = impl_block.target_ty(db);

            if impl_block.target_trait(db).is_some() {
                if let Some(tr) = impl_block.target_trait_ref(db) {
                    self.impls_by_trait
                        .entry(tr.trait_)
                        .or_insert_with(Vec::new)
                        .push((module.module_id, impl_id));
                }
            } else {
                if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
                    self.impls
                        .entry(target_ty_fp)
                        .or_insert_with(Vec::new)
                        .push((module.module_id, impl_id));
                }
            }
        }

        for child in module.children(db) {
            self.collect_recursive(db, &child);
        }
    }

    pub(crate) fn impls_in_crate_query(
        db: &impl HirDatabase,
        krate: Crate,
    ) -> Arc<CrateImplBlocks> {
        let mut crate_impl_blocks = CrateImplBlocks {
            krate,
            impls: FxHashMap::default(),
            impls_by_trait: FxHashMap::default(),
        };
        if let Some(module) = krate.root_module(db) {
            crate_impl_blocks.collect_recursive(db, &module);
        }
        Arc::new(crate_impl_blocks)
    }
}

fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> {
    macro_rules! lang_item_crate {
        ($db:expr, $cur_crate:expr, $($name:expr),+ $(,)?) => {{
            let mut v = ArrayVec::<[Crate; 2]>::new();
            $(
                v.push($db.lang_item($cur_crate, $name.into())?.krate($db)?);
            )+
            Some(v)
        }};
    }

    match ty {
        Ty::Apply(a_ty) => match a_ty.ctor {
            TypeCtor::Adt(def_id) => Some(std::iter::once(def_id.krate(db)?).collect()),
            TypeCtor::Bool => lang_item_crate![db, cur_crate, "bool"],
            TypeCtor::Char => lang_item_crate![db, cur_crate, "char"],
            TypeCtor::Float(UncertainFloatTy::Known(f)) => {
                lang_item_crate![db, cur_crate, f.ty_to_string()]
            }
            TypeCtor::Int(UncertainIntTy::Known(i)) => {
                lang_item_crate![db, cur_crate, i.ty_to_string()]
            }
            TypeCtor::Str => lang_item_crate![db, cur_crate, "str"],
            TypeCtor::Slice => lang_item_crate![db, cur_crate, "slice_alloc", "slice"],
            _ => None,
        },
        _ => None,
    }
}

/// Look up the method with the given name, returning the actual autoderefed
/// receiver type (but without autoref applied yet).
pub(crate) fn lookup_method(
    ty: &Canonical<Ty>,
    db: &impl HirDatabase,
    name: &Name,
    resolver: &Resolver,
) -> Option<(Ty, Function)> {
    iterate_method_candidates(ty, db, resolver, Some(name), |ty, f| Some((ty.clone(), f)))
}

// This would be nicer if it just returned an iterator, but that runs into
// lifetime problems, because we need to borrow temp `CrateImplBlocks`.
pub(crate) fn iterate_method_candidates<T>(
    ty: &Canonical<Ty>,
    db: &impl HirDatabase,
    resolver: &Resolver,
    name: Option<&Name>,
    mut callback: impl FnMut(&Ty, Function) -> Option<T>,
) -> Option<T> {
    // For method calls, rust first does any number of autoderef, and then one
    // autoref (i.e. when the method takes &self or &mut self). We just ignore
    // the autoref currently -- when we find a method matching the given name,
    // we assume it fits.

    // Also note that when we've got a receiver like &S, even if the method we
    // find in the end takes &self, we still do the autoderef step (just as
    // rustc does an autoderef and then autoref again).

    let krate = resolver.krate()?;
    for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) {
        if let Some(result) = iterate_inherent_methods(&derefed_ty, db, name, krate, &mut callback)
        {
            return Some(result);
        }
        if let Some(result) =
            iterate_trait_method_candidates(&derefed_ty, db, resolver, name, &mut callback)
        {
            return Some(result);
        }
    }
    None
}

fn iterate_trait_method_candidates<T>(
    ty: &Canonical<Ty>,
    db: &impl HirDatabase,
    resolver: &Resolver,
    name: Option<&Name>,
    mut callback: impl FnMut(&Ty, Function) -> Option<T>,
) -> Option<T> {
    let krate = resolver.krate()?;
    'traits: for t in resolver.traits_in_scope(db) {
        let data = t.trait_data(db);
        // we'll be lazy about checking whether the type implements the
        // trait, but if we find out it doesn't, we'll skip the rest of the
        // iteration
        let mut known_implemented = false;
        for item in data.items() {
            if let TraitItem::Function(m) = *item {
                let data = m.data(db);
                if name.map_or(true, |name| data.name() == name) && data.has_self_param() {
                    if !known_implemented {
                        let trait_ref = canonical_trait_ref(db, t, ty.clone());
                        if db.implements(krate, trait_ref).is_none() {
                            continue 'traits;
                        }
                    }
                    known_implemented = true;
                    if let Some(result) = callback(&ty.value, m) {
                        return Some(result);
                    }
                }
            }
        }
    }
    None
}

fn iterate_inherent_methods<T>(
    ty: &Canonical<Ty>,
    db: &impl HirDatabase,
    name: Option<&Name>,
    krate: Crate,
    mut callback: impl FnMut(&Ty, Function) -> Option<T>,
) -> Option<T> {
    for krate in def_crates(db, krate, &ty.value)? {
        let impls = db.impls_in_crate(krate);

        for impl_block in impls.lookup_impl_blocks(&ty.value) {
            for item in impl_block.items(db) {
                if let ImplItem::Method(f) = item {
                    let data = f.data(db);
                    if name.map_or(true, |name| data.name() == name) && data.has_self_param() {
                        if let Some(result) = callback(&ty.value, f) {
                            return Some(result);
                        }
                    }
                }
            }
        }
    }
    None
}

impl Ty {
    // This would be nicer if it just returned an iterator, but that runs into
    // lifetime problems, because we need to borrow temp `CrateImplBlocks`.
    pub fn iterate_impl_items<T>(
        self,
        db: &impl HirDatabase,
        krate: Crate,
        mut callback: impl FnMut(ImplItem) -> Option<T>,
    ) -> Option<T> {
        for krate in def_crates(db, krate, &self)? {
            let impls = db.impls_in_crate(krate);

            for impl_block in impls.lookup_impl_blocks(&self) {
                for item in impl_block.items(db) {
                    if let Some(result) = callback(item) {
                        return Some(result);
                    }
                }
            }
        }
        None
    }
}

/// This creates Substs for a trait with the given Self type and type variables
/// for all other parameters, to query Chalk with it.
fn canonical_trait_ref(
    db: &impl HirDatabase,
    trait_: Trait,
    self_ty: Canonical<Ty>,
) -> Canonical<TraitRef> {
    let mut substs = Vec::new();
    let generics = trait_.generic_params(db);
    let num_vars = self_ty.num_vars;
    substs.push(self_ty.value);
    substs.extend(
        generics
            .params_including_parent()
            .into_iter()
            .skip(1)
            .enumerate()
            .map(|(i, _p)| Ty::Bound((i + num_vars) as u32)),
    );
    Canonical {
        num_vars: substs.len() - 1 + self_ty.num_vars,
        value: TraitRef { trait_, substs: substs.into() },
    }
}
<|endoftext|>