Skip to main content

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(path: PathBuf, optional: bool, reload_on_change: bool, reload_delay: Option<Duration>) -> Self {
37        Self {
38            path,
39            optional,
40            reload_on_change,
41            reload_delay: reload_delay.unwrap_or(Duration::from_millis(250)),
42        }
43    }
44
45    /// Initializes a new, optional file configuration source.
46    ///
47    /// # Arguments
48    ///
49    /// * `path` - The source file path
50    pub fn optional<P: AsRef<Path>>(path: P) -> Self {
51        Self::new(path.as_ref().to_path_buf(), true, false, None)
52    }
53}
54
55impl From<PathBuf> for FileSource {
56    fn from(value: PathBuf) -> Self {
57        Self::new(value, false, false, None)
58    }
59}
60
61impl From<&PathBuf> for FileSource {
62    fn from(value: &PathBuf) -> Self {
63        Self::from(value.clone())
64    }
65}
66
67impl From<&Path> for FileSource {
68    fn from(value: &Path) -> Self {
69        Self::from(value.to_path_buf())
70    }
71}
72
73impl From<&str> for FileSource {
74    fn from(value: &str) -> Self {
75        Self::from(PathBuf::from(value))
76    }
77}
78
79impl From<String> for FileSource {
80    fn from(value: String) -> Self {
81        Self::from(PathBuf::from(value))
82    }
83}
84
85impl From<&String> for FileSource {
86    fn from(value: &String) -> Self {
87        Self::from(PathBuf::from(value))
88    }
89}
90
91/// Represents a builder for a file source.
92pub struct FileSourceBuilder {
93    path: PathBuf,
94    optional: bool,
95    reload_on_change: bool,
96    reload_delay: Option<Duration>,
97}
98
99impl FileSourceBuilder {
100    /// Initializes a new file source builder.
101    ///
102    /// # Arguments
103    ///
104    /// * `path` - The path to build a file source for
105    pub fn new(path: PathBuf) -> Self {
106        Self {
107            path,
108            optional: false,
109            reload_on_change: false,
110            reload_delay: None,
111        }
112    }
113
114    /// Indicates the file source is optional.
115    pub fn optional(mut self) -> Self {
116        self.optional = true;
117        self
118    }
119
120    /// Indicates the file source can be reloaded.
121    pub fn reloadable(mut self) -> Self {
122        self.reload_on_change = true;
123        self
124    }
125
126    /// Sets the delay to wait before reloading when a file source changes.
127    pub fn reload_delay(mut self, delay: Duration) -> Self {
128        self.reload_delay = Some(delay);
129        self
130    }
131
132    /// Creates and returns a new [`FileSource`].
133    pub fn build(&self) -> FileSource {
134        FileSource::new(
135            self.path.clone(),
136            self.optional,
137            self.reload_on_change,
138            self.reload_delay,
139        )
140    }
141}
142
143impl From<FileSourceBuilder> for FileSource {
144    fn from(value: FileSourceBuilder) -> Self {
145        value.build()
146    }
147}
148
149impl From<&FileSourceBuilder> for FileSource {
150    fn from(value: &FileSourceBuilder) -> Self {
151        value.build()
152    }
153}
154
155pub mod ext {
156
157    use super::*;
158
159    /// Provides extension methods to create a [`FileSourceBuilder`].
160    pub trait FileSourceBuilderExtensions {
161        fn is(&self) -> FileSourceBuilder;
162    }
163
164    impl<T: AsRef<Path>> FileSourceBuilderExtensions for T {
165        fn is(&self) -> FileSourceBuilder {
166            FileSourceBuilder::new(self.as_ref().to_path_buf())
167        }
168    }
169}