Refactor capnp-futures and capnp-rpc for Improved no-std Compatibility #599
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
This pull request introduces a significant refactoring of the
capnp-futuresandcapnp-rpccrates to enhance compatibility withno_stdenvironments. The changes replace direct usage ofstdwithallocandcorewhere possible, while introducing feature flags to control the level of standard library dependency. This enables the crates to be used in embedded systems and other constrained environments that cannot rely on the full standard library.Key Changes
1. Feature Flag Introduction
New Features in
capnp-futures/Cargo.toml:default = ["std"]: Maintains backward compatibility by defaulting to std-enabled buildsstd: Enables standard library features, includingfutures-channel/std,futures-util/std, andembedded-io-async?/stdalloc: Enables allocation features forfutures/allocandembedded-io-async?/allocembedded-io: Adds support forembedded-io-asyncas an optional dependency for embedded I/O operationsNew Features in
capnp-rpc/Cargo.toml:default = ["std"],std, andallocfeatures2. Library Configuration Updates
capnp-futures/src/lib.rs:#![cfg_attr(not(feature = "std"), no_std)]for conditional no_std compilationextern crate alloc;when theallocfeature is enabledclippy::std_instead_of_alloc,clippy::std_instead_of_core,clippy::alloc_instead_of_corecapnp-rpc/src/lib.rs:allocandcoreinstead ofstd3. Import and Type Replacements
std::future::Future→core::future::Futurestd::pin::Pin→core::pin::Pinstd::task::{Context, Poll}→core::task::{Context, Poll}std::rc::Rc→alloc::rc::Rcstd::sync::Arc→alloc::sync::Arcstd::vec::Vec→alloc::vec::Vecstd::boxed::Box→alloc::boxed::Boxstd::string::ToString→alloc::string::ToStringstd::collections::HashMap→ Conditional:std::collections::HashMap(with std) oralloc::collections::BTreeMap(without std)std::collections::BTreeMap→alloc::collections::BTreeMapstd::cell::RefCell→core::cell::RefCellstd::mem→core::memstd::marker::PhantomData→core::marker::PhantomDatastd::iter::Iterator→core::iter::Iteratorstd::fmt::Debug→core::fmt::Debug4. Conditional Compilation for Collections
capnp-rpc/src/rpc.rs:CapabilityServerSetnow usesstd::collections::HashMapwhenstdfeature is enabled, andalloc::collections::BTreeMapotherwise5. I/O Abstraction Updates
capnp-rpc/src/twoparty.rs:AsyncReadandAsyncWriteembedded-iofeature is enabled, usesembedded_io_async::{Read, Write}instead offutures::{AsyncRead, AsyncWrite}6. Error Handling Adjustments
capnp-rpc/src/rpc.rs:SystemTaskReaper::task_failednow conditionally prints errors only whenstdfeature is available7. Dependency Updates
capnp-futures/Cargo.toml:embedded-io-async = { version = "0.7.0", optional = true }futures-utilto usefeatures = ["io"]instead of["io", "std"]stdMotivation
The primary motivation for this refactoring is to enable the use of Cap'n Proto RPC in
no_stdenvironments, such as embedded systems, microcontrollers, and other constrained platforms. By minimizing dependencies on the standard library and providing feature flags for different levels of functionality, this change opens up new use cases for the library.Limitations and Current Constraints
Despite these improvements, there are still some limitations to full
no_stdcompatibility:I/O Operations Still Require
std: The current implementation still relies onstd::iofor certain I/O operations. This means that while the core RPC logic can operate withoutstd, actual network communication still requires standard library support.Embedded Platform Compatibility:
std::iodependency for I/O operations.stdsupport, but limited to bare-metal ESP32 microcontrollers. Full ESP-IDF integration would require additional work to abstract away the I/O layer.Collection Performance: In
no_stdmode,BTreeMapis used instead ofHashMap, which may have performance implications for applications with many capabilities.Testing and Compatibility
stdfeature enabledno_std+allocfunctionalityembedded-iofeature should be tested with actual embedded I/O implementationsFuture Work
To achieve full
no_stdcompatibility, future PRs should focus on:embedded-iotraits throughout the codebasestddependenciesno_stdenvironmentsThis refactoring represents a significant step towards broader platform support while maintaining backward compatibility for existing users.