fluvio_types/
config_file.rs1use std::fmt::Debug;
2use std::io::Error as IoError;
3use std::io::Write;
4use std::path::Path;
5use std::fs::{File, read_to_string};
6
7use tracing::debug;
8use serde::{Serialize, de::DeserializeOwned};
9use thiserror::Error;
10
11#[derive(Debug, Error)]
12pub enum LoadConfigError {
13 #[error("IoError: {0}")]
14 IoError(IoError),
15 #[error("TomlError: {0}")]
16 TomlError(toml::de::Error),
17}
18
19pub trait SaveLoadConfig {
20 fn save_to<T: AsRef<Path>>(&self, path: T) -> Result<(), IoError>;
21 fn load_from<T: AsRef<Path>>(path: T) -> Result<Self, LoadConfigError>
22 where
23 Self: Sized;
24 fn load_str(config: &str) -> Result<Self, LoadConfigError>
25 where
26 Self: Sized;
27}
28
29impl<S> SaveLoadConfig for S
30where
31 S: Serialize + DeserializeOwned + Debug,
32{
33 fn save_to<T: AsRef<Path>>(&self, path: T) -> Result<(), IoError> {
35 let path_ref = path.as_ref();
36 debug!("saving config: {:#?} to: {:#?}", self, path_ref);
37 let toml = toml::to_string(self).map_err(|err| IoError::other(format!("{err}")))?;
38
39 let mut file = File::create(path_ref)?;
40 file.write_all(toml.as_bytes())?;
41 file.sync_all()
43 }
44
45 fn load_from<T: AsRef<Path>>(path: T) -> Result<Self, LoadConfigError> {
46 let path_ref = path.as_ref();
47 debug!(?path_ref, "loading from");
48
49 let file_str = read_to_string(path_ref).map_err(LoadConfigError::IoError)?;
50
51 let config = toml::from_str(&file_str).map_err(LoadConfigError::TomlError)?;
52 Ok(config)
53 }
54
55 fn load_str(config: &str) -> Result<Self, LoadConfigError>
56 where
57 Self: Sized,
58 {
59 let config = toml::from_str(config).map_err(LoadConfigError::TomlError)?;
60 Ok(config)
61 }
62}