1use std::fmt;
2use std::path::PathBuf;
3use std::str::FromStr;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub enum Language {
7 NodeJs,
8 Python,
9 Ruby,
10 Php,
11 Go,
12 Rust,
13}
14
15impl Language {
16 pub fn as_str(&self) -> &'static str {
17 match self {
18 Language::NodeJs => "nodejs",
19 Language::Python => "python",
20 Language::Ruby => "ruby",
21 Language::Php => "php",
22 Language::Go => "go",
23 Language::Rust => "rust",
24 }
25 }
26
27 pub fn all() -> &'static [Language] {
28 &[
29 Language::NodeJs,
30 Language::Python,
31 Language::Ruby,
32 Language::Php,
33 Language::Go,
34 Language::Rust,
35 ]
36 }
37}
38
39impl FromStr for Language {
40 type Err = String;
41
42 fn from_str(s: &str) -> Result<Self, Self::Err> {
43 match s.to_lowercase().as_str() {
44 "nodejs" | "node" | "node.js" => Ok(Language::NodeJs),
45 "python" | "py" => Ok(Language::Python),
46 "ruby" | "rb" => Ok(Language::Ruby),
47 "php" => Ok(Language::Php),
48 "go" | "golang" => Ok(Language::Go),
49 "rust" | "rs" => Ok(Language::Rust),
50 _ => Err(format!("Unknown language: {s}")),
51 }
52 }
53}
54
55impl fmt::Display for Language {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 write!(f, "{}", self.as_str())
58 }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq)]
62pub struct Runtime {
63 pub language: Language,
64 pub version: String,
65 pub path: PathBuf,
66 pub size: u64,
67 pub sha256: String,
68}
69
70impl Runtime {
71 pub fn new(
72 language: Language,
73 version: String,
74 path: PathBuf,
75 size: u64,
76 sha256: String,
77 ) -> Self {
78 Self {
79 language,
80 version,
81 path,
82 size,
83 sha256,
84 }
85 }
86
87 pub fn filename(&self) -> String {
88 format!("{}-{}.wasm", self.language.as_str(), self.version)
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn test_language_from_str() {
98 assert_eq!("nodejs".parse::<Language>().unwrap(), Language::NodeJs);
99 assert_eq!("node".parse::<Language>().unwrap(), Language::NodeJs);
100 assert_eq!("node.js".parse::<Language>().unwrap(), Language::NodeJs);
101 assert_eq!("python".parse::<Language>().unwrap(), Language::Python);
102 assert_eq!("py".parse::<Language>().unwrap(), Language::Python);
103 assert_eq!("ruby".parse::<Language>().unwrap(), Language::Ruby);
104 assert_eq!("rb".parse::<Language>().unwrap(), Language::Ruby);
105 assert_eq!("php".parse::<Language>().unwrap(), Language::Php);
106 assert_eq!("go".parse::<Language>().unwrap(), Language::Go);
107 assert_eq!("golang".parse::<Language>().unwrap(), Language::Go);
108 assert_eq!("rust".parse::<Language>().unwrap(), Language::Rust);
109 assert_eq!("rs".parse::<Language>().unwrap(), Language::Rust);
110
111 assert!("unknown".parse::<Language>().is_err());
112 assert!("javascript".parse::<Language>().is_err());
113 }
114
115 #[test]
116 fn test_language_as_str() {
117 assert_eq!(Language::NodeJs.as_str(), "nodejs");
118 assert_eq!(Language::Python.as_str(), "python");
119 assert_eq!(Language::Ruby.as_str(), "ruby");
120 assert_eq!(Language::Php.as_str(), "php");
121 assert_eq!(Language::Go.as_str(), "go");
122 assert_eq!(Language::Rust.as_str(), "rust");
123 }
124
125 #[test]
126 fn test_language_display() {
127 assert_eq!(format!("{}", Language::NodeJs), "nodejs");
128 assert_eq!(format!("{}", Language::Python), "python");
129 }
130
131 #[test]
132 fn test_runtime_new() {
133 let runtime = Runtime::new(
134 Language::Python,
135 "3.11.7".to_string(),
136 PathBuf::from("/cache/python-3.11.7.wasm"),
137 1024,
138 "abc123".to_string(),
139 );
140
141 assert_eq!(runtime.language, Language::Python);
142 assert_eq!(runtime.version, "3.11.7");
143 assert_eq!(runtime.size, 1024);
144 assert_eq!(runtime.sha256, "abc123");
145 }
146
147 #[test]
148 fn test_runtime_filename() {
149 let runtime = Runtime::new(
150 Language::NodeJs,
151 "20.2.0".to_string(),
152 PathBuf::from("/cache/nodejs-20.2.0.wasm"),
153 2048,
154 "def456".to_string(),
155 );
156
157 assert_eq!(runtime.filename(), "nodejs-20.2.0.wasm");
158 }
159
160 #[test]
161 fn test_language_all() {
162 let languages = Language::all();
163 assert_eq!(languages.len(), 6);
164 assert!(languages.contains(&Language::NodeJs));
165 assert!(languages.contains(&Language::Python));
166 assert!(languages.contains(&Language::Ruby));
167 assert!(languages.contains(&Language::Php));
168 assert!(languages.contains(&Language::Go));
169 assert!(languages.contains(&Language::Rust));
170 }
171}