mirror of
https://github.com/rust-lang/rustlings.git
synced 2024-12-26 00:00:03 +03:00
Compare commits
1001 commits
5f2aff6783
...
e59c65cf45
Author | SHA1 | Date | |
---|---|---|---|
e59c65cf45 | |||
1c27aeead9 | |||
0c79f2ea3e | |||
0e9eb9e87e | |||
0d258b9e96 | |||
d4fa61e435 | |||
554301b8e9 | |||
a55e848359 | |||
2653c3c4d4 | |||
4e4b65711a | |||
89c40ba256 | |||
e56ae6d651 | |||
64b2f18d92 | |||
2894f3c45c | |||
1bae2dcb00 | |||
b540c6df25 | |||
8b476e678a | |||
47f8a0cbe5 | |||
9459eef032 | |||
5aaa8924a6 | |||
4ffce1c297 | |||
0513660b05 | |||
3947c4de28 | |||
664228ef8b | |||
234a61a3ee | |||
83d1275d72 | |||
45abd7d59e | |||
88e10a9e54 | |||
1f624d4c2a | |||
9a25309c1c | |||
2b7caf6fcb | |||
938500fd2f | |||
2d26358602 | |||
9faa5d3aa4 | |||
bcc2a136c8 | |||
dcad002057 | |||
51b8d2ab25 | |||
aa3eda70e5 | |||
2d0860fe1b | |||
17877366b7 | |||
5eb3dee59c | |||
247bd19f93 | |||
e5ed115288 | |||
03baa471d9 | |||
da8b3d143a | |||
20616ff954 | |||
f463cf8662 | |||
e9879eac91 | |||
47148e78a3 | |||
fea917c8f2 | |||
948e16e3c7 | |||
1e7fc46406 | |||
71494264ca | |||
3125561474 | |||
abf1228a0a | |||
547a9d947b | |||
f696d98270 | |||
44ab7f995d | |||
92a1214dcd | |||
388f8da97f | |||
e96623588c | |||
e1e316b931 | |||
c4fd29541b | |||
a8b13f5a82 | |||
86fc573d7a | |||
f82e47f2af | |||
75a38fa38b | |||
ac62a3713c | |||
ea52c99560 | |||
7d4100ed8a | |||
c8d1d9c51f | |||
ab2eb3442e | |||
dbbeb7d4ed | |||
bfa00ffbdc | |||
10eb1a3aee | |||
fd2bf9f6f6 | |||
fc1f9f0124 | |||
789492d1a9 | |||
afc320bed4 | |||
cba4a6f9c8 | |||
5556d42b46 | |||
7d2bc1c7a4 | |||
c209c874a9 | |||
dd52e9cd72 | |||
0f71a150ff | |||
74388d4bf4 | |||
e811dd15b5 | |||
f22700a4ec | |||
ee25a7d458 | |||
594e212b8a | |||
5c355468c1 | |||
d1571d18f9 | |||
cb86b44dea | |||
833e6e0c92 | |||
159273e532 | |||
631f2db1a3 | |||
a1f0eaab54 | |||
b1898f6d8b | |||
d29e9e7e07 | |||
360605e284 | |||
64772544fa | |||
5f4875e2ba | |||
fd2a8c01cb | |||
b6129ad081 | |||
28d0b0a21e | |||
b779c43126 | |||
4e12725616 | |||
570bc9f32d | |||
47976caa69 | |||
f1abd8577c | |||
423b50b068 | |||
bedf0789f2 | |||
a2d1cb3b22 | |||
e7ba88f905 | |||
50f6e5232e | |||
8854f0a5ed | |||
13cc3acdfd | |||
5b7368c46d | |||
27999f2d26 | |||
e74f2a4274 | |||
d141a73493 | |||
631f44331e | |||
b01fddef8b | |||
78a8553f1c | |||
b70c1abd7c | |||
71f31d74bc | |||
72e557b3a9 | |||
3eaccbb61a | |||
b678bd8ed2 | |||
2baa140615 | |||
e760f07767 | |||
ca5d5f0a49 | |||
69b4fd49fc | |||
36f315c344 | |||
8016f5ca2d | |||
8ef2ff1257 | |||
6ce31defb6 | |||
0b3ad9141b | |||
c903db5c53 | |||
8a038b946c | |||
ed9740b72c | |||
ce3dcc9856 | |||
4472d50eba | |||
a1d5702ba0 | |||
52a231ce2f | |||
16af981772 | |||
fc141b8dfc | |||
82ebd29ff6 | |||
f5737b5a49 | |||
55e68d2c63 | |||
479f45da9b | |||
140c4e4812 | |||
337460d299 | |||
e41c3a7c92 | |||
1b9faa4d61 | |||
9f9a754a64 | |||
f7b0cfe8d1 | |||
4ce8667b9d | |||
0785b24192 | |||
34f02cf83d | |||
8b43d79257 | |||
dc086c6bf1 | |||
dc0ffbe16e | |||
8df66f7991 | |||
39580381fa | |||
06a0f278e5 | |||
fd97470f35 | |||
11fc3f1e56 | |||
693bb708b2 | |||
97719fe8da | |||
4933ace50b | |||
81bf0a6430 | |||
24aed1b14e | |||
09c3ac02f8 | |||
45a39585b3 | |||
286a455fa9 | |||
bdf4960b6a | |||
13124aafe3 | |||
2128be8b28 | |||
175294fa5d | |||
5016c7cf7c | |||
1468206052 | |||
d1ff4b5cf0 | |||
700a065abd | |||
3fc462f90f | |||
65a8f6bb4b | |||
e0f0944bff | |||
c7590dd752 | |||
33a5680328 | |||
455d87cadd | |||
e65ae09789 | |||
dacdce1ea2 | |||
766f3c50ec | |||
802b97b2ed | |||
2ad408f2b8 | |||
c8fddd8f62 | |||
74fab994e2 | |||
3a99542f73 | |||
2ae9f3555b | |||
1937b4bf66 | |||
8beb290842 | |||
8fec5155c7 | |||
3f49decce9 | |||
e2492f65a0 | |||
5116a812fb | |||
82409c060f | |||
183ed3f88f | |||
447ac3c40b | |||
96f96927da | |||
2c79e29483 | |||
362473dde0 | |||
8339682112 | |||
3f06d767b5 | |||
2854dc9ab3 | |||
516fcf9168 | |||
12d1971b0d | |||
3e09e509d6 | |||
99fb11cc72 | |||
d176ddd27e | |||
0847b3a4bf | |||
6d2ea8dae3 | |||
47ba4502e0 | |||
6263cb6456 | |||
d7024d80ce | |||
59d6b852af | |||
e512928df5 | |||
a38029e3e7 | |||
b12b652a57 | |||
c793416495 | |||
01343f187b | |||
69021e1497 | |||
08c408aae0 | |||
bf698659b0 | |||
2d5d70693a | |||
a4091ade5c | |||
a7a881809f | |||
0f4cb94cfe | |||
6469e9734b | |||
5372caefb3 | |||
9d7b973a62 | |||
a5f221aa39 | |||
e764b75aef | |||
708cfef3f7 | |||
01b8432d58 | |||
9b5b652c71 | |||
981a4778a9 | |||
5d4363d58d | |||
48697b8225 | |||
1652bb67d9 | |||
1499f681a3 | |||
a21fa6ff40 | |||
186dc3c1ab | |||
6b7a27d080 | |||
c9017f9f7a | |||
fdada8b3d4 | |||
9e2ff7d037 | |||
65834fc420 | |||
f5a4965de7 | |||
db5911eb73 | |||
2f4e63b443 | |||
584164a6ff | |||
e6f6d26d13 | |||
67d8d5848c | |||
43d15f09f0 | |||
7123c7ae3a | |||
4d9c346a17 | |||
deed9d3943 | |||
652f0c7676 | |||
e479ec8fb6 | |||
a33501e6a7 | |||
47f8199a99 | |||
4bf0ddc0e1 | |||
4cd0ccce83 | |||
a3657188b6 | |||
b8fcd11286 | |||
4810555038 | |||
84b291852c | |||
74831dd88f | |||
0b220f9fff | |||
d3cdeed871 | |||
0524632199 | |||
30d5b7db92 | |||
2f60f4d9ea | |||
b017b87866 | |||
b87aa98634 | |||
a4c07ca948 | |||
b8826dd3b3 | |||
d54c050985 | |||
248dd4415e | |||
dec6772b05 | |||
b4f4c79ac4 | |||
c1d5252b87 | |||
0f71e12235 | |||
fa6b7d77b2 | |||
a72c26bdc3 | |||
fe3292c170 | |||
ad66fe0074 | |||
df64893f2b | |||
e5bc8588e0 | |||
23bc5d23fe | |||
28d2bb0432 | |||
1c010a129e | |||
f5ce4cf0a5 | |||
ff3e6c05a5 | |||
33dfe5331a | |||
888ad35d10 | |||
fa452b3a93 | |||
2f8fa469ac | |||
d3a0c26999 | |||
95f10c8068 | |||
9bb174e96e | |||
4c5573b09f | |||
43eb014026 | |||
2d792651ea | |||
6cf75d569b | |||
67ce9b9e56 | |||
bcebbb9df6 | |||
bdd76cdf77 | |||
825637f32c | |||
8ef5d10da2 | |||
5217cdc5e2 | |||
e3c8c457ba | |||
cddaf4881e | |||
428d64ffa0 | |||
09c94bef2d | |||
a0e810b471 | |||
78728d5238 | |||
cc2c0958c9 | |||
4cb15a4cda | |||
9845e046de | |||
cf90364fd7 | |||
a13e3cd07f | |||
dfa2b44f71 | |||
b000164eed | |||
663a03a17b | |||
a943f5ba32 | |||
f3842aa746 | |||
18a9a2e791 | |||
61c7eaed62 | |||
2dcf917fa1 | |||
f53d458920 | |||
2af437fd90 | |||
56a9197f55 | |||
eddbb97934 | |||
4f71f74b44 | |||
cf9041c0e4 | |||
746cf6863d | |||
803e32dad2 | |||
a4f8826301 | |||
6187216606 | |||
275a854d6e | |||
7efccc36b4 | |||
64c2de95ca | |||
c170740423 | |||
45cfe86fb0 | |||
db4d649e55 | |||
c0452d160b | |||
b4b7ae63ad | |||
c07209b635 | |||
091e1e7f7a | |||
92f249a52c | |||
e6228e92b4 | |||
3e9c4c8bb8 | |||
22b650c092 | |||
f0849447ad | |||
789223cc9e | |||
de3f846a53 | |||
46121b71cf | |||
b1daea1fe8 | |||
129884aff7 | |||
720b280bc1 | |||
9b7a5c041e | |||
c46d8bdf95 | |||
050a23ce67 | |||
2afe6b38d3 | |||
097f3c74ea | |||
25b5686dd2 | |||
a91888e79e | |||
c31e15c4cf | |||
1694682aa4 | |||
29bcb282da | |||
f1bd444792 | |||
fbc226a510 | |||
5baa503bfc | |||
0cd96afe63 | |||
3d540ed946 | |||
98cd00de63 | |||
ecbe9b7324 | |||
879f0cd5c6 | |||
613ec23f84 | |||
f574905b8e | |||
bd63ece47c | |||
2901d85662 | |||
020711fa97 | |||
a2dfbd86da | |||
d6fd251a73 | |||
1264510fc0 | |||
ef842d3a94 | |||
d768353806 | |||
e4dbbbf5f5 | |||
42b5c0a1f7 | |||
fd558065c7 | |||
68142aff7f | |||
946c29679e | |||
6a79ada7f2 | |||
835ec72622 | |||
a9f0c7bf1f | |||
1ede3a82e9 | |||
0abcdeed42 | |||
532c9ebb30 | |||
2a1bc53771 | |||
5bf8d1fa1b | |||
2ff1813746 | |||
42a3503906 | |||
98db579014 | |||
0338b1cbdf | |||
e1051724c3 | |||
0e4136d31e | |||
f8d38320cd | |||
42bd0b8b75 | |||
08ac11ff22 | |||
6ae4a979f4 | |||
a3ada0eee8 | |||
50530fa3cf | |||
611f9d8722 | |||
8e9c99ae5b | |||
c324ea10df | |||
1984a8d38e | |||
84a818dbda | |||
d140d49b61 | |||
beb7b24e8e | |||
5337620476 | |||
990c68efcb | |||
8d4145038d | |||
f2c3dcab3a | |||
73e84f8379 | |||
eafb157d60 | |||
7cdf6b7942 | |||
c8ad6c3960 | |||
3bb71c6b0c | |||
d0b843d6c4 | |||
0f4c42d54e | |||
bde2524c3b | |||
cf3f6fd6a1 | |||
c8481d35c1 | |||
96a44f3dcf | |||
0ae66d1860 | |||
700605ff35 | |||
a67e63cce0 | |||
d48e86b154 | |||
39a19f9450 | |||
2dfc7cdb1a | |||
0add5ac240 | |||
5a1d95028c | |||
e80e91faf2 | |||
4ae3fcc3ca | |||
17a2d42ffd | |||
a7bc6d53a5 | |||
56eb4a5d65 | |||
f6cf6c611c | |||
7a74a72dc8 | |||
a4da216a5c | |||
8b2d9ed503 | |||
d2b5906be2 | |||
f9e35a4344 | |||
0525739046 | |||
11fda5d70f | |||
c7a18b0781 | |||
01a78531ad | |||
c2414b8891 | |||
f03020a7e2 | |||
01509a2a84 | |||
66b3a9cdd7 | |||
baca8c9667 | |||
d9df809838 | |||
da9f97b0e0 | |||
2d0497bf3b | |||
5e7afce019 | |||
74180ba1cc | |||
d425dbe203 | |||
32415e1e6c | |||
8e178ac60d | |||
3ae6c208b2 | |||
563727f47f | |||
2b7ac91505 | |||
52c0f5b39e | |||
fef66b80ad | |||
b6f40f2ec8 | |||
8c3b8dcec4 | |||
7f73219041 | |||
196d3c1a98 | |||
8c60ac267e | |||
3c7e7368b2 | |||
593f0e0916 | |||
1508938fed | |||
881d3e9441 | |||
aedeff8b24 | |||
75e2804c83 | |||
c45d2c3255 | |||
ea40804371 | |||
ee2b772dd5 | |||
62a2c1a6d9 | |||
de0befef9c | |||
5658998c0c | |||
89e0f64279 | |||
edea76b5b9 | |||
016e6a014e | |||
cdeb8ce229 | |||
12504b01e9 | |||
c3a92b1248 | |||
181c81f016 | |||
cb7ce006b5 | |||
2150d629b1 | |||
c82c367324 | |||
dc5c72bc19 | |||
0ce5d9d4d7 | |||
37fcbeb596 | |||
2f071c97b0 | |||
9664f4357c | |||
74ae506603 | |||
2965867338 | |||
e63e668d86 | |||
b7289e59aa | |||
be4dfe8be0 | |||
e230ffcf03 | |||
0d7b036137 | |||
078142c43c | |||
5920a58e83 | |||
aaea5b490f | |||
8d45cdb09d | |||
a4e623ea94 | |||
5595e1c397 | |||
ca41f9e2df | |||
177e2870c5 | |||
3ce3235294 | |||
c51f1b3f31 | |||
8bf8b19a5d | |||
6d1d42d2dd | |||
212c82c6f6 | |||
fcefa3d614 | |||
b3b4b7d59c | |||
29abaee4ec | |||
c7c8d99680 | |||
c1d28b502e | |||
14fe248b4b | |||
88f27a5377 | |||
1f1a62d83e | |||
428998a4cf | |||
d26f47dddd | |||
2af0cd9cce | |||
f92d45fa68 | |||
67fa017742 | |||
d8c2ab8349 | |||
0df0be8352 | |||
8ebd2f9df2 | |||
4ef345e706 | |||
0a2d4dae5a | |||
71053101c3 | |||
53fdb9044d | |||
8a085a0a85 | |||
edf5762612 | |||
ef02c6c6ab | |||
e4ee2cd548 | |||
b77007887c | |||
2dac8e509b | |||
e5a19a4c33 | |||
5349f0e8d4 | |||
ad8e544483 | |||
86684b7fc9 | |||
4ce2714da1 | |||
e93a99e19e | |||
61a84a2c11 | |||
30040d7778 | |||
e3b9124b85 | |||
642c3bd37e | |||
49e4a1fab0 | |||
04d36996dd | |||
f1a60780b9 | |||
d83c91edc6 | |||
ea504e6bf1 | |||
a2be6754bf | |||
daa090981a | |||
aaf183142e | |||
7525ecd8c1 | |||
09d8bc83ff | |||
cc35a8431f | |||
819dea2500 | |||
01e6732e4d | |||
f04089b8bc | |||
2566f9aaf6 | |||
1eac00e89a | |||
2e9b9a9f13 | |||
9f5be60b40 | |||
d64836f317 | |||
634e17a5ab | |||
2f810a4da6 | |||
cb9f1ac9ce | |||
d83cc69afe | |||
d6bb27ec20 | |||
d42a6e7415 | |||
b9167e9299 | |||
28ec0f864a | |||
7005d8a400 | |||
7f433ae28f | |||
a2506f154b | |||
501b973c25 | |||
4eec81a113 | |||
9a13bccd63 | |||
30636e7cf3 | |||
67a15ef27f | |||
d322bcfcec | |||
0ac5aa7af2 | |||
f9be652b3b | |||
932f6b53a9 | |||
4d9eb35ad7 | |||
86d716cf8a | |||
87db9129bc | |||
6566c5904f | |||
aa813fbce1 | |||
d1ebbaa6f6 | |||
c07cf5bffe | |||
df448c069c | |||
25e7696565 | |||
92777c0a44 | |||
7ebc260924 | |||
f5eaa578b9 | |||
6f04570dd0 | |||
15ca847c37 | |||
c613b70363 | |||
dc02c38a94 | |||
7526c6b1f9 | |||
1cbabc3d28 | |||
bd10b154fe | |||
070a780d7f | |||
8aef915ee7 | |||
3da860927d | |||
1c90575b9f | |||
9dcc4b7df5 | |||
9831cbb139 | |||
bee62c89de | |||
5c0073a948 | |||
2a26dfcb00 | |||
24539666af | |||
757723a7e8 | |||
ff4c752984 | |||
06d1089714 | |||
6e827da570 | |||
279ebdc153 | |||
9b0eeb815a | |||
44824718b2 | |||
8bd03093eb | |||
d5a6dee1b3 | |||
a534de0312 | |||
98c5088a39 | |||
6807e63c5f | |||
2a95a3e966 | |||
1e3745ccdf | |||
d8160f9113 | |||
6494a8c50b | |||
864cfa725b | |||
e79bc727f0 | |||
2e1a87d7d3 | |||
f53a0e8700 | |||
470dc65956 | |||
686143100f | |||
c3933904f6 | |||
65849629f5 | |||
fa1f239a70 | |||
4bb6bda9f6 | |||
256c4013b7 | |||
27e9520665 | |||
b3642b0219 | |||
193e0a03b2 | |||
a59acf8835 | |||
62e92476e6 | |||
6255efe8b2 | |||
a46d66134b | |||
f034899c7f | |||
c9a5fa6097 | |||
d1a965f019 | |||
533a009257 | |||
4a80bf6441 | |||
c8d217ad50 | |||
a8ddc07a9a | |||
af85f2036c | |||
ff6c15f9c1 | |||
4110ae21af | |||
b15e0a279b | |||
787bec9875 | |||
f0ce2c1afa | |||
850c1d0234 | |||
ee7d976283 | |||
258ff6f462 | |||
95a3fe17fa | |||
501861e435 | |||
f3890cbae6 | |||
f714534393 | |||
d0fcd8ae8a | |||
7c46e7ac69 | |||
1db5de9653 | |||
b5fc06bd56 | |||
7c4d33654f | |||
05729b27a0 | |||
0bf3f7e01f | |||
bd5503a0d3 | |||
25e855a009 | |||
c2501ae733 | |||
3a4f2bebb4 | |||
394ca402a8 | |||
db25cc9157 | |||
93f8d1610d | |||
99c9ab467b | |||
db43efe3ec | |||
9a4ee47c52 | |||
0a674a158d | |||
3bd26c7a24 | |||
8c31d38fa1 | |||
d988054ad8 | |||
2db86833a9 | |||
b0a4750624 | |||
4f69285375 | |||
e640b4a1ff | |||
7f5a18fa34 | |||
c4897139ae | |||
372290a796 | |||
729385362c | |||
f6db88aca8 | |||
0819bbe21f | |||
18342b3aa3 | |||
c2daad8340 | |||
de9a0ed522 | |||
06e7216c83 | |||
60155294e9 | |||
3f2d41de9e | |||
b0f19fd862 | |||
0bf51c6a0d | |||
1d2c2cffd2 | |||
157fe016e5 | |||
5a233398eb | |||
919ba88413 | |||
445441ce25 | |||
34375b2ebf | |||
9ea744a710 | |||
2b6f9fb6a7 | |||
8c8f30d8ce | |||
b6c434c445 | |||
569a68eb73 | |||
1885ece2dc | |||
459c52137a | |||
190945352a | |||
def8d2c569 | |||
fdd7de00bd | |||
2f30eac27f | |||
14f3585816 | |||
8ad18de54c | |||
7560aec66b | |||
fb32d0b86f | |||
7090fffeae | |||
c1de4d46aa | |||
82b563f165 | |||
9cb25e16f9 | |||
ca07abf3dc | |||
b711dd692a | |||
1e1f031713 | |||
b5e17c965d | |||
23f0fae1c8 | |||
79ca821e26 | |||
fe7d775818 | |||
4e59857228 | |||
c2b7f45806 | |||
c6597d0010 | |||
1a4f55e0e6 | |||
30273a6ee5 | |||
8e3cc9d70c | |||
2b01811fe9 | |||
a561a0f7f0 | |||
36a8e3ac0e | |||
0f18d599e9 | |||
3959570221 | |||
3ff9b0cd2a | |||
5b4103bbac | |||
d5ed749e9f | |||
39bdd086a7 | |||
dd025391f2 | |||
e5efc68a91 | |||
62afbb034f | |||
9691c3cb55 | |||
24cb4a3bc9 | |||
0888952cb9 | |||
b8437bea73 | |||
842e341895 | |||
3df59379de | |||
58b03af587 | |||
5652862b23 | |||
9895c1f9bd | |||
4e7f9ca1b3 | |||
c7cf3720bd | |||
d2996b4cc6 | |||
19675008c8 | |||
4937cb5b7c | |||
7b20ca9d04 | |||
217c6d42fb | |||
fb8dd57d1f | |||
669adbeb60 | |||
dd72429af4 | |||
971e7f94dc | |||
92183a74c4 | |||
e7bb832bf3 | |||
34d04139cd | |||
c4d434a2b4 | |||
76764633b4 | |||
8e87c35c88 | |||
45a1a74559 | |||
b24f256f2a | |||
864d046058 | |||
a27741b131 | |||
b13bafa13e | |||
f995b4c041 | |||
b8a5886db4 | |||
b9d2756ce8 | |||
07dec76f7c | |||
deeefcf16c | |||
8e0f7e56f7 | |||
87ca05b4bb | |||
d69a8a7045 | |||
87001a68c0 | |||
a610fc1bc2 | |||
e89028581c | |||
980ffa2a2b | |||
1f2029ae55 | |||
ed0fcf8e3d | |||
f36efae25d | |||
853d0593d0 | |||
078f6ffc1c | |||
7a6f71f090 | |||
a158c77d81 | |||
8ddbf9635d | |||
8d3ec24c11 | |||
a5ba44bd6a | |||
f5135ae4df | |||
87e55ccffd | |||
d911586788 | |||
b932ed1f67 | |||
dca3ea355e | |||
d095a307dd | |||
51712cc19f | |||
efa9f57048 | |||
b3aef377be | |||
e4520602f5 | |||
83cd91ccca | |||
51b4c240ed | |||
bdf826a026 | |||
c0c112985b | |||
f205ee3d4c | |||
e1375ef431 | |||
0aeaccc3a5 | |||
01b7d6334c | |||
a325df55d1 | |||
27fa7c3e4a | |||
0d93266462 | |||
3dce7e5696 | |||
e276c12192 | |||
eb952a480d | |||
f2833c5279 | |||
9c6f56b836 | |||
f3fdb07507 | |||
1fe32a7ff2 | |||
71700c506c | |||
18d0f3411f | |||
e1fa6cf30b | |||
a07172a069 | |||
32d2c38aa2 | |||
80388c042b | |||
c723bcd594 | |||
d4233f8166 | |||
60f44cc509 | |||
14ca4e8197 | |||
ae69f423cd | |||
d8ecf4bc2d | |||
3eabf2aafc | |||
02acf83e99 | |||
d53ae18918 | |||
0d37f9011c | |||
244ec8fbf2 | |||
57984ae9f3 | |||
1e69e67997 | |||
1c3b129a53 | |||
a449d39bdc | |||
34df327d2a | |||
b7b74910d8 | |||
b7add6a1a8 | |||
ce5df2d84b | |||
76acf613c5 | |||
2966a29449 | |||
c01ddbc747 | |||
f8f627b6f7 | |||
c3f1183815 | |||
f08fd02f33 | |||
8d1258f26a | |||
4304b3981e | |||
31e7920cee | |||
6fb45305f8 | |||
9cf5a2f83f | |||
3d6b5e8102 | |||
8c5d091513 | |||
91df875847 | |||
1ac392a551 | |||
3f0dc81a9c | |||
44ef58be43 | |||
803e0a4fbb | |||
62b435a309 | |||
fe28feba1e | |||
cc27966980 | |||
6b0a2ff0d0 | |||
b0c50b3bc7 | |||
4c51cb0909 | |||
032e3c9f30 | |||
9bae712453 | |||
b057e09156 | |||
0d5c105c15 | |||
fe698d9096 | |||
c54ec23b9e | |||
6f1d309308 | |||
6f88dd437e | |||
557bbe2b85 | |||
32c19c2e47 | |||
27d1a31eb6 | |||
3c6c29e19e | |||
2b97faa1d3 | |||
17ee0e3c7a | |||
c46a711526 | |||
098ff228d7 | |||
f5e9db90cc | |||
36db08340d | |||
2fb135026c | |||
77903200a0 | |||
e424e9f6c7 | |||
11f0fd7fd9 | |||
547f3ac835 | |||
373676a576 | |||
9bda8598e1 | |||
19b5e24d5c | |||
1da82a0eab | |||
75ee0e4245 | |||
53c40024d8 | |||
bcb192c707 | |||
6072ec16a0 | |||
b70ed105db | |||
8d0aa11a35 | |||
e2674498c6 | |||
3200581d4d | |||
6afc4840b4 | |||
93aef73eb5 | |||
5453fad991 | |||
f35f63fa57 | |||
88b583f2bb | |||
8863855627 | |||
5bbdb3d5ba | |||
9f4b5566db | |||
f97f4bc4f1 | |||
3e7f1e3ff2 | |||
4b80097817 | |||
7f530ebf20 | |||
11e74147ae | |||
5d78a2f103 | |||
194e0b951d | |||
369a3d3678 | |||
21b1e6ecf8 | |||
12d1bf407a | |||
5c4821ac6f | |||
8bfe2ec71e | |||
adf7d1b975 | |||
14e423fe53 | |||
a49f231b5d | |||
70f472484f | |||
77b687d501 | |||
0f629a47a5 | |||
f01f2d13c7 | |||
3461c4f73d | |||
4d6cd0ebb4 | |||
3080141c5f | |||
bc3808cf29 | |||
761fced786 | |||
706e075908 | |||
a13c7b0ae3 | |||
dad2216984 | |||
7e12aaa24a | |||
6e7f1f5f07 | |||
e0904de6ea | |||
4ecc35131c | |||
22838ba227 | |||
3b34167924 | |||
cb47760978 | |||
fb327612f8 | |||
7e16e7721a | |||
3181d9f3f8 | |||
02b1b5f6ab | |||
9de432e6bf | |||
24f819d823 | |||
13837b25cf | |||
2ac6606c6c |
2509
.all-contributorsrc
2509
.all-contributorsrc
File diff suppressed because it is too large
Load diff
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/universal:2-linux",
|
|
||||||
"waitFor": "onCreateCommand",
|
|
||||||
"onCreateCommand": ".devcontainer/setup.sh",
|
|
||||||
"updateContentCommand": "cargo build",
|
|
||||||
"postCreateCommand": "",
|
|
||||||
"postAttachCommand": {
|
|
||||||
"server": "rustlings watch"
|
|
||||||
},
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"rust-lang.rust-analyzer"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
curl https://sh.rustup.rs -sSf | sh -s -- -y
|
|
||||||
|
|
||||||
# Update current shell environment variables after install to find rustup
|
|
||||||
. "$HOME/.cargo/env"
|
|
||||||
rustup install stable
|
|
||||||
bash install.sh
|
|
32
.github/workflows/rust.yml
vendored
32
.github/workflows/rust.yml
vendored
|
@ -2,36 +2,42 @@ name: Rustlings Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ main ]
|
branches: [main]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ main ]
|
branches: [main]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
clippy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: cargo clippy -- --deny warnings
|
||||||
fmt:
|
fmt:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: DavidAnson/markdownlint-cli2-action@v16
|
||||||
with:
|
|
||||||
components: rustfmt
|
|
||||||
- uses: DavidAnson/markdownlint-cli2-action@v9
|
|
||||||
with:
|
with:
|
||||||
globs: "exercises/**/*.md"
|
globs: "exercises/**/*.md"
|
||||||
- name: Run cargo fmt
|
- name: Run cargo fmt
|
||||||
run: |
|
run: cargo fmt --all --check
|
||||||
cargo fmt --all -- --check
|
|
||||||
test:
|
test:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
- uses: swatinem/rust-cache@v2
|
- uses: swatinem/rust-cache@v2
|
||||||
- name: Run cargo test
|
- name: Run cargo test
|
||||||
run: |
|
run: cargo test --workspace
|
||||||
cargo test
|
dev-check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: swatinem/rust-cache@v2
|
||||||
|
- name: Run rustlings dev check
|
||||||
|
run: cargo run -- dev check --require-solutions
|
||||||
|
|
3
.github/workflows/web.yml
vendored
3
.github/workflows/web.yml
vendored
|
@ -54,10 +54,9 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
# Setup
|
# Setup
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
- uses: swatinem/rust-cache@v2
|
- uses: swatinem/rust-cache@v2
|
||||||
|
|
||||||
# If you use any mdbook plugins, here's the place to install them!
|
# If you use any mdbook plugins, here's the place to install them!
|
||||||
|
|
33
.gitignore
vendored
33
.gitignore
vendored
|
@ -1,18 +1,23 @@
|
||||||
*.swp
|
# Cargo
|
||||||
target/
|
target/
|
||||||
**/*.rs.bk
|
Cargo.lock
|
||||||
.DS_Store
|
!/Cargo.lock
|
||||||
*.pdb
|
|
||||||
exercises/clippy/Cargo.toml
|
# State file
|
||||||
exercises/clippy/Cargo.lock
|
.rustlings-state.txt
|
||||||
rust-project.json
|
|
||||||
.idea
|
# oranda
|
||||||
.vscode/*
|
|
||||||
!.vscode/extensions.json
|
|
||||||
*.iml
|
|
||||||
*.o
|
|
||||||
public/
|
public/
|
||||||
|
.netlify
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
.direnv/
|
.direnv/
|
||||||
|
|
||||||
# Local Netlify folder
|
# Editor
|
||||||
.netlify
|
*.swp
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# Ignore file for editors like Helix
|
||||||
|
.ignore
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
tasks:
|
|
||||||
- init: /workspace/rustlings/install.sh
|
|
||||||
command: /workspace/.cargo/bin/rustlings watch
|
|
||||||
|
|
||||||
vscode:
|
|
||||||
extensions:
|
|
||||||
- rust-lang.rust-analyzer@0.3.1348
|
|
7
.typos.toml
Normal file
7
.typos.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[default.extend-words]
|
||||||
|
"earch" = "earch" # Because of <s>earch in the list footer
|
||||||
|
|
||||||
|
[files]
|
||||||
|
extend-exclude = [
|
||||||
|
"CHANGELOG.md",
|
||||||
|
]
|
5
.vscode/extensions.json
vendored
5
.vscode/extensions.json
vendored
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"rust-lang.rust-analyzer"
|
|
||||||
]
|
|
||||||
}
|
|
365
AUTHORS.md
365
AUTHORS.md
|
@ -1,365 +0,0 @@
|
||||||
## Authors
|
|
||||||
|
|
||||||
This file lists the people that have contributed to this project.
|
|
||||||
|
|
||||||
Excluded from this list are @carols10cents and @diannasoreil, the principal
|
|
||||||
authors.
|
|
||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
||||||
<!-- prettier-ignore-start -->
|
|
||||||
<!-- markdownlint-disable -->
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://carol-nichols.com"><img src="https://avatars2.githubusercontent.com/u/193874?v=4?s=100" width="100px;" alt="Carol (Nichols || Goulding)"/><br /><sub><b>Carol (Nichols || Goulding)</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=carols10cents" title="Code">💻</a> <a href="#content-carols10cents" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://twitter.com/QuietMisdreavus"><img src="https://avatars2.githubusercontent.com/u/5217170?v=4?s=100" width="100px;" alt="QuietMisdreavus"/><br /><sub><b>QuietMisdreavus</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=QuietMisdreavus" title="Code">💻</a> <a href="#content-QuietMisdreavus" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/robertlugg"><img src="https://avatars0.githubusercontent.com/u/6054540?v=4?s=100" width="100px;" alt="Robert M Lugg"/><br /><sub><b>Robert M Lugg</b></sub></a><br /><a href="#content-robertlugg" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://hynek.me/about/"><img src="https://avatars3.githubusercontent.com/u/41240?v=4?s=100" width="100px;" alt="Hynek Schlawack"/><br /><sub><b>Hynek Schlawack</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=hynek" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://spacekookie.de"><img src="https://avatars0.githubusercontent.com/u/7669898?v=4?s=100" width="100px;" alt="Katharina Fey"/><br /><sub><b>Katharina Fey</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=spacekookie" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/lukabavdaz"><img src="https://avatars0.githubusercontent.com/u/9624558?v=4?s=100" width="100px;" alt="lukabavdaz"/><br /><sub><b>lukabavdaz</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=lukabavdaz" title="Code">💻</a> <a href="#content-lukabavdaz" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://vestera.as"><img src="https://avatars2.githubusercontent.com/u/4187449?v=4?s=100" width="100px;" alt="Erik Vesteraas"/><br /><sub><b>Erik Vesteraas</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=evestera" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Delet0r"><img src="https://avatars1.githubusercontent.com/u/23195618?v=4?s=100" width="100px;" alt="delet0r"/><br /><sub><b>delet0r</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Delet0r" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://phinary.ca"><img src="https://avatars1.githubusercontent.com/u/10522375?v=4?s=100" width="100px;" alt="Shaun Bennett"/><br /><sub><b>Shaun Bennett</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=shaunbennett" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/abagshaw"><img src="https://avatars2.githubusercontent.com/u/8594541?v=4?s=100" width="100px;" alt="Andrew Bagshaw"/><br /><sub><b>Andrew Bagshaw</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=abagshaw" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://ai6ua.net/"><img src="https://avatars2.githubusercontent.com/u/175578?v=4?s=100" width="100px;" alt="Kyle Isom"/><br /><sub><b>Kyle Isom</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=kisom" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ColinPitrat"><img src="https://avatars3.githubusercontent.com/u/1541863?v=4?s=100" width="100px;" alt="Colin Pitrat"/><br /><sub><b>Colin Pitrat</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=ColinPitrat" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://zacanger.com"><img src="https://avatars3.githubusercontent.com/u/12520493?v=4?s=100" width="100px;" alt="Zac Anger"/><br /><sub><b>Zac Anger</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=zacanger" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/mgeier"><img src="https://avatars1.githubusercontent.com/u/705404?v=4?s=100" width="100px;" alt="Matthias Geier"/><br /><sub><b>Matthias Geier</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=mgeier" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/cjpearce"><img src="https://avatars1.githubusercontent.com/u/3453268?v=4?s=100" width="100px;" alt="Chris Pearce"/><br /><sub><b>Chris Pearce</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=cjpearce" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://yvan-sraka.github.io"><img src="https://avatars2.githubusercontent.com/u/705213?v=4?s=100" width="100px;" alt="Yvan Sraka"/><br /><sub><b>Yvan Sraka</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=yvan-sraka" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/dendi239"><img src="https://avatars3.githubusercontent.com/u/16478650?v=4?s=100" width="100px;" alt="Denys Smirnov"/><br /><sub><b>Denys Smirnov</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=dendi239" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/eddyp"><img src="https://avatars2.githubusercontent.com/u/123772?v=4?s=100" width="100px;" alt="eddyp"/><br /><sub><b>eddyp</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=eddyp" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://about.me/BrianKung"><img src="https://avatars1.githubusercontent.com/u/2836167?v=4?s=100" width="100px;" alt="Brian Kung"/><br /><sub><b>Brian Kung</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=briankung" title="Code">💻</a> <a href="#content-briankung" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://rcousineau.gitlab.io"><img src="https://avatars3.githubusercontent.com/u/281039?v=4?s=100" width="100px;" alt="Russell"/><br /><sub><b>Russell</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=miller-time" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://danwilhelm.com"><img src="https://avatars3.githubusercontent.com/u/6137185?v=4?s=100" width="100px;" alt="Dan Wilhelm"/><br /><sub><b>Dan Wilhelm</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=danwilhelm" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Jesse-Cameron"><img src="https://avatars3.githubusercontent.com/u/3723654?v=4?s=100" width="100px;" alt="Jesse"/><br /><sub><b>Jesse</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Jesse-Cameron" title="Code">💻</a> <a href="#content-Jesse-Cameron" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/MrFroop"><img src="https://avatars3.githubusercontent.com/u/196700?v=4?s=100" width="100px;" alt="Fredrik Jambrén"/><br /><sub><b>Fredrik Jambrén</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=MrFroop" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/petemcfarlane"><img src="https://avatars3.githubusercontent.com/u/3472717?v=4?s=100" width="100px;" alt="Pete McFarlane"/><br /><sub><b>Pete McFarlane</b></sub></a><br /><a href="#content-petemcfarlane" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/nkanderson"><img src="https://avatars0.githubusercontent.com/u/4128825?v=4?s=100" width="100px;" alt="nkanderson"/><br /><sub><b>nkanderson</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nkanderson" title="Code">💻</a> <a href="#content-nkanderson" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ajaxm"><img src="https://avatars0.githubusercontent.com/u/13360138?v=4?s=100" width="100px;" alt="Ajax M"/><br /><sub><b>Ajax M</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=ajaxm" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://dylnuge.com"><img src="https://avatars2.githubusercontent.com/u/118624?v=4?s=100" width="100px;" alt="Dylan Nugent"/><br /><sub><b>Dylan Nugent</b></sub></a><br /><a href="#content-Dylnuge" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/vyaslav"><img src="https://avatars0.githubusercontent.com/u/1385427?v=4?s=100" width="100px;" alt="vyaslav"/><br /><sub><b>vyaslav</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=vyaslav" title="Code">💻</a> <a href="#content-vyaslav" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://join.sfxd.org"><img src="https://avatars1.githubusercontent.com/u/17297466?v=4?s=100" width="100px;" alt="George"/><br /><sub><b>George</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=gdoenlen" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/nyxtom"><img src="https://avatars2.githubusercontent.com/u/222763?v=4?s=100" width="100px;" alt="Thomas Holloway"/><br /><sub><b>Thomas Holloway</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nyxtom" title="Code">💻</a> <a href="#content-nyxtom" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/workingjubilee"><img src="https://avatars1.githubusercontent.com/u/46493976?v=4?s=100" width="100px;" alt="Jubilee"/><br /><sub><b>Jubilee</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=workingjubilee" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/WofWca"><img src="https://avatars1.githubusercontent.com/u/39462442?v=4?s=100" width="100px;" alt="WofWca"/><br /><sub><b>WofWca</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=WofWca" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/jrvidal"><img src="https://avatars0.githubusercontent.com/u/1636604?v=4?s=100" width="100px;" alt="Roberto Vidal"/><br /><sub><b>Roberto Vidal</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=jrvidal" title="Code">💻</a> <a href="https://github.com/rust-lang/rustlings/commits?author=jrvidal" title="Documentation">📖</a> <a href="#ideas-jrvidal" title="Ideas, Planning, & Feedback">🤔</a> <a href="#maintenance-jrvidal" title="Maintenance">🚧</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/jensim"><img src="https://avatars0.githubusercontent.com/u/3663856?v=4?s=100" width="100px;" alt="Jens"/><br /><sub><b>Jens</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=jensim" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://rahatah.me/d"><img src="https://avatars3.githubusercontent.com/u/3174006?v=4?s=100" width="100px;" alt="Rahat Ahmed"/><br /><sub><b>Rahat Ahmed</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=rahatarmanahmed" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/AbdouSeck"><img src="https://avatars2.githubusercontent.com/u/6490055?v=4?s=100" width="100px;" alt="Abdou Seck"/><br /><sub><b>Abdou Seck</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=AbdouSeck" title="Code">💻</a> <a href="#content-AbdouSeck" title="Content">🖋</a> <a href="https://github.com/rust-lang/rustlings/pulls?q=is%3Apr+reviewed-by%3AAbdouSeck" title="Reviewed Pull Requests">👀</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://codehearts.com"><img src="https://avatars0.githubusercontent.com/u/2885412?v=4?s=100" width="100px;" alt="Katie"/><br /><sub><b>Katie</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=codehearts" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Socratides"><img src="https://avatars3.githubusercontent.com/u/27732983?v=4?s=100" width="100px;" alt="Socrates"/><br /><sub><b>Socrates</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Socratides" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/gnodarse"><img src="https://avatars3.githubusercontent.com/u/46761795?v=4?s=100" width="100px;" alt="gnodarse"/><br /><sub><b>gnodarse</b></sub></a><br /><a href="#content-gnodarse" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/harrisonmetz"><img src="https://avatars1.githubusercontent.com/u/7883408?v=4?s=100" width="100px;" alt="Harrison Metzger"/><br /><sub><b>Harrison Metzger</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=harrisonmetz" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/TorbenJ"><img src="https://avatars2.githubusercontent.com/u/9077102?v=4?s=100" width="100px;" alt="Torben Jonas"/><br /><sub><b>Torben Jonas</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=TorbenJ" title="Code">💻</a> <a href="#content-TorbenJ" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://paulbissex.com/"><img src="https://avatars0.githubusercontent.com/u/641?v=4?s=100" width="100px;" alt="Paul Bissex"/><br /><sub><b>Paul Bissex</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=pbx" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/sjmann"><img src="https://avatars0.githubusercontent.com/u/6589896?v=4?s=100" width="100px;" alt="Steven Mann"/><br /><sub><b>Steven Mann</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=sjmann" title="Code">💻</a> <a href="#content-sjmann" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://smmdb.net/"><img src="https://avatars2.githubusercontent.com/u/5855071?v=4?s=100" width="100px;" alt="Mario Reder"/><br /><sub><b>Mario Reder</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Tarnadas" title="Code">💻</a> <a href="#content-Tarnadas" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://keybase.io/skim"><img src="https://avatars0.githubusercontent.com/u/47347?v=4?s=100" width="100px;" alt="skim"/><br /><sub><b>skim</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=sl4m" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/sanjaykdragon"><img src="https://avatars1.githubusercontent.com/u/10261698?v=4?s=100" width="100px;" alt="Sanjay K"/><br /><sub><b>Sanjay K</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=sanjaykdragon" title="Code">💻</a> <a href="#content-sanjaykdragon" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://www.rohanjain.in"><img src="https://avatars1.githubusercontent.com/u/343499?v=4?s=100" width="100px;" alt="Rohan Jain"/><br /><sub><b>Rohan Jain</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=crodjer" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://www.saidaspen.se"><img src="https://avatars1.githubusercontent.com/u/7727687?v=4?s=100" width="100px;" alt="Said Aspen"/><br /><sub><b>Said Aspen</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=saidaspen" title="Code">💻</a> <a href="#content-saidaspen" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/uce"><img src="https://avatars3.githubusercontent.com/u/1756620?v=4?s=100" width="100px;" alt="Ufuk Celebi"/><br /><sub><b>Ufuk Celebi</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=uce" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/lebedevsergey"><img src="https://avatars2.githubusercontent.com/u/7325764?v=4?s=100" width="100px;" alt="lebedevsergey"/><br /><sub><b>lebedevsergey</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=lebedevsergey" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/avrong"><img src="https://avatars2.githubusercontent.com/u/6342851?v=4?s=100" width="100px;" alt="Aleksei Trifonov"/><br /><sub><b>Aleksei Trifonov</b></sub></a><br /><a href="#content-avrong" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://drn.ie"><img src="https://avatars2.githubusercontent.com/u/411136?v=4?s=100" width="100px;" alt="Darren Meehan"/><br /><sub><b>Darren Meehan</b></sub></a><br /><a href="#content-Darrenmeehan" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/jihchi"><img src="https://avatars1.githubusercontent.com/u/87983?v=4?s=100" width="100px;" alt="Jihchi Lee"/><br /><sub><b>Jihchi Lee</b></sub></a><br /><a href="#content-jihchi" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/bertonha"><img src="https://avatars3.githubusercontent.com/u/1225902?v=4?s=100" width="100px;" alt="Christofer Bertonha"/><br /><sub><b>Christofer Bertonha</b></sub></a><br /><a href="#content-bertonha" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/apatniv"><img src="https://avatars2.githubusercontent.com/u/22565917?v=4?s=100" width="100px;" alt="Vivek Bharath Akupatni"/><br /><sub><b>Vivek Bharath Akupatni</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=apatniv" title="Code">💻</a> <a href="https://github.com/rust-lang/rustlings/commits?author=apatniv" title="Tests">⚠️</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/DiD92"><img src="https://avatars3.githubusercontent.com/u/6002416?v=4?s=100" width="100px;" alt="Dídac Sementé Fernández"/><br /><sub><b>Dídac Sementé Fernández</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=DiD92" title="Code">💻</a> <a href="#content-DiD92" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/wrobstory"><img src="https://avatars3.githubusercontent.com/u/2601457?v=4?s=100" width="100px;" alt="Rob Story"/><br /><sub><b>Rob Story</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=wrobstory" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/siobhanjacobson"><img src="https://avatars2.githubusercontent.com/u/28983835?v=4?s=100" width="100px;" alt="Siobhan Jacobson"/><br /><sub><b>Siobhan Jacobson</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=siobhanjacobson" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://www.linkedin.com/in/evancarroll/"><img src="https://avatars2.githubusercontent.com/u/19922?v=4?s=100" width="100px;" alt="Evan Carroll"/><br /><sub><b>Evan Carroll</b></sub></a><br /><a href="#content-EvanCarroll" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://www.jawaadmahmood.com"><img src="https://avatars3.githubusercontent.com/u/95606?v=4?s=100" width="100px;" alt="Jawaad Mahmood"/><br /><sub><b>Jawaad Mahmood</b></sub></a><br /><a href="#content-jmahmood" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/GaurangTandon"><img src="https://avatars1.githubusercontent.com/u/6308683?v=4?s=100" width="100px;" alt="Gaurang Tandon"/><br /><sub><b>Gaurang Tandon</b></sub></a><br /><a href="#content-GaurangTandon" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/dev-cyprium"><img src="https://avatars1.githubusercontent.com/u/6002628?v=4?s=100" width="100px;" alt="Stefan Kupresak"/><br /><sub><b>Stefan Kupresak</b></sub></a><br /><a href="#content-dev-cyprium" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/greg-el"><img src="https://avatars3.githubusercontent.com/u/45019882?v=4?s=100" width="100px;" alt="Greg Leonard"/><br /><sub><b>Greg Leonard</b></sub></a><br /><a href="#content-greg-el" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://ryanpcmcquen.org"><img src="https://avatars3.githubusercontent.com/u/772937?v=4?s=100" width="100px;" alt="Ryan McQuen"/><br /><sub><b>Ryan McQuen</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=ryanpcmcquen" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/AnnikaCodes"><img src="https://avatars3.githubusercontent.com/u/56906084?v=4?s=100" width="100px;" alt="Annika"/><br /><sub><b>Annika</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/pulls?q=is%3Apr+reviewed-by%3AAnnikaCodes" title="Reviewed Pull Requests">👀</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://darnuria.eu"><img src="https://avatars1.githubusercontent.com/u/2827553?v=4?s=100" width="100px;" alt="Axel Viala"/><br /><sub><b>Axel Viala</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=darnuria" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://sazid.github.io"><img src="https://avatars1.githubusercontent.com/u/2370167?v=4?s=100" width="100px;" alt="Mohammed Sazid Al Rashid"/><br /><sub><b>Mohammed Sazid Al Rashid</b></sub></a><br /><a href="#content-sazid" title="Content">🖋</a> <a href="https://github.com/rust-lang/rustlings/commits?author=sazid" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://codingthemsoftly.com"><img src="https://avatars1.githubusercontent.com/u/17479099?v=4?s=100" width="100px;" alt="Caleb Webber"/><br /><sub><b>Caleb Webber</b></sub></a><br /><a href="#maintenance-seeplusplus" title="Maintenance">🚧</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/pcn"><img src="https://avatars2.githubusercontent.com/u/1056756?v=4?s=100" width="100px;" alt="Peter N"/><br /><sub><b>Peter N</b></sub></a><br /><a href="#maintenance-pcn" title="Maintenance">🚧</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/seancad"><img src="https://avatars1.githubusercontent.com/u/47405611?v=4?s=100" width="100px;" alt="seancad"/><br /><sub><b>seancad</b></sub></a><br /><a href="#maintenance-seancad" title="Maintenance">🚧</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://willhayworth.com"><img src="https://avatars3.githubusercontent.com/u/181174?v=4?s=100" width="100px;" alt="Will Hayworth"/><br /><sub><b>Will Hayworth</b></sub></a><br /><a href="#content-wsh" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/chrizel"><img src="https://avatars3.githubusercontent.com/u/20802?v=4?s=100" width="100px;" alt="Christian Zeller"/><br /><sub><b>Christian Zeller</b></sub></a><br /><a href="#content-chrizel" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/jfchevrette"><img src="https://avatars.githubusercontent.com/u/3001?v=4?s=100" width="100px;" alt="Jean-Francois Chevrette"/><br /><sub><b>Jean-Francois Chevrette</b></sub></a><br /><a href="#content-jfchevrette" title="Content">🖋</a> <a href="https://github.com/rust-lang/rustlings/commits?author=jfchevrette" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/jbaber"><img src="https://avatars.githubusercontent.com/u/1908117?v=4?s=100" width="100px;" alt="John Baber-Lucero"/><br /><sub><b>John Baber-Lucero</b></sub></a><br /><a href="#content-jbaber" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tal-zvon"><img src="https://avatars.githubusercontent.com/u/3195851?v=4?s=100" width="100px;" alt="Tal"/><br /><sub><b>Tal</b></sub></a><br /><a href="#content-tal-zvon" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/apogeeoak"><img src="https://avatars.githubusercontent.com/u/59737221?v=4?s=100" width="100px;" alt="apogeeoak"/><br /><sub><b>apogeeoak</b></sub></a><br /><a href="#content-apogeeoak" title="Content">🖋</a> <a href="https://github.com/rust-lang/rustlings/commits?author=apogeeoak" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://www.garfieldtech.com/"><img src="https://avatars.githubusercontent.com/u/254863?v=4?s=100" width="100px;" alt="Larry Garfield"/><br /><sub><b>Larry Garfield</b></sub></a><br /><a href="#content-Crell" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/circumspect"><img src="https://avatars.githubusercontent.com/u/40770208?v=4?s=100" width="100px;" alt="circumspect"/><br /><sub><b>circumspect</b></sub></a><br /><a href="#content-circumspect" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/cjwyett"><img src="https://avatars.githubusercontent.com/u/34195737?v=4?s=100" width="100px;" alt="Cyrus Wyett"/><br /><sub><b>Cyrus Wyett</b></sub></a><br /><a href="#content-cjwyett" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/cadolphs"><img src="https://avatars.githubusercontent.com/u/13894820?v=4?s=100" width="100px;" alt="cadolphs"/><br /><sub><b>cadolphs</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=cadolphs" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://www.haveneer.com"><img src="https://avatars.githubusercontent.com/u/26146722?v=4?s=100" width="100px;" alt="Pascal H."/><br /><sub><b>Pascal H.</b></sub></a><br /><a href="#content-hpwxf" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://twitter.com/chapeupreto"><img src="https://avatars.githubusercontent.com/u/834048?v=4?s=100" width="100px;" alt="Rod Elias"/><br /><sub><b>Rod Elias</b></sub></a><br /><a href="#content-chapeupreto" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/blerchy"><img src="https://avatars.githubusercontent.com/u/2555355?v=4?s=100" width="100px;" alt="Matt Lebl"/><br /><sub><b>Matt Lebl</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=blerchy" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://flakolefluk.dev"><img src="https://avatars.githubusercontent.com/u/11986564?v=4?s=100" width="100px;" alt="Ignacio Le Fluk"/><br /><sub><b>Ignacio Le Fluk</b></sub></a><br /><a href="#content-flakolefluk" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tlyu"><img src="https://avatars.githubusercontent.com/u/431873?v=4?s=100" width="100px;" alt="Taylor Yu"/><br /><sub><b>Taylor Yu</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=tlyu" title="Code">💻</a> <a href="#content-tlyu" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://zerotask.github.io"><img src="https://avatars.githubusercontent.com/u/20150243?v=4?s=100" width="100px;" alt="Patrick Hintermayer"/><br /><sub><b>Patrick Hintermayer</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Zerotask" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://petkopavlovski.com/"><img src="https://avatars.githubusercontent.com/u/32264020?v=4?s=100" width="100px;" alt="Pete Pavlovski"/><br /><sub><b>Pete Pavlovski</b></sub></a><br /><a href="#content-arthas168" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/k12ish"><img src="https://avatars.githubusercontent.com/u/45272873?v=4?s=100" width="100px;" alt="k12ish"/><br /><sub><b>k12ish</b></sub></a><br /><a href="#content-k12ish" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/hongshaoyang"><img src="https://avatars.githubusercontent.com/u/19281800?v=4?s=100" width="100px;" alt="Shao Yang Hong"/><br /><sub><b>Shao Yang Hong</b></sub></a><br /><a href="#content-hongshaoyang" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/bmacer"><img src="https://avatars.githubusercontent.com/u/13931806?v=4?s=100" width="100px;" alt="Brandon Macer"/><br /><sub><b>Brandon Macer</b></sub></a><br /><a href="#content-bmacer" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/stoiandan"><img src="https://avatars.githubusercontent.com/u/10388612?v=4?s=100" width="100px;" alt="Stoian Dan"/><br /><sub><b>Stoian Dan</b></sub></a><br /><a href="#content-stoiandan" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://about.me/pjdelport"><img src="https://avatars.githubusercontent.com/u/630271?v=4?s=100" width="100px;" alt="Pi Delport"/><br /><sub><b>Pi Delport</b></sub></a><br /><a href="#content-PiDelport" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/sateeshkumarb"><img src="https://avatars.githubusercontent.com/u/429263?v=4?s=100" width="100px;" alt="Sateesh "/><br /><sub><b>Sateesh </b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=sateeshkumarb" title="Code">💻</a> <a href="#content-sateeshkumarb" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/kayuapi"><img src="https://avatars.githubusercontent.com/u/10304328?v=4?s=100" width="100px;" alt="ZC"/><br /><sub><b>ZC</b></sub></a><br /><a href="#content-kayuapi" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/hyperparabolic"><img src="https://avatars.githubusercontent.com/u/12348474?v=4?s=100" width="100px;" alt="hyperparabolic"/><br /><sub><b>hyperparabolic</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=hyperparabolic" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://www.net4visions.at"><img src="https://avatars.githubusercontent.com/u/5228369?v=4?s=100" width="100px;" alt="arlecchino"/><br /><sub><b>arlecchino</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=kolbma" title="Documentation">📖</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://richthofen.io/"><img src="https://avatars.githubusercontent.com/u/7576730?v=4?s=100" width="100px;" alt="Richthofen"/><br /><sub><b>Richthofen</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=jazzplato" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/cseltol"><img src="https://avatars.githubusercontent.com/u/64264529?v=4?s=100" width="100px;" alt="Ivan Nerazumov"/><br /><sub><b>Ivan Nerazumov</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=cseltol" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/lauralindzey"><img src="https://avatars.githubusercontent.com/u/65185744?v=4?s=100" width="100px;" alt="lauralindzey"/><br /><sub><b>lauralindzey</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=lauralindzey" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/sinharaksh1t"><img src="https://avatars.githubusercontent.com/u/28585848?v=4?s=100" width="100px;" alt="Rakshit Sinha"/><br /><sub><b>Rakshit Sinha</b></sub></a><br /><a href="#content-sinharaksh1t" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/dbednar230"><img src="https://avatars.githubusercontent.com/u/54457902?v=4?s=100" width="100px;" alt="Damian"/><br /><sub><b>Damian</b></sub></a><br /><a href="#content-dbednar230" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://benarmstead.co.uk"><img src="https://avatars.githubusercontent.com/u/70973680?v=4?s=100" width="100px;" alt="Ben Armstead"/><br /><sub><b>Ben Armstead</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=benarmstead" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/anuk909"><img src="https://avatars.githubusercontent.com/u/34924662?v=4?s=100" width="100px;" alt="anuk909"/><br /><sub><b>anuk909</b></sub></a><br /><a href="#content-anuk909" title="Content">🖋</a> <a href="https://github.com/rust-lang/rustlings/commits?author=anuk909" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://granddaifuku.com/"><img src="https://avatars.githubusercontent.com/u/49578068?v=4?s=100" width="100px;" alt="granddaifuku"/><br /><sub><b>granddaifuku</b></sub></a><br /><a href="#content-granddaifuku" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://weilet.me"><img src="https://avatars.githubusercontent.com/u/32561597?v=4?s=100" width="100px;" alt="Weilet"/><br /><sub><b>Weilet</b></sub></a><br /><a href="#content-Weilet" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Millione"><img src="https://avatars.githubusercontent.com/u/38575932?v=4?s=100" width="100px;" alt="LIU JIE"/><br /><sub><b>LIU JIE</b></sub></a><br /><a href="#content-Millione" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/abusch"><img src="https://avatars.githubusercontent.com/u/506344?v=4?s=100" width="100px;" alt="Antoine Büsch"/><br /><sub><b>Antoine Büsch</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=abusch" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://frogtd.com/"><img src="https://avatars.githubusercontent.com/u/31412003?v=4?s=100" width="100px;" alt="frogtd"/><br /><sub><b>frogtd</b></sub></a><br /><a href="#content-frogtd" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/EmisonLu"><img src="https://avatars.githubusercontent.com/u/54395432?v=4?s=100" width="100px;" alt="Zhenghao Lu"/><br /><sub><b>Zhenghao Lu</b></sub></a><br /><a href="#content-EmisonLu" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://soundtrackyourbrand.com"><img src="https://avatars.githubusercontent.com/u/762956?v=4?s=100" width="100px;" alt="Fredrik Enestad"/><br /><sub><b>Fredrik Enestad</b></sub></a><br /><a href="#content-fredr" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://xuesong.pydevops.com"><img src="https://avatars.githubusercontent.com/u/18476085?v=4?s=100" width="100px;" alt="xuesong"/><br /><sub><b>xuesong</b></sub></a><br /><a href="#content-xuesongbj" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/MpdWalsh"><img src="https://avatars.githubusercontent.com/u/48160144?v=4?s=100" width="100px;" alt="Michael Walsh"/><br /><sub><b>Michael Walsh</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=MpdWalsh" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/alirezaghey"><img src="https://avatars.githubusercontent.com/u/26653424?v=4?s=100" width="100px;" alt="alirezaghey"/><br /><sub><b>alirezaghey</b></sub></a><br /><a href="#content-alirezaghey" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/frvannes16"><img src="https://avatars.githubusercontent.com/u/3188475?v=4?s=100" width="100px;" alt="Franklin van Nes"/><br /><sub><b>Franklin van Nes</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=frvannes16" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://nekonako.github.io"><img src="https://avatars.githubusercontent.com/u/46141275?v=4?s=100" width="100px;" alt="nekonako"/><br /><sub><b>nekonako</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nekonako" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tan-zx"><img src="https://avatars.githubusercontent.com/u/67887489?v=4?s=100" width="100px;" alt="ZX"/><br /><sub><b>ZX</b></sub></a><br /><a href="#content-tan-zx" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/sundevilyang"><img src="https://avatars.githubusercontent.com/u/1499214?v=4?s=100" width="100px;" alt="Yang Wen"/><br /><sub><b>Yang Wen</b></sub></a><br /><a href="#content-sundevilyang" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://brandon-high.com"><img src="https://avatars.githubusercontent.com/u/759848?v=4?s=100" width="100px;" alt="Brandon High"/><br /><sub><b>Brandon High</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=highb" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/x-hgg-x"><img src="https://avatars.githubusercontent.com/u/39058530?v=4?s=100" width="100px;" alt="x-hgg-x"/><br /><sub><b>x-hgg-x</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=x-hgg-x" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://kisaragieffective.github.io"><img src="https://avatars.githubusercontent.com/u/48310258?v=4?s=100" width="100px;" alt="Kisaragi"/><br /><sub><b>Kisaragi</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=KisaragiEffective" title="Documentation">📖</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Kallu-A"><img src="https://avatars.githubusercontent.com/u/73198738?v=4?s=100" width="100px;" alt="Lucas Aries"/><br /><sub><b>Lucas Aries</b></sub></a><br /><a href="#content-Kallu-A" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ragreenburg"><img src="https://avatars.githubusercontent.com/u/24358100?v=4?s=100" width="100px;" alt="ragreenburg"/><br /><sub><b>ragreenburg</b></sub></a><br /><a href="#content-ragreenburg" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/stevenfukase"><img src="https://avatars.githubusercontent.com/u/66785624?v=4?s=100" width="100px;" alt="stevenfukase"/><br /><sub><b>stevenfukase</b></sub></a><br /><a href="#content-stevenfukase" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/J-S-Kim"><img src="https://avatars.githubusercontent.com/u/17569303?v=4?s=100" width="100px;" alt="J-S-Kim"/><br /><sub><b>J-S-Kim</b></sub></a><br /><a href="#content-J-S-Kim" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Fointard"><img src="https://avatars.githubusercontent.com/u/9333398?v=4?s=100" width="100px;" alt="Fointard"/><br /><sub><b>Fointard</b></sub></a><br /><a href="#content-Fointard" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/rytheo"><img src="https://avatars.githubusercontent.com/u/22184325?v=4?s=100" width="100px;" alt="Ryan Lowe"/><br /><sub><b>Ryan Lowe</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=rytheo" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://www.dashen.tech"><img src="https://avatars.githubusercontent.com/u/15921519?v=4?s=100" width="100px;" alt="cui fliter"/><br /><sub><b>cui fliter</b></sub></a><br /><a href="#content-cuishuang" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/luskwater"><img src="https://avatars.githubusercontent.com/u/42529?v=4?s=100" width="100px;" alt="Ron Lusk"/><br /><sub><b>Ron Lusk</b></sub></a><br /><a href="#content-luskwater" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://liby.github.io/liby/"><img src="https://avatars.githubusercontent.com/u/38807139?v=4?s=100" width="100px;" alt="Bryan Lee"/><br /><sub><b>Bryan Lee</b></sub></a><br /><a href="#content-liby" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://nandaja.space"><img src="https://avatars.githubusercontent.com/u/2624550?v=4?s=100" width="100px;" alt="Nandaja Varma"/><br /><sub><b>Nandaja Varma</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nandajavarma" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/merelymyself"><img src="https://avatars.githubusercontent.com/u/88221256?v=4?s=100" width="100px;" alt="pwygab"/><br /><sub><b>pwygab</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=merelymyself" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://linkedin.com/in/lucasgrvarela"><img src="https://avatars.githubusercontent.com/u/37870368?v=4?s=100" width="100px;" alt="Lucas Grigolon Varela"/><br /><sub><b>Lucas Grigolon Varela</b></sub></a><br /><a href="#content-lucasgrvarela" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/bufo24"><img src="https://avatars.githubusercontent.com/u/32884105?v=4?s=100" width="100px;" alt="Bufo"/><br /><sub><b>Bufo</b></sub></a><br /><a href="#content-bufo24" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://rustnote.com"><img src="https://avatars.githubusercontent.com/u/77730378?v=4?s=100" width="100px;" alt="Jack Clayton"/><br /><sub><b>Jack Clayton</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=jackos" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/klkl0808"><img src="https://avatars.githubusercontent.com/u/24694249?v=4?s=100" width="100px;" alt="Konstantin"/><br /><sub><b>Konstantin</b></sub></a><br /><a href="#content-klkl0808" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/0pling"><img src="https://avatars.githubusercontent.com/u/104090344?v=4?s=100" width="100px;" alt="0pling"/><br /><sub><b>0pling</b></sub></a><br /><a href="#content-0pling" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/KatanaFluorescent"><img src="https://avatars.githubusercontent.com/u/60199077?v=4?s=100" width="100px;" alt="KatanaFluorescent"/><br /><sub><b>KatanaFluorescent</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=KatanaFluorescent" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Drew-Morris"><img src="https://avatars.githubusercontent.com/u/95818166?v=4?s=100" width="100px;" alt="Drew Morris"/><br /><sub><b>Drew Morris</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Drew-Morris" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/camperdue42"><img src="https://avatars.githubusercontent.com/u/43047763?v=4?s=100" width="100px;" alt="camperdue42"/><br /><sub><b>camperdue42</b></sub></a><br /><a href="#content-camperdue42" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/YsuOS"><img src="https://avatars.githubusercontent.com/u/30138661?v=4?s=100" width="100px;" alt="YsuOS"/><br /><sub><b>YsuOS</b></sub></a><br /><a href="#content-YsuOS" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://lichess.org/@/StevenEmily"><img src="https://avatars.githubusercontent.com/u/58114641?v=4?s=100" width="100px;" alt="Steven Nguyen"/><br /><sub><b>Steven Nguyen</b></sub></a><br /><a href="#content-icecream17" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://noahcairns.dev"><img src="https://avatars.githubusercontent.com/u/94420090?v=4?s=100" width="100px;" alt="nacairns1"/><br /><sub><b>nacairns1</b></sub></a><br /><a href="#content-nacairns1" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/pgjbz"><img src="https://avatars.githubusercontent.com/u/22059237?v=4?s=100" width="100px;" alt="Paulo Gabriel Justino Bezerra"/><br /><sub><b>Paulo Gabriel Justino Bezerra</b></sub></a><br /><a href="#content-pgjbz" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/jaystile"><img src="https://avatars.githubusercontent.com/u/46078028?v=4?s=100" width="100px;" alt="Jason"/><br /><sub><b>Jason</b></sub></a><br /><a href="#content-jaystile" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://exdx.github.io"><img src="https://avatars.githubusercontent.com/u/31546601?v=4?s=100" width="100px;" alt="exdx"/><br /><sub><b>exdx</b></sub></a><br /><a href="#content-exdx" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Jzow"><img src="https://avatars.githubusercontent.com/u/68860495?v=4?s=100" width="100px;" alt="James Zow"/><br /><sub><b>James Zow</b></sub></a><br /><a href="#content-Jzow" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://jamesabromley.wordpress.com/"><img src="https://avatars.githubusercontent.com/u/2474334?v=4?s=100" width="100px;" alt="James Bromley"/><br /><sub><b>James Bromley</b></sub></a><br /><a href="#content-jayber" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/swhiteCQC"><img src="https://avatars.githubusercontent.com/u/77438466?v=4?s=100" width="100px;" alt="swhiteCQC"/><br /><sub><b>swhiteCQC</b></sub></a><br /><a href="#content-swhiteCQC" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/neilpate"><img src="https://avatars.githubusercontent.com/u/7802334?v=4?s=100" width="100px;" alt="Neil Pate"/><br /><sub><b>Neil Pate</b></sub></a><br /><a href="#content-neilpate" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://wojexe.com"><img src="https://avatars.githubusercontent.com/u/21208490?v=4?s=100" width="100px;" alt="wojexe"/><br /><sub><b>wojexe</b></sub></a><br /><a href="#content-wojexe" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Tostapunk"><img src="https://avatars.githubusercontent.com/u/25140297?v=4?s=100" width="100px;" alt="Mattia Schiavon"/><br /><sub><b>Mattia Schiavon</b></sub></a><br /><a href="#content-Tostapunk" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://toucantoco.com"><img src="https://avatars.githubusercontent.com/u/18406791?v=4?s=100" width="100px;" alt="Eric Jolibois"/><br /><sub><b>Eric Jolibois</b></sub></a><br /><a href="#content-PrettyWood" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://edwinchang.vercel.app"><img src="https://avatars.githubusercontent.com/u/88263098?v=4?s=100" width="100px;" alt="Edwin Chang"/><br /><sub><b>Edwin Chang</b></sub></a><br /><a href="#content-EdwinChang24" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://saikat.dev/"><img src="https://avatars.githubusercontent.com/u/7412443?v=4?s=100" width="100px;" alt="Saikat Das"/><br /><sub><b>Saikat Das</b></sub></a><br /><a href="#content-saikatdas0790" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/thatlittleboy"><img src="https://avatars.githubusercontent.com/u/30731072?v=4?s=100" width="100px;" alt="Jeremy Goh"/><br /><sub><b>Jeremy Goh</b></sub></a><br /><a href="#content-thatlittleboy" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Lioness100"><img src="https://avatars.githubusercontent.com/u/65814829?v=4?s=100" width="100px;" alt="Lioness100"/><br /><sub><b>Lioness100</b></sub></a><br /><a href="#content-Lioness100" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tvkn"><img src="https://avatars.githubusercontent.com/u/79277926?v=4?s=100" width="100px;" alt="Tristan Nicholls"/><br /><sub><b>Tristan Nicholls</b></sub></a><br /><a href="#content-tvkn" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://clairewang.net"><img src="https://avatars.githubusercontent.com/u/9344258?v=4?s=100" width="100px;" alt="Claire"/><br /><sub><b>Claire</b></sub></a><br /><a href="#content-clairew" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Mouwrice"><img src="https://avatars.githubusercontent.com/u/56763273?v=4?s=100" width="100px;" alt="Maurice Van Wassenhove"/><br /><sub><b>Maurice Van Wassenhove</b></sub></a><br /><a href="#content-Mouwrice" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://jmthree.com"><img src="https://avatars.githubusercontent.com/u/77524?v=4?s=100" width="100px;" alt="John Mendelewski"/><br /><sub><b>John Mendelewski</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=johnmendel" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://fakhoury.xyz"><img src="https://avatars.githubusercontent.com/u/20828724?v=4?s=100" width="100px;" alt="Brian Fakhoury"/><br /><sub><b>Brian Fakhoury</b></sub></a><br /><a href="#content-brianfakhoury" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/markusboehme"><img src="https://avatars.githubusercontent.com/u/5074759?v=4?s=100" width="100px;" alt="Markus Boehme"/><br /><sub><b>Markus Boehme</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=markusboehme" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/nico-vromans"><img src="https://avatars.githubusercontent.com/u/48183857?v=4?s=100" width="100px;" alt="Nico Vromans"/><br /><sub><b>Nico Vromans</b></sub></a><br /><a href="#content-nico-vromans" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/vostok92"><img src="https://avatars.githubusercontent.com/u/540339?v=4?s=100" width="100px;" alt="vostok92"/><br /><sub><b>vostok92</b></sub></a><br /><a href="#content-vostok92" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://magnusrodseth.vercel.app"><img src="https://avatars.githubusercontent.com/u/59113973?v=4?s=100" width="100px;" alt="Magnus Rødseth"/><br /><sub><b>Magnus Rødseth</b></sub></a><br /><a href="#content-magnusrodseth" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/rubiesonthesky"><img src="https://avatars.githubusercontent.com/u/2591240?v=4?s=100" width="100px;" alt="rubiesonthesky"/><br /><sub><b>rubiesonthesky</b></sub></a><br /><a href="#content-rubiesonthesky" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://www.gabrielbianconi.com/"><img src="https://avatars.githubusercontent.com/u/1275491?v=4?s=100" width="100px;" alt="Gabriel Bianconi"/><br /><sub><b>Gabriel Bianconi</b></sub></a><br /><a href="#content-GabrielBianconi" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Kodylow"><img src="https://avatars.githubusercontent.com/u/74332828?v=4?s=100" width="100px;" alt="Kody Low"/><br /><sub><b>Kody Low</b></sub></a><br /><a href="#content-Kodylow" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/rzrymiak"><img src="https://avatars.githubusercontent.com/u/106121613?v=4?s=100" width="100px;" alt="rzrymiak"/><br /><sub><b>rzrymiak</b></sub></a><br /><a href="#content-rzrymiak" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/miguelraz"><img src="https://avatars.githubusercontent.com/u/13056181?v=4?s=100" width="100px;" alt="Miguel Raz Guzmán Macedo"/><br /><sub><b>Miguel Raz Guzmán Macedo</b></sub></a><br /><a href="#content-miguelraz" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/memark"><img src="https://avatars.githubusercontent.com/u/318504?v=4?s=100" width="100px;" alt="Magnus Markling"/><br /><sub><b>Magnus Markling</b></sub></a><br /><a href="#content-memark" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/gasparitiago"><img src="https://avatars.githubusercontent.com/u/3237254?v=4?s=100" width="100px;" alt="Tiago De Gaspari"/><br /><sub><b>Tiago De Gaspari</b></sub></a><br /><a href="#content-gasparitiago" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/skaunov"><img src="https://avatars.githubusercontent.com/u/65976143?v=4?s=100" width="100px;" alt="skaunov"/><br /><sub><b>skaunov</b></sub></a><br /><a href="#content-skaunov" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://caljacobson.dev"><img src="https://avatars.githubusercontent.com/u/9152032?v=4?s=100" width="100px;" alt="Cal Jacobson"/><br /><sub><b>Cal Jacobson</b></sub></a><br /><a href="#content-cj81499" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/duchonic"><img src="https://avatars.githubusercontent.com/u/34117620?v=4?s=100" width="100px;" alt="Duchoud Nicolas"/><br /><sub><b>Duchoud Nicolas</b></sub></a><br /><a href="#content-duchonic" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/gfaugere"><img src="https://avatars.githubusercontent.com/u/11901979?v=4?s=100" width="100px;" alt="Gaëtan Faugère"/><br /><sub><b>Gaëtan Faugère</b></sub></a><br /><a href="#tool-gfaugere" title="Tools">🔧</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/bhbuehler"><img src="https://avatars.githubusercontent.com/u/25541343?v=4?s=100" width="100px;" alt="bhbuehler"/><br /><sub><b>bhbuehler</b></sub></a><br /><a href="#content-bhbuehler" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/nyurik"><img src="https://avatars.githubusercontent.com/u/1641515?v=4?s=100" width="100px;" alt="Yuri Astrakhan"/><br /><sub><b>Yuri Astrakhan</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nyurik" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://azzamsa.com"><img src="https://avatars.githubusercontent.com/u/17734314?v=4?s=100" width="100px;" alt="azzamsa"/><br /><sub><b>azzamsa</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=azzamsa" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/mvanschellebeeck"><img src="https://avatars.githubusercontent.com/u/17671052?v=4?s=100" width="100px;" alt="mvanschellebeeck"/><br /><sub><b>mvanschellebeeck</b></sub></a><br /><a href="#content-mvanschellebeeck" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/aaarkid"><img src="https://avatars.githubusercontent.com/u/39987510?v=4?s=100" width="100px;" alt="Arkid"/><br /><sub><b>Arkid</b></sub></a><br /><a href="#content-aaarkid" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://tfpk.dev"><img src="https://avatars.githubusercontent.com/u/10906982?v=4?s=100" width="100px;" alt="Tom Kunc"/><br /><sub><b>Tom Kunc</b></sub></a><br /><a href="#content-tfpk" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/mfurak"><img src="https://avatars.githubusercontent.com/u/38523093?v=4?s=100" width="100px;" alt="Marek Furák"/><br /><sub><b>Marek Furák</b></sub></a><br /><a href="#content-mfurak" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://winter.cafe"><img src="https://avatars.githubusercontent.com/u/78392041?v=4?s=100" width="100px;" alt="Winter"/><br /><sub><b>Winter</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=winterqt" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://moritzboeh.me"><img src="https://avatars.githubusercontent.com/u/42215704?v=4?s=100" width="100px;" alt="Moritz Böhme"/><br /><sub><b>Moritz Böhme</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=MoritzBoehme" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/craymel"><img src="https://avatars.githubusercontent.com/u/71062756?v=4?s=100" width="100px;" alt="craymel"/><br /><sub><b>craymel</b></sub></a><br /><a href="#content-craymel" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tkburis"><img src="https://avatars.githubusercontent.com/u/20501289?v=4?s=100" width="100px;" alt="TK Buristrakul"/><br /><sub><b>TK Buristrakul</b></sub></a><br /><a href="#content-tkburis" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/HerschelW"><img src="https://avatars.githubusercontent.com/u/17935816?v=4?s=100" width="100px;" alt="Kent Worthington"/><br /><sub><b>Kent Worthington</b></sub></a><br /><a href="#content-HerschelW" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/seporterfield"><img src="https://avatars.githubusercontent.com/u/107010978?v=4?s=100" width="100px;" alt="seporterfield"/><br /><sub><b>seporterfield</b></sub></a><br /><a href="#content-seporterfield" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://www.linkedin.com/in/dbarrosop"><img src="https://avatars.githubusercontent.com/u/6246622?v=4?s=100" width="100px;" alt="David Barroso"/><br /><sub><b>David Barroso</b></sub></a><br /><a href="#infra-dbarrosop" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://distanz.ch"><img src="https://avatars.githubusercontent.com/u/539708?v=4?s=100" width="100px;" alt="Tobias Klauser"/><br /><sub><b>Tobias Klauser</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=tklauser" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/0xMySt1c"><img src="https://avatars.githubusercontent.com/u/101825630?v=4?s=100" width="100px;" alt="0xMySt1c"/><br /><sub><b>0xMySt1c</b></sub></a><br /><a href="#tool-0xMySt1c" title="Tools">🔧</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/AxolotlTears"><img src="https://avatars.githubusercontent.com/u/87157047?v=4?s=100" width="100px;" alt="Ten"/><br /><sub><b>Ten</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=AxolotlTears" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://h4x5p4c3.xyz"><img src="https://avatars.githubusercontent.com/u/66133688?v=4?s=100" width="100px;" alt="jones martin"/><br /><sub><b>jones martin</b></sub></a><br /><a href="#content-h4x5p4c3" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/cloppingemu"><img src="https://avatars.githubusercontent.com/u/12227963?v=4?s=100" width="100px;" alt="cloppingemu"/><br /><sub><b>cloppingemu</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=cloppingemu" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://github.com/zeromicro/go-zero"><img src="https://avatars.githubusercontent.com/u/1918356?v=4?s=100" width="100px;" alt="Kevin Wan"/><br /><sub><b>Kevin Wan</b></sub></a><br /><a href="#content-kevwan" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://kurowasaruby.cn"><img src="https://avatars.githubusercontent.com/u/43495006?v=4?s=100" width="100px;" alt="Ruby"/><br /><sub><b>Ruby</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=wjwrh" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/alexandergill"><img src="https://avatars.githubusercontent.com/u/7033716?v=4?s=100" width="100px;" alt="Alexander Gill"/><br /><sub><b>Alexander Gill</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=alexandergill" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://www.linkedin.com/in/jarrod-sanders/"><img src="https://avatars.githubusercontent.com/u/50600614?v=4?s=100" width="100px;" alt="Jarrod Sanders"/><br /><sub><b>Jarrod Sanders</b></sub></a><br /><a href="#content-kawaiiPlat" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/platformer"><img src="https://avatars.githubusercontent.com/u/40146328?v=4?s=100" width="100px;" alt="Andrew Sen"/><br /><sub><b>Andrew Sen</b></sub></a><br /><a href="#content-platformer" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://grzegorz-zur.com/"><img src="https://avatars.githubusercontent.com/u/5297583?v=4?s=100" width="100px;" alt="Grzegorz Żur"/><br /><sub><b>Grzegorz Żur</b></sub></a><br /><a href="#content-grzegorz-zur" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/black-puppydog"><img src="https://avatars.githubusercontent.com/u/189241?v=4?s=100" width="100px;" alt="Daan Wynen"/><br /><sub><b>Daan Wynen</b></sub></a><br /><a href="#content-black-puppydog" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Anush008"><img src="https://avatars.githubusercontent.com/u/46051506?v=4?s=100" width="100px;" alt="Anush"/><br /><sub><b>Anush</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Anush008" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/shgew"><img src="https://avatars.githubusercontent.com/u/5584672?v=4?s=100" width="100px;" alt="Gleb Shevchenko"/><br /><sub><b>Gleb Shevchenko</b></sub></a><br /><a href="#content-shgew" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/mdmundo"><img src="https://avatars.githubusercontent.com/u/60408300?v=4?s=100" width="100px;" alt="Edmundo Paulino"/><br /><sub><b>Edmundo Paulino</b></sub></a><br /><a href="#infra-mdmundo" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/eroullit"><img src="https://avatars.githubusercontent.com/u/301795?v=4?s=100" width="100px;" alt="Emmanuel Roullit"/><br /><sub><b>Emmanuel Roullit</b></sub></a><br /><a href="#infra-eroullit" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://nidhalmessaoudi.herokuapp.com"><img src="https://avatars.githubusercontent.com/u/63377412?v=4?s=100" width="100px;" alt="Nidhal Messaoudi"/><br /><sub><b>Nidhal Messaoudi</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nidhalmessaoudi" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/MahdiBM"><img src="https://avatars.githubusercontent.com/u/54685446?v=4?s=100" width="100px;" alt="Mahdi Bahrami"/><br /><sub><b>Mahdi Bahrami</b></sub></a><br /><a href="#tool-MahdiBM" title="Tools">🔧</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Nagidal"><img src="https://avatars.githubusercontent.com/u/7075397?v=4?s=100" width="100px;" alt="Nagidal"/><br /><sub><b>Nagidal</b></sub></a><br /><a href="#content-Nagidal" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://adabrew.com"><img src="https://avatars.githubusercontent.com/u/25161597?v=4?s=100" width="100px;" alt="Adam Brewer"/><br /><sub><b>Adam Brewer</b></sub></a><br /><a href="#content-adamhb123" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/eugkhp"><img src="https://avatars.githubusercontent.com/u/25910599?v=4?s=100" width="100px;" alt="Eugene"/><br /><sub><b>Eugene</b></sub></a><br /><a href="#tool-eugkhp" title="Tools">🔧</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://social.linux.pizza/@navicore"><img src="https://avatars.githubusercontent.com/u/110999?v=4?s=100" width="100px;" alt="Ed Sweeney"/><br /><sub><b>Ed Sweeney</b></sub></a><br /><a href="#content-navicore" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/javihernant"><img src="https://avatars.githubusercontent.com/u/73640929?v=4?s=100" width="100px;" alt="javihernant"/><br /><sub><b>javihernant</b></sub></a><br /><a href="#content-javihernant" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/VegardMatthey"><img src="https://avatars.githubusercontent.com/u/59250656?v=4?s=100" width="100px;" alt="Vegard"/><br /><sub><b>Vegard</b></sub></a><br /><a href="#content-VegardMatthey" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ryanwhitehouse"><img src="https://avatars.githubusercontent.com/u/13400784?v=4?s=100" width="100px;" alt="Ryan Whitehouse"/><br /><sub><b>Ryan Whitehouse</b></sub></a><br /><a href="#content-ryanwhitehouse" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/guoard"><img src="https://avatars.githubusercontent.com/u/65511355?v=4?s=100" width="100px;" alt="Ali Afsharzadeh"/><br /><sub><b>Ali Afsharzadeh</b></sub></a><br /><a href="#content-guoard" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://keogami.ml"><img src="https://avatars.githubusercontent.com/u/41939011?v=4?s=100" width="100px;" alt="Keogami"/><br /><sub><b>Keogami</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=keogami" title="Documentation">📖</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ahresse"><img src="https://avatars.githubusercontent.com/u/28402488?v=4?s=100" width="100px;" alt="Alexandre Esse"/><br /><sub><b>Alexandre Esse</b></sub></a><br /><a href="#content-ahresse" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://resilient.tech"><img src="https://avatars.githubusercontent.com/u/16315650?v=4?s=100" width="100px;" alt="Sagar Vora"/><br /><sub><b>Sagar Vora</b></sub></a><br /><a href="#content-sagarvora" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/poneciak57"><img src="https://avatars.githubusercontent.com/u/94321164?v=4?s=100" width="100px;" alt="Kacper Poneta"/><br /><sub><b>Kacper Poneta</b></sub></a><br /><a href="#content-poneciak57" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://ktheory.com/"><img src="https://avatars.githubusercontent.com/u/975?v=4?s=100" width="100px;" alt="Aaron Suggs"/><br /><sub><b>Aaron Suggs</b></sub></a><br /><a href="#content-ktheory" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/alexwh"><img src="https://avatars.githubusercontent.com/u/1723612?v=4?s=100" width="100px;" alt="Alex"/><br /><sub><b>Alex</b></sub></a><br /><a href="#content-alexwh" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/stornquist"><img src="https://avatars.githubusercontent.com/u/42915664?v=4?s=100" width="100px;" alt="Sebastian Törnquist"/><br /><sub><b>Sebastian Törnquist</b></sub></a><br /><a href="#content-stornquist" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://smlavine.com"><img src="https://avatars.githubusercontent.com/u/33563640?v=4?s=100" width="100px;" alt="Sebastian LaVine"/><br /><sub><b>Sebastian LaVine</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=smlavine" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://www.alangerber.us"><img src="https://avatars.githubusercontent.com/u/201313?v=4?s=100" width="100px;" alt="Alan Gerber"/><br /><sub><b>Alan Gerber</b></sub></a><br /><a href="#content-akgerber" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://esotuvaka.github.io"><img src="https://avatars.githubusercontent.com/u/104941850?v=4?s=100" width="100px;" alt="Eric"/><br /><sub><b>Eric</b></sub></a><br /><a href="#content-esotuvaka" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/az0977776"><img src="https://avatars.githubusercontent.com/u/9172038?v=4?s=100" width="100px;" alt="Aaron Wang"/><br /><sub><b>Aaron Wang</b></sub></a><br /><a href="#content-az0977776" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/nmay231"><img src="https://avatars.githubusercontent.com/u/35386821?v=4?s=100" width="100px;" alt="Noah"/><br /><sub><b>Noah</b></sub></a><br /><a href="#content-nmay231" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/rb5014"><img src="https://avatars.githubusercontent.com/u/105397317?v=4?s=100" width="100px;" alt="rb5014"/><br /><sub><b>rb5014</b></sub></a><br /><a href="#content-rb5014" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/deedy5"><img src="https://avatars.githubusercontent.com/u/65482418?v=4?s=100" width="100px;" alt="deedy5"/><br /><sub><b>deedy5</b></sub></a><br /><a href="#content-deedy5" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/lionel-rowe"><img src="https://avatars.githubusercontent.com/u/26078826?v=4?s=100" width="100px;" alt="lionel-rowe"/><br /><sub><b>lionel-rowe</b></sub></a><br /><a href="#content-lionel-rowe" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Ben2917"><img src="https://avatars.githubusercontent.com/u/10279994?v=4?s=100" width="100px;" alt="Ben"/><br /><sub><b>Ben</b></sub></a><br /><a href="#content-Ben2917" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/b1ue64"><img src="https://avatars.githubusercontent.com/u/77976308?v=4?s=100" width="100px;" alt="b1ue64"/><br /><sub><b>b1ue64</b></sub></a><br /><a href="#content-b1ue64" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/lazywalker"><img src="https://avatars.githubusercontent.com/u/53956?v=4?s=100" width="100px;" alt="lazywalker"/><br /><sub><b>lazywalker</b></sub></a><br /><a href="#content-lazywalker" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/proofconstruction"><img src="https://avatars.githubusercontent.com/u/74747193?v=4?s=100" width="100px;" alt="proofconstruction"/><br /><sub><b>proofconstruction</b></sub></a><br /><a href="#infra-proofconstruction" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://www.youtube.com/channel/UCQCjA6qUutAtWqkCA4Z36CQ"><img src="https://avatars.githubusercontent.com/u/16007179?v=4?s=100" width="100px;" alt="IVIURRAY"/><br /><sub><b>IVIURRAY</b></sub></a><br /><a href="#content-IVIURRAY" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/b-apperlo"><img src="https://avatars.githubusercontent.com/u/91734527?v=4?s=100" width="100px;" alt="Bert Apperlo"/><br /><sub><b>Bert Apperlo</b></sub></a><br /><a href="#content-b-apperlo" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://fwdekker.com/"><img src="https://avatars.githubusercontent.com/u/13442533?v=4?s=100" width="100px;" alt="Florine W. Dekker"/><br /><sub><b>Florine W. Dekker</b></sub></a><br /><a href="#content-FWDekker" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/luhem7"><img src="https://avatars.githubusercontent.com/u/4008215?v=4?s=100" width="100px;" alt="Mehul Gangavelli"/><br /><sub><b>Mehul Gangavelli</b></sub></a><br /><a href="#content-luhem7" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Frosthage"><img src="https://avatars.githubusercontent.com/u/14823314?v=4?s=100" width="100px;" alt="Mikael Frosthage"/><br /><sub><b>Mikael Frosthage</b></sub></a><br /><a href="#content-Frosthage" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://robertfry.xyz"><img src="https://avatars.githubusercontent.com/u/43712054?v=4?s=100" width="100px;" alt="Robert Fry"/><br /><sub><b>Robert Fry</b></sub></a><br /><a href="#content-robertefry" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tajo48"><img src="https://avatars.githubusercontent.com/u/55502906?v=4?s=100" width="100px;" alt="tajo48"/><br /><sub><b>tajo48</b></sub></a><br /><a href="#content-tajo48" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://anishchhetri.com.np"><img src="https://avatars.githubusercontent.com/u/98446102?v=4?s=100" width="100px;" alt="Anish"/><br /><sub><b>Anish</b></sub></a><br /><a href="#content-novanish" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/vnprc"><img src="https://avatars.githubusercontent.com/u/9425366?v=4?s=100" width="100px;" alt="vnprc"/><br /><sub><b>vnprc</b></sub></a><br /><a href="#content-vnprc" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://androecia.net"><img src="https://avatars.githubusercontent.com/u/61999256?v=4?s=100" width="100px;" alt="Joshua Carlson"/><br /><sub><b>Joshua Carlson</b></sub></a><br /><a href="#content-jrcarl624" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://johndesilencio.me"><img src="https://avatars.githubusercontent.com/u/20136554?v=4?s=100" width="100px;" alt="Nicholas R. Smith"/><br /><sub><b>Nicholas R. Smith</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=johnDeSilencio" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://alexfertel.me"><img src="https://avatars.githubusercontent.com/u/22298999?v=4?s=100" width="100px;" alt="Alexander González"/><br /><sub><b>Alexander González</b></sub></a><br /><a href="#content-alexfertel" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/softarn"><img src="https://avatars.githubusercontent.com/u/517619?v=4?s=100" width="100px;" alt="Marcus Höjvall"/><br /><sub><b>Marcus Höjvall</b></sub></a><br /><a href="#content-softarn" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/barlevalon"><img src="https://avatars.githubusercontent.com/u/3397911?v=4?s=100" width="100px;" alt="Alon Hearter"/><br /><sub><b>Alon Hearter</b></sub></a><br /><a href="#content-barlevalon" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/shirts"><img src="https://avatars.githubusercontent.com/u/4952151?v=4?s=100" width="100px;" alt="shirts"/><br /><sub><b>shirts</b></sub></a><br /><a href="#content-shirts" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/eLVas"><img src="https://avatars.githubusercontent.com/u/6797156?v=4?s=100" width="100px;" alt="Ivan Vasiunyk"/><br /><sub><b>Ivan Vasiunyk</b></sub></a><br /><a href="#content-eLVas" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://mo8it.com"><img src="https://avatars.githubusercontent.com/u/76752051?v=4?s=100" width="100px;" alt="Mo"/><br /><sub><b>Mo</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=mo8it" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/x10an14"><img src="https://avatars.githubusercontent.com/u/710608?v=4?s=100" width="100px;" alt="x10an14"/><br /><sub><b>x10an14</b></sub></a><br /><a href="#infra-x10an14" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/gabay"><img src="https://avatars.githubusercontent.com/u/5773610?v=4?s=100" width="100px;" alt="Roi Gabay"/><br /><sub><b>Roi Gabay</b></sub></a><br /><a href="#content-gabay" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/mkovaxx"><img src="https://avatars.githubusercontent.com/u/481354?v=4?s=100" width="100px;" alt="Máté Kovács"/><br /><sub><b>Máté Kovács</b></sub></a><br /><a href="#content-mkovaxx" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://szabgab.com/"><img src="https://avatars.githubusercontent.com/u/48833?v=4?s=100" width="100px;" alt="Gábor Szabó"/><br /><sub><b>Gábor Szabó</b></sub></a><br /><a href="#content-szabgab" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://moduslaborandi.net"><img src="https://avatars.githubusercontent.com/u/3340793?v=4?s=100" width="100px;" alt="Yamila Moreno"/><br /><sub><b>Yamila Moreno</b></sub></a><br /><a href="#content-yamila-moreno" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/willhack"><img src="https://avatars.githubusercontent.com/u/18036720?v=4?s=100" width="100px;" alt="Will Hack"/><br /><sub><b>Will Hack</b></sub></a><br /><a href="#content-willhack" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://cancompute.tech"><img src="https://avatars.githubusercontent.com/u/2052646?v=4?s=100" width="100px;" alt="Michael"/><br /><sub><b>Michael</b></sub></a><br /><a href="#content-bean5" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://www.sadiqpk.org"><img src="https://avatars.githubusercontent.com/u/1289514?v=4?s=100" width="100px;" alt="Mohammed Sadiq"/><br /><sub><b>Mohammed Sadiq</b></sub></a><br /><a href="#content-pksadiq" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Jak-Ch-ll"><img src="https://avatars.githubusercontent.com/u/56225668?v=4?s=100" width="100px;" alt="Jakob"/><br /><sub><b>Jakob</b></sub></a><br /><a href="#content-Jak-Ch-ll" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="http://oscarbonilla.com"><img src="https://avatars.githubusercontent.com/u/4950?v=4?s=100" width="100px;" alt="Oscar Bonilla"/><br /><sub><b>Oscar Bonilla</b></sub></a><br /><a href="#content-ob" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/husjon"><img src="https://avatars.githubusercontent.com/u/554229?v=4?s=100" width="100px;" alt="Jon Erling Hustadnes"/><br /><sub><b>Jon Erling Hustadnes</b></sub></a><br /><a href="#content-husjon" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/CobaltCause"><img src="https://avatars.githubusercontent.com/u/7003738?v=4?s=100" width="100px;" alt="Charles Hall"/><br /><sub><b>Charles Hall</b></sub></a><br /><a href="#infra-CobaltCause" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/krmpotic"><img src="https://avatars.githubusercontent.com/u/10350645?v=4?s=100" width="100px;" alt="Luka Krmpotić"/><br /><sub><b>Luka Krmpotić</b></sub></a><br /><a href="#content-krmpotic" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/jurglic"><img src="https://avatars.githubusercontent.com/u/112600?v=4?s=100" width="100px;" alt="Jurglic"/><br /><sub><b>Jurglic</b></sub></a><br /><a href="#content-jurglic" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/OfirLauber"><img src="https://avatars.githubusercontent.com/u/5631030?v=4?s=100" width="100px;" alt="Ofir Lauber"/><br /><sub><b>Ofir Lauber</b></sub></a><br /><a href="#content-OfirLauber" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/offbyone"><img src="https://avatars.githubusercontent.com/u/181693?v=4?s=100" width="100px;" alt="Chris Rose"/><br /><sub><b>Chris Rose</b></sub></a><br /><a href="#infra-offbyone" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/dieterplex"><img src="https://avatars.githubusercontent.com/u/507502?v=4?s=100" width="100px;" alt="d1t2"/><br /><sub><b>d1t2</b></sub></a><br /><a href="#infra-dieterplex" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/docwilco"><img src="https://avatars.githubusercontent.com/u/66911096?v=4?s=100" width="100px;" alt="docwilco"/><br /><sub><b>docwilco</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=docwilco" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://www.linkedin.com/in/matthew-nield1/"><img src="https://avatars.githubusercontent.com/u/64328730?v=4?s=100" width="100px;" alt="Matt Nield"/><br /><sub><b>Matt Nield</b></sub></a><br /><a href="#content-matthewjnield" title="Content">🖋</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/TheBearodactyl"><img src="https://avatars.githubusercontent.com/u/114454115?v=4?s=100" width="100px;" alt="The Bearodactyl"/><br /><sub><b>The Bearodactyl</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=TheBearodactyl" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/markgreene74"><img src="https://avatars.githubusercontent.com/u/18945890?v=4?s=100" width="100px;" alt="markgreene74"/><br /><sub><b>markgreene74</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=markgreene74" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/VeeDeltaVee"><img src="https://avatars.githubusercontent.com/u/45564258?v=4?s=100" width="100px;" alt="Versha Dhankar"/><br /><sub><b>Versha Dhankar</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=VeeDeltaVee" title="Documentation">📖</a></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<!-- markdownlint-restore -->
|
|
||||||
<!-- prettier-ignore-end -->
|
|
||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
||||||
|
|
||||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
|
161
CHANGELOG.md
161
CHANGELOG.md
|
@ -1,4 +1,157 @@
|
||||||
|
<a name="6.3.0"></a>
|
||||||
|
|
||||||
|
## 6.3.0 (2024-08-29)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add the following exercise lints:
|
||||||
|
- `forbid(unsafe_code)`: You shouldn't write unsafe code in Rustlings.
|
||||||
|
- `forbid(unstable_features)`: You don't need unstable features in Rustlings and shouldn't rely on them while learning Rust.
|
||||||
|
- `forbid(todo)`: You forgot a `todo!()`.
|
||||||
|
- `forbid(empty_loop)`: This can only happen by mistake in Rustlings.
|
||||||
|
- `deny(infinite_loop)`: No infinite loops are needed in Rustlings.
|
||||||
|
- `deny(mem_forget)`: You shouldn't leak memory while still learning Rust.
|
||||||
|
- Show a link to every exercise file in the list.
|
||||||
|
- Add scroll padding in the list.
|
||||||
|
- Break the help footer of the list into two lines when the terminal width isn't big enough.
|
||||||
|
- Enable scrolling with the mouse in the list.
|
||||||
|
- `dev check`: Show the progress of checks.
|
||||||
|
- `dev check`: Check that the length of all exercise names is lower than 32.
|
||||||
|
- `dev check`: Check if exercise contains no tests and isn't marked with `test = false`.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- The compilation time when installing Rustlings is reduced.
|
||||||
|
- Pressing `c` in the list for "continue on" now quits the list after setting the selected exercise as the current one.
|
||||||
|
- Better highlighting of the solution file after an exercise is done.
|
||||||
|
- Don't show the output of successful tests anymore. Instead, show the pretty output for tests.
|
||||||
|
- Be explicit about `q` only quitting the list and not the whole program in the list.
|
||||||
|
- Be explicit about `r` only resetting one exercise (the selected one) in the list.
|
||||||
|
- Ignore the standard output of `git init`.
|
||||||
|
- `threads3`: Remove the queue length and improve tests.
|
||||||
|
- `errors4`: Use match instead of a comparison chain in the solution.
|
||||||
|
- `functions3`: Only take `u8` to avoid using a too high number of iterations by mistake.
|
||||||
|
- `dev check`: Always check with strict Clippy (warnings to errors) when checking the solutions.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix the error on some systems about too many open files during the final check of all exercises.
|
||||||
|
- Fix the list when the terminal height is too low.
|
||||||
|
- Restore the terminal after an error in the list.
|
||||||
|
|
||||||
|
<a name="6.2.0"></a>
|
||||||
|
|
||||||
|
## 6.2.0 (2024-08-09)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Show a message before checking and running an exercise. This gives the user instant feedback and avoids confusion if the checks take too long.
|
||||||
|
- Show a helpful error message when trying to install Rustlings with a Rust version lower than the minimum one that Rustlings supports.
|
||||||
|
- Add a `README.md` file to the `solutions/` directory.
|
||||||
|
- Allow initializing Rustlings in a Cargo workspace.
|
||||||
|
- `dev check`: Check that all solutions are formatted with `rustfmt`.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Remove the state file and the solutions directory from the generated `.gitignore` file.
|
||||||
|
- Run the final check of all exercises in parallel.
|
||||||
|
- Small exercise improvements.
|
||||||
|
|
||||||
|
<a name="6.1.0"></a>
|
||||||
|
|
||||||
|
## 6.1.0 (2024-07-10)
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- `dev check`: Check that all exercises (including third-party ones) include at least one `TODO` comment.
|
||||||
|
- `dev check`: Check that all exercises actually fail to run (not already solved).
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Make enum variants more consistent between enum exercises.
|
||||||
|
- `iterators3`: Teach about the possible case of integer overflow during division.
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Exit with a helpful error message on missing/unsupported terminal/TTY.
|
||||||
|
- Mark the last exercise as done.
|
||||||
|
|
||||||
|
<a name="6.0.1"></a>
|
||||||
|
|
||||||
|
## 6.0.1 (2024-07-04)
|
||||||
|
|
||||||
|
Small exercise improvements and fixes.
|
||||||
|
Most importantly, fixed that the exercise `clippy1` was already solved 😅
|
||||||
|
|
||||||
|
<a name="6.0.0"></a>
|
||||||
|
|
||||||
|
## 6.0.0 (2024-07-03)
|
||||||
|
|
||||||
|
This release is the result of a complete rewrite to deliver a ton of new features and improvements ✨
|
||||||
|
The most important changes are highlighted below.
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
The installation has been simplified a lot!
|
||||||
|
To install Rustlings after installing Rust, all what you need to do now is running the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo install rustlings
|
||||||
|
```
|
||||||
|
|
||||||
|
Yes, this means that Rustlings is now on [crates.io](https://crates.io/crates/rustlings) 🎉
|
||||||
|
|
||||||
|
You can read about the motivations of this change in [this issue](https://github.com/rust-lang/rustlings/issues/1919).
|
||||||
|
|
||||||
|
### UI/UX
|
||||||
|
|
||||||
|
- The UI is now responsive when the terminal is resized.
|
||||||
|
- The progress bar was moved to the bottom so that you can always see your progress and the current exercise to work on.
|
||||||
|
- The current exercise path is now a terminal link. It will open the exercise file in your default editor when you click on it.
|
||||||
|
- A small prompt is now always shown at the bottom. It allows you to choose an action by entering a character. For example, entering `h` will show you the hint of the current exercise.
|
||||||
|
- The comment "I AM NOT DONE!" doesn't exist anymore. Instead of needing to remove it to go to the next exercise, you need to enter `n` in the terminal.
|
||||||
|
|
||||||
|
### List mode
|
||||||
|
|
||||||
|
A list mode was added using [Ratatui](https://ratatui.rs).
|
||||||
|
You can enter it by entering `l` in the watch mode.
|
||||||
|
It offers the following features:
|
||||||
|
|
||||||
|
- Browse all exercises and see their state (pending/done).
|
||||||
|
- Filter exercises based on their state (pending/done).
|
||||||
|
- Continue at another exercise. This allows you to skip some exercises or go back to previous ones.
|
||||||
|
- Reset an exercise so you can start over and revert your changes.
|
||||||
|
|
||||||
|
### Solutions
|
||||||
|
|
||||||
|
After finishing an exercise, a solution file will be available and Rustlings will show you its path in green.
|
||||||
|
This allows you to compare your solution with an idiomatic solution and maybe learn about other ways to solve a problem.
|
||||||
|
|
||||||
|
While writing the solutions, all exercises have been polished 🌟
|
||||||
|
For example, every exercise now contains `TODO` comments to highlight what the user needs to change and where.
|
||||||
|
|
||||||
|
### LSP support out of the box
|
||||||
|
|
||||||
|
Instead of creating a `project.json` file using `rustlings lsp`, Rustlings now works with a `Cargo.toml` file out of the box.
|
||||||
|
No actions are needed to activate the language server `rust-analyzer`.
|
||||||
|
|
||||||
|
This should avoid issues related to the language server or to running exercises, especially the ones with Clippy.
|
||||||
|
|
||||||
|
### Clippy
|
||||||
|
|
||||||
|
Clippy lints are now shown on all exercises, not only the Clippy exercises 📎
|
||||||
|
Make Clippy your friend from early on 🥰
|
||||||
|
|
||||||
|
### Third-party exercises
|
||||||
|
|
||||||
|
Rustlings now supports third-party exercises!
|
||||||
|
|
||||||
|
Do you want to create your own set of Rustlings exercises to focus on some specific topic?
|
||||||
|
Or do you want to translate the original Rustlings exercises?
|
||||||
|
Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXERCISES.md)!
|
||||||
|
|
||||||
<a name="5.6.1"></a>
|
<a name="5.6.1"></a>
|
||||||
|
|
||||||
## 5.6.1 (2023-09-18)
|
## 5.6.1 (2023-09-18)
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
|
@ -15,6 +168,7 @@
|
||||||
- `enums3`: Fixed formatting with `rustfmt`.
|
- `enums3`: Fixed formatting with `rustfmt`.
|
||||||
|
|
||||||
<a name="5.6.0"></a>
|
<a name="5.6.0"></a>
|
||||||
|
|
||||||
## 5.6.0 (2023-09-04)
|
## 5.6.0 (2023-09-04)
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
@ -30,7 +184,7 @@
|
||||||
- Swapped the order of threads and smart pointer exercises.
|
- Swapped the order of threads and smart pointer exercises.
|
||||||
- Rewrote the CLI to use `clap` - it's matured much since we switched to `argh` :)
|
- Rewrote the CLI to use `clap` - it's matured much since we switched to `argh` :)
|
||||||
- `structs3`: Switched from i32 to u32.
|
- `structs3`: Switched from i32 to u32.
|
||||||
- `move_semantics`: Switched 1-4 to tests, and rewrote them to be way simpler, while still teaching about the same
|
- `move_semantics`: Switched 1-4 to tests, and rewrote them to be way simpler, while still teaching about the same
|
||||||
concepts.
|
concepts.
|
||||||
|
|
||||||
#### Fixed
|
#### Fixed
|
||||||
|
@ -55,6 +209,7 @@
|
||||||
- Improved CI workflows, we're now testing on multiple platforms at once.
|
- Improved CI workflows, we're now testing on multiple platforms at once.
|
||||||
|
|
||||||
<a name="5.5.1"></a>
|
<a name="5.5.1"></a>
|
||||||
|
|
||||||
## 5.5.1 (2023-05-17)
|
## 5.5.1 (2023-05-17)
|
||||||
|
|
||||||
#### Fixed
|
#### Fixed
|
||||||
|
@ -62,6 +217,7 @@
|
||||||
- Reverted `rust-project.json` path generation due to an upstream `rust-analyzer` fix.
|
- Reverted `rust-project.json` path generation due to an upstream `rust-analyzer` fix.
|
||||||
|
|
||||||
<a name="5.5.0"></a>
|
<a name="5.5.0"></a>
|
||||||
|
|
||||||
## 5.5.0 (2023-05-17)
|
## 5.5.0 (2023-05-17)
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
@ -97,6 +253,7 @@
|
||||||
- Split quick installation section into two code blocks
|
- Split quick installation section into two code blocks
|
||||||
|
|
||||||
<a name="5.4.1"></a>
|
<a name="5.4.1"></a>
|
||||||
|
|
||||||
## 5.4.1 (2023-03-10)
|
## 5.4.1 (2023-03-10)
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
|
@ -167,7 +324,7 @@
|
||||||
- **structs3**: Clarifed the hint
|
- **structs3**: Clarifed the hint
|
||||||
- **quiz2, as_ref_mut, options1, traits1, traits2**: Clarified hints
|
- **quiz2, as_ref_mut, options1, traits1, traits2**: Clarified hints
|
||||||
- **traits1, traits2, cli**: Tidied up unmatching backticks
|
- **traits1, traits2, cli**: Tidied up unmatching backticks
|
||||||
- **enums2**: Removed unneccessary indirection of self
|
- **enums2**: Removed unnecessary indirection of self
|
||||||
- **enums3**: Added an extra tuple comment
|
- **enums3**: Added an extra tuple comment
|
||||||
|
|
||||||
#### Housekeeping
|
#### Housekeeping
|
||||||
|
|
153
CONTRIBUTING.md
153
CONTRIBUTING.md
|
@ -1,130 +1,61 @@
|
||||||
## Contributing to Rustlings
|
# Contributing to Rustlings
|
||||||
|
|
||||||
First off, thanks for taking the time to contribute!! ❤️
|
First off, thanks for taking the time to contribute! ❤️
|
||||||
|
|
||||||
### Quick Reference
|
## Quick Reference
|
||||||
|
|
||||||
I want to...
|
I want to …
|
||||||
|
|
||||||
_add an exercise! ➡️ [read this](#addex) and then [open a Pull Request](#prs)_
|
- _report a bug!_ ➡️ [open an issue](#issues)
|
||||||
|
- _fix a bug!_ ➡️ [open a pull request](#pull-requests)
|
||||||
|
- _implement a new feature!_ ➡️ [open an issue to discuss it first, then a pull request](#issues)
|
||||||
|
- _add an exercise!_ ➡️ [read this](#adding-an-exercise)
|
||||||
|
- _update an outdated exercise!_ ➡️ [open a pull request](#pull-requests)
|
||||||
|
|
||||||
_update an outdated exercise! ➡️ [open a Pull Request](#prs)_
|
## Issues
|
||||||
|
|
||||||
_report a bug! ➡️ [open an Issue](#issues)_
|
|
||||||
|
|
||||||
_fix a bug! ➡️ [open a Pull Request](#prs)_
|
|
||||||
|
|
||||||
_implement a new feature! ➡️ [open an Issue to discuss it first, then a Pull Request](#issues)_
|
|
||||||
|
|
||||||
<a name="#src"></a>
|
|
||||||
### Working on the source code
|
|
||||||
|
|
||||||
`rustlings` is basically a glorified `rustc` wrapper. Therefore the source code
|
|
||||||
isn't really that complicated since the bulk of the work is done by `rustc`.
|
|
||||||
`src/main.rs` contains a simple `argh` CLI that connects to most of the other source files.
|
|
||||||
|
|
||||||
<a name="addex"></a>
|
|
||||||
### Adding an exercise
|
|
||||||
|
|
||||||
The first step is to add the exercise! Name the file `exercises/yourTopic/yourTopicN.rs`, make sure to
|
|
||||||
put in some helpful links, and link to sections of the book in `exercises/yourTopic/README.md`.
|
|
||||||
|
|
||||||
Next make sure it runs with `rustlings`. The exercise metadata is stored in `info.toml`, under the `exercises` array. The order of the `exercises` array determines the order the exercises are run by `rustlings verify` and `rustlings watch`.
|
|
||||||
|
|
||||||
Add the metadata for your exercise in the correct order in the `exercises` array. If you are unsure of the correct ordering, add it at the bottom and ask in your pull request. The exercise metadata should contain the following:
|
|
||||||
```diff
|
|
||||||
...
|
|
||||||
+ [[exercises]]
|
|
||||||
+ name = "yourTopicN"
|
|
||||||
+ path = "exercises/yourTopic/yourTopicN.rs"
|
|
||||||
+ mode = "compile"
|
|
||||||
+ hint = """
|
|
||||||
+ Some kind of useful hint for your exercise."""
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
The `mode` attribute decides whether Rustlings will only compile your exercise, or compile and test it. If you have tests to verify in your exercise, choose `test`, otherwise `compile`. If you're working on a Clippy exercise, use `mode = "clippy"`.
|
|
||||||
|
|
||||||
That's all! Feel free to put up a pull request.
|
|
||||||
|
|
||||||
<a name="issues"></a>
|
|
||||||
### Issues
|
|
||||||
|
|
||||||
You can open an issue [here](https://github.com/rust-lang/rustlings/issues/new).
|
You can open an issue [here](https://github.com/rust-lang/rustlings/issues/new).
|
||||||
If you're reporting a bug, please include the output of the following commands:
|
If you're reporting a bug, please include the output of the following commands:
|
||||||
|
|
||||||
- `rustc --version`
|
- `cargo --version`
|
||||||
- `rustlings --version`
|
- `rustlings --version`
|
||||||
- `ls -la`
|
- `ls -la`
|
||||||
- Your OS name and version
|
- Your OS name and version
|
||||||
|
|
||||||
<a name="prs"></a>
|
## Pull Requests
|
||||||
### Pull Requests
|
|
||||||
|
|
||||||
Opening a pull request is as easy as forking the repository and committing your
|
You are welcome to open a pull request, but unless it is small and trivial, **please open an issue to discuss your idea first** 🙏🏼
|
||||||
changes. There's a couple of things to watch out for:
|
|
||||||
|
|
||||||
#### Write correct commit messages
|
Opening a pull request is as easy as forking the repository and committing your changes.
|
||||||
|
If you need any help with it or face any Git related problems, don't hesitate to ask for help 🤗
|
||||||
|
|
||||||
We follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4/)
|
It may take time to review your pull request.
|
||||||
specification.
|
Please be patient 😇
|
||||||
This means that you have to format your commit messages in a specific way. Say
|
|
||||||
you're working on adding a new exercise called `foobar1.rs`. You could write
|
|
||||||
the following commit message:
|
|
||||||
|
|
||||||
```
|
When updating an exercise, check if its solution needs to be updated.
|
||||||
feat: add foobar1.rs exercise
|
|
||||||
|
## Adding An Exercise
|
||||||
|
|
||||||
|
- Name the file `exercises/yourTopic/yourTopicN.rs`.
|
||||||
|
- Make sure to put in some helpful links, and link to sections of The Book in `exercises/yourTopic/README.md`.
|
||||||
|
- In the exercise, add a `// TODO: …` comment where user changes are required.
|
||||||
|
- Add a solution at `solutions/yourTopic/yourTopicN.rs` with comments explaining it.
|
||||||
|
- Add the [metadata for your exercise](#exercise-metadata) in the `rustlings-macros/info.toml` file.
|
||||||
|
- Make sure your exercise runs with `rustlings run yourTopicN`.
|
||||||
|
- [Open a pull request](#pull-requests).
|
||||||
|
|
||||||
|
### Exercise Metadata
|
||||||
|
|
||||||
|
The exercise metadata should contain the following:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[exercises]]
|
||||||
|
name = "yourTopicN"
|
||||||
|
dir = "yourTopic"
|
||||||
|
hint = """
|
||||||
|
A useful (multi-line) hint for your exercise.
|
||||||
|
Include links to a section in The Book or a documentation page."""
|
||||||
```
|
```
|
||||||
|
|
||||||
If you're just fixing a bug, please use the `fix` type:
|
If your exercise doesn't contain any test, add `test = false` to the exercise metadata.
|
||||||
|
But adding tests is recommended.
|
||||||
```
|
|
||||||
fix(verify): make sure verify doesn't self-destruct
|
|
||||||
```
|
|
||||||
|
|
||||||
The scope within the brackets is optional, but should be any of these:
|
|
||||||
|
|
||||||
- `installation` (for the installation script)
|
|
||||||
- `cli` (for general CLI changes)
|
|
||||||
- `verify` (for the verification source file)
|
|
||||||
- `watch` (for the watch functionality source)
|
|
||||||
- `run` (for the run functionality source)
|
|
||||||
- `EXERCISENAME` (if you're changing a specific exercise, or set of exercises,
|
|
||||||
substitute them here)
|
|
||||||
|
|
||||||
When the commit also happens to close an existing issue, link it in the message
|
|
||||||
body:
|
|
||||||
|
|
||||||
```
|
|
||||||
fix: update foobar
|
|
||||||
|
|
||||||
closes #101029908
|
|
||||||
```
|
|
||||||
|
|
||||||
If you're doing simple changes, like updating a book link, use `chore`:
|
|
||||||
|
|
||||||
```
|
|
||||||
chore: update exercise1.rs book link
|
|
||||||
```
|
|
||||||
|
|
||||||
If you're updating documentation, use `docs`:
|
|
||||||
|
|
||||||
```
|
|
||||||
docs: add more information to Readme
|
|
||||||
```
|
|
||||||
|
|
||||||
If, and only if, you're absolutely sure you want to make a breaking change
|
|
||||||
(please discuss this beforehand!), add an exclamation mark to the type and
|
|
||||||
explain the breaking change in the message body:
|
|
||||||
|
|
||||||
```
|
|
||||||
fix!: completely change verification
|
|
||||||
|
|
||||||
BREAKING CHANGE: This has to be done because lorem ipsum dolor
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Pull Request Workflow
|
|
||||||
|
|
||||||
Once you open a Pull Request, it may be reviewed or labeled (or both) until
|
|
||||||
the maintainers accept your change. Please be patient, it may take some time
|
|
||||||
for this to happen!
|
|
||||||
|
|
818
Cargo.lock
generated
818
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
103
Cargo.toml
103
Cargo.toml
|
@ -1,30 +1,91 @@
|
||||||
|
[workspace]
|
||||||
|
resolver = "2"
|
||||||
|
exclude = [
|
||||||
|
"tests/test_exercises",
|
||||||
|
"dev",
|
||||||
|
]
|
||||||
|
|
||||||
|
[workspace.package]
|
||||||
|
version = "6.3.0"
|
||||||
|
authors = [
|
||||||
|
"Mo Bitar <mo8it@proton.me>", # https://github.com/mo8it
|
||||||
|
"Liv <mokou@fastmail.com>", # https://github.com/shadows-withal
|
||||||
|
# Alumni
|
||||||
|
"Carol (Nichols || Goulding) <carol.nichols@gmail.com>", # https://github.com/carols10cents
|
||||||
|
]
|
||||||
|
repository = "https://github.com/rust-lang/rustlings"
|
||||||
|
license = "MIT"
|
||||||
|
edition = "2021" # On Update: Update the edition of the `rustfmt` command that checks the solutions.
|
||||||
|
rust-version = "1.80"
|
||||||
|
|
||||||
|
[workspace.dependencies]
|
||||||
|
serde = { version = "1.0.210", features = ["derive"] }
|
||||||
|
toml_edit = { version = "0.22.22", default-features = false, features = ["parse", "serde"] }
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "rustlings"
|
name = "rustlings"
|
||||||
description = "Small exercises to get you used to reading and writing Rust code!"
|
description = "Small exercises to get you used to reading and writing Rust code!"
|
||||||
version = "5.6.1"
|
version.workspace = true
|
||||||
authors = [
|
authors.workspace = true
|
||||||
"Liv <mokou@fastmail.com>",
|
repository.workspace = true
|
||||||
"Carol (Nichols || Goulding) <carol.nichols@gmail.com>",
|
license.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
rust-version.workspace = true
|
||||||
|
keywords = [
|
||||||
|
"exercise",
|
||||||
|
"learning",
|
||||||
|
]
|
||||||
|
include = [
|
||||||
|
"/src/",
|
||||||
|
"/exercises/",
|
||||||
|
"/solutions/",
|
||||||
|
# A symlink to be able to include `dev/Cargo.toml` although `dev` is excluded.
|
||||||
|
"/dev-Cargo.toml",
|
||||||
|
"/README.md",
|
||||||
|
"/LICENSE",
|
||||||
]
|
]
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
indicatif = "0.17.6"
|
ahash = { version = "0.8.11", default-features = false }
|
||||||
console = "0.15"
|
anyhow = "1.0.89"
|
||||||
notify = "4.0"
|
clap = { version = "4.5.18", features = ["derive"] }
|
||||||
toml = "0.7.6"
|
crossterm = { version = "0.28.1", default-features = false, features = ["windows", "events"] }
|
||||||
regex = "1.5"
|
notify = { version = "6.1.1", default-features = false, features = ["macos_fsevent"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
os_pipe = "1.2.1"
|
||||||
serde_json = "1.0.81"
|
rustlings-macros = { path = "rustlings-macros", version = "=6.3.0" }
|
||||||
home = "0.5.3"
|
serde_json = "1.0.128"
|
||||||
glob = "0.3.0"
|
serde.workspace = true
|
||||||
clap = { version = "4.4.0", features = ["derive"] }
|
toml_edit.workspace = true
|
||||||
|
|
||||||
[[bin]]
|
[target.'cfg(not(windows))'.dependencies]
|
||||||
name = "rustlings"
|
rustix = { version = "0.38.37", default-features = false, features = ["std", "stdio", "termios"] }
|
||||||
path = "src/main.rs"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_cmd = "2.0.12"
|
tempfile = "3.12.0"
|
||||||
predicates = "3.0.3"
|
|
||||||
glob = "0.3.0"
|
[profile.release]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[package.metadata.release]
|
||||||
|
pre-release-hook = ["./release-hook.sh"]
|
||||||
|
|
||||||
|
[workspace.lints.rust]
|
||||||
|
unsafe_code = "forbid"
|
||||||
|
unstable_features = "forbid"
|
||||||
|
|
||||||
|
[workspace.lints.clippy]
|
||||||
|
empty_loop = "forbid"
|
||||||
|
disallowed-types = "deny"
|
||||||
|
disallowed-methods = "deny"
|
||||||
|
infinite_loop = "deny"
|
||||||
|
mem_forget = "deny"
|
||||||
|
dbg_macro = "warn"
|
||||||
|
todo = "warn"
|
||||||
|
# TODO: Remove after the following fix is released: https://github.com/rust-lang/rust-clippy/pull/13102
|
||||||
|
needless_option_as_deref = "allow"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
210
README.md
210
README.md
|
@ -1,180 +1,156 @@
|
||||||
<div class="oranda-hide">
|
<div class="oranda-hide">
|
||||||
|
|
||||||
# rustlings 🦀❤️
|
# Rustlings 🦀❤️
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Greetings and welcome to `rustlings`. This project contains small exercises to get you used to reading and writing Rust code. This includes reading and responding to compiler messages!
|
Greetings and welcome to Rustlings.
|
||||||
|
This project contains small exercises to get you used to reading and writing Rust code.
|
||||||
|
This includes reading and responding to compiler messages!
|
||||||
|
|
||||||
_...looking for the old, web-based version of Rustlings? Try [here](https://github.com/rust-lang/rustlings/tree/rustlings-1)_
|
It is recommended to do the Rustlings exercises in parallel to reading [the official Rust book](https://doc.rust-lang.org/book/), the most comprehensive resource for learning Rust 📚️
|
||||||
|
|
||||||
Alternatively, for a first-time Rust learner, there are several other resources:
|
[Rust By Example](https://doc.rust-lang.org/rust-by-example/) is another recommended resource that you might find helpful.
|
||||||
|
It contains code examples and exercises similar to Rustlings, but online.
|
||||||
- [The Book](https://doc.rust-lang.org/book/index.html) - The most comprehensive resource for learning Rust, but a bit theoretical sometimes. You will be using this along with Rustlings!
|
|
||||||
- [Rust By Example](https://doc.rust-lang.org/rust-by-example/index.html) - Learn Rust by solving little exercises! It's almost like `rustlings`, but online
|
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
_Note: If you're on MacOS, make sure you've installed Xcode and its developer tools by typing `xcode-select --install`._
|
### Installing Rust
|
||||||
_Note: If you're on Linux, make sure you've installed gcc. Deb: `sudo apt install gcc`. Yum: `sudo yum -y install gcc`._
|
|
||||||
|
|
||||||
You will need to have Rust installed. You can get it by visiting <https://rustup.rs>. This'll also install Cargo, Rust's package/project manager.
|
Before installing Rustlings, you need to have the **latest version of Rust** installed.
|
||||||
|
Visit [www.rust-lang.org/tools/install](https://www.rust-lang.org/tools/install) for further instructions on installing Rust.
|
||||||
|
This will also install _Cargo_, Rust's package/project manager.
|
||||||
|
|
||||||
## MacOS/Linux
|
> 🐧 If you're on Linux, make sure you've installed `gcc` (for a linker).
|
||||||
|
>
|
||||||
|
> Deb: `sudo apt install gcc`.
|
||||||
|
> Dnf: `sudo dnf install gcc`.
|
||||||
|
|
||||||
Just run:
|
> 🍎 If you're on MacOS, make sure you've installed Xcode and its developer tools by running `xcode-select --install`.
|
||||||
|
|
||||||
|
### Installing Rustlings
|
||||||
|
|
||||||
|
The following command will download and compile Rustlings:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -L sh.rustlings.cool | bash
|
cargo install rustlings
|
||||||
```
|
```
|
||||||
|
|
||||||
Or if you want it to be installed to a different path:
|
<details>
|
||||||
|
<summary><strong>If the installation fails…</strong> (<em>click to expand</em>)</summary>
|
||||||
|
|
||||||
|
- Make sure you have the latest Rust version by running `rustup update`
|
||||||
|
- Try adding the `--locked` flag: `cargo install rustlings --locked`
|
||||||
|
- Otherwise, please [report the issue](https://github.com/rust-lang/rustlings/issues/new)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Initialization
|
||||||
|
|
||||||
|
After installing Rustlings, run the following command to initialize the `rustlings/` directory:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -L sh.rustlings.cool | bash -s mypath/
|
rustlings init
|
||||||
```
|
```
|
||||||
|
|
||||||
This will install Rustlings and give you access to the `rustlings` command. Run it to get started!
|
<details>
|
||||||
|
<summary><strong>If the command <code>rustlings</code> can't be found…</strong> (<em>click to expand</em>)</summary>
|
||||||
|
|
||||||
### Nix
|
You are probably using Linux and installed Rust using your package manager.
|
||||||
|
|
||||||
Basically: Clone the repository at the latest tag, finally run `nix develop` or `nix-shell`.
|
Cargo installs binaries to the directory `~/.cargo/bin`.
|
||||||
|
Sadly, package managers often don't add `~/.cargo/bin` to your `PATH` environment variable.
|
||||||
|
|
||||||
|
The solution is to …
|
||||||
|
|
||||||
|
- either add `~/.cargo/bin` manually to `PATH`
|
||||||
|
- or to uninstall Rust from the package manager and install it using the official way with `rustup`: https://www.rust-lang.org/tools/install
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
Now, go into the newly initialized directory and launch Rustlings for further instructions on getting started with the exercises:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.6.1)
|
cd rustlings/
|
||||||
git clone -b 5.6.1 --depth 1 https://github.com/rust-lang/rustlings
|
rustlings
|
||||||
cd rustlings
|
|
||||||
# if nix version > 2.3
|
|
||||||
nix develop
|
|
||||||
# if nix version <= 2.3
|
|
||||||
nix-shell
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Windows
|
## Working environment
|
||||||
|
|
||||||
In PowerShell (Run as Administrator), set `ExecutionPolicy` to `RemoteSigned`:
|
### Editor
|
||||||
|
|
||||||
```ps1
|
Our general recommendation is [VS Code](https://code.visualstudio.com/) with the [rust-analyzer plugin](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer).
|
||||||
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
But any editor that supports [rust-analyzer](https://rust-analyzer.github.io/) should be enough for working on the exercises.
|
||||||
```
|
|
||||||
|
|
||||||
Then, you can run:
|
### Terminal
|
||||||
|
|
||||||
```ps1
|
While working with Rustlings, please use a modern terminal for the best user experience.
|
||||||
Start-BitsTransfer -Source https://ps1.rustlings.cool -Destination $env:TMP/install_rustlings.ps1; Unblock-File $env:TMP/install_rustlings.ps1; Invoke-Expression $env:TMP/install_rustlings.ps1
|
The default terminal on Linux and Mac should be sufficient.
|
||||||
```
|
On Windows, we recommend the [Windows Terminal](https://aka.ms/terminal).
|
||||||
|
|
||||||
To install Rustlings. Same as on MacOS/Linux, you will have access to the `rustlings` command after it. Keep in mind that this works best in PowerShell, and any other terminals may give you errors.
|
|
||||||
|
|
||||||
If you get a permission denied message, you might have to exclude the directory where you cloned Rustlings in your antivirus.
|
|
||||||
|
|
||||||
## Browser
|
|
||||||
|
|
||||||
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/rust-lang/rustlings)
|
|
||||||
|
|
||||||
[![Open Rustlings On Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new/?repo=rust-lang%2Frustlings&ref=main)
|
|
||||||
|
|
||||||
## Manually
|
|
||||||
|
|
||||||
Basically: Clone the repository at the latest tag, run `cargo install --path .`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.6.1)
|
|
||||||
git clone -b 5.6.1 --depth 1 https://github.com/rust-lang/rustlings
|
|
||||||
cd rustlings
|
|
||||||
cargo install --force --path .
|
|
||||||
```
|
|
||||||
|
|
||||||
If there are installation errors, ensure that your toolchain is up to date. For the latest, run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rustup update
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, same as above, run `rustlings` to get started.
|
|
||||||
|
|
||||||
## Doing exercises
|
## Doing exercises
|
||||||
|
|
||||||
The exercises are sorted by topic and can be found in the subdirectory `rustlings/exercises/<topic>`. For every topic there is an additional README file with some resources to get you started on the topic. We really recommend that you have a look at them before you start.
|
The exercises are sorted by topic and can be found in the subdirectory `exercises/<topic>`.
|
||||||
|
For every topic, there is an additional `README.md` file with some resources to get you started on the topic.
|
||||||
|
We highly recommend that you have a look at them before you start 📚️
|
||||||
|
|
||||||
The task is simple. Most exercises contain an error that keeps them from compiling, and it's up to you to fix it! Some exercises are also run as tests, but rustlings handles them all the same. To run the exercises in the recommended order, execute:
|
Most exercises contain an error that keeps them from compiling, and it's up to you to fix it!
|
||||||
|
Some exercises contain tests that need to pass for the exercise to be done ✅
|
||||||
|
|
||||||
```bash
|
Search for `TODO` and `todo!()` to find out what you need to change.
|
||||||
rustlings watch
|
Ask for hints by entering `h` in the _watch mode_ 💡
|
||||||
```
|
|
||||||
|
|
||||||
This will try to verify the completion of every exercise in a predetermined order (what we think is best for newcomers). It will also rerun automatically every time you change a file in the `exercises/` directory. If you want to only run it once, you can use:
|
### Watch Mode
|
||||||
|
|
||||||
```bash
|
After [initialization](#initialization), Rustlings can be launched by simply running the command `rustlings`.
|
||||||
rustlings verify
|
|
||||||
```
|
|
||||||
|
|
||||||
This will do the same as watch, but it'll quit after running.
|
This will start the _watch mode_ which walks you through the exercises in a predefined order (what we think is best for newcomers).
|
||||||
|
It will rerun the current exercise automatically every time you change the exercise's file in the `exercises/` directory.
|
||||||
|
|
||||||
In case you want to go by your own order, or want to only verify a single exercise, you can run:
|
<details>
|
||||||
|
<summary><strong>If detecting file changes in the <code>exercises/</code> directory fails…</strong> (<em>click to expand</em>)</summary>
|
||||||
|
|
||||||
```bash
|
> You can add the **`--manual-run`** flag (`rustlings --manual-run`) to manually rerun the current exercise by entering `r` in the watch mode.
|
||||||
rustlings run myExercise1
|
>
|
||||||
```
|
> Please [report the issue](https://github.com/rust-lang/rustlings/issues/new) with some information about your operating system and whether you run Rustlings in a container or virtual machine (e.g. WSL).
|
||||||
|
|
||||||
Or simply use the following command to run the next unsolved exercise in the course:
|
</details>
|
||||||
|
|
||||||
```bash
|
### Exercise List
|
||||||
rustlings run next
|
|
||||||
```
|
|
||||||
|
|
||||||
In case you get stuck, you can run the following command to get a hint for your
|
In the [watch mode](#watch-mode) (after launching `rustlings`), you can enter `l` to open the interactive exercise list.
|
||||||
exercise:
|
|
||||||
|
|
||||||
```bash
|
The list allows you to…
|
||||||
rustlings hint myExercise1
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also get the hint for the next unsolved exercise with the following command:
|
- See the status of all exercises (done or pending)
|
||||||
|
- `c`: Continue at another exercise (temporarily skip some exercises or go back to a previous one)
|
||||||
|
- `r`: Reset status and file of an exercise (you need to _reload/reopen_ its file in your editor afterwards)
|
||||||
|
|
||||||
```bash
|
See the footer of the list for all possible keys.
|
||||||
rustlings hint next
|
|
||||||
```
|
|
||||||
|
|
||||||
To check your progress, you can run the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rustlings list
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing yourself
|
|
||||||
|
|
||||||
After every couple of sections, there will be a quiz that'll test your knowledge on a bunch of sections at once. These quizzes are found in `exercises/quizN.rs`.
|
|
||||||
|
|
||||||
## Enabling `rust-analyzer`
|
|
||||||
|
|
||||||
Run the command `rustlings lsp` which will generate a `rust-project.json` at the root of the project, this allows [rust-analyzer](https://rust-analyzer.github.io/) to parse each exercise.
|
|
||||||
|
|
||||||
## Continuing On
|
## Continuing On
|
||||||
|
|
||||||
Once you've completed Rustlings, put your new knowledge to good use! Continue practicing your Rust skills by building your own projects, contributing to Rustlings, or finding other open-source projects to contribute to.
|
Once you've completed Rustlings, put your new knowledge to good use!
|
||||||
|
Continue practicing your Rust skills by building your own projects, contributing to Rustlings, or finding other open-source projects to contribute to.
|
||||||
|
|
||||||
|
## Third-Party Exercises
|
||||||
|
|
||||||
|
Do you want to create your own set of Rustlings exercises to focus on some specific topic?
|
||||||
|
Or do you want to translate the original Rustlings exercises?
|
||||||
|
Then follow the link to the guide about [third-party exercises](https://github.com/rust-lang/rustlings/blob/main/THIRD_PARTY_EXERCISES.md)!
|
||||||
|
|
||||||
## Uninstalling Rustlings
|
## Uninstalling Rustlings
|
||||||
|
|
||||||
If you want to remove Rustlings from your system, there are two steps. First, you'll need to remove the exercises folder that the install script created
|
If you want to remove Rustlings from your system, run the following command:
|
||||||
for you:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rm -rf rustlings # or your custom folder name, if you chose and or renamed it
|
|
||||||
```
|
|
||||||
|
|
||||||
Second, run `cargo uninstall` to remove the `rustlings` binary:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo uninstall rustlings
|
cargo uninstall rustlings
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you should be done!
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
See [CONTRIBUTING.md](https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md).
|
See [CONTRIBUTING.md](https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md) 🔗
|
||||||
|
|
||||||
## Contributors ✨
|
## Contributors ✨
|
||||||
|
|
||||||
Thanks goes to the wonderful people listed in [AUTHORS.md](https://github.com/rust-lang/rustlings/blob/main/AUTHORS.md) 🎉
|
Thanks to [all the wonderful contributors](https://github.com/rust-lang/rustlings/graphs/contributors) 🎉
|
||||||
|
|
53
THIRD_PARTY_EXERCISES.md
Normal file
53
THIRD_PARTY_EXERCISES.md
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# Third-Party Exercises
|
||||||
|
|
||||||
|
The support of Rustlings for third-party exercises allows you to create your own set of Rustlings exercises to focus on some specific topic.
|
||||||
|
You could also offer a translation of the original Rustlings exercises as third-party exercises.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
To create third-party exercises, install Rustlings and run `rustlings dev new PROJECT_NAME`.
|
||||||
|
This command will, similar to `cargo new PROJECT_NAME`, create a template directory called `PROJECT_NAME` with all what you need to get started.
|
||||||
|
|
||||||
|
Read the comments in the generated `info.toml` file to understand its format.
|
||||||
|
It allows you to set a custom welcome and final message and specify the metadata of every exercise.
|
||||||
|
|
||||||
|
## Create an exercise
|
||||||
|
|
||||||
|
Here is an example of the metadata of one file:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[exercises]]
|
||||||
|
name = "intro1"
|
||||||
|
hint = """
|
||||||
|
To finish this exercise, you need to …
|
||||||
|
This link might help you …"""
|
||||||
|
```
|
||||||
|
|
||||||
|
After entering this in `info.toml`, create the file `intro1.rs` in the `exercises/` directory.
|
||||||
|
The exercise needs to contain a `main` function, but it can be empty.
|
||||||
|
Adding tests is recommended.
|
||||||
|
Look at the official Rustlings exercises for inspiration.
|
||||||
|
|
||||||
|
You can optionally add a solution file `intro1.rs` to the `solutions/` directory.
|
||||||
|
|
||||||
|
Now, run `rustlings dev check`.
|
||||||
|
It will tell you about any issues with your exercises.
|
||||||
|
For example, it will tell you to run `rustlings dev update` to update the `Cargo.toml` file to include the new exercise `intro1`.
|
||||||
|
|
||||||
|
`rustlings dev check` will also run your solutions (if you have any) to make sure that they run successfully.
|
||||||
|
|
||||||
|
That's it!
|
||||||
|
You finished your first exercise 🎉
|
||||||
|
|
||||||
|
## Publish
|
||||||
|
|
||||||
|
Now, add more exercises and publish them as a Git repository.
|
||||||
|
|
||||||
|
Users just have to clone that repository and run `rustlings` in it to start working on your set of exercises just like the official ones.
|
||||||
|
|
||||||
|
One difference to the official exercises is that the solution files will not be hidden until the user finishes an exercise.
|
||||||
|
But you can trust the users to not look at the solution too early 😉
|
||||||
|
|
||||||
|
## Share
|
||||||
|
|
||||||
|
After publishing your set of exercises, open an issue or a pull request in the official Rustlings repository to link to your project in the README 😃
|
16
clippy.toml
Normal file
16
clippy.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
disallowed-types = [
|
||||||
|
# Inefficient. Use `.queue(…)` instead.
|
||||||
|
"crossterm::style::Stylize",
|
||||||
|
"crossterm::style::styled_content::StyledContent",
|
||||||
|
]
|
||||||
|
|
||||||
|
disallowed-methods = [
|
||||||
|
# We use `ahash` instead of the default hasher.
|
||||||
|
"std::collections::HashSet::new",
|
||||||
|
"std::collections::HashSet::with_capacity",
|
||||||
|
# Inefficient. Use `.queue(…)` instead.
|
||||||
|
"crossterm::style::style",
|
||||||
|
# Use `thread::Builder::spawn` instead and handle the error.
|
||||||
|
"std::thread::spawn",
|
||||||
|
"std::thread::Scope::spawn",
|
||||||
|
]
|
1
dev-Cargo.toml
Symbolic link
1
dev-Cargo.toml
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
dev/Cargo.toml
|
227
dev/Cargo.toml
Normal file
227
dev/Cargo.toml
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
# Don't edit the `bin` list manually! It is updated by `cargo run -- dev update`. This comment line will be stripped in `rustlings init`.
|
||||||
|
bin = [
|
||||||
|
{ name = "intro1", path = "../exercises/00_intro/intro1.rs" },
|
||||||
|
{ name = "intro1_sol", path = "../solutions/00_intro/intro1.rs" },
|
||||||
|
{ name = "intro2", path = "../exercises/00_intro/intro2.rs" },
|
||||||
|
{ name = "intro2_sol", path = "../solutions/00_intro/intro2.rs" },
|
||||||
|
{ name = "variables1", path = "../exercises/01_variables/variables1.rs" },
|
||||||
|
{ name = "variables1_sol", path = "../solutions/01_variables/variables1.rs" },
|
||||||
|
{ name = "variables2", path = "../exercises/01_variables/variables2.rs" },
|
||||||
|
{ name = "variables2_sol", path = "../solutions/01_variables/variables2.rs" },
|
||||||
|
{ name = "variables3", path = "../exercises/01_variables/variables3.rs" },
|
||||||
|
{ name = "variables3_sol", path = "../solutions/01_variables/variables3.rs" },
|
||||||
|
{ name = "variables4", path = "../exercises/01_variables/variables4.rs" },
|
||||||
|
{ name = "variables4_sol", path = "../solutions/01_variables/variables4.rs" },
|
||||||
|
{ name = "variables5", path = "../exercises/01_variables/variables5.rs" },
|
||||||
|
{ name = "variables5_sol", path = "../solutions/01_variables/variables5.rs" },
|
||||||
|
{ name = "variables6", path = "../exercises/01_variables/variables6.rs" },
|
||||||
|
{ name = "variables6_sol", path = "../solutions/01_variables/variables6.rs" },
|
||||||
|
{ name = "functions1", path = "../exercises/02_functions/functions1.rs" },
|
||||||
|
{ name = "functions1_sol", path = "../solutions/02_functions/functions1.rs" },
|
||||||
|
{ name = "functions2", path = "../exercises/02_functions/functions2.rs" },
|
||||||
|
{ name = "functions2_sol", path = "../solutions/02_functions/functions2.rs" },
|
||||||
|
{ name = "functions3", path = "../exercises/02_functions/functions3.rs" },
|
||||||
|
{ name = "functions3_sol", path = "../solutions/02_functions/functions3.rs" },
|
||||||
|
{ name = "functions4", path = "../exercises/02_functions/functions4.rs" },
|
||||||
|
{ name = "functions4_sol", path = "../solutions/02_functions/functions4.rs" },
|
||||||
|
{ name = "functions5", path = "../exercises/02_functions/functions5.rs" },
|
||||||
|
{ name = "functions5_sol", path = "../solutions/02_functions/functions5.rs" },
|
||||||
|
{ name = "functions6", path = "../exercises/02_functions/functions6.rs" },
|
||||||
|
{ name = "functions6_sol", path = "../solutions/02_functions/functions6.rs" },
|
||||||
|
{ name = "if1", path = "../exercises/03_if/if1.rs" },
|
||||||
|
{ name = "if1_sol", path = "../solutions/03_if/if1.rs" },
|
||||||
|
{ name = "if2", path = "../exercises/03_if/if2.rs" },
|
||||||
|
{ name = "if2_sol", path = "../solutions/03_if/if2.rs" },
|
||||||
|
{ name = "if3", path = "../exercises/03_if/if3.rs" },
|
||||||
|
{ name = "if3_sol", path = "../solutions/03_if/if3.rs" },
|
||||||
|
{ name = "quiz1", path = "../exercises/quizzes/quiz1.rs" },
|
||||||
|
{ name = "quiz1_sol", path = "../solutions/quizzes/quiz1.rs" },
|
||||||
|
{ name = "primitive_types1", path = "../exercises/04_primitive_types/primitive_types1.rs" },
|
||||||
|
{ name = "primitive_types1_sol", path = "../solutions/04_primitive_types/primitive_types1.rs" },
|
||||||
|
{ name = "primitive_types2", path = "../exercises/04_primitive_types/primitive_types2.rs" },
|
||||||
|
{ name = "primitive_types2_sol", path = "../solutions/04_primitive_types/primitive_types2.rs" },
|
||||||
|
{ name = "primitive_types3", path = "../exercises/04_primitive_types/primitive_types3.rs" },
|
||||||
|
{ name = "primitive_types3_sol", path = "../solutions/04_primitive_types/primitive_types3.rs" },
|
||||||
|
{ name = "primitive_types4", path = "../exercises/04_primitive_types/primitive_types4.rs" },
|
||||||
|
{ name = "primitive_types4_sol", path = "../solutions/04_primitive_types/primitive_types4.rs" },
|
||||||
|
{ name = "primitive_types5", path = "../exercises/04_primitive_types/primitive_types5.rs" },
|
||||||
|
{ name = "primitive_types5_sol", path = "../solutions/04_primitive_types/primitive_types5.rs" },
|
||||||
|
{ name = "primitive_types6", path = "../exercises/04_primitive_types/primitive_types6.rs" },
|
||||||
|
{ name = "primitive_types6_sol", path = "../solutions/04_primitive_types/primitive_types6.rs" },
|
||||||
|
{ name = "vecs1", path = "../exercises/05_vecs/vecs1.rs" },
|
||||||
|
{ name = "vecs1_sol", path = "../solutions/05_vecs/vecs1.rs" },
|
||||||
|
{ name = "vecs2", path = "../exercises/05_vecs/vecs2.rs" },
|
||||||
|
{ name = "vecs2_sol", path = "../solutions/05_vecs/vecs2.rs" },
|
||||||
|
{ name = "move_semantics1", path = "../exercises/06_move_semantics/move_semantics1.rs" },
|
||||||
|
{ name = "move_semantics1_sol", path = "../solutions/06_move_semantics/move_semantics1.rs" },
|
||||||
|
{ name = "move_semantics2", path = "../exercises/06_move_semantics/move_semantics2.rs" },
|
||||||
|
{ name = "move_semantics2_sol", path = "../solutions/06_move_semantics/move_semantics2.rs" },
|
||||||
|
{ name = "move_semantics3", path = "../exercises/06_move_semantics/move_semantics3.rs" },
|
||||||
|
{ name = "move_semantics3_sol", path = "../solutions/06_move_semantics/move_semantics3.rs" },
|
||||||
|
{ name = "move_semantics4", path = "../exercises/06_move_semantics/move_semantics4.rs" },
|
||||||
|
{ name = "move_semantics4_sol", path = "../solutions/06_move_semantics/move_semantics4.rs" },
|
||||||
|
{ name = "move_semantics5", path = "../exercises/06_move_semantics/move_semantics5.rs" },
|
||||||
|
{ name = "move_semantics5_sol", path = "../solutions/06_move_semantics/move_semantics5.rs" },
|
||||||
|
{ name = "move_semantics6", path = "../exercises/06_move_semantics/move_semantics6.rs" },
|
||||||
|
{ name = "move_semantics6_sol", path = "../solutions/06_move_semantics/move_semantics6.rs" },
|
||||||
|
{ name = "structs1", path = "../exercises/07_structs/structs1.rs" },
|
||||||
|
{ name = "structs1_sol", path = "../solutions/07_structs/structs1.rs" },
|
||||||
|
{ name = "structs2", path = "../exercises/07_structs/structs2.rs" },
|
||||||
|
{ name = "structs2_sol", path = "../solutions/07_structs/structs2.rs" },
|
||||||
|
{ name = "structs3", path = "../exercises/07_structs/structs3.rs" },
|
||||||
|
{ name = "structs3_sol", path = "../solutions/07_structs/structs3.rs" },
|
||||||
|
{ name = "enums1", path = "../exercises/08_enums/enums1.rs" },
|
||||||
|
{ name = "enums1_sol", path = "../solutions/08_enums/enums1.rs" },
|
||||||
|
{ name = "enums2", path = "../exercises/08_enums/enums2.rs" },
|
||||||
|
{ name = "enums2_sol", path = "../solutions/08_enums/enums2.rs" },
|
||||||
|
{ name = "enums3", path = "../exercises/08_enums/enums3.rs" },
|
||||||
|
{ name = "enums3_sol", path = "../solutions/08_enums/enums3.rs" },
|
||||||
|
{ name = "strings1", path = "../exercises/09_strings/strings1.rs" },
|
||||||
|
{ name = "strings1_sol", path = "../solutions/09_strings/strings1.rs" },
|
||||||
|
{ name = "strings2", path = "../exercises/09_strings/strings2.rs" },
|
||||||
|
{ name = "strings2_sol", path = "../solutions/09_strings/strings2.rs" },
|
||||||
|
{ name = "strings3", path = "../exercises/09_strings/strings3.rs" },
|
||||||
|
{ name = "strings3_sol", path = "../solutions/09_strings/strings3.rs" },
|
||||||
|
{ name = "strings4", path = "../exercises/09_strings/strings4.rs" },
|
||||||
|
{ name = "strings4_sol", path = "../solutions/09_strings/strings4.rs" },
|
||||||
|
{ name = "modules1", path = "../exercises/10_modules/modules1.rs" },
|
||||||
|
{ name = "modules1_sol", path = "../solutions/10_modules/modules1.rs" },
|
||||||
|
{ name = "modules2", path = "../exercises/10_modules/modules2.rs" },
|
||||||
|
{ name = "modules2_sol", path = "../solutions/10_modules/modules2.rs" },
|
||||||
|
{ name = "modules3", path = "../exercises/10_modules/modules3.rs" },
|
||||||
|
{ name = "modules3_sol", path = "../solutions/10_modules/modules3.rs" },
|
||||||
|
{ name = "hashmaps1", path = "../exercises/11_hashmaps/hashmaps1.rs" },
|
||||||
|
{ name = "hashmaps1_sol", path = "../solutions/11_hashmaps/hashmaps1.rs" },
|
||||||
|
{ name = "hashmaps2", path = "../exercises/11_hashmaps/hashmaps2.rs" },
|
||||||
|
{ name = "hashmaps2_sol", path = "../solutions/11_hashmaps/hashmaps2.rs" },
|
||||||
|
{ name = "hashmaps3", path = "../exercises/11_hashmaps/hashmaps3.rs" },
|
||||||
|
{ name = "hashmaps3_sol", path = "../solutions/11_hashmaps/hashmaps3.rs" },
|
||||||
|
{ name = "quiz2", path = "../exercises/quizzes/quiz2.rs" },
|
||||||
|
{ name = "quiz2_sol", path = "../solutions/quizzes/quiz2.rs" },
|
||||||
|
{ name = "options1", path = "../exercises/12_options/options1.rs" },
|
||||||
|
{ name = "options1_sol", path = "../solutions/12_options/options1.rs" },
|
||||||
|
{ name = "options2", path = "../exercises/12_options/options2.rs" },
|
||||||
|
{ name = "options2_sol", path = "../solutions/12_options/options2.rs" },
|
||||||
|
{ name = "options3", path = "../exercises/12_options/options3.rs" },
|
||||||
|
{ name = "options3_sol", path = "../solutions/12_options/options3.rs" },
|
||||||
|
{ name = "errors1", path = "../exercises/13_error_handling/errors1.rs" },
|
||||||
|
{ name = "errors1_sol", path = "../solutions/13_error_handling/errors1.rs" },
|
||||||
|
{ name = "errors2", path = "../exercises/13_error_handling/errors2.rs" },
|
||||||
|
{ name = "errors2_sol", path = "../solutions/13_error_handling/errors2.rs" },
|
||||||
|
{ name = "errors3", path = "../exercises/13_error_handling/errors3.rs" },
|
||||||
|
{ name = "errors3_sol", path = "../solutions/13_error_handling/errors3.rs" },
|
||||||
|
{ name = "errors4", path = "../exercises/13_error_handling/errors4.rs" },
|
||||||
|
{ name = "errors4_sol", path = "../solutions/13_error_handling/errors4.rs" },
|
||||||
|
{ name = "errors5", path = "../exercises/13_error_handling/errors5.rs" },
|
||||||
|
{ name = "errors5_sol", path = "../solutions/13_error_handling/errors5.rs" },
|
||||||
|
{ name = "errors6", path = "../exercises/13_error_handling/errors6.rs" },
|
||||||
|
{ name = "errors6_sol", path = "../solutions/13_error_handling/errors6.rs" },
|
||||||
|
{ name = "generics1", path = "../exercises/14_generics/generics1.rs" },
|
||||||
|
{ name = "generics1_sol", path = "../solutions/14_generics/generics1.rs" },
|
||||||
|
{ name = "generics2", path = "../exercises/14_generics/generics2.rs" },
|
||||||
|
{ name = "generics2_sol", path = "../solutions/14_generics/generics2.rs" },
|
||||||
|
{ name = "traits1", path = "../exercises/15_traits/traits1.rs" },
|
||||||
|
{ name = "traits1_sol", path = "../solutions/15_traits/traits1.rs" },
|
||||||
|
{ name = "traits2", path = "../exercises/15_traits/traits2.rs" },
|
||||||
|
{ name = "traits2_sol", path = "../solutions/15_traits/traits2.rs" },
|
||||||
|
{ name = "traits3", path = "../exercises/15_traits/traits3.rs" },
|
||||||
|
{ name = "traits3_sol", path = "../solutions/15_traits/traits3.rs" },
|
||||||
|
{ name = "traits4", path = "../exercises/15_traits/traits4.rs" },
|
||||||
|
{ name = "traits4_sol", path = "../solutions/15_traits/traits4.rs" },
|
||||||
|
{ name = "traits5", path = "../exercises/15_traits/traits5.rs" },
|
||||||
|
{ name = "traits5_sol", path = "../solutions/15_traits/traits5.rs" },
|
||||||
|
{ name = "quiz3", path = "../exercises/quizzes/quiz3.rs" },
|
||||||
|
{ name = "quiz3_sol", path = "../solutions/quizzes/quiz3.rs" },
|
||||||
|
{ name = "lifetimes1", path = "../exercises/16_lifetimes/lifetimes1.rs" },
|
||||||
|
{ name = "lifetimes1_sol", path = "../solutions/16_lifetimes/lifetimes1.rs" },
|
||||||
|
{ name = "lifetimes2", path = "../exercises/16_lifetimes/lifetimes2.rs" },
|
||||||
|
{ name = "lifetimes2_sol", path = "../solutions/16_lifetimes/lifetimes2.rs" },
|
||||||
|
{ name = "lifetimes3", path = "../exercises/16_lifetimes/lifetimes3.rs" },
|
||||||
|
{ name = "lifetimes3_sol", path = "../solutions/16_lifetimes/lifetimes3.rs" },
|
||||||
|
{ name = "tests1", path = "../exercises/17_tests/tests1.rs" },
|
||||||
|
{ name = "tests1_sol", path = "../solutions/17_tests/tests1.rs" },
|
||||||
|
{ name = "tests2", path = "../exercises/17_tests/tests2.rs" },
|
||||||
|
{ name = "tests2_sol", path = "../solutions/17_tests/tests2.rs" },
|
||||||
|
{ name = "tests3", path = "../exercises/17_tests/tests3.rs" },
|
||||||
|
{ name = "tests3_sol", path = "../solutions/17_tests/tests3.rs" },
|
||||||
|
{ name = "iterators1", path = "../exercises/18_iterators/iterators1.rs" },
|
||||||
|
{ name = "iterators1_sol", path = "../solutions/18_iterators/iterators1.rs" },
|
||||||
|
{ name = "iterators2", path = "../exercises/18_iterators/iterators2.rs" },
|
||||||
|
{ name = "iterators2_sol", path = "../solutions/18_iterators/iterators2.rs" },
|
||||||
|
{ name = "iterators3", path = "../exercises/18_iterators/iterators3.rs" },
|
||||||
|
{ name = "iterators3_sol", path = "../solutions/18_iterators/iterators3.rs" },
|
||||||
|
{ name = "iterators4", path = "../exercises/18_iterators/iterators4.rs" },
|
||||||
|
{ name = "iterators4_sol", path = "../solutions/18_iterators/iterators4.rs" },
|
||||||
|
{ name = "iterators5", path = "../exercises/18_iterators/iterators5.rs" },
|
||||||
|
{ name = "iterators5_sol", path = "../solutions/18_iterators/iterators5.rs" },
|
||||||
|
{ name = "box1", path = "../exercises/19_smart_pointers/box1.rs" },
|
||||||
|
{ name = "box1_sol", path = "../solutions/19_smart_pointers/box1.rs" },
|
||||||
|
{ name = "rc1", path = "../exercises/19_smart_pointers/rc1.rs" },
|
||||||
|
{ name = "rc1_sol", path = "../solutions/19_smart_pointers/rc1.rs" },
|
||||||
|
{ name = "arc1", path = "../exercises/19_smart_pointers/arc1.rs" },
|
||||||
|
{ name = "arc1_sol", path = "../solutions/19_smart_pointers/arc1.rs" },
|
||||||
|
{ name = "cow1", path = "../exercises/19_smart_pointers/cow1.rs" },
|
||||||
|
{ name = "cow1_sol", path = "../solutions/19_smart_pointers/cow1.rs" },
|
||||||
|
{ name = "threads1", path = "../exercises/20_threads/threads1.rs" },
|
||||||
|
{ name = "threads1_sol", path = "../solutions/20_threads/threads1.rs" },
|
||||||
|
{ name = "threads2", path = "../exercises/20_threads/threads2.rs" },
|
||||||
|
{ name = "threads2_sol", path = "../solutions/20_threads/threads2.rs" },
|
||||||
|
{ name = "threads3", path = "../exercises/20_threads/threads3.rs" },
|
||||||
|
{ name = "threads3_sol", path = "../solutions/20_threads/threads3.rs" },
|
||||||
|
{ name = "macros1", path = "../exercises/21_macros/macros1.rs" },
|
||||||
|
{ name = "macros1_sol", path = "../solutions/21_macros/macros1.rs" },
|
||||||
|
{ name = "macros2", path = "../exercises/21_macros/macros2.rs" },
|
||||||
|
{ name = "macros2_sol", path = "../solutions/21_macros/macros2.rs" },
|
||||||
|
{ name = "macros3", path = "../exercises/21_macros/macros3.rs" },
|
||||||
|
{ name = "macros3_sol", path = "../solutions/21_macros/macros3.rs" },
|
||||||
|
{ name = "macros4", path = "../exercises/21_macros/macros4.rs" },
|
||||||
|
{ name = "macros4_sol", path = "../solutions/21_macros/macros4.rs" },
|
||||||
|
{ name = "clippy1", path = "../exercises/22_clippy/clippy1.rs" },
|
||||||
|
{ name = "clippy1_sol", path = "../solutions/22_clippy/clippy1.rs" },
|
||||||
|
{ name = "clippy2", path = "../exercises/22_clippy/clippy2.rs" },
|
||||||
|
{ name = "clippy2_sol", path = "../solutions/22_clippy/clippy2.rs" },
|
||||||
|
{ name = "clippy3", path = "../exercises/22_clippy/clippy3.rs" },
|
||||||
|
{ name = "clippy3_sol", path = "../solutions/22_clippy/clippy3.rs" },
|
||||||
|
{ name = "using_as", path = "../exercises/23_conversions/using_as.rs" },
|
||||||
|
{ name = "using_as_sol", path = "../solutions/23_conversions/using_as.rs" },
|
||||||
|
{ name = "from_into", path = "../exercises/23_conversions/from_into.rs" },
|
||||||
|
{ name = "from_into_sol", path = "../solutions/23_conversions/from_into.rs" },
|
||||||
|
{ name = "from_str", path = "../exercises/23_conversions/from_str.rs" },
|
||||||
|
{ name = "from_str_sol", path = "../solutions/23_conversions/from_str.rs" },
|
||||||
|
{ name = "try_from_into", path = "../exercises/23_conversions/try_from_into.rs" },
|
||||||
|
{ name = "try_from_into_sol", path = "../solutions/23_conversions/try_from_into.rs" },
|
||||||
|
{ name = "as_ref_mut", path = "../exercises/23_conversions/as_ref_mut.rs" },
|
||||||
|
{ name = "as_ref_mut_sol", path = "../solutions/23_conversions/as_ref_mut.rs" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "exercises"
|
||||||
|
edition = "2021"
|
||||||
|
# Don't publish the exercises on crates.io!
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[lints.rust]
|
||||||
|
# You shouldn't write unsafe code in Rustlings!
|
||||||
|
unsafe_code = "forbid"
|
||||||
|
# You don't need unstable features in Rustlings and shouldn't rely on them while learning Rust.
|
||||||
|
unstable_features = "forbid"
|
||||||
|
# Dead code warnings can't be avoided in some exercises and might distract while learning.
|
||||||
|
dead_code = "allow"
|
||||||
|
|
||||||
|
[lints.clippy]
|
||||||
|
# You forgot a `todo!()`!
|
||||||
|
todo = "forbid"
|
||||||
|
# This can only happen by mistake in Rustlings.
|
||||||
|
empty_loop = "forbid"
|
||||||
|
# No infinite loops are needed in Rustlings.
|
||||||
|
infinite_loop = "deny"
|
||||||
|
# You shouldn't leak memory while still learning Rust!
|
||||||
|
mem_forget = "deny"
|
||||||
|
# Currently, there are no disallowed methods. This line avoids problems when developing Rustlings.
|
||||||
|
disallowed_methods = "allow"
|
1
dev/rustlings-repo.txt
Normal file
1
dev/rustlings-repo.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
This file is used to check if the user tries to run Rustlings in the repository (the method before version 6)
|
|
@ -1,23 +1,12 @@
|
||||||
// intro1.rs
|
// TODO: We sometimes encourage you to keep trying things on a given exercise
|
||||||
|
// even after you already figured it out. If you got everything working and feel
|
||||||
|
// ready for the next exercise, enter `n` in the terminal.
|
||||||
//
|
//
|
||||||
// About this `I AM NOT DONE` thing:
|
// The exercise file will be reloaded when you change one of the lines below!
|
||||||
// We sometimes encourage you to keep trying things on a given exercise, even
|
// Try adding a new `println!` and check the updated output in the terminal.
|
||||||
// after you already figured it out. If you got everything working and feel
|
|
||||||
// ready for the next exercise, remove the `I AM NOT DONE` comment below.
|
|
||||||
//
|
|
||||||
// If you're running this using `rustlings watch`: The exercise file will be
|
|
||||||
// reloaded when you change one of the lines below! Try adding a `println!`
|
|
||||||
// line, or try changing what it outputs in your terminal. Try removing a
|
|
||||||
// semicolon and see what happens!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint intro1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello and");
|
println!(r#" Welcome to... "#);
|
||||||
println!(r#" welcome to... "#);
|
|
||||||
println!(r#" _ _ _ "#);
|
println!(r#" _ _ _ "#);
|
||||||
println!(r#" _ __ _ _ ___| |_| (_)_ __ __ _ ___ "#);
|
println!(r#" _ __ _ _ ___| |_| (_)_ __ __ _ ___ "#);
|
||||||
println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
|
println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
|
||||||
|
@ -29,13 +18,7 @@ fn main() {
|
||||||
println!("or logic error. The central concept behind Rustlings is to fix these errors and");
|
println!("or logic error. The central concept behind Rustlings is to fix these errors and");
|
||||||
println!("solve the exercises. Good luck!");
|
println!("solve the exercises. Good luck!");
|
||||||
println!();
|
println!();
|
||||||
println!("The source for this exercise is in `exercises/00_intro/intro1.rs`. Have a look!");
|
println!("The file of this exercise is `exercises/00_intro/intro1.rs`. Have a look!");
|
||||||
println!(
|
println!("The current exercise path will be always shown under the progress bar.");
|
||||||
"Going forward, the source of the exercises will always be in the success/failure output."
|
println!("You can click on the path to open the exercise file in your editor.");
|
||||||
);
|
|
||||||
println!();
|
|
||||||
println!(
|
|
||||||
"If you want to use rust-analyzer, Rust's LSP implementation, make sure your editor is set"
|
|
||||||
);
|
|
||||||
println!("up, and then run `rustlings lsp` before continuing.")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
// intro2.rs
|
|
||||||
//
|
|
||||||
// Make the code print a greeting to the world.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint intro2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello {}!");
|
// TODO: Fix the code to print "Hello world!".
|
||||||
|
printline!("Hello world!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
// variables1.rs
|
|
||||||
//
|
|
||||||
// Make me compile!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint variables1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// TODO: Add the missing keyword.
|
||||||
x = 5;
|
x = 5;
|
||||||
println!("x has the value {}", x);
|
|
||||||
|
println!("x has the value {x}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
// variables2.rs
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint variables2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// TODO: Change the line below to fix the compiler error.
|
||||||
let x;
|
let x;
|
||||||
|
|
||||||
if x == 10 {
|
if x == 10 {
|
||||||
println!("x is ten!");
|
println!("x is ten!");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
// variables3.rs
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint variables3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// TODO: Change the line below to fix the compiler error.
|
||||||
let x: i32;
|
let x: i32;
|
||||||
println!("Number {}", x);
|
|
||||||
|
println!("Number {x}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
// variables4.rs
|
// TODO: Fix the compiler error.
|
||||||
//
|
|
||||||
// Execute `rustlings hint variables4` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = 3;
|
let x = 3;
|
||||||
println!("Number {}", x);
|
println!("Number {x}");
|
||||||
x = 5; // don't change this line
|
|
||||||
println!("Number {}", x);
|
x = 5; // Don't change this line
|
||||||
|
println!("Number {x}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
// variables5.rs
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint variables5` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let number = "T-H-R-E-E"; // don't change this line
|
let number = "T-H-R-E-E"; // Don't change this line
|
||||||
println!("Spell a Number : {}", number);
|
println!("Spell a number: {}", number);
|
||||||
number = 3; // don't rename this variable
|
|
||||||
println!("Number plus two is : {}", number + 2);
|
// TODO: Fix the compiler error by changing the line below without renaming the variable.
|
||||||
|
number = 3;
|
||||||
|
println!("Number plus two is: {}", number + 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
// variables6.rs
|
// TODO: Change the line below to fix the compiler error.
|
||||||
//
|
|
||||||
// Execute `rustlings hint variables6` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
const NUMBER = 3;
|
const NUMBER = 3;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Number {}", NUMBER);
|
println!("Number: {NUMBER}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
// functions1.rs
|
// TODO: Add some function with the name `call_me` without arguments or a return value.
|
||||||
//
|
|
||||||
// Execute `rustlings hint functions1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
call_me();
|
call_me(); // Don't change this line
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,10 @@
|
||||||
// functions2.rs
|
// TODO: Add the missing type of the argument `num` after the colon `:`.
|
||||||
//
|
|
||||||
// Execute `rustlings hint functions2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
call_me(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call_me(num:) {
|
fn call_me(num:) {
|
||||||
for i in 0..num {
|
for i in 0..num {
|
||||||
println!("Ring! Call number {}", i + 1);
|
println!("Ring! Call number {}", i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
call_me(3);
|
||||||
|
}
|
||||||
|
|
|
@ -1,16 +1,10 @@
|
||||||
// functions3.rs
|
fn call_me(num: u8) {
|
||||||
//
|
|
||||||
// Execute `rustlings hint functions3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
call_me();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call_me(num: u32) {
|
|
||||||
for i in 0..num {
|
for i in 0..num {
|
||||||
println!("Ring! Call number {}", i + 1);
|
println!("Ring! Call number {}", i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// TODO: Fix the function call.
|
||||||
|
call_me();
|
||||||
|
}
|
||||||
|
|
|
@ -1,21 +1,14 @@
|
||||||
// functions4.rs
|
|
||||||
//
|
|
||||||
// This store is having a sale where if the price is an even number, you get 10
|
// This store is having a sale where if the price is an even number, you get 10
|
||||||
// Rustbucks off, but if it's an odd number, it's 3 Rustbucks off. (Don't worry
|
// Rustbucks off, but if it's an odd number, it's 3 Rustbucks off.
|
||||||
// about the function bodies themselves, we're only interested in the signatures
|
// Don't worry about the function bodies themselves, we are only interested in
|
||||||
// for now. If anything, this is a good way to peek ahead to future exercises!)
|
// the signatures for now.
|
||||||
//
|
|
||||||
// Execute `rustlings hint functions4` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
fn is_even(num: i64) -> bool {
|
||||||
|
num % 2 == 0
|
||||||
fn main() {
|
|
||||||
let original_price = 51;
|
|
||||||
println!("Your sale price is {}", sale_price(original_price));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sale_price(price: i32) -> {
|
// TODO: Fix the function signature.
|
||||||
|
fn sale_price(price: i64) -> {
|
||||||
if is_even(price) {
|
if is_even(price) {
|
||||||
price - 10
|
price - 10
|
||||||
} else {
|
} else {
|
||||||
|
@ -23,6 +16,7 @@ fn sale_price(price: i32) -> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_even(num: i32) -> bool {
|
fn main() {
|
||||||
num % 2 == 0
|
let original_price = 51;
|
||||||
|
println!("Your sale price is {}", sale_price(original_price));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
// functions5.rs
|
// TODO: Fix the function body without changing the signature.
|
||||||
//
|
|
||||||
// Execute `rustlings hint functions5` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let answer = square(3);
|
|
||||||
println!("The square of 3 is {}", answer);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn square(num: i32) -> i32 {
|
fn square(num: i32) -> i32 {
|
||||||
num * num;
|
num * num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let answer = square(3);
|
||||||
|
println!("The square of 3 is {answer}");
|
||||||
|
}
|
||||||
|
|
|
@ -8,13 +8,12 @@
|
||||||
// Execute `rustlings hint functions6` or use the `hint` watch subcommand for
|
// Execute `rustlings hint functions6` or use the `hint` watch subcommand for
|
||||||
// some hints.
|
// some hints.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// TODO: ensure the definition of captured variable
|
||||||
let closure_1 = |input_var: u32| -> u32 {input_var + outer_var};
|
let closure_1 = |input_var: u32| -> u32 {input_var + outer_var};
|
||||||
println!("Closure#1 returns {}", closure_1(5));
|
println!("Closure#1 returns {}", closure_1(5));
|
||||||
|
|
||||||
let closure_2 = |input_var| println!("Closure#2 (input_var {})", input_var);
|
let closure_2 = |input_var| println!("Closure#2 (input_var {})", input_var);
|
||||||
closure_2(2);
|
closure_2(2);
|
||||||
closure_2("5");
|
closure_2("5"); // TODO: look at the captured variable type here
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
// if1.rs
|
fn bigger(a: i32, b: i32) -> i32 {
|
||||||
//
|
// TODO: Complete this function to return the bigger number!
|
||||||
// Execute `rustlings hint if1` or use the `hint` watch subcommand for a hint.
|
// If both numbers are equal, any of them can be returned.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub fn bigger(a: i32, b: i32) -> i32 {
|
|
||||||
// Complete this function to return the bigger number!
|
|
||||||
// Do not use:
|
// Do not use:
|
||||||
// - another function call
|
// - another function call
|
||||||
// - additional variables
|
// - additional variables
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
// Don't mind this for now :)
|
// Don't mind this for now :)
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
// if2.rs
|
// TODO: Fix the compiler error on this function.
|
||||||
//
|
fn picky_eater(food: &str) -> &str {
|
||||||
// Step 1: Make me compile!
|
if food == "strawberry" {
|
||||||
// Step 2: Get the bar_for_fuzz and default_to_baz tests passing!
|
"Yummy!"
|
||||||
//
|
|
||||||
// Execute `rustlings hint if2` or use the `hint` watch subcommand for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub fn foo_if_fizz(fizzish: &str) -> &str {
|
|
||||||
if fizzish == "fizz" {
|
|
||||||
"foo"
|
|
||||||
} else {
|
} else {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No test changes needed!
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Read the tests to understand the desired behavior.
|
||||||
|
// Make all tests pass without changing them.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn foo_for_fizz() {
|
fn yummy_food() {
|
||||||
assert_eq!(foo_if_fizz("fizz"), "foo")
|
// This means that calling `picky_eater` with the argument "food" should return "Yummy!".
|
||||||
|
assert_eq!(picky_eater("strawberry"), "Yummy!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bar_for_fuzz() {
|
fn neutral_food() {
|
||||||
assert_eq!(foo_if_fizz("fuzz"), "bar")
|
assert_eq!(picky_eater("potato"), "I guess I can eat that.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn default_to_baz() {
|
fn default_disliked_food() {
|
||||||
assert_eq!(foo_if_fizz("literally anything"), "baz")
|
assert_eq!(picky_eater("broccoli"), "No thanks!");
|
||||||
|
assert_eq!(picky_eater("gummy bears"), "No thanks!");
|
||||||
|
assert_eq!(picky_eater("literally anything"), "No thanks!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
// if3.rs
|
fn animal_habitat(animal: &str) -> &str {
|
||||||
//
|
// TODO: Fix the compiler error in the statement below.
|
||||||
// Execute `rustlings hint if3` or use the `hint` watch subcommand for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub fn animal_habitat(animal: &str) -> &'static str {
|
|
||||||
let identifier = if animal == "crab" {
|
let identifier = if animal == "crab" {
|
||||||
1
|
1
|
||||||
} else if animal == "gopher" {
|
} else if animal == "gopher" {
|
||||||
|
@ -15,8 +10,8 @@ pub fn animal_habitat(animal: &str) -> &'static str {
|
||||||
"Unknown"
|
"Unknown"
|
||||||
};
|
};
|
||||||
|
|
||||||
// DO NOT CHANGE THIS STATEMENT BELOW
|
// Don't change the expression below!
|
||||||
let habitat = if identifier == 1 {
|
if identifier == 1 {
|
||||||
"Beach"
|
"Beach"
|
||||||
} else if identifier == 2 {
|
} else if identifier == 2 {
|
||||||
"Burrow"
|
"Burrow"
|
||||||
|
@ -24,12 +19,14 @@ pub fn animal_habitat(animal: &str) -> &'static str {
|
||||||
"Desert"
|
"Desert"
|
||||||
} else {
|
} else {
|
||||||
"Unknown"
|
"Unknown"
|
||||||
};
|
}
|
||||||
|
|
||||||
habitat
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No test changes needed.
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't change the tests!
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -5,5 +5,5 @@ compiler. In this section, we'll go through the most important ones.
|
||||||
|
|
||||||
## Further information
|
## Further information
|
||||||
|
|
||||||
- [Data Types](https://doc.rust-lang.org/stable/book/ch03-02-data-types.html)
|
- [Data Types](https://doc.rust-lang.org/book/ch03-02-data-types.html)
|
||||||
- [The Slice Type](https://doc.rust-lang.org/stable/book/ch04-03-slices.html)
|
- [The Slice Type](https://doc.rust-lang.org/book/ch04-03-slices.html)
|
||||||
|
|
|
@ -1,19 +1,14 @@
|
||||||
// primitive_types1.rs
|
// Booleans (`bool`)
|
||||||
//
|
|
||||||
// Fill in the rest of the line that has code missing! No hints, there's no
|
|
||||||
// tricks, just get used to typing these :)
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Booleans (`bool`)
|
|
||||||
|
|
||||||
let is_morning = true;
|
let is_morning = true;
|
||||||
if is_morning {
|
if is_morning {
|
||||||
println!("Good morning!");
|
println!("Good morning!");
|
||||||
}
|
}
|
||||||
|
|
||||||
let // Finish the rest of this line like the example! Or make it be false!
|
// TODO: Define a boolean variable with the name `is_evening` before the `if` statement below.
|
||||||
|
// The value of the variable should be the negation (opposite) of `is_morning`.
|
||||||
|
// let …
|
||||||
if is_evening {
|
if is_evening {
|
||||||
println!("Good evening!");
|
println!("Good evening!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
// primitive_types2.rs
|
// Characters (`char`)
|
||||||
//
|
|
||||||
// Fill in the rest of the line that has code missing! No hints, there's no
|
|
||||||
// tricks, just get used to typing these :)
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Characters (`char`)
|
|
||||||
|
|
||||||
// Note the _single_ quotes, these are different from the double quotes
|
// Note the _single_ quotes, these are different from the double quotes
|
||||||
// you've been seeing around.
|
// you've been seeing around.
|
||||||
let my_first_initial = 'C';
|
let my_first_initial = 'C';
|
||||||
|
@ -19,9 +12,12 @@ fn main() {
|
||||||
println!("Neither alphabetic nor numeric!");
|
println!("Neither alphabetic nor numeric!");
|
||||||
}
|
}
|
||||||
|
|
||||||
let // Finish this line like the example! What's your favorite character?
|
// TODO: Analogous to the example before, declare a variable called `your_character`
|
||||||
// Try a letter, try a number, try a special character, try a character
|
// below with your favorite character.
|
||||||
// from a different language than your own, try an emoji!
|
// Try a letter, try a digit (in single quotes), try a special character, try a character
|
||||||
|
// from a different language than your own, try an emoji 😉
|
||||||
|
// let your_character = '';
|
||||||
|
|
||||||
if your_character.is_alphabetic() {
|
if your_character.is_alphabetic() {
|
||||||
println!("Alphabetical!");
|
println!("Alphabetical!");
|
||||||
} else if your_character.is_numeric() {
|
} else if your_character.is_numeric() {
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
// primitive_types3.rs
|
|
||||||
//
|
|
||||||
// Create an array with at least 100 elements in it where the ??? is.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint primitive_types3` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = ???
|
// TODO: Create an array called `a` with at least 100 elements in it.
|
||||||
|
// let a = ???
|
||||||
|
|
||||||
if a.len() >= 100 {
|
if a.len() >= 100 {
|
||||||
println!("Wow, that's a big array!");
|
println!("Wow, that's a big array!");
|
||||||
} else {
|
} else {
|
||||||
println!("Meh, I eat arrays like that for breakfast.");
|
println!("Meh, I eat arrays like that for breakfast.");
|
||||||
panic!("Array not big enough, more elements needed")
|
panic!("Array not big enough, more elements needed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
// primitive_types4.rs
|
fn main() {
|
||||||
//
|
// You can optionally experiment here.
|
||||||
// Get a slice out of Array a where the ??? is so that the test passes.
|
}
|
||||||
//
|
|
||||||
// Execute `rustlings hint primitive_types4` or use the `hint` watch subcommand
|
#[cfg(test)]
|
||||||
// for a hint.
|
mod tests {
|
||||||
|
#[test]
|
||||||
// I AM NOT DONE
|
fn slice_out_of_array() {
|
||||||
|
let a = [1, 2, 3, 4, 5];
|
||||||
#[test]
|
|
||||||
fn slice_out_of_array() {
|
// TODO: Get a slice called `nice_slice` out of the array `a` so that the test passes.
|
||||||
let a = [1, 2, 3, 4, 5];
|
// let nice_slice = ???
|
||||||
|
|
||||||
let nice_slice = ???
|
assert_eq!([2, 3, 4], nice_slice);
|
||||||
|
}
|
||||||
assert_eq!([2, 3, 4], nice_slice)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,8 @@
|
||||||
// primitive_types5.rs
|
|
||||||
//
|
|
||||||
// Destructure the `cat` tuple so that the println will work.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint primitive_types5` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cat = ("Furry McFurson", 3.5);
|
let cat = ("Furry McFurson", 3.5);
|
||||||
let /* your pattern here */ = cat;
|
|
||||||
|
|
||||||
println!("{} is {} years old.", name, age);
|
// TODO: Destructure the `cat` tuple in one statement so that the println works.
|
||||||
|
// let /* your pattern here */ = cat;
|
||||||
|
|
||||||
|
println!("{name} is {age} years old");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
// primitive_types6.rs
|
fn main() {
|
||||||
//
|
// You can optionally experiment here.
|
||||||
// Use a tuple index to access the second element of `numbers`. You can put the
|
}
|
||||||
// expression for the second element where ??? is so that the test passes.
|
|
||||||
//
|
#[cfg(test)]
|
||||||
// Execute `rustlings hint primitive_types6` or use the `hint` watch subcommand
|
mod tests {
|
||||||
// for a hint.
|
#[test]
|
||||||
|
fn indexing_tuple() {
|
||||||
// I AM NOT DONE
|
let numbers = (1, 2, 3);
|
||||||
|
|
||||||
#[test]
|
// TODO: Use a tuple index to access the second element of `numbers`
|
||||||
fn indexing_tuple() {
|
// and assign it to a variable called `second`.
|
||||||
let numbers = (1, 2, 3);
|
// let second = ???;
|
||||||
// Replace below ??? with the tuple indexing syntax.
|
|
||||||
let second = ???;
|
assert_eq!(second, 2, "This is not the 2nd number in the tuple!");
|
||||||
|
}
|
||||||
assert_eq!(2, second,
|
|
||||||
"This is not the 2nd number in the tuple!")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,6 @@ the other useful data structure, hash maps, later.
|
||||||
|
|
||||||
## Further information
|
## Further information
|
||||||
|
|
||||||
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)
|
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/book/ch08-01-vectors.html)
|
||||||
- [`iter_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.iter_mut)
|
- [`iter_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.iter_mut)
|
||||||
- [`map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map)
|
- [`map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map)
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
// vecs1.rs
|
|
||||||
//
|
|
||||||
// Your task is to create a `Vec` which holds the exact same elements as in the
|
|
||||||
// array `a`.
|
|
||||||
//
|
|
||||||
// Make me compile and pass the test!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint vecs1` or use the `hint` watch subcommand for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
|
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
|
||||||
let a = [10, 20, 30, 40]; // a plain array
|
let a = [10, 20, 30, 40]; // Array
|
||||||
let v = // TODO: declare your vector here with the macro for vectors
|
|
||||||
|
// TODO: Create a vector called `v` which contains the exact same elements as in the array `a`.
|
||||||
|
// Use the vector macro.
|
||||||
|
// let v = ???;
|
||||||
|
|
||||||
(a, v)
|
(a, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -23,6 +19,6 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_array_and_vec_similarity() {
|
fn test_array_and_vec_similarity() {
|
||||||
let (a, v) = array_and_vec();
|
let (a, v) = array_and_vec();
|
||||||
assert_eq!(a, v[..]);
|
assert_eq!(a, *v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,36 @@
|
||||||
// vecs2.rs
|
fn vec_loop(input: &[i32]) -> Vec<i32> {
|
||||||
//
|
let mut output = Vec::new();
|
||||||
// A Vec of even numbers is given. Your task is to complete the loop so that
|
|
||||||
// each number in the Vec is multiplied by 2.
|
|
||||||
//
|
|
||||||
// Make me pass the test!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint vecs2` or use the `hint` watch subcommand for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
for element in input {
|
||||||
|
// TODO: Multiply each element in the `input` slice by 2 and push it to
|
||||||
fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
|
// the `output` vector.
|
||||||
for element in v.iter_mut() {
|
|
||||||
// TODO: Fill this up so that each element in the Vec `v` is
|
|
||||||
// multiplied by 2.
|
|
||||||
???
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, `v` should be equal to [4, 8, 12, 16, 20].
|
output
|
||||||
v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vec_map(v: &Vec<i32>) -> Vec<i32> {
|
fn vec_map_example(input: &[i32]) -> Vec<i32> {
|
||||||
v.iter().map(|element| {
|
// An example of collecting a vector after mapping.
|
||||||
// TODO: Do the same thing as above - but instead of mutating the
|
// We map each element of the `input` slice to its value plus 1.
|
||||||
// Vec, you can just return the new number!
|
// If the input is `[1, 2, 3]`, the output is `[2, 3, 4]`.
|
||||||
???
|
input.iter().map(|element| element + 1).collect()
|
||||||
}).collect()
|
}
|
||||||
|
|
||||||
|
fn vec_map(input: &[i32]) -> Vec<i32> {
|
||||||
|
// TODO: Here, we also want to multiply each element in the `input` slice
|
||||||
|
// by 2, but with iterator mapping instead of manually pushing into an empty
|
||||||
|
// vector.
|
||||||
|
// See the example in the function `vec_map_example` above.
|
||||||
|
input
|
||||||
|
.iter()
|
||||||
|
.map(|element| {
|
||||||
|
// ???
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -34,17 +39,22 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_vec_loop() {
|
fn test_vec_loop() {
|
||||||
let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
|
let input = [2, 4, 6, 8, 10];
|
||||||
let ans = vec_loop(v.clone());
|
let ans = vec_loop(&input);
|
||||||
|
assert_eq!(ans, [4, 8, 12, 16, 20]);
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(ans, v.iter().map(|x| x * 2).collect::<Vec<i32>>());
|
#[test]
|
||||||
|
fn test_vec_map_example() {
|
||||||
|
let input = [1, 2, 3];
|
||||||
|
let ans = vec_map_example(&input);
|
||||||
|
assert_eq!(ans, [2, 3, 4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_vec_map() {
|
fn test_vec_map() {
|
||||||
let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
|
let input = [2, 4, 6, 8, 10];
|
||||||
let ans = vec_map(&v);
|
let ans = vec_map(&input);
|
||||||
|
assert_eq!(ans, [4, 8, 12, 16, 20]);
|
||||||
assert_eq!(ans, v.iter().map(|x| x * 2).collect::<Vec<i32>>());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,4 @@
|
||||||
// move_semantics1.rs
|
// TODO: Fix the compiler error in this function.
|
||||||
//
|
|
||||||
// Execute `rustlings hint move_semantics1` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn main() {
|
|
||||||
let vec0 = vec![22, 44, 66];
|
|
||||||
|
|
||||||
let vec1 = fill_vec(vec0);
|
|
||||||
|
|
||||||
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||||
let vec = vec;
|
let vec = vec;
|
||||||
|
|
||||||
|
@ -21,3 +6,19 @@ fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn move_semantics1() {
|
||||||
|
let vec0 = vec![22, 44, 66];
|
||||||
|
let vec1 = fill_vec(vec0);
|
||||||
|
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,22 +1,3 @@
|
||||||
// move_semantics2.rs
|
|
||||||
//
|
|
||||||
// Make the test pass by finding a way to keep both Vecs separate!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn main() {
|
|
||||||
let vec0 = vec![22, 44, 66];
|
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
|
||||||
|
|
||||||
assert_eq!(vec0, vec![22, 44, 66]);
|
|
||||||
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||||
let mut vec = vec;
|
let mut vec = vec;
|
||||||
|
|
||||||
|
@ -24,3 +5,24 @@ fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
// TODO: Make both vectors `vec0` and `vec1` accessible at the same time to
|
||||||
|
// fix the compiler error in the test.
|
||||||
|
#[test]
|
||||||
|
fn move_semantics2() {
|
||||||
|
let vec0 = vec![22, 44, 66];
|
||||||
|
|
||||||
|
let vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
|
assert_eq!(vec0, [22, 44, 66]);
|
||||||
|
assert_eq!(vec1, [22, 44, 66, 88]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
// move_semantics3.rs
|
// TODO: Fix the compiler error in the function without adding any new line.
|
||||||
//
|
|
||||||
// Make me compile without adding new lines -- just changing existing lines! (no
|
|
||||||
// lines with multiple semicolons necessary!)
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint move_semantics3` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn main() {
|
|
||||||
let vec0 = vec![22, 44, 66];
|
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
|
||||||
|
|
||||||
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||||
vec.push(88);
|
vec.push(88);
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn move_semantics3() {
|
||||||
|
let vec0 = vec![22, 44, 66];
|
||||||
|
let vec1 = fill_vec(vec0);
|
||||||
|
assert_eq!(vec1, [22, 44, 66, 88]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,29 +1,18 @@
|
||||||
// move_semantics4.rs
|
|
||||||
//
|
|
||||||
// Refactor this code so that instead of passing `vec0` into the `fill_vec`
|
|
||||||
// function, the Vector gets created in the function itself and passed back to
|
|
||||||
// the main function.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint move_semantics4` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = vec![22, 44, 66];
|
// You can optionally experiment here.
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
|
||||||
|
|
||||||
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// `fill_vec()` no longer takes `vec: Vec<i32>` as argument - don't change this!
|
#[cfg(test)]
|
||||||
fn fill_vec() -> Vec<i32> {
|
mod tests {
|
||||||
// Instead, let's create and fill the Vec in here - how do you do that?
|
// TODO: Fix the compiler errors only by reordering the lines in the test.
|
||||||
let mut vec = vec;
|
// Don't add, change or remove any line.
|
||||||
|
#[test]
|
||||||
vec.push(88);
|
fn move_semantics4() {
|
||||||
|
let mut x = Vec::new();
|
||||||
vec
|
let y = &mut x;
|
||||||
|
let z = &mut x;
|
||||||
|
y.push(42);
|
||||||
|
z.push(13);
|
||||||
|
assert_eq!(x, [42, 13]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
// move_semantics5.rs
|
#![allow(clippy::ptr_arg)]
|
||||||
//
|
|
||||||
// Make me compile only by reordering the lines in `main()`, but without adding,
|
|
||||||
// changing or removing any of them.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint move_semantics5` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
// TODO: Fix the compiler errors without changing anything except adding or
|
||||||
|
// removing references (the character `&`).
|
||||||
|
|
||||||
#[test]
|
// Shouldn't take ownership
|
||||||
fn main() {
|
fn get_char(data: String) -> char {
|
||||||
let mut x = 100;
|
data.chars().last().unwrap()
|
||||||
let y = &mut x;
|
}
|
||||||
let z = &mut x;
|
|
||||||
*y += 100;
|
// Should take ownership
|
||||||
*z += 1000;
|
fn string_uppercase(mut data: &String) {
|
||||||
assert_eq!(x, 1200);
|
data = data.to_uppercase();
|
||||||
|
|
||||||
|
println!("{data}");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let data = "Rust is great!".to_string();
|
||||||
|
|
||||||
|
get_char(data);
|
||||||
|
|
||||||
|
string_uppercase(&data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,25 @@
|
||||||
// move_semantics6.rs
|
// move_semantics6.rs
|
||||||
//
|
//
|
||||||
// You can't change anything except adding or removing references.
|
// Here you will practice how mutable/immutable borrowing works in the context
|
||||||
|
// of a closure.
|
||||||
//
|
//
|
||||||
// Execute `rustlings hint move_semantics6` or use the `hint` watch subcommand
|
// Try to fix this code to make it compile and not panic.
|
||||||
|
// You can't change anything except removing 1 line.
|
||||||
|
//
|
||||||
|
// Execute `rustlings hint move_semantics7` or use the `hint` watch subcommand
|
||||||
// for a hint.
|
// for a hint.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let data = "Rust is great!".to_string();
|
let mut counter = 0;
|
||||||
|
|
||||||
get_char(data);
|
let mut increment = || {
|
||||||
|
counter += 1;
|
||||||
|
println!("counter equals {}", counter);
|
||||||
|
};
|
||||||
|
|
||||||
string_uppercase(&data);
|
increment();
|
||||||
}
|
let _reborrowed_counter = &counter; // TODO: figure out where to put this borrowing instruction
|
||||||
|
increment();
|
||||||
// Should not take ownership
|
|
||||||
fn get_char(data: String) -> char {
|
assert_eq!(counter, 2);
|
||||||
data.chars().last().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should take ownership
|
|
||||||
fn string_uppercase(mut data: &String) {
|
|
||||||
data = &data.to_uppercase();
|
|
||||||
|
|
||||||
println!("{}", data);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
// move_semantics6.rs
|
|
||||||
//
|
|
||||||
// Here you will practice how mutable/immutable borrowing works in the context
|
|
||||||
// of a closure.
|
|
||||||
//
|
|
||||||
// Try to fix this code to make it compile and not panic.
|
|
||||||
// You can't change anything except removing 1 line.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint move_semantics7` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut counter = 0;
|
|
||||||
|
|
||||||
let mut increment = || {
|
|
||||||
counter += 1;
|
|
||||||
println!("counter: {}", counter);
|
|
||||||
};
|
|
||||||
|
|
||||||
increment();
|
|
||||||
let _reborrowed_counter = &counter;
|
|
||||||
increment();
|
|
||||||
|
|
||||||
assert_eq!(counter, 2);
|
|
||||||
}
|
|
|
@ -1,28 +1,24 @@
|
||||||
// structs1.rs
|
struct ColorRegularStruct {
|
||||||
//
|
// TODO: Add the fields that the test `regular_structs` expects.
|
||||||
// Address all the TODOs to make the tests pass!
|
// What types should the fields have? What are the minimum and maximum values for RGB colors?
|
||||||
//
|
|
||||||
// Execute `rustlings hint structs1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
struct ColorClassicStruct {
|
|
||||||
// TODO: Something goes here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ColorTupleStruct(/* TODO: Something goes here */);
|
struct ColorTupleStruct(/* TODO: Add the fields that the test `tuple_structs` expects */);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct UnitLikeStruct;
|
struct UnitStruct;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn classic_c_structs() {
|
fn regular_structs() {
|
||||||
// TODO: Instantiate a classic c struct!
|
// TODO: Instantiate a regular struct.
|
||||||
// let green =
|
// let green =
|
||||||
|
|
||||||
assert_eq!(green.red, 0);
|
assert_eq!(green.red, 0);
|
||||||
|
@ -32,7 +28,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tuple_structs() {
|
fn tuple_structs() {
|
||||||
// TODO: Instantiate a tuple struct!
|
// TODO: Instantiate a tuple struct.
|
||||||
// let green =
|
// let green =
|
||||||
|
|
||||||
assert_eq!(green.0, 0);
|
assert_eq!(green.0, 0);
|
||||||
|
@ -42,10 +38,10 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unit_structs() {
|
fn unit_structs() {
|
||||||
// TODO: Instantiate a unit-like struct!
|
// TODO: Instantiate a unit struct.
|
||||||
// let unit_like_struct =
|
// let unit_struct =
|
||||||
let message = format!("{:?}s are fun!", unit_like_struct);
|
let message = format!("{unit_struct:?}s are fun!");
|
||||||
|
|
||||||
assert_eq!(message, "UnitLikeStructs are fun!");
|
assert_eq!(message, "UnitStructs are fun!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
// structs2.rs
|
|
||||||
//
|
|
||||||
// Address all the TODOs to make the tests pass!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint structs2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Order {
|
struct Order {
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -30,6 +21,10 @@ fn create_order_template() -> Order {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -37,8 +32,10 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn your_order() {
|
fn your_order() {
|
||||||
let order_template = create_order_template();
|
let order_template = create_order_template();
|
||||||
|
|
||||||
// TODO: Create your own order using the update syntax and template above!
|
// TODO: Create your own order using the update syntax and template above!
|
||||||
// let your_order =
|
// let your_order =
|
||||||
|
|
||||||
assert_eq!(your_order.name, "Hacker in Rust");
|
assert_eq!(your_order.name, "Hacker in Rust");
|
||||||
assert_eq!(your_order.year, order_template.year);
|
assert_eq!(your_order.year, order_template.year);
|
||||||
assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
|
assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
|
||||||
|
|
|
@ -1,13 +1,5 @@
|
||||||
// structs3.rs
|
// Structs contain data, but can also have logic. In this exercise, we have
|
||||||
//
|
// defined the `Package` struct, and we want to test some logic attached to it.
|
||||||
// Structs contain data, but can also have logic. In this exercise we have
|
|
||||||
// defined the Package struct and we want to test some logic attached to it.
|
|
||||||
// Make the code compile and the tests pass!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint structs3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Package {
|
struct Package {
|
||||||
|
@ -17,29 +9,36 @@ struct Package {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Package {
|
impl Package {
|
||||||
fn new(sender_country: String, recipient_country: String, weight_in_grams: u32) -> Package {
|
fn new(sender_country: String, recipient_country: String, weight_in_grams: u32) -> Self {
|
||||||
if weight_in_grams < 10 {
|
if weight_in_grams < 10 {
|
||||||
// This is not how you should handle errors in Rust,
|
// This isn't how you should handle errors in Rust, but we will
|
||||||
// but we will learn about error handling later.
|
// learn about error handling later.
|
||||||
panic!("Can not ship a package with weight below 10 grams.")
|
panic!("Can't ship a package with weight below 10 grams");
|
||||||
} else {
|
}
|
||||||
Package {
|
|
||||||
sender_country,
|
Self {
|
||||||
recipient_country,
|
sender_country,
|
||||||
weight_in_grams,
|
recipient_country,
|
||||||
}
|
weight_in_grams,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_international(&self) -> ??? {
|
// TODO: Add the correct return type to the function signature.
|
||||||
// Something goes here...
|
fn is_international(&self) {
|
||||||
|
// TODO: Read the tests that use this method to find out when a package
|
||||||
|
// is considered international.
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_fees(&self, cents_per_gram: u32) -> ??? {
|
// TODO: Add the correct return type to the function signature.
|
||||||
// Something goes here...
|
fn get_fees(&self, cents_per_gram: u32) {
|
||||||
|
// TODO: Calculate the package's fees.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
// enums1.rs
|
|
||||||
//
|
|
||||||
// No hints this time! ;)
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Message {
|
enum Message {
|
||||||
// TODO: define a few types of messages as used below
|
// TODO: Define a few types of messages as used below.
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{:?}", Message::Quit);
|
println!("{:?}", Message::Resize);
|
||||||
println!("{:?}", Message::Echo);
|
|
||||||
println!("{:?}", Message::Move);
|
println!("{:?}", Message::Move);
|
||||||
|
println!("{:?}", Message::Echo);
|
||||||
println!("{:?}", Message::ChangeColor);
|
println!("{:?}", Message::ChangeColor);
|
||||||
|
println!("{:?}", Message::Quit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,27 @@
|
||||||
// enums2.rs
|
#[derive(Debug)]
|
||||||
//
|
struct Point {
|
||||||
// Execute `rustlings hint enums2` or use the `hint` watch subcommand for a
|
x: u64,
|
||||||
// hint.
|
y: u64,
|
||||||
|
}
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Message {
|
enum Message {
|
||||||
// TODO: define the different variants used below
|
// TODO: Define the different variants used below.
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message {
|
impl Message {
|
||||||
fn call(&self) {
|
fn call(&self) {
|
||||||
println!("{:?}", self);
|
println!("{self:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let messages = [
|
let messages = [
|
||||||
Message::Move { x: 10, y: 30 },
|
Message::Resize {
|
||||||
|
width: 10,
|
||||||
|
height: 30,
|
||||||
|
},
|
||||||
|
Message::Move(Point { x: 10, y: 15 }),
|
||||||
Message::Echo(String::from("hello world")),
|
Message::Echo(String::from("hello world")),
|
||||||
Message::ChangeColor(200, 255, 255),
|
Message::ChangeColor(200, 255, 255),
|
||||||
Message::Quit,
|
Message::Quit,
|
||||||
|
|
|
@ -1,52 +1,58 @@
|
||||||
// enums3.rs
|
struct Point {
|
||||||
//
|
x: u64,
|
||||||
// Address all the TODOs to make the tests pass!
|
y: u64,
|
||||||
//
|
|
||||||
// Execute `rustlings hint enums3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
enum Message {
|
|
||||||
// TODO: implement the message variant types based on their usage below
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Point {
|
enum Message {
|
||||||
x: u8,
|
Resize { width: u64, height: u64 },
|
||||||
y: u8,
|
Move(Point),
|
||||||
|
Echo(String),
|
||||||
|
ChangeColor(u8, u8, u8),
|
||||||
|
Quit,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
color: (u8, u8, u8),
|
width: u64,
|
||||||
|
height: u64,
|
||||||
position: Point,
|
position: Point,
|
||||||
quit: bool,
|
|
||||||
message: String,
|
message: String,
|
||||||
|
// RGB color composed of red, green and blue.
|
||||||
|
color: (u8, u8, u8),
|
||||||
|
quit: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
fn change_color(&mut self, color: (u8, u8, u8)) {
|
fn resize(&mut self, width: u64, height: u64) {
|
||||||
self.color = color;
|
self.width = width;
|
||||||
|
self.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_position(&mut self, point: Point) {
|
||||||
|
self.position = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn echo(&mut self, s: String) {
|
||||||
|
self.message = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn change_color(&mut self, red: u8, green: u8, blue: u8) {
|
||||||
|
self.color = (red, green, blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn quit(&mut self) {
|
fn quit(&mut self) {
|
||||||
self.quit = true;
|
self.quit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn echo(&mut self, s: String) {
|
|
||||||
self.message = s
|
|
||||||
}
|
|
||||||
|
|
||||||
fn move_position(&mut self, p: Point) {
|
|
||||||
self.position = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn process(&mut self, message: Message) {
|
fn process(&mut self, message: Message) {
|
||||||
// TODO: create a match expression to process the different message variants
|
// TODO: Create a match expression to process the different message
|
||||||
// Remember: When passing a tuple as a function argument, you'll need extra parentheses:
|
// variants using the methods defined above.
|
||||||
// fn function((t, u, p, l, e))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -54,20 +60,29 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_match_message_call() {
|
fn test_match_message_call() {
|
||||||
let mut state = State {
|
let mut state = State {
|
||||||
quit: false,
|
width: 0,
|
||||||
|
height: 0,
|
||||||
position: Point { x: 0, y: 0 },
|
position: Point { x: 0, y: 0 },
|
||||||
|
message: String::from("hello world"),
|
||||||
color: (0, 0, 0),
|
color: (0, 0, 0),
|
||||||
message: "hello world".to_string(),
|
quit: false,
|
||||||
};
|
};
|
||||||
state.process(Message::ChangeColor(255, 0, 255));
|
|
||||||
state.process(Message::Echo(String::from("Hello world!")));
|
state.process(Message::Resize {
|
||||||
|
width: 10,
|
||||||
|
height: 30,
|
||||||
|
});
|
||||||
state.process(Message::Move(Point { x: 10, y: 15 }));
|
state.process(Message::Move(Point { x: 10, y: 15 }));
|
||||||
|
state.process(Message::Echo(String::from("Hello world!")));
|
||||||
|
state.process(Message::ChangeColor(255, 0, 255));
|
||||||
state.process(Message::Quit);
|
state.process(Message::Quit);
|
||||||
|
|
||||||
assert_eq!(state.color, (255, 0, 255));
|
assert_eq!(state.width, 10);
|
||||||
|
assert_eq!(state.height, 30);
|
||||||
assert_eq!(state.position.x, 10);
|
assert_eq!(state.position.x, 10);
|
||||||
assert_eq!(state.position.y, 15);
|
assert_eq!(state.position.y, 15);
|
||||||
assert_eq!(state.quit, true);
|
|
||||||
assert_eq!(state.message, "Hello world!");
|
assert_eq!(state.message, "Hello world!");
|
||||||
|
assert_eq!(state.color, (255, 0, 255));
|
||||||
|
assert!(state.quit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
// strings1.rs
|
// TODO: Fix the compiler error without changing the function signature.
|
||||||
//
|
|
||||||
// Make me compile without changing the function signature!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint strings1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let answer = current_favorite_color();
|
|
||||||
println!("My current favorite color is {}", answer);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_favorite_color() -> String {
|
fn current_favorite_color() -> String {
|
||||||
"blue"
|
"blue"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let answer = current_favorite_color();
|
||||||
|
println!("My current favorite color is {answer}");
|
||||||
|
}
|
||||||
|
|
|
@ -1,21 +1,14 @@
|
||||||
// strings2.rs
|
// TODO: Fix the compiler error in the `main` function without changing this function.
|
||||||
//
|
fn is_a_color_word(attempt: &str) -> bool {
|
||||||
// Make me compile without changing the function signature!
|
attempt == "green" || attempt == "blue" || attempt == "red"
|
||||||
//
|
}
|
||||||
// Execute `rustlings hint strings2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let word = String::from("green"); // Try not changing this line :)
|
let word = String::from("green"); // Don't change this line.
|
||||||
|
|
||||||
if is_a_color_word(word) {
|
if is_a_color_word(word) {
|
||||||
println!("That is a color word I know!");
|
println!("That is a color word I know!");
|
||||||
} else {
|
} else {
|
||||||
println!("That is not a color word I know.");
|
println!("That is not a color word I know.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_a_color_word(attempt: &str) -> bool {
|
|
||||||
attempt == "green" || attempt == "blue" || attempt == "red"
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,23 +1,17 @@
|
||||||
// strings3.rs
|
fn trim_me(input: &str) -> &str {
|
||||||
//
|
// TODO: Remove whitespace from both ends of a string.
|
||||||
// Execute `rustlings hint strings3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn trim_me(input: &str) -> String {
|
|
||||||
// TODO: Remove whitespace from both ends of a string!
|
|
||||||
???
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compose_me(input: &str) -> String {
|
fn compose_me(input: &str) -> String {
|
||||||
// TODO: Add " world!" to the string! There's multiple ways to do this!
|
// TODO: Add " world!" to the string! There are multiple ways to do this.
|
||||||
???
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_me(input: &str) -> String {
|
fn replace_me(input: &str) -> String {
|
||||||
// TODO: Replace "cars" in the string with "balloons"!
|
// TODO: Replace "cars" in the string with "balloons".
|
||||||
???
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -39,7 +33,13 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn replace_a_string() {
|
fn replace_a_string() {
|
||||||
assert_eq!(replace_me("I think cars are cool"), "I think balloons are cool");
|
assert_eq!(
|
||||||
assert_eq!(replace_me("I love to look at cars"), "I love to look at balloons");
|
replace_me("I think cars are cool"),
|
||||||
|
"I think balloons are cool",
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
replace_me("I love to look at cars"),
|
||||||
|
"I love to look at balloons",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,37 @@
|
||||||
// strings4.rs
|
// Calls of this function should be replaced with calls of `string_slice` or `string`.
|
||||||
//
|
fn placeholder() {}
|
||||||
// Ok, here are a bunch of values-- some are `String`s, some are `&str`s. 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`
|
|
||||||
// before the parentheses on each line. If you're right, it will compile!
|
|
||||||
//
|
|
||||||
// No hints this time!
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn string_slice(arg: &str) {
|
fn string_slice(arg: &str) {
|
||||||
println!("{}", arg);
|
println!("{arg}");
|
||||||
}
|
|
||||||
fn string(arg: String) {
|
|
||||||
println!("{}", arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn string(arg: String) {
|
||||||
???("blue");
|
println!("{arg}");
|
||||||
???("red".to_string());
|
}
|
||||||
???(String::from("hi"));
|
|
||||||
???("rust is fun!".to_owned());
|
// TODO: Here are a bunch of values - some are `String`, some are `&str`.
|
||||||
???("nice weather".into());
|
// Your task is to replace `placeholder(…)` with either `string_slice(…)`
|
||||||
???(format!("Interpolation {}", "Station"));
|
// or `string(…)` depending on what you think each value is.
|
||||||
???(&String::from("abc")[0..1]);
|
fn main() {
|
||||||
???(" hello there ".trim());
|
placeholder("blue");
|
||||||
???("Happy Monday!".to_string().replace("Mon", "Tues"));
|
|
||||||
???("mY sHiFt KeY iS sTiCkY".to_lowercase());
|
placeholder("red".to_string());
|
||||||
|
|
||||||
|
placeholder(String::from("hi"));
|
||||||
|
|
||||||
|
placeholder("rust is fun!".to_owned());
|
||||||
|
|
||||||
|
placeholder("nice weather".into());
|
||||||
|
|
||||||
|
placeholder(format!("Interpolation {}", "Station"));
|
||||||
|
|
||||||
|
// WARNING: This is byte indexing, not character indexing.
|
||||||
|
// Character indexing can be done using `s.chars().nth(INDEX)`.
|
||||||
|
placeholder(&String::from("abc")[0..1]);
|
||||||
|
|
||||||
|
placeholder(" hello there ".trim());
|
||||||
|
|
||||||
|
placeholder("Happy Monday!".replace("Mon", "Tues"));
|
||||||
|
|
||||||
|
placeholder("mY sHiFt KeY iS sTiCkY".to_lowercase());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
// modules1.rs
|
// TODO: Fix the compiler error about calling a private function.
|
||||||
//
|
|
||||||
// Execute `rustlings hint modules1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
mod sausage_factory {
|
mod sausage_factory {
|
||||||
// Don't let anybody outside of this module see this!
|
// Don't let anybody outside of this module see this!
|
||||||
fn get_secret_recipe() -> String {
|
fn get_secret_recipe() -> String {
|
||||||
|
|
|
@ -1,27 +1,19 @@
|
||||||
// modules2.rs
|
|
||||||
//
|
|
||||||
// You can bring module paths into scopes and provide new names for them with
|
// You can bring module paths into scopes and provide new names for them with
|
||||||
// the 'use' and 'as' keywords. Fix these 'use' statements to make the code
|
// the `use` and `as` keywords.
|
||||||
// compile.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint modules2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
mod delicious_snacks {
|
mod delicious_snacks {
|
||||||
// TODO: Fix these use statements
|
// TODO: Add the following two `use` statements after fixing them.
|
||||||
use self::fruits::PEAR as ???
|
// use self::fruits::PEAR as ???;
|
||||||
use self::veggies::CUCUMBER as ???
|
// use self::veggies::CUCUMBER as ???;
|
||||||
|
|
||||||
mod fruits {
|
mod fruits {
|
||||||
pub const PEAR: &'static str = "Pear";
|
pub const PEAR: &str = "Pear";
|
||||||
pub const APPLE: &'static str = "Apple";
|
pub const APPLE: &str = "Apple";
|
||||||
}
|
}
|
||||||
|
|
||||||
mod veggies {
|
mod veggies {
|
||||||
pub const CUCUMBER: &'static str = "Cucumber";
|
pub const CUCUMBER: &str = "Cucumber";
|
||||||
pub const CARROT: &'static str = "Carrot";
|
pub const CARROT: &str = "Carrot";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +21,6 @@ fn main() {
|
||||||
println!(
|
println!(
|
||||||
"favorite snacks: {} and {}",
|
"favorite snacks: {} and {}",
|
||||||
delicious_snacks::fruit,
|
delicious_snacks::fruit,
|
||||||
delicious_snacks::veggie
|
delicious_snacks::veggie,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
// modules3.rs
|
// You can use the `use` keyword to bring module paths from modules from
|
||||||
//
|
// anywhere and especially from the standard library into your scope.
|
||||||
// You can use the 'use' keyword to bring module paths from modules from
|
|
||||||
// anywhere and especially from the Rust standard library into your scope. Bring
|
|
||||||
// SystemTime and UNIX_EPOCH from the std::time module. Bonus style points if
|
|
||||||
// you can do it with one line!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint modules3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
// TODO: Bring `SystemTime` and `UNIX_EPOCH` from the `std::time` module into
|
||||||
|
// your scope. Bonus style points if you can do it with one line!
|
||||||
// TODO: Complete this use statement
|
// use ???;
|
||||||
use ???
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
match SystemTime::now().duration_since(UNIX_EPOCH) {
|
match SystemTime::now().duration_since(UNIX_EPOCH) {
|
||||||
|
|
|
@ -1,31 +1,27 @@
|
||||||
// hashmaps1.rs
|
|
||||||
//
|
|
||||||
// A basket of fruits in the form of a hash map needs to be defined. The key
|
// A basket of fruits in the form of a hash map needs to be defined. The key
|
||||||
// represents the name of the fruit and the value represents how many of that
|
// represents the name of the fruit and the value represents how many of that
|
||||||
// particular fruit is in the basket. You have to put at least three different
|
// particular fruit is in the basket. You have to put at least 3 different
|
||||||
// types of fruits (e.g apple, banana, mango) in the basket and the total count
|
// types of fruits (e.g. apple, banana, mango) in the basket and the total count
|
||||||
// of all the fruits should be at least five.
|
// of all the fruits should be at least 5.
|
||||||
//
|
|
||||||
// Make me compile and pass the tests!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint hashmaps1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
fn fruit_basket() -> HashMap<String, u32> {
|
fn fruit_basket() -> HashMap<String, u32> {
|
||||||
let mut basket = // TODO: declare your hash map here.
|
// TODO: Declare the hash map.
|
||||||
|
// let mut basket =
|
||||||
|
|
||||||
// Two bananas are already given for you :)
|
// Two bananas are already given for you :)
|
||||||
basket.insert(String::from("banana"), 2);
|
basket.insert(String::from("banana"), 2);
|
||||||
|
|
||||||
// TODO: Put more fruits in your basket here.
|
// TODO: Put more fruits in your basket.
|
||||||
|
|
||||||
basket
|
basket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// hashmaps2.rs
|
|
||||||
//
|
|
||||||
// We're collecting different fruits to bake a delicious fruit cake. For this,
|
// We're collecting different fruits to bake a delicious fruit cake. For this,
|
||||||
// we have a basket, which we'll represent in the form of a hash map. The key
|
// we have a basket, which we'll represent in the form of a hash map. The key
|
||||||
// represents the name of each fruit we collect and the value represents how
|
// represents the name of each fruit we collect and the value represents how
|
||||||
|
@ -7,18 +5,12 @@
|
||||||
// Apple (4), Mango (2) and Lychee (5) are already in the basket hash map. You
|
// Apple (4), Mango (2) and Lychee (5) are already in the basket hash map. You
|
||||||
// must add fruit to the basket so that there is at least one of each kind and
|
// must add fruit to the basket so that there is at least one of each kind and
|
||||||
// more than 11 in total - we have a lot of mouths to feed. You are not allowed
|
// more than 11 in total - we have a lot of mouths to feed. You are not allowed
|
||||||
// to insert any more of these fruits!
|
// to insert any more of the fruits that are already in the basket (Apple,
|
||||||
//
|
// Mango, and Lychee).
|
||||||
// Make me pass the tests!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint hashmaps2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Hash, PartialEq, Eq)]
|
#[derive(Hash, PartialEq, Eq, Debug)]
|
||||||
enum Fruit {
|
enum Fruit {
|
||||||
Apple,
|
Apple,
|
||||||
Banana,
|
Banana,
|
||||||
|
@ -28,7 +20,7 @@ enum Fruit {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
|
fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
|
||||||
let fruit_kinds = vec![
|
let fruit_kinds = [
|
||||||
Fruit::Apple,
|
Fruit::Apple,
|
||||||
Fruit::Banana,
|
Fruit::Banana,
|
||||||
Fruit::Mango,
|
Fruit::Mango,
|
||||||
|
@ -43,18 +35,18 @@ fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
// Don't modify this function!
|
// Don't modify this function!
|
||||||
fn get_fruit_basket() -> HashMap<Fruit, u32> {
|
fn get_fruit_basket() -> HashMap<Fruit, u32> {
|
||||||
let mut basket = HashMap::<Fruit, u32>::new();
|
let content = [(Fruit::Apple, 4), (Fruit::Mango, 2), (Fruit::Lychee, 5)];
|
||||||
basket.insert(Fruit::Apple, 4);
|
HashMap::from_iter(content)
|
||||||
basket.insert(Fruit::Mango, 2);
|
|
||||||
basket.insert(Fruit::Lychee, 5);
|
|
||||||
|
|
||||||
basket
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -81,13 +73,25 @@ mod tests {
|
||||||
let count = basket.values().sum::<u32>();
|
let count = basket.values().sum::<u32>();
|
||||||
assert!(count > 11);
|
assert!(count > 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn all_fruit_types_in_basket() {
|
fn all_fruit_types_in_basket() {
|
||||||
|
let fruit_kinds = [
|
||||||
|
Fruit::Apple,
|
||||||
|
Fruit::Banana,
|
||||||
|
Fruit::Mango,
|
||||||
|
Fruit::Lychee,
|
||||||
|
Fruit::Pineapple,
|
||||||
|
];
|
||||||
|
|
||||||
let mut basket = get_fruit_basket();
|
let mut basket = get_fruit_basket();
|
||||||
fruit_basket(&mut basket);
|
fruit_basket(&mut basket);
|
||||||
for amount in basket.values() {
|
|
||||||
assert_ne!(amount, &0);
|
for fruit_kind in fruit_kinds {
|
||||||
|
let Some(amount) = basket.get(&fruit_kind) else {
|
||||||
|
panic!("Fruit kind {fruit_kind:?} was not found in basket");
|
||||||
|
};
|
||||||
|
assert!(*amount > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,86 +1,77 @@
|
||||||
// hashmaps3.rs
|
|
||||||
//
|
|
||||||
// A list of scores (one per line) of a soccer match is given. Each line is of
|
// A list of scores (one per line) of a soccer match is given. Each line is of
|
||||||
// the form : "<team_1_name>,<team_2_name>,<team_1_goals>,<team_2_goals>"
|
// the form "<team_1_name>,<team_2_name>,<team_1_goals>,<team_2_goals>"
|
||||||
// Example: England,France,4,2 (England scored 4 goals, France 2).
|
// Example: "England,France,4,2" (England scored 4 goals, France 2).
|
||||||
//
|
//
|
||||||
// You have to build a scores table containing the name of the team, goals the
|
// You have to build a scores table containing the name of the team, the total
|
||||||
// team scored, and goals the team conceded. One approach to build the scores
|
// number of goals the team scored, and the total number of goals the team
|
||||||
// table is to use a Hashmap. The solution is partially written to use a
|
// conceded.
|
||||||
// Hashmap, complete it to pass the test.
|
|
||||||
//
|
|
||||||
// Make me pass the tests!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint hashmaps3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
// A structure to store the goal details of a team.
|
// A structure to store the goal details of a team.
|
||||||
struct Team {
|
#[derive(Default)]
|
||||||
|
struct TeamScores {
|
||||||
goals_scored: u8,
|
goals_scored: u8,
|
||||||
goals_conceded: u8,
|
goals_conceded: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_scores_table(results: String) -> HashMap<String, Team> {
|
fn build_scores_table(results: &str) -> HashMap<&str, TeamScores> {
|
||||||
// The name of the team is the key and its associated struct is the value.
|
// The name of the team is the key and its associated struct is the value.
|
||||||
let mut scores: HashMap<String, Team> = HashMap::new();
|
let mut scores = HashMap::new();
|
||||||
|
|
||||||
for r in results.lines() {
|
for line in results.lines() {
|
||||||
let v: Vec<&str> = r.split(',').collect();
|
let mut split_iterator = line.split(',');
|
||||||
let team_1_name = v[0].to_string();
|
// NOTE: We use `unwrap` because we didn't deal with error handling yet.
|
||||||
let team_1_score: u8 = v[2].parse().unwrap();
|
let team_1_name = split_iterator.next().unwrap();
|
||||||
let team_2_name = v[1].to_string();
|
let team_2_name = split_iterator.next().unwrap();
|
||||||
let team_2_score: u8 = v[3].parse().unwrap();
|
let team_1_score: u8 = split_iterator.next().unwrap().parse().unwrap();
|
||||||
// TODO: Populate the scores table with details extracted from the
|
let team_2_score: u8 = split_iterator.next().unwrap().parse().unwrap();
|
||||||
// current line. Keep in mind that goals scored by team_1
|
|
||||||
// will be the number of goals conceded from team_2, and similarly
|
// TODO: Populate the scores table with the extracted details.
|
||||||
// goals scored by team_2 will be the number of goals conceded by
|
// Keep in mind that goals scored by team 1 will be the number of goals
|
||||||
// team_1.
|
// conceded by team 2. Similarly, goals scored by team 2 will be the
|
||||||
|
// number of goals conceded by team 1.
|
||||||
}
|
}
|
||||||
|
|
||||||
scores
|
scores
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn get_results() -> String {
|
const RESULTS: &str = "England,France,4,2
|
||||||
let results = "".to_string()
|
France,Italy,3,1
|
||||||
+ "England,France,4,2\n"
|
Poland,Spain,2,0
|
||||||
+ "France,Italy,3,1\n"
|
Germany,England,2,1
|
||||||
+ "Poland,Spain,2,0\n"
|
England,Spain,1,0";
|
||||||
+ "Germany,England,2,1\n";
|
|
||||||
results
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn build_scores() {
|
fn build_scores() {
|
||||||
let scores = build_scores_table(get_results());
|
let scores = build_scores_table(RESULTS);
|
||||||
|
|
||||||
let mut keys: Vec<&String> = scores.keys().collect();
|
assert!(["England", "France", "Germany", "Italy", "Poland", "Spain"]
|
||||||
keys.sort();
|
.into_iter()
|
||||||
assert_eq!(
|
.all(|team_name| scores.contains_key(team_name)));
|
||||||
keys,
|
|
||||||
vec!["England", "France", "Germany", "Italy", "Poland", "Spain"]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn validate_team_score_1() {
|
fn validate_team_score_1() {
|
||||||
let scores = build_scores_table(get_results());
|
let scores = build_scores_table(RESULTS);
|
||||||
let team = scores.get("England").unwrap();
|
let team = scores.get("England").unwrap();
|
||||||
assert_eq!(team.goals_scored, 5);
|
assert_eq!(team.goals_scored, 6);
|
||||||
assert_eq!(team.goals_conceded, 4);
|
assert_eq!(team.goals_conceded, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn validate_team_score_2() {
|
fn validate_team_score_2() {
|
||||||
let scores = build_scores_table(get_results());
|
let scores = build_scores_table(RESULTS);
|
||||||
let team = scores.get("Spain").unwrap();
|
let team = scores.get("Spain").unwrap();
|
||||||
assert_eq!(team.goals_scored, 0);
|
assert_eq!(team.goals_scored, 0);
|
||||||
assert_eq!(team.goals_conceded, 2);
|
assert_eq!(team.goals_conceded, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ Option types are very common in Rust code, as they have a number of uses:
|
||||||
|
|
||||||
## Further Information
|
## Further Information
|
||||||
|
|
||||||
- [Option Enum Format](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-enum-definitions)
|
- [Option Enum Format](https://doc.rust-lang.org/book/ch10-01-syntax.html#in-enum-definitions)
|
||||||
- [Option Module Documentation](https://doc.rust-lang.org/std/option/)
|
- [Option Module Documentation](https://doc.rust-lang.org/std/option/)
|
||||||
- [Option Enum Documentation](https://doc.rust-lang.org/std/option/enum.Option.html)
|
- [Option Enum Documentation](https://doc.rust-lang.org/std/option/enum.Option.html)
|
||||||
- [if let](https://doc.rust-lang.org/rust-by-example/flow_control/if_let.html)
|
- [if let](https://doc.rust-lang.org/rust-by-example/flow_control/if_let.html)
|
||||||
|
|
|
@ -1,19 +1,13 @@
|
||||||
// options1.rs
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint options1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
// This function returns how much icecream there is left in the fridge.
|
// This function returns how much icecream there is left in the fridge.
|
||||||
// If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them
|
// If it's before 22:00 (24-hour system), then 5 scoops are left. At 22:00,
|
||||||
// all, so there'll be no more left :(
|
// someone eats it all, so no icecream is left (value 0). Return `None` if
|
||||||
fn maybe_icecream(time_of_day: u16) -> Option<u16> {
|
// `hour_of_day` is higher than 23.
|
||||||
// We use the 24-hour system here, so 10PM is a value of 22 and 12AM is a
|
fn maybe_icecream(hour_of_day: u16) -> Option<u16> {
|
||||||
// value of 0 The Option output should gracefully handle cases where
|
// TODO: Complete the function body.
|
||||||
// time_of_day > 23.
|
}
|
||||||
// TODO: Complete the function body - remember to return an Option!
|
|
||||||
???
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -21,19 +15,22 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_icecream() {
|
fn raw_value() {
|
||||||
assert_eq!(maybe_icecream(9), Some(5));
|
// TODO: Fix this test. How do you get the value contained in the
|
||||||
assert_eq!(maybe_icecream(10), Some(5));
|
// Option?
|
||||||
assert_eq!(maybe_icecream(23), Some(0));
|
let icecreams = maybe_icecream(12);
|
||||||
assert_eq!(maybe_icecream(22), Some(0));
|
|
||||||
assert_eq!(maybe_icecream(25), None);
|
assert_eq!(icecreams, 5); // Don't change this line.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn raw_value() {
|
fn check_icecream() {
|
||||||
// TODO: Fix this test. How do you get at the value contained in the
|
assert_eq!(maybe_icecream(0), Some(5));
|
||||||
// Option?
|
assert_eq!(maybe_icecream(9), Some(5));
|
||||||
let icecreams = maybe_icecream(12);
|
assert_eq!(maybe_icecream(18), Some(5));
|
||||||
assert_eq!(icecreams, 5);
|
assert_eq!(maybe_icecream(22), Some(0));
|
||||||
|
assert_eq!(maybe_icecream(23), Some(0));
|
||||||
|
assert_eq!(maybe_icecream(24), None);
|
||||||
|
assert_eq!(maybe_icecream(25), None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
// options2.rs
|
fn main() {
|
||||||
//
|
// You can optionally experiment here.
|
||||||
// Execute `rustlings hint options2` or use the `hint` watch subcommand for a
|
}
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -12,7 +9,7 @@ mod tests {
|
||||||
let target = "rustlings";
|
let target = "rustlings";
|
||||||
let optional_target = Some(target);
|
let optional_target = Some(target);
|
||||||
|
|
||||||
// TODO: Make this an if let statement whose value is "Some" type
|
// TODO: Make this an if-let statement whose value is `Some`.
|
||||||
word = optional_target {
|
word = optional_target {
|
||||||
assert_eq!(word, target);
|
assert_eq!(word, target);
|
||||||
}
|
}
|
||||||
|
@ -23,15 +20,15 @@ mod tests {
|
||||||
let range = 10;
|
let range = 10;
|
||||||
let mut optional_integers: Vec<Option<i8>> = vec![None];
|
let mut optional_integers: Vec<Option<i8>> = vec![None];
|
||||||
|
|
||||||
for i in 1..(range + 1) {
|
for i in 1..=range {
|
||||||
optional_integers.push(Some(i));
|
optional_integers.push(Some(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cursor = range;
|
let mut cursor = range;
|
||||||
|
|
||||||
// TODO: make this a while let statement - remember that vector.pop also
|
// TODO: Make this a while-let statement. Remember that `Vec::pop()`
|
||||||
// adds another layer of Option<T>. You can stack `Option<T>`s into
|
// adds another layer of `Option`. You can do nested pattern matching
|
||||||
// while let and if let.
|
// in if-let and while-let statements.
|
||||||
integer = optional_integers.pop() {
|
integer = optional_integers.pop() {
|
||||||
assert_eq!(integer, cursor);
|
assert_eq!(integer, cursor);
|
||||||
cursor -= 1;
|
cursor -= 1;
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
// options3.rs
|
#[derive(Debug)]
|
||||||
//
|
|
||||||
// Execute `rustlings hint options3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
struct Point {
|
struct Point {
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let y: Option<Point> = Some(Point { x: 100, y: 200 });
|
let optional_point = Some(Point { x: 100, y: 200 });
|
||||||
|
|
||||||
match y {
|
// TODO: Fix the compiler error by adding something to this match statement.
|
||||||
Some(p) => println!("Co-ordinates are {},{} ", p.x, p.y),
|
match optional_point {
|
||||||
_ => panic!("no match!"),
|
Some(p) => println!("Co-ordinates are {},{}", p.x, p.y),
|
||||||
|
_ => panic!("No match!"),
|
||||||
}
|
}
|
||||||
y; // Fix without deleting this line.
|
|
||||||
|
println!("{optional_point:?}"); // Don't change this line.
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,22 @@
|
||||||
// errors1.rs
|
// TODO: This function refuses to generate text to be printed on a nametag if
|
||||||
//
|
// you pass it an empty string. It'd be nicer if it explained what the problem
|
||||||
// This function refuses to generate text to be printed on a nametag if you pass
|
// was instead of just returning `None`. Thankfully, Rust has a similar
|
||||||
// it an empty string. It'd be nicer if it explained what the problem was,
|
// construct to `Option` that can be used to express error conditions. Change
|
||||||
// instead of just sometimes returning `None`. Thankfully, Rust has a similar
|
// the function signature and body to return `Result<String, String>` instead
|
||||||
// construct to `Option` that can be used to express error conditions. Let's use
|
// of `Option<String>`.
|
||||||
// it!
|
fn generate_nametag_text(name: String) -> Option<String> {
|
||||||
//
|
|
||||||
// Execute `rustlings hint errors1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub fn generate_nametag_text(name: String) -> Option<String> {
|
|
||||||
if name.is_empty() {
|
if name.is_empty() {
|
||||||
// Empty names aren't allowed.
|
// Empty names aren't allowed
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(format!("Hi! My name is {}", name))
|
Some(format!("Hi! My name is {name}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -27,17 +24,18 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn generates_nametag_text_for_a_nonempty_name() {
|
fn generates_nametag_text_for_a_nonempty_name() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
generate_nametag_text("Beyoncé".into()),
|
generate_nametag_text("Beyoncé".to_string()).as_deref(),
|
||||||
Ok("Hi! My name is Beyoncé".into())
|
Ok("Hi! My name is Beyoncé"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn explains_why_generating_nametag_text_fails() {
|
fn explains_why_generating_nametag_text_fails() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
generate_nametag_text("".into()),
|
generate_nametag_text(String::new())
|
||||||
// Don't change this line
|
.as_ref()
|
||||||
Err("`name` was empty; it must be nonempty.".into())
|
.map_err(|e| e.as_str()),
|
||||||
|
Err("Empty names aren't allowed"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
// errors2.rs
|
|
||||||
//
|
|
||||||
// Say we're writing a game where you can buy items with tokens. All items cost
|
// Say we're writing a game where you can buy items with tokens. All items cost
|
||||||
// 5 tokens, and whenever you purchase items there is a processing fee of 1
|
// 5 tokens, and whenever you purchase items there is a processing fee of 1
|
||||||
// token. A player of the game will type in how many items they want to buy, and
|
// token. A player of the game will type in how many items they want to buy, and
|
||||||
// the `total_cost` function will calculate the total cost of the items. Since
|
// the `total_cost` function will calculate the total cost of the items. Since
|
||||||
// the player typed in the quantity, though, we get it as a string-- and they
|
// the player typed in the quantity, we get it as a string. They might have
|
||||||
// might have typed anything, not just numbers!
|
// typed anything, not just numbers!
|
||||||
//
|
//
|
||||||
// Right now, this function isn't handling the error case at all (and isn't
|
// Right now, this function isn't handling the error case at all. What we want
|
||||||
// handling the success case properly either). What we want to do is: if we call
|
// to do is: If we call the `total_cost` function on a string that is not a
|
||||||
// the `total_cost` function on a string that is not a number, that function
|
// number, that function will return a `ParseIntError`. In that case, we want to
|
||||||
// will return a `ParseIntError`, and in that case, we want to immediately
|
// immediately return that error from our function and not try to multiply and
|
||||||
// return that error from our function and not try to multiply and add.
|
// add.
|
||||||
//
|
//
|
||||||
// There are at least two ways to implement this that are both correct-- but one
|
// There are at least two ways to implement this that are both correct. But one
|
||||||
// is a lot shorter!
|
// is a lot shorter!
|
||||||
//
|
|
||||||
// Execute `rustlings hint errors2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
|
fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
|
||||||
let processing_fee = 1;
|
let processing_fee = 1;
|
||||||
let cost_per_item = 5;
|
let cost_per_item = 5;
|
||||||
|
|
||||||
|
// TODO: Handle the error case as described above.
|
||||||
let qty = item_quantity.parse::<i32>();
|
let qty = item_quantity.parse::<i32>();
|
||||||
|
|
||||||
Ok(qty * cost_per_item + processing_fee)
|
Ok(qty * cost_per_item + processing_fee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::num::IntErrorKind;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn item_quantity_is_a_valid_number() {
|
fn item_quantity_is_a_valid_number() {
|
||||||
|
@ -43,8 +43,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn item_quantity_is_an_invalid_number() {
|
fn item_quantity_is_an_invalid_number() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
total_cost("beep boop").unwrap_err().to_string(),
|
total_cost("beep boop").unwrap_err().kind(),
|
||||||
"invalid digit found in string"
|
&IntErrorKind::InvalidDigit,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,31 @@
|
||||||
// errors3.rs
|
|
||||||
//
|
|
||||||
// This is a program that is trying to use a completed version of the
|
// This is a program that is trying to use a completed version of the
|
||||||
// `total_cost` function from the previous exercise. It's not working though!
|
// `total_cost` function from the previous exercise. It's not working though!
|
||||||
// Why not? What should we do to fix it?
|
// Why not? What should we do to fix it?
|
||||||
//
|
|
||||||
// Execute `rustlings hint errors3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
fn main() {
|
// Don't change this function.
|
||||||
let mut tokens = 100;
|
fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
|
||||||
let pretend_user_input = "8";
|
|
||||||
|
|
||||||
let cost = total_cost(pretend_user_input)?;
|
|
||||||
|
|
||||||
if cost > tokens {
|
|
||||||
println!("You can't afford that many!");
|
|
||||||
} else {
|
|
||||||
tokens -= cost;
|
|
||||||
println!("You now have {} tokens.", tokens);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
|
|
||||||
let processing_fee = 1;
|
let processing_fee = 1;
|
||||||
let cost_per_item = 5;
|
let cost_per_item = 5;
|
||||||
let qty = item_quantity.parse::<i32>()?;
|
let qty = item_quantity.parse::<i32>()?;
|
||||||
|
|
||||||
Ok(qty * cost_per_item + processing_fee)
|
Ok(qty * cost_per_item + processing_fee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Fix the compiler error by changing the signature and body of the
|
||||||
|
// `main` function.
|
||||||
|
fn main() {
|
||||||
|
let mut tokens = 100;
|
||||||
|
let pretend_user_input = "8";
|
||||||
|
|
||||||
|
// Don't change this line.
|
||||||
|
let cost = total_cost(pretend_user_input)?;
|
||||||
|
|
||||||
|
if cost > tokens {
|
||||||
|
println!("You can't afford that many!");
|
||||||
|
} else {
|
||||||
|
tokens -= cost;
|
||||||
|
println!("You now have {tokens} tokens.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,32 +1,37 @@
|
||||||
// errors4.rs
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint errors4` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
struct PositiveNonzeroInteger(u64);
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
enum CreationError {
|
enum CreationError {
|
||||||
Negative,
|
Negative,
|
||||||
Zero,
|
Zero,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
struct PositiveNonzeroInteger(u64);
|
||||||
|
|
||||||
impl PositiveNonzeroInteger {
|
impl PositiveNonzeroInteger {
|
||||||
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
|
fn new(value: i64) -> Result<Self, CreationError> {
|
||||||
// Hmm... Why is this always returning an Ok value?
|
// TODO: This function shouldn't always return an `Ok`.
|
||||||
Ok(PositiveNonzeroInteger(value as u64))
|
Ok(Self(value as u64))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn main() {
|
||||||
fn test_creation() {
|
// You can optionally experiment here.
|
||||||
assert!(PositiveNonzeroInteger::new(10).is_ok());
|
}
|
||||||
assert_eq!(
|
|
||||||
Err(CreationError::Negative),
|
#[cfg(test)]
|
||||||
PositiveNonzeroInteger::new(-10)
|
mod tests {
|
||||||
);
|
use super::*;
|
||||||
assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
|
|
||||||
|
#[test]
|
||||||
|
fn test_creation() {
|
||||||
|
assert_eq!(
|
||||||
|
PositiveNonzeroInteger::new(10),
|
||||||
|
Ok(PositiveNonzeroInteger(10)),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
PositiveNonzeroInteger::new(-10),
|
||||||
|
Err(CreationError::Negative),
|
||||||
|
);
|
||||||
|
assert_eq!(PositiveNonzeroInteger::new(0), Err(CreationError::Zero));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,18 @@
|
||||||
// errors5.rs
|
// This exercise is an altered version of the `errors4` exercise. It uses some
|
||||||
//
|
// concepts that we won't get to until later in the course, like `Box` and the
|
||||||
// This program uses an altered version of the code from errors4.
|
// `From` trait. It's not important to understand them in detail right now, but
|
||||||
//
|
// you can read ahead if you like. For now, think of the `Box<dyn ???>` type as
|
||||||
// This exercise uses some concepts that we won't get to until later in the
|
// an "I want anything that does ???" type.
|
||||||
// course, like `Box` and the `From` trait. It's not important to understand
|
|
||||||
// them in detail right now, but you can read ahead if you like. For now, think
|
|
||||||
// of the `Box<dyn ???>` type as an "I want anything that does ???" type, which,
|
|
||||||
// given Rust's usual standards for runtime safety, should strike you as
|
|
||||||
// somewhat lenient!
|
|
||||||
//
|
//
|
||||||
// In short, this particular use case for boxes is for when you want to own a
|
// In short, this particular use case for boxes is for when you want to own a
|
||||||
// value and you care only that it is a type which implements a particular
|
// value and you care only that it is a type which implements a particular
|
||||||
// trait. To do so, The Box is declared as of type Box<dyn Trait> where Trait is
|
// trait. To do so, The `Box` is declared as of type `Box<dyn Trait>` where
|
||||||
// the trait the compiler looks for on any value used in that context. For this
|
// `Trait` is the trait the compiler looks for on any value used in that
|
||||||
// exercise, that context is the potential errors which can be returned in a
|
// context. For this exercise, that context is the potential errors which
|
||||||
// Result.
|
// can be returned in a `Result`.
|
||||||
//
|
|
||||||
// What can we use to describe both errors? In other words, is there a trait
|
|
||||||
// which both errors implement?
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint errors5` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
use std::error::Error;
|
||||||
|
|
||||||
use std::error;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::num::ParseIntError;
|
|
||||||
|
|
||||||
// TODO: update the return type of `main()` to make this compile.
|
|
||||||
fn main() -> Result<(), Box<dyn ???>> {
|
|
||||||
let pretend_user_input = "42";
|
|
||||||
let x: i64 = pretend_user_input.parse()?;
|
|
||||||
println!("output={:?}", PositiveNonzeroInteger::new(x)?);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't change anything below this line.
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
struct PositiveNonzeroInteger(u64);
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
enum CreationError {
|
enum CreationError {
|
||||||
|
@ -47,17 +20,7 @@ enum CreationError {
|
||||||
Zero,
|
Zero,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PositiveNonzeroInteger {
|
// This is required so that `CreationError` can implement `Error`.
|
||||||
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
|
|
||||||
match value {
|
|
||||||
x if x < 0 => Err(CreationError::Negative),
|
|
||||||
x if x == 0 => Err(CreationError::Zero),
|
|
||||||
x => Ok(PositiveNonzeroInteger(x as u64)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is required so that `CreationError` can implement `error::Error`.
|
|
||||||
impl fmt::Display for CreationError {
|
impl fmt::Display for CreationError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let description = match *self {
|
let description = match *self {
|
||||||
|
@ -68,4 +31,26 @@ impl fmt::Display for CreationError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl error::Error for CreationError {}
|
impl Error for CreationError {}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
struct PositiveNonzeroInteger(u64);
|
||||||
|
|
||||||
|
impl PositiveNonzeroInteger {
|
||||||
|
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
|
||||||
|
match value {
|
||||||
|
x if x < 0 => Err(CreationError::Negative),
|
||||||
|
0 => Err(CreationError::Zero),
|
||||||
|
x => Ok(PositiveNonzeroInteger(x as u64)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add the correct return type `Result<(), Box<dyn ???>>`. What can we
|
||||||
|
// use to describe both errors? Is there a trait which both errors implement?
|
||||||
|
fn main() {
|
||||||
|
let pretend_user_input = "42";
|
||||||
|
let x: i64 = pretend_user_input.parse()?;
|
||||||
|
println!("output={:?}", PositiveNonzeroInteger::new(x)?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -1,59 +1,55 @@
|
||||||
// errors6.rs
|
// Using catch-all error types like `Box<dyn Error>` isn't recommended for
|
||||||
//
|
// library code where callers might want to make decisions based on the error
|
||||||
// Using catch-all error types like `Box<dyn error::Error>` isn't recommended
|
// content instead of printing it out or propagating it further. Here, we define
|
||||||
// for library code, where callers might want to make decisions based on the
|
// a custom error type to make it possible for callers to decide what to do next
|
||||||
// error content, instead of printing it out or propagating it further. Here, we
|
// when our function returns an error.
|
||||||
// define a custom error type to make it possible for callers to decide what to
|
|
||||||
// do next when our function returns an error.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint errors6` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
// This is a custom error type that we will be using in `parse_pos_nonzero()`.
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
enum ParsePosNonzeroError {
|
|
||||||
Creation(CreationError),
|
|
||||||
ParseInt(ParseIntError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ParsePosNonzeroError {
|
|
||||||
fn from_creation(err: CreationError) -> ParsePosNonzeroError {
|
|
||||||
ParsePosNonzeroError::Creation(err)
|
|
||||||
}
|
|
||||||
// TODO: add another error conversion function here.
|
|
||||||
// fn from_parseint...
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_pos_nonzero(s: &str) -> Result<PositiveNonzeroInteger, ParsePosNonzeroError> {
|
|
||||||
// TODO: change this to return an appropriate error instead of panicking
|
|
||||||
// when `parse()` returns an error.
|
|
||||||
let x: i64 = s.parse().unwrap();
|
|
||||||
PositiveNonzeroInteger::new(x).map_err(ParsePosNonzeroError::from_creation)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't change anything below this line.
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
struct PositiveNonzeroInteger(u64);
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
enum CreationError {
|
enum CreationError {
|
||||||
Negative,
|
Negative,
|
||||||
Zero,
|
Zero,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A custom error type that we will be using in `PositiveNonzeroInteger::parse`.
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
enum ParsePosNonzeroError {
|
||||||
|
Creation(CreationError),
|
||||||
|
ParseInt(ParseIntError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParsePosNonzeroError {
|
||||||
|
fn from_creation(err: CreationError) -> Self {
|
||||||
|
Self::Creation(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add another error conversion function here.
|
||||||
|
// fn from_parse_int(???) -> Self { ??? }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
struct PositiveNonzeroInteger(u64);
|
||||||
|
|
||||||
impl PositiveNonzeroInteger {
|
impl PositiveNonzeroInteger {
|
||||||
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
|
fn new(value: i64) -> Result<Self, CreationError> {
|
||||||
match value {
|
match value {
|
||||||
x if x < 0 => Err(CreationError::Negative),
|
x if x < 0 => Err(CreationError::Negative),
|
||||||
x if x == 0 => Err(CreationError::Zero),
|
0 => Err(CreationError::Zero),
|
||||||
x => Ok(PositiveNonzeroInteger(x as u64)),
|
x => Ok(Self(x as u64)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse(s: &str) -> Result<Self, ParsePosNonzeroError> {
|
||||||
|
// TODO: change this to return an appropriate error instead of panicking
|
||||||
|
// when `parse()` returns an error.
|
||||||
|
let x: i64 = s.parse().unwrap();
|
||||||
|
Self::new(x).map_err(ParsePosNonzeroError::from_creation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -62,33 +58,32 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_error() {
|
fn test_parse_error() {
|
||||||
// We can't construct a ParseIntError, so we have to pattern match.
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
parse_pos_nonzero("not a number"),
|
PositiveNonzeroInteger::parse("not a number"),
|
||||||
Err(ParsePosNonzeroError::ParseInt(_))
|
Err(ParsePosNonzeroError::ParseInt(_)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_negative() {
|
fn test_negative() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_pos_nonzero("-555"),
|
PositiveNonzeroInteger::parse("-555"),
|
||||||
Err(ParsePosNonzeroError::Creation(CreationError::Negative))
|
Err(ParsePosNonzeroError::Creation(CreationError::Negative)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_zero() {
|
fn test_zero() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_pos_nonzero("0"),
|
PositiveNonzeroInteger::parse("0"),
|
||||||
Err(ParsePosNonzeroError::Creation(CreationError::Zero))
|
Err(ParsePosNonzeroError::Creation(CreationError::Zero)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_positive() {
|
fn test_positive() {
|
||||||
let x = PositiveNonzeroInteger::new(42);
|
let x = PositiveNonzeroInteger::new(42).unwrap();
|
||||||
assert!(x.is_ok());
|
assert_eq!(x.0, 42);
|
||||||
assert_eq!(parse_pos_nonzero("42"), Ok(x.unwrap()));
|
assert_eq!(PositiveNonzeroInteger::parse("42"), Ok(x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Generics
|
# Generics
|
||||||
|
|
||||||
Generics is the topic of generalizing types and functionalities to broader cases.
|
Generics is the topic of generalizing types and functionalities to broader cases.
|
||||||
This is extremely useful for reducing code duplication in many ways, but can call for rather involving syntax.
|
This is extremely useful for reducing code duplication in many ways, but can call for some rather involved syntax.
|
||||||
Namely, being generic requires taking great care to specify over which types a generic type is actually considered valid.
|
Namely, being generic requires taking great care to specify over which types a generic type is actually considered valid.
|
||||||
The simplest and most common use of generics is for type parameters.
|
The simplest and most common use of generics is for type parameters.
|
||||||
|
|
||||||
## Further information
|
## Further information
|
||||||
|
|
||||||
- [Generic Data Types](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html)
|
- [Generic Data Types](https://doc.rust-lang.org/book/ch10-01-syntax.html)
|
||||||
- [Bounds](https://doc.rust-lang.org/rust-by-example/generics/bounds.html)
|
- [Bounds](https://doc.rust-lang.org/rust-by-example/generics/bounds.html)
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
// generics1.rs
|
// `Vec<T>` is generic over the type `T`. In most cases, the compiler is able to
|
||||||
//
|
// infer `T`, for example after pushing a value with a concrete type to the vector.
|
||||||
// This shopping list program isn't compiling! Use your knowledge of generics to
|
// But in this exercise, the compiler needs some help through a type annotation.
|
||||||
// fix it.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint generics1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut shopping_list: Vec<?> = Vec::new();
|
// TODO: Fix the compiler error by annotating the type of the vector
|
||||||
shopping_list.push("milk");
|
// `Vec<T>`. Choose `T` as some integer type that can be created from
|
||||||
|
// `u8` and `i8`.
|
||||||
|
let mut numbers = Vec::new();
|
||||||
|
|
||||||
|
// Don't change the lines below.
|
||||||
|
let n1: u8 = 42;
|
||||||
|
numbers.push(n1.into());
|
||||||
|
let n2: i8 = -1;
|
||||||
|
numbers.push(n2.into());
|
||||||
|
|
||||||
|
println!("{numbers:?}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
// generics2.rs
|
|
||||||
//
|
|
||||||
// This powerful wrapper provides the ability to store a positive integer value.
|
// This powerful wrapper provides the ability to store a positive integer value.
|
||||||
// Rewrite it using generics so that it supports wrapping ANY type.
|
// TODO: Rewrite it using a generic so that it supports wrapping ANY type.
|
||||||
//
|
|
||||||
// Execute `rustlings hint generics2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
struct Wrapper {
|
struct Wrapper {
|
||||||
value: u32,
|
value: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Adapt the struct's implementation to be generic over the wrapped value.
|
||||||
impl Wrapper {
|
impl Wrapper {
|
||||||
pub fn new(value: u32) -> Self {
|
fn new(value: u32) -> Self {
|
||||||
Wrapper { value }
|
Wrapper { value }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -1,26 +1,17 @@
|
||||||
// traits1.rs
|
// The trait `AppendBar` has only one function which appends "Bar" to any object
|
||||||
//
|
// implementing this trait.
|
||||||
// Time to implement some traits! Your task is to implement the trait
|
|
||||||
// `AppendBar` for the type `String`. The trait AppendBar has only one function,
|
|
||||||
// which appends "Bar" to any object implementing this trait.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint traits1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
trait AppendBar {
|
trait AppendBar {
|
||||||
fn append_bar(self) -> Self;
|
fn append_bar(self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppendBar for String {
|
impl AppendBar for String {
|
||||||
// TODO: Implement `AppendBar` for type `String`.
|
// TODO: Implement `AppendBar` for the type `String`.
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let s = String::from("Foo");
|
let s = String::from("Foo");
|
||||||
let s = s.append_bar();
|
let s = s.append_bar();
|
||||||
println!("s: {}", s);
|
println!("s: {s}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -29,14 +20,11 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_foo_bar() {
|
fn is_foo_bar() {
|
||||||
assert_eq!(String::from("Foo").append_bar(), String::from("FooBar"));
|
assert_eq!(String::from("Foo").append_bar(), "FooBar");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_bar_bar() {
|
fn is_bar_bar() {
|
||||||
assert_eq!(
|
assert_eq!(String::from("").append_bar().append_bar(), "BarBar");
|
||||||
String::from("").append_bar().append_bar(),
|
|
||||||
String::from("BarBar")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,13 @@
|
||||||
// traits2.rs
|
|
||||||
//
|
|
||||||
// Your task is to implement the trait `AppendBar` for a vector of strings. To
|
|
||||||
// implement this trait, consider for a moment what it means to 'append "Bar"'
|
|
||||||
// to a vector of strings.
|
|
||||||
//
|
|
||||||
// No boiler plate code this time, you can do this!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint traits2` or use the `hint` watch subcommand for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
trait AppendBar {
|
trait AppendBar {
|
||||||
fn append_bar(self) -> Self;
|
fn append_bar(self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement trait `AppendBar` for a vector of strings.
|
// TODO: Implement the trait `AppendBar` for a vector of strings.
|
||||||
|
// `append_bar` should push the string "Bar" into the vector.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -23,7 +16,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn is_vec_pop_eq_bar() {
|
fn is_vec_pop_eq_bar() {
|
||||||
let mut foo = vec![String::from("Foo")].append_bar();
|
let mut foo = vec![String::from("Foo")].append_bar();
|
||||||
assert_eq!(foo.pop().unwrap(), String::from("Bar"));
|
assert_eq!(foo.pop().unwrap(), "Bar");
|
||||||
assert_eq!(foo.pop().unwrap(), String::from("Foo"));
|
assert_eq!(foo.pop().unwrap(), "Foo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,8 @@
|
||||||
// traits3.rs
|
trait Licensed {
|
||||||
//
|
// TODO: Add a default implementation for `licensing_info` so that
|
||||||
// Your task is to implement the Licensed trait for both structures and have
|
// implementors like the two structs below can share that default behavior
|
||||||
// them return the same information without writing the same function twice.
|
// without repeating the function.
|
||||||
//
|
// The default license information should be the string "Default license".
|
||||||
// Consider what you can add to the Licensed trait.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint traits3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub trait Licensed {
|
|
||||||
fn licensing_info(&self) -> String;
|
fn licensing_info(&self) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,8 +14,12 @@ struct OtherSoftware {
|
||||||
version_number: String,
|
version_number: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Licensed for SomeSoftware {} // Don't edit this line
|
impl Licensed for SomeSoftware {} // Don't edit this line.
|
||||||
impl Licensed for OtherSoftware {} // Don't edit this line
|
impl Licensed for OtherSoftware {} // Don't edit this line.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -31,7 +27,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_licensing_info_the_same() {
|
fn is_licensing_info_the_same() {
|
||||||
let licensing_info = String::from("Some information");
|
let licensing_info = "Default license";
|
||||||
let some_software = SomeSoftware { version_number: 1 };
|
let some_software = SomeSoftware { version_number: 1 };
|
||||||
let other_software = OtherSoftware {
|
let other_software = OtherSoftware {
|
||||||
version_number: "v2.0.0".to_string(),
|
version_number: "v2.0.0".to_string(),
|
||||||
|
|
|
@ -1,30 +1,22 @@
|
||||||
// traits4.rs
|
trait Licensed {
|
||||||
//
|
|
||||||
// Your task is to replace the '??' sections so the code compiles.
|
|
||||||
//
|
|
||||||
// Don't change any line other than the marked one.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint traits4` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub trait Licensed {
|
|
||||||
fn licensing_info(&self) -> String {
|
fn licensing_info(&self) -> String {
|
||||||
"some information".to_string()
|
"Default license".to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SomeSoftware {}
|
struct SomeSoftware;
|
||||||
|
struct OtherSoftware;
|
||||||
struct OtherSoftware {}
|
|
||||||
|
|
||||||
impl Licensed for SomeSoftware {}
|
impl Licensed for SomeSoftware {}
|
||||||
impl Licensed for OtherSoftware {}
|
impl Licensed for OtherSoftware {}
|
||||||
|
|
||||||
// YOU MAY ONLY CHANGE THE NEXT LINE
|
// TODO: Fix the compiler error by only changing the signature of this function.
|
||||||
fn compare_license_types(software: ??, software_two: ??) -> bool {
|
fn compare_license_types(software1: ???, software2: ???) -> bool {
|
||||||
software.licensing_info() == software_two.licensing_info()
|
software1.licensing_info() == software2.licensing_info()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -33,17 +25,11 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn compare_license_information() {
|
fn compare_license_information() {
|
||||||
let some_software = SomeSoftware {};
|
assert!(compare_license_types(SomeSoftware, OtherSoftware));
|
||||||
let other_software = OtherSoftware {};
|
|
||||||
|
|
||||||
assert!(compare_license_types(some_software, other_software));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn compare_license_information_backwards() {
|
fn compare_license_information_backwards() {
|
||||||
let some_software = SomeSoftware {};
|
assert!(compare_license_types(OtherSoftware, SomeSoftware));
|
||||||
let other_software = OtherSoftware {};
|
|
||||||
|
|
||||||
assert!(compare_license_types(other_software, some_software));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,39 @@
|
||||||
// traits5.rs
|
trait SomeTrait {
|
||||||
//
|
|
||||||
// Your task is to replace the '??' sections so the code compiles.
|
|
||||||
//
|
|
||||||
// Don't change any line other than the marked one.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint traits5` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub trait SomeTrait {
|
|
||||||
fn some_function(&self) -> bool {
|
fn some_function(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait OtherTrait {
|
trait OtherTrait {
|
||||||
fn other_function(&self) -> bool {
|
fn other_function(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SomeStruct {}
|
struct SomeStruct;
|
||||||
struct OtherStruct {}
|
|
||||||
|
|
||||||
impl SomeTrait for SomeStruct {}
|
impl SomeTrait for SomeStruct {}
|
||||||
impl OtherTrait for SomeStruct {}
|
impl OtherTrait for SomeStruct {}
|
||||||
|
|
||||||
|
struct OtherStruct;
|
||||||
impl SomeTrait for OtherStruct {}
|
impl SomeTrait for OtherStruct {}
|
||||||
impl OtherTrait for OtherStruct {}
|
impl OtherTrait for OtherStruct {}
|
||||||
|
|
||||||
// YOU MAY ONLY CHANGE THE NEXT LINE
|
// TODO: Fix the compiler error by only changing the signature of this function.
|
||||||
fn some_func(item: ??) -> bool {
|
fn some_func(item: ???) -> bool {
|
||||||
item.some_function() && item.other_function()
|
item.some_function() && item.other_function()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
some_func(SomeStruct {});
|
// You can optionally experiment here.
|
||||||
some_func(OtherStruct {});
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_some_func() {
|
||||||
|
assert!(some_func(SomeStruct));
|
||||||
|
assert!(some_func(OtherStruct));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
// lifetimes1.rs
|
|
||||||
//
|
|
||||||
// The Rust compiler needs to know how to check whether supplied references are
|
// The Rust compiler needs to know how to check whether supplied references are
|
||||||
// valid, so that it can let the programmer know if a reference is at risk of
|
// valid, so that it can let the programmer know if a reference is at risk of
|
||||||
// going out of scope before it is used. Remember, references are borrows and do
|
// going out of scope before it is used. Remember, references are borrows and do
|
||||||
// not own their own data. What if their owner goes out of scope?
|
// not own their own data. What if their owner goes out of scope?
|
||||||
//
|
|
||||||
// Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
|
// TODO: Fix the compiler error by updating the function signature.
|
||||||
fn longest(x: &str, y: &str) -> &str {
|
fn longest(x: &str, y: &str) -> &str {
|
||||||
if x.len() > y.len() {
|
if x.len() > y.len() {
|
||||||
x
|
x
|
||||||
|
@ -19,9 +13,16 @@ fn longest(x: &str, y: &str) -> &str {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let string1 = String::from("abcd");
|
// You can optionally experiment here.
|
||||||
let string2 = "xyz";
|
}
|
||||||
|
|
||||||
let result = longest(string1.as_str(), string2);
|
#[cfg(test)]
|
||||||
println!("The longest string is '{}'", result);
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_longest() {
|
||||||
|
assert_eq!(longest("abcd", "123"), "abcd");
|
||||||
|
assert_eq!(longest("abc", "1234"), "1234");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,4 @@
|
||||||
// lifetimes2.rs
|
// Don't change this function.
|
||||||
//
|
|
||||||
// So if the compiler is just validating the references passed to the annotated
|
|
||||||
// parameters and the return type, what do we need to change?
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
|
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
|
||||||
if x.len() > y.len() {
|
if x.len() > y.len() {
|
||||||
x
|
x
|
||||||
|
@ -17,11 +8,13 @@ fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// TODO: Fix the compiler error by moving one line.
|
||||||
|
|
||||||
let string1 = String::from("long string is long");
|
let string1 = String::from("long string is long");
|
||||||
let result;
|
let result;
|
||||||
{
|
{
|
||||||
let string2 = String::from("xyz");
|
let string2 = String::from("xyz");
|
||||||
result = longest(string1.as_str(), string2.as_str());
|
result = longest(&string1, &string2);
|
||||||
}
|
}
|
||||||
println!("The longest string is '{}'", result);
|
println!("The longest string is '{result}'");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,16 @@
|
||||||
// lifetimes3.rs
|
|
||||||
//
|
|
||||||
// Lifetimes are also needed when structs hold references.
|
// Lifetimes are also needed when structs hold references.
|
||||||
//
|
|
||||||
// Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
|
// TODO: Fix the compiler errors about the struct.
|
||||||
struct Book {
|
struct Book {
|
||||||
author: &str,
|
author: &str,
|
||||||
title: &str,
|
title: &str,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let name = String::from("Jill Smith");
|
let book = Book {
|
||||||
let title = String::from("Fish Flying");
|
author: "George Orwell",
|
||||||
let book = Book { author: &name, title: &title };
|
title: "1984",
|
||||||
|
};
|
||||||
|
|
||||||
println!("{} by {}", book.title, book.author);
|
println!("{} by {}", book.title, book.author);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
// tests1.rs
|
|
||||||
//
|
|
||||||
// Tests are important to ensure that your code does what you think it should
|
// 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: rustlings run
|
// do.
|
||||||
// tests1
|
|
||||||
//
|
|
||||||
// This test has a problem with it -- make the test compile! Make the test pass!
|
|
||||||
// Make the test fail!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint tests1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
fn is_even(n: i64) -> bool {
|
||||||
|
n % 2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
// TODO: Import `is_even`. You can use a wildcard to import everything in
|
||||||
|
// the outer module.
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn you_can_assert() {
|
fn you_can_assert() {
|
||||||
|
// TODO: Test the function `is_even` with some values.
|
||||||
|
assert!();
|
||||||
assert!();
|
assert!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,23 @@
|
||||||
// tests2.rs
|
// Calculates the power of 2 using a bit shift.
|
||||||
//
|
// `1 << n` is equivalent to "2 to the power of n".
|
||||||
// This test has a problem with it -- make the test compile! Make the test pass!
|
fn power_of_2(n: u8) -> u64 {
|
||||||
// Make the test fail!
|
1 << n
|
||||||
//
|
}
|
||||||
// Execute `rustlings hint tests2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn you_can_assert_eq() {
|
fn you_can_assert_eq() {
|
||||||
|
// TODO: Test the function `power_of_2` with some values.
|
||||||
|
assert_eq!();
|
||||||
|
assert_eq!();
|
||||||
|
assert_eq!();
|
||||||
assert_eq!();
|
assert_eq!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,23 @@
|
||||||
// tests3.rs
|
struct Rectangle {
|
||||||
//
|
width: i32,
|
||||||
// This test isn't testing our function -- make it do that in such a way that
|
height: i32,
|
||||||
// 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)`.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint tests3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
impl Rectangle {
|
||||||
|
// Don't change this function.
|
||||||
|
fn new(width: i32, height: i32) -> Self {
|
||||||
|
if width <= 0 || height <= 0 {
|
||||||
|
// Returning a `Result` would be better here. But we want to learn
|
||||||
|
// how to test functions that can panic.
|
||||||
|
panic!("Rectangle width and height must be positive");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_even(num: i32) -> bool {
|
Rectangle { width, height }
|
||||||
num % 2 == 0
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -18,12 +25,25 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_true_when_even() {
|
fn correct_width_and_height() {
|
||||||
assert!();
|
// TODO: This test should check if the rectangle has the size that we
|
||||||
|
// pass to its constructor.
|
||||||
|
let rect = Rectangle::new(10, 20);
|
||||||
|
assert_eq!(todo!(), 10); // Check width
|
||||||
|
assert_eq!(todo!(), 20); // Check height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This test should check if the program panics when we try to create
|
||||||
|
// a rectangle with negative width.
|
||||||
#[test]
|
#[test]
|
||||||
fn is_false_when_odd() {
|
fn negative_width() {
|
||||||
assert!();
|
let _rect = Rectangle::new(-10, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: This test should check if the program panics when we try to create
|
||||||
|
// a rectangle with negative height.
|
||||||
|
#[test]
|
||||||
|
fn negative_height() {
|
||||||
|
let _rect = Rectangle::new(10, -10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
// tests4.rs
|
|
||||||
//
|
|
||||||
// Make sure that we're testing for the correct conditions!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint tests4` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
struct Rectangle {
|
|
||||||
width: i32,
|
|
||||||
height: i32
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Rectangle {
|
|
||||||
// Only change the test functions themselves
|
|
||||||
pub fn new(width: i32, height: i32) -> Self {
|
|
||||||
if width <= 0 || height <= 0 {
|
|
||||||
panic!("Rectangle width and height cannot be negative!")
|
|
||||||
}
|
|
||||||
Rectangle {width, height}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn correct_width_and_height() {
|
|
||||||
// This test should check if the rectangle is the size that we pass into its constructor
|
|
||||||
let rect = Rectangle::new(10, 20);
|
|
||||||
assert_eq!(???, 10); // check width
|
|
||||||
assert_eq!(???, 20); // check height
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn negative_width() {
|
|
||||||
// This test should check if program panics when we try to create rectangle with negative width
|
|
||||||
let _rect = Rectangle::new(-10, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn negative_height() {
|
|
||||||
// This test should check if program panics when we try to create rectangle with negative height
|
|
||||||
let _rect = Rectangle::new(10, -10);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +1,25 @@
|
||||||
// iterators1.rs
|
|
||||||
//
|
|
||||||
// When performing operations on elements within a collection, iterators are
|
// When performing operations on elements within a collection, iterators are
|
||||||
// essential. This module helps you get familiar with the structure of using an
|
// essential. This module helps you get familiar with the structure of using an
|
||||||
// iterator and how to go through elements within an iterable collection.
|
// iterator and how to go through elements within an iterable collection.
|
||||||
//
|
|
||||||
// Make me compile by filling in the `???`s
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
let mut my_iterable_fav_fruits = ???; // TODO: Step 1
|
|
||||||
|
#[cfg(test)]
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana"));
|
mod tests {
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2
|
#[test]
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"avocado"));
|
fn iterators() {
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 3
|
let my_fav_fruits = ["banana", "custard apple", "avocado", "peach", "raspberry"];
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry"));
|
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 4
|
// TODO: Create an iterator over the array.
|
||||||
|
let mut fav_fruits_iterator = todo!();
|
||||||
|
|
||||||
|
assert_eq!(fav_fruits_iterator.next(), Some(&"banana"));
|
||||||
|
assert_eq!(fav_fruits_iterator.next(), todo!()); // TODO: Replace `todo!()`
|
||||||
|
assert_eq!(fav_fruits_iterator.next(), Some(&"avocado"));
|
||||||
|
assert_eq!(fav_fruits_iterator.next(), todo!()); // TODO: Replace `todo!()`
|
||||||
|
assert_eq!(fav_fruits_iterator.next(), Some(&"raspberry"));
|
||||||
|
assert_eq!(fav_fruits_iterator.next(), todo!()); // TODO: Replace `todo!()`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,32 @@
|
||||||
// iterators2.rs
|
|
||||||
//
|
|
||||||
// In this exercise, you'll learn some of the unique advantages that iterators
|
// In this exercise, you'll learn some of the unique advantages that iterators
|
||||||
// can offer. Follow the steps to complete the exercise.
|
// can offer.
|
||||||
//
|
|
||||||
// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
// TODO: Complete the `capitalize_first` function.
|
||||||
|
|
||||||
// Step 1.
|
|
||||||
// Complete the `capitalize_first` function.
|
|
||||||
// "hello" -> "Hello"
|
// "hello" -> "Hello"
|
||||||
pub fn capitalize_first(input: &str) -> String {
|
fn capitalize_first(input: &str) -> String {
|
||||||
let mut c = input.chars();
|
let mut chars = input.chars();
|
||||||
match c.next() {
|
match chars.next() {
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
Some(first) => ???,
|
Some(first) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2.
|
// TODO: Apply the `capitalize_first` function to a slice of string slices.
|
||||||
// Apply the `capitalize_first` function to a slice of string slices.
|
|
||||||
// Return a vector of strings.
|
// Return a vector of strings.
|
||||||
// ["hello", "world"] -> ["Hello", "World"]
|
// ["hello", "world"] -> ["Hello", "World"]
|
||||||
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
|
fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
|
||||||
vec![]
|
// ???
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3.
|
// TODO: Apply the `capitalize_first` function again to a slice of string
|
||||||
// Apply the `capitalize_first` function again to a slice of string slices.
|
// slices. Return a single string.
|
||||||
// Return a single string.
|
|
||||||
// ["hello", " ", "world"] -> "Hello World"
|
// ["hello", " ", "world"] -> "Hello World"
|
||||||
pub fn capitalize_words_string(words: &[&str]) -> String {
|
fn capitalize_words_string(words: &[&str]) -> String {
|
||||||
String::new()
|
// ???
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1,50 +1,37 @@
|
||||||
// iterators3.rs
|
|
||||||
//
|
|
||||||
// This is a bigger exercise than most of the others! You can do it! Here is
|
|
||||||
// your mission, should you choose to accept it:
|
|
||||||
// 1. Complete the divide function to get the first four tests to pass.
|
|
||||||
// 2. Get the remaining tests to pass by completing the result_with_list and
|
|
||||||
// list_of_results functions.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum DivisionError {
|
enum DivisionError {
|
||||||
NotDivisible(NotDivisibleError),
|
// Example: 42 / 0
|
||||||
DivideByZero,
|
DivideByZero,
|
||||||
|
// Only case for `i64`: `i64::MIN / -1` because the result is `i64::MAX + 1`
|
||||||
|
IntegerOverflow,
|
||||||
|
// Example: 5 / 2 = 2.5
|
||||||
|
NotDivisible,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
// TODO: Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
|
||||||
pub struct NotDivisibleError {
|
|
||||||
dividend: i32,
|
|
||||||
divisor: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
|
|
||||||
// Otherwise, return a suitable error.
|
// Otherwise, return a suitable error.
|
||||||
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
|
fn divide(a: i64, b: i64) -> Result<i64, DivisionError> {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete the function and return a value of the correct type so the test
|
// TODO: Add the correct return type and complete the function body.
|
||||||
// passes.
|
// Desired output: `Ok([1, 11, 1426, 3])`
|
||||||
// Desired output: Ok([1, 11, 1426, 3])
|
fn result_with_list() {
|
||||||
fn result_with_list() -> () {
|
let numbers = [27, 297, 38502, 81];
|
||||||
let numbers = vec![27, 297, 38502, 81];
|
|
||||||
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete the function and return a value of the correct type so the test
|
// TODO: Add the correct return type and complete the function body.
|
||||||
// passes.
|
// Desired output: `[Ok(1), Ok(11), Ok(1426), Ok(3)]`
|
||||||
// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)]
|
fn list_of_results() {
|
||||||
fn list_of_results() -> () {
|
let numbers = [27, 297, 38502, 81];
|
||||||
let numbers = vec![27, 297, 38502, 81];
|
|
||||||
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -55,19 +42,18 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_not_divisible() {
|
fn test_divide_by_0() {
|
||||||
assert_eq!(
|
assert_eq!(divide(81, 0), Err(DivisionError::DivideByZero));
|
||||||
divide(81, 6),
|
|
||||||
Err(DivisionError::NotDivisible(NotDivisibleError {
|
|
||||||
dividend: 81,
|
|
||||||
divisor: 6
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_divide_by_0() {
|
fn test_integer_overflow() {
|
||||||
assert_eq!(divide(81, 0), Err(DivisionError::DivideByZero));
|
assert_eq!(divide(i64::MIN, -1), Err(DivisionError::IntegerOverflow));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_not_divisible() {
|
||||||
|
assert_eq!(divide(81, 6), Err(DivisionError::NotDivisible));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -77,14 +63,11 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_result_with_list() {
|
fn test_result_with_list() {
|
||||||
assert_eq!(format!("{:?}", result_with_list()), "Ok([1, 11, 1426, 3])");
|
assert_eq!(result_with_list().unwrap(), [1, 11, 1426, 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_list_of_results() {
|
fn test_list_of_results() {
|
||||||
assert_eq!(
|
assert_eq!(list_of_results(), [Ok(1), Ok(11), Ok(1426), Ok(3)]);
|
||||||
format!("{:?}", list_of_results()),
|
|
||||||
"[Ok(1), Ok(11), Ok(1426), Ok(3)]"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
// iterators4.rs
|
fn factorial(num: u64) -> u64 {
|
||||||
//
|
// TODO: Complete this function to return the factorial of `num` which is
|
||||||
// Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a
|
// defined as `1 * 2 * 3 * … * num`.
|
||||||
// hint.
|
// https://en.wikipedia.org/wiki/Factorial
|
||||||
|
//
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub fn factorial(num: u64) -> u64 {
|
|
||||||
// Complete this function to return the factorial of num
|
|
||||||
// Do not use:
|
// Do not use:
|
||||||
// - return
|
// - early returns (using the `return` keyword explicitly)
|
||||||
// Try not to use:
|
// Try not to use:
|
||||||
// - imperative style loops (for, while)
|
// - imperative style loops (for/while)
|
||||||
// - additional variables
|
// - additional variables
|
||||||
// For an extra challenge, don't use:
|
// For an extra challenge, don't use:
|
||||||
// - recursion
|
// - recursion
|
||||||
// Execute `rustlings hint iterators4` for hints.
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -23,20 +22,20 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn factorial_of_0() {
|
fn factorial_of_0() {
|
||||||
assert_eq!(1, factorial(0));
|
assert_eq!(factorial(0), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn factorial_of_1() {
|
fn factorial_of_1() {
|
||||||
assert_eq!(1, factorial(1));
|
assert_eq!(factorial(1), 1);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn factorial_of_2() {
|
fn factorial_of_2() {
|
||||||
assert_eq!(2, factorial(2));
|
assert_eq!(factorial(2), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn factorial_of_4() {
|
fn factorial_of_4() {
|
||||||
assert_eq!(24, factorial(4));
|
assert_eq!(factorial(4), 24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,8 @@
|
||||||
// iterators5.rs
|
// Let's define a simple model to track Rustlings' exercise progress. Progress
|
||||||
//
|
|
||||||
// Let's define a simple model to track Rustlings exercise progress. Progress
|
|
||||||
// will be modelled using a hash map. The name of the exercise is the key and
|
// will be modelled using a hash map. The name of the exercise is the key and
|
||||||
// the progress is the value. Two counting functions were created to count the
|
// the progress is the value. Two counting functions were created to count the
|
||||||
// number of exercises with a given progress. Recreate this counting
|
// number of exercises with a given progress. Recreate this counting
|
||||||
// functionality using iterators. Try not to use imperative loops (for, while).
|
// functionality using iterators. Try to not use imperative loops (for/while).
|
||||||
// Only the two iterator methods (count_iterator and count_collection_iterator)
|
|
||||||
// need to be modified.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
@ -25,24 +16,25 @@ enum Progress {
|
||||||
fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
|
fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for val in map.values() {
|
for val in map.values() {
|
||||||
if val == &value {
|
if *val == value {
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count
|
count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Implement the functionality of `count_for` but with an iterator instead
|
||||||
|
// of a `for` loop.
|
||||||
fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
|
fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
|
||||||
// map is a hashmap with String keys and Progress values.
|
// `map` is a hash map with `String` keys and `Progress` values.
|
||||||
// map = { "variables1": Complete, "from_str": None, ... }
|
// map = { "variables1": Complete, "from_str": None, … }
|
||||||
todo!();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
|
fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for map in collection {
|
for map in collection {
|
||||||
for val in map.values() {
|
for val in map.values() {
|
||||||
if val == &value {
|
if *val == value {
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,81 +42,22 @@ fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progres
|
||||||
count
|
count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Implement the functionality of `count_collection_for` but with an
|
||||||
|
// iterator instead of a `for` loop.
|
||||||
fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
|
fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
|
||||||
// collection is a slice of hashmaps.
|
// `collection` is a slice of hash maps.
|
||||||
// collection = [{ "variables1": Complete, "from_str": None, ... },
|
// collection = [{ "variables1": Complete, "from_str": None, … },
|
||||||
// { "variables2": Complete, ... }, ... ]
|
// { "variables2": Complete, … }, … ]
|
||||||
todo!();
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// You can optionally experiment here.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn count_complete() {
|
|
||||||
let map = get_map();
|
|
||||||
assert_eq!(3, count_iterator(&map, Progress::Complete));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn count_some() {
|
|
||||||
let map = get_map();
|
|
||||||
assert_eq!(1, count_iterator(&map, Progress::Some));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn count_none() {
|
|
||||||
let map = get_map();
|
|
||||||
assert_eq!(2, count_iterator(&map, Progress::None));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn count_complete_equals_for() {
|
|
||||||
let map = get_map();
|
|
||||||
let progress_states = vec![Progress::Complete, Progress::Some, Progress::None];
|
|
||||||
for progress_state in progress_states {
|
|
||||||
assert_eq!(
|
|
||||||
count_for(&map, progress_state),
|
|
||||||
count_iterator(&map, progress_state)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn count_collection_complete() {
|
|
||||||
let collection = get_vec_map();
|
|
||||||
assert_eq!(
|
|
||||||
6,
|
|
||||||
count_collection_iterator(&collection, Progress::Complete)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn count_collection_some() {
|
|
||||||
let collection = get_vec_map();
|
|
||||||
assert_eq!(1, count_collection_iterator(&collection, Progress::Some));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn count_collection_none() {
|
|
||||||
let collection = get_vec_map();
|
|
||||||
assert_eq!(4, count_collection_iterator(&collection, Progress::None));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn count_collection_equals_for() {
|
|
||||||
let progress_states = vec![Progress::Complete, Progress::Some, Progress::None];
|
|
||||||
let collection = get_vec_map();
|
|
||||||
|
|
||||||
for progress_state in progress_states {
|
|
||||||
assert_eq!(
|
|
||||||
count_collection_for(&collection, progress_state),
|
|
||||||
count_collection_iterator(&collection, progress_state)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_map() -> HashMap<String, Progress> {
|
fn get_map() -> HashMap<String, Progress> {
|
||||||
use Progress::*;
|
use Progress::*;
|
||||||
|
|
||||||
|
@ -153,4 +86,68 @@ mod tests {
|
||||||
|
|
||||||
vec![map, other]
|
vec![map, other]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_complete() {
|
||||||
|
let map = get_map();
|
||||||
|
assert_eq!(count_iterator(&map, Progress::Complete), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_some() {
|
||||||
|
let map = get_map();
|
||||||
|
assert_eq!(count_iterator(&map, Progress::Some), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_none() {
|
||||||
|
let map = get_map();
|
||||||
|
assert_eq!(count_iterator(&map, Progress::None), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_complete_equals_for() {
|
||||||
|
let map = get_map();
|
||||||
|
let progress_states = [Progress::Complete, Progress::Some, Progress::None];
|
||||||
|
for progress_state in progress_states {
|
||||||
|
assert_eq!(
|
||||||
|
count_for(&map, progress_state),
|
||||||
|
count_iterator(&map, progress_state),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_collection_complete() {
|
||||||
|
let collection = get_vec_map();
|
||||||
|
assert_eq!(
|
||||||
|
count_collection_iterator(&collection, Progress::Complete),
|
||||||
|
6,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_collection_some() {
|
||||||
|
let collection = get_vec_map();
|
||||||
|
assert_eq!(count_collection_iterator(&collection, Progress::Some), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_collection_none() {
|
||||||
|
let collection = get_vec_map();
|
||||||
|
assert_eq!(count_collection_iterator(&collection, Progress::None), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_collection_equals_for() {
|
||||||
|
let collection = get_vec_map();
|
||||||
|
let progress_states = [Progress::Complete, Progress::Some, Progress::None];
|
||||||
|
|
||||||
|
for progress_state in progress_states {
|
||||||
|
assert_eq!(
|
||||||
|
count_collection_for(&collection, progress_state),
|
||||||
|
count_collection_iterator(&collection, progress_state),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue