//! > Test expansion of StarkNet storage logic.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: warnings_only)

//! > cairo_code
#[derive(Drop, starknet::Store, Hash)]
struct OuterType {
    x: u32,
}

// TODO(ilya): update format.
#[starknet::contract]
mod test_contract {
    #[storage]
    struct Storage {
        var_felt252: felt252,
        var_u8: u8,
        var_u16: u16,
        var_u32: u32,
        var_u64: u64,
        var_u128: u128,
        var_bool: bool,
        felt252_to_u128: LegacyMap::<felt252, u128>,
        u128_to_bool: LegacyMap::<u128, bool>,
        bool_to_felt252: LegacyMap::<bool, felt252>,
        outer_type_var: super::OuterType,
        outer_type_to_outer_type: LegacyMap::<super::OuterType, super::OuterType>,
        inner_type_var: inner::InnerType,
        inner_type_to_inner_type: LegacyMap::<inner::InnerType, inner::InnerType>,
    }

    mod inner {
        #[derive(Drop, starknet::Store, Hash)]
        struct InnerType {
            x: u32,
        }
    }
}

//! > generated_cairo_code
lib.cairo:

#[derive(Drop, starknet::Store, Hash)]
struct OuterType {
    x: u32,
}

// TODO(ilya): update format.
#[starknet::contract]
mod test_contract {
    #[storage]
    struct Storage {
        var_felt252: felt252,
        var_u8: u8,
        var_u16: u16,
        var_u32: u32,
        var_u64: u64,
        var_u128: u128,
        var_bool: bool,
        felt252_to_u128: LegacyMap::<felt252, u128>,
        u128_to_bool: LegacyMap::<u128, bool>,
        bool_to_felt252: LegacyMap::<bool, felt252>,
        outer_type_var: super::OuterType,
        outer_type_to_outer_type: LegacyMap::<super::OuterType, super::OuterType>,
        inner_type_var: inner::InnerType,
        inner_type_to_inner_type: LegacyMap::<inner::InnerType, inner::InnerType>,
    }

    mod inner {
        #[derive(Drop, starknet::Store, Hash)]
        struct InnerType {
            x: u32,
        }
    }
}

lib.cairo:1:1
#[derive(Drop, starknet::Store, Hash)]
^************************************^
impls:

impl OuterTypeDrop of core::traits::Drop::<OuterType>;
impl OuterTypeHash<
    __State,
    impl __SHashState: core::hash::HashStateTrait<__State>,
    +Drop<__State>
> of core::hash::Hash<OuterType, __State, __SHashState> {
    #[inline(always)]
    fn update_state(state: __State, value: OuterType) -> __State {
        let state = core::hash::Hash::update_state(state, value.x);
        state
    }
}


lib.cairo:1:16
#[derive(Drop, starknet::Store, Hash)]
               ^*************^
starknet_derive:

impl StoreOuterType of starknet::Store::<OuterType> {
    fn read(address_domain: u32, base: starknet::storage_access::StorageBaseAddress) -> starknet::SyscallResult<OuterType> {
        let x = starknet::Store::<u32>::read(address_domain, base)?;
        starknet::SyscallResult::Ok(
            OuterType {
                x,
            }
        )
    }
    fn write(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, value: OuterType) -> starknet::SyscallResult<()> {
        starknet::Store::<u32>::write(address_domain, base, value.x)?;
        starknet::SyscallResult::Ok(())
    }
    fn read_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8) -> starknet::SyscallResult<OuterType> {
        let x = starknet::Store::<u32>::read_at_offset(address_domain, base, offset)?;
        starknet::SyscallResult::Ok(
            OuterType {
                x,
            }
        )
    }
    #[inline(always)]
    fn write_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8, value: OuterType) -> starknet::SyscallResult<()> {
        starknet::Store::<u32>::write_at_offset(address_domain, base, offset, value.x)?;
        starknet::SyscallResult::Ok(())
    }
    #[inline(always)]
    fn size() -> u8 {
        starknet::Store::<u32>::size()
    }
}

