pub use crate::error::FormatterError;
use crate::{
config::{
comments::Comments, expr::Expressions, heuristics::Heuristics, imports::Imports,
items::Items, lists::Lists, literals::Literals, ordering::Ordering, user_def::Structures,
user_opts::*, whitespace::Whitespace,
},
constants::SWAY_FORMAT_FILE_NAME,
error::ConfigError,
};
use forc_util::{find_parent_dir_with_file, println_yellow_err};
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
#[derive(Debug, Default, Clone)]
pub struct Config {
pub whitespace: Whitespace,
pub imports: Imports,
pub ordering: Ordering,
pub items: Items,
pub lists: Lists,
pub literals: Literals,
pub expressions: Expressions,
pub heuristics: Heuristics,
pub structures: Structures,
pub comments: Comments,
}
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
#[serde(rename_all = "snake_case")]
pub struct ConfigOptions {
pub whitespace: Option<WhitespaceOptions>,
pub imports: Option<ImportsOptions>,
pub ordering: Option<OrderingOptions>,
pub items: Option<ItemsOptions>,
pub lists: Option<ListsOptions>,
pub literals: Option<LiteralsOptions>,
pub expressions: Option<ExpressionsOptions>,
pub heuristics: Option<HeuristicsOptions>,
pub structures: Option<StructuresOptions>,
pub comments: Option<CommentsOptions>,
}
impl Config {
pub fn from_opts(opts: ConfigOptions) -> Self {
Self {
whitespace: opts
.whitespace
.as_ref()
.map(Whitespace::from_opts)
.unwrap_or_default(),
imports: opts
.imports
.as_ref()
.map(Imports::from_opts)
.unwrap_or_default(),
ordering: opts
.ordering
.as_ref()
.map(Ordering::from_opts)
.unwrap_or_default(),
items: opts
.items
.as_ref()
.map(Items::from_opts)
.unwrap_or_default(),
lists: opts
.lists
.as_ref()
.map(Lists::from_opts)
.unwrap_or_default(),
literals: opts
.literals
.as_ref()
.map(Literals::from_opts)
.unwrap_or_default(),
expressions: opts
.expressions
.as_ref()
.map(Expressions::from_opts)
.unwrap_or_default(),
heuristics: opts
.heuristics
.as_ref()
.map(Heuristics::from_opts)
.unwrap_or_default(),
structures: opts
.structures
.as_ref()
.map(Structures::from_opts)
.unwrap_or_default(),
comments: opts
.comments
.as_ref()
.map(Comments::from_opts)
.unwrap_or_default(),
}
}
pub fn from_dir(config_path: &Path) -> Result<Self, ConfigError> {
let config_opts = ConfigOptions::from_dir(config_path)?;
Ok(Self::from_opts(config_opts))
}
}
impl ConfigOptions {
pub fn from_file(config_path: PathBuf) -> Result<Self, ConfigError> {
let config_str =
std::fs::read_to_string(&config_path).map_err(|e| ConfigError::ReadConfig {
path: config_path,
err: e,
})?;
let toml_de = &mut toml::de::Deserializer::new(&config_str);
let config_opts: Self = serde_ignored::deserialize(toml_de, |field| {
let warning = format!(" WARNING! found unusable configuration: {}", field);
println_yellow_err(&warning);
})
.map_err(|e| ConfigError::Deserialize { err: (e) })?;
Ok(config_opts)
}
pub fn from_dir(dir: &Path) -> Result<Self, ConfigError> {
let config_dir =
find_parent_dir_with_file(dir, SWAY_FORMAT_FILE_NAME).ok_or(ConfigError::NotFound)?;
let file_path = config_dir.join(SWAY_FORMAT_FILE_NAME);
Self::from_file(file_path)
}
}