use std::fs::{File, create_dir_all};
use std::io::Write;
use std::path::{Path, PathBuf};
use namada_sdk::chain::ChainId;
use serde::{Deserialize, Serialize};
use thiserror::Error;
pub const FILENAME: &str = "global-config.toml";
#[derive(Error, Debug)]
pub enum Error {
#[error("Error while reading config: {0}")]
ReadError(config::ConfigError),
#[error("Error while deserializing config: {0}")]
DeserializationError(config::ConfigError),
#[error("Error while writing config: {0}")]
WriteError(std::io::Error),
#[error("Error while serializing to toml: {0}")]
TomlError(toml::ser::Error),
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct GlobalConfig {
pub default_chain_id: Option<ChainId>,
}
impl GlobalConfig {
pub fn new(default_chain_id: ChainId) -> Self {
Self {
default_chain_id: Some(default_chain_id),
}
}
pub fn read(base_dir: impl AsRef<Path>) -> Result<Self> {
let file_path = Self::file_path(base_dir.as_ref());
let file_name = file_path.to_str().expect("Expected UTF-8 file path");
let mut config = config::Config::default();
if file_path.exists() {
config = config::Config::builder()
.add_source(config::File::with_name(file_name))
.build()
.map_err(Error::ReadError)?;
}
config
.try_deserialize()
.map_err(|e: config::ConfigError| Error::DeserializationError(e))
}
pub fn write(&self, base_dir: impl AsRef<Path>) -> Result<()> {
let file_path = Self::file_path(base_dir.as_ref());
let file_dir = file_path.parent().unwrap();
create_dir_all(file_dir).map_err(Error::WriteError)?;
let mut file = File::create(file_path).map_err(Error::WriteError)?;
let toml = toml::ser::to_string(&self).map_err(Error::TomlError)?;
file.write_all(toml.as_bytes()).map_err(Error::WriteError)
}
pub fn file_path(base_dir: impl AsRef<Path>) -> PathBuf {
base_dir.as_ref().join(FILENAME)
}
}