<commit_before>use std::collections::BTreeMap;
use rustc_serialize::json::{ToJson, Json};
use uuid::Uuid;
use std::fmt;

use youtube;
use soundcloud;
use error::Error;
use super::{conn, PaginatedCollection};

#[derive(Debug, Clone)]
pub enum Provider {
    YouTube,
    SoundCloud,
    Raw
}
impl PartialEq for Provider {
    fn eq(&self, p: &Provider) -> bool {
        match *self {
            Provider::YouTube    => match *p { Provider::YouTube    => true, _ => false },
            Provider::SoundCloud => match *p { Provider::SoundCloud => true, _ => false },
            Provider::Raw        => match *p { Provider::Raw        => true, _ => false }
        }
    }
}
impl Provider {
    fn to_string(&self) -> String {
        match *self {
            Provider::YouTube    => "YouTube",
            Provider::SoundCloud => "SoundCloud",
            Provider::Raw        => "Raw",
        }.to_string()
    }
    pub fn new(str: String) -> Provider {
        match str.as_ref() {
            "YouTube"    => Provider::YouTube,
            "youtube"    => Provider::YouTube,
            "SoundCloud" => Provider::SoundCloud,
            "soundcloud" => Provider::SoundCloud,
            _            => Provider::Raw,
        }
    }
}

impl ToJson for Provider {
    fn to_json(&self) -> Json {
        self.to_string().to_json()
    }
}

impl fmt::Display for Provider {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({})", self.to_string())
    }
}

#[derive(Debug, Clone)]
pub struct Track {
    pub id:         Uuid,
    pub provider:   Provider,
    pub title:      String,
    pub url:        String,
    pub identifier: String
}

impl PartialEq for Track {
    fn eq(&self, t: &Track) -> bool {
        return self.identifier == t.identifier && self.provider == t.provider
    }
}

impl ToJson for Track {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("id".to_string(),         self.id.to_string().to_json());
        d.insert("provider".to_string(),   self.provider.to_json());
        d.insert("identifier".to_string(), self.identifier.to_json());
        d.insert("title".to_string(),      self.title.to_json());
        d.insert("url".to_string(),        self.url.to_json());
        Json::Object(d)
    }
}

impl fmt::Display for Track {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}:{}", self.provider, self.identifier)
    }
}

impl Track {
    pub fn from_yt_playlist_item(item: &youtube::PlaylistItem) -> Track {
        let identifier = (*item).snippet.resourceId["videoId"].to_string();
        Track {
                    id: Uuid::new_v4(),
              provider: Provider::YouTube,
                 title: (*item).snippet.title.to_string(),
                   url: format!("https://www.youtube.com/watch/?v={}", identifier),
            identifier: identifier
        }
    }
    pub fn from_sc_track(track: &soundcloud::Track) -> Track {
        Track {
                    id: Uuid::new_v4(),
              provider: Provider::SoundCloud,
                 title: (*track).title.to_string(),
                   url: (*track).permalink_url.to_string(),
            identifier: (*track).id.to_string()
        }
    }
    pub fn find_by_id(id: &str) -> Result<Track, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, provider, title, url, identifier
                                 FROM tracks WHERE id = $1").unwrap();
        let uuid = try!(Uuid::parse_str(id).map_err(|_| Error::Unprocessable));
        for row in stmt.query(&[&uuid]).unwrap().iter() {
            let track = Track {
                      id: row.get(0),
                provider: Provider::new(row.get(1)),
                   title: row.get(2),
                     url: row.get(3),
              identifier: row.get(4)
            };
            return Ok(track);
        }
        return Err(Error::NotFound)
    }

    pub fn find_by(provider: &Provider, identifier: &str) -> Result<Track, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id,  provider, title, url, identifier
                                 FROM tracks WHERE provider = $1
                                 AND identifier = $2").unwrap();
        for row in stmt.query(&[&(*provider).to_string(), &identifier]).unwrap().iter() {
            let track = Track {
                      id: row.get(0),
                provider: Provider::new(row.get(1)),
                   title: row.get(2),
                     url: row.get(3),
              identifier: row.get(4)
            };
            return Ok(track);
        }
        return Err(Error::NotFound)
    }

    pub fn find_by_entry_id(entry_id: Uuid) -> Vec<Track> {
        let mut tracks = Vec::new();
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT t.id,
                                        t.provider,
                                        t.title,
                                        t.url,
                                        t.identifier
                                 FROM tracks t LEFT JOIN track_entries te
                                 ON t.id = te.track_id
                                 WHERE te.entry_id = $1").unwrap();
        for row in stmt.query(&[&entry_id]).unwrap().iter() {
            tracks.push(Track {
                      id: row.get(0),
                provider: Provider::new(row.get(1)),
                   title: row.get(2),
                     url: row.get(3),
              identifier: row.get(4)
            });
        }
        return tracks
    }

    pub fn find(page: i64, per_page: i64) -> PaginatedCollection<Track> {
        let mut tracks = Vec::new();
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, provider, title, url, identifier FROM tracks LIMIT $2 OFFSET $1").unwrap();
        let offset = page * per_page;
        for row in stmt.query(&[&offset, &per_page]).unwrap().iter() {
            let track = Track {
                      id: row.get(0),
                provider: Provider::new(row.get(1)),
                   title: row.get(2),
                     url: row.get(3),
              identifier: row.get(4)
            };
            tracks.push(track);
        }
        let mut total: i64 = 0;
        for row in conn.query("SELECT COUNT(*) FROM tracks", &[]).unwrap().iter() {
            total = row.get(0);
        }
        PaginatedCollection {
            page:     page,
            per_page: per_page,
            total:    total,
            items:    tracks,
        }
    }

    pub fn create(provider: Provider,
                  title: String,
                  url: String,
                  identifier: String) -> Result<Track, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("INSERT INTO tracks (provider, title, url, identifier)
                                 VALUES ($1, $2, $3, $4) RETURNING id").unwrap();
        let rows = try!(stmt.query(&[&provider.to_string(), &title, &url, &identifier]));
        for row in rows.iter() {
            let track = Track {
                        id: row.get(0),
                  provider: provider,
                     title: title,
                       url: url,
                identifier: identifier
            };
            return Ok(track);
        }
        Err(Error::Unexpected)
    }

    pub fn find_or_create(provider: Provider,
                          title: String,
                          url: String,
                          identifier: String) -> Result<Track, Error> {
        return match Track::find_by(&provider, &identifier) {
            Ok(track) => Ok(track),
            Err(_)    => Track::create(provider, title, url, identifier)
        }
    }

    pub fn save(&self) -> Result<(), Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("UPDATE track SET title=$1, url=$2 WHERE id = $3").unwrap();
        let result = stmt.query(&[&self.title, &self.url, &self.id.to_string()]);
        match result {
            Ok(_)  => Ok(()),
            Err(_) => Err(Error::Unexpected)
        }
    }
}

pub struct Playlist {
    pub title:  String,
    pub tracks: Vec<Track>,
}

<commit_msg>Update model::Track. Add properties<commit_after>use std::collections::BTreeMap;
use rustc_serialize::json::{ToJson, Json};
use postgres;
use uuid::Uuid;
use std::fmt;

use youtube;
use soundcloud;
use error::Error;
use super::{conn, PaginatedCollection};

#[derive(Debug, Copy, Clone)]
pub enum Provider {
    YouTube,
    SoundCloud,
    Raw
}
impl PartialEq for Provider {
    fn eq(&self, p: &Provider) -> bool {
        match *self {
            Provider::YouTube    => match *p { Provider::YouTube    => true, _ => false },
            Provider::SoundCloud => match *p { Provider::SoundCloud => true, _ => false },
            Provider::Raw        => match *p { Provider::Raw        => true, _ => false }
        }
    }
}
impl Provider {
    fn to_string(&self) -> String {
        match *self {
            Provider::YouTube    => "YouTube",
            Provider::SoundCloud => "SoundCloud",
            Provider::Raw        => "Raw",
        }.to_string()
    }
    pub fn new(str: String) -> Provider {
        match str.as_ref() {
            "YouTube"    => Provider::YouTube,
            "youtube"    => Provider::YouTube,
            "SoundCloud" => Provider::SoundCloud,
            "soundcloud" => Provider::SoundCloud,
            _            => Provider::Raw,
        }
    }
}

impl ToJson for Provider {
    fn to_json(&self) -> Json {
        self.to_string().to_json()
    }
}

impl fmt::Display for Provider {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({})", self.to_string())
    }
}

#[derive(Debug, Clone)]
pub struct Track {
    pub id:            Uuid,
    pub provider:      Provider,
    pub identifier:    String,
    pub url:           String,
    pub title:         String,
    pub description:   Option<String>,
    pub artist:        Option<String>,
    pub thumbnail_url: Option<String>,
    pub artwork_url:   Option<String>,
    pub duration:      i32,
}

impl PartialEq for Track {
    fn eq(&self, t: &Track) -> bool {
        return self.identifier == t.identifier && self.provider == t.provider
    }
}

impl ToJson for Track {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("id".to_string()           , self.id.to_string().to_json());
        d.insert("provider".to_string()     , self.provider.to_json());
        d.insert("identifier".to_string()   , self.identifier.to_json());
        d.insert("url".to_string()          , self.url.to_json());
        d.insert("title".to_string()        , self.title.to_json());
        d.insert("description".to_string()  , self.description.to_json());
        d.insert("artist".to_string()       , self.artist.to_json());
        d.insert("thumbnail_url".to_string(), self.thumbnail_url.to_json());
        d.insert("artwork_url".to_string()  , self.artwork_url.to_json());
        d.insert("duration".to_string()     , self.duration.to_json());
        Json::Object(d)
    }
}

impl fmt::Display for Track {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}:{}", self.provider, self.identifier)
    }
}

impl Track {
    pub fn new(provider: Provider, identifier: String) -> Track {
        Track {
            id:            Uuid::new_v4(),
            provider:      provider,
            identifier:    identifier,
            url:           "".to_string(),
            title:         "".to_string(),
            description:   None,
            artist:        None,
            thumbnail_url: None,
            artwork_url:   None,
            duration:      0,
        }
    }
    pub fn from_yt_playlist_item(item: &youtube::PlaylistItem) -> Track {
        let identifier = (*item).snippet.resourceId["videoId"].to_string();
        Track::new(Provider::YouTube, identifier.to_string())
            .update_with_yt_playlist_item(item)
            .clone()
    }
    pub fn from_sc_track(track: &soundcloud::Track) -> Track {
        Track::new(Provider::SoundCloud, (*track).id.to_string())
            .update_with_sc_track(track)
            .clone()
    }

    pub fn update_with_yt_video(&mut self, video: &youtube::Video) -> &mut Track {
        self.provider      = Provider::YouTube;
        self.identifier    = video.id.to_string();
        self.url           = format!("https://www.youtube.com/watch/?v={}", video.id);
        self.title         = video.snippet.title.to_string();
        self.description   = Some(video.snippet.description.to_string());
        self.artist        = Some(video.snippet.channelTitle.to_string());
        self.thumbnail_url = Some(video.snippet.thumbnails["default"].url.to_string());
        self.artwork_url   = Some(video.snippet.thumbnails["maxres"].url.to_string());
        self
    }

