Skip to main content

selene_core/
lib.rs

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