//! > Test expansion of a simple starknet contract.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: false)

//! > cairo_code
#[derive(starknet::Event, starknet::Store, PartialEq, Drop, Serde)]
struct A {
    x: felt252,
    #[key]
    data: usize,
}

#[derive(starknet::Event, PartialEq, Drop, Serde)]
struct B {
    x: felt252,
}


#[derive(starknet::Event, PartialEq, Drop)]
enum NestedEventEnum {
    B: B,
}


#[derive(starknet::Event, PartialEq, Drop)]
enum MyEventEnum {
    A: A,
    B: B,
    #[flat]
    C: NestedEventEnum,
    #[flat]
    D: NestedEventEnum,
}

//! > generated_cairo_code
lib.cairo:

#[derive(starknet::Event, starknet::Store, PartialEq, Drop, Serde)]
struct A {
    x: felt252,
    #[key]
    data: usize,
}

#[derive(starknet::Event, PartialEq, Drop, Serde)]
struct B {
    x: felt252,
}


#[derive(starknet::Event, PartialEq, Drop)]
enum NestedEventEnum {
    B: B,
}


#[derive(starknet::Event, PartialEq, Drop)]
enum MyEventEnum {
    A: A,
    B: B,
    #[flat]
    C: NestedEventEnum,
    #[flat]
    D: NestedEventEnum,
}

lib.cairo:1:1
#[derive(starknet::Event, starknet::Store, PartialEq, Drop, Serde)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
impls:

impl APartialEq of core::traits::PartialEq::<A> {
    fn eq(lhs: @A, rhs: @A) -> bool {
        lhs.x == rhs.x && lhs.data == rhs.data
    }
}
impl ADrop of core::traits::Drop::<A>;
impl ASerde of core::serde::Serde::<A> {
    fn serialize(self: @A, ref output: core::array::Array<felt252>) {
        core::serde::Serde::serialize(self.x, ref output);
        core::serde::Serde::serialize(self.data, ref output)
    }
    fn deserialize(ref serialized: core::array::Span<felt252>) -> core::option::Option<A> {
        core::option::Option::Some(A {
            x: core::serde::Serde::deserialize(ref serialized)?,
            data: core::serde::Serde::deserialize(ref serialized)?,
        })
    }
}


lib.cairo:1:1-6:1
  #[derive(starknet::Event, starknet::Store, PartialEq, Drop, Serde)]
 _^
| ...
| }
|_^
starknet_derive:

