|
@@ -1,7 +1,7 @@
|
|
|
use log::{info, warn};
|
|
use log::{info, warn};
|
|
|
use serde::{Deserialize, Serialize};
|
|
use serde::{Deserialize, Serialize};
|
|
|
use std::fs;
|
|
use std::fs;
|
|
|
-use std::path::PathBuf;
|
|
|
|
|
|
|
+use std::path::{Path, PathBuf};
|
|
|
|
|
|
|
|
const CONFIG_TEMPLATE: &str = include_str!("../pandora-config.example.toml");
|
|
const CONFIG_TEMPLATE: &str = include_str!("../pandora-config.example.toml");
|
|
|
|
|
|
|
@@ -483,6 +483,45 @@ impl Config {
|
|
|
Self::write_template_if_missing()
|
|
Self::write_template_if_missing()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ pub fn from_path(path: impl AsRef<Path>) -> Self {
|
|
|
|
|
+ let path = path.as_ref().to_path_buf();
|
|
|
|
|
+
|
|
|
|
|
+ // First, ensure there is at least a file on disk (template on first run).
|
|
|
|
|
+ if let Err(e) = Self::write_template_if_missing() {
|
|
|
|
|
+ warn!(
|
|
|
|
|
+ "Warning: failed to ensure config template at {}: {}",
|
|
|
|
|
+ path.display(),
|
|
|
|
|
+ e
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Try to load and parse the user config file.
|
|
|
|
|
+ match fs::read_to_string(&path) {
|
|
|
|
|
+ Ok(content) => match toml::from_str::<Config>(&content) {
|
|
|
|
|
+ Ok(cfg) => cfg,
|
|
|
|
|
+ Err(e) => {
|
|
|
|
|
+ warn!(
|
|
|
|
|
+ "Warning: failed to parse user config {}: {}. Falling back to embedded template.",
|
|
|
|
|
+ path.display(),
|
|
|
|
|
+ e
|
|
|
|
|
+ );
|
|
|
|
|
+ // Fallback: parse the embedded template.
|
|
|
|
|
+ toml::from_str::<Config>(CONFIG_TEMPLATE)
|
|
|
|
|
+ .expect("embedded config template is invalid")
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ Err(e) => {
|
|
|
|
|
+ warn!(
|
|
|
|
|
+ "Warning: failed to read user config {}: {}. Falling back to embedded template.",
|
|
|
|
|
+ path.display(),
|
|
|
|
|
+ e
|
|
|
|
|
+ );
|
|
|
|
|
+ toml::from_str::<Config>(CONFIG_TEMPLATE)
|
|
|
|
|
+ .expect("embedded config template is invalid")
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/// Returns `<result_dir>/<id>/<tumoral_name>`.
|
|
/// Returns `<result_dir>/<id>/<tumoral_name>`.
|
|
|
#[inline]
|
|
#[inline]
|
|
|
pub fn tumoral_dir(&self, id: &str) -> String {
|
|
pub fn tumoral_dir(&self, id: &str) -> String {
|
|
@@ -966,40 +1005,6 @@ impl Config {
|
|
|
impl Default for Config {
|
|
impl Default for Config {
|
|
|
fn default() -> Self {
|
|
fn default() -> Self {
|
|
|
let path = Self::config_path();
|
|
let path = Self::config_path();
|
|
|
-
|
|
|
|
|
- // First, ensure there is at least a file on disk (template on first run).
|
|
|
|
|
- if let Err(e) = Self::write_template_if_missing() {
|
|
|
|
|
- warn!(
|
|
|
|
|
- "Warning: failed to ensure config template at {}: {}",
|
|
|
|
|
- path.display(),
|
|
|
|
|
- e
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Try to load and parse the user config file.
|
|
|
|
|
- match fs::read_to_string(&path) {
|
|
|
|
|
- Ok(content) => match toml::from_str::<Config>(&content) {
|
|
|
|
|
- Ok(cfg) => cfg,
|
|
|
|
|
- Err(e) => {
|
|
|
|
|
- warn!(
|
|
|
|
|
- "Warning: failed to parse user config {}: {}. Falling back to embedded template.",
|
|
|
|
|
- path.display(),
|
|
|
|
|
- e
|
|
|
|
|
- );
|
|
|
|
|
- // Fallback: parse the embedded template.
|
|
|
|
|
- toml::from_str::<Config>(CONFIG_TEMPLATE)
|
|
|
|
|
- .expect("embedded config template is invalid")
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- Err(e) => {
|
|
|
|
|
- warn!(
|
|
|
|
|
- "Warning: failed to read user config {}: {}. Falling back to embedded template.",
|
|
|
|
|
- path.display(),
|
|
|
|
|
- e
|
|
|
|
|
- );
|
|
|
|
|
- toml::from_str::<Config>(CONFIG_TEMPLATE)
|
|
|
|
|
- .expect("embedded config template is invalid")
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ Self::from_path(path)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|