use std::ops::DerefMut;
use regex_pool::util::pool::{Pool, PoolGuard};
type CachePoolFn<T> = Box<dyn Fn() -> T + Send + Sync>;
pub type SharedPoolGuard<'a, T, const MAX_POOL_STACKS: usize> =
PoolGuard<'a, T, CachePoolFn<T>, MAX_POOL_STACKS>;
pub struct SharedPool<T> {
pool: Box<dyn AutoStacksSizePool<T>>,
}
pub trait AutoStacksSizePool<T>: Sync + Send {
fn get(&self) -> Box<dyn AutoStacksSizeGuard<T> + '_>;
}
pub trait AutoStacksSizeGuard<T> {
fn get_ref(&mut self) -> &mut T;
}
impl<T: Send, const MAX_POOL_STACKS: usize> AutoStacksSizeGuard<T>
for PoolGuard<'_, T, CachePoolFn<T>, MAX_POOL_STACKS>
{
fn get_ref(&mut self) -> &mut T {
self.deref_mut()
}
}
impl<T: Send, const MAX_POOL_STACKS: usize> AutoStacksSizePool<T>
for Pool<T, CachePoolFn<T>, MAX_POOL_STACKS>
{
fn get(&self) -> Box<dyn AutoStacksSizeGuard<T> + '_> {
Box::new(Pool::get(self))
}
}
impl<T: Send + 'static> SharedPool<T> {
pub fn new(factory: CachePoolFn<T>, count: usize) -> Self {
let pool = if count <= 4 {
Box::new(Pool::<_, _, 4>::new(factory)) as Box<dyn AutoStacksSizePool<T>>
} else if count <= 8 {
Box::new(Pool::<_, _, 8>::new(factory)) as Box<dyn AutoStacksSizePool<T>>
} else if count <= 16 {
Box::new(Pool::<_, _, 16>::new(factory)) as Box<dyn AutoStacksSizePool<T>>
} else if count <= 32 {
Box::new(Pool::<_, _, 32>::new(factory)) as Box<dyn AutoStacksSizePool<T>>
} else {
Box::new(Pool::<_, _, 64>::new(factory)) as Box<dyn AutoStacksSizePool<T>>
};
Self { pool }
}
pub fn get(&self) -> Box<dyn AutoStacksSizeGuard<T> + '_> {
self.pool.get()
}
}