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}