Skip to main content

construct/runtime/
mod.rs

1pub mod docker;
2pub mod native;
3pub mod traits;
4
5pub use docker::DockerRuntime;
6pub use native::NativeRuntime;
7pub use traits::RuntimeAdapter;
8
9use crate::config::RuntimeConfig;
10
11/// Factory: create the right runtime from config
12pub fn create_runtime(config: &RuntimeConfig) -> anyhow::Result<Box<dyn RuntimeAdapter>> {
13    match config.kind.as_str() {
14        "native" => Ok(Box::new(NativeRuntime::new())),
15        "docker" => Ok(Box::new(DockerRuntime::new(config.docker.clone()))),
16        "cloudflare" => anyhow::bail!(
17            "runtime.kind='cloudflare' is not implemented yet. Use runtime.kind='native' for now."
18        ),
19        other if other.trim().is_empty() => {
20            anyhow::bail!("runtime.kind cannot be empty. Supported values: native, docker")
21        }
22        other => anyhow::bail!("Unknown runtime kind '{other}'. Supported values: native, docker"),
23    }
24}
25
26#[cfg(test)]
27mod tests {
28    use super::*;
29
30    #[test]
31    fn factory_native() {
32        let cfg = RuntimeConfig {
33            kind: "native".into(),
34            ..RuntimeConfig::default()
35        };
36        let rt = create_runtime(&cfg).unwrap();
37        assert_eq!(rt.name(), "native");
38        assert!(rt.has_shell_access());
39    }
40
41    #[test]
42    fn factory_docker() {
43        let cfg = RuntimeConfig {
44            kind: "docker".into(),
45            ..RuntimeConfig::default()
46        };
47        let rt = create_runtime(&cfg).unwrap();
48        assert_eq!(rt.name(), "docker");
49        assert!(rt.has_shell_access());
50    }
51
52    #[test]
53    fn factory_cloudflare_errors() {
54        let cfg = RuntimeConfig {
55            kind: "cloudflare".into(),
56            ..RuntimeConfig::default()
57        };
58        match create_runtime(&cfg) {
59            Err(err) => assert!(err.to_string().contains("not implemented")),
60            Ok(_) => panic!("cloudflare runtime should error"),
61        }
62    }
63
64    #[test]
65    fn factory_unknown_errors() {
66        let cfg = RuntimeConfig {
67            kind: "wasm-edge-unknown".into(),
68            ..RuntimeConfig::default()
69        };
70        match create_runtime(&cfg) {
71            Err(err) => assert!(err.to_string().contains("Unknown runtime kind")),
72            Ok(_) => panic!("unknown runtime should error"),
73        }
74    }
75
76    #[test]
77    fn factory_empty_errors() {
78        let cfg = RuntimeConfig {
79            kind: String::new(),
80            ..RuntimeConfig::default()
81        };
82        match create_runtime(&cfg) {
83            Err(err) => assert!(err.to_string().contains("cannot be empty")),
84            Ok(_) => panic!("empty runtime should error"),
85        }
86    }
87}