From 6aef446134cabfdfffef71f32990bc17aac5c665 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 19 Jan 2021 22:54:50 +0100
Subject: [PATCH] impl View traits for Option<V>

---
 src/core/view.rs        |  7 +++++--
 src/index/map_item.rs   |  4 ++--
 src/index/map_key.rs    |  4 ++--
 src/index/mod.rs        | 20 ++++++++++++++++++--
 src/sequence/mod.rs     | 19 +++++++++++++++++--
 src/sequence/seq2idx.rs |  5 ++---
 src/string_editor.rs    | 21 +++++----------------
 7 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/src/core/view.rs b/src/core/view.rs
index 1f76892..bfe8274 100644
--- a/src/core/view.rs
+++ b/src/core/view.rs
@@ -13,12 +13,15 @@ pub trait View : Send + Sync {
 
 use std::sync::{Arc, RwLock};
 
-impl<V: View> View for RwLock<V> {
+impl<V: View + ?Sized> View for RwLock<V> {
     type Msg = V::Msg;
 }
 
-impl<V: View> View for Arc<V> {
+impl<V: View + ?Sized> View for Arc<V> {
     type Msg = V::Msg;
 }
 
+impl<V: View> View for Option<V> {
+    type Msg = V::Msg;
+}
 
diff --git a/src/index/map_item.rs b/src/index/map_item.rs
index 28bc582..4493d59 100644
--- a/src/index/map_item.rs
+++ b/src/index/map_item.rs
@@ -78,11 +78,11 @@ where SrcView: IndexView<Key> + ?Sized,
     type Item = DstItem;
 
     fn get(&self, key: &Key) -> Option<Self::Item> {
-        self.src_view.as_ref()?.get(key).as_ref().map(|item| (self.f)(key, item))
+        self.src_view.get(key).as_ref().map(|item| (self.f)(key, item))
     }
 
     fn area(&self) -> Option<Vec<Key>> {
-        self.src_view.as_ref()?.area()
+        self.src_view.area()
     }
 }
 
diff --git a/src/index/map_key.rs b/src/index/map_key.rs
index 8138c3b..3b33f2d 100644
--- a/src/index/map_key.rs
+++ b/src/index/map_key.rs
@@ -88,11 +88,11 @@ where SrcView: IndexView<SrcKey> + ?Sized,
     type Item = SrcView::Item;
 
     fn get(&self, key: &DstKey) -> Option<Self::Item> {
-        self.src_view.as_ref()?.get(&(self.f2)(key)?)
+        self.src_view.get(&(self.f2)(key)?)
     }
 
     fn area(&self) -> Option<Vec<DstKey>> {
-        Some(self.src_view.as_ref()?.area()?.iter().map(&self.f1).collect())
+        Some(self.src_view.area()?.iter().map(&self.f1).collect())
     }
 }
 
diff --git a/src/index/mod.rs b/src/index/mod.rs
index 8bcf20b..96fcbd4 100644
--- a/src/index/mod.rs
+++ b/src/index/mod.rs
@@ -25,7 +25,7 @@ pub trait IndexView<Key> : View<Msg = Key> {
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
-impl<Key, V: IndexView<Key>> IndexView<Key> for RwLock<V> {
+impl<Key, V: IndexView<Key> + ?Sized> IndexView<Key> for RwLock<V> {
     type Item = V::Item;
 
     fn get(&self, key: &Key) -> Option<Self::Item> {
@@ -37,7 +37,7 @@ impl<Key, V: IndexView<Key>> IndexView<Key> for RwLock<V> {
     }
 }
 
-impl<Key, V: IndexView<Key>> IndexView<Key> for Arc<V> {
+impl<Key, V: IndexView<Key> + ?Sized> IndexView<Key> for Arc<V> {
     type Item = V::Item;
 
     fn get(&self, key: &Key) -> Option<Self::Item> {
@@ -49,6 +49,22 @@ impl<Key, V: IndexView<Key>> IndexView<Key> for Arc<V> {
     }
 }
 
+impl<Key, V: IndexView<Key>> IndexView<Key> for Option<V> {
+    type Item = V::Item;
+
+    fn get(&self, key: &Key) -> Option<Self::Item> {
+        (self.as_ref()? as &V).get(key)
+    }
+
+    fn area(&self) -> Option<Vec<Key>> {
+        if let Some(v) = self.as_ref() {
+            v.area()
+        } else {
+            Some(Vec::new())
+        }
+    }
+}
+
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
 pub trait ImplIndexView : Send + Sync {
diff --git a/src/sequence/mod.rs b/src/sequence/mod.rs
index e80e98a..bb09a04 100644
--- a/src/sequence/mod.rs
+++ b/src/sequence/mod.rs
@@ -25,7 +25,7 @@ use std::{
     ops::{Deref}
 };
 
-impl<V: SequenceView> SequenceView for RwLock<V> {
+impl<V: SequenceView + ?Sized> SequenceView for RwLock<V> {
     type Item = V::Item;
 
     fn get(&self, idx: &usize) -> Option<Self::Item> {
@@ -37,7 +37,7 @@ impl<V: SequenceView> SequenceView for RwLock<V> {
     }
 }
 
-impl<V: SequenceView> SequenceView for Arc<V> {
+impl<V: SequenceView + ?Sized> SequenceView for Arc<V> {
     type Item = V::Item;
 
     fn get(&self, idx: &usize) -> Option<Self::Item> {
@@ -49,4 +49,19 @@ impl<V: SequenceView> SequenceView for Arc<V> {
     }
 }
 
+impl<V: SequenceView> SequenceView for Option<V> {
+    type Item = V::Item;
+
+    fn get(&self, idx: &usize) -> Option<Self::Item> {
+        (self.as_ref()? as &V).get(idx)
+    }
+
+    fn len(&self) -> Option<usize> {
+        if let Some(v) = self.as_ref() {
+            v.len()
+        } else {
+            Some(0)
+        }
+    }
+}
 
diff --git a/src/sequence/seq2idx.rs b/src/sequence/seq2idx.rs
index c42af0b..0f0ad0b 100644
--- a/src/sequence/seq2idx.rs
+++ b/src/sequence/seq2idx.rs
@@ -53,12 +53,11 @@ where SrcView: SequenceView + ?Sized + 'static {
     type Item = SrcView::Item;
 
     fn get(&self, key: &usize) -> Option<Self::Item> {
-        self.src_view.as_ref()?.get(key)
+        self.src_view.get(key)
     }
 
     fn area(&self) -> Option<Vec<usize>> {
-        let len = self.src_view.as_ref()?.len()?;
-        Some((0 .. len).collect())
+        Some((0 .. self.src_view.len()?).collect())
     }
 }
 
diff --git a/src/string_editor.rs b/src/string_editor.rs
index 07d62e0..d270be9 100644
--- a/src/string_editor.rs
+++ b/src/string_editor.rs
@@ -9,6 +9,7 @@ use {
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
+#[derive(Clone)]
 pub struct StringEditor {
     data: VecBuffer<char>,
     cursor: SingletonBuffer<usize>,
@@ -34,11 +35,11 @@ impl StringEditor {
     pub fn get_data_port(&self) -> OuterViewPort<RwLock<Vec<char>>> {
         self.data_port.outer()
     }
-    
+
     pub fn get_cursor_port(&self) -> OuterViewPort<dyn SingletonView<Item = usize>> {
         self.cursor_port.outer()
     }
-    
+
     pub fn goto(&mut self, new_pos: usize) {
         if new_pos <= self.data.len() {
             self.cursor.set(new_pos);
@@ -123,21 +124,9 @@ pub mod insert_view {
 
     impl Observer<dyn SequenceView<Item = char>> for DataObserver {
         fn reset(&mut self, new_data: Option<Arc<dyn SequenceView<Item = char>>>) {
-            let old_len =
-                if let Some(data) = self.data.as_ref() {
-                    data.len().unwrap_or(0)
-                } else {
-                    0
-                };
-
+            let old_len = self.data.len().unwrap_or(0);
             self.data = new_data;
-
-            let new_len =
-                if let Some(data) = self.data.as_ref() {
-                    data.len().unwrap_or(0)
-                } else {
-                    0
-                };
+            let new_len = self.data.len().unwrap_or(0);
 
             self.edit
                 .upgrade().unwrap()