Skip to content

Instantly share code, notes, and snippets.

@cart
Created July 18, 2020 04:08
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 cart/824022d8c00a0b95ca2e9431a324a5e0 to your computer and use it in GitHub Desktop.
Save cart/824022d8c00a0b95ca2e9431a324a5e0 to your computer and use it in GitHub Desktop.
tracker
use std::{fmt::Debug, ops::{Deref, DerefMut}};
pub struct Track<T> {
modified: bool,
value: T,
}
pub trait Tracker {
fn is_modified(&self) -> bool;
fn reset(&mut self);
}
impl<T> Tracker for Track<T> {
fn is_modified(&self) -> bool {
self.is_modified()
}
fn reset(&mut self) {
self.reset()
}
}
impl<T> Track<T> {
pub fn new(value: T) -> Self {
Self {
value,
modified: false,
}
}
pub fn reset(&mut self) {
self.modified = false;
}
pub fn is_modified(&self) -> bool {
self.modified
}
}
impl<T> Debug for Track<T> where T: Debug {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.value.fmt(f)
}
}
impl<T> Deref for Track<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<T> DerefMut for Track<T> {
fn deref_mut(&mut self) -> &mut T {
self.modified = true;
&mut self.value
}
}
pub struct ModifiedIter<I> {
iter: I
}
impl<'a, I, T> Iterator for ModifiedIter<I> where I: Iterator<Item=&'a T>, T: Tracker + 'static {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.iter.next() {
Some(value) => if value.is_modified() {
break Some(value);
},
None => {
break None
}
}
}
}
}
pub trait IntoModifiedIter<I> {
fn modified(self) -> ModifiedIter<I>;
}
impl<'a, I, T> IntoModifiedIter<I> for I where I: Iterator<Item=&'a T>, T: Tracker + 'static {
fn modified(self) -> ModifiedIter<I> {
ModifiedIter {
iter: self
}
}
}
#[cfg(test)]
mod tests {
use super::{IntoModifiedIter, Track};
#[test]
fn track() {
let mut x = Track::new(vec![]);
assert!(!x.is_modified());
x.push(1);
assert!(x.is_modified());
let values = vec![
Track::new(vec![2]),
x,
Track::new(vec![3]),
];
for x in values.iter().modified() {
println!("{:?}", x);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment