Allow patches to be composed with edit iterators in addition to other Patches

Nathan Sobo and Max Brunsfeld created

This can avoid an extra allocation in some cases.

Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>

Change summary

crates/text/src/patch.rs | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)

Detailed changes

crates/text/src/patch.rs 🔗

@@ -9,7 +9,8 @@ pub struct Patch<T>(Vec<Edit<T>>);
 
 impl<T> Patch<T>
 where
-    T: Clone
+    T: 'static
+        + Clone
         + Copy
         + Ord
         + Sub<T, Output = T>
@@ -41,9 +42,9 @@ where
         self.0
     }
 
-    pub fn compose(&self, other: &Self) -> Self {
+    pub fn compose(&self, new_edits_iter: impl IntoIterator<Item = Edit<T>>) -> Self {
         let mut old_edits_iter = self.0.iter().cloned().peekable();
-        let mut new_edits_iter = other.0.iter().cloned().peekable();
+        let mut new_edits_iter = new_edits_iter.into_iter().peekable();
         let mut composed = Patch(Vec::new());
 
         let mut old_start = T::default();
@@ -200,6 +201,15 @@ where
     }
 }
 
+impl<'a, T: Clone> IntoIterator for &'a Patch<T> {
+    type Item = Edit<T>;
+    type IntoIter = std::iter::Cloned<std::slice::Iter<'a, Edit<T>>>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.0.iter().cloned()
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;