use crate::ule::AsULE;
use crate::ZeroSlice;
use core::cmp::Ordering;
use core::fmt;
use super::kv::ZeroMapKV;
use super::vecs::ZeroVecLike;
pub struct ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a>,
V: ZeroMapKV<'a>,
K: ?Sized,
V: ?Sized,
{
pub(crate) keys: &'a <K as ZeroMapKV<'a>>::Slice,
pub(crate) values: &'a <V as ZeroMapKV<'a>>::Slice,
}
impl<'a, K, V> Copy for ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a>,
V: ZeroMapKV<'a>,
K: ?Sized,
V: ?Sized,
{
}
impl<'a, K, V> Clone for ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a>,
V: ZeroMapKV<'a>,
K: ?Sized,
V: ?Sized,
{
fn clone(&self) -> Self {
*self
}
}
impl<'a, K, V> Default for ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a>,
V: ZeroMapKV<'a>,
K::Slice: 'static,
V::Slice: 'static,
K: ?Sized,
V: ?Sized,
{
fn default() -> Self {
Self::new()
}
}
impl<'a, K, V> ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a>,
V: ZeroMapKV<'a>,
K::Slice: 'static,
V::Slice: 'static,
K: ?Sized,
V: ?Sized,
{
pub fn new() -> Self {
Self {
keys: K::Container::zvl_new_borrowed(),
values: V::Container::zvl_new_borrowed(),
}
}
}
impl<'a, K, V> ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a>,
V: ZeroMapKV<'a>,
K: ?Sized,
V: ?Sized,
{
#[doc(hidden)] pub const unsafe fn from_parts_unchecked(
keys: &'a <K as ZeroMapKV<'a>>::Slice,
values: &'a <V as ZeroMapKV<'a>>::Slice,
) -> Self {
Self { keys, values }
}
pub fn len(self) -> usize {
self.values.zvl_len()
}
pub fn is_empty(self) -> bool {
self.values.zvl_len() == 0
}
}
impl<'a, K, V> ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a> + Ord,
V: ZeroMapKV<'a>,
K: ?Sized,
V: ?Sized,
{
pub fn get(self, key: &K) -> Option<&'a V::GetType> {
let index = self.keys.zvl_binary_search(key).ok()?;
self.values.zvl_get(index)
}
pub fn get_by(self, predicate: impl FnMut(&K) -> Ordering) -> Option<&'a V::GetType> {
let index = self.keys.zvl_binary_search_by(predicate).ok()?;
self.values.zvl_get(index)
}
pub fn contains_key(self, key: &K) -> bool {
self.keys.zvl_binary_search(key).is_ok()
}
}
impl<'a, K, V> ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a> + ?Sized,
V: ZeroMapKV<'a> + ?Sized,
{
pub fn iter(
self,
) -> impl Iterator<
Item = (
&'a <K as ZeroMapKV<'a>>::GetType,
&'a <V as ZeroMapKV<'a>>::GetType,
),
> {
self.iter_keys().zip(self.iter_values())
}
pub fn iter_keys(self) -> impl Iterator<Item = &'a <K as ZeroMapKV<'a>>::GetType> {
#[expect(clippy::unwrap_used)] (0..self.keys.zvl_len()).map(move |idx| self.keys.zvl_get(idx).unwrap())
}
pub fn iter_values(self) -> impl Iterator<Item = &'a <V as ZeroMapKV<'a>>::GetType> {
#[expect(clippy::unwrap_used)] (0..self.values.zvl_len()).map(move |idx| self.values.zvl_get(idx).unwrap())
}
}
impl<'a, K, V> ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a> + Ord + ?Sized,
V: ZeroMapKV<'a, Slice = ZeroSlice<V>> + AsULE + Copy + 'static,
{
pub fn get_copied(self, key: &K) -> Option<V> {
let index = self.keys.zvl_binary_search(key).ok()?;
self.values.get(index)
}
pub fn get_copied_by(self, predicate: impl FnMut(&K) -> Ordering) -> Option<V> {
let index = self.keys.zvl_binary_search_by(predicate).ok()?;
self.values.get(index)
}
pub fn iter_copied_values(
self,
) -> impl Iterator<Item = (&'a <K as ZeroMapKV<'a>>::GetType, V)> {
(0..self.keys.zvl_len()).map(move |idx| {
(
#[expect(clippy::unwrap_used)] self.keys.zvl_get(idx).unwrap(),
#[expect(clippy::unwrap_used)] self.values.get(idx).unwrap(),
)
})
}
}
impl<'a, K, V> ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a, Slice = ZeroSlice<K>> + AsULE + Copy + Ord + 'static,
V: ZeroMapKV<'a, Slice = ZeroSlice<V>> + AsULE + Copy + 'static,
{
pub fn iter_copied(self) -> impl Iterator<Item = (K, V)> + 'a {
let len = self.keys.zvl_len();
(0..len).map(move |idx| {
(
#[expect(clippy::unwrap_used)] ZeroSlice::get(self.keys, idx).unwrap(),
#[expect(clippy::unwrap_used)] ZeroSlice::get(self.values, idx).unwrap(),
)
})
}
}
impl<'a, 'b, K, V> PartialEq<ZeroMapBorrowed<'b, K, V>> for ZeroMapBorrowed<'a, K, V>
where
K: for<'c> ZeroMapKV<'c> + ?Sized,
V: for<'c> ZeroMapKV<'c> + ?Sized,
<K as ZeroMapKV<'a>>::Slice: PartialEq<<K as ZeroMapKV<'b>>::Slice>,
<V as ZeroMapKV<'a>>::Slice: PartialEq<<V as ZeroMapKV<'b>>::Slice>,
{
fn eq(&self, other: &ZeroMapBorrowed<'b, K, V>) -> bool {
self.keys.eq(other.keys) && self.values.eq(other.values)
}
}
impl<'a, K, V> fmt::Debug for ZeroMapBorrowed<'a, K, V>
where
K: ZeroMapKV<'a> + ?Sized,
V: ZeroMapKV<'a> + ?Sized,
K::Slice: fmt::Debug,
V::Slice: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.debug_struct("ZeroMapBorrowed")
.field("keys", &self.keys)
.field("values", &self.values)
.finish()
}
}