srtool_lib/
container_engine.rs1use std::{fmt::Display, process::Command};
2
3use crate::SrtoolLibError;
4
5#[derive(Clone, Copy, PartialEq)]
7pub enum ContainerEngine {
8 Docker,
10 Podman,
12}
13
14impl ContainerEngine {
15 pub fn detect() -> Result<ContainerEngine, SrtoolLibError> {
17 if let Ok(engine) = std::env::var("ENGINE") {
18 return ContainerEngine::try_from(engine.as_str());
19 }
20
21 let podman_output: Option<std::process::Output> = Command::new("podman").arg("--version").output().ok();
22 if let Some(podman) = podman_output {
23 let podman = String::from_utf8_lossy(&podman.stdout);
24 if podman.to_lowercase().contains("podman") {
25 return Ok(ContainerEngine::Podman);
26 } else if podman.contains("docker") {
27 return Ok(ContainerEngine::Docker);
28 }
29 }
30
31 let docker_output = Command::new("docker").arg("--version").output().ok();
32 if let Some(docker) = docker_output {
33 let docker = String::from_utf8_lossy(&docker.stdout);
34 if docker.to_lowercase().contains("docker") {
35 return Ok(ContainerEngine::Docker);
36 } else if docker.contains("podman") {
37 return Ok(ContainerEngine::Podman);
38 }
39 }
40
41 Err(SrtoolLibError::UnknownContainerEngine(None))
42 }
43}
44
45impl TryFrom<&str> for ContainerEngine {
46 type Error = SrtoolLibError;
47
48 fn try_from(s: &str) -> Result<Self, Self::Error> {
49 match s.to_ascii_lowercase().as_str() {
50 "auto" => Self::detect(),
51 "podman" => Ok(ContainerEngine::Podman),
52 "docker" => {
53 println!("WARNING: You are using docker. We recommend using podman instead.");
54 Ok(ContainerEngine::Docker)
55 }
56 _ => Err(SrtoolLibError::UnknownContainerEngine(Some(s.into()))),
57 }
58 }
59}
60
61impl Display for ContainerEngine {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 match self {
64 ContainerEngine::Docker => write!(f, "docker"),
65 ContainerEngine::Podman => write!(f, "podman"),
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use std::env;
74
75 #[test]
76 fn detect_works() {
77 env::set_var("ENGINE", "docker");
78 assert!(ContainerEngine::detect().unwrap() == ContainerEngine::Docker);
79
80 env::set_var("ENGINE", "podman");
81 assert!(ContainerEngine::detect().unwrap() == ContainerEngine::Podman);
82 env::remove_var("ENGINE");
84 }
85
86 #[test]
87 fn container_enginer_try_from_works() {
88 assert!(ContainerEngine::try_from("docker").unwrap() == ContainerEngine::Docker);
89 assert!(ContainerEngine::try_from("podman").unwrap() == ContainerEngine::Podman);
90 assert!(matches!(ContainerEngine::try_from("invalid"), Err(SrtoolLibError::UnknownContainerEngine(Some(_)))));
91 }
92
93 #[test]
94 fn container_enginer_display_works() {
95 assert_eq!(ContainerEngine::Docker.to_string(), "docker");
96 assert_eq!(ContainerEngine::Podman.to_string(), "podman");
97 }
98}