Skip to main content

oku_fs/
config.rs

1use crate::{
2    discovery::{DEFAULT_INITIAL_PUBLISH_DELAY, DEFAULT_REPUBLISH_DELAY},
3    fs::FS_PATH,
4};
5use log::error;
6use miette::{miette, IntoDiagnostic};
7use serde::{Deserialize, Serialize};
8use std::{
9    path::PathBuf,
10    sync::{Arc, LazyLock, Mutex},
11    time::Duration,
12};
13
14pub(crate) static CONFIG_PATH: LazyLock<PathBuf> =
15    LazyLock::new(|| PathBuf::from(FS_PATH).join("config.toml"));
16
17#[derive(Clone, Debug, Serialize, Deserialize)]
18/// Configuration of an Oku file system node.
19pub struct OkuFsConfig {
20    /// The delay between republishing content to the Mainline DHT (defaults to [`crate::discovery::DEFAULT_REPUBLISH_DELAY`]).
21    republish_delay: Arc<Mutex<Option<Duration>>>,
22    /// The initial delay before publishing content to the Mainline DHT (defaults to [`crate::discovery::DEFAULT_INITIAL_PUBLISH_DELAY`]).
23    initial_publish_delay: Arc<Mutex<Option<Duration>>>,
24}
25
26impl Default for OkuFsConfig {
27    fn default() -> Self {
28        Self {
29            republish_delay: Arc::new(Mutex::new(None)),
30            initial_publish_delay: Arc::new(Mutex::new(None)),
31        }
32    }
33}
34
35impl OkuFsConfig {
36    /// Loads the configuration of the file system from disk, or creates a new configuration if none exists.
37    ///
38    /// # Returns
39    ///
40    /// The configuration of the file system.
41    pub fn load_or_create_config() -> miette::Result<Self> {
42        let config_file_contents = std::fs::read_to_string(&*CONFIG_PATH);
43        match config_file_contents {
44            Ok(config_file_toml) => match toml::from_str(&config_file_toml) {
45                Ok(config) => Ok(config),
46                Err(e) => {
47                    error!("{}", e);
48                    let config = Self::default();
49                    Ok(config)
50                }
51            },
52            Err(e) => {
53                error!("{}", e);
54                let config = Self::default();
55                let config_toml = toml::to_string_pretty(&config).into_diagnostic()?;
56                std::fs::write(&*CONFIG_PATH, config_toml).into_diagnostic()?;
57                Ok(config)
58            }
59        }
60    }
61
62    /// Writes the configuration to disk.
63    pub fn save(&self) -> miette::Result<()> {
64        let config_toml = toml::to_string_pretty(&self).into_diagnostic()?;
65        std::fs::write(&*CONFIG_PATH, config_toml).into_diagnostic()?;
66        Ok(())
67    }
68
69    /// Gets [`OkuFsConfig::republish_delay`].
70    ///
71    /// # Returns
72    ///
73    /// [`OkuFsConfig::republish_delay`] if set, or [`crate::discovery::DEFAULT_REPUBLISH_DELAY`] otherwise.
74    pub fn get_republish_delay(&self) -> Duration {
75        self.republish_delay
76            .try_lock()
77            .ok()
78            .map(|x| x.to_owned())
79            .flatten()
80            .unwrap_or(DEFAULT_REPUBLISH_DELAY)
81    }
82
83    /// Sets [`OkuFsConfig::republish_delay`].
84    ///
85    /// # Arguments
86    ///
87    /// * `republish_delay` - An optional republish delay; if unspecified, the default will be used.
88    pub fn set_republish_delay(&self, republish_delay: &Option<Duration>) -> miette::Result<()> {
89        *self
90            .republish_delay
91            .try_lock()
92            .map_err(|e| miette!("{}", e))? = *republish_delay;
93        Ok(())
94    }
95
96    /// Gets [`OkuFsConfig::initial_publish_delay`].
97    ///
98    /// # Returns
99    ///
100    /// [`OkuFsConfig::initial_publish_delay`] if set, or [`crate::discovery::DEFAULT_INITIAL_PUBLISH_DELAY`] otherwise.
101    pub fn get_initial_publish_delay(&self) -> Duration {
102        self.initial_publish_delay
103            .try_lock()
104            .ok()
105            .map(|x| x.to_owned())
106            .flatten()
107            .unwrap_or(DEFAULT_INITIAL_PUBLISH_DELAY)
108    }
109
110    /// Sets [`OkuFsConfig::initial_publish_delay`].
111    ///
112    /// # Arguments
113    ///
114    /// * `initial_publish_delay` - An optional initial publish delay; if unspecified, the default will be used.
115    pub fn set_initial_publish_delay(
116        &self,
117        initial_publish_delay: &Option<Duration>,
118    ) -> miette::Result<()> {
119        *self
120            .initial_publish_delay
121            .try_lock()
122            .map_err(|e| miette!("{}", e))? = *initial_publish_delay;
123        Ok(())
124    }
125}