Skip to content

Add no_std support#72

Merged
Ethiraric merged 3 commits into
saphyr-rs:masterfrom
bushrat011899:no_std
Oct 13, 2025
Merged

Add no_std support#72
Ethiraric merged 3 commits into
saphyr-rs:masterfrom
bushrat011899:no_std

Conversation

@bushrat011899

@bushrat011899 bushrat011899 commented Oct 6, 2025

Copy link
Copy Markdown
Contributor

Objective

Add no_std support while preserving the API as-is as much as possible. Since this project is still in an early pre-1.0 form, adding no_std support now will avoid possibly breaking changes later in its life.

Solution

  • Switched to alloc::collections::BTreeMap from std::collections::HashMap. hashbrown could be used instead, but since it is not currently included in saphyr-parser's dependency graph, I think it is preferable to use BTreeMap.
  • Switched to deriving thiserror::Error instead of manual Error implementation. This is done to preserve the 1.65 MSRV (since thiserror correctly handles choosing between core::error::Error and std::error::Error based on compiler version). This dependency is used in tests already, but is now a proper dependency. As an alternative, MSRV could be increased to the point where Error in core is stable, or a build.rs could be added which uses the same technique as thiserror. Just using thiserror is the least intrusive option in my opinion.
  • Ensured saphyr-parser and saphyr compile for no_std targets such as wasm32v1-none and x86_64-unknown-none. Added this to CI to ensure compatibility doesn't regress.
  • Marked sahpyr::loader::LoadError as non_exhaustive to handle the IO variant in no_std contexts. This is the only breaking change in this PR.
  • Switched to core and alloc instead of std where possible. Note that this implies that the crates are not no_alloc compatible (a much harder hurdle to clear).
  • Removed hashlink from saphyr-parser (it is currently unused) and arraydeque from sahpyr (likewise). These are no_std compatible, but they are unused and so just increase compilation time.

Notes

  • serde is also no_std compatible, so a future version of this crate with serde compatibility can still be no_std.
  • I've deliberately not added std features to either saphyr or saphyr_parser. The existing debug_prints and encoding features perfectly isolate the std functionality already, so an extra feature wouldn't really add anything.
  • I've marked the crates as always no_std using #![no_std], rather than using cfg_attr(...) to conditionally enable no_std support. This is a deliberate choice to avoid changes in the implicit prelude, which can cause extremely annoying CI failures based on feature combinations.
  • The one and only use of alloc::sync::Arc is currently feature-gated on saphyr/encoding, this has the added benefit of supporting platforms with partial atomic support (e.g., Raspberry Pi Pico, etc.). In the future, if Arc is required even in no_std contexts, I would recommend using portable_atomic and portable_atomic_util to maintain support for those platforms.

- Switched to `hashbrown::HashMap` from `std::collections::HashMap`. This dependency was already in-tree and is only used internally, so no public facing change.
- Switched to deriving `thiserror::Error` instead of manual `Error` implementation. This is done to preserve the 1.65 MSRV (since `thiserror` correctly handles choosing between `core::error::Error` and `std::error::Error` based on compiler version). This dependency is used in tests already, but is now a proper dependency.
- Ensured `saphyr-parser` and `saphyr` compile for `no_std` targets such as `wasm32v1-none` and `x86_64-unknown-none`. Added this to CI to ensure compatibility doesn't regress.
@bushrat011899

Copy link
Copy Markdown
Contributor Author

CI failure was caused by attempting to compile tools, benchmarks, etc. for no_std as well, instead of exclusively checking saphyr.

@Ethiraric

Ethiraric commented Oct 9, 2025

Copy link
Copy Markdown
Contributor

Yeah, that's intentional. The setup with tools is pretty convoluted and it's hard to not forget anything when updating. Edit: I misunderstood.

I usually run just before_commit before each of my commits, which helps prevent unwanted CI surprises.

@Ethiraric Ethiraric left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just like 2 changes to that and I'll merge:

  • Add an entry to the CHANGELOG.md, especially describing the breaking change you mentioned.
  • Add the cargo check for no_std to the justfile.

Thanks for your contribution! <3 It's always appreciated to have folks dedicated to broadening usages!

@bushrat011899

Copy link
Copy Markdown
Contributor Author
* Add an entry to the `CHANGELOG.md`, especially describing the breaking change you mentioned.

Done! saphyr-parser had no breaking changes, so I've just mentioned the no_std support in its changelog.

* Add the `cargo check` for `no_std` to the `justfile`.

I've added a new check_no_std entry to the justfile so it can be clearly documented why we're explicitly checking against wasm32v1-none as a target. This does have the unfortunate side-effect of requiring the wasm32v1-none target be added for just before_commit to fully succeed. Currently, this is the least intrusive way to check for no_std compatibility in Rust.

Thanks for your contribution! <3 It's always appreciated to have folks dedicated to broadening usages!

Happy to help!

@Ethiraric

Copy link
Copy Markdown
Contributor

All good, thanks a lot!

@Ethiraric Ethiraric merged commit 001b709 into saphyr-rs:master Oct 13, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants