<commit_before>use super::event_manager::*;
use glium::glutin::{ElementState, Event, VirtualKeyCode};
use std::f32::consts;
use base::math::*;

#[derive(Debug)]
pub struct DayTime {
    time_year: u32,
    time_day: u32,
    time_on_day: f32,
    speed: f32,
}

// `DEFAULT_TIME_SPEED` is 1.0 so the time goes at normal speed
// `PLUS_TIME_SPEED` is the factor with which the time is sped up, when the
// speed-up key is pressed
const DEFAULT_TIME_SPEED: f32 = 1.0;
const PLUS_TIME_SPEED: f32 = 1000.0;

impl Default for DayTime {
    fn default() -> DayTime {
        DayTime {
            time_year: 0,
            time_day: 0,
            time_on_day: 0.0,
            speed: 1.0,
        }
    }
}

const DAY_LENGTH: f32 = 720.0;
const YEAR_LENGTH: u32 = 12;

const MONTH_DIFFERENCE: f32 = 3.1415 / 18.0;

impl DayTime {
    pub fn set_time(&mut self, time_year: u32, time_day: u32, time_on_day: f32) {
        self.time_year = time_year;
        self.time_day = time_day;
        self.time_on_day = time_on_day;
        self.speed = DEFAULT_TIME_SPEED;
    }

    pub fn get_time_year(&self) -> u32 {
        self.time_year
    }

    pub fn get_time_day(&self) -> u32 {
        self.time_day
    }

    pub fn get_time_on_day(&self) -> f32 {
        self.time_on_day
    }

    /// Updates time with the use of `delta` as additionally passed time
    /// `DAY_LENGTH` defines the length of a day in real-life seconds
    /// `YEAR_LENGTH` defines the length of a year in `DAY_LENGTH`s
    pub fn update(&mut self, delta: f32) {
        // Output of Time
        debug!("Year: {} Day: {} Time: {}",
               self.time_year,
               self.time_day,
               self.time_on_day);

        // Checks if one day has passed
        self.time_on_day += delta * self.speed;
        if (self.time_on_day) >= DAY_LENGTH {
            self.time_on_day -= DAY_LENGTH; // Removes one day from time_on_day
            self.time_day += 1;
            if (self.time_day) >= YEAR_LENGTH {
                self.time_day = 0;
                self.time_year += 1;
            }
        }

    }

    /// returns the position of the sun corresponding to time
    pub fn get_sun_position(&self) -> Vector3f {
        // 0 degrees for mid summer
        // 60 degrees for hard winter
        let half_year = YEAR_LENGTH as f32 / 2.0;
        let half_day = DAY_LENGTH as f32 / 2.0;

        let mut theta = self.time_day as f32 - half_year;
        if theta < 0.0 {
            theta *= -1.0;
        }
        // theta now is the day difference from the highest day, sunposition-wise
        theta *= MONTH_DIFFERENCE;

        if self.time_on_day < half_day {
            // pre noon
            // sun rising
            theta += consts::PI - consts::PI * (self.time_on_day / half_day)
        } else {
            // after noon
            // sun going down
            theta += consts::PI * ((self.time_on_day - half_day) / half_day)
        }

        let phi = self.time_on_day / DAY_LENGTH as f32 * 2.0 * consts::PI;

        // for debugging
        // info!("THETA: {} PHI: {}", theta, phi);

        // returns sun position in cartesian coordinates
        Vector3f::new(theta.sin() * phi.cos(),
                      theta.sin() * phi.sin(),
                      theta.cos())

    }

    /// returns the Vector3f for the directional sunlight
    pub fn get_sun_light_vector(&self) -> Vector3f {
        Vector3f::new(0.0, 0.0, 0.0) - self.get_sun_position()
    }
}

/// Handler to speed up time with use of '+' key
impl EventHandler for DayTime {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Add)) => {
                self.speed = PLUS_TIME_SPEED;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Add)) => {
                self.speed = DEFAULT_TIME_SPEED;
                EventResponse::Continue
            }
            _ => EventResponse::NotHandled,
        }

    }
}
<commit_msg>change speed in default function of daytime to `DEFAULT_TIME_SPEED`<commit_after>use super::event_manager::*;
use glium::glutin::{ElementState, Event, VirtualKeyCode};
use std::f32::consts;
use base::math::*;

#[derive(Debug)]
pub struct DayTime {
    time_year: u32,
    time_day: u32,
    time_on_day: f32,
    speed: f32,
}

// `DEFAULT_TIME_SPEED` is 1.0 so the time goes at normal speed
// `PLUS_TIME_SPEED` is the factor with which the time is sped up, when the
// speed-up key is pressed
const DEFAULT_TIME_SPEED: f32 = 1.0;
const PLUS_TIME_SPEED: f32 = 1000.0;

impl Default for DayTime {
    fn default() -> DayTime {
        DayTime {
            time_year: 0,
            time_day: 0,
            time_on_day: 0.0,
            speed: DEFAULT_TIME_SPEED,
        }
    }
}

const DAY_LENGTH: f32 = 720.0;
const YEAR_LENGTH: u32 = 12;

const MONTH_DIFFERENCE: f32 = 3.1415 / 18.0;

impl DayTime {
    pub fn set_time(&mut self, time_year: u32, time_day: u32, time_on_day: f32) {
        self.time_year = time_year;
        self.time_day = time_day;
        self.time_on_day = time_on_day;
        self.speed = DEFAULT_TIME_SPEED;
    }

    pub fn get_time_year(&self) -> u32 {
        self.time_year
    }

    pub fn get_time_day(&self) -> u32 {
        self.time_day
    }

    pub fn get_time_on_day(&self) -> f32 {
        self.time_on_day
    }

    /// Updates time with the use of `delta` as additionally passed time
    /// `DAY_LENGTH` defines the length of a day in real-life seconds
    /// `YEAR_LENGTH` defines the length of a year in `DAY_LENGTH`s
    pub fn update(&mut self, delta: f32) {
        // Output of Time
        debug!("Year: {} Day: {} Time: {}",
               self.time_year,
               self.time_day,
               self.time_on_day);

        // Checks if one day has passed
        self.time_on_day += delta * self.speed;
        if (self.time_on_day) >= DAY_LENGTH {
            self.time_on_day -= DAY_LENGTH; // Removes one day from time_on_day
            self.time_day += 1;
            if (self.time_day) >= YEAR_LENGTH {
                self.time_day = 0;
                self.time_year += 1;
            }
        }

    }

    /// returns the position of the sun corresponding to time
    pub fn get_sun_position(&self) -> Vector3f {
        // 0 degrees for mid summer
        // 60 degrees for hard winter
        let half_year = YEAR_LENGTH as f32 / 2.0;
        let half_day = DAY_LENGTH as f32 / 2.0;

        let mut theta = self.time_day as f32 - half_year;
        if theta < 0.0 {
            theta *= -1.0;
        }
        // theta now is the day difference from the highest day, sunposition-wise
        theta *= MONTH_DIFFERENCE;

        if self.time_on_day < half_day {
            // pre noon
            // sun rising
            theta += consts::PI - consts::PI * (self.time_on_day / half_day)
        } else {
            // after noon
            // sun going down
            theta += consts::PI * ((self.time_on_day - half_day) / half_day)
        }

        let phi = self.time_on_day / DAY_LENGTH as f32 * 2.0 * consts::PI;

        // for debugging
        // info!("THETA: {} PHI: {}", theta, phi);

        // returns sun position in cartesian coordinates
        Vector3f::new(theta.sin() * phi.cos(),
                      theta.sin() * phi.sin(),
                      theta.cos())

    }

    /// returns the Vector3f for the directional sunlight
    pub fn get_sun_light_vector(&self) -> Vector3f {
        Vector3f::new(0.0, 0.0, 0.0) - self.get_sun_position()
    }
}

/// Handler to speed up time with use of '+' key
impl EventHandler for DayTime {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Add)) => {
                self.speed = PLUS_TIME_SPEED;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Add)) => {
                self.speed = DEFAULT_TIME_SPEED;
                EventResponse::Continue
            }
            _ => EventResponse::NotHandled,
        }

    }
}
<|endoftext|>


<commit_before>use super::event_manager::*;
use glium::glutin::{ElementState, Event, VirtualKeyCode};
use std::f32::consts;
use base::math::*;

#[derive(Debug)]
pub struct DayTime {
    time_year: u32,
    time_day: u32,
    time_on_day: f32,
    speed: f32,
}

// `DEFAULT_TIME_SPEED` is 1.0 so the time goes at normal speed
// `PLUS_TIME_SPEED` is the factor with which the time is sped up, when the
// speed-up key is pressed
const DEFAULT_TIME_SPEED: f32 = 1.0;
const PLUS_TIME_SPEED: f32 = 500.0;

impl Default for DayTime {
    fn default() -> DayTime {
        DayTime {
            time_year: 0,
            time_day: 0,
            time_on_day: 0.0,
            speed: DEFAULT_TIME_SPEED,
        }
    }
}

const DAY_LENGTH: f32 = 720.0;
const YEAR_LENGTH: u32 = 12;

const MONTH_DIFFERENCE: f32 = 3.1415 / 18.0;

impl DayTime {
    pub fn set_time(&mut self, time_year: u32, time_day: u32, time_on_day: f32) {
        self.time_year = time_year;
        self.time_day = time_day;
        self.time_on_day = time_on_day;
        self.speed = DEFAULT_TIME_SPEED;
    }

    pub fn get_time_year(&self) -> u32 {
        self.time_year
    }

    pub fn get_time_day(&self) -> u32 {
        self.time_day
    }

    pub fn get_time_on_day(&self) -> f32 {
        self.time_on_day
    }

    /// Updates time with the use of `delta` as additionally passed time
    /// `DAY_LENGTH` defines the length of a day in real-life seconds
    /// `YEAR_LENGTH` defines the length of a year in `DAY_LENGTH`s
    pub fn update(&mut self, delta: f32) {
        // Output of Time
        debug!("Year: {} Day: {} Time: {}",
               self.time_year,
               self.time_day,
               self.time_on_day);

        // Checks if one day has passed
        self.time_on_day += delta * self.speed;
        if (self.time_on_day) >= DAY_LENGTH {
            self.time_on_day -= DAY_LENGTH; // Removes one day from time_on_day
            self.time_day += 1;
            if (self.time_day) >= YEAR_LENGTH {
                self.time_day = 0;
                self.time_year += 1;
            }
        }

    }

    /// returns the position of the sun corresponding to time
    /// only mid summer
    pub fn get_sun_position(&self) -> Vector3f {
        // 0 degrees for mid summer
        // 60 degrees for hard winter
        let half_day = DAY_LENGTH as f32 / 2.0;

        let theta;
        let phi;
        if self.time_on_day < half_day {
            // pre noon
            // sun rising
            theta = consts::PI - consts::PI * (self.time_on_day / half_day);
            phi = 0.0;
        } else {
            // after noon
            // sun going down
            theta = consts::PI * ((self.time_on_day - half_day) / half_day);
            phi = consts::PI;
        }

        // for debugging
        // info!("THETA: {} PHI: {}", theta, phi);

        // returns sun position in cartesian coordinates
        Vector3f::new(theta.sin() * phi.cos(),
                      theta.sin() * phi.sin(),
                      theta.cos())

    }

