#![no_std]
use core::{
fmt::{self, Debug},
iter::Enumerate,
marker::PhantomData,
ops::{Index, IndexMut},
slice,
};
extern crate alloc;
use alloc::vec::{self, Vec};
use serde::{
de::{MapAccess, Visitor},
ser::SerializeMap,
Deserialize, Serialize,
};
#[derive(Clone)]
pub struct Registry<T> {
data: Vec<Option<T>>,
indices: Vec<usize>,
}
impl<T> Default for Registry<T> {
fn default() -> Self {
Self {
data: Vec::new(),
indices: Vec::new(),
}
}
}
impl<T> Registry<T> {
#[inline]
#[must_use]
pub const fn new() -> Self {
Self {
data: Vec::new(),
indices: Vec::new(),
}
}
#[inline]
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
data: Vec::with_capacity(capacity),
indices: Vec::new(),
}
}
#[inline]
#[must_use]
pub fn capacity(&self) -> usize {
self.data.capacity()
}
#[must_use]
pub fn insert(&mut self, item: T) -> usize {
if let Some(index) = self.indices.pop() {
self.data[index] = Some(item);
index
} else {
self.data.push(Some(item));
self.data.len() - 1
}
}
pub fn remove(&mut self, index: usize) -> Option<T> {
if let Some(value) = self.data.get_mut(index) {
self.indices.push(index);
value.take()
} else {
None
}
}
pub fn retain<F: FnMut(&T) -> bool>(&mut self, mut f: F) {
for (i, v) in self.data.iter_mut().enumerate() {
if !v.as_ref().map(&mut f).unwrap_or(false) {
*v = None;
self.indices.push(i);
}
}
}
pub fn retain_mut<F: FnMut(&T) -> bool>(&mut self, mut f: F) {
for (i, v) in self.data.iter_mut().enumerate() {
if !v.as_mut().map(|x| f(x)).unwrap_or(false) {
*v = None;
self.indices.push(i);
}
}
}
pub fn clear(&mut self) {
self.data.clear();
self.indices.clear();
}
#[must_use]
pub fn len(&self) -> usize {
self.data.len() - self.indices.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[must_use]
pub fn get(&self, index: usize) -> Option<&T> {
self.data.get(index).and_then(Option::as_ref)
}
#[must_use]
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
self.data.get_mut(index).and_then(Option::as_mut)
}
pub fn swap(&mut self, a: usize, b: usize) {
let x_a = self
.data
.get_mut(a)
.expect("index a is not in the registry")
.take()
.expect("index a is not in the registry");
let x_b = self
.data
.get_mut(b)
.expect("index b is not in the registry")
.take()
.expect("index b is not in the registry");
self.data[a] = Some(x_b);
self.data[b] = Some(x_a);
}
#[must_use]
pub fn contains_value(&self, x: &T) -> bool
where
T: PartialEq,
{
self.data
.iter()
.any(|opt| opt.as_ref().is_some_and(|v| *v == *x))
}
#[must_use]
pub fn contains_index(&self, index: usize) -> bool {
self.data.get(index).is_some()
}
#[must_use]
pub fn iter(&self) -> Iter<'_, T> {
self.into_iter()
}
#[must_use]
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
self.into_iter()
}
#[must_use]
pub fn into_values(self) -> IntoValues<T> {
IntoValues {
data_iter: self.data.into_iter(),
free_indices: self.indices.len(),
}
}
#[must_use]
pub fn values(&self) -> Values<'_, T> {
Values {
data_iter: self.data.iter(),
free_indices: self.indices.len(),
}
}
#[must_use]
pub fn values_mut(&mut self) -> ValuesMut<'_, T> {
ValuesMut {
data_iter: self.data.iter_mut(),
free_indices: self.indices.len(),
}
}
#[must_use]
pub fn keys(&self) -> Keys<'_, T> {
Keys {
data_iter: self.data.iter().enumerate(),
free_indices: self.indices.len(),
}
}
}
impl<T> Debug for Registry<T>
where
T: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<T, const N: usize> From<[T; N]> for Registry<T> {
fn from(value: [T; N]) -> Self {
Self {
data: value.into_iter().map(Some).collect(),
indices: Vec::new(),
}
}
}
impl<T> FromIterator<T> for Registry<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self {
data: iter.into_iter().map(Some).collect(),
indices: Vec::new(),
}
}
}
impl<T> Index<usize> for Registry<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
self.get(index).expect("no entry found for index")
}
}
impl<T> IndexMut<usize> for Registry<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
self.get_mut(index).expect("no entry found for index")
}
}
impl<'a, T> IntoIterator for &'a Registry<T> {
type Item = (usize, &'a T);
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
Self::IntoIter {
data_iter: self.data.iter().enumerate(),
free_indices: self.indices.len(),
}
}
}
impl<'a, T> IntoIterator for &'a mut Registry<T> {
type Item = (usize, &'a mut T);
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
Self::IntoIter {
data_iter: self.data.iter_mut().enumerate(),
free_indices: self.indices.len(),
}
}
}
impl<T> IntoIterator for Registry<T> {
type Item = (usize, T);
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
Self::IntoIter {
data_iter: self.data.into_iter().enumerate(),
free_indices: self.indices.len(),
}
}
}
impl<T: Serialize> Serialize for Registry<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut map = serializer.serialize_map(Some(self.len()))?;
for (i, v) in self {
map.serialize_entry(&i, v)?;
}
map.end()
}
}
struct RegistryVisitor<T>(PhantomData<T>);
impl<T> Default for RegistryVisitor<T> {
fn default() -> Self {
Self(PhantomData)
}
}
impl<'de, T: Deserialize<'de>> Visitor<'de> for RegistryVisitor<T> {
type Value = Registry<T>;
fn expecting(&self, formatter: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
formatter.write_str("a uint-indexed map")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut reg = Registry::with_capacity(map.size_hint().unwrap_or(0));
while let Some((i, entry)) = map.next_entry()? {
for j in reg.data.len()..i {
reg.data.push(None);
reg.indices.push(j);
}
reg.data.push(Some(entry));
}
Ok(reg)
}
}
impl<'de, T: Deserialize<'de>> Deserialize<'de> for Registry<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_map(RegistryVisitor::default())
}
}
#[derive(Debug)]
pub struct IntoIter<T> {
data_iter: Enumerate<vec::IntoIter<Option<T>>>,
free_indices: usize,
}
impl<T> Iterator for IntoIter<T> {
type Item = (usize, T);
fn next(&mut self) -> Option<Self::Item> {
loop {
if let (index, Some(item)) = self.data_iter.next()? {
return Some((index, item));
}
self.free_indices -= 1;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
fn count(self) -> usize
where
Self: Sized,
{
self.len()
}
}
impl<T> ExactSizeIterator for IntoIter<T> {
fn len(&self) -> usize {
self.data_iter.len() - self.free_indices
}
}
impl<T> DoubleEndedIterator for IntoIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
if let (index, Some(item)) = self.data_iter.next_back()? {
return Some((index, item));
}
self.free_indices -= 1;
}
}
}
#[derive(Debug)]
pub struct Iter<'a, T> {
data_iter: Enumerate<slice::Iter<'a, Option<T>>>,
free_indices: usize,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = (usize, &'a T);
fn next(&mut self) -> Option<Self::Item> {
loop {
if let (index, Some(item)) = self.data_iter.next()? {
return Some((index, item));
}
self.free_indices -= 1;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
fn count(self) -> usize
where
Self: Sized,
{
self.len()
}
}
impl<'a, T> ExactSizeIterator for Iter<'a, T> {
fn len(&self) -> usize {
self.data_iter.len() - self.free_indices
}
}
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
if let (index, Some(item)) = self.data_iter.next_back()? {
return Some((index, item));
}
self.free_indices -= 1;
}
}
}
#[derive(Debug)]
pub struct IterMut<'a, T> {
data_iter: Enumerate<slice::IterMut<'a, Option<T>>>,
free_indices: usize,
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = (usize, &'a mut T);
fn next(&mut self) -> Option<Self::Item> {
loop {
if let (index, Some(item)) = self.data_iter.next()? {
return Some((index, item));
}
self.free_indices -= 1;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
fn count(self) -> usize
where
Self: Sized,
{
self.len()
}
}
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
fn len(&self) -> usize {
self.data_iter.len() - self.free_indices
}
}
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
if let (index, Some(item)) = self.data_iter.next_back()? {
return Some((index, item));
}
self.free_indices -= 1;
}
}
}
#[derive(Debug)]
pub struct IntoValues<T> {
data_iter: vec::IntoIter<Option<T>>,
free_indices: usize,
}
impl<T> Iterator for IntoValues<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(item) = self.data_iter.next()? {
return Some(item);
}
self.free_indices -= 1;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
fn count(self) -> usize
where
Self: Sized,
{
self.len()
}
}
impl<T> ExactSizeIterator for IntoValues<T> {
fn len(&self) -> usize {
self.data_iter.len() - self.free_indices
}
}
impl<T> DoubleEndedIterator for IntoValues<T> {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
if let Some(item) = self.data_iter.next_back()? {
return Some(item);
}
self.free_indices -= 1;
}
}
}
#[derive(Debug)]
pub struct Values<'a, T> {
data_iter: slice::Iter<'a, Option<T>>,
free_indices: usize,
}
impl<'a, T> Iterator for Values<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(item) = self.data_iter.next()? {
return Some(item);
}
self.free_indices -= 1;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
fn count(self) -> usize
where
Self: Sized,
{
self.len()
}
}
impl<'a, T> ExactSizeIterator for Values<'a, T> {
fn len(&self) -> usize {
self.data_iter.len() - self.free_indices
}
}
impl<'a, T> DoubleEndedIterator for Values<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
if let Some(item) = self.data_iter.next_back()? {
return Some(item);
}
self.free_indices -= 1;
}
}
}
#[derive(Debug)]
pub struct ValuesMut<'a, T> {
data_iter: slice::IterMut<'a, Option<T>>,
free_indices: usize,
}
impl<'a, T> Iterator for ValuesMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(item) = self.data_iter.next()? {
return Some(item);
}
self.free_indices -= 1;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
fn count(self) -> usize
where
Self: Sized,
{
self.len()
}
}
impl<'a, T> ExactSizeIterator for ValuesMut<'a, T> {
fn len(&self) -> usize {
self.data_iter.len() - self.free_indices
}
}
impl<'a, T> DoubleEndedIterator for ValuesMut<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
if let Some(item) = self.data_iter.next_back()? {
return Some(item);
}
self.free_indices -= 1;
}
}
}
#[derive(Debug)]
pub struct Keys<'a, T> {
data_iter: Enumerate<slice::Iter<'a, Option<T>>>,
free_indices: usize,
}
impl<'a, T> Iterator for Keys<'a, T> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let (i, Some(_)) = self.data_iter.next()? {
return Some(i);
}
self.free_indices -= 1;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
fn count(self) -> usize
where
Self: Sized,
{
self.len()
}
}
impl<'a, T> ExactSizeIterator for Keys<'a, T> {
fn len(&self) -> usize {
self.data_iter.len() - self.free_indices
}
}
impl<'a, T> DoubleEndedIterator for Keys<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
if let (i, Some(_)) = self.data_iter.next_back()? {
return Some(i);
}
self.free_indices -= 1;
}
}
}