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)