separate default and base config

This commit is contained in:
mat 2024-04-18 04:41:26 +00:00
parent afc526c6f2
commit 75572c17a2
7 changed files with 60 additions and 43 deletions

2
README
View File

@ -13,7 +13,7 @@ build it with `cargo b -r`, the resulting binary will be at
`target/release/metasearch2`.
the config.toml file is created in your current working directory on the first
run of metasearch2. alternatively, you can copy the default-config.toml in the
run of metasearch2. alternatively, you can copy the config-default.toml in the
repo and rename it to config.toml.
the default port is 28019.

View File

@ -1,3 +1,5 @@
# This is the config that's used as a fallback when a field is missing from the user's config.toml.
bind = "0.0.0.0:28019"
engine_list_separator = false

13
config-default.toml Normal file
View File

@ -0,0 +1,13 @@
# See https://github.com/mat-1/metasearch2/blob/master/config-base.toml and
# https://github.com/mat-1/metasearch2/blob/master/src/config.rs for some of
# the possible options
bind = "0.0.0.0:28019"
[ui]
# engine_list_separator = true
# version_info = true
[engines]
# numbat = false
# fend = true

View File

@ -9,40 +9,52 @@ use crate::engines::Engine;
#[derive(Deserialize, Debug)]
pub struct Config {
pub bind: SocketAddr,
#[serde(default)]
pub engine_list_separator: Option<bool>,
#[serde(default)]
pub version_info: Option<bool>,
pub ui: UiConfig,
pub engines: EnginesConfig,
}
impl Config {
pub fn read_or_create() -> eyre::Result<Self> {
let default_config_str = include_str!("../default-config.toml");
let mut config: Config = toml::from_str(default_config_str)?;
#[derive(Deserialize, Debug)]
pub struct UiConfig {
#[serde(default)]
pub show_engine_list_separator: Option<bool>,
#[serde(default)]
pub show_version_info: Option<bool>,
}
#[derive(Deserialize, Debug)]
pub struct EnginesConfig {
#[serde(flatten)]
pub map: HashMap<Engine, DefaultableEngineConfig>,
}
impl Config {
pub fn read_or_create(config_path: &Path) -> eyre::Result<Self> {
let base_config_str = include_str!("../config-base.toml");
let mut config: Config = toml::from_str(base_config_str)?;
if !config_path.exists() {
info!("No config found, creating one at {config_path:?}");
let default_config_str = include_str!("../config-default.toml");
fs::write(config_path, default_config_str)?;
}
let config_path = std::env::args().nth(1).unwrap_or("config.toml".into());
let config_path = Path::new(&config_path);
if config_path.exists() {
let given_config = toml::from_str::<Config>(&fs::read_to_string(config_path)?)?;
config.update(given_config);
Ok(config)
} else {
info!("No config found, creating one at {config_path:?}");
fs::write(config_path, default_config_str)?;
Ok(config)
}
}
// Update the current config with the given config. This is used to make it so
// the default-config.toml is always used as a fallback if the user decides to
// the config-base.toml is always used as a fallback if the user decides to
// use the default for something.
pub fn update(&mut self, new: Config) {
self.bind = new.bind;
self.engine_list_separator = new.engine_list_separator.or(self.engine_list_separator);
assert_ne!(self.engine_list_separator, None);
self.version_info = new.version_info.or(self.version_info);
assert_ne!(self.version_info, None);
self.ui.show_engine_list_separator = new
.ui
.show_engine_list_separator
.or(self.ui.show_engine_list_separator);
assert_ne!(self.ui.show_engine_list_separator, None);
self.ui.show_version_info = new.ui.show_version_info.or(self.ui.show_version_info);
assert_ne!(self.ui.show_version_info, None);
for (key, new) in new.engines.map {
if let Some(existing) = self.engines.map.get_mut(&key) {
existing.update(new);
@ -53,12 +65,6 @@ impl Config {
}
}
#[derive(Deserialize, Debug)]
pub struct EnginesConfig {
#[serde(flatten)]
pub map: HashMap<Engine, DefaultableEngineConfig>,
}
static DEFAULT_ENABLED_FULL_ENGINE_CONFIG: Lazy<FullEngineConfig> =
Lazy::new(FullEngineConfig::default);
static DEFAULT_DISABLED_FULL_ENGINE_CONFIG: Lazy<FullEngineConfig> =

View File

@ -1,3 +1,5 @@
use std::path::Path;
use config::Config;
use tracing::error;
@ -11,7 +13,10 @@ pub mod web;
async fn main() {
tracing_subscriber::fmt::init();
let config = match Config::read_or_create() {
let config_path = std::env::args().nth(1).unwrap_or("config.toml".into());
let config_path = Path::new(&config_path);
let config = match Config::read_or_create(config_path) {
Ok(config) => config,
Err(err) => {
error!("Couldn't parse config:\n{err}");

View File

@ -33,7 +33,7 @@ pub async fn index(State(config): State<Arc<Config>>) -> impl IntoResponse {
input type="submit" value="Search";
}
}
@if config.version_info.unwrap() {
@if config.ui.show_version_info.unwrap() {
span."version-info" {
@if COMMIT_HASH == "unknown" || COMMIT_HASH_SHORT == "unknown" {
"Version "

View File

@ -55,26 +55,17 @@ fn render_end_of_html() -> String {
fn render_engine_list(engines: &[engines::Engine], config: &Config) -> PreEscaped<String> {
let mut html = String::new();
let mut first_iter = true;
for engine in engines {
if config.engine_list_separator.unwrap() && !first_iter {
for (i, engine) in engines.iter().enumerate() {
if config.ui.show_engine_list_separator.unwrap() && i > 0 {
html.push_str(" &middot; ");
}
first_iter = false;
let raw_engine_id = &engine.id();
let engine_id = if config.engine_list_separator.unwrap() {
let engine_id = if config.ui.show_engine_list_separator.unwrap() {
raw_engine_id.replace('_', " ")
} else {
raw_engine_id.to_string()
};
html.push_str(
&html! {
span."engine-list-item" {
(engine_id)
}
}
.into_string(),
)
html.push_str(&html! { span."engine-list-item" { (engine_id) } }.into_string())
}
html! {
div."engine-list" {