Advertisement
Guest User

Untitled

a guest
Jul 20th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.04 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement