1use serde::{Deserialize, Serialize};
4use std::path::Path;
5
6use crate::error::{Error, Result};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
10#[serde(rename_all = "kebab-case")]
11pub enum Backend {
12 #[default]
14 Auto,
15 Rayon,
17 IoUring,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23#[serde(default)]
24pub struct Config {
25 pub include: Vec<String>,
27 pub exclude: Vec<String>,
29 pub max_file_size: u64,
31 pub respect_gitignore: bool,
33 pub index_hidden: bool,
35 pub backend: Backend,
37 pub merge_threshold: usize,
39}
40
41impl Default for Config {
42 fn default() -> Self {
43 Self {
44 include: Vec::new(),
45 exclude: vec![
46 "**/.git/**".to_string(),
47 "**/node_modules/**".to_string(),
48 "**/target/**".to_string(),
49 "**/.greplm/**".to_string(),
50 ],
51 max_file_size: 4 * 1024 * 1024,
52 respect_gitignore: true,
53 index_hidden: false,
54 backend: Backend::Auto,
55 merge_threshold: 16,
56 }
57 }
58}
59
60impl Config {
61 pub fn load(path: &Path) -> Result<Config> {
62 match std::fs::read_to_string(path) {
63 Ok(s) => Ok(toml::from_str(&s)?),
64 Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(Config::default()),
65 Err(e) => Err(Error::io(path, e)),
66 }
67 }
68
69 pub fn save(&self, path: &Path) -> Result<()> {
70 let s = toml::to_string_pretty(self)?;
71 std::fs::write(path, s).map_err(|e| Error::io(path, e))
72 }
73}