<commit_before>//! FIXME: write short doc here
use assists::utils::TryEnum;
use syntax::{
    ast::{self, AstNode},
    TextRange, TextSize,
};
use text_edit::TextEdit;

use crate::{
    completion::{
        completion_config::SnippetCap,
        completion_context::CompletionContext,
        completion_item::{Builder, CompletionKind, Completions},
    },
    CompletionItem, CompletionItemKind,
};

pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
    if !ctx.config.enable_postfix_completions {
        return;
    }

    let dot_receiver = match &ctx.dot_receiver {
        Some(it) => it,
        None => return,
    };

    let receiver_text =
        get_receiver_text(dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal);

    let receiver_ty = match ctx.sema.type_of_expr(&dot_receiver) {
        Some(it) => it,
        None => return,
    };

    let cap = match ctx.config.snippet_cap {
        Some(it) => it,
        None => return,
    };
    let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty);
    if let Some(try_enum) = &try_enum {
        match try_enum {
            TryEnum::Result => {
                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "ifl",
                    "if let Ok {}",
                    &format!("if let Ok($1) = {} {{\n    $0\n}}", receiver_text),
                )
                .add_to(acc);

                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "while",
                    "while let Ok {}",
                    &format!("while let Ok($1) = {} {{\n    $0\n}}", receiver_text),
                )
                .add_to(acc);
            }
            TryEnum::Option => {
                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "ifl",
                    "if let Some {}",
                    &format!("if let Some($1) = {} {{\n    $0\n}}", receiver_text),
                )
                .add_to(acc);

                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "while",
                    "while let Some {}",
                    &format!("while let Some($1) = {} {{\n    $0\n}}", receiver_text),
                )
                .add_to(acc);
            }
        }
    } else if receiver_ty.is_bool() || receiver_ty.is_unknown() {
        postfix_snippet(
            ctx,
            cap,
            &dot_receiver,
            "if",
            "if expr {}",
            &format!("if {} {{\n    $0\n}}", receiver_text),
        )
        .add_to(acc);
        postfix_snippet(
            ctx,
            cap,
            &dot_receiver,
            "while",
            "while expr {}",
            &format!("while {} {{\n    $0\n}}", receiver_text),
        )
        .add_to(acc);
        postfix_snippet(ctx, cap, &dot_receiver, "not", "!expr", &format!("!{}", receiver_text))
            .add_to(acc);
    }

    postfix_snippet(ctx, cap, &dot_receiver, "ref", "&expr", &format!("&{}", receiver_text))
        .add_to(acc);
    postfix_snippet(
        ctx,
        cap,
        &dot_receiver,
        "refm",
        "&mut expr",
        &format!("&mut {}", receiver_text),
    )
    .add_to(acc);

    // The rest of the postfix completions create an expression that moves an argument,
    // so it's better to consider references now to avoid breaking the compilation
    let dot_receiver = include_references(dot_receiver);
    let receiver_text =
        get_receiver_text(&dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal);

    match try_enum {
        Some(try_enum) => match try_enum {
            TryEnum::Result => {
                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "match",
                    "match expr {}",
                    &format!("match {} {{\n    Ok(${{1:_}}) => {{$2}},\n    Err(${{3:_}}) => {{$0}},\n}}", receiver_text),
                )
                .add_to(acc);
            }
            TryEnum::Option => {
                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "match",
                    "match expr {}",
                    &format!(
                        "match {} {{\n    Some(${{1:_}}) => {{$2}},\n    None => {{$0}},\n}}",
                        receiver_text
                    ),
                )
                .add_to(acc);
            }
        },
        None => {
            postfix_snippet(
                ctx,
                cap,
                &dot_receiver,
                "match",
                "match expr {}",
                &format!("match {} {{\n    ${{1:_}} => {{$0}},\n}}", receiver_text),
            )
            .add_to(acc);
        }
    }

    postfix_snippet(
        ctx,
        cap,
        &dot_receiver,
        "box",
        "Box::new(expr)",
        &format!("Box::new({})", receiver_text),
    )
    .add_to(acc);

    postfix_snippet(
        ctx,
        cap,
        &dot_receiver,
        "ok",
        "Ok(expr)",
        &format!("Ok({})", receiver_text),
    )
    .add_to(acc);

    postfix_snippet(
        ctx,
        cap,
        &dot_receiver,
        "dbg",
        "dbg!(expr)",
        &format!("dbg!({})", receiver_text),
    )
    .add_to(acc);

    postfix_snippet(
        ctx,
        cap,
        &dot_receiver,
        "call",
        "function(expr)",
        &format!("${{1}}({})", receiver_text),
    )
    .add_to(acc);
}

fn get_receiver_text(receiver: &ast::Expr, receiver_is_ambiguous_float_literal: bool) -> String {
    if receiver_is_ambiguous_float_literal {
        let text = receiver.syntax().text();
        let without_dot = ..text.len() - TextSize::of('.');
        text.slice(without_dot).to_string()
    } else {
        receiver.to_string()
    }
}

fn include_references(initial_element: &ast::Expr) -> ast::Expr {
    let mut resulting_element = initial_element.clone();
    while let Some(parent_ref_element) =
        resulting_element.syntax().parent().and_then(ast::RefExpr::cast)
    {
        resulting_element = ast::Expr::from(parent_ref_element);
    }
    resulting_element
}

fn postfix_snippet(
    ctx: &CompletionContext,
    cap: SnippetCap,
    receiver: &ast::Expr,
    label: &str,
    detail: &str,
    snippet: &str,
) -> Builder {
    let edit = {
        let receiver_syntax = receiver.syntax();
        let receiver_range = ctx.sema.original_range(receiver_syntax).range;
        let delete_range = TextRange::new(receiver_range.start(), ctx.source_range().end());
        TextEdit::replace(delete_range, snippet.to_string())
    };
    CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label)
        .detail(detail)
        .kind(CompletionItemKind::Snippet)
        .snippet_edit(cap, edit)
}

#[cfg(test)]
mod tests {
    use expect_test::{expect, Expect};

    use crate::completion::{
        test_utils::{check_edit, completion_list},
        CompletionKind,
    };

    fn check(ra_fixture: &str, expect: Expect) {
        let actual = completion_list(ra_fixture, CompletionKind::Postfix);
        expect.assert_eq(&actual)
    }

    #[test]
    fn postfix_completion_works_for_trivial_path_expression() {
        check(
            r#"
fn main() {
    let bar = true;
    bar.<|>
}
"#,
            expect![[r#"
                sn box   Box::new(expr)
                sn call  function(expr)
                sn dbg   dbg!(expr)
                sn if    if expr {}
                sn match match expr {}
                sn not   !expr
                sn ok    Ok(expr)
                sn ref   &expr
                sn refm  &mut expr
                sn while while expr {}
            "#]],
        );
    }

    #[test]
    fn postfix_type_filtering() {
        check(
            r#"
fn main() {
    let bar: u8 = 12;
    bar.<|>
}
"#,
            expect![[r#"
                sn box   Box::new(expr)
                sn call  function(expr)
                sn dbg   dbg!(expr)
                sn match match expr {}
                sn ok    Ok(expr)
                sn ref   &expr
                sn refm  &mut expr
            "#]],
        )
    }

    #[test]
    fn option_iflet() {
        check_edit(
            "ifl",
            r#"
enum Option<T> { Some(T), None }

fn main() {
    let bar = Option::Some(true);
    bar.<|>
}
"#,
            r#"
enum Option<T> { Some(T), None }

fn main() {
    let bar = Option::Some(true);
    if let Some($1) = bar {
    $0
}
}
"#,
        );
    }

    #[test]
    fn result_match() {
        check_edit(
            "match",
            r#"
enum Result<T, E> { Ok(T), Err(E) }

fn main() {
    let bar = Result::Ok(true);
    bar.<|>
}
"#,
            r#"
enum Result<T, E> { Ok(T), Err(E) }

fn main() {
    let bar = Result::Ok(true);
    match bar {
    Ok(${1:_}) => {$2},
    Err(${3:_}) => {$0},
}
}
"#,
        );
    }

    #[test]
    fn postfix_completion_works_for_ambiguous_float_literal() {
        check_edit("refm", r#"fn main() { 42.<|> }"#, r#"fn main() { &mut 42 }"#)
    }

    #[test]
    fn works_in_simple_macro() {
        check_edit(
            "dbg",
            r#"
macro_rules! m { ($e:expr) => { $e } }
fn main() {
    let bar: u8 = 12;
    m!(bar.d<|>)
}
"#,
            r#"
macro_rules! m { ($e:expr) => { $e } }
fn main() {
    let bar: u8 = 12;
    m!(dbg!(bar))
}
"#,
        );
    }

    #[test]
    fn postfix_completion_for_references() {
        check_edit("dbg", r#"fn main() { &&42.<|> }"#, r#"fn main() { dbg!(&&42) }"#);
        check_edit("refm", r#"fn main() { &&42.<|> }"#, r#"fn main() { &&&mut 42 }"#);
    }
}
<commit_msg>Cargo fmt<commit_after>//! FIXME: write short doc here
use assists::utils::TryEnum;
use syntax::{
    ast::{self, AstNode},
    TextRange, TextSize,
};
use text_edit::TextEdit;

use crate::{
    completion::{
        completion_config::SnippetCap,
        completion_context::CompletionContext,
        completion_item::{Builder, CompletionKind, Completions},
    },
    CompletionItem, CompletionItemKind,
};

pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
    if !ctx.config.enable_postfix_completions {
        return;
    }

    let dot_receiver = match &ctx.dot_receiver {
        Some(it) => it,
        None => return,
    };

    let receiver_text =
        get_receiver_text(dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal);

    let receiver_ty = match ctx.sema.type_of_expr(&dot_receiver) {
        Some(it) => it,
        None => return,
    };

    let cap = match ctx.config.snippet_cap {
        Some(it) => it,
        None => return,
    };
    let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty);
    if let Some(try_enum) = &try_enum {
        match try_enum {
            TryEnum::Result => {
                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "ifl",
                    "if let Ok {}",
                    &format!("if let Ok($1) = {} {{\n    $0\n}}", receiver_text),
                )
                .add_to(acc);

                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "while",
                    "while let Ok {}",
                    &format!("while let Ok($1) = {} {{\n    $0\n}}", receiver_text),
                )
                .add_to(acc);
            }
            TryEnum::Option => {
                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "ifl",
                    "if let Some {}",
                    &format!("if let Some($1) = {} {{\n    $0\n}}", receiver_text),
                )
                .add_to(acc);

                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "while",
                    "while let Some {}",
                    &format!("while let Some($1) = {} {{\n    $0\n}}", receiver_text),
                )
                .add_to(acc);
            }
        }
    } else if receiver_ty.is_bool() || receiver_ty.is_unknown() {
        postfix_snippet(
            ctx,
            cap,
            &dot_receiver,
            "if",
            "if expr {}",
            &format!("if {} {{\n    $0\n}}", receiver_text),
        )
        .add_to(acc);
        postfix_snippet(
            ctx,
            cap,
            &dot_receiver,
            "while",
            "while expr {}",
            &format!("while {} {{\n    $0\n}}", receiver_text),
        )
        .add_to(acc);
        postfix_snippet(ctx, cap, &dot_receiver, "not", "!expr", &format!("!{}", receiver_text))
            .add_to(acc);
    }

    postfix_snippet(ctx, cap, &dot_receiver, "ref", "&expr", &format!("&{}", receiver_text))
        .add_to(acc);
    postfix_snippet(
        ctx,
        cap,
        &dot_receiver,
        "refm",
        "&mut expr",
        &format!("&mut {}", receiver_text),
    )
    .add_to(acc);

    // The rest of the postfix completions create an expression that moves an argument,
    // so it's better to consider references now to avoid breaking the compilation
    let dot_receiver = include_references(dot_receiver);
    let receiver_text =
        get_receiver_text(&dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal);

    match try_enum {
        Some(try_enum) => match try_enum {
            TryEnum::Result => {
                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "match",
                    "match expr {}",
                    &format!("match {} {{\n    Ok(${{1:_}}) => {{$2}},\n    Err(${{3:_}}) => {{$0}},\n}}", receiver_text),
                )
                .add_to(acc);
            }
            TryEnum::Option => {
                postfix_snippet(
                    ctx,
                    cap,
                    &dot_receiver,
                    "match",
                    "match expr {}",
                    &format!(
                        "match {} {{\n    Some(${{1:_}}) => {{$2}},\n    None => {{$0}},\n}}",
                        receiver_text
                    ),
                )
                .add_to(acc);
            }
        },
        None => {
            postfix_snippet(
                ctx,
                cap,
                &dot_receiver,
                "match",
                "match expr {}",
                &format!("match {} {{\n    ${{1:_}} => {{$0}},\n}}", receiver_text),
            )
            .add_to(acc);
        }
    }

