From 87d8131f1f004a68adcdba74ef8b94290739e90b Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sun, 4 Mar 2018 12:41:55 -0500 Subject: [PATCH] Start a script to regenerate README.md from a template So far this doesn't actually do any templating, just adds a note about the README being autogenerated :) --- .gitignore | 1 + Cargo.lock | 4 + Cargo.toml | 4 + README-template.md | 152 +++++++++++++++++++++++++++++++++++++ README.md | 4 + src/bin/generate_readme.rs | 23 ++++++ 6 files changed, 188 insertions(+) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README-template.md create mode 100644 src/bin/generate_readme.rs diff --git a/.gitignore b/.gitignore index 1377554e..d6c11944 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.swp +target/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..910962c2 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4 @@ +[root] +name = "rustlings" +version = "0.1.0" + diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..3adb3618 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "rustlings" +version = "0.1.0" +authors = ["Carol (Nichols || Goulding) "] diff --git a/README-template.md b/README-template.md new file mode 100644 index 00000000..15921110 --- /dev/null +++ b/README-template.md @@ -0,0 +1,152 @@ +# 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/stable/book/first-edition/variable-bindings.html) + +- ["variables1.rs"](https://play.rust-lang.org/?code=%2F%2F+variables1.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++x+%3D+5%3B%0A++++println%21%28%22x+has+the+value+%7B%7D%22%2C+x%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Hint%3A+The+declaration+on+line+4+is+missing+a+keyword+that+is+needed+in+Rust%0A%2F%2F+to+create+a+new+variable+binding.%0A) +- ["variables2.rs"](https://play.rust-lang.org/?code=%2F%2F+variables2.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++let+x%3B%0A++++if+x+%3D%3D+10+%7B%0A++++++++println%21%28%22Ten%21%22%29%3B%0A++++%7D+else+%7B%0A++++++++println%21%28%22Not+ten%21%22%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+The+compiler+message+is+saying+that+Rust+cannot+infer+the+type+that+the%0A%2F%2F+variable+binding+%60x%60+has+with+what+is+given+here.%0A%2F%2F+What+happens+if+you+annotate+line+4+with+a+type+annotation%3F%0A%2F%2F+What+if+you+give+x+a+value%3F%0A%2F%2F+What+if+you+do+both%3F%0A%2F%2F+What+type+should+x+be%2C+anyway%3F%0A%2F%2F+What+if+x+is+the+same+type+as+10%3F+What+if+it%27s+a+different+type%3F%0A) +- ["variables3.rs"](https://play.rust-lang.org/?code=%2F%2F+variables3.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++let+x+%3D+3%3B%0A++++println%21%28%22Number+%7B%7D%22%2C+x%29%3B%0A++++x+%3D+5%3B%0A++++println%21%28%22Number+%7B%7D%22%2C+x%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+In+Rust%2C+variable+bindings+are+immutable+by+default.+But+here+we%27re+trying%0A%2F%2F+to+reassign+a+different+value+to+x%21+There%27s+a+keyword+we+can+use+to+make%0A%2F%2F+a+variable+binding+mutable+instead.%0A) +- ["variables4.rs"](https://play.rust-lang.org/?code=%2F%2F+variables4.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++let+x%3A+i32%3B%0A++++println%21%28%22Number+%7B%7D%22%2C+x%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Oops%21+In+this+exercise%2C+we+have+a+variable+binding+that+we%27ve+created+on%0A%2F%2F+line+4%2C+and+we%27re+trying+to+use+it+on+line+5%2C+but+we+haven%27t+given+it+a%0A%2F%2F+value.+We+can%27t+print+out+something+that+isn%27t+there%3B+try+giving+x+a+value%21%0A%2F%2F+This+is+an+error+that+can+cause+bugs+that%27s+very+easy+to+make+in+any%0A%2F%2F+programming+language+--+thankfully+the+Rust+compiler+has+caught+this+for+us%21%0A) + +### Functions + +[Relevant chapter in The Rust Programming Language](https://doc.rust-lang.org/stable/book/first-edition/functions.html) + +- ["functions1.rs"](https://play.rust-lang.org/?code=%2F%2F+functions1.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++call_me%28%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+This+main+function+is+calling+a+function+that+it+expects+to+exist%2C+but+the%0A%2F%2F+function+doesn%27t+exist.+It+expects+this+function+to+have+the+name+%60call_me%60.%0A%2F%2F+It+expects+this+function+to+not+take+any+arguments+and+not+return+a+value.%0A%2F%2F+Sounds+a+lot+like+%60main%60%2C+doesn%27t+it%3F%0A) +- ["functions2.rs"](https://play.rust-lang.org/?code=%2F%2F+functions2.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++call_me%283%29%3B%0A%7D%0A%0Afn+call_me%28num%29+%7B%0A++++for+i+in+0..num+%7B%0A++++++++println%21%28%22Ring%21+Call+number+%7B%7D%22%2C+i+%2B+1%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Rust+requires+that+all+parts+of+a+function%27s+signature+have+type+annotations%2C%0A%2F%2F+but+%60call_me%60+is+missing+the+type+annotation+of+%60num%60.%0A) +- ["functions3.rs"](https://play.rust-lang.org/?code=%2F%2F+functions3.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++call_me%28%29%3B%0A%7D%0A%0Afn+call_me%28num%3A+i32%29+%7B%0A++++for+i+in+0..num+%7B%0A++++++++println%21%28%22Ring%21+Call+number+%7B%7D%22%2C+i+%2B+1%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+This+time%2C+the+function+*declaration*+is+okay%2C+but+there%27s+something+wrong%0A%2F%2F+with+the+place+where+we%27re+calling+the+function.%0A) +- ["functions4.rs"](https://play.rust-lang.org/?code=%2F%2F+functions4.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0A%2F%2F+This+store+is+having+a+sale+where+if+the+price+is+an+even+number%2C+you+get%0A%2F%2F+10+%28money+unit%29+off%2C+but+if+it%27s+an+odd+number%2C+it%27s+3+%28money+unit%29+less.%0A%0Afn+main%28%29+%7B%0A++++let+original_price+%3D+51%3B%0A++++println%21%28%22Your+sale+price+is+%7B%7D%22%2C+sale_price%28original_price%29%29%3B%0A%7D%0A%0Afn+sale_price%28price%3A+i32%29+-%3E+%7B%0A++++if+is_even%28price%29+%7B%0A++++++++price+-+10%0A++++%7D+else+%7B%0A++++++++price+-+3%0A++++%7D%0A%7D%0A%0Afn+is_even%28num%3A+i32%29+-%3E+bool+%7B%0A++++num+%25+2+%3D%3D+0%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+The+error+message+points+to+line+10+and+says+it+expects+a+type+after+the%0A%2F%2F+%60-%3E%60.+This+is+where+the+function%27s+return+type+should+be--+take+a+look+at%0A%2F%2F+the+%60is_even%60+function+for+an+example%21%0A) +- ["functions5.rs"](https://play.rust-lang.org/?code=%2F%2F+functions5.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++let+answer+%3D+square%283%29%3B%0A++++println%21%28%22The+answer+is+%7B%7D%22%2C+answer%29%3B%0A%7D%0A%0Afn+square%28num%3A+i32%29+-%3E+i32+%7B%0A++++num+*+num%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+This+is+a+really+common+error+that+can+be+fixed+by+removing+one+character.%0A%2F%2F+It+happens+because+Rust+distinguishes+between+expressions+and+statements%3A+expressions+return%0A%2F%2F+a+value+and+statements+don%27t.+We+want+to+return+a+value+from+the+%60square%60+function%2C+but+it%0A%2F%2F+isn%27t+returning+one+right+now...%0A) + +### Primitive types + +[Relevant chapter in The Rust Programming Language](https://doc.rust-lang.org/stable/book/first-edition/primitive-types.html) + +- ["primitive_types1.rs"](https://play.rust-lang.org/?code=%2F%2F+primitive_types1.rs%0A%2F%2F+Fill+in+the+rest+of+the+line+that+has+code+missing%21%0A%2F%2F+No+hints%2C+there%27s+no+tricks%2C+just+get+used+to+typing+these+%3A%29%0A%0Afn+main%28%29+%7B%0A++++%2F%2F+Booleans+%28%60bool%60%29%0A%0A++++let+is_morning+%3D+true%3B%0A++++if+is_morning+%7B%0A++++++++println%21%28%22Good+morning%21%22%29%3B%0A++++%7D%0A%0A++++let+%2F%2F+Finish+the+rest+of+this+line+like+the+example%21+Or+make+it+be+false%21%0A++++if+is_evening+%7B%0A++++++++println%21%28%22Good+evening%21%22%29%3B%0A++++%7D%0A%7D%0A) +- ["primitive_types2.rs"](https://play.rust-lang.org/?code=%2F%2F+primitive_types2.rs%0A%2F%2F+Fill+in+the+rest+of+the+line+that+has+code+missing%21%0A%2F%2F+No+hints%2C+there%27s+no+tricks%2C+just+get+used+to+typing+these+%3A%29%0A%0Afn+main%28%29+%7B%0A++++%2F%2F+Characters+%28%60char%60%29%0A%0A++++let+my_first_initial+%3D+%27C%27%3B%0A++++if+my_first_initial.is_alphabetic%28%29+%7B%0A++++++++println%21%28%22Alphabetical%21%22%29%3B%0A++++%7D+else+if+my_first_initial.is_numeric%28%29+%7B%0A++++++++println%21%28%22Numerical%21%22%29%3B%0A++++%7D+else+%7B%0A++++++++println%21%28%22Neither+alphabetic+nor+numeric%21%22%29%3B%0A++++%7D%0A%0A++++let+%2F%2F+Finish+this+line+like+the+example%21+What%27s+your+favorite+character%3F%0A++++%2F%2F+Try+a+letter%2C+try+a+number%2C+try+a+special+character%2C+try+a+character%0A++++%2F%2F+from+a+different+language+than+your+own%2C+try+an+emoji%21%0A++++if+your_character.is_alphabetic%28%29+%7B%0A++++++++println%21%28%22Alphabetical%21%22%29%3B%0A++++%7D+else+if+your_character.is_numeric%28%29+%7B%0A++++++++println%21%28%22Numerical%21%22%29%3B%0A++++%7D+else+%7B%0A++++++++println%21%28%22Neither+alphabetic+nor+numeric%21%22%29%3B%0A++++%7D%0A%7D%0A) +- ["primitive_types3.rs"](https://play.rust-lang.org/?code=%2F%2F+primitive_types3.rs%0A%2F%2F+Create+an+array+with+at+least+100+elements+in+it+where+the+%3F%3F%3F+is.+%0A%2F%2F+Scroll+down+for+hints%21%0A%0Afn+main%28%29+%7B%0A++++let+a+%3D+%3F%3F%3F%0A%0A++++if+a.len%28%29+%3E%3D+100+%7B%0A++++++++println%21%28%22Wow%2C+that%27s+a+big+array%21%22%29%3B%0A++++%7D+else+%7B%0A++++++++println%21%28%22Meh%2C+I+eat+arrays+like+that+for+breakfast.%22%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+There%27s+a+shorthand+to+initialize+Arrays+with+a+certain+size+that+does+not+%0A%2F%2F+require+you+to+type+in+100+items+%28but+you+certainly+can+if+you+want%21%29%0A%2F%2F+Check+out+the+Primitive+Types+-%3E+Arrays+section+of+the+book%3A%0A%2F%2F+https%3A%2F%2Fdoc.rust-lang.org%2Fstable%2Fbook%2Fsecond-edition%2Fch03-02-data-types.html%23arrays%0A%2F%2F+Bonus%3A+what+are+some+other+things+you+could+have+that+would+return+true%0A%2F%2F+for+%60a.len%28%29+%3E%3D+100%60%3F%0A) +- ["primitive_types4.rs"](https://play.rust-lang.org/?code=%2F%2F+primitive_types4.rs%0A%2F%2F+Get+a+slice+out+of+Array+a+where+the+%3F%3F%3F+is+so+that+the+%60if%60+statement%0A%2F%2F+returns+true.+Scroll+down+for+hints%21%21%0A%0Afn+main%28%29+%7B%0A++++let+a+%3D+%5B1%2C+2%2C+3%2C+4%2C+5%5D%3B%0A%0A++++let+nice_slice+%3D+%3F%3F%3F%0A%0A++++if+nice_slice+%3D%3D+%5B2%2C+3%2C+4%5D+%7B%0A++++++++println%21%28%22Nice+slice%21%22%29%3B%0A++++%7D+else+%7B%0A++++++++println%21%28%22Not+quite+what+I+was+expecting...+I+see%3A+%7B%3A%3F%7D%22%2C+nice_slice%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Take+a+look+at+the+Primitive+Types+-%3E+Slices+section+of+the+book%3A%0A%2F%2F+http%3A%2F%2Fdoc.rust-lang.org%2Fstable%2Fbook%2Fprimitive-types.html%23slices%0A%2F%2F+and+use+the+starting+and+ending+indices+of+the+items+in+the+Array%0A%2F%2F+that+you+want+to+end+up+in+the+slice.%0A%0A%2F%2F+If+you%27re+curious+why+the+right+hand+of+the+%60%3D%3D%60+comparison+does+not%0A%2F%2F+have+an+ampersand+for+a+reference+since+the+left+hand+side+is+a%0A%2F%2F+reference%2C+take+a+look+at+the+Deref+coercions+chapter%3A%0A%2F%2F+http%3A%2F%2Fdoc.rust-lang.org%2Fstable%2Fbook%2Fderef-coercions.html%0A) +- ["primitive_types5.rs"](https://play.rust-lang.org/?code=%2F%2F+primitive_types5.rs%0A%2F%2F+Destructure+the+%60cat%60+tuple+so+that+the+println+will+work.%0A%2F%2F+Scroll+down+for+hints%21%0A%0Afn+main%28%29+%7B%0A++++let+cat+%3D+%28%22Furry+McFurson%22%2C+3.5%29%3B%0A++++let+%2F*+your+pattern+here+*%2F+%3D+cat%3B%0A%0A++++println%21%28%22%7B%7D+is+%7B%7D+years+old.%22%2C+name%2C+age%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Take+a+look+at+the+Primitive+Types+-%3E+Tuples+section+of+the+book%3A%0A%2F%2F+http%3A%2F%2Fdoc.rust-lang.org%2Fstable%2Fbook%2Fprimitive-types.html%23tuples%0A%2F%2F+Particularly+the+part+about+%22destructuring+lets%22.+You%27ll+need+to%0A%2F%2F+make+a+pattern+to+bind+%60name%60+and+%60age%60+to+the+appropriate+parts%0A%2F%2F+of+the+tuple.+You+can+do+it%21%21%0A) +- ["primitive_types6.rs"](https://play.rust-lang.org/?code=%2F%2F+primitive_types6.rs%0A%2F%2F+Use+a+tuple+index+to+access+the+second+element+of+%60numbers%60.%0A%2F%2F+You+can+put+this+right+into+the+%60println%21%60+where+the+%3F%3F%3F+is.%0A%2F%2F+Scroll+down+for+hints%21%0A%0Afn+main%28%29+%7B%0A++++let+numbers+%3D+%281%2C+2%2C+3%29%3B%0A++++println%21%28%22The+second+number+is+%7B%7D%22%2C+%3F%3F%3F%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+While+you+could+use+a+destructuring+%60let%60+for+the+tuple+here%2C+try+%0A%2F%2F+indexing+into+it+instead%2C+as+explained+here%3A%0A%2F%2F+http%3A%2F%2Fdoc.rust-lang.org%2Fstable%2Fbook%2Fprimitive-types.html%23tuple-indexing%0A%2F%2F+Now+you+have+another+tool+in+your+toolbox%21%0A) + +### Tests + +Going out of order from the Syntax and Semantics section of the book to cover tests-- many of the +following exercises will ask you to make tests pass! + +[Testing chapter from the Effective Rust section of the book](https://doc.rust-lang.org/stable/book/first-edition/testing.html) + +- ["tests1.rs"](https://play.rust-lang.org/?code=%2F%2F+tests1.rs%0A%2F%2F+Tests+are+important+to+ensure+that+your+code+does+what+you+think+it+should+do.%0A%2F%2F+Tests+can+be+run+on+this+file+with+the+following+command%3A%0A%2F%2F+rustc+--test+tests1.rs%0A%0A%2F%2F+This+test+has+a+problem+with+it+--+make+the+test+compile%21+Make+the+test%0A%2F%2F+pass%21+Make+the+test+fail%21+Scroll+down+for+hints+%3A%29%0A%0A%23%5Bcfg%28test%29%5D%0Amod+tests+%7B%0A++++%23%5Btest%5D%0A++++fn+you_can_assert%28%29+%7B%0A++++++++assert%21%28%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+You+don%27t+even+need+to+write+any+code+to+test+--+you+can+just+test+values+and+run+that%2C+even%0A%2F%2F+though+you+wouldn%27t+do+that+in+real+life+%3A%29+%60assert%21%60+is+a+macro+that+needs+an+argument.%0A%2F%2F+Depending+on+the+value+of+the+argument%2C+%60assert%21%60+will+do+nothing+%28in+which+case+the+test+will%0A%2F%2F+pass%29+or+%60assert%21%60+will+panic+%28in+which+case+the+test+will+fail%29.+So+try+giving+different+values%0A%2F%2F+to+%60assert%21%60+and+see+which+ones+compile%2C+which+ones+pass%2C+and+which+ones+fail+%3A%29%0A) +- ["tests2.rs"](https://play.rust-lang.org/?code=%2F%2F+tests2.rs%0A%2F%2F+This+test+has+a+problem+with+it+--+make+the+test+compile%21+Make+the+test%0A%2F%2F+pass%21+Make+the+test+fail%21+Scroll+down+for+hints+%3A%29%0A%0A%23%5Bcfg%28test%29%5D%0Amod+tests+%7B%0A++++%23%5Btest%5D%0A++++fn+you_can_assert_eq%28%29+%7B%0A++++++++assert_eq%21%28%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Like+the+previous+exercise%2C+you+don%27t+need+to+write+any+code+to+get+this+test+to+compile+and%0A%2F%2F+run.+%60assert_eq%21%60+is+a+macro+that+takes+two+arguments+and+compares+them.+Try+giving+it+two%0A%2F%2F+values+that+are+equal%21+Try+giving+it+two+arguments+that+are+different%21+Try+giving+it+two+values%0A%2F%2F+that+are+of+different+types%21+Try+switching+which+argument+comes+first+and+which+comes+second%21%0A) +- ["tests3.rs"](https://play.rust-lang.org/?code=%2F%2F+tests3.rs%0A%2F%2F+This+test+isn%27t+testing+our+function+--+make+it+do+that+in+such+a+way+that%0A%2F%2F+the+test+passes.+Then+write+a+second+test+that+tests+that+we+get+the+result%0A%2F%2F+we+expect+to+get+when+we+call+%60is_even%285%29%60.+Scroll+down+for+hints%21%0A%0Apub+fn+is_even%28num%3A+i32%29+-%3E+bool+%7B%0A++++num+%25+2+%3D%3D+0%0A%7D%0A%0A%23%5Bcfg%28test%29%5D%0Amod+tests+%7B%0A++++use+super%3A%3A*%3B%0A%0A++++%23%5Btest%5D%0A++++fn+is_true_when_even%28%29+%7B%0A++++++++assert%21%28false%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+You+can+call+a+function+right+where+you%27re+passing+arguments+to+%60assert%21%60+--+so+you+could+do%0A%2F%2F+something+like+%60assert%21%28having_fun%28%29%29%60.+If+you+want+to+check+that+you+indeed+get+false%2C+you%0A%2F%2F+can+negate+the+result+of+what+you%27re+doing+using+%60%21%60%2C+like+%60assert%21%28%21having_fun%28%29%29%60.%0A) +- ["tests4.rs"](https://play.rust-lang.org/?code=%2F%2F+tests4.rs%0A%2F%2F+This+test+isn%27t+testing+our+function+--+make+it+do+that+in+such+a+way+that%0A%2F%2F+the+test+passes.+Then+write+a+second+test+that+tests+that+we+get+the+result%0A%2F%2F+we+expect+to+get+when+we+call+%60times_two%60+with+a+negative+number.%0A%2F%2F+No+hints%2C+you+can+do+this+%3A%29%0A%0Apub+fn+times_two%28num%3A+i32%29+-%3E+i32+%7B%0A++++num+*+2%0A%7D%0A%0A%23%5Bcfg%28test%29%5D%0Amod+tests+%7B%0A++++use+super%3A%3A*%3B%0A%0A++++%23%5Btest%5D%0A++++fn+returns_twice_of_positive_numbers%28%29+%7B%0A++++++++assert_eq%21%284%2C+4%29%3B%0A++++%7D%0A%7D%0A) + +### If + +[Relevant chapter in The Rust Programming Language](https://doc.rust-lang.org/stable/book/first-edition/if.html) + +- ["if1.rs"](https://play.rust-lang.org/?code=%2F%2F+if1.rs%0A%0Apub+fn+bigger%28a%3A+i32%2C+b%3Ai32%29+-%3E+i32+%7B%0A++++%2F%2F+Complete+this+function+to+return+the+bigger+number%21%0A++++%2F%2F+Do+not+use%3A%0A++++%2F%2F+-+return%0A++++%2F%2F+-+another+function+call%0A++++%2F%2F+-+additional+variables%0A++++%2F%2F+Scroll+down+for+hints.%0A%7D%0A%0A%23%5Bcfg%28test%29%5D%0Amod+tests+%7B%0A++++use+super%3A%3A*%3B%0A%0A++++%23%5Btest%5D%0A++++fn+ten_is_bigger_than_eight%28%29+%7B%0A++++++++assert_eq%21%2810%2C+bigger%2810%2C+8%29%29%3B%0A++++%7D%0A%0A++++%23%5Btest%5D%0A++++fn+fortytwo_is_bigger_than_thirtytwo%28%29+%7B%0A++++++++assert_eq%21%2842%2C+bigger%2832%2C+42%29%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+It%27s+possible+to+do+this+in+one+line+if+you+would+like%21%0A%2F%2F+Some+similar+examples+from+other+languages%3A%0A%2F%2F+-+In+C%28%2B%2B%29+this+would+be%3A+%60a+%3E+b+%3F+a+%3A+b%60%0A%2F%2F+-+In+Python+this+would+be%3A++%60a+if+a+%3E+b+else+b%60%0A%2F%2F+Remember+in+Rust+that%3A%0A%2F%2F+-+the+%60if%60+condition+does+not+need+to+be+surrounded+by+parentheses%0A%2F%2F+-+%60if%60%2F%60else%60+conditionals+are+expressions%0A%2F%2F+-+Each+condition+is+followed+by+a+%60%7B%7D%60+block.%0A) + +### Strings + +[Relevant chapter in The Rust Programming Language](https://doc.rust-lang.org/stable/book/first-edition/strings.html) + +- ["strings1.rs"](https://play.rust-lang.org/?code=%2F%2F+strings1.rs%0A%2F%2F+Make+me+compile+without+changing+the+function+signature%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++let+answer+%3D+current_favorite_color%28%29%3B%0A++++println%21%28%22My+current+favorite+color+is+%7B%7D%22%2C+answer%29%3B%0A%7D%0A%0Afn+current_favorite_color%28%29+-%3E+String+%7B%0A++++%22blue%22%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+The+%60current_favorite_color%60+function+is+currently+returning+a+string+slice+with+the+%60%27static%60%0A%2F%2F+lifetime.+We+know+this+because+the+data+of+the+string+lives+in+our+code+itself+--+it+doesn%27t%0A%2F%2F+come+from+a+file+or+user+input+or+another+program+--+so+it+will+live+as+long+as+our+program%0A%2F%2F+lives.+But+it+is+still+a+string+slice.+There%27s+one+way+to+create+a+%60String%60+by+converting+a%0A%2F%2F+string+slice+covered+in+the+Strings+chapter+of+the+book%2C+and+another+way+that+uses+the+%60From%60%0A%2F%2F+trait.%0A) +- ["strings2.rs"](https://play.rust-lang.org/?code=%2F%2F+strings2.rs%0A%2F%2F+Make+me+compile+without+changing+the+function+signature%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++let+word+%3D+String%3A%3Afrom%28%22green%22%29%3B+%2F%2F+Try+not+changing+this+line+%3A%29%0A++++if+is_a_color_word%28word%29+%7B%0A++++++++println%21%28%22That+is+a+color+word+I+know%21%22%29%3B%0A++++%7D+else+%7B%0A++++++++println%21%28%22That+is+not+a+color+word+I+know.%22%29%3B%0A++++%7D%0A%7D%0A%0Afn+is_a_color_word%28attempt%3A+%26str%29+-%3E+bool+%7B%0A++++attempt+%3D%3D+%22green%22+%7C%7C+attempt+%3D%3D+%22blue%22+%7C%7C+attempt+%3D%3D+%22red%22%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Yes%2C+it+would+be+really+easy+to+fix+this+by+just+changing+the+value+bound+to+%60word%60+to+be+a%0A%2F%2F+string+slice+instead+of+a+%60String%60%2C+wouldn%27t+it%3F%3F+There+is+a+way+to+add+one+character+to+line%0A%2F%2F+5%2C+though%2C+that+will+coerce+the+%60String%60+into+a+string+slice.%0A) +- ["strings3.rs"](https://play.rust-lang.org/?code=%2F%2F+strings3.rs%0A%2F%2F+Ok%2C+here+are+a+bunch+of+values--+some+are+%60Strings%60%2C+some+are+%60%26strs%60.+Your%0A%2F%2F+task+is+to+call+one+of+these+two+functions+on+each+value+depending+on+what%0A%2F%2F+you+think+each+value+is.+That+is%2C+add+either+%60string_slice%60+or+%60string%60%0A%2F%2F+before+the+parentheses+on+each+line.+If+you%27re+right%2C+it+will+compile%21%0A%0Afn+string_slice%28arg%3A+%26str%29+%7B+println%21%28%22%7B%7D%22%2C+arg%29%3B+%7D%0Afn+string%28arg%3A+String%29+%7B+println%21%28%22%7B%7D%22%2C+arg%29%3B+%7D%0A%0Afn+main%28%29+%7B%0A++++%28%22blue%22%29%3B%0A++++%28%22red%22.to_string%28%29%29%3B%0A++++%28String%3A%3Afrom%28%22hi%22%29%29%3B%0A++++%28%22rust+is+fun%21%22.to_owned%28%29%29%3B%0A++++%28%22nice+weather%22.into%28%29%29%3B%0A++++%28format%21%28%22Interpolation+%7B%7D%22%2C+%22Station%22%29%29%3B%0A++++%28%26String%3A%3Afrom%28%22abc%22%29%5B0..1%5D%29%3B%0A++++%28%22++hello+there+%22.trim%28%29%29%3B%0A++++%28%22Happy+Monday%21%22.to_string%28%29.replace%28%22Mon%22%2C+%22Tues%22%29%29%3B%0A++++%28%22mY+sHiFt+KeY+iS+sTiCkY%22.to_lowercase%28%29%29%3B%0A%7D%0A) + +### 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/stable/book/first-edition/ownership.html) +- [References and borrowing](https://doc.rust-lang.org/stable/book/first-edition/references-and-borrowing.html) + +Note that the exercises in this section may look similar to each other but they are subtly different :) + +- ["move_semantics1.rs"](https://play.rust-lang.org/?code=%2F%2F+move_semantics1.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Apub+fn+main%28%29+%7B%0A++++let+vec0+%3D+Vec%3A%3Anew%28%29%3B%0A%0A++++let+vec1+%3D+fill_vec%28vec0%29%3B%0A%0A++++println%21%28%22%7B%7D+has+length+%7B%7D+content+%60%7B%3A%3F%7D%60%22%2C+%22vec1%22%2C+vec1.len%28%29%2C+vec1%29%3B%0A%0A++++vec1.push%2888%29%3B%0A%0A++++println%21%28%22%7B%7D+has+length+%7B%7D+content+%60%7B%3A%3F%7D%60%22%2C+%22vec1%22%2C+vec1.len%28%29%2C+vec1%29%3B%0A%0A%7D%0A%0Afn+fill_vec%28vec%3A+Vec%3Ci32%3E%29+-%3E+Vec%3Ci32%3E+%7B%0A++++let+mut+vec+%3D+vec%3B%0A%0A++++vec.push%2822%29%3B%0A++++vec.push%2844%29%3B%0A++++vec.push%2866%29%3B%0A%0A++++vec%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+So+you%27ve+got+the+%22cannot+borrow+immutable+local+variable+%60vec1%60+as+mutable%22+error+on+line+10%2C%0A%2F%2F+right%3F+The+fix+for+this+is+going+to+be+adding+one+keyword%2C+and+the+addition+is+NOT+on+line+10%0A%2F%2F+where+the+error+is.%0A) +- ["move_semantics2.rs"](https://play.rust-lang.org/?code=%2F%2F+move_semantics2.rs%0A%2F%2F+Make+me+compile+without+changing+line+9%21+Scroll+down+for+hints+%3A%29%0A%0Apub+fn+main%28%29+%7B%0A++++let+vec0+%3D+Vec%3A%3Anew%28%29%3B%0A%0A++++let+mut+vec1+%3D+fill_vec%28vec0%29%3B%0A%0A++++%2F%2F+Do+not+change+the+following+line%21%0A++++println%21%28%22%7B%7D+has+length+%7B%7D+content+%60%7B%3A%3F%7D%60%22%2C+%22vec0%22%2C+vec0.len%28%29%2C+vec0%29%3B%0A%0A++++vec1.push%2888%29%3B%0A%0A++++println%21%28%22%7B%7D+has+length+%7B%7D+content+%60%7B%3A%3F%7D%60%22%2C+%22vec1%22%2C+vec1.len%28%29%2C+vec1%29%3B%0A%0A%7D%0A%0Afn+fill_vec%28vec%3A+Vec%3Ci32%3E%29+-%3E+Vec%3Ci32%3E+%7B%0A++++let+mut+vec+%3D+vec%3B%0A%0A++++vec.push%2822%29%3B%0A++++vec.push%2844%29%3B%0A++++vec.push%2866%29%3B%0A%0A++++vec%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+So+%60vec0%60+is+being+*moved*+into+the+function+%60fill_vec%60+when+we+call+it+on%0A%2F%2F+line+6%2C+which+means+it+gets+dropped+at+the+end+of+%60fill_vec%60%2C+which+means+we%0A%2F%2F+can%27t+use+%60vec0%60+again+on+line+9+%28or+anywhere+else+in+%60main%60+after+the%0A%2F%2F+%60fill_vec%60+call+for+that+matter%29.+We+could+fix+this+in+a+few+ways%2C+try+them%0A%2F%2F+all%21%0A%2F%2F+1.+Make+another%2C+separate+version+of+the+data+that%27s+in+%60vec0%60+and+pass+that%0A%2F%2F+to+%60fill_vec%60+instead.%0A%2F%2F+2.+Make+%60fill_vec%60+borrow+its+argument+instead+of+taking+ownership+of+it%2C%0A%2F%2F+and+then+copy+the+data+within+the+function+in+order+to+return+an+owned%0A%2F%2F+%60Vec%3Ci32%3E%60%0A%2F%2F+3.+Make+%60fill_vec%60+*mutably*+borrow+its+argument+%28which+will+need+to+be%0A%2F%2F+mutable%29%2C+modify+it+directly%2C+then+not+return+anything.+Then+you+can+get+rid%0A%2F%2F+of+%60vec1%60+entirely+--+note+that+this+will+change+what+gets+printed+by+the%0A%2F%2F+first+%60println%21%60%0A) +- ["move_semantics3.rs"](https://play.rust-lang.org/?code=%2F%2F+move_semantics3.rs%0A%2F%2F+Make+me+compile+without+adding+new+lines--+just+changing+existing+lines%21%0A%2F%2F+%28no+lines+with+multiple+semicolons+necessary%21%29%0A%2F%2F+Scroll+down+for+hints+%3A%29%0A%0Apub+fn+main%28%29+%7B%0A++++let+vec0+%3D+Vec%3A%3Anew%28%29%3B%0A%0A++++let+mut+vec1+%3D+fill_vec%28vec0%29%3B%0A%0A++++println%21%28%22%7B%7D+has+length+%7B%7D+content+%60%7B%3A%3F%7D%60%22%2C+%22vec1%22%2C+vec1.len%28%29%2C+vec1%29%3B%0A%0A++++vec1.push%2888%29%3B%0A%0A++++println%21%28%22%7B%7D+has+length+%7B%7D+content+%60%7B%3A%3F%7D%60%22%2C+%22vec1%22%2C+vec1.len%28%29%2C+vec1%29%3B%0A%0A%7D%0A%0Afn+fill_vec%28vec%3A+Vec%3Ci32%3E%29+-%3E+Vec%3Ci32%3E+%7B%0A++++vec.push%2822%29%3B%0A++++vec.push%2844%29%3B%0A++++vec.push%2866%29%3B%0A%0A++++vec%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+The+difference+between+this+one+and+the+previous+ones+is+that+the+first+line%0A%2F%2F+of+%60fn+fill_vec%60+that+had+%60let+mut+vec+%3D+vec%3B%60+is+no+longer+there.+You+can%2C%0A%2F%2F+instead+of+adding+that+line+back%2C+add+%60mut%60+in+one+place+that+will+change%0A%2F%2F+an+existing+binding+to+be+a+mutable+binding+instead+of+an+immutable+one+%3A%29%0A) +- ["move_semantics4.rs"](https://play.rust-lang.org/?code=%2F%2F+move_semantics4.rs%0A%2F%2F+Refactor+this+code+so+that+instead+of+having+%60vec0%60+and+creating+the+vector%0A%2F%2F+in+%60fn+main%60%2C+we+instead+create+it+within+%60fn+fill_vec%60+and+transfer+the%0A%2F%2F+freshly+created+vector+from+fill_vec+to+its+caller.+Scroll+for+hints%21%0A%0Apub+fn+main%28%29+%7B%0A++++let+vec0+%3D+Vec%3A%3Anew%28%29%3B%0A%0A++++let+mut+vec1+%3D+fill_vec%28vec0%29%3B%0A%0A++++println%21%28%22%7B%7D+has+length+%7B%7D+content+%60%7B%3A%3F%7D%60%22%2C+%22vec1%22%2C+vec1.len%28%29%2C+vec1%29%3B%0A%0A++++vec1.push%2888%29%3B%0A%0A++++println%21%28%22%7B%7D+has+length+%7B%7D+content+%60%7B%3A%3F%7D%60%22%2C+%22vec1%22%2C+vec1.len%28%29%2C+vec1%29%3B%0A%0A%7D%0A%0Afn+fill_vec%28vec%3A+Vec%3Ci32%3E%29+-%3E+Vec%3Ci32%3E+%7B%0A++++let+mut+vec+%3D+vec%3B%0A%0A++++vec.push%2822%29%3B%0A++++vec.push%2844%29%3B%0A++++vec.push%2866%29%3B%0A%0A++++vec%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Stop+reading+whenever+you+feel+like+you+have+enough+direction+%3A%29+Or+try%0A%2F%2F+doing+one+step+and+then+fixing+the+compiler+errors+that+result%21%0A%2F%2F+So+the+end+goal+is+to%3A%0A%2F%2F+-+get+rid+of+the+first+line+in+main+that+creates+the+new+vector%0A%2F%2F+-+so+then+%60vec0%60+doesn%27t+exist%2C+so+we+can%27t+pass+it+to+%60fill_vec%60%0A%2F%2F+-+we+don%27t+want+to+pass+anything+to+%60fill_vec%60%2C+so+its+signature+should%0A%2F%2F+++reflect+that+it+does+not+take+any+arguments%0A%2F%2F+-+since+we%27re+not+creating+a+new+vec+in+%60main%60+anymore%2C+we+need+to+create%0A%2F%2F+++a+new+vec+in+%60fill_vec%60%2C+similarly+to+the+way+we+did+in+%60main%60%0A) + +### Modules + +[Relevant chapter in The Rust Programming Language](https://doc.rust-lang.org/stable/book/first-edition/crates-and-modules.html) + +- ["modules1.rs"](https://play.rust-lang.org/?code=%2F%2F+modules1.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Amod+sausage_factory+%7B%0A++++fn+make_sausage%28%29+%7B%0A++++++++println%21%28%22sausage%21%22%29%3B%0A++++%7D%0A%7D%0A%0Afn+main%28%29+%7B%0A++++sausage_factory%3A%3Amake_sausage%28%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Everything+is+private+in+Rust+by+default--+but+there%27s+a+keyword+we+can+use%0A%2F%2F+to+make+something+public%21+The+compiler+error+should+point+to+the+thing+that%0A%2F%2F+needs+to+be+public.%0A) +- ["modules2.rs"](https://play.rust-lang.org/?code=%2F%2F+modules2.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Amod+us_presidential_frontrunners+%7B%0A++++use+self%3A%3Ademocrats%3A%3AHILLARY_CLINTON+as+democrat%3B%0A++++use+self%3A%3Arepublicans%3A%3ADONALD_TRUMP+as+republican%3B%0A%0A++++mod+democrats+%7B%0A++++++++pub+const+HILLARY_CLINTON%3A+%26%27static+str+%3D+%22Hillary+Clinton%22%3B%0A++++++++pub+const+BERNIE_SANDERS%3A+%26%27static+str+%3D+%22Bernie+Sanders%22%3B%0A++++%7D%0A%0A++++mod+republicans+%7B%0A++++++++pub+const+DONALD_TRUMP%3A+%26%27static+str+%3D+%22Donald+Trump%22%3B%0A++++++++pub+const+JEB_BUSH%3A+%26%27static+str+%3D+%22Jeb+Bush%22%3B%0A++++%7D%0A%7D%0A%0Afn+main%28%29+%7B%0A++++println%21%28%22candidates%3A+%7B%7D+and+%7B%7D%22%2C%0A+++++++++++++us_presidential_frontrunners%3A%3Ademocrat%2C%0A+++++++++++++us_presidential_frontrunners%3A%3Arepublican%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+The+us_presidential_frontrunners+module+is+trying+to+present+an+external%0A%2F%2F+interface+%28the+%60democrat%60+and+%60republican%60+constants%29+that+is+different+than%0A%2F%2F+its+internal+structure+%28the+%60democrats%60+and+%60republicans%60+modules+and%0A%2F%2F+associated+constants%29.+It%27s+almost+there+except+for+one+keyword+missing+for%0A%2F%2F+each+constant.%0A%2F%2F+One+more+hint%3A+I+wish+the+compiler+error%2C+instead+of+saying+%22unresolved+name%0A%2F%2F+%60us_presidential_frontrunners%3A%3Ademocrat%60%22%2C+could+say++%22constant%0A%2F%2F+%60us_presidential_frontrunners%3A%3Ademocrat%60+is+private%22%21) + +### Macros + +[Check out the Macros section of the book](https://doc.rust-lang.org/book/first-edition/macros.html). + +- ["macros1.rs"](https://play.rust-lang.org/?code=%2F%2F+macros1.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Amacro_rules%21+my_macro+%7B%0A++++%28%29+%3D%3E+%7B%0A++++++++println%21%28%22Check+out+my+macro%21%22%29%3B%0A++++%7D%3B%0A%7D%0A%0Afn+main%28%29+%7B%0A++++my_macro%28%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+When+you+call+a+macro%2C+you+need+to+add+something+special+compared+to+a%0A%2F%2F+regular+function+call.+If+you%27re+stuck%2C+take+a+look+at+what%27s+inside%0A%2F%2F+%60my_macro%60.%0A) +- ["macros2.rs"](https://play.rust-lang.org/?code=%2F%2F+macros2.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++my_macro%21%28%29%3B%0A%7D%0A%0Amacro_rules%21+my_macro+%7B%0A++++%28%29+%3D%3E+%7B%0A++++++++println%21%28%22Check+out+my+macro%21%22%29%3B%0A++++%7D%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Macros+don%27t+quite+play+by+the+same+rules+as+the+rest+of+Rust%2C+in+terms+of%0A%2F%2F+what%27s+available+where.%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Unlike+other+things+in+Rust%2C+the+order+of+%22where+you+define+a+macro%22+versus%0A%2F%2F+%22where+you+use+it%22+actually+matters.%0A) +- ["macros3.rs"](https://play.rust-lang.org/?code=%2F%2F+macros3.rs%0A%2F%2F+Make+me+compile%2C+without+taking+the+macro+out+of+the+module%21+Scroll+down+for+hints+%3A%29%0A%0Amod+macros+%7B%0A++++macro_rules%21+my_macro+%7B%0A++++++++%28%29+%3D%3E+%7B%0A++++++++++++println%21%28%22Check+out+my+macro%21%22%29%3B%0A++++++++%7D%3B%0A++++%7D%0A%7D%0A%0Afn+main%28%29+%7B%0A++++my_macro%21%28%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+In+order+to+use+a+macro+outside+of+its+module%2C+you+need+to+do+something%0A%2F%2F+special+to+the+module+to+lift+the+macro+out+into+its+parent.%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+The+same+trick+also+works+on+%22extern+crate%22+statements+for+crates+that+have%0A%2F%2F+exported+macros%2C+if+you%27ve+seen+any+of+those+around.%0A) +- ["macros4.rs"](https://play.rust-lang.org/?code=%2F%2F+macros4.rs%0A%2F%2F+Make+me+compile%21+Scroll+down+for+hints+%3A%29%0A%0Amacro_rules%21+my_macro+%7B%0A++++%28%29+%3D%3E+%7B%0A++++++++println%21%28%22Check+out+my+macro%21%22%29%3B%0A++++%7D%0A++++%28%24val%3Aexpr%29+%3D%3E+%7B%0A++++++++println%21%28%22Look+at+this+other+macro%3A+%7B%7D%22%2C+%24val%29%3B%0A++++%7D%0A%7D%0A%0Afn+main%28%29+%7B%0A++++my_macro%21%28%29%3B%0A++++my_macro%21%287777%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+You+only+need+to+add+a+single+character+to+make+this+compile.%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+The+way+macros+are+written%2C+it+wants+to+see+something+between+each%0A%2F%2F+%22macro+arm%22%2C+so+it+can+separate+them.%0A) + +### Error Handling + +The [Error Handling](https://doc.rust-lang.org/stable/book/first-edition/error-handling.html) and [Generics](https://doc.rust-lang.org/stable/book/first-edition/generics.html) sections are relevant. + +- ["option1.rs"](https://play.rust-lang.org/?code=%2F%2F+option1.rs%0A%2F%2F+This+example+panics+because+the+second+time+it+calls+%60pop%60%2C+the+%60vec%60%0A%2F%2F+is+empty%2C+so+%60pop%60+returns+%60None%60%2C+and+%60unwrap%60+panics+if+it%27s+called%0A%2F%2F+on+%60None%60.+Handle+this+in+a+more+graceful+way+than+calling+%60unwrap%60%21%0A%2F%2F+Scroll+down+for+hints+%3A%29%0A%0Afn+main%28%29+%7B%0A++++let+mut+list+%3D+vec%21%5B3%5D%3B%0A%0A++++let+last+%3D+list.pop%28%29.unwrap%28%29%3B%0A++++println%21%28%22The+last+item+in+the+list+is+%7B%3A%3F%7D%22%2C+last%29%3B%0A%0A++++let+second_to_last+%3D+list.pop%28%29.unwrap%28%29%3B%0A++++println%21%28%22The+second-to-last+item+in+the+list+is+%7B%3A%3F%7D%22%2C+second_to_last%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Try+using+a+%60match%60+statement+where+the+arms+are+%60Some%28thing%29%60+and+%60None%60.%0A%2F%2F+Or+set+a+default+value+to+print+out+if+you+get+%60None%60+by+using+the%0A%2F%2F+function+%60unwrap_or%60.%0A%2F%2F+Or+use+an+%60if+let%60+statement+on+the+result+of+%60pop%28%29%60+to+both+destructure%0A%2F%2F+a+%60Some%60+value+and+only+print+out+something+if+we+have+a+value%21%0A) +- ["result1.rs"](https://play.rust-lang.org/?code=%2F%2F+result1.rs%0A%2F%2F+Make+this+test+pass%21+Scroll+down+for+hints+%3A%29%0A%0A%23%5Bderive%28PartialEq%2CDebug%29%5D%0Astruct+PositiveNonzeroInteger%28u64%29%3B%0A%0A%23%5Bderive%28PartialEq%2CDebug%29%5D%0Aenum+CreationError+%7B%0A++++Negative%2C%0A++++Zero%2C%0A%7D%0A%0Aimpl+PositiveNonzeroInteger+%7B%0A++++fn+new%28value%3A+i64%29+-%3E+Result%3CPositiveNonzeroInteger%2C+CreationError%3E+%7B%0A++++++++Ok%28PositiveNonzeroInteger%28value+as+u64%29%29%0A++++%7D%0A%7D%0A%0A%23%5Btest%5D%0Afn+test_creation%28%29+%7B%0A++++assert%21%28PositiveNonzeroInteger%3A%3Anew%2810%29.is_ok%28%29%29%3B%0A++++assert_eq%21%28Err%28CreationError%3A%3ANegative%29%2C+PositiveNonzeroInteger%3A%3Anew%28-10%29%29%3B%0A++++assert_eq%21%28Err%28CreationError%3A%3AZero%29%2C+PositiveNonzeroInteger%3A%3Anew%280%29%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+%60PositiveNonzeroInteger%3A%3Anew%60+is+always+creating+a+new+instance+and+returning+an+%60Ok%60+result.%0A%2F%2F+It+should+be+doing+some+checking%2C+returning+an+%60Err%60+result+if+those+checks+fail%2C+and+only%0A%2F%2F+returning+an+%60Ok%60+result+if+those+checks+determine+that+everything+is...+okay+%3A%29%0A) +- ["errors1.rs"](https://play.rust-lang.org/?code=%2F%2F+errors1.rs%0A%2F%2F+This+function+refuses+to+generate+text+to+be+printed+on+a+nametag+if%0A%2F%2F+you+pass+it+an+empty+string.+It%27d+be+nicer+if+it+explained+what+the+problem%0A%2F%2F+was%2C+instead+of+just+sometimes+returning+%60None%60.+The+2nd+test+currently%0A%2F%2F+does+not+compile+or+pass%2C+but+it+illustrates+the+behavior+we+would+like%0A%2F%2F+this+function+to+have.%0A%2F%2F+Scroll+down+for+hints%21%21%21%0A%0Apub+fn+generate_nametag_text%28name%3A+String%29+-%3E+Option%3CString%3E+%7B%0A++++if+name.len%28%29+%3E+0+%7B%0A++++++++Some%28format%21%28%22Hi%21+My+name+is+%7B%7D%22%2C+name%29%29%0A++++%7D+else+%7B%0A++++++++%2F%2F+Empty+names+aren%27t+allowed.%0A++++++++None%0A++++%7D%0A%7D%0A%0A%23%5Bcfg%28test%29%5D%0Amod+tests+%7B%0A++++use+super%3A%3A*%3B%0A%0A++++%2F%2F+This+test+passes+initially+if+you+comment+out+the+2nd+test.%0A++++%2F%2F+You%27ll+need+to+update+what+this+test+expects+when+you+change%0A++++%2F%2F+the+function+under+test%21%0A++++%23%5Btest%5D%0A++++fn+generates_nametag_text_for_a_nonempty_name%28%29+%7B%0A++++++++assert_eq%21%28%0A++++++++++++generate_nametag_text%28%22Beyonc%C3%A9%22.into%28%29%29%2C%0A++++++++++++Some%28%22Hi%21+My+name+is+Beyonc%C3%A9%22.into%28%29%29%0A++++++++%29%3B%0A++++%7D%0A%0A++++%23%5Btest%5D%0A++++fn+explains_why_generating_nametag_text_fails%28%29+%7B%0A++++++++assert_eq%21%28%0A++++++++++++generate_nametag_text%28%22%22.into%28%29%29%2C%0A++++++++++++Err%28%22%60name%60+was+empty%3B+it+must+be+nonempty.%22.into%28%29%29%0A++++++++%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+%60Err%60+is+one+of+the+variants+of+%60Result%60%2C+so+what+the+2nd+test+is+saying%0A%2F%2F+is+that+%60generate_nametag_text%60+should+return+a+%60Result%60+instead+of+an%0A%2F%2F+%60Option%60.%0A%0A%2F%2F+To+make+this+change%2C+you%27ll+need+to%3A%0A%2F%2F+-+update+the+return+type+in+the+function+signature+to+be+a+Result+that%0A%2F%2F+++could+be+the+variants+%60Ok%28String%29%60+and+%60Err%28String%29%60%0A%2F%2F+-+change+the+body+of+the+function+to+return+%60Ok%28stuff%29%60+where+it+currently%0A%2F%2F+++returns+%60Some%28stuff%29%60%0A%2F%2F+-+change+the+body+of+the+function+to+return+%60Err%28error+message%29%60+where+it%0A%2F%2F+++currently+returns+%60None%60%0A%2F%2F+-+change+the+first+test+to+expect+%60Ok%28stuff%29%60+where+it+currently+expects%0A%2F%2F+++%60Some%28stuff%29%60.%0A) +- ["errors2.rs"](https://play.rust-lang.org/?code=%2F%2F+errors2.rs%0A%2F%2F+Say+we%27re+writing+a+game+where+you+can+buy+items+with+tokens.+All+items+cost%0A%2F%2F+5+tokens%2C+and+whenever+you+purchase+items+there+is+a+processing+fee+of+1%0A%2F%2F+token.+A+player+of+the+game+will+type+in+how+many+items+they+want+to+buy%2C%0A%2F%2F+and+the+%60total_cost%60+function+will+calculate+the+total+number+of+tokens.%0A%2F%2F+Since+the+player+typed+in+the+quantity%2C+though%2C+we+get+it+as+a+string--+and%0A%2F%2F+they+might+have+typed+anything%2C+not+just+numbers%21%0A%0A%2F%2F+Right+now%2C+this+function+isn%27t+handling+the+error+case+at+all+%28and+isn%27t%0A%2F%2F+handling+the+success+case+properly+either%29.+What+we+want+to+do+is%3A%0A%2F%2F+if+we+call+the+%60parse%60+function+on+a+string+that+is+not+a+number%2C+that%0A%2F%2F+function+will+return+a+%60ParseIntError%60%2C+and+in+that+case%2C+we+want+to%0A%2F%2F+immediately+return+that+error+from+our+function+and+not+try+to+multiply%0A%2F%2F+and+add.%0A%0A%2F%2F+There+are+at+least+two+ways+to+implement+this+that+are+both+correct--+but%0A%2F%2F+one+is+a+lot+shorter%21+Scroll+down+for+hints+to+both+ways.%0A%0Ause+std%3A%3Anum%3A%3AParseIntError%3B%0A%0Apub+fn+total_cost%28item_quantity%3A+%26str%29+-%3E+Result%3Ci32%2C+ParseIntError%3E+%7B%0A++++let+processing_fee+%3D+1%3B%0A++++let+cost_per_item+%3D+5%3B%0A++++let+qty+%3D+item_quantity.parse%3A%3A%3Ci32%3E%28%29%3B%0A%0A++++Ok%28qty+*+cost_per_item+%2B+processing_fee%29%0A%7D%0A%0A%23%5Bcfg%28test%29%5D%0Amod+tests+%7B%0A++++use+super%3A%3A*%3B%0A%0A++++%23%5Btest%5D%0A++++fn+item_quantity_is_a_valid_number%28%29+%7B%0A++++++++assert_eq%21%28%0A++++++++++++total_cost%28%2234%22%29%2C%0A++++++++++++Ok%28171%29%0A++++++++%29%3B%0A++++%7D%0A%0A++++%23%5Btest%5D%0A++++fn+item_quantity_is_an_invalid_number%28%29+%7B%0A++++++++assert_eq%21%28%0A++++++++++++total_cost%28%22beep+boop%22%29.unwrap_err%28%29.to_string%28%29%2C%0A++++++++++++%22invalid+digit+found+in+string%22%0A++++++++%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+One+way+to+handle+this+is+using+a+%60match%60+statement+on%0A%2F%2F+%60item_quantity.parse%3A%3A%3Ci32%3E%28%29%60+where+the+cases+are+%60Ok%28something%29%60+and%0A%2F%2F+%60Err%28something%29%60.+This+pattern+is+very+common+in+Rust%2C+though%2C+so+there%27s%0A%2F%2F+a+%60try%21%60+macro+that+does+pretty+much+what+you+would+make+that+match+statement%0A%2F%2F+do+for+you%21+Take+a+look+at+this+section+of+the+Error+Handling+chapter%3A%0A%2F%2F+https%3A%2F%2Fdoc.rust-lang.org%2Fstable%2Fbook%2Ferror-handling.html%23the-try-macro%0A%2F%2F+and+give+it+a+%60try%21%60%0A) +- ["errors3.rs"](https://play.rust-lang.org/?code=%2F%2F+errors3.rs%0A%2F%2F+This+is+a+program+that+is+trying+to+use+a+completed+version+of+the%0A%2F%2F+%60total_cost%60+function+from+the+previous+exercise.+It%27s+not+working+though--%0A%2F%2F+we+can%27t+call+the+%60try%21%60+macro+in+the+%60main%28%29%60+function%21+Why+not%3F%0A%2F%2F+What+should+we+do+instead%3F+Scroll+for+hints%21%0A%0Ause+std%3A%3Anum%3A%3AParseIntError%3B%0A%0Afn+main%28%29+%7B%0A++++let+mut+tokens+%3D+100%3B%0A++++let+pretend_user_input+%3D+%228%22%3B%0A%0A++++let+cost+%3D+try%21%28total_cost%28pretend_user_input%29%29%3B%0A%0A++++if+cost+%3E+tokens+%7B%0A++++++++println%21%28%22You+can%27t+afford+that+many%21%22%29%3B%0A++++%7D+else+%7B%0A++++++++tokens+-%3D+cost%3B%0A++++++++println%21%28%22You+now+have+%7B%7D+tokens.%22%2C+tokens%29%3B%0A++++%7D%0A%7D%0A%0Apub+fn+total_cost%28item_quantity%3A+%26str%29+-%3E+Result%3Ci32%2C+ParseIntError%3E+%7B%0A++++let+processing_fee+%3D+1%3B%0A++++let+cost_per_item+%3D+5%3B%0A++++let+qty+%3D+try%21%28item_quantity.parse%3A%3A%3Ci32%3E%28%29%29%3B%0A%0A++++Ok%28qty+*+cost_per_item+%2B+processing_fee%29%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Since+the+%60try%21%60+macro+returns+an+%60Err%60+early+if+the+thing+it%27s+trying+to%0A%2F%2F+do+fails%2C+you+can+only+use+the+%60try%21%60+macro+in+functions+that+have+a%0A%2F%2F+%60Result%60+as+their+return+type.%0A%0A%2F%2F+The+error+that+you+get+if+you+run+this+code+is%3A%0A%0A%2F%2F+%60%60%60%0A%2F%2F+error%3A+mismatched+types%3A%0A%2F%2F+expected+%60%28%29%60%2C%0A%2F%2F+found+%60std%3A%3Aresult%3A%3AResult%3C_%2C+_%3E%60%0A%2F%2F+%60%60%60%0A%0A%2F%2F+which+is+saying+that+the+expected+return+type+of+the+%60main%60+function+is%0A%2F%2F+the+empty+tuple%2C+but+we+tried+to+return+a+%60Result%60--+and+that%27s+happening%0A%2F%2F+in+the+implementation+of+%60try%21%60.+The+%60main%60+function+never+has+a+return+type%2C%0A%2F%2F+so+we+have+to+use+another+way+of+handling+a+%60Result%60+within+%60main%60.%0A%0A%2F%2F+Decide+what+we+should+do+if+%60pretend_user_input%60+has+a+string+value+that+does%0A%2F%2F+not+parse+to+an+integer%2C+and+implement+that+instead+of+calling+the+%60try%21%60%0A%2F%2F+macro.%0A) +- ["errorsn.rs"](https://play.rust-lang.org/?code=%2F%2F+errorsn.rs%0A%2F%2F+This+is+a+bigger+error+exercise+than+the+previous+ones%21%0A%2F%2F+You+can+do+it%21%0A%2F%2F%0A%2F%2F+Edit+the+%60read_and_validate%60+function+so+that+it+compiles+and%0A%2F%2F+passes+the+tests...+so+many+things+could+go+wrong%21%0A%2F%2F%0A%2F%2F+-+Reading+from+stdin+could+produce+an+io%3A%3AError%0A%2F%2F+-+Parsing+the+input+could+produce+a+num%3A%3AParseIntError%0A%2F%2F+-+Validating+the+input+could+produce+a+CreationError+%28defined+below%29%0A%2F%2F%0A%2F%2F+How+can+we+lump+these+errors+into+one+general+error%3F+That+is%2C+what%0A%2F%2F+type+goes+where+the+question+marks+are%2C+and+how+do+we+return%0A%2F%2F+that+type+from+the+body+of+read_and_validate%3F%0A%2F%2F%0A%2F%2F+Scroll+down+for+hints+%3A%29%0A%0Ause+std%3A%3Aerror%3B%0Ause+std%3A%3Afmt%3B%0Ause+std%3A%3Aio%3B%0A%0A%2F%2F+PositiveNonzeroInteger+is+a+struct+defined+below+the+tests.%0Afn+read_and_validate%28b%3A+%26mut+io%3A%3ABufRead%29+-%3E+Result%3CPositiveNonzeroInteger%2C+%3F%3F%3F%3E+%7B%0A++++let+mut+line+%3D+String%3A%3Anew%28%29%3B%0A++++b.read_line%28%26mut+line%29%3B%0A++++let+num%3A+i64+%3D+line.trim%28%29.parse%28%29%3B%0A++++let+answer+%3D+PositiveNonzeroInteger%3A%3Anew%28num%29%3B%0A++++answer%0A%7D%0A%0A%2F%2F+This+is+a+test+helper+function+that+turns+a+%26str+into+a+BufReader.%0Afn+test_with_str%28s%3A+%26str%29+-%3E+Result%3CPositiveNonzeroInteger%2C+Box%3Cerror%3A%3AError%3E%3E+%7B%0A++++let+mut+b+%3D+io%3A%3ABufReader%3A%3Anew%28s.as_bytes%28%29%29%3B%0A++++read_and_validate%28%26mut+b%29%0A%7D%0A%0A%23%5Btest%5D%0Afn+test_success%28%29+%7B%0A++++let+x+%3D+test_with_str%28%2242%5Cn%22%29%3B%0A++++assert_eq%21%28PositiveNonzeroInteger%2842%29%2C+x.unwrap%28%29%29%3B%0A%7D%0A%0A%23%5Btest%5D%0Afn+test_not_num%28%29+%7B%0A++++let+x+%3D+test_with_str%28%22eleven+billion%5Cn%22%29%3B%0A++++assert%21%28x.is_err%28%29%29%3B%0A%7D%0A%0A%23%5Btest%5D%0Afn+test_non_positive%28%29+%7B%0A++++let+x+%3D+test_with_str%28%22-40%5Cn%22%29%3B%0A++++assert%21%28x.is_err%28%29%29%3B%0A%7D%0A%0A%23%5Btest%5D%0Afn+test_ioerror%28%29+%7B%0A++++struct+Broken%3B%0A++++impl+io%3A%3ARead+for+Broken+%7B%0A++++++++fn+read%28%26mut+self%2C+_buf%3A+%26mut+%5Bu8%5D%29+-%3E+io%3A%3AResult%3Cusize%3E+%7B%0A++++++++++++Err%28io%3A%3AError%3A%3Anew%28io%3A%3AErrorKind%3A%3ABrokenPipe%2C+%22uh-oh%21%22%29%29%0A++++++++%7D%0A++++%7D%0A++++let+mut+b+%3D+io%3A%3ABufReader%3A%3Anew%28Broken%29%3B%0A++++assert%21%28read_and_validate%28%26mut+b%29.is_err%28%29%29%3B%0A++++assert_eq%21%28%22uh-oh%21%22%2C+read_and_validate%28%26mut+b%29.unwrap_err%28%29.to_string%28%29%29%3B%0A%7D%0A%0A%23%5Bderive%28PartialEq%2CDebug%29%5D%0Astruct+PositiveNonzeroInteger%28u64%29%3B%0A%0Aimpl+PositiveNonzeroInteger+%7B%0A++++fn+new%28value%3A+i64%29+-%3E+Result%3CPositiveNonzeroInteger%2C+CreationError%3E+%7B%0A++++++++if+value+%3D%3D+0+%7B%0A++++++++++++Err%28CreationError%3A%3AZero%29%0A++++++++%7D+else+if+value+%3C+0+%7B%0A++++++++++++Err%28CreationError%3A%3ANegative%29%0A++++++++%7D+else+%7B%0A++++++++++++Ok%28PositiveNonzeroInteger%28value+as+u64%29%29%0A++++++++%7D%0A++++%7D%0A%7D%0A%0A%23%5Btest%5D%0Afn+test_positive_nonzero_integer_creation%28%29+%7B%0A++++assert%21%28PositiveNonzeroInteger%3A%3Anew%2810%29.is_ok%28%29%29%3B%0A++++assert_eq%21%28Err%28CreationError%3A%3ANegative%29%2C+PositiveNonzeroInteger%3A%3Anew%28-10%29%29%3B%0A++++assert_eq%21%28Err%28CreationError%3A%3AZero%29%2C+PositiveNonzeroInteger%3A%3Anew%280%29%29%3B%0A%7D%0A%0A%23%5Bderive%28PartialEq%2CDebug%29%5D%0Aenum+CreationError+%7B%0A++++Negative%2C%0A++++Zero%2C%0A%7D%0A%0Aimpl+fmt%3A%3ADisplay+for+CreationError+%7B%0A++++fn+fmt%28%26self%2C+f%3A+%26mut+fmt%3A%3AFormatter%29+-%3E+fmt%3A%3AResult+%7B%0A++++++++f.write_str%28%28self+as+%26error%3A%3AError%29.description%28%29%29%0A++++%7D%0A%7D%0A%0Aimpl+error%3A%3AError+for+CreationError+%7B%0A++++fn+description%28%26self%29+-%3E+%26str+%7B%0A++++++++match+*self+%7B%0A++++++++++++CreationError%3A%3ANegative+%3D%3E+%22Negative%22%2C%0A++++++++++++CreationError%3A%3AZero+%3D%3E+%22Zero%22%2C%0A++++++++%7D%0A++++%7D%0A%7D%0A%0A%2F%2F+First+hint%3A+To+figure+out+what+type+should+go+where+the+%3F%3F%3F+is%2C+take+a+look%0A%2F%2F+at+the+test+helper+function+%60test_with_str%60%2C+since+it+returns+whatever%0A%2F%2F+%60read_and_validate%60+returns+and%60test_with_str%60+has+its+signature+fully%0A%2F%2F+specified.%0A%0A%2F%2F+Next+hint%3A+There+are+three+places+in+%60read_and_validate%60+that+we+call+a%0A%2F%2F+function+that+returns+a+%60Result%60+%28that+is%2C+the+functions+might+fail%29.%0A%2F%2F+Wrap+those+calls+in+a+%60try%21%60+macro+call+so+that+we+return+immediately+from%0A%2F%2F+%60read_and_validate%60+if+those+function+calls+fail.%0A%0A%2F%2F+Another+hint%3A+under+the+hood%2C+the+%60try%21%60+macro+calls+%60From%3A%3Afrom%60%0A%2F%2F+on+the+error+value+to+convert+it+to+a+boxed+trait+object%2C+a+Box%3Cerror%3A%3AError%3E%2C%0A%2F%2F+which+is+polymorphic--+that+means+that+lots+of+different+kinds+of+errors%0A%2F%2F+can+be+returned+from+the+same+function+because+all+errors+act+the+same%0A%2F%2F+since+they+all+implement+the+%60error%3A%3AError%60+trait.%0A%2F%2F+Check+out+this+section+of+the+book%3A%0A%2F%2F+https%3A%2F%2Fdoc.rust-lang.org%2Fstable%2Fbook%2Ferror-handling.html%23standard-library-traits-used-for-error-handling%0A%0A%2F%2F+Another+another+hint%3A+Note+that+because+the+%60try%21%60+macro+returns%0A%2F%2F+the+*unwrapped*+value+in+the+%60Ok%60+case%2C+if+we+want+to+return+a+%60Result%60+from%0A%2F%2F+%60read_and_validate%60+for+*its*+success+case%2C+we%27ll+have+to+rewrap+a+value%0A%2F%2F+that+we+got+from+the+return+value+of+a+%60try%21%60+call+in+an+%60Ok%60--+this+will%0A%2F%2F+look+like+%60Ok%28something%29%60.%0A%0A%2F%2F+Another+another+another+hint%3A+%60Result%60s+must+be+%22used%22%2C+that+is%2C+you%27ll%0A%2F%2F+get+a+warning+if+you+don%27t+handle+a+%60Result%60+that+you+get+in+your%0A%2F%2F+function.+Read+more+about+that+in+the+%60std%3A%3Aresult%60+module+docs%3A%0A%2F%2F+https%3A%2F%2Fdoc.rust-lang.org%2Fstd%2Fresult%2F%23results-must-be-used%0A) + +### Standard library types + +#### `Arc` + +The [Concurrency](https://doc.rust-lang.org/stable/book/first-edition/concurrency.html) section is relevant. + +- ["arc1.rs"](https://play.rust-lang.org/?code=%2F%2F+arc1.rs%0A%2F%2F+Make+this+code+compile+by+filling+in+a+value+for+%60shared_numbers%60+where+the%0A%2F%2F+TODO+comment+is+and+creating+an+initial+binding+for+%60child_numbers%60%0A%2F%2F+somewhere.+Try+not+to+create+any+copies+of+the+%60numbers%60+Vec%21%0A%2F%2F+Scroll+down+for+hints+%3A%29%0A%0Ause+std%3A%3Async%3A%3AArc%3B%0Ause+std%3A%3Athread%3B%0A%0Afn+main%28%29+%7B%0A++++let+numbers%3A+Vec%3C_%3E+%3D+%280..100u32%29.collect%28%29%3B%0A++++let+shared_numbers+%3D+%2F%2F+TODO%0A++++let+mut+joinhandles+%3D+Vec%3A%3Anew%28%29%3B%0A%0A++++for+offset+in+0..8+%7B%0A++++++++joinhandles.push%28%0A++++++++thread%3A%3Aspawn%28move+%7C%7C+%7B%0A++++++++++++let+mut+i+%3D+offset%3B%0A++++++++++++let+mut+sum+%3D+0%3B%0A++++++++++++while+i+%3C+child_numbers.len%28%29+%7B%0A++++++++++++++++sum+%2B%3D+child_numbers%5Bi%5D%3B%0A++++++++++++++++i+%2B%3D+5%3B%0A++++++++++++%7D%0A++++++++++++println%21%28%22Sum+of+offset+%7B%7D+is+%7B%7D%22%2C+offset%2C+sum%29%3B%0A++++++++%7D%29%29%3B%0A++++%7D%0A++++for+handle+in+joinhandles.into_iter%28%29+%7B%0A++++++++handle.join%28%29.unwrap%28%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Make+%60shared_numbers%60+be+an+%60Arc%60+from+the+numbers+vector.+Then%2C+in+order%0A%2F%2F+to+avoid+creating+a+copy+of+%60numbers%60%2C+you%27ll+need+to+create+%60child_numbers%60%0A%2F%2F+inside+the+loop+but+still+in+the+main+thread.%0A%0A%2F%2F+%60child_numbers%60+should+be+a+clone+of+the+Arc+of+the+numbers+instead+of+a%0A%2F%2F+thread-local+copy+of+the+numbers.%0A) + + +#### 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/stable/book/first-edition/iterators.html) and the [Iterator docs](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html). + +- ["iterator3.rs"](https://play.rust-lang.org/?code=%2F%2F+iterator3.rs%0A%2F%2F+This+is+a+bigger+exercise+than+most+of+the+others%21+You+can+do+it%21%0A%2F%2F+Here+is+your+mission%2C+should+you+choose+to+accept+it%3A%0A%2F%2F+1.+Complete+the+divide+function+to+get+the+first+four+tests+to+pass%0A%2F%2F+2.+Uncomment+the+last+two+tests+and+get+them+to+pass+by+filling+in%0A%2F%2F++++values+for+%60x%60+using+%60division_results%60.%0A%2F%2F+Scroll+down+for+a+minor+hint+for+part+2%2C+and+scroll+down+further+for%0A%2F%2F+a+major+hint.%0A%2F%2F+Have+fun+%3A-%29%0A%0A%23%5Bderive%28Debug%2C+PartialEq%2C+Eq%29%5D%0Apub+enum+DivisionError+%7B%0A++++NotDivisible%28NotDivisibleError%29%2C%0A++++DivideByZero%2C%0A%7D%0A%0A%23%5Bderive%28Debug%2C+PartialEq%2C+Eq%29%5D%0Apub+struct+NotDivisibleError+%7B%0A++++dividend%3A+i32%2C%0A++++divisor%3A+i32%2C%0A%7D%0A%0A%2F%2F+This+function+should+calculate+%60a%60+divided+by+%60b%60+if+%60a%60+is%0A%2F%2F+evenly+divisible+by+b.%0A%2F%2F+Otherwise%2C+it+should+return+a+suitable+error.%0Apub+fn+divide%28a%3A+i32%2C+b%3A+i32%29+-%3E+Result%3Ci32%2C+DivisionError%3E+%7B%0A%7D%0A%0A%23%5Bcfg%28test%29%5D%0Amod+tests+%7B%0A++++use+super%3A%3A*%3B%0A%0A++++%2F%2F+Tests+that+verify+your+%60divide%60+function+implementation%0A++++%23%5Btest%5D%0A++++fn+test_success%28%29+%7B%0A++++++++assert_eq%21%28divide%2881%2C+9%29%2C+Ok%289%29%29%3B%0A++++%7D%0A%0A++++%23%5Btest%5D%0A++++fn+test_not_divisible%28%29+%7B%0A++++++++assert_eq%21%28%0A++++++++++++divide%2881%2C+6%29%2C%0A++++++++++++Err%28DivisionError%3A%3ANotDivisible%28NotDivisibleError%7B%0A++++++++++++++++dividend%3A+81%2C%0A++++++++++++++++divisor%3A+6%0A++++++++++++%7D%29%29%0A++++++++%29%3B%0A++++%7D%0A%0A++++%23%5Btest%5D%0A++++fn+test_divide_by_0%28%29+%7B%0A++++++++assert_eq%21%28divide%2881%2C+0%29%2C+Err%28DivisionError%3A%3ADivideByZero%29%29%3B%0A++++%7D%0A%0A++++%23%5Btest%5D%0A++++fn+test_divide_0_by_something%28%29+%7B%0A++++++++assert_eq%21%28divide%280%2C+81%29%2C+Ok%280%29%29%3B%0A++++%7D%0A%0A++++%2F%2F+Iterator+exercises+using+your+%60divide%60+function%0A++++%2F*%0A++++%23%5Btest%5D%0A++++fn+result_with_list%28%29+%7B%0A++++++++let+numbers+%3D+vec%21%5B27%2C+297%2C+38502%2C+81%5D%3B%0A++++++++let+division_results+%3D+numbers.into_iter%28%29.map%28%7Cn%7C+divide%28n%2C+27%29%29%3B%0A++++++++let+x+%2F%2F...+Fill+in+here%21%0A++++++++assert_eq%21%28format%21%28%22%7B%3A%3F%7D%22%2C+x%29%2C+%22Ok%28%5B1%2C+11%2C+1426%2C+3%5D%29%22%29%3B%0A++++%7D%0A%0A++++%23%5Btest%5D%0A++++fn+list_of_results%28%29+%7B%0A++++++++let+numbers+%3D+vec%21%5B27%2C+297%2C+38502%2C+81%5D%3B%0A++++++++let+division_results+%3D+numbers.into_iter%28%29.map%28%7Cn%7C+divide%28n%2C+27%29%29%3B%0A++++++++let+x+%2F%2F...+Fill+in+here%21%0A++++++++assert_eq%21%28format%21%28%22%7B%3A%3F%7D%22%2C+x%29%2C+%22%5BOk%281%29%2C+Ok%2811%29%2C+Ok%281426%29%2C+Ok%283%29%5D%22%29%3B%0A++++%7D%0A++++*%2F%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Minor+hint%3A+In+each+of+the+two+cases+in+the+match+in+main%2C+you+can+create+x+with+either+a+%27turbofish%27+or+by+hinting+the+type+of+x+to+the+compiler.+You+may+try+both.%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Major+hint%3A+Have+a+look+at+the+Iter+trait+and+at+the+explanation+of+its+collect+function.+Especially+the+part+about+Result+is+interesting.%0A) +- ["iterators4.rs"](https://play.rust-lang.org/?code=%2F%2F+iterators4.rs%0A%0Apub+fn+factorial%28num%3A+u64%29+-%3E+u64+%7B%0A++++%2F%2F+Complete+this+function+to+return+factorial+of+num%0A++++%2F%2F+Do+not+use%3A%0A++++%2F%2F+-+return%0A++++%2F%2F+For+extra+fun+don%27t+use%3A%0A++++%2F%2F+-+imperative+style+loops+%28for%2C+while%29%0A++++%2F%2F+-+additional+variables%0A++++%2F%2F+For+the+most+fun+don%27t+use%3A%0A++++%2F%2F+-+recursion%0A++++%2F%2F+Scroll+down+for+hints.%0A%7D%0A%0A%23%5Bcfg%28test%29%5D%0Amod+tests+%7B%0A++++use+super%3A%3A*%3B%0A%0A++++%23%5Btest%5D%0A++++fn+factorial_of_1%28%29+%7B%0A++++++++assert_eq%21%281%2C+factorial%281%29%29%3B%0A++++%7D%0A++++%23%5Btest%5D%0A++++fn+factorial_of_2%28%29+%7B%0A++++++++assert_eq%21%282%2C+factorial%282%29%29%3B%0A++++%7D%0A%0A++++%23%5Btest%5D%0A++++fn+factorial_of_4%28%29+%7B%0A++++++++assert_eq%21%2824%2C+factorial%284%29%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+In+an+imperative+language+you+might+write+a+for+loop+to+iterate+through%0A%2F%2F+multiply+the+values+into+a+mutable+variable.+Or+you+might+write+code+more%0A%2F%2F+functionally+with+recursion+and+a+match+clause.+But+you+can+also+use+ranges%0A%2F%2F+and+iterators+to+solve+this+in+rust.%0A) + +### Threads + +See [the Dining Philosophers example](https://doc.rust-lang.org/1.4.0/book/first-edition/dining-philosophers.html) and the [Concurrency Chapter](https://doc.rust-lang.org/stable/book/first-edition/concurrency.html) from the book. + +- ["threads1.rs"](https://play.rust-lang.org/?code=%2F%2F+threads1.rs%0A%2F%2F+Make+this+compile%21+Scroll+down+for+hints+%3A%29+The+idea+is+the+thread%0A%2F%2F+spawned+on+line+17+is+completing+jobs+while+the+main+thread+is%0A%2F%2F+monitoring+progress+until+10+jobs+are+completed.+If+you+see+6+lines%0A%2F%2F+of+%22waiting...%22+and+the+program+ends+without+timing+out+the+playground%2C%0A%2F%2F+you%27ve+got+it+%3A%29%0A%0Ause+std%3A%3Async%3A%3AArc%3B%0Ause+std%3A%3Athread%3B%0Ause+std%3A%3Atime%3A%3ADuration%3B%0A%0Astruct+JobStatus+%7B%0A++++jobs_completed%3A+u32%2C%0A%7D%0A%0Afn+main%28%29+%7B%0A++++let+status+%3D+Arc%3A%3Anew%28JobStatus+%7B+jobs_completed%3A+0+%7D%29%3B%0A++++let+status_shared+%3D+status.clone%28%29%3B%0A++++thread%3A%3Aspawn%28move+%7C%7C+%7B%0A++++++++for+_+in+0..10+%7B%0A++++++++++++thread%3A%3Asleep%28Duration%3A%3Afrom_millis%28250%29%29%3B%0A++++++++++++status_shared.jobs_completed+%2B%3D+1%3B%0A++++++++%7D%0A++++%7D%29%3B%0A++++while+status.jobs_completed+%3C+10+%7B%0A++++++++println%21%28%22waiting...+%22%29%3B%0A++++++++thread%3A%3Asleep%28Duration%3A%3Afrom_millis%28500%29%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+%60Arc%60+is+an+Atomic+Reference+Counted+pointer+that+allows+safe%2C+shared+access%0A%2F%2F+to+**immutable**+data.+But+we+want+to+*change*+the+number+of+%60jobs_completed%60%0A%2F%2F+so+we%27ll+need+to+also+use+another+type+that+will+only+allow+one+thread+to%0A%2F%2F+mutate+the+data+at+a+time.+Take+a+look+at+this+section+of+the+book%3A%0A%2F%2F+https%3A%2F%2Fdoc.rust-lang.org%2Fstable%2Fbook%2Fconcurrency.html%23safe-shared-mutable-state%0A%2F%2F+and+keep+scrolling+if+you%27d+like+more+hints+%3A%29%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Do+you+now+have+an+%60Arc%60+%60Mutex%60+%60JobStatus%60+at+the+beginning+of+main%3F+Like%3A%0A%2F%2F+%60let+status+%3D+Arc%3A%3Anew%28Mutex%3A%3Anew%28JobStatus+%7B+jobs_completed%3A+0+%7D%29%29%3B%60%0A%2F%2F+Similar+to+the+code+in+the+example+in+the+book+that+happens+after+the+text%0A%2F%2F+that+says+%22We+can+use+Arc%3CT%3E+to+fix+this.%22.+If+not%2C+give+that+a+try%21+If+you%0A%2F%2F+do+and+would+like+more+hints%2C+keep+scrolling%21%21%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Make+sure+neither+of+your+threads+are+holding+onto+the+lock+of+the+mutex%0A%2F%2F+while+they+are+sleeping%2C+since+this+will+prevent+the+other+thread+from%0A%2F%2F+being+allowed+to+get+the+lock.+Locks+are+automatically+released+when%0A%2F%2F+they+go+out+of+scope.%0A%0A%2F%2F+Ok%2C+so%2C+real+talk%2C+this+was+actually+tricky+for+*me*+to+do+too.+And%0A%2F%2F+I+could+see+a+lot+of+different+problems+you+might+run+into%2C+so+at+this%0A%2F%2F+point+I%27m+not+sure+which+one+you%27ve+hit+%3A%29+Please+see+a+few+possible%0A%2F%2F+answers+on+https%3A%2F%2Fgithub.com%2Fcarols10cents%2Frustlings%2Fissues%2F3+--%0A%2F%2F+mine+is+a+little+more+complicated+because+I+decided+I+wanted+to+see%0A%2F%2F+the+number+of+jobs+currently+done+when+I+was+checking+the+status.%0A%0A%2F%2F+Please+open+an+issue+if+you%27re+still+running+into+a+problem+that%0A%2F%2F+these+hints+are+not+helping+you+with%2C+or+if+you%27ve+looked+at+the+sample%0A%2F%2F+answers+and+don%27t+understand+why+they+work+and+yours+doesn%27t.%0A%0A%2F%2F+If+you%27ve+learned+from+the+sample+solutions%2C+I+encourage+you+to+come%0A%2F%2F+back+to+this+exercise+and+try+it+again+in+a+few+days+to+reinforce%0A%2F%2F+what+you%27ve+learned+%3A%29%0A) + +### Uncategorized + +A few exercises based on things I've encountered or had trouble with getting used to. + +- ["ex1.rs"](https://play.rust-lang.org/?code=%2F%2F+ex1.rs%0A%2F%2F+Make+me+compile%21%0A%0Afn+main%28%29+%7B%0A++++println%28%29%3B%0A%7D%0A) +- ["ex2.rs"](https://play.rust-lang.org/?code=%2F%2F+ex2.rs%0A%2F%2F+Make+me+compile%21%0A%0Afn+something%28%29+-%3E+String+%7B%0A++++%22hi%21%22%0A%7D%0A%0Afn+main%28%29+%7B%0A++++println%21%28%22%7B%7D%22%2C+something%28%29%29%3B%0A%7D%0A) +- ["ex3.rs"](https://play.rust-lang.org/?code=%2F%2F+ex3.rs%0A%2F%2F+Make+me+compile%21%0A%0Astruct+Foo+%7B%0A++++capacity%3A+i32%2C%0A%7D%0A%0Afn+main%28%29+%7B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+Foo+%7B+capacity%3A+3+%7D%29%3B%0A%7D%0A) +- ["ex4.rs"](https://play.rust-lang.org/?code=%2F%2F+ex4.rs%0A%2F%2F+Make+me+compile%21%0A%0Afn+something%28%29+-%3E+Result%3Ci32%2C+std%3A%3Anum%3A%3AParseIntError%3E+%7B%0A++++let+x%3Ai32+%3D+%223%22.parse%28%29%3B%0A++++Ok%28x+*+4%29%0A%7D%0A%0Afn+main%28%29+%7B%0A++++match+something%28%29+%7B%0A++++++++Ok%28..%29+%3D%3E+println%21%28%22You+win%21%22%29%2C%0A++++++++Err%28e%29+%3D%3E+println%21%28%22Oh+no+something+went+wrong%3A+%7B%7D%22%2C+e%29%2C%0A++++%7D%0A%7D%0A) +- ["ex5.rs"](https://play.rust-lang.org/?code=%2F%2F+ex5.rs%0A%2F%2F+Make+me+compile%21%0A%0Aenum+Reaction%3C%27a%3E+%7B%0A++++Sad%28%26%27a+str%29%2C%0A++++Happy%28%26%27a+str%29%2C%0A%7D%0A%0Afn+express%28sentiment%3A+Reaction%29+%7B%0A++++match+sentiment+%7B%0A++++++++Reaction%3A%3ASad%28s%29+%3D%3E+println%21%28%22%3A%28+%7B%7D%22%2C+s%29%2C%0A++++++++Reaction%3A%3AHappy%28s%29+%3D%3E+println%21%28%22%3A%29+%7B%7D%22%2C+s%29%2C%0A++++%7D%0A%7D%0A%0Afn+main+%28%29+%7B%0A++++let+x+%3D+Reaction%3A%3AHappy%28%22It%27s+a+great+day+for+Rust%21%22%29%3B%0A++++express%28x%29%3B%0A++++express%28x%29%3B%0A++++let+y+%3D+Reaction%3A%3ASad%28%22This+code+doesn%27t+compile+yet.%22%29%3B%0A++++express%28y%29%3B%0A%7D%0A) + +## 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?? diff --git a/README.md b/README.md index 15921110..7c0a6e38 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ + + # rustlings Small exercises to get you used to reading and writing Rust code. Includes practice reading and responding to diff --git a/src/bin/generate_readme.rs b/src/bin/generate_readme.rs new file mode 100644 index 00000000..28b6cbde --- /dev/null +++ b/src/bin/generate_readme.rs @@ -0,0 +1,23 @@ +// 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. + +use std::fs::File; +use std::io::prelude::*; + +fn main() { + let template = include_str!("../../README-template.md"); + + let mut generated_readme = File::create("README.md").unwrap(); + write!(generated_readme, "\ + + +").unwrap(); + write!(generated_readme, "{}", template).unwrap(); +}