<commit_before>extern crate disasm6502;

#[test]
fn check_disasm() {
    let bytes = vec![0x05, 0x0B, 0x6C, 0x01, 0x02, 0x0A, 0xA2, 0xFF, 0x20, 0x02, 0xFD, 0x78, 0xD0, 0xFC, 0x1D, 0x05, 0x1E, 0x04, 0x15, 0x02, 0x96, 0xAB, 0x58, 0x61, 0x01, 0x91, 0xFB, 0x90];

    let instructions = disasm6502::from_array(&bytes).unwrap();

    for i in instructions.iter() {
        println!("{}", i);
    }
}

#[test]
fn check_disasm_file() {
    let instructions = disasm6502::from_file("tests/test_pattern.bin").unwrap();

    for i in instructions.iter() {
        let cc = if i.extra_cycle {
            format!("(*{}) ", i.cycles)
        } else {
            format!("({})  ", i.cycles)
        };

        let rr = if let Some(ref reg_read) = i.registers_read {
            let mut r_str = String::from(" Reads:[");
            for r in reg_read.iter() {
                r_str.push_str(format!("{}", r).as_str());
            }
            r_str.push_str("]");
            r_str.to_owned()
        } else {
            String::from("          ")
        };

        let rw = if let Some(ref reg_written) = i.registers_written {
            let mut r_str = String::from(" Writes:[");
            for r in reg_written.iter() {
                r_str.push_str(format!("{}", r).as_str());
            }
            r_str.push_str("]");
            r_str.to_owned()
        } else {
            String::from("")
        };

        let af = if let Some(ref aff_flags) = i.affected_flags {
            let mut f_str = String::from(" Affects:[");
            for f in aff_flags.iter() {
                f_str.push_str(format!("{}", f).as_str());
            }
            f_str.push_str("]");
            f_str.to_owned()
        } else {
            String::from("")
        };

        println!("{}{}{}{}{}", i, cc, rr, rw, af);
    }
}

#[test]
#[should_panic]
fn check_disasm_file_fail() {
    let _ = disasm6502::from_file("tests/foo").unwrap_or_else(|e| { panic!("{}", e); }); }

#[test]
fn check_relative_addressing() {
    const BEQ: u8 = 0xF0;

    // Test various relative addressing edge conditions
    struct RelativeTest {
        start: u16,
        bytes: &'static [u8],
        expect: u16
    };
    static TESTS: [RelativeTest; 60] = [
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0xFD], expect: 0xFFFF },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0xFE], expect: 0x0000 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0xFF], expect: 0x0001 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x00], expect: 0x0002 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x01], expect: 0x0003 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x02], expect: 0x0004 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x7D], expect: 0x007F },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x7E], expect: 0x0080 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x7F], expect: 0x0081 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x80], expect: 0xFF82 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x81], expect: 0xFF83 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x82], expect: 0xFF84 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0xFD], expect: 0x3FFF },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0xFE], expect: 0x4000 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0xFF], expect: 0x4001 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x00], expect: 0x4002 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x01], expect: 0x4003 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x02], expect: 0x4004 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x7D], expect: 0x407F },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x7E], expect: 0x4080 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x7F], expect: 0x4081 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x80], expect: 0x3F82 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x81], expect: 0x3F83 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x82], expect: 0x3F84 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0xFD], expect: 0x7FFE },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0xFE], expect: 0x7FFF },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0xFF], expect: 0x8000 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x00], expect: 0x8001 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x01], expect: 0x8002 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x02], expect: 0x8003 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x7D], expect: 0x807E },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x7E], expect: 0x807F },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x7F], expect: 0x8080 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x80], expect: 0x7F81 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x81], expect: 0x7F82 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x82], expect: 0x7f83 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0xFD], expect: 0x7FFF },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0xFE], expect: 0x8000 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0xFF], expect: 0x8001 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x00], expect: 0x8002 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x01], expect: 0x8003 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x02], expect: 0x8004 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x7D], expect: 0x807F },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x7E], expect: 0x8080 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x7F], expect: 0x8081 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x80], expect: 0x7F82 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x81], expect: 0x7F83 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x82], expect: 0x7F84 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0xFD], expect: 0xFFFE },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0xFE], expect: 0xFFFF },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0xFF], expect: 0x0000 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x00], expect: 0x0001 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x01], expect: 0x0002 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x02], expect: 0x0003 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x7D], expect: 0x007E },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x7E], expect: 0x007F },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x7F], expect: 0x0080 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x80], expect: 0xFF81 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x81], expect: 0xFF82 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x82], expect: 0xFF83 },
    ];

    for test in TESTS.iter() {
        // Disassemble the instruction
        let instructions = disasm6502::from_addr_array(&test.bytes, test.start).unwrap();
        assert_eq!(instructions.len(), 1);
        let disassembly = format!("{}", instructions.get(0).unwrap());
        // Extract the address of the branch target
        let address = u16::from_str_radix(
            disassembly
                .split_ascii_whitespace()
                .last()
                .unwrap()
                .trim_start_matches('$'),
            16,
        ).unwrap();
        // Confirm the relative address was applied correctly.
        assert_eq!(address, test.expect);
    }
}
<commit_msg>Fixed warning.<commit_after>extern crate disasm6502;

#[test]
fn check_disasm() {
    let bytes = vec![0x05, 0x0B, 0x6C, 0x01, 0x02, 0x0A, 0xA2, 0xFF, 0x20, 0x02, 0xFD, 0x78, 0xD0, 0xFC, 0x1D, 0x05, 0x1E, 0x04, 0x15, 0x02, 0x96, 0xAB, 0x58, 0x61, 0x01, 0x91, 0xFB, 0x90];

    let instructions = disasm6502::from_array(&bytes).unwrap();

    for i in instructions.iter() {
        println!("{}", i);
    }
}

#[test]
fn check_disasm_file() {
    let instructions = disasm6502::from_file("tests/test_pattern.bin").unwrap();

    for i in instructions.iter() {
        let cc = if i.extra_cycle {
            format!("(*{}) ", i.cycles)
        } else {
            format!("({})  ", i.cycles)
        };

        let rr = if let Some(ref reg_read) = i.registers_read {
            let mut r_str = String::from(" Reads:[");
            for r in reg_read.iter() {
                r_str.push_str(format!("{}", r).as_str());
            }
            r_str.push_str("]");
            r_str.to_owned()
        } else {
            String::from("          ")
        };

        let rw = if let Some(ref reg_written) = i.registers_written {
            let mut r_str = String::from(" Writes:[");
            for r in reg_written.iter() {
                r_str.push_str(format!("{}", r).as_str());
            }
            r_str.push_str("]");
            r_str.to_owned()
        } else {
            String::from("")
        };

        let af = if let Some(ref aff_flags) = i.affected_flags {
            let mut f_str = String::from(" Affects:[");
            for f in aff_flags.iter() {
                f_str.push_str(format!("{}", f).as_str());
            }
            f_str.push_str("]");
            f_str.to_owned()
        } else {
            String::from("")
        };

        println!("{}{}{}{}{}", i, cc, rr, rw, af);
    }
}

#[test]
#[should_panic]
fn check_disasm_file_fail() {
    let _ = disasm6502::from_file("tests/foo").unwrap_or_else(|e| { panic!("{}", e); }); }

#[test]
fn check_relative_addressing() {
    const BEQ: u8 = 0xF0;

    // Test various relative addressing edge conditions
    struct RelativeTest {
        start: u16,
        bytes: &'static [u8],
        expect: u16
    }
    static TESTS: [RelativeTest; 60] = [
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0xFD], expect: 0xFFFF },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0xFE], expect: 0x0000 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0xFF], expect: 0x0001 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x00], expect: 0x0002 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x01], expect: 0x0003 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x02], expect: 0x0004 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x7D], expect: 0x007F },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x7E], expect: 0x0080 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x7F], expect: 0x0081 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x80], expect: 0xFF82 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x81], expect: 0xFF83 },
        RelativeTest { start: 0x0000, bytes: &[BEQ, 0x82], expect: 0xFF84 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0xFD], expect: 0x3FFF },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0xFE], expect: 0x4000 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0xFF], expect: 0x4001 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x00], expect: 0x4002 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x01], expect: 0x4003 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x02], expect: 0x4004 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x7D], expect: 0x407F },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x7E], expect: 0x4080 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x7F], expect: 0x4081 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x80], expect: 0x3F82 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x81], expect: 0x3F83 },
        RelativeTest { start: 0x4000, bytes: &[BEQ, 0x82], expect: 0x3F84 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0xFD], expect: 0x7FFE },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0xFE], expect: 0x7FFF },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0xFF], expect: 0x8000 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x00], expect: 0x8001 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x01], expect: 0x8002 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x02], expect: 0x8003 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x7D], expect: 0x807E },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x7E], expect: 0x807F },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x7F], expect: 0x8080 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x80], expect: 0x7F81 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x81], expect: 0x7F82 },
        RelativeTest { start: 0x7FFF, bytes: &[BEQ, 0x82], expect: 0x7f83 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0xFD], expect: 0x7FFF },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0xFE], expect: 0x8000 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0xFF], expect: 0x8001 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x00], expect: 0x8002 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x01], expect: 0x8003 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x02], expect: 0x8004 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x7D], expect: 0x807F },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x7E], expect: 0x8080 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x7F], expect: 0x8081 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x80], expect: 0x7F82 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x81], expect: 0x7F83 },
        RelativeTest { start: 0x8000, bytes: &[BEQ, 0x82], expect: 0x7F84 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0xFD], expect: 0xFFFE },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0xFE], expect: 0xFFFF },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0xFF], expect: 0x0000 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x00], expect: 0x0001 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x01], expect: 0x0002 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x02], expect: 0x0003 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x7D], expect: 0x007E },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x7E], expect: 0x007F },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x7F], expect: 0x0080 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x80], expect: 0xFF81 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x81], expect: 0xFF82 },
        RelativeTest { start: 0xFFFF, bytes: &[BEQ, 0x82], expect: 0xFF83 },
    ];

    for test in TESTS.iter() {
        // Disassemble the instruction
        let instructions = disasm6502::from_addr_array(&test.bytes, test.start).unwrap();
        assert_eq!(instructions.len(), 1);
        let disassembly = format!("{}", instructions.get(0).unwrap());
        // Extract the address of the branch target
        let address = u16::from_str_radix(
            disassembly
                .split_ascii_whitespace()
                .last()
                .unwrap()
                .trim_start_matches('$'),
            16,
        ).unwrap();
        // Confirm the relative address was applied correctly.
        assert_eq!(address, test.expect);
    }
}
<|endoftext|>


<commit_before>extern crate codespawn;

#[test]
fn check_from_xml() {
    let raw_code = codespawn::from_xml("examples/sample.xml").unwrap();

    for c in raw_code.configs.iter() {
        println!("{}", c.1);
    }

    println!("{}", raw_code);
    println!("{}", raw_code.to_cpp());
    println!("{}", raw_code.to_rust());

    // save to .rst file instead of .rs so that subsequent test don't get confused
    let _ = raw_code.to_rust().to_file("tests/sample.rst");
    let _ = raw_code.to_cpp().to_file("tests/sample.cpp");
}

