use crate::errors::NonEmptyError;
#[cfg(feature = "im")]
use im::Vector;
use std::collections::vec_deque::IntoIter;
use std::collections::vec_deque::{Iter, IterMut};
use std::collections::VecDeque;
use std::ops::Index;
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub struct NEVec<T>(VecDeque<T>);
impl<T> NEVec<T> {
pub fn new(head: T, tail: Vec<T>) -> Self {
let mut vec = VecDeque::from(tail);
vec.push_front(head);
Self(vec)
}
pub fn singleton(value: T) -> Self {
let mut vec = VecDeque::new();
vec.push_back(value);
Self(vec)
}
pub fn head(&self) -> &T {
self.0.front().expect("[NonEmptyVec] invariant violated.")
}
pub fn init(&self) -> Iter<'_, T> {
self.0.range(..self.0.len() - 1)
}
pub fn tail(&self) -> Iter<'_, T> {
self.0.range(1..self.0.len())
}
pub fn last(&self) -> &T {
self.0.back().expect("[NonEmptyVec] invariant violated.")
}
pub fn from_vec(vec: Vec<T>) -> Result<Self, NonEmptyError> {
match vec.is_empty() {
true => Err(NonEmptyError::Empty),
false => Ok(Self(VecDeque::from(vec))),
}
}
pub fn from_deque(deque: VecDeque<T>) -> Result<Self, NonEmptyError> {
match deque.is_empty() {
true => Err(NonEmptyError::Empty),
false => Ok(Self(deque)),
}
}
#[cfg(feature = "im")]
pub fn from_vector(vector: Vector<T>) -> Result<Self, NonEmptyError>
where
T: Clone,
{
match vector.is_empty() {
true => Err(NonEmptyError::Empty),
false => Ok(Self(VecDeque::from_iter(vector.into_iter()))),
}
}
#[doc(hidden)]
pub fn __from_vec_unsafe(vec: Vec<T>) -> Self {
debug_assert!(!vec.is_empty());
Self::from_vec(vec).unwrap()
}
#[doc(hidden)]
pub fn __from_deque_unsafe(deque: VecDeque<T>) -> Self {
debug_assert!(!deque.is_empty());
Self::from_deque(deque).unwrap()
}
#[doc(hidden)]
#[cfg(feature = "im")]
pub fn __from_vector_unsafe(vector: Vector<T>) -> Self
where
T: Clone,
{
debug_assert!(!vector.is_empty());
Self::from_vector(vector).unwrap()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
false
}
pub fn as_slice(&mut self) -> &[T] {
self.0.make_contiguous();
self.0.as_slices().0
}
pub fn push_front(&mut self, value: T) {
self.0.push_front(value);
}
pub fn push_back(&mut self, value: T) {
self.0.push_back(value);
}
pub fn pop_front(&mut self) -> Result<T, NonEmptyError> {
match self.0.len() {
0 => Err(NonEmptyError::Empty),
1 => Err(NonEmptyError::AlreadySingleton),
_ => Ok(self
.0
.pop_front()
.expect("[NonEmptyVec] invariant violated.")),
}
}
pub fn pop_back(&mut self) -> Result<T, NonEmptyError> {
match self.0.len() {
0 => Err(NonEmptyError::Empty),
1 => Err(NonEmptyError::AlreadySingleton),
_ => Ok(self
.0
.pop_back()
.expect("[NonEmptyVec] invariant violated.")),
}
}
pub fn split_first(&self) -> (&T, Iter<'_, T>) {
(self.head(), self.tail())
}
pub fn split_last(&self) -> (Iter<'_, T>, &T) {
(self.init(), self.last())
}
pub fn take_split_first(self) -> (T, IntoIter<T>) {
let mut iter = self.0.into_iter();
let head = iter.next().expect("[NonEmptyVec] invariant violated.");
(head, iter)
}
pub fn take_split_last(self) -> (IntoIter<T>, T) {
let mut iter = self.0.into_iter();
let last = iter.next_back().expect("[NonEmptyVec] invariant violated.");
(iter, last)
}
pub fn iter(&self) -> Iter<'_, T> {
self.0.iter()
}
pub fn extend<I: IntoIterator<Item = T>>(&mut self, other: I) {
self.0.extend(other);
}
}
impl<T> From<NEVec<T>> for Vec<T> {
fn from(ne: NEVec<T>) -> Self {
ne.0.into()
}
}
impl<T> From<NEVec<T>> for VecDeque<T> {
fn from(ne: NEVec<T>) -> Self {
ne.0
}
}
#[cfg(feature = "im")]
impl<T> From<NEVec<T>> for Vector<T>
where
T: Clone,
{
fn from(ne: NEVec<T>) -> Self {
Vector::from_iter(ne.0.into_iter())
}
}
impl<T> TryFrom<Vec<T>> for NEVec<T> {
type Error = NonEmptyError;
fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
NEVec::from_vec(vec)
}
}
impl<T> From<(T, Vec<T>)> for NEVec<T> {
fn from(value: (T, Vec<T>)) -> Self {
let (head, tail) = value;
Self::new(head, tail)
}
}
impl<T> From<(T, VecDeque<T>)> for NEVec<T> {
fn from(value: (T, VecDeque<T>)) -> Self {
let (head, tail) = value;
Self::new(head, Vec::from(tail))
}
}
#[cfg(feature = "im")]
impl<T: Clone> From<(T, Vector<T>)> for NEVec<T> {
fn from(value: (T, Vector<T>)) -> Self {
let (head, tail) = value;
Self::new(head, Vec::from_iter(tail.into_iter()))
}
}
impl<T> From<T> for NEVec<T> {
fn from(value: T) -> Self {
Self::singleton(value)
}
}
impl<'a, T> IntoIterator for &'a NEVec<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl<'a, T> IntoIterator for &'a mut NEVec<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter_mut()
}
}
impl<T> IntoIterator for NEVec<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<T> Index<usize> for NEVec<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.0[index]
}
}