#[cfg(any(test, feature = "std"))]
extern crate std;
extern crate alloc;
use alloc::{borrow::ToOwned, vec::Vec};
use core::{borrow::Borrow, fmt, ops::Deref};
mod iter;
pub use iter::{Drain, IntoIter, Iter};
use crate::shared::{PrefixBorrowed, PrefixOwned, ScratchSpace};
#[derive(PartialEq, Eq)]
pub struct PrefixArraySet<K: Borrow<str>>(pub(crate) Vec<K>);
impl<K: Borrow<str> + fmt::Debug> fmt::Debug for PrefixArraySet<K> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "PrefixArraySet")?;
f.debug_set().entries(self.iter()).finish()
}
}
impl<K: Borrow<str> + Clone> Clone for PrefixArraySet<K> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
fn clone_from(&mut self, other: &Self) {
self.0.clone_from(&other.0);
}
}
impl<K: Borrow<str>> Default for PrefixArraySet<K> {
fn default() -> Self {
PrefixArraySet::new()
}
}
impl<K: Borrow<str>> PrefixArraySet<K> {
#[must_use]
pub const fn new() -> Self {
Self(Vec::new())
}
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self(Vec::with_capacity(capacity))
}
pub fn reserve(&mut self, additional: usize) {
self.0.reserve(additional);
}
pub fn reserve_exact(&mut self, additional: usize) {
self.0.reserve_exact(additional);
}
#[must_use]
pub fn from_vec_lossy(v: Vec<K>) -> Self {
Self::from_vec_lossy_impl(v)
}
pub fn insert(&mut self, key: K) -> bool {
self.insert_impl(key).is_none()
}
pub fn replace(&mut self, key: K) -> Option<K> {
self.insert_replace_impl(key)
}
pub fn drain_all_with_prefix<'a>(&'a mut self, prefix: &str) -> Drain<'a, K> {
let range = self.find_all_with_prefix_idx_impl(prefix);
Drain(self.0.drain(range))
}
pub fn drain(&mut self) -> Drain<'_, K> {
Drain(self.0.drain(..))
}
pub fn remove(&mut self, key: &str) -> bool {
self.remove_entry_impl(key).is_some()
}
#[must_use]
pub fn capacity(&self) -> usize {
self.0.capacity()
}
pub fn clear(&mut self) {
self.0.clear();
}
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit();
}
pub fn shrink_to(&mut self, min_capacity: usize) {
self.0.shrink_to(min_capacity);
}
pub fn extend_with<I>(&mut self, scratch: &mut ScratchSpace<Self>, iter: I)
where
I: IntoIterator<Item = K>,
{
self.extend_with_impl(&mut scratch.0, iter);
}
fn from_unique_iter<T: IntoIterator<Item = K>>(v: T) -> Self {
Self::from_unique_iter_impl(v)
}
}
impl<K: Borrow<str>> Extend<K> for PrefixArraySet<K> {
fn extend<T>(&mut self, iter: T)
where
T: IntoIterator<Item = K>,
{
self.extend_with(&mut ScratchSpace::new(), iter);
}
}
#[cfg(feature = "std")]
impl<K: Borrow<str>, H> From<std::collections::HashSet<K, H>> for PrefixArraySet<K> {
fn from(v: std::collections::HashSet<K, H>) -> Self {
Self::from_unique_iter(v)
}
}
impl<K: Borrow<str>> From<alloc::collections::BTreeSet<K>> for PrefixArraySet<K> {
fn from(v: alloc::collections::BTreeSet<K>) -> Self {
Self::from_unique_iter(v)
}
}
impl<K: Borrow<str>> From<PrefixArraySet<K>> for Vec<K> {
fn from(v: PrefixArraySet<K>) -> Vec<K> {
v.0
}
}
impl<K: Borrow<str>> Deref for PrefixArraySet<K> {
type Target = SetSubSlice<K>;
fn deref(&self) -> &Self::Target {
SetSubSlice::cast_from_slice_core(&self.0)
}
}
impl<K: Borrow<str>> core::borrow::Borrow<SetSubSlice<K>> for PrefixArraySet<K> {
fn borrow(&self) -> &SetSubSlice<K> {
self
}
}
impl<K: Borrow<str> + Clone> ToOwned for SetSubSlice<K> {
type Owned = PrefixArraySet<K>;
fn to_owned(&self) -> PrefixArraySet<K> {
PrefixArraySet(self.to_vec())
}
fn clone_into(&self, target: &mut PrefixArraySet<K>) {
self.0.clone_into(&mut target.0);
}
}
impl<K: Borrow<str> + fmt::Debug> fmt::Debug for SetSubSlice<K> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "SetSubSlice")?;
f.debug_set().entries(self.iter()).finish()
}
}
#[repr(transparent)]
#[derive(PartialEq, Eq)]
pub struct SetSubSlice<K: Borrow<str>>(pub(crate) [K]);
impl<K: Borrow<str>> SetSubSlice<K> {
pub(crate) fn cast_from_slice_core(v: &[K]) -> &Self {
unsafe { &*(v as *const [K] as *const Self) }
}
pub(crate) fn cast_from_slice_mut_core(v: &mut [K]) -> &mut Self {
unsafe { &mut *(v as *mut [K] as *mut Self) }
}
pub fn iter(&self) -> Iter<'_, K> {
Iter(self.0.iter())
}
pub fn to_vec(&self) -> Vec<K>
where
K: Clone,
{
self.0.to_vec()
}
pub fn find_all_with_prefix<'a>(&'a self, prefix: &str) -> &'a Self {
let range = self.find_all_with_prefix_idx_impl(prefix);
self.reslice(range)
}
pub fn common_prefix(&self) -> &str {
self.common_prefix_impl()
}
pub fn contains(&self, key: &str) -> bool {
self.contains_key_impl(key)
}
pub const fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub const fn len(&self) -> usize {
self.0.len()
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec;
#[test]
fn replace_replaces() {
#[derive(Debug)]
struct TrackerStr<'a>(&'a str, u64);
impl core::borrow::Borrow<str> for TrackerStr<'_> {
fn borrow(&self) -> &str {
self.0
}
}
let mut parray = PrefixArraySet::from_iter([TrackerStr("abc", 0)]);
assert!(matches!(
parray.replace(TrackerStr("abc", 1)),
Some(TrackerStr("abc", 0))
));
assert!(parray.contains("abc"));
}
#[test]
fn submatches() {
let parray = PrefixArraySet::from_vec_lossy(vec![
"abcde", "234234", "among", "we", "weed", "who", "what", "why", "abde", "abch",
"america",
]);
assert_eq!(
&["abcde", "abch", "abde"],
&*parray.find_all_with_prefix("ab").to_vec()
);
assert_eq!("ab", parray.find_all_with_prefix("ab").common_prefix());
let mut parraysingle = PrefixArraySet::from_vec_lossy(vec!["abcde"]);
assert_eq!("abcde", parraysingle.to_vec()[0]);
assert_eq!(
&["abcde"],
&*parraysingle.find_all_with_prefix("a").to_vec()
);
assert!(parraysingle.find_all_with_prefix("b").is_empty());
_ = parraysingle.drain_all_with_prefix("a");
assert!(parraysingle.is_empty());
}
#[test]
fn is_eq() {
let arr1 = PrefixArraySet::from_iter(["abcde", "among"]);
let arr2 = PrefixArraySet::from_iter(["abcde", "among"]);
assert_eq!(arr1, arr2);
let arr3 = PrefixArraySet::new();
assert_ne!(&*arr3, &*arr2);
}
}