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