use super::*;
use crate::prelude::*;
use core::fmt;
use core::ops::DerefMut;
impl<U: Unsigned, T: Volume<U = U>> Octree<U, T> {
#[inline]
pub fn entry(&mut self, key: TUVec3<U>) -> Entry<'_, U, T> {
match self.find(&key) {
Some(value) => Entry::Occupied(OccupiedEntry {
base: self,
element: value,
key,
}),
None => Entry::Vacant(VacantEntry { base: self, key }),
}
}
}
pub enum Entry<'a, U: Unsigned, T: Volume<U = U>> {
Occupied(OccupiedEntry<'a, U, T>),
Vacant(VacantEntry<'a, U, T>),
}
impl<U: Unsigned, T: Volume<U = U>> fmt::Debug for Entry<'_, U, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Self::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
Self::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
}
}
}
impl<'a, U: Unsigned, T: Volume<U = U>> Entry<'a, U, T> {
#[inline]
pub fn or_insert(self, default: T) -> OccupiedEntry<'a, U, T> {
match self {
Self::Occupied(entry) => entry,
Self::Vacant(entry) => entry.insert(default),
}
}
#[inline]
pub fn or_try_insert(self, default: T) -> Result<OccupiedEntry<'a, U, T>, TreeError> {
match self {
Self::Occupied(entry) => Ok(entry),
Self::Vacant(entry) => entry.try_insert(default),
}
}
#[inline]
pub fn or_insert_with<F: FnOnce() -> T>(self, default: F) -> OccupiedEntry<'a, U, T> {
match self {
Self::Occupied(entry) => entry,
Self::Vacant(entry) => entry.insert(default()),
}
}
#[inline]
pub fn or_try_insert_with<F: FnOnce() -> T>(
self,
default: F,
) -> Result<OccupiedEntry<'a, U, T>, TreeError> {
match self {
Self::Occupied(entry) => Ok(entry),
Self::Vacant(entry) => entry.try_insert(default()),
}
}
#[inline]
pub fn or_insert_with_key<F: FnOnce(&TUVec3<U>) -> T>(
self,
default: F,
) -> OccupiedEntry<'a, U, T> {
match self {
Self::Occupied(entry) => entry,
Self::Vacant(entry) => {
let value = default(entry.key());
entry.insert(value)
}
}
}
#[inline]
pub fn or_try_insert_with_key<F: FnOnce(&TUVec3<U>) -> T>(
self,
default: F,
) -> Result<OccupiedEntry<'a, U, T>, TreeError> {
match self {
Self::Occupied(entry) => Ok(entry),
Self::Vacant(entry) => {
let value = default(entry.key());
entry.try_insert(value)
}
}
}
#[inline]
pub fn key(&self) -> &TUVec3<U> {
match *self {
Self::Occupied(ref entry) => entry.key(),
Self::Vacant(ref entry) => entry.key(),
}
}
#[inline]
pub fn and<F>(self, f: F) -> Self
where
F: FnOnce(&T),
{
match self {
Self::Occupied(entry) => {
f(entry.get());
Self::Occupied(entry)
}
Self::Vacant(entry) => Self::Vacant(entry),
}
}
#[inline]
pub fn and_modify<F>(self, f: F) -> Self
where
F: FnOnce(&mut T),
{
match self {
Self::Occupied(mut entry) => {
f(entry.get_mut());
Self::Occupied(entry)
}
Self::Vacant(entry) => Self::Vacant(entry),
}
}
}
pub struct OccupiedEntry<'a, U: Unsigned, T: Volume<U = U>> {
base: &'a mut Octree<U, T>,
key: TUVec3<U>,
element: ElementId,
}
impl<U: Unsigned, T: Volume<U = U>> fmt::Debug for OccupiedEntry<'_, U, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedEntry")
.field("key", &self.key)
.field("element", &self.element)
.finish_non_exhaustive()
}
}
impl<'a, U: Unsigned, T: Volume<U = U>> OccupiedEntry<'a, U, T> {
#[inline]
pub fn key(&self) -> &TUVec3<U> {
&self.key
}
#[inline]
pub fn element(&self) -> ElementId {
self.element
}
#[inline]
pub fn get(&self) -> &T {
self.base.get_element(self.element).unwrap()
}
#[inline]
pub fn get_mut(&mut self) -> &mut T {
self.base.get_element_mut(self.element).unwrap()
}
#[inline]
pub fn into_ref(self) -> &'a T {
self.base.get_element(self.element).unwrap()
}
#[inline]
pub fn into_mut(self) -> &'a mut T {
self.base.get_element_mut(self.element).unwrap()
}
#[inline]
pub fn insert(&'a mut self, value: T) -> &'a mut T {
let ret = self.base.get_element_mut(self.element).unwrap();
*ret = value;
ret
}
}
impl<U: Unsigned, T: Volume<U = U>> Deref for OccupiedEntry<'_, U, T> {
type Target = T;
fn deref(&self) -> &T {
self.get()
}
}
impl<U: Unsigned, T: Volume<U = U>> DerefMut for OccupiedEntry<'_, U, T> {
fn deref_mut(&mut self) -> &mut T {
self.get_mut()
}
}
pub struct VacantEntry<'a, U: Unsigned, T: Volume<U = U>> {
base: &'a mut Octree<U, T>,
key: TUVec3<U>,
}
impl<U: Unsigned, T: Volume<U = U>> fmt::Debug for VacantEntry<'_, U, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("VacantEntry")
.field("key", &self.key)
.finish_non_exhaustive()
}
}
impl<'a, U: Unsigned, T: Volume<U = U>> VacantEntry<'a, U, T> {
#[inline]
pub fn key(&self) -> &TUVec3<U> {
&self.key
}
#[inline]
pub fn into_key(self) -> TUVec3<U> {
self.key
}
#[inline]
pub fn insert(self, value: T) -> OccupiedEntry<'a, U, T> {
let element = self.base.insert(value).unwrap();
OccupiedEntry {
base: self.base,
key: self.key,
element,
}
}
#[inline]
pub fn try_insert(self, value: T) -> Result<OccupiedEntry<'a, U, T>, TreeError> {
let element = self.base.insert(value)?;
Ok(OccupiedEntry {
base: self.base,
key: self.key,
element,
})
}
}