2

I'm trying to use sp_std::collections::btree_map::BTreeMap for offchain worker Local Storage.

While

let foo = StorageValueRef::persistent(b"bar::foo");
foo.get::<BTreeMap<u32, u32>>();

compiles,

when a custom struct is used as a key as follows:

use sp_core::{Decode, Encode};

#[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
struct Foo(u32);

let foo = StorageValueRef::persistent(b"bar::foo");
foo.get::<BTreeMap<Foo, u32>>();

compilation fails due to:

  18 |     foo.get::<BTreeMap<Foo, u32>>();
     |               ^^^^^^^^^^^^^^^^^^ the trait `sp_core::Decode` is not implemented for `BTreeMap<Foo, u32>`
     |
     = help: the trait `sp_core::Decode` is implemented for `BTreeMap<K, V>`

Curiously, I can use a sp_std::vec::Vec like so

    let foo = StorageValueRef::persistent(b"bar::foo");
    foo.get::<Vec<(Foo, u32)>>();

which compiles just fine.

1 Answer 1

1

https://docs.rs/parity-scale-codec/3.4.0/src/parity_scale_codec/codec.rs.html#1084-1093

impl_codec_through_iterator! {
    BTreeMap { K: Ord, V } { LikeK, LikeV}
        { K: EncodeLike<LikeK>, LikeK: Encode, V: EncodeLike<LikeV>, LikeV: Encode }
    BTreeSet { T: Ord } { LikeT }
        { T: EncodeLike<LikeT>, LikeT: Encode }
    LinkedList { T } { LikeT }
        { T: EncodeLike<LikeT>, LikeT: Encode }
    BinaryHeap { T: Ord } { LikeT }
        { T: EncodeLike<LikeT>, LikeT: Encode }
}

It only implements for BTreeMap<K, V: Decode>.

But in your case, your K is a Decodeable thing, which does not satisfy this implementation.

BTreeMap<u32, Foo> will work.

1
  • oops, my fault, I didn't notice Ord impl was missing, the error message possibly confused me. Thanks ! Commented May 10, 2023 at 23:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.