    pub fn update_with_yt_playlist_item(&mut self, item: &youtube::PlaylistItem) -> &mut Track {
        self.provider      = Provider::YouTube;
        self.identifier    = item.id.to_string();
        self.url           = format!("https://www.youtube.com/watch/?v={}", item.id);
        self.title         = item.snippet.title.to_string();
        self.description   = Some(item.snippet.description.to_string());
        self.artist        = Some(item.snippet.channelTitle.to_string());
        self.thumbnail_url = Some(item.snippet.thumbnails["default"].url.to_string());
        self.artwork_url   = Some(item.snippet.thumbnails["maxres"].url.to_string());
        self
    }

    pub fn update_with_sc_track(&mut self, track: &soundcloud::Track) -> &mut Track {
        self.provider      = Provider::SoundCloud;
        self.identifier    = track.id.to_string();
        self.url           = track.permalink_url.to_string();
        self.title         = track.title.to_string();
        self.description   = Some(track.description.to_string());
        self.artist        = track.artist.clone();
        self.thumbnail_url = track.artwork_url.clone();
        self.artwork_url   = track.artwork_url.clone();
        self
    }

    fn rows_to_tracks(rows: postgres::rows::Rows) -> Vec<Track> {
        let mut tracks = Vec::new();
        for row in rows.iter() {
            let track = Track {
                id:            row.get(0),
                provider:      Provider::new(row.get(1)),
                identifier:    row.get(2),
                url:           row.get(3),
                title:         row.get(4),
                description:   row.get(5),
                artist:        row.get(6),
                thumbnail_url: row.get(7),
                artwork_url:   row.get(8),
                duration:      row.get(9)
            };
            tracks.push(track)
        }
        tracks
    }

    pub fn find_by_id(id: &str) -> Result<Track, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, provider, identifier, url, title, description,
                                        artist, thumbnail_url, artwork_url, duration
                                 FROM tracks WHERE id = $1").unwrap();
        let uuid   = try!(Uuid::parse_str(id).map_err(|_| Error::Unprocessable));
        let rows   = stmt.query(&[&uuid]).unwrap();
        let tracks = Track::rows_to_tracks(rows);
        if tracks.len() > 0 {
            return Ok(tracks[0].clone());
        }
        return Err(Error::NotFound)
    }

    pub fn find_by(provider: &Provider, identifier: &str) -> Result<Track, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, provider, identifier, url, title, description,
                                        artist, thumbnail_url, artwork_url, duration
                                 FROM tracks WHERE provider = $1
                                 AND identifier = $2").unwrap();
        let rows = stmt.query(&[&(*provider).to_string(), &identifier]).unwrap();
        let tracks = Track::rows_to_tracks(rows);
        if tracks.len() > 0 {
            return Ok(tracks[0].clone());
        }
        return Err(Error::NotFound)
    }

    pub fn find_by_entry_id(entry_id: Uuid) -> Vec<Track> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT t.id, t.provider, t.identifier, t.url, t.title, t.description,
                                        t.artist, t.thumbnail_url, t.artwork_url, t.duration
                                 FROM tracks t LEFT JOIN track_entries te
                                 ON t.id = te.track_id
                                 WHERE te.entry_id = $1").unwrap();
        let rows = stmt.query(&[&entry_id]).unwrap();
        Track::rows_to_tracks(rows)
    }

    pub fn find(page: i64, per_page: i64) -> PaginatedCollection<Track> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, provider, identifier, url, title, description,
                                        artist, thumbnail_url, artwork_url, duration
                                 FROM tracks LIMIT $2 OFFSET $1").unwrap();
        let offset = page * per_page;
        let rows   = stmt.query(&[&offset, &per_page]).unwrap();
        let tracks = Track::rows_to_tracks(rows);
        let mut total: i64 = 0;
        for row in conn.query("SELECT COUNT(*) FROM tracks", &[]).unwrap().iter() {
            total = row.get(0);
        }
        PaginatedCollection {
            page:     page,
            per_page: per_page,
            total:    total,
            items:    tracks,
        }
    }

    pub fn create(&self) -> Result<Track, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("INSERT INTO tracks (provider, identifier, url, title)
                                 VALUES ($1, $2, $3, $4) RETURNING id").unwrap();
        let rows = try!(stmt.query(&[&self.provider.to_string(), &self.identifier, &self.url, &self.title]));
        let mut track = self.clone();
        for row in rows.iter() {
            track.id = row.get(0);
        }
        Ok(track)
    }

    pub fn find_or_create(provider: Provider, identifier: String) -> Result<Track, Error> {
        return match Track::find_by(&provider, &identifier) {
            Ok(track) => Ok(track),
            Err(_)    => Track::new(provider, identifier).create()
        }
    }

    pub fn save(&self) -> Result<(), Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("UPDATE tracks SET
                                 provider      = $2,
                                 identifier    = $3,
                                 url           = $4,
                                 title         = $5,
                                 description   = $6,
                                 artist        = $7,
                                 thumbnail_url = $8,
                                 artwork_url   = $9,
                                 duration      = $10
                                 WHERE id = $1").unwrap();
        let result = stmt.query(&[&self.id,
                                  &self.provider.to_string(),
                                  &self.identifier,
                                  &self.url,
                                  &self.title,
                                  &self.description,
                                  &self.artist,
                                  &self.thumbnail_url,
                                  &self.artwork_url,
                                  &self.duration]);
        match result {
            Ok(_)  => Ok(()),
            Err(_) => Err(Error::Unexpected)
        }
    }
}

pub struct Playlist {
    pub title:  String,
    pub tracks: Vec<Track>,
}

<|endoftext|>


<commit_before>use std::error::Error;
use std::fmt;

use ansi_term::{Color, Style};

/// Holds information about how to style a module
pub struct ModuleStyle {
    pub background: Color,
    pub foreground: Color,
    /// Attributes like bold, italicized, underlined, etc...
    pub text_properties: Vec<Style>,
}

/// Attempts to convert a string into an `ansi_term::Color`.
///
/// Returns a `TryFromError` if the provided string doesn't match
/// any of the colors defined in crate `ansi_term`.
pub fn try_color_from_str(s: &str) -> Result<Color, TryFromError> {
    match s {
        "black" => Ok(Color::Black),
        "red" => Ok(Color::Red),
        "green" => Ok(Color::Green),
        "yellow" => Ok(Color::Yellow),
        "blue" => Ok(Color::Blue),
        "purple" => Ok(Color::Purple),
        "cyan" => Ok(Color::Cyan),
        "white" => Ok(Color::White),
        _ => Err(TryFromError),
    }
}

#[derive(Debug, PartialEq)]
/// Error type for when converting a string fails
pub struct TryFromError;

impl fmt::Display for TryFromError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl Error for TryFromError {
    fn description(&self) -> &str {
        "unrecognized input"
    }
}

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

    #[test]
    fn test_color_try_from_str() {
        assert_eq!(try_color_from_str("blue"), Ok(Color::Blue));
        assert_eq!(try_color_from_str("teal"), Err(TryFromError));
    }
}
<commit_msg>feat: add error type for config parsing<commit_after>use std::error::Error;
use std::fmt;

use ansi_term::{Color, Style};

/// Holds information about how to style a module
pub struct ModuleStyle {
    pub background: Color,
    pub foreground: Color,
    /// Attributes like bold, italicized, underlined, etc...
    pub text_properties: Vec<Style>,
}

// We use methods of the form "try_*_from_*" because the user should
// just be able to specify (in their config) what color/style they
// want, and we have to be able to parse what they say into a
// meaningful type.

/// Attempts to convert a string into an `ansi_term::Color`.
///
/// Returns a `ConvertError` if the provided string doesn't match
/// any of the colors defined in crate `ansi_term`.
pub fn try_color_from_str(s: &str) -> Result<Color, ConvertError> {
    match s {
        "black" => Ok(Color::Black),
        "red" => Ok(Color::Red),
        "green" => Ok(Color::Green),
        "yellow" => Ok(Color::Yellow),
        "blue" => Ok(Color::Blue),
        "purple" => Ok(Color::Purple),
        "cyan" => Ok(Color::Cyan),
        "white" => Ok(Color::White),
        _ => Err(ConvertError::NoSuchMatch),
    }
}

// NOTE: We do not need a try_color_from_u8.
// The implementation would just look like:
// pub fn try_color_from_u8(i: u8) -> Color { Color::u8(i) }
// It would always succeed due to Rust's type system.

/// Attempts to convert a string into an `ansi_term::Color::RGB`.
///
/// Returns a `ConvertError::InvalidForm` if the provided string is
/// not of the form "(u8, u8, u8)".
pub fn try_rgb_from_str(s: &str) -> Result<Color, ConvertError> {
    unimplemented!()
}

#[derive(Debug, PartialEq)]
/// Error type for when a conversion fails
pub enum ConvertError {
    /// Input doesn't correspond to a valid result
    NoSuchMatch,
    /// Input is malformed and cannot be parsed
    InvalidForm,
}

impl fmt::Display for ConvertError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl Error for ConvertError {
    fn description(&self) -> &str {
        match *self {
            ConvertError::NoSuchMatch => "no match was found for the provided input",
            ConvertError::InvalidForm => "provided input was malformed and could not be parsed",
        }
    }
}

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

    #[test]
    fn test_color_try_from_str() {
        assert_eq!(try_color_from_str("blue"), Ok(Color::Blue));
        assert_eq!(try_color_from_str("teal"), Err(ConvertError::NoSuchMatch));
    }
}
<|endoftext|>


<commit_before>extern crate conv;
extern crate rand;

use self::conv::prelude::*;
use neat::genome::Genome;
use neat::organism::Organism;
use self::rand::distributions::{IndependentSample, Range};

#[derive(Debug, Clone)]
pub struct Specie{
    representative: Genome,
    pub organisms: Vec<Organism>
}

const MUTATION_PROBABILITY: f64 = 0.25f64;
const INTERSPECIE_MATE_PROBABILITY: f64 = 0.001f64;

impl Specie{
    pub fn new(genome: Genome) -> Specie{
        Specie{ organisms: vec![], representative: genome }
    }

    pub fn add(&mut self, organism: Organism){
        self.organisms.push(organism);
    }

    pub fn match_genome(&self, organism: &Organism) -> bool{
        self.representative.is_same_specie(&organism.genome)
    }

    pub fn average_fitness(&self) -> f64{
        let organisms_count = self.organisms.len().value_as::<f64>().unwrap();
        let total_fitness = self.organisms.iter().fold(0f64, |total, organism| total + organism.fitness);
        total_fitness / organisms_count
    }

    pub fn generate_offspring(&mut self, num_of_organisms: usize, population_organisms: &Vec<Organism>){

        let champion: Option<Organism> = self.organisms.iter().fold(None, |champion, organism| {
            if champion.is_none() || champion.as_ref().unwrap().fitness < organism.fitness {
                Some(organism.clone())
            } else {
                champion
            }
        });

        let copy_champion = if champion.as_ref().unwrap().genome.total_genes() > 5 { 1 } else { 0 };

        let mut rng = rand::thread_rng();
        let mut offspring: Vec<Organism>;
        {
            let mut selected_organisms = vec![];
            let range = Range::new(0, self.organisms.len());
            for _ in 0..num_of_organisms - copy_champion {
                selected_organisms.push(range.ind_sample(&mut rng));
            }
            offspring = selected_organisms.iter().map(|organism_pos| self.create_child(&self.organisms[*organism_pos], population_organisms)).collect::<Vec<Organism>>();
        }

        if copy_champion == 1 { offspring.push(champion.unwrap()); };
        self.organisms = offspring;
    }

    pub fn get_representative_genome(&self) -> Genome {
        self.representative.clone()
    }

