<commit_before>use syntax::{
    ast::{
        self,
        edit::{AstNodeEdit, IndentLevel},
    },
    AstNode, SyntaxKind, TextRange, T,
};

use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, Assists};

// Assist: unwrap_block
//
// This assist removes if...else, for, while and loop control statements to just keep the body.
//
// ```
// fn foo() {
//     if true {$0
//         println!("foo");
//     }
// }
// ```
// ->
// ```
// fn foo() {
//     println!("foo");
// }
// ```
pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let assist_id = AssistId("unwrap_block", AssistKind::RefactorRewrite);
    let assist_label = "Unwrap block";

    let l_curly_token = ctx.find_token_syntax_at_offset(T!['{'])?;
    let mut block = ast::BlockExpr::cast(l_curly_token.ancestors().nth(1)?)?;
    let target = block.syntax().text_range();
    let mut parent = block.syntax().parent()?;
    if ast::MatchArm::can_cast(parent.kind()) {
        parent = parent.ancestors().find(|it| ast::MatchExpr::can_cast(it.kind()))?
    }

    if matches!(parent.kind(), SyntaxKind::STMT_LIST | SyntaxKind::EXPR_STMT) {
        return acc.add(assist_id, assist_label, target, |builder| {
            builder.replace(block.syntax().text_range(), update_expr_string(block.to_string()));
        });
    }

    let parent = ast::Expr::cast(parent)?;

    match parent.clone() {
        ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
        ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)),
        ast::Expr::IfExpr(if_expr) => {
            let then_branch = if_expr.then_branch()?;
            if then_branch == block {
                if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
                    // For `else if` blocks
                    let ancestor_then_branch = ancestor.then_branch()?;

                    return acc.add(assist_id, assist_label, target, |edit| {
                        let range_to_del_else_if = TextRange::new(
                            ancestor_then_branch.syntax().text_range().end(),
                            l_curly_token.text_range().start(),
                        );
                        let range_to_del_rest = TextRange::new(
                            then_branch.syntax().text_range().end(),
                            if_expr.syntax().text_range().end(),
                        );

                        edit.delete(range_to_del_rest);
                        edit.delete(range_to_del_else_if);
                        edit.replace(
                            target,
                            update_expr_string_without_newline(then_branch.to_string()),
                        );
                    });
                }
            } else {
                return acc.add(assist_id, assist_label, target, |edit| {
                    let range_to_del = TextRange::new(
                        then_branch.syntax().text_range().end(),
                        l_curly_token.text_range().start(),
                    );

                    edit.delete(range_to_del);
                    edit.replace(target, update_expr_string_without_newline(block.to_string()));
                });
            }
        }
        _ => return None,
    };

    let unwrapped = unwrap_trivial_block(block);
    acc.add(assist_id, assist_label, target, |builder| {
        builder.replace(parent.syntax().text_range(), update_expr_string(unwrapped.to_string()));
    })
}

fn update_expr_string(expr_string: String) -> String {
    update_expr_string_with_pat(expr_string, &[' ', '\n'])
}

fn update_expr_string_without_newline(expr_string: String) -> String {
    update_expr_string_with_pat(expr_string, &[' '])
}

fn update_expr_string_with_pat(expr_str: String, whitespace_pat: &[char]) -> String {
    // Remove leading whitespace, index [1..] to remove the leading '{',
    // then continue to remove leading whitespace.
    let expr_str =
        expr_str.trim_start_matches(whitespace_pat)[1..].trim_start_matches(whitespace_pat);

    // Remove trailing whitespace, index [..expr_str.len() - 1] to remove the trailing '}',
    // then continue to remove trailing whitespace.
    let expr_str = expr_str.trim_end_matches(whitespace_pat);
    let expr_str = expr_str[..expr_str.len() - 1].trim_end_matches(whitespace_pat);

    expr_str
        .lines()
        .map(|line| line.replacen("    ", "", 1)) // Delete indentation
        .collect::<Vec<String>>()
        .join("\n")
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    #[test]
    fn unwrap_tail_expr_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92
    }
}
"#,
            r#"
fn main() {
    92
}
"#,
        )
    }

    #[test]
    fn unwrap_stmt_expr_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92;
    }
    ()
}
"#,
            r#"
fn main() {
    92;
    ()
}
"#,
        );
        // Pedantically, we should add an `;` here...
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92
    }
    ()
}
"#,
            r#"
fn main() {
    92
    ()
}
"#,
        );
    }

    #[test]
    fn simple_if() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    bar();
    if true {$0
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
            r#"
fn main() {
    bar();
    foo();

    // comment
    bar();
}
"#,
        );
    }

    #[test]
    fn simple_if_else() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    bar();
    if true {
        foo();

        // comment
        bar();
    } else {$0
        println!("bar");
    }
}
"#,
            r#"
fn main() {
    bar();
    if true {
        foo();

        // comment
        bar();
    }
    println!("bar");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {$0
        println!("bar");
    } else {
        println!("foo");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    }
    println!("bar");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {$0
        println!("foo");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    }
    println!("foo");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested_else() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {
        println!("foo");
    } else {$0
        println!("else");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {
        println!("foo");
    }
    println!("else");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested_middle() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {$0
        println!("foo");
    } else {
        println!("else");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    }
    println!("foo");
}
"#,
        );
    }

    #[test]
    fn simple_if_bad_cursor_position() {
        check_assist_not_applicable(
            unwrap_block,
            r#"
fn main() {
    bar();$0
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_for() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    for i in 0..5 {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_if_in_for() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    for i in 0..5 {
        if true {$0
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    for i in 0..5 {
        foo();

        // comment
        bar();
    }
}
"#,
        );
    }

    #[test]
    fn simple_loop() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    loop {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_while() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    while true {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn unwrap_match_arm() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    match rel_path {
        Ok(rel_path) => {$0
            let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
            Some((*id, rel_path))
        }
        Err(_) => None,
    }
}
"#,
            r#"
fn main() {
    let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
    Some((*id, rel_path))
}
"#,
        );
    }

    #[test]
    fn simple_if_in_while_bad_cursor_position() {
        check_assist_not_applicable(
            unwrap_block,
            r#"
fn main() {
    while true {
        if true {
            foo();$0

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
        );
    }

    #[test]
    fn simple_single_line() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    {$0 0 }
}
"#,
            r#"
fn main() {
    0
}
"#,
        );
    }

    #[test]
    fn simple_nested_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        {
            3
        }
    }
}
"#,
            r#"
fn main() {
    {
        3
    }
}
"#,
        );
    }

    #[test]
    fn nested_single_line() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    {$0 { println!("foo"); } }
}
"#,
            r#"
fn main() {
    { println!("foo"); }
}
"#,
        );

        check_assist(
            unwrap_block,
            r#"
fn main() {
    {$0 { 0 } }
}
"#,
            r#"
fn main() {
    { 0 }
}
"#,
        );
    }

    #[test]
    fn simple_if_single_line() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    if true {$0 /* foo */ foo() } else { bar() /* bar */}
}
"#,
            r#"
fn main() {
    /* foo */ foo()
}
"#,
        );
    }
}
<commit_msg>fix unwrap_block by removing double trimming<commit_after>use syntax::{
    ast::{
        self,
        edit::{AstNodeEdit, IndentLevel},
    },
    AstNode, SyntaxKind, TextRange, T,
};

use crate::{AssistContext, AssistId, AssistKind, Assists};

// Assist: unwrap_block
//
// This assist removes if...else, for, while and loop control statements to just keep the body.
//
// ```
// fn foo() {
//     if true {$0
//         println!("foo");
//     }
// }
// ```
// ->
// ```
// fn foo() {
//     println!("foo");
// }
// ```
pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let assist_id = AssistId("unwrap_block", AssistKind::RefactorRewrite);
    let assist_label = "Unwrap block";

    let l_curly_token = ctx.find_token_syntax_at_offset(T!['{'])?;
    let mut block = ast::BlockExpr::cast(l_curly_token.ancestors().nth(1)?)?;
    let target = block.syntax().text_range();
    let mut parent = block.syntax().parent()?;
    if ast::MatchArm::can_cast(parent.kind()) {
        parent = parent.ancestors().find(|it| ast::MatchExpr::can_cast(it.kind()))?
    }

    if matches!(parent.kind(), SyntaxKind::STMT_LIST | SyntaxKind::EXPR_STMT) {
        return acc.add(assist_id, assist_label, target, |builder| {
            builder.replace(block.syntax().text_range(), update_expr_string(block.to_string()));
        });
    }

    let parent = ast::Expr::cast(parent)?;

    match parent.clone() {
        ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
        ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)),
        ast::Expr::IfExpr(if_expr) => {
            let then_branch = if_expr.then_branch()?;
            if then_branch == block {
                if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
                    // For `else if` blocks
                    let ancestor_then_branch = ancestor.then_branch()?;

                    return acc.add(assist_id, assist_label, target, |edit| {
                        let range_to_del_else_if = TextRange::new(
                            ancestor_then_branch.syntax().text_range().end(),
                            l_curly_token.text_range().start(),
                        );
                        let range_to_del_rest = TextRange::new(
                            then_branch.syntax().text_range().end(),
                            if_expr.syntax().text_range().end(),
                        );

                        edit.delete(range_to_del_rest);
                        edit.delete(range_to_del_else_if);
                        edit.replace(
                            target,
                            update_expr_string_without_newline(then_branch.to_string()),
                        );
                    });
                }
            } else {
                return acc.add(assist_id, assist_label, target, |edit| {
                    let range_to_del = TextRange::new(
                        then_branch.syntax().text_range().end(),
                        l_curly_token.text_range().start(),
                    );

                    edit.delete(range_to_del);
                    edit.replace(target, update_expr_string_without_newline(block.to_string()));
                });
            }
        }
        _ => return None,
    };

    acc.add(assist_id, assist_label, target, |builder| {
        builder.replace(parent.syntax().text_range(), update_expr_string(block.to_string()));
    })
}

fn update_expr_string(expr_string: String) -> String {
    update_expr_string_with_pat(expr_string, &[' ', '\n'])
}

fn update_expr_string_without_newline(expr_string: String) -> String {
    update_expr_string_with_pat(expr_string, &[' '])
}

