06 Jun 2020
Over the past few years, many people have expressed interest in using capnproto-rust in no_std environments – that is, without pulling in the Rust standard library. Today I’m happy to announce that the latest release, version 0.13.0, supports that.
To use a no_std
capnproto-rust,
update your Cargo.toml
to the new capnp
version and disable default features, like this:
[capnp.dependencies]
version = "0.13"
default-features = false
This turns off the new
“std” feature flag
in the capnp
crate.
In turn, that feature controls a
crate-level no_std
attribute
and gates the parts of the crate that depend on the standard library.
To see no_std
capnproto-rust in action,
check out this new example
that passes data to a WebAssembly function through a Cap’n Proto message.
I observed the size of this example’s generated wasm code to shrink from
1.6MB down to 660KB when I added #![no_std]
.
The biggest challenge in getting capnproto-rust to work with no_std
was dealing with
input/output traits.
In previous releases, capnproto-rust defined its main serialization functions in terms of
std::io::Read
and std::io::Write
. That would be a problem in a no_std
context,
because those traits are stuck in std
.
The solution I settled on was to define custom
capnp::io::Read
and
capnp::io::Write
traits, and then to define the capnp
serialization functions in terms of those.
Blanket impls like the following then allow existing call sites to continue to work without being altered:
#[cfg(feature="std")]
mod std_impls {
impl <R: std::io::Read> crate::io::Read for R {
...
}
impl <W: std::io::Write> crate::io::Write for W {
...
}
}
Two recent Rust developments paved the way for today’s release:
Vec
are now usable with no_std
. (capnproto-rust strives
to minimize allocations, but still relies on the global allocator for some things like
messages with a dynamic number of segments.)async
blocks wherever we want. Previously, we would have needed to define
some custom Future
implementations to avoid putting an async
block in the capnp
crate.Many people contributed useful ideas in the discussion that led up to the 0.13 release. I am especially grateful to nicholastmosher and bbqsrc for submitting diffs that explored the design space.