Skip to main content

lavende_core/
lib.rs

1pub mod audio;
2pub mod common;
3pub mod config;
4pub mod events;
5pub mod gateway;
6pub mod pipeline;
7pub mod player;
8pub mod protocol;
9pub mod routeplanner;
10pub mod sources;
11pub mod transport;
12pub mod utils;
13
14pub use player::Player;
15
16use config::AppConfig;
17use sources::manager::SourceManager;
18use std::fs;
19use std::path::Path;
20use std::sync::{Arc, Mutex, OnceLock};
21
22static SOURCE_MANAGER: OnceLock<Mutex<Option<Arc<SourceManager>>>> = OnceLock::new();
23static CONFIG_PATH: Mutex<Option<String>> = Mutex::new(None);
24
25pub fn set_config_path(path: Option<String>) {
26    if let Ok(mut config_path) = CONFIG_PATH.lock() {
27        *config_path = path;
28    }
29}
30
31pub fn get_source_manager() -> &'static Mutex<Option<Arc<SourceManager>>> {
32    SOURCE_MANAGER.get_or_init(|| {
33        let config_file = CONFIG_PATH
34            .lock()
35            .ok()
36            .and_then(|p| p.clone())
37            .unwrap_or_else(|| "source.json".to_string());
38
39        let mut config = AppConfig::default();
40        let path = Path::new(&config_file);
41
42        if path.exists() {
43            if let Ok(raw) = fs::read_to_string(path) {
44                if let Ok(json_val) = serde_json::from_str::<serde_json::Value>(&raw) {
45                    if let Some(sources_val) = json_val.get("sources") {
46                        if let Ok(sources_cfg) = serde_json::from_value(sources_val.clone()) {
47                            config.sources = sources_cfg;
48                        }
49                    }
50                    if let Some(rp_val) = json_val.get("route_planner") {
51                        if let Ok(rp_cfg) = serde_json::from_value(rp_val.clone()) {
52                            config.route_planner = rp_cfg;
53                        }
54                    }
55                    if let Some(player_val) = json_val.get("player") {
56                        if let Ok(player_cfg) = serde_json::from_value(player_val.clone()) {
57                            config.player = player_cfg;
58                        }
59                    }
60                }
61            }
62        } else {
63            println!(
64                "Warning: {} not found in current directory. Using default source configuration.",
65                config_file
66            );
67        }
68
69        let logging_cfg = config.logging.clone().unwrap_or_default();
70        common::logger::init(&logging_cfg);
71        Mutex::new(Some(Arc::new(SourceManager::new(&config))))
72    })
73}
74
75pub async fn resolve_jiosaavn(url_or_token: String) -> Result<String, String> {
76    Ok(url_or_token)
77}
78
79pub async fn resolve_youtube(url_or_id: String) -> Result<String, String> {
80    Ok(url_or_id)
81}
82
83pub async fn load(identifier: String) -> Result<String, String> {
84    let sm_arc = {
85        let sm_guard = get_source_manager().lock().map_err(|e| e.to_string())?;
86        sm_guard
87            .as_ref()
88            .ok_or("SourceManager not initialized")?
89            .clone()
90    };
91    let res = sm_arc.load(&identifier, None).await;
92    serde_json::to_string(&res).map_err(|e| e.to_string())
93}