fn update_expr_string_with_pat(expr_str: String, whitespace_pat: &[char]) -> String {
    // Remove leading whitespace, index [1..] to remove the leading '{',
    // then continue to remove leading whitespace.
    let expr_str =
        expr_str.trim_start_matches(whitespace_pat)[1..].trim_start_matches(whitespace_pat);

    // Remove trailing whitespace, index [..expr_str.len() - 1] to remove the trailing '}',
    // then continue to remove trailing whitespace.
    let expr_str = expr_str.trim_end_matches(whitespace_pat);
    let expr_str = expr_str[..expr_str.len() - 1].trim_end_matches(whitespace_pat);

    expr_str
        .lines()
        .map(|line| line.replacen("    ", "", 1)) // Delete indentation
        .collect::<Vec<String>>()
        .join("\n")
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    #[test]
    fn unwrap_tail_expr_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92
    }
}
"#,
            r#"
fn main() {
    92
}
"#,
        )
    }

    #[test]
    fn unwrap_stmt_expr_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92;
    }
    ()
}
"#,
            r#"
fn main() {
    92;
    ()
}
"#,
        );
        // Pedantically, we should add an `;` here...
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92
    }
    ()
}
"#,
            r#"
fn main() {
    92
    ()
}
"#,
        );
    }

    #[test]
    fn simple_if() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    bar();
    if true {$0
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
            r#"
fn main() {
    bar();
    foo();

    // comment
    bar();
}
"#,
        );
    }

    #[test]
    fn simple_if_else() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    bar();
    if true {
        foo();

        // comment
        bar();
    } else {$0
        println!("bar");
    }
}
"#,
            r#"
fn main() {
    bar();
    if true {
        foo();

        // comment
        bar();
    }
    println!("bar");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {$0
        println!("bar");
    } else {
        println!("foo");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    }
    println!("bar");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {$0
        println!("foo");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    }
    println!("foo");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested_else() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {
        println!("foo");
    } else {$0
        println!("else");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {
        println!("foo");
    }
    println!("else");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested_middle() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {$0
        println!("foo");
    } else {
        println!("else");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    }
    println!("foo");
}
"#,
        );
    }

    #[test]
    fn simple_if_bad_cursor_position() {
        check_assist_not_applicable(
            unwrap_block,
            r#"
fn main() {
    bar();$0
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_for() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    for i in 0..5 {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_if_in_for() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    for i in 0..5 {
        if true {$0
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    for i in 0..5 {
        foo();

        // comment
        bar();
    }
}
"#,
        );
    }

    #[test]
    fn simple_loop() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    loop {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_while() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    while true {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn unwrap_match_arm() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    match rel_path {
        Ok(rel_path) => {$0
            let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
            Some((*id, rel_path))
        }
        Err(_) => None,
    }
}
"#,
            r#"
fn main() {
    let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
    Some((*id, rel_path))
}
"#,
        );
    }

    #[test]
    fn simple_if_in_while_bad_cursor_position() {
        check_assist_not_applicable(
            unwrap_block,
            r#"
fn main() {
    while true {
        if true {
            foo();$0

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
        );
    }

    #[test]
    fn simple_single_line() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    {$0 0 }
}
"#,
            r#"
fn main() {
    0
}
"#,
        );
    }

    #[test]
    fn simple_nested_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        {
            3
        }
    }
}
"#,
            r#"
fn main() {
    {
        3
    }
}
"#,
        );
    }

    #[test]
    fn nested_single_line() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    {$0 { println!("foo"); } }
}
"#,
            r#"
fn main() {
    { println!("foo"); }
}
"#,
        );

        check_assist(
            unwrap_block,
            r#"
fn main() {
    {$0 { 0 } }
}
"#,
            r#"
fn main() {
    { 0 }
}
"#,
        );
    }

    #[test]
    fn simple_if_single_line() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    if true {$0 /* foo */ foo() } else { bar() /* bar */}
}
"#,
            r#"
fn main() {
    /* foo */ foo()
}
"#,
        );
    }

    #[test]
    fn if_single_statement() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    if true {$0
        return 3;
    }
}
"#,
            r#"
fn main() {
    return 3;
}
"#,
        );
    }

    #[test]
    fn multiple_statements() {
        check_assist(
            unwrap_block,
            r#"
fn main() -> i32 {
    if 2 > 1 {$0
        let a = 5;
        return 3;
    }
    5
}
"#,
            r#"
fn main() -> i32 {
    let a = 5;
    return 3;
    5
}
"#,
        );
    }
}
<|endoftext|>


<commit_before>use std::iter::successors;

use ra_syntax::{
    algo::{neighbor, SyntaxRewriter},
    ast::{self, edit::AstNodeEdit, make},
    AstNode, Direction, InsertPosition, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxToken, Token,
    T,
};

use crate::{Assist, AssistCtx, AssistId};

// Assist: merge_imports
//
// Merges two imports with a common prefix.
//
// ```
// use std::<|>fmt::Formatter;
// use std::io;
// ```
// ->
// ```
// use std::{fmt::Formatter, io};
// ```
pub(crate) fn merge_imports(ctx: AssistCtx) -> Option<Assist> {
    let tree: ast::UseTree = ctx.find_node_at_offset()?;
    let mut rewriter = SyntaxRewriter::default();
    let mut offset = ctx.frange.range.start();

    if let Some(use_item) = tree.syntax().parent().and_then(ast::UseItem::cast) {
        let (merged, to_delete) = next_prev()
            .filter_map(|dir| neighbor(&use_item, dir))
            .filter_map(|it| Some((it.clone(), it.use_tree()?)))
            .find_map(|(use_item, use_tree)| {
                Some((try_merge_trees(&tree, &use_tree)?, use_item.clone()))
            })?;

        rewriter.replace_ast(&tree, &merged);
        rewriter += to_delete.remove();

        if to_delete.syntax().text_range().end() < offset {
            offset -= to_delete.syntax().text_range().len();
        }
    } else {
        let (merged, to_delete) = next_prev()
            .filter_map(|dir| neighbor(&tree, dir))
            .find_map(|use_tree| Some((try_merge_trees(&tree, &use_tree)?, use_tree.clone())))?;

        rewriter.replace_ast(&tree, &merged);
        rewriter += to_delete.remove();

        if to_delete.syntax().text_range().end() < offset {
            offset -= to_delete.syntax().text_range().len();
        }
    };

    ctx.add_assist(AssistId("merge_imports"), "Merge imports", |edit| {
        edit.rewrite(rewriter);
        // FIXME: we only need because our diff is imprecise
        edit.set_cursor(offset);
    })
}

fn next_prev() -> impl Iterator<Item = Direction> {
    [Direction::Next, Direction::Prev].iter().copied()
}

fn try_merge_trees(old: &ast::UseTree, new: &ast::UseTree) -> Option<ast::UseTree> {
    let lhs_path = old.path()?;
    let rhs_path = new.path()?;

    let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?;

    let lhs = old.split_prefix(&lhs_prefix);
    let rhs = new.split_prefix(&rhs_prefix);

    let mut should_insert_comma = true;

    lhs.syntax()
        .last_child()
        .and_then(|child| child.children().last())
        .and_then(|last| last.next_sibling_or_token())
        .map(|next_sibling| {
            // FIXME: there's probably a better way to check if it's a COMMA
            if let NodeOrToken::Token(maybe_comma) = next_sibling {
                should_insert_comma = maybe_comma.to_string() != ",";
            }
        });

    let mut to_insert: Vec<SyntaxElement> = Vec::new();
    if should_insert_comma {
        to_insert.push(make::token(T![,]).into());
        to_insert.push(make::tokens::single_space().into());
    }
    to_insert.extend(
        rhs.use_tree_list()?
            .syntax()
            .children_with_tokens()
            .filter(|it| it.kind() != T!['{'] && it.kind() != T!['}']),
    );
    let use_tree_list = lhs.use_tree_list()?;
    let pos = InsertPosition::Before(use_tree_list.r_curly_token()?.into());
    let use_tree_list = use_tree_list.insert_children(pos, to_insert);
    Some(lhs.with_use_tree_list(use_tree_list))
}

fn common_prefix(lhs: &ast::Path, rhs: &ast::Path) -> Option<(ast::Path, ast::Path)> {
    let mut res = None;
    let mut lhs_curr = first_path(&lhs);
    let mut rhs_curr = first_path(&rhs);
    loop {
        match (lhs_curr.segment(), rhs_curr.segment()) {
            (Some(lhs), Some(rhs)) if lhs.syntax().text() == rhs.syntax().text() => (),
            _ => break,
        }
        res = Some((lhs_curr.clone(), rhs_curr.clone()));

        match (lhs_curr.parent_path(), rhs_curr.parent_path()) {
            (Some(lhs), Some(rhs)) => {
                lhs_curr = lhs;
                rhs_curr = rhs;
            }
            _ => break,
        }
    }

    res
}

fn first_path(path: &ast::Path) -> ast::Path {
    successors(Some(path.clone()), |it| it.qualifier()).last().unwrap()
}

#[cfg(test)]
mod tests {
    use crate::helpers::check_assist;

    use super::*;

    #[test]
    fn test_merge_first() {
        check_assist(
            merge_imports,
            r"
use std::fmt<|>::Debug;
use std::fmt::Display;
",
            r"
use std::fmt<|>::{Debug, Display};
",
        )
    }

    #[test]
    fn test_merge_second() {
        check_assist(
            merge_imports,
            r"
use std::fmt::Debug;
use std::fmt<|>::Display;
",
            r"
use std::fmt:<|>:{Display, Debug};
",
        );
    }

    #[test]
    fn test_merge_nested() {
        check_assist(
            merge_imports,
            r"
use std::{fmt<|>::Debug, fmt::Display};
",
            r"
use std::{fmt<|>::{Debug, Display}};
",
        );
        check_assist(
            merge_imports,
            r"
use std::{fmt::Debug, fmt<|>::Display};
",
            r"
use std::{fmt::<|>{Display, Debug}};
",
        );
    }

    #[test]
    fn test_merge_single_wildcard_diff_prefixes() {
        check_assist(
            merge_imports,
            r"
use std<|>::cell::*;
use std::str;
",
            r"
use std<|>::{cell::*, str};
",
        )
    }

