use std::path::PathBuf;
use super::schema::*;
use crate::metadata::load_metadata;
pub enum RyraStatus {
NotInitialized,
Initialized(StatusInfo),
Error(String),
}
pub struct StatusInfo {
pub config_path: PathBuf,
pub smtp: ProviderStatus,
pub auth: ProviderStatus,
pub backup: Option<BackupSummary>,
pub tailscale: Option<TailscaleSummary>,
pub services: Vec<ServiceInfo>,
}
pub enum ProviderStatus {
None,
Configured { name: String },
}
pub struct BackupSummary {
pub backend_label: String,
pub included: usize,
}
pub struct TailscaleSummary {
pub advertised: usize,
}
pub struct ServiceInfo {
pub name: String,
pub url: Option<String>,
pub ports: std::collections::BTreeMap<String, u16>,
pub installed: bool,
pub backup_enabled: bool,
pub tailscale_exposed: bool,
}
impl StatusInfo {
pub fn from_config(config_path: PathBuf, config: &Config) -> Self {
let services: Vec<ServiceInfo> = crate::list_installed()
.unwrap_or_default()
.into_iter()
.map(|s| {
let backup_enabled = load_metadata(&s.name)
.ok()
.flatten()
.map(|m| m.backup_enabled)
.unwrap_or(false);
let url = s.exposure.url().map(|u| u.to_string());
let tailscale_exposed = url.as_deref().is_some_and(crate::is_tailscale_url);
ServiceInfo {
name: s.name,
url,
ports: s.ports,
installed: s.installed,
backup_enabled,
tailscale_exposed,
}
})
.collect();
let backup = config.backup.as_ref().map(|b| BackupSummary {
backend_label: format_backend(&b.backend),
included: services.iter().filter(|s| s.backup_enabled).count(),
});
let tailscale = config.tailscale.as_ref().map(|_| TailscaleSummary {
advertised: services.iter().filter(|s| s.tailscale_exposed).count(),
});
Self {
config_path,
smtp: match &config.smtp {
None => ProviderStatus::None,
Some(smtp) => ProviderStatus::Configured {
name: smtp.host.clone(),
},
},
auth: match &config.auth {
None => ProviderStatus::None,
Some(auth) => ProviderStatus::Configured {
name: format!("{} ({})", auth.provider_name(), auth.url()),
},
},
backup,
tailscale,
services,
}
}
}
fn format_backend(backend: &BackupBackend) -> String {
match backend {
BackupBackend::S3 {
endpoint, bucket, ..
} => format!("S3 ({endpoint}/{bucket})"),
BackupBackend::Local { path } => format!("local ({})", path.display()),
}
}