    /// returns the position of the sun corresponding to time
    /// does not work right now
    pub fn get_sun_position_real(&self) -> Vector3f {
        // 0 degrees for mid summer
        // 60 degrees for hard winter
        let half_year = YEAR_LENGTH as f32 / 2.0;
        let half_day = DAY_LENGTH as f32 / 2.0;

        let mut theta = self.time_day as f32 - half_year;
        if theta < 0.0 {
            theta *= -1.0;
        }
        // theta now is the day difference from the highest day, sunposition-wise
        theta *= MONTH_DIFFERENCE;

        if self.time_on_day < half_day {
            // pre noon
            // sun rising
            theta += consts::PI - consts::PI * (self.time_on_day / half_day)
        } else {
            // after noon
            // sun going down
            theta += consts::PI * ((self.time_on_day - half_day) / half_day)
        }

        let phi = self.time_on_day / DAY_LENGTH as f32 * 2.0 * consts::PI;

        // for debugging
        // info!("THETA: {} PHI: {}", theta, phi);

        // returns sun position in cartesian coordinates
        Vector3f::new(theta.sin() * phi.cos(),
                      theta.sin() * phi.sin(),
                      theta.cos())

    }

    /// returns the Vector3f for the directional sunlight
    pub fn get_sun_light_vector(&self) -> Vector3f {
        Vector3f::new(0.0, 0.0, 0.0) - self.get_sun_position()
    }
}

/// Handler to speed up time with use of '+' key
impl EventHandler for DayTime {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Add)) => {
                self.speed = PLUS_TIME_SPEED;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Add)) => {
                self.speed = DEFAULT_TIME_SPEED;
                EventResponse::Continue
            }
            _ => EventResponse::NotHandled,
        }

    }
}
<commit_msg>change `PLUS_TIME_SPEED` to 200.0<commit_after>use super::event_manager::*;
use glium::glutin::{ElementState, Event, VirtualKeyCode};
use std::f32::consts;
use base::math::*;

#[derive(Debug)]
pub struct DayTime {
    time_year: u32,
    time_day: u32,
    time_on_day: f32,
    speed: f32,
}

// `DEFAULT_TIME_SPEED` is 1.0 so the time goes at normal speed
// `PLUS_TIME_SPEED` is the factor with which the time is sped up, when the
// speed-up key is pressed
const DEFAULT_TIME_SPEED: f32 = 1.0;
const PLUS_TIME_SPEED: f32 = 200.0;

impl Default for DayTime {
    fn default() -> DayTime {
        DayTime {
            time_year: 0,
            time_day: 0,
            time_on_day: 0.0,
            speed: DEFAULT_TIME_SPEED,
        }
    }
}

const DAY_LENGTH: f32 = 720.0;
const YEAR_LENGTH: u32 = 12;

const MONTH_DIFFERENCE: f32 = 3.1415 / 18.0;

impl DayTime {
    pub fn set_time(&mut self, time_year: u32, time_day: u32, time_on_day: f32) {
        self.time_year = time_year;
        self.time_day = time_day;
        self.time_on_day = time_on_day;
        self.speed = DEFAULT_TIME_SPEED;
    }

    pub fn get_time_year(&self) -> u32 {
        self.time_year
    }

    pub fn get_time_day(&self) -> u32 {
        self.time_day
    }

    pub fn get_time_on_day(&self) -> f32 {
        self.time_on_day
    }

    /// Updates time with the use of `delta` as additionally passed time
    /// `DAY_LENGTH` defines the length of a day in real-life seconds
    /// `YEAR_LENGTH` defines the length of a year in `DAY_LENGTH`s
    pub fn update(&mut self, delta: f32) {
        // Output of Time
        debug!("Year: {} Day: {} Time: {}",
               self.time_year,
               self.time_day,
               self.time_on_day);

        // Checks if one day has passed
        self.time_on_day += delta * self.speed;
        if (self.time_on_day) >= DAY_LENGTH {
            self.time_on_day -= DAY_LENGTH; // Removes one day from time_on_day
            self.time_day += 1;
            if (self.time_day) >= YEAR_LENGTH {
                self.time_day = 0;
                self.time_year += 1;
            }
        }

    }

    /// returns the position of the sun corresponding to time
    /// only mid summer
    pub fn get_sun_position(&self) -> Vector3f {
        // 0 degrees for mid summer
        // 60 degrees for hard winter
        let half_day = DAY_LENGTH as f32 / 2.0;

        let theta;
        let phi;
        if self.time_on_day < half_day {
            // pre noon
            // sun rising
            theta = consts::PI - consts::PI * (self.time_on_day / half_day);
            phi = 0.0;
        } else {
            // after noon
            // sun going down
            theta = consts::PI * ((self.time_on_day - half_day) / half_day);
            phi = consts::PI;
        }

        // for debugging
        // info!("THETA: {} PHI: {}", theta, phi);

        // returns sun position in cartesian coordinates
        Vector3f::new(theta.sin() * phi.cos(),
                      theta.sin() * phi.sin(),
                      theta.cos())

    }

    /// returns the position of the sun corresponding to time
    /// does not work right now
    pub fn get_sun_position_real(&self) -> Vector3f {
        // 0 degrees for mid summer
        // 60 degrees for hard winter
        let half_year = YEAR_LENGTH as f32 / 2.0;
        let half_day = DAY_LENGTH as f32 / 2.0;

        let mut theta = self.time_day as f32 - half_year;
        if theta < 0.0 {
            theta *= -1.0;
        }
        // theta now is the day difference from the highest day, sunposition-wise
        theta *= MONTH_DIFFERENCE;

        if self.time_on_day < half_day {
            // pre noon
            // sun rising
            theta += consts::PI - consts::PI * (self.time_on_day / half_day)
        } else {
            // after noon
            // sun going down
            theta += consts::PI * ((self.time_on_day - half_day) / half_day)
        }

        let phi = self.time_on_day / DAY_LENGTH as f32 * 2.0 * consts::PI;

        // for debugging
        // info!("THETA: {} PHI: {}", theta, phi);

        // returns sun position in cartesian coordinates
        Vector3f::new(theta.sin() * phi.cos(),
                      theta.sin() * phi.sin(),
                      theta.cos())

    }

    /// returns the Vector3f for the directional sunlight
    pub fn get_sun_light_vector(&self) -> Vector3f {
        Vector3f::new(0.0, 0.0, 0.0) - self.get_sun_position()
    }
}

/// Handler to speed up time with use of '+' key
impl EventHandler for DayTime {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Add)) => {
                self.speed = PLUS_TIME_SPEED;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Add)) => {
                self.speed = DEFAULT_TIME_SPEED;
                EventResponse::Continue
            }
            _ => EventResponse::NotHandled,
        }

    }
}
<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::sync::Arc;

use regex::Regex;
use threadpool::{self, ThreadPool};

use config::Config;
use errors::*;
use git::Git;
use git_clone_manager::GitCloneManager;
use github;
use github::api::Session;
use messenger;
use slack::{SlackAttachmentBuilder, SlackRequest};
use worker::{self, WorkSender};

pub fn merge_pull_request(
    session: &Session,
    clone_mgr: &GitCloneManager,
    owner: &str,
    repo: &str,
    pull_request: &github::PullRequest,
    target_branch: &str,
) -> Result<github::PullRequest> {
    Merger::new(session, clone_mgr).merge_pull_request(
        owner,
        repo,
        pull_request,
        target_branch,
    )
}

struct Merger<'a> {
    session: &'a Session,
    clone_mgr: &'a GitCloneManager,
}

impl<'a> Merger<'a> {
    pub fn new(session: &'a Session, clone_mgr: &'a GitCloneManager) -> Merger<'a> {
        Merger {
            session: session,
            clone_mgr: clone_mgr,
        }
    }

    pub fn merge_pull_request(
        &self,
        owner: &str,
        repo: &str,
        pull_request: &github::PullRequest,
        target_branch: &str,
    ) -> Result<github::PullRequest> {
        if !pull_request.is_merged() {
            return Err(format!("Pull Request #{} is not yet merged.", pull_request.number).into());
        }

        let merge_commit_sha;
        if let Some(ref sha) = pull_request.merge_commit_sha {
            merge_commit_sha = sha;
        } else {
            return Err(format!("Pull Request #{} has no merge commit.", pull_request.number).into());
        }

        // strip everything before last slash
        let regex = Regex::new(r".*/").unwrap();
        let pr_branch_name =
            format!("{}-{}", regex.replace(&pull_request.head.ref_name, ""), regex.replace(&target_branch, ""));

        let held_clone_dir = self.clone_mgr.clone(owner, repo)?;
        let clone_dir = held_clone_dir.dir();

        let git = Git::new(self.session.github_host(), self.session.github_token(), clone_dir);

        // make sure there isn't already such a branch
        let current_remotes = git.run(&["ls-remote", "--heads"])?;
        if current_remotes.contains(&format!("refs/heads/{}", pr_branch_name)) {
            return Err(format!("PR branch already exists on origin: '{}'", pr_branch_name).into());
        }

        let (title, body) = self.cherry_pick(
            &git,
            &merge_commit_sha,
            &pr_branch_name,
            pull_request.number,
            &target_branch,
            &pull_request.base.ref_name,
        )?;

        git.run(&["push", "origin", &format!("{}:{}", pr_branch_name, pr_branch_name)])?;

        let new_pr = self.session.create_pull_request(
            owner,
            repo,
            &title,
            &body,
            &pr_branch_name,
            &target_branch,
        )?;

        let assignees: Vec<String> = pull_request.assignees.iter().map(|a| a.login().to_string()).collect();
        self.session.assign_pull_request(owner, repo, new_pr.number, assignees)?;

        Ok(new_pr)
    }

    fn cherry_pick(
        &self,
        git: &Git,
        commit_hash: &str,
        pr_branch_name: &str,
        pr_number: u32,
        target_branch: &str,
        orig_base_branch: &str,
    ) -> Result<(String, String)> {
        git.checkout_branch(pr_branch_name, &format!("origin/{}", target_branch))?;

        // cherry-pick!
        git.run(
            &[
                "-c",
                "merge.renameLimit=999999",
                "cherry-pick",
                "-X",
                "ignore-all-space",
                commit_hash,
            ],
        )?;

        let desc = git.get_commit_desc(commit_hash)?;
        let desc = make_merge_desc(desc, commit_hash, pr_number, target_branch, orig_base_branch);

        // change commit message
        git.run_with_stdin(
            &["commit", "--amend", "-F", "-"],
            &format!("{}\n\n{}", &desc.0, &desc.1),
        )?;

        Ok(desc)
    }
}

fn make_merge_desc(
    orig_desc: (String, String),
    commit_hash: &str,
    pr_number: u32,
    target_branch: &str,
    orig_base_branch: &str,
) -> (String, String) {
    // grab original title and strip out the PR number at the end
    let pr_regex = Regex::new(r"(\s*\(#\d+\))+$").unwrap();
    let orig_title = pr_regex.replace(&orig_desc.0, "");
    // strip out 'release' from the prefix to keep titles shorter
    let release_branch_regex = Regex::new(r"^release/").unwrap();
    let title = format!("{}->{}: {}", orig_base_branch, release_branch_regex.replace(target_branch, ""), orig_title);
    let mut body = orig_desc.1;

    if body.len() != 0 {
        body += "\n\n";
    }
    body += format!("(cherry-picked from {}, PR #{})", commit_hash, pr_number).as_str();

    (title, body)
}

#[derive(Debug)]
pub struct PRMergeRequest {
    pub repo: github::Repo,
    pub pull_request: github::PullRequest,
    pub target_branch: String,
}

struct Runner {
    config: Arc<Config>,
    github_session: Arc<Session>,
    clone_mgr: Arc<GitCloneManager>,
    slack: WorkSender<SlackRequest>,
    thread_pool: ThreadPool,
}