    postfix_snippet(
        ctx,
        cap,
        &dot_receiver,
        "box",
        "Box::new(expr)",
        &format!("Box::new({})", receiver_text),
    )
    .add_to(acc);

    postfix_snippet(ctx, cap, &dot_receiver, "ok", "Ok(expr)", &format!("Ok({})", receiver_text))
        .add_to(acc);

    postfix_snippet(
        ctx,
        cap,
        &dot_receiver,
        "dbg",
        "dbg!(expr)",
        &format!("dbg!({})", receiver_text),
    )
    .add_to(acc);

    postfix_snippet(
        ctx,
        cap,
        &dot_receiver,
        "call",
        "function(expr)",
        &format!("${{1}}({})", receiver_text),
    )
    .add_to(acc);
}

fn get_receiver_text(receiver: &ast::Expr, receiver_is_ambiguous_float_literal: bool) -> String {
    if receiver_is_ambiguous_float_literal {
        let text = receiver.syntax().text();
        let without_dot = ..text.len() - TextSize::of('.');
        text.slice(without_dot).to_string()
    } else {
        receiver.to_string()
    }
}

fn include_references(initial_element: &ast::Expr) -> ast::Expr {
    let mut resulting_element = initial_element.clone();
    while let Some(parent_ref_element) =
        resulting_element.syntax().parent().and_then(ast::RefExpr::cast)
    {
        resulting_element = ast::Expr::from(parent_ref_element);
    }
    resulting_element
}

fn postfix_snippet(
    ctx: &CompletionContext,
    cap: SnippetCap,
    receiver: &ast::Expr,
    label: &str,
    detail: &str,
    snippet: &str,
) -> Builder {
    let edit = {
        let receiver_syntax = receiver.syntax();
        let receiver_range = ctx.sema.original_range(receiver_syntax).range;
        let delete_range = TextRange::new(receiver_range.start(), ctx.source_range().end());
        TextEdit::replace(delete_range, snippet.to_string())
    };
    CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label)
        .detail(detail)
        .kind(CompletionItemKind::Snippet)
        .snippet_edit(cap, edit)
}

#[cfg(test)]
mod tests {
    use expect_test::{expect, Expect};

    use crate::completion::{
        test_utils::{check_edit, completion_list},
        CompletionKind,
    };

    fn check(ra_fixture: &str, expect: Expect) {
        let actual = completion_list(ra_fixture, CompletionKind::Postfix);
        expect.assert_eq(&actual)
    }

