Skip to main content

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}