1
use std::path::PathBuf;
2

            
3
use schemars::JsonSchema;
4
use serde::{
5
  Deserialize,
6
  Serialize,
7
};
8
use which::which;
9

            
10
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema)]
11
#[serde(rename_all = "snake_case")]
12
/// The container runtime to use.
13
pub enum ContainerRuntime {
14
  Auto,
15
  Docker,
16
  Nerdctl,
17
  Podman,
18
}
19

            
20
impl ContainerRuntime {
21
  pub fn resolve(runtime: Option<&ContainerRuntime>) -> anyhow::Result<PathBuf> {
22
    match runtime.unwrap_or(&ContainerRuntime::Auto) {
23
      ContainerRuntime::Auto => which("docker")
24
        .or_else(|_| which("nerdctl"))
25
        .or_else(|_| which("podman"))
26
        .map_err(|_| {
27
          anyhow::anyhow!(
28
            "No container runtime found. Install Docker, nerdctl, or Podman and ensure one is available in PATH."
29
          )
30
        }),
31
      ContainerRuntime::Docker => which("docker")
32
        .map_err(|_| anyhow::anyhow!("Docker not found. Install Docker and ensure it is available in PATH.")),
33
      ContainerRuntime::Nerdctl => which("nerdctl")
34
        .map_err(|_| anyhow::anyhow!("nerdctl not found. Install nerdctl and ensure it is available in PATH.")),
35
      ContainerRuntime::Podman => which("podman")
36
        .map_err(|_| anyhow::anyhow!("Podman not found. Install Podman and ensure it is available in PATH.")),
37
    }
38
  }
39

            
40
8
  pub fn name(&self) -> &'static str {
41
8
    match self {
42
8
      ContainerRuntime::Auto => "auto",
43
      ContainerRuntime::Docker => "docker",
44
      ContainerRuntime::Nerdctl => "nerdctl",
45
      ContainerRuntime::Podman => "podman",
46
    }
47
8
  }
48
}