impl AIsEvent of starknet::Event<A> {
    fn append_keys_and_data(
        self: @A, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
            core::serde::Serde::serialize(self.x, ref data);
                core::serde::Serde::serialize(self.data, ref keys);
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<A> {
                let x = core::serde::Serde::deserialize(
                    ref data
                )?;
                let data = core::serde::Serde::deserialize(
                    ref keys
                )?;
        Option::Some(A {x, data, })
    }
}
impl StoreA of starknet::Store::<A> {
    fn read(address_domain: u32, base: starknet::storage_access::StorageBaseAddress) -> starknet::SyscallResult<A> {
        let x = starknet::Store::<felt252>::read(address_domain, base)?;
        let mut current_offset = starknet::Store::<felt252>::size();
        let data = starknet::Store::<usize>::read_at_offset(address_domain, base, current_offset)?;
        starknet::SyscallResult::Ok(
            A {
                x,
                data,
            }
        )
    }
    fn write(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, value: A) -> starknet::SyscallResult<()> {
        starknet::Store::<felt252>::write(address_domain, base, value.x)?;
        let mut current_offset = starknet::Store::<felt252>::size();
        starknet::Store::<usize>::write_at_offset(address_domain, base, current_offset, value.data)?;
        starknet::SyscallResult::Ok(())
    }
    fn read_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8) -> starknet::SyscallResult<A> {
        let x = starknet::Store::<felt252>::read_at_offset(address_domain, base, offset)?;
        let mut current_offset = offset + starknet::Store::<felt252>::size();
        let data = starknet::Store::<usize>::read_at_offset(address_domain, base, current_offset)?;
        starknet::SyscallResult::Ok(
            A {
                x,
                data,
            }
        )
    }
    #[inline(always)]
    fn write_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8, value: A) -> starknet::SyscallResult<()> {
        starknet::Store::<felt252>::write_at_offset(address_domain, base, offset, value.x)?;
        let mut current_offset = offset + starknet::Store::<felt252>::size();
        starknet::Store::<usize>::write_at_offset(address_domain, base, current_offset, value.data)?;
        starknet::SyscallResult::Ok(())
    }
    #[inline(always)]
    fn size() -> u8 {
        starknet::Store::<felt252>::size() +
        starknet::Store::<usize>::size()
    }
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct ASubPointers {
    pub x: starknet::storage::StoragePointer<felt252>,
    #[key]
    pub data: starknet::storage::StoragePointer<usize>,
}
#[doc(hidden)]
impl ASubPointersImpl of starknet::storage::SubPointers<A> {
    type SubPointersType = ASubPointers;
    fn sub_pointers(self: starknet::storage::StoragePointer<A>) -> ASubPointers {
        let base_address = self.__storage_pointer_address__;
        let mut current_offset = self.__storage_pointer_offset__;
        let __x_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
        current_offset = current_offset + starknet::Store::<felt252>::size();
        let __data_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
                ASubPointers {
           x: __x_value__,
           data: __data_value__,
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct ASubPointersMut {
    pub x: starknet::storage::StoragePointer<starknet::storage::Mutable::<felt252>>,
    #[key]
    pub data: starknet::storage::StoragePointer<starknet::storage::Mutable::<usize>>,
}
#[doc(hidden)]
impl ASubPointersMutImpl of starknet::storage::SubPointersMut<A> {
    type SubPointersType = ASubPointersMut;
    fn sub_pointers_mut(self: starknet::storage::StoragePointer<starknet::storage::Mutable::<A>>) -> ASubPointersMut {
        let base_address = self.__storage_pointer_address__;
        let mut current_offset = self.__storage_pointer_offset__;
        let __x_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
        current_offset = current_offset + starknet::Store::<felt252>::size();
        let __data_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
                ASubPointersMut {
           x: __x_value__,
           data: __data_value__,
        }
    }
}


lib.cairo:8:1
#[derive(starknet::Event, PartialEq, Drop, Serde)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
impls:

impl BPartialEq of core::traits::PartialEq::<B> {
    fn eq(lhs: @B, rhs: @B) -> bool {
        lhs.x == rhs.x
    }
}
impl BDrop of core::traits::Drop::<B>;
impl BSerde of core::serde::Serde::<B> {
    fn serialize(self: @B, ref output: core::array::Array<felt252>) {
        core::serde::Serde::serialize(self.x, ref output)
    }
    fn deserialize(ref serialized: core::array::Span<felt252>) -> core::option::Option<B> {
        core::option::Option::Some(B {
            x: core::serde::Serde::deserialize(ref serialized)?,
        })
    }
}


lib.cairo:8:10
#[derive(starknet::Event, PartialEq, Drop, Serde)]
         ^^^^^^^^^^^^^^^
starknet_derive:

impl BIsEvent of starknet::Event<B> {
    fn append_keys_and_data(
        self: @B, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
            core::serde::Serde::serialize(self.x, ref data);
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<B> {
                let x = core::serde::Serde::deserialize(
                    ref data
                )?;
        Option::Some(B {x, })
    }
}


lib.cairo:14:1
#[derive(starknet::Event, PartialEq, Drop)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
impls:

impl NestedEventEnumPartialEq of core::traits::PartialEq::<NestedEventEnum> {
    fn eq(lhs: @NestedEventEnum, rhs: @NestedEventEnum) -> bool {
        match lhs {
            NestedEventEnum::B(x) => match rhs {
                NestedEventEnum::B(y) => x == y,
            },
        }
    }
}
impl NestedEventEnumDrop of core::traits::Drop::<NestedEventEnum>;


lib.cairo:14:10
#[derive(starknet::Event, PartialEq, Drop)]
         ^^^^^^^^^^^^^^^
starknet_derive:

impl NestedEventEnumIsEvent of starknet::Event<NestedEventEnum> {
    fn append_keys_and_data(
        self: @NestedEventEnum, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
            NestedEventEnum::B(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("B"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<NestedEventEnum> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        if __selector__ == selector!("B") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(NestedEventEnum::B(val));
        }
        Option::None
    }
}
impl NestedEventEnumBIntoEvent of Into<B, NestedEventEnum> {
    fn into(self: B) -> NestedEventEnum {
        NestedEventEnum::B(self)
    }
}



lib.cairo:20:1
#[derive(starknet::Event, PartialEq, Drop)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
impls:

impl MyEventEnumPartialEq of core::traits::PartialEq::<MyEventEnum> {
    fn eq(lhs: @MyEventEnum, rhs: @MyEventEnum) -> bool {
        match lhs {
            MyEventEnum::A(x) => match rhs {
                MyEventEnum::A(y) => x == y,
                MyEventEnum::B(_y) => false,
                MyEventEnum::C(_y) => false,
                MyEventEnum::D(_y) => false,
            },
            MyEventEnum::B(x) => match rhs {
                MyEventEnum::A(_y) => false,
                MyEventEnum::B(y) => x == y,
                MyEventEnum::C(_y) => false,
                MyEventEnum::D(_y) => false,
            },
            MyEventEnum::C(x) => match rhs {
                MyEventEnum::A(_y) => false,
                MyEventEnum::B(_y) => false,
                MyEventEnum::C(y) => x == y,
                MyEventEnum::D(_y) => false,
            },
            MyEventEnum::D(x) => match rhs {
                MyEventEnum::A(_y) => false,
                MyEventEnum::B(_y) => false,
                MyEventEnum::C(_y) => false,
                MyEventEnum::D(y) => x == y,
            },
        }
    }
}
impl MyEventEnumDrop of core::traits::Drop::<MyEventEnum>;


lib.cairo:20:10
#[derive(starknet::Event, PartialEq, Drop)]
         ^^^^^^^^^^^^^^^
starknet_derive:

impl MyEventEnumIsEvent of starknet::Event<MyEventEnum> {
    fn append_keys_and_data(
        self: @MyEventEnum, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
            MyEventEnum::A(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("A"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
            MyEventEnum::B(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("B"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
            MyEventEnum::C(val) => {
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
            MyEventEnum::D(val) => {
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<MyEventEnum> {
        {
            let mut keys = keys;
            let mut data = data;
            match starknet::Event::deserialize(ref keys, ref data) {
                Option::Some(val) => {
                    return Option::Some(MyEventEnum::C(val));
                },
                Option::None => {},
            };
        }
        {
            let mut keys = keys;
            let mut data = data;
            match starknet::Event::deserialize(ref keys, ref data) {
                Option::Some(val) => {
                    return Option::Some(MyEventEnum::D(val));
                },
                Option::None => {},
            };
        }
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        if __selector__ == selector!("A") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(MyEventEnum::A(val));
        }
        if __selector__ == selector!("B") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(MyEventEnum::B(val));
        }
        Option::None
    }
}
impl MyEventEnumAIntoEvent of Into<A, MyEventEnum> {
    fn into(self: A) -> MyEventEnum {
        MyEventEnum::A(self)
    }
}
impl MyEventEnumBIntoEvent of Into<B, MyEventEnum> {
    fn into(self: B) -> MyEventEnum {
        MyEventEnum::B(self)
    }
}
impl MyEventEnumCIntoEvent of Into<NestedEventEnum, MyEventEnum> {
    fn into(self: NestedEventEnum) -> MyEventEnum {
        MyEventEnum::C(self)
    }
}
impl MyEventEnumDIntoEvent of Into<NestedEventEnum, MyEventEnum> {
    fn into(self: NestedEventEnum) -> MyEventEnum {
        MyEventEnum::D(self)
    }
}



lib.cairo:1:27
#[derive(starknet::Event, starknet::Store, PartialEq, Drop, Serde)]
                          ^^^^^^^^^^^^^^^
impls:

impl ASubPointersDrop of core::traits::Drop::<ASubPointers>;
impl ASubPointersCopy of core::traits::Copy::<ASubPointers>;


lib.cairo:1:27
#[derive(starknet::Event, starknet::Store, PartialEq, Drop, Serde)]
                          ^^^^^^^^^^^^^^^
impls:

impl ASubPointersMutDrop of core::traits::Drop::<ASubPointersMut>;
impl ASubPointersMutCopy of core::traits::Copy::<ASubPointersMut>;

//! > expected_diagnostics
