Skip to main content

selene_core/config/
common.rs

1use std::{
2    path::{Path, PathBuf},
3    sync::{LazyLock, RwLock},
4};
5
6use crate::config::Config;
7use lunar_lib::error;
8use serde::{Deserialize, Serialize};
9
10pub mod accessors;
11pub(crate) mod internal;
12pub mod mutators;
13
14#[derive(Serialize, Deserialize, Debug, Default)]
15pub struct CommonConfig {
16    pub(crate) source_dirs: Vec<PathBuf>,
17    pub(crate) library_dir: Option<PathBuf>,
18
19    pub loudnorm_config: LoudnormConfig,
20    pub track_name_config: TrackNameConfig,
21}
22
23impl Config for CommonConfig {
24    const CONFIG_FILE_NAME: &'static str = "common";
25}
26
27impl CommonConfig {
28    #[must_use]
29    pub fn library_dir(&self) -> Option<&Path> {
30        self.library_dir.as_deref()
31    }
32
33    #[must_use]
34    pub fn sources(&self) -> &[PathBuf] {
35        &self.source_dirs
36    }
37}
38
39static COMMON_CONFIG: LazyLock<RwLock<CommonConfig>> = LazyLock::new(|| {
40    let config = match CommonConfig::load() {
41        Ok(config) => config,
42        Err(err) => {
43            error!(
44                "Could not load common config from file, assuming defaults. Reason: {:?}",
45                err
46            );
47            CommonConfig::default()
48        }
49    };
50    RwLock::new(config)
51});
52
53/// Returns a read-only guard to the common config.
54///
55/// # Panics
56///
57/// This function will panic if the read/write lock is poisoned
58pub fn common_config() -> std::sync::RwLockReadGuard<'static, CommonConfig> {
59    COMMON_CONFIG.read().unwrap()
60}
61
62/// Returns a mutable guard to the common config.
63///
64/// # Panics
65///
66/// This function will panic if the read/write lock is poisoned
67pub fn common_config_mut() -> std::sync::RwLockWriteGuard<'static, CommonConfig> {
68    COMMON_CONFIG.write().unwrap()
69}
70
71#[derive(Debug, Clone, Deserialize, Serialize)]
72pub struct TrackNameConfig {
73    pub format_string: String,
74    pub artist_separator: String,
75    pub alt_artist_separator: String,
76}
77
78impl Default for TrackNameConfig {
79    fn default() -> Self {
80        let format_string = if cfg!(windows) {
81            "{$album>\\\\}$track_num{$disc_num@$track_num<-}{. @$track_num}{$main_track_artist?UNKNOWN ARTIST} - {$title?UNKNOWN TITLE}{$feat_track_artists< (feat. >)}"
82        } else {
83            "{$album>/}$track_num{$disc_num@$track_num<-}{. @$track_num}{$main_track_artist?UNKNOWN ARTIST} - {$title?UNKNOWN TITLE}{$feat_track_artists< (feat. >)}"
84        };
85
86        Self {
87            format_string: format_string.to_owned(),
88            artist_separator: ", ".to_owned(),
89            alt_artist_separator: " & ".to_owned(),
90        }
91    }
92}
93
94#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize, Copy)]
95pub struct LoudnormConfig {
96    pub linear: bool,
97    pub target_offset: f32,
98    pub target_i: f32,
99    pub target_tp: f32,
100    pub target_lra: f32,
101}
102
103impl Default for LoudnormConfig {
104    fn default() -> Self {
105        Self {
106            linear: true,
107            target_offset: 0.0,
108            target_i: -24.0,
109            target_tp: -2.0,
110            target_lra: 7.0,
111        }
112    }
113}