zinit 0.3.7

Process supervisor with dependency management
Documentation
//! Socket path helpers for zinit IPC.

use std::path::PathBuf;

/// System-wide socket path.
/// Using /run instead of /var/run for early boot compatibility.
pub const SYSTEM_SOCKET: &str = "/run/zinit.sock";

/// User socket path suffix (relative to home directory).
pub const USER_SOCKET_SUFFIX: &str = "hero/var/zinit.sock";

/// Returns the default socket path.
///
/// Uses the system socket if it exists, otherwise falls back to the user socket.
pub fn default_path() -> PathBuf {
    let system = system_path();
    if system.exists() { system } else { user_path() }
}

/// Returns the system socket path.
pub fn system_path() -> PathBuf {
    PathBuf::from(SYSTEM_SOCKET)
}

/// Returns the user socket path.
///
/// Constructs the path as `$HOME/hero/var/zinit.sock`.
pub fn user_path() -> PathBuf {
    if let Some(home) = std::env::var_os("HOME") {
        PathBuf::from(home).join(USER_SOCKET_SUFFIX)
    } else {
        // Fallback if HOME is not set
        PathBuf::from("/tmp/zinit.sock")
    }
}

/// System-wide service configuration directory.
pub const SYSTEM_CONFIG_DIR: &str = "/etc/zinit/services";

/// User service configuration directory suffix.
pub const USER_CONFIG_DIR_SUFFIX: &str = "hero/cfg/zinit";

/// Returns the system configuration directory.
pub fn system_config_dir() -> PathBuf {
    PathBuf::from(SYSTEM_CONFIG_DIR)
}

/// Returns the user configuration directory.
pub fn user_config_dir() -> PathBuf {
    if let Some(home) = std::env::var_os("HOME") {
        PathBuf::from(home).join(USER_CONFIG_DIR_SUFFIX)
    } else {
        PathBuf::from("/tmp/zinit/services")
    }
}

/// Returns all configuration directories to search, in order of priority.
///
/// User directory takes precedence over system directory.
pub fn config_dirs() -> Vec<PathBuf> {
    vec![user_config_dir(), system_config_dir()]
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_system_path() {
        assert_eq!(system_path(), PathBuf::from("/run/zinit.sock"));
    }

    #[test]
    fn test_user_path() {
        let path = user_path();
        // Should end with the suffix
        assert!(path.to_string_lossy().ends_with(USER_SOCKET_SUFFIX));
    }

    #[test]
    fn test_config_dirs() {
        let dirs = config_dirs();
        assert_eq!(dirs.len(), 2);
        // User dir comes first
        assert!(dirs[0].to_string_lossy().contains(USER_CONFIG_DIR_SUFFIX));
        assert_eq!(dirs[1], PathBuf::from(SYSTEM_CONFIG_DIR));
    }
}