    #[test]
    fn postfix_completion_works_for_trivial_path_expression() {
        check(
            r#"
fn main() {
    let bar = true;
    bar.<|>
}
"#,
            expect![[r#"
                sn box   Box::new(expr)
                sn call  function(expr)
                sn dbg   dbg!(expr)
                sn if    if expr {}
                sn match match expr {}
                sn not   !expr
                sn ok    Ok(expr)
                sn ref   &expr
                sn refm  &mut expr
                sn while while expr {}
            "#]],
        );
    }

    #[test]
    fn postfix_type_filtering() {
        check(
            r#"
fn main() {
    let bar: u8 = 12;
    bar.<|>
}
"#,
            expect![[r#"
                sn box   Box::new(expr)
                sn call  function(expr)
                sn dbg   dbg!(expr)
                sn match match expr {}
                sn ok    Ok(expr)
                sn ref   &expr
                sn refm  &mut expr
            "#]],
        )
    }

    #[test]
    fn option_iflet() {
        check_edit(
            "ifl",
            r#"
enum Option<T> { Some(T), None }

fn main() {
    let bar = Option::Some(true);
    bar.<|>
}
"#,
            r#"
enum Option<T> { Some(T), None }

fn main() {
    let bar = Option::Some(true);
    if let Some($1) = bar {
    $0
}
}
"#,
        );
    }

    #[test]
    fn result_match() {
        check_edit(
            "match",
            r#"
enum Result<T, E> { Ok(T), Err(E) }

fn main() {
    let bar = Result::Ok(true);
    bar.<|>
}
"#,
            r#"
enum Result<T, E> { Ok(T), Err(E) }

fn main() {
    let bar = Result::Ok(true);
    match bar {
    Ok(${1:_}) => {$2},
    Err(${3:_}) => {$0},
}
}
"#,
        );
    }

    #[test]
    fn postfix_completion_works_for_ambiguous_float_literal() {
        check_edit("refm", r#"fn main() { 42.<|> }"#, r#"fn main() { &mut 42 }"#)
    }

    #[test]
    fn works_in_simple_macro() {
        check_edit(
            "dbg",
            r#"
macro_rules! m { ($e:expr) => { $e } }
fn main() {
    let bar: u8 = 12;
    m!(bar.d<|>)
}
"#,
            r#"
macro_rules! m { ($e:expr) => { $e } }
fn main() {
    let bar: u8 = 12;
    m!(dbg!(bar))
}
"#,
        );
    }

    #[test]
    fn postfix_completion_for_references() {
        check_edit("dbg", r#"fn main() { &&42.<|> }"#, r#"fn main() { dbg!(&&42) }"#);
        check_edit("refm", r#"fn main() { &&42.<|> }"#, r#"fn main() { &&&mut 42 }"#);
    }
}
<|endoftext|>


<commit_before>// Copyright 2016-2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The Poisson distribution.

use Rng;
use distributions::Distribution;
use distributions::log_gamma::log_gamma;
use std::f64::consts::PI;

/// The Poisson distribution `Poisson(lambda)`.
///
/// This distribution has a density function:
/// `f(k) = lambda^k * exp(-lambda) / k!` for `k >= 0`.
///
/// # Example
///
/// ```rust
/// use rand::distributions::{Poisson, Distribution};
///
/// let poi = Poisson::new(2.0);
/// let v = poi.sample(&mut rand::thread_rng());
/// println!("{} is from a Poisson(2) distribution", v);
/// ```
#[derive(Clone, Copy, Debug)]
pub struct Poisson {
    lambda: f64,
    // precalculated values
    exp_lambda: f64,
    log_lambda: f64,
    magic_val: f64,
}

impl Poisson {
    /// Construct a new `Poisson` with the given shape parameter
    /// `lambda`. Panics if `lambda <= 0`.
    pub fn new(lambda: f64) -> Poisson {
        assert!(lambda > 0.0, "Poisson::new called with lambda <= 0");
        Poisson {
            lambda: lambda,
            exp_lambda: (-lambda).exp(),
            log_lambda: lambda.ln(),
            magic_val: lambda * lambda.ln() - log_gamma(1.0 + lambda),
        }
    }
}

impl Distribution<u64> for Poisson {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u64 {
        // using the algorithm from Numerical Recipes in C

        // for low expected values use the Knuth method
        if self.lambda < 12.0 {
            let mut result = 0;
            let mut p = 1.0;
            while p > self.exp_lambda {
                p *= rng.gen::<f64>();
                result += 1;
            }
            result - 1
        }
        // high expected values - rejection method
        else {
            // some cached values
            let tmp = (2.0 * self.lambda).sqrt();
            let mut int_result: u64;

            loop {
                let mut result;
                let mut comp_dev;

                // we use the lorentzian distribution as the comparison distribution
                // f(x) ~ 1/(1+x/^2)
                loop {
                    // draw from the lorentzian distribution
                    comp_dev = (PI * rng.gen::<f64>()).tan();
                    // shift the peak of the comparison ditribution
                    result = tmp * comp_dev + self.lambda;
                    // repeat the drawing until we are in the range of possible values
                    if result >= 0.0 {
                        break;
                    }
                }
                // now the result is a random variable greater than 0 with Lorentzian distribution
                // the result should be an integer value
                result = result.floor();
                int_result = result as u64;

                // this is the ratio of the Poisson distribution to the comparison distribution
                // the magic value scales the distribution function to a range of approximately 0-1
                // since it is not exact, we multiply the ratio by 0.9 to avoid ratios greater than 1
                // this doesn't change the resulting distribution, only increases the rate of failed drawings
                let check = 0.9 * (1.0 + comp_dev * comp_dev)
                    * (result * self.log_lambda - log_gamma(1.0 + result) - self.magic_val).exp();

                // check with uniform random value - if below the threshold, we are within the target distribution
                if rng.gen::<f64>() <= check {
                    break;
                }
            }
            int_result
        }
    }
}

#[cfg(test)]
mod test {
    use distributions::Distribution;
    use super::Poisson;

    #[test]
    fn test_poisson() {
        let poisson = Poisson::new(10.0);
        let mut rng = ::test::rng(123);
        let mut sum = 0;
        for _ in 0..1000 {
            sum += poisson.sample(&mut rng);
        }
        let avg = (sum as f64) / 1000.0;
        println!("Poisson average: {}", avg);
        assert!((avg - 10.0).abs() < 0.5); // not 100% certain, but probable enough
    }

    #[test]
    #[should_panic]
    #[cfg_attr(target_env = "msvc", ignore)]
    fn test_poisson_invalid_lambda_zero() {
        Poisson::new(0.0);
    }
    #[test]
    #[should_panic]
    #[cfg_attr(target_env = "msvc", ignore)]
    fn test_poisson_invalid_lambda_neg() {
        Poisson::new(-10.0);
    }
}
<commit_msg>Address more comments<commit_after>// Copyright 2016-2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The Poisson distribution.

use Rng;
use distributions::Distribution;
use distributions::log_gamma::log_gamma;
use std::f64::consts::PI;

/// The Poisson distribution `Poisson(lambda)`.
///
/// This distribution has a density function:
/// `f(k) = lambda^k * exp(-lambda) / k!` for `k >= 0`.
///
/// # Example
///
/// ```rust
/// use rand::distributions::{Poisson, Distribution};
///
/// let poi = Poisson::new(2.0);
/// let v = poi.sample(&mut rand::thread_rng());
/// println!("{} is from a Poisson(2) distribution", v);
/// ```
#[derive(Clone, Copy, Debug)]
pub struct Poisson {
    lambda: f64,
    // precalculated values
    exp_lambda: f64,
    log_lambda: f64,
    sqrt_2lambda: f64,
    magic_val: f64,
}

impl Poisson {
    /// Construct a new `Poisson` with the given shape parameter
    /// `lambda`. Panics if `lambda <= 0`.
    pub fn new(lambda: f64) -> Poisson {
        assert!(lambda > 0.0, "Poisson::new called with lambda <= 0");
        let log_lambda = lambda.ln();
        Poisson {
            lambda: lambda,
            exp_lambda: (-lambda).exp(),
            log_lambda: log_lambda,
            sqrt_2lambda: (2.0 * lambda).sqrt(),
            magic_val: lambda * log_lambda - log_gamma(1.0 + lambda),
        }
    }
}

impl Distribution<u64> for Poisson {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u64 {
        // using the algorithm from Numerical Recipes in C

        // for low expected values use the Knuth method
        if self.lambda < 12.0 {
            let mut result = 0;
            let mut p = 1.0;
            while p > self.exp_lambda {
                p *= rng.gen::<f64>();
                result += 1;
            }
            result - 1
        }
        // high expected values - rejection method
        else {
            let mut int_result: u64;

            loop {
                let mut result;
                let mut comp_dev;

                // we use the lorentzian distribution as the comparison distribution
                // f(x) ~ 1/(1+x/^2)
                loop {
                    // draw from the lorentzian distribution
                    comp_dev = (PI * rng.gen::<f64>()).tan();
                    // shift the peak of the comparison ditribution
                    result = self.sqrt_2lambda * comp_dev + self.lambda;
                    // repeat the drawing until we are in the range of possible values
                    if result >= 0.0 {
                        break;
                    }
                }
                // now the result is a random variable greater than 0 with Lorentzian distribution
                // the result should be an integer value
                result = result.floor();
                int_result = result as u64;

                // this is the ratio of the Poisson distribution to the comparison distribution
                // the magic value scales the distribution function to a range of approximately 0-1
                // since it is not exact, we multiply the ratio by 0.9 to avoid ratios greater than 1
                // this doesn't change the resulting distribution, only increases the rate of failed drawings
                let check = 0.9 * (1.0 + comp_dev * comp_dev)
                    * (result * self.log_lambda - log_gamma(1.0 + result) - self.magic_val).exp();

                // check with uniform random value - if below the threshold, we are within the target distribution
                if rng.gen::<f64>() <= check {
                    break;
                }
            }
            int_result
        }
    }
}

#[cfg(test)]
mod test {
    use distributions::Distribution;
    use super::Poisson;

    #[test]
    fn test_poisson() {
        let poisson = Poisson::new(10.0);
        let mut rng = ::test::rng(123);
        let mut sum = 0;
        for _ in 0..1000 {
            sum += poisson.sample(&mut rng);
        }
        let avg = (sum as f64) / 1000.0;
        println!("Poisson average: {}", avg);
        assert!((avg - 10.0).abs() < 0.5); // not 100% certain, but probable enough
    }

    #[test]
    #[should_panic]
    #[cfg_attr(target_env = "msvc", ignore)]
    fn test_poisson_invalid_lambda_zero() {
        Poisson::new(0.0);
    }
    #[test]
    #[should_panic]
    #[cfg_attr(target_env = "msvc", ignore)]
    fn test_poisson_invalid_lambda_neg() {
        Poisson::new(-10.0);
    }
}
<|endoftext|>


<commit_before>use rustwlc::{input, Point, ResizeEdge, Geometry,
              RESIZE_LEFT, RESIZE_RIGHT, RESIZE_TOP, RESIZE_BOTTOM,
              RESIZE_TOPLEFT, RESIZE_TOPRIGHT, RESIZE_BOTTOMLEFT, RESIZE_BOTTOMRIGHT,
};

use super::super::{Action, Direction, LayoutTree, TreeError};
use super::super::commands::{CommandResult};
use super::super::core::container::{ContainerType, MIN_SIZE};
use uuid::Uuid;

#[derive(Debug, Clone, Copy)]
pub enum ResizeErr {
    /// Expected the node associated with the UUID to be floating.
    ExpectedFloating(Uuid),
    /// Expected the node associated with the UUID to not be floating
    ExpectedNotFloating(Uuid)
}

impl LayoutTree {
    /// Updates pointer position for the node behind the id,
    /// in the same direction as the edge.
    pub fn update_pointer_pos(&self, id: Uuid, edge: ResizeEdge) -> CommandResult {
        let container = try!(self.lookup(id));
        let Geometry { mut origin, size } = container.get_geometry()
            .expect("Container had no geometry");
        drop(container);
        if edge.contains(RESIZE_TOPLEFT) {
            input::pointer::set_position(origin);
        } else if edge.contains(RESIZE_TOPRIGHT) {
            origin.x += size.w as i32;
            input::pointer::set_position(origin);
        } else if edge.contains(RESIZE_BOTTOMLEFT) {
            origin.y += size.h as i32;
            input::pointer::set_position(origin);
        } else if edge.contains(RESIZE_BOTTOMRIGHT) {
            origin.x += size.w as i32;
            origin.y += size.h as i32;
            input::pointer::set_position(origin);
        }
        Ok(())
    }

    /// Resizes a floating container. If the container was not floating, an Err is returned.
    pub fn resize_floating(&mut self, id: Uuid, edge: ResizeEdge, pointer: Point,
                           action: &mut Action) -> CommandResult {
        {
            let container = try!(self.lookup_mut(id));
            if !container.floating() {
                return Err(TreeError::Resize(ResizeErr::ExpectedFloating(container.get_id())))
            }
            match container.get_type() {
                ContainerType::View | ContainerType::Container => {},
                _ => return Err(TreeError::UuidWrongType(container.get_id(),
                                                        vec!(ContainerType::View)))
            }
            let geo = container.get_geometry()
                .expect("Could not get geometry of the container");

            let new_geo = calculate_resize(geo, edge, pointer, action.grab);
            action.grab = pointer;
            container.set_geometry(edge, new_geo);
        }
        self.update_pointer_pos(id, edge)
    }

    pub fn resize_tiled(&mut self, id: Uuid, edge: ResizeEdge, pointer: Point,
                        action: &mut Action) -> CommandResult {
        // There can be multiple directions we are moving in, e.g up and left.
        let parent_id = try!(self.parent_of(id)).get_id();
        let dirs_moving_in = Direction::from_edge(edge);
        let siblings: Vec<Uuid> = dirs_moving_in.iter()
            .map(|dir| self.sibling_in_dir(id, *dir))
            // TODO There MUST be a better way to do something like this...
            .filter(|thing| thing.is_ok())
            .map(|thing| thing.unwrap())
            .collect();

        // Because we can't have multiple mutable references active in the tree at once,
        // first we modify the one the user is resizing and then adjust the siblings.
        {
            let container = try!(self.lookup_mut(id));
            if container.floating() {
                return Err(TreeError::Resize(ResizeErr::ExpectedNotFloating(container.get_id())))
            }
            match container.get_type() {
                ContainerType::View | ContainerType::Container => {},
                _ => return Err(TreeError::UuidWrongType(container.get_id(),
                                                        vec!(ContainerType::View)))
            }
            let geo = container.get_geometry()
                .expect("Could not get geometry of the container");
            let new_geo = calculate_resize(geo, edge, pointer, action.grab);
            container.set_geometry(edge, new_geo);
        }
        //....update parent?
        {
            let container = try!(self.lookup_mut(parent_id));
            if container.floating() {
                return Err(TreeError::Resize(ResizeErr::ExpectedNotFloating(container.get_id())))
            }
            match container.get_type() {
                ContainerType::View | ContainerType::Container => {},
                _ => return Err(TreeError::UuidWrongType(container.get_id(),
                                                          vec!(ContainerType::View)))
            }
            let geo = container.get_geometry()
                .expect("Could not get geometry of the container");
            let new_geo = calculate_resize(geo, edge, pointer, action.grab);
            container.set_geometry(edge, new_geo);

        }
        // and now we mutate the siblings
        let reversed_dir: Vec<Direction> = dirs_moving_in.iter()
            .map(|dir| dir.reverse()).collect();
        let reversed_edge = Direction::to_edge(reversed_dir.as_slice());
        for sibling in siblings {
            // TODO Abstract, the only thing different from above
            // is the edge and the exact node we are doing the calc on
            let container = try!(self.lookup_mut(sibling));
            if container.floating() {
                return Err(TreeError::Resize(ResizeErr::ExpectedNotFloating(container.get_id())))
            }
            match container.get_type() {
                ContainerType::View | ContainerType::Container => {},
                _ => return Err(TreeError::UuidWrongType(container.get_id(),
                                                         vec!(ContainerType::View)))
            }
            let geo = container.get_geometry()
                .expect("Could not get geometry of the container");
            let new_geo = calculate_resize(geo, reversed_edge, pointer, action.grab);
            action.grab = pointer;
            container.set_geometry(reversed_edge, new_geo);
        }
        let node_ix = self.tree.lookup_id(id)
            .expect("Could not find node index for an id");
        let workspace_ix = try!(self.tree.ancestor_of_type(node_ix,
                                                           ContainerType::Workspace)
                                .map_err(|err| TreeError::PetGraph(err)));
        self.layout(workspace_ix);
        action.grab = pointer;
        self.update_pointer_pos(id, edge)
    }
}

/// Calculates what the new geometry is of a window.
/// Needs the geometry of the window, the edge direction the pointer is moving in,
/// the current position of the pointer, and the previous place the pointer was at.
fn calculate_resize(geo: Geometry, edge: ResizeEdge,
                    cur_pointer: Point, prev_pointer: Point) -> Geometry {
    let mut new_geo = geo.clone();
    let dx = cur_pointer.x - prev_pointer.x;
    let dy = cur_pointer.y - prev_pointer.y;
    if edge.contains(RESIZE_LEFT) {
        if dx < 0 {
            new_geo.size.w = geo.size.w.saturating_add(dx.abs() as u32);
        } else {
            new_geo.size.w = geo.size.w.saturating_sub(dx.abs() as u32);
        }
        new_geo.origin.x += dx;
    }
    else if edge.contains(RESIZE_RIGHT) {
        if dx < 0 {
            new_geo.size.w = geo.size.w.saturating_sub(dx.abs() as u32);
        } else {
            new_geo.size.w = geo.size.w.saturating_add(dx.abs() as u32);
        }
    }

    if edge.contains(RESIZE_TOP) {
        if dy < 0 {
            new_geo.size.h = geo.size.h.saturating_add(dy.abs() as u32);
        } else {
            new_geo.size.h = geo.size.h.saturating_sub(dy.abs() as u32);
        }
        new_geo.origin.y += dy;
    }
    else if edge.contains(RESIZE_BOTTOM) {
        if dy < 0 {
            new_geo.size.h = geo.size.h.saturating_sub(dy.abs() as u32);
        } else {
            new_geo.size.h = geo.size.h.saturating_add(dy.abs() as u32);
        }
    }

    if new_geo.size.w <= MIN_SIZE.w {
        new_geo.origin.x = geo.origin.x;
        new_geo.size.w = geo.size.w;
    }

    if new_geo.size.h <= MIN_SIZE.h {
        new_geo.origin.y = geo.origin.y;
        new_geo.size.h = geo.size.h;
    }
    new_geo
}
<commit_msg>Disabled tiling after resizing, to fix the bugs<commit_after>use rustwlc::{input, Point, ResizeEdge, Geometry,
              RESIZE_LEFT, RESIZE_RIGHT, RESIZE_TOP, RESIZE_BOTTOM,
              RESIZE_TOPLEFT, RESIZE_TOPRIGHT, RESIZE_BOTTOMLEFT, RESIZE_BOTTOMRIGHT,
};

use super::super::{Action, Direction, LayoutTree, TreeError};
use super::super::commands::{CommandResult};
use super::super::core::container::{ContainerType, MIN_SIZE};
use uuid::Uuid;

#[derive(Debug, Clone, Copy)]
pub enum ResizeErr {
    /// Expected the node associated with the UUID to be floating.
    ExpectedFloating(Uuid),
    /// Expected the node associated with the UUID to not be floating
    ExpectedNotFloating(Uuid)
}

impl LayoutTree {
    /// Updates pointer position for the node behind the id,
    /// in the same direction as the edge.
    pub fn update_pointer_pos(&self, id: Uuid, edge: ResizeEdge) -> CommandResult {
        let container = try!(self.lookup(id));
        let Geometry { mut origin, size } = container.get_geometry()
            .expect("Container had no geometry");
        drop(container);
        if edge.contains(RESIZE_TOPLEFT) {
            input::pointer::set_position(origin);
        } else if edge.contains(RESIZE_TOPRIGHT) {
            origin.x += size.w as i32;
            input::pointer::set_position(origin);
        } else if edge.contains(RESIZE_BOTTOMLEFT) {
            origin.y += size.h as i32;
            input::pointer::set_position(origin);
        } else if edge.contains(RESIZE_BOTTOMRIGHT) {
            origin.x += size.w as i32;
            origin.y += size.h as i32;
            input::pointer::set_position(origin);
        }
        Ok(())
    }

    /// Resizes a floating container. If the container was not floating, an Err is returned.
    pub fn resize_floating(&mut self, id: Uuid, edge: ResizeEdge, pointer: Point,
                           action: &mut Action) -> CommandResult {
        {
            let container = try!(self.lookup_mut(id));
            if !container.floating() {
                return Err(TreeError::Resize(ResizeErr::ExpectedFloating(container.get_id())))
            }
            match container.get_type() {
                ContainerType::View | ContainerType::Container => {},
                _ => return Err(TreeError::UuidWrongType(container.get_id(),
                                                        vec!(ContainerType::View)))
            }
            let geo = container.get_geometry()
                .expect("Could not get geometry of the container");

            let new_geo = calculate_resize(geo, edge, pointer, action.grab);
            action.grab = pointer;
            container.set_geometry(edge, new_geo);
        }
        self.update_pointer_pos(id, edge)
    }

    pub fn resize_tiled(&mut self, id: Uuid, edge: ResizeEdge, pointer: Point,
                        action: &mut Action) -> CommandResult {
        // There can be multiple directions we are moving in, e.g up and left.
        let parent_id = try!(self.parent_of(id)).get_id();
        let dirs_moving_in = Direction::from_edge(edge);
        let siblings: Vec<Uuid> = dirs_moving_in.iter()
            .map(|dir| self.sibling_in_dir(id, *dir))
            // TODO There MUST be a better way to do something like this...
            .filter(|thing| thing.is_ok())
            .map(|thing| thing.unwrap())
            .collect();

        // Because we can't have multiple mutable references active in the tree at once,
        // first we modify the one the user is resizing and then adjust the siblings.
        {
            let container = try!(self.lookup_mut(id));
            if container.floating() {
                return Err(TreeError::Resize(ResizeErr::ExpectedNotFloating(container.get_id())))
            }
            match container.get_type() {
                ContainerType::View | ContainerType::Container => {},
                _ => return Err(TreeError::UuidWrongType(container.get_id(),
                                                        vec!(ContainerType::View)))
            }
            let geo = container.get_geometry()
                .expect("Could not get geometry of the container");
            let new_geo = calculate_resize(geo, edge, pointer, action.grab);
            container.set_geometry(edge, new_geo);
        }
        //....update parent?
        {
            let container = try!(self.lookup_mut(parent_id));
            if container.floating() {
                return Err(TreeError::Resize(ResizeErr::ExpectedNotFloating(container.get_id())))
            }
            match container.get_type() {
                ContainerType::View | ContainerType::Container => {},
                _ => return Err(TreeError::UuidWrongType(container.get_id(),
                                                          vec!(ContainerType::View)))
            }
            let geo = container.get_geometry()
                .expect("Could not get geometry of the container");
            let new_geo = calculate_resize(geo, edge, pointer, action.grab);
            container.set_geometry(edge, new_geo);

        }
        // and now we mutate the siblings
        let reversed_dir: Vec<Direction> = dirs_moving_in.iter()
            .map(|dir| dir.reverse()).collect();
        let reversed_edge = Direction::to_edge(reversed_dir.as_slice());
        for sibling in siblings {
            // TODO Abstract, the only thing different from above
            // is the edge and the exact node we are doing the calc on
            let container = try!(self.lookup_mut(sibling));
            if container.floating() {
                return Err(TreeError::Resize(ResizeErr::ExpectedNotFloating(container.get_id())))
            }
            match container.get_type() {
                ContainerType::View | ContainerType::Container => {},
                _ => return Err(TreeError::UuidWrongType(container.get_id(),
                                                         vec!(ContainerType::View)))
            }
            let geo = container.get_geometry()
                .expect("Could not get geometry of the container");
            let new_geo = calculate_resize(geo, reversed_edge, pointer, action.grab);
            action.grab = pointer;
            container.set_geometry(reversed_edge, new_geo);
        }
        /*let node_ix = self.tree.lookup_id(id)
            .expect("Could not find node index for an id");
        let workspace_ix = try!(self.tree.ancestor_of_type(node_ix,
                                                           ContainerType::Workspace)
                                .map_err(|err| TreeError::PetGraph(err)));
        self.layout(workspace_ix);*/
        action.grab = pointer;
        self.update_pointer_pos(id, edge)
    }
}

/// Calculates what the new geometry is of a window.
/// Needs the geometry of the window, the edge direction the pointer is moving in,
/// the current position of the pointer, and the previous place the pointer was at.
fn calculate_resize(geo: Geometry, edge: ResizeEdge,
                    cur_pointer: Point, prev_pointer: Point) -> Geometry {
    let mut new_geo = geo.clone();
    let dx = cur_pointer.x - prev_pointer.x;
    let dy = cur_pointer.y - prev_pointer.y;
    if edge.contains(RESIZE_LEFT) {
        if dx < 0 {
            new_geo.size.w = geo.size.w.saturating_add(dx.abs() as u32);
        } else {
            new_geo.size.w = geo.size.w.saturating_sub(dx.abs() as u32);
        }
        new_geo.origin.x += dx;
    }
    else if edge.contains(RESIZE_RIGHT) {
        if dx < 0 {
            new_geo.size.w = geo.size.w.saturating_sub(dx.abs() as u32);
        } else {
            new_geo.size.w = geo.size.w.saturating_add(dx.abs() as u32);
        }
    }

    if edge.contains(RESIZE_TOP) {
        if dy < 0 {
            new_geo.size.h = geo.size.h.saturating_add(dy.abs() as u32);
        } else {
            new_geo.size.h = geo.size.h.saturating_sub(dy.abs() as u32);
        }
        new_geo.origin.y += dy;
    }
    else if edge.contains(RESIZE_BOTTOM) {
        if dy < 0 {
            new_geo.size.h = geo.size.h.saturating_sub(dy.abs() as u32);
        } else {
            new_geo.size.h = geo.size.h.saturating_add(dy.abs() as u32);
        }
    }

    if new_geo.size.w <= MIN_SIZE.w {
        new_geo.origin.x = geo.origin.x;
        new_geo.size.w = geo.size.w;
    }

    if new_geo.size.h <= MIN_SIZE.h {
        new_geo.origin.y = geo.origin.y;
        new_geo.size.h = geo.size.h;
    }
    new_geo
}
<|endoftext|>


<commit_before>
fn main() {
    let mut vec = vec![0];
}
<commit_msg>completed function. result correct<commit_after>
fn main() {
    let mut vec = vec![0];
    for x in 0..1000 {
        if x % 3 == 0 {
            vec.push(x);
        } else if x % 5 == 0 {
            vec.push(x);
        }
    }
    let vecsum: u32 = vec.iter().sum();
    println!("The sum of all multiples of 3 and 5 below 1000 equals to {}", vecsum);
}
<|endoftext|>


<commit_before>// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com
//
// Exercise 7-4: Wolfram Cellular Automata

// Simple demonstration of a Wolfram 1-dimensional cellular automata
// with the system scrolling by
// Also implements wrap around

extern crate nannou;

use nannou::prelude::*;
use std::ops::Range;

const RULE: i32 = 2;

fn main() {
    nannou::app(model).update(update).run();
}

// A Type to manage the CA
struct Ca {
    generation: i32,    // How many generations?
    rule_set: Vec<i32>, // An array to store the ruleset, for example {0,1,1,0,1,1,0,1}
    w: usize,
    matrix: Vec<Vec<i32>>,
    columns: usize,
    rows: usize,
    col_range: Range<usize>,
}

impl Ca {
    fn new(r: Vec<i32>, rect: Rect) -> Self {
        let rule_set = r;
        let generation = 0;
        let w = 4;
        let columns = rect.w() as usize / w;
        let rows = rect.h() as usize / w;
        let col_range = 1..columns - 1;
        let matrix = vec![vec![0; rows]; columns];

        let mut ca = Ca {
            rule_set,
            generation,
            w,
            columns,
            rows,
            col_range,
            matrix,
        };
        ca.restart();
        ca
    }

    // Make a random rule set
    fn _randomize(&mut self) {
        self.rule_set = (0..self.rule_set.len())
            .map(|_| random_range(0i32, 2))
            .collect();
    }

    // Reset generation to 0
    fn restart(&mut self) {
        self.matrix = vec![vec![0; self.rows]; self.columns];
        self.matrix[self.columns / 2][0] = 1; // We arbitrarily start with just the middle cell having a state of "1"
        self.generation = 0;
    }

    // The process of creating the new generation
    fn generate(&mut self) {
        // For every spot, determine new state by examing current state, and neighbor states
        // Ignore edges that only have one neighor
        for i in self.col_range.clone() {
            let left = self.matrix[(i + self.columns - 1) % self.columns]
                [(self.generation % self.rows as i32) as usize]; // Left neighbor state
            let me = self.matrix[i][(self.generation % self.rows as i32) as usize]; // Current state
            let right =
                self.matrix[(i + 1) % self.columns][(self.generation % self.rows as i32) as usize]; // Right beighbor state
            self.matrix[i][((self.generation + 1) % self.rows as i32) as usize] =
                self.rules(left, me, right); // Compute next generation state based on ruleset
        }
        self.generation += 1;
    }

    // This is the easy part, just draw the cells fill white if 1, black if 0
    fn display(&self, draw: &app::Draw, rect: &Rect) {
        let offset = (self.generation % self.rows as i32) as usize;
        for i in 0..self.columns {
            for j in 0..self.rows {
                let mut y = j - offset;
                // if y <= 0 {
                if y >= rect.top() as usize {
                    y = self.rows + y;
                }
                // Only draw if cell state is 1
                let mut fill = 1.0;
                if self.matrix[i][j] == 1 {
                    fill = 0.0;
                }
                draw.rect()
                    .x_y(
                        ((self.w as i32 / 2) + i as i32 * self.w as i32) as f32
                            - rect.right() as f32,
                        rect.top() - (self.w / 2) as f32 - ((y - 1) * self.w) as f32,
                        //                        rect.top() as f32 - ((y - 1) * self.w + (self.w / 2)) as f32,
                    )
                    .w_h(self.w as f32, self.w as f32)
                    .rgb(fill, fill, fill);
            }
        }
    }

    // Implementing the Wolfram rules
    // Could be improved and made more concise, but here we can explicitly see what is going on for each case
    fn rules(&self, a: i32, b: i32, c: i32) -> i32 {
        if a == 1 && b == 1 && c == 1 {
            return self.rule_set[0];
        }
        if a == 1 && b == 1 && c == 0 {
            return self.rule_set[1];
        }
        if a == 1 && b == 0 && c == 1 {
            return self.rule_set[2];
        }
        if a == 1 && b == 0 && c == 0 {
            return self.rule_set[3];
        }
        if a == 0 && b == 1 && c == 1 {
            return self.rule_set[4];
        }
        if a == 0 && b == 1 && c == 0 {
            return self.rule_set[5];
        }
        if a == 0 && b == 0 && c == 1 {
            return self.rule_set[6];
        }
        if a == 0 && b == 0 && c == 0 {
            return self.rule_set[7];
        }
        0
    }

    // The CA is done if it reaches the bottom of the screen
    fn _finished(&self, rect: &Rect) -> bool {
        if self.generation > rect.h() as i32 / self.w as i32 {
            true
        } else {
            false
        }
    }
}

struct Model {
    ca: Ca,
}

fn model(app: &App) -> Model {
    let rect = Rect::from_w_h(640.0, 800.0);
    app.new_window()
        .with_dimensions(rect.w() as u32, rect.h() as u32)
        .view(view)
        .build()
        .unwrap();

    let rule_set = match RULE {
        1 => vec![0, 1, 1, 1, 1, 0, 1, 1], // Rule 222
        2 => vec![0, 1, 1, 1, 1, 1, 0, 1], // Rule 190
        3 => vec![0, 1, 1, 1, 1, 0, 0, 0], // Rule 30
        4 => vec![0, 1, 1, 1, 0, 1, 1, 0], // Rule 110
        5 => vec![0, 1, 0, 1, 1, 0, 1, 0], // Rule 90
        _ => vec![0, 0, 0, 0, 0, 0, 0, 0],
    };

    let ca = Ca::new(rule_set, rect);
    Model { ca }
}

fn update(_app: &App, m: &mut Model, _update: Update) {
    m.ca.generate();
}

fn view(app: &App, m: &Model, frame: Frame) -> Frame {
    // Begin drawing
    let draw = app.draw();

    m.ca.display(&draw, &app.window_rect());

    // Write the result of our drawing to the window's OpenGL frame.
    draw.to_frame(app, &frame).unwrap();

    // Return the drawn frame.
    frame
}
<commit_msg>Fix panic in nature of code CA example 7_04<commit_after>// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com
//
// Exercise 7-4: Wolfram Cellular Automata

// Simple demonstration of a Wolfram 1-dimensional cellular automata
// with the system scrolling by
// Also implements wrap around

extern crate nannou;

use nannou::prelude::*;
use std::ops::Range;

const RULE: i32 = 2;

fn main() {
    nannou::app(model).update(update).run();
}

// A Type to manage the CA
struct Ca {
    generation: i32,    // How many generations?
    rule_set: Vec<i32>, // An array to store the ruleset, for example {0,1,1,0,1,1,0,1}
    w: usize,
    matrix: Vec<Vec<i32>>,
    columns: usize,
    rows: usize,
    col_range: Range<usize>,
}

impl Ca {
    fn new(r: Vec<i32>, rect: Rect) -> Self {
        let rule_set = r;
        let generation = 0;
        let w = 4;
        let columns = rect.w() as usize / w;
        let rows = rect.h() as usize / w;
        let col_range = 1..columns - 1;
        let matrix = vec![vec![0; rows]; columns];

        let mut ca = Ca {
            rule_set,
            generation,
            w,
            columns,
            rows,
            col_range,
            matrix,
        };
        ca.restart();
        ca
    }

    // Make a random rule set
    fn _randomize(&mut self) {
        self.rule_set = (0..self.rule_set.len())
            .map(|_| random_range(0i32, 2))
            .collect();
    }

    // Reset generation to 0
    fn restart(&mut self) {
        self.matrix = vec![vec![0; self.rows]; self.columns];
        self.matrix[self.columns / 2][0] = 1; // We arbitrarily start with just the middle cell having a state of "1"
        self.generation = 0;
    }

    // The process of creating the new generation
    fn generate(&mut self) {
        // For every spot, determine new state by examing current state, and neighbor states
        // Ignore edges that only have one neighor
        for i in self.col_range.clone() {
            let left = self.matrix[(i + self.columns - 1) % self.columns]
                [(self.generation % self.rows as i32) as usize]; // Left neighbor state
            let me = self.matrix[i][(self.generation % self.rows as i32) as usize]; // Current state
            let right =
                self.matrix[(i + 1) % self.columns][(self.generation % self.rows as i32) as usize]; // Right beighbor state
            self.matrix[i][((self.generation + 1) % self.rows as i32) as usize] =
                self.rules(left, me, right); // Compute next generation state based on ruleset
        }
        self.generation += 1;
    }

    // This is the easy part, just draw the cells fill white if 1, black if 0
    fn display(&self, draw: &app::Draw, rect: &Rect) {
        let offset = self.generation % self.rows as i32;
        for col in 0..self.columns {
            for row in 0..self.rows {
                let mut y = row as i32 - offset;
                if y >= rect.top() as i32 {
                    y = self.rows as i32 + y;
                }
                // Only draw if cell state is 1
                let mut fill = 1.0;
                if self.matrix[col][row] == 1 {
                    fill = 0.0;
                }
                let x = ((self.w as i32 / 2) + col as i32 * self.w as i32) as f32
                    - rect.right() as f32;
                let y = rect.top() - (self.w / 2) as f32 - ((y - 1) * self.w as i32) as f32;
                draw.rect()
                    .x_y(x, y)
                    .w_h(self.w as f32, self.w as f32)
                    .rgb(fill, fill, fill);
            }
        }
    }

    // Implementing the Wolfram rules
    // Could be improved and made more concise, but here we can explicitly see what is going on for each case
    fn rules(&self, a: i32, b: i32, c: i32) -> i32 {
        if a == 1 && b == 1 && c == 1 {
            return self.rule_set[0];
        }
        if a == 1 && b == 1 && c == 0 {
            return self.rule_set[1];
        }
        if a == 1 && b == 0 && c == 1 {
            return self.rule_set[2];
        }
        if a == 1 && b == 0 && c == 0 {
            return self.rule_set[3];
        }
        if a == 0 && b == 1 && c == 1 {
            return self.rule_set[4];
        }
        if a == 0 && b == 1 && c == 0 {
            return self.rule_set[5];
        }
        if a == 0 && b == 0 && c == 1 {
            return self.rule_set[6];
        }
        if a == 0 && b == 0 && c == 0 {
            return self.rule_set[7];
        }
        0
    }

    // The CA is done if it reaches the bottom of the screen
    fn _finished(&self, rect: &Rect) -> bool {
        if self.generation > rect.h() as i32 / self.w as i32 {
            true
        } else {
            false
        }
    }
}

struct Model {
    ca: Ca,
}

fn model(app: &App) -> Model {
    let rect = Rect::from_w_h(640.0, 800.0);
    app.new_window()
        .with_dimensions(rect.w() as u32, rect.h() as u32)
        .view(view)
        .build()
        .unwrap();

    let rule_set = match RULE {
        1 => vec![0, 1, 1, 1, 1, 0, 1, 1], // Rule 222
        2 => vec![0, 1, 1, 1, 1, 1, 0, 1], // Rule 190
        3 => vec![0, 1, 1, 1, 1, 0, 0, 0], // Rule 30
        4 => vec![0, 1, 1, 1, 0, 1, 1, 0], // Rule 110
        5 => vec![0, 1, 0, 1, 1, 0, 1, 0], // Rule 90
        _ => vec![0, 0, 0, 0, 0, 0, 0, 0],
    };

    let ca = Ca::new(rule_set, rect);
    Model { ca }
}

fn update(_app: &App, m: &mut Model, _update: Update) {
    m.ca.generate();
}

fn view(app: &App, m: &Model, frame: Frame) -> Frame {
    // Begin drawing
    let draw = app.draw();

    m.ca.display(&draw, &app.window_rect());

    // Write the result of our drawing to the window's OpenGL frame.
    draw.to_frame(app, &frame).unwrap();

    // Return the drawn frame.
    frame
}
<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use cast;
use libc;
use option::*;
use task;
use task::atomically;
use unstable::finally::Finally;
use unstable::intrinsics;
use ops::Drop;
use clone::Clone;
use kinds::Owned;

/// An atomically reference counted pointer.
///
/// Enforces no shared-memory safety.
pub struct UnsafeAtomicRcBox<T> {
    data: *mut libc::c_void,
}

struct AtomicRcBoxData<T> {
    count: int,
    data: Option<T>,
}

impl<T: Owned> UnsafeAtomicRcBox<T> {
    pub fn new(data: T) -> UnsafeAtomicRcBox<T> {
        unsafe {
            let data = ~AtomicRcBoxData { count: 1, data: Some(data) };
            let ptr = cast::transmute(data);
            return UnsafeAtomicRcBox { data: ptr };
        }
    }

    #[inline(always)]
    pub unsafe fn get(&self) -> *mut T
    {
        let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
        assert!(data.count > 0);
        let r: *mut T = data.data.get_mut_ref();
        cast::forget(data);
        return r;
    }

    #[inline(always)]
    pub unsafe fn get_immut(&self) -> *T
    {
        let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
        assert!(data.count > 0);
        let r: *T = cast::transmute_immut(data.data.get_mut_ref());
        cast::forget(data);
        return r;
    }
}

impl<T: Owned> Clone for UnsafeAtomicRcBox<T> {
    fn clone(&self) -> UnsafeAtomicRcBox<T> {
        unsafe {
            let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
            let new_count = intrinsics::atomic_xadd(&mut data.count, 1) + 1;
            assert!(new_count >= 2);
            cast::forget(data);
            return UnsafeAtomicRcBox { data: self.data };
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for UnsafeAtomicRcBox<T>{
    fn finalize(&self) {
        unsafe {
            do task::unkillable {
                let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
                let new_count = intrinsics::atomic_xsub(&mut data.count, 1) - 1;
                assert!(new_count >= 0);
                if new_count == 0 {
                    // drop glue takes over.
                } else {
                    cast::forget(data);
                }
            }
        }
    }
}

/****************************************************************************/

#[allow(non_camel_case_types)] // runtime type
pub type rust_little_lock = *libc::c_void;

struct LittleLock {
    l: rust_little_lock,
}

impl Drop for LittleLock {
    fn finalize(&self) {
        unsafe {
            rust_destroy_little_lock(self.l);
        }
    }
}

fn LittleLock() -> LittleLock {
    unsafe {
        LittleLock {
            l: rust_create_little_lock()
        }
    }
}

pub impl LittleLock {
    #[inline(always)]
    unsafe fn lock<T>(&self, f: &fn() -> T) -> T {
        do atomically {
            rust_lock_little_lock(self.l);
            do (|| {
                f()
            }).finally {
                rust_unlock_little_lock(self.l);
            }
        }
    }
}

struct ExData<T> {
    lock: LittleLock,
    failed: bool,
    data: T,
}

/**
 * An arc over mutable data that is protected by a lock. For library use only.
 */
pub struct Exclusive<T> {
    x: UnsafeAtomicRcBox<ExData<T>>
}

pub fn exclusive<T:Owned>(user_data: T) -> Exclusive<T> {
    let data = ExData {
        lock: LittleLock(),
        failed: false,
        data: user_data
    };
    Exclusive {
        x: UnsafeAtomicRcBox::new(data)
    }
}

impl<T:Owned> Clone for Exclusive<T> {
    // Duplicate an exclusive ARC, as std::arc::clone.
    fn clone(&self) -> Exclusive<T> {
        Exclusive { x: self.x.clone() }
    }
}

pub impl<T:Owned> Exclusive<T> {
    // Exactly like std::arc::mutex_arc,access(), but with the little_lock
    // instead of a proper mutex. Same reason for being unsafe.
    //
    // Currently, scheduling operations (i.e., yielding, receiving on a pipe,
    // accessing the provided condition variable) are prohibited while inside
    // the exclusive. Supporting that is a work in progress.
    #[inline(always)]
    unsafe fn with<U>(&self, f: &fn(x: &mut T) -> U) -> U {
        let rec = self.x.get();
        do (*rec).lock.lock {
            if (*rec).failed {
                fail!("Poisoned exclusive - another task failed inside!");
            }
            (*rec).failed = true;
            let result = f(&mut (*rec).data);
            (*rec).failed = false;
            result
        }
    }

    #[inline(always)]
    unsafe fn with_imm<U>(&self, f: &fn(x: &T) -> U) -> U {
        do self.with |x| {
            f(cast::transmute_immut(x))
        }
    }
}

fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool {
    unsafe {
        let old = intrinsics::atomic_cxchg(address, oldval, newval);
        old == oldval
    }
}

extern {
    fn rust_create_little_lock() -> rust_little_lock;
    fn rust_destroy_little_lock(lock: rust_little_lock);
    fn rust_lock_little_lock(lock: rust_little_lock);
    fn rust_unlock_little_lock(lock: rust_little_lock);
}

#[cfg(test)]
mod tests {
    use comm;
    use super::exclusive;
    use task;
    use uint;

    #[test]
    fn exclusive_arc() {
        let mut futures = ~[];

        let num_tasks = 10;
        let count = 10;

        let total = exclusive(~0);

        for uint::range(0, num_tasks) |_i| {
            let total = total.clone();
            let (port, chan) = comm::stream();
            futures.push(port);

            do task::spawn || {
                for uint::range(0, count) |_i| {
                    do total.with |count| {
                        **count += 1;
                    }
                }
                chan.send(());
            }
        };

        for futures.each |f| { f.recv() }

        do total.with |total| {
            assert!(**total == num_tasks * count)
        };
    }

    #[test] #[should_fail] #[ignore(cfg(windows))]
    fn exclusive_poison() {
        // Tests that if one task fails inside of an exclusive, subsequent
        // accesses will also fail.
        let x = exclusive(1);
        let x2 = x.clone();
        do task::try || {
            do x2.with |one| {
                assert_eq!(*one, 2);
            }
        };
        do x.with |one| {
            assert_eq!(*one, 1);
        }
    }
}
<commit_msg>Add AtomicUint newtype<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use cast;
use libc;
use option::*;
use task;
use task::atomically;
use unstable::finally::Finally;
use unstable::intrinsics;
use ops::Drop;
use clone::Clone;
use kinds::Owned;

/// An atomically reference counted pointer.
///
/// Enforces no shared-memory safety.
pub struct UnsafeAtomicRcBox<T> {
    data: *mut libc::c_void,
}

struct AtomicRcBoxData<T> {
    count: int,
    data: Option<T>,
}

impl<T: Owned> UnsafeAtomicRcBox<T> {
    pub fn new(data: T) -> UnsafeAtomicRcBox<T> {
        unsafe {
            let data = ~AtomicRcBoxData { count: 1, data: Some(data) };
            let ptr = cast::transmute(data);
            return UnsafeAtomicRcBox { data: ptr };
        }
    }

    #[inline(always)]
    pub unsafe fn get(&self) -> *mut T
    {
        let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
        assert!(data.count > 0);
        let r: *mut T = data.data.get_mut_ref();
        cast::forget(data);
        return r;
    }

    #[inline(always)]
    pub unsafe fn get_immut(&self) -> *T
    {
        let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
        assert!(data.count > 0);
        let r: *T = cast::transmute_immut(data.data.get_mut_ref());
        cast::forget(data);
        return r;
    }
}

impl<T: Owned> Clone for UnsafeAtomicRcBox<T> {
    fn clone(&self) -> UnsafeAtomicRcBox<T> {
        unsafe {
            let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
            let new_count = intrinsics::atomic_xadd(&mut data.count, 1) + 1;
            assert!(new_count >= 2);
            cast::forget(data);
            return UnsafeAtomicRcBox { data: self.data };
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for UnsafeAtomicRcBox<T>{
    fn finalize(&self) {
        unsafe {
            do task::unkillable {
                let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
                let new_count = intrinsics::atomic_xsub(&mut data.count, 1) - 1;
                assert!(new_count >= 0);
                if new_count == 0 {
                    // drop glue takes over.
                } else {
                    cast::forget(data);
                }
            }
        }
    }
}

/****************************************************************************/

#[allow(non_camel_case_types)] // runtime type
pub type rust_little_lock = *libc::c_void;

struct LittleLock {
    l: rust_little_lock,
}

impl Drop for LittleLock {
    fn finalize(&self) {
        unsafe {
            rust_destroy_little_lock(self.l);
        }
    }
}

fn LittleLock() -> LittleLock {
    unsafe {
        LittleLock {
            l: rust_create_little_lock()
        }
    }
}

pub impl LittleLock {
    #[inline(always)]
    unsafe fn lock<T>(&self, f: &fn() -> T) -> T {
        do atomically {
            rust_lock_little_lock(self.l);
            do (|| {
                f()
            }).finally {
                rust_unlock_little_lock(self.l);
            }
        }
    }
}

struct ExData<T> {
    lock: LittleLock,
    failed: bool,
    data: T,
}

/**
 * An arc over mutable data that is protected by a lock. For library use only.
 */
pub struct Exclusive<T> {
    x: UnsafeAtomicRcBox<ExData<T>>
}

pub fn exclusive<T:Owned>(user_data: T) -> Exclusive<T> {
    let data = ExData {
        lock: LittleLock(),
        failed: false,
        data: user_data
    };
    Exclusive {
        x: UnsafeAtomicRcBox::new(data)
    }
}

impl<T:Owned> Clone for Exclusive<T> {
    // Duplicate an exclusive ARC, as std::arc::clone.
    fn clone(&self) -> Exclusive<T> {
        Exclusive { x: self.x.clone() }
    }
}

pub impl<T:Owned> Exclusive<T> {
    // Exactly like std::arc::mutex_arc,access(), but with the little_lock
    // instead of a proper mutex. Same reason for being unsafe.
    //
    // Currently, scheduling operations (i.e., yielding, receiving on a pipe,
    // accessing the provided condition variable) are prohibited while inside
    // the exclusive. Supporting that is a work in progress.
    #[inline(always)]
    unsafe fn with<U>(&self, f: &fn(x: &mut T) -> U) -> U {
        let rec = self.x.get();
        do (*rec).lock.lock {
            if (*rec).failed {
                fail!("Poisoned exclusive - another task failed inside!");
            }
            (*rec).failed = true;
            let result = f(&mut (*rec).data);
            (*rec).failed = false;
            result
        }
    }

    #[inline(always)]
    unsafe fn with_imm<U>(&self, f: &fn(x: &T) -> U) -> U {
        do self.with |x| {
            f(cast::transmute_immut(x))
        }
    }
}

fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool {
    unsafe {
        let old = intrinsics::atomic_cxchg(address, oldval, newval);
        old == oldval
    }
}

extern {
    fn rust_create_little_lock() -> rust_little_lock;
    fn rust_destroy_little_lock(lock: rust_little_lock);
    fn rust_lock_little_lock(lock: rust_little_lock);
    fn rust_unlock_little_lock(lock: rust_little_lock);
}

/* *********************************************************************/

//FIXME: #5042 This should be replaced by proper atomic type
pub struct AtomicUint(uint);
pub impl AtomicUint {
    fn load(&self) -> uint {
        unsafe { intrinsics::atomic_load(cast::transmute(self)) as uint }
    }
    fn store(&mut self, val:uint) {
        unsafe { intrinsics::atomic_store(cast::transmute(self), val as int); }
    }
    fn add(&mut self, val:int) -> uint {
        unsafe { intrinsics::atomic_xadd(cast::transmute(self), val as int) as uint }
    }
    fn cas(&self, old:uint, new:uint) -> uint {
        unsafe { intrinsics::atomic_cxchg(cast::transmute(self), old as int, new as int) as uint }
    }
}

#[cfg(test)]
mod tests {
    use comm;
    use super::exclusive;
    use task;
    use uint;

    #[test]
    fn exclusive_arc() {
        let mut futures = ~[];

        let num_tasks = 10;
        let count = 10;

        let total = exclusive(~0);

        for uint::range(0, num_tasks) |_i| {
            let total = total.clone();
            let (port, chan) = comm::stream();
            futures.push(port);

            do task::spawn || {
                for uint::range(0, count) |_i| {
                    do total.with |count| {
                        **count += 1;
                    }
                }
                chan.send(());
            }
        };

        for futures.each |f| { f.recv() }

        do total.with |total| {
            assert!(**total == num_tasks * count)
        };
    }

    #[test] #[should_fail] #[ignore(cfg(windows))]
    fn exclusive_poison() {
        // Tests that if one task fails inside of an exclusive, subsequent
        // accesses will also fail.
        let x = exclusive(1);
        let x2 = x.clone();
        do task::try || {
            do x2.with |one| {
                assert_eq!(*one, 2);
            }
        };
        do x.with |one| {
            assert_eq!(*one, 1);
        }
    }
}
<|endoftext|>


<commit_before>extern crate serde_json;
extern crate regex;

pub mod common;
pub mod did;
pub mod pool;
pub mod wallet;
pub mod ledger;
pub mod payment_address;

use self::regex::Regex;

use command_executor::{CommandContext, CommandParams};

use std;
use libindy::ledger::Ledger;

pub fn get_str_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<&'a str, ()> {
    match params.get(name) {
        Some(v) if v == "" => {
            println_err!("Required \"{}\" parameter is empty.", name);
            Err(())
        }
        Some(v) => Ok(v.as_str()),
        None => {
            println_err!("No required \"{}\" parameter present.", name);
            Err(())
        }
    }
}

pub fn get_opt_str_param<'a>(key: &'a str, params: &'a CommandParams) -> Result<Option<&'a str>, ()> {
    match params.get(key) {
        Some(v) if v == "" => {
            println_err!("Optional parameter \"{}\" is empty.", key);
            Err(())
        }
        Some(v) => Ok(Some(v.as_str())),
        None => Ok(None)
    }
}

pub fn get_opt_empty_str_param<'a>(key: &'a str, params: &'a CommandParams) -> Result<Option<&'a str>, ()> {
    Ok(params.get(key).map(|v| v.as_str()))
}

pub fn _get_int_param<T>(name: &str, params: &CommandParams) -> Result<T, ()>
    where T: std::str::FromStr, <T as std::str::FromStr>::Err: std::fmt::Display {
    match params.get(name) {
        Some(v) => {
            Ok(v.parse::<T>().map_err(|err|
                println_err!("Can't parse integer parameter \"{}\": err {}", name, err))?)
        }
        None => {
            println_err!("No required \"{}\" parameter present", name);
            Err(())
        }
    }
}

pub fn get_opt_number_param<T>(key: &str, params: &CommandParams) -> Result<Option<T>, ()>
    where T: std::str::FromStr, <T as std::str::FromStr>::Err: std::fmt::Display {
    let res = match params.get(key) {
        Some(value) => Some(value.parse::<T>().map_err(|err|
            println_err!("Can't parse integer parameter \"{}\": err {}", key, err))?),
        None => None
    };
    Ok(res)
}

pub fn get_bool_param(key: &str, params: &CommandParams) -> Result<bool, ()> {
    match params.get(key) {
        Some(value) => Ok(value.parse::<bool>().map_err(|err|
            println_err!("Can't parse bool parameter \"{}\": err {}", key, err))?),
        None => {
            println_err!("No required \"{}\" parameter present", key);
            Err(())
        }
    }
}

pub fn get_opt_bool_param(key: &str, params: &CommandParams) -> Result<Option<bool>, ()> {
    match params.get(key) {
        Some(value) => Ok(Some(value.parse::<bool>().map_err(|err|
            println_err!("Can't parse bool parameter \"{}\": err {}", key, err))?)),
        None => Ok(None)
    }
}

pub fn get_str_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Vec<&'a str>, ()> {
    match params.get(name) {
        None => Err(println_err!("No required \"{}\" parameter present", name)),
        Some(v) if v.is_empty() => Err(println_err!("No required \"{}\" parameter present", name)),
        Some(v) => Ok(v.split(",").collect::<Vec<&'a str>>())
    }
}

pub fn get_opt_str_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<Vec<&'a str>>, ()> {
    match params.get(name) {
        Some(v) =>
            if v.is_empty() {
                Ok(Some(Vec::<&'a str>::new()))
            } else {
                Ok(Some(v.split(",").collect::<Vec<&'a str>>()))
            },
        None => Ok(None)
    }
}

pub fn get_object_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<serde_json::Value, ()> {
    match params.get(name) {
        Some(v) => Ok(serde_json::from_str(v).map_err(|err|
            println_err!("Can't parse object parameter \"{}\": err {}", name, err))?),
        None => {
            println_err!("No required \"{}\" parameter present", name);
            Err(())
        }
    }
}

pub fn get_opt_object_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<serde_json::Value>, ()> {
    match params.get(name) {
        Some(_) => Ok(Some(get_object_param(name, params)?)),
        None => Ok(None)
    }
}

fn extract_array_tuples<'a>(param: &'a str) -> Vec<String> {
    let re = Regex::new(r#"\(([^\(\)]+)\),?"#).unwrap();
    re.captures_iter(param).map(|c| c[1].to_string()).collect::<Vec<String>>()
}

pub fn get_str_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Vec<String>, ()> {
    match params.get(name) {
        Some(v) if !v.is_empty() => {
            let tuples = extract_array_tuples(v);
            if tuples.len() == 0 {
                Err(println_err!("Parameter \"{}\" has invalid format", name))
            } else {
                Ok(tuples)
            }
        }
        _ => Err(println_err!("No required \"{}\" parameter present", name))
    }
}

pub fn get_opt_str_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<Vec<String>>, ()> {
    match params.get(name) {
        Some(v) =>
            if v.is_empty() {
                Ok(Some(Vec::<String>::new()))
            } else {
                Ok(Some(extract_array_tuples(v)))
            },
        None => Ok(None)
    }
}

pub fn ensure_active_did(ctx: &CommandContext) -> Result<String, ()> {
    match ctx.get_string_value("ACTIVE_DID") {
        Some(did) => Ok(did),
        None => Err(println_err!("There is no active did"))
    }
}

pub fn get_active_did(ctx: &CommandContext) -> Option<String> {
    ctx.get_string_value("ACTIVE_DID")
}

pub fn set_active_did(ctx: &CommandContext, did: Option<String>) {
    ctx.set_string_value("ACTIVE_DID", did.clone());
    ctx.set_sub_prompt(3, did.map(|did| format!("did({}...{})", &did[..3], &did[did.len() - 3..])));
}

pub fn ensure_opened_wallet_handle(ctx: &CommandContext) -> Result<i32, ()> {
    match ctx.get_int_value("OPENED_WALLET_HANDLE") {
        Some(wallet_handle) => Ok(wallet_handle),
        None => Err(println_err!("There is no opened wallet now"))
    }
}

pub fn ensure_opened_wallet(ctx: &CommandContext) -> Result<(i32, String), ()> {
    let handle = ctx.get_int_value("OPENED_WALLET_HANDLE");
    let name = ctx.get_string_value("OPENED_WALLET_NAME");

    match (handle, name) {
        (Some(handle), Some(name)) => Ok((handle, name)),
        _ => Err(println_err!("There is no opened wallet now"))
    }
}

pub fn get_opened_wallet(ctx: &CommandContext) -> Option<(i32, String)> {
    let handle = ctx.get_int_value("OPENED_WALLET_HANDLE");
    let name = ctx.get_string_value("OPENED_WALLET_NAME");

    if let (Some(handle), Some(name)) = (handle, name) {
        Some((handle, name))
    } else {
        None
    }
}

pub fn set_opened_wallet(ctx: &CommandContext, value: Option<(i32, String)>) {
    ctx.set_int_value("OPENED_WALLET_HANDLE", value.as_ref().map(|value| value.0.to_owned()));
    ctx.set_string_value("OPENED_WALLET_NAME", value.as_ref().map(|value| value.1.to_owned()));
    ctx.set_sub_prompt(2, value.map(|value| format!("wallet({})", value.1)));
}

pub fn ensure_connected_pool_handle(ctx: &CommandContext) -> Result<i32, ()> {
    match ctx.get_int_value("CONNECTED_POOL_HANDLE") {
        Some(pool_handle) => Ok(pool_handle),
        None => Err(println_err!("There is no opened pool now"))
    }
}

pub fn ensure_connected_pool(ctx: &CommandContext) -> Result<(i32, String), ()> {
    let handle = ctx.get_int_value("CONNECTED_POOL_HANDLE");
    let name = ctx.get_string_value("CONNECTED_POOL_NAME");

    match (handle, name) {
        (Some(handle), Some(name)) => Ok((handle, name)),
        _ => Err(println_err!("There is no opened pool now"))
    }
}

pub fn get_connected_pool(ctx: &CommandContext) -> Option<(i32, String)> {
    let handle = ctx.get_int_value("CONNECTED_POOL_HANDLE");
    let name = ctx.get_string_value("CONNECTED_POOL_NAME");

    if let (Some(handle), Some(name)) = (handle, name) {
        Some((handle, name))
    } else {
        None
    }
}

pub fn set_connected_pool(ctx: &CommandContext, value: Option<(i32, String)>) {
    ctx.set_int_value("CONNECTED_POOL_HANDLE", value.as_ref().map(|value| value.0.to_owned()));
    ctx.set_string_value("CONNECTED_POOL_NAME", value.as_ref().map(|value| value.1.to_owned()));
    ctx.set_sub_prompt(1, value.map(|value| format!("pool({})", value.1)));
}

pub fn submit_retry<F, T, E>(ctx: &CommandContext, request: &str, parser: F) -> Result<(), ()>
    where F: Fn(&str) -> Result<T, E> {
    const SUBMIT_RETRY_CNT: usize = 3;
    const SUBMIT_TIMEOUT_SEC: u64 = 2;

    let pool_handle = ensure_connected_pool_handle(ctx).unwrap();

    for _ in 0..SUBMIT_RETRY_CNT {
        let response = Ledger::submit_request(pool_handle, request).unwrap();
        if parser(&response).is_ok() {
            return Ok(());
        }
        ::std::thread::sleep(::std::time::Duration::from_secs(SUBMIT_TIMEOUT_SEC));
    }

    return Err(());
}<commit_msg>IS-1132 Add #[cfg(test)]<commit_after>extern crate serde_json;
extern crate regex;

pub mod common;
pub mod did;
pub mod pool;
pub mod wallet;
pub mod ledger;
pub mod payment_address;

use self::regex::Regex;

use command_executor::{CommandContext, CommandParams};

use std;
use libindy::ledger::Ledger;

pub fn get_str_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<&'a str, ()> {
    match params.get(name) {
        Some(v) if v == "" => {
            println_err!("Required \"{}\" parameter is empty.", name);
            Err(())
        }
        Some(v) => Ok(v.as_str()),
        None => {
            println_err!("No required \"{}\" parameter present.", name);
            Err(())
        }
    }
}

pub fn get_opt_str_param<'a>(key: &'a str, params: &'a CommandParams) -> Result<Option<&'a str>, ()> {
    match params.get(key) {
        Some(v) if v == "" => {
            println_err!("Optional parameter \"{}\" is empty.", key);
            Err(())
        }
        Some(v) => Ok(Some(v.as_str())),
        None => Ok(None)
    }
}

pub fn get_opt_empty_str_param<'a>(key: &'a str, params: &'a CommandParams) -> Result<Option<&'a str>, ()> {
    Ok(params.get(key).map(|v| v.as_str()))
}

pub fn _get_int_param<T>(name: &str, params: &CommandParams) -> Result<T, ()>
    where T: std::str::FromStr, <T as std::str::FromStr>::Err: std::fmt::Display {
    match params.get(name) {
        Some(v) => {
            Ok(v.parse::<T>().map_err(|err|
                println_err!("Can't parse integer parameter \"{}\": err {}", name, err))?)
        }
        None => {
            println_err!("No required \"{}\" parameter present", name);
            Err(())
        }
    }
}

pub fn get_opt_number_param<T>(key: &str, params: &CommandParams) -> Result<Option<T>, ()>
    where T: std::str::FromStr, <T as std::str::FromStr>::Err: std::fmt::Display {
    let res = match params.get(key) {
        Some(value) => Some(value.parse::<T>().map_err(|err|
            println_err!("Can't parse integer parameter \"{}\": err {}", key, err))?),
        None => None
    };
    Ok(res)
}

pub fn get_bool_param(key: &str, params: &CommandParams) -> Result<bool, ()> {
    match params.get(key) {
        Some(value) => Ok(value.parse::<bool>().map_err(|err|
            println_err!("Can't parse bool parameter \"{}\": err {}", key, err))?),
        None => {
            println_err!("No required \"{}\" parameter present", key);
            Err(())
        }
    }
}

pub fn get_opt_bool_param(key: &str, params: &CommandParams) -> Result<Option<bool>, ()> {
    match params.get(key) {
        Some(value) => Ok(Some(value.parse::<bool>().map_err(|err|
            println_err!("Can't parse bool parameter \"{}\": err {}", key, err))?)),
        None => Ok(None)
    }
}

pub fn get_str_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Vec<&'a str>, ()> {
    match params.get(name) {
        None => Err(println_err!("No required \"{}\" parameter present", name)),
        Some(v) if v.is_empty() => Err(println_err!("No required \"{}\" parameter present", name)),
        Some(v) => Ok(v.split(",").collect::<Vec<&'a str>>())
    }
}

pub fn get_opt_str_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<Vec<&'a str>>, ()> {
    match params.get(name) {
        Some(v) =>
            if v.is_empty() {
                Ok(Some(Vec::<&'a str>::new()))
            } else {
                Ok(Some(v.split(",").collect::<Vec<&'a str>>()))
            },
        None => Ok(None)
    }
}

pub fn get_object_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<serde_json::Value, ()> {
    match params.get(name) {
        Some(v) => Ok(serde_json::from_str(v).map_err(|err|
            println_err!("Can't parse object parameter \"{}\": err {}", name, err))?),
        None => {
            println_err!("No required \"{}\" parameter present", name);
            Err(())
        }
    }
}

pub fn get_opt_object_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<serde_json::Value>, ()> {
    match params.get(name) {
        Some(_) => Ok(Some(get_object_param(name, params)?)),
        None => Ok(None)
    }
}

fn extract_array_tuples<'a>(param: &'a str) -> Vec<String> {
    let re = Regex::new(r#"\(([^\(\)]+)\),?"#).unwrap();
    re.captures_iter(param).map(|c| c[1].to_string()).collect::<Vec<String>>()
}

pub fn get_str_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Vec<String>, ()> {
    match params.get(name) {
        Some(v) if !v.is_empty() => {
            let tuples = extract_array_tuples(v);
            if tuples.len() == 0 {
                Err(println_err!("Parameter \"{}\" has invalid format", name))
            } else {
                Ok(tuples)
            }
        }
        _ => Err(println_err!("No required \"{}\" parameter present", name))
    }
}

pub fn get_opt_str_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<Vec<String>>, ()> {
    match params.get(name) {
        Some(v) =>
            if v.is_empty() {
                Ok(Some(Vec::<String>::new()))
            } else {
                Ok(Some(extract_array_tuples(v)))
            },
        None => Ok(None)
    }
}

pub fn ensure_active_did(ctx: &CommandContext) -> Result<String, ()> {
    match ctx.get_string_value("ACTIVE_DID") {
        Some(did) => Ok(did),
        None => Err(println_err!("There is no active did"))
    }
}

pub fn get_active_did(ctx: &CommandContext) -> Option<String> {
    ctx.get_string_value("ACTIVE_DID")
}

pub fn set_active_did(ctx: &CommandContext, did: Option<String>) {
    ctx.set_string_value("ACTIVE_DID", did.clone());
    ctx.set_sub_prompt(3, did.map(|did| format!("did({}...{})", &did[..3], &did[did.len() - 3..])));
}

pub fn ensure_opened_wallet_handle(ctx: &CommandContext) -> Result<i32, ()> {
    match ctx.get_int_value("OPENED_WALLET_HANDLE") {
        Some(wallet_handle) => Ok(wallet_handle),
        None => Err(println_err!("There is no opened wallet now"))
    }
}

pub fn ensure_opened_wallet(ctx: &CommandContext) -> Result<(i32, String), ()> {
    let handle = ctx.get_int_value("OPENED_WALLET_HANDLE");
    let name = ctx.get_string_value("OPENED_WALLET_NAME");

    match (handle, name) {
        (Some(handle), Some(name)) => Ok((handle, name)),
        _ => Err(println_err!("There is no opened wallet now"))
    }
}

pub fn get_opened_wallet(ctx: &CommandContext) -> Option<(i32, String)> {
    let handle = ctx.get_int_value("OPENED_WALLET_HANDLE");
    let name = ctx.get_string_value("OPENED_WALLET_NAME");

    if let (Some(handle), Some(name)) = (handle, name) {
        Some((handle, name))
    } else {
        None
    }
}

pub fn set_opened_wallet(ctx: &CommandContext, value: Option<(i32, String)>) {
    ctx.set_int_value("OPENED_WALLET_HANDLE", value.as_ref().map(|value| value.0.to_owned()));
    ctx.set_string_value("OPENED_WALLET_NAME", value.as_ref().map(|value| value.1.to_owned()));
    ctx.set_sub_prompt(2, value.map(|value| format!("wallet({})", value.1)));
}

pub fn ensure_connected_pool_handle(ctx: &CommandContext) -> Result<i32, ()> {
    match ctx.get_int_value("CONNECTED_POOL_HANDLE") {
        Some(pool_handle) => Ok(pool_handle),
        None => Err(println_err!("There is no opened pool now"))
    }
}

pub fn ensure_connected_pool(ctx: &CommandContext) -> Result<(i32, String), ()> {
    let handle = ctx.get_int_value("CONNECTED_POOL_HANDLE");
    let name = ctx.get_string_value("CONNECTED_POOL_NAME");

    match (handle, name) {
        (Some(handle), Some(name)) => Ok((handle, name)),
        _ => Err(println_err!("There is no opened pool now"))
    }
}

pub fn get_connected_pool(ctx: &CommandContext) -> Option<(i32, String)> {
    let handle = ctx.get_int_value("CONNECTED_POOL_HANDLE");
    let name = ctx.get_string_value("CONNECTED_POOL_NAME");

    if let (Some(handle), Some(name)) = (handle, name) {
        Some((handle, name))
    } else {
        None
    }
}

pub fn set_connected_pool(ctx: &CommandContext, value: Option<(i32, String)>) {
    ctx.set_int_value("CONNECTED_POOL_HANDLE", value.as_ref().map(|value| value.0.to_owned()));
    ctx.set_string_value("CONNECTED_POOL_NAME", value.as_ref().map(|value| value.1.to_owned()));
    ctx.set_sub_prompt(1, value.map(|value| format!("pool({})", value.1)));
}

#[cfg(test)]
pub fn submit_retry<F, T, E>(ctx: &CommandContext, request: &str, parser: F) -> Result<(), ()>
    where F: Fn(&str) -> Result<T, E> {
    const SUBMIT_RETRY_CNT: usize = 3;
    const SUBMIT_TIMEOUT_SEC: u64 = 2;

    let pool_handle = ensure_connected_pool_handle(ctx).unwrap();

    for _ in 0..SUBMIT_RETRY_CNT {
        let response = Ledger::submit_request(pool_handle, request).unwrap();
        if parser(&response).is_ok() {
            return Ok(());
        }
        ::std::thread::sleep(::std::time::Duration::from_secs(SUBMIT_TIMEOUT_SEC));
    }

    return Err(());
}<|endoftext|>


<commit_before>use std::io;
use std::path::PathBuf;
use std::sync::Arc;

use filemap::{FileMap, FileName};
use index::{ByteIndex, ByteOffset};

#[derive(Debug, Default)]
pub struct CodeMap {
    files: Vec<Arc<FileMap>>,
}

impl CodeMap {
    /// Creates an empty `CodeMap`.
    pub fn new() -> CodeMap {
        CodeMap::default()
    }

    /// The next start index to use for a new filemap
    fn next_start_index(&self) -> ByteIndex {
        let end_index = self.files
            .last()
            .map(|x| x.span().end())
            .unwrap_or(ByteIndex::none());

        // Add one byte of padding between each file
        end_index + ByteOffset(1)
    }

    /// Adds a filemap to the codemap with the given name and source string
    pub fn add_filemap(&mut self, name: FileName, src: String) -> Arc<FileMap> {
        let file = Arc::new(FileMap::new(name, src, self.next_start_index()));
        self.files.push(file.clone());
        file
    }

    /// Adds a filemap to the codemap with the given name and source string
    pub fn add_filemap_from_disk<P: Into<PathBuf>>(&mut self, name: P) -> io::Result<Arc<FileMap>> {
        let file = Arc::new(FileMap::from_disk(name, self.next_start_index())?);
        self.files.push(file.clone());
        Ok(file)
    }

    /// Looks up the `File` that contains the specified byte index.
    pub fn find_file(&self, index: ByteIndex) -> Option<&Arc<FileMap>> {
        use std::cmp::Ordering;

        self.files
            .binary_search_by(|file| match () {
                () if file.span().start() > index => Ordering::Greater,
                () if file.span().end() < index => Ordering::Less,
                () => Ordering::Equal,
            })
            .ok()
            .map(|i| &self.files[i])
    }
}
<commit_msg>Prefer unwrap_or_else to unwrap_or.<commit_after>use std::io;
use std::path::PathBuf;
use std::sync::Arc;

use filemap::{FileMap, FileName};
use index::{ByteIndex, ByteOffset};

#[derive(Debug, Default)]
pub struct CodeMap {
    files: Vec<Arc<FileMap>>,
}

impl CodeMap {
    /// Creates an empty `CodeMap`.
    pub fn new() -> CodeMap {
        CodeMap::default()
    }

    /// The next start index to use for a new filemap
    fn next_start_index(&self) -> ByteIndex {
        let end_index = self.files
            .last()
            .map(|x| x.span().end())
            .unwrap_or_else(ByteIndex::none);

        // Add one byte of padding between each file
        end_index + ByteOffset(1)
    }

    /// Adds a filemap to the codemap with the given name and source string
    pub fn add_filemap(&mut self, name: FileName, src: String) -> Arc<FileMap> {
        let file = Arc::new(FileMap::new(name, src, self.next_start_index()));
        self.files.push(file.clone());
        file
    }

    /// Adds a filemap to the codemap with the given name and source string
    pub fn add_filemap_from_disk<P: Into<PathBuf>>(&mut self, name: P) -> io::Result<Arc<FileMap>> {
        let file = Arc::new(FileMap::from_disk(name, self.next_start_index())?);
        self.files.push(file.clone());
        Ok(file)
    }

    /// Looks up the `File` that contains the specified byte index.
    pub fn find_file(&self, index: ByteIndex) -> Option<&Arc<FileMap>> {
        use std::cmp::Ordering;

        self.files
            .binary_search_by(|file| match () {
                () if file.span().start() > index => Ordering::Greater,
                () if file.span().end() < index => Ordering::Less,
                () => Ordering::Equal,
            })
            .ok()
            .map(|i| &self.files[i])
    }
}
<|endoftext|>