    fn create_child(&self, organism: &Organism, population_organisms: &Vec<Organism>) -> Organism {
        if rand::random::<f64>() < MUTATION_PROBABILITY || population_organisms.len() < 2 {
            self.create_child_by_mutation(organism)
        } else {
            self.create_child_by_mate(organism, population_organisms)
        }
    }

    fn create_child_by_mutation(&self, organism: &Organism) -> Organism {
        organism.mutate()
    }

    fn create_child_by_mate(&self, organism: &Organism, population_organisms: &Vec<Organism>) -> Organism {
        let mut rng = rand::thread_rng();
        if rand::random::<f64>() > INTERSPECIE_MATE_PROBABILITY {
            let selected_mate = rand::sample(&mut rng, 0..self.organisms.len(), 1)[0];
            organism.mate(&self.organisms[selected_mate])
        }else{
            let selected_mate = rand::sample(&mut rng, 0..population_organisms.len(), 1)[0];
            organism.mate(&population_organisms[selected_mate])
        }
    }
}

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

    #[test]
    fn specie_should_return_correct_average_fitness(){
        let mut specie = Specie::new(Genome::new());
        let mut organism1 = Organism::new(Genome::new());
        organism1.fitness = 10f64;

        let mut organism2 = Organism::new(Genome::new());
        organism2.fitness = 15f64;

        let mut organism3 = Organism::new(Genome::new());
        organism3.fitness = 20f64;

        specie.add(organism1);
        specie.add(organism2);
        specie.add(organism3);

        assert!(specie.average_fitness() == 15f64);
    }
}

<commit_msg>Doesn't copy champion if has less than 5 networks<commit_after>extern crate conv;
extern crate rand;

use self::conv::prelude::*;
use neat::genome::Genome;
use neat::organism::Organism;
use self::rand::distributions::{IndependentSample, Range};

#[derive(Debug, Clone)]
pub struct Specie{
    representative: Genome,
    pub organisms: Vec<Organism>
}

const MUTATION_PROBABILITY: f64 = 0.25f64;
const INTERSPECIE_MATE_PROBABILITY: f64 = 0.001f64;

impl Specie{
    pub fn new(genome: Genome) -> Specie{
        Specie{ organisms: vec![], representative: genome }
    }

    pub fn add(&mut self, organism: Organism){
        self.organisms.push(organism);
    }

    pub fn match_genome(&self, organism: &Organism) -> bool{
        self.representative.is_same_specie(&organism.genome)
    }

    pub fn average_fitness(&self) -> f64{
        let organisms_count = self.organisms.len().value_as::<f64>().unwrap();
        let total_fitness = self.organisms.iter().fold(0f64, |total, organism| total + organism.fitness);
        total_fitness / organisms_count
    }

    pub fn generate_offspring(&mut self, num_of_organisms: usize, population_organisms: &Vec<Organism>){

        let champion: Option<Organism> = self.organisms.iter().fold(None, |champion, organism| {
            if champion.is_none() || champion.as_ref().unwrap().fitness < organism.fitness {
                Some(organism.clone())
            } else {
                champion
            }
        });

        let copy_champion = if num_of_organisms > 5 { 1 } else { 0 };

        let mut rng = rand::thread_rng();
        let mut offspring: Vec<Organism>;
        {
            let mut selected_organisms = vec![];
            let range = Range::new(0, self.organisms.len());
            for _ in 0..num_of_organisms - copy_champion {
                selected_organisms.push(range.ind_sample(&mut rng));
            }
            offspring = selected_organisms.iter().map(|organism_pos| self.create_child(&self.organisms[*organism_pos], population_organisms)).collect::<Vec<Organism>>();
        }

        if copy_champion == 1 { offspring.push(champion.unwrap()); };
        self.organisms = offspring;
    }

    pub fn get_representative_genome(&self) -> Genome {
        self.representative.clone()
    }

    fn create_child(&self, organism: &Organism, population_organisms: &Vec<Organism>) -> Organism {
        if rand::random::<f64>() < MUTATION_PROBABILITY || population_organisms.len() < 2 {
            self.create_child_by_mutation(organism)
        } else {
            self.create_child_by_mate(organism, population_organisms)
        }
    }

    fn create_child_by_mutation(&self, organism: &Organism) -> Organism {
        organism.mutate()
    }

    fn create_child_by_mate(&self, organism: &Organism, population_organisms: &Vec<Organism>) -> Organism {
        let mut rng = rand::thread_rng();
        if rand::random::<f64>() > INTERSPECIE_MATE_PROBABILITY {
            let selected_mate = rand::sample(&mut rng, 0..self.organisms.len(), 1)[0];
            organism.mate(&self.organisms[selected_mate])
        }else{
            let selected_mate = rand::sample(&mut rng, 0..population_organisms.len(), 1)[0];
            organism.mate(&population_organisms[selected_mate])
        }
    }
}

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

    #[test]
    fn specie_should_return_correct_average_fitness(){
        let mut specie = Specie::new(Genome::new());
        let mut organism1 = Organism::new(Genome::new());
        organism1.fitness = 10f64;

        let mut organism2 = Organism::new(Genome::new());
        organism2.fitness = 15f64;

        let mut organism3 = Organism::new(Genome::new());
        organism3.fitness = 20f64;

        specie.add(organism1);
        specie.add(organism2);
        specie.add(organism3);

        assert!(specie.average_fitness() == 15f64);
    }
}

<|endoftext|>


<commit_before>use Display;

use context;
use version::Api;
use gl;

/// Provides a way to wait for a server-side operation to be finished.
///
/// Creating a `SyncFence` injects an element in the commands queue of the backend.
/// When this element is reached, the fence becomes signaled.
///
/// ## Example
///
/// ```no_run
/// # let display: glium::Display = unsafe { std::mem::uninitialized() };
/// # fn do_something<T>(_: &T) {}
/// let fence = glium::SyncFence::new_if_supported(&display).unwrap();
/// do_something(&display);
/// fence.wait();   // blocks until the previous operations have finished
/// ```
pub struct SyncFence {
    display: Display,
    id: Option<SyncObjectWrapper>,
}

impl SyncFence {
    /// Builds a new `SyncFence` that is injected in the server.
    ///
    /// ## Features
    ///
    /// Only available if the `gl_sync` feature is enabled.
    #[cfg(feature = "gl_sync")]
    pub fn new(display: &Display) -> SyncFence {
        SyncFence::new_if_supported(display).unwrap()
    }

    /// Builds a new `SyncFence` that is injected in the server.
    ///
    /// Returns `None` is this is not supported by the backend.
    pub fn new_if_supported(display: &Display) -> Option<SyncFence> {
        let mut ctxt = display.context.context.make_current();

        unsafe { new_linear_sync_fence_if_supported(&mut ctxt) }
            .map(|f| f.into_sync_fence(display))
    }

    /// Blocks until the operation has finished on the server.
    pub fn wait(mut self) {
        let sync = self.id.take().unwrap();

        let ctxt = self.display.context.context.make_current();

        let result = unsafe {
            // waiting with a deadline of one year
            // the reason why the deadline is so long is because if you attach a GL debugger,
            // the wait can be blocked during a breaking point of the debugger
            let result = ctxt.gl.ClientWaitSync(sync.0, gl::SYNC_FLUSH_COMMANDS_BIT,
                                                365 * 24 * 3600 * 1000 * 1000 * 1000);
            ctxt.gl.DeleteSync(sync.0);
            result
        };

        match result {
            gl::ALREADY_SIGNALED | gl::CONDITION_SATISFIED => (),
            _ => panic!("Could not wait for the fence")
        };
    }
}

impl Drop for SyncFence {
    fn drop(&mut self) {
        let sync = match self.id {
            None => return,     // fence has already been deleted
            Some(s) => s
        };

        let ctxt = self.display.context.context.make_current();
        unsafe { ctxt.gl.DeleteSync(sync.0); }
    }
}

/// Prototype for a `SyncFence`.
///
/// The fence must be consumed with either `into_sync_fence`, otherwise
/// the destructor will panic.
#[must_use]
pub struct LinearSyncFence {
    id: Option<SyncObjectWrapper>,
}

unsafe impl Send for LinearSyncFence {}

impl LinearSyncFence {
    /// Turns the prototype into a real fence.
    pub fn into_sync_fence(mut self, display: &Display) -> SyncFence {
        SyncFence {
            display: display.clone(),
            id: self.id.take()
        }
    }
}

impl Drop for LinearSyncFence {
    fn drop(&mut self) {
        assert!(self.id.is_none());
    }
}

#[cfg(feature = "gl_sync")]
pub unsafe fn new_linear_sync_fence(ctxt: &mut context::CommandContext) -> LinearSyncFence {
    LinearSyncFence {
        id: Some(SyncObjectWrapper(ctxt.gl.FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0))),
    }
}

pub unsafe fn new_linear_sync_fence_if_supported(ctxt: &mut context::CommandContext) -> Option<LinearSyncFence> {
    if ctxt.version < &context::GlVersion(Api::Gl, 3, 2) && !ctxt.extensions.gl_arb_sync {
        return None;
    }

    Some(LinearSyncFence {
        id: Some(SyncObjectWrapper(ctxt.gl.FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0))),
    })
}

/// Waits for this fence and destroys it, from within the commands context.
pub unsafe fn wait_linear_sync_fence_and_drop(mut fence: LinearSyncFence, ctxt: &mut context::CommandContext) {
    let fence = fence.id.take().unwrap();

    // we try waiting without flushing first
    let success = match ctxt.gl.ClientWaitSync(fence.0, 0, 0) {
        gl::ALREADY_SIGNALED => true,
        gl::TIMEOUT_EXPIRED => false,
        gl::WAIT_FAILED => false,
        gl::CONDITION_SATISFIED => true,
        _ => unreachable!()
    };

    // waiting *with* flushing this time
    if !success {
        ctxt.gl.ClientWaitSync(fence.0, gl::SYNC_FLUSH_COMMANDS_BIT,
                               365 * 24 * 3600 * 1000 * 1000 * 1000);
    }

    ctxt.gl.DeleteSync(fence.0);
}

#[derive(Copy)]
struct SyncObjectWrapper(gl::types::GLsync);
unsafe impl Send for SyncObjectWrapper {}
unsafe impl Sync for SyncObjectWrapper {}
<commit_msg>Remove the SyncObjectWrapper<commit_after>use Display;

use context;
use version::Api;
use gl;

/// Provides a way to wait for a server-side operation to be finished.
///
/// Creating a `SyncFence` injects an element in the commands queue of the backend.
/// When this element is reached, the fence becomes signaled.
///
/// ## Example
///
/// ```no_run
/// # let display: glium::Display = unsafe { std::mem::uninitialized() };
/// # fn do_something<T>(_: &T) {}
/// let fence = glium::SyncFence::new_if_supported(&display).unwrap();
/// do_something(&display);
/// fence.wait();   // blocks until the previous operations have finished
/// ```
pub struct SyncFence {
    display: Display,
    id: Option<gl::types::GLsync>,
}

impl SyncFence {
    /// Builds a new `SyncFence` that is injected in the server.
    ///
    /// ## Features
    ///
    /// Only available if the `gl_sync` feature is enabled.
    #[cfg(feature = "gl_sync")]
    pub fn new(display: &Display) -> SyncFence {
        SyncFence::new_if_supported(display).unwrap()
    }

