merge conflict

This commit is contained in:
Jack Harper 2021-09-25 10:16:21 +01:00
commit 90e990901d
7 changed files with 143 additions and 56 deletions

View File

@ -957,6 +957,51 @@
"content",
"code"
]
},
{
"login": "granddaifuku",
"name": "granddaifuku",
"avatar_url": "https://avatars.githubusercontent.com/u/49578068?v=4",
"profile": "https://granddaifuku.com/",
"contributions": [
"content"
]
},
{
"login": "Weilet",
"name": "Weilet",
"avatar_url": "https://avatars.githubusercontent.com/u/32561597?v=4",
"profile": "https://weilet.me",
"contributions": [
"content"
]
},
{
"login": "Millione",
"name": "LIU JIE",
"avatar_url": "https://avatars.githubusercontent.com/u/38575932?v=4",
"profile": "https://github.com/Millione",
"contributions": [
"content"
]
},
{
"login": "abusch",
"name": "Antoine Büsch",
"avatar_url": "https://avatars.githubusercontent.com/u/506344?v=4",
"profile": "https://github.com/abusch",
"contributions": [
"code"
]
},
{
"login": "frogtd",
"name": "frogtd",
"avatar_url": "https://avatars.githubusercontent.com/u/31412003?v=4",
"profile": "https://frogtd.com/",
"contributions": [
"content"
]
}
],
"contributorsPerLine": 8,

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ exercises/clippy/Cargo.toml
exercises/clippy/Cargo.lock
.idea
.vscode
*.iml

View File

@ -1,5 +1,5 @@
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-103-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-108-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
# rustlings 🦀❤️
@ -305,6 +305,13 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center"><a href="https://github.com/dbednar230"><img src="https://avatars.githubusercontent.com/u/54457902?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Damian</b></sub></a><br /><a href="#content-dbednar230" title="Content">🖋</a></td>
<td align="center"><a href="https://benarmstead.co.uk"><img src="https://avatars.githubusercontent.com/u/70973680?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ben Armstead</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=benarmstead" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/anuk909"><img src="https://avatars.githubusercontent.com/u/34924662?v=4?s=100" width="100px;" alt=""/><br /><sub><b>anuk909</b></sub></a><br /><a href="#content-anuk909" title="Content">🖋</a> <a href="https://github.com/rust-lang/rustlings/commits?author=anuk909" title="Code">💻</a></td>
<td align="center"><a href="https://granddaifuku.com/"><img src="https://avatars.githubusercontent.com/u/49578068?v=4?s=100" width="100px;" alt=""/><br /><sub><b>granddaifuku</b></sub></a><br /><a href="#content-granddaifuku" title="Content">🖋</a></td>
</tr>
<tr>
<td align="center"><a href="https://weilet.me"><img src="https://avatars.githubusercontent.com/u/32561597?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Weilet</b></sub></a><br /><a href="#content-Weilet" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/Millione"><img src="https://avatars.githubusercontent.com/u/38575932?v=4?s=100" width="100px;" alt=""/><br /><sub><b>LIU JIE</b></sub></a><br /><a href="#content-Millione" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/abusch"><img src="https://avatars.githubusercontent.com/u/506344?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Antoine Büsch</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=abusch" title="Code">💻</a></td>
<td align="center"><a href="https://frogtd.com/"><img src="https://avatars.githubusercontent.com/u/31412003?v=4?s=100" width="100px;" alt=""/><br /><sub><b>frogtd</b></sub></a><br /><a href="#content-frogtd" title="Content">🖋</a></td>
</tr>
</table>

View File

