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}