Skip to content

Instantly share code, notes, and snippets.

@aavogt
Last active February 21, 2023 02:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aavogt/cf7ad3ceed1a8e50676e8090c6d8e5b5 to your computer and use it in GitHub Desktop.
Save aavogt/cf7ad3ceed1a8e50676e8090c6d8e5b5 to your computer and use it in GitHub Desktop.
struct Zipper<'a, T> {
up : Vec<&'a mut T>,
focus : &'a mut T,
down : Vec<&'a mut T>,
}
impl<'a, T> Zipper<'a, T> {
fn focus_n(&'a mut self, n: i32) -> Option<&mut Self> {
let mut x = self.focus_top()?;
// n focus downs from the top
for _ in 1..n { x = x.focus_down()?; }
return x.focus_down();
}
fn focus_top(&'a mut self) -> Option<&mut Self> {
self.down.push(self.focus);
self.up.reverse();
self.up.append(&mut self.down);
self.down.clear();
std::mem::swap(&mut self.up, &mut self.down);
self.focus = self.down.pop()?;
Some(self)
}
fn focus_up(&'a mut self) -> Option<&mut Self> {
self.down.push(self.focus);
self.focus = self.up.pop()?;
Some(self)
}
fn focus_down(&'a mut self) -> Option<&mut Self> {
self.up.push(self.focus);
self.focus = self.down.pop()?;
Some(self)
}
fn new(data: &'a mut [T]) -> Option<Self> {
if data.is_empty() {
return None;
}
let mut dit = data.iter_mut();
let focus = dit.next()?;
let up = Vec::new();
let down = dit.collect();
Some(Self { up, focus, down })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment