A file-based task manager
at v0.4.0 61 lines 1.8 kB view raw
1use std::collections::BTreeMap; 2use std::collections::btree_map::Entry; 3use std::collections::btree_map::{IntoIter as BTreeIntoIter, Iter as BTreeMapIter}; 4use std::iter::Chain; 5 6type Map = BTreeMap<String, String>; 7 8#[allow(dead_code)] 9/// Holds xattributes in a way that allows for differentiating between attributes that have been 10/// added/modified or that were present when reading the file. This is an *optimization* over 11/// infrequently modified values. 12#[derive(Default, Clone, Debug)] 13pub(crate) struct Attrs { 14 pub written: Map, 15 pub updated: Map, 16} 17 18impl IntoIterator for Attrs { 19 type Item = (String, String); 20 21 type IntoIter = Chain<BTreeIntoIter<String, String>, BTreeIntoIter<String, String>>; 22 23 fn into_iter(self) -> Self::IntoIter { 24 self.written.into_iter().chain(self.updated) 25 } 26} 27 28#[allow(dead_code)] 29impl Attrs { 30 pub(crate) fn from_written(written: Map) -> Self { 31 Self { 32 written, 33 ..Default::default() 34 } 35 } 36 37 pub(crate) fn get(&self, key: &str) -> Option<&String> { 38 self.updated.get(key).or_else(|| self.written.get(key)) 39 } 40 41 pub(crate) fn insert(&mut self, key: String, value: String) -> Option<String> { 42 match self.updated.entry(key.clone()) { 43 Entry::Occupied(mut e) => Some(e.insert(value)), 44 Entry::Vacant(e) => { 45 e.insert(value); 46 let maybe_old_value = self.written.get(&key); 47 maybe_old_value.cloned() 48 } 49 } 50 } 51 52 pub(crate) fn is_empty(&self) -> bool { 53 self.updated.is_empty() && self.written.is_empty() 54 } 55 56 pub(crate) fn iter( 57 &self, 58 ) -> Chain<BTreeMapIter<'_, String, String>, BTreeMapIter<'_, String, String>> { 59 self.written.iter().chain(self.updated.iter()) 60 } 61}