    /// Builds a new `SyncFence` that is injected in the server.
    ///
    /// Returns `None` is this is not supported by the backend.
    pub fn new_if_supported(display: &Display) -> Option<SyncFence> {
        let mut ctxt = display.context.context.make_current();

        unsafe { new_linear_sync_fence_if_supported(&mut ctxt) }
            .map(|f| f.into_sync_fence(display))
    }

    /// Blocks until the operation has finished on the server.
    pub fn wait(mut self) {
        let sync = self.id.take().unwrap();

        let ctxt = self.display.context.context.make_current();

        let result = unsafe {
            // waiting with a deadline of one year
            // the reason why the deadline is so long is because if you attach a GL debugger,
            // the wait can be blocked during a breaking point of the debugger
            let result = ctxt.gl.ClientWaitSync(sync, gl::SYNC_FLUSH_COMMANDS_BIT,
                                                365 * 24 * 3600 * 1000 * 1000 * 1000);
            ctxt.gl.DeleteSync(sync);
            result
        };

        match result {
            gl::ALREADY_SIGNALED | gl::CONDITION_SATISFIED => (),
            _ => panic!("Could not wait for the fence")
        };
    }
}

impl Drop for SyncFence {
    fn drop(&mut self) {
        let sync = match self.id {
            None => return,     // fence has already been deleted
            Some(s) => s
        };

        let ctxt = self.display.context.context.make_current();
        unsafe { ctxt.gl.DeleteSync(sync); }
    }
}

/// Prototype for a `SyncFence`.
///
/// The fence must be consumed with either `into_sync_fence`, otherwise
/// the destructor will panic.
#[must_use]
pub struct LinearSyncFence {
    id: Option<gl::types::GLsync>,
}

unsafe impl Send for LinearSyncFence {}

impl LinearSyncFence {
    /// Turns the prototype into a real fence.
    pub fn into_sync_fence(mut self, display: &Display) -> SyncFence {
        SyncFence {
            display: display.clone(),
            id: self.id.take()
        }
    }
}

impl Drop for LinearSyncFence {
    fn drop(&mut self) {
        assert!(self.id.is_none());
    }
}

#[cfg(feature = "gl_sync")]
pub unsafe fn new_linear_sync_fence(ctxt: &mut context::CommandContext) -> LinearSyncFence {
    LinearSyncFence {
        id: Some(ctxt.gl.FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0)),
    }
}

pub unsafe fn new_linear_sync_fence_if_supported(ctxt: &mut context::CommandContext) -> Option<LinearSyncFence> {
    if ctxt.version < &context::GlVersion(Api::Gl, 3, 2) && !ctxt.extensions.gl_arb_sync {
        return None;
    }

    Some(LinearSyncFence {
        id: Some(ctxt.gl.FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0)),
    })
}

/// Waits for this fence and destroys it, from within the commands context.
pub unsafe fn wait_linear_sync_fence_and_drop(mut fence: LinearSyncFence, ctxt: &mut context::CommandContext) {
    let fence = fence.id.take().unwrap();

    // we try waiting without flushing first
    let success = match ctxt.gl.ClientWaitSync(fence, 0, 0) {
        gl::ALREADY_SIGNALED => true,
        gl::TIMEOUT_EXPIRED => false,
        gl::WAIT_FAILED => false,
        gl::CONDITION_SATISFIED => true,
        _ => unreachable!()
    };

    // waiting *with* flushing this time
    if !success {
        ctxt.gl.ClientWaitSync(fence, gl::SYNC_FLUSH_COMMANDS_BIT,
                               365 * 24 * 3600 * 1000 * 1000 * 1000);
    }

    ctxt.gl.DeleteSync(fence);
}
<|endoftext|>


<commit_before>use clap::ArgMatches;
use client::Client;
use hostname::get_hostname;
use member::{self, NewMember, Member};
use super::Result;

pub enum TeamId {
    Id(i32),
    Hostname(String),
}

pub fn create<C: Client>(matches: &ArgMatches, client: &C) -> Result<Team> {
    let time_per_driver_in_minutes = matches.value_of("minutes")
        .map(|minutes| minutes.parse::<f64>())
        .unwrap_or(Ok(5.0))?;

    let new_members = member::build(matches);

    let new_team = NewTeam::new(new_members, time_per_driver_in_minutes, hostname());
    let team = client.create_team(&new_team)?;

    Ok(team)
}

fn hostname() -> String {
    get_hostname().expect("system to have a hostname")
}

#[derive(Debug, Serialize)]
pub struct NewTeam {
    time: f64,
    hostname: String,
    members: Vec<NewMember>,
}

