use super::NamedEntity;
use std::sync::{Arc, Weak};
#[derive(Clone, Default)]
pub struct Implicits<T>(Arc<T>);
pub type ImplicitVec = Implicits<Vec<Weak<NamedEntity>>>;
pub type ImplicitVecBuilder = ImplicitsBuilder<Vec<Weak<NamedEntity>>>;
impl<T: Default> Implicits<T> {
pub fn build() -> ImplicitsBuilder<T> {
ImplicitsBuilder(Default::default())
}
}
impl<T> std::ops::Deref for Implicits<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl ImplicitVec {
pub fn iter(&self) -> impl Iterator<Item = Arc<NamedEntity>> + '_ {
self.0.iter().filter_map(|weak_ent| weak_ent.upgrade())
}
pub unsafe fn push(&self, ent: &Arc<NamedEntity>) {
raw_mut(&self.0).push(Arc::downgrade(ent));
}
}
#[derive(Default)]
pub struct ImplicitsBuilder<T>(Arc<T>);
impl<T> ImplicitsBuilder<T> {
pub fn inner(&self) -> Implicits<T> {
Implicits(self.0.clone())
}
}
impl ImplicitVecBuilder {
pub fn push(&self, ent: &Arc<NamedEntity>) {
unsafe {
raw_mut(&self.0).push(Arc::downgrade(ent));
}
}
}
#[allow(clippy::mut_from_ref)]
unsafe fn raw_mut<T>(arc: &Arc<T>) -> &mut T {
let ptr = arc.as_ref() as *const T as *mut T;
&mut *ptr
}