pub fn req(repo: &github::Repo, pull_request: &github::PullRequest, target_branch: &str) -> PRMergeRequest {
    PRMergeRequest {
        repo: repo.clone(),
        pull_request: pull_request.clone(),
        target_branch: target_branch.to_string(),
    }
}

pub fn new_worker(
    max_concurrency: usize,
    config: Arc<Config>,
    github_session: Arc<Session>,
    clone_mgr: Arc<GitCloneManager>,
    slack: WorkSender<SlackRequest>,
) -> worker::Worker<PRMergeRequest> {
    worker::Worker::new(
        "pr-merge",
        Runner {
            config: config,
            github_session: github_session,
            clone_mgr: clone_mgr.clone(),
            slack: slack,
            thread_pool: threadpool::Builder::new()
                .num_threads(max_concurrency)
                .thread_name("pr-merge".to_string())
                .build(),
        },
    )
}

impl worker::Runner<PRMergeRequest> for Runner {
    fn handle(&self, req: PRMergeRequest) {
        let github_session = self.github_session.clone();
        let clone_mgr = self.clone_mgr.clone();
        let config = self.config.clone();

        let slack = self.slack.clone();

        // launch another thread to do the merge
        self.thread_pool.execute(move || {
            let merge_result = merge_pull_request(
                github_session.borrow(),
                &clone_mgr,
                &req.repo.owner.login(),
                &req.repo.name,
                &req.pull_request,
                &req.target_branch,
            );
            if let Err(e) = merge_result {

                let attach = SlackAttachmentBuilder::new(&format!("{}", e))
                    .title(
                        format!("Source PR: #{}: \"{}\"", req.pull_request.number, req.pull_request.title)
                            .as_str(),
                    )
                    .title_link(req.pull_request.html_url.clone())
                    .color("danger")
                    .build();

                let messenger = messenger::new(config, slack);
                messenger.send_to_owner(
                    &format!("Error creating merge PR from {} to {}", req.pull_request.head.ref_name, req.target_branch),
                    &vec![attach],
                    &req.pull_request.user,
                    &req.repo,
                );
            }
        });
    }
}

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

    #[test]
    fn test_make_merge_desc() {
        let desc = make_merge_desc(
            (String::from("Yay, I made a change (#99)"), String::from("here is more data about it")),
            "abcdef",
            99,
            "release/target_branch",
            "source_branch",
        );

        assert_eq!(desc.0, "source_branch->target_branch: Yay, I made a change");
        assert_eq!(desc.1, "here is more data about it\n\n(cherry-picked from abcdef, PR #99)");
    }

    #[test]
    fn test_make_merge_desc_no_body() {
        let desc = make_merge_desc(
            (String::from("Yay, I made a change (#99)"), String::from("")),
            "abcdef",
            99,
            "release/target_branch",
            "source_branch",
        );

        assert_eq!(desc.0, "source_branch->target_branch: Yay, I made a change");
        assert_eq!(desc.1, "(cherry-picked from abcdef, PR #99)");
    }

    #[test]
    fn test_make_merge_desc_no_release_branch() {
        let desc = make_merge_desc(
            (String::from("Yay, I made a change (#99)"), String::from("")),
            "abcdef",
            99,
            "other_branch",
            "source_branch",
        );

        assert_eq!(desc.0, "source_branch->other_branch: Yay, I made a change");
        assert_eq!(desc.1, "(cherry-picked from abcdef, PR #99)");
    }
}
<commit_msg>Allow backport of empty commits (#181)<commit_after>use std::borrow::Borrow;
use std::sync::Arc;

use regex::Regex;
use threadpool::{self, ThreadPool};

use config::Config;
use errors::*;
use git::Git;
use git_clone_manager::GitCloneManager;
use github;
use github::api::Session;
use messenger;
use slack::{SlackAttachmentBuilder, SlackRequest};
use worker::{self, WorkSender};

pub fn merge_pull_request(
    session: &Session,
    clone_mgr: &GitCloneManager,
    owner: &str,
    repo: &str,
    pull_request: &github::PullRequest,
    target_branch: &str,
) -> Result<github::PullRequest> {
    Merger::new(session, clone_mgr).merge_pull_request(
        owner,
        repo,
        pull_request,
        target_branch,
    )
}

struct Merger<'a> {
    session: &'a Session,
    clone_mgr: &'a GitCloneManager,
}

impl<'a> Merger<'a> {
    pub fn new(session: &'a Session, clone_mgr: &'a GitCloneManager) -> Merger<'a> {
        Merger {
            session: session,
            clone_mgr: clone_mgr,
        }
    }

    pub fn merge_pull_request(
        &self,
        owner: &str,
        repo: &str,
        pull_request: &github::PullRequest,
        target_branch: &str,
    ) -> Result<github::PullRequest> {
        if !pull_request.is_merged() {
            return Err(format!("Pull Request #{} is not yet merged.", pull_request.number).into());
        }

        let merge_commit_sha;
        if let Some(ref sha) = pull_request.merge_commit_sha {
            merge_commit_sha = sha;
        } else {
            return Err(format!("Pull Request #{} has no merge commit.", pull_request.number).into());
        }

        // strip everything before last slash
        let regex = Regex::new(r".*/").unwrap();
        let pr_branch_name =
            format!("{}-{}", regex.replace(&pull_request.head.ref_name, ""), regex.replace(&target_branch, ""));

        let held_clone_dir = self.clone_mgr.clone(owner, repo)?;
        let clone_dir = held_clone_dir.dir();

        let git = Git::new(self.session.github_host(), self.session.github_token(), clone_dir);

        // make sure there isn't already such a branch
        let current_remotes = git.run(&["ls-remote", "--heads"])?;
        if current_remotes.contains(&format!("refs/heads/{}", pr_branch_name)) {
            return Err(format!("PR branch already exists on origin: '{}'", pr_branch_name).into());
        }

        let (title, body) = self.cherry_pick(
            &git,
            &merge_commit_sha,
            &pr_branch_name,
            pull_request.number,
            &target_branch,
            &pull_request.base.ref_name,
        )?;

        git.run(&["push", "origin", &format!("{}:{}", pr_branch_name, pr_branch_name)])?;

        let new_pr = self.session.create_pull_request(
            owner,
            repo,
            &title,
            &body,
            &pr_branch_name,
            &target_branch,
        )?;

        let assignees: Vec<String> = pull_request.assignees.iter().map(|a| a.login().to_string()).collect();
        self.session.assign_pull_request(owner, repo, new_pr.number, assignees)?;

        Ok(new_pr)
    }

    fn cherry_pick(
        &self,
        git: &Git,
        commit_hash: &str,
        pr_branch_name: &str,
        pr_number: u32,
        target_branch: &str,
        orig_base_branch: &str,
    ) -> Result<(String, String)> {
        git.checkout_branch(pr_branch_name, &format!("origin/{}", target_branch))?;

        // cherry-pick!
        git.run(
            &[
                "-c",
                "merge.renameLimit=999999",
                "cherry-pick",
                "--allow-empty",
                "-X",
                "ignore-all-space",
                commit_hash,
            ],
        )?;

        let desc = git.get_commit_desc(commit_hash)?;
        let desc = make_merge_desc(desc, commit_hash, pr_number, target_branch, orig_base_branch);

        // change commit message
        git.run_with_stdin(
            &["commit", "--amend", "-F", "-"],
            &format!("{}\n\n{}", &desc.0, &desc.1),
        )?;

        Ok(desc)
    }
}

fn make_merge_desc(
    orig_desc: (String, String),
    commit_hash: &str,
    pr_number: u32,
    target_branch: &str,
    orig_base_branch: &str,
) -> (String, String) {
    // grab original title and strip out the PR number at the end
    let pr_regex = Regex::new(r"(\s*\(#\d+\))+$").unwrap();
    let orig_title = pr_regex.replace(&orig_desc.0, "");
    // strip out 'release' from the prefix to keep titles shorter
    let release_branch_regex = Regex::new(r"^release/").unwrap();
    let title = format!("{}->{}: {}", orig_base_branch, release_branch_regex.replace(target_branch, ""), orig_title);
    let mut body = orig_desc.1;

    if body.len() != 0 {
        body += "\n\n";
    }
    body += format!("(cherry-picked from {}, PR #{})", commit_hash, pr_number).as_str();

    (title, body)
}

#[derive(Debug)]
pub struct PRMergeRequest {
    pub repo: github::Repo,
    pub pull_request: github::PullRequest,
    pub target_branch: String,
}

struct Runner {
    config: Arc<Config>,
    github_session: Arc<Session>,
    clone_mgr: Arc<GitCloneManager>,
    slack: WorkSender<SlackRequest>,
    thread_pool: ThreadPool,
}

pub fn req(repo: &github::Repo, pull_request: &github::PullRequest, target_branch: &str) -> PRMergeRequest {
    PRMergeRequest {
        repo: repo.clone(),
        pull_request: pull_request.clone(),
        target_branch: target_branch.to_string(),
    }
}

pub fn new_worker(
    max_concurrency: usize,
    config: Arc<Config>,
    github_session: Arc<Session>,
    clone_mgr: Arc<GitCloneManager>,
    slack: WorkSender<SlackRequest>,
) -> worker::Worker<PRMergeRequest> {
    worker::Worker::new(
        "pr-merge",
        Runner {
            config: config,
            github_session: github_session,
            clone_mgr: clone_mgr.clone(),
            slack: slack,
            thread_pool: threadpool::Builder::new()
                .num_threads(max_concurrency)
                .thread_name("pr-merge".to_string())
                .build(),
        },
    )
}

impl worker::Runner<PRMergeRequest> for Runner {
    fn handle(&self, req: PRMergeRequest) {
        let github_session = self.github_session.clone();
        let clone_mgr = self.clone_mgr.clone();
        let config = self.config.clone();

        let slack = self.slack.clone();

        // launch another thread to do the merge
        self.thread_pool.execute(move || {
            let merge_result = merge_pull_request(
                github_session.borrow(),
                &clone_mgr,
                &req.repo.owner.login(),
                &req.repo.name,
                &req.pull_request,
                &req.target_branch,
            );
            if let Err(e) = merge_result {

                let attach = SlackAttachmentBuilder::new(&format!("{}", e))
                    .title(
                        format!("Source PR: #{}: \"{}\"", req.pull_request.number, req.pull_request.title)
                            .as_str(),
                    )
                    .title_link(req.pull_request.html_url.clone())
                    .color("danger")
                    .build();

                let messenger = messenger::new(config, slack);
                messenger.send_to_owner(
                    &format!("Error creating merge PR from {} to {}", req.pull_request.head.ref_name, req.target_branch),
                    &vec![attach],
                    &req.pull_request.user,
                    &req.repo,
                );
            }
        });
    }
}

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

    #[test]
    fn test_make_merge_desc() {
        let desc = make_merge_desc(
            (String::from("Yay, I made a change (#99)"), String::from("here is more data about it")),
            "abcdef",
            99,
            "release/target_branch",
            "source_branch",
        );

        assert_eq!(desc.0, "source_branch->target_branch: Yay, I made a change");
        assert_eq!(desc.1, "here is more data about it\n\n(cherry-picked from abcdef, PR #99)");
    }

    #[test]
    fn test_make_merge_desc_no_body() {
        let desc = make_merge_desc(
            (String::from("Yay, I made a change (#99)"), String::from("")),
            "abcdef",
            99,
            "release/target_branch",
            "source_branch",
        );

        assert_eq!(desc.0, "source_branch->target_branch: Yay, I made a change");
        assert_eq!(desc.1, "(cherry-picked from abcdef, PR #99)");
    }

    #[test]
    fn test_make_merge_desc_no_release_branch() {
        let desc = make_merge_desc(
            (String::from("Yay, I made a change (#99)"), String::from("")),
            "abcdef",
            99,
            "other_branch",
            "source_branch",
        );

        assert_eq!(desc.0, "source_branch->other_branch: Yay, I made a change");
        assert_eq!(desc.1, "(cherry-picked from abcdef, PR #99)");
    }
}
<|endoftext|>


