use std::{
path::PathBuf,
sync::{LazyLock, RwLock, RwLockReadGuard, RwLockWriteGuard},
};
use lunar_lib::{config::Config, error};
use serde::{Deserialize, Serialize};
mod encoding;
pub use encoding::*;
static COMMON_CONFIG: LazyLock<RwLock<CommonConfig>> = LazyLock::new(|| {
let config = match CommonConfig::load() {
Ok(config) => config,
Err(err) => {
error!(
"Could not load common config from file, assuming defaults. Reason: {:?}",
err
);
CommonConfig::default()
}
};
RwLock::new(config)
});
pub fn common_config() -> RwLockReadGuard<'static, CommonConfig> {
COMMON_CONFIG.read().unwrap()
}
pub fn common_config_mut() -> RwLockWriteGuard<'static, CommonConfig> {
COMMON_CONFIG.write().unwrap()
}
mod core_impls;
use crate::media_container::ContainerFormat;
#[derive(Debug, Serialize, Deserialize, Default)]
#[serde(default)]
pub struct CommonConfig {
pub library: LibrarySettings,
pub loudnorm: LoudnormSettings,
pub track_name: TrackNameSettings,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(default)]
pub struct LibrarySettings {
source_directories: Vec<PathBuf>,
file_name_format: TrackNameSettings,
transcode_options: Vec<TranscodeSettings>,
}
impl Default for LibrarySettings {
fn default() -> Self {
Self {
source_directories: Default::default(),
file_name_format: Default::default(),
transcode_options: vec![
TranscodeSettings::to_flac(Some(ContainerFormat::Wav), None),
TranscodeSettings::to_flac(Some(ContainerFormat::Aiff), None),
TranscodeSettings::to_flac(Some(ContainerFormat::Ape), None),
],
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(default)]
pub struct TrackNameSettings {
pub format_string: String,
pub artist_separator: String,
pub alt_artist_separator: String,
}
impl Default for TrackNameSettings {
fn default() -> Self {
const DEFAULT_FORMAT_STRING: &str = if cfg!(windows) {
"{$album>\\\\}{$main_track_artist?UNKNOWN ARTIST} - {$title?UNKNOWN TITLE}{$feat_track_artists< (feat. >)}"
} else {
"{$album>/}{$main_track_artist?UNKNOWN ARTIST} - {$title?UNKNOWN TITLE}{$feat_track_artists< (feat. >)}"
};
Self {
format_string: DEFAULT_FORMAT_STRING.to_owned(),
artist_separator: ", ".to_owned(),
alt_artist_separator: " & ".to_owned(),
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[serde(default)]
pub struct LoudnormSettings {
pub accurate_true_peak: bool,
pub target_offset: f64,
pub target_i: f64,
pub target_tp: f64,
}
impl Default for LoudnormSettings {
fn default() -> Self {
Self {
accurate_true_peak: true,
target_offset: 0.0,
target_i: -14.0,
target_tp: -2.0,
}
}
}