1use std::{
2 path::{Path, PathBuf},
3 sync::LazyLock,
4};
5
6use directories::{BaseDirs, UserDirs};
7pub use lofty::picture::PictureType;
8#[cfg(feature = "net-features")]
9use reqwest::blocking::Client;
10
11use crate::media_container::{Codec, ContainerFormat};
12
13pub const PROGRAM_FS_NAME: &str = "selene";
14pub const PROGRAM_DISPLAY_NAME: &str = "Selene";
15
16pub mod config;
17pub mod database;
18pub mod errors;
19mod ffmpeg;
20pub mod library;
21pub mod media_container;
22pub mod utils;
23
24pub mod decoding;
25
26pub mod synced_lyrics;
27
28#[cfg(feature = "net-features")]
29static REQWEST_CLIENT: LazyLock<Client> = LazyLock::new(|| {
30 Client::builder()
31 .user_agent(format!(
32 "{PROGRAM_DISPLAY_NAME} v{ver} (https://codeberg.org/CrypticCreator/Selene)",
33 ver = env!("CARGO_PKG_VERSION")
34 ))
35 .build()
36 .unwrap()
37});
38
39#[cfg(feature = "net-features")]
40pub mod lrclib;
41
42static BASE_DIRS: LazyLock<Option<BaseDirs>> = LazyLock::new(BaseDirs::new);
43
44#[must_use]
50pub fn base_dirs() -> &'static BaseDirs {
51 BASE_DIRS.as_ref().unwrap()
52}
53
54#[must_use]
55pub fn config_dir() -> &'static Path {
56 &CONFIG_DIR
57}
58static CONFIG_DIR: LazyLock<PathBuf> =
59 LazyLock::new(|| base_dirs().config_dir().join(PROGRAM_FS_NAME));
60
61#[must_use]
62pub fn data_dir() -> &'static Path {
63 &DATA_DIR
64}
65static DATA_DIR: LazyLock<PathBuf> = LazyLock::new(|| base_dirs().data_dir().join(PROGRAM_FS_NAME));
66
67#[must_use]
68pub fn cache_dir() -> PathBuf {
69 base_dirs().cache_dir().join(PROGRAM_FS_NAME)
70}
71
72#[must_use]
73pub fn runtime_dir() -> PathBuf {
74 base_dirs().runtime_dir().unwrap().join(PROGRAM_FS_NAME)
75}
76
77pub fn music_dir() -> Option<&'static Path> {
78 MUSIC_DIR.as_deref()
79}
80static MUSIC_DIR: LazyLock<Option<PathBuf>> = LazyLock::new(|| {
81 UserDirs::new().and_then(|user_dirs| user_dirs.audio_dir().map(|p| p.join("Selene Library")))
82});
83
84pub const VALID_TRANSCODE_PAIRS: [(ContainerFormat, Codec); 2] = [
86 (ContainerFormat::Flac, Codec::Flac),
87 (ContainerFormat::Ogg, Codec::Vorbis),
88];
89
90pub const VALID_LIBRARY_FORMATS: [ContainerFormat; 3] = [
91 ContainerFormat::Flac,
92 ContainerFormat::Mpa,
93 ContainerFormat::Ogg,
94];
95pub const VALID_LIBRARY_CODECS: [Codec; 3] = [Codec::Flac, Codec::Vorbis, Codec::Mp3];