-
Notifications
You must be signed in to change notification settings - Fork 24
Closed
Description
We don't suppose it'd be possible to have something along these lines?
struct IntrusiveQCellOwner<T: ?Sized> {
inner: Arc<QCell<T>>,
}
// impl<T: ?Sized> !Clone for IntrusiveQCellOwner<T>;
impl<T> IntrusiveQCellOwner {
fn new(value: T) -> Self {
Arc::new_cyclic(|arc| {
QCell { owner: QCellOwnerID(arc.as_ptr() as *const () as usize), value: UnsafeCell::new(value) }
})
}
}
}
impl<T: ?Sized> IntrusiveQCellOwner {
fn id(&self) -> QCellOwnerID {
self.inner.owner
}
// the usual stuff, rw etc.
fn clone_inner(&self) -> Arc<QCell<T>> {
self.inner.clone()
}
// in fact, might aswell just use Deref and DerefMut for these.
//fn mut_inner(&mut self) -> &mut T {
// ...
//}
//fn get_inner(&self) -> &T {
// ...
//}
}The main use-case would be the same as #16 except without a separate "owner".
pub struct ConfigManager {
resources: Vec<Resource>,
}
pub struct AddConfigSource<'a, T: DataSourceBase + Send + Sync + 'static> {
resource: &'a mut Resource,
source: Arc<QCell<T>>,
}
struct Resource {
// actual resource
base: IntrusiveQCellOwner<dyn DataSourceBase + Send + Sync>,
// views of the actual resource
title: Option<Arc<QCell<dyn DataSource<InstanceTitle> + Send + Sync>>>,
url: Option<Arc<QCell<dyn DataSource<InstanceBaseUrl> + Send + Sync>>>,
repolist: Option<Arc<QCell<dyn DataSource<RepoListUrl> + Send + Sync>>>,
}
impl ConfigManager {
pub fn add_source<T>(&mut self, source: T) -> AddConfigSource<'_, T>
where
T: DataSourceBase + Send + Sync + 'static,
{
let base = IntrusiveQCellOwner::new(source);
let arc = base.clone_inner();
self.resources.push(Resource::new(base));
AddConfigSource {
resource: self.resources.last_mut().unwrap(),
source: arc,
}
}
}
impl<'a, T: DataSourceBase + Send + Sync + 'static> AddConfigSource<'a, T> {
pub fn for_title(self) -> Self where T: DataSource<InstanceTitle> {
let arc = &self.source;
self.resource.title.get_or_insert_with(|| {
arc.clone()
});
self
}
pub fn for_base_url(self) -> Self where T: DataSource<InstanceBaseUrl> {
let arc = &self.source;
self.resource.url.get_or_insert_with(|| {
arc.clone()
});
self
}
pub fn for_repo_lists(self) -> Self where T: DataSource<RepoListUrl> {
let arc = &self.source;
self.resource.repolist.get_or_insert_with(|| {
arc.clone()
});
self
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels