use serde::Serialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum Server {
Wayland,
X11,
Unknown,
}
impl Server {
pub fn name(self) -> &'static str {
match self {
Self::Wayland => "wayland",
Self::X11 => "x11",
Self::Unknown => "unknown",
}
}
}
pub fn detect(
session_type: Option<&str>,
wayland_display: Option<&str>,
x_display: Option<&str>,
) -> Server {
let declared = session_type.map(str::trim).unwrap_or_default();
match declared.to_ascii_lowercase().as_str() {
"wayland" => return Server::Wayland,
"x11" => return Server::X11,
_ => {}
}
if present(wayland_display) {
return Server::Wayland;
}
if present(x_display) {
return Server::X11;
}
Server::Unknown
}
fn present(value: Option<&str>) -> bool {
value.is_some_and(|value| !value.trim().is_empty())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_declared_session_type_wins() {
assert_eq!(detect(Some("wayland"), None, None), Server::Wayland);
assert_eq!(detect(Some("x11"), None, None), Server::X11);
assert_eq!(
detect(Some("wayland"), Some("wayland-0"), Some(":0")),
Server::Wayland
);
assert_eq!(detect(Some("x11"), None, Some(":0")), Server::X11);
}
#[test]
fn case_and_whitespace_in_the_declaration_are_tolerated() {
assert_eq!(detect(Some("Wayland"), None, None), Server::Wayland);
assert_eq!(detect(Some(" X11 "), None, None), Server::X11);
}
#[test]
fn an_unhelpful_declaration_falls_through_to_the_sockets() {
assert_eq!(
detect(Some("tty"), Some("wayland-0"), None),
Server::Wayland
);
assert_eq!(detect(Some("tty"), None, Some(":0")), Server::X11);
assert_eq!(detect(Some("tty"), None, None), Server::Unknown);
}
#[test]
fn wayland_wins_over_a_leftover_x_display() {
assert_eq!(detect(None, Some("wayland-0"), Some(":0")), Server::Wayland);
}
#[test]
fn nothing_set_is_unknown_rather_than_a_guess() {
assert_eq!(detect(None, None, None), Server::Unknown);
}
#[test]
fn an_empty_variable_is_not_a_session() {
assert_eq!(detect(Some(""), Some(""), Some("")), Server::Unknown);
assert_eq!(detect(None, Some(" "), Some(":0")), Server::X11);
}
#[test]
fn every_server_has_a_name() {
assert_eq!(Server::Wayland.name(), "wayland");
assert_eq!(Server::X11.name(), "x11");
assert_eq!(Server::Unknown.name(), "unknown");
}
}