<commit_before>use rand;
use rand::Rng;
use rand::distributions::{IndependentSample, Range};
use std::thread;
use std::sync::{Mutex, MutexGuard};
use time;
use std::time::Duration;
use std::collections::BTreeMap;
use self::state_machine::master::MasterStateMachine;
use std::cmp::min;

#[macro_use]
mod state_machine;

trait RaftMsg {
    fn encode(&self) -> (usize, Vec<u8>);
}

const CHECKER_MS: u64 = 50;

#[derive(Serialize, Deserialize, Debug)]
pub struct LogEntry {
    id: u64,
    term: u64,
    sm_id: u64,
    fn_id: u64,
    data: Vec<u8>
}

type LogEntries = Vec<LogEntry>;

service! {
    rpc append_entries(term: u64, leaderId: u64, prev_log_id: u64, prev_log_term: u64, entries: Option<LogEntries>, leader_commit: u64) -> (u64, bool);
    rpc request_vote(term: u64, candidate_id: u64, last_log_id: u64, last_log_term: u64) -> (u64, bool); // term, voteGranted
    rpc install_snapshot(term: u64, leader_id: u64, last_included_index: u64, last_included_term: u64, data: Vec<u8>, done: bool) -> u64;
}

fn gen_rand(lower: u64, higher: u64) -> u64 {
    let between = Range::new(lower, higher);
    let mut rng = rand::thread_rng();
    between.ind_sample(&mut rng) + 1
}

fn get_time() -> u64 {
    let timespec = time::get_time();
    let mills: f64 = timespec.sec as f64 + (timespec.nsec as f64 / 1000.0 / 1000.0 / 1000.0 );
    mills as u64
}

pub enum Membership {
    LEADER,
    FOLLOWER,
    CANDIDATE,
    OFFLINE,
}

pub struct RaftMeta {
    term: u64,
    voted: bool,
    timeout: u64,
    last_checked: u64,
    last_updated: u64,
    membership: Membership,
    leader_id: u64,
    logs: BTreeMap<u64, LogEntry>,
    state_machine: MasterStateMachine,
    commit_index: u64,
    last_applied: u64,
}

#[derive(Clone)]
pub enum Storage {
    MEMORY,
    DISK(String),
}

impl Storage {
    pub fn Default() -> Storage {
        Storage::MEMORY
    }
}

#[derive(Clone)]
pub struct Options {
    pub storage: Storage,
    pub address: String,
}

pub struct RaftServer {
    meta: Arc<Mutex<RaftMeta>>,
    pub options: Options,
}

impl RaftServer {
    pub fn new(opts: Options) -> Arc<RaftServer> {
        let server = Arc::new(RaftServer {
            meta: Arc::new(Mutex::new(
                RaftMeta {
                    term: 0, //TODO: read from persistent state
                    voted: false, //TODO: read from persistent state
                    timeout: gen_rand(100, 500), // 10~500 ms for timeout
                    last_checked: get_time(),
                    last_updated: get_time(),
                    membership: Membership::FOLLOWER,
                    leader_id: 0,
                    logs: BTreeMap::new(), //TODO: read from persistent state
                    state_machine: MasterStateMachine::new(),
                    commit_index: 0,
                    last_applied: 0,
                }
            )),
            options: opts.clone(),
        });
        let svr_ref = server.clone();
        thread::spawn(move ||{
            listen(svr_ref, &opts.address);
        });
        let checker_ref = server.clone();
        thread::spawn(move ||{
            let server = checker_ref;
            loop {
                {
                    let mut meta = server.meta.lock().unwrap(); //WARNING: Reentering not supported
                    match meta.membership {
                        Membership::LEADER => {
                            if get_time() > (meta.last_updated + CHECKER_MS) {
                                server.send_heartbeat(&mut meta, None);
                            }
                        },
                        Membership::FOLLOWER | Membership::CANDIDATE => {
                            if get_time() > (meta.timeout + meta.last_checked) { //Timeout, require election
                                server.become_candidate(&mut meta);
                            }
                        },
                        Membership::OFFLINE => {
                            break;
                        }
                    }
                }
                thread::sleep(Duration::from_millis(CHECKER_MS));
            }
        });
        server
    }
    fn become_candidate(&self, meta: &mut MutexGuard<RaftMeta>) {
        meta.membership = Membership::CANDIDATE;
    }
    fn become_follower(&self, meta: &mut MutexGuard<RaftMeta>) {
        meta.membership = Membership::FOLLOWER;
    }
    fn send_heartbeat(&self, meta: &mut MutexGuard<RaftMeta>, entries: Option<LogEntries>) {

    }

    //check term number, return reject = false if server term is stale
    fn check_term(&self, meta: &mut MutexGuard<RaftMeta>, remote_term: u64) -> bool {
        if remote_term > meta.term {
            (*meta).term = remote_term;
            self.become_follower(meta)
        } else if remote_term < meta.term {
            return false;
        }
        return true;
    }
}

impl Server for RaftServer {
    fn append_entries(
        &self,
        term: u64, leaderId: u64, prev_log_id: u64,
        prev_log_term: u64, entries: Option<LogEntries>,
        leader_commit: u64
    ) -> Result<(u64, bool), ()>  {
        let mut meta = self.meta.lock().unwrap();
        let term_ok = self.check_term(&mut meta, term); // RI, 1
        if term_ok {
            { //RI, 2
                let contains_prev_log = (*meta).logs.contains_key(&prev_log_id);
                let mut log_mismatch = false;
                if contains_prev_log {
                    let entry = (*meta).logs.get(&prev_log_id).unwrap();
                    log_mismatch = entry.term != prev_log_term;
                } else {
                    return Ok((meta.term, false))
                }
                if log_mismatch { //RI, 3
                    let keys: Vec<u64> = (*meta).logs.keys().cloned().collect();
                    for id in keys {
                        if id >= prev_log_id {
                            (*meta).logs.remove(&id);
                        }
                    }
                    return Ok((meta.term, false))
                }
            }
            if let Some(entries) = entries { // entry not empty
                let entries_len = entries.len();
                for entry in entries {
                    meta.logs.entry(entry.id).or_insert(entry);// RI, 4
                }
                if leader_commit > meta.commit_index { //RI, 5
                    meta.commit_index = min(leader_commit, prev_log_id + entries_len as u64);
                }
            }
            Ok((meta.term, true))
        } else {
            Ok((meta.term, false))
        }
    }

    fn request_vote(
        &self,
        term: u64, candidate_id: u64,
        last_log_id: u64, last_log_term: u64
    ) -> Result<(u64, bool), ()> {
        let mut meta = self.meta.lock().unwrap();
        let term_ok = self.check_term(&mut meta, term);
        let voted = meta.voted;
        let mut vote_granted = false;
        if term_ok && !voted {
            if !meta.logs.is_empty() {
                let (last_id, _) = meta.logs.iter().next_back().unwrap();
                let last_term = meta.logs.get(last_id).unwrap().term;
                if last_log_id >= *last_id && last_log_term >= last_term {
                    vote_granted = true;
                }
            } else {
                vote_granted = true;
            }
        }
        if vote_granted {
            meta.voted = true;
        }
        Ok((meta.term, vote_granted))
    }

    fn install_snapshot(
        &self,
        term: u64, leader_id: u64, last_included_index: u64,
        last_included_term: u64, data: Vec<u8>, done: bool
    ) -> Result<u64, ()> {
        let mut meta = self.meta.lock().unwrap();
        let term_ok = self.check_term(&mut meta, term);
        Ok(meta.term)
    }
}
<commit_msg>allow repeat vote<commit_after>use rand;
use rand::Rng;
use rand::distributions::{IndependentSample, Range};
use std::thread;
use std::sync::{Mutex, MutexGuard};
use time;
use std::time::Duration;
use std::collections::BTreeMap;
use self::state_machine::master::MasterStateMachine;
use std::cmp::min;

#[macro_use]
mod state_machine;

trait RaftMsg {
    fn encode(&self) -> (usize, Vec<u8>);
}

const CHECKER_MS: u64 = 50;

#[derive(Serialize, Deserialize, Debug)]
pub struct LogEntry {
    id: u64,
    term: u64,
    sm_id: u64,
    fn_id: u64,
    data: Vec<u8>
}

type LogEntries = Vec<LogEntry>;

service! {
    rpc append_entries(term: u64, leaderId: u64, prev_log_id: u64, prev_log_term: u64, entries: Option<LogEntries>, leader_commit: u64) -> (u64, bool);
    rpc request_vote(term: u64, candidate_id: u64, last_log_id: u64, last_log_term: u64) -> (u64, bool); // term, voteGranted
    rpc install_snapshot(term: u64, leader_id: u64, last_included_index: u64, last_included_term: u64, data: Vec<u8>, done: bool) -> u64;
}

fn gen_rand(lower: u64, higher: u64) -> u64 {
    let between = Range::new(lower, higher);
    let mut rng = rand::thread_rng();
    between.ind_sample(&mut rng) + 1
}

fn get_time() -> u64 {
    let timespec = time::get_time();
    let mills: f64 = timespec.sec as f64 + (timespec.nsec as f64 / 1000.0 / 1000.0 / 1000.0 );
    mills as u64
}

pub enum Membership {
    LEADER,
    FOLLOWER,
    CANDIDATE,
    OFFLINE,
}

pub struct RaftMeta {
    term: u64,
    vote_for: Option<u64>,
    timeout: u64,
    last_checked: u64,
    last_updated: u64,
    membership: Membership,
    leader_id: u64,
    logs: BTreeMap<u64, LogEntry>,
    state_machine: MasterStateMachine,
    commit_index: u64,
    last_applied: u64,
}

#[derive(Clone)]
pub enum Storage {
    MEMORY,
    DISK(String),
}

impl Storage {
    pub fn Default() -> Storage {
        Storage::MEMORY
    }
}

#[derive(Clone)]
pub struct Options {
    pub storage: Storage,
    pub address: String,
}

pub struct RaftServer {
    meta: Arc<Mutex<RaftMeta>>,
    pub options: Options,
}

impl RaftServer {
    pub fn new(opts: Options) -> Arc<RaftServer> {
        let server = Arc::new(RaftServer {
            meta: Arc::new(Mutex::new(
                RaftMeta {
                    term: 0, //TODO: read from persistent state
                    vote_for: None, //TODO: read from persistent state
                    timeout: gen_rand(100, 500), // 10~500 ms for timeout
                    last_checked: get_time(),
                    last_updated: get_time(),
                    membership: Membership::FOLLOWER,
                    leader_id: 0,
                    logs: BTreeMap::new(), //TODO: read from persistent state
                    state_machine: MasterStateMachine::new(),
                    commit_index: 0,
                    last_applied: 0,
                }
            )),
            options: opts.clone(),
        });
        let svr_ref = server.clone();
        thread::spawn(move ||{
            listen(svr_ref, &opts.address);
        });
        let checker_ref = server.clone();
        thread::spawn(move ||{
            let server = checker_ref;
            loop {
                {
                    let mut meta = server.meta.lock().unwrap(); //WARNING: Reentering not supported
                    match meta.membership {
                        Membership::LEADER => {
                            if get_time() > (meta.last_updated + CHECKER_MS) {
                                server.send_heartbeat(&mut meta, None);
                            }
                        },
                        Membership::FOLLOWER | Membership::CANDIDATE => {
                            if get_time() > (meta.timeout + meta.last_checked) { //Timeout, require election
                                server.become_candidate(&mut meta);
                            }
                        },
                        Membership::OFFLINE => {
                            break;
                        }
                    }
                }
                thread::sleep(Duration::from_millis(CHECKER_MS));
            }
        });
        server
    }
    fn become_candidate(&self, meta: &mut MutexGuard<RaftMeta>) {
        meta.membership = Membership::CANDIDATE;
    }
    fn become_follower(&self, meta: &mut MutexGuard<RaftMeta>) {
        meta.membership = Membership::FOLLOWER;
    }
    fn send_heartbeat(&self, meta: &mut MutexGuard<RaftMeta>, entries: Option<LogEntries>) {

    }