impl NewTeam {
    fn new(new_members: Vec<NewMember>, time: f64, hostname: String) -> NewTeam {
        NewTeam {
            time: time,
            hostname: hostname,
            members: new_members,
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct Team {
    pub id: i32,
    pub driver: Member,
    pub hostname: String,
    pub time: f64,
    pub members: Vec<Member>,
}

impl Team {
    pub fn next_driver(&self) -> Member {
        let next_driver_position = next_driver_position(
            self.driver.position + 1,
            &self.members);

        self.members
            .clone()
            .into_iter()
            .find(|member| member.position == next_driver_position)
            .expect("Member to exist at position")
    }
}

fn next_driver_position(next_position: i32, members: &Vec<Member>) -> i32 {
    match members.into_iter().find(|member| member.position == next_position) {
        Some(driver) => {
            if driver.is_active() {
                driver.position
            } else {
                next_driver_position(driver.position + 1, members)
            }
        }
        None => next_driver_position(0, members)

    }
}

#[cfg(test)]
mod test {
    use super::{Member, Team};

    #[test]
    fn test_next_driver() {
        let current_driver = Member::new(1, "Mike", 1, true, true);
        let next_driver = Member::new(2, "Brian", 2, true, false);
        let members: Vec<Member> = vec![
            current_driver.clone(),
            next_driver.clone(),
            Member::new(3, "Patrick", 3, true, false)];

        let team = Team {
            id: 1,
            driver: current_driver,
            hostname: "example".into(),
            time: 5.0,
            members: members,
        };

        assert_eq!(team.next_driver(), next_driver);
    }

    #[test]
    fn test_next_driver_ignores_inactive() {
        let current_driver  = Member::new(1, "Mike", 1, true, true);
        let inactive_driver  = Member::new(2, "Brian", 2, false, false);
        let next_driver  = Member::new(3, "Patrick", 3, true, false);

        let members: Vec<Member> = vec![
            current_driver.clone(),
            inactive_driver,
            next_driver.clone()];

        let team = Team {
            id: 1,
            driver: current_driver,
            hostname: "example".into(),
            time: 5.0,
            members: members,
        };

        assert_eq!(team.next_driver(), next_driver);
    }
}
<commit_msg>fix: Set next driver member driver true<commit_after>use clap::ArgMatches;
use client::Client;
use hostname::get_hostname;
use member::{self, NewMember, Member};
use super::Result;

pub enum TeamId {
    Id(i32),
    Hostname(String),
}

pub fn create<C: Client>(matches: &ArgMatches, client: &C) -> Result<Team> {
    let time_per_driver_in_minutes = matches.value_of("minutes")
        .map(|minutes| minutes.parse::<f64>())
        .unwrap_or(Ok(5.0))?;

    let new_members = member::build(matches);

    let new_team = NewTeam::new(new_members, time_per_driver_in_minutes, hostname());
    let team = client.create_team(&new_team)?;

    Ok(team)
}

fn hostname() -> String {
    get_hostname().expect("system to have a hostname")
}

#[derive(Debug, Serialize)]
pub struct NewTeam {
    time: f64,
    hostname: String,
    members: Vec<NewMember>,
}

impl NewTeam {
    fn new(new_members: Vec<NewMember>, time: f64, hostname: String) -> NewTeam {
        NewTeam {
            time: time,
            hostname: hostname,
            members: new_members,
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct Team {
    pub id: i32,
    pub driver: Member,
    pub hostname: String,
    pub time: f64,
    pub members: Vec<Member>,
}

impl Team {
    pub fn next_driver(&self) -> Member {
        let next_driver_position = next_driver_position(
            self.driver.position + 1,
            &self.members);

        let mut next_driver = self.members
            .clone()
            .into_iter()
            .find(|member| member.position == next_driver_position)
            .expect("Member to exist at position");
        next_driver.driver = true;
        next_driver
    }
}

fn next_driver_position(next_position: i32, members: &Vec<Member>) -> i32 {
    match members.into_iter().find(|member| member.position == next_position) {
        Some(driver) => {
            if driver.is_active() {
                driver.position
            } else {
                next_driver_position(driver.position + 1, members)
            }
        }
        None => next_driver_position(0, members)

    }
}

#[cfg(test)]
mod test {
    use super::{Member, Team};

    #[test]
    fn test_next_driver() {
        let current_driver = Member::new(1, "Mike", 1, true, true);
        let next_driver = Member::new(2, "Brian", 2, true, false);
        let members: Vec<Member> = vec![
            current_driver.clone(),
            next_driver.clone(),
            Member::new(3, "Patrick", 3, true, false)];

        let team = Team {
            id: 1,
            driver: current_driver,
            hostname: "example".into(),
            time: 5.0,
            members: members,
        };

        assert_eq!(team.next_driver(), next_driver);
    }

    #[test]
    fn test_next_driver_ignores_inactive() {
        let current_driver  = Member::new(1, "Mike", 1, true, true);
        let inactive_driver  = Member::new(2, "Brian", 2, false, false);
        let next_driver  = Member::new(3, "Patrick", 3, true, false);

        let members: Vec<Member> = vec![
            current_driver.clone(),
            inactive_driver,
            next_driver.clone()];

        let team = Team {
            id: 1,
            driver: current_driver,
            hostname: "example".into(),
            time: 5.0,
            members: members,
        };

        assert_eq!(team.next_driver(), next_driver);
    }
}
<|endoftext|>


<commit_before>use cairo::{Context, Surface};
use pango::{FontDescription, Layout, LayoutExt};
use pangocairo::CairoContextExt;

#[derive(Clone, Debug)]
pub struct Color {
    red: f64,
    green: f64,
    blue: f64,
}

macro_rules! color {
    ($name:ident, ($r:expr, $g:expr, $b:expr)) => {
        #[allow(dead_code)]
        pub fn $name() -> Color {
            Color {
                red: $r, green: $g, blue: $b,
            }
        }
    }
}

impl Color {
    color!(red, (1.0, 0.0, 0.0));
    color!(green, (0.0, 1.0, 0.0));
    color!(blue, (0.0, 0.0, 1.0));
    color!(white, (1.0, 1.0, 1.0));
    color!(black, (0.0, 0.0, 0.0));

    pub fn apply_to_context(&self, cr: &Context) {
        cr.set_source_rgb(self.red, self.green, self.blue);
    }
}

#[derive(Clone, Debug)]
pub struct Padding {
    left: f64,
    right: f64,
    top: f64,
    bottom: f64,
}

impl Padding {
    pub fn new(left: f64, right: f64, top: f64, bottom: f64) -> Padding {
        Padding {
            left,
            right,
            top,
            bottom,
        }
    }
}

#[derive(Clone)]
pub struct Attributes {
    pub font: FontDescription,
    pub fg_color: Color,
    pub bg_color: Option<Color>,
    pub padding: Padding,
}

impl Attributes {
    #[allow(dead_code)]
    pub fn with_font(&self, font: FontDescription) -> Attributes {
        let mut new = self.clone();
        new.font = font;
        new
    }

    #[allow(dead_code)]
    pub fn with_fg_color(&self, fg_color: Color) -> Attributes {
        let mut new = self.clone();
        new.fg_color = fg_color;
        new
    }

    #[allow(dead_code)]
    pub fn with_bg_color(&self, bg_color: Option<Color>) -> Attributes {
        let mut new = self.clone();
        new.bg_color = bg_color;
        new
    }

    #[allow(dead_code)]
    pub fn with_padding(&self, padding: Padding) -> Attributes {
        let mut new = self.clone();
        new.padding = padding;
        new
    }
}

#[derive(Clone)]
pub struct Text {
    pub attr: Attributes,
    pub text: String,
    pub stretch: bool,
}

impl Text {
    fn create_contexts(&self, surface: &Surface) -> (Context, Layout) {
        let context = Context::new(&surface);

        let layout = context.create_pango_layout();
        layout.set_text(&self.text, self.text.len() as i32);
        layout.set_font_description(Some(&self.attr.font));

        (context, layout)
    }

    fn width_and_height_for_layout(&self, layout: &Layout) -> (f64, f64) {
        let padding = &self.attr.padding;
        let (text_width, text_height) = layout.get_pixel_size();
        let width = text_width as f64 + padding.left + padding.right;
        let height = text_height as f64 + padding.top + padding.bottom;
        (width, height)
    }

    pub fn compute_width_and_height(&self, surface: &Surface) -> (f64, f64) {
        let (_, layout) = self.create_contexts(surface);
        self.width_and_height_for_layout(&layout)
    }

    pub fn render(&self,
                  surface: &Surface,
                  x: f64,
                  y: f64,
                  width: Option<f64>,
                  height: Option<f64>)
                  -> (f64, f64) {
        let (context, layout) = self.create_contexts(surface);
        context.translate(x, y + self.attr.padding.top);

        // The `width`/`height` parameters allow the caller to override how big we'll draw
        // this block of text. If they are not specified, then we'll default to whatever
        // width/height the text actually takes.
        let (layout_width, layout_height) = self.width_and_height_for_layout(&layout);
        let width = width.unwrap_or(layout_width);
        let height = height.unwrap_or(layout_height);

        if let Some(ref bg_color) = self.attr.bg_color {
            bg_color.apply_to_context(&context);
            // FIXME: The use of `height` isnt' right here: we want to do the
            // full height of the bar, not the full height of the text. It
            // would be useful if we could do Surface.get_height(), but that
            // doesn't seem to be available in cairo-rs for some reason?
            context.rectangle(0.0, 0.0, width, height);
            context.fill();
        }

        self.attr.fg_color.apply_to_context(&context);
        context.translate(self.attr.padding.left, self.attr.padding.top);
        context.show_pango_layout(&layout);

        (width, height)
    }
}
<commit_msg>Don't translate top padding twice.<commit_after>use cairo::{Context, Surface};
use pango::{FontDescription, Layout, LayoutExt};
use pangocairo::CairoContextExt;

#[derive(Clone, Debug)]
pub struct Color {
    red: f64,
    green: f64,
    blue: f64,
}

macro_rules! color {
    ($name:ident, ($r:expr, $g:expr, $b:expr)) => {
        #[allow(dead_code)]
        pub fn $name() -> Color {
            Color {
                red: $r, green: $g, blue: $b,
            }
        }
    }
}

impl Color {
    color!(red, (1.0, 0.0, 0.0));
    color!(green, (0.0, 1.0, 0.0));
    color!(blue, (0.0, 0.0, 1.0));
    color!(white, (1.0, 1.0, 1.0));
    color!(black, (0.0, 0.0, 0.0));

    pub fn apply_to_context(&self, cr: &Context) {
        cr.set_source_rgb(self.red, self.green, self.blue);
    }
}

#[derive(Clone, Debug)]
pub struct Padding {
    left: f64,
    right: f64,
    top: f64,
    bottom: f64,
}

impl Padding {
    pub fn new(left: f64, right: f64, top: f64, bottom: f64) -> Padding {
        Padding {
            left,
            right,
            top,
            bottom,
        }
    }
}

#[derive(Clone)]
pub struct Attributes {
    pub font: FontDescription,
    pub fg_color: Color,
    pub bg_color: Option<Color>,
    pub padding: Padding,
}

impl Attributes {
    #[allow(dead_code)]
    pub fn with_font(&self, font: FontDescription) -> Attributes {
        let mut new = self.clone();
        new.font = font;
        new
    }

    #[allow(dead_code)]
    pub fn with_fg_color(&self, fg_color: Color) -> Attributes {
        let mut new = self.clone();
        new.fg_color = fg_color;
        new
    }

    #[allow(dead_code)]
    pub fn with_bg_color(&self, bg_color: Option<Color>) -> Attributes {
        let mut new = self.clone();
        new.bg_color = bg_color;
        new
    }

    #[allow(dead_code)]
    pub fn with_padding(&self, padding: Padding) -> Attributes {
        let mut new = self.clone();
        new.padding = padding;
        new
    }
}

#[derive(Clone)]
pub struct Text {
    pub attr: Attributes,
    pub text: String,
    pub stretch: bool,
}

impl Text {
    fn create_contexts(&self, surface: &Surface) -> (Context, Layout) {
        let context = Context::new(&surface);

        let layout = context.create_pango_layout();
        layout.set_text(&self.text, self.text.len() as i32);
        layout.set_font_description(Some(&self.attr.font));

        (context, layout)
    }

    fn width_and_height_for_layout(&self, layout: &Layout) -> (f64, f64) {
        let padding = &self.attr.padding;
        let (text_width, text_height) = layout.get_pixel_size();
        let width = text_width as f64 + padding.left + padding.right;
        let height = text_height as f64 + padding.top + padding.bottom;
        (width, height)
    }

    pub fn compute_width_and_height(&self, surface: &Surface) -> (f64, f64) {
        let (_, layout) = self.create_contexts(surface);
        self.width_and_height_for_layout(&layout)
    }

    pub fn render(&self,
                  surface: &Surface,
                  x: f64,
                  y: f64,
                  width: Option<f64>,
                  height: Option<f64>)
                  -> (f64, f64) {
        let (context, layout) = self.create_contexts(surface);
        context.translate(x, y);

        // The `width`/`height` parameters allow the caller to override how big we'll draw
        // this block of text. If they are not specified, then we'll default to whatever
        // width/height the text actually takes.
        let (layout_width, layout_height) = self.width_and_height_for_layout(&layout);
        let width = width.unwrap_or(layout_width);
        let height = height.unwrap_or(layout_height);

        if let Some(ref bg_color) = self.attr.bg_color {
            bg_color.apply_to_context(&context);
            // FIXME: The use of `height` isnt' right here: we want to do the
            // full height of the bar, not the full height of the text. It
            // would be useful if we could do Surface.get_height(), but that
            // doesn't seem to be available in cairo-rs for some reason?
            context.rectangle(0.0, 0.0, width, height);
            context.fill();
        }

        self.attr.fg_color.apply_to_context(&context);
        context.translate(self.attr.padding.left, self.attr.padding.top);
        context.show_pango_layout(&layout);

        (width, height)
    }
}
<|endoftext|>


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

use compare::{Compare, Natural, natural};

static DELTA: usize = 3;
static GAMMA: usize = 2;

struct TreeNode<K, V> {
    size: usize,
    elem: (K, V),
    left: Option<Rc<TreeNode<K, V>>>,
    right: Option<Rc<TreeNode<K, V>>>
}

struct Tree<K, V, C: Compare<K> = Natural<K>> {
    root: Option<Rc<TreeNode<K, V>>>,
    cmp: C
}

impl<K, V, C> Tree<K, V, C> where C: Compare<K> {
    pub fn with_comparator(cmp: C) -> Tree<K, V, C> {
        Tree { root: None, cmp: cmp }
    }

    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
        where C: Compare<Q, K>
    {
        fn f<'r, K, V, C, Q: ?Sized>(node: &'r Option<Rc<TreeNode<K, V>>>, cmp: &C, key: &Q)
                -> Option<&'r V> where C: Compare<Q, K>
        {
            find_exact(node, |k| cmp.compare(key, k))
        }

        f(&self.root, &self.cmp, key)
    }
}

impl<K, V, C> Tree<K, V, C> where K: Clone, V: Clone, C: Compare<K> + Clone {
    pub fn insert(&self, key: K, value: V) -> Tree<K, V, C>{
        let mut root = insert(&self.root, (key, value), &self.cmp);
        Tree { root: Some(Rc::new(root)), cmp: self.cmp.clone() }
    }
}

impl<K: Ord, V> Tree<K, V> {
    pub fn new() -> Tree<K, V> {
        Tree::with_comparator(natural())
    }
}

impl<K, V> TreeNode<K, V> {
    fn new(elem: (K, V), left: Option<Rc<TreeNode<K, V>>>, right: Option<Rc<TreeNode<K, V>>>)
        -> TreeNode<K, V>
    {
        TreeNode {
            elem: elem,
            size: size(&left) + size(&right) + 1,
            left: left,
            right: right
        }
    }
}

fn find_exact<K, V, F>(node: &Option<Rc<TreeNode<K, V>>>, mut f: F) -> Option<&V>
    where F: FnMut(&K) -> Ordering
{
    let mut cursor = node;
    loop {
        match *cursor {
            None => return None,
            Some(ref n) => match f(&n.elem.0) {
                Ordering::Less => cursor = &n.left,
                Ordering::Equal => return Some(&n.elem.1),
                Ordering::Greater => cursor = &n.right,
            }
        }
    }
}

fn insert<K, V, C>(node: &Option<Rc<TreeNode<K, V>>>, elem: (K, V), cmp: &C) -> TreeNode<K, V>
    where K: Clone, V: Clone, C: Compare<K>
{
    match *node {
        None => TreeNode {
            size: 1,
            elem: elem,
            left: None,
            right: None
        },
        Some(ref n) => match cmp.compare(&elem.0, &n.elem.0) {
            Ordering::Less => {
                balance_right(n.elem.clone(), insert(&n.left, elem, cmp), &n.right)
            },
            Ordering::Greater => {
                balance_left(n.elem.clone(), &n.left, insert(&n.right, elem, cmp))
            },
            Ordering::Equal => TreeNode {
                size: n.size,
                elem: elem,
                left: n.left.clone(),
                right: n.right.clone()
            }
        }
    }
}

fn is_balanced(a: usize, b: usize) -> bool
{
    DELTA * (a + 1) >= b + 1
}

fn is_single(a: usize, b: usize) -> bool
{
    a + 1 < GAMMA * (b + 1)
}

fn size<K, V>(node: &Option<Rc<TreeNode<K, V>>>) -> usize {
    match *node {
        None => 0,
        Some(ref n) => n.size
    }
}

fn balance_left<K, V>(elem: (K, V),
                      left: &Option<Rc<TreeNode<K, V>>>,
                      right: TreeNode<K, V>) -> TreeNode<K, V>
    where K: Clone, V: Clone
{
    let lsize = size(left);
    if is_balanced(lsize, right.size) {
        TreeNode::new(elem, left.clone(), Some(Rc::new(right)))
    } else {
        let TreeNode { elem: r_elem, size: rsize, left: rl, right: rr } = right;
        if is_single(size(&rl), size(&rr)) {
            let new_l = TreeNode::new(elem, left.clone(), rl);
            TreeNode::new(
                r_elem,
                Some(Rc::new(new_l)),
                rr
            )
        } else {
            if let Some(ref rl_node) = rl {
                let new_l = TreeNode::new(elem, left.clone(), rl_node.left.clone());
                let new_r = TreeNode::new(r_elem, rl_node.right.clone(), rr);
                TreeNode::new(
                    rl_node.elem.clone(),
                    Some(Rc::new(new_l)),
                    Some(Rc::new(new_r))
                )
            } else {
                panic!("size invariant does not match!")
            }
        }
    }
}

fn balance_right<K, V>(elem: (K, V),
                       left: TreeNode<K, V>,
                       right: &Option<Rc<TreeNode<K, V>>>) -> TreeNode<K, V>
    where K: Clone, V: Clone
{
    let rsize = size(right);
    if is_balanced(rsize, left.size) {
        TreeNode::new(elem, Some(Rc::new(left)), right.clone())
    } else {
        let TreeNode { elem: l_elem, size: lsize, left: ll, right: lr } = left;
        if is_single(size(&lr), size(&ll)) {
            let new_r = TreeNode::new(elem, lr, right.clone());
            TreeNode::new(
                l_elem,
                ll,
                Some(Rc::new(new_r)),
            )
        } else {
            if let Some(ref lr_node) = lr {
                let new_l = TreeNode::new(l_elem, ll, lr_node.left.clone());
                let new_r = TreeNode::new(elem, lr_node.right.clone(), right.clone());
                TreeNode::new(
                    lr_node.elem.clone(),
                    Some(Rc::new(new_l)),
                    Some(Rc::new(new_r))
                )
            } else {
                panic!("size invariant does not match!")
            }
        }
    }
}

#[cfg(test)]
mod test {
    use std::rc::Rc;

    use super::{Tree, TreeNode, is_balanced, size};

    fn traverse<K, V>(node: &Option<Rc<TreeNode<K, V>>>, res: &mut Vec<(K, V)>)
        where K: Clone, V: Clone
    {
        if let Some(ref n) = *node {
            traverse(&n.left, res);
            res.push(n.elem.clone());
            traverse(&n.right, res);
        }
    }

    fn balanced<K, V>(node: &Option<Rc<TreeNode<K, V>>>) -> bool
    {
        if let Some(ref n) = *node {
            is_balanced(size(&n.left), size(&n.right))
                && is_balanced(size(&n.right), size(&n.left))
                && balanced(&n.left)
                && balanced(&n.right)
        } else {
            true
        }
    }

    #[test]
    fn test_insert() {
        let r0 = Tree::new();
        let r1 = r0.insert(4, 'd');
        let r2 = r1.insert(7, 'g');
        let r3 = r2.insert(12, 'l');
        let r4 = r3.insert(15, 'o');
        let r5 = r4.insert(3, 'c');
        let r6 = r5.insert(5, 'e');
        let r7 = r6.insert(14, 'n');
        let r8 = r7.insert(18, 'r');
        let r9 = r8.insert(16, 'p');
        let r10 = r9.insert(17, 'q');

        let expected = vec![
            (3, 'c'), (4, 'd'), (5, 'e'), (7, 'g'),
            (12, 'l'), (14, 'n'), (15, 'o'), (16, 'p'),
            (17, 'q'), (18, 'r')
        ];

        let mut res = Vec::new();
        traverse(&r10.root, &mut res);

        assert_eq!(expected, res);
        assert!(balanced(&r10.root));
    }
}
<commit_msg>Tree::len function<commit_after>use std::cmp::Ordering;
use std::rc::Rc;

use compare::{Compare, Natural, natural};

static DELTA: usize = 3;
static GAMMA: usize = 2;

struct TreeNode<V> {
    size: usize,
    elem: V,
    left: Option<Rc<TreeNode<V>>>,
    right: Option<Rc<TreeNode<V>>>
}

struct Tree<V, C: Compare<V> = Natural<V>> {
    root: Option<Rc<TreeNode<V>>>,
    cmp: C
}

impl<V, C> Tree<V, C> where C: Compare<V> {
    pub fn with_comparator(cmp: C) -> Tree<V, C> {
        Tree { root: None, cmp: cmp }
    }

    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
        where C: Compare<Q, V>
    {
        fn f<'r, V, C, Q: ?Sized>(node: &'r Option<Rc<TreeNode<V>>>, cmp: &C, key: &Q)
                -> Option<&'r V> where C: Compare<Q, V>
        {
            find_exact(node, |x| cmp.compare(key, x))
        }

        f(&self.root, &self.cmp, key)
    }

    pub fn len(&self) -> usize {
        size(&self.root)
    }
}

impl<V, C> Tree<V, C> where V: Clone, C: Compare<V> + Clone {
    pub fn insert(&self, value: V) -> Tree<V, C>{
        let root = insert(&self.root, value, &self.cmp);
        Tree { root: Some(Rc::new(root)), cmp: self.cmp.clone() }
    }
}

impl<V: Ord> Tree<V> {
    pub fn new() -> Tree<V> {
        Tree::with_comparator(natural())
    }
}

impl<V> TreeNode<V> {
    fn new(elem: V, left: Option<Rc<TreeNode<V>>>, right: Option<Rc<TreeNode<V>>>)
        -> TreeNode<V>
    {
        TreeNode {
            elem: elem,
            size: size(&left) + size(&right) + 1,
            left: left,
            right: right
        }
    }
}

fn find_exact<V, F>(node: &Option<Rc<TreeNode<V>>>, mut f: F) -> Option<&V>
    where F: FnMut(&V) -> Ordering
{
    let mut cursor = node;
    loop {
        match *cursor {
            None => return None,
            Some(ref n) => match f(&n.elem) {
                Ordering::Less => cursor = &n.left,
                Ordering::Equal => return Some(&n.elem),
                Ordering::Greater => cursor = &n.right,
            }
        }
    }
}

fn insert<V, C>(node: &Option<Rc<TreeNode<V>>>, elem: V, cmp: &C) -> TreeNode<V>
    where V: Clone, C: Compare<V>
{
    match *node {
        None => TreeNode {
            size: 1,
            elem: elem,
            left: None,
            right: None
        },
        Some(ref n) => match cmp.compare(&elem, &n.elem) {
            Ordering::Less => {
                balance_right(n.elem.clone(), insert(&n.left, elem, cmp), &n.right)
            },
            Ordering::Greater => {
                balance_left(n.elem.clone(), &n.left, insert(&n.right, elem, cmp))
            },
            Ordering::Equal => TreeNode {
                size: n.size,
                elem: elem,
                left: n.left.clone(),
                right: n.right.clone()
            }
        }
    }
}

fn is_balanced(a: usize, b: usize) -> bool
{
    DELTA * (a + 1) >= b + 1
}

fn is_single(a: usize, b: usize) -> bool
{
    a + 1 < GAMMA * (b + 1)
}

fn size<V>(node: &Option<Rc<TreeNode<V>>>) -> usize {
    match *node {
        None => 0,
        Some(ref n) => n.size
    }
}

fn balance_left<V>(elem: V,
                   left: &Option<Rc<TreeNode<V>>>,
                   right: TreeNode<V>) -> TreeNode<V>
    where V: Clone
{
    let lsize = size(left);
    if is_balanced(lsize, right.size) {
        TreeNode::new(elem, left.clone(), Some(Rc::new(right)))
    } else {
        let TreeNode { elem: r_elem, size: rsize, left: rl, right: rr } = right;
        if is_single(size(&rl), size(&rr)) {
            let new_l = TreeNode::new(elem, left.clone(), rl);
            TreeNode::new(
                r_elem,
                Some(Rc::new(new_l)),
                rr
            )
        } else {
            if let Some(ref rl_node) = rl {
                let new_l = TreeNode::new(elem, left.clone(), rl_node.left.clone());
                let new_r = TreeNode::new(r_elem, rl_node.right.clone(), rr);
                TreeNode::new(
                    rl_node.elem.clone(),
                    Some(Rc::new(new_l)),
                    Some(Rc::new(new_r))
                )
            } else {
                panic!("size invariant does not match!")
            }
        }
    }
}

fn balance_right<V>(elem: V,
                    left: TreeNode<V>,
                    right: &Option<Rc<TreeNode<V>>>) -> TreeNode<V>
    where V: Clone
{
    let rsize = size(right);
    if is_balanced(rsize, left.size) {
        TreeNode::new(elem, Some(Rc::new(left)), right.clone())
    } else {
        let TreeNode { elem: l_elem, size: lsize, left: ll, right: lr } = left;
        if is_single(size(&lr), size(&ll)) {
            let new_r = TreeNode::new(elem, lr, right.clone());
            TreeNode::new(
                l_elem,
                ll,
                Some(Rc::new(new_r)),
            )
        } else {
            if let Some(ref lr_node) = lr {
                let new_l = TreeNode::new(l_elem, ll, lr_node.left.clone());
                let new_r = TreeNode::new(elem, lr_node.right.clone(), right.clone());
                TreeNode::new(
                    lr_node.elem.clone(),
                    Some(Rc::new(new_l)),
                    Some(Rc::new(new_r))
                )
            } else {
                panic!("size invariant does not match!")
            }
        }
    }
}

#[cfg(test)]
mod test {
    use std::rc::Rc;

    use super::{Tree, TreeNode, is_balanced, size};

    fn traverse<V>(node: &Option<Rc<TreeNode<V>>>, res: &mut Vec<V>)
        where V: Clone
    {
        if let Some(ref n) = *node {
            traverse(&n.left, res);
            res.push(n.elem.clone());
            traverse(&n.right, res);
        }
    }

    fn balanced<V>(node: &Option<Rc<TreeNode<V>>>) -> bool
    {
        if let Some(ref n) = *node {
            is_balanced(size(&n.left), size(&n.right))
                && is_balanced(size(&n.right), size(&n.left))
                && balanced(&n.left)
                && balanced(&n.right)
        } else {
            true
        }
    }

    #[test]
    fn test_insert() {
        let r0 = Tree::new();
        let r1 = r0.insert((4, 'd'));
        let r2 = r1.insert((7, 'g'));
        let r3 = r2.insert((12, 'l'));
        let r4 = r3.insert((15, 'o'));
        let r5 = r4.insert((3, 'c'));
        let r6 = r5.insert((5, 'e'));
        let r7 = r6.insert((14, 'n'));
        let r8 = r7.insert((18, 'r'));
        let r9 = r8.insert((16, 'p'));
        let r10 = r9.insert((17, 'q'));

        let expected = vec![
            (3, 'c'), (4, 'd'), (5, 'e'), (7, 'g'),
            (12, 'l'), (14, 'n'), (15, 'o'), (16, 'p'),
            (17, 'q'), (18, 'r')
        ];

        let mut res = Vec::new();
        traverse(&r10.root, &mut res);

        assert_eq!(expected, res);
        assert_eq!(10, r10.len());
        assert!(balanced(&r10.root));
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove unnecessary file<commit_after><|endoftext|>


<commit_before>//! Get project by id.
//!
//! https://docs.gitlab.com/ce/api/projects.html#get-single-project
//!
//! # Get single project
//!
//! Get a specific project, identified by project ID or NAMESPACE/PROJECT_NAME, which is owned by
//! the authenticated user.
//! If using namespaced projects call make sure that the NAMESPACE/PROJECT_NAME is URL-encoded,
//! eg. `/api/v3/projects/diaspora%2Fdiaspora` (where `/` is represented by `%2F`).
//!
//! ```text
//! GET /projects/ID
//! ```
//!
//! Parameters:
//!
//! | Attribute | Type | Required | Description |
//! | --------- | ---- | -------- | ----------- |
//! | `id` | integer/string | yes | The ID or NAMESPACE/PROJECT_NAME of the project |
<commit_msg>Add projects from id<commit_after>//! Get project by id.
//!
//! https://docs.gitlab.com/ce/api/projects.html#get-single-project
//!
//! # Get single project
//!
//! Get a specific project, identified by project ID or NAMESPACE/PROJECT_NAME, which is owned by
//! the authenticated user.
//! If using namespaced projects call make sure that the NAMESPACE/PROJECT_NAME is URL-encoded,
//! eg. `/api/v3/projects/diaspora%2Fdiaspora` (where `/` is represented by `%2F`).
//!
//! ```text
//! GET /projects/ID
//! ```
//!
//! Parameters:
//!
//! | Attribute | Type | Required | Description |
//! | --------- | ---- | -------- | ----------- |
//! | `id` | integer/string | yes | The ID or NAMESPACE/PROJECT_NAME of the project |

use BuildQuery;

#[derive(Debug, Clone)]
pub enum ListingId {
    Id(i64),
    NamespaceProject(String),
}

#[derive(Default, Debug, Clone)]
pub struct Listing {
    /// The ID or NAMESPACE/PROJECT_NAME of the project
    id:  Option<ListingId>,
}

impl Listing {
    pub fn new() -> Listing {
        Default::default()
    }
    pub fn id(&mut self, id: ListingId) -> &mut Listing {
        self.id = Some(id);
        self
    }
}

impl BuildQuery for Listing {
    fn build_query(&self) -> String {

        let mut query = String::from("projects");

        let amp_char = "&";
        let none_char = "";
        let mut split_char = &none_char;

        // Append a "?" only if at least one of the `Option` is `Some(_)` or if
        // strings contain something.
        query.push_str(match &self.id {
            &None => "",
            _ => "?",
        });

        self.id.clone().map(|id| {
            query.push_str(split_char);
            split_char = &amp_char;

            query.push_str("id=");
            query.push_str(&match id {
                ListingId::Id(id) => id.to_string(),
                ListingId::NamespaceProject(s) => s.replace("/", "%2F"),
            });
        });

        query
    }
}

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

    #[test]
    fn projects_build_query_default() {
        let expected_string = "projects";
        let listing: Listing = Default::default();
        let query = listing.build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects";
        let listing = Listing::new();
        let query = listing.build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn projects_build_query_id() {
        let expected_string = "projects?id=123";
        let query = Listing::new().id(ListingId::Id(123)).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?id=group%2Fproject";
        let query = Listing::new().id(ListingId::NamespaceProject("group/project".to_string())).build_query();
        assert_eq!(query, expected_string);
    }
}
<|endoftext|>


<commit_before>extern crate elma;
extern crate rand;
#[cfg(test)]
mod tests {
    use elma::{ lev, rec, Position };
    use rand::random;

    #[test]
    fn test_decrypt_encrypt () {
        let mut initial: Vec<u8> = vec![];
        for _ in 0..688 {
            initial.push(random::<u8>());
        }
        let decrypted = lev::crypt_top10(&initial);
        let encrypted = lev::crypt_top10(&decrypted);
        assert_eq!(initial, encrypted);
    }

    #[test]
    // Probably redundant, but maybe some new fields are added in the future.
    // Doesn't hurt or impact anything.
    fn level_default_values () {
        let level = lev::Level::new();
        assert_eq!(level.version, lev::Version::Elma);
        assert_eq!(level.link, 0);
        assert_eq!(level.integrity, [0_f64; 4]);
        assert_eq!(level.name, "");
        assert_eq!(level.lgr, "default");
        assert_eq!(level.ground, "ground");
        assert_eq!(level.sky, "sky");
        assert_eq!(level.polygons, vec![]);
        assert_eq!(level.objects, vec![]);
        assert_eq!(level.pictures, vec![]);
        assert_eq!(level.top10_single, vec![]);
        assert_eq!(level.top10_multi, vec![]);
    }

    #[test]
    fn load_valid_level_1 () {
        let level = lev::Level::load_level("tests/test_1.lev");
        assert_eq!(level.version, lev::Version::Elma);
        assert_eq!(level.link, 1524269776);
        assert_eq!(level.integrity, [-1148375.210607791_f64,
                                      1164056.210607791_f64,
                                      1162467.210607791_f64,
                                      1162283.210607791_f64]);
        assert_eq!(level.name, "Rust test");
        assert_eq!(level.lgr, "default");
        assert_eq!(level.ground, "ground");
        assert_eq!(level.sky, "sky");

        // Polygon tests.
        assert_eq!(level.polygons.len(), 2);
        assert_eq!(level.polygons, vec![lev::Polygon {
                grass: false, vertices: vec![
                    Position { x: -23.993693053024586_f64, y: -3.135779367971911_f64 },
                    Position { x: -15.989070625361132_f64, y: -3.135779367971911_f64 },
                    Position { x: -15.989070625361132_f64, y: 1.995755366905195_f64 },
                    Position { x: -24f64, y: 2f64 }]
            },
            lev::Polygon {
                grass: true, vertices: vec![
                    Position { x: -23.83645939819548_f64, y: 2.310222676563402_f64 },
                    Position { x: -17.60428907951465_f64, y: 2.2816347393217473_f64 },
                    Position { x: -17.53281923641051_f64, y: 1.8956975865594021_f64 },
                    Position { x: -23.96510511578293_f64, y: 1.924285523801057_f64 }]
            }
        ]);

        // Object tests.
        assert_eq!(level.objects.len(), 8);
        assert_eq!(level.objects, vec![lev::Object {
                position: Position { x: -23.221818747499896_f64, y: -1.3204453531268072_f64 },
                object_type: lev::ObjectType::Killer
            },
            lev::Object {
                position: Position { x: -20.37252715482359_f64, y: -0.3124543521844827_f64 },
                object_type: lev::ObjectType::Apple { gravity: lev::Direction::Normal, animation: 9 }
            },
            lev::Object {
                position: Position { x: -20.3914786548306_f64, y: 0.5277288147929609_f64 },
                object_type: lev::ObjectType::Apple { gravity: lev::Direction::Up, animation: 1 }
            },
            lev::Object {
                position: Position { x: -19.526026821177144_f64, y: 0.36348248139887396_f64 },
                object_type: lev::ObjectType::Apple { gravity: lev::Direction::Right, animation: 5 }
            },
            lev::Object {
                position: Position { x: -21.269564821822065_f64, y: 0.38243398140588436_f64 },
                object_type: lev::ObjectType::Apple { gravity: lev::Direction::Left, animation: 1 }
            },
            lev::Object {
                position: Position { x: -19.55761265452216_f64, y: -0.4387976855645497_f64 },
                object_type: lev::ObjectType::Apple { gravity: lev::Direction::Up, animation: 1 }
            },
            lev::Object {
                position: Position { x: -20.075620321380434_f64, y: -1.2473950191969765_f64 },
                object_type: lev::ObjectType::Exit
            },
            lev::Object {
                position: Position { x: -22.94993115577695_f64, y: 1.5068896484884773_f64 },
                object_type: lev::ObjectType::Player
            }
        ]);

        // Picture tests.
        assert_eq!(level.pictures.len(), 2);
        assert_eq!(level.pictures, vec![lev::Picture {
            name: String::from("barrel"),
            texture: String::new(),
            mask: String::new(),
            position: Position { x: -19.37674118849727_f64, y: 0.895119783101471_f64 },
            distance: 380,
            clip: lev::Clip::Sky
        },
        lev::Picture {
            name: String::new(),
            texture: String::from("stone1"),
            mask: String::from("maskbig"),
            position: Position { x: -24.465394017511894_f64, y: -3.964829547979911_f64 },
            distance: 750,
            clip: lev::Clip::Sky
        }]);

        // Top10 tests.
        assert_eq!(level.top10_single[0], lev::ListEntry {
            name_1: String::from("Rust"),
            name_2: String::from("Cargo"),
            time: 201
        });
        assert_eq!(level.top10_single[2], lev::ListEntry {
            name_1: String::from("Cargo"),
            name_2: String::from("Rust"),
            time: 206
        });
        assert_eq!(level.top10_single[9], lev::ListEntry {
            name_1: String::from("Rust"),
            name_2: String::from("Cargo"),
            time: 308
        });
    }

    // TODO: Add more levels to test, including some corrupt ones!

    #[test]
    // Probably redundant, but maybe some new fields are added in the future.
    // Doesn't hurt or impact anything.
    fn rec_default_values () {
        let replay = rec::Replay::new();
        assert_eq!(replay.multi, false);
        assert_eq!(replay.flag_tag, false);
        assert_eq!(replay.link, 0);
        assert_eq!(replay.level, "");
        assert_eq!(replay.frames, vec![]);
        assert_eq!(replay.events, vec![]);
    }

    #[test]
    fn load_valid_replay_1 () {
        let replay = rec::Replay::load_replay("tests/test_1.rec");
        assert_eq!(replay.multi, false);
        assert_eq!(replay.flag_tag, false);
        assert_eq!(replay.link, 2549082363);
        assert_eq!(replay.level, "tutor14.lev");

        // Frames tests.
        assert_eq!(replay.frames.len(), 440);
        assert_eq!(replay.frames[0], rec::Frame {
            bike: Position { x: 34.30250_f32, y: -1.1253119_f32 },
            left_wheel: Position { x: -850, y: -524 },
            right_wheel: Position { x: 849 , y: -524 },
            head: Position { x: 0, y: 439 },
            rotation: 10000,
            left_wheel_rotation: 250,
            right_wheel_rotation: 0,
            throttle: true,
            right: false,
            volume: 5120
        });
        assert_eq!(replay.frames[100], rec::Frame {
            bike: Position { x: 27.142517089844_f32, y: -1.1152113676071_f32 },
            left_wheel: Position { x: -903, y: -514 },
            right_wheel: Position { x: 586, y: -534 },
            head: Position { x: 74, y: 397 },
            rotation: 9826,
            left_wheel_rotation: 248,
            right_wheel_rotation: 238,
            throttle: true,
            right: false,
            volume: -5398
        });
        assert_eq!(replay.frames[201], rec::Frame {
            bike: Position { x: 11.07129573822_f32, y: 2.8753623962402_f32 },
            left_wheel: Position { x: -511, y: 917 },
            right_wheel: Position { x: -692, y: -789 },
            head: Position { x: 471, y: 10 },
            rotation: 7325,
            left_wheel_rotation: 25,
            right_wheel_rotation: 23,
            throttle: true,
            right: false,
            volume: -5398
        });
        assert_eq!(replay.frames[439], rec::Frame {
            bike: Position { x: -34.779712677002_f32, y: 11.526465415955_f32 },
            left_wheel: Position { x: -1050, y: -33 },
            right_wheel: Position { x: 286, y: -757 },
            head: Position { x: 226, y: 376 },
            rotation: 9047,
            left_wheel_rotation: 73,
            right_wheel_rotation: 163,
            throttle: true,
            right: false,
            volume: 5652
        });

        // Event tests.
        assert_eq!(replay.events.len(), 24);
        assert_eq!(replay.events[0], rec::Event {
            time: 1.57728480001688_f64,
            event_type: rec::EventType::VoltRight
         });
        assert_eq!(replay.events[1], rec::Event {
            time: 1.6974048000097273_f64,
            event_type: rec::EventType::Ground { alternative: false }
         });
        assert_eq!(replay.events[11], rec::Event {
            time: 3.9464880000114437_f64,
            event_type: rec::EventType::VoltLeft
         });
        assert_eq!(replay.events[23], rec::Event {
            time: 6.398683200001716_f64,
            event_type: rec::EventType::Touch { index: 3 }
         });
    }
}
<commit_msg>Add tests for time format function<commit_after>extern crate elma;
extern crate rand;
#[cfg(test)]
mod tests {
    use elma::{ lev, rec, Position, time_format };
    use rand::random;

    // Helper functions.
    #[test]
    fn test_decrypt_encrypt () {
        let mut initial: Vec<u8> = vec![];
        for _ in 0..688 {
            initial.push(random::<u8>());
        }
        let decrypted = lev::crypt_top10(&initial);
        let encrypted = lev::crypt_top10(&decrypted);
        assert_eq!(initial, encrypted);
    }

    #[test]
    fn test_time_format () {
        assert_eq!("11:48,01", time_format(114801));
        assert_eq!("01:00,21", time_format(10021));
        assert_eq!("00:10,00", time_format(1000));
        assert_eq!("10:00,00", time_format(100000));
        assert_eq!("00:00,00", time_format(0));
    }

    #[test]
    // Probably redundant, but maybe some new fields are added in the future.
    // Doesn't hurt or impact anything.
    fn level_default_values () {
        let level = lev::Level::new();
        assert_eq!(level.version, lev::Version::Elma);
        assert_eq!(level.link, 0);
        assert_eq!(level.integrity, [0_f64; 4]);
        assert_eq!(level.name, "");
        assert_eq!(level.lgr, "default");
        assert_eq!(level.ground, "ground");
        assert_eq!(level.sky, "sky");
        assert_eq!(level.polygons, vec![]);
        assert_eq!(level.objects, vec![]);
        assert_eq!(level.pictures, vec![]);
        assert_eq!(level.top10_single, vec![]);
        assert_eq!(level.top10_multi, vec![]);
    }

    #[test]
    fn load_valid_level_1 () {
        let level = lev::Level::load_level("tests/test_1.lev");
        assert_eq!(level.version, lev::Version::Elma);
        assert_eq!(level.link, 1524269776);
        assert_eq!(level.integrity, [-1148375.210607791_f64,
                                      1164056.210607791_f64,
                                      1162467.210607791_f64,
                                      1162283.210607791_f64]);
        assert_eq!(level.name, "Rust test");
        assert_eq!(level.lgr, "default");
        assert_eq!(level.ground, "ground");
        assert_eq!(level.sky, "sky");

        // Polygon tests.
        assert_eq!(level.polygons.len(), 2);
        assert_eq!(level.polygons, vec![lev::Polygon {
                grass: false, vertices: vec![
                    Position { x: -23.993693053024586_f64, y: -3.135779367971911_f64 },
                    Position { x: -15.989070625361132_f64, y: -3.135779367971911_f64 },
                    Position { x: -15.989070625361132_f64, y: 1.995755366905195_f64 },
                    Position { x: -24f64, y: 2f64 }]
            },
            lev::Polygon {
                grass: true, vertices: vec![
                    Position { x: -23.83645939819548_f64, y: 2.310222676563402_f64 },
                    Position { x: -17.60428907951465_f64, y: 2.2816347393217473_f64 },
                    Position { x: -17.53281923641051_f64, y: 1.8956975865594021_f64 },
                    Position { x: -23.96510511578293_f64, y: 1.924285523801057_f64 }]
            }
        ]);

        // Object tests.
        assert_eq!(level.objects.len(), 8);
        assert_eq!(level.objects, vec![lev::Object {
                position: Position { x: -23.221818747499896_f64, y: -1.3204453531268072_f64 },
                object_type: lev::ObjectType::Killer
            },
            lev::Object {
                position: Position { x: -20.37252715482359_f64, y: -0.3124543521844827_f64 },
                object_type: lev::ObjectType::Apple { gravity: lev::Direction::Normal, animation: 9 }
            },
            lev::Object {
                position: Position { x: -20.3914786548306_f64, y: 0.5277288147929609_f64 },
                object_type: lev::ObjectType::Apple { gravity: lev::Direction::Up, animation: 1 }
            },
            lev::Object {
                position: Position { x: -19.526026821177144_f64, y: 0.36348248139887396_f64 },
                object_type: lev::ObjectType::Apple { gravity: lev::Direction::Right, animation: 5 }
            },
            lev::Object {
                position: Position { x: -21.269564821822065_f64, y: 0.38243398140588436_f64 },
                object_type: lev::ObjectType::Apple { gravity: lev::Direction::Left, animation: 1 }
            },
            lev::Object {
                position: Position { x: -19.55761265452216_f64, y: -0.4387976855645497_f64 },
                object_type: lev::ObjectType::Apple { gravity: lev::Direction::Up, animation: 1 }
            },
            lev::Object {
                position: Position { x: -20.075620321380434_f64, y: -1.2473950191969765_f64 },
                object_type: lev::ObjectType::Exit
            },
            lev::Object {
                position: Position { x: -22.94993115577695_f64, y: 1.5068896484884773_f64 },
                object_type: lev::ObjectType::Player
            }
        ]);

        // Picture tests.
        assert_eq!(level.pictures.len(), 2);
        assert_eq!(level.pictures, vec![lev::Picture {
            name: String::from("barrel"),
            texture: String::new(),
            mask: String::new(),
            position: Position { x: -19.37674118849727_f64, y: 0.895119783101471_f64 },
            distance: 380,
            clip: lev::Clip::Sky
        },
        lev::Picture {
            name: String::new(),
            texture: String::from("stone1"),
            mask: String::from("maskbig"),
            position: Position { x: -24.465394017511894_f64, y: -3.964829547979911_f64 },
            distance: 750,
            clip: lev::Clip::Sky
        }]);

        // Top10 tests.
        assert_eq!(level.top10_single[0], lev::ListEntry {
            name_1: String::from("Rust"),
            name_2: String::from("Cargo"),
            time: 201
        });
        assert_eq!(level.top10_single[2], lev::ListEntry {
            name_1: String::from("Cargo"),
            name_2: String::from("Rust"),
            time: 206
        });
        assert_eq!(level.top10_single[9], lev::ListEntry {
            name_1: String::from("Rust"),
            name_2: String::from("Cargo"),
            time: 308
        });
    }

    // TODO: Add more levels to test, including some corrupt ones!

    #[test]
    // Probably redundant, but maybe some new fields are added in the future.
    // Doesn't hurt or impact anything.
    fn rec_default_values () {
        let replay = rec::Replay::new();
        assert_eq!(replay.multi, false);
        assert_eq!(replay.flag_tag, false);
        assert_eq!(replay.link, 0);
        assert_eq!(replay.level, "");
        assert_eq!(replay.frames, vec![]);
        assert_eq!(replay.events, vec![]);
    }

    #[test]
    fn load_valid_replay_1 () {
        let replay = rec::Replay::load_replay("tests/test_1.rec");
        assert_eq!(replay.multi, false);
        assert_eq!(replay.flag_tag, false);
        assert_eq!(replay.link, 2549082363);
        assert_eq!(replay.level, "tutor14.lev");

        // Frames tests.
        assert_eq!(replay.frames.len(), 440);
        assert_eq!(replay.frames[0], rec::Frame {
            bike: Position { x: 34.30250_f32, y: -1.1253119_f32 },
            left_wheel: Position { x: -850, y: -524 },
            right_wheel: Position { x: 849 , y: -524 },
            head: Position { x: 0, y: 439 },
            rotation: 10000,
            left_wheel_rotation: 250,
            right_wheel_rotation: 0,
            throttle: true,
            right: false,
            volume: 5120
        });
        assert_eq!(replay.frames[100], rec::Frame {
            bike: Position { x: 27.142517089844_f32, y: -1.1152113676071_f32 },
            left_wheel: Position { x: -903, y: -514 },
            right_wheel: Position { x: 586, y: -534 },
            head: Position { x: 74, y: 397 },
            rotation: 9826,
            left_wheel_rotation: 248,
            right_wheel_rotation: 238,
            throttle: true,
            right: false,
            volume: -5398
        });
        assert_eq!(replay.frames[201], rec::Frame {
            bike: Position { x: 11.07129573822_f32, y: 2.8753623962402_f32 },
            left_wheel: Position { x: -511, y: 917 },
            right_wheel: Position { x: -692, y: -789 },
            head: Position { x: 471, y: 10 },
            rotation: 7325,
            left_wheel_rotation: 25,
            right_wheel_rotation: 23,
            throttle: true,
            right: false,
            volume: -5398
        });
        assert_eq!(replay.frames[439], rec::Frame {
            bike: Position { x: -34.779712677002_f32, y: 11.526465415955_f32 },
            left_wheel: Position { x: -1050, y: -33 },
            right_wheel: Position { x: 286, y: -757 },
            head: Position { x: 226, y: 376 },
            rotation: 9047,
            left_wheel_rotation: 73,
            right_wheel_rotation: 163,
            throttle: true,
            right: false,
            volume: 5652
        });

        // Event tests.
        assert_eq!(replay.events.len(), 24);
        assert_eq!(replay.events[0], rec::Event {
            time: 1.57728480001688_f64,
            event_type: rec::EventType::VoltRight
         });
        assert_eq!(replay.events[1], rec::Event {
            time: 1.6974048000097273_f64,
            event_type: rec::EventType::Ground { alternative: false }
         });
        assert_eq!(replay.events[11], rec::Event {
            time: 3.9464880000114437_f64,
            event_type: rec::EventType::VoltLeft
         });
        assert_eq!(replay.events[23], rec::Event {
            time: 6.398683200001716_f64,
            event_type: rec::EventType::Touch { index: 3 }
         });
    }
}
<|endoftext|>


<commit_before>extern crate littletest;

use littletest::{Runnable, TestResult, TestRunner};

struct TestCase {
    result: TestResult
}

impl TestCase {
    fn new(result: TestResult) -> TestCase {
        TestCase {
            result: result
        }
    }
}

impl Runnable for TestCase {
    fn run(&self) -> TestResult {
        match self.result {
            TestResult::Pass => TestResult::Pass,
            TestResult::Fail => TestResult::Fail,
            TestResult::Error => TestResult::Error,
            TestResult::Skipped => TestResult::Skipped
        }
    }
}

#[test]
fn it_works() {
    let tests = vec![TestResult::Pass];
    let runnables: Vec<Box<Runnable>> = tests
        .into_iter()
        .map(|result| Box::new(TestCase::new(result)) as Box<Runnable>)
        .collect();

    let runner = TestRunner;
    runner.run(&runnables);
}
<commit_msg>Use new clone in the integration tests.<commit_after>extern crate littletest;

use littletest::{Runnable, TestResult, TestRunner};

struct TestCase {
    result: TestResult
}

impl TestCase {
    fn new(result: TestResult) -> TestCase {
        TestCase {
            result: result
        }
    }
}

impl Runnable for TestCase {
    fn run(&self) -> TestResult {
        self.result.clone()
    }
}

#[test]
fn it_works() {
    let tests = vec![TestResult::Pass];
    let runnables: Vec<Box<Runnable>> = tests
        .into_iter()
        .map(|result| Box::new(TestCase::new(result)) as Box<Runnable>)
        .collect();

    let runner = TestRunner;
    runner.run(&runnables);
}
<|endoftext|>