konnektoren_core/challenges/package/
package_impl.rs1use crate::{challenges::Custom, prelude::ChallengeConfig};
2
3use super::package_metadata::PackageMetadata;
4use std::collections::HashMap;
5
6#[derive(Debug, PartialEq, Clone)]
7pub struct Package {
8 pub metadata: PackageMetadata,
9 pub files: HashMap<String, Vec<u8>>,
10}
11
12impl Package {
13 pub fn new(metadata: PackageMetadata) -> Self {
14 Self {
15 metadata,
16 files: HashMap::new(),
17 }
18 }
19
20 pub fn add_file(&mut self, path: String, content: Vec<u8>) {
21 self.files.insert(path, content);
22 }
23
24 pub fn get_file(&self, path: &str) -> Option<&Vec<u8>> {
25 self.files.get(path)
26 }
27
28 pub fn get_file_as_string(&self, path: &str) -> Option<String> {
29 self.files
30 .get(path)
31 .map(|v| String::from_utf8_lossy(v).to_string())
32 }
33
34 pub fn get_challenge_config(&self) -> Option<ChallengeConfig> {
36 Some(self.metadata.config.clone())
37 }
38
39 pub fn get_custom_challenge(&self) -> Option<Custom> {
40 Some(self.metadata.custom.clone())
41 }
42
43 pub fn get_html_file(&self) -> Option<String> {
44 let custom_challenge = self.get_custom_challenge()?;
45 let filename = custom_challenge.html;
46 self.get_file_as_string(&filename)
47 }
48
49 pub fn get_css_file(&self) -> Option<String> {
50 let custom_challenge = self.get_custom_challenge()?;
51 let filename = custom_challenge.css;
52 self.get_file_as_string(&filename)
53 }
54
55 pub fn get_js_file(&self) -> Option<String> {
56 let custom_challenge = self.get_custom_challenge()?;
57 let filename = custom_challenge.js;
58 self.get_file_as_string(&filename)
59 }
60
61 pub fn get_results_file(&self) -> Option<String> {
62 let custom_challenge = self.get_custom_challenge()?;
63 let filename = custom_challenge.results_html;
64 match filename {
65 Some(filename) => self.get_file_as_string(&filename),
66 None => None,
67 }
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::challenges::Custom;
75
76 #[test]
77 fn test_package() {
78 let metadata = PackageMetadata::default();
79 let mut package = Package::new(metadata);
80 package.add_file("test.txt".to_string(), b"test".to_vec());
81 assert_eq!(package.get_file("test.txt"), Some(&b"test".to_vec()));
82 assert_eq!(
83 package.get_file_as_string("test.txt"),
84 Some("test".to_string())
85 );
86 }
87
88 #[test]
89 fn test_challenge_config() {
90 let mut metadata = PackageMetadata::default();
91 let config = ChallengeConfig {
92 tasks: 3.into(),
93 ..Default::default()
94 };
95 metadata.config = config.clone();
96 let mut package = Package::new(metadata);
97
98 package.add_file(
99 "config.yml".to_string(),
100 serde_yaml::to_string(&config).unwrap().into_bytes(),
101 );
102 assert_eq!(
103 package.get_challenge_config(),
104 Some(ChallengeConfig {
105 tasks: 3.into(),
106 ..Default::default()
107 })
108 );
109 }
110
111 #[test]
112 fn test_custom_challenge() {
113 let mut metadata = PackageMetadata::default();
114 let custom = Custom {
115 id: "custom_challenge".to_string(),
116 name: "Custom Challenge".to_string(),
117 description: "This is a custom challenge".to_string(),
118 ..Default::default()
119 };
120 metadata.custom = custom.clone();
121 let mut package = Package::new(metadata);
122
123 package.add_file(
124 "challenge.yml".to_string(),
125 serde_yaml::to_string(&custom).unwrap().into_bytes(),
126 );
127 assert_eq!(
128 package.get_custom_challenge(),
129 Some(Custom {
130 id: "custom_challenge".to_string(),
131 name: "Custom Challenge".to_string(),
132 description: "This is a custom challenge".to_string(),
133 ..Default::default()
134 })
135 );
136 }
137
138 #[test]
139 fn test_html_file() {
140 let mut metadata = PackageMetadata::default();
141 let custom = Custom {
142 id: "custom_challenge".to_string(),
143 name: "Custom Challenge".to_string(),
144 description: "This is a custom challenge".to_string(),
145 html: "index.html".to_string(),
146 ..Default::default()
147 };
148 metadata.custom = custom.clone();
149 let mut package = Package::new(metadata);
150
151 package.add_file(
152 "challenge.yml".to_string(),
153 serde_yaml::to_string(&custom).unwrap().into_bytes(),
154 );
155 package.add_file("index.html".to_string(), b"<html></html>".to_vec());
156 assert_eq!(package.get_html_file(), Some("<html></html>".to_string()));
157 }
158
159 #[test]
160 fn test_css_file() {
161 let mut metadata = PackageMetadata::default();
162 let custom = Custom {
163 id: "custom_challenge".to_string(),
164 name: "Custom Challenge".to_string(),
165 description: "This is a custom challenge".to_string(),
166 css: "style.css".to_string(),
167 ..Default::default()
168 };
169 metadata.custom = custom.clone();
170 let mut package = Package::new(metadata);
171
172 package.add_file(
173 "challenge.yml".to_string(),
174 serde_yaml::to_string(&custom).unwrap().into_bytes(),
175 );
176 package.add_file("style.css".to_string(), b"body { color: red; }".to_vec());
177 assert_eq!(
178 package.get_css_file(),
179 Some("body { color: red; }".to_string())
180 );
181 }
182
183 #[test]
184 fn test_js_file() {
185 let mut metadata = PackageMetadata::default();
186 let custom = Custom {
187 id: "custom_challenge".to_string(),
188 name: "Custom Challenge".to_string(),
189 description: "This is a custom challenge".to_string(),
190 js: "script.js".to_string(),
191 ..Default::default()
192 };
193 metadata.custom = custom.clone();
194 let mut package = Package::new(metadata);
195
196 package.add_file(
197 "challenge.yml".to_string(),
198 serde_yaml::to_string(&custom).unwrap().into_bytes(),
199 );
200 package.add_file(
201 "script.js".to_string(),
202 b"console.log('Hello, World!');".to_vec(),
203 );
204 assert_eq!(
205 package.get_js_file(),
206 Some("console.log('Hello, World!');".to_string())
207 );
208 }
209
210 #[test]
211 fn test_results_file() {
212 let mut metadata = PackageMetadata::default();
213 let custom = Custom {
214 id: "custom_challenge".to_string(),
215 name: "Custom Challenge".to_string(),
216 description: "This is a custom challenge".to_string(),
217 results_html: Some("results.html".to_string()),
218 ..Default::default()
219 };
220 metadata.custom = custom.clone();
221 let mut package = Package::new(metadata);
222
223 package.add_file(
224 "challenge.yml".to_string(),
225 serde_yaml::to_string(&custom).unwrap().into_bytes(),
226 );
227 package.add_file("results.html".to_string(), b"<html></html>".to_vec());
228 assert_eq!(
229 package.get_results_file(),
230 Some("<html></html>".to_string())
231 );
232 }
233}