diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2022-11-12 20:28:57 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2022-11-12 20:28:57 -0300 |
commit | 44a6ee680308a3d756ef7c17db2f64518bb2b493 (patch) | |
tree | 26bda4072601bd220592ccefb5d600d5c4282fa1 /src/vm/mod.rs | |
parent | d6223b31784d45d996fe290647bb862706483e38 (diff) |
Make Packer::visit_map mostly usable
Diffstat (limited to 'src/vm/mod.rs')
-rw-r--r-- | src/vm/mod.rs | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 2e9d796..9f76ec5 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -353,8 +353,9 @@ pub struct Pack<'pat, 'de> { } impl<'pat, 'de> Pack<'pat, 'de> { - /// Merges two packs, with elements from `other` coming after `self`. - fn merge_from(&mut self, mut other: Self) { + /// Merges two packs, with elements from `other` coming after `self`, as if + /// parts of the same iteration. + fn merge_breadth(&mut self, mut other: Self) { match (self.subpacks.len(), other.subpacks.len()) { (0, _) => { *self = other; @@ -365,14 +366,23 @@ impl<'pat, 'de> Pack<'pat, 'de> { l.extend(r) } }, - _ => unreachable!("merge_from unbalanced iterations"), + _ => unreachable!("merge_breadth unbalanced iterations"), } } - /// Same as `merge_from` but borrows `other` instead of `self`. - fn merge_into(mut self, other: &mut Self) { - std::mem::swap(&mut self, other); - other.merge_from(self); + /// Merges two packs, with elements from `other` coming inside the last + /// element of `self` recursively, if any. + fn merge_depth(&mut self, mut other: Self) { + // note that we can't actually recurse deeper than the VM + // actually does itself, so we don't need to worry about + // blowing the stack. + if let Some(into) = self.subpacks.iter_mut().rev().filter(|map| { + !map.is_empty() + }).next() { + into.last_mut().unwrap().1.0.merge_depth(other); + } else { + *self = other; + } } } |