    #[test]
    fn test_merge_both_wildcard_diff_prefixes() {
        check_assist(
            merge_imports,
            r"
use std<|>::cell::*;
use std::str::*;
",
            r"
use std<|>::{cell::*, str::*};
",
        )
    }

    #[test]
    fn removes_just_enough_whitespace() {
        check_assist(
            merge_imports,
            r"
use foo<|>::bar;
use foo::baz;

/// Doc comment
",
            r"
use foo<|>::{bar, baz};

/// Doc comment
",
        );
    }

    #[test]
    fn works_with_trailing_comma() {
        check_assist(
            merge_imports,
            r"
use {
    foo<|>::bar,
    foo::baz,
};
",
            r"
use {
    foo<|>::{bar, baz},
};
",
        );
        check_assist(
            merge_imports,
            r"
use {
    foo::baz,
    foo<|>::bar,
};
",
            r"
use {
    foo::{bar<|>, baz},
};
",
        );
    }

    #[test]
    fn test_double_comma() {
        check_assist(
            merge_imports,
            r"
use hyper::service::make_service_fn;
use hyper::<|>{
    StatusCode,
};
",
            r"
use hyper::{<|>
    StatusCode,
service::make_service_fn};
",
        )
    }
}
<commit_msg>Generalize test and clean up imports<commit_after>use std::iter::successors;

use ra_syntax::{
    algo::{neighbor, SyntaxRewriter},
    ast::{self, edit::AstNodeEdit, make},
    AstNode, Direction, InsertPosition, NodeOrToken, SyntaxElement, T,
};

use crate::{Assist, AssistCtx, AssistId};

// Assist: merge_imports
//
// Merges two imports with a common prefix.
//
// ```
// use std::<|>fmt::Formatter;
// use std::io;
// ```
// ->
// ```
// use std::{fmt::Formatter, io};
// ```
pub(crate) fn merge_imports(ctx: AssistCtx) -> Option<Assist> {
    let tree: ast::UseTree = ctx.find_node_at_offset()?;
    let mut rewriter = SyntaxRewriter::default();
    let mut offset = ctx.frange.range.start();

    if let Some(use_item) = tree.syntax().parent().and_then(ast::UseItem::cast) {
        let (merged, to_delete) = next_prev()
            .filter_map(|dir| neighbor(&use_item, dir))
            .filter_map(|it| Some((it.clone(), it.use_tree()?)))
            .find_map(|(use_item, use_tree)| {
                Some((try_merge_trees(&tree, &use_tree)?, use_item.clone()))
            })?;

        rewriter.replace_ast(&tree, &merged);
        rewriter += to_delete.remove();

        if to_delete.syntax().text_range().end() < offset {
            offset -= to_delete.syntax().text_range().len();
        }
    } else {
        let (merged, to_delete) = next_prev()
            .filter_map(|dir| neighbor(&tree, dir))
            .find_map(|use_tree| Some((try_merge_trees(&tree, &use_tree)?, use_tree.clone())))?;

        rewriter.replace_ast(&tree, &merged);
        rewriter += to_delete.remove();

        if to_delete.syntax().text_range().end() < offset {
            offset -= to_delete.syntax().text_range().len();
        }
    };

    ctx.add_assist(AssistId("merge_imports"), "Merge imports", |edit| {
        edit.rewrite(rewriter);
        // FIXME: we only need because our diff is imprecise
        edit.set_cursor(offset);
    })
}

fn next_prev() -> impl Iterator<Item = Direction> {
    [Direction::Next, Direction::Prev].iter().copied()
}

fn try_merge_trees(old: &ast::UseTree, new: &ast::UseTree) -> Option<ast::UseTree> {
    let lhs_path = old.path()?;
    let rhs_path = new.path()?;

    let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?;

    let lhs = old.split_prefix(&lhs_prefix);
    let rhs = new.split_prefix(&rhs_prefix);

    let mut should_insert_comma = true;

    lhs.syntax()
        .last_child()
        .and_then(|child| child.children().last())
        .and_then(|last| last.next_sibling_or_token())
        .map(|next_sibling| {
            // FIXME: there's probably a better way to check if it's a COMMA
            if let NodeOrToken::Token(maybe_comma) = next_sibling {
                should_insert_comma = maybe_comma.to_string() != ",";
            }
        });

    let mut to_insert: Vec<SyntaxElement> = Vec::new();
    if should_insert_comma {
        to_insert.push(make::token(T![,]).into());
        to_insert.push(make::tokens::single_space().into());
    }
    to_insert.extend(
        rhs.use_tree_list()?
            .syntax()
            .children_with_tokens()
            .filter(|it| it.kind() != T!['{'] && it.kind() != T!['}']),
    );
    let use_tree_list = lhs.use_tree_list()?;
    let pos = InsertPosition::Before(use_tree_list.r_curly_token()?.into());
    let use_tree_list = use_tree_list.insert_children(pos, to_insert);
    Some(lhs.with_use_tree_list(use_tree_list))
}

fn common_prefix(lhs: &ast::Path, rhs: &ast::Path) -> Option<(ast::Path, ast::Path)> {
    let mut res = None;
    let mut lhs_curr = first_path(&lhs);
    let mut rhs_curr = first_path(&rhs);
    loop {
        match (lhs_curr.segment(), rhs_curr.segment()) {
            (Some(lhs), Some(rhs)) if lhs.syntax().text() == rhs.syntax().text() => (),
            _ => break,
        }
        res = Some((lhs_curr.clone(), rhs_curr.clone()));

        match (lhs_curr.parent_path(), rhs_curr.parent_path()) {
            (Some(lhs), Some(rhs)) => {
                lhs_curr = lhs;
                rhs_curr = rhs;
            }
            _ => break,
        }
    }

    res
}

fn first_path(path: &ast::Path) -> ast::Path {
    successors(Some(path.clone()), |it| it.qualifier()).last().unwrap()
}

#[cfg(test)]
mod tests {
    use crate::helpers::check_assist;

    use super::*;

    #[test]
    fn test_merge_first() {
        check_assist(
            merge_imports,
            r"
use std::fmt<|>::Debug;
use std::fmt::Display;
",
            r"
use std::fmt<|>::{Debug, Display};
",
        )
    }

    #[test]
    fn test_merge_second() {
        check_assist(
            merge_imports,
            r"
use std::fmt::Debug;
use std::fmt<|>::Display;
",
            r"
use std::fmt:<|>:{Display, Debug};
",
        );
    }

    #[test]
    fn test_merge_nested() {
        check_assist(
            merge_imports,
            r"
use std::{fmt<|>::Debug, fmt::Display};
",
            r"
use std::{fmt<|>::{Debug, Display}};
",
        );
        check_assist(
            merge_imports,
            r"
use std::{fmt::Debug, fmt<|>::Display};
",
            r"
use std::{fmt::<|>{Display, Debug}};
",
        );
    }

    #[test]
    fn test_merge_single_wildcard_diff_prefixes() {
        check_assist(
            merge_imports,
            r"
use std<|>::cell::*;
use std::str;
",
            r"
use std<|>::{cell::*, str};
",
        )
    }

    #[test]
    fn test_merge_both_wildcard_diff_prefixes() {
        check_assist(
            merge_imports,
            r"
use std<|>::cell::*;
use std::str::*;
",
            r"
use std<|>::{cell::*, str::*};
",
        )
    }

    #[test]
    fn removes_just_enough_whitespace() {
        check_assist(
            merge_imports,
            r"
use foo<|>::bar;
use foo::baz;

/// Doc comment
",
            r"
use foo<|>::{bar, baz};

/// Doc comment
",
        );
    }

    #[test]
    fn works_with_trailing_comma() {
        check_assist(
            merge_imports,
            r"
use {
    foo<|>::bar,
    foo::baz,
};
",
            r"
use {
    foo<|>::{bar, baz},
};
",
        );
        check_assist(
            merge_imports,
            r"
use {
    foo::baz,
    foo<|>::bar,
};
",
            r"
use {
    foo::{bar<|>, baz},
};
",
        );
    }

    #[test]
    fn test_double_comma() {
        check_assist(
            merge_imports,
            r"
use foo::bar::baz;
use foo::<|>{
    FooBar,
};
",
            r"
use foo::{<|>
    FooBar,
bar::baz};
",
        )
    }
}
<|endoftext|>


<commit_before>// vim: tw=80
use super::*;
use quote::ToTokens;
use syn::parse::{Parse, ParseStream};

fn find_ident_from_path(path: &Path) -> (Ident, PathArguments) {
        if path.segments.len() != 1 {
            compile_error(path.span(),
                "mockall_derive only supports structs defined in the current module");
            return (Ident::new("", path.span()), PathArguments::None);
        }
        let last_seg = path.segments.last().unwrap();
        (last_seg.ident.clone(), last_seg.arguments.clone())
}

/// Performs transformations on the method to make it mockable
fn mockable_method(mut meth: ImplItemMethod) -> ImplItemMethod {
    demutify(&mut meth.sig.inputs);
    deimplify(&mut meth.sig.output);
    meth
}

/// Performs transformations on the trait to make it mockable
fn mockable_trait(mut trait_: ItemTrait) -> ItemTrait {
    for item in trait_.items.iter_mut() {
        if let TraitItem::Method(tim) = item {
            demutify(&mut tim.sig.inputs);
            deimplify(&mut tim.sig.output);
        }
    }
    trait_
}

/// Converts a TraitItemMethod into an ImplItemMethod
fn tim2iim(m: syn::TraitItemMethod, vis: &syn::Visibility)
    -> syn::ImplItemMethod
{
    let empty_block = Block {
        brace_token: token::Brace::default(),
        stmts: Vec::new()
    };
    syn::ImplItemMethod{
        attrs: m.attrs,
        vis: vis.clone(),
        defaultness: None,
        sig: m.sig,
        block: empty_block
    }
}

pub(crate) struct MockableStruct {
    pub attrs: Vec<Attribute>,
    pub generics: Generics,
    /// Inherent methods of the mockable struct
    pub methods: Vec<ImplItemMethod>,
    pub name: Ident,
    /// Name of the original struct.
    pub original_name: Ident,
    pub vis: Visibility,
    pub traits: Vec<ItemTrait>
}

