use crate::drain::Drain;
use std::collections::vec_deque::IntoIter;
use std::collections::VecDeque;
use std::fmt;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone)]
pub struct Queue<T> {
capacity: usize,
data: VecDeque<T>,
}
impl<T> fmt::Display for Queue<T>
where
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.peek() {
Some(item) => write!(
f,
"{{ next: {}, len: {}, capacity: {} }}",
item,
self.len(),
self.capacity()
),
None => write!(
f,
"{{ len: {}, capacity: {} }}",
self.len(),
self.capacity()
),
}
}
}
impl<T> Queue<T> {
pub fn new(capacity: usize) -> Self {
Queue {
capacity,
data: VecDeque::with_capacity(capacity + 1),
}
}
#[inline]
pub fn len(&self) -> usize {
self.data.len()
}
#[inline]
pub fn capacity(&self) -> usize {
self.capacity
}
#[inline]
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
#[inline]
pub fn is_full(&self) -> bool {
self.len() >= self.capacity()
}
#[inline]
pub fn clear(&mut self) {
self.data.clear()
}
pub fn resize(&mut self, capacity: usize) -> usize {
self.capacity = capacity;
let old_size = self.data.len();
if old_size > capacity {
self.data.truncate(capacity);
old_size - capacity
} else {
if capacity > old_size {
self.data.try_reserve(capacity + 1 - old_size).ok();
}
0
}
}
pub fn push(&mut self, item: T) -> Option<T> {
if self.capacity == 0 {
return None;
}
self.data.push_front(item);
if self.data.len() > self.capacity {
self.pop()
} else {
None
}
}
pub fn pop(&mut self) -> Option<T> {
self.data.pop_back()
}
pub fn peek(&self) -> Option<&T> {
let len = self.data.len();
if len > 0 {
self.data.get(len - 1)
} else {
None
}
}
pub fn drain(&mut self) -> Drain<T> {
Drain::new(self)
}
}
impl<T> std::iter::IntoIterator for Queue<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
self.data.into_iter()
}
}
impl<T> FromIterator<T> for Queue<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut queue = Queue::new(0);
for i in iter {
queue.resize(queue.len() + 1);
queue.push(i);
}
queue
}
}
impl<T> PartialEq<Queue<T>> for Queue<T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
if self.capacity != other.capacity {
return false;
}
if self.len() != other.len() {
return false;
}
let mut iter_other = other.data.iter();
for self_v in self.data.iter() {
match iter_other.next() {
Some(other_v) => {
if self_v != other_v {
return false;
}
}
None => return false,
}
}
true
}
}
impl<T> Eq for Queue<T> where T: Eq {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_queue_0() {
let mut queue: Queue<usize> = Queue::new(0);
assert_eq!(None, queue.push(42));
assert_eq!(None, queue.pop());
assert_eq!(0, queue.capacity());
assert_eq!(true, queue.is_full());
assert_eq!(true, queue.is_empty());
}
#[cfg(feature = "serde")]
#[test]
fn test_json() {
use serde_json::json;
let mut queue1 = Queue::<usize>::new(10);
queue1.push(1);
queue1.push(2);
let export = json!(&queue1).to_string();
assert_eq!("{\"capacity\":10,\"data\":[2,1]}", export);
let queue2: Queue<usize> = serde_json::from_str(&export).unwrap();
assert_eq!(&queue1, &queue2);
queue1.clear();
assert_eq!(0, queue1.len());
assert_eq!(2, queue2.len());
}
}