<commit_before>use ::ast::*;
use ::ast::ExprNode::*;
use ::ast::NumNode::*;
use super::*;
use super::parser_combinators::{Parser,parser};

#[test]
fn test_line_comment() {
    assert_eq!(parser(line_comment).parse(";this is a fake line comment\n"),
        Ok(((),"")));
}

#[test]
fn test_line_comment_ignore() {
    assert_eq!(parser(expr).parse(
r#";this is a fake line comment
ident"#),
        Ok((Name(NameNode { name: "ident".to_string() }), ""))
        )
}

#[test]
fn test_basic_ident() {
    assert_eq!(
        parser(expr).parse("ident"),
        Ok((Name(NameNode { name: "ident".to_string() }), ""))
        );
    assert_eq!(
        parser(expr).parse("a"),
        Ok((Name(NameNode { name: "a".to_string() }), ""))
        );
    assert_eq!(
        parser(expr).parse("ident_With\\special!Chars:~-+"),
        Ok((Name(NameNode { name: "ident_With\\special!Chars:~-+".to_string() }), ""))
        );
}

#[test]
fn test_basic_sexpr() {
    assert_eq!(
        parser(expr).parse("(ident arg1 arg2)"),
        Ok((SExpr(SExprNode {
            operator: box Name(NameNode { name: "ident".to_string() }),
            operands: vec![
                Name(NameNode { name: "arg1".to_string() }),
                Name(NameNode { name: "arg2".to_string() })
            ]
        }), ""))
        );
}
#[test]
fn test_square_bracket_sexpr() {
    assert_eq!(
        parser(expr).parse("[ident arg1 arg2]"),
        Ok((SExpr(SExprNode {
            operator: box Name(NameNode { name: "ident".to_string() }),
            operands: vec![
                Name(NameNode { name: "arg1".to_string() }),
                Name(NameNode { name: "arg2".to_string() })
            ]
        }), ""))
        );
}

#[test]
fn test_lex_sint_pos() {
    assert_eq!(
        parser(number).parse("1234"),
        Ok((IntConst(IntNode { value: 1234isize }), ""))
        );
    assert_eq!(
        parser(number).parse("#d1234"),
        Ok((IntConst(IntNode { value: 1234isize }), ""))
        );
    assert_eq!(
        parser(number).parse("#D1234"),
        Ok((IntConst(IntNode { value: 1234isize }), ""))
        );
}

#[test]
fn test_lex_sint_neg() {
    assert_eq!(
        parser(number).parse("-1234"),
        Ok((IntConst(IntNode { value: -1234isize }), ""))
        );
}

#[test]
fn test_lex_sint_hex() {
    assert_eq!(
        parser(number).parse("#x0ff"),
        Ok((IntConst(IntNode { value: 0x0ffisize }), ""))
        );
    assert_eq!(
        parser(number).parse("#X0FF"),
        Ok((IntConst(IntNode { value: 0x0ffisize }), ""))
        );
}
/* // Currently unsupported
#[test]
fn test_parse_sint_bin_upper() {
    assert_eq!(
        parser(number).parse("0B01"),
        Ok((IntConst(IntNode { value: 0b01isize }), ""))
        );
    assert_eq!(
        parser(number).parse("0b01"),
        Ok((IntConst(IntNode { value: 0b01isize }), ""))
        );
}*/

#[test]
fn test_lex_uint() {
    assert_eq!(
        parser(number).parse("1234u"),
        Ok((UIntConst(UIntNode { value: 1234usize }), ""))
        );
    assert_eq!(
        parser(number).parse("4321U"),
        Ok((UIntConst(UIntNode { value: 4321usize }), ""))
        );
}

#[test]
fn test_lex_uint_hex() {
    assert_eq!(
        parser(number).parse("#x0ffu"),
        Ok((UIntConst(UIntNode { value: 0x0ffusize }), ""))
        );
    assert_eq!(
        parser(number).parse("#X0FFu"),
        Ok((UIntConst(UIntNode { value: 0x0ffusize }), ""))
        );
}

#[test]
fn test_lex_float() {
    assert_eq!(
        parser(number).parse("1.0"),
        Ok((FloatConst(FloatNode { value: 1.0f64 }), ""))
        );/* // Unsupported
    assert_eq!(
        parser(number).parse("1f").unwrap(),
        (FloatConst(FloatNode { value: 1.0f64 }), "")
        );
    assert_eq!(
        parser(number).parse("22.2222").unwrap(),
        (FloatConst(FloatNode { value: 22.2222f64 }), "")
        );
    assert_eq!(
        parser(number).parse("22.2222f").unwrap(),
        (FloatConst(FloatNode { value: 22.2222f64 }), "")
        );*/
}

/// This is the parsing component of basic arithmetic
/// integration target
///
/// ```lisp
/// (+ 10 10)
/// ```
#[test]
fn test_parse_arith() {
    assert_eq!(
        parser(expr).parse("(+ 10 10)"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode { name: "+".to_string() }),
                operands: vec![
                    NumConst(IntConst(IntNode{ value: 10 })),
                    NumConst(IntConst(IntNode{ value: 10 }))
                ]
            }),
            ""))
        );
}

/// This is the parsing component of the CAR integration target
///
/// ```lisp
/// (car (cons 10 (cons 20 nil)))
/// ```
#[test]
fn test_parse_car() {
    assert_eq!(
        parser(expr).parse("(car (cons 10 (cons 20 nil)))"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode { name: "car".to_string() }),
                operands: vec![
                    SExpr(SExprNode {
                        operator: box Name(NameNode { name: "cons".to_string() }),
                        operands: vec![
                            NumConst(IntConst(IntNode{ value: 10 })),
                            SExpr(SExprNode {
                                operator: box Name(NameNode { name: "cons".to_string() }),
                                operands: vec![
                                    NumConst(IntConst(IntNode{ value: 20 })),
                                    Name(NameNode { name: "nil".to_string() })
                                ]
                            })
                        ]
                    })
                ]
            }),
            ""))
        );
}

/// This is the parsing component of the CDR integration target
///
/// ```lisp
/// (cdr (cons 10 (cons 20 nil)))
/// ```
#[test]
fn test_parse_cdr() {
    assert_eq!(
        parser(expr).parse("(cdr (cons 10 (cons 20 nil)))"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode { name: "cdr".to_string() }),
                operands: vec![
                    SExpr(SExprNode {
                        operator: box Name(NameNode { name: "cons".to_string() }),
                        operands: vec![
                            NumConst(IntConst(IntNode{ value: 10 })),
                            SExpr(SExprNode {
                                operator: box Name(NameNode { name: "cons".to_string() }),
                                operands: vec![
                                    NumConst(IntConst(IntNode{ value: 20 })),
                                    Name(NameNode { name: "nil".to_string() })
                                ]
                            })
                        ]
                    })
                ]
            }),
            ""))
        );
}

/// This is the parsing component of nested arithmetic
/// integration target with square brackets added
/// (just to ensure that the parser handles them correctly)
///
/// ```lisp
/// (- 20 [+ 5 5])
/// ```
#[test]
fn test_parse_nested_arith_square_bracket() {
    assert_eq!(
        parser(expr).parse("(- 20 [+ 5 5])"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode { name: "-".to_string() }),
                operands: vec![
                    NumConst(IntConst(IntNode{ value: 20 })),
                    SExpr(SExprNode {
                        operator: box Name(NameNode { name: "+".to_string() }),
                        operands: vec![
                            NumConst(IntConst(IntNode{ value: 5 })),
                            NumConst(IntConst(IntNode{ value: 5 }))
                        ]
                    })
                ]
            }),
            ""))
        );
}

/// This is the parsing component of nested arithmetic
/// integration target
///
/// ```lisp
/// (- 20 (+ 5 5))
/// ```
#[test]
fn test_parse_nested_arith() {
    assert_eq!(
        parser(expr).parse("(- 20 (+ 5 5))"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode { name: "-".to_string() }),
                operands: vec![
                    NumConst(IntConst(IntNode{ value: 20 })),
                    SExpr(SExprNode {
                        operator: box Name(NameNode { name: "+".to_string() }),
                        operands: vec![
                            NumConst(IntConst(IntNode{ value: 5 })),
                            NumConst(IntConst(IntNode{ value: 5 }))
                        ]
                    })
                ]
            }),
            ""))
        );
}

/// This is the parsing component of the `compile_basic_branching_1`
/// integration target.
///
/// ```lisp
/// (if (= 0 (- 1 1)) #t #f)
/// ``
#[test]
fn test_parse_basic_branching_1() {
    assert_eq!(
        parser(expr).parse("(if (= 0 (- 1 1)) #t #f)"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode::new("if".to_string())),
                operands: vec![
                    SExpr(SExprNode{
                        operator: box Name(NameNode::new("=".to_string())),
                        operands: vec![
                            NumConst(IntConst(IntNode{value: 0})),
                            SExpr(SExprNode{
                                operator: box Name(NameNode::new("-".to_string())),
                                operands: vec![
                                    NumConst(IntConst(IntNode{ value: 1 })),
                                    NumConst(IntConst(IntNode{ value: 1 }))
                                ]
                            })
                        ]
                    }),
                    BoolConst(BoolNode{value:true}),
                    BoolConst(BoolNode{value:false}),
                ]
            }
            ),
            "")
        )
    )
}

/// This is the parsing component of the `compile_basic_branching_2`
/// integration target.
///
/// ```lisp
/// (+ 10 (if (nil? nil) 10 20))
/// ``
#[test]
fn test_parse_basic_branching_2() {
    assert_eq!(
        parser(expr).parse("(+ 10 (if (nil? nil) 10 20))"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode::new("+".to_string())),
                operands: vec![
                    NumConst(IntConst(IntNode{value:10})),
                    SExpr(SExprNode{
                        operator: box Name(NameNode::new("if".to_string())),
                        operands: vec![
                            SExpr(SExprNode{
                                operator: box Name(NameNode::new("nil?".to_string())),
                                operands: vec![Name(NameNode::new("nil".to_string()))]

                            }),
                            NumConst(IntConst(IntNode{value:10})),
                            NumConst(IntConst(IntNode{value:20}))
                        ]
                    })
                ]
            }
            ),
            "")
        )
    )
}

