linked_list_r4l/lib.rs
1#![cfg_attr(not(test), no_std)]
2#![doc = include_str!("../README.md")]
3
4mod linked_list;
5mod raw_list;
6pub use linked_list::List;
7pub use raw_list::{GetLinks, Links, RawList};
8
9#[macro_export(local_inner_macros)]
10#[doc(hidden)]
11macro_rules! __def_node_internal {
12 ($(#[$meta:meta])* $vis:vis struct $name:ident($type:ty);) => {
13 $(#[$meta])*
14 $vis struct $name {
15 inner: $type,
16 links: $crate::Links<Self>,
17 }
18
19 impl $crate::GetLinks for $name {
20 type EntryType = Self;
21
22 #[inline]
23 fn get_links(t: &Self) -> &$crate::Links<Self> {
24 &t.links
25 }
26 }
27
28 impl $name {
29 #[doc = "Create a node"]
30 pub const fn new(inner: $type) -> Self {
31 Self {
32 inner,
33 links: $crate::Links::new(),
34 }
35 }
36
37 #[inline]
38 #[doc = "Return the referece of wrapped inner"]
39 pub const fn inner(&self) -> &$type {
40 &self.inner
41 }
42
43 #[inline]
44 #[doc = "Consumes the `node`, returning the wrapped inner"]
45 pub fn into_inner(self) -> $type {
46 self.inner
47 }
48 }
49
50 impl core::ops::Deref for $name {
51 type Target = $type;
52
53 #[inline]
54 fn deref(&self) -> &Self::Target {
55 &self.inner
56 }
57 }
58 };
59
60 ($(#[$meta:meta])* $vis:vis struct $name:ident<$gen:ident>($type:ty);) => {
61 $(#[$meta])*
62 $vis struct $name<$gen> {
63 inner: $type,
64 links: $crate::Links<Self>,
65 }
66
67 impl<$gen> $crate::GetLinks for $name<$gen> {
68 type EntryType = Self;
69
70 #[inline]
71 fn get_links(t: &Self) -> &$crate::Links<Self> {
72 &t.links
73 }
74 }
75
76 impl<$gen> $name<$gen> {
77 #[doc = "Create a node"]
78 pub const fn new(inner: $type) -> Self {
79 Self {
80 inner,
81 links: $crate::Links::new(),
82 }
83 }
84
85 #[inline]
86 #[doc = "Return the referece of wrapped inner"]
87 pub const fn inner(&self) -> &$type {
88 &self.inner
89 }
90
91 #[inline]
92 #[doc = "Consumes the `node`, returning the wrapped inner"]
93 pub fn into_inner(self) -> $type {
94 self.inner
95 }
96 }
97
98 impl<$gen> core::ops::Deref for $name<$gen> {
99 type Target = $type;
100
101 #[inline]
102 fn deref(&self) -> &Self::Target {
103 &self.inner
104 }
105 }
106 };
107}
108
109/// A macro for create a node type that can be used in List.
110///
111/// # Syntax
112///
113/// ```ignore
114/// def_node! {
115/// /// A node with usize value.
116/// [pub] struct UsizedNode(usize);
117/// /// A node with generic inner type.
118/// [pub] struct WrapperNode<T>(T);
119/// }
120/// ```
121///
122/// # Example
123///
124/// ```rust
125/// use linked_list_r4l::{def_node, List};
126///
127/// def_node!{
128/// /// An example Node with usize
129/// struct ExampleNode(usize);
130/// /// An example Node with generic Inner type and pub(crate)
131/// pub(crate) struct NativeGenericNode(usize);
132/// /// An example Node with generic Inner type and pub vis
133/// pub struct GenericNode<T>(T);
134/// }
135///
136/// let node1 = Box::new(ExampleNode::new(0));
137/// let node2 = Box::new(ExampleNode::new(1));
138/// let mut list = List::<Box<ExampleNode>>::new();
139///
140/// list.push_back(node1);
141/// list.push_back(node2);
142///
143/// for (i,e) in list.iter().enumerate() {
144/// assert!(*e.inner() == i);
145/// }
146///
147/// let node1 = list.pop_front().unwrap();
148/// let node2 = list.pop_front().unwrap();
149///
150/// assert!(node1.into_inner() == 0);
151/// assert!(node2.into_inner() == 1);
152/// assert!(list.pop_front().is_none());
153///
154/// let node1 = Box::new(GenericNode::new(0));
155/// let node2 = Box::new(GenericNode::new(1));
156///
157/// let mut list = List::<Box<GenericNode<usize>>>::new();
158///
159/// list.push_back(node1);
160/// list.push_back(node2);
161///
162/// for (i,e) in list.iter().enumerate() {
163/// assert!(*e.inner() == i);
164/// }
165/// ```
166///
167#[macro_export(local_inner_macros)]
168macro_rules! def_node {
169 ($(#[$meta:meta])* $vis:vis struct $name:ident($type:ty); $($t:tt)*) => {
170 __def_node_internal!($(#[$meta])* $vis struct $name($type););
171 def_node!($($t)*);
172 };
173 ($(#[$meta:meta])* $vis:vis struct $name:ident<$gen:ident>($type:ty); $($t:tt)*) => {
174 __def_node_internal!($(#[$meta])* $vis struct $name<$gen>($type););
175 def_node!($($t)*);
176 };
177 () => ()
178}