1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! # filecaster
//!
//! `filecaster` provides the core `FromFile` trait, which is used in conjunction with the
//! `filecaster-derive` crate to enable automatic deserialization and merging of
//! configuration from various file formats into Rust structs.
//!
//! This crate defines the fundamental interface for types that can be constructed
//! from an optional "shadow" representation, typically deserialized from a file.
//! The `filecaster-derive` crate provides a procedural macro to automatically
//! implement this trait for your structs, handling default values and merging logic.
//!
//! ## How it works
//!
//! The `FromFile` trait defines how a final configuration struct (`Self`) can be
//! constructed from an optional intermediate "shadow" struct (`Self::Shadow`).
//! The `filecaster-derive` macro generates this `Shadow` struct and the
//! `from_file` implementation for your configuration types.
//!
//! When you derive `FromFile` for a struct, `filecaster-derive` creates a
//! corresponding `YourStructFile` (the `Shadow` type) where all fields are
//! wrapped in `Option<T>`. This `YourStructFile` can then be deserialized
//! from a file (e.g., JSON, TOML, YAML) using `serde`.
//!
//! The `from_file` method then takes this `Option<YourStructFile>` and
//! constructs your final `YourStruct`, applying default values for any fields
//! that were `None` in the `YourStructFile`.
//!
//! ## Example
//!
//! While the `FromFile` trait is implemented via the `filecaster-derive` macro,
//! here's a conceptual example of how it's used:
//!
//! ```rust,ignore
//! use filecaster::FromFile;
//! use serde::{Deserialize, Serialize};
//!
//! // This struct would typically have `#[derive(FromFile)]`
//! // from the `filecaster-derive` crate.
//! #[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
//! struct AppConfig {
//! host: String,
//! port: u16,
//! auto_reload: bool,
//! }
//!
//! // The `Shadow` type is automatically generated by `filecaster-derive`
//! // and would look something like this:
//! #[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
//! struct AppConfigFile {
//! host: Option<String>,
//! port: Option<u16>,
//! auto_reload: Option<bool>,
//! }
//!
//! // The `FromFile` implementation is also automatically generated.
//! // For demonstration, here's a simplified manual implementation:
//! impl FromFile for AppConfig {
//! type Shadow = AppConfigFile;
//!
//! fn from_file(file: Option<Self::Shadow>) -> Self {
//! let file = file.unwrap_or_default();
//! AppConfig {
//! host: file.host.unwrap_or_else(|| "127.0.0.1".to_string()),
//! port: file.port.unwrap_or(8080),
//! auto_reload: file.auto_reload.unwrap_or(true),
//! }
//! }
//! }
//!
//! fn example() {
//! // Simulate deserializing from a file
//! let file_content = r#"{ "host": "localhost", "port": 3000 }"#;
//! let partial_config: AppConfigFile = serde_json::from_str(file_content).unwrap();
//!
//! // Construct the final config using the FromFile trait
//! let config = AppConfig::from_file(Some(partial_config));
//!
//! assert_eq!(config.host, "localhost");
//! assert_eq!(config.port, 3000);
//! assert_eq!(config.auto_reload, false); // `Default::default()` for bool is `false`
//!
//! println!("Final Config: {:#?}", config);
//!
//! // Example with no file content (all defaults)
//! let default_config = AppConfig::from_file(None);
//! assert_eq!(default_config.host, "127.0.0.1");
//! assert_eq!(default_config.port, 8080);
//! assert_eq!(default_config.auto_reload, false);
//! }
//! ```
//!
//! ## Feature flags
//!
//! - `derive`: Enables the `filecaster-derive` crate, allowing you to use `#[derive(FromFile)]`.
//! - `serde`: Enables `serde` serialization/deserialization support for the `FromFile` trait.
//! - `merge`: Enables `merge` crate support, allowing for merging multiple partial configurations.
pub use FromFile;
use ;
/// Marker for types that can be built from an [`Option<Shadow>`] produced by the macro.
///
/// The `FromFile` trait is the core interface for `filecaster`. It defines how a
/// final configuration struct (`Self`) can be constructed from an optional
/// intermediate "shadow" struct (`Self::Shadow`).
///
/// The `Self::Shadow` associated type represents the intermediate structure
/// that is typically deserialized from a configuration file. All fields in
/// `Self::Shadow` are usually `Option<T>`, allowing for partial configurations.
///
/// The `from_file` method takes an `Option<Self::Shadow>` and is responsible
/// for producing a fully-populated `Self` instance. This involves applying
/// default values for any fields that were `None` in the `Shadow` instance.
///
/// This trait is primarily designed to be implemented automatically via the
/// `#[derive(FromFile)]` procedural macro provided by the `filecaster-derive` crate.