navi/config/
yaml.rs

1use super::env::EnvConfig;
2use crate::common::fs;
3use crate::filesystem::default_config_pathbuf;
4use crate::finder::FinderChoice;
5use crate::prelude::*;
6use crossterm::style::Color as TerminalColor;
7use serde::de;
8
9#[derive(Deserialize, Debug)]
10pub struct Color(#[serde(deserialize_with = "color_deserialize")] TerminalColor);
11
12impl Color {
13    pub fn get(&self) -> TerminalColor {
14        self.0
15    }
16}
17
18fn color_deserialize<'de, D>(deserializer: D) -> Result<TerminalColor, D::Error>
19where
20    D: de::Deserializer<'de>,
21{
22    let s: String = Deserialize::deserialize(deserializer)?;
23    TerminalColor::try_from(s.as_str())
24        .map_err(|_| de::Error::custom(format!("Failed to deserialize color: {s}")))
25}
26
27#[derive(Deserialize, Debug)]
28#[serde(default)]
29pub struct ColorWidth {
30    pub color: Color,
31    pub width_percentage: u16,
32    pub min_width: u16,
33}
34
35#[derive(Deserialize, Debug)]
36#[serde(default)]
37pub struct Style {
38    pub tag: ColorWidth,
39    pub comment: ColorWidth,
40    pub snippet: ColorWidth,
41}
42
43#[derive(Deserialize, Debug)]
44#[serde(default)]
45pub struct Finder {
46    #[serde(deserialize_with = "finder_deserialize")]
47    pub command: FinderChoice,
48    pub overrides: Option<String>,
49    pub overrides_var: Option<String>,
50}
51
52fn finder_deserialize<'de, D>(deserializer: D) -> Result<FinderChoice, D::Error>
53where
54    D: de::Deserializer<'de>,
55{
56    let s: String = Deserialize::deserialize(deserializer)?;
57    FinderChoice::from_str(s.to_lowercase().as_str())
58        .map_err(|_| de::Error::custom(format!("Failed to deserialize finder: {s}")))
59}
60
61#[derive(Deserialize, Default, Debug)]
62#[serde(default)]
63pub struct Cheats {
64    pub path: Option<String>,
65    pub paths: Vec<String>,
66}
67
68#[derive(Deserialize, Default, Debug)]
69#[serde(default)]
70pub struct Search {
71    pub tags: Option<String>,
72}
73
74#[derive(Deserialize, Debug)]
75#[serde(default)]
76pub struct Shell {
77    pub command: String,
78    pub finder_command: Option<String>,
79}
80
81#[derive(Deserialize, Default, Debug)]
82#[serde(default)]
83pub struct YamlConfig {
84    pub style: Style,
85    pub finder: Finder,
86    pub cheats: Cheats,
87    pub search: Search,
88    pub shell: Shell,
89}
90
91impl YamlConfig {
92    fn from_str(text: &str) -> Result<Self> {
93        serde_yaml::from_str(text).map_err(|e| e.into())
94    }
95
96    fn from_path(path: &Path) -> Result<Self> {
97        let file = fs::open(path)?;
98        let reader = BufReader::new(file);
99        serde_yaml::from_reader(reader).map_err(|e| e.into())
100    }
101
102    pub fn get(env: &EnvConfig) -> Result<Self> {
103        if let Some(yaml) = env.config_yaml.as_ref() {
104            return Self::from_str(yaml);
105        }
106        if let Some(path_str) = env.config_path.as_ref() {
107            let p = PathBuf::from(path_str);
108            return YamlConfig::from_path(&p);
109        }
110        if let Ok(p) = default_config_pathbuf() {
111            if p.exists() {
112                return YamlConfig::from_path(&p);
113            }
114        }
115        Ok(YamlConfig::default())
116    }
117}
118
119impl Default for ColorWidth {
120    fn default() -> Self {
121        Self {
122            color: Color(TerminalColor::Blue),
123            width_percentage: 26,
124            min_width: 20,
125        }
126    }
127}
128
129impl Default for Style {
130    fn default() -> Self {
131        Self {
132            tag: ColorWidth {
133                color: Color(TerminalColor::Cyan),
134                width_percentage: 26,
135                min_width: 20,
136            },
137            comment: ColorWidth {
138                color: Color(TerminalColor::Blue),
139                width_percentage: 42,
140                min_width: 45,
141            },
142            snippet: Default::default(),
143        }
144    }
145}
146
147impl Default for Finder {
148    fn default() -> Self {
149        Self {
150            command: FinderChoice::Fzf,
151            overrides: None,
152            overrides_var: None,
153        }
154    }
155}
156
157impl Default for Shell {
158    fn default() -> Self {
159        Self {
160            command: "bash".to_string(),
161            finder_command: None,
162        }
163    }
164}