//! > Test expansion of panic_with.

//! > test_function_name
test_expand_plugin

//! > cairo_code
#[panic_with('1', foo_improved)]
extern fn foo(a: felt, b: other) -> Option::<()> implicits(RangeCheck, GasBuiltin) nopanic;

#[panic_with('2', bar_changed)]
extern fn bar() -> Result::<felt, Err> nopanic;

#[panic_with('3', non_extern_stuff)]
fn non_extern(_: some_type) -> Option::<(felt, other)> nopanic {
    (4, 56)
}

//! > generated_cairo_code
#[panic_with('1', foo_improved)]
extern fn foo(a: felt, b: other) -> Option::<()> implicits(RangeCheck, GasBuiltin) nopanic;

fn foo_improved(a: felt, b: other) -> () {
    match foo(a, b) {
        Option::Some (v) => {
            v
        },
        Option::None (v) => {
            let mut data = array_new::<felt>();
            array_append::<felt>(data, '1');
            panic(data)
        },
    }
}


#[panic_with('2', bar_changed)]
extern fn bar() -> Result::<felt, Err> nopanic;

fn bar_changed() -> felt {
    match bar() {
        Result::Ok (v) => {
            v
        },
        Result::Err (v) => {
            let mut data = array_new::<felt>();
            array_append::<felt>(data, '2');
            panic(data)
        },
    }
}


#[panic_with('3', non_extern_stuff)]
fn non_extern(_: some_type) -> Option::<(felt, other)> nopanic {
    (4, 56)
}
fn non_extern_stuff(_: some_type) -> (felt, other) {
    match non_extern(_) {
        Option::Some (v) => {
            v
        },
        Option::None (v) => {
            let mut data = array_new::<felt>();
            array_append::<felt>(data, '3');
            panic(data)
        },
    }
}

//! > expected_diagnostics

//! > ==========================================================================

//! > Test diagnostics of panic with.

//! > test_function_name
test_expand_plugin

//! > cairo_code
#[panic_with(123, foo_bad_err_code)]
extern fn foo(a: felt, b: other) -> Option::<()> implicits(RangeCheck, GasBuiltin) nopanic;

#[panic_with('2', bar_not_nopanic)]
fn bar() -> Result::<felt, Err> { Result::<felt, Err>::Ok(1) }

#[panic_with(missing_args)]
extern fn non_extern(_: some_type) -> Option::<(felt, other)> nopanic;

#[panic_with(missing_args)]
extern fn bad_ret_type(_: some_type) -> felt nopanic;

//! > generated_cairo_code

//! > expected_diagnostics
error: Failed to extract panic data attribute
 --> dummy_file.cairo:1:1
#[panic_with(123, foo_bad_err_code)]
^**********************************^

error: Only nopanic functions can be wrapped
 --> dummy_file.cairo:4:1
#[panic_with('2', bar_not_nopanic)]
^*********************************^

error: Failed to extract panic data attribute
 --> dummy_file.cairo:7:1
#[panic_with(missing_args)]
^*************************^

error: Currently only wrapping functions returning an Option<T> or Result<T, E>
 --> dummy_file.cairo:11:38
extern fn bad_ret_type(_: some_type) -> felt nopanic;
                                     ^*****^
