Iterating through a `StateMap` to create a vector

I am using this function

    let response = *host.state().collections.iter().map(| (_id, address) | address).collect::<Vec<AccountAddress>>();

to get the values of the Map and store them in a vector. I am getting this error

a value of type `concordium_std::Vec<concordium_std::AccountAddress>` cannot be built from an iterator over elements of type `StateRef<'_, concordium_std::ContractAddress>`
the trait `FromIterator<StateRef<'_, concordium_std::ContractAddress>>` is not implemented for `concordium_std::Vec<concordium_std::AccountAddress>`

I dereferences the host to be able to get values rather than StateRef but the error is still persistent.

The iter is an iterator over StateRef's (StateRef in concordium_std - Rust ). This is something like a MutexGuard.

If you want to get the data out you need to dereference it, e.g.,

    let response = *host.state().collections.iter().map(| (_id, address) | *address).collect::<Vec<AccountAddress>>();

Does that make sense?

1 Like

Makes sense but now I am getting the error

the size for values of type `[concordium_std::ContractAddress]` cannot be known at compilation time
the trait `Sized` is not implemented for `[concordium_std::ContractAddress]`
all local variables must have a statically known size
unsized locals are gated as an unstable feature

I am building a function that returns a vector of addresses

Can you tell me the type of your collections?

collections: StateMap<u32,ContractAddress, S>,

I am not sure why you are getting that error exactly, but

fn convert<S: HasStateApi>(state: &StateMap<u32, ContractAddress, S>) -> Vec<ContractAddress> {
    state.iter().map(|(_, addr)| *addr).collect::<Vec<_>>()
}

compiles without issues.

I can see that in your line you have

::<Vec<AccountAddress>>

but you want

::<Vec<ContractAddress>>

But I don’t expect the exact error you have as a result of this. The error should be

     |
77   |     state.iter().map(|(_, addr)| *addr).collect::<Vec<AccountAddress>>()
     |                                         ^^^^^^^ value of type `concordium_std::Vec<concordium_std::AccountAddress>` cannot be built from `std::iter::Iterator<Item=concordium_std::ContractAddress>`
     |
     = help: the trait `FromIterator<concordium_std::ContractAddress>` is not implemented for `concordium_std::Vec<concordium_std::AccountAddress>`
     = help: the trait `FromIterator<T>` is implemented for `concordium_std::Vec<T>`