impl From<(Attrs, ItemTrait)> for MockableStruct {
    fn from((attrs, item_trait): (Attrs, ItemTrait)) -> MockableStruct {
        let trait_ = attrs.substitute_trait(&item_trait);
        MockableStruct {
            attrs: trait_.attrs.clone(),
            vis: trait_.vis.clone(),
            name: gen_mock_ident(&trait_.ident),
            generics: trait_.generics.clone(),
            methods: Vec::new(),
            original_name: trait_.ident.clone(),
            traits: vec![mockable_trait(trait_)]
        }
    }
}

impl From<ItemImpl> for MockableStruct {
    fn from(item_impl: ItemImpl) -> MockableStruct {
        let (name, original_name) = match *item_impl.self_ty {
            Type::Path(type_path) => {
                let n = find_ident_from_path(&type_path.path).0;
                (gen_mock_ident(&n), n)
            },
            x => {
                compile_error(x.span(),
                    "mockall_derive only supports mocking traits and structs");
                (Ident::new("", Span::call_site()),
                 Ident::new("", Span::call_site()))
            }
        };
        let mut methods = Vec::new();
        for item in item_impl.items.into_iter() {
            if let ImplItem::Method(meth) = item {
                methods.push(mockable_method(meth));
            }
        }
        let pub_token = Token![pub](Span::call_site());
        let vis = Visibility::Public(VisPublic{pub_token});
        MockableStruct {
            attrs: item_impl.attrs.clone(),
            vis,
            name,
            generics: item_impl.generics,
            methods,
            original_name,
            traits: Vec::new()
        }
    }
}

impl Parse for MockableStruct {
    fn parse(input: ParseStream) -> syn::parse::Result<Self> {
        let attrs = input.call(syn::Attribute::parse_outer)?;
        let vis: syn::Visibility = input.parse()?;
        let original_name: syn::Ident = input.parse()?;
        let mut generics: syn::Generics = input.parse()?;
        let wc: Option<syn::WhereClause> = input.parse()?;
        generics.where_clause = wc;

        let impl_content;
        let _brace_token = braced!(impl_content in input);
        let mut methods = Vec::new();
        while !impl_content.is_empty() {
            let method: syn::TraitItem = impl_content.parse()?;
            match method {
                syn::TraitItem::Method(meth) => {
                    methods.push(tim2iim(meth, &vis))
                },
                _ => {
                    return Err(input.error("Unsupported in this context"));
                }
            }
        }

        let mut traits = Vec::new();
        while !input.is_empty() {
            let trait_: syn::ItemTrait = input.parse()?;
            traits.push(mockable_trait(trait_));
        }

        Ok(
            MockableStruct {
                attrs: attrs,
                vis,
                name: gen_mock_ident(&original_name),
                generics,
                methods,
                original_name,
                traits
            }
        )
    }
}
<commit_msg>deselfify constructor methods<commit_after>// vim: tw=80
use super::*;
use quote::ToTokens;
use syn::parse::{Parse, ParseStream};

fn find_ident_from_path(path: &Path) -> (Ident, PathArguments) {
        if path.segments.len() != 1 {
            compile_error(path.span(),
                "mockall_derive only supports structs defined in the current module");
            return (Ident::new("", path.span()), PathArguments::None);
        }
        let last_seg = path.segments.last().unwrap();
        (last_seg.ident.clone(), last_seg.arguments.clone())
}

/// Performs transformations on the method to make it mockable
fn mockable_method(mut meth: ImplItemMethod, name: &Ident, generics: &Generics)
    -> ImplItemMethod
{
    demutify(&mut meth.sig.inputs);
    deimplify(&mut meth.sig.output);
    if let ReturnType::Type(_, ty) = &mut meth.sig.output {
        deselfify(ty, name, generics);
    }
    meth
}

/// Performs transformations on the method to make it mockable
fn mockable_trait_method(
    meth: &mut TraitItemMethod,
    name: &Ident,
    generics: &Generics)
{
    demutify(&mut meth.sig.inputs);
    deimplify(&mut meth.sig.output);
    if let ReturnType::Type(_, ty) = &mut meth.sig.output {
        deselfify(ty, name, generics);
    }
}

/// Performs transformations on the trait to make it mockable
fn mockable_trait(mut trait_: ItemTrait, name: &Ident, generics: &Generics)
    -> ItemTrait
{
    for item in trait_.items.iter_mut() {
        if let TraitItem::Method(tim) = item {
            mockable_trait_method(tim, name, generics);
        }
    }
    trait_
}

/// Converts a TraitItemMethod into an ImplItemMethod
fn tim2iim(m: syn::TraitItemMethod, vis: &syn::Visibility)
    -> syn::ImplItemMethod
{
    let empty_block = Block {
        brace_token: token::Brace::default(),
        stmts: Vec::new()
    };
    syn::ImplItemMethod{
        attrs: m.attrs,
        vis: vis.clone(),
        defaultness: None,
        sig: m.sig,
        block: empty_block
    }
}

pub(crate) struct MockableStruct {
    pub attrs: Vec<Attribute>,
    pub generics: Generics,
    /// Inherent methods of the mockable struct
    pub methods: Vec<ImplItemMethod>,
    pub name: Ident,
    /// Name of the original struct.
    pub original_name: Ident,
    pub vis: Visibility,
    pub traits: Vec<ItemTrait>
}

impl From<(Attrs, ItemTrait)> for MockableStruct {
    fn from((attrs, item_trait): (Attrs, ItemTrait)) -> MockableStruct {
        let trait_ = attrs.substitute_trait(&item_trait);
        let attrs = trait_.attrs.clone();
        let vis = trait_.vis.clone();
        let name = gen_mock_ident(&trait_.ident);
        let generics = trait_.generics.clone();
        let original_name = trait_.ident.clone();
        let traits = vec![mockable_trait(trait_, &name, &generics)];
        MockableStruct {
            attrs,
            vis,
            name,
            generics,
            methods: Vec::new(),
            original_name,
            traits
        }
    }
}

impl From<ItemImpl> for MockableStruct {
    fn from(item_impl: ItemImpl) -> MockableStruct {
        let (name, original_name) = match *item_impl.self_ty {
            Type::Path(type_path) => {
                let n = find_ident_from_path(&type_path.path).0;
                (gen_mock_ident(&n), n)
            },
            x => {
                compile_error(x.span(),
                    "mockall_derive only supports mocking traits and structs");
                (Ident::new("", Span::call_site()),
                 Ident::new("", Span::call_site()))
            }
        };
        let mut methods = Vec::new();
        for item in item_impl.items.into_iter() {
            if let ImplItem::Method(meth) = item {
                methods.push(mockable_method(meth, &name, &item_impl.generics));
            }
        }
        let pub_token = Token![pub](Span::call_site());
        let vis = Visibility::Public(VisPublic{pub_token});
        MockableStruct {
            attrs: item_impl.attrs.clone(),
            vis,
            name,
            generics: item_impl.generics,
            methods,
            original_name,
            traits: Vec::new()
        }
    }
}

impl Parse for MockableStruct {
    fn parse(input: ParseStream) -> syn::parse::Result<Self> {
        let attrs = input.call(syn::Attribute::parse_outer)?;
        let vis: syn::Visibility = input.parse()?;
        let original_name: syn::Ident = input.parse()?;
        let mut generics: syn::Generics = input.parse()?;
        let wc: Option<syn::WhereClause> = input.parse()?;
        generics.where_clause = wc;
        let name = gen_mock_ident(&original_name);

        let impl_content;
        let _brace_token = braced!(impl_content in input);
        let mut methods = Vec::new();
        while !impl_content.is_empty() {
            let method: syn::TraitItem = impl_content.parse()?;
            match method {
                syn::TraitItem::Method(mut meth) => {
                    mockable_trait_method(&mut meth, &name, &generics);
                    methods.push(tim2iim(meth, &vis))
                },
                _ => {
                    return Err(input.error("Unsupported in this context"));
                }
            }
        }

        let mut traits = Vec::new();
        while !input.is_empty() {
            let trait_: syn::ItemTrait = input.parse()?;
            traits.push(mockable_trait(trait_, &name, &generics));
        }

        Ok(
            MockableStruct {
                attrs: attrs,
                vis,
                name,
                generics,
                methods,
                original_name,
                traits
            }
        )
    }
}
<|endoftext|>


<commit_before>use std::fmt::{self, Debug, Formatter};
use std::path::Path;

use conrod::{self, Labelable, Positionable, Sizeable, Widget};
use piston;
use piston::window::Window;
use piston_window::{self, Context, G2d, G2dTexture};
use piston_window::texture::UpdateTexture;

use ::{GameState, Resources, StateTransition};

widget_ids!(struct GameWidgetIds { canvas, resume, quit });

pub struct PauseMenu {
    ui: conrod::Ui,
    widget_ids: GameWidgetIds,
    image_map: conrod::image::Map<G2dTexture>,
    glyph_cache: conrod::text::GlyphCache,
    text_texture_cache: G2dTexture,
    text_vertex_data: Vec<u8>,
}

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

impl PauseMenu {
    pub fn new(resources: &mut Resources) -> PauseMenu {
        let window_size = resources.window.size();

        // Construct our `Ui`.
        let mut ui = conrod::UiBuilder::new([window_size.width as f64,
                                             window_size.height as f64])
            .build();

        // Generate the widget identifiers.
        let ids = GameWidgetIds::new(ui.widget_id_generator());

        // Add a `Font` to the `Ui`'s `font::Map` from file.
        let font_path = Path::new("assets/NotoSans-Regular.ttf");
        assert!(font_path.exists());
        ui.fonts.insert_from_file(font_path).unwrap();

        // Create a texture to use for efficiently caching text on the GPU.
        let (glyph_cache, text_texture_cache) = {
            let cache =
                conrod::text::GlyphCache::new(window_size.width,
                                              window_size.height,
                                              0.1, 0.1);
            let buffer_len = window_size.width as usize * window_size.height as usize;
            let init = vec![128; buffer_len];
            let settings = piston_window::TextureSettings::new();
            let factory = &mut resources.window.factory;
            let texture = G2dTexture::from_memory_alpha(
                factory, &init, window_size.width, window_size.height, &settings).unwrap();
            (cache, texture)
        };

        // The image map describing each of our widget->image mappings (in our case, none).
        let image_map = conrod::image::Map::new();

        PauseMenu {
            ui: ui,
            widget_ids: ids,
            image_map: image_map,
            glyph_cache: glyph_cache,
            text_texture_cache: text_texture_cache,
            text_vertex_data: Vec::new(),
        }
    }
}

