1use anyhow::{anyhow, Result};
2
3#[derive(Debug, Clone)]
4pub enum Runtime {
5 Bun(String), Node(String), Python(String), }
9
10impl Runtime {
11 pub fn parse(runtime_spec: &str) -> Result<Self> {
12 if runtime_spec.starts_with("bun") {
13 let version = if runtime_spec.contains('@') {
14 runtime_spec
15 .split('@')
16 .nth(1)
17 .unwrap_or("latest")
18 .to_string()
19 } else {
20 "latest".to_string()
21 };
22 Ok(Runtime::Bun(version))
23 } else if runtime_spec.starts_with("node") {
24 let version = if runtime_spec.contains('@') {
25 runtime_spec
26 .split('@')
27 .nth(1)
28 .unwrap_or("latest")
29 .to_string()
30 } else {
31 "latest".to_string()
32 };
33 Ok(Runtime::Node(version))
34 } else if runtime_spec.starts_with("python") || runtime_spec.starts_with("py") {
35 let version = if runtime_spec.contains('@') {
36 runtime_spec
37 .split('@')
38 .nth(1)
39 .unwrap_or("latest")
40 .to_string()
41 } else {
42 "latest".to_string()
43 };
44 Ok(Runtime::Python(version))
45 } else {
46 Err(anyhow!(
47 "Unknown runtime: {}. Supported: bun, node, python",
48 runtime_spec
49 ))
50 }
51 }
52
53 pub fn name(&self) -> &str {
54 match self {
55 Runtime::Bun(_) => "bun",
56 Runtime::Node(_) => "node",
57 Runtime::Python(_) => "python",
58 }
59 }
60
61 pub fn version(&self) -> &str {
62 match self {
63 Runtime::Bun(v) | Runtime::Node(v) | Runtime::Python(v) => v,
64 }
65 }
66
67 pub fn from_name_version(name: &str, version: &str) -> Self {
68 match name {
69 "bun" => Runtime::Bun(version.to_string()),
70 "node" => Runtime::Node(version.to_string()),
71 "python" => Runtime::Python(version.to_string()),
72 _ => Runtime::Bun("latest".to_string()),
73 }
74 }
75}
76
77impl Default for Runtime {
78 fn default() -> Self {
79 Runtime::Bun("latest".to_string())
80 }
81}