    //check term number, return reject = false if server term is stale
    fn check_term(&self, meta: &mut MutexGuard<RaftMeta>, remote_term: u64) -> bool {
        if remote_term > meta.term {
            (*meta).term = remote_term;
            self.become_follower(meta)
        } else if remote_term < meta.term {
            return false;
        }
        return true;
    }
}

impl Server for RaftServer {
    fn append_entries(
        &self,
        term: u64, leaderId: u64, prev_log_id: u64,
        prev_log_term: u64, entries: Option<LogEntries>,
        leader_commit: u64
    ) -> Result<(u64, bool), ()>  {
        let mut meta = self.meta.lock().unwrap();
        let term_ok = self.check_term(&mut meta, term); // RI, 1
        if term_ok {
            { //RI, 2
                let contains_prev_log = (*meta).logs.contains_key(&prev_log_id);
                let mut log_mismatch = false;
                if contains_prev_log {
                    let entry = (*meta).logs.get(&prev_log_id).unwrap();
                    log_mismatch = entry.term != prev_log_term;
                } else {
                    return Ok((meta.term, false))
                }
                if log_mismatch { //RI, 3
                    let keys: Vec<u64> = (*meta).logs.keys().cloned().collect();
                    for id in keys {
                        if id >= prev_log_id {
                            (*meta).logs.remove(&id);
                        }
                    }
                    return Ok((meta.term, false))
                }
            }
            if let Some(entries) = entries { // entry not empty
                let entries_len = entries.len();
                for entry in entries {
                    meta.logs.entry(entry.id).or_insert(entry);// RI, 4
                }
                if leader_commit > meta.commit_index { //RI, 5
                    meta.commit_index = min(leader_commit, prev_log_id + entries_len as u64);
                }
            }
            Ok((meta.term, true))
        } else {
            Ok((meta.term, false))
        }
    }

    fn request_vote(
        &self,
        term: u64, candidate_id: u64,
        last_log_id: u64, last_log_term: u64
    ) -> Result<(u64, bool), ()> {
        let mut meta = self.meta.lock().unwrap();
        let term_ok = self.check_term(&mut meta, term);
        let vote_for = meta.vote_for;
        let mut vote_granted = false;
        if term_ok && (vote_for.is_none() || vote_for.unwrap() == candidate_id) {
            if !meta.logs.is_empty() {
                let (last_id, _) = meta.logs.iter().next_back().unwrap();
                let last_term = meta.logs.get(last_id).unwrap().term;
                if last_log_id >= *last_id && last_log_term >= last_term {
                    vote_granted = true;
                }
            } else {
                vote_granted = true;
            }
        }
        if vote_granted {
            meta.vote_for = Some(candidate_id);
        }
        Ok((meta.term, vote_granted))
    }

    fn install_snapshot(
        &self,
        term: u64, leader_id: u64, last_included_index: u64,
        last_included_term: u64, data: Vec<u8>, done: bool
    ) -> Result<u64, ()> {
        let mut meta = self.meta.lock().unwrap();
        let term_ok = self.check_term(&mut meta, term);
        Ok(meta.term)
    }
}
<|endoftext|>


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

#![allow(dead_code, unused_imports)]

use std::ops::{
    Add, Sub, Mul, Div, Rem, Neg,
    AddAssign, SubAssign, MulAssign, DivAssign,
};
use std::fmt;

use int::Int;

#[derive(Clone)]
pub struct Rational {
    n: Int,
    d: Int
}

impl Rational {
    pub fn new(n: Int, d: Int) -> Rational {
        let mut rat = Rational {
            n: n,
            d: d
        };

        rat.normalize();

        rat
    }

    pub fn normalized(&self) -> bool {
        let gcd = self.n.gcd(&self.d);
        gcd == 1
    }

    pub fn normalize(&mut self) {
        let gcd = self.n.gcd(&self.d);

        self.n /= &gcd;
        self.d /= gcd;

        // Make sure the denominator is positive
        if self.d < 0 {
            self.d.negate();
            self.n.negate();
        }
    }

    pub fn invert(self) -> Rational {
        Rational {
            n: self.d,
            d: self.n
        }
    }

    pub fn to_f64(&self) -> f64 {
        let mut normalized = self.clone();
        normalized.normalize();
        normalized.n.to_f64() / normalized.d.to_f64()
    }
}

fn make_common_denominator(a: &mut Rational, b: &mut Rational) {
    if a.d == b.d {
        return;
    }

    let lcm = a.d.lcm(&b.d);

    if lcm != a.d {
        let factor = &lcm / &a.d;
        a.n *= factor;
        a.d = lcm.clone();
    }

    if lcm != b.d {
        let factor = &lcm / &b.d;
        b.n *= factor;
        b.d = lcm;
    }

    debug_assert!(a.d == b.d);
}

impl AddAssign<Rational> for Rational {
    fn add_assign(&mut self, mut other: Rational) {
        make_common_denominator(self, &mut other);

        self.n += other.n;
    }
}

impl<'a> AddAssign<&'a Rational> for Rational {
    fn add_assign(&mut self, other: &'a Rational) {
        if self.d == other.d {
            self.n += &other.n;
        } else {
            *self += other.clone();
        }
    }
}

impl AddAssign<Int> for Rational {
    fn add_assign(&mut self, other: Int) {
        self.n += other * &self.d;
    }
}

impl<'a> AddAssign<&'a Int> for Rational {
    fn add_assign(&mut self, other: &'a Int) {
        self.n += other * &self.d;
    }
}

impl Add<Rational> for Rational {
    type Output = Rational;

    fn add(mut self, other: Rational) -> Rational {
        self += other;
        self
    }
}

impl<'a> Add<&'a Rational> for Rational {
    type Output = Rational;

    fn add(mut self, other: &'a Rational) -> Rational {
        self += other;
        self
    }
}

impl<'a> Add<Rational> for &'a Rational {
    type Output = Rational;

    fn add(self, mut other: Rational) -> Rational {
        other += self;
        other
    }
}

impl<'a> Add<&'a Rational> for &'a Rational {
    type Output = Rational;

    fn add(self, other: &'a Rational) -> Rational {
        self.clone().add(other)
    }
}

impl Add<Int> for Rational {
    type Output = Rational;

    fn add(mut self, other: Int) -> Rational {
        self += other;
        self
    }
}

impl<'a> Add<&'a Int> for Rational {
    type Output = Rational;

    fn add(mut self, other: &'a Int) -> Rational {
        self += other;
        self
    }
}

impl<'a> Add<Int> for &'a Rational {
    type Output = Rational;

    fn add(self, other: Int) -> Rational {
        self.clone() + other
    }
}

impl<'a> Add<&'a Int> for &'a Rational {
    type Output = Rational;

    fn add(self, other: &'a Int) -> Rational {
        self.clone() + other
    }
}

impl Add<Rational> for Int {
    type Output = Rational;

    fn add(self, other: Rational) -> Rational {
        other + self
    }
}

impl<'a> Add<&'a Rational> for Int {
    type Output = Rational;

    fn add(self, other: &'a Rational) -> Rational {
        other + self
    }
}

impl<'a> Add<Rational> for &'a Int {
    type Output = Rational;

    fn add(self, other: Rational) -> Rational {
        other + self
    }
}

impl<'a> Add<&'a Rational> for &'a Int {
    type Output = Rational;

    fn add(self, other: &'a Rational) -> Rational {
        other + self
    }
}

impl SubAssign<Rational> for Rational {
    fn sub_assign(&mut self, mut other: Rational) {
        make_common_denominator(self, &mut other);
        self.n -= other.n;
    }
}

impl<'a> SubAssign<&'a Rational> for Rational {
    fn sub_assign(&mut self, other: &'a Rational) {
        if self.d == other.d {
            self.n -= &other.n;
        } else {
            *self -= other.clone();
        }
    }
}

impl Sub<Rational> for Rational {
    type Output = Rational;

    fn sub(mut self, other: Rational) -> Rational {
        self -= other;
        self
    }
}

impl<'a> Sub<&'a Rational> for Rational {
    type Output = Rational;

    fn sub(mut self, other: &'a Rational) -> Rational {
        self -= other;
        self
    }
}

impl<'a> Sub<Rational> for &'a Rational {
    type Output = Rational;

    fn sub(self, mut other: Rational) -> Rational {
        other -= self;
        other
    }
}

impl<'a> Sub<&'a Rational> for &'a Rational {
    type Output = Rational;

    fn sub(self, other: &'a Rational) -> Rational {
        self.clone().sub(other)
    }
}

impl<'a> MulAssign<&'a Rational> for Rational {
    fn mul_assign(&mut self, other: &'a Rational) {
        self.n *= &other.n;
        self.d *= &other.d;
    }
}

impl MulAssign<Rational> for Rational {
    fn mul_assign(&mut self, other: Rational) {
        *self *= &other
    }
}

impl MulAssign<Int> for Rational {
    fn mul_assign(&mut self, other: Int) {
        self.n *= other;
    }
}

impl<'a> MulAssign<&'a Int> for Rational {
    fn mul_assign(&mut self, other: &'a Int) {
        self.n *= other;
    }
}

impl Mul<Rational> for Rational {
    type Output = Rational;

    fn mul(mut self, other: Rational) -> Rational {
        self *= other;
        self
    }
}

impl<'a> Mul<&'a Rational> for Rational {
    type Output = Rational;

    fn mul(mut self, other: &'a Rational) -> Rational {
        self *= other;
        self
    }
}

impl<'a> Mul<Rational> for &'a Rational {
    type Output = Rational;

    fn mul(self, mut other: Rational) -> Rational {
        other *= self;
        other
    }
}

impl<'a> Mul<&'a Rational> for &'a Rational {
    type Output = Rational;

    fn mul(self, other: &'a Rational) -> Rational {
        self.clone().mul(other)
    }
}

impl Mul<Int> for Rational {
    type Output = Rational;

    fn mul(mut self, other: Int) -> Rational {
        self *= other;
        self
    }
}

impl<'a> Mul<&'a Int> for Rational {
    type Output = Rational;

    fn mul(mut self, other: &'a Int) -> Rational {
        self *= other;
        self
    }
}

impl<'a> Mul<Int> for &'a Rational {
    type Output = Rational;

    fn mul(self, other: Int) -> Rational {
        self.clone() * other
    }
}

impl<'a> Mul<&'a Int> for &'a Rational {
    type Output = Rational;

    fn mul(self, other: &'a Int) -> Rational {
        self.clone() * other
    }
}

impl Mul<Rational> for Int {
    type Output = Rational;

    fn mul(self, other: Rational) -> Rational {
        other * self
    }
}

impl<'a> Mul<&'a Rational> for Int {
    type Output = Rational;

    fn mul(self, other: &'a Rational) -> Rational {
        other * self
    }
}

impl<'a> Mul<Rational> for &'a Int {
    type Output = Rational;

    fn mul(self, other: Rational) -> Rational {
        other * self
    }
}

