#![warn(missing_docs)]
#![expect(clippy::cast_ptr_alignment)]
#![cfg_attr(not(feature = "std"), no_std)]
#[macro_use]
extern crate alloc;
use alloc::borrow::ToOwned;
use alloc::string::String;
use alloc::vec::Vec;
use core::cmp::Ordering;
pub use map::{GenericPatriciaMap, PatriciaMap, StringPatriciaMap};
pub use set::{GenericPatriciaSet, PatriciaSet, StringPatriciaSet};
pub mod map;
pub mod set;
mod node;
#[cfg(feature = "serde")]
mod serialization;
mod tree;
pub trait Bytes {
type Borrowed: ?Sized + BorrowedBytes + ToOwned<Owned = Self>;
}
impl Bytes for Vec<u8> {
type Borrowed = [u8];
}
impl Bytes for String {
type Borrowed = str;
}
pub trait BorrowedBytes {
fn as_bytes(&self) -> &[u8];
fn is_valid_bytes(bytes: &[u8]) -> bool;
fn from_bytes(bytes: &[u8]) -> &Self;
fn strip_common_prefix(&self, bytes: &[u8]) -> &Self;
fn strip_common_prefix_and_len(&self, bytes: &[u8]) -> (&Self, usize) {
let next = self.strip_common_prefix(bytes);
let common_prefix_len = self.as_bytes().len() - next.as_bytes().len();
(next, common_prefix_len)
}
fn cmp_first_item(&self, bytes: &[u8]) -> Ordering;
fn is_empty(&self) -> bool {
self.as_bytes().is_empty()
}
fn strip_n_prefix(&self, n: usize) -> &Self;
}
impl BorrowedBytes for [u8] {
fn as_bytes(&self) -> &[u8] {
self
}
fn is_valid_bytes(_bytes: &[u8]) -> bool {
true
}
fn from_bytes(bytes: &[u8]) -> &Self {
bytes
}
fn strip_common_prefix(&self, bytes: &[u8]) -> &Self {
let i = self
.iter()
.zip(bytes.iter())
.take_while(|(a, b)| a == b)
.count();
&self[i..]
}
fn cmp_first_item(&self, bytes: &[u8]) -> Ordering {
self.first().cmp(&bytes.first())
}
fn strip_n_prefix(&self, n: usize) -> &Self {
&self[n..]
}
}
impl BorrowedBytes for str {
fn as_bytes(&self) -> &[u8] {
self.as_bytes()
}
fn is_valid_bytes(bytes: &[u8]) -> bool {
core::str::from_utf8(bytes).is_ok()
}
fn from_bytes(bytes: &[u8]) -> &Self {
core::str::from_utf8(bytes).expect("unreachable")
}
fn strip_common_prefix(&self, bytes: &[u8]) -> &Self {
for (i, c) in self.char_indices() {
let n = c.len_utf8();
if self.as_bytes()[i..i + n]
.iter()
.ne(bytes[i..].iter().take(n))
{
return &self[i..];
}
}
""
}
fn cmp_first_item(&self, bytes: &[u8]) -> Ordering {
self.chars()
.next()
.cmp(&Self::from_bytes(bytes).chars().next())
}
fn strip_n_prefix(&self, n: usize) -> &Self {
&self[n..]
}
}