impl GameState for PauseMenu {
    fn handle_event(&mut self, event: &piston::input::Event,
                    resources: &mut Resources) -> StateTransition
    {
        // Convert the piston event to a conrod event.
        let window_size = resources.window.size();
        if let Some(ce) = conrod::backend::piston::event::convert(
            event.clone(), window_size.width as f64, window_size.height as f64)
        {
            self.ui.handle_event(ce);
        }

        let ui = &mut self.ui.set_widgets();

        // Create a background canvas upon which we'll place the button.
        conrod::widget::Canvas::new().floating(true).w_h(100.0, 70.0).pad(10.0).middle()
            .set(self.widget_ids.canvas, ui);

        // Draw the buttons.
        if conrod::widget::Button::new()
            .mid_top_of(self.widget_ids.canvas)
            .w_h(80.0, 20.0)
            .label("Resume")
            .set(self.widget_ids.resume, ui)
            .was_clicked()
        {
            StateTransition::End
        } else if conrod::widget::Button::new()
            .down(10.0)
            .w_h(80.0, 20.0)
            .label("Quit")
            .set(self.widget_ids.quit, ui)
            .was_clicked()
        {
            StateTransition::Quit
        } else {
            StateTransition::Continue
        }
    }

    fn update(&mut self, dt: f64, resources: &mut Resources) -> StateTransition {
        StateTransition::Continue
    }

    fn draw(&mut self, c: Context, g: &mut G2d) {
        let primitives = self.ui.draw();

        let text_vertex_data = &mut self.text_vertex_data;
        let cache_queued_glyphs = |graphics: &mut G2d,
                                   cache: &mut G2dTexture,
                                   rect: conrod::text::rt::Rect<u32>,
                                   data: &[u8]|
        {
            let offset = [rect.min.x, rect.min.y];
            let size = [rect.width(), rect.height()];
            let format = piston_window::texture::Format::Rgba8;
            let encoder = &mut graphics.encoder;
            text_vertex_data.clear();
            text_vertex_data.extend(
                data.iter().flat_map(|&b| vec![255, 255, 255, b]));
            UpdateTexture::update(cache, encoder, format,
                                  &text_vertex_data[..], offset, size)
                .expect("failed to update texture")
        };

        fn texture_from_image<T>(img: &T) -> &T { img };

        conrod::backend::piston::draw::primitives(primitives, c, g,
                                                  &mut self.text_texture_cache,
                                                  &mut self.glyph_cache,
                                                  &self.image_map,
                                                  cache_queued_glyphs,
                                                  texture_from_image);
    }
}
<commit_msg>Make buttons bigger<commit_after>use std::fmt::{self, Debug, Formatter};
use std::path::Path;

use conrod::{self, Labelable, Positionable, Sizeable, Widget};
use piston;
use piston::window::Window;
use piston_window::{self, Context, G2d, G2dTexture};
use piston_window::texture::UpdateTexture;

use ::{GameState, Resources, StateTransition};

widget_ids!(struct GameWidgetIds { canvas, resume, quit });

pub struct PauseMenu {
    ui: conrod::Ui,
    widget_ids: GameWidgetIds,
    image_map: conrod::image::Map<G2dTexture>,
    glyph_cache: conrod::text::GlyphCache,
    text_texture_cache: G2dTexture,
    text_vertex_data: Vec<u8>,
}

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

impl PauseMenu {
    pub fn new(resources: &mut Resources) -> PauseMenu {
        let window_size = resources.window.size();

        // Construct our `Ui`.
        let mut ui = conrod::UiBuilder::new([window_size.width as f64,
                                             window_size.height as f64])
            .build();

        // Generate the widget identifiers.
        let ids = GameWidgetIds::new(ui.widget_id_generator());

        // Add a `Font` to the `Ui`'s `font::Map` from file.
        let font_path = Path::new("assets/NotoSans-Regular.ttf");
        assert!(font_path.exists());
        ui.fonts.insert_from_file(font_path).unwrap();

        // Create a texture to use for efficiently caching text on the GPU.
        let (glyph_cache, text_texture_cache) = {
            let cache =
                conrod::text::GlyphCache::new(window_size.width,
                                              window_size.height,
                                              0.1, 0.1);
            let buffer_len = window_size.width as usize * window_size.height as usize;
            let init = vec![128; buffer_len];
            let settings = piston_window::TextureSettings::new();
            let factory = &mut resources.window.factory;
            let texture = G2dTexture::from_memory_alpha(
                factory, &init, window_size.width, window_size.height, &settings).unwrap();
            (cache, texture)
        };

        // The image map describing each of our widget->image mappings (in our case, none).
        let image_map = conrod::image::Map::new();

        PauseMenu {
            ui: ui,
            widget_ids: ids,
            image_map: image_map,
            glyph_cache: glyph_cache,
            text_texture_cache: text_texture_cache,
            text_vertex_data: Vec::new(),
        }
    }
}

impl GameState for PauseMenu {
    fn handle_event(&mut self, event: &piston::input::Event,
                    resources: &mut Resources) -> StateTransition
    {
        // Convert the piston event to a conrod event.
        let window_size = resources.window.size();
        if let Some(ce) = conrod::backend::piston::event::convert(
            event.clone(), window_size.width as f64, window_size.height as f64)
        {
            self.ui.handle_event(ce);
        }

        let ui = &mut self.ui.set_widgets();

        // Create a background canvas upon which we'll place the button.
        conrod::widget::Canvas::new().floating(true).w_h(100.0, 85.0).pad(10.0).middle()
            .set(self.widget_ids.canvas, ui);

        // Draw the buttons.
        if conrod::widget::Button::new()
            .mid_top_of(self.widget_ids.canvas)
            .w_h(80.0, 25.0)
            .label("Resume")
            .set(self.widget_ids.resume, ui)
            .was_clicked()
        {
            StateTransition::End
        } else if conrod::widget::Button::new()
            .down(15.0)
            .w_h(80.0, 25.0)
            .label("Quit")
            .set(self.widget_ids.quit, ui)
            .was_clicked()
        {
            StateTransition::Quit
        } else {
            StateTransition::Continue
        }
    }

    fn update(&mut self, dt: f64, resources: &mut Resources) -> StateTransition {
        StateTransition::Continue
    }

    fn draw(&mut self, c: Context, g: &mut G2d) {
        let primitives = self.ui.draw();

        let text_vertex_data = &mut self.text_vertex_data;
        let cache_queued_glyphs = |graphics: &mut G2d,
                                   cache: &mut G2dTexture,
                                   rect: conrod::text::rt::Rect<u32>,
                                   data: &[u8]|
        {
            let offset = [rect.min.x, rect.min.y];
            let size = [rect.width(), rect.height()];
            let format = piston_window::texture::Format::Rgba8;
            let encoder = &mut graphics.encoder;
            text_vertex_data.clear();
            text_vertex_data.extend(
                data.iter().flat_map(|&b| vec![255, 255, 255, b]));
            UpdateTexture::update(cache, encoder, format,
                                  &text_vertex_data[..], offset, size)
                .expect("failed to update texture")
        };

        fn texture_from_image<T>(img: &T) -> &T { img };

        conrod::backend::piston::draw::primitives(primitives, c, g,
                                                  &mut self.text_texture_cache,
                                                  &mut self.glyph_cache,
                                                  &self.image_map,
                                                  cache_queued_glyphs,
                                                  texture_from_image);
    }
}
<|endoftext|>


<commit_before>use chan;
use chan::Sender;
use rustc_serialize::json;
use std::char;
use std::io::{Read, Write};
use std::net::Shutdown;
use std::sync::{Arc, Mutex};
use std::{fs, mem, thread};

use datatype::{Command, Error, Event};
use super::{Gateway, Interpret};
use unix_socket::{UnixListener, UnixStream};

/// The `Socket` gateway is used for communication via Unix Domain Sockets.
pub struct Socket {
    pub path: String
}

impl Gateway for Socket {
    fn initialize(&mut self, itx: Sender<Interpret>) -> Result<(), String> {
        let itx = Arc::new(Mutex::new(itx));
        let _   = fs::remove_file(&self.path);

        let server = match UnixListener::bind(self.path.clone()) {
            Ok(server) => server,
            Err(err)   => return Err(format!("couldn't start socket gateway: {}", err))
        };

        thread::spawn(move || {
            for input in server.incoming() {
                if let Err(err) = input {
                    error!("couldn't read socket input: {}", err);
                    continue
                }
                let mut stream = input.unwrap();
                let itx = itx.clone();

                thread::spawn(move || {
                    let resp = handle_client(&mut stream, itx)
                        .map(|ev| json::encode(&ev).expect("couldn't encode Event").into_bytes())
                        .unwrap_or_else(|err| format!("{}", err).into_bytes());

                    stream.write_all(&resp)
                        .unwrap_or_else(|err| error!("couldn't write to socket: {}", err));
                    stream.shutdown(Shutdown::Write)
                        .unwrap_or_else(|err| error!("couldn't close socket for writing: {}", err))
                });
            }
        });

        Ok(info!("Unix Domain Socket gateway listening at {}.", self.path))
    }
}

fn handle_client(stream: &mut UnixStream, itx: Arc<Mutex<Sender<Interpret>>>) -> Result<Event, Error> {
    info!("New domain socket connection");

    let mut input = String::new();
    let mut buf: [u8;4] = [0,0,0,0];
    let mut n = 0;

    for byte in stream.bytes() {
        buf[n]  = try!(byte);
        let chr = unsafe { mem::transmute::<[u8; 4], u32>(buf) };
        if let Some(c) = char::from_u32(chr) {
            input.push(c);
            buf = [0,0,0,0];
            n   = 0;
        } else {
            n += 1;
        }
    }

    debug!("socket input: {}", input);
    let cmd = try!(input.parse::<Command>());
    let (etx, erx) = chan::async::<Event>();
    itx.lock().unwrap().send(Interpret {
        command:     cmd,
        response_tx: Some(Arc::new(Mutex::new(etx))),
    });
    erx.recv().ok_or(Error::Socket("internal receiver error".to_string()))
}

#[cfg(test)]
mod tests {
    use chan;
    use crossbeam;
    use rustc_serialize::json;
    use std::thread;
    use std::io::{Read, Write};
    use std::net::Shutdown;
    use std::time::Duration;