impl<'a> Mul<&'a Rational> for &'a Int {
    type Output = Rational;

    fn mul(self, other: &'a Rational) -> Rational {
        other * self
    }
}

impl DivAssign<Rational> for Rational {
    fn div_assign(&mut self, other: &'a Rational) {
        *self *= other.invert();
    }
}

impl<'a> DivAssign<&'a Rational> for Rational {
    fn div_assign(&mut self, other: Rational) {
        *self *= other.clone();
    }
}

impl DivAssign<Int> for Rational {
    fn div_assign(&mut self, other: Int) {
        self.d *= other;
    }
}

impl<'a> DivAssign<&'a Int> for Rational {
    fn div_assign(&mut self, other: &'a Int) {
        self.d *= other;
    }
}

impl Div<Rational> for Rational {
    type Output = Rational;

    fn div(mut self, other: Rational) -> Rational {
        self /= other;
        self
    }
}

impl<'a> Div<&'a Rational> for Rational {
    type Output = Rational;

    fn div(mut self, other: &'a Rational) -> Rational {
        self /= other;
        self
    }
}

impl<'a> Div<Rational> for &'a Rational {
    type Output = Rational;

    fn div(self, mut other: Rational) -> Rational {
        other /= self;
        other.invert()
    }
}

impl<'a> Div<&'a Rational> for &'a Rational {
    type Output = Rational;

    fn div(self, other: &'a Rational) -> Rational {
        self.clone().div(other)
    }
}

impl Div<Int> for Rational {
    type Output = Rational;

    fn div(mut self, other: Int) -> Rational {
        self /= other;
        self
    }
}

impl<'a> Div<&'a Int> for Rational {
    type Output = Rational;

    fn div(mut self, other: &'a Int) -> Rational {
        self /= other;
        self
    }
}

impl<'a> Div<Int> for &'a Rational {
    type Output = Rational;

    fn div(self, other: Int) -> Rational {
        self.clone() / other
    }
}

impl<'a> Div<&'a Int> for &'a Rational {
    type Output = Rational;

    fn div(self, other: &'a Int) -> Rational {
        self.clone() / other
    }
}

impl Div<Rational> for Int {
    type Output = Rational;

    fn div(self, other: Rational) -> Rational {
        (other / self).invert()
    }
}

impl<'a> Div<&'a Rational> for Int {
    type Output = Rational;

    fn div(self, other: &'a Rational) -> Rational {
        (other / self).invert()
    }
}

impl<'a> Div<Rational> for &'a Int {
    type Output = Rational;

    fn div(self, other: Rational) -> Rational {
        (other / self).invert()
    }
}

impl<'a> Div<&'a Rational> for &'a Int {
    type Output = Rational;

    fn div(self, other: &'a Rational) -> Rational {
        (other / self).invert()
    }
}

impl fmt::Debug for Rational {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}/{:?}", self.n, self.d)
    }
}

impl fmt::Display for Rational {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if !self.normalized() {
            let mut normalized = self.clone();
            normalized.normalize();
            write!(f, "{}/{}", normalized.n, normalized.d)
        } else {
            write!(f, "{}/{}", self.n, self.d)
        }
    }
}
<commit_msg>Add some documentation to Rational<commit_after>// Copyright 2016 The Ramp Developers
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

#![allow(dead_code, unused_imports)]

use std::ops::{
    Add, Sub, Mul, Div, Rem, Neg,
    AddAssign, SubAssign, MulAssign, DivAssign,
};
use std::fmt;

use ll;

use int::Int;

/**
 * An arbitrary-precision rational number.
 *
 * This type is used to represent numbers in the form `a / b` where `a` and `b`
 * are integers and `b` is non-zero.
 */
#[derive(Clone)]
pub struct Rational {
    n: Int,
    d: Int
}

impl Rational {

    pub fn new(n: Int, d: Int) -> Rational {
        assert!(d != 0, "Denominator is zero");

        if n == 0 {
            return Rational {
                n: n,
                d: Int::one()
            }
        }

        let mut rat = Rational {
            n: n,
            d: d
        };

        rat.normalize();

        rat
    }

    /**
     * Returns whether or not this rational is normalized or not
     */
    pub fn normalized(&self) -> bool {
        let gcd = self.n.gcd(&self.d);
        gcd == 1
    }

    /**
     * Normalize this Rational.
     *
     * This method will cause the value to be represented in the
     * form `a/b` where `a` and `b` are relatively prime. It also
     * ensures that the denominator is positive.
     *
     * Normalizing rationals will result in faster calculations as
     * it ensures that the numerator and denominator are as small as
     * they can be.
     */
    pub fn normalize(&mut self) {
        let gcd = self.n.gcd(&self.d);

        self.n /= &gcd;
        self.d /= gcd;

        // Make sure the denominator is positive
        if self.d < 0 {
            self.d.negate();
            self.n.negate();
        }
    }

    /**
     * Returns the reciprocal of this Rational
     */
    pub fn invert(self) -> Rational {
        Rational {
            n: self.d,
            d: self.n
        }
    }

    /**
     * Converts this Rational to an `f64` value.
     */
    pub fn to_f64(&self) -> f64 {
        let mut normalized = self.clone();
        normalized.normalize();
        normalized.n.to_f64() / normalized.d.to_f64()
    }
}

fn make_common_denominator(a: &mut Rational, b: &mut Rational) {
    if a.d == b.d {
        return;
    }

    let lcm = a.d.lcm(&b.d);

    if lcm != a.d {
        let factor = &lcm / &a.d;
        a.n *= factor;
        a.d = lcm.clone();
    }

    if lcm != b.d {
        let factor = &lcm / &b.d;
        b.n *= factor;
        b.d = lcm;
    }

    debug_assert!(a.d == b.d);
}

impl AddAssign<Rational> for Rational {
    fn add_assign(&mut self, mut other: Rational) {
        make_common_denominator(self, &mut other);

        self.n += other.n;
    }
}

impl<'a> AddAssign<&'a Rational> for Rational {
    fn add_assign(&mut self, other: &'a Rational) {
        if self.d == other.d {
            self.n += &other.n;
        } else {
            *self += other.clone();
        }
    }
}

impl AddAssign<Int> for Rational {
    fn add_assign(&mut self, other: Int) {
        self.n += other * &self.d;
    }
}

impl<'a> AddAssign<&'a Int> for Rational {
    fn add_assign(&mut self, other: &'a Int) {
        self.n += other * &self.d;
    }
}

impl Add<Rational> for Rational {
    type Output = Rational;

    fn add(mut self, other: Rational) -> Rational {
        self += other;
        self
    }
}

impl<'a> Add<&'a Rational> for Rational {
    type Output = Rational;

    fn add(mut self, other: &'a Rational) -> Rational {
        self += other;
        self
    }
}

impl<'a> Add<Rational> for &'a Rational {
    type Output = Rational;

    fn add(self, mut other: Rational) -> Rational {
        other += self;
        other
    }
}

impl<'a> Add<&'a Rational> for &'a Rational {
    type Output = Rational;

    fn add(self, other: &'a Rational) -> Rational {
        self.clone().add(other)
    }
}

impl Add<Int> for Rational {
    type Output = Rational;

    fn add(mut self, other: Int) -> Rational {
        self += other;
        self
    }
}

impl<'a> Add<&'a Int> for Rational {
    type Output = Rational;

    fn add(mut self, other: &'a Int) -> Rational {
        self += other;
        self
    }
}

impl<'a> Add<Int> for &'a Rational {
    type Output = Rational;

    fn add(self, other: Int) -> Rational {
        self.clone() + other
    }
}

impl<'a> Add<&'a Int> for &'a Rational {
    type Output = Rational;

    fn add(self, other: &'a Int) -> Rational {
        self.clone() + other
    }
}

impl Add<Rational> for Int {
    type Output = Rational;

    fn add(self, other: Rational) -> Rational {
        other + self
    }
}

impl<'a> Add<&'a Rational> for Int {
    type Output = Rational;

    fn add(self, other: &'a Rational) -> Rational {
        other + self
    }
}

impl<'a> Add<Rational> for &'a Int {
    type Output = Rational;

    fn add(self, other: Rational) -> Rational {
        other + self
    }
}

impl<'a> Add<&'a Rational> for &'a Int {
    type Output = Rational;

    fn add(self, other: &'a Rational) -> Rational {
        other + self
    }
}

impl SubAssign<Rational> for Rational {
    fn sub_assign(&mut self, mut other: Rational) {
        make_common_denominator(self, &mut other);
        self.n -= other.n;
    }
}

impl<'a> SubAssign<&'a Rational> for Rational {
    fn sub_assign(&mut self, other: &'a Rational) {
        if self.d == other.d {
            self.n -= &other.n;
        } else {
            *self -= other.clone();
        }
    }
}

impl Sub<Rational> for Rational {
    type Output = Rational;

    fn sub(mut self, other: Rational) -> Rational {
        self -= other;
        self
    }
}

impl<'a> Sub<&'a Rational> for Rational {
    type Output = Rational;

    fn sub(mut self, other: &'a Rational) -> Rational {
        self -= other;
        self
    }
}

impl<'a> Sub<Rational> for &'a Rational {
    type Output = Rational;

    fn sub(self, mut other: Rational) -> Rational {
        other -= self;
        other
    }
}

impl<'a> Sub<&'a Rational> for &'a Rational {
    type Output = Rational;

    fn sub(self, other: &'a Rational) -> Rational {
        self.clone().sub(other)
    }
}

impl<'a> MulAssign<&'a Rational> for Rational {
    fn mul_assign(&mut self, other: &'a Rational) {
        self.n *= &other.n;
        self.d *= &other.d;
    }
}

impl MulAssign<Rational> for Rational {
    fn mul_assign(&mut self, other: Rational) {
        *self *= &other
    }
}

impl MulAssign<Int> for Rational {
    fn mul_assign(&mut self, other: Int) {
        self.n *= other;
    }
}

impl<'a> MulAssign<&'a Int> for Rational {
    fn mul_assign(&mut self, other: &'a Int) {
        self.n *= other;
    }
}

impl Mul<Rational> for Rational {
    type Output = Rational;

    fn mul(mut self, other: Rational) -> Rational {
        self *= other;
        self
    }
}

impl<'a> Mul<&'a Rational> for Rational {
    type Output = Rational;

    fn mul(mut self, other: &'a Rational) -> Rational {
        self *= other;
        self
    }
}

impl<'a> Mul<Rational> for &'a Rational {
    type Output = Rational;

    fn mul(self, mut other: Rational) -> Rational {
        other *= self;
        other
    }
}

impl<'a> Mul<&'a Rational> for &'a Rational {
    type Output = Rational;

    fn mul(self, other: &'a Rational) -> Rational {
        self.clone().mul(other)
    }
}

impl Mul<Int> for Rational {
    type Output = Rational;

    fn mul(mut self, other: Int) -> Rational {
        self *= other;
        self
    }
}

impl<'a> Mul<&'a Int> for Rational {
    type Output = Rational;

    fn mul(mut self, other: &'a Int) -> Rational {
        self *= other;
        self
    }
}

impl<'a> Mul<Int> for &'a Rational {
    type Output = Rational;

    fn mul(self, other: Int) -> Rational {
        self.clone() * other
    }
}

impl<'a> Mul<&'a Int> for &'a Rational {
    type Output = Rational;

    fn mul(self, other: &'a Int) -> Rational {
        self.clone() * other
    }
}

impl Mul<Rational> for Int {
    type Output = Rational;

    fn mul(self, other: Rational) -> Rational {
        other * self
    }
}

impl<'a> Mul<&'a Rational> for Int {
    type Output = Rational;

