vuio/
lib.rs

1pub mod config;
2pub mod database;
3pub mod error;
4pub mod logging;
5pub mod media;
6pub mod platform;
7pub mod ssdp;
8pub mod watcher;
9pub mod web;
10
11pub mod state {
12    use crate::{
13        config::AppConfig,
14        database::DatabaseManager,
15        platform::{filesystem::FileSystemManager, PlatformInfo},
16    };
17    use std::sync::Arc;
18
19    #[derive(Clone)]
20    pub struct AppState {
21        pub config: Arc<AppConfig>,
22        pub database: Arc<dyn DatabaseManager>,
23        pub platform_info: Arc<PlatformInfo>,
24        pub filesystem_manager: Arc<dyn FileSystemManager>,
25        pub content_update_id: Arc<std::sync::atomic::AtomicU32>,
26        pub web_metrics: Arc<crate::web::handlers::WebHandlerMetrics>,
27    }
28
29    impl AppState {
30        /// Get the server's IP address using unified logic from platform_info
31        pub fn get_server_ip(&self) -> String {
32            // Check if server IP is explicitly configured (important for Docker)
33            if let Some(server_ip) = &self.config.server.ip {
34                if !server_ip.is_empty() && server_ip != "0.0.0.0" {
35                    return server_ip.clone();
36                }
37            }
38            
39            // Use the SSDP interface from config if it's a specific IP address
40            match &self.config.network.interface_selection {
41                crate::config::NetworkInterfaceConfig::Specific(ip) => {
42                    return ip.clone();
43                }
44                _ => {
45                    // For Auto or All, fallback to server interface if it's not 0.0.0.0
46                    if self.config.server.interface != "0.0.0.0" && !self.config.server.interface.is_empty() {
47                        return self.config.server.interface.clone();
48                    }
49                }
50            }
51            
52            // Use the primary interface detected at startup instead of re-detecting
53            if let Some(primary_interface) = self.platform_info.get_primary_interface() {
54                return primary_interface.ip_address.to_string();
55            }
56            
57            // Check if host IP is overridden via environment variable (for containers)
58            if let Ok(host_ip) = std::env::var("VUIO_IP") {
59                if !host_ip.is_empty() {
60                    return host_ip;
61                }
62            }
63            
64            // Last resort
65            tracing::warn!("Could not auto-detect IP, falling back to 127.0.0.1");
66            "127.0.0.1".to_string()
67        }
68    }
69}