vtcode_core/utils/
cached_style_parser.rs1use anstyle::Style as AnsiStyle;
2use anyhow::{Context, Result};
3use vtcode_commons::lr_map::LrMap;
4
5pub struct CachedStyleParser {
7 git_cache: LrMap<String, AnsiStyle>,
8 ls_colors_cache: LrMap<String, AnsiStyle>,
9}
10
11impl CachedStyleParser {
12 pub fn new() -> Self {
13 Self {
14 git_cache: LrMap::new(),
15 ls_colors_cache: LrMap::new(),
16 }
17 }
18
19 pub fn parse_git_style(&self, input: &str) -> Result<AnsiStyle> {
20 if let Some(cached) = self.git_cache.get(input) {
21 return Ok(cached);
22 }
23
24 let result = anstyle_git::parse(input)
25 .map_err(|e| anyhow::anyhow!("Failed to parse Git style '{}': {:?}", input, e))?;
26
27 self.git_cache.insert(input.to_string(), result);
28 Ok(result)
29 }
30
31 pub fn parse_ls_colors(&self, input: &str) -> Result<AnsiStyle> {
32 if let Some(cached) = self.ls_colors_cache.get(input) {
33 return Ok(cached);
34 }
35
36 let result = anstyle_ls::parse(input)
37 .ok_or_else(|| anyhow::anyhow!("Failed to parse LS_COLORS '{}'", input))?;
38
39 self.ls_colors_cache.insert(input.to_string(), result);
40 Ok(result)
41 }
42
43 pub fn parse_flexible(&self, input: &str) -> Result<AnsiStyle> {
44 match self.parse_git_style(input) {
45 Ok(style) => Ok(style),
46 Err(_) => self
47 .parse_ls_colors(input)
48 .with_context(|| format!("Could not parse style string: '{}'", input)),
49 }
50 }
51}
52
53impl Default for CachedStyleParser {
54 fn default() -> Self {
55 Self::new()
56 }
57}