Skip to main content

selene_core/
lib.rs

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/// Returns the users `base_dirs`
45///
46/// # Panics
47///
48/// Panics if the internal `BASE_DIRS` static is [`None`]. This can only happen if the home directory is not found
49#[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
84// These two are the only two valid transcode pairs I plan on supporting for selene
85pub 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];