use crate::iter::FromNonEmptyIterator;
use crate::iter::IntoNonEmptyIterator;
use crate::iter::NonEmptyIterator;
use crate::slice::NEChunks;
use crate::Singleton;
use core::fmt;
use std::cmp::Ordering;
use std::fmt::Debug;
use std::fmt::Formatter;
use std::num::NonZeroUsize;
use std::slice::SliceIndex;
#[cfg(feature = "serde")]
use serde::Deserialize;
#[cfg(feature = "serde")]
use serde::Serialize;
#[macro_export]
macro_rules! nev {
() => {compile_error!("An NEVec cannot be empty")};
($h:expr, $( $x:expr ),* $(,)?) => {{
let mut v = $crate::NEVec::new($h);
$( v.push($x); )*
v
}};
($h:expr) => {
$crate::NEVec::new($h)
};
($elem:expr; $n:expr) => {{
let n = const { ::std::num::NonZero::new($n).expect("Length cannot be 0") };
$crate::vector::NEVec::from_elem($elem, n)
}};
}
#[cfg_attr(
feature = "serde",
derive(Deserialize, Serialize),
serde(bound(serialize = "T: Clone + Serialize")),
serde(into = "Vec<T>", try_from = "Vec<T>")
)]
#[allow(clippy::unsafe_derive_deserialize)] #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NEVec<T> {
inner: Vec<T>,
}
impl<T> NEVec<T> {
#[must_use]
pub fn new(head: T) -> Self {
NEVec { inner: vec![head] }
}
#[must_use]
pub fn from_elem(elem: T, n: NonZeroUsize) -> Self
where
T: Clone,
{
NEVec {
inner: vec![elem; n.get()],
}
}
#[must_use]
pub fn with_capacity(capacity: NonZeroUsize, head: T) -> Self {
let mut inner = Vec::with_capacity(capacity.get());
inner.push(head);
NEVec { inner }
}
#[must_use]
pub fn first(&self) -> &T {
unsafe { self.inner.get_unchecked(0) }
}
#[must_use]
pub fn first_mut(&mut self) -> &mut T {
unsafe { self.inner.get_unchecked_mut(0) }
}
pub fn push(&mut self, e: T) {
self.inner.push(e);
}
pub fn pop(&mut self) -> Option<T> {
if self.len() > NonZeroUsize::MIN {
self.inner.pop()
} else {
None
}
}
pub fn remove(&mut self, index: usize) -> Option<T> {
(self.len() > NonZeroUsize::MIN).then(|| self.inner.remove(index))
}
pub fn swap_remove(&mut self, index: usize) -> Option<T> {
(self.len() > NonZeroUsize::MIN).then(|| self.inner.swap_remove(index))
}
pub fn retain<F>(self, mut f: F) -> Result<Self, Vec<T>>
where
F: FnMut(&T) -> bool,
{
self.retain_mut(|item| f(item))
}
pub fn retain_mut<F>(mut self, f: F) -> Result<Self, Vec<T>>
where
F: FnMut(&mut T) -> bool,
{
self.inner.retain_mut(f);
if self.inner.is_empty() {
Err(self.inner)
} else {
Ok(self)
}
}
pub fn insert(&mut self, index: usize, element: T) {
self.inner.insert(index, element);
}
#[must_use]
pub fn len(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.inner.len()) }
}
#[deprecated(since = "0.1.0", note = "A NEVec is never empty.")]
#[must_use]
pub const fn is_empty(&self) -> bool {
false
}
#[must_use]
pub fn capacity(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.inner.capacity()) }
}
#[must_use]
#[allow(clippy::missing_panics_doc)] pub fn last(&self) -> &T {
self.inner.last().unwrap()
}
#[must_use]
#[allow(clippy::missing_panics_doc)] pub fn last_mut(&mut self) -> &mut T {
self.inner.last_mut().unwrap()
}
#[must_use]
pub fn contains(&self, x: &T) -> bool
where
T: PartialEq,
{
self.inner.contains(x)
}
#[must_use]
pub fn get(&self, index: usize) -> Option<&T> {
self.inner.get(index)
}
#[must_use]
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
self.inner.get_mut(index)
}
pub fn truncate(&mut self, len: NonZeroUsize) {
self.inner.truncate(len.get());
}
pub fn iter(&self) -> std::slice::Iter<'_, T> {
self.inner.iter()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
self.inner.iter_mut()
}
pub fn nonempty_iter(&self) -> Iter<'_, T> {
Iter {
iter: self.inner.iter(),
}
}
pub fn nonempty_iter_mut(&mut self) -> IterMut<'_, T> {
IterMut {
inner: self.inner.iter_mut(),
}
}
#[must_use]
pub fn try_from_slice(slice: &[T]) -> Option<NEVec<T>>
where
T: Clone,
{
if slice.is_empty() {
None
} else {
Some(NEVec {
inner: slice.to_vec(),
})
}
}
#[must_use]
pub fn try_from_vec(vec: Vec<T>) -> Option<NEVec<T>> {
if vec.is_empty() {
None
} else {
Some(NEVec { inner: vec })
}
}
#[must_use]
#[allow(clippy::missing_panics_doc)] pub fn split_first(&self) -> (&T, &[T]) {
self.inner.split_first().unwrap()
}
#[must_use]
pub fn split(&self) -> (&T, &[T], &T) {
let (first, rest) = self.split_first();
if let Some((last, middle)) = rest.split_last() {
(first, middle, last)
} else {
(first, &[], first)
}
}
pub fn append(&mut self, other: &mut Vec<T>) {
self.inner.append(other);
}
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
where
T: Ord,
{
self.binary_search_by(|p| p.cmp(x))
}
pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where
F: FnMut(&'a T) -> Ordering,
{
self.inner.binary_search_by(f)
}
pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
where
B: Ord,
F: FnMut(&'a T) -> B,
{
self.binary_search_by(|k| f(k).cmp(b))
}
pub fn sort(&mut self)
where
T: Ord,
{
self.inner.sort();
}
pub fn sort_by<F>(&mut self, f: F)
where
F: FnMut(&T, &T) -> Ordering,
{
self.inner.sort_by(f);
}
pub fn sort_by_key<K, F>(&mut self, f: F)
where
F: FnMut(&T) -> K,
K: Ord,
{
self.inner.sort_by_key(f);
}
#[must_use]
pub fn as_nonempty_slice(&self) -> crate::NESlice<'_, T> {
unsafe { crate::NESlice::from_slice_unchecked(self.inner.as_slice()) }
}
pub fn dedup_by_key<F, K>(&mut self, mut key: F)
where
F: FnMut(&mut T) -> K,
K: PartialEq,
{
self.dedup_by(|a, b| key(a) == key(b));
}
pub fn dedup_by<F>(&mut self, same_bucket: F)
where
F: FnMut(&mut T, &mut T) -> bool,
{
self.inner.dedup_by(same_bucket);
}
pub fn nonempty_chunks(&self, chunk_size: NonZeroUsize) -> NEChunks<'_, T> {
NEChunks {
inner: self.inner.chunks(chunk_size.get()),
}
}
#[must_use]
pub fn partition_point<P>(&self, mut pred: P) -> usize
where
P: FnMut(&T) -> bool,
{
self.binary_search_by(|x| {
if pred(x) {
Ordering::Less
} else {
Ordering::Greater
}
})
.unwrap_or_else(|i| i)
}
}
impl<T: PartialEq> NEVec<T> {
pub fn dedup(&mut self) {
self.dedup_by(|a, b| a == b);
}
}
impl<T> From<NEVec<T>> for Vec<T> {
fn from(nonempty: NEVec<T>) -> Vec<T> {
nonempty.inner
}
}
impl<T> From<(T, Vec<T>)> for NEVec<T> {
fn from((head, tail): (T, Vec<T>)) -> Self {
let mut vec = vec![head];
vec.extend(tail);
NEVec { inner: vec }
}
}
impl<T> AsRef<Vec<T>> for NEVec<T> {
fn as_ref(&self) -> &Vec<T> {
self.inner.as_ref()
}
}
impl<T> AsMut<Vec<T>> for NEVec<T> {
fn as_mut(&mut self) -> &mut Vec<T> {
self.inner.as_mut()
}
}
impl<T> FromNonEmptyIterator<T> for NEVec<T> {
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = T>,
{
NEVec {
inner: iter.into_nonempty_iter().into_iter().collect(),
}
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Iter<'a, T: 'a> {
iter: std::slice::Iter<'a, T>,
}
impl<T> NonEmptyIterator for Iter<'_, T> {}
impl<'a, T> IntoIterator for Iter<'a, T> {
type Item = &'a T;
type IntoIter = std::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<T> Clone for Iter<'_, T> {
fn clone(&self) -> Self {
Iter {
iter: self.iter.clone(),
}
}
}
impl<T: Debug> Debug for Iter<'_, T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.iter.fmt(f)
}
}
#[derive(Debug)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct IterMut<'a, T: 'a> {
inner: std::slice::IterMut<'a, T>,
}
impl<T> NonEmptyIterator for IterMut<'_, T> {}
impl<'a, T> IntoIterator for IterMut<'a, T> {
type Item = &'a mut T;
type IntoIter = std::slice::IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
#[derive(Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct IntoIter<T> {
inner: std::vec::IntoIter<T>,
}
impl<T> NonEmptyIterator for IntoIter<T> {}
impl<T> IntoIterator for IntoIter<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<T: Debug> Debug for IntoIter<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl<T> IntoNonEmptyIterator for NEVec<T> {
type IntoNEIter = IntoIter<T>;
fn into_nonempty_iter(self) -> Self::IntoNEIter {
IntoIter {
inner: self.inner.into_iter(),
}
}
}
impl<'a, T> IntoNonEmptyIterator for &'a NEVec<T> {
type IntoNEIter = Iter<'a, T>;
fn into_nonempty_iter(self) -> Self::IntoNEIter {
self.nonempty_iter()
}
}
impl<T> IntoIterator for NEVec<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}
impl<'a, T> IntoIterator for &'a NEVec<T> {
type Item = &'a T;
type IntoIter = std::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut NEVec<T> {
type Item = &'a mut T;
type IntoIter = std::slice::IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T, I> std::ops::Index<I> for NEVec<T>
where
I: SliceIndex<[T]>,
{
type Output = I::Output;
fn index(&self, index: I) -> &Self::Output {
self.inner.index(index)
}
}
impl<T, I> std::ops::IndexMut<I> for NEVec<T>
where
I: SliceIndex<[T]>,
{
fn index_mut(&mut self, index: I) -> &mut Self::Output {
self.inner.index_mut(index)
}
}
impl<T: Debug> Debug for NEVec<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl<T> TryFrom<Vec<T>> for NEVec<T> {
type Error = crate::Error;
fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
NEVec::try_from_vec(vec).ok_or(crate::Error::Empty)
}
}
impl<T> Extend<T> for NEVec<T> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>,
{
self.inner.extend(iter);
}
}
impl<T> Singleton for NEVec<T> {
type Item = T;
fn singleton(item: T) -> NEVec<T> {
NEVec::new(item)
}
}
#[cfg(test)]
mod tests {
use crate::NEVec;
#[derive(Debug, Clone, PartialEq)]
struct Foo {
user: String,
}
#[test]
fn macro_usage() {
let a = Foo {
user: "a".to_string(),
};
let b = Foo {
user: "b".to_string(),
};
let v = nev![a, b];
assert_eq!("a", v.first().user);
}
#[test]
fn macro_semicolon() {
let a = Foo {
user: "a".to_string(),
};
let v = nev![a.clone(); 3];
let expected = NEVec { inner: vec![a; 3] };
assert_eq!(v, expected);
}
#[test]
fn test_from_conversion() {
let result = NEVec::from((1, vec![2, 3, 4, 5]));
let expected = NEVec {
inner: vec![1, 2, 3, 4, 5],
};
assert_eq!(result, expected);
}
#[test]
fn test_into_iter() {
let nonempty = NEVec::from((0usize, vec![1, 2, 3]));
for (i, n) in nonempty.into_iter().enumerate() {
assert_eq!(i, n);
}
}
#[test]
fn test_iter_syntax() {
let nonempty = NEVec::from((0, vec![1, 2, 3]));
for n in &nonempty {
assert_eq!(*n, *n); }
for _ in nonempty {}
}
#[cfg(feature = "serde")]
mod serialize {
use serde::Deserialize;
use serde::Serialize;
use crate::NEVec;
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
struct SimpleSerializable(i32);
#[test]
fn test_simple_round_trip() -> Result<(), Box<dyn std::error::Error>> {
let mut v = NEVec::new(SimpleSerializable(42));
v.push(SimpleSerializable(777));
let expected_value = v.clone();
let res =
serde_json::from_str::<'_, NEVec<SimpleSerializable>>(&serde_json::to_string(&v)?)?;
assert_eq!(res, expected_value);
Ok(())
}
}
#[test]
fn test_result_collect() {
use crate::IntoNonEmptyIterator;
use crate::NonEmptyIterator;
let nonempty = nev![2, 4, 8];
let output = nonempty
.into_nonempty_iter()
.map(|n| {
if n % 2 == 0 {
Ok(n)
} else {
Err("odd number!")
}
})
.collect::<Result<NEVec<u32>, &'static str>>();
assert_eq!(output, Ok(nev![2, 4, 8]));
let nonempty = nev![2, 1, 8];
let output = nonempty
.into_nonempty_iter()
.map(|n| {
if n % 2 == 0 {
Ok(n)
} else {
Err("odd number!")
}
})
.collect::<Result<NEVec<u32>, &'static str>>();
assert_eq!(output, Err("odd number!"));
}
#[test]
fn test_as_slice() {
let nonempty = NEVec::from((0, vec![1, 2, 3]));
assert_eq!(
crate::NESlice::try_from_slice(&[0, 1, 2, 3]).unwrap(),
nonempty.as_nonempty_slice(),
);
}
#[test]
fn debug_impl() {
let actual = format!("{:?}", nev![0, 1, 2, 3]);
let expected = format!("{:?}", vec![0, 1, 2, 3]);
assert_eq!(expected, actual);
}
#[test]
fn sorting() {
let mut n = nev![1, 5, 4, 3, 2, 1];
n.sort();
assert_eq!(nev![1, 1, 2, 3, 4, 5], n);
let mut m = nev![1];
m.sort();
assert_eq!(nev![1], m);
}
#[test]
fn extend() {
let mut n = nev![1, 2, 3];
let v = vec![4, 5, 6];
n.extend(v);
assert_eq!(n, nev![1, 2, 3, 4, 5, 6]);
}
#[test]
fn iter_mut() {
let mut v = nev![0, 1, 2, 3];
v.iter_mut().for_each(|x| {
*x += 1;
});
assert_eq!(nev![1, 2, 3, 4], v);
for x in &mut v {
*x -= 1;
}
assert_eq!(nev![0, 1, 2, 3], v);
}
#[test]
fn retain() {
let v = nev![0, 1, 2, 3];
let result = v.retain(|_| true);
assert_eq!(
Ok(nev![0, 1, 2, 3]),
result,
"retaining all values should not change anything"
);
let v = nev![0, 1, 2, 3];
let result = v.retain(|_| false);
assert_eq!(
Err(vec![]),
result,
"removing all values should return a regular vec"
);
let v = nev![3, 7];
let result = v.retain_mut(|x| *x == 3);
assert_eq!(Ok(nev![3]), result, "only 3 should remain");
}
#[test]
fn retain_mut() {
let v = nev![0, 1, 2, 3];
let result = v.retain_mut(|x| {
*x += 1;
true
});
assert_eq!(
Ok(nev![1, 2, 3, 4]),
result,
"each value must be incremented by 1"
);
let v = nev![0, 1, 2, 3];
let result = v.retain_mut(|x| {
*x += 1;
false
});
assert_eq!(
Err(vec![]),
result,
"removing all values should return a regular vec"
);
let v = nev![3, 7];
let result = v.retain_mut(|x| {
if *x == 3 {
*x += 1;
true
} else {
false
}
});
assert_eq!(Ok(nev![4]), result, "only 3+1 = 4 should remain");
}
}