diff --git a/nested/src/sequence/map.rs b/nested/src/sequence/map.rs new file mode 100644 index 0000000..dc2d1c1 --- /dev/null +++ b/nested/src/sequence/map.rs @@ -0,0 +1,90 @@ +use { + std::sync::Arc, + std::sync::RwLock, + crate::{ + sequence::{SequenceView}, + core::{ + Observer, ObserverExt, ObserverBroadcast, + View, ViewPort, InnerViewPort, OuterViewPort + } + } +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl OuterViewPort> { + pub fn map< + DstItem: 'static, + F: Fn(&Item) -> DstItem + Send + Sync + 'static + >( + &self, + f: F + ) -> OuterViewPort> { + let port = ViewPort::new(); + let map = Arc::new(RwLock::new(MapSequenceItem { + src_view: None, + f, + cast: port.inner().get_broadcast() + })); + + self.add_observer(map.clone()); + port.inner().set_view(Some(map)); + port.into_outer() + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub struct MapSequenceItem +where SrcView: SequenceView + ?Sized, + F: Fn(&SrcView::Item) -> DstItem + Send + Sync +{ + src_view: Option>, + f: F, + cast: Arc>>> +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl View for MapSequenceItem +where SrcView: SequenceView + ?Sized, + F: Fn(&SrcView::Item) -> DstItem + Send + Sync +{ + type Msg = usize; +} + +impl SequenceView for MapSequenceItem +where SrcView: SequenceView + ?Sized, + F: Fn(&SrcView::Item) -> DstItem + Send + Sync +{ + type Item = DstItem; + + fn len(&self) -> Option { + self.src_view.len() + } + + fn get(&self, idx: &usize) -> Option { + self.src_view.get(idx).as_ref().map(|item| (self.f)(item)) + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl Observer for MapSequenceItem +where SrcView: SequenceView + ?Sized, + F: Fn(&SrcView::Item) -> DstItem + Send + Sync +{ + fn reset(&mut self, view: Option>) { + let old_len = self.len(); + self.src_view = view; + let new_len = self.len(); + + if let Some(len) = old_len { self.cast.notify_each(0 .. len ); } + if let Some(len) = new_len { self.cast.notify_each(0 .. len ); } + } + + fn notify(&self, msg: &usize) { + self.cast.notify(msg); + } +} + diff --git a/nested/src/sequence/mod.rs b/nested/src/sequence/mod.rs index 2dda5fa..d0f8366 100644 --- a/nested/src/sequence/mod.rs +++ b/nested/src/sequence/mod.rs @@ -1,6 +1,7 @@ pub mod seq2idx; pub mod vec_buffer; +pub mod map; pub mod flatten; pub use {