markdown_translator/
config.rs

1//! 配置管理模块
2//!
3//! 提供TOML配置文件的读取、写入和自动发现功能。
4
5use crate::types::TranslationConfig;
6use serde::{Deserialize, Serialize};
7use std::fs;
8use std::path::Path;
9
10/// 翻译库配置结构
11///
12/// 包含所有翻译相关的配置选项,支持从TOML文件加载和保存。
13///
14/// # 示例
15///
16/// ```rust
17/// use markdown_translator::TranslationLibConfig;
18///
19/// // 从默认位置加载配置
20/// let config = TranslationLibConfig::load_from_default_locations();
21///
22/// // 从指定文件加载配置
23/// let config = TranslationLibConfig::from_file("config.toml").unwrap();
24///
25/// // 保存配置到文件
26/// config.save_to_file("output.toml").unwrap();
27/// ```
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct TranslationLibConfig {
30    /// 翻译配置
31    #[serde(default)]
32    pub translation: TranslationConfig,
33}
34
35impl Default for TranslationLibConfig {
36    fn default() -> Self {
37        Self {
38            translation: TranslationConfig::default(),
39        }
40    }
41}
42
43impl TranslationLibConfig {
44    /// Load configuration from TOML file
45    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, Box<dyn std::error::Error>> {
46        let content = fs::read_to_string(path)?;
47        let config: TranslationLibConfig = toml::from_str(&content)?;
48        Ok(config)
49    }
50
51    /// Save configuration to TOML file
52    pub fn save_to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), Box<dyn std::error::Error>> {
53        let content = toml::to_string_pretty(self)?;
54        fs::write(path, content)?;
55        Ok(())
56    }
57
58    /// Load configuration from multiple possible locations
59    pub fn load_from_default_locations() -> Self {
60        let possible_paths = [
61            "translation-config.toml",
62            "config.toml",
63            ".translation-config.toml",
64        ];
65
66        for path in &possible_paths {
67            if Path::new(path).exists() {
68                match Self::from_file(path) {
69                    Ok(config) => {
70                        println!("Loaded configuration from: {}", path);
71                        return config;
72                    }
73                    Err(e) => {
74                        eprintln!("Warning: Failed to load config from {}: {}", path, e);
75                    }
76                }
77            }
78        }
79
80        println!("No configuration file found, using defaults");
81        Self::default()
82    }
83
84    /// Generate example configuration file
85    pub fn generate_example_config<P: AsRef<Path>>(
86        path: P,
87    ) -> Result<(), Box<dyn std::error::Error>> {
88        let example_config = Self::default();
89        example_config.save_to_file(path)?;
90        Ok(())
91    }
92}