queues/
lib.rs

1//! # Queues
2//!
3//! `queues` provides a number of efficient FIFO Queue data structures for
4//! usage in your libraries. These are all implemented on top of rust's `Vector`
5//! type.
6//!
7//! A queue is a linear data structure that commonly defines three methods:
8//!
9//! 1. `add`: Also called `queue` or `push`, this adds elements to the queue.
10//! 2. `remove`: Also called `deque` or `pop`, this removes the _oldest_
11//!     element from the queue.
12//! 3. `peek`: Show the next element in the queue scheduled for removal.
13//!
14//! There are a number of variants of queues. In this crate, the available
15//! variants are:
16//!
17//! - `Queue<T>`: A simple FIFO queue with a growable size and no limit on its
18//!     capacity.
19//! - `Buffer<T>`: A FIFO queue with with a limited capacity. The buffer can
20//!     have a growable size (up to the defined capacity), or it can be
21//!     initialized at capacity, with empty slots being occupied by default
22//!     values.
23//! - `CircularBuffer<T>`: Similar to the buffer above, but allowing for
24//!     overflow. Any additions to the circular buffer that would exceed its
25//!     capacity causes its oldest element to be pushed out.
26//!
27//! # Quick start
28//!
29//! Quick guide to getting started with the project:
30//!
31//! ## Installation
32//!
33//! ### Library usage
34//!
35//! To use the library in your project, simply ensure that the `queues` crate
36//! has been added to your dependencies in your `Cargo.toml` file.
37//!
38//! ```yaml
39//! [dependencies]
40//! queues = "1.0.2"
41//! ```
42//!
43//! In your files, import the crate and use it's members:
44//!
45//! ```rust
46//! # #[macro_use]
47//! extern crate queues;
48//! use queues::*;
49//! # fn main() { }
50//! ```
51//!
52//! ### Source code
53//!
54//! To get the project up and running:
55//!
56//! ```bash
57//! > cd ${WORKING_DIR}
58//! > git clone <this_repo>
59//! > cargo build
60//! ```
61//!
62//! ## Testing
63//!
64//! Run the test suite using `cargo`:
65//!
66//! ```bash
67//! > cd ${PROJECT_FOLDER}
68//! > cargo test
69//! ```
70//!
71//! ## Examples
72//!
73//! The project has a number of examples you can run to see how the library members work.
74//!
75//! The example names are:
76//!
77//! - `queue` Queue example
78//! - `buf` Buffer example
79//! - `cbuf` Circular buffer example
80//! - `cbuf_def` Circular buffer with default values example
81//!
82//! ```bash
83//! > cd ${PROJECT_FOLDER}
84//! > cargo run --example ${EXAMPLE_NAME}
85//! ```
86//!
87//! # Usage
88//!
89//! Simple usage is described below:
90//!
91//! ```rust
92//! #[macro_use]
93//! extern crate queues;
94//!
95//! use queues::*;
96//!
97//! fn main() {
98//!     // Create a simple Queue
99//!     let mut q: Queue<isize> = queue![];
100//!
101//!     // Add some elements to it
102//!     q.add(1);
103//!     q.add(-2);
104//!     q.add(3);
105//!
106//!     // Check the Queue's size
107//!     q.size();  // 3
108//!
109//!     // Remove an element
110//!     q.remove();  // Ok(1)
111//!
112//!     // Check the Queue's size
113//!     q.size();  // 2
114//!
115//!     // Peek at the next element scheduled for removal
116//!     q.peek();  // Ok(-2)
117//!
118//!     // Confirm that the Queue size hasn't changed
119//!     q.size();  // 2
120//!
121//!     // Remove the remaining elements
122//!     q.remove();  // Ok(-2)
123//!     q.remove();  // Ok(3)
124//!
125//!     // Peek into an empty Queue
126//!     q.peek();  // Raises an error
127//!
128//!     // Attempt to remove an element from an empty Queue
129//!     q.remove();  // Raises an error
130//! }
131//! ```
132//!
133//! The examples contain more information on `Buffer` and `CircularBuffer`
134//! usage
135
136#![warn(missing_docs)]
137
138/// Defines methods that would be expected on a queue data structure
139pub trait IsQueue<T: Clone> {
140    /// Adds a new value to a queue
141    ///
142    /// # Parameters
143    /// - `val`: Value to add to the queue
144    ///
145    /// # Returns
146    /// - `Ok(_)`: If the element add was successful.
147    ///     - `Some(T)`: If adding an element resulted in the removal of an
148    ///         existing one (in the case of a circular buffer, for instance)
149    ///     - `None`: Adding an element did not return any value
150    /// - `Error`: If the element add was unsuccessful
151    ///
152    /// # Errors
153    /// Attempting to add an element to a full queue that does not allow for
154    /// overflow will return an error.
155    fn add(&mut self, val: T) -> Result<Option<T>, &str>;
156
157    /// Removes an element from the queue and returns it
158    ///
159    /// For queues with default values, removing an element will add a new
160    /// default value into the queue.
161    ///
162    /// # Returns
163    /// - `Ok(T)`: The oldest element in the queue
164    /// - `Error`
165    ///
166    /// # Errors
167    /// Returns an error if an attempt is made to remove an element from
168    /// an empty queue
169    fn remove(&mut self) -> Result<T, &str>;
170
171    /// Peek at the head of the queue
172    ///
173    /// # Returns
174    /// - `Ok(T)`: The next element scheduled for removal from the queue
175    /// - `Error`
176    ///
177    /// # Errors
178    /// Returns an error if an attempt is made to peek into an empty queue
179    fn peek(&self) -> Result<T, &str>;
180
181    /// Gets the size of the queue
182    ///
183    /// # Returns
184    /// The number of elements in the queue. Note, this _includes_ default
185    /// values when specified, which means that the `size` of a queue with
186    /// default values should always be equal to its `capacity`
187    fn size(&self) -> usize;
188}
189
190/// A simple FIFO queue with a growable size and no limit on its capacity.
191///
192/// # Type parameters
193/// - `T`: Any type that implements the `Clone` trait.
194///
195/// # Examples
196///
197/// This example uses the `queue!` macro to add elements to the queue. Note
198/// that the first element in the list of elements passed to the macro is
199/// considered the 'oldest'.
200///
201/// ```
202/// # #[macro_use] extern crate queues;
203/// # use queues::*;
204/// # fn main() {
205/// let mut q = queue![3isize, 4, 5];
206///
207/// // Add an element
208/// assert_eq!(q.add(6), Ok(None));
209///
210/// // Remove some elements
211/// assert_eq!(q.remove(), Ok(3));
212/// assert_eq!(q.remove(), Ok(4));
213///
214/// // Peek at the next element scheduled for removal
215/// assert_eq!(q.peek(), Ok(5));
216///
217/// // Check the queue size
218/// assert_eq!(q.size(), 2);
219/// # }
220/// ```
221#[derive(Debug)]
222pub struct Queue<T: Clone> {
223    queue: Vec<T>,
224}
225
226impl<T: Clone> Queue<T> {
227    /// Create a new queue
228    ///
229    /// # Returns
230    /// A new, empty `Queue<T>`
231    ///
232    /// # Examples
233    ///
234    /// ```
235    /// # use queues::*;
236    /// let q: Queue<isize> = Queue::new();
237    /// assert_eq!(q.size(), 0);
238    /// ```
239    pub fn new() -> Queue<T> {
240        Queue { queue: vec![] }
241    }
242}
243
244impl<T: Clone> Default for Queue<T> {
245    /// Default queue initializer
246    ///
247    /// # Returns
248    /// A new, empty `Queue<T>`
249    ///
250    /// # Examples
251    ///
252    /// ```
253    /// # use queues::*;
254    /// let q: Queue<isize> = Queue::default();
255    /// assert_eq!(q.size(), 0);
256    /// ```
257    fn default() -> Queue<T> {
258        Queue { queue: vec![] }
259    }
260}
261
262impl<T: Clone> IsQueue<T> for Queue<T> {
263    /// Adds an element to a queue
264    ///
265    /// # Parameters
266    /// - `val`: Value to add to the queue
267    ///
268    /// # Returns
269    /// `Ok(None)` as the element addition should always be successful
270    ///
271    /// # Examples
272    ///
273    /// ```
274    /// # use queues::*;
275    /// let mut q: Queue<isize> = Queue::new();
276    /// assert_eq!(q.add(42), Ok(None));
277    /// assert_eq!(q.size(), 1);
278    /// ```
279    fn add(&mut self, val: T) -> Result<Option<T>, &str> {
280        self.queue.push(val);
281        Ok(None)
282    }
283
284    /// Removes an element from the queue and returns it
285    ///
286    /// # Returns
287    /// - `Ok(T)`: The oldest element in the queue
288    /// - `Error`
289    ///
290    /// # Errors
291    /// Returns an error if an attempt is made to remove an element from
292    /// an empty queue
293    ///
294    /// # Examples
295    ///
296    /// ```
297    /// # use queues::*;
298    /// let mut q: Queue<isize> = Queue::new();
299    /// q.add(42);
300    /// assert_eq!(q.remove(), Ok(42));
301    /// assert_eq!(q.size(), 0);
302    /// ```
303    fn remove(&mut self) -> Result<T, &str> {
304        if !self.queue.is_empty() {
305            Ok(self.queue.remove(0usize))
306        } else {
307            Err("The queue is empty")
308        }
309    }
310
311    /// Peek at the head of the queue
312    ///
313    /// # Returns
314    /// - `Ok(T)`: The next element scheduled for removal from the queue
315    /// - `Error`
316    ///
317    /// # Errors
318    /// Returns an error if an attempt is made to peek into an empty queue
319    ///
320    /// # Examples
321    ///
322    /// ```
323    /// # use queues::*;
324    /// let mut q: Queue<isize> = Queue::new();
325    /// q.add(42);
326    /// assert_eq!(q.peek(), Ok(42));
327    /// ```
328    fn peek(&self) -> Result<T, &str> {
329        match self.queue.first() {
330            Some(val) => Ok(val.clone()),
331            None => Err("The Queue is empty"),
332        }
333    }
334
335    /// Gets the size of the queue
336    ///
337    /// # Returns
338    /// The number of elements in the queue
339    ///
340    /// # Examples
341    ///
342    /// ```
343    /// # use queues::*;
344    /// let mut q: Queue<isize> = Queue::new();
345    /// assert_eq!(q.size(), 0);
346    /// let _ = q.add(42);
347    /// assert_eq!(q.size(), 1);
348    /// ```
349    fn size(&self) -> usize {
350        self.queue.len()
351    }
352}
353
354/// Creates a new `Queue<T>`
355///
356/// Delegates to the default queue initializer. Note that the elements are
357/// added to the queue from left to right, therefore the first element in the
358/// list of parameters passed to the macro is considered the 'oldest' element
359/// in the queue.
360///
361/// # Example
362/// ```
363/// # #[macro_use]
364/// # extern crate queues;
365/// # use queues::*;
366///
367/// # fn main() {
368/// let q = queue![3isize, 4, 5];
369/// assert_eq!(q.peek(), Ok(3));
370///
371/// let q_empty: Queue<isize> = queue![];
372/// assert_eq!(q_empty.size(), 0);
373/// # }
374/// ```
375#[macro_export]
376macro_rules! queue {
377    () => { Queue::new() };
378    ($($x:expr),+) => {
379        {
380            let mut temp_q = Queue::default();
381            $(
382                let _ = temp_q.add($x);
383            )*
384            temp_q
385        }
386    };
387}
388
389/// A FIFO buffer with a growable size and a capacity limit
390///
391/// # Type parameters
392/// - `T`: Any type that implements the `Clone` trait.
393///
394/// # Examples
395///
396/// ```
397/// # use queues::*;
398/// let mut buf = Buffer::new(3);
399///
400/// // Add some elements
401/// assert_eq!(buf.add(6), Ok(None));
402/// assert_eq!(buf.add(7), Ok(None));
403///
404/// // Remove an element
405/// assert_eq!(buf.remove(), Ok(6));
406///
407/// // Peek at the next element scheduled for removal
408/// assert_eq!(buf.peek(), Ok(7));
409///
410/// // Check the queue size
411/// assert_eq!(buf.size(), 1);
412/// ```
413#[derive(Debug)]
414pub struct Buffer<T: Clone> {
415    queue: Vec<T>,
416    capacity: usize,
417}
418
419impl<T: Clone> Buffer<T> {
420    /// Create a new buffer
421    ///
422    /// # Returns
423    /// A new, empty `Buffer<T>`
424    ///
425    /// # Examples
426    ///
427    /// ```
428    /// # use queues::*;
429    /// let buf: Buffer<isize> = Buffer::new(3);
430    /// assert_eq!(buf.size(), 0);
431    /// ```
432    pub fn new(capacity: usize) -> Buffer<T> {
433        Buffer {
434            queue: vec![],
435            capacity,
436        }
437    }
438
439    /// Gets the capacity of the buffer
440    ///
441    /// # Returns
442    /// The number of allowed elements in the buffer
443    ///
444    /// # Examples
445    ///
446    /// ```
447    /// # use queues::*;
448    /// let mut buf: Buffer<isize> = Buffer::new(5);
449    /// assert_eq!(buf.capacity(), 5);
450    /// ```
451    pub fn capacity(&self) -> usize {
452        self.capacity
453    }
454}
455
456impl<T: Clone> IsQueue<T> for Buffer<T> {
457    /// Adds an element to a buffer
458    ///
459    /// # Parameters
460    /// - `val`: Value to add to the buffer
461    ///
462    /// # Returns
463    /// - `Ok(None)`: Element addition was successful
464    /// - `Error`
465    ///
466    /// # Errors
467    /// Returns an error if an attempt is made to add an element to a full
468    /// buffer
469    ///
470    /// # Examples
471    ///
472    /// ```
473    /// use queues::*;
474    ///
475    /// let mut buf: Buffer<isize> = Buffer::new(3);
476    /// assert_eq!(buf.add(42), Ok(None));
477    /// ```
478    fn add(&mut self, val: T) -> Result<Option<T>, &str> {
479        if self.queue.len() < self.capacity {
480            self.queue.push(val);
481            Ok(None)
482        } else {
483            Err("The buffer is full")
484        }
485    }
486
487    /// Removes an element from the buffer and returns it.
488    ///
489    /// # Returns
490    /// - `Ok(T)`: The oldest element in the buffer
491    /// - `Error`
492    ///
493    /// # Errors
494    /// Returns an error if an attempt is made to remove an element from
495    /// an empty buffer
496    ///
497    /// # Examples
498    ///
499    /// ```
500    /// # use queues::*;
501    /// let mut buf: Buffer<isize> = Buffer::new(3);
502    /// buf.add(42);
503    /// assert_eq!(buf.remove(), Ok(42));
504    /// assert_eq!(buf.size(), 0);
505    /// ```
506    fn remove(&mut self) -> Result<T, &str> {
507        if !self.queue.is_empty() {
508            Ok(self.queue.remove(0usize))
509        } else {
510            Err("The buffer is empty")
511        }
512    }
513
514    /// Peek at the head of the buffer
515    ///
516    /// # Returns
517    /// - `Ok(T)`: The next element scheduled for removal from the buffer
518    /// - `Error`
519    ///
520    /// # Errors
521    /// Returns an error if an attempt is made to peek into an empty buffer
522    ///
523    /// # Examples
524    ///
525    /// ```
526    /// # use queues::*;
527    /// let mut buf: Buffer<isize> = Buffer::new(3);
528    /// buf.add(42);
529    /// assert_eq!(buf.peek(), Ok(42));
530    /// ```
531    fn peek(&self) -> Result<T, &str> {
532        match self.queue.first() {
533            Some(val) => Ok(val.clone()),
534            None => Err("The buffer is empty"),
535        }
536    }
537
538    /// Gets the size of the buffer
539    ///
540    /// # Returns
541    /// The number of elements in the buffer.
542    ///
543    /// # Examples
544    ///
545    /// ```
546    /// # use queues::*;
547    /// let mut buf: Buffer<isize> = Buffer::new(3);
548    /// assert_eq!(buf.size(), 0);
549    /// buf.add(42);
550    /// assert_eq!(buf.size(), 1);
551    /// ```
552    fn size(&self) -> usize {
553        self.queue.len()
554    }
555}
556
557/// Represents a FIFO `CircularBuffer<T>` data structure.
558///
559/// This structure is a limited capacity queue, with optional provisions
560/// for default values. Under normal circumstances, the `size` of the
561/// queue grows until it reaches its `capacity`, at which point any
562/// further additions push out its oldest member.
563///
564/// If default values are specified, then the `size` of the queue
565/// is always equal to its `capacity`, with empty slots occupied by the
566/// specified default value.
567///
568/// # Type parameters
569/// - `T`: Any type that implements the `Clone` trait.
570///
571/// # Examples
572///
573/// ```
574/// # use queues::*;
575/// # fn main() {
576/// let mut cbuf = CircularBuffer::<isize>::new(3);
577/// let mut cbuf_def = CircularBuffer::with_default(3, 0isize);
578///
579/// // Check sizes
580/// assert_eq!(cbuf.size(), 0);
581/// assert_eq!(cbuf_def.size(), 3);
582///
583/// // Add elements
584/// cbuf.add(6);
585/// cbuf_def.add(7);
586///
587/// // Peek at the next element scheduled for removal
588/// assert_eq!(cbuf.peek().unwrap(), 6);
589/// assert_eq!(cbuf_def.peek().unwrap(), 0);
590/// # }
591/// ```
592#[derive(Debug)]
593pub struct CircularBuffer<T: Clone> {
594    queue: Vec<T>,
595    capacity: usize,
596    default_value: Option<T>,
597}
598
599impl<T: Clone> CircularBuffer<T> {
600    /// Default `CircularBuffer<T>` initializer
601    ///
602    /// # Returns
603    /// A new, empty `CircularBuffer<T>`
604    ///
605    /// # Examples
606    ///
607    /// ```
608    /// # use queues::*;
609    /// let cbuf: CircularBuffer<isize> = CircularBuffer::new(3);
610    /// assert_eq!(cbuf.size(), 0);
611    /// assert_eq!(cbuf.capacity(), 3);
612    /// ```
613    pub fn new(capacity: usize) -> CircularBuffer<T> {
614        CircularBuffer {
615            queue: vec![],
616            capacity,
617            default_value: None,
618        }
619    }
620
621    /// Create a `CircularBuffer<T>` with default values
622    ///
623    /// # Returns
624    /// A new `CircularBuffer<T>` filled with default values
625    ///
626    /// # Examples
627    ///
628    /// ```
629    /// # use queues::*;
630    /// let cbuf_def = CircularBuffer::with_default(3, -1isize);
631    /// assert_eq!(cbuf_def.size(), 3);
632    /// assert_eq!(cbuf_def.capacity(), 3);
633    /// assert_eq!(cbuf_def.peek(), Ok(-1));
634    /// ```
635    pub fn with_default(capacity: usize, default_value: T) -> CircularBuffer<T> {
636        let queue = vec![default_value.clone(); capacity];
637
638        CircularBuffer {
639            queue,
640            capacity,
641            default_value: Some(default_value),
642        }
643    }
644
645    /// Gets the capacity of the `CircularBuffer<T>`
646    ///
647    /// # Returns
648    /// The number of allowed elements in the buffer
649    ///
650    /// # Examples
651    ///
652    /// ```
653    /// # use queues::CircularBuffer;
654    /// let mut cbuf: CircularBuffer<isize> = CircularBuffer::new(3);
655    /// assert_eq!(cbuf.capacity(), 3);
656    /// ```
657    pub fn capacity(&self) -> usize {
658        self.capacity
659    }
660}
661
662impl<T: Clone> IsQueue<T> for CircularBuffer<T> {
663    /// Adds an element to a circular buffer
664    ///
665    /// # Parameters
666    /// - `val`: Value to add to the buffer
667    ///
668    /// # Returns
669    /// - `Ok(Some(T))`: The oldest value in the buffer, in case the addition
670    ///     causes an overflow.
671    /// - `Ok(None)`: Nothing, if the buffer has room for the added element
672    ///
673    /// # Examples
674    ///
675    /// ```
676    /// # use queues::*;
677    /// let mut cbuf: CircularBuffer<isize> = CircularBuffer::new(3);
678    /// let mut cbuf_def = CircularBuffer::with_default(3, 5isize);
679    /// assert_eq!(cbuf.add(42), Ok(None));
680    /// assert_eq!(cbuf_def.add(42), Ok(Some(5)));
681    /// ```
682    fn add(&mut self, val: T) -> Result<Option<T>, &str> {
683        if self.queue.len() < self.capacity {
684            self.queue.push(val);
685            Ok(None)
686        } else {
687            self.queue.push(val);
688            Ok(Some(self.queue.remove(0usize)))
689        }
690    }
691
692    /// Removes an element from the circular buffer and returns it.
693    ///
694    /// For circular buffers with default values, removing an element will add
695    /// a new default value into the buffer.
696    ///
697    /// # Returns
698    /// - `Ok(T)`: The oldest element in the buffer
699    /// - `Error`
700    ///
701    /// # Errors
702    /// Returns an error if an attempt is made to remove an element from
703    /// an empty buffer
704    ///
705    /// # Examples
706    ///
707    /// ```
708    /// # use queues::*;
709    /// let mut cbuf: CircularBuffer<isize> = CircularBuffer::new(3);
710    /// cbuf.add(42);
711    /// assert_eq!(cbuf.remove(), Ok(42));
712    /// assert_eq!(cbuf.size(), 0);
713    ///
714    /// let mut cbuf_def = CircularBuffer::with_default(3, 4isize);
715    /// cbuf_def.add(42);
716    /// assert_eq!(cbuf_def.remove(), Ok(4));
717    /// ```
718    fn remove(&mut self) -> Result<T, &str> {
719        if !self.queue.is_empty() {
720            if let Some(val) = self.default_value.clone() {
721                self.queue.push(val);
722            };
723            Ok(self.queue.remove(0usize))
724        } else {
725            Err("The Buffer is empty")
726        }
727    }
728
729    /// Peek at the head of the circular buffer
730    ///
731    /// # Returns
732    /// - `Ok(T)`: The next element scheduled for removal from the buffer
733    /// - `Error`
734    ///
735    /// # Errors
736    /// Returns an error if an attempt is made to peek into an empty buffer
737    ///
738    /// # Examples
739    ///
740    /// ```
741    /// # use queues::*;
742    /// let mut cbuf: CircularBuffer<isize> = CircularBuffer::new(3);
743    /// cbuf.add(42);
744    /// assert_eq!(cbuf.peek(), Ok(42));
745    /// ```
746    fn peek(&self) -> Result<T, &str> {
747        match self.queue.first() {
748            Some(val) => Ok(val.clone()),
749            None => Err("The Queue is empty"),
750        }
751    }
752
753    /// Gets the size of the circular buffer
754    ///
755    /// # Returns
756    /// The number of elements in the buffer. Note, this _includes_ default
757    /// values, which means that the `size` of a buffer with default values
758    /// should always be equal to its `capacity`
759    ///
760    /// # Examples
761    ///
762    /// ```
763    /// # use queues::*;
764    /// let mut cbuf: CircularBuffer<isize> = CircularBuffer::new(3);
765    /// assert_eq!(cbuf.size(), 0);
766    /// cbuf.add(42);
767    /// assert_eq!(cbuf.size(), 1);
768    /// ```
769    fn size(&self) -> usize {
770        self.queue.len()
771    }
772}