#[derive(Drop, Copy)]
pub struct OuterTypeSubPointers {
    pub x: starknet::storage::StoragePointer<u32>,
}
impl OuterTypeSubPointersImpl of starknet::storage::SubPointers<OuterType> {
    type SubPointersType = OuterTypeSubPointers;
    fn sub_pointers(self: starknet::storage::StoragePointer<OuterType>) -> OuterTypeSubPointers {
        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,
        };
                OuterTypeSubPointers {
           x: x_value,
        }
    }
}
#[derive(Drop, Copy)]
pub struct OuterTypeSubPointersMut {
    pub x: starknet::storage::StoragePointer<starknet::storage::Mutable::<u32>>,
}
impl OuterTypeSubPointersMutImpl of starknet::storage::SubPointersMut<OuterType> {
    type SubPointersType = OuterTypeSubPointersMut;
    fn sub_pointers_mut(self: starknet::storage::StoragePointer<starknet::storage::Mutable::<OuterType>>) -> OuterTypeSubPointersMut {
        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,
        };
                OuterTypeSubPointersMut {
           x: x_value,
        }
    }
}


lib.cairo:1:16
#[derive(Drop, starknet::Store, Hash)]
               ^*************^
impls:

impl OuterTypeSubPointersDrop of core::traits::Drop::<OuterTypeSubPointers>;
impl OuterTypeSubPointersCopy of core::traits::Copy::<OuterTypeSubPointers>;


lib.cairo:1:16
#[derive(Drop, starknet::Store, Hash)]
               ^*************^
impls:

impl OuterTypeSubPointersMutDrop of core::traits::Drop::<OuterTypeSubPointersMut>;
impl OuterTypeSubPointersMutCopy of core::traits::Copy::<OuterTypeSubPointersMut>;


lib.cairo:7:1
#[starknet::contract]
^*******************^
contract:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
        pub var_felt252: felt252,
        pub var_u8: u8,
        pub var_u16: u16,
        pub var_u32: u32,
        pub var_u64: u64,
        pub var_u128: u128,
        pub var_bool: bool,
        pub felt252_to_u128: LegacyMap::<felt252, u128>,
        pub u128_to_bool: LegacyMap::<u128, bool>,
        pub bool_to_felt252: LegacyMap::<bool, felt252>,
        pub outer_type_var: super::OuterType,
        pub outer_type_to_outer_type: LegacyMap::<super::OuterType, super::OuterType>,
        pub inner_type_var: inner::InnerType,
        pub inner_type_to_inner_type: LegacyMap::<inner::InnerType, inner::InnerType>,
}

