commit
df3389cfb0
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,5 @@
|
|||||||
*.swp
|
*.swp
|
||||||
target/
|
target/
|
||||||
|
**/*.rs.bk
|
||||||
|
Cargo.lock
|
||||||
|
.DS_Store
|
||||||
|
19
.travis.yml
19
.travis.yml
@ -1,19 +0,0 @@
|
|||||||
language: rust
|
|
||||||
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
|
|
||||||
cache:
|
|
||||||
cargo: true
|
|
||||||
|
|
||||||
script:
|
|
||||||
- cargo run --bin generate_readme
|
|
||||||
- git config user.name "Carol (Nichols || Goulding)"
|
|
||||||
- git config user.email "carol.nichols@gmail.com"
|
|
||||||
- git commit -am "Regenerate README" && git remote add upstream "https://$GH_TOKEN@github.com/carols10cents/rustlings.git" && git push -q upstream HEAD:master > /dev/null 2>&1 || true
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
email:
|
|
||||||
on_success: never
|
|
||||||
|
|
11
Cargo.toml
11
Cargo.toml
@ -1,9 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rustlings"
|
name = "rustlings"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Carol (Nichols || Goulding) <carol.nichols@gmail.com>"]
|
authors = ["olivia <819880950@qq.com>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
handlebars = "0.32.0"
|
clap = "2.32.0"
|
||||||
serde_json = "1.0.10"
|
indicatif = "0.9.0"
|
||||||
prlink = { git = "https://github.com/btbytes/prlink" }
|
console = "0.6.2"
|
||||||
|
syntect = "3.0.2"
|
||||||
|
notify = "4.0.0"
|
||||||
|
@ -1,191 +0,0 @@
|
|||||||
<!--
|
|
||||||
{{ autogenerated_notice }}
|
|
||||||
-->
|
|
||||||
|
|
||||||
# rustlings
|
|
||||||
|
|
||||||
Small exercises to get you used to reading and writing Rust code. Includes practice reading and
|
|
||||||
responding to compiler messages!
|
|
||||||
|
|
||||||
This repo is very much the smallest thing that could possibly work :)
|
|
||||||
|
|
||||||
## To do these exercises
|
|
||||||
|
|
||||||
Thanks to [btbytes'](https://twitter.com/btbytes) [prlinks](https://github.com/btbytes/prlink), you
|
|
||||||
can now click on the links below to load the exercises in the rust playground!
|
|
||||||
|
|
||||||
There are infinite correct answers-- the exercises are sometimes left very open-ended. Scroll down
|
|
||||||
in the playground to find comments that have hints.
|
|
||||||
|
|
||||||
If you need more help or would like to compare solutions, you can ask in [#rust-beginners on
|
|
||||||
irc.mozilla.org](https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-beginners ), the
|
|
||||||
[user forum](https://users.rust-lang.org/), or [the subreddit](https://reddit.com/r/rust). If an
|
|
||||||
exercise could be improved in any way, please [create an
|
|
||||||
issue](https://github.com/carols10cents/rustlings/issues/new) or submit a pull request!
|
|
||||||
|
|
||||||
### Variable bindings
|
|
||||||
|
|
||||||
[Relevant chapter in The Rust Programming
|
|
||||||
Language](https://doc.rust-lang.org/book/second-edition/ch03-01-variables-and-mutability.html)
|
|
||||||
|
|
||||||
{{ playground_link "variables/variables1.rs" }}
|
|
||||||
{{ playground_link "variables/variables2.rs" }}
|
|
||||||
{{ playground_link "variables/variables3.rs" }}
|
|
||||||
{{ playground_link "variables/variables4.rs" }}
|
|
||||||
|
|
||||||
### Functions
|
|
||||||
|
|
||||||
[Relevant chapter in The Rust Programming
|
|
||||||
Language](https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html)
|
|
||||||
|
|
||||||
{{ playground_link "functions/functions1.rs" }}
|
|
||||||
{{ playground_link "functions/functions2.rs" }}
|
|
||||||
{{ playground_link "functions/functions3.rs" }}
|
|
||||||
{{ playground_link "functions/functions4.rs" }}
|
|
||||||
{{ playground_link "functions/functions5.rs" }}
|
|
||||||
|
|
||||||
### Primitive types
|
|
||||||
|
|
||||||
[Relevant chapter in The Rust Programming
|
|
||||||
Language](https://doc.rust-lang.org/book/second-edition/ch03-02-data-types.html)
|
|
||||||
|
|
||||||
{{ playground_link "primitive_types/primitive_types1.rs" }}
|
|
||||||
{{ playground_link "primitive_types/primitive_types2.rs" }}
|
|
||||||
{{ playground_link "primitive_types/primitive_types3.rs" }}
|
|
||||||
{{ playground_link "primitive_types/primitive_types4.rs" }}
|
|
||||||
{{ playground_link "primitive_types/primitive_types5.rs" }}
|
|
||||||
{{ playground_link "primitive_types/primitive_types6.rs" }}
|
|
||||||
|
|
||||||
### Tests
|
|
||||||
|
|
||||||
Going out of order from the book to cover tests-- many of the following exercises will ask you to
|
|
||||||
make tests pass!
|
|
||||||
|
|
||||||
[Relevant chapter in The Rust Programming
|
|
||||||
Language](https://doc.rust-lang.org/book/second-edition/ch11-01-writing-tests.html)
|
|
||||||
|
|
||||||
{{ playground_link "tests/tests1.rs" }}
|
|
||||||
{{ playground_link "tests/tests2.rs" }}
|
|
||||||
{{ playground_link "tests/tests3.rs" }}
|
|
||||||
{{ playground_link "tests/tests4.rs" }}
|
|
||||||
|
|
||||||
### If
|
|
||||||
|
|
||||||
[Relevant chapter in The Rust Programming
|
|
||||||
Language](https://doc.rust-lang.org/book/second-edition/ch03-05-control-flow.html)
|
|
||||||
|
|
||||||
{{ playground_link "if/if1.rs" }}
|
|
||||||
|
|
||||||
### Strings
|
|
||||||
|
|
||||||
[Relevant chapter in The Rust Programming
|
|
||||||
Language](https://doc.rust-lang.org/book/second-edition/ch08-02-strings.html)
|
|
||||||
|
|
||||||
{{ playground_link "strings/strings1.rs" }}
|
|
||||||
{{ playground_link "strings/strings2.rs" }}
|
|
||||||
{{ playground_link "strings/strings3.rs" }}
|
|
||||||
|
|
||||||
### Move semantics
|
|
||||||
|
|
||||||
These exercises are adapted from [pnkfelix]()'s [Rust
|
|
||||||
Tutorial](https://pnkfelix.github.io/rust-examples-icfp2014/) -- thank you Felix!!!
|
|
||||||
|
|
||||||
Relevant chapters in the book:
|
|
||||||
|
|
||||||
- [Ownership](https://doc.rust-lang.org/book/second-edition/ch04-01-what-is-ownership.html)
|
|
||||||
- [References and borrowing](https://doc.rust-lang.org/book/second-edition/ch04-02-references-and-borrowing.html)
|
|
||||||
|
|
||||||
Note that the exercises in this section may look similar to each other but they are subtly
|
|
||||||
different :)
|
|
||||||
|
|
||||||
{{ playground_link "move_semantics/move_semantics1.rs" }}
|
|
||||||
{{ playground_link "move_semantics/move_semantics2.rs" }}
|
|
||||||
{{ playground_link "move_semantics/move_semantics3.rs" }}
|
|
||||||
{{ playground_link "move_semantics/move_semantics4.rs" }}
|
|
||||||
|
|
||||||
### Modules
|
|
||||||
|
|
||||||
[Relevant chapter in The Rust Programming
|
|
||||||
Language](https://doc.rust-lang.org/book/second-edition/ch07-01-mod-and-the-filesystem.html)
|
|
||||||
|
|
||||||
{{ playground_link "modules/modules1.rs" }}
|
|
||||||
{{ playground_link "modules/modules2.rs" }}
|
|
||||||
|
|
||||||
### Macros
|
|
||||||
|
|
||||||
Check out:
|
|
||||||
|
|
||||||
- [The Macros section of the first edition of the book
|
|
||||||
book](https://doc.rust-lang.org/book/first-edition/macros.html)
|
|
||||||
- [The Macros appendix of the second edition of the
|
|
||||||
book](https://doc.rust-lang.org/book/second-edition/appendix-04-macros.html)
|
|
||||||
- [The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html)
|
|
||||||
|
|
||||||
{{ playground_link "macros/macros1.rs" }}
|
|
||||||
{{ playground_link "macros/macros2.rs" }}
|
|
||||||
{{ playground_link "macros/macros3.rs" }}
|
|
||||||
{{ playground_link "macros/macros4.rs" }}
|
|
||||||
|
|
||||||
### Error Handling
|
|
||||||
|
|
||||||
The [Error
|
|
||||||
Handling](https://doc.rust-lang.org/book/second-edition/ch09-02-recoverable-errors-with-result.html)
|
|
||||||
and [Generics](https://doc.rust-lang.org/book/second-edition/ch10-01-syntax.html) sections are
|
|
||||||
relevant.
|
|
||||||
|
|
||||||
{{ playground_link "error_handling/option1.rs" }}
|
|
||||||
{{ playground_link "error_handling/result1.rs" }}
|
|
||||||
{{ playground_link "error_handling/errors1.rs" }}
|
|
||||||
{{ playground_link "error_handling/errors2.rs" }}
|
|
||||||
{{ playground_link "error_handling/errors3.rs" }}
|
|
||||||
{{ playground_link "error_handling/errorsn.rs" }}
|
|
||||||
|
|
||||||
### Standard library types
|
|
||||||
|
|
||||||
#### `Arc`
|
|
||||||
|
|
||||||
The [Concurrency](https://doc.rust-lang.org/book/second-edition/ch16-03-shared-state.html) section
|
|
||||||
is relevant.
|
|
||||||
|
|
||||||
{{ playground_link "standard_library_types/arc1.rs" }}
|
|
||||||
|
|
||||||
#### Iterators
|
|
||||||
|
|
||||||
Do not adjust your monitors-- iterators 1 and 2 are indeed missing. Iterator 3 is a bit challenging
|
|
||||||
so we're leaving space for some exercises to lead up to it!
|
|
||||||
|
|
||||||
Check out the [Iterators chapter of the
|
|
||||||
book](https://doc.rust-lang.org/book/second-edition/ch13-02-iterators.html) and the [Iterator
|
|
||||||
docs](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html).
|
|
||||||
|
|
||||||
{{ playground_link "standard_library_types/iterator3.rs" }}
|
|
||||||
{{ playground_link "standard_library_types/iterators4.rs" }}
|
|
||||||
|
|
||||||
### Threads
|
|
||||||
|
|
||||||
See [the Dining Philosophers
|
|
||||||
example](https://doc.rust-lang.org/1.4.0/book/dining-philosophers.html) and the
|
|
||||||
[Concurrency Chapter](https://doc.rust-lang.org/book/second-edition/ch16-01-threads.html) from the
|
|
||||||
book.
|
|
||||||
|
|
||||||
{{ playground_link "threads/threads1.rs" }}
|
|
||||||
|
|
||||||
### Uncategorized
|
|
||||||
|
|
||||||
A few exercises based on things I've encountered or had trouble with getting used to.
|
|
||||||
|
|
||||||
{{ playground_link "ex1.rs" }}
|
|
||||||
{{ playground_link "ex2.rs" }}
|
|
||||||
{{ playground_link "ex3.rs" }}
|
|
||||||
{{ playground_link "ex4.rs" }}
|
|
||||||
{{ playground_link "ex5.rs" }}
|
|
||||||
{{ playground_link "ex6.rs" }}
|
|
||||||
|
|
||||||
## To help with this repo/TODO list
|
|
||||||
|
|
||||||
* File issues for problems or suggestions!
|
|
||||||
* Contribute more exercises! Anything that took you time to get used to, or that you had trouble
|
|
||||||
with, or that deserves practice would be a good exercise!
|
|
||||||
* How could the process of doing these exercises work better? This is an open-ended question :) Are
|
|
||||||
the playground links good enough? Are there ways that we could make going to the next exercise
|
|
||||||
easier without forking the playground??
|
|
20
default_out.md
Normal file
20
default_out.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
Thanks for installing `rustlings`!
|
||||||
|
|
||||||
|
## Is this your first time?
|
||||||
|
|
||||||
|
Let's make sure you're up to speed:
|
||||||
|
- You have Rust installed, preferably via `rustup`
|
||||||
|
- You have `~/.cargo/bin` added to your PATH variable
|
||||||
|
- You have cloned this repository (https://github.com/rustlings/rustlings)
|
||||||
|
- You have installed Rust language support for your editor
|
||||||
|
- You have locally installed the `rustlings` command by running:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo install --path .
|
||||||
|
```
|
||||||
|
|
||||||
|
If you've done all of this (or even most of it), congrats! You're ready
|
||||||
|
to start working with Rust.
|
||||||
|
|
||||||
|
To get started, run `rustlings verify` in order to get the first exercise.
|
||||||
|
Make sure to have your editor open!
|
10
ex2.rs
10
ex2.rs
@ -1,10 +0,0 @@
|
|||||||
// ex2.rs
|
|
||||||
// Make me compile!
|
|
||||||
|
|
||||||
fn something() -> String {
|
|
||||||
"hi!"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("{}", something());
|
|
||||||
}
|
|
10
ex3.rs
10
ex3.rs
@ -1,10 +0,0 @@
|
|||||||
// ex3.rs
|
|
||||||
// Make me compile!
|
|
||||||
|
|
||||||
struct Foo {
|
|
||||||
capacity: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("{:?}", Foo { capacity: 3 });
|
|
||||||
}
|
|
14
ex4.rs
14
ex4.rs
@ -1,14 +0,0 @@
|
|||||||
// ex4.rs
|
|
||||||
// Make me compile!
|
|
||||||
|
|
||||||
fn something() -> Result<i32, std::num::ParseIntError> {
|
|
||||||
let x:i32 = "3".parse();
|
|
||||||
Ok(x * 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
match something() {
|
|
||||||
Ok(..) => println!("You win!"),
|
|
||||||
Err(e) => println!("Oh no something went wrong: {}", e),
|
|
||||||
}
|
|
||||||
}
|
|
22
ex5.rs
22
ex5.rs
@ -1,22 +0,0 @@
|
|||||||
// ex5.rs
|
|
||||||
// Make me compile!
|
|
||||||
|
|
||||||
enum Reaction<'a> {
|
|
||||||
Sad(&'a str),
|
|
||||||
Happy(&'a str),
|
|
||||||
}
|
|
||||||
|
|
||||||
fn express(sentiment: Reaction) {
|
|
||||||
match sentiment {
|
|
||||||
Reaction::Sad(s) => println!(":( {}", s),
|
|
||||||
Reaction::Happy(s) => println!(":) {}", s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main () {
|
|
||||||
let x = Reaction::Happy("It's a great day for Rust!");
|
|
||||||
express(x);
|
|
||||||
express(x);
|
|
||||||
let y = Reaction::Sad("This code doesn't compile yet.");
|
|
||||||
express(y);
|
|
||||||
}
|
|
47
ex6.rs
47
ex6.rs
@ -1,47 +0,0 @@
|
|||||||
// ex6.rs
|
|
||||||
// Make me compile! Scroll down for hints :)
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let robot_name = Some(String::from("Bors"));
|
|
||||||
|
|
||||||
match robot_name {
|
|
||||||
Some(name) => println!("Found a name: {}", name),
|
|
||||||
None => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("robot_name is: {:?}", robot_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Hint: The following two statements are equivalent:
|
|
||||||
// let x = &y;
|
|
||||||
// let ref x = y;
|
|
5
exercises/error_handling/README.md
Normal file
5
exercises/error_handling/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
For this exercise check out the sections:
|
||||||
|
- [Error Handling](https://doc.rust-lang.org/book/2018-edition/ch09-02-recoverable-errors-with-result.html)
|
||||||
|
- [Generics](https://doc.rust-lang.org/book/2018-edition/ch10-01-syntax.html)
|
||||||
|
|
||||||
|
of the Rust Book.
|
0
error_handling/errors1.rs → exercises/error_handling/errors1.rs
Normal file → Executable file
0
error_handling/errors1.rs → exercises/error_handling/errors1.rs
Normal file → Executable file
0
error_handling/errors2.rs → exercises/error_handling/errors2.rs
Normal file → Executable file
0
error_handling/errors2.rs → exercises/error_handling/errors2.rs
Normal file → Executable file
0
error_handling/errors3.rs → exercises/error_handling/errors3.rs
Normal file → Executable file
0
error_handling/errors3.rs → exercises/error_handling/errors3.rs
Normal file → Executable file
0
error_handling/errorsn.rs → exercises/error_handling/errorsn.rs
Normal file → Executable file
0
error_handling/errorsn.rs → exercises/error_handling/errorsn.rs
Normal file → Executable file
0
error_handling/option1.rs → exercises/error_handling/option1.rs
Normal file → Executable file
0
error_handling/option1.rs → exercises/error_handling/option1.rs
Normal file → Executable file
0
error_handling/result1.rs → exercises/error_handling/result1.rs
Normal file → Executable file
0
error_handling/result1.rs → exercises/error_handling/result1.rs
Normal file → Executable file
7
exercises/functions/REAMDE.md
Normal file
7
exercises/functions/REAMDE.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
### Functions
|
||||||
|
|
||||||
|
Here, you'll learn how to write functions and how Rust's compiler can trace things way back.
|
||||||
|
|
||||||
|
#### Book Sections
|
||||||
|
|
||||||
|
- [How Functions Work](https://doc.rust-lang.org/stable/book/ch03-03-how-functions-work.html)
|
0
functions/functions1.rs → exercises/functions/functions1.rs
Normal file → Executable file
0
functions/functions1.rs → exercises/functions/functions1.rs
Normal file → Executable file
0
functions/functions2.rs → exercises/functions/functions2.rs
Normal file → Executable file
0
functions/functions2.rs → exercises/functions/functions2.rs
Normal file → Executable file
0
functions/functions3.rs → exercises/functions/functions3.rs
Normal file → Executable file
0
functions/functions3.rs → exercises/functions/functions3.rs
Normal file → Executable file
0
functions/functions4.rs → exercises/functions/functions4.rs
Normal file → Executable file
0
functions/functions4.rs → exercises/functions/functions4.rs
Normal file → Executable file
0
functions/functions5.rs → exercises/functions/functions5.rs
Normal file → Executable file
0
functions/functions5.rs → exercises/functions/functions5.rs
Normal file → Executable file
7
exercises/if/README.md
Normal file
7
exercises/if/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
### If
|
||||||
|
|
||||||
|
`if`, the most basic type of control flow, is what you'll learn here.
|
||||||
|
|
||||||
|
#### Book Sections
|
||||||
|
|
||||||
|
- [Control Flow - if expressions](https://doc.rust-lang.org/stable/book/ch03-05-control-flow.html#if-expressions)
|
1
if/if1.rs → exercises/if/if1.rs
Normal file → Executable file
1
if/if1.rs → exercises/if/if1.rs
Normal file → Executable file
@ -9,6 +9,7 @@ pub fn bigger(a: i32, b:i32) -> i32 {
|
|||||||
// Scroll down for hints.
|
// Scroll down for hints.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't mind this for now :)
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
10
exercises/macros/README.md
Normal file
10
exercises/macros/README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
### Macros
|
||||||
|
|
||||||
|
Rust's macro system is very powerful, but also kind of difficult to wrap your
|
||||||
|
head around. We're not going to teach you how to write your own fully-featured
|
||||||
|
modules, instead we'll show you how to use and create them.
|
||||||
|
|
||||||
|
#### Book Sections
|
||||||
|
|
||||||
|
- [Macros](https://doc.rust-lang.org/stable/book/ch19-06-macros.html)
|
||||||
|
- [The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html)
|
0
macros/macros1.rs → exercises/macros/macros1.rs
Normal file → Executable file
0
macros/macros1.rs → exercises/macros/macros1.rs
Normal file → Executable file
0
macros/macros2.rs → exercises/macros/macros2.rs
Normal file → Executable file
0
macros/macros2.rs → exercises/macros/macros2.rs
Normal file → Executable file
0
macros/macros3.rs → exercises/macros/macros3.rs
Normal file → Executable file
0
macros/macros3.rs → exercises/macros/macros3.rs
Normal file → Executable file
0
macros/macros4.rs → exercises/macros/macros4.rs
Normal file → Executable file
0
macros/macros4.rs → exercises/macros/macros4.rs
Normal file → Executable file
7
exercises/modules/README.md
Normal file
7
exercises/modules/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
### Modules
|
||||||
|
|
||||||
|
In this section we'll give you an introduction to Rust's module system.
|
||||||
|
|
||||||
|
#### Book Sections
|
||||||
|
|
||||||
|
- [The Module System](https://doc.rust-lang.org/stable/book/ch07-02-modules-and-use-to-control-scope-and-privacy.html)
|
0
modules/modules1.rs → exercises/modules/modules1.rs
Normal file → Executable file
0
modules/modules1.rs → exercises/modules/modules1.rs
Normal file → Executable file
45
exercises/modules/modules2.rs
Executable file
45
exercises/modules/modules2.rs
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
// modules2.rs
|
||||||
|
// Make me compile! Scroll down for hints :)
|
||||||
|
|
||||||
|
mod delicious_snacks {
|
||||||
|
use self::fruits::PEAR as fruit;
|
||||||
|
use self::veggies::CUCUMBER as veggie;
|
||||||
|
|
||||||
|
mod fruits {
|
||||||
|
pub const PEAR: &'static str = "Pear";
|
||||||
|
pub const APPLE: &'static str = "Apple";
|
||||||
|
}
|
||||||
|
|
||||||
|
mod veggies {
|
||||||
|
pub const CUCUMBER: &'static str = "Cucumber";
|
||||||
|
pub const CARROT: &'static str = "Carrot";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("favorite snacks: {} and {}",
|
||||||
|
delicious_snacks::fruit,
|
||||||
|
delicious_snacks::veggie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The delicious_snacks module is trying to present an external
|
||||||
|
// interface (the `fruit` and `veggie` constants) that is different than
|
||||||
|
// its internal structure (the `fruits` and `veggies` modules and
|
||||||
|
// associated constants). It's almost there except for one keyword missing for
|
||||||
|
// each constant.
|
10
exercises/move_semantics/README.md
Normal file
10
exercises/move_semantics/README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
### Move Semantics
|
||||||
|
|
||||||
|
These exercises are adapted from [pnkfelix](https://github.com/pnkfelix)'s [Rust Tutorial](https://pnkfelix.github.io/rust-examples-icfp2014/) -- Thank you Felix!!!
|
||||||
|
|
||||||
|
#### Book Sections
|
||||||
|
|
||||||
|
For this section, the book links are especially important.
|
||||||
|
|
||||||
|
- [Ownership](https://doc.rust-lang.org/stable/book/ch04-01-what-is-ownership.html)
|
||||||
|
- [Reference and borrowing](https://doc.rust-lang.org/stable/book/ch04-02-references-and-borrowing.html)
|
0
move_semantics/move_semantics1.rs → exercises/move_semantics/move_semantics1.rs
Normal file → Executable file
0
move_semantics/move_semantics1.rs → exercises/move_semantics/move_semantics1.rs
Normal file → Executable file
0
move_semantics/move_semantics2.rs → exercises/move_semantics/move_semantics2.rs
Normal file → Executable file
0
move_semantics/move_semantics2.rs → exercises/move_semantics/move_semantics2.rs
Normal file → Executable file
0
move_semantics/move_semantics3.rs → exercises/move_semantics/move_semantics3.rs
Normal file → Executable file
0
move_semantics/move_semantics3.rs → exercises/move_semantics/move_semantics3.rs
Normal file → Executable file
0
move_semantics/move_semantics4.rs → exercises/move_semantics/move_semantics4.rs
Normal file → Executable file
0
move_semantics/move_semantics4.rs → exercises/move_semantics/move_semantics4.rs
Normal file → Executable file
8
exercises/primitive_types/README.md
Normal file
8
exercises/primitive_types/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
### Primitive Types
|
||||||
|
|
||||||
|
Rust has a couple of basic types that are directly implemented into the
|
||||||
|
compiler. In this section, we'll go through the most important ones.
|
||||||
|
|
||||||
|
#### Book Sections
|
||||||
|
|
||||||
|
- [Data Types](https://doc.rust-lang.org/stable/book/ch03-02-data-types.html)
|
0
primitive_types/primitive_types1.rs → exercises/primitive_types/primitive_types1.rs
Normal file → Executable file
0
primitive_types/primitive_types1.rs → exercises/primitive_types/primitive_types1.rs
Normal file → Executable file
0
primitive_types/primitive_types2.rs → exercises/primitive_types/primitive_types2.rs
Normal file → Executable file
0
primitive_types/primitive_types2.rs → exercises/primitive_types/primitive_types2.rs
Normal file → Executable file
0
primitive_types/primitive_types3.rs → exercises/primitive_types/primitive_types3.rs
Normal file → Executable file
0
primitive_types/primitive_types3.rs → exercises/primitive_types/primitive_types3.rs
Normal file → Executable file
4
primitive_types/primitive_types4.rs → exercises/primitive_types/primitive_types4.rs
Normal file → Executable file
4
primitive_types/primitive_types4.rs → exercises/primitive_types/primitive_types4.rs
Normal file → Executable file
@ -39,11 +39,11 @@ fn main() {
|
|||||||
|
|
||||||
|
|
||||||
// Take a look at the Understanding Ownership -> Slices -> Other Slices section of the book:
|
// Take a look at the Understanding Ownership -> Slices -> Other Slices section of the book:
|
||||||
// https://doc.rust-lang.org/stable/book/second-edition/ch04-03-slices.html#other-slices
|
// https://doc.rust-lang.org/book/ch04-03-slices.html
|
||||||
// and use the starting and ending indices of the items in the Array
|
// and use the starting and ending indices of the items in the Array
|
||||||
// that you want to end up in the slice.
|
// that you want to end up in the slice.
|
||||||
|
|
||||||
// If you're curious why the right hand of the `==` comparison does not
|
// If you're curious why the right hand of the `==` comparison does not
|
||||||
// have an ampersand for a reference since the left hand side is a
|
// have an ampersand for a reference since the left hand side is a
|
||||||
// reference, take a look at the Deref coercions section of the book:
|
// reference, take a look at the Deref coercions section of the book:
|
||||||
// https://doc.rust-lang.org/stable/book/second-edition/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods
|
// https://doc.rust-lang.org/book/ch15-02-deref.html
|
2
primitive_types/primitive_types5.rs → exercises/primitive_types/primitive_types5.rs
Normal file → Executable file
2
primitive_types/primitive_types5.rs → exercises/primitive_types/primitive_types5.rs
Normal file → Executable file
@ -39,7 +39,7 @@ fn main() {
|
|||||||
|
|
||||||
|
|
||||||
// Take a look at the Data Types -> The Tuple Type section of the book:
|
// Take a look at the Data Types -> The Tuple Type section of the book:
|
||||||
// https://doc.rust-lang.org/stable/book/second-edition/ch03-02-data-types.html#the-tuple-type
|
// https://doc.rust-lang.org/stable/book/ch03-02-data-types.html#the-tuple-type
|
||||||
// Particularly the part about destructuring (second to last example in the section).
|
// Particularly the part about destructuring (second to last example in the section).
|
||||||
// You'll need to make a pattern to bind `name` and `age` to the appropriate parts
|
// You'll need to make a pattern to bind `name` and `age` to the appropriate parts
|
||||||
// of the tuple. You can do it!!
|
// of the tuple. You can do it!!
|
2
primitive_types/primitive_types6.rs → exercises/primitive_types/primitive_types6.rs
Normal file → Executable file
2
primitive_types/primitive_types6.rs → exercises/primitive_types/primitive_types6.rs
Normal file → Executable file
@ -41,5 +41,5 @@ fn main() {
|
|||||||
// While you could use a destructuring `let` for the tuple here, try
|
// While you could use a destructuring `let` for the tuple here, try
|
||||||
// indexing into it instead, as explained in the last example of the
|
// indexing into it instead, as explained in the last example of the
|
||||||
// Data Types -> The Tuple Type section of the book:
|
// Data Types -> The Tuple Type section of the book:
|
||||||
// https://doc.rust-lang.org/stable/book/second-edition/ch03-02-data-types.html#the-tuple-type
|
// https://doc.rust-lang.org/stable/book/ch03-02-data-types.html#the-tuple-type
|
||||||
// Now you have another tool in your toolbox!
|
// Now you have another tool in your toolbox!
|
5
exercises/standard_library_types/README.md
Normal file
5
exercises/standard_library_types/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
For the Arc exercise check out the chapter [Shared-State Concurrency](https://doc.rust-lang.org/book/2018-edition/ch16-03-shared-state.html) of the Rust Book.
|
||||||
|
|
||||||
|
For the Iterator exercise check out the chapters [Iterator](https://doc.rust-lang.org/book/2018-edition/ch13-02-iterators.html) of the Rust Book and the [Iterator documentation](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.htmlj).
|
||||||
|
Do not adjust your monitors-- iterators 1 and 2 are indeed missing. Iterator 3 is a bit challenging so we're leaving space for some exercises to lead up to it!
|
||||||
|
|
0
standard_library_types/arc1.rs → exercises/standard_library_types/arc1.rs
Normal file → Executable file
0
standard_library_types/arc1.rs → exercises/standard_library_types/arc1.rs
Normal file → Executable file
0
standard_library_types/iterator3.rs → exercises/standard_library_types/iterator3.rs
Normal file → Executable file
0
standard_library_types/iterator3.rs → exercises/standard_library_types/iterator3.rs
Normal file → Executable file
0
standard_library_types/iterators4.rs → exercises/standard_library_types/iterators4.rs
Normal file → Executable file
0
standard_library_types/iterators4.rs → exercises/standard_library_types/iterators4.rs
Normal file → Executable file
9
exercises/strings/REAMDE.md
Normal file
9
exercises/strings/REAMDE.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
### Strings
|
||||||
|
|
||||||
|
Rust has two string types, a string slice (`&str`) and an owned string (`String`).
|
||||||
|
We're not going to dictate when you should use which one, but we'll show you how
|
||||||
|
to identify and create them, as well as use them.
|
||||||
|
|
||||||
|
#### Book Sections
|
||||||
|
|
||||||
|
- [Strings](https://doc.rust-lang.org/stable/book/ch08-02-strings.html)
|
0
strings/strings1.rs → exercises/strings/strings1.rs
Normal file → Executable file
0
strings/strings1.rs → exercises/strings/strings1.rs
Normal file → Executable file
0
strings/strings2.rs → exercises/strings/strings2.rs
Normal file → Executable file
0
strings/strings2.rs → exercises/strings/strings2.rs
Normal file → Executable file
20
exercises/test1.rs
Normal file
20
exercises/test1.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// test1.rs
|
||||||
|
// This is a test for the following sections:
|
||||||
|
// - Variables
|
||||||
|
// - Functions
|
||||||
|
|
||||||
|
// Mary is buying apples. One apple usually costs 2 dollars, but if you buy
|
||||||
|
// more than 40 at once, each apple only costs 1! Write a function that calculates
|
||||||
|
// the price of an order of apples given the order amount.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let price1 = calculateprice(55);
|
||||||
|
let price2 = calculateprice(40);
|
||||||
|
|
||||||
|
// Don't modify this!
|
||||||
|
if price1 == 55 && price2 == 80 {
|
||||||
|
println!("Good job!");
|
||||||
|
} else {
|
||||||
|
panic!("Uh oh! Wrong price!");
|
||||||
|
}
|
||||||
|
}
|
5
tests/tests4.rs → exercises/test2.rs
Normal file → Executable file
5
tests/tests4.rs → exercises/test2.rs
Normal file → Executable file
@ -1,4 +1,7 @@
|
|||||||
// tests4.rs
|
// test2.rs
|
||||||
|
// This is a test for the following sections:
|
||||||
|
// - Tests
|
||||||
|
|
||||||
// This test isn't testing our function -- make it do that in such a way that
|
// This test isn't testing our function -- make it do that in such a way that
|
||||||
// the test passes. Then write a second test that tests that we get the result
|
// the test passes. Then write a second test that tests that we get the result
|
||||||
// we expect to get when we call `times_two` with a negative number.
|
// we expect to get when we call `times_two` with a negative number.
|
3
strings/strings3.rs → exercises/test3.rs
Normal file → Executable file
3
strings/strings3.rs → exercises/test3.rs
Normal file → Executable file
@ -1,4 +1,7 @@
|
|||||||
// strings3.rs
|
// strings3.rs
|
||||||
|
// This is a test for the following sections:
|
||||||
|
// - Strings
|
||||||
|
|
||||||
// Ok, here are a bunch of values-- some are `Strings`, some are `&strs`. Your
|
// Ok, here are a bunch of values-- some are `Strings`, some are `&strs`. Your
|
||||||
// task is to call one of these two functions on each value depending on what
|
// task is to call one of these two functions on each value depending on what
|
||||||
// you think each value is. That is, add either `string_slice` or `string`
|
// you think each value is. That is, add either `string_slice` or `string`
|
12
exercises/test4.rs
Normal file
12
exercises/test4.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// test4.rs
|
||||||
|
// This test covers the sections:
|
||||||
|
// - Modules
|
||||||
|
// - Macros
|
||||||
|
|
||||||
|
// Write a macro that passes the test! No hints this time, you can do it!
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if my_macro!("world!") != "Hello world!" {
|
||||||
|
panic!("Oh no! Wrong output!");
|
||||||
|
}
|
||||||
|
}
|
7
exercises/tests/README.md
Normal file
7
exercises/tests/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
### Tests
|
||||||
|
|
||||||
|
Going out of order from the book to cover tests -- many of the following exercises will ask you to make tests pass!
|
||||||
|
|
||||||
|
#### Book Sections
|
||||||
|
|
||||||
|
- [Writing Tests](https://doc.rust-lang.org/stable/book/ch11-01-writing-tests.html)
|
2
tests/tests1.rs → exercises/tests/tests1.rs
Normal file → Executable file
2
tests/tests1.rs → exercises/tests/tests1.rs
Normal file → Executable file
@ -1,7 +1,7 @@
|
|||||||
// tests1.rs
|
// tests1.rs
|
||||||
// Tests are important to ensure that your code does what you think it should do.
|
// Tests are important to ensure that your code does what you think it should do.
|
||||||
// Tests can be run on this file with the following command:
|
// Tests can be run on this file with the following command:
|
||||||
// rustc --test tests1.rs
|
// rustlings run --test exercises/tests/tests1.rs
|
||||||
|
|
||||||
// This test has a problem with it -- make the test compile! Make the test
|
// This test has a problem with it -- make the test compile! Make the test
|
||||||
// pass! Make the test fail! Scroll down for hints :)
|
// pass! Make the test fail! Scroll down for hints :)
|
0
tests/tests2.rs → exercises/tests/tests2.rs
Normal file → Executable file
0
tests/tests2.rs → exercises/tests/tests2.rs
Normal file → Executable file
4
tests/tests3.rs → exercises/tests/tests3.rs
Normal file → Executable file
4
tests/tests3.rs → exercises/tests/tests3.rs
Normal file → Executable file
@ -1,6 +1,6 @@
|
|||||||
// tests3.rs
|
// tests3.rs
|
||||||
// This test isn't testing our function -- make it do that in such a way that
|
// This test isn't testing our function -- make it do that in such a way that
|
||||||
// the test passes. Then write a second test that tests that we get the result
|
// the test passes. Then write a second test that tests whether we get the result
|
||||||
// we expect to get when we call `is_even(5)`. Scroll down for hints!
|
// we expect to get when we call `is_even(5)`. Scroll down for hints!
|
||||||
|
|
||||||
pub fn is_even(num: i32) -> bool {
|
pub fn is_even(num: i32) -> bool {
|
||||||
@ -13,7 +13,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_true_when_even() {
|
fn is_true_when_even() {
|
||||||
assert!(false);
|
assert!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
exercises/threads/README.md
Normal file
1
exercises/threads/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
For this exercise check out the [Dining Philosophers example](https://doc.rust-lang.org/1.4.0/book/dining-philosophers.html) and the chapter [Concurrency](https://doc.rust-lang.org/book/2018-edition/ch16-01-threads.html) of the Rust Book.
|
0
threads/threads1.rs → exercises/threads/threads1.rs
Normal file → Executable file
0
threads/threads1.rs → exercises/threads/threads1.rs
Normal file → Executable file
7
exercises/variables/README.md
Normal file
7
exercises/variables/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
### Variables
|
||||||
|
|
||||||
|
Here you'll learn about simple variables.
|
||||||
|
|
||||||
|
#### Book Sections
|
||||||
|
|
||||||
|
- [Variables and Mutability](https://doc.rust-lang.org/stable/book/ch03-01-variables-and-mutability.html)
|
0
variables/variables1.rs → exercises/variables/variables1.rs
Normal file → Executable file
0
variables/variables1.rs → exercises/variables/variables1.rs
Normal file → Executable file
0
variables/variables2.rs → exercises/variables/variables2.rs
Normal file → Executable file
0
variables/variables2.rs → exercises/variables/variables2.rs
Normal file → Executable file
0
variables/variables3.rs → exercises/variables/variables3.rs
Normal file → Executable file
0
variables/variables3.rs → exercises/variables/variables3.rs
Normal file → Executable file
0
variables/variables4.rs → exercises/variables/variables4.rs
Normal file → Executable file
0
variables/variables4.rs → exercises/variables/variables4.rs
Normal file → Executable file
@ -1,45 +0,0 @@
|
|||||||
// modules2.rs
|
|
||||||
// Make me compile! Scroll down for hints :)
|
|
||||||
|
|
||||||
mod us_presidential_frontrunners {
|
|
||||||
use self::democrats::HILLARY_CLINTON as democrat;
|
|
||||||
use self::republicans::DONALD_TRUMP as republican;
|
|
||||||
|
|
||||||
mod democrats {
|
|
||||||
pub const HILLARY_CLINTON: &'static str = "Hillary Clinton";
|
|
||||||
pub const BERNIE_SANDERS: &'static str = "Bernie Sanders";
|
|
||||||
}
|
|
||||||
|
|
||||||
mod republicans {
|
|
||||||
pub const DONALD_TRUMP: &'static str = "Donald Trump";
|
|
||||||
pub const JEB_BUSH: &'static str = "Jeb Bush";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("candidates: {} and {}",
|
|
||||||
us_presidential_frontrunners::democrat,
|
|
||||||
us_presidential_frontrunners::republican);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// The us_presidential_frontrunners module is trying to present an external
|
|
||||||
// interface (the `democrat` and `republican` constants) that is different than
|
|
||||||
// its internal structure (the `democrats` and `republicans` modules and
|
|
||||||
// associated constants). It's almost there except for one keyword missing for
|
|
||||||
// each constant.
|
|
@ -1,49 +0,0 @@
|
|||||||
// This script reads README-template.md and generates the playground links
|
|
||||||
// from the Rust source files in the various directories.
|
|
||||||
|
|
||||||
// To add a new exercise, add it to the appropriate place in README-template.md
|
|
||||||
// and then make sure to recompile this script (because the template gets
|
|
||||||
// included at compile time and then run it to generate a new version of
|
|
||||||
// README.md.
|
|
||||||
|
|
||||||
extern crate handlebars;
|
|
||||||
extern crate prlink;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_json;
|
|
||||||
|
|
||||||
use handlebars::{Handlebars, Helper, RenderContext, RenderError};
|
|
||||||
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut template_file = File::open("README-template.hbs").unwrap();
|
|
||||||
let mut template = String::new();
|
|
||||||
template_file.read_to_string(&mut template).unwrap();
|
|
||||||
|
|
||||||
let autogenerated_notice = "This file was autogenerated by the script in src/bin/generate_readme.rs.
|
|
||||||
Please edit either the script or the template in README-template.md in
|
|
||||||
order to make changes here rather than committing the changes directly.";
|
|
||||||
|
|
||||||
let mut generated_readme = File::create("README.md").unwrap();
|
|
||||||
|
|
||||||
let mut hbs = Handlebars::new();
|
|
||||||
hbs.register_helper("playground_link", Box::new(playground_link_helper));
|
|
||||||
|
|
||||||
write!(
|
|
||||||
generated_readme,
|
|
||||||
"{}",
|
|
||||||
hbs.render_template(
|
|
||||||
&template,
|
|
||||||
&json!({ "autogenerated_notice": autogenerated_notice }),
|
|
||||||
).unwrap()
|
|
||||||
).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn playground_link_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
|
||||||
let filename = PathBuf::from(h.param(0).unwrap().value().as_str().unwrap());
|
|
||||||
let link = prlink::linkify_file(&filename);
|
|
||||||
rc.writer.write(link.into_bytes().as_ref())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
96
src/main.rs
Normal file
96
src/main.rs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
use crate::run::run;
|
||||||
|
use crate::verify::verify;
|
||||||
|
use clap::{crate_version, App, Arg, SubCommand};
|
||||||
|
use notify::DebouncedEvent;
|
||||||
|
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::sync::mpsc::channel;
|
||||||
|
use std::time::Duration;
|
||||||
|
use syntect::easy::HighlightFile;
|
||||||
|
use syntect::highlighting::{Style, ThemeSet};
|
||||||
|
use syntect::parsing::SyntaxSet;
|
||||||
|
use syntect::util::as_24_bit_terminal_escaped;
|
||||||
|
|
||||||
|
mod run;
|
||||||
|
mod util;
|
||||||
|
mod verify;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let matches = App::new("rustlings")
|
||||||
|
.version(crate_version!())
|
||||||
|
.author("Olivia Hugger, Carol Nichols")
|
||||||
|
.about("Rustlings is a collection of small exercises to get you used to writing and reading Rust code")
|
||||||
|
.subcommand(SubCommand::with_name("verify").alias("v").about("Verifies all exercises according to the recommended order"))
|
||||||
|
.subcommand(SubCommand::with_name("watch").alias("w").about("Reruns `verify` when files were edited"))
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("run")
|
||||||
|
.alias("r")
|
||||||
|
.about("Runs/Tests a single exercise")
|
||||||
|
.arg(Arg::with_name("file").required(true).index(1))
|
||||||
|
.arg(Arg::with_name("test").short("t").long("test").help("Run the file as a test")),
|
||||||
|
)
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
let ss = SyntaxSet::load_defaults_newlines();
|
||||||
|
let ts = ThemeSet::load_defaults();
|
||||||
|
|
||||||
|
if None == matches.subcommand_name() {
|
||||||
|
println!("");
|
||||||
|
println!(r#" welcome to... "#);
|
||||||
|
println!(r#" _ _ _ "#);
|
||||||
|
println!(r#" _ __ _ _ ___| |_| (_)_ __ __ _ ___ "#);
|
||||||
|
println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
|
||||||
|
println!(r#" | | | |_| \__ \ |_| | | | | | (_| \__ \ "#);
|
||||||
|
println!(r#" |_| \__,_|___/\__|_|_|_| |_|\__, |___/ "#);
|
||||||
|
println!(r#" |___/ "#);
|
||||||
|
println!("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(matches) = matches.subcommand_matches("run") {
|
||||||
|
run(matches.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(_) = matches.subcommand_matches("verify") {
|
||||||
|
match verify() {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(_) => std::process::exit(1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(_) = matches.subcommand_matches("watch") {
|
||||||
|
watch().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let None = matches.subcommand_name() {
|
||||||
|
let mut highlighter =
|
||||||
|
HighlightFile::new("default_out.md", &ss, &ts.themes["base16-eighties.dark"]).unwrap();
|
||||||
|
for maybe_line in highlighter.reader.lines() {
|
||||||
|
let line = maybe_line.unwrap();
|
||||||
|
let regions: Vec<(Style, &str)> = highlighter.highlight_lines.highlight(&line, &ss);
|
||||||
|
println!("{}", as_24_bit_terminal_escaped(®ions[..], true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\x1b[0m");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn watch() -> notify::Result<()> {
|
||||||
|
let (tx, rx) = channel();
|
||||||
|
|
||||||
|
let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(2))?;
|
||||||
|
watcher.watch("./exercises", RecursiveMode::Recursive)?;
|
||||||
|
|
||||||
|
let _ignored = verify();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match rx.recv() {
|
||||||
|
Ok(event) => match event {
|
||||||
|
DebouncedEvent::Chmod(_) | DebouncedEvent::Write(_) => {
|
||||||
|
let _ignored = verify();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
Err(e) => println!("watch error: {:?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
55
src/run.rs
Normal file
55
src/run.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
use crate::util::clean;
|
||||||
|
use crate::verify::test;
|
||||||
|
use console::{style, Emoji};
|
||||||
|
use indicatif::ProgressBar;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
pub fn run(matches: clap::ArgMatches) {
|
||||||
|
if let Some(filename) = matches.value_of("file") {
|
||||||
|
if matches.is_present("test") {
|
||||||
|
match test(filename) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(_) => (),
|
||||||
|
}
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
let bar = ProgressBar::new_spinner();
|
||||||
|
bar.set_message(format!("Compiling {}...", filename).as_str());
|
||||||
|
bar.enable_steady_tick(100);
|
||||||
|
let compilecmd = Command::new("rustc")
|
||||||
|
.args(&[filename, "-o", "temp"])
|
||||||
|
.output()
|
||||||
|
.expect("fail");
|
||||||
|
bar.set_message(format!("Running {}...", filename).as_str());
|
||||||
|
if compilecmd.status.success() {
|
||||||
|
let runcmd = Command::new("./temp").output().expect("fail");
|
||||||
|
bar.finish_and_clear();
|
||||||
|
|
||||||
|
if runcmd.status.success() {
|
||||||
|
println!("{}", String::from_utf8_lossy(&runcmd.stdout));
|
||||||
|
let formatstr = format!("{} Successfully ran {}", Emoji("✅", "✓"), filename);
|
||||||
|
println!("{}", style(formatstr).green());
|
||||||
|
clean();
|
||||||
|
} else {
|
||||||
|
println!("{}", String::from_utf8_lossy(&runcmd.stdout));
|
||||||
|
println!("{}", String::from_utf8_lossy(&runcmd.stderr));
|
||||||
|
|
||||||
|
let formatstr = format!("{} Ran {} with errors", Emoji("⚠️ ", "!"), filename);
|
||||||
|
println!("{}", style(formatstr).red());
|
||||||
|
clean();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bar.finish_and_clear();
|
||||||
|
let formatstr = format!(
|
||||||
|
"{} Compilation of {} failed! Compiler error message:\n",
|
||||||
|
Emoji("⚠️ ", "!"),
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
println!("{}", style(formatstr).red());
|
||||||
|
println!("{}", String::from_utf8_lossy(&compilecmd.stderr));
|
||||||
|
clean();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("Please supply a filename!");
|
||||||
|
}
|
||||||
|
}
|
5
src/util.rs
Normal file
5
src/util.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
use std::fs::remove_file;
|
||||||
|
|
||||||
|
pub fn clean() {
|
||||||
|
let _ignored = remove_file("temp");
|
||||||
|
}
|
106
src/verify.rs
Normal file
106
src/verify.rs
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
use crate::util::clean;
|
||||||
|
use console::{style, Emoji};
|
||||||
|
use indicatif::ProgressBar;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
pub fn verify() -> Result<(), ()> {
|
||||||
|
compile_only("exercises/variables/variables1.rs")?;
|
||||||
|
compile_only("exercises/variables/variables2.rs")?;
|
||||||
|
compile_only("exercises/variables/variables3.rs")?;
|
||||||
|
compile_only("exercises/variables/variables4.rs")?;
|
||||||
|
test("exercises/if/if1.rs")?;
|
||||||
|
compile_only("exercises/functions/functions1.rs")?;
|
||||||
|
compile_only("exercises/functions/functions2.rs")?;
|
||||||
|
compile_only("exercises/functions/functions3.rs")?;
|
||||||
|
compile_only("exercises/functions/functions4.rs")?;
|
||||||
|
compile_only("exercises/functions/functions5.rs")?;
|
||||||
|
compile_only("exercises/test1.rs")?;
|
||||||
|
compile_only("exercises/primitive_types/primitive_types1.rs")?;
|
||||||
|
compile_only("exercises/primitive_types/primitive_types2.rs")?;
|
||||||
|
compile_only("exercises/primitive_types/primitive_types3.rs")?;
|
||||||
|
compile_only("exercises/primitive_types/primitive_types4.rs")?;
|
||||||
|
compile_only("exercises/primitive_types/primitive_types5.rs")?;
|
||||||
|
compile_only("exercises/primitive_types/primitive_types6.rs")?;
|
||||||
|
test("exercises/tests/tests1.rs")?;
|
||||||
|
test("exercises/tests/tests2.rs")?;
|
||||||
|
test("exercises/tests/tests3.rs")?;
|
||||||
|
test("exercises/test2.rs")?;
|
||||||
|
compile_only("exercises/strings/strings1.rs")?;
|
||||||
|
compile_only("exercises/strings/strings2.rs")?;
|
||||||
|
compile_only("exercises/test3.rs")?;
|
||||||
|
compile_only("exercises/modules/modules1.rs")?;
|
||||||
|
compile_only("exercises/modules/modules2.rs")?;
|
||||||
|
compile_only("exercises/macros/macros1.rs")?;
|
||||||
|
compile_only("exercises/macros/macros2.rs")?;
|
||||||
|
compile_only("exercises/macros/macros3.rs")?;
|
||||||
|
compile_only("exercises/macros/macros4.rs")?;
|
||||||
|
compile_only("exercises/test4.rs")?;
|
||||||
|
compile_only("exercises/move_semantics/move_semantics1.rs")?;
|
||||||
|
compile_only("exercises/move_semantics/move_semantics2.rs")?;
|
||||||
|
compile_only("exercises/move_semantics/move_semantics3.rs")?;
|
||||||
|
compile_only("exercises/move_semantics/move_semantics4.rs")?;
|
||||||
|
test("exercises/error_handling/errors1.rs")?;
|
||||||
|
test("exercises/error_handling/errors2.rs")?;
|
||||||
|
test("exercises/error_handling/errors3.rs")?;
|
||||||
|
test("exercises/error_handling/errorsn.rs")?;
|
||||||
|
compile_only("exercises/error_handling/option1.rs")?;
|
||||||
|
test("exercises/error_handling/result1.rs")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compile_only(filename: &str) -> Result<(), ()> {
|
||||||
|
let bar = ProgressBar::new_spinner();
|
||||||
|
bar.set_message(format!("Compiling {}...", filename).as_str());
|
||||||
|
bar.enable_steady_tick(100);
|
||||||
|
let compilecmd = Command::new("rustc")
|
||||||
|
.args(&[filename, "-o", "temp", "--color", "always"])
|
||||||
|
.output()
|
||||||
|
.expect("fail");
|
||||||
|
bar.finish_and_clear();
|
||||||
|
if compilecmd.status.success() {
|
||||||
|
let formatstr = format!(
|
||||||
|
"{} Successfully compiled {}!",
|
||||||
|
Emoji("✅", "✓"),
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
println!("{}", style(formatstr).green());
|
||||||
|
clean();
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
let formatstr = format!(
|
||||||
|
"{} Compilation of {} failed! Compiler error message:\n",
|
||||||
|
Emoji("⚠️ ", "!"),
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
println!("{}", style(formatstr).red());
|
||||||
|
println!("{}", String::from_utf8_lossy(&compilecmd.stderr));
|
||||||
|
clean();
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test(filename: &str) -> Result<(), ()> {
|
||||||
|
let bar = ProgressBar::new_spinner();
|
||||||
|
bar.set_message(format!("Testing {}...", filename).as_str());
|
||||||
|
bar.enable_steady_tick(100);
|
||||||
|
let testcmd = Command::new("rustc")
|
||||||
|
.args(&["--test", filename, "-o", "temp"])
|
||||||
|
.output()
|
||||||
|
.expect("fail");
|
||||||
|
bar.finish_and_clear();
|
||||||
|
if testcmd.status.success() {
|
||||||
|
let formatstr = format!("{} Successfully tested {}!", Emoji("✅", "✓"), filename);
|
||||||
|
println!("{}", style(formatstr).green());
|
||||||
|
clean();
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
let formatstr = format!(
|
||||||
|
"{} Testing of {} failed! Please try again.",
|
||||||
|
Emoji("⚠️ ", "!"),
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
println!("{}", style(formatstr).red());
|
||||||
|
clean();
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user