Skip to main content

commit_wizard/engine/capabilities/config/
show.rs

1use std::path::{Path, PathBuf};
2
3use crate::engine::{
4    config::{ProjectConfig, StandardConfig},
5    constants::{CONFIG_FILE_NAME, PROJECT_CONFIG_FILE_NAME, paths::app_config_dir},
6    error::{ErrorCode, Result},
7};
8
9#[derive(Debug, Clone, Copy)]
10pub enum ConfigTarget {
11    Project,
12    Global,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum ConfigShowFormat {
17    Human,
18    Json,
19    Toml,
20}
21
22pub struct ConfigPathInput<'a> {
23    pub cwd: &'a Path,
24    pub target: ConfigTarget,
25}
26
27pub struct ConfigPathOutput {
28    pub path: PathBuf,
29}
30
31pub struct ConfigShowInput<'a> {
32    pub cwd: &'a Path,
33    pub target: ConfigTarget,
34    pub explicit_path: Option<&'a Path>,
35    pub format: ConfigShowFormat,
36}
37
38pub struct ConfigShowOutput {
39    pub path: PathBuf,
40    pub exists: bool,
41    pub content: String,
42}
43
44pub fn resolve_config_path(target: ConfigTarget, cwd: &Path) -> Result<PathBuf> {
45    match target {
46        ConfigTarget::Project => Ok(cwd.join(PROJECT_CONFIG_FILE_NAME)),
47        ConfigTarget::Global => Ok(app_config_dir()?.join(CONFIG_FILE_NAME)),
48    }
49}
50
51pub fn config_path(input: &ConfigPathInput<'_>) -> Result<ConfigPathOutput> {
52    Ok(ConfigPathOutput {
53        path: resolve_config_path(input.target, input.cwd)?,
54    })
55}
56
57pub fn config_show(input: &ConfigShowInput<'_>) -> Result<ConfigShowOutput> {
58    let path = resolve_config_path(input.target, input.cwd)?;
59
60    if !path.exists() {
61        return Err(ErrorCode::ConfigUnreadable
62            .error()
63            .with_context("path", path.display().to_string())
64            .with_context("reason", "config file does not exist"));
65    }
66
67    let raw = std::fs::read_to_string(&path)?;
68
69    let content = match input.target {
70        ConfigTarget::Project => {
71            let parsed = ProjectConfig::from_toml_str(&raw)?;
72            match input.format {
73                ConfigShowFormat::Human | ConfigShowFormat::Toml => raw,
74                ConfigShowFormat::Json => serde_json::to_string_pretty(&parsed).map_err(|err| {
75                    ErrorCode::SerializationFailure
76                        .error()
77                        .with_context("error", err.to_string())
78                })?,
79            }
80        }
81        ConfigTarget::Global => {
82            let parsed = StandardConfig::from_toml_str(&raw)?;
83            match input.format {
84                ConfigShowFormat::Human | ConfigShowFormat::Toml => raw,
85                ConfigShowFormat::Json => serde_json::to_string_pretty(&parsed).map_err(|err| {
86                    ErrorCode::SerializationFailure
87                        .error()
88                        .with_context("error", err.to_string())
89                })?,
90            }
91        }
92    };
93
94    Ok(ConfigShowOutput {
95        path,
96        exists: true,
97        content,
98    })
99}