#[derive(Drop, Copy)]
pub struct StorageStorageBase {
    pub var_felt252: starknet::storage::StorageBase<felt252>,
    pub var_u8: starknet::storage::StorageBase<u8>,
    pub var_u16: starknet::storage::StorageBase<u16>,
    pub var_u32: starknet::storage::StorageBase<u32>,
    pub var_u64: starknet::storage::StorageBase<u64>,
    pub var_u128: starknet::storage::StorageBase<u128>,
    pub var_bool: starknet::storage::StorageBase<bool>,
    pub felt252_to_u128: starknet::storage::StorageBase<LegacyMap::<felt252, u128>>,
    pub u128_to_bool: starknet::storage::StorageBase<LegacyMap::<u128, bool>>,
    pub bool_to_felt252: starknet::storage::StorageBase<LegacyMap::<bool, felt252>>,
    pub outer_type_var: starknet::storage::StorageBase<super::OuterType>,
    pub outer_type_to_outer_type: starknet::storage::StorageBase<LegacyMap::<super::OuterType, super::OuterType>>,
    pub inner_type_var: starknet::storage::StorageBase<inner::InnerType>,
    pub inner_type_to_inner_type: starknet::storage::StorageBase<LegacyMap::<inner::InnerType, inner::InnerType>>,
}
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        let var_felt252_value = starknet::storage::StorageBase {__base_address__: selector!("var_felt252")};
        let var_u8_value = starknet::storage::StorageBase {__base_address__: selector!("var_u8")};
        let var_u16_value = starknet::storage::StorageBase {__base_address__: selector!("var_u16")};
        let var_u32_value = starknet::storage::StorageBase {__base_address__: selector!("var_u32")};
        let var_u64_value = starknet::storage::StorageBase {__base_address__: selector!("var_u64")};
        let var_u128_value = starknet::storage::StorageBase {__base_address__: selector!("var_u128")};
        let var_bool_value = starknet::storage::StorageBase {__base_address__: selector!("var_bool")};
        let felt252_to_u128_value = starknet::storage::StorageBase {__base_address__: selector!("felt252_to_u128")};
        let u128_to_bool_value = starknet::storage::StorageBase {__base_address__: selector!("u128_to_bool")};
        let bool_to_felt252_value = starknet::storage::StorageBase {__base_address__: selector!("bool_to_felt252")};
        let outer_type_var_value = starknet::storage::StorageBase {__base_address__: selector!("outer_type_var")};
        let outer_type_to_outer_type_value = starknet::storage::StorageBase {__base_address__: selector!("outer_type_to_outer_type")};
        let inner_type_var_value = starknet::storage::StorageBase {__base_address__: selector!("inner_type_var")};
        let inner_type_to_inner_type_value = starknet::storage::StorageBase {__base_address__: selector!("inner_type_to_inner_type")};
        StorageStorageBase {
           var_felt252: var_felt252_value,
           var_u8: var_u8_value,
           var_u16: var_u16_value,
           var_u32: var_u32_value,
           var_u64: var_u64_value,
           var_u128: var_u128_value,
           var_bool: var_bool_value,
           felt252_to_u128: felt252_to_u128_value,
           u128_to_bool: u128_to_bool_value,
           bool_to_felt252: bool_to_felt252_value,
           outer_type_var: outer_type_var_value,
           outer_type_to_outer_type: outer_type_to_outer_type_value,
           inner_type_var: inner_type_var_value,
           inner_type_to_inner_type: inner_type_to_inner_type_value,
        }
    }
}
#[derive(Drop, Copy)]
pub struct StorageStorageBaseMut {
    pub var_felt252: starknet::storage::StorageBase<starknet::storage::Mutable::<felt252>>,
    pub var_u8: starknet::storage::StorageBase<starknet::storage::Mutable::<u8>>,
    pub var_u16: starknet::storage::StorageBase<starknet::storage::Mutable::<u16>>,
    pub var_u32: starknet::storage::StorageBase<starknet::storage::Mutable::<u32>>,
    pub var_u64: starknet::storage::StorageBase<starknet::storage::Mutable::<u64>>,
    pub var_u128: starknet::storage::StorageBase<starknet::storage::Mutable::<u128>>,
    pub var_bool: starknet::storage::StorageBase<starknet::storage::Mutable::<bool>>,
    pub felt252_to_u128: starknet::storage::StorageBase<starknet::storage::Mutable::<LegacyMap::<felt252, u128>>>,
    pub u128_to_bool: starknet::storage::StorageBase<starknet::storage::Mutable::<LegacyMap::<u128, bool>>>,
    pub bool_to_felt252: starknet::storage::StorageBase<starknet::storage::Mutable::<LegacyMap::<bool, felt252>>>,
    pub outer_type_var: starknet::storage::StorageBase<starknet::storage::Mutable::<super::OuterType>>,
    pub outer_type_to_outer_type: starknet::storage::StorageBase<starknet::storage::Mutable::<LegacyMap::<super::OuterType, super::OuterType>>>,
    pub inner_type_var: starknet::storage::StorageBase<starknet::storage::Mutable::<inner::InnerType>>,
    pub inner_type_to_inner_type: starknet::storage::StorageBase<starknet::storage::Mutable::<LegacyMap::<inner::InnerType, inner::InnerType>>>,
}
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        let var_felt252_value = starknet::storage::StorageBase {__base_address__: selector!("var_felt252")};
        let var_u8_value = starknet::storage::StorageBase {__base_address__: selector!("var_u8")};
        let var_u16_value = starknet::storage::StorageBase {__base_address__: selector!("var_u16")};
        let var_u32_value = starknet::storage::StorageBase {__base_address__: selector!("var_u32")};
        let var_u64_value = starknet::storage::StorageBase {__base_address__: selector!("var_u64")};
        let var_u128_value = starknet::storage::StorageBase {__base_address__: selector!("var_u128")};
        let var_bool_value = starknet::storage::StorageBase {__base_address__: selector!("var_bool")};
        let felt252_to_u128_value = starknet::storage::StorageBase {__base_address__: selector!("felt252_to_u128")};
        let u128_to_bool_value = starknet::storage::StorageBase {__base_address__: selector!("u128_to_bool")};
        let bool_to_felt252_value = starknet::storage::StorageBase {__base_address__: selector!("bool_to_felt252")};
        let outer_type_var_value = starknet::storage::StorageBase {__base_address__: selector!("outer_type_var")};
        let outer_type_to_outer_type_value = starknet::storage::StorageBase {__base_address__: selector!("outer_type_to_outer_type")};
        let inner_type_var_value = starknet::storage::StorageBase {__base_address__: selector!("inner_type_var")};
        let inner_type_to_inner_type_value = starknet::storage::StorageBase {__base_address__: selector!("inner_type_to_inner_type")};
        StorageStorageBaseMut {
           var_felt252: var_felt252_value,
           var_u8: var_u8_value,
           var_u16: var_u16_value,
           var_u32: var_u32_value,
           var_u64: var_u64_value,
           var_u128: var_u128_value,
           var_bool: var_bool_value,
           felt252_to_u128: felt252_to_u128_value,
           u128_to_bool: u128_to_bool_value,
           bool_to_felt252: bool_to_felt252_value,
           outer_type_var: outer_type_var_value,
           outer_type_to_outer_type: outer_type_to_outer_type_value,
           inner_type_var: inner_type_var_value,
           inner_type_to_inner_type: inner_type_to_inner_type_value,
        }
    }
}

