3 releases
Uses new Rust 2024
| 0.1.2 | Jun 29, 2025 |
|---|---|
| 0.1.1 | Apr 25, 2025 |
| 0.1.0 | Apr 6, 2025 |
#307 in Embedded development
240 downloads per month
125KB
841 lines
RustyList
RustyList is a safe, intrusive doubly-linked list crate for Rust. It provides a way to embed list nodes directly within your data structures (similar to Linux kernel's list_head), allowing efficient in-place list management with no heap allocation. RustyList is #![no_std] compatible and ensures that all unsafe operations are confined internally, presenting a clean 100% safe public API.
Screenshot

Features
- No Standard Library Required: Designed for
#![no_std]environments, ideal for embedded systems, kernels, and other low-level applications where heap allocation or the standard library may not be available. RustyList allocates no memory on its own. - Intrusive Doubly-Linked List: Instead of storing data in nodes managed by the list, RustyList intrudes into your data type by embedding a
RustyListNodewithin it. This means no separate node allocations – your struct itself carries the pointers for list links. - Safe API (Internal Unsafe): You do not need to write any
unsafecode to use RustyList. All pointer arithmetic and aliasing trickery are handled internally. - Doubly-Linked: Every list node contains pointers to both the next and previous nodes in the list.
- Optional Sorting: You can provide an ordering function to maintain a sorted list.
- Versatile Operations: Includes
push,pop,insert,remove, andfind_equal. - Static Allocation Friendly: Use with statically or stack-allocated structures.
Use Cases
- Embedded systems
- OS kernels
- Real-time schedulers
- Static object pools
- Custom allocators
- Performance-sensitive queues or resource managers
Getting Started
Usage
- Define your struct and embed a
RustyListNode<T>. - Implement
HasRustyNodefor that struct. - Create a
RustyList<T>and set the offset using.new()or.new_with_order(). - Use
insert,push,pop,remove,find_equalas needed.
Struct Requirements
Example:
#[repr(C)]
struct MyStruct {
value: u32,
node: RustyListNode<MyStruct>,
}
impl HasRustyNode for MyStruct {
fn rusty_offset() -> usize {
rusty_offset(|s: &Self| &s.node)
}
}
🔒
#[repr(C)]is required to ensure predictable field layout for offset math.
Order Function
Used for sorted insert() and find_equal():
fn my_cmp(a: *const MyStruct, b: *const MyStruct) -> i32 {
unsafe {
(*a).value.cmp(&(*b).value) as i32
}
}
Examples
Creating and Using a List
let mut list = RustyList::<MyItem>::new_with_order(|a, b| a.value.cmp(&b.value));
let mut item = MyItem { value: 42, node: RustyListNode::new() };
list.insert(&mut item);
Insert Sorted Items
let mut list = RustyList::<MyStruct>::new_with_order(my_cmp);
for item in my_items.iter_mut() {
list.insert(item) ;
}
Push (Unsorted Append)
list.push(&mut my_item);
Pop (Remove Head)
let item = list.pop();
Remove Specific Node
if let Some(ptr) = list.find_equal(&target) {
list.remove(ptr);
}
list.remove(ptr);
Tests
All core operations are covered with unit tests:
insert(sorted + head/tail/middle)remove(head, tail, middle)pushandpop(non-sorted FIFO)find_equalvia order function- End-to-end integration test with static arrays
To run tests:
cargo test
Note:
stdis enabled during tests to allow use ofVec,assert_eq!, etc.
Safety Considerations
- Ensure inserted items remain valid while in the list.
- Only one
RustyListNodeper list per item. - Not thread-safe by default.
Contact
| Name | Contact |
|---|---|
| Anthony Tropeano | GitHub |
License
This project is distributed under the MIT License. See LICENSE for details.