#[test]
fn check_from_json() {
    let raw_code = codespawn::from_json("examples/sample.json").unwrap();

    for c in raw_code.configs.iter() {
        println!("{}", c.1);
    }

    println!("{}", raw_code);
    println!("{}", raw_code.to_cpp());
    println!("{}", raw_code.to_rust());

    // save to .rst file instead of .rs so that subsequent test don't get confused
    let _ = raw_code.to_rust().to_file("tests/sample.rst");
    let _ = raw_code.to_cpp().to_file("tests/sample.cpp");
}

#[test]
#[should_panic]
fn check_from_xml_fail() {
    let _ = codespawn::from_xml("foobar").unwrap(); }

#[test]
#[should_panic]
fn check_from_json_fail() {
    let _ = codespawn::from_json("foobar").unwrap(); }

#[test]
#[should_panic]
fn check_from_xml_fail_cfg() {
    let _ = codespawn::from_xml_str("<config file=\"foobar\"/><var name=\"x\" type=\"int\"/>").unwrap(); }

#[test]
#[should_panic]
fn check_from_json_fail_cfg() {
    let _ = codespawn::from_json_str("{\"config\": { \"file\": \"foobar\" }, \"var\": {\"name\": \"x\", \"type\":\"int\" }}").unwrap(); }

#[test]
#[should_panic]
fn check_from_xml_fail_malformed() {
    let _ = codespawn::from_xml_str("<config file=\"foobar\"/>var name=\"x\" type=\"int\"/>").unwrap(); }

#[test]
#[should_panic]
fn check_from_json_fail_malformed() {
    let _ = codespawn::from_json_str("{\"config\": { \"file\": \"examples/rust.json\" } \"var\": {\"name\": \"x\", \"type\":\"int\" }}").unwrap(); }

#[test]
#[should_panic]
fn check_from_xml_fail_enum() {
    let rc = codespawn::from_xml_str("<enum name=\"Foo\"><func name=\"x\" type=\"int\"/></enum>").unwrap();
    rc.to_rust().to_string(); }

#[test]
#[should_panic]
fn check_from_json_fail_enum() {
    let rc = codespawn::from_json_str("{\"enum\":{ \"name\":\"Foo\",\"func\": { \"name\":\"x\",\"type\":\"int\"}}}").unwrap();
    rc.to_cpp().to_string(); }

#[test]
#[should_panic]
fn check_from_xml_fail_func() {
    let rc = codespawn::from_xml_str("<func name=\"x\" type=\"int\"><enum name=\"Foo\"></enum></func>").unwrap();
    rc.to_rust().to_string(); }

#[test]
#[should_panic]
fn check_from_json_fail_func() {
    let rc = codespawn::from_json_str("{\"func\": {\"name\":\"x\",\"type\":\"int\",\"enum\": {\"name\":\"Foo\"}}}").unwrap();
    rc.to_cpp().to_string(); }

#[test]
#[should_panic]
fn check_from_xml_fail_malformed_cfg() {
    let _ = codespawn::from_xml_str("<config file=\"tests/malformed_cfg.xml\"/><var name=\"x\" type=\"int\"/>").unwrap(); }

#[test]
#[should_panic]
fn check_write_file() {
    let raw_code = codespawn::from_xml("examples/sample.xml").unwrap();
    raw_code.to_cpp().to_file("").unwrap(); }
<commit_msg>added tests for bitflags<commit_after>extern crate codespawn;

#[test]
fn check_from_xml() {
    let raw_code = codespawn::from_xml("examples/sample.xml").unwrap();

    for c in raw_code.configs.iter() {
        println!("{}", c.1);
    }

    println!("{}", raw_code);
    println!("{}", raw_code.to_cpp());
    println!("{}", raw_code.to_rust());

    // save to .rst file instead of .rs so that subsequent test don't get confused
    let _ = raw_code.to_rust().to_file("tests/sample.rst");
    let _ = raw_code.to_cpp().to_file("tests/sample.cpp");
}

#[test]
fn check_from_json() {
    let raw_code = codespawn::from_json("examples/sample.json").unwrap();

    for c in raw_code.configs.iter() {
        println!("{}", c.1);
    }

    println!("{}", raw_code);
    println!("{}", raw_code.to_cpp());
    println!("{}", raw_code.to_rust());

    // save to .rst file instead of .rs so that subsequent test don't get confused
    let _ = raw_code.to_rust().to_file("tests/sample.rst");
    let _ = raw_code.to_cpp().to_file("tests/sample.cpp");
}

#[test]
#[should_panic]
fn check_from_xml_fail() {
    let _ = codespawn::from_xml("foobar").unwrap(); }

#[test]
#[should_panic]
fn check_from_json_fail() {
    let _ = codespawn::from_json("foobar").unwrap(); }

#[test]
#[should_panic]
fn check_from_xml_fail_cfg() {
    let _ = codespawn::from_xml_str("<config file=\"foobar\"/><var name=\"x\" type=\"int\"/>").unwrap(); }

#[test]
#[should_panic]
fn check_from_json_fail_cfg() {
    let _ = codespawn::from_json_str("{\"config\": { \"file\": \"foobar\" }, \"var\": {\"name\": \"x\", \"type\":\"int\" }}").unwrap(); }

#[test]
#[should_panic]
fn check_from_xml_fail_malformed() {
    let _ = codespawn::from_xml_str("<config file=\"foobar\"/>var name=\"x\" type=\"int\"/>").unwrap(); }

#[test]
#[should_panic]
fn check_from_json_fail_malformed() {
    let _ = codespawn::from_json_str("{\"config\": { \"file\": \"examples/rust.json\" } \"var\": {\"name\": \"x\", \"type\":\"int\" }}").unwrap(); }

#[test]
#[should_panic]
fn check_from_xml_fail_enum() {
    let rc = codespawn::from_xml_str("<enum name=\"Foo\"><func name=\"x\" type=\"int\"/></enum>").unwrap();
    rc.to_rust().to_string(); }

#[test]
#[should_panic]
fn check_from_json_fail_enum() {
    let rc = codespawn::from_json_str("{\"enum\":{ \"name\":\"Foo\",\"func\": { \"name\":\"x\",\"type\":\"int\"}}}").unwrap();
    rc.to_cpp().to_string(); }

#[test]
#[should_panic]
fn check_from_xml_fail_func() {
    let rc = codespawn::from_xml_str("<func name=\"x\" type=\"int\"><enum name=\"Foo\"></enum></func>").unwrap();
    rc.to_rust().to_string(); }

#[test]
#[should_panic]
fn check_from_json_fail_func() {
    let rc = codespawn::from_json_str("{\"func\": {\"name\":\"x\",\"type\":\"int\",\"enum\": {\"name\":\"Foo\"}}}").unwrap();
    rc.to_cpp().to_string(); }

#[test]
#[should_panic]
fn check_from_xml_fail_bitflags() {
    let rc = codespawn::from_xml_str("<struct name=\"Foo\"><bitflags name=\"x\" type=\"int\"/><enum></enum></bitflags></struct>").unwrap();
    rc.to_rust().to_string(); }

#[test]
#[should_panic]
fn check_from_json_fail_bitflags() {
    let rc = codespawn::from_json_str("{\"struct\":{ \"name\":\"Foo\",\"bitflags\": { \"name\":\"x\",\"type\":\"int\", \"enum\": { \"name\": \"foonum\" }}}}").unwrap();
    rc.to_cpp().to_string(); }

#[test]
#[should_panic]
fn check_from_xml_fail_malformed_cfg() {
    let _ = codespawn::from_xml_str("<config file=\"tests/malformed_cfg.xml\"/><var name=\"x\" type=\"int\"/>").unwrap(); }

#[test]
#[should_panic]
fn check_write_file() {
    let raw_code = codespawn::from_xml("examples/sample.xml").unwrap();
    raw_code.to_cpp().to_file("").unwrap(); }
<|endoftext|>


<commit_before>#[macro_export]
macro_rules! xs_return {
    ($ctx:ident, $( $val:expr ),*) => {{
        $ctx.st_prepush();
        $( $ctx.st_push($val); )*
        $ctx.st_putback();
        return;
    }}
}

/// Define Perl modules and packages.
///
/// First form of this macro is used to define a Perl package inside a module. Each invocation
/// should contain only one package and there should be only one such invocation per Rust module.
///
/// ```
/// mod acme {
///     xs! {
///         package Acme;
///         sub foo(ctx) { /* code */ }
///     }
/// }
/// ```
///
/// Second form is used to generate bootstrap function used by Perl to intialize XS module. Each
/// crate should contain exactly one invocation in this form:
///
/// ```
/// xs! {
///     bootstrap boot_Acme;
///     use acme;
/// }
/// ```
///
/// Function name given to `bootstrap` keyword must start with `boot_` followed by the module name.
#[macro_export]
macro_rules! xs {
    (
        package $pkg:ident ;
        $( sub $name:ident ($ctx:ident) $body:block )*
    ) => (
        $(
            extern "C" fn $name (pthx: $crate::raw::PerlThreadContext,
                                 _cv: *mut $crate::raw::CV) {
                let mut $ctx = $crate::Context::new(&pthx);
                $body
            }
        )*

        pub const PERL_XS: &'static [ (&'static str, $crate::raw::XSUBADDR_t) ] = &[
            $(
                (
                    concat!(stringify!($pkg), "::", stringify!($name)),
                    $name as $crate::raw::XSUBADDR_t,
                )
            ),*
        ];
    );

    (
        bootstrap $boot:ident;
        $( use $( $name:ident )::+ ; )*
    ) => (
        #[no_mangle]
        #[allow(non_snake_case)]
        pub extern "C" fn $boot (pthx: $crate::raw::PerlThreadContext,
                                 _cv: *mut $crate::raw::CV) {
            let mut ctx = $crate::Context::new(&pthx);
            $(
                for &(subname, subptr) in $( $name )::*::PERL_XS {
                    let cname = ::std::ffi::CString::new(subname).unwrap();
                    ctx.new_xs(&cname, subptr);
                }
            )*

            xs_return!(ctx, 1 as $crate::raw::IV);
        }
    );
}

#[macro_export]
macro_rules! cstr {
    ($e:expr) => (&::std::ffi::CString::new($e).unwrap())
}
<commit_msg>Fix package syntax.<commit_after>#[macro_export]
macro_rules! xs_return {
    ($ctx:ident, $( $val:expr ),*) => {{
        $ctx.st_prepush();
        $( $ctx.st_push($val); )*
        $ctx.st_putback();
        return;
    }}
}