pub struct ContractState {
}

impl ContractStateDrop of Drop<ContractState> {}
 
impl ContractStateDeref of core::ops::SnapshotDeref<ContractState> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn snapshot_deref(self: @ContractState) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ContractStateDerefMut of core::ops::DerefMut<ContractState> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ContractState) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_contract_state() -> ContractState {
    ContractState {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn contract_state_for_testing() -> ContractState {
    unsafe_new_contract_state()
}

// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
use starknet::storage::Map as LegacyMap;
#[cfg(target: 'test')]
pub const TEST_CLASS_HASH: felt252 = 0x33d119d7988d8f3251d554948b07e3215c9d66cf56f21bc80a6e513ea8e536;


pub mod __external {
}
pub mod __l1_handler {
}
pub mod __constructor {
}
    impl ContractStateEventEmitter of starknet::event::EventEmitter<
        ContractState, Event
    > {
        fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(
            ref self: ContractState, event: S
        ) {
            let event: Event = core::traits::Into::into(event);
            let mut keys = Default::<core::array::Array>::default();
            let mut data = Default::<core::array::Array>::default();
            starknet::Event::append_keys_and_data(@event, ref keys, ref data);
            starknet::SyscallResultTrait::unwrap_syscall(
                starknet::syscalls::emit_event_syscall(
                    core::array::ArrayTrait::span(@keys),
                    core::array::ArrayTrait::span(@data),
                )
            )
        }
    }



lib.cairo:7:1
#[starknet::contract]
^*******************^
impls:

impl EventDrop of core::traits::Drop::<Event>;


lib.cairo:7:1
#[starknet::contract]
^*******************^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:7:1
#[starknet::contract]
^*******************^
impls:

impl StorageStorageBaseDrop of core::traits::Drop::<StorageStorageBase>;
impl StorageStorageBaseCopy of core::traits::Copy::<StorageStorageBase>;


lib.cairo:7:1
#[starknet::contract]
^*******************^
impls:

impl StorageStorageBaseMutDrop of core::traits::Drop::<StorageStorageBaseMut>;
impl StorageStorageBaseMutCopy of core::traits::Copy::<StorageStorageBaseMut>;

//! > expected_diagnostics
warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[feature("deprecated_legacy_map")]` attribute. Note: "Use `starknet::storage::Map` instead."
 --> lib.cairo:18:26
        felt252_to_u128: LegacyMap::<felt252, u128>,
                         ^*******^

warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[feature("deprecated_legacy_map")]` attribute. Note: "Use `starknet::storage::Map` instead."
 --> lib.cairo:19:23
        u128_to_bool: LegacyMap::<u128, bool>,
                      ^*******^

warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[feature("deprecated_legacy_map")]` attribute. Note: "Use `starknet::storage::Map` instead."
 --> lib.cairo:20:26
        bool_to_felt252: LegacyMap::<bool, felt252>,
                         ^*******^

warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[feature("deprecated_legacy_map")]` attribute. Note: "Use `starknet::storage::Map` instead."
 --> lib.cairo:22:35
        outer_type_to_outer_type: LegacyMap::<super::OuterType, super::OuterType>,
                                  ^*******^

warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[feature("deprecated_legacy_map")]` attribute. Note: "Use `starknet::storage::Map` instead."
 --> lib.cairo:24:35
        inner_type_to_inner_type: LegacyMap::<inner::InnerType, inner::InnerType>,
                                  ^*******^

warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[feature("deprecated_legacy_map")]` attribute. Note: "Use `starknet::storage::Map` instead."
 --> lib.cairo:7:1
#[starknet::contract]
^*******************^