    use datatype::{Command, Event};
    use gateway::{Gateway, Interpret};
    use super::*;
    use unix_socket::UnixStream;

    #[test]
    fn unix_domain_socket_connections() {
        let (etx, erx) = chan::sync::<Event>(0);
        let (itx, irx) = chan::sync::<Interpret>(0);

        thread::spawn(move || Socket { path: "/tmp/sota.socket".to_string() }.start(itx, erx));
        thread::sleep(Duration::from_millis(100)); // wait until socket is created

        thread::spawn(move || {
            let _ = etx; // move into this scope
            loop {
                let interpret = irx.recv().expect("gtx is closed");
                match interpret.command {
                    Command::AcceptUpdates(ids) => {
                        let tx = interpret.response_tx.unwrap();
                        tx.lock().unwrap().send(Event::Error(ids.first().unwrap().to_owned()));
                    }
                    _ => panic!("expected AcceptUpdates"),
                }
            }
        });

        crossbeam::scope(|scope| {
            for id in 0..10 {
                scope.spawn(move || {
                    let mut stream = UnixStream::connect("/tmp/sota.socket").expect("couldn't connect to socket");
                    let _ = stream.write_all(&format!("acc {}", id).into_bytes()).expect("couldn't write to stream");
                    stream.shutdown(Shutdown::Write).expect("couldn't shut down writing");

                    let mut resp = String::new();
                    stream.read_to_string(&mut resp).expect("couldn't read from stream");
                    let ev: Event = json::decode(&resp).expect("couldn't decode json event");
                    assert_eq!(ev, Event::Error(format!("{}", id)));
                });
            }
        });
    }
}
<commit_msg>Use BufReader for reading string input<commit_after>use chan;
use chan::Sender;
use rustc_serialize::json;
use std::io::{BufReader, Read, Write};
use std::net::Shutdown;
use std::sync::{Arc, Mutex};
use std::{fs, thread};

use datatype::{Command, Error, Event};
use super::{Gateway, Interpret};
use unix_socket::{UnixListener, UnixStream};

/// The `Socket` gateway is used for communication via Unix Domain Sockets.
pub struct Socket {
    pub path: String
}

impl Gateway for Socket {
    fn initialize(&mut self, itx: Sender<Interpret>) -> Result<(), String> {
        let itx = Arc::new(Mutex::new(itx));
        let _   = fs::remove_file(&self.path);

        let server = match UnixListener::bind(self.path.clone()) {
            Ok(server) => server,
            Err(err)   => return Err(format!("couldn't start socket gateway: {}", err))
        };

        thread::spawn(move || {
            for input in server.incoming() {
                if let Err(err) = input {
                    error!("couldn't read socket input: {}", err);
                    continue
                }
                let mut stream = input.unwrap();
                let itx = itx.clone();

                thread::spawn(move || {
                    let resp = handle_client(&mut stream, itx)
                        .map(|ev| json::encode(&ev).expect("couldn't encode Event").into_bytes())
                        .unwrap_or_else(|err| format!("{}", err).into_bytes());

                    stream.write_all(&resp)
                        .unwrap_or_else(|err| error!("couldn't write to socket: {}", err));
                    stream.shutdown(Shutdown::Write)
                        .unwrap_or_else(|err| error!("couldn't close socket for writing: {}", err))
                });
            }
        });

        Ok(info!("Unix Domain Socket gateway listening at {}.", self.path))
    }
}

fn handle_client(stream: &mut UnixStream, itx: Arc<Mutex<Sender<Interpret>>>) -> Result<Event, Error> {
    info!("New domain socket connection");
    let mut reader = BufReader::new(stream);
    let mut input  = String::new();
    try!(reader.read_to_string(&mut input));
    debug!("socket input: {}", input);

    let cmd = try!(input.parse::<Command>());
    let (etx, erx) = chan::async::<Event>();
    itx.lock().unwrap().send(Interpret {
        command:     cmd,
        response_tx: Some(Arc::new(Mutex::new(etx))),
    });
    erx.recv().ok_or(Error::Socket("internal receiver error".to_string()))
}

#[cfg(test)]
mod tests {
    use chan;
    use crossbeam;
    use rustc_serialize::json;
    use std::thread;
    use std::io::{Read, Write};
    use std::net::Shutdown;
    use std::time::Duration;

    use datatype::{Command, Event};
    use gateway::{Gateway, Interpret};
    use super::*;
    use unix_socket::UnixStream;

    #[test]
    fn unix_domain_socket_connections() {
        let (etx, erx) = chan::sync::<Event>(0);
        let (itx, irx) = chan::sync::<Interpret>(0);

        thread::spawn(move || Socket { path: "/tmp/sota.socket".to_string() }.start(itx, erx));
        thread::sleep(Duration::from_millis(100)); // wait until socket is created

        thread::spawn(move || {
            let _ = etx; // move into this scope
            loop {
                let interpret = irx.recv().expect("gtx is closed");
                match interpret.command {
                    Command::AcceptUpdates(ids) => {
                        let tx = interpret.response_tx.unwrap();
                        tx.lock().unwrap().send(Event::Error(ids.first().unwrap().to_owned()));
                    }
                    _ => panic!("expected AcceptUpdates"),
                }
            }
        });

        crossbeam::scope(|scope| {
            for id in 0..10 {
                scope.spawn(move || {
                    let mut stream = UnixStream::connect("/tmp/sota.socket").expect("couldn't connect to socket");
                    let _ = stream.write_all(&format!("acc {}", id).into_bytes()).expect("couldn't write to stream");
                    stream.shutdown(Shutdown::Write).expect("couldn't shut down writing");

                    let mut resp = String::new();
                    stream.read_to_string(&mut resp).expect("couldn't read from stream");
                    let ev: Event = json::decode(&resp).expect("couldn't decode json event");
                    assert_eq!(ev, Event::Error(format!("{}", id)));
                });
            }
        });
    }
}
<|endoftext|>


<commit_before>// Interact with the OS.
// Based on the code generators in chris-morgan's rust-http

use std::io::{File, Open, Truncate, Read, Write};
use std::os;

mod mimegen;

fn main() {
    let args = os::args();
    match args.len() {
        3 => {
            let mime_list = Path::new(args.get(1).as_slice());
            let mime_mod = Path::new(args.get(2).as_slice());

            // Generate mimes
            ::mimegen::generate(mime_list, mime_mod).unwrap()
        },
        0 => {
            println!("usage: mimegen <input: mime list>.txt <output: mime module>.rs");
            os::set_exit_status(1);
        },
        _ => {
            println!("usage: {} <input: mime list>.txt <output: mime module>.rs", args.get(0));
            os::set_exit_status(1);
        }
    }
}

pub fn get_reader(path: Path) -> Box<Reader> {
  match File::open_mode(&path, Open, Read) {
    Ok(reader) => box reader as Box<Reader>,
    Err(e) => fail!("Unable to read file: {}", e.desc)
  }
}

pub fn get_writer(path: Path) -> Box<Writer> {
    match File::open_mode(&path, Truncate, Write) {
        Ok(writer) => box writer as Box<Writer>,
        Err(e) => fail!("Unable to write file: {}", e.desc)
    }
}
<commit_msg>(fix) Fix file reader/writer.<commit_after>// Interact with the OS.
// Based on the code generators in chris-morgan's rust-http

use std::io::{File, Open, Truncate, Read, Write};
use std::os;

mod mimegen;

fn main() {
    let args = os::args();
    match args.len() {
        3 => {
            let mime_list = Path::new(args.get(1).as_slice());
            let mime_mod = Path::new(args.get(2).as_slice());

            // Generate mimes
            ::mimegen::generate(mime_list, mime_mod).unwrap()
        },
        0 => {
            println!("usage: mimegen <input: mime list>.txt <output: mime module>.rs");
            os::set_exit_status(1);
        },
        _ => {
            println!("usage: {} <input: mime list>.txt <output: mime module>.rs", args.get(0));
            os::set_exit_status(1);
        }
    }
}

// Writing to this file will cause a run-time error,
// but coercing it to a Box<Reader> prevents getting
// an iterator to it, so it is left as is.
pub fn get_file_reader(path: Path) -> File {
  match File::open_mode(&path, Open, Read) {
    Ok(reader) => reader,
    Err(e) => fail!("Unable to read file: {}", e.desc)
  }
}

pub fn get_file_writer(path: Path) -> Box<Writer> {
    match File::open_mode(&path, Truncate, Write) {
        Ok(writer) => box writer as Box<Writer>,
        Err(e) => fail!("Unable to write file: {}", e.desc)
    }
}
<|endoftext|>


<commit_before>extern crate bls;
extern crate boolean_bitfield;
extern crate ethereum_types;
extern crate ssz;

pub mod test_utils;

pub mod active_state;
pub mod attestation_data;
pub mod attestation;
pub mod beacon_block;
pub mod beacon_block_body;
pub mod beacon_state;
pub mod candidate_pow_receipt_root_record;
pub mod casper_slashing;
pub mod chain_config;
pub mod crosslink_record;
pub mod crystallized_state;
pub mod deposit;
pub mod deposit_data;
pub mod deposit_input;
<<<<<<< HEAD
=======
pub mod exit;
>>>>>>> master
pub mod fork_data;
pub mod pending_attestation_record;
pub mod proposal_signed_data;
pub mod proposer_slashing;
pub mod shard_and_committee;
pub mod shard_reassignment_record;
pub mod special_record;
pub mod slashable_vote_data;
pub mod validator_record;

use self::ethereum_types::{H160, H256, U256};
use std::collections::HashMap;

pub use crate::active_state::ActiveState;
pub use crate::attestation_data::AttestationData;
pub use crate::attestation::Attestation;
pub use crate::beacon_block::BeaconBlock;
pub use crate::beacon_block_body::BeaconBlockBody;
pub use crate::beacon_state::BeaconState;
pub use crate::casper_slashing::CasperSlashing;
pub use crate::chain_config::ChainConfig;
pub use crate::crosslink_record::CrosslinkRecord;
pub use crate::crystallized_state::CrystallizedState;
pub use crate::deposit::Deposit;
pub use crate::deposit_data::DepositData;
pub use crate::deposit_input::DepositInput;
<<<<<<< HEAD
=======
pub use crate::exit::Exit;
>>>>>>> master
pub use crate::fork_data::ForkData;
pub use crate::pending_attestation_record::PendingAttestationRecord;
pub use crate::proposal_signed_data::ProposalSignedData;
pub use crate::proposer_slashing::ProposerSlashing;
pub use crate::slashable_vote_data::SlashableVoteData;
pub use crate::shard_and_committee::ShardAndCommittee;
pub use crate::special_record::{SpecialRecord, SpecialRecordKind};
pub use crate::validator_record::{ValidatorRecord, ValidatorStatus};

