use crate::{
pool::{Pool, PoolInner},
reset::Reset,
};
use alloc::sync::{Arc, Weak};
use core::{
borrow::{Borrow, BorrowMut},
cmp::Ordering,
fmt::{self, Debug, Display},
hash::{Hash, Hasher},
ops::{Deref, DerefMut},
};
pub struct Pooled<T: Default + Reset> {
pool_inner: Weak<PoolInner<T>>,
object: Option<T>,
}
impl<T: Default + Reset> Pooled<T> {
pub(super) fn new(object: T, pool: &Pool<T>) -> Self {
Self {
object: Some(object),
pool_inner: Arc::downgrade(&pool.inner),
}
}
pub fn detach(mut this: Self) -> T {
this.object.take().expect("always some")
}
pub fn get_pool(this: &Self) -> Option<Pool<T>> {
this.pool_inner.upgrade().map(|inner| Pool { inner })
}
}
impl<T: Default + Reset> Drop for Pooled<T> {
fn drop(&mut self) {
if let Some(pool_inner) = self.pool_inner.upgrade() {
if let Some(mut object) = self.object.take() {
object.reset();
let _ = pool_inner.push(object);
}
}
}
}
impl<T: Default + Reset> Deref for Pooled<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.object.as_ref().expect("always some")
}
}
impl<T: Default + Reset> DerefMut for Pooled<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.object.as_mut().expect("always some")
}
}
impl<T: Default + Reset> AsRef<T> for Pooled<T> {
fn as_ref(&self) -> &T {
self
}
}
impl<T: Default + Reset> AsMut<T> for Pooled<T> {
fn as_mut(&mut self) -> &mut T {
self
}
}
impl<T: Default + Reset> Borrow<T> for Pooled<T> {
fn borrow(&self) -> &T {
self
}
}
impl<T: Default + Reset> BorrowMut<T> for Pooled<T> {
fn borrow_mut(&mut self) -> &mut T {
self
}
}
impl<T: Default + Reset> Hash for Pooled<T>
where
T: Hash,
{
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}
impl<T: Default + Reset> PartialEq for Pooled<T>
where
T: PartialEq<T>,
{
fn eq(&self, other: &Self) -> bool {
(**self).eq(other)
}
}
impl<T: Default + Reset> PartialEq<T> for Pooled<T>
where
T: PartialEq<T>,
{
fn eq(&self, other: &T) -> bool {
(**self).eq(other)
}
}
impl<T: Default + Reset> Eq for Pooled<T> where T: Eq {}
impl<T: Default + Reset> PartialOrd for Pooled<T>
where
T: PartialOrd<T>,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(**self).partial_cmp(other)
}
}
impl<T: Default + Reset> Ord for Pooled<T>
where
T: Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
(**self).cmp(other)
}
}
impl<T: Default + Reset + PartialOrd<T>> PartialOrd<T> for Pooled<T> {
fn partial_cmp(&self, other: &T) -> Option<Ordering> {
(**self).partial_cmp(other)
}
}
impl<T: Default + Reset> Debug for Pooled<T>
where
T: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: Default + Reset> Display for Pooled<T>
where
T: Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(**self).fmt(f)
}
}