1use anyhow::Result;
8use serde::{Deserialize, Serialize};
9use std::path::PathBuf;
10
11#[derive(Debug, Clone, Serialize, Deserialize, Default)]
13pub struct Config {
14 #[serde(default)]
16 pub default_format: Option<String>,
17
18 #[serde(default)]
20 pub date_format: Option<String>,
21
22 #[serde(default)]
24 pub output_dir: Option<String>,
25
26 #[serde(default)]
28 pub excel: ExcelConfig,
29
30 #[serde(default)]
32 pub csv: CsvConfig,
33
34 #[serde(default)]
36 pub google_sheets: GoogleSheetsConfig,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize, Default)]
41pub struct ExcelConfig {
42 #[serde(default)]
44 pub header_bold: Option<bool>,
45
46 #[serde(default)]
48 pub header_bg_color: Option<String>,
49
50 #[serde(default)]
52 pub header_font_color: Option<String>,
53
54 #[serde(default)]
56 pub auto_filter: Option<bool>,
57
58 #[serde(default)]
60 pub freeze_header: Option<bool>,
61
62 #[serde(default)]
64 pub auto_fit: Option<bool>,
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize, Default)]
69pub struct CsvConfig {
70 #[serde(default)]
72 pub delimiter: Option<String>,
73
74 #[serde(default)]
76 pub quote: Option<String>,
77
78 #[serde(default)]
80 pub has_header: Option<bool>,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize, Default)]
85pub struct GoogleSheetsConfig {
86 #[serde(default)]
88 pub service_account_file: Option<String>,
89
90 #[serde(default)]
92 pub client_secrets_file: Option<String>,
93
94 #[serde(default)]
96 pub token_file: Option<String>,
97
98 #[serde(default)]
100 pub default_spreadsheet_id: Option<String>,
101
102 #[serde(default)]
104 pub api_key: Option<String>,
105
106 #[serde(default = "default_scopes")]
108 pub scopes: Vec<String>,
109}
110
111fn default_scopes() -> Vec<String> {
112 vec![
113 "https://www.googleapis.com/auth/spreadsheets".to_string(),
114 "https://www.googleapis.com/auth/drive.readonly".to_string(),
115 ]
116}
117
118impl Config {
119 pub fn load() -> Result<Self> {
121 let paths = vec![
123 PathBuf::from(".xls-rs.toml"),
125 dirs::home_dir()
127 .map(|p| p.join(".xls-rs.toml"))
128 .unwrap_or_default(),
129 dirs::config_dir()
131 .map(|p| p.join("xls-rs/config.toml"))
132 .unwrap_or_default(),
133 ];
134
135 for path in paths {
136 if path.exists() {
137 let content = std::fs::read_to_string(&path)?;
138 let config: Config = toml::from_str(&content)?;
139 return Ok(config);
140 }
141 }
142
143 Ok(Config::default())
145 }
146
147 pub fn load_from(path: &str) -> Result<Self> {
149 let content = std::fs::read_to_string(path)?;
150 let config: Config = toml::from_str(&content)?;
151 Ok(config)
152 }
153
154 pub fn save(&self, path: &str) -> Result<()> {
156 let content = toml::to_string_pretty(self)?;
157 std::fs::write(path, content)?;
158 Ok(())
159 }
160
161 pub fn default_config_content() -> &'static str {
163 r#"# xls-rs configuration file
164# Place this file at ~/.xls-rs.toml or .xls-rs.toml in your project
165
166# Default output format: csv, json, markdown
167default_format = "csv"
168
169# Default date format for parsing
170date_format = "%Y-%m-%d"
171
172# Default output directory for batch operations
173# output_dir = "output"
174
175[excel]
176# Make header row bold
177header_bold = true
178
179# Header background color (hex without #)
180header_bg_color = "4472C4"
181
182# Header font color (hex without #)
183header_font_color = "FFFFFF"
184
185# Enable auto-filter on headers
186auto_filter = true
187
188# Freeze first row (header)
189freeze_header = true
190
191# Auto-fit column widths
192auto_fit = true
193
194[csv]
195# Delimiter character (default: comma)
196delimiter = ","
197
198# Quote character (default: double quote)
199quote = "\""
200
201# Has header row
202has_header = true
203
204[google_sheets]
205# Path to service account JSON file (for server-to-server auth)
206# service_account_file = "/path/to/service-account.json"
207
208# Path to client secrets JSON file (for OAuth flow)
209# client_secrets_file = "/path/to/client-secrets.json"
210
211# Path to token storage file (for OAuth flow)
212# token_file = "/path/to/token.json"
213
214# Default spreadsheet ID (can be overridden in commands)
215# default_spreadsheet_id = "your-spreadsheet-id"
216
217# API key for read-only access to public sheets
218# api_key = "your-api-key"
219"#
220 }
221}