pub type Hash256 = H256;
pub type Address = H160;
pub type EthBalance = U256;
pub type Bitfield = boolean_bitfield::BooleanBitfield;
pub type BitfieldError = boolean_bitfield::Error;

/// Maps a (slot, shard_id) to attestation_indices.
pub type AttesterMap = HashMap<(u64, u16), Vec<usize>>;

/// Maps a slot to a block proposer.
pub type ProposerMap = HashMap<u64, usize>;
<commit_msg>fixed conflicts<commit_after>extern crate bls;
extern crate boolean_bitfield;
extern crate ethereum_types;
extern crate ssz;

pub mod test_utils;

pub mod active_state;
pub mod attestation_data;
pub mod attestation;
pub mod beacon_block;
pub mod beacon_block_body;
pub mod beacon_state;
pub mod candidate_pow_receipt_root_record;
pub mod casper_slashing;
pub mod chain_config;
pub mod crosslink_record;
pub mod crystallized_state;
pub mod deposit;
pub mod deposit_data;
pub mod deposit_input;
pub mod exit;
pub mod fork_data;
pub mod pending_attestation_record;
pub mod proposal_signed_data;
pub mod proposer_slashing;
pub mod shard_and_committee;
pub mod shard_reassignment_record;
pub mod special_record;
pub mod slashable_vote_data;
pub mod validator_record;

use self::ethereum_types::{H160, H256, U256};
use std::collections::HashMap;

pub use crate::active_state::ActiveState;
pub use crate::attestation_data::AttestationData;
pub use crate::attestation::Attestation;
pub use crate::beacon_block::BeaconBlock;
pub use crate::beacon_block_body::BeaconBlockBody;
pub use crate::beacon_state::BeaconState;
pub use crate::casper_slashing::CasperSlashing;
pub use crate::chain_config::ChainConfig;
pub use crate::crosslink_record::CrosslinkRecord;
pub use crate::crystallized_state::CrystallizedState;
pub use crate::deposit::Deposit;
pub use crate::deposit_data::DepositData;
pub use crate::deposit_input::DepositInput;
pub use crate::exit::Exit;
pub use crate::fork_data::ForkData;
pub use crate::pending_attestation_record::PendingAttestationRecord;
pub use crate::proposal_signed_data::ProposalSignedData;
pub use crate::proposer_slashing::ProposerSlashing;
pub use crate::slashable_vote_data::SlashableVoteData;
pub use crate::shard_and_committee::ShardAndCommittee;
pub use crate::special_record::{SpecialRecord, SpecialRecordKind};
pub use crate::validator_record::{ValidatorRecord, ValidatorStatus};

pub type Hash256 = H256;
pub type Address = H160;
pub type EthBalance = U256;
pub type Bitfield = boolean_bitfield::BooleanBitfield;
pub type BitfieldError = boolean_bitfield::Error;

/// Maps a (slot, shard_id) to attestation_indices.
pub type AttesterMap = HashMap<(u64, u16), Vec<usize>>;

/// Maps a slot to a block proposer.
pub type ProposerMap = HashMap<u64, usize>;
<|endoftext|>


<commit_before>use std::io::{Error, ErrorKind};
use std::result::Result;

fn range_vec<T>(nl: &Vec<T>, i: usize, j: usize) -> Result<Vec<T>, Error>
where
    T: Copy + Clone,
{
    if i >= nl.len() {
        return Err(Error::new(
            ErrorKind::Other,
            "first index larger than length",
        ));
    }

    let mut jj;

    if j > nl.len() {
        jj = nl.len() - 1;
    } else {
        jj = j - 1;
    }

    let mut ind = 0;
    let mut result: Vec<T> = vec![];

    for this in nl {
        if ind >= i && ind <= jj {
            result.push(*this);
        }
        ind += 1;
    }

    Result::Ok(result)
}

fn main() {
    let a = vec![1, 2, 3, 4, 5, 6];
    println!("{:?}", range_vec(&a, 0, 1));
    println!("{:?}", range_vec(&a, 2, 6));
    println!("{:?}", range_vec(&a, 6, 6));
    println!("{:?}", range_vec(&a, 5, 6));
}
<commit_msg>learn how to resolve Associated types vs type parameter conflict<commit_after>use std::io::{Error, ErrorKind};
use std::ops::Add;
use std::result::Result;

fn range_vec<T>(nl: &Vec<T>, i: usize, j: usize) -> Result<Vec<T>, Error>
where
    T: Copy + Clone,
{
    if i >= nl.len() {
        return Err(Error::new(
            ErrorKind::Other,
            "first index larger than length",
        ));
    }

    let mut jj;

    if j > nl.len() {
        jj = nl.len() - 1;
    } else {
        jj = j - 1;
    }

    let mut ind = 0;
    let mut result: Vec<T> = vec![];

    for this in nl {
        if ind >= i && ind <= jj {
            result.push(*this);
        }
        ind += 1;
    }

    Result::Ok(result)
}

fn sum_vec<T>(nl: &Vec<T>) -> T
where
    T: Add<Output = T> + Copy + Clone,
{
    let mut result: T = *nl.first().unwrap();
    if let Some((_, last)) = nl.split_first() {
        for this in last {
            result = result + (*this);
        }
    }
    result
}

/*
fn sum_range<T>(nl: &Vec<T>, i: usize, j: usize) -> Result<T, Error>
where
    T: Add + Copy + Clone,
{

}*/

fn main() {
    let a = vec![1, 2, 3, 4, 5, 6];
    println!("{:?}", range_vec(&a, 0, 1));
    println!("{:?}", range_vec(&a, 2, 6));
    println!("{:?}", range_vec(&a, 6, 6));
    println!("{:?}", range_vec(&a, 5, 6));
    //main thread cannot use `?`
    //println!("{:?}", range_vec(&a, 2, 6)?);

    println!("{:?}", sum_vec(&a));
}
<|endoftext|>


<commit_before>//! Functions relating to network operations.
//!
//! This will eventually be moved

pub mod game_connection;
use self::game_connection::GameConnection;

pub mod packet;

use std::net::TcpListener;

use std::thread;

fn start_listening(port: u16) -> Result<TcpListener, &'static str> {

    let listener = TcpListener::bind(("127.0.0.1", port));

    if listener.is_ok() {
        return Ok(listener.unwrap());
    } else {
        return Err("Could not listen on requested port");
    }

}

pub fn start_network() {

    let listener = start_listening(25565);

    if listener.is_err() {
        error!("Could not start listening on port {}", 25565);
    }

    let listener = listener.unwrap();

    for stream in listener.incoming() {

        match stream {
            Ok(stream) => {
                thread::spawn(move || {
                    // New connection succeeded
                    //TODO: Add this connection to a list of connections
                    GameConnection::new(stream).start_listening()
                });
            }
            Err(e) => {
                error!("Could not accept a new stream: {}", e);
            }
        }

    }

    drop(listener);

}
<commit_msg>Listen on all addresses<commit_after>//! Functions relating to network operations.
//!
//! This will eventually be moved

pub mod game_connection;
use self::game_connection::GameConnection;

pub mod packet;

use std::net::TcpListener;

use std::thread;

fn start_listening(port: u16) -> Result<TcpListener, &'static str> {

    let listener = TcpListener::bind(("0.0.0.0", port));

    if listener.is_ok() {
        return Ok(listener.unwrap());
    } else {
        return Err("Could not listen on requested port");
    }

}

pub fn start_network() {

    let listener = start_listening(25565);

    if listener.is_err() {
        error!("Could not start listening on port {}", 25565);
    }

    let listener = listener.unwrap();

    for stream in listener.incoming() {

        match stream {
            Ok(stream) => {
                thread::spawn(move || {
                    // New connection succeeded
                    //TODO: Add this connection to a list of connections
                    GameConnection::new(stream).start_listening()
                });
            }
            Err(e) => {
                error!("Could not accept a new stream: {}", e);
            }
        }

    }

    drop(listener);

}
<|endoftext|>


<commit_before>use std::mem;
use gapbuffer::GapBuffer;

pub struct Lines<'a> {
    pub buffer: &'a GapBuffer<u8>,
    pub tail: usize,
    pub head: usize,
}

impl<'a> Iterator for Lines<'a> {
    type Item = Vec<u8>;

    fn next(&mut self) -> Option<Vec<u8>> {
        if self.tail != self.head {
            let old_tail = self.tail;
            //update tail to either the first char after the next \n or to self.head
            self.tail = (old_tail..self.head).filter(|i| { *i + 1 == self.head
                                                           || self.buffer[*i] == b'\n' })
                                             .take(1)
                                             .next()
                                             .unwrap() + 1;
            Some((old_tail..if self.tail == self.head { self.tail - 1 } else { self.tail })
                .map( |i| self.buffer[i] ).collect())
        } else { None }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        //TODO: this is technically correct but a better estimate could be implemented
        (1, Some(self.head))
    }

}

/// Iterator traversing GapBuffer as chars
/// Can be made to traverse forwards or backwards with the methods
/// `rev()` `forward()` and `backward()`
pub struct Chars<'a> {
    pub buffer: &'a GapBuffer<u8>,
    pub idx: usize,
    pub forward: bool,
}

// helper macros/constants
// u8 -> char code is mostly copied from core::str::Chars
const CONT_MASK:   u8 = 0b0011_1111u8;
const TAG_CONT_U8: u8 = 0b1000_0000u8;

// Return the initial codepoint accumulator for the first byte.
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
// for width 3, and 3 bits for width 4
macro_rules! utf8_first_byte {
    ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32)
}

// return the value of $ch updated with continuation byte $byte
macro_rules! utf8_acc_cont_byte {
    ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & CONT_MASK) as u32)
}

macro_rules! utf8_is_cont_byte {
    ($byte:expr) => (($byte & !CONT_MASK) == TAG_CONT_U8)
}

impl<'a> Chars<'a> {
    fn next_u8(&mut self) -> Option<u8> {
        let n = if self.idx < self.buffer.len() {
            Some(self.buffer[self.idx])
        } else { None };

        if self.forward {
            self.idx += 1;
        } else {
            self.idx -= 1;
        }
        n
    }
}

impl<'a> Iterator for Chars<'a> {
    type Item = char;

    #[inline]
    fn next(&mut self) -> Option<char> {
        if self.forward {
            // read u8s forwards into char (largely copied from core::str::Chars)
            let x = match self.next_u8() {
                None => return None,
                Some(next_byte) if next_byte < 128 => return Some(next_byte as char),
                Some(next_byte) => next_byte
            };

            // Multibyte case follows
            // Decode from a byte combination out of: [[[x y] z] w]
            let init = utf8_first_byte!(x, 2);
            let y = self.next_u8().unwrap_or(0);
            let mut ch = utf8_acc_cont_byte!(init, y);
            if x >= 0xE0 {
                // [[x y z] w] case
                // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid
                let z = self.next_u8().unwrap_or(0);
                let y_z = utf8_acc_cont_byte!((y & CONT_MASK) as u32, z);
                ch = init << 12 | y_z;
                if x >= 0xF0 {
                    // [x y z w] case
                    // use only the lower 3 bits of `init`
                    let w = self.next_u8().unwrap_or(0);
                    ch = (init & 7) << 18 | utf8_acc_cont_byte!(y_z, w);
                }
            }

            // str invariant says `ch` is a valid Unicode Scalar Value
            unsafe { Some(mem::transmute(ch)) }
        } else {
            // read u8s backwards into char (largely copied from core::str::Chars)
            let w = match self.next_u8() {
                None => return None,
                Some(back_byte) if back_byte < 128 => return Some(back_byte as char),
                Some(back_byte) => back_byte,
            };

            // Multibyte case follows
            // Decode from a byte combination out of: [x [y [z w]]]
            let mut ch;
            let z = self.next_u8().unwrap_or(0);
            ch = utf8_first_byte!(z, 2);
            if utf8_is_cont_byte!(z) {
                let y = self.next_u8().unwrap_or(0);
                ch = utf8_first_byte!(y, 3);
                if utf8_is_cont_byte!(y) {
                    let x = self.next_u8().unwrap_or(0);
                    ch = utf8_first_byte!(x, 4);
                    ch = utf8_acc_cont_byte!(ch, y);
                }
                ch = utf8_acc_cont_byte!(ch, z);
            }
            ch = utf8_acc_cont_byte!(ch, w);

            // str invariant says `ch` is a valid Unicode Scalar Value
            unsafe { Some(mem::transmute(ch)) }
        }
    }
}
<commit_msg>Removed Chars iterator<commit_after>use gapbuffer::GapBuffer;

pub struct Lines<'a> {
    pub buffer: &'a GapBuffer<u8>,
    pub tail: usize,
    pub head: usize,
}

impl<'a> Iterator for Lines<'a> {
    type Item = Vec<u8>;

    fn next(&mut self) -> Option<Vec<u8>> {
        if self.tail != self.head {
            let old_tail = self.tail;
            //update tail to either the first char after the next \n or to self.head
            self.tail = (old_tail..self.head).filter(|i| { *i + 1 == self.head
                                                           || self.buffer[*i] == b'\n' })
                                             .take(1)
                                             .next()
                                             .unwrap() + 1;
            Some((old_tail..if self.tail == self.head { self.tail - 1 } else { self.tail })
                .map( |i| self.buffer[i] ).collect())
        } else { None }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        //TODO: this is technically correct but a better estimate could be implemented
        (1, Some(self.head))
    }

}
<|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.

//! A wrapper around any Reader to treat it as an RNG.

use Rng;

/// An RNG that reads random bytes straight from a `Reader`. This will
/// work best with an infinite reader, but this is not required.
///
/// It will fail if it there is insufficient data to fulfill a request.
///
/// # Example
///
/// ```rust
/// use rand::{reader, Rng};
/// use std::io::MemReader;
///
/// let mut rng = reader::ReaderRng::new(MemReader::new(~[1,2,3,4,5,6,7,8]));
/// println!("{:x}", rng.gen::<uint>());
/// ```
pub struct ReaderRng<R> {
    reader: R
}

impl<R: Reader> ReaderRng<R> {
    /// Create a new `ReaderRng` from a `Reader`.
    pub fn new(r: R) -> ReaderRng<R> {
        ReaderRng {
            reader: r
        }
    }
}

impl<R: Reader> Rng for ReaderRng<R> {
    fn next_u32(&mut self) -> u32 {
        // This is designed for speed: reading a LE integer on a LE
        // platform just involves blitting the bytes into the memory
        // of the u32, similarly for BE on BE; avoiding byteswapping.
        if cfg!(target_endian="little") {
            self.reader.read_le_u32().unwrap()
        } else {
            self.reader.read_be_u32().unwrap()
        }
    }
    fn next_u64(&mut self) -> u64 {
        // see above for explanation.
        if cfg!(target_endian="little") {
            self.reader.read_le_u64().unwrap()
        } else {
            self.reader.read_be_u64().unwrap()
        }
    }
    fn fill_bytes(&mut self, v: &mut [u8]) {
        if v.len() == 0 { return }
        match self.reader.fill(v) {
            Ok(()) => {}
            Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
        }
    }
}

#[cfg(test)]
#[allow(deprecated_owned_vector)]
mod test {
    use super::ReaderRng;
    use std::io::MemReader;
    use std::cast;
    use Rng;

    #[test]
    fn test_reader_rng_u64() {
        // transmute from the target to avoid endianness concerns.
        let v = ~[1u64, 2u64, 3u64];
        let bytes: ~[u8] = unsafe {cast::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes));

        assert_eq!(rng.next_u64(), 1);
        assert_eq!(rng.next_u64(), 2);
        assert_eq!(rng.next_u64(), 3);
    }
    #[test]
    fn test_reader_rng_u32() {
        // transmute from the target to avoid endianness concerns.
        let v = ~[1u32, 2u32, 3u32];
        let bytes: ~[u8] = unsafe {cast::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes));

        assert_eq!(rng.next_u32(), 1);
        assert_eq!(rng.next_u32(), 2);
        assert_eq!(rng.next_u32(), 3);
    }
    #[test]
    fn test_reader_rng_fill_bytes() {
        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
        let mut w = [0u8, .. 8];

        let mut rng = ReaderRng::new(MemReader::new(v.to_owned()));
        rng.fill_bytes(w);

        assert!(v == w);
    }

    #[test]
    #[should_fail]
    fn test_reader_rng_insufficient_bytes() {
        let mut rng = ReaderRng::new(MemReader::new(~[]));
        let mut v = [0u8, .. 3];
        rng.fill_bytes(v);
    }
}
<commit_msg>auto merge of #13165 : sfackler/rust/io-vec, r=alexcrichton<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.

//! A wrapper around any Reader to treat it as an RNG.

use Rng;

/// An RNG that reads random bytes straight from a `Reader`. This will
/// work best with an infinite reader, but this is not required.
///
/// It will fail if it there is insufficient data to fulfill a request.
///
/// # Example
///
/// ```rust
/// use rand::{reader, Rng};
/// use std::io::MemReader;
///
/// let mut rng = reader::ReaderRng::new(MemReader::new(vec!(1,2,3,4,5,6,7,8)));
/// println!("{:x}", rng.gen::<uint>());
/// ```
pub struct ReaderRng<R> {
    reader: R
}

impl<R: Reader> ReaderRng<R> {
    /// Create a new `ReaderRng` from a `Reader`.
    pub fn new(r: R) -> ReaderRng<R> {
        ReaderRng {
            reader: r
        }
    }
}

impl<R: Reader> Rng for ReaderRng<R> {
    fn next_u32(&mut self) -> u32 {
        // This is designed for speed: reading a LE integer on a LE
        // platform just involves blitting the bytes into the memory
        // of the u32, similarly for BE on BE; avoiding byteswapping.
        if cfg!(target_endian="little") {
            self.reader.read_le_u32().unwrap()
        } else {
            self.reader.read_be_u32().unwrap()
        }
    }
    fn next_u64(&mut self) -> u64 {
        // see above for explanation.
        if cfg!(target_endian="little") {
            self.reader.read_le_u64().unwrap()
        } else {
            self.reader.read_be_u64().unwrap()
        }
    }
    fn fill_bytes(&mut self, v: &mut [u8]) {
        if v.len() == 0 { return }
        match self.reader.fill(v) {
            Ok(()) => {}
            Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
        }
    }
}

#[cfg(test)]
#[allow(deprecated_owned_vector)]
mod test {
    use super::ReaderRng;
    use std::io::MemReader;
    use std::cast;
    use Rng;

    #[test]
    fn test_reader_rng_u64() {
        // transmute from the target to avoid endianness concerns.
        let v = ~[1u64, 2u64, 3u64];
        let bytes: ~[u8] = unsafe {cast::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes.move_iter().collect()));

        assert_eq!(rng.next_u64(), 1);
        assert_eq!(rng.next_u64(), 2);
        assert_eq!(rng.next_u64(), 3);
    }
    #[test]
    fn test_reader_rng_u32() {
        // transmute from the target to avoid endianness concerns.
        let v = ~[1u32, 2u32, 3u32];
        let bytes: ~[u8] = unsafe {cast::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes.move_iter().collect()));

        assert_eq!(rng.next_u32(), 1);
        assert_eq!(rng.next_u32(), 2);
        assert_eq!(rng.next_u32(), 3);
    }
    #[test]
    fn test_reader_rng_fill_bytes() {
        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
        let mut w = [0u8, .. 8];

        let mut rng = ReaderRng::new(MemReader::new(Vec::from_slice(v)));
        rng.fill_bytes(w);

        assert!(v == w);
    }

    #[test]
    #[should_fail]
    fn test_reader_rng_insufficient_bytes() {
        let mut rng = ReaderRng::new(MemReader::new(vec!()));
        let mut v = [0u8, .. 3];
        rng.fill_bytes(v);
    }
}
<|endoftext|>