Refactor embedded files to add solutions

This commit is contained in:
mo8it 2024-04-23 19:18:25 +02:00
parent e5a19a4c33
commit 2dac8e509b
105 changed files with 198 additions and 158 deletions

2
Cargo.lock generated
View file

@ -690,6 +690,8 @@ name = "rustlings-macros"
version = "6.0.0-alpha.0" version = "6.0.0-alpha.0"
dependencies = [ dependencies = [
"quote", "quote",
"serde",
"toml_edit",
] ]
[[package]] [[package]]

View file

@ -17,6 +17,10 @@ authors = [
license = "MIT" license = "MIT"
edition = "2021" edition = "2021"
[workspace.dependencies]
serde = { version = "1.0.198", features = ["derive"] }
toml_edit = { version = "0.22.12", default-features = false, features = ["parse", "serde"] }
[package] [package]
name = "rustlings" name = "rustlings"
description = "Small exercises to get you used to reading and writing Rust code!" description = "Small exercises to get you used to reading and writing Rust code!"
@ -41,8 +45,8 @@ hashbrown = "0.14.3"
notify-debouncer-mini = "0.4.1" notify-debouncer-mini = "0.4.1"
ratatui = "0.26.2" ratatui = "0.26.2"
rustlings-macros = { path = "rustlings-macros", version = "6.0.0-alpha.0" } rustlings-macros = { path = "rustlings-macros", version = "6.0.0-alpha.0" }
serde = { version = "1.0.198", features = ["derive"] } serde.workspace = true
toml_edit = { version = "0.22.12", default-features = false, features = ["parse", "serde"] } toml_edit.workspace = true
which = "6.0.1" which = "6.0.1"
[dev-dependencies] [dev-dependencies]

View file

@ -236,6 +236,7 @@ Make sure the type is consistent across all arms."""
[[exercises]] [[exercises]]
name = "quiz1" name = "quiz1"
dir = "quizzes"
mode = "test" mode = "test"
hint = "No hints this time ;)" hint = "No hints this time ;)"
@ -637,6 +638,7 @@ Learn more at https://doc.rust-lang.org/book/ch08-03-hash-maps.html#updating-a-v
[[exercises]] [[exercises]]
name = "quiz2" name = "quiz2"
dir = "quizzes"
mode = "test" mode = "test"
hint = "No hints this time ;)" hint = "No hints this time ;)"
@ -870,6 +872,7 @@ See the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#spe
[[exercises]] [[exercises]]
name = "quiz3" name = "quiz3"
dir = "quizzes"
mode = "test" mode = "test"
hint = """ hint = """
To find the best solution to this challenge you're going to need to think back To find the best solution to this challenge you're going to need to think back

View file

@ -11,3 +11,5 @@ proc-macro = true
[dependencies] [dependencies]
quote = "1.0.36" quote = "1.0.36"
serde.workspace = true
toml_edit.workspace = true

View file

@ -1,86 +1,39 @@
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use quote::quote;
use std::{fs::read_dir, panic, path::PathBuf}; use serde::Deserialize;
fn path_to_string(path: PathBuf) -> String { #[derive(Deserialize)]
path.into_os_string() struct ExerciseInfo {
.into_string() name: String,
.unwrap_or_else(|original| { dir: String,
panic!("The path {} is invalid UTF8", original.to_string_lossy()); }
})
#[derive(Deserialize)]
struct InfoFile {
exercises: Vec<ExerciseInfo>,
} }
#[proc_macro] #[proc_macro]
pub fn include_files(_: TokenStream) -> TokenStream { pub fn include_files(_: TokenStream) -> TokenStream {
let mut files = Vec::with_capacity(8); let exercises = toml_edit::de::from_str::<InfoFile>(include_str!("../../info.toml"))
let mut dirs = Vec::with_capacity(128); .expect("Failed to parse `info.toml`")
.exercises;
for entry in read_dir("exercises").expect("Failed to open the `exercises` directory") { let exercise_files = exercises
let entry = entry.expect("Failed to read the `exercises` directory"); .iter()
.map(|exercise| format!("../exercises/{}/{}.rs", exercise.dir, exercise.name));
if entry.file_type().unwrap().is_file() { let solution_files = exercises
let path = entry.path(); .iter()
if path.file_name().unwrap() != "README.md" { .map(|exercise| format!("../solutions/{}/{}.rs", exercise.dir, exercise.name));
files.push(path_to_string(path)); let dirs = exercises.iter().map(|exercise| &exercise.dir);
} let readmes = exercises
.iter()
continue; .map(|exercise| format!("../exercises/{}/README.md", exercise.dir));
}
let dir_path = entry.path();
let dir_files = read_dir(&dir_path).unwrap_or_else(|e| {
panic!("Failed to open the directory {}: {e}", dir_path.display());
});
let dir_path = path_to_string(dir_path);
let dir_files = dir_files.filter_map(|entry| {
let entry = entry.unwrap_or_else(|e| {
panic!("Failed to read the directory {dir_path}: {e}");
});
let path = entry.path();
if !entry.file_type().unwrap().is_file() {
panic!("Found {} but expected only files", path.display());
}
if path.file_name().unwrap() == "README.md" {
return None;
}
Some(path_to_string(path))
});
dirs.push(quote! {
EmbeddedFlatDir {
path: #dir_path,
readme: EmbeddedFile {
path: ::std::concat!(#dir_path, "/README.md"),
content: ::std::include_bytes!(::std::concat!("../", #dir_path, "/README.md")),
},
content: &[
#(EmbeddedFile {
path: #dir_files,
content: ::std::include_bytes!(::std::concat!("../", #dir_files)),
}),*
],
}
});
}
quote! { quote! {
EmbeddedFiles { EmbeddedFiles {
exercises_dir: ExercisesDir { exercise_files: &[#(ExerciseFiles { exercise: include_bytes!(#exercise_files), solution: include_bytes!(#solution_files) }),*],
readme: EmbeddedFile { exercise_dirs: &[#(ExerciseDir { name: #dirs, readme: include_bytes!(#readmes) }),*]
path: "exercises/README.md",
content: ::std::include_bytes!("../exercises/README.md"),
},
files: &[#(
EmbeddedFile {
path: #files,
content: ::std::include_bytes!(::std::concat!("../", #files)),
}
),*],
dirs: &[#(#dirs),*],
},
} }
} }
.into() .into()

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

1
solutions/03_if/if1.rs Normal file
View file

@ -0,0 +1 @@
// TODO

1
solutions/03_if/if2.rs Normal file
View file

@ -0,0 +1 @@
// TODO

1
solutions/03_if/if3.rs Normal file
View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

View file

@ -0,0 +1 @@
// TODO

Some files were not shown because too many files have changed in this diff Show more