use crate::eval::value::Value;
use super::{Container, ContainerError, ContainerResult};
use std::sync::{Arc, RwLock};
#[derive(Clone, Debug)]
pub struct ListQueue {
data: Vec<Value>,
name: Option<String>,
}
impl ListQueue {
pub fn new() -> Self {
Self {
data: Vec::new(),
name: None,
}
}
pub fn with_name(name: impl Into<String>) -> Self {
let mut queue = Self::new();
queue.name = Some(name.into());
queue
}
pub fn from_vec(values: Vec<Value>) -> Self {
Self {
data: values,
name: None,
}
}
pub fn enqueue(&mut self, value: Value) {
self.data.push(value);
}
pub fn dequeue(&mut self) -> Option<Value> {
if self.data.is_empty() {
None
} else {
Some(self.data.remove(0))
}
}
pub fn front(&self) -> Option<&Value> {
self.data.first()
}
pub fn back(&self) -> Option<&Value> {
self.data.last()
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn to_vec(&self) -> Vec<Value> {
self.data.clone()
}
pub fn iter(&self) -> std::slice::Iter<'_, Value> {
self.data.iter()
}
pub fn append(&mut self, other: &Self) {
self.data.extend(other.data.iter().cloned());
}
pub fn concat(&self, other: &Self) -> Self {
let mut result = self.clone();
result.append(other);
result
}
pub fn reverse(&mut self) {
self.data.reverse();
}
pub fn reversed(&self) -> Self {
let mut result = self.clone();
result.reverse();
result
}
}
impl Container for ListQueue {
fn len(&self) -> usize {
self.data.len()
}
fn clear(&mut self) {
self.data.clear();
}
}
impl Default for ListQueue {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Debug)]
pub struct ThreadSafeListQueue {
inner: Arc<RwLock<ListQueue>>,
}
impl ThreadSafeListQueue {
pub fn new() -> Self {
Self {
inner: Arc::new(RwLock::new(ListQueue::new())),
}
}
pub fn with_name(name: impl Into<String>) -> Self {
Self {
inner: Arc::new(RwLock::new(ListQueue::with_name(name))),
}
}
pub fn from_vec(values: Vec<Value>) -> Self {
Self {
inner: Arc::new(RwLock::new(ListQueue::from_vec(values))),
}
}
pub fn enqueue(&self, value: Value) {
self.inner.write().unwrap().enqueue(value);
}
pub fn dequeue(&self) -> Option<Value> {
self.inner.write().unwrap().dequeue()
}
pub fn front(&self) -> Option<Value> {
self.inner.read().unwrap().front().cloned()
}
pub fn back(&self) -> Option<Value> {
self.inner.read().unwrap().back().cloned()
}
pub fn len(&self) -> usize {
self.inner.read().unwrap().len()
}
pub fn is_empty(&self) -> bool {
self.inner.read().unwrap().is_empty()
}
pub fn clear(&self) {
self.inner.write().unwrap().clear();
}
pub fn to_vec(&self) -> Vec<Value> {
self.inner.read().unwrap().to_vec()
}
pub fn append(&self, other: &Self) {
let other_data = other.to_vec();
let mut inner = self.inner.write().unwrap();
for value in other_data {
inner.enqueue(value);
}
}
pub fn concat(&self, other: &Self) -> Self {
let self_data = self.to_vec();
let other_data = other.to_vec();
let mut result_data = self_data;
result_data.extend(other_data);
Self::from_vec(result_data)
}
pub fn with_read<F, R>(&self, f: F) -> R
where
F: FnOnce(&ListQueue) -> R,
{
f(&self.inner.read().unwrap())
}
pub fn with_write<F, R>(&self, f: F) -> R
where
F: FnOnce(&mut ListQueue) -> R,
{
f(&mut self.inner.write().unwrap())
}
}
impl Default for ThreadSafeListQueue {
fn default() -> Self {
Self::new()
}
}
impl ListQueue {
pub fn list_queue_front(&self) -> ContainerResult<Value> {
self.front().cloned().ok_or(ContainerError::EmptyContainer {
operation: "list-queue-front".to_string(),
})
}
pub fn list_queue_back(&self) -> ContainerResult<Value> {
self.back().cloned().ok_or(ContainerError::EmptyContainer {
operation: "list-queue-back".to_string(),
})
}
pub fn list_queue_remove_front(&mut self) -> ContainerResult<Value> {
self.dequeue().ok_or(ContainerError::EmptyContainer {
operation: "list-queue-remove-front!".to_string(),
})
}
pub fn list_queue_add_front(&mut self, value: Value) {
self.data.insert(0, value);
}
pub fn list_queue_add_back(&mut self, value: Value) {
self.enqueue(value);
}
pub fn list_queue_remove_back(&mut self) -> ContainerResult<Value> {
if self.is_empty() {
Err(ContainerError::EmptyContainer {
operation: "list-queue-remove-back!".to_string(),
})
} else {
Ok(self.data.pop().unwrap())
}
}
pub fn list_queue_to_list(&self) -> Value {
Value::list(self.to_vec())
}
pub fn list_to_list_queue(list: &Value) -> ContainerResult<Self> {
match list.as_list() {
Some(values) => Ok(Self::from_vec(values)),
None => Err(ContainerError::InvalidComparator {
message: "Expected a proper list".to_string(),
}),
}
}
pub fn list_queue_append_mut(&mut self, other: &Self) {
self.append(other);
}
pub fn list_queue_append(&self, other: &Self) -> Self {
self.concat(other)
}
pub fn list_queue_concatenate(queues: &[&Self]) -> Self {
let mut result = Self::new();
for queue in queues {
result.append(queue);
}
result
}
pub fn list_queue_map<F>(&self, mut f: F) -> Self
where
F: FnMut(&Value) -> Value,
{
let mapped: Vec<_> = self.iter().map(f).collect();
Self::from_vec(mapped)
}
pub fn list_queue_map_mut<F>(&mut self, mut f: F)
where
F: FnMut(&Value) -> Value,
{
for value in &mut self.data {
*value = f(value);
}
}
pub fn list_queue_for_each<F>(&self, mut f: F)
where
F: FnMut(&Value),
{
for value in self.iter() {
f(value);
}
}
pub fn list_queue_fold<F, Acc>(&self, mut init: Acc, mut f: F) -> Acc
where
F: FnMut(Acc, &Value) -> Acc,
{
for value in self.iter() {
init = f(init, value);
}
init
}
pub fn list_queue_fold_right<F, Acc>(&self, mut init: Acc, mut f: F) -> Acc
where
F: FnMut(&Value, Acc) -> Acc,
{
for value in self.iter().rev() {
init = f(value, init);
}
init
}
pub fn list_queue_filter<F>(&self, mut predicate: F) -> Self
where
F: FnMut(&Value) -> bool,
{
let filtered: Vec<_> = self.iter().filter(|v| predicate(v)).cloned().collect();
Self::from_vec(filtered)
}
pub fn list_queue_remove<F>(&self, mut predicate: F) -> Self
where
F: FnMut(&Value) -> bool,
{
let filtered: Vec<_> = self.iter().filter(|v| !predicate(v)).cloned().collect();
Self::from_vec(filtered)
}
pub fn list_queue_partition<F>(&self, mut predicate: F) -> (Self, Self)
where
F: FnMut(&Value) -> bool,
{
let mut true_queue = Self::new();
let mut false_queue = Self::new();
for value in self.iter() {
if predicate(value) {
true_queue.enqueue(value.clone());
} else {
false_queue.enqueue(value.clone());
}
}
(true_queue, false_queue)
}
pub fn list_queue_find<F>(&self, mut predicate: F) -> Option<Value>
where
F: FnMut(&Value) -> bool,
{
self.iter().find(|v| predicate(v)).cloned()
}
pub fn list_queue_any<F>(&self, mut predicate: F) -> bool
where
F: FnMut(&Value) -> bool,
{
self.iter().any(predicate)
}
pub fn list_queue_every<F>(&self, mut predicate: F) -> bool
where
F: FnMut(&Value) -> bool,
{
self.iter().all(predicate)
}
pub fn list_queue_count<F>(&self, mut predicate: F) -> usize
where
F: FnMut(&Value) -> bool,
{
self.iter().filter(|v| predicate(v)).count()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_operations() {
let mut queue = ListQueue::new();
assert!(queue.is_empty());
assert_eq!(queue.len(), 0);
queue.enqueue(Value::number(1.0));
queue.enqueue(Value::number(2.0));
queue.enqueue(Value::number(3.0));
assert_eq!(queue.len(), 3);
assert!(!queue.is_empty());
assert_eq!(queue.front(), Some(&Value::number(1.0)));
assert_eq!(queue.back(), Some(&Value::number(3.0)));
assert_eq!(queue.dequeue(), Some(Value::number(1.0)));
assert_eq!(queue.dequeue(), Some(Value::number(2.0)));
assert_eq!(queue.len(), 1);
assert_eq!(queue.front(), Some(&Value::number(3.0)));
assert_eq!(queue.back(), Some(&Value::number(3.0)));
assert_eq!(queue.dequeue(), Some(Value::number(3.0)));
assert!(queue.is_empty());
assert_eq!(queue.dequeue(), None);
}
#[test]
fn test_from_vec() {
let values = vec![
Value::number(1.0),
Value::number(2.0),
Value::number(3.0),
];
let queue = ListQueue::from_vec(values.clone());
assert_eq!(queue.len(), 3);
assert_eq!(queue.to_vec(), values);
assert_eq!(queue.front(), Some(&Value::number(1.0)));
assert_eq!(queue.back(), Some(&Value::number(3.0)));
}
#[test]
fn test_thread_safe_queue() {
let queue = ThreadSafeListQueue::new();
queue.enqueue(Value::number(1.0));
queue.enqueue(Value::number(2.0));
assert_eq!(queue.len(), 2);
assert_eq!(queue.front(), Some(Value::number(1.0)));
assert_eq!(queue.back(), Some(Value::number(2.0)));
assert_eq!(queue.dequeue(), Some(Value::number(1.0)));
assert_eq!(queue.len(), 1);
queue.clear();
assert!(queue.is_empty());
}
}