diff --git a/src/sequence/mod.rs b/src/sequence/mod.rs index 086b250..813ad2d 100644 --- a/src/sequence/mod.rs +++ b/src/sequence/mod.rs @@ -1,8 +1,52 @@ -use crate::index::IndexView; + +pub mod seq2idx; +pub mod vec_buffer; + +pub use { + seq2idx::{Sequence2Index}, + vec_buffer::{VecBuffer, VecSequence} +}; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -pub trait SequenceView = IndexView; +use crate::core::View; + +pub trait SequenceView : View { + type Item; + + fn get(&self, idx: usize) -> Self::Item; + fn len(&self) -> Option; +} //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +use std::{ + sync::{Arc, RwLock}, + ops::{Deref} +}; + +impl SequenceView for RwLock { + type Item = V::Item; + + fn get(&self, idx: usize) -> Self::Item { + self.read().unwrap().get(idx) + } + + fn len(&self) -> Option { + self.read().unwrap().len() + } +} + +impl SequenceView for Arc { + type Item = V::Item; + + fn get(&self, idx: usize) -> Self::Item { + self.deref().get(idx) + } + + fn len(&self) -> Option { + self.deref().len() + } +} + + diff --git a/src/sequence/seq2idx.rs b/src/sequence/seq2idx.rs new file mode 100644 index 0000000..699abc0 --- /dev/null +++ b/src/sequence/seq2idx.rs @@ -0,0 +1,90 @@ +use { + std::{ + sync::{Arc, RwLock}, + boxed::Box + }, + crate::{ + core::{ + View, Observer, ObserverExt, ObserverBroadcast, + ViewPort, InnerViewPort, OuterViewPort + }, + sequence::SequenceView, + index::IndexView + } +}; + +/// Transforms a SequenceView into IndexView +pub struct Sequence2Index +where SrcView: SequenceView + ?Sized + 'static { + src_view: Option>, + cast: Arc>>>> +} + +impl Sequence2Index +where SrcView: SequenceView + ?Sized + 'static { + pub fn new( + port: InnerViewPort>> + ) -> Arc> { + let s2i = Arc::new(RwLock::new( + Sequence2Index { + src_view: None, + cast: port.get_broadcast() + } + )); + port.set_view(Some(s2i.clone())); + s2i + } +} + +impl OuterViewPort> { + pub fn to_index(&self) -> OuterViewPort>> { + let port = ViewPort::new(); + self.add_observer(Sequence2Index::new(port.inner())); + port.into_outer() + } +} + +impl View for Sequence2Index +where SrcView: SequenceView + ?Sized + 'static { + type Msg = usize; +} + +impl IndexView for Sequence2Index +where SrcView: SequenceView + ?Sized + 'static { + type Item = Option; + + fn get(&self, key: &usize) -> Self::Item { + if let Some(v) = self.src_view.as_ref() { + if *key < v.len().unwrap_or(usize::MAX) { + return Some(v.get(*key)); + } + } + None + } + + fn area(&self) -> Option> { + if let Some(v) = self.src_view.as_ref() { + if let Some(len) = v.len() { + return Some((0 .. len).collect()); + } + } + None + } +} + +impl Observer for Sequence2Index +where SrcView: SequenceView + ?Sized + 'static { + fn reset(&mut self, view: Option>) { + let old_area = self.area(); + self.src_view = view; + let new_area = self.area(); + + if let Some(area) = old_area { self.cast.notify_each(area); } + if let Some(area) = new_area { self.cast.notify_each(area); } + } + + fn notify(&self, msg: &usize) { + self.cast.notify(msg); + } +} +