/// Define Perl modules and packages.
///
/// First form of this macro is used to define a Perl package inside a module. Each invocation
/// should contain only one package and there should be only one such invocation per Rust module.
///
/// ```
/// mod acme {
///     xs! {
///         package Acme;
///         sub foo(ctx) { /* code */ }
///     }
/// }
/// ```
///
/// Second form is used to generate bootstrap function used by Perl to intialize XS module. Each
/// crate should contain exactly one invocation in this form:
///
/// ```
/// xs! {
///     bootstrap boot_Acme;
///     use acme;
/// }
/// ```
///
/// Function name given to `bootstrap` keyword must start with `boot_` followed by the module name.
#[macro_export]
macro_rules! xs {
    (
        package $pkg:path ;
        $( sub $name:ident ($ctx:ident) $body:block )*
    ) => (
        $(
            extern "C" fn $name (pthx: $crate::raw::PerlThreadContext,
                                 _cv: *mut $crate::raw::CV) {
                let mut $ctx = $crate::Context::new(&pthx);
                $body
            }
        )*

        pub const PERL_XS: &'static [ (&'static str, $crate::raw::XSUBADDR_t) ] = &[
            $(
                (
                    concat!(stringify!($pkg), "::", stringify!($name)),
                    $name as $crate::raw::XSUBADDR_t,
                )
            ),*
        ];
    );

    (
        bootstrap $boot:ident;
        $( use $( $name:ident )::+ ; )*
    ) => (
        #[no_mangle]
        #[allow(non_snake_case)]
        pub extern "C" fn $boot (pthx: $crate::raw::PerlThreadContext,
                                 _cv: *mut $crate::raw::CV) {
            let mut ctx = $crate::Context::new(&pthx);
            $(
                for &(subname, subptr) in $( $name )::*::PERL_XS {
                    let cname = ::std::ffi::CString::new(subname).unwrap();
                    ctx.new_xs(&cname, subptr);
                }
            )*

            xs_return!(ctx, 1 as $crate::raw::IV);
        }
    );
}

#[macro_export]
macro_rules! cstr {
    ($e:expr) => (&::std::ffi::CString::new($e).unwrap())
}
<|endoftext|>


<commit_before>// De-duplication macro used in src/app.rs
macro_rules! get_help {
	($opt:ident) => {
		if let Some(h) = $opt.help {
	        format!("{}{}", h,
	            if let Some(ref pv) = $opt.possible_vals {
	                let mut pv_s = pv.iter().fold(String::with_capacity(50), |acc, name| acc + &format!(" {}",name)[..]);
	                pv_s.shrink_to_fit();
	                format!(" [values:{}]", &pv_s[..])
	            }else{"".to_owned()})
	    } else {
	        "    ".to_owned()
	    }
	};
}

// Thanks to bluss and flan3002 in #rust IRC
//
// Helps with rightward drift when iterating over something and matching each item.
macro_rules! for_match {
	($it:ident, $($p:pat => $($e:expr);+),*) => {
		for i in $it {
			match i {
			$(
			    $p => { $($e)+ }
			)*
			}
		}
	};
}

/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr`
/// This macro returns a `Result<T,String>` which allows you as the developer to decide
/// what you'd like to do on a failed parse. There are two types of errors, parse failures
/// and those where the argument wasn't present (such as a non-required argument).
///
/// You can use it to get a single value, or a `Vec<T>` with the `values_of()`
///
/// **NOTE:** Be cautious, as since this a macro invocation it's not exactly like
/// standard syntax.
///
///
/// # Example single value
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[length] 'Set the length to use as a pos whole num, i.e. 20'")
///				  .get_matches();
/// let len = value_t!(matches.value_of("length"), u32)
/// 				.unwrap_or_else(|e|{
///						println!("{}",e);
///						std::process::exit(1)
///					});
///
/// println!("{} + 2: {}", len, len + 2);
/// # }
/// ```
///
///
/// # Example multiple values
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[seq]... 'A sequence of pos whole nums, i.e. 20 45'")
///				  .get_matches();
/// for v in value_t!(matches.values_of("seq"), u32)
///				.unwrap_or_else(|e|{
///					println!("{}",e);
///					std::process::exit(1)
///				}) {
/// 	println!("{} + 2: {}", v, v + 2);
///	}
/// # }
/// ```
#[macro_export]
macro_rules! value_t {
	($m:ident.value_of($v:expr), $t:ty) => {
		match $m.value_of($v) {
			Some(v) => {
				match v.parse::<$t>() {
					Ok(val) => Ok(val),
					Err(_)  => Err(format!("{} isn't a valid {}",v,stringify!($t))),
				}
			},
			None => Err(format!("Argument \"{}\" not found", $v))
		}
	};
	($m:ident.values_of($v:expr), $t:ty) => {
		match $m.values_of($v) {
			Some(ref v) => {
				let mut tmp = Vec::with_capacity(v.len());
				let mut err = None;
				for pv in v {
					match pv.parse::<$t>() {
						Ok(rv) => tmp.push(rv),
						Err(e) => {
							err = Some(format!("{} isn't a valid {}\n{}",pv,stringify!($t),e));
							break
						}
					}
				}
				match err {
					Some(e) => Err(e),
					None => Ok(tmp)
				}
			},
			None => Err(format!("Argument \"{}\" not found", $v))
		}
	};
}

/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr`
/// This macro returns a `T` or `Vec<T>` or exits with a usage string upon failure. This
/// removes some of the boiler plate to handle failures from value_t! above.
///
/// You can use it to get a single value `T`, or a `Vec<T>` with the `values_of()`
///
/// **NOTE:** This should only be used on required arguments, as it can be confusing to the user
/// why they are getting error messages when it appears they're entering all required argumetns.
///
/// **NOTE:** Be cautious, as since this a macro invocation it's not exactly like
/// standard syntax.
///
///
/// # Example single value
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[length] 'Set the length to use as a pos whole num, i.e. 20'")
///				  .get_matches();
/// let len = value_t_or_exit!(matches.value_of("length"), u32);
///
/// println!("{} + 2: {}", len, len + 2);
/// # }
/// ```
///
///
/// # Example multiple values
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///                   .arg_from_usage("[seq]... 'A sequence of pos whole nums, i.e. 20 45'")
///					  .get_matches();
/// for v in value_t_or_exit!(matches.values_of("seq"), u32) {
/// 	println!("{} + 2: {}", v, v + 2);
///	}
/// # }
/// ```
#[macro_export]
macro_rules! value_t_or_exit {
	($m:ident.value_of($v:expr), $t:ty) => {
		match $m.value_of($v) {
			Some(v) => {
				match v.parse::<$t>() {
					Ok(val) => val,
					Err(e)  => {
						println!("{} isn't a valid {}\n{}\n{}\nPlease re-run with --help for more information",
							v,
							stringify!($t),
							e,
							$m.usage());
						::std::process::exit(1);
					}
				}
			},
			None => {
				println!("Argument \"{}\" not found or is not valid\n{}\nPlease re-run with --help for more information",
					$v,
					$m.usage());
				::std::process::exit(1);
			}
		}
	};
	($m:ident.values_of($v:expr), $t:ty) => {
		match $m.values_of($v) {
			Some(ref v) => {
				let mut tmp = Vec::with_capacity(v.len());
				for pv in v {
					match pv.parse::<$t>() {
						Ok(rv) => tmp.push(rv),
						Err(_)  => {
							println!("{} isn't a valid {}\n{}\nPlease re-run with --help for more information",
								pv,
								stringify!($t),
								$m.usage());
							::std::process::exit(1);
						}
					}
				}
				tmp
			},
			None => {
				println!("Argument \"{}\" not found or is not valid\n{}\nPlease re-run with --help for more information",
					$v,
					$m.usage());
				::std::process::exit(1);
			}
		}
	};
}

