orx_meta/queue/st_queue.rs
1/// A strongly typed non-empty queue of heterogeneous elements.
2///
3/// There exist two implementations:
4/// * [`QueueSingle`] which includes exactly one element, and
5/// * [`Queue`] containing multiple (>=2) elements.
6///
7/// Also see [`define_queue`] macro to define a queue of heterogeneous elements
8/// all of which exhibit a common behavior, or implement a common set of traits.
9/// For more information, please see
10/// * examples [3_composition_idea](https://github.com/orxfun/orx-meta/blob/main/docs/3_composition_idea.md)
11/// and [5_solution_with_macros](https://github.com/orxfun/orx-meta/blob/main/docs/5_solution_with_macros.md); and
12/// * the article [zero cost composition](https://orxfun.github.io/orxfun-notes/#/zero-cost-composition-2025-10-15).
13///
14/// [`define_queue`]: crate::define_queue
15/// [`QueueSingle`]: crate::queue::QueueSingle
16/// [`Queue`]: crate::queue::Queue
17#[allow(clippy::len_without_is_empty)]
18pub trait StQueue {
19 /// Type of the queue obtained by adding an element of type `Elem` to this queue.
20 type PushBack<Elem>: StQueue;
21
22 /// Type of the element at the front of the queue.
23 type Front;
24
25 /// Type of the queue that would be obtained by popping the `Front` element of the queue.
26 type Back: StQueue;
27
28 /// Number of elements in the queue.
29 const LEN: usize;
30
31 /// Pushes the `element` and returns the resulting queue.
32 ///
33 /// *Type of the resulting queue is known by the generic associated type `Self::PushBack<Elem>`.*
34 ///
35 /// # Examples
36 ///
37 /// ```
38 /// use orx_meta::queue::*;
39 ///
40 /// let queue = Queue::new(42);
41 /// assert_eq!(queue.as_tuple(), &42);
42 ///
43 /// let queue = Queue::new(42).push(true).push('x');
44 /// assert_eq!(queue.as_tuple(), (&42, &true, &'x'));
45 ///
46 /// let queue = queue.push("foo");
47 /// assert_eq!(queue.as_tuple(), (&42, &true, &'x', &"foo"));
48 /// ```
49 fn push<Elem>(self, element: Elem) -> Self::PushBack<Elem>;
50
51 /// Pushes the `element` and returns the resulting queue.
52 ///
53 /// *This method is provided for convention. Length of the queue is actually known by the constant `Self::LEN`.*
54 ///
55 /// # Examples
56 ///
57 /// ```
58 /// use orx_meta::queue::*;
59 ///
60 /// let queue = Queue::new(42);
61 /// assert_eq!(queue.len(), 1);
62 ///
63 /// let queue = Queue::new(42).push(true).push('x');
64 /// assert_eq!(queue.len(), 3);
65 ///
66 /// let (num, queue) = queue.pop();
67 /// assert_eq!(num, 42);
68 /// assert_eq!(queue.len(), 2);
69 ///
70 /// let queue = queue.push(true);
71 /// assert_eq!(queue.len(), 3);
72 /// ```
73 #[inline(always)]
74 fn len(&self) -> usize {
75 Self::LEN
76 }
77
78 /// Returns a reference to the element in the front of the queue.
79 ///
80 /// # Examples
81 ///
82 /// ```
83 /// use orx_meta::queue::*;
84 ///
85 /// let queue = Queue::new(42);
86 /// assert_eq!(queue.front(), &42);
87 ///
88 /// let queue = Queue::new(42).push(true).push('x').push("foo");
89 /// assert_eq!(queue.front(), &42);
90 ///
91 /// let (num, queue) = queue.pop();
92 /// assert_eq!(num, 42);
93 /// assert_eq!(queue.front(), &true);
94 ///
95 /// let (flag, queue) = queue.pop();
96 /// assert_eq!(flag, true);
97 /// assert_eq!(queue.front(), &'x');
98 ///
99 /// let (c, queue) = queue.pop();
100 /// assert_eq!(c, 'x');
101 /// assert_eq!(queue.front(), &"foo");
102 ///
103 /// let s = queue.pop();
104 /// assert_eq!(s, "foo");
105 /// ```
106 fn front(&self) -> &Self::Front;
107
108 /// Returns a mutable reference to the element in the front of the queue.
109 ///
110 /// # Examples
111 ///
112 /// ```
113 /// use orx_meta::queue::*;
114 ///
115 /// let mut queue = Queue::new(42).push(true).push('x');
116 ///
117 /// *queue.front_mut() *= 2;
118 /// *queue.back_mut().front_mut() = false;
119 /// *queue.back_mut().back_mut().front_mut() = 'y';
120 ///
121 /// assert_eq!(queue.as_tuple(), (&84, &false, &'y'));
122 /// ```
123 fn front_mut(&mut self) -> &mut Self::Front;
124
125 /// Consumes the queue and returns the element in the front of the queue.
126 ///
127 /// # Examples
128 ///
129 /// ```
130 /// use orx_meta::queue::*;
131 ///
132 /// let queue = Queue::new(42);
133 /// assert_eq!(queue.into_front(), 42);
134 ///
135 /// let queue = Queue::new(42).push(true).push('x').push("foo".to_string());
136 /// assert_eq!(queue.into_front(), 42);
137 ///
138 /// let queue = Queue::new(42).push(true).push('x').push("foo".to_string());
139 /// let (num, queue) = queue.pop();
140 /// assert_eq!(num, 42);
141 /// let (flag, queue) = queue.pop();
142 /// assert_eq!(flag, true);
143 ///
144 /// assert_eq!(queue.into_front(), 'x');
145 /// ```
146 fn into_front(self) -> Self::Front;
147}