summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormo8it <mo8it@proton.me>2024-03-28 21:06:36 +0100
committermo8it <mo8it@proton.me>2024-03-28 21:06:36 +0100
commitd5ed749e9fde03212fd6fe5d60e2ddfe9b2429c9 (patch)
tree62cff8cd63eeb25ad70f50335b8d6a0a7c1edcd1 /src
parent39bdd086a775d87115691b830f65e2a438874fec (diff)
Add embedded.rs
Diffstat (limited to 'src')
-rw-r--r--src/embedded.rs101
-rw-r--r--src/main.rs25
2 files changed, 102 insertions, 24 deletions
diff --git a/src/embedded.rs b/src/embedded.rs
new file mode 100644
index 0000000..8f6c14e
--- /dev/null
+++ b/src/embedded.rs
@@ -0,0 +1,101 @@
+use std::{
+ fs::{create_dir, File, OpenOptions},
+ io::{self, Write},
+ path::Path,
+};
+
+pub static EMBEDDED_FILES: EmbeddedFiles = rustlings_macros::include_files!();
+
+#[derive(Clone, Copy)]
+pub enum WriteStrategy {
+ IfNotExists,
+ Overwrite,
+}
+
+impl WriteStrategy {
+ fn open<P: AsRef<Path>>(self, path: P) -> io::Result<File> {
+ match self {
+ Self::IfNotExists => OpenOptions::new().create_new(true).write(true).open(path),
+ Self::Overwrite => OpenOptions::new()
+ .create(true)
+ .write(true)
+ .truncate(true)
+ .open(path),
+ }
+ }
+}
+
+struct EmbeddedFile {
+ path: &'static str,
+ content: &'static [u8],
+}
+
+impl EmbeddedFile {
+ fn write_to_disk(&self, strategy: WriteStrategy) -> io::Result<()> {
+ strategy.open(self.path)?.write_all(self.content)
+ }
+}
+
+struct EmbeddedFlatDir {
+ path: &'static str,
+ readme: EmbeddedFile,
+ content: &'static [EmbeddedFile],
+}
+
+impl EmbeddedFlatDir {
+ fn init_on_disk(&self) -> io::Result<()> {
+ let path = Path::new(self.path);
+
+ if let Err(e) = create_dir(path) {
+ if !path.is_dir() {
+ return Err(e);
+ }
+ }
+
+ self.readme.write_to_disk(WriteStrategy::Overwrite)
+ }
+}
+
+struct ExercisesDir {
+ readme: EmbeddedFile,
+ files: &'static [EmbeddedFile],
+ dirs: &'static [EmbeddedFlatDir],
+}
+
+pub struct EmbeddedFiles {
+ info_toml_content: &'static str,
+ exercises_dir: ExercisesDir,
+}
+
+impl EmbeddedFiles {
+ pub fn init_exercises_dir(&self) -> io::Result<()> {
+ create_dir("exercises")?;
+ self.exercises_dir
+ .readme
+ .write_to_disk(WriteStrategy::Overwrite)
+ }
+
+ pub fn write_exercise_to_disk(&self, path: &Path, strategy: WriteStrategy) -> io::Result<()> {
+ if let Some(file) = self
+ .exercises_dir
+ .files
+ .iter()
+ .find(|file| file.path == path.as_os_str())
+ {
+ return file.write_to_disk(strategy);
+ }
+
+ for dir in self.exercises_dir.dirs {
+ if let Some(file) = dir
+ .content
+ .iter()
+ .find(|file| file.path == path.as_os_str())
+ {
+ dir.init_on_disk()?;
+ return file.write_to_disk(strategy);
+ }
+ }
+
+ Err(io::Error::from(io::ErrorKind::NotFound))
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index 7822d12..1e0aa66 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -22,35 +22,12 @@ use std::time::Duration;
#[macro_use]
mod ui;
+mod embedded;
mod exercise;
mod project;
mod run;
mod verify;
-struct EmbeddedFile {
- path: &'static str,
- content: &'static [u8],
-}
-
-struct EmbeddedFlatDir {
- path: &'static str,
- readme: EmbeddedFile,
- content: &'static [EmbeddedFile],
-}
-
-struct ExercisesDir {
- readme: EmbeddedFile,
- files: &'static [EmbeddedFile],
- dirs: &'static [EmbeddedFlatDir],
-}
-
-struct EmbeddedFiles {
- info_toml_content: &'static str,
- exercises_dir: ExercisesDir,
-}
-
-static EMBEDDED_FILES: EmbeddedFiles = rustlings_macros::include_files!();
-
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
#[derive(Parser)]
#[command(version)]