commit
df3389cfb0
|
@ -1,2 +1,5 @@
|
|||
*.swp
|
||||
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]
|
||||
name = "rustlings"
|
||||
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]
|
||||
handlebars = "0.32.0"
|
||||
serde_json = "1.0.10"
|
||||
prlink = { git = "https://github.com/btbytes/prlink" }
|
||||
clap = "2.32.0"
|
||||
indicatif = "0.9.0"
|
||||
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??
|
|
@ -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;
|
|
@ -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,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,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)
|
|
@ -9,6 +9,7 @@ pub fn bigger(a: i32, b:i32) -> i32 {
|
|||
// Scroll down for hints.
|
||||
}
|
||||
|
||||
// Don't mind this for now :)
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
|
@ -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,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,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.
|
|
@ -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
|
@ -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:
|
||||
// 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
|
||||
// that you want to end up in the slice.
|
||||
|
||||
// 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
|
||||
// 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:
|
||||
// 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).
|
||||
// You'll need to make a pattern to bind `name` and `age` to the appropriate parts
|
||||
// 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
|
||||
// indexing into it instead, as explained in the last example of 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
|
||||
// Now you have another tool in your toolbox!
|
|
@ -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
|
@ -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,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!");
|
||||
}
|
||||
}
|
|
@ -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
|
||||
// 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.
|
|
@ -1,4 +1,7 @@
|
|||
// 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
|
||||
// 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`
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -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)
|
|
@ -1,7 +1,7 @@
|
|||
// tests1.rs
|
||||
// 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:
|
||||
// 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
|
||||
// pass! Make the test fail! Scroll down for hints :)
|
|
@ -1,6 +1,6 @@
|
|||
// tests3.rs
|
||||
// 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!
|
||||
|
||||
pub fn is_even(num: i32) -> bool {
|
||||
|
@ -13,7 +13,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn is_true_when_even() {
|
||||
assert!(false);
|
||||
assert!();
|
||||
}
|
||||
}
|
||||
|
|
@ -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,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)
|
|
@ -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(())
|
||||
}
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
use std::fs::remove_file;
|
||||
|
||||
pub fn clean() {
|
||||
let _ignored = remove_file("temp");
|
||||
}
|
|
@ -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(())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue