Search code examples
rustwebassemblyrust-no-std

What do I replace Vec and HashSet with in a no_std environmement?


I'm working on a project that's meant to be compiled to webassembly. So I guess I have to mark the library as no_std. But as it currently relies on Vec, String and HashSet quite a lot this seems to be impossible as I get errors for those features.

How can I remove/replace those features without loosing the functionality in a no_std environment like webassembly. I guess I could go for &str instead of String, but what about the others?

If I remove #![cfg_attr(not(test), no_std)] and compile the project it seems to work as a webassembly binary. Why is that, if I get errors when adding the line?


Solution

  • As has been mentioned in the comments, you don't need to restrict yourself to no_std in WASM, since much of the standard library is available, including both of these collections.

    However, if you're building in a real no_std environment, you can use Vec provided you use the alloc crate, which allows you to allocate memory. String is likewise available. In most situations, you will have some memory allocation available, so alloc is an option.

    You can't use HashMap or HashSet in a no_std environment because to avoid hash collision attacks, they need to have access to a secure source of random data. Even no_std environments may deal with untrusted data, so preserving this security invariant is important. There, you can use the BTreeMap and BTreeSet instead (also from alloc), which provide similar functionality with slightly different performance characteristics and slightly different requirements on the data in question. Because these collections are deterministic, they can be implemented without more than a memory allocator.