use std::error::Error;
use std::fs::File;
use std::io::{self, Write};
use std::path::Path;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct History {
pub start: String,
pub depth: Option<usize>,
pub pattern: String,
pub file_pattern: Option<String>,
pub names_only: bool,
pub search_hidden: bool,
pub excluded_dirs: Vec<String>,
pub locations: Vec<Location>,
}
impl History {
pub fn build(
start: &Path,
depth: Option<usize>,
pattern: &str,
file_pattern: Option<&str>,
names_only: bool,
search_hidden: bool,
excluded_dirs: &[String],
) -> io::Result<Self> {
let start = start.canonicalize()?;
let mut excluded_dirs = super::Rebaser::new(&start, excluded_dirs)
.map(|p| p.map(|p| p.to_string_lossy().to_string()))
.collect::<io::Result<Vec<String>>>()?;
excluded_dirs.sort();
Ok(Self {
start: start.to_string_lossy().to_string(),
depth,
pattern: pattern.to_string(),
file_pattern: file_pattern.map(String::from),
names_only,
search_hidden,
excluded_dirs,
locations: Vec::new(),
})
}
pub fn from_file(file: &Path) -> Result<Self, Box<dyn Error>> {
let file = File::open(file)?;
Ok(serde_json::from_reader(file)?)
}
pub fn add_location(&mut self, file: &Path, line: usize) -> io::Result<()> {
let absolute = file.canonicalize()?.to_string_lossy().to_string();
self.locations.push(Location { path: absolute, line });
Ok(())
}
pub fn save(&self, file: &Path) -> io::Result<()> {
let dump = serde_json::to_string_pretty(self).unwrap();
let mut file = File::create(file)?;
file.write_all(dump.as_bytes())?;
Ok(())
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Location {
pub path: String,
pub line: usize,
}