data_gov/
config.rs

1use crate::colors::ColorMode;
2use data_gov_ckan::{ApiKey, Configuration as CkanConfiguration};
3use std::path::PathBuf;
4use std::sync::Arc;
5
6/// Operating mode for the client
7#[derive(Debug, Clone, PartialEq)]
8pub enum OperatingMode {
9    /// Interactive REPL mode - downloads to system Downloads directory
10    Interactive,
11    /// Command-line mode - downloads to current directory
12    CommandLine,
13}
14
15/// Configuration for the Data.gov client
16#[derive(Debug, Clone)]
17pub struct DataGovConfig {
18    /// CKAN client configuration
19    pub ckan_config: Arc<CkanConfiguration>,
20    /// Operating mode (affects base download directory)
21    pub mode: OperatingMode,
22    /// Base download directory for files (before dataset subdirectory)
23    pub base_download_dir: PathBuf,
24    /// User agent for HTTP requests
25    pub user_agent: String,
26    /// Maximum concurrent downloads
27    pub max_concurrent_downloads: usize,
28    /// Timeout for downloads in seconds
29    pub download_timeout_secs: u64,
30    /// Enable progress bars for downloads
31    pub show_progress: bool,
32    /// Color mode for output
33    pub color_mode: ColorMode,
34}
35
36impl Default for DataGovConfig {
37    fn default() -> Self {
38        Self {
39            ckan_config: Arc::new(CkanConfiguration::default()),
40            mode: OperatingMode::Interactive, // Default to interactive mode
41            base_download_dir: Self::get_default_download_dir(),
42            user_agent: "data-gov-rs/1.0".to_string(),
43            max_concurrent_downloads: 3,
44            download_timeout_secs: 300, // 5 minutes
45            show_progress: true,
46            color_mode: ColorMode::default(),
47        }
48    }
49}
50
51impl DataGovConfig {
52    /// Get the default download directory (system Downloads folder)
53    fn get_default_download_dir() -> PathBuf {
54        // Try to get the user's Downloads directory
55        if let Some(download_dir) = dirs::download_dir() {
56            download_dir
57        } else {
58            // Fallback to home directory + Downloads
59            let home = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
60            home.join("Downloads")
61        }
62    }
63
64    /// Create a new configuration for data.gov
65    pub fn new() -> Self {
66        Self::default()
67    }
68
69    /// Create configuration with custom base download directory
70    pub fn with_download_dir<P: Into<PathBuf>>(mut self, dir: P) -> Self {
71        self.base_download_dir = dir.into();
72        self
73    }
74
75    /// Set the operating mode
76    pub fn with_mode(mut self, mode: OperatingMode) -> Self {
77        self.mode = mode;
78        self
79    }
80
81    /// Get the base download directory based on operating mode
82    pub fn get_base_download_dir(&self) -> PathBuf {
83        match self.mode {
84            OperatingMode::Interactive => {
85                // Use the configured base directory (usually system Downloads)
86                self.base_download_dir.clone()
87            }
88            OperatingMode::CommandLine => {
89                // Use current working directory for CLI mode
90                std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."))
91            }
92        }
93    }
94
95    /// Get the full download directory for a specific dataset
96    pub fn get_dataset_download_dir(&self, dataset_name: &str) -> PathBuf {
97        self.get_base_download_dir().join(dataset_name)
98    }
99
100    /// Add API key for higher rate limits
101    pub fn with_api_key<S: Into<String>>(mut self, api_key: S) -> Self {
102        let mut ckan_config = (*self.ckan_config).clone();
103        ckan_config.api_key = Some(ApiKey {
104            key: api_key.into(),
105            prefix: None,
106        });
107        self.ckan_config = Arc::new(ckan_config);
108        self
109    }
110
111    /// Set custom user agent
112    pub fn with_user_agent<S: Into<String>>(mut self, user_agent: S) -> Self {
113        self.user_agent = user_agent.into();
114        let mut ckan_config = (*self.ckan_config).clone();
115        ckan_config.user_agent = Some(self.user_agent.clone());
116        self.ckan_config = Arc::new(ckan_config);
117        self
118    }
119
120    /// Set maximum concurrent downloads
121    pub fn with_max_concurrent_downloads(mut self, max: usize) -> Self {
122        self.max_concurrent_downloads = max.max(1);
123        self
124    }
125
126    /// Set download timeout
127    pub fn with_download_timeout(mut self, timeout_secs: u64) -> Self {
128        self.download_timeout_secs = timeout_secs;
129        self
130    }
131
132    /// Enable or disable progress bars
133    pub fn with_progress(mut self, show_progress: bool) -> Self {
134        self.show_progress = show_progress;
135        self
136    }
137
138    /// Set color mode
139    pub fn with_color_mode(mut self, color_mode: ColorMode) -> Self {
140        self.color_mode = color_mode;
141        self
142    }
143}