    fn mul(self, other: &'a Rational) -> Rational {
        other * self
    }
}

impl<'a> Mul<Rational> for &'a Int {
    type Output = Rational;

    fn mul(self, other: Rational) -> Rational {
        other * self
    }
}

impl<'a> Mul<&'a Rational> for &'a Int {
    type Output = Rational;

    fn mul(self, other: &'a Rational) -> Rational {
        other * self
    }
}

impl DivAssign<Rational> for Rational {
    fn div_assign(&mut self, other: Rational) {
        *self *= other.invert();
    }
}

impl<'a> DivAssign<&'a Rational> for Rational {
    fn div_assign(&mut self, other: &'a Rational) {
        *self *= other.clone();
    }
}

impl DivAssign<Int> for Rational {
    fn div_assign(&mut self, other: Int) {
        if other == 0 {
            ll::divide_by_zero();
        }
        self.d *= other;
    }
}

impl<'a> DivAssign<&'a Int> for Rational {
    fn div_assign(&mut self, other: &'a Int) {
        if *other == 0 {
            ll::divide_by_zero();
        }
        self.d *= other;
    }
}

impl Div<Rational> for Rational {
    type Output = Rational;

    fn div(mut self, other: Rational) -> Rational {
        self /= other;
        self
    }
}

impl<'a> Div<&'a Rational> for Rational {
    type Output = Rational;

    fn div(mut self, other: &'a Rational) -> Rational {
        self /= other;
        self
    }
}

impl<'a> Div<Rational> for &'a Rational {
    type Output = Rational;

    fn div(self, mut other: Rational) -> Rational {
        other /= self;
        other.invert()
    }
}

impl<'a> Div<&'a Rational> for &'a Rational {
    type Output = Rational;

    fn div(self, other: &'a Rational) -> Rational {
        self.clone().div(other)
    }
}

impl Div<Int> for Rational {
    type Output = Rational;

    fn div(mut self, other: Int) -> Rational {
        self /= other;
        self
    }
}

impl<'a> Div<&'a Int> for Rational {
    type Output = Rational;

    fn div(mut self, other: &'a Int) -> Rational {
        self /= other;
        self
    }
}

impl<'a> Div<Int> for &'a Rational {
    type Output = Rational;

    fn div(self, other: Int) -> Rational {
        self.clone() / other
    }
}

impl<'a> Div<&'a Int> for &'a Rational {
    type Output = Rational;

    fn div(self, other: &'a Int) -> Rational {
        self.clone() / other
    }
}

impl Div<Rational> for Int {
    type Output = Rational;

    fn div(self, other: Rational) -> Rational {
        (other / self).invert()
    }
}

impl<'a> Div<&'a Rational> for Int {
    type Output = Rational;

    fn div(self, other: &'a Rational) -> Rational {
        (other / self).invert()
    }
}

impl<'a> Div<Rational> for &'a Int {
    type Output = Rational;

    fn div(self, other: Rational) -> Rational {
        (other / self).invert()
    }
}

impl<'a> Div<&'a Rational> for &'a Int {
    type Output = Rational;

    fn div(self, other: &'a Rational) -> Rational {
        (other / self).invert()
    }
}

impl fmt::Debug for Rational {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}/{:?}", self.n, self.d)
    }
}

impl fmt::Display for Rational {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if !self.normalized() {
            let mut normalized = self.clone();
            normalized.normalize();
            write!(f, "{}/{}", normalized.n, normalized.d)
        } else {
            write!(f, "{}/{}", self.n, self.d)
        }
    }
}
<|endoftext|>


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

use metric::Metric;

pub trait Registry<'a> {
    fn get(&'a self, name: &'a str) -> &'a Metric;

    fn insert<T: Metric + 'a>(&mut self, name: &'a str, metric: T);
}

pub struct StdRegistry<'a> {
    metrics: HashMap<&'a str, Box<Metric + 'a>>,
}

// Specific stuff for registry goes here
impl<'a> Registry<'a> for StdRegistry<'a> {
    fn get(&'a self, name: &'a str) -> &'a Metric {
        &*self.metrics[name]
    }

    fn insert<T: Metric + 'a>(&mut self, name: &'a str, metric: T) {
        let boxed = Box::new(metric);

        self.metrics.insert(name, boxed);
    }
}

// General StdRegistry
impl<'a> StdRegistry<'a> {
    #[allow(dead_code)]
    fn new() -> StdRegistry<'a> {
        StdRegistry{
            metrics: HashMap::new()
        }
    }
}

#[cfg(test)]
mod test {
    use meter::StdMeter;
    use registry::{Registry, StdRegistry};

    #[test]
    fn meter() {
        let mut r: StdRegistry = StdRegistry::new();
        let m: StdMeter = StdMeter::new();

        r.insert("foo", m);
        r.get("foo");
    }
}
<commit_msg>New needs to be public if people are to use it<commit_after>use std::collections::HashMap;

use metric::Metric;

pub trait Registry<'a> {
    fn get(&'a self, name: &'a str) -> &'a Metric;

    fn insert<T: Metric + 'a>(&mut self, name: &'a str, metric: T);
}

pub struct StdRegistry<'a> {
    metrics: HashMap<&'a str, Box<Metric + 'a>>,
}

// Specific stuff for registry goes here
impl<'a> Registry<'a> for StdRegistry<'a> {
    fn get(&'a self, name: &'a str) -> &'a Metric {
        &*self.metrics[name]
    }

    fn insert<T: Metric + 'a>(&mut self, name: &'a str, metric: T) {
        let boxed = Box::new(metric);

        self.metrics.insert(name, boxed);
    }
}

// General StdRegistry
impl<'a> StdRegistry<'a> {
    #[allow(dead_code)]
    pub fn new() -> StdRegistry<'a> {
        StdRegistry{
            metrics: HashMap::new()
        }
    }
}

#[cfg(test)]
mod test {
    use meter::StdMeter;
    use registry::{Registry, StdRegistry};

    #[test]
    fn meter() {
        let mut r: StdRegistry = StdRegistry::new();
        let m: StdMeter = StdMeter::new();

        r.insert("foo", m);
        r.get("foo");
    }
}
<|endoftext|>


<commit_before>/*!

Simple compression

*/

use libc::{c_void, size_t, c_int};

extern mod rustrt {

    fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
                                  src_buf_len: size_t,
                                  pout_len: *size_t,
                                  flags: c_int) -> *c_void;

    fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
                                    src_buf_len: size_t,
                                    pout_len: *size_t,
                                    flags: c_int) -> *c_void;
}

const lz_none : c_int = 0x0;   // Huffman-coding only.
const lz_fast : c_int = 0x1;   // LZ with only one probe
const lz_norm : c_int = 0x80;  // LZ with 128 probes, "normal"
const lz_best : c_int = 0xfff; // LZ with 4095 probes, "best"

fn deflate_bytes(bytes: &[const u8]) -> ~[u8] {
    do vec::as_const_buf(bytes) |b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tdefl_compress_mem_to_heap(b as *c_void,
                                                   len as size_t,
                                                   ptr::addr_of(outsz),
                                                   lz_norm);
            assert res as int != 0;
            let out = vec::raw::from_buf(res as *u8,
                                            outsz as uint);
            libc::free(res);
            move out
        }
    }
}

fn inflate_bytes(bytes: &[const u8]) -> ~[u8] {
    do vec::as_const_buf(bytes) |b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
                                                     len as size_t,
                                                     ptr::addr_of(outsz),
                                                     0);
            assert res as int != 0;
            let out = vec::raw::from_buf(res as *u8,
                                            outsz as uint);
            libc::free(res);
            move out
        }
    }
}

#[test]
#[allow(non_implicitly_copyable_typarams)]
fn test_flate_round_trip() {
    let r = rand::Rng();
    let mut words = ~[];
    for 20.times {
        vec::push(words, r.gen_bytes(r.gen_uint_range(1, 10)));
    }
    for 20.times {
        let mut in = ~[];
        for 2000.times {
            vec::push_all(in, r.choose(words));
        }
        debug!("de/inflate of %u bytes of random word-sequences",
               in.len());
        let cmp = flate::deflate_bytes(in);
        let out = flate::inflate_bytes(cmp);
        debug!("%u bytes deflated to %u (%.1f%% size)",
               in.len(), cmp.len(),
               100.0 * ((cmp.len() as float) / (in.len() as float)));
        assert(in == out);
    }
}
<commit_msg>core: Indicate that flate is demoded<commit_after>/*!

Simple compression

*/

// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use libc::{c_void, size_t, c_int};

extern mod rustrt {

    fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
                                  src_buf_len: size_t,
                                  pout_len: *size_t,
                                  flags: c_int) -> *c_void;

    fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
                                    src_buf_len: size_t,
                                    pout_len: *size_t,
                                    flags: c_int) -> *c_void;
}

const lz_none : c_int = 0x0;   // Huffman-coding only.
const lz_fast : c_int = 0x1;   // LZ with only one probe
const lz_norm : c_int = 0x80;  // LZ with 128 probes, "normal"
const lz_best : c_int = 0xfff; // LZ with 4095 probes, "best"

fn deflate_bytes(bytes: &[const u8]) -> ~[u8] {
    do vec::as_const_buf(bytes) |b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tdefl_compress_mem_to_heap(b as *c_void,
                                                   len as size_t,
                                                   ptr::addr_of(outsz),
                                                   lz_norm);
            assert res as int != 0;
            let out = vec::raw::from_buf(res as *u8,
                                            outsz as uint);
            libc::free(res);
            move out
        }
    }
}

fn inflate_bytes(bytes: &[const u8]) -> ~[u8] {
    do vec::as_const_buf(bytes) |b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
                                                     len as size_t,
                                                     ptr::addr_of(outsz),
                                                     0);
            assert res as int != 0;
            let out = vec::raw::from_buf(res as *u8,
                                            outsz as uint);
            libc::free(res);
            move out
        }
    }
}

#[test]
#[allow(non_implicitly_copyable_typarams)]
fn test_flate_round_trip() {
    let r = rand::Rng();
    let mut words = ~[];
    for 20.times {
        vec::push(words, r.gen_bytes(r.gen_uint_range(1, 10)));
    }
    for 20.times {
        let mut in = ~[];
        for 2000.times {
            vec::push_all(in, r.choose(words));
        }
        debug!("de/inflate of %u bytes of random word-sequences",
               in.len());
        let cmp = flate::deflate_bytes(in);
        let out = flate::inflate_bytes(cmp);
        debug!("%u bytes deflated to %u (%.1f%% size)",
               in.len(), cmp.len(),
               100.0 * ((cmp.len() as float) / (in.len() as float)));
        assert(in == out);
    }
}
<|endoftext|>


<commit_before>#![crate_id(name="groups", vers="1.0.0", author="Alan Andrade")]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Alan Andrade <alan.andradec@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
#![feature(macro_rules)]

extern crate getopts;

use std::os;
use getopts::{
    optflag,
    getopts,
    usage
};
use c_types::{get_pw_from_args, group};

#[path = "../common/util.rs"] mod util;
#[path = "../common/c_types.rs"] mod c_types;

static NAME: &'static str = "groups";

