bsky_sdk/agent/config/
file.rs

1use super::{Config, Loader, Saver};
2use anyhow::anyhow;
3use std::path::{Path, PathBuf};
4
5/// An implementation of [`Loader`] and [`Saver`] that reads and writes a configuration file.
6pub struct FileStore {
7    path: PathBuf,
8}
9
10impl FileStore {
11    /// Create a new [`FileStore`] with the given path.
12    ///
13    /// This `FileStore` will read and write to the file at the given path.
14    /// [`Config`] data will be serialized and deserialized using the file extension.
15    /// By default, this supports only `.json` files.
16    pub fn new(path: impl AsRef<Path>) -> Self {
17        Self { path: path.as_ref().to_path_buf() }
18    }
19}
20
21impl Loader for FileStore {
22    async fn load(
23        &self,
24    ) -> core::result::Result<Config, Box<dyn std::error::Error + Send + Sync + 'static>> {
25        match self.path.extension().and_then(|ext| ext.to_str()) {
26            Some("json") => Ok(serde_json::from_str(&std::fs::read_to_string(&self.path)?)?),
27            #[cfg(feature = "config-toml")]
28            Some("toml") => Ok(toml::from_str(&std::fs::read_to_string(&self.path)?)?),
29            _ => Err(anyhow!("Unsupported file format").into()),
30        }
31    }
32}
33
34impl Saver for FileStore {
35    async fn save(
36        &self,
37        config: &Config,
38    ) -> core::result::Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
39        match self.path.extension().and_then(|ext| ext.to_str()) {
40            Some("json") => Ok(std::fs::write(&self.path, serde_json::to_string_pretty(config)?)?),
41            #[cfg(feature = "config-toml")]
42            Some("toml") => Ok(std::fs::write(&self.path, toml::to_string_pretty(config)?)?),
43            _ => Err(anyhow!("Unsupported file format").into()),
44        }
45    }
46}