SHARE
TWEET

Untitled

a guest Jul 20th, 2019 69 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. use std::fs;
  2. use std::io;
  3. use std::path;
  4.  
  5. #[derive(Default)]
  6. pub struct History<'a> {
  7.     history: Vec<String>,
  8.     current: &'a str,
  9.     cursor: usize,
  10.     path: path::PathBuf,
  11. }
  12.  
  13. impl <'a>History<'a> {
  14.     pub fn new(path: path::PathBuf) -> io::Result<Self> {
  15.         let _ = fs::create_dir_all(&path);
  16.  
  17.         let path = path.join("history");
  18.         if !path.exists() {
  19.             let _ = fs::File::create(&path);
  20.         }
  21.  
  22.         let history: Vec<String> = fs::read_to_string(&path)?
  23.             .lines()
  24.             .map(ToOwned::to_owned)
  25.             .collect();
  26.         let cursor = history.len();
  27.         let current = "";
  28.  
  29.         Ok(Self {
  30.             history,
  31.             current,
  32.             cursor,
  33.             path,
  34.         })
  35.     }
  36.     pub fn down(&mut self) -> Option<&str> {
  37.         let filtered = self.filter();
  38.         self.cursor += 1;
  39.         if self.cursor >= filtered.len() {
  40.             self.cursor = filtered.len();
  41.             Some(self.current)
  42.         } else {
  43.             Some(&filtered[self.cursor])
  44.         }
  45.     }
  46.  
  47.     pub fn up(&mut self) -> Option<&str> {
  48.         let filtered = self.filter();
  49.         self.cursor = std::cmp::min(self.cursor, filtered.len());
  50.         if self.cursor == 0 || filtered.is_empty() {
  51.             None
  52.         } else {
  53.             self.cursor = self.cursor.saturating_sub(1);
  54.             Some(&filtered[self.cursor])
  55.         }
  56.     }
  57.  
  58.     pub fn push(&mut self, buffer: String) {
  59.         if !buffer.is_empty() && Some(&buffer) != self.history.last() {
  60.             //self.current.clear();
  61.             self.history.push(buffer);
  62.             self.go_to_last();
  63.         }
  64.     }
  65.  
  66.     pub fn update_current(&mut self, buffer: &'a str) {
  67.         self.current = buffer;
  68.         self.cursor = self.history.len();
  69.     }
  70.  
  71.     pub fn save(&mut self) {
  72.         self.keep_unique_history();
  73.         let history: String = self.history.join("\n");
  74.         let _ = fs::write(&self.path, history);
  75.     }
  76.  
  77.     fn keep_unique_history(&mut self) {
  78.         // remove all duplicates while keeping the latest one
  79.         let mut i: i32 = self.history.len() as i32 - 1;
  80.         while i >= 0 {
  81.             let current_his = self.history[i as usize].clone();
  82.             let mut j = 1;
  83.             let mut removed = 0;
  84.             while i - j >= 0 {
  85.                 let search_idx = (i - j) as usize;
  86.                 if current_his.trim() == self.history[search_idx].trim() {
  87.                     self.history.remove(search_idx);
  88.                     removed += 1;
  89.                 }
  90.                 j += 1;
  91.             }
  92.             i -= 1 + removed;
  93.         }
  94.     }
  95.  
  96.     pub fn get(&self) -> &[String] {
  97.         &self.history
  98.     }
  99.  
  100.     fn filter(&self) -> Vec<String> {
  101.         self.history
  102.             .iter()
  103.             .filter(|h| h.contains(&self.current))
  104.             .map(ToOwned::to_owned)
  105.             .collect()
  106.     }
  107.  
  108.     fn go_to_last(&mut self) {
  109.         if !self.history.is_empty() {
  110.             self.cursor = self.history.len();
  111.         }
  112.     }
  113. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top