#[allow(dead_code)]
fn main () { os::set_exit_status(uumain(os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let options = [
            optflag("h", "", "Help")
        ];

    let matches = match getopts(args.tail(), options) {
        Ok(m) => { m },
        Err(_) => {
            show_error!("{}", usage(NAME, options));
            return 1;
        }
    };

    group(get_pw_from_args(&matches.free), true);

    0
}
<commit_msg>groups: fix argument parsing<commit_after>#![crate_id(name="groups", vers="1.0.0", author="Alan Andrade")]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Alan Andrade <alan.andradec@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
#![feature(macro_rules)]

extern crate getopts;

use std::os;
use getopts::{
    optflag,
    getopts,
    usage
};
use c_types::{get_pw_from_args, group};

#[path = "../common/util.rs"] mod util;
#[path = "../common/c_types.rs"] mod c_types;

static NAME: &'static str = "groups";
static VERSION: &'static str = "1.0.0";

#[allow(dead_code)]
fn main () { os::set_exit_status(uumain(os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0).clone();

    let options = [
        optflag("h", "help", "display this help menu and exit"),
        optflag("V", "version", "display version information and exit")
    ];

    let matches = match getopts(args.tail(), options) {
        Ok(m) => { m },
        Err(f) => {
            show_error!("{}", f.to_err_msg());
            return 1;
        }
    };

    if matches.opt_present("version") {
        println!("{} v{}", NAME, VERSION);
    } else if matches.opt_present("help") {
        print!("{} v{}\n\n\
                Usage:\n  \
                  {} [OPTION]... [USER]...\n\n\
                {}", NAME, VERSION, program, usage("Prints the groups a user is in to standard output.", options));
    } else {
        group(get_pw_from_args(&matches.free), true);
    }

    0
}
<|endoftext|>


<commit_before>//! Asynchronous values.

use core::cell::Cell;
use core::marker::Unpin;
use core::pin::Pin;
use core::option::Option;
use core::ptr::NonNull;
use core::task::{Context, Poll};
use core::ops::{Drop, Generator, GeneratorState};

#[doc(inline)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub use core::future::*;

/// Wrap a generator in a future.
///
/// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
/// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
#[unstable(feature = "gen_future", issue = "50547")]
pub fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> {
    GenFuture(x)
}

/// A wrapper around generators used to implement `Future` for `async`/`await` code.
#[unstable(feature = "gen_future", issue = "50547")]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
struct GenFuture<T: Generator<Yield = ()>>(T);

// We rely on the fact that async/await futures are immovable in order to create
// self-referential borrows in the underlying generator.
impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {}

#[unstable(feature = "gen_future", issue = "50547")]
impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
    type Output = T::Return;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        // Safe because we're !Unpin + !Drop mapping to a ?Unpin value
        let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
        set_task_context(cx, || match gen.resume() {
            GeneratorState::Yielded(()) => Poll::Pending,
            GeneratorState::Complete(x) => Poll::Ready(x),
        })
    }
}

thread_local! {
    static TLS_CX: Cell<Option<NonNull<Context<'static>>>> = Cell::new(None);
}

struct SetOnDrop(Option<NonNull<Context<'static>>>);

impl Drop for SetOnDrop {
    fn drop(&mut self) {
        TLS_CX.with(|tls_cx| {
            tls_cx.set(self.0.take());
        });
    }
}

#[unstable(feature = "gen_future", issue = "50547")]
/// Sets the thread-local task context used by async/await futures.
pub fn set_task_context<F, R>(cx: &mut Context<'_>, f: F) -> R
where
    F: FnOnce() -> R
{
    // transmute the context's lifetime to 'static so we can store it.
    let cx = unsafe {
        core::mem::transmute::<&mut Context<'_>, &mut Context<'static>>(cx)
    };
    let old_cx = TLS_CX.with(|tls_cx| {
        tls_cx.replace(Some(NonNull::from(cx)))
    });
    let _reset = SetOnDrop(old_cx);
    f()
}

#[unstable(feature = "gen_future", issue = "50547")]
/// Retrieves the thread-local task context used by async/await futures.
///
/// This function acquires exclusive access to the task context.
///
/// Panics if no context has been set or if the context has already been
/// retrieved by a surrounding call to get_task_context.
pub fn get_task_context<F, R>(f: F) -> R
where
    F: FnOnce(&mut Context<'_>) -> R
{
    let cx_ptr = TLS_CX.with(|tls_cx| {
        // Clear the entry so that nested `get_task_waker` calls
        // will fail or set their own value.
        tls_cx.replace(None)
    });
    let _reset = SetOnDrop(cx_ptr);

    let mut cx_ptr = cx_ptr.expect(
        "TLS Context not set. This is a rustc bug. \
        Please file an issue on https://github.com/rust-lang/rust.");

    // Safety: we've ensured exclusive access to the context by
    // removing the pointer from TLS, only to be replaced once
    // we're done with it.
    //
    // The pointer that was inserted came from an `&mut Context<'_>`,
    // so it is safe to treat as mutable.
    unsafe { f(cx_ptr.as_mut()) }
}

#[unstable(feature = "gen_future", issue = "50547")]
/// Polls a future in the current thread-local task waker.
pub fn poll_with_tls_context<F>(f: Pin<&mut F>) -> Poll<F::Output>
where
    F: Future
{
    get_task_context(|cx| F::poll(f, cx))
}
<commit_msg>Hide gen_future API from documentation<commit_after>//! Asynchronous values.

use core::cell::Cell;
use core::marker::Unpin;
use core::pin::Pin;
use core::option::Option;
use core::ptr::NonNull;
use core::task::{Context, Poll};
use core::ops::{Drop, Generator, GeneratorState};

#[doc(inline)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub use core::future::*;

/// Wrap a generator in a future.
///
/// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
/// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
pub fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> {
    GenFuture(x)
}

/// A wrapper around generators used to implement `Future` for `async`/`await` code.
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
struct GenFuture<T: Generator<Yield = ()>>(T);

// We rely on the fact that async/await futures are immovable in order to create
// self-referential borrows in the underlying generator.
impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {}

#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
    type Output = T::Return;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        // Safe because we're !Unpin + !Drop mapping to a ?Unpin value
        let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
        set_task_context(cx, || match gen.resume() {
            GeneratorState::Yielded(()) => Poll::Pending,
            GeneratorState::Complete(x) => Poll::Ready(x),
        })
    }
}

thread_local! {
    static TLS_CX: Cell<Option<NonNull<Context<'static>>>> = Cell::new(None);
}

struct SetOnDrop(Option<NonNull<Context<'static>>>);

impl Drop for SetOnDrop {
    fn drop(&mut self) {
        TLS_CX.with(|tls_cx| {
            tls_cx.set(self.0.take());
        });
    }
}

#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
/// Sets the thread-local task context used by async/await futures.
pub fn set_task_context<F, R>(cx: &mut Context<'_>, f: F) -> R
where
    F: FnOnce() -> R
{
    // transmute the context's lifetime to 'static so we can store it.
    let cx = unsafe {
        core::mem::transmute::<&mut Context<'_>, &mut Context<'static>>(cx)
    };
    let old_cx = TLS_CX.with(|tls_cx| {
        tls_cx.replace(Some(NonNull::from(cx)))
    });
    let _reset = SetOnDrop(old_cx);
    f()
}

#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
/// Retrieves the thread-local task context used by async/await futures.
///
/// This function acquires exclusive access to the task context.
///
/// Panics if no context has been set or if the context has already been
/// retrieved by a surrounding call to get_task_context.
pub fn get_task_context<F, R>(f: F) -> R
where
    F: FnOnce(&mut Context<'_>) -> R
{
    let cx_ptr = TLS_CX.with(|tls_cx| {
        // Clear the entry so that nested `get_task_waker` calls
        // will fail or set their own value.
        tls_cx.replace(None)
    });
    let _reset = SetOnDrop(cx_ptr);

    let mut cx_ptr = cx_ptr.expect(
        "TLS Context not set. This is a rustc bug. \
        Please file an issue on https://github.com/rust-lang/rust.");

    // Safety: we've ensured exclusive access to the context by
    // removing the pointer from TLS, only to be replaced once
    // we're done with it.
    //
    // The pointer that was inserted came from an `&mut Context<'_>`,
    // so it is safe to treat as mutable.
    unsafe { f(cx_ptr.as_mut()) }
}

#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
/// Polls a future in the current thread-local task waker.
pub fn poll_with_tls_context<F>(f: Pin<&mut F>) -> Poll<F::Output>
where
    F: Future
{
    get_task_context(|cx| F::poll(f, cx))
}
<|endoftext|>


<commit_before>/*
Module: option

Represents the presence or absence of a value.

Every option<T> value can either be some(T) or none. Where in other languages
you might use a nullable type, in Rust you would use an option type.
*/

/*
Tag: t

The option type
*/
tag t<T> {
    /* Variant: none */
    none;
    /* Variant: some */
    some(T);
}

/* Section: Operations */

/*
Function: get

Gets the value out of an option

Failure:

Fails if the value equals `none`.
*/
fn get<copy T>(opt: t<T>) -> T {
    alt opt { some(x) { ret x; } none. { fail "option none"; } }
}

/*
*/
fn map<T, U>(f: block(T) -> U, opt: t<T>) -> t<U> {
    alt opt { some(x) { some(f(x)) } none. { none } }
}

/*
Function: is_none

Returns true if the option equals none
*/
pure fn is_none<T>(opt: t<T>) -> bool {
    alt opt { none. { true } some(_) { false } }
}

/*
Function: is_some

Returns true if the option contains some value
*/
pure fn is_some<T>(opt: t<T>) -> bool { !is_none(opt) }

/*
Function: from_maybe

Returns the contained value or a default
*/
fn from_maybe<T>(def: T, opt: t<T>) -> T {
    alt opt { some(x) { x } none. { def } }
}

/*
Function: maybe

Applies a function to the contained value or returns a default
*/
fn maybe<T, U>(def: U, f: block(T) -> U, opt: t<T>) -> U {
    alt opt { none. { def } some(t) { f(t) } }
}

// FIXME: Can be defined in terms of the above when/if we have const bind.
/*
Function: may

Performs an operation on the contained value or does nothing
*/
fn may<T>(f: block(T), opt: t<T>) {
    alt opt { none. {/* nothing */ } some(t) { f(t); } }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>Swap arg order for option::{may,maybe}<commit_after>/*
Module: option

Represents the presence or absence of a value.

Every option<T> value can either be some(T) or none. Where in other languages
you might use a nullable type, in Rust you would use an option type.
*/

/*
Tag: t

The option type
*/
tag t<T> {
    /* Variant: none */
    none;
    /* Variant: some */
    some(T);
}

/* Section: Operations */

/*
Function: get

Gets the value out of an option

Failure:

Fails if the value equals `none`.
*/
fn get<copy T>(opt: t<T>) -> T {
    alt opt { some(x) { ret x; } none. { fail "option none"; } }
}

/*
*/
fn map<T, U>(f: block(T) -> U, opt: t<T>) -> t<U> {
    alt opt { some(x) { some(f(x)) } none. { none } }
}

/*
Function: is_none

Returns true if the option equals none
*/
pure fn is_none<T>(opt: t<T>) -> bool {
    alt opt { none. { true } some(_) { false } }
}

/*
Function: is_some

Returns true if the option contains some value
*/
pure fn is_some<T>(opt: t<T>) -> bool { !is_none(opt) }

/*
Function: from_maybe

Returns the contained value or a default
*/
fn from_maybe<T>(def: T, opt: t<T>) -> T {
    alt opt { some(x) { x } none. { def } }
}

/*
Function: maybe

Applies a function to the contained value or returns a default
*/
fn maybe<T, U>(def: U, opt: t<T>, f: block(T) -> U) -> U {
    alt opt { none. { def } some(t) { f(t) } }
}

// FIXME: Can be defined in terms of the above when/if we have const bind.
/*
Function: may

Performs an operation on the contained value or does nothing
*/
fn may<T>(opt: t<T>, f: block(T)) {
    alt opt { none. {/* nothing */ } some(t) { f(t); } }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>