{"id":15031856,"url":"https://github.com/peter-lyons-kehl/no_std_rna_slice_patterns_presentation","last_synced_at":"2026-03-16T22:33:33.176Z","repository":{"id":83242527,"uuid":"529867388","full_name":"peter-lyons-kehl/no_std_rna_slice_patterns_presentation","owner":"peter-lyons-kehl","description":"no_std (embedded/low level-compatible) patterns in Rust - presentation","archived":false,"fork":false,"pushed_at":"2022-10-06T19:50:59.000Z","size":35,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-19T22:51:09.080Z","etag":null,"topics":["embedded","nostd","nostdlib","patterns","presentation","presentation-slides","rust","rust-embedded","rust-lang","rust-language","slices","slides"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peter-lyons-kehl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-28T13:16:13.000Z","updated_at":"2023-07-07T21:25:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"9da15b04-be5f-4d50-a564-00f6f457eb2c","html_url":"https://github.com/peter-lyons-kehl/no_std_rna_slice_patterns_presentation","commit_stats":null,"previous_names":["peter-lyons-kehl/no_std_rna_slice_patterns_presentation"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peter-lyons-kehl%2Fno_std_rna_slice_patterns_presentation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peter-lyons-kehl%2Fno_std_rna_slice_patterns_presentation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peter-lyons-kehl%2Fno_std_rna_slice_patterns_presentation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peter-lyons-kehl%2Fno_std_rna_slice_patterns_presentation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peter-lyons-kehl","download_url":"https://codeload.github.com/peter-lyons-kehl/no_std_rna_slice_patterns_presentation/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243351841,"owners_count":20276908,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["embedded","nostd","nostdlib","patterns","presentation","presentation-slides","rust","rust-embedded","rust-lang","rust-language","slices","slides"],"created_at":"2024-09-24T20:16:47.560Z","updated_at":"2025-12-29T22:05:48.795Z","avatar_url":"https://github.com/peter-lyons-kehl.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Scope\n\n- Primary focus: Memory handling.\n\nTODO\n- beware that vscode.dev can't display inferred types (of `let` definitions), neither declared\n  parameter names in function calls\n- vote for [enabling rust-analyzer on vscode.dev](https://github.com/rust-lang/rust-analyzer/issues/11309)\n- https://github.dev/peter-kehl/no_std_rna_slice_patterns\n  - VS-Code-like horizontal menu (if you have it hidden by default, toggle it with \"Alt\")\n  - your VS Code theme (if you use VS Code sync)\n  - `Ctrl + comma` shows VS-Code-like Settings\n- Alternative: Online VS Code:\n - https://vscode.dev/github/peter-kehl/no_std_rna_slice_patterns\n - [Insiders (beta-like version)](https://insiders.vscode.dev/github/peter-kehl/no_std_rna_slice_patterns)\n - these don't have a horizontal menu, but open it by the hamburger button\n\n---\n# Prerequisites\n\n- `nightly` Rust compiler\n - the actual solutions work with `stable` Rust. However, the test harness (with extras on top of of\n   Exercism's tests) needs `nightly` Rust (as of mid 2022).\n\n# List of patterns (and shared utils)\n- [00_utils](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/00_utils/src/lib.rs)\n- [00_test_harness](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/00_test_harness/src/lib.rs) TODO other files\n\nThese [examples](https://github.com/peter-kehl/no_std_rna_slice_patterns) are ordered as they progress:\n- [01_on_heap-bytes-own_mut-string](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/01_on_heap-bytes-own_mut-string/src/lib.rs)\n- [02_no_heap-chars-own_mut-array-const_overall-limit](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/02_no_heap-chars-own_mut-array-const_overall-limit/src/lib.rs)\n- [03_no_heap-array-const_limit-bytes-wipe_on_mut](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/03_no_heap-array-const_limit-bytes-wipe_on_mut/src/lib.rs)\n- [04_no_heap-array-const_limit-bytes-wipe_on_clone](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/04_no_heap-array-const_limit-bytes-wipe_on_clone/src/lib.rs)\n- [05_no_heap-array-const_limit-bytes-wipe_on_clone-unsafe (*)](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/05_no_heap-array-const_limit-bytes-wipe_on_clone-unsafe/src/lib.rs)\n- [06_no_heap-array-const_generic_exact-bytes](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/06_no_heap-array-const_generic_exact-bytes/src/lib.rs)\n- [07_no_heap-array-const_generic_limit-bytes-wipe_on_mut](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/07_no_heap-array-const_generic_limit-bytes-wipe_on_mut/src/lib.rs)\n- [08_no_heap-array-const_generic_limit-bytes-wipe_on_clone](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/08_no_heap-array-const_generic_limit-bytes-wipe_on_clone/src/lib.rs)\n- [09_no_heap-slice-pass_in-bytes-wipe_on_mut](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/09_no_heap-slice-pass_in-bytes-wipe_on_mut/src/lib.rs)\n- [10_no_heap-slice-pass_in-bytes-wipe_on_drop](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/10_no_heap-slice-pass_in-bytes-wipe_on_drop/src/lib.rs)\n- [11_ok_heap-slices-box_dyn_trait-map](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/11_ok_heap-slices-box_dyn_trait-map/src/lib.rs)\n- [12_no_heap-slices-iterator_enum](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/12_no_heap-slices-iterator_enum/src/lib.rs)\n- [13_no_heap-slices-iterator_impl](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/13_no_heap-slices-iterator_impl/src/lib.rs)\n- [14_no_heap-eq_branch_iterators-dyn_trait](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/14_no_heap-eq_branch_iterators-dyn_trait/src/lib.rs)\n- [15_no_heap-eq_branch_iterators-matrix](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/15_no_heap-eq_branch_iterators-matrix/src/lib.rs)\n- [16_no_heap-eq_iterator_to_generic_fn](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/16_no_heap-eq_iterator_to_generic_fn/src/lib.rs)\n- [17_no_heap-eq_dispatch_specialized](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/17_no_heap-eq_dispatch_specialized/src/lib.rs)\n- [18_no_heap-eq_dispatch_universal](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/18_no_heap-eq_dispatch_universal/src/lib.rs)\n\n(*) `05_no_heap-array-const_limit-bytes-wipe_on_clone-unsafe` (as compared to the previous\nimplementation) doesn't introduce anything new related to `no_std`, but it fits here. (Also,\n`unsafe` is more likely to be used with `no_std` anyway).\n---\n\n# Properties of patterns\n| Property | [01](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/01_on_heap-bytes-own_mut-string/src/lib.rs \"01_on_heap-bytes-own_mut-string\") | [02](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/02_no_heap-chars-own_mut-array-const_overall-limit/src/lib.rs \"02_no_heap-chars-own_mut-array-const_overall-limit\") | [03](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/03_no_heap-bytes-own_mut-array-const_overall-limit/src/lib.rs \"03_no_heap-bytes-own_mut-array-const_overall-limit\") | [04](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/04_no_heap-bytes-own_mut-array-const_overall-limit-unsafe_str/src/lib.rs \"04_no_heap-bytes-own_mut-array-const_overall-limit-unsafe_str\") (\\*) | [05](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/05_no_heap-bytes-own_mut-array-const_generic-exact/src/lib.rs \"05_no_heap-bytes-own_mut-array-const_generic-exact\") | [06](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/06_no_heap-bytes-own_mut-array-const_generic-limit/src/lib.rs \"06_no_heap-bytes-own_mut-array-const_generic-limit\") | [07](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/07_no_heap-bytes-ref_mut-slice-pass_in_storage-mut_anytime/src/lib.rs \"07_no_heap-bytes-ref_mut-slice-pass_in_storage-mut_anytime\") | [08](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/08_no_heap-bytes-ref_mix-slice-pass_in_storage-mut_initial-macro/src/lib.rs \"08_no_heap-bytes-ref_mix-slice-pass_in_storage-mut_initial-macro\") | [09](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/09_on_heap-bytes-ref_shr-slice-dispatch_dyn-map/src/lib.rs \"09_on_heap-bytes-ref_shr-slice-dispatch_dyn-map\") | [10](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/10_no_heap-bytes-ref_shr-slice-dispatch_sta-iterator_enum/src/lib.rs \"10_no_heap-bytes-ref_shr-slice-dispatch_sta-iterator_enum\") | [11](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/11_no_heap-bytes-ref_shr-slice-dispatch_sta-iterator_impl/src/lib.rs \"11_no_heap-bytes-ref_shr-slice-dispatch_sta-iterator_impl\") | [12](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/12_no_heap-bytes-ref_shr-slice-dispatch_dyn-eq_branch_iterators/src/lib.rs \"12_no_heap-bytes-ref_shr-slice-dispatch_dyn-eq_branch_iterators\") | [13](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/13_no_heap-bytes-ref_shr-slice-dispatch_sta-eq_branch_iterators-matrix/src/lib.rs \"13_no_heap-bytes-ref_shr-slice-dispatch_sta-eq_branch_iterators-matrix\") | [14](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/14_no_heap-bytes-ref_shr-slice-dispatch_sta-eq_iterator_to_generic_fn/src/lib.rs \"14_no_heap-bytes-ref_shr-slice-dispatch_sta-eq_iterator_to_generic_fn\") | [15](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/15_no_heap-bytes-ref_shr-slice-dispatch_dyn-eq_dispatch_to_specialized/src/lib.rs \"15_no_heap-bytes-ref_shr-slice-dispatch_dyn-eq_dispatch_to_specialized\") | [16](https://github.com/peter-kehl/no_std_rna_slice_patterns/blob/main/16_no_heap-bytes-ref_shr-slice-dispatch_dyn-eq_dispatch_to_universal/src/lib.rs \"16_no_heap-bytes-ref_shr-slice-dispatch_dyn-eq_dispatch_to_universal\") |\n| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\n| Implemented | ✓ | ✓ | ✓ | ✓ | ✓ | | part | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |\n| extra work for securing observability/serialization: array or passed-in mutable slice could leak data! |\n| fixed compile-time size limit for all instances (one type) | | ✓ | ✓ | ✓ | | | | | | | | | | | | |\n| various compile-time size limits per instance (generic type), can have a default limit | | | | | ✓ | ✓ | | | | | | | | | | |\n| no compile-time limit | ✓ |  |  |  |  |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |\n| random access \u0026 data storage (rather than sequential access only) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |  |  |  |  |  |  |  |  |\n| refer to the original (with a lifetime) (rather than copy the original) |  |  |  |  |  |  |  |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |\n| refer to extra mutable storage (with a lifetime) |  |  |  |  |  |  | ✓ | ✓ |  |  |  |  |  |  |  |  |\n| non-obvious or impractical API (\\*) | 05 \u0026 07 \u0026 08 |\n| TODO mutable storage at/just before initiation, but then immutable -\u003e shareable? |\n| mutable \u0026 unlimited resize |\n| --\u003e TODO implement mutation for # 01 |\n| mutable \u0026 limited resize |\n| mutable, but no ability to resize |\n| immutable |\n| extra handling of strings/UTF-8 (\\*) |  |  | 🛆 | 🛆 |  | 🛆🛆 | 🛆 | 🛆 |  |  |  |  |  |  |  |  |\n| `Clone` is `derive`-d |\n| `Clone` is implemented |\n| no `Clone` -- needed at all? |\n| `Copy` |\n| different types for mutation and for sharing: 07 \u0026 08 |\n| minor `unsafe` code |\n| --- |\n|`dyn` (virtual) dispatch \u003c-\u003e static (compile-time) dispatch |\n| extra dispatch methods |\n| thread safe (`Sync` - if used in `std`) -\u003e TODO \"tests\": `struct EnsureSync\u003cT: Sync\u003e; type _EnsureSyncRna = EnsureSync\u003cRna\u003e;` |\n\n- All \"unlimited\" properties are constrained by available memory.\n- (\\*) indicates a property or implementation that isn't `no_std`-specific, or is specific to this workspace. It's here for clarification.\n\nTODO Group implementations?\n\n---\n\n# Methods\n\n# no_std with heap\n\nReplace use of `HashSet/HashMap` with `BTreeSet/BTreeMap` when possible. Or create different data\nstructures. Or use 3rd party crates.\n\nReplace `Arc` with `Rc` (since there is no multi-threading in `no_std`).\n\n# no_std without heap\n\n- Have your functions accept [slices](https://doc.rust-lang.org/nightly/book/ch04-03-slices.html)\n   (shared or mutable), rather than `Vec` or `String`, wherever possible. Both `Vec` and `String`\n   auto cast/expose themselves as a slice. (This is a good practice even with heap, or in `std`.)\n- Similarly, whenever possible, have your `struct`-s and `enum`-s store references, or slices,\n   rather than own the data. It does involve\n   [`lifetimes`](https://www.cloudbees.com/blog/lifetimes-in-rust), but that can be a good practice,\n   too.\n\n- Can't\n   [`core::iter::Iterator.collect()`](https://doc.rust-lang.org/core/iter/trait.Iterator.html#method.collect).\n  - Even though `collect()` does exist in `core` (and not only in `std`), it can collect only to\n   implementations of\n   [`core::iter::FromIterator`](https://doc.rust-lang.org/core/iter/trait.FromIterator.html). (That,\n   again, exists in `core`, in addition to `std`). However, there are no `core`-only implementors of\n   `FromIterator` (other than collecting zero or one item [to\n   `core::option::Option`](https://doc.rust-lang.org/core/iter/trait.FromIterator.html#impl-FromIterator%3COption%3CA%3E%3E)\n   or [to\n   `core::result::Result`](https://doc.rust-lang.org/core/iter/trait.FromIterator.html#impl-FromIterator%3CResult%3CA%2C%20E%3E%3E)).\n  - `collect()` doesn't exist for arrays nor slices (without heap). Hence we need to iterate and\n   store in a (mutable) array or slice.  _New to Rust? And Worried about side effects?_ Good news:\n   _Safe_ Rust prevents unintended side effects, because we \"[cannot have a mutable reference while\n   we have an immutable\n   one](https://doc.rust-lang.org/nightly/book/ch04-02-references-and-borrowing.html#mutable-references)\n   to the same value.\"\n- there is no dynamic/resizable data storage\n  - a `no_std` design needs to batch/buffer/limit the total data\n  - use slices (instead of arrays) as parameter types wherever possible\n    - design function as accepting (shared or mutable) slices\n    - functions may need to write to mutable slice parameters  (instead of returning).\n\n---\n\n- _New to Rust?_ Mutating slices or references/arrays may sound less \"functional\". But, in Rust any\n     mutated parameters must be declared so. Any parameter that may be modified must be either\n  - [`borrowed`](https://doc.rust-lang.org/nightly/book/ch04-02-references-and-borrowing.html)\n       (passed) as a mutable reference or slice (which has exclusive access), or\n  - passing ownership of the object:\n    - [_\"move\"-d_](https://doc.rust-lang.org/nightly/book/ch04-01-what-is-ownership.html#ownership-and-functions)\n         (or [`clone()`-d](https://doc.rust-lang.org/core/clone/trait.Clone.html) first and then the\n         clone is moved), or\n    - [_copied_: Ownership \u003e Stack-Only Data: Copy]\n         ](\u003chttps://doc.rust-lang.org/nightly/book/ch04-01-what-is-ownership.html#stack-only-data-copy\u003e)\n         if it implements [`Copy` ](https://doc.rust-lang.org/core/marker/trait.Copy.html) trait.\n         _New to Rust?_ A `trait` is similar to an `interface` in Java, a `virtual` abstract\n         field-less class with virtual methods in C++, or a `protocol` in some other languages.\n  - See also\n       [ownership](https://doc.rust-lang.org/nightly/book/ch04-00-understanding-ownership.html),\n       [borrowing](https://doc.rust-lang.org/nightly/book/ch04-02-references-and-borrowing.html) and\n       [lifetimes](https://doc.rust-lang.org/nightly/book/ch10-03-lifetime-syntax.html).\n- alternatively, use [`const` generics](https://rust-lang.github.io/rfcs/2000-const-generics.html),\n     a subset of Rust [generics](https://doc.rust-lang.org/nightly/book/ch10-00-generics.html), for\n     both function parameters and return values\n  - make the array size (which has to be known in compile time) a `const` generic parameter\n  - beware that generics make the executable larger, and the build process takes longer; it helps to\n       combine (`const`) generics for some functions, and slices for other\n- application's top level function(s) define the array(s), or array-containing structs/enums, on\n     stack. Then they call the processing functions with slices, or with const generic-sized arrays\n     (or their references)\n\n---\n\n- this way you can re-use the same processing functions\n- if you can process the incoming data last in, first out (in LIFO/stack order), you could recurse\n     (possibly batching the data in an array at every recursion level)\n- Have functions return an iterator wherever possible. (And use it for parameters, too. Again, a\n   good practice even in `std`.)\n  - may need to implement\n     [core::iter::Iterator](https://doc.rust-lang.org/core/iter/trait.Iterator.html) to represents\n     results of your transformation. Such iterators refer to the underlying iterator (data\n     source/origin) and they may keep some state on top of it (a state machine).\n  - You may want to combine/chain functions accepting and returning iterators. Use keyword\n     [`impl`](https://doc.rust-lang.org/nightly/book/ch10-02-traits.html#returning-types-that-implement-traits)\n     to define types like `impl Iterator\u003cItem = YourItemType\u003e`.\n\n---\n\n# no_std without heap \u003e Alternatives to collect()\n\nWhen developing for `no_heap`, we can't `collect()` from iterators. That makes some tasks that need\nrandom access (access to all items at the same time, like sorting) difficult.\n\nThis would need limit on number of items to be known at build time. Then the caller would pass a\n(mutable) reference to an array, or a slice, where we would manually collect the items (in a `for`\nloop, or `.foreach()` closure).\n\n---\n\n# no_std without heap \u003e Compound iterators\n\nFor some purposes we may not need access to all items if we don't need to access the whole\ncollection. Then all we do needs sequential access only, for example a one-to-one transformation,\nand/or filtering.\n\nFor that we may need to implement a compound iterator. It would contain an underlying iterator (or\nseveral iterators) over the source data. It iterates and transforms and/or filters the source data.\n\n[Exercism Rust track](https://exercism.org/tracks/rust/exercises) \u003e [RNA\nTranscription](https://exercism.org/tracks/rust/exercises/rna-transcription)\n\nIn addition to the text of the assignment, it helps to see the\n[tests](https://github.com/peter-kehl/x-rust/blob/main/rust/rna-transcription-std/tests/rna-transcription.rs)\n(or the same tests used for [`no_std`\nversion](https://github.com/peter-kehl/x-rust/blob/main/rust/rna-transcription-no_std-no_heap/tests/rna-transcription.rs))\n\n\u003chttps://github.com/peter-kehl/x-rust/blob/main/rust/rna-transcription-std/src/lib.rs\u003e\n\n\u003chttps://github.com/peter-kehl/x-rust/blob/main/rust/rna-transcription-no_std-no_heap/src/lib.rs\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeter-lyons-kehl%2Fno_std_rna_slice_patterns_presentation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeter-lyons-kehl%2Fno_std_rna_slice_patterns_presentation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeter-lyons-kehl%2Fno_std_rna_slice_patterns_presentation/lists"}