#[test]
fn test_lex_bool() {
    assert_eq!(
        parser(bool_const).parse("#t"),
        Ok((BoolNode { value: true}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#T"),
        Ok((BoolNode { value: true}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#f"),
        Ok((BoolNode { value: false}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#F"),
        Ok((BoolNode { value: false}, ""))
        );
}

#[test]
fn test_lex_char() {
    assert_eq!(
        parser(character).parse("#\\c"),
        Ok((CharNode { value: 'c'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\A"),
        Ok((CharNode { value: 'A'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\tab"),
        Ok((CharNode { value: '\t'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\newline"),
        Ok((CharNode { value: '\n'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\nul"),
        Ok((CharNode { value: '\u{0000}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\backspace"),
        Ok((CharNode { value: '\u{0008}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\vtab"),
        Ok((CharNode { value: '\u{000B}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\page"),
        Ok((CharNode { value: '\u{000C}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\return"),
        Ok((CharNode { value: '\u{000D}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\esc"),
        Ok((CharNode { value: '\u{001B}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\delete"),
        Ok((CharNode { value: '\u{007F}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\alarm"),
        Ok((CharNode { value: '\u{0007}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\linefeed"),
        Ok((CharNode { value: '\n'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\space"),
        Ok((CharNode { value: ' '}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\x0020"),
        Ok((CharNode { value: ' '}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\x001B"),
        Ok((CharNode { value: '\u{001B}' }, ""))
        );
}

#[test]
fn test_lex_string() {
    assert_eq!(
        parser(string_const).parse("\"a string\""),
        Ok((StringNode { value: "a string".to_string() }, ""))
    );
    assert_eq!(
        parser(string_const).parse("\"a string with a\\ttab\""),
        Ok((StringNode { value: "a string with a\ttab".to_string() },""))
    );
    assert_eq!(
        parser(string_const).parse("\"a string with an \\\"escaped\\\" quote\""),
        Ok((StringNode { value: "a string with an \"escaped\" quote".to_string() },""))
    );
    assert_eq!(
        parser(string_const).parse("\"the\\\\worst string ever\\\"\""),
        Ok((StringNode { value: "the\\worst string ever\"".to_string() }, ""))
    );
}
#[test]
fn test_space_sexpr() {
 assert_eq!(parser(expr).parse("(+ 10 (if (nil? nil) 10 20) )"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode::new("+".to_string())),
                operands: vec![
                    NumConst(IntConst(IntNode{value:10})),
                    SExpr(SExprNode{
                        operator: box Name(NameNode::new("if".to_string())),
                        operands: vec![
                            SExpr(SExprNode{
                                operator: box Name(NameNode::new("nil?".to_string())),
                                operands: vec![Name(NameNode::new("nil".to_string()))]

                            }),
                            NumConst(IntConst(IntNode{value:10})),
                            NumConst(IntConst(IntNode{value:20}))
                        ]
                    })
                ]
            }
            ),
            "")
        )
    )
}
<commit_msg>Space S-exp test is supposed to be disabled<commit_after>use ::ast::*;
use ::ast::ExprNode::*;
use ::ast::NumNode::*;
use super::*;
use super::parser_combinators::{Parser,parser};

#[test]
fn test_line_comment() {
    assert_eq!(parser(line_comment).parse(";this is a fake line comment\n"),
        Ok(((),"")));
}

#[test]
fn test_line_comment_ignore() {
    assert_eq!(parser(expr).parse(
r#";this is a fake line comment
ident"#),
        Ok((Name(NameNode { name: "ident".to_string() }), ""))
        )
}

#[test]
fn test_basic_ident() {
    assert_eq!(
        parser(expr).parse("ident"),
        Ok((Name(NameNode { name: "ident".to_string() }), ""))
        );
    assert_eq!(
        parser(expr).parse("a"),
        Ok((Name(NameNode { name: "a".to_string() }), ""))
        );
    assert_eq!(
        parser(expr).parse("ident_With\\special!Chars:~-+"),
        Ok((Name(NameNode { name: "ident_With\\special!Chars:~-+".to_string() }), ""))
        );
}

#[test]
fn test_basic_sexpr() {
    assert_eq!(
        parser(expr).parse("(ident arg1 arg2)"),
        Ok((SExpr(SExprNode {
            operator: box Name(NameNode { name: "ident".to_string() }),
            operands: vec![
                Name(NameNode { name: "arg1".to_string() }),
                Name(NameNode { name: "arg2".to_string() })
            ]
        }), ""))
        );
}
#[test]
fn test_square_bracket_sexpr() {
    assert_eq!(
        parser(expr).parse("[ident arg1 arg2]"),
        Ok((SExpr(SExprNode {
            operator: box Name(NameNode { name: "ident".to_string() }),
            operands: vec![
                Name(NameNode { name: "arg1".to_string() }),
                Name(NameNode { name: "arg2".to_string() })
            ]
        }), ""))
        );
}

#[test]
fn test_lex_sint_pos() {
    assert_eq!(
        parser(number).parse("1234"),
        Ok((IntConst(IntNode { value: 1234isize }), ""))
        );
    assert_eq!(
        parser(number).parse("#d1234"),
        Ok((IntConst(IntNode { value: 1234isize }), ""))
        );
    assert_eq!(
        parser(number).parse("#D1234"),
        Ok((IntConst(IntNode { value: 1234isize }), ""))
        );
}

#[test]
fn test_lex_sint_neg() {
    assert_eq!(
        parser(number).parse("-1234"),
        Ok((IntConst(IntNode { value: -1234isize }), ""))
        );
}

#[test]
fn test_lex_sint_hex() {
    assert_eq!(
        parser(number).parse("#x0ff"),
        Ok((IntConst(IntNode { value: 0x0ffisize }), ""))
        );
    assert_eq!(
        parser(number).parse("#X0FF"),
        Ok((IntConst(IntNode { value: 0x0ffisize }), ""))
        );
}
/* // Currently unsupported
#[test]
fn test_parse_sint_bin_upper() {
    assert_eq!(
        parser(number).parse("0B01"),
        Ok((IntConst(IntNode { value: 0b01isize }), ""))
        );
    assert_eq!(
        parser(number).parse("0b01"),
        Ok((IntConst(IntNode { value: 0b01isize }), ""))
        );
}*/

#[test]
fn test_lex_uint() {
    assert_eq!(
        parser(number).parse("1234u"),
        Ok((UIntConst(UIntNode { value: 1234usize }), ""))
        );
    assert_eq!(
        parser(number).parse("4321U"),
        Ok((UIntConst(UIntNode { value: 4321usize }), ""))
        );
}

#[test]
fn test_lex_uint_hex() {
    assert_eq!(
        parser(number).parse("#x0ffu"),
        Ok((UIntConst(UIntNode { value: 0x0ffusize }), ""))
        );
    assert_eq!(
        parser(number).parse("#X0FFu"),
        Ok((UIntConst(UIntNode { value: 0x0ffusize }), ""))
        );
}

#[test]
fn test_lex_float() {
    assert_eq!(
        parser(number).parse("1.0"),
        Ok((FloatConst(FloatNode { value: 1.0f64 }), ""))
        );/* // Unsupported
    assert_eq!(
        parser(number).parse("1f").unwrap(),
        (FloatConst(FloatNode { value: 1.0f64 }), "")
        );
    assert_eq!(
        parser(number).parse("22.2222").unwrap(),
        (FloatConst(FloatNode { value: 22.2222f64 }), "")
        );
    assert_eq!(
        parser(number).parse("22.2222f").unwrap(),
        (FloatConst(FloatNode { value: 22.2222f64 }), "")
        );*/
}

/// This is the parsing component of basic arithmetic
/// integration target
///
/// ```lisp
/// (+ 10 10)
/// ```
#[test]
fn test_parse_arith() {
    assert_eq!(
        parser(expr).parse("(+ 10 10)"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode { name: "+".to_string() }),
                operands: vec![
                    NumConst(IntConst(IntNode{ value: 10 })),
                    NumConst(IntConst(IntNode{ value: 10 }))
                ]
            }),
            ""))
        );
}

/// This is the parsing component of the CAR integration target
///
/// ```lisp
/// (car (cons 10 (cons 20 nil)))
/// ```
#[test]
fn test_parse_car() {
    assert_eq!(
        parser(expr).parse("(car (cons 10 (cons 20 nil)))"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode { name: "car".to_string() }),
                operands: vec![
                    SExpr(SExprNode {
                        operator: box Name(NameNode { name: "cons".to_string() }),
                        operands: vec![
                            NumConst(IntConst(IntNode{ value: 10 })),
                            SExpr(SExprNode {
                                operator: box Name(NameNode { name: "cons".to_string() }),
                                operands: vec![
                                    NumConst(IntConst(IntNode{ value: 20 })),
                                    Name(NameNode { name: "nil".to_string() })
                                ]
                            })
                        ]
                    })
                ]
            }),
            ""))
        );
}

/// This is the parsing component of the CDR integration target
///
/// ```lisp
/// (cdr (cons 10 (cons 20 nil)))
/// ```
#[test]
fn test_parse_cdr() {
    assert_eq!(
        parser(expr).parse("(cdr (cons 10 (cons 20 nil)))"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode { name: "cdr".to_string() }),
                operands: vec![
                    SExpr(SExprNode {
                        operator: box Name(NameNode { name: "cons".to_string() }),
                        operands: vec![
                            NumConst(IntConst(IntNode{ value: 10 })),
                            SExpr(SExprNode {
                                operator: box Name(NameNode { name: "cons".to_string() }),
                                operands: vec![
                                    NumConst(IntConst(IntNode{ value: 20 })),
                                    Name(NameNode { name: "nil".to_string() })
                                ]
                            })
                        ]
                    })
                ]
            }),
            ""))
        );
}

/// This is the parsing component of nested arithmetic
/// integration target with square brackets added
/// (just to ensure that the parser handles them correctly)
///
/// ```lisp
/// (- 20 [+ 5 5])
/// ```
#[test]
fn test_parse_nested_arith_square_bracket() {
    assert_eq!(
        parser(expr).parse("(- 20 [+ 5 5])"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode { name: "-".to_string() }),
                operands: vec![
                    NumConst(IntConst(IntNode{ value: 20 })),
                    SExpr(SExprNode {
                        operator: box Name(NameNode { name: "+".to_string() }),
                        operands: vec![
                            NumConst(IntConst(IntNode{ value: 5 })),
                            NumConst(IntConst(IntNode{ value: 5 }))
                        ]
                    })
                ]
            }),
            ""))
        );
}

/// This is the parsing component of nested arithmetic
/// integration target
///
/// ```lisp
/// (- 20 (+ 5 5))
/// ```
#[test]
fn test_parse_nested_arith() {
    assert_eq!(
        parser(expr).parse("(- 20 (+ 5 5))"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode { name: "-".to_string() }),
                operands: vec![
                    NumConst(IntConst(IntNode{ value: 20 })),
                    SExpr(SExprNode {
                        operator: box Name(NameNode { name: "+".to_string() }),
                        operands: vec![
                            NumConst(IntConst(IntNode{ value: 5 })),
                            NumConst(IntConst(IntNode{ value: 5 }))
                        ]
                    })
                ]
            }),
            ""))
        );
}

/// This is the parsing component of the `compile_basic_branching_1`
/// integration target.
///
/// ```lisp
/// (if (= 0 (- 1 1)) #t #f)
/// ``
#[test]
fn test_parse_basic_branching_1() {
    assert_eq!(
        parser(expr).parse("(if (= 0 (- 1 1)) #t #f)"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode::new("if".to_string())),
                operands: vec![
                    SExpr(SExprNode{
                        operator: box Name(NameNode::new("=".to_string())),
                        operands: vec![
                            NumConst(IntConst(IntNode{value: 0})),
                            SExpr(SExprNode{
                                operator: box Name(NameNode::new("-".to_string())),
                                operands: vec![
                                    NumConst(IntConst(IntNode{ value: 1 })),
                                    NumConst(IntConst(IntNode{ value: 1 }))
                                ]
                            })
                        ]
                    }),
                    BoolConst(BoolNode{value:true}),
                    BoolConst(BoolNode{value:false}),
                ]
            }
            ),
            "")
        )
    )
}

/// This is the parsing component of the `compile_basic_branching_2`
/// integration target.
///
/// ```lisp
/// (+ 10 (if (nil? nil) 10 20))
/// ``
#[test]
fn test_parse_basic_branching_2() {
    assert_eq!(
        parser(expr).parse("(+ 10 (if (nil? nil) 10 20))"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode::new("+".to_string())),
                operands: vec![
                    NumConst(IntConst(IntNode{value:10})),
                    SExpr(SExprNode{
                        operator: box Name(NameNode::new("if".to_string())),
                        operands: vec![
                            SExpr(SExprNode{
                                operator: box Name(NameNode::new("nil?".to_string())),
                                operands: vec![Name(NameNode::new("nil".to_string()))]

                            }),
                            NumConst(IntConst(IntNode{value:10})),
                            NumConst(IntConst(IntNode{value:20}))
                        ]
                    })
                ]
            }
            ),
            "")
        )
    )
}

#[test]
fn test_lex_bool() {
    assert_eq!(
        parser(bool_const).parse("#t"),
        Ok((BoolNode { value: true}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#T"),
        Ok((BoolNode { value: true}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#f"),
        Ok((BoolNode { value: false}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#F"),
        Ok((BoolNode { value: false}, ""))
        );
}

#[test]
fn test_lex_char() {
    assert_eq!(
        parser(character).parse("#\\c"),
        Ok((CharNode { value: 'c'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\A"),
        Ok((CharNode { value: 'A'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\tab"),
        Ok((CharNode { value: '\t'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\newline"),
        Ok((CharNode { value: '\n'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\nul"),
        Ok((CharNode { value: '\u{0000}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\backspace"),
        Ok((CharNode { value: '\u{0008}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\vtab"),
        Ok((CharNode { value: '\u{000B}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\page"),
        Ok((CharNode { value: '\u{000C}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\return"),
        Ok((CharNode { value: '\u{000D}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\esc"),
        Ok((CharNode { value: '\u{001B}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\delete"),
        Ok((CharNode { value: '\u{007F}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\alarm"),
        Ok((CharNode { value: '\u{0007}' }, ""))
        );
    assert_eq!(
        parser(character).parse("#\\linefeed"),
        Ok((CharNode { value: '\n'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\space"),
        Ok((CharNode { value: ' '}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\x0020"),
        Ok((CharNode { value: ' '}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\x001B"),
        Ok((CharNode { value: '\u{001B}' }, ""))
        );
}

#[test]
fn test_lex_string() {
    assert_eq!(
        parser(string_const).parse("\"a string\""),
        Ok((StringNode { value: "a string".to_string() }, ""))
    );
    assert_eq!(
        parser(string_const).parse("\"a string with a\\ttab\""),
        Ok((StringNode { value: "a string with a\ttab".to_string() },""))
    );
    assert_eq!(
        parser(string_const).parse("\"a string with an \\\"escaped\\\" quote\""),
        Ok((StringNode { value: "a string with an \"escaped\" quote".to_string() },""))
    );
    assert_eq!(
        parser(string_const).parse("\"the\\\\worst string ever\\\"\""),
        Ok((StringNode { value: "the\\worst string ever\"".to_string() }, ""))
    );
}
/*
#[test]
fn test_space_sexpr() {
 assert_eq!(parser(expr).parse("(+ 10 (if (nil? nil) 10 20) )"),
        Ok((
            SExpr(SExprNode {
                operator: box Name(NameNode::new("+".to_string())),
                operands: vec![
                    NumConst(IntConst(IntNode{value:10})),
                    SExpr(SExprNode{
                        operator: box Name(NameNode::new("if".to_string())),
                        operands: vec![
                            SExpr(SExprNode{
                                operator: box Name(NameNode::new("nil?".to_string())),
                                operands: vec![Name(NameNode::new("nil".to_string()))]

                            }),
                            NumConst(IntConst(IntNode{value:10})),
                            NumConst(IntConst(IntNode{value:20}))
                        ]
                    })
                ]
            }
            ),
            "")
        )
    )
}*/
<|endoftext|>


<commit_before>extern crate opencl;

use opencl::hl;

fn main() {
    for platform in hl::get_platforms().iter() {
        println!("Platform: {}", platform.name());
        println!("Vendor:   {}", platform.vendor());
        println!("Profile:  {}", platform.profile());
        println!("Available extensions: {}", platform.extensions());
        println!("Available devices:");
        for device in platform.get_devices().iter() {
            println!("   {}", device.name());
        }
    }
}
<commit_msg>Got some more fields for platform example<commit_after>extern crate opencl;

use opencl::hl;

fn main() {
    for platform in hl::get_platforms().iter() {
        println!("Platform: {}", platform.name());
        println!("Platform Version: {}", platform.version());
        println!("Vendor:   {}", platform.vendor());
        println!("Profile:  {}", platform.profile());
        println!("Available extensions: {}", platform.extensions());
        println!("Available devices:");
        for device in platform.get_devices().iter() {
            println!("   Name: {}", device.name());
            println!("   Type: {}", device.device_type());
            println!("   Profile: {}", device.profile());
            println!("   Compute Units: {}", device.compute_units());
        }
    }
}
<|endoftext|>


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

use syntax::{
    ast::{
        self,
        edit::{AstNodeEdit, IndentLevel},
        make, HasLoopBody,
    },
    AstNode, T,
};

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

// Assist: convert_while_to_loop
//
// Replace a while with a loop.
//
// ```
// fn main() {
//     $0while cond {
//         foo();
//     }
// }
// ```
// ->
// ```
// fn main() {
//     loop {
//         if !cond {
//             break;
//         }
//         foo();
//     }
// }
// ```
pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let while_kw = ctx.find_token_syntax_at_offset(T![while])?;
    let while_expr = while_kw.parent().and_then(ast::WhileExpr::cast)?;
    let while_body = while_expr.loop_body()?;
    let while_cond = while_expr.condition()?;

    let if_cond = match while_cond.pat() {
        Some(_) => while_expr.condition()?,
        None => make::condition(invert_boolean_expression(while_cond.expr()?), None),
    };
    let target = while_expr.syntax().text_range();
    acc.add(
        AssistId("convert_while_to_loop", AssistKind::RefactorRewrite),
        "Convert while to loop",
        target,
        |edit| {
            let while_indent_level = IndentLevel::from_node(while_expr.syntax());

            let break_block =
                make::block_expr(once(make::expr_stmt(make::expr_break(None)).into()), None)
                    .indent(while_indent_level);
            let block_expr = match while_cond.pat() {
                Some(_) => {
                    let if_expr = make::expr_if(if_cond, while_body, Some(break_block.into()));
                    let stmts = once(make::expr_stmt(if_expr).into());
                    make::block_expr(stmts, None)
                }
                None => {
                    let if_expr = make::expr_if(if_cond, break_block, None);
                    let stmts =
                        once(make::expr_stmt(if_expr).into()).chain(while_body.statements());
                    make::block_expr(stmts, while_body.tail_expr())
                }
            };

            let replacement = make::expr_loop(block_expr.indent(while_indent_level));
            edit.replace(target, replacement.syntax().text())
        },
    )
}

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

    use super::*;

    #[test]
    fn convert_inside_fn() {
        check_assist(
            convert_while_to_loop,
            r#"
fn main() {
    while$0 cond {
        foo();
    }
}
"#,
            r#"
fn main() {
    loop {
        if !cond {
            break;
        }
        foo();
    }
}
"#,
        );
    }

    #[test]
    fn convert_busy_wait() {
        check_assist(
            convert_while_to_loop,
            r#"
fn main() {
    while$0 cond() {}
}
"#,
            r#"
fn main() {
    loop {
        if !cond() {
            break;
        }
    }
}
"#,
        );
    }

    #[test]
    fn convert_trailing_expr() {
        check_assist(
            convert_while_to_loop,
            r#"
fn main() {
    while$0 cond() {
        bar()
    }
}
"#,
            r#"
fn main() {
    loop {
        if !cond() {
            break;
        }
        bar()
    }
}
"#,
        );
    }

    #[test]
    fn convert_while_let() {
        check_assist(
            convert_while_to_loop,
            r#"
fn main() {
    while$0 let Some(_) = foo() {
        bar();
    }
}
"#,
            r#"
fn main() {
    loop {
        if let Some(_) = foo() {
            bar();
        } else {
            break;
        }
    }
}
"#,
        );
    }

    #[test]
    fn ignore_cursor_in_body() {
        check_assist_not_applicable(
            convert_while_to_loop,
            r#"
fn main() {
    while cond {$0
        bar();
    }
}
"#,
        );
    }
}
<commit_msg>fix: defer condition construction<commit_after>use std::iter::once;

use syntax::{
    ast::{
        self,
        edit::{AstNodeEdit, IndentLevel},
        make, HasLoopBody,
    },
    AstNode, T,
};

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

// Assist: convert_while_to_loop
//
// Replace a while with a loop.
//
// ```
// fn main() {
//     $0while cond {
//         foo();
//     }
// }
// ```
// ->
// ```
// fn main() {
//     loop {
//         if !cond {
//             break;
//         }
//         foo();
//     }
// }
// ```
pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let while_kw = ctx.find_token_syntax_at_offset(T![while])?;
    let while_expr = while_kw.parent().and_then(ast::WhileExpr::cast)?;
    let while_body = while_expr.loop_body()?;
    let while_cond = while_expr.condition()?;
    let while_cond_expr = while_cond.expr()?;

    let target = while_expr.syntax().text_range();
    acc.add(
        AssistId("convert_while_to_loop", AssistKind::RefactorRewrite),
        "Convert while to loop",
        target,
        |edit| {
            let while_indent_level = IndentLevel::from_node(while_expr.syntax());

            let break_block =
                make::block_expr(once(make::expr_stmt(make::expr_break(None)).into()), None)
                    .indent(while_indent_level);
            let block_expr = match while_cond.pat() {
                Some(_) => {
                    let if_expr = make::expr_if(while_cond, while_body, Some(break_block.into()));
                    let stmts = once(make::expr_stmt(if_expr).into());
                    make::block_expr(stmts, None)
                }
                None => {
                    let if_cond = make::condition(invert_boolean_expression(while_cond_expr), None);
                    let if_expr = make::expr_if(if_cond, break_block, None);
                    let stmts =
                        once(make::expr_stmt(if_expr).into()).chain(while_body.statements());
                    make::block_expr(stmts, while_body.tail_expr())
                }
            };

            let replacement = make::expr_loop(block_expr.indent(while_indent_level));
            edit.replace(target, replacement.syntax().text())
        },
    )
}

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

    use super::*;

    #[test]
    fn convert_inside_fn() {
        check_assist(
            convert_while_to_loop,
            r#"
fn main() {
    while$0 cond {
        foo();
    }
}
"#,
            r#"
fn main() {
    loop {
        if !cond {
            break;
        }
        foo();
    }
}
"#,
        );
    }

    #[test]
    fn convert_busy_wait() {
        check_assist(
            convert_while_to_loop,
            r#"
fn main() {
    while$0 cond() {}
}
"#,
            r#"
fn main() {
    loop {
        if !cond() {
            break;
        }
    }
}
"#,
        );
    }

    #[test]
    fn convert_trailing_expr() {
        check_assist(
            convert_while_to_loop,
            r#"
fn main() {
    while$0 cond() {
        bar()
    }
}
"#,
            r#"
fn main() {
    loop {
        if !cond() {
            break;
        }
        bar()
    }
}
"#,
        );
    }

    #[test]
    fn convert_while_let() {
        check_assist(
            convert_while_to_loop,
            r#"
fn main() {
    while$0 let Some(_) = foo() {
        bar();
    }
}
"#,
            r#"
fn main() {
    loop {
        if let Some(_) = foo() {
            bar();
        } else {
            break;
        }
    }
}
"#,
        );
    }

    #[test]
    fn ignore_cursor_in_body() {
        check_assist_not_applicable(
            convert_while_to_loop,
            r#"
fn main() {
    while cond {$0
        bar();
    }
}
"#,
        );
    }
}
<|endoftext|>


<commit_before>use std::thread;
use std::net::SocketAddr;

use log::{LogRecord, LogLevel, SetLoggerError};
use env_logger::LogBuilder;
use colored::*;
use router::Router;
use iron::{Chain, Iron};

use std::env;
use std::time::{SystemTime, UNIX_EPOCH};

use blockchain::{GenesisConfig, ApiContext};
use node::{NodeConfig, Node};
use crypto::gen_keypair;
use explorer::ExplorerApi;
use api::Api;

pub mod clap;

pub fn init_logger() -> Result<(), SetLoggerError> {
    let mut builder = LogBuilder::new();
    builder.format(format_log_record);

    if env::var("RUST_LOG").is_ok() {
        builder.parse(&env::var("RUST_LOG").unwrap());
    }

    builder.init()
}

pub fn generate_testnet_config(count: u8, start_port: u16) -> Vec<NodeConfig> {
    let validators = (0..count as usize)
        .map(|_| gen_keypair())
        .collect::<Vec<_>>();
    let genesis = GenesisConfig::new(validators.iter().map(|x| x.0));
    let peers = (0..validators.len())
        .map(|x| {
                 format!("127.0.0.1:{}", start_port + x as u16)
                     .parse()
                     .unwrap()
             })
        .collect::<Vec<_>>();

    validators
        .into_iter()
        .enumerate()
        .map(|(idx, validator)| {
            NodeConfig {
                listen_address: peers[idx],
                network: Default::default(),
                peers: peers.clone(),
                public_key: validator.0,
                secret_key: validator.1,
                genesis: genesis.clone(),
            }
        })
        .collect::<Vec<_>>()
}

/// Options for the `run_node_with_api` function.
pub struct NodeRunOptions {
    /// Enable api endpoints for the `blockchain_explorer` on public api address.
    pub enable_explorer: bool,
    /// Listen address for public api endpoints
    pub public_api_address: Option<SocketAddr>,
    /// Listen address for private api endpoints
    pub private_api_address: Option<SocketAddr>,
}

/// A generic implementation that launches `Node` and optionally creates threads
/// for public and private api handlers.
pub fn run_node_with_api(mut node: Node, options: NodeRunOptions) {
    let blockchain = node.handler().blockchain.clone();
    let private_config_api_thread = match options.private_api_address {
        Some(listen_address) => {
            let mut router = Router::new();
            let api_context = ApiContext::new(&node);
            api_context.wire_private_api(&mut router);

            let thread = thread::spawn(move || {
                info!("Private exonum api started on {}", listen_address);
                let chain = Chain::new(router);
                Iron::new(chain).http(listen_address).unwrap();
            });
            Some(thread)
        }
        None => None,
    };

    let public_config_api_thread = match options.public_api_address {
        Some(listen_address) => {
            let api_context = ApiContext::new(&node);
            let mut router = Router::new();
            api_context.wire_public_api(&mut router);
            if options.enable_explorer {
                let explorer_api = ExplorerApi {
                    blockchain: blockchain
                };
                explorer_api.wire(&mut router);
            }

            let thread = thread::spawn(move || {
                info!("Public exonum api started on {}", listen_address);

                let chain = Chain::new(router);
                Iron::new(chain).http(listen_address).unwrap();
            });
            Some(thread)
        }
        None => None,
    };

    node.run().unwrap();
    if let Some(private_config_api_thread) = private_config_api_thread {
        private_config_api_thread.join().unwrap();
    }
    if let Some(public_config_api_thread) = public_config_api_thread {
        public_config_api_thread.join().unwrap();
    }
}

fn has_colors() -> bool {
    use term::terminfo::TerminfoTerminal;
    use term::Terminal;
    use std::io;

    let out = io::stderr();
    if let Some(term) = TerminfoTerminal::new(out) {
        term.supports_color()
    } else {
        false
    }
}

fn format_log_record(record: &LogRecord) -> String {
    let ts = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
    let secs = ts.as_secs().to_string();
    let millis = (ts.subsec_nanos() as u64 / 1000000).to_string();

    let module = record.location().module_path();
    let file = record.location().file();
    let line = record.location().line();

    let source_path;
    let verbose_src_path = match env::var("RUST_VERBOSE_PATH") {
        Ok(val) => val.parse::<bool>().unwrap_or(false),
        Err(_) => false,
    };
    if verbose_src_path {
        source_path = format!("{}:{}:{}", module, file, line);
    } else {
        source_path = module.to_string();
    }

    if has_colors() {
        let level = match record.level() {
            LogLevel::Error => "ERROR".red(),
            LogLevel::Warn => "WARN".yellow(),
            LogLevel::Info => "INFO".green(),
            LogLevel::Debug => "DEBUG".cyan(),
            LogLevel::Trace => "TRACE".white(),
        };
        format!("[{} : {}] - [ {} ] - {} - {}",
                secs.bold(),
                millis.bold(),
                level,
                &source_path,
                record.args())
    } else {
        let level = match record.level() {
            LogLevel::Error => "ERROR",
            LogLevel::Warn => "WARN",
            LogLevel::Info => "INFO",
            LogLevel::Debug => "DEBUG",
            LogLevel::Trace => "TRACE",
        };
        format!("[{} : {}] - [ {} ] - {} - {}",
                secs,
                millis,
                level,
                &source_path,
                record.args())
    }
}<commit_msg>Fix clippy warning<commit_after>use std::thread;
use std::net::SocketAddr;

use log::{LogRecord, LogLevel, SetLoggerError};
use env_logger::LogBuilder;
use colored::*;
use router::Router;
use iron::{Chain, Iron};

use std::env;
use std::time::{SystemTime, UNIX_EPOCH};

use blockchain::{GenesisConfig, ApiContext};
use node::{NodeConfig, Node};
use crypto::gen_keypair;
use explorer::ExplorerApi;
use api::Api;

pub mod clap;

pub fn init_logger() -> Result<(), SetLoggerError> {
    let mut builder = LogBuilder::new();
    builder.format(format_log_record);

    if env::var("RUST_LOG").is_ok() {
        builder.parse(&env::var("RUST_LOG").unwrap());
    }

    builder.init()
}

pub fn generate_testnet_config(count: u8, start_port: u16) -> Vec<NodeConfig> {
    let validators = (0..count as usize)
        .map(|_| gen_keypair())
        .collect::<Vec<_>>();
    let genesis = GenesisConfig::new(validators.iter().map(|x| x.0));
    let peers = (0..validators.len())
        .map(|x| {
                 format!("127.0.0.1:{}", start_port + x as u16)
                     .parse()
                     .unwrap()
             })
        .collect::<Vec<_>>();

    validators
        .into_iter()
        .enumerate()
        .map(|(idx, validator)| {
            NodeConfig {
                listen_address: peers[idx],
                network: Default::default(),
                peers: peers.clone(),
                public_key: validator.0,
                secret_key: validator.1,
                genesis: genesis.clone(),
            }
        })
        .collect::<Vec<_>>()
}

/// Options for the `run_node_with_api` function.
pub struct NodeRunOptions {
    /// Enable api endpoints for the `blockchain_explorer` on public api address.
    pub enable_explorer: bool,
    /// Listen address for public api endpoints
    pub public_api_address: Option<SocketAddr>,
    /// Listen address for private api endpoints
    pub private_api_address: Option<SocketAddr>,
}

/// A generic implementation that launches `Node` and optionally creates threads
/// for public and private api handlers.
pub fn run_node_with_api(mut node: Node, options: &NodeRunOptions) {
    let blockchain = node.handler().blockchain.clone();
    let private_config_api_thread = match options.private_api_address {
        Some(listen_address) => {
            let mut router = Router::new();
            let api_context = ApiContext::new(&node);
            api_context.wire_private_api(&mut router);

            let thread = thread::spawn(move || {
                info!("Private exonum api started on {}", listen_address);
                let chain = Chain::new(router);
                Iron::new(chain).http(listen_address).unwrap();
            });
            Some(thread)
        }
        None => None,
    };

    let public_config_api_thread = match options.public_api_address {
        Some(listen_address) => {
            let api_context = ApiContext::new(&node);
            let mut router = Router::new();
            api_context.wire_public_api(&mut router);
            if options.enable_explorer {
                let explorer_api = ExplorerApi {
                    blockchain: blockchain
                };
                explorer_api.wire(&mut router);
            }

            let thread = thread::spawn(move || {
                info!("Public exonum api started on {}", listen_address);

                let chain = Chain::new(router);
                Iron::new(chain).http(listen_address).unwrap();
            });
            Some(thread)
        }
        None => None,
    };

    node.run().unwrap();
    if let Some(private_config_api_thread) = private_config_api_thread {
        private_config_api_thread.join().unwrap();
    }
    if let Some(public_config_api_thread) = public_config_api_thread {
        public_config_api_thread.join().unwrap();
    }
}

fn has_colors() -> bool {
    use term::terminfo::TerminfoTerminal;
    use term::Terminal;
    use std::io;

    let out = io::stderr();
    if let Some(term) = TerminfoTerminal::new(out) {
        term.supports_color()
    } else {
        false
    }
}

fn format_log_record(record: &LogRecord) -> String {
    let ts = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
    let secs = ts.as_secs().to_string();
    let millis = (ts.subsec_nanos() as u64 / 1000000).to_string();

    let module = record.location().module_path();
    let file = record.location().file();
    let line = record.location().line();

    let source_path;
    let verbose_src_path = match env::var("RUST_VERBOSE_PATH") {
        Ok(val) => val.parse::<bool>().unwrap_or(false),
        Err(_) => false,
    };
    if verbose_src_path {
        source_path = format!("{}:{}:{}", module, file, line);
    } else {
        source_path = module.to_string();
    }

    if has_colors() {
        let level = match record.level() {
            LogLevel::Error => "ERROR".red(),
            LogLevel::Warn => "WARN".yellow(),
            LogLevel::Info => "INFO".green(),
            LogLevel::Debug => "DEBUG".cyan(),
            LogLevel::Trace => "TRACE".white(),
        };
        format!("[{} : {}] - [ {} ] - {} - {}",
                secs.bold(),
                millis.bold(),
                level,
                &source_path,
                record.args())
    } else {
        let level = match record.level() {
            LogLevel::Error => "ERROR",
            LogLevel::Warn => "WARN",
            LogLevel::Info => "INFO",
            LogLevel::Debug => "DEBUG",
            LogLevel::Trace => "TRACE",
        };
        format!("[{} : {}] - [ {} ] - {} - {}",
                secs,
                millis,
                level,
                &source_path,
                record.args())
    }
}<|endoftext|>


<commit_before>extern crate futures;
extern crate hyper;

use futures::future;
use hyper::rt::{Future, Stream};
use hyper::service::service_fn;
use hyper::{Body, Method, Request, Response, Server, StatusCode};

type BoxFut = Box<Future<Item = Response<Body>, Error = hyper::Error> + Send>;

fn echo(req: Request<Body>) -> BoxFut {
    let mut response = Response::new(Body::empty());

    match (req.method(), req.uri().path()) {
        (&Method::GET, "/") => {
            *response.body_mut() = Body::from("Try POSTing data to /echo");
        }
        (&Method::POST, "/echo") => {
            *response.body_mut() = req.into_body();
        }
        (&Method::POST, "/echo/uppercase") => {
            let mapping = req.into_body().map(|chunk| {
                chunk
                    .iter()
                    .map(|byte| byte.to_ascii_uppercase())
                    .collect::<Vec<u8>>()
            });

            *response.body_mut() = Body::wrap_stream(mapping);
        }
        (&Method::POST, "/echo/reversed") => {
            let reversed = req.into_body().concat2().map(move |chunk| {
                let body = chunk.iter().rev().cloned().collect::<Vec<u8>>();
                *response.body_mut() = Body::from(body);
                response
            });

            return Box::new(reversed);
        }
        _ => {
            *response.status_mut() = StatusCode::NOT_FOUND;
        }
    };

    Box::new(future::ok(response))
}

fn main() {
    let addr = ([127, 0, 0, 1], 3000).into();

    let server = Server::bind(&addr)
        .serve(|| service_fn(echo))
        .map_err(|e| eprintln!("server error: {}", e));

    println!("The magic happens on port {}", addr.port());
    hyper::rt::run(server);
}
<commit_msg>docs(examples): add comments to the echo example<commit_after>extern crate futures;
extern crate hyper;

use futures::future;
use hyper::rt::{Future, Stream};
use hyper::service::service_fn;
use hyper::{Body, Method, Request, Response, Server, StatusCode};

/// We need to return different futures depending on the route matched,
/// and we can do that with an enum, such as `futures::Either`, or with
/// trait objects.
///
/// A boxed Future (trait object) is used as it is easier to understand
/// and extend with more types. Advanced users could switch to `Either`.
type BoxFut = Box<Future<Item = Response<Body>, Error = hyper::Error> + Send>;

/// This is our service handler. It receives a Request, routes on its
/// path, and returns a Future of a Response.
fn echo(req: Request<Body>) -> BoxFut {
    let mut response = Response::new(Body::empty());

    match (req.method(), req.uri().path()) {
        // Serve some instructions at /
        (Method::GET, "/") => {
            *response.body_mut() = Body::from("Try POSTing data to /echo");
        }

        // Simply echo the body back to the client.
        (Method::POST, "/echo") => {
            *response.body_mut() = req.into_body();
        }

        // Convert to uppercase before sending back to client.
        (Method::POST, "/echo/uppercase") => {
            let mapping = req.into_body().map(|chunk| {
                chunk
                    .iter()
                    .map(|byte| byte.to_ascii_uppercase())
                    .collect::<Vec<u8>>()
            });

            *response.body_mut() = Body::wrap_stream(mapping);
        }

        // Reverse the entire body before sending back to the client.
        //
        // Since we don't know the end yet, we can't simply stream
        // the chunks as they arrive. So, this returns a different
        // future, waiting on concatenating the full body, so that
        // it can be reversed. Only then can we return a `Response`.
        (Method::POST, "/echo/reversed") => {
            let reversed = req.into_body().concat2().map(move |chunk| {
                let body = chunk.iter().rev().cloned().collect::<Vec<u8>>();
                *response.body_mut() = Body::from(body);
                response
            });

            return Box::new(reversed);
        }

        // The 404 Not Found route...
        _ => {
            *response.status_mut() = StatusCode::NOT_FOUND;
        }
    };

    Box::new(future::ok(response))
}

fn main() {
    let addr = ([127, 0, 0, 1], 3000).into();

    let server = Server::bind(&addr)
        .serve(|| service_fn(echo))
        .map_err(|e| eprintln!("server error: {}", e));

    println!("Listening on http://{}", addr);
    hyper::rt::run(server);
}
<|endoftext|>


<commit_before>extern crate minifb;

use minifb::{Window, Key, Scale, WindowOptions, Menu, MenuItem};
use minifb::{MENU_KEY_COMMAND, MENU_KEY_CTRL};

const WIDTH: usize = 640;
const HEIGHT: usize = 360;

/*
const MENU_TEST_ID: usize = 1;
const OTHER_MENU_ID: usize = 2;
const COLOR_0_ID: usize = 3;
const COLOR_1_ID: usize = 4;
const COLOR_2_ID: usize = 5;
const CLOSE_MENU_ID: usize = 6;
*/

fn main() {
    let mut buffer: Vec<u32> = vec![0; WIDTH * HEIGHT];

    let mut window = Window::new("Noise Test - Press ESC to exit",
                                 WIDTH,
                                 HEIGHT,
                                 WindowOptions {
                                     resize: true,
                                     scale: Scale::X2,
                                     ..WindowOptions::default()
                                 })
                         .expect("Unable to Open Window");

    // Setup a sub menu

    /*
    let sub_menu = vec![
        Menu {
            name: "Color 0",
            key: Key::F1,
            id: COLOR_0_ID,
            ..Menu::default()
        },
        Menu {
            name: "Color 1",
            key: Key::F2,
            id: COLOR_1_ID,
            ..Menu::default()
        },
        Menu {
            name: "Color 2",
            key: Key::F12,
            id: COLOR_2_ID,
            ..Menu::default()
        },
    ];

    // Main menu

    let menu = vec![
        Menu {
            name: "Menu Test",
            key: Key::W,
            id: MENU_TEST_ID,
            modifier: MENU_KEY_CTRL,
            mac_mod: MENU_KEY_COMMAND,
            ..Menu::default()
        },
        Menu::separotor(),
        Menu {
            name: "Other menu!",
            key: Key::S,
            modifier: MENU_KEY_CTRL,
            mac_mod: MENU_KEY_CTRL,
            id: OTHER_MENU_ID,
            ..Menu::default()
        },
        Menu {
            name: "Remove Menu",
            key: Key::R,
            id: CLOSE_MENU_ID,
            ..Menu::default()
        },
        Menu {
            name: "Select Color",
            sub_menu: Some(&sub_menu),
            ..Menu::default()
        }
    ];
    */

    //window.add_menu("Test", &menu).expect("Unable to add menu");

    let mut menu = Menu::new("TestMenu").unwrap();
    let mut sub = Menu::new("SubMenu").unwrap();

    menu.add_menu_item(&MenuItem::new("Item 1", 1).shortcut(Key::S, 0));
    menu.add_menu_item(&MenuItem::new("Item 2", 2));
    menu.add_menu_item(&MenuItem::new("Item 3", 3));

    sub.add_item("Test", 0).build();
    sub.add_item("Test 2", 0).build();

    menu.add_item("", 0).separator().build();
    menu.add_item("Some item", 2).shortcut(Key::Y, MENU_KEY_CTRL).build();

    menu.add_sub_menu("Sub Test", &sub);

    let _ = window.add_menu(&menu);

    let color_mul = 1;

    while window.is_open() && !window.is_key_down(Key::Escape) {
        for y in 0..HEIGHT {
            for x in 0..WIDTH {
                buffer[(y * WIDTH) + x] = (((x ^ y) & 0xff) * color_mul) as u32;
            }
        }

        /*
        window.is_menu_pressed().map(|menu_id| {
            match menu_id {
                COLOR_0_ID => {
                    color_mul = 0xfe0000;
                }
                COLOR_1_ID => {
                    color_mul = 0xff00;
                }
                COLOR_2_ID => {
                    color_mul = 1;
                }
                CLOSE_MENU_ID => {
                    println!("remove menu");
                    //window.remove_menu("Test").expect("Unable to remove menu");
                }
                _ => (),
            }

            println!("Menu id {} pressed", menu_id);
        });
        */

        window.get_keys().map(|keys| {
            for t in keys {
                match t {
                    Key::W => println!("holding w!"),
                    Key::T => println!("holding t!"),
                    _ => (),
                }
            }
        });

        window.update_with_buffer(&buffer);
    }
}
<commit_msg>Restored f-keys so the work again<commit_after>extern crate minifb;

use minifb::{Window, Key, Scale, WindowOptions, Menu, MenuItem};
use minifb::{MENU_KEY_COMMAND, MENU_KEY_CTRL};

const WIDTH: usize = 640;
const HEIGHT: usize = 360;

const MENU_TEST_ID: usize = 1;
const OTHER_MENU_ID: usize = 2;
const COLOR_0_ID: usize = 3;
const COLOR_1_ID: usize = 4;
const COLOR_2_ID: usize = 5;
const CLOSE_MENU_ID: usize = 6;

fn main() {
    let mut buffer: Vec<u32> = vec![0; WIDTH * HEIGHT];

    let mut window = Window::new("Noise Test - Press ESC to exit",
                                 WIDTH,
                                 HEIGHT,
                                 WindowOptions {
                                     resize: true,
                                     scale: Scale::X2,
                                     ..WindowOptions::default()
                                 })
                         .expect("Unable to Open Window");

    let mut menu = Menu::new("Test").unwrap();
    let mut sub = Menu::new("Select Color").unwrap();

    sub.add_item("Color 0", COLOR_0_ID).shortcut(Key::F1, 0).build();
    sub.add_item("Color 1", COLOR_1_ID).shortcut(Key::F2, 0).build();
    sub.add_item("Color 2", COLOR_2_ID).shortcut(Key::F7, 0).build();

    menu.add_item("Menu Test", MENU_TEST_ID).shortcut(Key::W, MENU_KEY_CTRL).build();
    menu.add_separator();
    menu.add_item("Other Menu", OTHER_MENU_ID).shortcut(Key::W, MENU_KEY_CTRL).build();
    menu.add_item("Remove Menu", CLOSE_MENU_ID).shortcut(Key::R, 0).build();

    menu.add_sub_menu("Sub Test", &sub);

    let _ = window.add_menu(&menu);

    let mut color_mul = 1;

    while window.is_open() && !window.is_key_down(Key::Escape) {
        for y in 0..HEIGHT {
            for x in 0..WIDTH {
                buffer[(y * WIDTH) + x] = (((x ^ y) & 0xff) * color_mul) as u32;
            }
        }

        window.is_menu_pressed().map(|menu_id| {
            match menu_id {
                COLOR_0_ID => {
                    color_mul = 0xfe0000;
                }
                COLOR_1_ID => {
                    color_mul = 0xff00;
                }
                COLOR_2_ID => {
                    color_mul = 1;
                }
                CLOSE_MENU_ID => {
                    println!("remove menu");
                    //window.remove_menu(
                }
                _ => (),
            }

            println!("Menu id {} pressed", menu_id);
        });

        window.get_keys().map(|keys| {
            for t in keys {
                match t {
                    Key::W => println!("holding w!"),
                    Key::T => println!("holding t!"),
                    _ => (),
                }
            }
        });

        window.update_with_buffer(&buffer);
    }
}
<|endoftext|>


<commit_before>extern crate rsoundio;
extern crate rb;

use rb::{RB, SpscRb, RbProducer, RbConsumer};
use std::f32::consts::PI as PI32;
use std::thread;
use std::time::Duration;

fn main() {
    let rb = SpscRb::new(4096);
    let (producer, consumer) = (rb.producer(), rb.consumer());
    // create an audio context
    let mut sio = rsoundio::SoundIo::new();
    sio.set_name("rsoundio-example").unwrap();
    // connect to the default audio backend
    sio.connect().unwrap();
    let backend = sio.current_backend().unwrap();
    println!("Connected to backend: {}", backend);
    sio.flush_events();
    // get default output device
    let dev = sio.default_output_device().unwrap();
    assert!(dev.probe_error().is_none());
    println!("Using output device: {}", dev);
    // create output stream
    let mut out = dev.create_outstream().unwrap();
    assert!(out.set_name("sine").is_ok());
    out.set_format(rsoundio::SioFormat::Float32LE).unwrap();
    println!("Output format: {}", out.format().unwrap());

    thread::spawn(move || {
        const LEN: usize = 1024;
        let mut pos = 0;
        loop {
            const f: f32 = 440.0;
            const w: f32 = 2.0 * f * PI32 / 48_000.0;
            const a: f32 = 0.6;
            const cycle: usize = (48_000f32 / f) as usize;

            let samples: Vec<f32> = (0..LEN)
                                        .map(|i| (w * (i + pos) as f32).sin() * a)
                                        .collect();
            producer.write_blocking(&samples).unwrap();
            pos = (pos + LEN) % cycle;
        }
    });

    // register callbacks
    out.register_write_callback(|out: rsoundio::OutStream,
                                 min_frame_count: u32,
                                 max_frame_count: u32| {
        const BUF_SIZE: usize = 2048;
        let mut data = vec![0.0f32; BUF_SIZE];
        let len = if backend != rsoundio::SioBackend::PulseAudio {
            ::std::cmp::min(BUF_SIZE, max_frame_count as usize)
        } else {
            BUF_SIZE
        };
        consumer.read_blocking(&mut data[..len]);
        let frames = vec![data[..len].iter().cloned().collect(),
                          data[..len].iter().cloned().collect()];
        out.write_stream_f32(min_frame_count, &frames).unwrap();
    });
    out.register_underflow_callback(|out: rsoundio::OutStream| {
        println!("Underflow in {} occured!", out.name().unwrap())
    });
    out.register_error_callback(|out: rsoundio::OutStream, err: rsoundio::SioError| {
        println!("{} error: {}", out.name().unwrap(), err)
    });

    // open output stream
    out.open().unwrap();
    let sr = out.sample_rate();
    println!("Sample rate: {}", sr);

    match out.latency() {
        Ok(latency) => println!("SW latency: {}", latency),
        Err(err) => println!("err: {}", err),
    }
    let layout = out.layout();
    println!("Output channel layout: {}", layout);
    // start audio output (now the `write_callback` will be called periodically)
    out.start().unwrap();
    thread::sleep(Duration::new(3, 0));
    println!("Pause for 1s");
    out.pause();
    thread::sleep(Duration::new(1, 0));
    println!("Unpausing");
    out.unpause();
    thread::sleep(Duration::new(3, 0));
}
<commit_msg>Use uppercase identifiers for constants<commit_after>extern crate rsoundio;
extern crate rb;

use rb::{RB, SpscRb, RbProducer, RbConsumer};
use std::f32::consts::PI as PI32;
use std::thread;
use std::time::Duration;

fn main() {
    let rb = SpscRb::new(4096);
    let (producer, consumer) = (rb.producer(), rb.consumer());
    // create an audio context
    let mut sio = rsoundio::SoundIo::new();
    sio.set_name("rsoundio-example").unwrap();
    // connect to the default audio backend
    sio.connect().unwrap();
    let backend = sio.current_backend().unwrap();
    println!("Connected to backend: {}", backend);
    sio.flush_events();
    // get default output device
    let dev = sio.default_output_device().unwrap();
    assert!(dev.probe_error().is_none());
    println!("Using output device: {}", dev);
    // create output stream
    let mut out = dev.create_outstream().unwrap();
    assert!(out.set_name("sine").is_ok());
    out.set_format(rsoundio::SioFormat::Float32LE).unwrap();
    println!("Output format: {}", out.format().unwrap());

    thread::spawn(move || {
        const LEN: usize = 1024;
        let mut pos = 0;
        loop {
            const F: f32 = 440.0;
            const W: f32 = 2.0 * F * PI32 / 48_000.0;
            const A: f32 = 0.6;
            const CYCLE: usize = (48_000f32 / F) as usize;

            let samples: Vec<f32> = (0..LEN)
                                        .map(|i| (W * (i + pos) as f32).sin() * A)
                                        .collect();
            producer.write_blocking(&samples).unwrap();
            pos = (pos + LEN) % CYCLE;
        }
    });

    // register callbacks
    out.register_write_callback(|out: rsoundio::OutStream,
                                 min_frame_count: u32,
                                 max_frame_count: u32| {
        const BUF_SIZE: usize = 2048;
        let mut data = vec![0.0f32; BUF_SIZE];
        let len = if backend != rsoundio::SioBackend::PulseAudio {
            ::std::cmp::min(BUF_SIZE, max_frame_count as usize)
        } else {
            BUF_SIZE
        };
        consumer.read_blocking(&mut data[..len]);
        let frames = vec![data[..len].iter().cloned().collect(),
                          data[..len].iter().cloned().collect()];
        out.write_stream_f32(min_frame_count, &frames).unwrap();
    });
    out.register_underflow_callback(|out: rsoundio::OutStream| {
        println!("Underflow in {} occured!", out.name().unwrap())
    });
    out.register_error_callback(|out: rsoundio::OutStream, err: rsoundio::SioError| {
        println!("{} error: {}", out.name().unwrap(), err)
    });

    // open output stream
    out.open().unwrap();
    let sr = out.sample_rate();
    println!("Sample rate: {}", sr);

    match out.latency() {
        Ok(latency) => println!("SW latency: {}", latency),
        Err(err) => println!("err: {}", err),
    }
    let layout = out.layout();
    println!("Output channel layout: {}", layout);
    // start audio output (now the `write_callback` will be called periodically)
    out.start().unwrap();
    thread::sleep(Duration::new(3, 0));
    println!("Pause for 1s");
    out.pause();
    thread::sleep(Duration::new(1, 0));
    println!("Unpausing");
    out.unpause();
    thread::sleep(Duration::new(3, 0));
}
<|endoftext|>


<commit_before>// This is a buggy quick sort implementation, QuickCheck will find the bug for you

extern crate quickcheck;

use quickcheck::quickcheck;

fn smaller_than<T: Clone + Ord>(xs: &[T], pivot: &T) -> Vec<T> {
    return xs.iter().filter(|&x| *x < *pivot).map(|x| x.clone()).collect();
}

fn larger_than<T: Clone + Ord>(xs: &[T], pivot: &T) -> Vec<T> {
    return xs.iter().filter(|&x| *x > *pivot).map(|x| x.clone()).collect();
}

fn sortk<T: Clone + Ord>(x: &T, xs: &[T]) -> Vec<T> {
    let mut result : Vec<T> = sort(smaller_than(xs, x).as_slice());
    let last_part = sort(larger_than(xs, x).as_slice());
    result.push(x.clone());
    result.extend(last_part.iter().map(|x| x.clone()));
    result
}

fn sort<T: Clone + Ord>(list: &[T]) -> Vec<T> {
    match list {
        [] => vec!(),
        [ref x, ..xs] => sortk(x, xs)
    }
}

fn main() {
    fn is_sorted(xs: Vec<int>) -> bool {
        for win in xs.as_slice().windows(2) {
            if win[0] > win[1] {
                return false
            }
        }
        true
    }

    fn keeps_length(xs: Vec<int>) -> bool {
        xs.len() == sort(xs.as_slice()).len()
    }
    quickcheck(keeps_length);

    quickcheck(is_sorted)
}
<commit_msg>Update bitrotten pr #10.<commit_after>// This is a buggy quick sort implementation, QuickCheck will find the bug for you

extern crate quickcheck;

use quickcheck::quickcheck;

fn smaller_than<T: Clone + Ord>(xs: &[T], pivot: &T) -> Vec<T> {
    return xs.iter().filter(|&x| *x < *pivot).map(|x| x.clone()).collect();
}

fn larger_than<T: Clone + Ord>(xs: &[T], pivot: &T) -> Vec<T> {
    return xs.iter().filter(|&x| *x > *pivot).map(|x| x.clone()).collect();
}

fn sortk<T: Clone + Ord>(x: &T, xs: &[T]) -> Vec<T> {
    let mut result : Vec<T> = sort(smaller_than(xs, x).as_slice());
    let last_part = sort(larger_than(xs, x).as_slice());
    result.push(x.clone());
    result.extend(last_part.iter().map(|x| x.clone()));
    result
}

fn sort<T: Clone + Ord>(list: &[T]) -> Vec<T> {
    if list.is_empty() {
        vec![]
    } else {
        sortk(&list[0], list.tail())
    }
}

fn main() {
    fn is_sorted(xs: Vec<int>) -> bool {
        for win in xs.as_slice().windows(2) {
            if win[0] > win[1] {
                return false
            }
        }
        true
    }

    fn keeps_length(xs: Vec<int>) -> bool {
        xs.len() == sort(xs.as_slice()).len()
    }
    quickcheck(keeps_length);

    quickcheck(is_sorted)
}
<|endoftext|>


<commit_before><commit_msg>Use `RtlGenRandom` on Windows<commit_after><|endoftext|>


<commit_before>//! This example demonstrates how to use `Text` to draw TrueType font texts efficiently.

use ggez::glam::Vec2;
use ggez::graphics::{self, Color, PxScale, Text, TextAlign, TextFragment};
use ggez::timer;
use ggez::{
    conf::{WindowMode, WindowSetup},
    graphics::Drawable,
};
use ggez::{event, graphics::TextLayout};
use ggez::{Context, ContextBuilder, GameResult};
use std::collections::BTreeMap;
use std::env;
use std::path;

/// Creates a random RGB color.
fn random_color(rng: &mut oorandom::Rand32) -> Color {
    Color::new(rng.rand_float(), rng.rand_float(), rng.rand_float(), 1.0)
}

struct App {
    // Doesn't have to be a `BTreeMap`; it's handy if you care about specific elements,
    // want to retrieve them by trivial handles, and have to preserve ordering.
    texts: BTreeMap<&'static str, Text>,
    rng: oorandom::Rand32,
}

impl App {
    #[allow(clippy::needless_update)]
    fn new(ctx: &mut Context) -> GameResult<App> {
        let mut texts = BTreeMap::new();

        // We just use a fixed RNG seed for simplicity.
        let mut rng = oorandom::Rand32::new(314159);

        // This is the simplest way to create a drawable text;
        // the color, font, and scale will be default: white, LiberationMono-Regular, 16px unform.
        // Note that you don't even have to load a font: LiberationMono-Regular is baked into `ggez` itself.
        let text = Text::new("Hello, World!");
        // Store the text in `App`s map, for drawing in main loop.
        texts.insert("0_hello", text);

        // This is what actually happens in `Text::new()`: the `&str` gets
        // automatically converted into a `TextFragment`.
        let mut text = Text::new(TextFragment {
            // `TextFragment` stores a string, and optional parameters which will override those
            // of `Text` itself. This allows inlining differently formatted lines, words,
            // or even individual letters, into the same block of text.
            text: "Small red fragment".to_string(),
            color: Some(Color::new(1.0, 0.0, 0.0, 1.0)),
            // The font name refers to a loaded TTF, stored inside the `GraphicsContext`.
            // A default font always exists and maps to LiberationMono-Regular.
            font: Some("LiberationMono-Regular".into()),
            scale: Some(PxScale::from(10.0)),
            // This doesn't do anything at this point; can be used to omit fields in declarations.
            ..Default::default()
        });

        // More fragments can be appended at any time.
        text.add(" default fragment, should be long enough to showcase everything")
            // `add()` can be chained, along with most `Text` methods.
            .add(TextFragment::new(" magenta fragment").color(Color::new(1.0, 0.0, 1.0, 1.0)))
            .add(" another default fragment, to really drive the point home");

        // This loads a new TrueType font into the context named "Fancy font".
        ctx.gfx.add_font(
            "Fancy font",
            graphics::FontData::from_path(ctx, "/Tangerine_Regular.ttf")?,
        );

        // `Font` is really only an integer handle, and can be copied around.
        text.add(
            TextFragment::new(" fancy fragment")
                .font("Fancy font")
                .scale(PxScale::from(25.0)),
        )
        .add(" and a default one, for symmetry");
        // Store a copy of the built text, retain original for further modifications.
        texts.insert("1_demo_text_1", text.clone());

        // Text can be wrapped by setting it's bounds, in screen coordinates;
        // vertical bound will cut off the extra off the bottom.
        // Alignment within the bounds can be set by `Align` enum.
        text.set_bounds(Vec2::new(400.0, f32::INFINITY))
            .set_layout(TextLayout {
                h_align: TextAlign::Begin,
                v_align: TextAlign::Begin,
            });
        texts.insert("1_demo_text_2", text.clone());

        text.set_bounds(Vec2::new(500.0, f32::INFINITY))
            .set_layout(TextLayout {
                h_align: TextAlign::Begin,
                v_align: TextAlign::Begin,
            });
        texts.insert("1_demo_text_3", text.clone());

        // This can be used to set the font and scale unformatted fragments will use.
        // Color is specified when drawing, via `DrawParam`.
        // Side note: TrueType fonts aren't very consistent between themselves in terms
        // of apparent scale - this font with default scale will appear too small.
        text.set_font("Fancy font")
            .set_scale(16.0)
            .set_bounds(Vec2::new(300.0, f32::INFINITY))
            .set_layout(TextLayout {
                h_align: TextAlign::Middle,
                v_align: TextAlign::Begin,
            });
        texts.insert("1_demo_text_4", text);

        // These methods can be combined to easily create a variety of simple effects.
        let chroma_string = "Not quite a rainbow.";
        // `default()` exists pretty much specifically for this usecase.
        let mut chroma_text = Text::default();
        for ch in chroma_string.chars() {
            chroma_text.add(TextFragment::new(ch).color(random_color(&mut rng)));
        }
        texts.insert("2_rainbow", chroma_text);

        let wonky_string = "So, so wonky.";
        let mut wonky_text = Text::default();
        for ch in wonky_string.chars() {
            wonky_text
                .add(TextFragment::new(ch).scale(PxScale::from(10.0 + 24.0 * rng.rand_float())));
        }
        texts.insert("3_wonky", wonky_text);

        Ok(App { texts, rng })
    }
}

impl event::EventHandler<ggez::GameError> for App {
    fn update(&mut self, ctx: &mut Context) -> GameResult {
        const DESIRED_FPS: u32 = 60;
        while ctx.time.check_update_time(DESIRED_FPS) {}
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult {
        let mut canvas = graphics::Canvas::from_frame(ctx, Color::from([0.1, 0.2, 0.3, 1.0]));

        let fps = ctx.time.fps();
        let fps_display = Text::new(format!("FPS: {}", fps));
        // When drawing through these calls, `DrawParam` will work as they are documented.
        canvas.draw(
            &fps_display,
            graphics::DrawParam::from([200.0, 0.0]).color(Color::WHITE),
        );

        let mut height = 0.0;
        for (key, text) in self.texts.iter() {
            let x = if *key == "1_demo_text_4" { 250.0 } else { 20.0 };
            canvas.draw(text, Vec2::new(x, 20.0 + height));
            //height += 20.0 + text.height(ctx) as f32;
            height += 20.0 + text.dimensions(ctx).unwrap().h as f32;
        }

        // Individual fragments within the `Text` can be replaced;
        // this can be used for inlining animated sentences, words, etc.
        if let Some(text) = self.texts.get_mut("1_demo_text_3") {
            // `.fragments_mut()` returns a mutable slice of contained fragments.
            // Fragments are indexed in order of their addition, starting at 0 (of course).
            text.fragments_mut()[3].color = Some(random_color(&mut self.rng));
        }

        // Another animation example. Note, this is relatively inefficient as-is.
        let wobble_string = "WOBBLE";
        let mut wobble = Text::default();
        for ch in wobble_string.chars() {
            wobble.add(
                TextFragment::new(ch).scale(PxScale::from(10.0 + 6.0 * self.rng.rand_float())),
            );
        }
        let wobble_rect = wobble.dimensions(ctx).unwrap();
        canvas.draw(
            &wobble,
            graphics::DrawParam::new()
                .color((0.0, 1.0, 1.0, 1.0))
                .dest([500.0, 300.0])
                .rotation(-0.5),
        );
        let t = Text::new(format!(
            "width: {}\nheight: {}",
            wobble_rect.w, wobble_rect.h
        ));
        canvas.draw(&t, graphics::DrawParam::from([500.0, 320.0]).rotation(-0.5));

        canvas.finish(ctx)?;
        timer::yield_now();
        Ok(())
    }
}

pub fn main() -> GameResult {
    if cfg!(debug_assertions) && env::var("yes_i_really_want_debug_mode").is_err() {
        eprintln!(
            "Note: Release mode will improve performance greatly.\n    \
             e.g. use `cargo run --example text --release`"
        );
    }
    let resource_dir = if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
        let mut path = path::PathBuf::from(manifest_dir);
        path.push("resources");
        path
    } else {
        path::PathBuf::from("./resources")
    };

    let (mut ctx, events_loop) = ContextBuilder::new("text_cached", "ggez")
        .window_setup(WindowSetup::default().title("Cached text example!"))
        .window_mode(
            WindowMode::default()
                .dimensions(640.0, 480.0)
                .resizable(true),
        )
        .add_resource_path(resource_dir)
        .build()?;

    let state = App::new(&mut ctx)?;
    event::run(ctx, events_loop, state)
}
<commit_msg>Fixes text position<commit_after>//! This example demonstrates how to use `Text` to draw TrueType font texts efficiently.

use ggez::glam::Vec2;
use ggez::graphics::{self, Color, PxScale, Text, TextAlign, TextFragment};
use ggez::timer;
use ggez::{
    conf::{WindowMode, WindowSetup},
    graphics::Drawable,
};
use ggez::{event, graphics::TextLayout};
use ggez::{Context, ContextBuilder, GameResult};
use std::collections::BTreeMap;
use std::env;
use std::path;

/// Creates a random RGB color.
fn random_color(rng: &mut oorandom::Rand32) -> Color {
    Color::new(rng.rand_float(), rng.rand_float(), rng.rand_float(), 1.0)
}

struct App {
    // Doesn't have to be a `BTreeMap`; it's handy if you care about specific elements,
    // want to retrieve them by trivial handles, and have to preserve ordering.
    texts: BTreeMap<&'static str, Text>,
    rng: oorandom::Rand32,
}

impl App {
    #[allow(clippy::needless_update)]
    fn new(ctx: &mut Context) -> GameResult<App> {
        let mut texts = BTreeMap::new();

        // We just use a fixed RNG seed for simplicity.
        let mut rng = oorandom::Rand32::new(314159);

        // This is the simplest way to create a drawable text;
        // the color, font, and scale will be default: white, LiberationMono-Regular, 16px unform.
        // Note that you don't even have to load a font: LiberationMono-Regular is baked into `ggez` itself.
        let text = Text::new("Hello, World!");
        // Store the text in `App`s map, for drawing in main loop.
        texts.insert("0_hello", text);

        // This is what actually happens in `Text::new()`: the `&str` gets
        // automatically converted into a `TextFragment`.
        let mut text = Text::new(TextFragment {
            // `TextFragment` stores a string, and optional parameters which will override those
            // of `Text` itself. This allows inlining differently formatted lines, words,
            // or even individual letters, into the same block of text.
            text: "Small red fragment".to_string(),
            color: Some(Color::new(1.0, 0.0, 0.0, 1.0)),
            // The font name refers to a loaded TTF, stored inside the `GraphicsContext`.
            // A default font always exists and maps to LiberationMono-Regular.
            font: Some("LiberationMono-Regular".into()),
            scale: Some(PxScale::from(10.0)),
            // This doesn't do anything at this point; can be used to omit fields in declarations.
            ..Default::default()
        });

        // More fragments can be appended at any time.
        text.add(" default fragment, should be long enough to showcase everything")
            // `add()` can be chained, along with most `Text` methods.
            .add(TextFragment::new(" magenta fragment").color(Color::new(1.0, 0.0, 1.0, 1.0)))
            .add(" another default fragment, to really drive the point home");

        // This loads a new TrueType font into the context named "Fancy font".
        ctx.gfx.add_font(
            "Fancy font",
            graphics::FontData::from_path(ctx, "/Tangerine_Regular.ttf")?,
        );

        // `Font` is really only an integer handle, and can be copied around.
        text.add(
            TextFragment::new(" fancy fragment")
                .font("Fancy font")
                .scale(PxScale::from(25.0)),
        )
        .add(" and a default one, for symmetry");
        // Store a copy of the built text, retain original for further modifications.
        texts.insert("1_demo_text_1", text.clone());

        // Text can be wrapped by setting it's bounds, in screen coordinates;
        // vertical bound will cut off the extra off the bottom.
        // Alignment within the bounds can be set by `Align` enum.
        text.set_bounds(Vec2::new(400.0, f32::INFINITY))
            .set_layout(TextLayout {
                h_align: TextAlign::Begin,
                v_align: TextAlign::Begin,
            });
        texts.insert("1_demo_text_2", text.clone());

        text.set_bounds(Vec2::new(500.0, f32::INFINITY))
            .set_layout(TextLayout {
                h_align: TextAlign::End,
                v_align: TextAlign::Begin,
            });
        texts.insert("1_demo_text_3", text.clone());

        // This can be used to set the font and scale unformatted fragments will use.
        // Color is specified when drawing, via `DrawParam`.
        // Side note: TrueType fonts aren't very consistent between themselves in terms
        // of apparent scale - this font with default scale will appear too small.
        text.set_font("Fancy font")
            .set_scale(16.0)
            .set_bounds(Vec2::new(300.0, f32::INFINITY))
            .set_layout(TextLayout {
                h_align: TextAlign::Middle,
                v_align: TextAlign::Begin,
            });
        texts.insert("1_demo_text_4", text);

        // These methods can be combined to easily create a variety of simple effects.
        let chroma_string = "Not quite a rainbow.";
        // `default()` exists pretty much specifically for this usecase.
        let mut chroma_text = Text::default();
        for ch in chroma_string.chars() {
            chroma_text.add(TextFragment::new(ch).color(random_color(&mut rng)));
        }
        texts.insert("2_rainbow", chroma_text);

        let wonky_string = "So, so wonky.";
        let mut wonky_text = Text::default();
        for ch in wonky_string.chars() {
            wonky_text
                .add(TextFragment::new(ch).scale(PxScale::from(10.0 + 24.0 * rng.rand_float())));
        }
        texts.insert("3_wonky", wonky_text);

        Ok(App { texts, rng })
    }
}

impl event::EventHandler<ggez::GameError> for App {
    fn update(&mut self, ctx: &mut Context) -> GameResult {
        const DESIRED_FPS: u32 = 60;
        while ctx.time.check_update_time(DESIRED_FPS) {}
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult {
        let mut canvas = graphics::Canvas::from_frame(ctx, Color::from([0.1, 0.2, 0.3, 1.0]));

        let fps = ctx.time.fps();
        let fps_display = Text::new(format!("FPS: {}", fps));
        // When drawing through these calls, `DrawParam` will work as they are documented.
        canvas.draw(
            &fps_display,
            graphics::DrawParam::from([200.0, 0.0]).color(Color::WHITE),
        );

        let mut height = 0.0;
        for (key, text) in self.texts.iter() {
            let x = match *key {
                // (bounds position) + 20
                "1_demo_text_3" => 500.0 + 20.0,
                "1_demo_text_4" => (300.0 / 2.0) + 20.0,
                _ => 20.0,
            };
            canvas.draw(text, Vec2::new(x, 20.0 + height));
            //height += 20.0 + text.height(ctx) as f32;
            height += 20.0 + text.dimensions(ctx).unwrap().h as f32;
        }

        // Individual fragments within the `Text` can be replaced;
        // this can be used for inlining animated sentences, words, etc.
        if let Some(text) = self.texts.get_mut("1_demo_text_3") {
            // `.fragments_mut()` returns a mutable slice of contained fragments.
            // Fragments are indexed in order of their addition, starting at 0 (of course).
            text.fragments_mut()[3].color = Some(random_color(&mut self.rng));
        }

        // Another animation example. Note, this is relatively inefficient as-is.
        let wobble_string = "WOBBLE";
        let mut wobble = Text::default();
        for ch in wobble_string.chars() {
            wobble.add(
                TextFragment::new(ch).scale(PxScale::from(10.0 + 6.0 * self.rng.rand_float())),
            );
        }
        let wobble_rect = wobble.dimensions(ctx).unwrap();
        canvas.draw(
            &wobble,
            graphics::DrawParam::new()
                .color((0.0, 1.0, 1.0, 1.0))
                .dest([500.0, 300.0])
                .rotation(-0.5),
        );
        let t = Text::new(format!(
            "width: {}\nheight: {}",
            wobble_rect.w, wobble_rect.h
        ));
        canvas.draw(&t, graphics::DrawParam::from([500.0, 320.0]).rotation(-0.5));

        canvas.finish(ctx)?;
        timer::yield_now();
        Ok(())
    }
}

pub fn main() -> GameResult {
    if cfg!(debug_assertions) && env::var("yes_i_really_want_debug_mode").is_err() {
        eprintln!(
            "Note: Release mode will improve performance greatly.\n    \
             e.g. use `cargo run --example text --release`"
        );
    }
    let resource_dir = if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
        let mut path = path::PathBuf::from(manifest_dir);
        path.push("resources");
        path
    } else {
        path::PathBuf::from("./resources")
    };

    let (mut ctx, events_loop) = ContextBuilder::new("text_cached", "ggez")
        .window_setup(WindowSetup::default().title("Cached text example!"))
        .window_mode(
            WindowMode::default()
                .dimensions(640.0, 480.0)
                .resizable(true),
        )
        .add_resource_path(resource_dir)
        .build()?;

    let state = App::new(&mut ctx)?;
    event::run(ctx, events_loop, state)
}
<|endoftext|>


<commit_before>use super::*;

impl Editor {
    /// Convert an instruction to a motion (new coordinate)
    pub fn to_motion(&mut self, Inst(n, cmd): Inst) -> Option<(usize, usize)> {
        use super::Key::*;
        match cmd {
            Char('h') => Some(self.left(n.d())),
            Char('l') => Some(self.right(n.d())),
            Char('j') => Some(self.down(n.d())),
            Char('k') => Some(self.up(n.d())),
            Char('g') => Some((0, n.or(1) - 1)),
            Char('G') => Some((0, self.text.len() - 1)),
            Char('L') => Some(self.ln_end()),
            Char('H') => Some((0, self.y())),
            Char('t') => {

                                                   // ~v~ Optimize (sorry, Knuth)
                if let Some(o) = self.next_ocur(ch, n.d()) {
                    Some(o)
                } else {
                    None
                }
            },
            _ => None,
        }
    }
}
<commit_msg>Fix error<commit_after>use super::*;

impl Editor {
    /// Convert an instruction to a motion (new coordinate)
    pub fn to_motion(&mut self, Inst(n, cmd): Inst) -> Option<(usize, usize)> {
        use super::Key::*;
        match cmd {
            Char('h') => Some(self.left(n.d())),
            Char('l') => Some(self.right(n.d())),
            Char('j') => Some(self.down(n.d())),
            Char('k') => Some(self.up(n.d())),
            Char('g') => Some((0, n.or(1) - 1)),
            Char('G') => Some((0, self.text.len() - 1)),
            Char('L') => Some(self.ln_end()),
            Char('H') => Some((0, self.y())),
            Char('t') => {

                let ch = self.next_char();

                                                   // ~v~ Optimize (sorry, Knuth)
                if let Some(o) = self.next_ocur(ch, n.d()) {
                    Some(o)
                } else {
                    None
                }
            },
            _ => None,
        }
    }
}
<|endoftext|>