cfgmatic_files/lib.rs
1//! Configuration file discovery and reading with multiple format support.
2//!
3//! **DEPRECATED**: This crate is deprecated since version 2.0.1.
4//! Use `cfgmatic-source` instead, which provides a more comprehensive
5//! and unified API for configuration source management.
6//!
7//! # Migration Guide
8//!
9//! This crate has been superseded by `cfgmatic-source`. Below is a guide
10//! for migrating your code to the new API.
11//!
12//! ## Crate Replacement
13//!
14//! Replace in `Cargo.toml`:
15//! ```toml
16//! // Old (deprecated)
17//! [dependencies]
18//! cfgmatic-files = "2.0"
19//!
20//! // New
21//! [dependencies]
22//! cfgmatic-source = "2.0"
23//! ```
24//!
25//! ## Type Mappings
26//!
27//! | Old (cfgmatic-files) | New (cfgmatic-source) | Notes |
28//! |----------------------|----------------------|-------|
29//! | `ConfigFile` | `FileSource` | File-based configuration source |
30//! | `ConfigFiles` | `CompositeSource` | Multiple sources with priority |
31//! | `FileFinder` | `Loader` with `FileConfig` | Unified loading interface |
32//! | `Mergeable` | `Merge` trait from `cfgmatic-merge` | Direct merge trait |
33//! | `Format` | `cfgmatic_source::Format` | Same enum, new location |
34//! | `FileError` | `SourceError` | Unified error type |
35//!
36//! ## API Examples
37//!
38//! ### Loading a Single File
39//!
40//! ```rust,ignore
41//! // Old API (deprecated)
42//! use cfgmatic_files::FileFinder;
43//! let files = FileFinder::new("myapp").find()?;
44//! let config: Config = files.first().unwrap().parse()?;
45//!
46//! // New API
47//! use cfgmatic_source::prelude::*;
48//! let config: Config = FileSource::new("config.toml").load()?.parse_as()?;
49//! ```
50//!
51//! ### Loading with Multiple Sources
52//!
53//! ```rust,ignore
54//! // Old API (deprecated)
55//! use cfgmatic_files::load_merged;
56//! let config: Config = load_merged("myapp")?;
57//!
58//! // New API
59//! use cfgmatic_source::prelude::*;
60//! let source = CompositeSource::new()
61//! .with_source(FileSource::new("config.toml"), SourcePriority::High)
62//! .with_source(EnvSource::new("APP"), SourcePriority::Low);
63//! let config: Config = source.load()?.parse_as()?;
64//! ```
65//!
66//! ### Finding Config Files
67//!
68//! ```rust,ignore
69//! // Old API (deprecated)
70//! use cfgmatic_files::{FileFinder, find_files};
71//! let files = find_files("myapp")?;
72//!
73//! // New API
74//! use cfgmatic_source::prelude::*;
75//! let loader = Loader::new()
76//! .with_source(FileConfig::new().app_name("myapp"));
77//! let result = loader.load()?;
78//! ```
79//!
80//! # Features
81//!
82//! The new `cfgmatic-source` crate supports all features from this crate:
83//!
84//! - `toml` - TOML format support (default)
85//! - `json` - JSON format support (default)
86//! - `yaml` - YAML format support
87//! - `env` - Environment variable sources
88//! - `async` - Async loading support
89//! - `remote` - Remote HTTP/HTTPS sources
90//! - `watch` - File watching support
91//!
92//! # Transition Period
93//!
94//! During the transition period, this crate re-exports types from
95//! `cfgmatic-source` for convenience. However, new code should use
96//! `cfgmatic-source` directly.
97
98#![deprecated(
99 since = "2.0.1",
100 note = "use cfgmatic-source crate instead, which provides a unified configuration source API"
101)]
102#![warn(missing_docs)]
103// Deprecated crate - allow all pedantic lints and deprecated usage internally
104#![allow(deprecated)]
105#![allow(clippy::all)]
106#![allow(clippy::pedantic)]
107#![allow(clippy::cargo)]
108
109// =============================================================================
110// Re-exports from cfgmatic-source (new API)
111// =============================================================================
112
113/// Re-export of cfgmatic-source types for migration convenience.
114pub use cfgmatic_source::{
115 LoadResult, Loader, LoaderBuilder, Source, SourceError, SourceKind, SourceMetadata,
116};
117
118// Feature-gated re-exports from cfgmatic-source
119#[cfg(feature = "toml")]
120pub use cfgmatic_source::FileSource;
121
122// =============================================================================
123// Legacy types (deprecated but kept for backwards compatibility)
124// =============================================================================
125
126// Legacy module
127mod legacy;
128
129pub use error::{FileError, Result};
130pub use file::{ConfigFile, ConfigFiles, Mergeable};
131pub use finder::{FileFinder, FileFinderState, find_files, find_first_file, load_first};
132pub use format::Format;
133pub use loader::{RuleBasedLoader, load_with_rules};
134pub use merge::{ArrayMergeStrategy, MergeBehavior, MergeOptions};
135
136// Re-export from cfgmatic-paths for convenience (legacy)
137pub use cfgmatic_paths::{
138 ConfigCandidate, ConfigFileRule, ConfigRuleSet, ConfigTier, FragmentRule, RuleBasedDiscovery,
139 TierSearchMode,
140};
141
142mod error;
143mod file;
144mod finder;
145mod format;
146mod loader;
147mod merge;
148
149/// Convenience functions for common operations.
150///
151/// **Deprecated**: Use `cfgmatic_source::prelude` instead.
152pub mod prelude {
153 /// Common imports for working with configuration files.
154 ///
155 /// **Deprecated**: Use `cfgmatic_source::prelude` instead.
156 #[deprecated(since = "2.0.1", note = "use cfgmatic_source::prelude instead")]
157 pub use crate::{
158 ArrayMergeStrategy, ConfigFile, ConfigFiles, ConfigTier, FileFinder, FileFinderState,
159 Format, MergeBehavior, MergeOptions, Mergeable, Result, find_files, find_first_file,
160 load_first,
161 };
162
163 // Re-export new types for migration
164 pub use cfgmatic_source::{
165 Format as SourceFormat, LoadResult, Loader, LoaderBuilder, Source, SourceError, SourceKind,
166 SourceMetadata,
167 };
168
169 #[cfg(feature = "toml")]
170 pub use cfgmatic_source::FileSource;
171}
172
173/// Load and merge configuration from all found files.
174///
175/// **Deprecated**: Use `cfgmatic_source::Loader` instead.
176///
177/// # Example
178///
179/// ```
180/// use cfgmatic_files::load_merged;
181///
182/// match load_merged::<serde_json::Value>("myapp") {
183/// Ok(config) => println!("Loaded: {:?}", config),
184/// Err(e) => eprintln!("Failed to load config: {}", e),
185/// }
186/// ```
187///
188/// # Errors
189///
190/// Returns an error if directories cannot be accessed or files cannot be parsed.
191#[deprecated(since = "2.0.1", note = "use cfgmatic_source::Loader instead")]
192pub fn load_merged<T: serde::de::DeserializeOwned + Mergeable + Default>(
193 app_name: impl Into<String>,
194) -> Result<T> {
195 let mut files = FileFinder::new(app_name).find()?;
196 files.merge()
197}
198
199/// Find configuration files with a specific format.
200///
201/// **Deprecated**: Use `cfgmatic_source::Loader` with `FileConfig` instead.
202///
203/// # Example
204///
205/// ```
206/// use cfgmatic_files::find_with_format;
207///
208/// let files = find_with_format("myapp", cfgmatic_files::Format::Toml)
209/// .expect("find toml files");
210/// ```
211///
212/// # Errors
213///
214/// Returns an error if directories cannot be accessed.
215#[deprecated(
216 since = "2.0.1",
217 note = "use cfgmatic_source::Loader with FileConfig instead"
218)]
219pub fn find_with_format(app_name: impl Into<String>, format: Format) -> Result<ConfigFiles> {
220 FileFinder::new(app_name).formats(&[format]).find()
221}
222
223/// Check if a configuration exists for the application.
224///
225/// Returns `true` if at least one configuration file is found.
226#[deprecated(since = "2.0.1", note = "use cfgmatic_source::Loader instead")]
227pub fn config_exists(app_name: impl Into<String>) -> bool {
228 find_first_file(app_name)
229 .map(|f| f.is_some())
230 .unwrap_or(false)
231}
232
233#[cfg(test)]
234mod tests {
235 use super::*;
236
237 #[test]
238 #[allow(deprecated)]
239 fn test_module_exports() {
240 // Just verify all public types are accessible
241 let _: FileFinder = FileFinder::new("test");
242 let _: Format = Format::Toml;
243 }
244
245 #[test]
246 #[allow(deprecated)]
247 fn test_config_exists_nonexistent() {
248 assert!(!config_exists("nonexistent_app_12345"));
249 }
250}