use super::FlexZeroSlice;
use super::FlexZeroVecOwned;
use crate::ZeroVecError;
use core::cmp::Ordering;
use core::iter::FromIterator;
use core::ops::Deref;
#[derive(Debug)]
#[non_exhaustive]
pub enum FlexZeroVec<'a> {
Owned(FlexZeroVecOwned),
Borrowed(&'a FlexZeroSlice),
}
impl<'a> Deref for FlexZeroVec<'a> {
type Target = FlexZeroSlice;
fn deref(&self) -> &Self::Target {
match self {
FlexZeroVec::Owned(v) => v.deref(),
FlexZeroVec::Borrowed(v) => v,
}
}
}
impl<'a> AsRef<FlexZeroSlice> for FlexZeroVec<'a> {
fn as_ref(&self) -> &FlexZeroSlice {
self.deref()
}
}
impl Eq for FlexZeroVec<'_> {}
impl<'a, 'b> PartialEq<FlexZeroVec<'b>> for FlexZeroVec<'a> {
#[inline]
fn eq(&self, other: &FlexZeroVec<'b>) -> bool {
self.iter().eq(other.iter())
}
}
impl<'a> Default for FlexZeroVec<'a> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<'a> PartialOrd for FlexZeroVec<'a> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<'a> Ord for FlexZeroVec<'a> {
fn cmp(&self, other: &Self) -> Ordering {
self.iter().cmp(other.iter())
}
}
impl<'a> FlexZeroVec<'a> {
#[inline]
pub const fn new() -> Self {
Self::Borrowed(FlexZeroSlice::new_empty())
}
pub fn parse_byte_slice(bytes: &'a [u8]) -> Result<Self, ZeroVecError> {
let slice: &'a FlexZeroSlice = FlexZeroSlice::parse_byte_slice(bytes)?;
Ok(Self::Borrowed(slice))
}
pub fn into_owned(self) -> FlexZeroVec<'static> {
match self {
Self::Owned(owned) => FlexZeroVec::Owned(owned),
Self::Borrowed(slice) => FlexZeroVec::Owned(FlexZeroVecOwned::from_slice(slice)),
}
}
pub fn to_mut(&mut self) -> &mut FlexZeroVecOwned {
match self {
Self::Owned(ref mut owned) => owned,
Self::Borrowed(slice) => {
*self = FlexZeroVec::Owned(FlexZeroVecOwned::from_slice(slice));
self.to_mut()
}
}
}
pub fn clear(&mut self) {
*self = Self::Borrowed(FlexZeroSlice::new_empty())
}
}
impl FromIterator<usize> for FlexZeroVec<'_> {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = usize>,
{
FlexZeroVecOwned::from_iter(iter).into_flexzerovec()
}
}
#[test]
fn test_zeromap_usize() {
use crate::ZeroMap;
let mut zm = ZeroMap::<usize, usize>::new();
assert!(zm.try_append(&29, &92).is_none());
assert!(zm.try_append(&38, &83).is_none());
assert!(zm.try_append(&47, &74).is_none());
assert!(zm.try_append(&56, &65).is_none());
assert_eq!(zm.keys.get_width(), 1);
assert_eq!(zm.values.get_width(), 1);
assert_eq!(zm.insert(&47, &744), Some(74));
assert_eq!(zm.values.get_width(), 2);
assert_eq!(zm.insert(&47, &774), Some(744));
assert_eq!(zm.values.get_width(), 2);
assert!(zm.try_append(&1100, &1).is_none());
assert_eq!(zm.keys.get_width(), 2);
assert_eq!(zm.remove(&1100), Some(1));
assert_eq!(zm.keys.get_width(), 1);
assert_eq!(zm.get_copied(&0), None);
assert_eq!(zm.get_copied(&29), Some(92));
assert_eq!(zm.get_copied(&38), Some(83));
assert_eq!(zm.get_copied(&47), Some(774));
assert_eq!(zm.get_copied(&56), Some(65));
assert_eq!(zm.get_copied(&usize::MAX), None);
}