/// Convenience macro generated a simple enum with variants to be used as a type when parsing
/// arguments.
///
/// # Example
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::{App, Arg};
/// simple_enum!{Foo => Bar, Baz, Qux}
/// // Foo enum can now be used via Foo::Bar, or Foo::Baz, etc
/// // and implements std::str::FromStr to use with the value_t! macros
/// fn main() {
/// 	let m = App::new("app")
///					.arg(Arg::from_usage("<foo> 'the foo'")
///						.possible_values(vec!["Bar", "Baz", "Qux"]))
///					.get_matches();
/// 	let f = value_t_or_exit!(m.value_of("foo"), Foo);
///
///		// Use f like any other Foo variant...
/// }
/// ```
#[macro_export]
macro_rules! simple_enum {
	($e:ident => $($v:ident),+) => {
		enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,<Self as std::str::FromStr>::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
}

/// Convenience macro to generate more complete enums with variants to be used as a type when parsing
/// arguments.
///
/// These enums support pub (or not) and use of the #[derive()] traits
///
///
/// # Example
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::{App, Arg};
/// arg_enum!{
/// 	#[derive(Debug)]
///		pub enum Foo {
///			Bar,
///			Baz,
///			Qux
///		}
/// }
/// // Foo enum can now be used via Foo::Bar, or Foo::Baz, etc
/// // and implements std::str::FromStr to use with the value_t! macros
/// fn main() {
/// 	let m = App::new("app")
///					.arg_from_usage("<foo> 'the foo'")
///					.get_matches();
/// 	let f = value_t_or_exit!(m.value_of("foo"), Foo);
///
///		// Use f like any other Foo variant...
/// }
/// ```
#[macro_export]
macro_rules! arg_enum {
	(enum $e:ident { $($v:ident),+ } ) => {
		enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,<Self as std::str::FromStr>::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(pub enum $e:ident { $($v:ident),+ } ) => {
		pub enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,<Self as std::str::FromStr>::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(#[derive($($d:ident),+)] enum $e:ident { $($v:ident),+ } ) => {
		#[derive($($d,)+)]
		enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,<Self as std::str::FromStr>::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(#[derive($($d:ident),+)] pub enum $e:ident { $($v:ident),+ } ) => {
		#[derive($($d,)+)]
		pub enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,<Self as std::str::FromStr>::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
}<commit_msg>refactor(macros.rs): improve trait implmentation readability<commit_after>// De-duplication macro used in src/app.rs
macro_rules! get_help {
	($opt:ident) => {
		if let Some(h) = $opt.help {
	        format!("{}{}", h,
	            if let Some(ref pv) = $opt.possible_vals {
	                let mut pv_s = pv.iter().fold(String::with_capacity(50), |acc, name| acc + &format!(" {}",name)[..]);
	                pv_s.shrink_to_fit();
	                format!(" [values:{}]", &pv_s[..])
	            }else{"".to_owned()})
	    } else {
	        "    ".to_owned()
	    }
	};
}

// Thanks to bluss and flan3002 in #rust IRC
//
// Helps with rightward drift when iterating over something and matching each item.
macro_rules! for_match {
	($it:ident, $($p:pat => $($e:expr);+),*) => {
		for i in $it {
			match i {
			$(
			    $p => { $($e)+ }
			)*
			}
		}
	};
}

/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr`
/// This macro returns a `Result<T,String>` which allows you as the developer to decide
/// what you'd like to do on a failed parse. There are two types of errors, parse failures
/// and those where the argument wasn't present (such as a non-required argument).
///
/// You can use it to get a single value, or a `Vec<T>` with the `values_of()`
///
/// **NOTE:** Be cautious, as since this a macro invocation it's not exactly like
/// standard syntax.
///
///
/// # Example single value
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[length] 'Set the length to use as a pos whole num, i.e. 20'")
///				  .get_matches();
/// let len = value_t!(matches.value_of("length"), u32)
/// 				.unwrap_or_else(|e|{
///						println!("{}",e);
///						std::process::exit(1)
///					});
///
/// println!("{} + 2: {}", len, len + 2);
/// # }
/// ```
///
///
/// # Example multiple values
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[seq]... 'A sequence of pos whole nums, i.e. 20 45'")
///				  .get_matches();
/// for v in value_t!(matches.values_of("seq"), u32)
///				.unwrap_or_else(|e|{
///					println!("{}",e);
///					std::process::exit(1)
///				}) {
/// 	println!("{} + 2: {}", v, v + 2);
///	}
/// # }
/// ```
#[macro_export]
macro_rules! value_t {
	($m:ident.value_of($v:expr), $t:ty) => {
		match $m.value_of($v) {
			Some(v) => {
				match v.parse::<$t>() {
					Ok(val) => Ok(val),
					Err(_)  => Err(format!("{} isn't a valid {}",v,stringify!($t))),
				}
			},
			None => Err(format!("Argument \"{}\" not found", $v))
		}
	};
	($m:ident.values_of($v:expr), $t:ty) => {
		match $m.values_of($v) {
			Some(ref v) => {
				let mut tmp = Vec::with_capacity(v.len());
				let mut err = None;
				for pv in v {
					match pv.parse::<$t>() {
						Ok(rv) => tmp.push(rv),
						Err(e) => {
							err = Some(format!("{} isn't a valid {}\n{}",pv,stringify!($t),e));
							break
						}
					}
				}
				match err {
					Some(e) => Err(e),
					None => Ok(tmp)
				}
			},
			None => Err(format!("Argument \"{}\" not found", $v))
		}
	};
}

/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr`
/// This macro returns a `T` or `Vec<T>` or exits with a usage string upon failure. This
/// removes some of the boiler plate to handle failures from value_t! above.
///
/// You can use it to get a single value `T`, or a `Vec<T>` with the `values_of()`
///
/// **NOTE:** This should only be used on required arguments, as it can be confusing to the user
/// why they are getting error messages when it appears they're entering all required argumetns.
///
/// **NOTE:** Be cautious, as since this a macro invocation it's not exactly like
/// standard syntax.
///
///
/// # Example single value
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[length] 'Set the length to use as a pos whole num, i.e. 20'")
///				  .get_matches();
/// let len = value_t_or_exit!(matches.value_of("length"), u32);
///
/// println!("{} + 2: {}", len, len + 2);
/// # }
/// ```
///
///
/// # Example multiple values
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///                   .arg_from_usage("[seq]... 'A sequence of pos whole nums, i.e. 20 45'")
///					  .get_matches();
/// for v in value_t_or_exit!(matches.values_of("seq"), u32) {
/// 	println!("{} + 2: {}", v, v + 2);
///	}
/// # }
/// ```
#[macro_export]
macro_rules! value_t_or_exit {
	($m:ident.value_of($v:expr), $t:ty) => {
		match $m.value_of($v) {
			Some(v) => {
				match v.parse::<$t>() {
					Ok(val) => val,
					Err(e)  => {
						println!("{} isn't a valid {}\n{}\n{}\nPlease re-run with --help for more information",
							v,
							stringify!($t),
							e,
							$m.usage());
						::std::process::exit(1);
					}
				}
			},
			None => {
				println!("Argument \"{}\" not found or is not valid\n{}\nPlease re-run with --help for more information",
					$v,
					$m.usage());
				::std::process::exit(1);
			}
		}
	};
	($m:ident.values_of($v:expr), $t:ty) => {
		match $m.values_of($v) {
			Some(ref v) => {
				let mut tmp = Vec::with_capacity(v.len());
				for pv in v {
					match pv.parse::<$t>() {
						Ok(rv) => tmp.push(rv),
						Err(_)  => {
							println!("{} isn't a valid {}\n{}\nPlease re-run with --help for more information",
								pv,
								stringify!($t),
								$m.usage());
							::std::process::exit(1);
						}
					}
				}
				tmp
			},
			None => {
				println!("Argument \"{}\" not found or is not valid\n{}\nPlease re-run with --help for more information",
					$v,
					$m.usage());
				::std::process::exit(1);
			}
		}
	};
}

/// Convenience macro generated a simple enum with variants to be used as a type when parsing
/// arguments.
///
/// # Example
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::{App, Arg};
/// simple_enum!{Foo => Bar, Baz, Qux}
/// // Foo enum can now be used via Foo::Bar, or Foo::Baz, etc
/// // and implements std::str::FromStr to use with the value_t! macros
/// fn main() {
/// 	let m = App::new("app")
///					.arg(Arg::from_usage("<foo> 'the foo'")
///						.possible_values(vec!["Bar", "Baz", "Qux"]))
///					.get_matches();
/// 	let f = value_t_or_exit!(m.value_of("foo"), Foo);
///
///		// Use f like any other Foo variant...
/// }
/// ```
#[macro_export]
macro_rules! simple_enum {
	($e:ident => $($v:ident),+) => {
		enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
}

/// Convenience macro to generate more complete enums with variants to be used as a type when parsing
/// arguments.
///
/// These enums support pub (or not) and use of the #[derive()] traits
///
///
/// # Example
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::{App, Arg};
/// arg_enum!{
/// 	#[derive(Debug)]
///		pub enum Foo {
///			Bar,
///			Baz,
///			Qux
///		}
/// }
/// // Foo enum can now be used via Foo::Bar, or Foo::Baz, etc
/// // and implements std::str::FromStr to use with the value_t! macros
/// fn main() {
/// 	let m = App::new("app")
///					.arg_from_usage("<foo> 'the foo'")
///					.get_matches();
/// 	let f = value_t_or_exit!(m.value_of("foo"), Foo);
///
///		// Use f like any other Foo variant...
/// }
/// ```
#[macro_export]
macro_rules! arg_enum {
	(enum $e:ident { $($v:ident),+ } ) => {
		enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(pub enum $e:ident { $($v:ident),+ } ) => {
		pub enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(#[derive($($d:ident),+)] enum $e:ident { $($v:ident),+ } ) => {
		#[derive($($d,)+)]
		enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(#[derive($($d:ident),+)] pub enum $e:ident { $($v:ident),+ } ) => {
		#[derive($($d,)+)]
		pub enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
}
<|endoftext|>


<commit_before>#[macro_export]
macro_rules! rusty_peg {
    { parser $name:ident: $base:ty { $($grammar_defn:tt)* } } => {
        rusty_peg_with_nonterminals! {
            rusty_peg_declare_parser(($name) ($base)); $($grammar_defn)*
        }

        rusty_peg_with_nonterminals! {
            rusty_peg_init_parser(($name) ($base)); $($grammar_defn)*
        }

        rusty_peg_declare_nonterminals! { $name, $($grammar_defn)* }
    }
}

#[macro_export]
macro_rules! rusty_peg_with_nonterminals {
    ( $m:ident($($args:tt)*) ;
      $nonterminal:ident: $ty:ty = $defn:tt => $body:expr ;
      $($remainder:tt)* ) => {
        rusty_peg_with_nonterminals! { $m($($args)* ($nonterminal, $ty));
                                       $($remainder)* }
    };
    ( $m:ident($($args:tt)*) ;
      $nonterminal:ident: $ty:ty = $defn:tt ;
      $($remainder:tt)* ) => {
        rusty_peg_with_nonterminals! { $m($($args)* ($nonterminal, $ty));
                                       $($remainder)* }
    };
    ( $m:ident($($args:tt)*) ; ) => {
        $m! { $($args)* }
    };
}

#[macro_export]
macro_rules! rusty_peg_declare_parser {
    ( ($name:ident) ($base:ty) $(($nonterminal:ident, $ty:ty))* ) => {
        #[allow(non_snake_case)]
        pub struct $name<'input> {
            marker: $crate::util::PhantomData<&'input()>,
            base: $base,
            $($nonterminal: $crate::Cache<'input,$ty>),*
        }
    }
}

#[macro_export]
macro_rules! rusty_peg_init_parser {
    ( ($name:ident) ($base:ty) $(($nonterminal:ident, $ty:ty))* ) => {
        impl<'input> $name<'input> {
            fn new(base: $base) -> $name<'input> {
                $name {
                    marker: $crate::util::PhantomData,
                    base: base,
                    $($nonterminal: $crate::util::HashMap::new()),*
                }
            }
        }
    }
}

#[macro_export]
macro_rules! rusty_peg_declare_nonterminals {
    ( $grammar:ident, $nonterminal:ident: $ty:ty = $defn:tt => $body:expr ;
      $($remainder:tt)* ) => {
        rusty_peg_declare_map_nonterminal! { $grammar, $nonterminal, $ty, $defn, $body }
        rusty_peg_declare_nonterminals! { $grammar, $($remainder)* }
    };
    ( $grammar:ident, $nonterminal:ident: $ty:ty = $defn:tt ;
      $($remainder:tt)* ) => {
        rusty_peg_declare_identity_nonterminal! { $grammar, $nonterminal, $ty, $defn }
        rusty_peg_declare_nonterminals! { $grammar, $($remainder)* }
    };
    ( $grammar:ident, ) => {
    };
}

#[macro_export]
macro_rules! rusty_peg_declare_map_nonterminal {
    ($grammar:ident, $nonterminal:ident, $ty:ty, $defn:tt, $body:expr) => {
        #[allow(non_camel_case_types)]
        #[derive(Debug)]
        pub struct $nonterminal;

        impl<'input> $crate::Symbol<'input,$grammar<'input>> for $nonterminal {
            type Output = $ty;

            fn pretty_print(&self) -> String {
                format!("{:?}", self)
            }

            fn parse(&self,
                     grammar: &mut $grammar<'input>,
                     start: $crate::Input<'input>)
                     -> $crate::ParseResult<'input,$ty>
            {
                $crate::util::memoize(
                    grammar,
                    |g| &mut g.$nonterminal,
                    start.offset,
                    |g| {
                        let parser = rusty_peg_named_item!($defn);
                        let (end, rusty_peg_named_item_pat!($defn)) =
                            try!($crate::Symbol::parse(&parser, g, start));
                        Ok((end,$body))
                    })
            }
        }
    }
}

#[macro_export]
macro_rules! rusty_peg_declare_identity_nonterminal {
    ($grammar:ident, $nonterminal:ident, $ty:ty, $defn:tt) => {
        #[allow(non_camel_case_types)]
        #[derive(Debug)]
        pub struct $nonterminal;

        impl<'input> $crate::Symbol<'input,$grammar<'input>> for $nonterminal {
            type Output = $ty;

            fn pretty_print(&self) -> String {
                format!("{:?}", self)
            }

            fn parse(&self,
                     grammar: &mut $grammar<'input>,
                     start: $crate::Input<'input>)
                     -> $crate::ParseResult<'input,$ty>
            {
                $crate::util::memoize(
                    grammar,
                    |g| &mut g.$nonterminal,
                    start.offset,
                    |g| {
                        let parser = rusty_peg_item!($defn);
                        $crate::Symbol::parse(&parser, g, start)
                    })
            }
        }
    }
}

#[macro_export]
macro_rules! rusty_peg_named_item {
    ( ( $($a:tt)* ) ) => {
        rusty_peg_named_items!($($a)*)
    };
    ( $a:tt ) => {
        rusty_peg_item!($a)
    }
}

#[macro_export]
macro_rules! rusty_peg_named_items {
    ( < $name:ident : $a:tt > , $($bs:tt)* ) => {
        {
            let bs = rusty_peg_named_items!($($bs)*);
            rusty_peg_items!($a, bs)
        }
    };
    ( < $name:ident : $a:tt > ) => {
        rusty_peg_item!($a)
    };
    ( $a:tt, $($bs:tt)* ) => {
        {
            let bs = rusty_peg_named_items!($($bs)*);
            rusty_peg_items!($a, bs)
        }
    };
    ( $a:tt ) => {
        rusty_peg_item!($a)
    };
    ( ) => {
        Empty
    };
}

#[macro_export]
macro_rules! rusty_peg_named_item_pat {
    ( ( $($a:tt)* ) ) => {
        rusty_peg_named_items_pat!($($a)*)
    };
    ( $a:tt ) => {
        _
    }
}

#[macro_export]
macro_rules! rusty_peg_named_items_pat {
    ( < $name:ident : $a:tt > , $($bs:tt)* ) => {
        ($name, rusty_peg_named_items_pat!($($bs)*))
    };
    ( < $name:ident : $a:tt > ) => {
        $name
    };
    ( $a:tt, $($bs:tt)* ) => {
        (_, rusty_peg_named_items_pat!($($bs)*))
    };
    ( $a:tt ) => {
        _
    };
    ( ) => {
        ()
    };
}

#[macro_export]
macro_rules! rusty_peg_items {
    ( $a:tt, $($bs:tt)* ) => {
        $crate::util::Join { first: rusty_peg_item!($a), second: rusty_peg_items!($($bs)*), }
    };
    ( $a:tt / $($bs:tt)* ) => {
        $crate::util::Or { a: rusty_peg_item!($a), b: rusty_peg_items!($($bs)*) }
    };
    ( $a:tt ) => {
        rusty_peg_item!($a)
    };
    ( ) => {
        Empty
    }
}

#[macro_export]
macro_rules! rusty_peg_item {
    { ( ) } => {
        Empty
    };

    { ( $tt:tt ) } => {
        rusty_peg_item!($tt)
    };

    { ( $($tt:tt)* ) } => {
        rusty_peg_items!($($tt)*)
    };

    { [ $($tt:tt)* ] } => {
        $crate::util::Optional { parser: rusty_peg_items!($($tt)*) }
    };

    { { + $($tt:tt)* } } => {
        $crate::util::Repeat { parser: rusty_peg_items!($($tt)*), min: 1,
                               separator: $crate::util::Whitespace }
    };

    { { * $($tt:tt)* } } => {
        $crate::util::Repeat { parser: rusty_peg_items!($($tt)*), min: 0,
                               separator: $crate::util::Whitespace }
    };

    { { $($tt:tt)* } } => {
        $crate::util::Repeat { parser: rusty_peg_items!($($tt)*), min: 0,
                               separator: $crate::util::Whitespace }
    };

    { $name:expr } => {
        $name
    };
}

<commit_msg>introduce a default base type (`()`) and force the syntax to declare the lifetime 'input<commit_after>#[macro_export]
macro_rules! rusty_peg {
    { parser $name:ident<'input>: $base:ty { $($grammar_defn:tt)* } } => {
        rusty_peg_parser! {
            parser $name: $base { $($grammar_defn)* }
        }
    };

    { parser $name:ident<'input> { $($grammar_defn:tt)* } } => {
        rusty_peg_parser! {
            parser $name: () { $($grammar_defn)* }
        }
    };
}

#[macro_export]
macro_rules! rusty_peg_parser {
    { parser $name:ident: $base:ty { $($grammar_defn:tt)* } } => {
        rusty_peg_with_nonterminals! {
            rusty_peg_declare_parser(($name) ($base)); $($grammar_defn)*
        }

        rusty_peg_with_nonterminals! {
            rusty_peg_init_parser(($name) ($base)); $($grammar_defn)*
        }

        rusty_peg_declare_nonterminals! { $name, $($grammar_defn)* }
    }
}

#[macro_export]
macro_rules! rusty_peg_with_nonterminals {
    ( $m:ident($($args:tt)*) ;
      $nonterminal:ident: $ty:ty = $defn:tt => $body:expr ;
      $($remainder:tt)* ) => {
        rusty_peg_with_nonterminals! { $m($($args)* ($nonterminal, $ty));
                                       $($remainder)* }
    };
    ( $m:ident($($args:tt)*) ;
      $nonterminal:ident: $ty:ty = $defn:tt ;
      $($remainder:tt)* ) => {
        rusty_peg_with_nonterminals! { $m($($args)* ($nonterminal, $ty));
                                       $($remainder)* }
    };
    ( $m:ident($($args:tt)*) ; ) => {
        $m! { $($args)* }
    };
}

#[macro_export]
macro_rules! rusty_peg_declare_parser {
    ( ($name:ident) ($base:ty) $(($nonterminal:ident, $ty:ty))* ) => {
        #[allow(non_snake_case)]
        pub struct $name<'input> {
            marker: $crate::util::PhantomData<&'input()>,
            base: $base,
            $($nonterminal: $crate::Cache<'input,$ty>),*
        }
    }
}

#[macro_export]
macro_rules! rusty_peg_init_parser {
    ( ($name:ident) ($base:ty) $(($nonterminal:ident, $ty:ty))* ) => {
        impl<'input> $name<'input> {
            fn new(base: $base) -> $name<'input> {
                $name {
                    marker: $crate::util::PhantomData,
                    base: base,
                    $($nonterminal: $crate::util::HashMap::new()),*
                }
            }
        }
    }
}

#[macro_export]
macro_rules! rusty_peg_declare_nonterminals {
    ( $grammar:ident, $nonterminal:ident: $ty:ty = $defn:tt => $body:expr ;
      $($remainder:tt)* ) => {
        rusty_peg_declare_map_nonterminal! { $grammar, $nonterminal, $ty, $defn, $body }
        rusty_peg_declare_nonterminals! { $grammar, $($remainder)* }
    };
    ( $grammar:ident, $nonterminal:ident: $ty:ty = $defn:tt ;
      $($remainder:tt)* ) => {
        rusty_peg_declare_identity_nonterminal! { $grammar, $nonterminal, $ty, $defn }
        rusty_peg_declare_nonterminals! { $grammar, $($remainder)* }
    };
    ( $grammar:ident, ) => {
    };
}

#[macro_export]
macro_rules! rusty_peg_declare_map_nonterminal {
    ($grammar:ident, $nonterminal:ident, $ty:ty, $defn:tt, $body:expr) => {
        #[allow(non_camel_case_types)]
        #[derive(Debug)]
        pub struct $nonterminal;

        impl<'input> $crate::Symbol<'input,$grammar<'input>> for $nonterminal {
            type Output = $ty;

            fn pretty_print(&self) -> String {
                format!("{:?}", self)
            }

            fn parse(&self,
                     grammar: &mut $grammar<'input>,
                     start: $crate::Input<'input>)
                     -> $crate::ParseResult<'input,$ty>
            {
                $crate::util::memoize(
                    grammar,
                    |g| &mut g.$nonterminal,
                    start.offset,
                    |g| {
                        let parser = rusty_peg_named_item!($defn);
                        let (end, rusty_peg_named_item_pat!($defn)) =
                            try!($crate::Symbol::parse(&parser, g, start));
                        Ok((end,$body))
                    })
            }
        }
    }
}

#[macro_export]
macro_rules! rusty_peg_declare_identity_nonterminal {
    ($grammar:ident, $nonterminal:ident, $ty:ty, $defn:tt) => {
        #[allow(non_camel_case_types)]
        #[derive(Debug)]
        pub struct $nonterminal;

        impl<'input> $crate::Symbol<'input,$grammar<'input>> for $nonterminal {
            type Output = $ty;

            fn pretty_print(&self) -> String {
                format!("{:?}", self)
            }

            fn parse(&self,
                     grammar: &mut $grammar<'input>,
                     start: $crate::Input<'input>)
                     -> $crate::ParseResult<'input,$ty>
            {
                $crate::util::memoize(
                    grammar,
                    |g| &mut g.$nonterminal,
                    start.offset,
                    |g| {
                        let parser = rusty_peg_item!($defn);
                        $crate::Symbol::parse(&parser, g, start)
                    })
            }
        }
    }
}

#[macro_export]
macro_rules! rusty_peg_named_item {
    ( ( $($a:tt)* ) ) => {
        rusty_peg_named_items!($($a)*)
    };
    ( $a:tt ) => {
        rusty_peg_item!($a)
    }
}

#[macro_export]
macro_rules! rusty_peg_named_items {
    ( < $name:ident : $a:tt > , $($bs:tt)* ) => {
        {
            let bs = rusty_peg_named_items!($($bs)*);
            rusty_peg_items!($a, bs)
        }
    };
    ( < $name:ident : $a:tt > ) => {
        rusty_peg_item!($a)
    };
    ( $a:tt, $($bs:tt)* ) => {
        {
            let bs = rusty_peg_named_items!($($bs)*);
            rusty_peg_items!($a, bs)
        }
    };
    ( $a:tt ) => {
        rusty_peg_item!($a)
    };
    ( ) => {
        Empty
    };
}

#[macro_export]
macro_rules! rusty_peg_named_item_pat {
    ( ( $($a:tt)* ) ) => {
        rusty_peg_named_items_pat!($($a)*)
    };
    ( $a:tt ) => {
        _
    }
}

#[macro_export]
macro_rules! rusty_peg_named_items_pat {
    ( < $name:ident : $a:tt > , $($bs:tt)* ) => {
        ($name, rusty_peg_named_items_pat!($($bs)*))
    };
    ( < $name:ident : $a:tt > ) => {
        $name
    };
    ( $a:tt, $($bs:tt)* ) => {
        (_, rusty_peg_named_items_pat!($($bs)*))
    };
    ( $a:tt ) => {
        _
    };
    ( ) => {
        ()
    };
}

#[macro_export]
macro_rules! rusty_peg_items {
    ( $a:tt, $($bs:tt)* ) => {
        $crate::util::Join { first: rusty_peg_item!($a), second: rusty_peg_items!($($bs)*), }
    };
    ( $a:tt / $($bs:tt)* ) => {
        $crate::util::Or { a: rusty_peg_item!($a), b: rusty_peg_items!($($bs)*) }
    };
    ( $a:tt ) => {
        rusty_peg_item!($a)
    };
    ( ) => {
        Empty
    }
}

#[macro_export]
macro_rules! rusty_peg_item {
    { ( ) } => {
        Empty
    };

    { ( $tt:tt ) } => {
        rusty_peg_item!($tt)
    };

    { ( $($tt:tt)* ) } => {
        rusty_peg_items!($($tt)*)
    };

    { [ $($tt:tt)* ] } => {
        $crate::util::Optional { parser: rusty_peg_items!($($tt)*) }
    };

    { { + $($tt:tt)* } } => {
        $crate::util::Repeat { parser: rusty_peg_items!($($tt)*), min: 1,
                               separator: $crate::util::Whitespace }
    };

    { { * $($tt:tt)* } } => {
        $crate::util::Repeat { parser: rusty_peg_items!($($tt)*), min: 0,
                               separator: $crate::util::Whitespace }
    };

    { { $($tt:tt)* } } => {
        $crate::util::Repeat { parser: rusty_peg_items!($($tt)*), min: 0,
                               separator: $crate::util::Whitespace }
    };

    { $name:expr } => {
        $name
    };
}

<|endoftext|>


<commit_before>#[macro_export]
macro_rules! declare_types {
    { $(#[$attr:meta])* pub class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_class! { #![reopen(false)] #![pub(true)] $(#[$attr])* pub class $cls { $($body)* } $($rest)* }
    };

    { $(#[$attr:meta])* class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_class! { #![reopen(false)] #![pub(false)] $(#[$attr])* class $cls { $($body)* } $($rest)* }
    };

    { $(#[$attr:meta])* pub reopen class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_class! { #![reopen(true)] #![pub(true)] $(#[$attr])* pub class $cls { $($body)* } $($rest)* }
    };

    { $(#[$attr:meta])* reopen class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_class! { #![reopen(true)] #![pub(false)] $(#[$attr])* class $cls { $($body)* } $($rest)* }
    };

    { } => { };
}

#[doc(hidden)]
#[macro_export]
macro_rules! define_struct {
    (true $(#[$attr:meta])* $cls:ident) => (
        #[derive(Copy, Clone, Debug)]
        #[repr(C)]
        $(#[$attr])*
        pub struct $cls($crate::sys::VALUE);
    );

    (false $(#[$attr:meta])* $cls:ident) => (
        #[derive(Copy, Clone, Debug)]
        #[repr(C)]
        $(#[$attr])*
        struct $cls($crate::sys::VALUE);
    );
}

#[doc(hidden)]
#[macro_export]
macro_rules! define_class {
    { #![reopen(false)] #![pub($is_pub:tt)] $(#[$attr:meta])* class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_struct!($(#[$attr:meta])* $is_pub $cls);
        class_definition! { $cls ; () ; () ; $($body)* }
        declare_types! { $($rest)* }
    };

    { #![reopen(true)] #![pub($is_pub:tt)] $(#[$attr:meta])* class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_struct!($(#[$attr:meta])* $is_pub $cls);
        reopen_class_definition! { $cls ; () ; () ; $($body)* }
        declare_types! { $($rest)* }
    };

}

#[doc(hidden)]
#[macro_export]
macro_rules! class_definition {
    { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; defn $name:ident; $self_arg:tt ; ($($arg:ident : $argty:ty),*) ; $body:block ; $ret:ty ; $($rest:tt)* } => {
        class_definition! {
            $cls ;
            ($($mimpl)* pub fn $name($self_arg, $($arg : $argty),*) -> $ret $body) ;
            ($($mdef)* {
                extern "C" fn __ruby_method__(rb_self: $cls, $($arg : $crate::sys::VALUE),*) -> $crate::sys::VALUE {
                    let checked = __checked_call__(rb_self, $($arg),*);
                    match checked {
                        Ok(val) => $crate::ToRuby::to_ruby(val),
                        Err(err) => { println!("TYPE ERROR: {:?}", err); $crate::sys::Qnil }
                    }
                }

                fn __checked_call__(rb_self: $cls, $($arg : $crate::sys::VALUE),*) -> Result<$ret, ::std::ffi::CString> {
                    #[allow(unused_imports)]
                    use $crate::{ToRust};

                    $(
                        let $arg = try!($crate::UncheckedValue::<$argty>::to_checked($arg));
                    )*

                    $(
                        let $arg = $crate::ToRust::to_rust($arg);
                    )*

                    Ok(rb_self.$name($($arg),*))
                }

                let name = stringify!($name);
                let arity = method_arity!($($arg),*);
                let method = __ruby_method__ as *const $crate::libc::c_void;

                $crate::MethodDefinition::new(name, method, arity)
            }) ;
            $($rest)*
        }
    };

    { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ty),* ) -> $ret:ty $body:block $($rest:tt)* } => {
        class_definition! { $cls; ($($mimpl)*) ; ($($mdef)*) ; defn $name ; $self_arg ; ($($arg : $argty),*) ; $body ; $ret ; $($rest)*  }
    };

    { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ty),* ) $body:block $($rest:tt)* } => {
        class_definition! { $cls; ($($mimpl)*) ; ($($mdef)*) ; defn $name ; $self_arg ; ($($arg : $argty),*) ; $body ; () ; $($rest)*  }
    };

    // { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ty),* ) -> $ret:ty $body:block $($rest:tt)* } => {
    //     class_definition! { $cls; ($($mimpl)*) ; ($($mdef)*) ; def $name( $self_arg , $($arg : $argty),* ) ; $ret ; { $body } ; $($rest)* }
    // };

    ( $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt ) $body:block $($rest:tt)* ) => {
        class_definition! { $cls ; ($($mimpl)*); ($($mdef)*); def $name( $self_arg, ) $body $($rest)* }
    };

    ( $cls:ident ; ($($mimpl:tt)*) ; ($($mdef:block)*) ; ) => {
        item! {
            impl $cls {
                $($mimpl)*
            }
        }

        init! {
            $crate::ClassDefinition::new(stringify!($cls))$(.define_method($mdef))*;
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! reopen_class_definition {
    ( $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ty),* ) $body:block ; $ret:ty ; $($rest:tt)* ) => {
        reopen_class_definition! {
            $cls ;
            ($($mimpl)* pub fn $name($self_arg, $($arg : $argty),*) -> $crate::sys::VALUE $body) ;
            ($($mdef)* {
                extern "C" fn __ruby_method__(rb_self: $cls, $($arg : $crate::sys::VALUE),*) -> $crate::sys::VALUE {
                    let checked = __checked_call__(rb_self, $($arg),*);
                    match checked {
                        Ok(val) => val,
                        Err(err) => { println!("TYPE ERROR: {:?}", err); $crate::sys::Qnil }
                    }
                }

                fn __checked_call__(rb_self: $cls, $($arg : $crate::sys::VALUE),*) -> Result<$crate::sys::VALUE, ::std::ffi::CString> {
                    #[allow(unused_imports)]
                    use $crate::{ToRust};

                    $(
                        let $arg = try!($crate::UncheckedValue::<$argty>::to_checked($arg));
                    )*

                    $(
                        let $arg = $arg.to_rust();
                    )*

                    Ok(rb_self.$name($($arg),*))
                }

                let name = stringify!($name);
                let arity = method_arity!($($arg),*);
                let method = __ruby_method__ as *const $crate::libc::c_void;

                $crate::MethodDefinition::new(name, method, arity)
            }) ;
            $($rest)*
        }
    };

    { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ty),* ) -> $ret:ty { $body:block } $($rest:tt)* } => {
        reopen_class_definition! { $cls; ($($mimpl)*) ; ($($mdef)*) ; def $name( $self_arg , $($arg : $argty),* ) $body ; $ret ; $($rest)*  }
    };

    { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ty),* ) $body:block $($rest:tt)* } => {
        reopen_class_definition! { $cls; ($($mimpl)*) ; ($($mdef)*) ; def $name( $self_arg , $($arg : $argty),* ) $body ; () ; $($rest)*  }
    };

    ( $cls:ident ; ($($mimpl:tt)*) ; ($($mdef:block)*) ; ) => {
        item! {
            impl $cls {
                $($mimpl)*
            }
        }

        init! {
            $crate::ClassDefinition::reopen(stringify!($cls))$(.define_method($mdef))*;
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! item {
    ($it: item) => { $it }
}

#[doc(hidden)]
#[macro_export]
macro_rules! replace_expr {
    ($_t:tt $sub:expr) => {$sub};
}

#[doc(hidden)]
#[macro_export]
macro_rules! method_arity {
  ( $($id:pat ),* ) => {
    { 0isize $(+ replace_expr!($id 1isize))* }
  }
}<commit_msg>update macros so they build on stable<commit_after>#[macro_export]
macro_rules! declare_types {
    { $(#[$attr:meta])* pub class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_class! { #![reopen(false)] #![pub(true)] $(#[$attr])* pub class $cls { $($body)* } $($rest)* }
    };

    { $(#[$attr:meta])* class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_class! { #![reopen(false)] #![pub(false)] $(#[$attr])* class $cls { $($body)* } $($rest)* }
    };

    { $(#[$attr:meta])* pub reopen class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_class! { #![reopen(true)] #![pub(true)] $(#[$attr])* pub class $cls { $($body)* } $($rest)* }
    };

    { $(#[$attr:meta])* reopen class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_class! { #![reopen(true)] #![pub(false)] $(#[$attr])* class $cls { $($body)* } $($rest)* }
    };

    { } => { };
}

#[doc(hidden)]
#[macro_export]
macro_rules! define_struct {
    (true $(#[$attr:meta])* $cls:ident) => (
        #[derive(Copy, Clone, Debug)]
        #[repr(C)]
        $(#[$attr])*
        pub struct $cls($crate::sys::VALUE);
    );

    (false $(#[$attr:meta])* $cls:ident) => (
        #[derive(Copy, Clone, Debug)]
        #[repr(C)]
        $(#[$attr])*
        struct $cls($crate::sys::VALUE);
    );
}

#[doc(hidden)]
#[macro_export]
macro_rules! define_class {
    { #![reopen(false)] #![pub($is_pub:tt)] $(#[$attr:meta])* class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_struct!($(#[$attr:meta])* $is_pub $cls);
        class_definition! { $cls ; () ; () ; $($body)* }
        declare_types! { $($rest)* }
    };

    { #![reopen(true)] #![pub($is_pub:tt)] $(#[$attr:meta])* class $cls:ident { $($body:tt)* } $($rest:tt)* } => {
        define_struct!($(#[$attr:meta])* $is_pub $cls);
        reopen_class_definition! { $cls ; () ; () ; $($body)* }
        declare_types! { $($rest)* }
    };

}

#[doc(hidden)]
#[macro_export]
macro_rules! class_definition {
    { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; defn $name:ident; $self_arg:tt ; ($($arg:ident : $argty:ty),*) ; $body:block ; $ret:ty ; $($rest:tt)* } => {
        class_definition! {
            $cls ;
            ($($mimpl)* pub fn $name($self_arg, $($arg : $argty),*) -> $ret $body) ;
            ($($mdef)* {
                extern "C" fn __ruby_method__(rb_self: $cls, $($arg : $crate::sys::VALUE),*) -> $crate::sys::VALUE {
                    let checked = __checked_call__(rb_self, $($arg),*);
                    match checked {
                        Ok(val) => $crate::ToRuby::to_ruby(val),
                        Err(err) => { println!("TYPE ERROR: {:?}", err); $crate::sys::Qnil }
                    }
                }

                fn __checked_call__(rb_self: $cls, $($arg : $crate::sys::VALUE),*) -> Result<$ret, ::std::ffi::CString> {
                    #[allow(unused_imports)]
                    use $crate::{ToRust};

                    $(
                        let $arg = try!($crate::UncheckedValue::<$argty>::to_checked($arg));
                    )*

                    $(
                        let $arg = $crate::ToRust::to_rust($arg);
                    )*

                    Ok(rb_self.$name($($arg),*))
                }

                let name = stringify!($name);
                let arity = method_arity!($($arg),*);
                let method = __ruby_method__ as *const $crate::libc::c_void;

                $crate::MethodDefinition::new(name, method, arity)
            }) ;
            $($rest)*
        }
    };

    { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ident),* ) -> $ret:ident $body:block $($rest:tt)* } => {
        class_definition! { $cls; ($($mimpl)*) ; ($($mdef)*) ; defn $name ; $self_arg ; ($($arg : $argty),*) ; $body ; $ret ; $($rest)*  }
    };

    { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ident),* ) $body:block $($rest:tt)* } => {
        class_definition! { $cls; ($($mimpl)*) ; ($($mdef)*) ; defn $name ; $self_arg ; ($($arg : $argty),*) ; $body ; () ; $($rest)*  }
    };

    // { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ty),* ) -> $ret:ty $body:block $($rest:tt)* } => {
    //     class_definition! { $cls; ($($mimpl)*) ; ($($mdef)*) ; def $name( $self_arg , $($arg : $argty),* ) ; $ret ; { $body } ; $($rest)* }
    // };

    ( $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt ) $body:block $($rest:tt)* ) => {
        class_definition! { $cls ; ($($mimpl)*); ($($mdef)*); def $name( $self_arg, ) $body $($rest)* }
    };

    ( $cls:ident ; ($($mimpl:tt)*) ; ($($mdef:block)*) ; ) => {
        item! {
            impl $cls {
                $($mimpl)*
            }
        }

        init! {
            $crate::ClassDefinition::new(stringify!($cls))$(.define_method($mdef))*;
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! reopen_class_definition {
    ( $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ty),* ) $body:block ; $ret:ty ; $($rest:tt)* ) => {
        reopen_class_definition! {
            $cls ;
            ($($mimpl)* pub fn $name($self_arg, $($arg : $argty),*) -> $crate::sys::VALUE $body) ;
            ($($mdef)* {
                extern "C" fn __ruby_method__(rb_self: $cls, $($arg : $crate::sys::VALUE),*) -> $crate::sys::VALUE {
                    let checked = __checked_call__(rb_self, $($arg),*);
                    match checked {
                        Ok(val) => val,
                        Err(err) => { println!("TYPE ERROR: {:?}", err); $crate::sys::Qnil }
                    }
                }

                fn __checked_call__(rb_self: $cls, $($arg : $crate::sys::VALUE),*) -> Result<$crate::sys::VALUE, ::std::ffi::CString> {
                    #[allow(unused_imports)]
                    use $crate::{ToRust};

                    $(
                        let $arg = try!($crate::UncheckedValue::<$argty>::to_checked($arg));
                    )*

                    $(
                        let $arg = $arg.to_rust();
                    )*

                    Ok(rb_self.$name($($arg),*))
                }

                let name = stringify!($name);
                let arity = method_arity!($($arg),*);
                let method = __ruby_method__ as *const $crate::libc::c_void;

                $crate::MethodDefinition::new(name, method, arity)
            }) ;
            $($rest)*
        }
    };

    { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ty),* ) -> $ret:ty { $body:block } $($rest:tt)* } => {
        reopen_class_definition! { $cls; ($($mimpl)*) ; ($($mdef)*) ; def $name( $self_arg , $($arg : $argty),* ) $body ; $ret ; $($rest)*  }
    };

    { $cls:ident; ($($mimpl:tt)*) ; ($($mdef:tt)*) ; def $name:ident( $self_arg:tt , $($arg:ident : $argty:ty),* ) $body:block $($rest:tt)* } => {
        reopen_class_definition! { $cls; ($($mimpl)*) ; ($($mdef)*) ; def $name( $self_arg , $($arg : $argty),* ) $body ; () ; $($rest)*  }
    };

    ( $cls:ident ; ($($mimpl:tt)*) ; ($($mdef:block)*) ; ) => {
        item! {
            impl $cls {
                $($mimpl)*
            }
        }

        init! {
            $crate::ClassDefinition::reopen(stringify!($cls))$(.define_method($mdef))*;
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! item {
    ($it: item) => { $it }
}

#[doc(hidden)]
#[macro_export]
macro_rules! replace_expr {
    ($_t:tt $sub:expr) => {$sub};
}

#[doc(hidden)]
#[macro_export]
macro_rules! method_arity {
  ( $($id:pat ),* ) => {
    { 0isize $(+ replace_expr!($id 1isize))* }
  }
}
<|endoftext|>


<commit_before>/*
  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

use std::path::Path;
use store;
use AplibObject;
use AplibType;
use audit::{
    audit_get_str_value, audit_get_int_value, audit_get_bool_value,
    Report
};

pub struct Master {
    uuid: Option<String>,
    model_id: Option<i64>,
    project_uuid: Option<String>,

    pub alternate_master: Option<String>,
    pub original_version_uuid: Option<String>,
    pub import_group_uuid: Option<String>,
    pub filename: Option<String>,
    pub name: Option<String>,
    pub original_version_name: Option<String>,
    pub db_version: Option<i64>,
    pub master_type: Option<String>,
    pub subtype: Option<String>,
    pub image_path: Option<String>,
    pub is_reference: Option<bool>,
}

impl AplibObject for Master {
    fn from_path(plist_path: &Path,
                 mut auditor: Option<&mut Report>) -> Option<Master> {

        use plutils::*;
        let plist = parse_plist(plist_path);
        match plist {
            Plist::Dictionary(ref dict) => {
                let result = Some(Master {
                    uuid: audit_get_str_value(dict, "uuid", &mut auditor),
                    alternate_master: audit_get_str_value(
                        dict, "alternateMasterUuid", &mut auditor),
                    original_version_uuid: audit_get_str_value(
                        dict, "originalVersionUuid", &mut auditor),
                    project_uuid: audit_get_str_value(
                        dict, "projectUuid", &mut auditor),
                    import_group_uuid: audit_get_str_value(
                        dict, "importGroupUuid", &mut auditor),
                    filename: audit_get_str_value(dict, "fileName", &mut auditor),
                    name: audit_get_str_value(dict, "name", &mut auditor),
                    original_version_name: audit_get_str_value(
                        dict, "originalVersionName", &mut auditor),
                    db_version: audit_get_int_value(dict, "version", &mut auditor),
                    master_type: audit_get_str_value(dict, "type", &mut auditor),
                    subtype: audit_get_str_value(dict, "subtype", &mut auditor),
                    model_id: audit_get_int_value(dict, "modelId", &mut auditor),
                    image_path: audit_get_str_value(
                        dict, "imagePath", &mut auditor),
                    is_reference: audit_get_bool_value(
                        dict, "fileIsReference", &mut auditor),
                });
                if auditor.is_some() {
                    let ref mut auditor = auditor.unwrap();
                    auditor.audit_ignored(dict, None);
                }
                result
            },
            _ =>
                None
        }
    }
    fn obj_type(&self) -> AplibType {
        AplibType::Master
    }
    fn uuid(&self) -> &Option<String> {
        &self.uuid
    }
    fn parent(&self) -> &Option<String> {
        &self.project_uuid
    }
    fn model_id(&self) -> i64 {
        self.model_id.unwrap_or(0)
    }
    fn is_valid(&self) -> bool {
        self.uuid.is_some()
    }
    fn wrap(obj: Master) -> store::Wrapper {
        store::Wrapper::Master(Box::new(obj))
    }
}

impl Master {

}
<commit_msg>masters: handle most of the properties. Ignore others.<commit_after>/*
  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

use std::path::Path;
use chrono::{
    DateTime,
    Utc
};
use store;
use AplibObject;
use AplibType;
use audit::{
    audit_get_str_value, audit_get_int_value, audit_get_bool_value,
    audit_get_date_value,
    Report, SkipReason
};

pub struct Master {
    uuid: Option<String>,
    model_id: Option<i64>,
    project_uuid: Option<String>,

    pub alternate_master: Option<String>,
    pub original_version_uuid: Option<String>,
    pub import_group_uuid: Option<String>,
    pub filename: Option<String>,
    pub name: Option<String>,
    pub original_version_name: Option<String>,
    pub db_version: Option<i64>,
    pub master_type: Option<String>,
    pub subtype: Option<String>,
    pub image_path: Option<String>,
    pub is_reference: Option<bool>,
    pub is_truly_raw: Option<bool>,
    pub is_in_trash: Option<bool>,
    pub is_missing: Option<bool>,
    pub is_externaly_editable: Option<bool>,
    pub create_date: Option<DateTime<Utc>>,
    pub image_date: Option<DateTime<Utc>>,
    pub file_creation_date: Option<DateTime<Utc>>,
    pub file_modification_date: Option<DateTime<Utc>>,
    pub original_file_name: Option<String>,
    pub file_size: Option<i64>,
    pub file_volume_uuid: Option<String>,
    pub color_space_name: Option<String>,
    pub pixel_format: Option<i64>,
    pub has_focus_points: Option<i64>,
    pub image_format: Option<i64>, // XXX fix this is a 4char MSB
}

impl AplibObject for Master {
    fn from_path(plist_path: &Path,
                 mut auditor: Option<&mut Report>) -> Option<Master> {

        use plutils::*;
        let plist = parse_plist(plist_path);
        match plist {
            Plist::Dictionary(ref dict) => {
                let result = Some(Master {
                    uuid: audit_get_str_value(dict, "uuid", &mut auditor),
                    alternate_master: audit_get_str_value(
                        dict, "alternateMasterUuid", &mut auditor),
                    original_version_uuid: audit_get_str_value(
                        dict, "originalVersionUuid", &mut auditor),
                    project_uuid: audit_get_str_value(
                        dict, "projectUuid", &mut auditor),
                    import_group_uuid: audit_get_str_value(
                        dict, "importGroupUuid", &mut auditor),
                    filename: audit_get_str_value(dict, "fileName", &mut auditor),
                    name: audit_get_str_value(dict, "name", &mut auditor),
                    original_version_name: audit_get_str_value(
                        dict, "originalVersionName", &mut auditor),
                    original_file_name: audit_get_str_value(
                        dict, "originalFileName", &mut auditor),
                    file_volume_uuid: audit_get_str_value(
                        dict, "fileVolumeUuid", &mut auditor),
                    db_version: audit_get_int_value(dict, "version", &mut auditor),
                    master_type: audit_get_str_value(dict, "type", &mut auditor),
                    subtype: audit_get_str_value(dict, "subtype", &mut auditor),
                    model_id: audit_get_int_value(dict, "modelId", &mut auditor),
                    image_path: audit_get_str_value(dict, "imagePath", &mut auditor),
                    file_size: audit_get_int_value(dict, "fileSize", &mut auditor),
                    is_reference: audit_get_bool_value(
                        dict, "fileIsReference", &mut auditor),
                    is_externaly_editable: audit_get_bool_value(
                        dict, "isExternallyEditable", &mut auditor),
                    is_in_trash: audit_get_bool_value(
                        dict, "isInTrash", &mut auditor),
                    is_missing: audit_get_bool_value(
                        dict, "isMissing", &mut auditor),
                    is_truly_raw: audit_get_bool_value(
                        dict, "isTrulyRaw", &mut auditor),
                    color_space_name: audit_get_str_value(
                        dict, "colorSpaceName", &mut auditor),
                    create_date: audit_get_date_value(dict, "createDate", &mut auditor),
                    image_date: audit_get_date_value(dict, "imageDate", &mut auditor),
                    file_creation_date: audit_get_date_value(dict, "fileCreationDate", &mut auditor),
                    file_modification_date: audit_get_date_value(
                        dict, "fileModificationDate", &mut auditor),
                    has_focus_points: audit_get_int_value(dict, "hasFocusPoints", &mut auditor),
                    image_format: audit_get_int_value(dict, "imageFormat", &mut auditor),
                    pixel_format: audit_get_int_value(dict, "pixelFormat", &mut auditor),
                });
                if auditor.is_some() {
                    let ref mut auditor = auditor.unwrap();
                    auditor.skip("faceDetectionState", SkipReason::Ignore);
                    auditor.skip("fileAliasData", SkipReason::Ignore);
                    auditor.skip("notes", SkipReason::Ignore);
                    auditor.skip("importedBy", SkipReason::Ignore);
                    auditor.skip("importGroup", SkipReason::Ignore);
                    auditor.skip("plistWriteTimestamp", SkipReason::Ignore);

                    auditor.audit_ignored(dict, None);
                }
                result
            },
            _ =>
                None
        }
    }
    fn obj_type(&self) -> AplibType {
        AplibType::Master
    }
    fn uuid(&self) -> &Option<String> {
        &self.uuid
    }
    fn parent(&self) -> &Option<String> {
        &self.project_uuid
    }
    fn model_id(&self) -> i64 {
        self.model_id.unwrap_or(0)
    }
    fn is_valid(&self) -> bool {
        self.uuid.is_some()
    }
    fn wrap(obj: Master) -> store::Wrapper {
        store::Wrapper::Master(Box::new(obj))
    }
}

impl Master {

}
<|endoftext|>


<commit_before>use super::{AssertionFailure, Spec};

use std::cmp::PartialEq;
use std::fmt::Debug;

pub trait OptionAssertions<'r, T>
    where T: Debug
{
    fn is_some(&mut self) -> Spec<'r, T>;
    fn is_none(&mut self);
}

pub trait ContainingOptionAssertions<T>
    where T: Debug + PartialEq
{
    fn contains_value(&mut self, expected_value: &T);
}

impl<'s, T> ContainingOptionAssertions<T> for Spec<'s, Option<T>>
    where T: Debug + PartialEq
{
    /// Asserts that the subject is a `Some` containing the expected value. The subject type must
    /// be an `Option`.
    ///
    /// ```rust,ignore
    /// assert_that(&Some(1)).contains_value(&1);
    /// ```
    fn contains_value(&mut self, expected_value: &T) {
        match *self.subject {
            Some(ref val) => {
                if !val.eq(expected_value) {
                    AssertionFailure::from_spec(self)
                        .with_expected(format!("option to contain <{:?}>", expected_value))
                        .with_actual(format!("<{:?}>", val))
                        .fail();
                }
            }
            None => {
                AssertionFailure::from_spec(self)
                    .with_expected(format!("option<{:?}>", expected_value))
                    .with_actual(format!("option[none]"))
                    .fail();
            }
        };
    }
}

impl<'s, T> OptionAssertions<'s, T> for Spec<'s, Option<T>>
    where T: Debug
{
    /// Asserts that the subject is `Some`. The subject type must be an `Option`.
    ///
    /// This will return a new `Spec` containing the unwrapped value if it is `Some`.
    ///
    /// ```rust,ignore
    /// assert_that(&Some(1)).is_some();
    /// ```
    fn is_some(&mut self) -> Spec<'s, T> {
        match *self.subject {
            Some(ref val) => {
                Spec {
                    subject: val,
                    subject_name: self.subject_name,
                    location: self.location.clone(),
                    description: self.description,
                }
            }
            None => {
                AssertionFailure::from_spec(self)
                    .with_expected(format!("option[some]"))
                    .with_actual(format!("option[none]"))
                    .fail();

                unreachable!();
            }
        }
    }

    /// Asserts that the subject is `None`. The value type must be an `Option`.
    ///
    /// ```rust,ignore
    /// assert_that(&Option::None::<String>).is_none();
    /// ```
    fn is_none(&mut self) {
        match *self.subject {
            None => (),
            Some(ref val) => {
                AssertionFailure::from_spec(self)
                    .with_expected(format!("option[none]"))
                    .with_actual(format!("option<{:?}>", val))
                    .fail();
            }
        }
    }
}

#[cfg(test)]
mod tests {

    use super::super::prelude::*;

    #[test]
    fn should_not_panic_if_option_is_expected_to_contain_value_and_does() {
        let option = Some("Hello");
        assert_that(&option).is_some();
    }

    #[test]
    #[should_panic(expected = "\n\texpected: option[some]\n\t but was: option[none]")]
    fn should_panic_if_option_is_expected_to_contain_value_and_does_not() {
        let option: Option<&str> = None;
        assert_that(&option).is_some();
    }

    #[test]
    fn should_be_able_to_unwrap_option_if_some() {
        let option = Some("Hello");
        assert_that(&option).is_some().is_equal_to(&"Hello");
    }

    #[test]
    fn should_not_panic_if_option_contains_expected_value() {
        let option = Some("Hello");
        assert_that(&option).contains_value(&"Hello");
    }

    #[test]
    #[should_panic(expected = "\n\texpected: option to contain <\"Hi\">\n\t but was: <\"Hello\">")]
    fn should_panic_if_option_does_not_contain_expected_value() {
        let option = Some("Hello");
        assert_that(&option).contains_value(&"Hi");
    }

    #[test]
    #[should_panic(expected = "\n\texpected: option<\"Hello\">\n\t but was: option[none]")]
    fn should_panic_if_option_is_none_but_expected_value() {
        let option: Option<&str> = None;
        assert_that(&option).contains_value(&"Hello");
    }

    #[test]
    fn should_not_panic_if_option_is_empty() {
        let option: Option<&str> = None;
        assert_that(&option).is_none();
    }

    #[test]
    #[should_panic(expected = "\n\texpected: option[none]\n\t but was: option<\"Hello\"")]
    fn should_panic_if_option_is_not_empty_but_was_expected_as_empty() {
        let option = Some("Hello");
        assert_that(&option).is_none();
    }

}
<commit_msg>Add Borrow trait on assertions for Option<commit_after>use super::{AssertionFailure, Spec};

use std::borrow::Borrow;
use std::cmp::PartialEq;
use std::fmt::Debug;

pub trait OptionAssertions<'r, T>
    where T: Debug
{
    fn is_some(&mut self) -> Spec<'r, T>;
    fn is_none(&mut self);
}

pub trait ContainingOptionAssertions<T>
    where T: Debug + PartialEq
{
    fn contains_value<E: Borrow<T>>(&mut self, expected_value: E);
}

impl<'s, T> ContainingOptionAssertions<T> for Spec<'s, Option<T>>
    where T: Debug + PartialEq
{
    /// Asserts that the subject is a `Some` containing the expected value. The subject type must
    /// be an `Option`.
    ///
    /// ```rust,ignore
    /// assert_that(&Some(1)).contains_value(&1);
    /// ```
    fn contains_value<E: Borrow<T>>(&mut self, expected_value: E) {
        let borrowed_expected_value = expected_value.borrow();

        match *self.subject {
            Some(ref val) => {
                if !val.eq(borrowed_expected_value) {
                    AssertionFailure::from_spec(self)
                        .with_expected(format!("option to contain <{:?}>",
                                               borrowed_expected_value))
                        .with_actual(format!("<{:?}>", val))
                        .fail();
                }
            }
            None => {
                AssertionFailure::from_spec(self)
                    .with_expected(format!("option<{:?}>", borrowed_expected_value))
                    .with_actual(format!("option[none]"))
                    .fail();
            }
        };
    }
}

impl<'s, T> OptionAssertions<'s, T> for Spec<'s, Option<T>>
    where T: Debug
{
    /// Asserts that the subject is `Some`. The subject type must be an `Option`.
    ///
    /// This will return a new `Spec` containing the unwrapped value if it is `Some`.
    ///
    /// ```rust,ignore
    /// assert_that(&Some(1)).is_some();
    /// ```
    fn is_some(&mut self) -> Spec<'s, T> {
        match *self.subject {
            Some(ref val) => {
                Spec {
                    subject: val,
                    subject_name: self.subject_name,
                    location: self.location.clone(),
                    description: self.description,
                }
            }
            None => {
                AssertionFailure::from_spec(self)
                    .with_expected(format!("option[some]"))
                    .with_actual(format!("option[none]"))
                    .fail();

                unreachable!();
            }
        }
    }

    /// Asserts that the subject is `None`. The value type must be an `Option`.
    ///
    /// ```rust,ignore
    /// assert_that(&Option::None::<String>).is_none();
    /// ```
    fn is_none(&mut self) {
        match *self.subject {
            None => (),
            Some(ref val) => {
                AssertionFailure::from_spec(self)
                    .with_expected(format!("option[none]"))
                    .with_actual(format!("option<{:?}>", val))
                    .fail();
            }
        }
    }
}

#[cfg(test)]
mod tests {

    use super::super::prelude::*;

    #[test]
    fn should_not_panic_if_option_is_expected_to_contain_value_and_does() {
        let option = Some("Hello");
        assert_that(&option).is_some();
    }

    #[test]
    #[should_panic(expected = "\n\texpected: option[some]\n\t but was: option[none]")]
    fn should_panic_if_option_is_expected_to_contain_value_and_does_not() {
        let option: Option<&str> = None;
        assert_that(&option).is_some();
    }

    #[test]
    fn should_be_able_to_unwrap_option_if_some() {
        let option = Some("Hello");
        assert_that(&option).is_some().is_equal_to(&"Hello");
    }

    #[test]
    fn contains_value_should_allow_multiple_borrow_types() {
        let option = Some("Hello");
        assert_that(&option).contains_value("Hello");
        assert_that(&option).contains_value(&mut "Hello");
        assert_that(&option).contains_value(&"Hello");
    }

    #[test]
    fn should_not_panic_if_option_contains_expected_value() {
        let option = Some("Hello");
        assert_that(&option).contains_value(&"Hello");
    }

    #[test]
    #[should_panic(expected = "\n\texpected: option to contain <\"Hi\">\n\t but was: <\"Hello\">")]
    fn should_panic_if_option_does_not_contain_expected_value() {
        let option = Some("Hello");
        assert_that(&option).contains_value(&"Hi");
    }

    #[test]
    #[should_panic(expected = "\n\texpected: option<\"Hello\">\n\t but was: option[none]")]
    fn should_panic_if_option_is_none_but_expected_value() {
        let option: Option<&str> = None;
        assert_that(&option).contains_value(&"Hello");
    }

    #[test]
    fn should_not_panic_if_option_is_empty() {
        let option: Option<&str> = None;
        assert_that(&option).is_none();
    }

    #[test]
    #[should_panic(expected = "\n\texpected: option[none]\n\t but was: option<\"Hello\"")]
    fn should_panic_if_option_is_not_empty_but_was_expected_as_empty() {
        let option = Some("Hello");
        assert_that(&option).is_none();
    }

}
<|endoftext|>