lib-nested/nested/src/index/map_item.rs

108 lines
2.9 KiB
Rust
Raw Normal View History

2021-01-12 23:13:27 +01:00
pub use {
crate::{
core::{
2021-11-19 12:19:52 +01:00
InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort,
2021-01-12 23:13:27 +01:00
},
2021-11-19 12:19:52 +01:00
index::{IndexArea, IndexView},
},
std::sync::RwLock,
std::{boxed::Box, sync::Arc},
2021-01-12 23:13:27 +01:00
};
impl<Key, Item> OuterViewPort<dyn IndexView<Key, Item = Item>>
2021-11-19 12:19:52 +01:00
where
Key: Clone + Send + Sync + 'static,
Item: Send + Sync + 'static,
{
2021-11-19 12:19:52 +01:00
pub fn map_item<DstItem: 'static, F: Fn(&Key, &Item) -> DstItem + Send + Sync + 'static>(
2021-01-12 23:13:27 +01:00
&self,
2021-11-19 12:19:52 +01:00
f: F,
2021-01-12 23:13:27 +01:00
) -> OuterViewPort<dyn IndexView<Key, Item = DstItem>> {
let port = ViewPort::new();
port.add_update_hook(Arc::new(self.0.clone()));
2021-01-12 23:13:27 +01:00
let map = MapIndexItem::new(port.inner(), f);
self.add_observer(map.clone());
port.into_outer()
}
}
pub struct MapIndexItem<Key, DstItem, SrcView, F>
2021-11-19 12:19:52 +01:00
where
Key: Clone + Send + Sync,
SrcView: IndexView<Key> + ?Sized,
F: Fn(&Key, &SrcView::Item) -> DstItem + Send + Sync,
2021-01-12 23:13:27 +01:00
{
src_view: Option<Arc<SrcView>>,
f: F,
2021-11-19 12:19:52 +01:00
cast: Arc<RwLock<ObserverBroadcast<dyn IndexView<Key, Item = DstItem>>>>,
2021-01-12 23:13:27 +01:00
}
impl<Key, DstItem, SrcView, F> MapIndexItem<Key, DstItem, SrcView, F>
2021-11-19 12:19:52 +01:00
where
Key: Clone + Send + Sync + 'static,
DstItem: 'static,
SrcView: IndexView<Key> + ?Sized + 'static,
F: Fn(&Key, &SrcView::Item) -> DstItem + Send + Sync + 'static,
2021-01-12 23:13:27 +01:00
{
2021-11-19 12:19:52 +01:00
fn new(port: InnerViewPort<dyn IndexView<Key, Item = DstItem>>, f: F) -> Arc<RwLock<Self>> {
let map = Arc::new(RwLock::new(MapIndexItem {
src_view: None,
f,
cast: port.get_broadcast(),
}));
2021-01-12 23:13:27 +01:00
port.set_view(Some(map.clone()));
map
}
}
impl<Key, DstItem, SrcView, F> View for MapIndexItem<Key, DstItem, SrcView, F>
2021-11-19 12:19:52 +01:00
where
Key: Clone + Send + Sync,
SrcView: IndexView<Key> + ?Sized,
F: Fn(&Key, &SrcView::Item) -> DstItem + Send + Sync,
2021-01-12 23:13:27 +01:00
{
type Msg = IndexArea<Key>;
2021-01-12 23:13:27 +01:00
}
impl<Key, DstItem, SrcView, F> IndexView<Key> for MapIndexItem<Key, DstItem, SrcView, F>
2021-11-19 12:19:52 +01:00
where
Key: Clone + Send + Sync,
SrcView: IndexView<Key> + ?Sized,
F: Fn(&Key, &SrcView::Item) -> DstItem + Send + Sync,
2021-01-12 23:13:27 +01:00
{
type Item = DstItem;
fn get(&self, key: &Key) -> Option<Self::Item> {
2021-11-19 12:19:52 +01:00
self.src_view
.get(key)
.as_ref()
.map(|item| (self.f)(key, item))
2021-01-12 23:13:27 +01:00
}
fn area(&self) -> IndexArea<Key> {
2021-01-19 22:54:50 +01:00
self.src_view.area()
2021-01-12 23:13:27 +01:00
}
}
impl<Key, DstItem, SrcView, F> Observer<SrcView> for MapIndexItem<Key, DstItem, SrcView, F>
2021-11-19 12:19:52 +01:00
where
Key: Clone + Send + Sync,
SrcView: IndexView<Key> + ?Sized,
F: Fn(&Key, &SrcView::Item) -> DstItem + Send + Sync,
2021-01-12 23:13:27 +01:00
{
fn reset(&mut self, view: Option<Arc<SrcView>>) {
let old_area = self.area();
2021-01-12 23:13:27 +01:00
self.src_view = view;
self.cast.notify(&old_area);
self.cast.notify(&self.src_view.area())
2021-01-12 23:13:27 +01:00
}
fn notify(&mut self, area: &IndexArea<Key>) {
self.cast.notify(area);
2021-01-12 23:13:27 +01:00
}
}