use crate::eval::value::Value;
use super::{Container, Persistent, ContainerError, ContainerResult};
use std::sync::Arc;
#[derive(Clone, Debug)]
pub struct Ideque {
data: Vec<Value>,
name: Option<String>,
}
impl Ideque {
pub fn new() -> Self {
Self {
data: Vec::new(),
name: None,
}
}
pub fn from_vec(values: Vec<Value>) -> Self {
Self {
data: values,
name: None,
}
}
pub fn push_front(&mut self, value: Value) {
self.data.insert(0, value);
}
pub fn push_back(&mut self, value: Value) {
self.data.push(value);
}
pub fn pop_front(&mut self) -> Option<Value> {
if self.data.is_empty() {
None
} else {
Some(self.data.remove(0))
}
}
pub fn pop_back(&mut self) -> Option<Value> {
self.data.pop()
}
pub fn front(&self) -> Option<&Value> {
self.data.first()
}
pub fn back(&self) -> Option<&Value> {
self.data.last()
}
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());
}
}
impl Container for Ideque {
fn len(&self) -> usize {
self.data.len()
}
fn clear(&mut self) {
self.data.clear();
}
}
impl Default for Ideque {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Debug)]
pub struct PersistentIdeque {
data: Arc<Vec<Value>>,
}
impl PersistentIdeque {
pub fn new() -> Self {
Self {
data: Arc::new(Vec::new()),
}
}
pub fn from_vec(values: Vec<Value>) -> Self {
Self {
data: Arc::new(values),
}
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn cons(&self, value: Value) -> Self {
let mut new_data = vec![value];
new_data.extend(self.data.iter().cloned());
Self {
data: Arc::new(new_data),
}
}
pub fn snoc(&self, value: Value) -> Self {
let mut new_data = self.data.as_ref().clone();
new_data.push(value);
Self {
data: Arc::new(new_data),
}
}
pub fn uncons(&self) -> Option<(Value, Self)> {
if self.data.is_empty() {
None
} else {
let front = self.data[0].clone();
let rest = self.data[1..].to_vec();
Some((front, Self {
data: Arc::new(rest),
}))
}
}
pub fn unsnoc(&self) -> Option<(Self, Value)> {
if self.data.is_empty() {
None
} else {
let back = self.data[self.data.len() - 1].clone();
let rest = self.data[..self.data.len() - 1].to_vec();
Some((Self {
data: Arc::new(rest),
}, back))
}
}
pub fn front(&self) -> Option<Value> {
self.data.first().cloned()
}
pub fn back(&self) -> Option<Value> {
self.data.last().cloned()
}
pub fn to_vec(&self) -> Vec<Value> {
self.data.as_ref().clone()
}
pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
self.data.iter().cloned()
}
pub fn append(&self, other: &Self) -> Self {
let mut new_data = self.data.as_ref().clone();
new_data.extend(other.data.iter().cloned());
Self {
data: Arc::new(new_data),
}
}
pub fn reverse(&self) -> Self {
let mut new_data = self.data.as_ref().clone();
new_data.reverse();
Self {
data: Arc::new(new_data),
}
}
}
impl Default for PersistentIdeque {
fn default() -> Self {
Self::new()
}
}
impl Persistent<Value> for PersistentIdeque {
fn insert(&self, element: Value) -> Self {
self.snoc(element)
}
fn remove(&self, element: &Value) -> Self {
let filtered: Vec<_> = self.data.iter().filter(|v| *v != element).cloned().collect();
Self {
data: Arc::new(filtered),
}
}
}
impl Ideque {
pub fn ideque_front(&self) -> ContainerResult<Value> {
self.front().cloned().ok_or(ContainerError::EmptyContainer {
operation: "ideque-front".to_string(),
})
}
pub fn ideque_back(&self) -> ContainerResult<Value> {
self.back().cloned().ok_or(ContainerError::EmptyContainer {
operation: "ideque-back".to_string(),
})
}
pub fn ideque_remove_front(&mut self) -> ContainerResult<Value> {
self.pop_front().ok_or(ContainerError::EmptyContainer {
operation: "ideque-remove-front".to_string(),
})
}
pub fn ideque_remove_back(&mut self) -> ContainerResult<Value> {
self.pop_back().ok_or(ContainerError::EmptyContainer {
operation: "ideque-remove-back".to_string(),
})
}
pub fn ideque_add_front(&mut self, value: Value) {
self.push_front(value);
}
pub fn ideque_add_back(&mut self, value: Value) {
self.push_back(value);
}
pub fn ideque_to_list(&self) -> Value {
Value::list(self.to_vec())
}
pub fn list_to_ideque(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 ideque_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 ideque_fold_right<F, Acc>(&self, mut init: Acc, mut f: F) -> Acc
where
F: FnMut(&Value, Acc) -> Acc,
{
for value in self.data.iter().rev() {
init = f(value, init);
}
init
}
pub fn ideque_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 ideque_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 ideque_append(&self, other: &Self) -> Self {
let mut result = self.clone();
result.append(other);
result
}
pub fn ideque_reverse(&self) -> Self {
let mut result = self.clone();
result.data.reverse();
result
}
pub fn ideque_count<F>(&self, mut predicate: F) -> usize
where
F: FnMut(&Value) -> bool,
{
self.iter().filter(|v| predicate(v)).count()
}
pub fn ideque_any<F>(&self, mut predicate: F) -> bool
where
F: FnMut(&Value) -> bool,
{
self.iter().any(predicate)
}
pub fn ideque_every<F>(&self, mut predicate: F) -> bool
where
F: FnMut(&Value) -> bool,
{
self.iter().all(predicate)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_operations() {
let mut ideque = Ideque::new();
assert!(ideque.is_empty());
assert_eq!(ideque.len(), 0);
ideque.push_back(Value::number(1.0));
ideque.push_back(Value::number(2.0));
assert_eq!(ideque.len(), 2);
assert_eq!(ideque.front(), Some(&Value::number(1.0)));
assert_eq!(ideque.back(), Some(&Value::number(2.0)));
ideque.push_front(Value::number(0.0));
assert_eq!(ideque.len(), 3);
assert_eq!(ideque.front(), Some(&Value::number(0.0)));
assert_eq!(ideque.pop_front(), Some(Value::number(0.0)));
assert_eq!(ideque.pop_back(), Some(Value::number(2.0)));
assert_eq!(ideque.len(), 1);
assert_eq!(ideque.front(), Some(&Value::number(1.0)));
}
#[test]
fn test_persistent_ideque() {
let ideque = PersistentIdeque::new();
assert!(ideque.is_empty());
let ideque1 = ideque.cons(Value::number(1.0));
let ideque2 = ideque1.snoc(Value::number(2.0));
let ideque3 = ideque2.cons(Value::number(0.0));
assert!(ideque.is_empty());
assert_eq!(ideque1.len(), 1);
assert_eq!(ideque2.len(), 2);
assert_eq!(ideque3.len(), 3);
if let Some((front, rest)) = ideque3.uncons() {
assert_eq!(front, Value::number(0.0));
assert_eq!(rest.len(), 2);
}
if let Some((rest, back)) = ideque3.unsnoc() {
assert_eq!(back, Value::number(2.0));
assert_eq!(rest.len(), 2);
}
}
#[test]
fn test_from_vec() {
let values = vec![
Value::number(1.0),
Value::number(2.0),
Value::number(3.0),
];
let ideque = Ideque::from_vec(values.clone());
assert_eq!(ideque.len(), 3);
assert_eq!(ideque.to_vec(), values);
let persistent = PersistentIdeque::from_vec(values.clone());
assert_eq!(persistent.len(), 3);
assert_eq!(persistent.to_vec(), values);
}
}