mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-01-09 20:03:24 +03:00
Compare commits
No commits in common. "d8c2ab8349854cbc7f4a994c7413d266cc38bc24" and "86684b7fc9dd5e8bedad6056565645d1d980925c" have entirely different histories.
d8c2ab8349
...
86684b7fc9
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -656,9 +656,9 @@ checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
version = "0.38.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
checksum = "e3cc72858054fcff6d7dea32df2aeaee6a7c24227366d7ea429aada2f26b16ad"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"errno",
|
||||
|
@ -669,7 +669,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustlings"
|
||||
version = "6.0.0-beta.0"
|
||||
version = "6.0.0-alpha.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_cmd",
|
||||
|
@ -687,11 +687,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustlings-macros"
|
||||
version = "6.0.0-beta.0"
|
||||
version = "6.0.0-alpha.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"serde",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -954,11 +952,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.7"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134306a13c5647ad6453e8deaec55d3a44d6021970129e6188735e74bf546697"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
21
Cargo.toml
21
Cargo.toml
|
@ -8,34 +8,23 @@ exclude = [
|
|||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "6.0.0-beta.0"
|
||||
version = "6.0.0-alpha.0"
|
||||
authors = [
|
||||
"Liv <mokou@fastmail.com>",
|
||||
"Mo Bitar <mo8it@proton.me>",
|
||||
# Alumni
|
||||
"Carol (Nichols || Goulding) <carol.nichols@gmail.com>",
|
||||
"Mo <mo8it@proton.me>",
|
||||
]
|
||||
repository = "https://github.com/rust-lang/rustlings"
|
||||
license = "MIT"
|
||||
edition = "2021"
|
||||
|
||||
[workspace.dependencies]
|
||||
serde = { version = "1.0.198", features = ["derive"] }
|
||||
toml_edit = { version = "0.22.12", default-features = false, features = ["parse", "serde"] }
|
||||
|
||||
[package]
|
||||
name = "rustlings"
|
||||
description = "Small exercises to get you used to reading and writing Rust code!"
|
||||
default-run = "rustlings"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
keywords = [
|
||||
"exercise",
|
||||
"learning",
|
||||
]
|
||||
include = [
|
||||
"/exercises/",
|
||||
"/info.toml",
|
||||
|
@ -51,9 +40,9 @@ crossterm = "0.27.0"
|
|||
hashbrown = "0.14.3"
|
||||
notify-debouncer-mini = "0.4.1"
|
||||
ratatui = "0.26.2"
|
||||
rustlings-macros = { path = "rustlings-macros", version = "6.0.0-beta.0" }
|
||||
serde.workspace = true
|
||||
toml_edit.workspace = true
|
||||
rustlings-macros = { path = "rustlings-macros", version = "6.0.0-alpha.0" }
|
||||
serde = { version = "1.0.198", features = ["derive"] }
|
||||
toml_edit = { version = "0.22.12", default-features = false, features = ["parse", "serde"] }
|
||||
which = "6.0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -90,6 +90,11 @@ You can also get the hint for the next pending exercise with the following comma
|
|||
rustlings hint
|
||||
```
|
||||
|
||||
## Quizzes
|
||||
|
||||
After every couple of sections, there will be a quiz that'll test your knowledge on a bunch of sections at once.
|
||||
These quizzes are found in `exercises/quizN.rs`.
|
||||
|
||||
## Continuing On
|
||||
|
||||
<!-- TODO: Mention third-party exercises -->
|
||||
|
|
|
@ -7,4 +7,3 @@ Within your program, you can also have independent parts that run simultaneously
|
|||
|
||||
- [Dining Philosophers example](https://doc.rust-lang.org/1.4.0/book/dining-philosophers.html)
|
||||
- [Using Threads to Run Code Simultaneously](https://doc.rust-lang.org/book/ch16-01-threads.html)
|
||||
- [Using Message Passing to Transfer Data Between Threads](https://doc.rust-lang.org/book/ch16-02-message-passing.html)
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
# Quizzes
|
||||
|
||||
After every couple of sections, there will be a quiz in this directory that'll test your knowledge on a bunch of sections at once.
|
|
@ -175,7 +175,10 @@ mode = "run"
|
|||
hint = """
|
||||
The error message points to the function `sale_price` and says it expects a type
|
||||
after the `->`. This is where the function's return type should be -- take a
|
||||
look at the `is_even` function for an example!"""
|
||||
look at the `is_even` function for an example!
|
||||
|
||||
Also: Did you figure out that, technically, `u32` would be the more fitting type
|
||||
for the inputs of the functions here, since the original prices shouldn't be negative? If so, kudos!"""
|
||||
|
||||
[[exercises]]
|
||||
name = "functions5"
|
||||
|
@ -233,7 +236,6 @@ Make sure the type is consistent across all arms."""
|
|||
|
||||
[[exercises]]
|
||||
name = "quiz1"
|
||||
dir = "quizzes"
|
||||
mode = "test"
|
||||
hint = "No hints this time ;)"
|
||||
|
||||
|
@ -635,7 +637,6 @@ Learn more at https://doc.rust-lang.org/book/ch08-03-hash-maps.html#updating-a-v
|
|||
|
||||
[[exercises]]
|
||||
name = "quiz2"
|
||||
dir = "quizzes"
|
||||
mode = "test"
|
||||
hint = "No hints this time ;)"
|
||||
|
||||
|
@ -869,7 +870,6 @@ See the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#spe
|
|||
|
||||
[[exercises]]
|
||||
name = "quiz3"
|
||||
dir = "quizzes"
|
||||
mode = "test"
|
||||
hint = """
|
||||
To find the best solution to this challenge you're going to need to think back
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
[package]
|
||||
name = "rustlings-macros"
|
||||
description = "A macros crate intended to be used only by Rustlings"
|
||||
description = "A macros crate intended to be only used by rustlings"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
|
@ -12,5 +11,3 @@ proc-macro = true
|
|||
|
||||
[dependencies]
|
||||
quote = "1.0.36"
|
||||
serde.workspace = true
|
||||
toml_edit.workspace = true
|
||||
|
|
|
@ -1,39 +1,86 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use serde::Deserialize;
|
||||
use std::{fs::read_dir, panic, path::PathBuf};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ExerciseInfo {
|
||||
name: String,
|
||||
dir: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct InfoFile {
|
||||
exercises: Vec<ExerciseInfo>,
|
||||
fn path_to_string(path: PathBuf) -> String {
|
||||
path.into_os_string()
|
||||
.into_string()
|
||||
.unwrap_or_else(|original| {
|
||||
panic!("The path {} is invalid UTF8", original.to_string_lossy());
|
||||
})
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn include_files(_: TokenStream) -> TokenStream {
|
||||
let exercises = toml_edit::de::from_str::<InfoFile>(include_str!("../../info.toml"))
|
||||
.expect("Failed to parse `info.toml`")
|
||||
.exercises;
|
||||
let mut files = Vec::with_capacity(8);
|
||||
let mut dirs = Vec::with_capacity(128);
|
||||
|
||||
let exercise_files = exercises
|
||||
.iter()
|
||||
.map(|exercise| format!("../exercises/{}/{}.rs", exercise.dir, exercise.name));
|
||||
let solution_files = exercises
|
||||
.iter()
|
||||
.map(|exercise| format!("../solutions/{}/{}.rs", exercise.dir, exercise.name));
|
||||
let dirs = exercises.iter().map(|exercise| &exercise.dir);
|
||||
let readmes = exercises
|
||||
.iter()
|
||||
.map(|exercise| format!("../exercises/{}/README.md", exercise.dir));
|
||||
for entry in read_dir("exercises").expect("Failed to open the `exercises` directory") {
|
||||
let entry = entry.expect("Failed to read the `exercises` directory");
|
||||
|
||||
if entry.file_type().unwrap().is_file() {
|
||||
let path = entry.path();
|
||||
if path.file_name().unwrap() != "README.md" {
|
||||
files.push(path_to_string(path));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
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! {
|
||||
EmbeddedFiles {
|
||||
exercise_files: &[#(ExerciseFiles { exercise: include_bytes!(#exercise_files), solution: include_bytes!(#solution_files) }),*],
|
||||
exercise_dirs: &[#(ExerciseDir { name: #dirs, readme: include_bytes!(#readmes) }),*]
|
||||
exercises_dir: ExercisesDir {
|
||||
readme: EmbeddedFile {
|
||||
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()
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
|
@ -1 +0,0 @@
|
|||
// TODO
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue