Files
Jędrzej Stuczyński 4a1ce8154a chore: resolve 1.87 clippy warnings (#5802)
* Clippy in wallet & sdk

* Clippy in wallet

* Pin rust to 1.86 in builder

* apply changes from b7da75a18c

* missing nym-node features

* Box all the things

* additional boxes in the wallet

* post rebasing clippy

---------

Co-authored-by: dynco-nym <173912580+dynco-nym@users.noreply.github.com>
2025-05-27 11:08:36 +01:00

251 lines
7.9 KiB
Rust

// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use handlebars::{Handlebars, TemplateRenderError};
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::fs::{create_dir_all, File};
use std::io::Write;
use std::path::{Path, PathBuf};
use std::{fs, io};
pub use helpers::{parse_urls, OptionalSet};
pub use toml::de::Error as TomlDeError;
pub mod defaults;
pub mod error;
pub mod helpers;
pub mod legacy_helpers;
pub mod serde_helpers;
pub const NYM_DIR: &str = ".nym";
pub const DEFAULT_NYM_APIS_DIR: &str = "nym-api";
pub const DEFAULT_CONFIG_DIR: &str = "config";
pub const DEFAULT_DATA_DIR: &str = "data";
pub const DEFAULT_CONFIG_FILENAME: &str = "config.toml";
#[cfg(feature = "dirs")]
pub fn must_get_home() -> PathBuf {
if let Some(home_dir) = std::env::var_os("NYM_HOME_DIR") {
home_dir.into()
} else {
dirs::home_dir().expect("Failed to evaluate $HOME value")
}
}
#[cfg(feature = "dirs")]
pub fn may_get_home() -> Option<PathBuf> {
if let Some(home_dir) = std::env::var_os("NYM_HOME_DIR") {
Some(home_dir.into())
} else {
dirs::home_dir()
}
}
pub trait NymConfigTemplate: Serialize {
fn template(&self) -> &'static str;
fn format_to_string(&self) -> String {
// it is responsibility of whoever is implementing the trait to ensure the template is valid
Handlebars::new()
.render_template(self.template(), &self)
.unwrap()
}
fn format_to_writer<W: Write>(&self, writer: W) -> io::Result<()> {
if let Err(err) = Handlebars::new().render_template_to_write(self.template(), &self, writer)
{
match err {
TemplateRenderError::IOError(err, _) => return Err(err),
other_err => {
// it is responsibility of whoever is implementing the trait to ensure the template is valid
panic!("invalid template: {other_err}")
}
}
}
Ok(())
}
}
pub fn save_formatted_config_to_file<C, P>(config: &C, path: P) -> io::Result<()>
where
C: NymConfigTemplate,
P: AsRef<Path>,
{
let path = path.as_ref();
log::info!("saving config file to {}", path.display());
if let Some(parent) = path.parent() {
create_dir_all(parent)?;
}
let file = File::create(path)?;
// TODO: check for whether any of our configs store anything sensitive
// and change that to 0o644 instead
#[cfg(target_family = "unix")]
{
use std::os::unix::fs::PermissionsExt;
let mut perms = fs::metadata(path)?.permissions();
perms.set_mode(0o600);
fs::set_permissions(path, perms)?;
}
config.format_to_writer(file)
}
pub fn save_unformatted_config_to_file<C, P>(
config: &C,
path: P,
) -> Result<(), error::NymConfigTomlError>
where
C: Serialize + ?Sized,
P: AsRef<Path>,
{
let path = path.as_ref();
log::info!("saving config file to {}", path.display());
if let Some(parent) = path.parent() {
create_dir_all(parent)?;
}
let mut file = File::create(path)?;
// TODO: check for whether any of our configs store anything sensitive
// and change that to 0o644 instead
#[cfg(target_family = "unix")]
{
use std::os::unix::fs::PermissionsExt;
let mut perms = fs::metadata(path)?.permissions();
perms.set_mode(0o600);
fs::set_permissions(path, perms)?;
}
// let serde format the TOML in whatever ugly way it chooses
// TODO: in https://docs.rs/toml/latest/toml/fn.to_string_pretty.html it recommends using
// https://docs.rs/toml_edit/latest/toml_edit/struct.DocumentMut.html to preserve formatting
let toml_string = toml::to_string_pretty(config)?;
Ok(file.write_all(toml_string.as_bytes())?)
}
pub fn deserialize_config_from_toml_str<C>(raw: &str) -> Result<C, TomlDeError>
where
C: DeserializeOwned,
{
toml::from_str(raw)
}
pub fn read_config_from_toml_file<C, P>(path: P) -> io::Result<C>
where
C: DeserializeOwned,
P: AsRef<Path>,
{
log::trace!(
"trying to read config file from {}",
path.as_ref().display()
);
let content = fs::read_to_string(path)?;
// TODO: should we be preserving original error type instead?
deserialize_config_from_toml_str(&content).map_err(io::Error::other)
}
//
//
//
// pub trait NymConfig: Default + Serialize + DeserializeOwned {
// fn template(&self) -> &'static str;
//
// fn config_file_name() -> String {
// "config.toml".to_string()
// }
//
// fn default_root_directory() -> PathBuf;
//
// // default, most probable, implementations; can be easily overridden where required
// fn default_config_directory(id: &str) -> PathBuf {
// Self::default_root_directory()
// .join(id)
// .join(DEFAULT_CONFIG_DIR)
// }
//
// fn default_data_directory(id: &str) -> PathBuf {
// Self::default_root_directory()
// .join(id)
// .join(DEFAULT_DATA_DIR)
// }
//
// fn default_config_file_path(id: &str) -> PathBuf {
// Self::default_config_directory(id).join(Self::config_file_name())
// }
//
// // We provide a second set of functions that tries to not panic.
//
// fn try_default_root_directory() -> Option<PathBuf>;
//
// fn try_default_config_directory(id: &str) -> Option<PathBuf> {
// Self::try_default_root_directory().map(|d| d.join(id).join(DEFAULT_CONFIG_DIR))
// }
//
// fn try_default_data_directory(id: &str) -> Option<PathBuf> {
// Self::try_default_root_directory().map(|d| d.join(id).join(DEFAULT_DATA_DIR))
// }
//
// fn try_default_config_file_path(id: &str) -> Option<PathBuf> {
// Self::try_default_config_directory(id).map(|d| d.join(Self::config_file_name()))
// }
//
// fn root_directory(&self) -> PathBuf;
// fn config_directory(&self) -> PathBuf;
// fn data_directory(&self) -> PathBuf;
//
// fn save_to_file(&self, custom_location: Option<PathBuf>) -> io::Result<()> {
// Ok(())
// // let reg = Handlebars::new();
// // // it's whoever is implementing the trait responsibility to make sure you can execute your own template on your data
// // let templated_config = reg.render_template(Self::template(), self).unwrap();
// //
// // // make sure the whole directory structure actually exists
// // match custom_location.clone() {
// // Some(loc) => {
// // if let Some(parent_dir) = loc.parent() {
// // fs::create_dir_all(parent_dir)
// // } else {
// // Ok(())
// // }
// // }
// // None => fs::create_dir_all(self.config_directory()),
// // }?;
// //
// // let location = custom_location
// // .unwrap_or_else(|| self.config_directory().join(Self::config_file_name()));
// // log::info!("Configuration file will be saved to {:?}", location);
// //
// // cfg_if::cfg_if! {
// // if #[cfg(unix)] {
// // fs::write(location.clone(), templated_config)?;
// // let mut perms = fs::metadata(location.clone())?.permissions();
// // perms.set_mode(0o600);
// // fs::set_permissions(location, perms)?;
// // } else {
// // fs::write(location, templated_config)?;
// // }
// // }
// //
// // Ok(())
// }
//
// fn load_from_file(id: &str) -> io::Result<Self> {
// let file = Self::default_config_file_path(id);
// log::trace!("Loading from file: {:#?}", file);
// let config_contents = fs::read_to_string(file)?;
//
// toml::from_str(&config_contents)
// .map_err(|toml_err| io::Error::new(io::ErrorKind::Other, toml_err))
// }
// }