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}