@ -1,13 +1,13 @@
// modules2.rs
// You can bring module paths into scopes and provide new names for them with the
// 'use' and 'as' keywords. Fix these 'use' statments to make the code compile.
// 'use' and 'as' keywords. Fix these 'use' statements to make the code compile.
// Make me compile! Execute `rustlings hint modules2` for hints :)
// I AM NOT DONE
mod delicious_snacks {
// TODO: Fix these use statments
// TODO: Fix these use statements
use self::fruits::PEAR as ???
use self::veggies::CUCUMBER as ???

View File

@ -7,8 +7,7 @@
// more than 40 at once, each apple only costs 1! Write a function that calculates
// the price of an order of apples given the quantity bought. No hints this time!
// Put your function here!
// fn ..... {
// Put your function here!// fn ..... {
fn calculate_apple_price(quantity:i32) -> i32 {
if quantity > 40 {
return quantity * 1;
@ -16,6 +15,7 @@ fn calculate_apple_price(quantity:i32) -> i32 {
return quantity * 2;
}
}
// fn calculate_apple_price {
// Don't modify this function!
#[test]

View File

@ -133,7 +133,7 @@ path = "{}.rs""#,
"Failed to write 📎 Clippy 📎 Cargo.toml file."
};
fs::write(CLIPPY_CARGO_TOML_PATH, cargo_toml).expect(cargo_toml_error_msg);
// To support the ability to run the clipy exercises, build
// To support the ability to run the clippy exercises, build
// an executable, in addition to running clippy. With a
// compilation failure, this would silently fail. But we expect
// clippy to reflect the same failure while compiling later.

View File

@ -10,7 +10,8 @@ use std::fs;
use std::io::{self, prelude::*};
use std::path::Path;
use std::process::{Command, Stdio};
use std::sync::mpsc::channel;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{RecvTimeoutError, channel};
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
@ -217,65 +218,85 @@ fn main() {
}
Subcommands::Watch(_subargs) => {
if let Err(e) = watch(&exercises, verbose) {
println!(
"Error: Could not watch your progress. Error message was {:?}.",
e
);
println!("Most likely you've run out of disk space or your 'inotify limit' has been reached.");
std::process::exit(1);
match watch(&exercises, verbose) {
Err(e) => {
println!(
"Error: Could not watch your progress. Error message was {:?}.",
e
);
println!("Most likely you've run out of disk space or your 'inotify limit' has been reached.");
std::process::exit(1);
}
Ok(WatchStatus::Finished) => {
println!(
"{emoji} All exercises completed! {emoji}",
emoji = Emoji("🎉", "")
);
println!();
println!("+----------------------------------------------------+");
println!("| You made it to the Fe-nish line! |");
println!("+-------------------------- ------------------------+");
println!(" \\/ ");
println!(" ▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒ ");
println!(" ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ ");
println!(" ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ ");
println!(" ░░▒▒▒▒░░▒▒ ▒▒ ▒▒ ▒▒ ▒▒░░▒▒▒▒ ");
println!(" ▓▓▓▓▓▓▓▓ ▓▓ ▓▓██ ▓▓ ▓▓██ ▓▓ ▓▓▓▓▓▓▓▓ ");
println!(" ▒▒▒▒ ▒▒ ████ ▒▒ ████ ▒▒░░ ▒▒▒▒ ");
println!(" ▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒ ");
println!(" ▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒▒▒▒▒▒▒▒▓▓▒▒▓▓▒▒▒▒▒▒▒▒ ");
println!(" ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ");
println!(" ▒▒▒▒▒▒▒▒▒▒██▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒ ");
println!(" ▒▒ ▒▒▒▒▒▒▒▒▒▒██████▒▒▒▒▒▒▒▒▒▒ ▒▒ ");
println!(" ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ");
println!(" ▒▒ ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ▒▒ ");
println!(" ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ");
println!(" ▒▒ ▒▒ ▒▒ ▒▒ ");
println!();
println!("We hope you enjoyed learning about the various aspects of Rust!");
println!(
"If you noticed any issues, please don't hesitate to report them to our repo."
);
println!("You can also contribute your own exercises to help the greater community!");
println!();
println!("Before reporting an issue or contributing, please read our guidelines:");
println!("https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md");
}
Ok(WatchStatus::Unfinished) => {
println!("We hope you're enjoying learning about Rust!");
println!("If you want to continue working on the exercises at a later point, you can simply run `rustlings watch` again");
}
}
println!(
"{emoji} All exercises completed! {emoji}",
emoji = Emoji("🎉", "")
);
println!();
println!("+----------------------------------------------------+");
println!("| You made it to the Fe-nish line! |");
println!("+-------------------------- ------------------------+");
println!(" \\/ ");
println!(" ▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒ ");
println!(" ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ ");
println!(" ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ ");
println!(" ░░▒▒▒▒░░▒▒ ▒▒ ▒▒ ▒▒ ▒▒░░▒▒▒▒ ");
println!(" ▓▓▓▓▓▓▓▓ ▓▓ ▓▓██ ▓▓ ▓▓██ ▓▓ ▓▓▓▓▓▓▓▓ ");
println!(" ▒▒▒▒ ▒▒ ████ ▒▒ ████ ▒▒░░ ▒▒▒▒ ");
println!(" ▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒ ");
println!(" ▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒▒▒▒▒▒▒▒▓▓▒▒▓▓▒▒▒▒▒▒▒▒ ");
println!(" ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ");
println!(" ▒▒▒▒▒▒▒▒▒▒██▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒ ");
println!(" ▒▒ ▒▒▒▒▒▒▒▒▒▒██████▒▒▒▒▒▒▒▒▒▒ ▒▒ ");
println!(" ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ");
println!(" ▒▒ ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ▒▒ ");
println!(" ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ");
println!(" ▒▒ ▒▒ ▒▒ ▒▒ ");
println!();
println!("We hope you enjoyed learning about the various aspects of Rust!");
println!(
"If you noticed any issues, please don't hesitate to report them to our repo."
);
println!("You can also contribute your own exercises to help the greater community!");
println!();
println!("Before reporting an issue or contributing, please read our guidelines:");
println!("https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md");
}
}
}
fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>) {
fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>, should_quit: Arc<AtomicBool>) {
let failed_exercise_hint = Arc::clone(failed_exercise_hint);
println!("Type 'hint' or open the corresponding README.md file to get help or type 'clear' to clear the screen.");
println!("Welcome to watch mode! You can type 'help' to get an overview of the commands you can use here.");
thread::spawn(move || loop {
let mut input = String::new();
match io::stdin().read_line(&mut input) {
Ok(_) => {
let input = input.trim();
if input.eq("hint") {
if input == "hint" {
if let Some(hint) = &*failed_exercise_hint.lock().unwrap() {
println!("{}", hint);
}
} else if input.eq("clear") {
} else if input == "clear" {
println!("\x1B[2J\x1B[1;1H");
} else if input.eq("quit") {
should_quit.store(true, Ordering::SeqCst);
println!("Bye!");
} else if input.eq("help") {
println!("Commands available to you in watch mode:");
println!(" hint - prints the current exercise's hint");
println!(" clear - clears the screen");
println!(" quit - quits watch mode");
println!(" help - displays this help message");
println!();
println!("Watch mode automatically re-evaluates the current exercise");
println!("when you edit a file's contents.")
} else {
println!("unknown command: {}", input);
}
@ -306,7 +327,12 @@ fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> &'a Exercise {
}
}
fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
enum WatchStatus {
Finished,
Unfinished,
}
fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<WatchStatus> {
/* Clears the terminal with an ANSI escape code.
Works in UNIX and newer Windows terminals. */
fn clear_screen() {
@ -314,6 +340,7 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
}
let (tx, rx) = channel();
let should_quit = Arc::new(AtomicBool::new(false));
let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(2))?;
watcher.watch(Path::new("./exercises"), RecursiveMode::Recursive)?;
@ -322,12 +349,12 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
let to_owned_hint = |t: &Exercise| t.hint.to_owned();
let failed_exercise_hint = match verify(exercises.iter(), verbose) {
Ok(_) => return Ok(()),
Ok(_) => return Ok(WatchStatus::Finished),
Err(exercise) => Arc::new(Mutex::new(Some(to_owned_hint(exercise)))),
};
spawn_watch_shell(&failed_exercise_hint);
spawn_watch_shell(&failed_exercise_hint, Arc::clone(&should_quit));
loop {
match rx.recv() {
match rx.recv_timeout(Duration::from_secs(1)) {
Ok(event) => match event {
DebouncedEvent::Create(b) | DebouncedEvent::Chmod(b) | DebouncedEvent::Write(b) => {
if b.extension() == Some(OsStr::new("rs")) && b.exists() {
@ -343,7 +370,7 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
);
clear_screen();
match verify(pending_exercises, verbose) {
Ok(_) => return Ok(()),
Ok(_) => return Ok(WatchStatus::Finished),
Err(exercise) => {
let mut failed_exercise_hint = failed_exercise_hint.lock().unwrap();
*failed_exercise_hint = Some(to_owned_hint(exercise));
@ -353,8 +380,15 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
}
_ => {}
},
Err(RecvTimeoutError::Timeout) => {
// the timeout expired, just check the `should_quit` variable below then loop again
}
Err(e) => println!("watch error: {:?}", e),
}
// Check if we need to exit
if should_quit.load(Ordering::SeqCst) {
return Ok(WatchStatus::Unfinished);
}
}
}