User-Friendly API
Relevant source files
This page documents the user-friendly API layer of the linked_list_r4l crate, which provides the simplest interface for typical usage scenarios. This layer consists of the def_node! macro for automatic node generation and the simple List<T> interface for basic list operations.
For advanced ownership management and custom wrapper types, see Advanced API. For low-level unsafe operations and performance-critical usage, see Low-Level API.
The def_node! Macro
The def_node! macro is the primary entry point for users to create list-compatible node types. It automatically generates the necessary boilerplate code to make any type work with the linked list system.
Macro Syntax
The macro supports two syntax forms:
| Form | Example | Use Case |
|---|---|---|
| Simple struct | struct NodeName(inner_type); | Non-generic wrapped types |
| Generic struct | struct NodeName | Generic wrapped types |
Generated Node Structure
When you invoke def_node!, it generates a complete node structure with the following components:
flowchart TD
subgraph subGraph3["List Integration"]
ListUsage["List>"]
end
subgraph subGraph2["Generated Implementations"]
GetLinksImpl["GetLinks implementation"]
NodeMethods["Node methods:• new()• inner()• into_inner()"]
DerefImpl["Deref implementation"]
end
subgraph subGraph1["Generated Node Structure"]
NodeStruct["MyNode struct"]
InnerField["inner: i32"]
LinksField["links: Links"]
end
subgraph subGraph0["def_node! Macro Input"]
UserStruct["struct MyNode(i32)"]
end
NodeStruct --> DerefImpl
NodeStruct --> GetLinksImpl
NodeStruct --> InnerField
NodeStruct --> LinksField
NodeStruct --> ListUsage
NodeStruct --> NodeMethods
UserStruct --> NodeStruct
Sources: src/lib.rs(L11 - L107) src/lib.rs(L168 - L178)
Node Methods
Each generated node provides these essential methods:
| Method | Signature | Purpose |
|---|---|---|
| new() | pub const fn new(inner: T) -> Self | Creates a new node wrapping the inner value |
| inner() | pub const fn inner(&self) -> &T | Returns a reference to the wrapped value |
| into_inner() | pub fn into_inner(self) -> T | Consumes the node and returns the wrapped value |
The generated nodes also implement Deref, allowing direct access to the inner type's methods through the node.
Sources: src/lib.rs(L28 - L48) src/lib.rs(L76 - L96) src/lib.rs(L50 - L57) src/lib.rs(L98 - L105)
Code Generation Flow
The macro expansion process transforms user declarations into fully functional list nodes:
flowchart TD
subgraph subGraph3["Usage Ready"]
BoxedUsage["Box"]
ListUsage["List>"]
end
subgraph subGraph2["Generated Code Components"]
StructDef["struct MyNode {inner: i32,links: Links}"]
GetLinksImpl["impl GetLinks for MyNode"]
Methods["impl MyNode {new(), inner(), into_inner()}"]
DerefImpl["impl Deref for MyNode"]
end
subgraph subGraph1["Macro Processing"]
DefNodeMacro["def_node! macro"]
InternalMacro["__def_node_internal! macro"]
end
subgraph subGraph0["User Code"]
UserDecl["def_node! {struct MyNode(i32);}"]
end
BoxedUsage --> ListUsage
DefNodeMacro --> InternalMacro
InternalMacro --> DerefImpl
InternalMacro --> GetLinksImpl
InternalMacro --> Methods
InternalMacro --> StructDef
StructDef --> BoxedUsage
UserDecl --> DefNodeMacro
Sources: src/lib.rs(L168 - L178) src/lib.rs(L11 - L107)
Simple List Interface
The user-friendly API provides a straightforward List<T> interface that works with any boxed node type generated by def_node!.
Basic Operations
The simple list interface supports these fundamental operations:
| Operation | Method | Description |
|---|---|---|
| Creation | List::new() | Creates an empty list |
| Insertion | push_back(node),push_front(node) | Adds nodes to the list |
| Removal | pop_back(),pop_front() | Removes and returns nodes |
| Iteration | iter() | Provides iterator over list elements |
Typical Usage Pattern
Here's the standard workflow for using the user-friendly API:
Sources: src/lib.rs(L124 - L165) README.md(L15 - L62)
Complete Usage Example
The macro documentation includes a comprehensive example showing both simple and generic node usage:
- Node Definition: Using
def_node!to create various node types with different visibility modifiers - List Creation: Instantiating typed lists for specific node types
- List Operations: Adding, iterating, and removing nodes
- Value Access: Using
inner()to access wrapped values andinto_inner()to extract them
The example demonstrates the seamless integration between the macro-generated nodes and the list operations, showing how the user-friendly API hides the complexity of the underlying link management.
Sources: src/lib.rs(L124 - L165) README.md(L46 - L61)
Integration with Type System
The user-friendly API integrates cleanly with Rust's type system:
- Ownership: Nodes are typically owned through
Box<T>for heap allocation - Type Safety: The list type
List<Box<NodeType>>ensures only compatible nodes can be inserted - Generic Support: Both the nodes and lists can be generic over inner types
- Deref Coercion: Nodes automatically dereference to their inner type for convenient method access
This design allows users to work with linked lists using familiar Rust patterns while benefiting from the high-performance constant-time removal capabilities of the underlying implementation.
Sources: src/lib.rs(L6) src/lib.rs(L50 - L57) src/lib.rs(L98 - L105)