config/
file.rs

1use std::path::{Path, PathBuf};
2use std::time::Duration;
3
4/// Represents a file configuration source.
5#[derive(Clone)]
6pub struct FileSource {
7    /// Gets or sets the source file path.
8    pub path: PathBuf,
9
10    /// Gets or sets a value indicating whether the file is optional.
11    /// The default value is false.
12    pub optional: bool,
13
14    /// Gets or sets a value indicating whether the file will be loaded
15    /// if the underlying file changes. The default value is false.
16    pub reload_on_change: bool,
17
18    /// Get or sets the amount of time to wait after a change before reloading.
19    /// The default value is 250ms.
20    ///
21    /// # Remarks
22    ///
23    /// This helps avoid triggering reload before a file is completely written.
24    pub reload_delay: Duration,
25}
26
27impl FileSource {
28    /// Initializes a new file configuration source.
29    ///
30    /// # Arguments
31    ///
32    /// * `path` - The source file path
33    /// * `optional` - Indicates whether the source file must exist
34    /// * `reload_on_change` - Indicates if a reload should occur if the source file changes
35    /// * `reload_delay` - The amount of delay before reload after the source file changes
36    pub fn new(
37        path: PathBuf,
38        optional: bool,
39        reload_on_change: bool,
40        reload_delay: Option<Duration>,
41    ) -> Self {
42        Self {
43            path,
44            optional,
45            reload_on_change,
46            reload_delay: reload_delay.unwrap_or(Duration::from_millis(250)),
47        }
48    }
49
50    /// Initializes a new, optional file configuration source.
51    ///
52    /// # Arguments
53    ///
54    /// * `path` - The source file path
55    pub fn optional<P: AsRef<Path>>(path: P) -> Self {
56        Self::new(path.as_ref().to_path_buf(), true, false, None)
57    }
58}
59
60impl From<PathBuf> for FileSource {
61    fn from(value: PathBuf) -> Self {
62        Self::new(value, false, false, None)
63    }
64}
65
66impl From<&PathBuf> for FileSource {
67    fn from(value: &PathBuf) -> Self {
68        Self::from(value.clone())
69    }
70}
71
72impl From<&Path> for FileSource {
73    fn from(value: &Path) -> Self {
74        Self::from(value.to_path_buf())
75    }
76}
77
78impl From<&str> for FileSource {
79    fn from(value: &str) -> Self {
80        Self::from(PathBuf::from(value))
81    }
82}
83
84impl From<String> for FileSource {
85    fn from(value: String) -> Self {
86        Self::from(PathBuf::from(value))
87    }
88}
89
90impl From<&String> for FileSource {
91    fn from(value: &String) -> Self {
92        Self::from(PathBuf::from(value))
93    }
94}
95
96/// Represents a builder for a file source.
97pub struct FileSourceBuilder {
98    path: PathBuf,
99    optional: bool,
100    reload_on_change: bool,
101    reload_delay: Option<Duration>,
102}
103
104impl FileSourceBuilder {
105    /// Initializes a new file source builder.
106    ///
107    /// # Arguments
108    ///
109    /// * `path` - The path to build a file source for
110    pub fn new(path: PathBuf) -> Self {
111        Self {
112            path,
113            optional: false,
114            reload_on_change: false,
115            reload_delay: None,
116        }
117    }
118
119    /// Indicates the file source is optional.
120    pub fn optional(mut self) -> Self {
121        self.optional = true;
122        self
123    }
124
125    /// Indicates the file source can be reloaded.
126    pub fn reloadable(mut self) -> Self {
127        self.reload_on_change = true;
128        self
129    }
130
131    /// Sets the delay to wait before reloading when a file source changes.
132    pub fn reload_delay(mut self, delay: Duration) -> Self {
133        self.reload_delay = Some(delay);
134        self
135    }
136
137    /// Creates and returns a new [`FileSource`].
138    pub fn build(&self) -> FileSource {
139        FileSource::new(
140            self.path.clone(),
141            self.optional,
142            self.reload_on_change,
143            self.reload_delay,
144        )
145    }
146}
147
148impl From<FileSourceBuilder> for FileSource {
149    fn from(value: FileSourceBuilder) -> Self {
150        value.build()
151    }
152}
153
154impl From<&FileSourceBuilder> for FileSource {
155    fn from(value: &FileSourceBuilder) -> Self {
156        value.build()
157    }
158}
159
160pub mod ext {
161
162    use super::*;
163
164    /// Provides extension methods to create a [`FileSourceBuilder`].
165    pub trait FileSourceBuilderExtensions {
166        fn is(&self) -> FileSourceBuilder;
167    }
168
169    impl<T: AsRef<Path>> FileSourceBuilderExtensions for T {
170        fn is(&self) -> FileSourceBuilder {
171            FileSourceBuilder::new(self.as_ref().to_path_buf())
172        }
173    }
174}