use crate::entry::Entry;
#[derive(Debug)]
pub struct Newer {
pub last_read_id: Option<String>,
}
impl Newer {
#[must_use]
pub fn new() -> Self {
Self { last_read_id: None }
}
pub fn mark_as_read(&mut self, id: &str) {
self.last_read_id = Some(id.to_owned());
}
pub fn remove_read_from(&self, list: &mut Vec<Entry>) {
if let Some(last_read_id) = &self.last_read_id {
if let Some(last_read_id_pos) = list.iter().position(|x| {
let id = match &x.id {
Some(id) => id,
None => return false,
};
last_read_id == id
}) {
list.drain(last_read_id_pos..);
}
}
}
#[must_use]
pub fn last_read(&self) -> Option<&str> {
self.last_read_id.as_deref()
}
}
impl Default for Newer {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::unwrap_used)]
use super::*;
#[test]
fn mark_as_read() {
let mut rf = Newer::new();
rf.mark_as_read("13");
assert_eq!(rf.last_read_id.as_deref().unwrap(), "13");
rf.mark_as_read("1002");
assert_eq!(rf.last_read_id.as_deref().unwrap(), "1002");
}
#[test]
fn last_read() {
let mut rf = Newer::new();
assert_eq!(None, rf.last_read());
rf.mark_as_read("0");
rf.mark_as_read("1");
rf.mark_as_read("2");
assert_eq!(Some("2"), rf.last_read());
rf.mark_as_read("4");
assert_eq!(Some("4"), rf.last_read());
rf.mark_as_read("100");
rf.mark_as_read("101");
rf.mark_as_read("200");
assert_eq!(Some("200"), rf.last_read());
}
#[test]
fn remove_read_long_list() {
let mut rf = Newer::new();
rf.mark_as_read("3");
let mut entries = vec![
Entry {
id: None,
..Default::default()
},
Entry {
id: Some("5".to_owned()),
..Default::default()
},
Entry {
id: Some("4".to_owned()),
..Default::default()
},
Entry {
id: None,
..Default::default()
},
Entry {
id: Some("0".to_owned()),
..Default::default()
},
Entry {
id: Some("1".to_owned()),
..Default::default()
},
Entry {
id: Some("3".to_owned()),
..Default::default()
},
Entry {
id: None,
..Default::default()
},
Entry {
id: Some("6".to_owned()),
..Default::default()
},
Entry {
id: Some("8".to_owned()),
..Default::default()
},
];
rf.remove_read_from(&mut entries);
let entries = entries.iter().map(|e| e.id.as_deref()).collect::<Vec<_>>();
assert_eq!(
&entries,
&[None, Some("5"), Some("4"), None, Some("0"), Some("1")]
);
}
#[test]
fn remove_read_single_different() {
let mut rf = Newer::new();
rf.mark_as_read("3");
let mut entries = vec![Entry {
id: Some("1".to_owned()),
..Default::default()
}];
rf.remove_read_from(&mut entries);
let entries_ids = entries.iter().map(|e| e.id.as_deref()).collect::<Vec<_>>();
assert_eq!(&entries_ids, &[Some("1")]);
}
#[test]
fn remove_read_single_same() {
let mut rf = Newer::new();
rf.mark_as_read("1");
let mut entries = vec![Entry {
id: Some("1".to_owned()),
..Default::default()
}];
rf.remove_read_from(&mut entries);
let entries_ids = entries.iter().map(|e| e.id.as_deref()).collect::<Vec<_>>();
assert_eq!(&entries_ids, &[]);
}
}