Compare commits
No commits in common. "main" and "fix/remove-highlighting" have entirely different histories.
main
...
fix/remove
2446
.all-contributorsrc
2446
.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
|
|
|
@ -1,7 +0,0 @@
|
||||||
root = true
|
|
||||||
|
|
||||||
[*.rs]
|
|
||||||
end_of_line = lf
|
|
||||||
insert_final_newline = true
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
4
.envrc
4
.envrc
|
@ -1,4 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Automatically Load nix devShell w/dotenv
|
|
||||||
use flake
|
|
|
@ -1,37 +0,0 @@
|
||||||
name: Rustlings Tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ main ]
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
fmt:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
components: rustfmt
|
|
||||||
- uses: DavidAnson/markdownlint-cli2-action@v9
|
|
||||||
with:
|
|
||||||
globs: "exercises/**/*.md"
|
|
||||||
- name: Run cargo fmt
|
|
||||||
run: |
|
|
||||||
cargo fmt --all -- --check
|
|
||||||
test:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
- uses: swatinem/rust-cache@v2
|
|
||||||
- name: Run cargo test
|
|
||||||
run: |
|
|
||||||
cargo test
|
|
|
@ -1,88 +0,0 @@
|
||||||
# Workflow to build your docs with oranda (and mdbook)
|
|
||||||
# and deploy them to Github Pages
|
|
||||||
name: Web
|
|
||||||
|
|
||||||
# We're going to push to the gh-pages branch, so we need that permission
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
# What situations do we want to build docs in?
|
|
||||||
# All of these work independently and can be removed / commented out
|
|
||||||
# if you don't want oranda/mdbook running in that situation
|
|
||||||
on:
|
|
||||||
# Check that a PR didn't break docs!
|
|
||||||
#
|
|
||||||
# Note that the "Deploy to Github Pages" step won't run in this mode,
|
|
||||||
# so this won't have any side-effects. But it will tell you if a PR
|
|
||||||
# completely broke oranda/mdbook. Sadly we don't provide previews (yet)!
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
# Whenever something gets pushed to main, update the docs!
|
|
||||||
# This is great for getting docs changes live without cutting a full release.
|
|
||||||
#
|
|
||||||
# Note that if you're using cargo-dist, this will "race" the Release workflow
|
|
||||||
# that actually builds the Github Release that oranda tries to read (and
|
|
||||||
# this will almost certainly complete first). As a result you will publish
|
|
||||||
# docs for the latest commit but the oranda landing page won't know about
|
|
||||||
# the latest release. The workflow_run trigger below will properly wait for
|
|
||||||
# cargo-dist, and so this half-published state will only last for ~10 minutes.
|
|
||||||
#
|
|
||||||
# If you only want docs to update with releases, disable this, or change it to
|
|
||||||
# a "release" branch. You can, of course, also manually trigger a workflow run
|
|
||||||
# when you want the docs to update.
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
# Whenever a workflow called "Release" completes, update the docs!
|
|
||||||
#
|
|
||||||
# If you're using cargo-dist, this is recommended, as it will ensure that
|
|
||||||
# oranda always sees the latest release right when it's available. Note
|
|
||||||
# however that Github's UI is wonky when you use workflow_run, and won't
|
|
||||||
# show this workflow as part of any commit. You have to go to the "actions"
|
|
||||||
# tab for your repo to see this one running (the gh-pages deploy will also
|
|
||||||
# only show up there).
|
|
||||||
workflow_run:
|
|
||||||
workflows: [ "Release" ]
|
|
||||||
types:
|
|
||||||
- completed
|
|
||||||
|
|
||||||
# Alright, let's do it!
|
|
||||||
jobs:
|
|
||||||
web:
|
|
||||||
name: Build and deploy site and docs
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# Setup
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
- uses: swatinem/rust-cache@v2
|
|
||||||
|
|
||||||
# If you use any mdbook plugins, here's the place to install them!
|
|
||||||
|
|
||||||
# Install and run oranda (and mdbook)
|
|
||||||
# This will write all output to ./public/ (including copying mdbook's output to there)
|
|
||||||
- name: Install and run oranda
|
|
||||||
run: |
|
|
||||||
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/oranda/releases/download/v0.3.1/oranda-installer.sh | sh
|
|
||||||
oranda build
|
|
||||||
|
|
||||||
# Deploy to our gh-pages branch (creating it if it doesn't exist)
|
|
||||||
# the "public" dir that oranda made above will become the root dir
|
|
||||||
# of this branch.
|
|
||||||
#
|
|
||||||
# Note that once the gh-pages branch exists, you must
|
|
||||||
# go into repo's settings > pages and set "deploy from branch: gh-pages"
|
|
||||||
# the other defaults work fine.
|
|
||||||
- name: Deploy to Github Pages
|
|
||||||
uses: JamesIves/github-pages-deploy-action@v4.4.1
|
|
||||||
# ONLY if we're on main (so no PRs or feature branches allowed!)
|
|
||||||
if: ${{ github.ref == 'refs/heads/main' }}
|
|
||||||
with:
|
|
||||||
branch: gh-pages
|
|
||||||
# Gotta tell the action where to find oranda's output
|
|
||||||
folder: public
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
single-commit: true
|
|
|
@ -2,17 +2,3 @@
|
||||||
target/
|
target/
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.pdb
|
|
||||||
exercises/clippy/Cargo.toml
|
|
||||||
exercises/clippy/Cargo.lock
|
|
||||||
rust-project.json
|
|
||||||
.idea
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/extensions.json
|
|
||||||
*.iml
|
|
||||||
*.o
|
|
||||||
public/
|
|
||||||
.direnv/
|
|
||||||
|
|
||||||
# Local Netlify folder
|
|
||||||
.netlify
|
|
||||||
|
|
|
@ -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
|
|
|
@ -1,2 +0,0 @@
|
||||||
# MD013/line-length Line length, Expected: 80
|
|
||||||
MD013: false
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
language: rust
|
||||||
|
rust:
|
||||||
|
- stable
|
||||||
|
- beta
|
||||||
|
- nightly
|
||||||
|
script: cargo test --verbose
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- rust: nightly
|
||||||
|
fast_finish: true
|
||||||
|
cache: cargo
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"rust-lang.rust-analyzer"
|
|
||||||
]
|
|
||||||
}
|
|
356
AUTHORS.md
356
AUTHORS.md
|
@ -1,356 +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>
|
|
||||||
</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!
|
|
871
CHANGELOG.md
871
CHANGELOG.md
|
@ -1,871 +0,0 @@
|
||||||
<a name="5.6.1"></a>
|
|
||||||
## 5.6.1 (2023-09-18)
|
|
||||||
|
|
||||||
#### Changed
|
|
||||||
|
|
||||||
- Converted all exercises with assertions to test mode.
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
|
|
||||||
- `cow1`: Reverted regression introduced by calling `to_mut` where it
|
|
||||||
shouldn't have been called, and clarified comment.
|
|
||||||
- `primitive_types3`: Require at least an array of 100 elements.
|
|
||||||
- Removed hint comments when no hint exists for the exercise.
|
|
||||||
- `as_ref_mut`: Fixed a typo in a test function name.
|
|
||||||
- `enums3`: Fixed formatting with `rustfmt`.
|
|
||||||
|
|
||||||
<a name="5.6.0"></a>
|
|
||||||
## 5.6.0 (2023-09-04)
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
|
|
||||||
- New exercise: `if3`, teaching the user about `if let` statements.
|
|
||||||
- `hashmaps2`: Added an extra test function to check if the amount of fruits is higher than zero.
|
|
||||||
- `enums3`: Added a test for `Message`.
|
|
||||||
- `if1`: Added a test case to check equal values.
|
|
||||||
- `if3`: Added a note specifying that there are no test changes needed.
|
|
||||||
|
|
||||||
#### Changed
|
|
||||||
|
|
||||||
- Swapped the order of threads and smart pointer exercises.
|
|
||||||
- Rewrote the CLI to use `clap` - it's matured much since we switched to `argh` :)
|
|
||||||
- `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
|
|
||||||
concepts.
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
|
|
||||||
- `iterators5`:
|
|
||||||
- Removed an outdated part of the hint.
|
|
||||||
- Renamed variables to use snake_case.
|
|
||||||
- `vecs2`: Updated the hint to reference the renamed loop variable.
|
|
||||||
- `enums3`: Changed message string in test so that it gets properly tested.
|
|
||||||
- `strings2`: Corrected line number in hint, then removed it (this both happened as part of this release cycle).
|
|
||||||
- `primitive_types4`: Updated hint to the correct ending index.
|
|
||||||
- `quiz1`: Removed duplicated sentence from exercise comments.
|
|
||||||
- `errors4`: Improved comment.
|
|
||||||
- `from_into`: Fixed test values.
|
|
||||||
- `cow1`: Added `.to_mut()` to distinguish from the previous test case.
|
|
||||||
- `threads2`: Updated hint text to reference the correct book heading.
|
|
||||||
|
|
||||||
#### Housekeeping
|
|
||||||
|
|
||||||
- Cleaned up the explanation paragraphs at the start of each exercise.
|
|
||||||
- Lots of Nix housekeeping that I don't feel qualified to write about!
|
|
||||||
- Improved CI workflows, we're now testing on multiple platforms at once.
|
|
||||||
|
|
||||||
<a name="5.5.1"></a>
|
|
||||||
## 5.5.1 (2023-05-17)
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
|
|
||||||
- Reverted `rust-project.json` path generation due to an upstream `rust-analyzer` fix.
|
|
||||||
|
|
||||||
<a name="5.5.0"></a>
|
|
||||||
## 5.5.0 (2023-05-17)
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
|
|
||||||
- `strings2`: Added a reference to the book chapter for reference conversion
|
|
||||||
- `lifetimes`: Added a link to the lifetimekata project
|
|
||||||
- Added a new `tests4` exercises, which teaches about testing for panics
|
|
||||||
- Added a `!` prefix command to watch mode that runs an external command
|
|
||||||
- Added a `--success-hints` option to watch mode that shows hints on exercise success
|
|
||||||
|
|
||||||
#### Changed
|
|
||||||
|
|
||||||
- `vecs2`: Renamed iterator variable bindings for clarify
|
|
||||||
- `lifetimes`: Changed order of book references
|
|
||||||
- `hashmaps2`: Clarified instructions in the todo block
|
|
||||||
- Moved lifetime exercises before test exercises (via the recommended book ordering)
|
|
||||||
- `options2`: Improved tests for layering options
|
|
||||||
- `modules2`: Added more information to the hint
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
|
|
||||||
- `errors2`: Corrected a comment wording
|
|
||||||
- `iterators2`: Fixed a spelling mistake in the hint text
|
|
||||||
- `variables`: Wrapped the mut keyword with backticks for readability
|
|
||||||
- `move_semantics2`: Removed references to line numbers
|
|
||||||
- `cow1`: Clarified the `owned_no_mutation` comments
|
|
||||||
- `options3`: Changed exercise to panic when no match is found
|
|
||||||
- `rustlings lsp` now generates absolute paths, which should fix VSCode `rust-analyzer` usage on Windows
|
|
||||||
|
|
||||||
#### Housekeeping
|
|
||||||
|
|
||||||
- Added a markdown linter to run on GitHub actions
|
|
||||||
- Split quick installation section into two code blocks
|
|
||||||
|
|
||||||
<a name="5.4.1"></a>
|
|
||||||
## 5.4.1 (2023-03-10)
|
|
||||||
|
|
||||||
#### Changed
|
|
||||||
|
|
||||||
- `vecs`: Added links to `iter_mut` and `map` to README.md
|
|
||||||
- `cow1`: Changed main to tests
|
|
||||||
- `iterators1`: Formatted according to rustfmt
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
|
|
||||||
- `errors5`: Unified undisclosed type notation
|
|
||||||
- `arc1`: Improved readability by avoiding implicit dereference
|
|
||||||
- `macros4`: Prevented auto-fix by adding `#[rustfmt::skip]`
|
|
||||||
- `cli`: Actually show correct progress percentages
|
|
||||||
|
|
||||||
<a name="5.4.0"></a>
|
|
||||||
|
|
||||||
## 5.4.0 (2023-02-12)
|
|
||||||
|
|
||||||
#### Changed
|
|
||||||
|
|
||||||
- Reordered exercises
|
|
||||||
- Unwrapped `standard_library_types` into `iterators` and `smart_pointers`
|
|
||||||
- Moved smart pointer exercises behind threads
|
|
||||||
- Ordered `rc1` before `arc1`
|
|
||||||
- **intro1**: Added a note on `rustlings lsp`
|
|
||||||
- **threads1**: Panic if threads are not joined
|
|
||||||
- **cli**:
|
|
||||||
- Made progress bar update proportional to amount of files verified
|
|
||||||
- Decreased `watch` delay from 2 to 1 second
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
|
|
||||||
- Capitalized "Rust" in exercise hints
|
|
||||||
- **enums3**: Removed superfluous tuple brackets
|
|
||||||
- **quiz2, clippy1, iterators1**: Fixed a typo
|
|
||||||
- **rc1**: Fixed a prompt error
|
|
||||||
- **cli**:
|
|
||||||
- Fixed a typo in a method name
|
|
||||||
- Specified the edition in `rustc` commands
|
|
||||||
|
|
||||||
#### Housekeeping
|
|
||||||
|
|
||||||
- Bumped min Rust version to 1.58 in installation script
|
|
||||||
|
|
||||||
<a name="5.3.0"></a>
|
|
||||||
|
|
||||||
## 5.3.0 (2022-12-23)
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
|
|
||||||
- **cli**: Added a percentage display in watch mode
|
|
||||||
- Added a `flake.nix` for Nix users
|
|
||||||
|
|
||||||
#### Changed
|
|
||||||
|
|
||||||
- **structs3**: Added an additional test
|
|
||||||
- **macros**: Added a link to MacroKata in the README
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
|
|
||||||
- **strings3**: Added a link to `std` in the hint
|
|
||||||
- **threads1**: Corrected a hint link
|
|
||||||
- **iterators1**: Clarified hint steps
|
|
||||||
- **errors5**: Fix a typo in the hint
|
|
||||||
- **options1**: Clarified on the usage of the 24-hour system
|
|
||||||
- **threads2, threads3**: Explicitly use `Arc::clone`
|
|
||||||
- **structs3**: Clarifed the hint
|
|
||||||
- **quiz2, as_ref_mut, options1, traits1, traits2**: Clarified hints
|
|
||||||
- **traits1, traits2, cli**: Tidied up unmatching backticks
|
|
||||||
- **enums2**: Removed unneccessary indirection of self
|
|
||||||
- **enums3**: Added an extra tuple comment
|
|
||||||
|
|
||||||
#### Housekeeping
|
|
||||||
|
|
||||||
- Added a VSCode extension recommendation
|
|
||||||
- Applied some Clippy and rustfmt formatting
|
|
||||||
- Added a note on Windows PowerShell and other shell compatibility
|
|
||||||
|
|
||||||
<a name="5.2.1"></a>
|
|
||||||
|
|
||||||
## 5.2.1 (2022-09-06)
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
|
|
||||||
- **quiz1**: Reworded the comment to actually reflect what's going on in the tests.
|
|
||||||
Also added another assert just to make sure.
|
|
||||||
- **rc1**: Fixed a typo in the hint.
|
|
||||||
- **lifetimes**: Add quotes to the `println!` output, for readability.
|
|
||||||
|
|
||||||
#### Housekeeping
|
|
||||||
|
|
||||||
- Fixed a typo in README.md
|
|
||||||
|
|
||||||
<a name="5.2.0"></a>
|
|
||||||
|
|
||||||
## 5.2.0 (2022-08-27)
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
|
|
||||||
- Added a `reset` command
|
|
||||||
|
|
||||||
#### Changed
|
|
||||||
|
|
||||||
- **options2**: Convert the exercise to use tests
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
|
|
||||||
- **threads3**: Fixed a typo
|
|
||||||
- **quiz1**: Adjusted the explanations to be consistent with
|
|
||||||
the tests
|
|
||||||
|
|
||||||
<a name="5.1.1"></a>
|
|
||||||
|
|
||||||
## 5.1.1 (2022-08-17)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Fixed an incorrect assertion in options1
|
|
||||||
|
|
||||||
<a name="5.1.0"></a>
|
|
||||||
|
|
||||||
## 5.1.0 (2022-08-16)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Added a new `rc1` exercise.
|
|
||||||
- Added a new `cow1` exercise.
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- **variables5**: Corrected reference to previous exercise
|
|
||||||
- **functions4**: Fixed line number reference
|
|
||||||
- **strings3**: Clarified comment wording
|
|
||||||
- **traits4, traits5**: Fixed line number reference
|
|
||||||
- **traits5**:
|
|
||||||
- Fixed typo in "parameter"
|
|
||||||
- Made exercise prefer a traits-based solution
|
|
||||||
- **lifetimes2**: Improved hint
|
|
||||||
- **threads3**: Fixed typo in hint
|
|
||||||
- **box1**: Replaced `unimplemented!` with `todo!`
|
|
||||||
- **errors5**: Provided an explanation for usage of `Box<dyn Error>`
|
|
||||||
- **quiz2**: Fixed a typo
|
|
||||||
- **macros**: Updated the macros book link
|
|
||||||
- **options1**:
|
|
||||||
- Removed unused code
|
|
||||||
- Added more granular tests
|
|
||||||
- Fixed some comment syntax shenanigans in info.toml
|
|
||||||
|
|
||||||
#### Housekeeping
|
|
||||||
|
|
||||||
- Fixed a typo in .editorconfig
|
|
||||||
- Fixed a typo in integration_tests.rs
|
|
||||||
- Clarified manual installation instructions using `cargo install --path .`
|
|
||||||
- Added a link to our Zulip in the readme file
|
|
||||||
|
|
||||||
<a name="5.0.0"></a>
|
|
||||||
|
|
||||||
## 5.0.0 (2022-07-16)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Hint comments in exercises now also include a reference to the
|
|
||||||
`hint` watch mode subcommand.
|
|
||||||
- **intro1**: Added more hints to point the user to the source file.
|
|
||||||
- **variables**: Switched variables3 and variables4.
|
|
||||||
- Moved `vec` and `primitive_types` exercises before `move_semantics`.
|
|
||||||
- Renamed `vec` to `vecs` to be more in line with the naming in general.
|
|
||||||
- Split up the `collections` exercises in their own folders.
|
|
||||||
- **vec2**: Added a second part of the function that provides an alternative,
|
|
||||||
immutable way of modifying vec values.
|
|
||||||
- **enums3**: Added a hint.
|
|
||||||
- Moved `strings` before `modules`.
|
|
||||||
- Added a `strings3` exercise to teach modifying strings.
|
|
||||||
- Added a `hashmaps3` exercise for some advanced usage of hashmaps.
|
|
||||||
- Moved the original `quiz2` to be `strings4`, since it only tested strings
|
|
||||||
anyways.
|
|
||||||
- Reworked `quiz2` into a new exercise that tests more chapters.
|
|
||||||
- Renamed `option` to `options`.
|
|
||||||
- **options1**: Rewrote parts of the exercise to remove the weird array
|
|
||||||
iteration stuff.
|
|
||||||
- Moved `generics3` to be `quiz3`.
|
|
||||||
- Moved box/arc exercises behind `iterators`.
|
|
||||||
- **iterators4**: Added a test for factorials of zero.
|
|
||||||
- Split `threads1` between two exercises, the first one focusing more on
|
|
||||||
`JoinHandle`s.
|
|
||||||
- Added a `threads3` exercises that uses `std::sync::mpsc`.
|
|
||||||
- Added a `clippy3` exercises with some more interesting checks.
|
|
||||||
- **as_ref_mut**: Added a section that actually tests `AsMut`.
|
|
||||||
- Added 3 new lifetimes exercises.
|
|
||||||
- Added 3 new traits exercises.
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- **variables2**: Made output messages more verbose.
|
|
||||||
- **variables5**: Added a nudging hint about shadowing.
|
|
||||||
- **variables6**: Fixed link to book.
|
|
||||||
- **functions**: Clarified the README wording. Generally cleaned up
|
|
||||||
some hints and added some extra comments.
|
|
||||||
- **if2**: Renamed function name to `foo_if_fizz`.
|
|
||||||
- **move_semantics**: Clarified some hints.
|
|
||||||
- **quiz1**: Renamed the function name to be more verbose.
|
|
||||||
- **structs1**: Use an integer type instead of strings. Renamed "unit structs"
|
|
||||||
to "unit-like structs", as is used in the book.
|
|
||||||
- **structs3**: Added the `panic!` statement in from the beginning.
|
|
||||||
- **errors1**: Use `is_empty()` instead of `len() > 0`
|
|
||||||
- **errors3**: Improved the hint.
|
|
||||||
- **errors5**: Improved exercise instructions and the hint.
|
|
||||||
- **errors6**: Provided the skeleton of one of the functions that's supposed
|
|
||||||
to be implemented.
|
|
||||||
- **iterators3**: Inserted `todo!` into `divide()` to keep a compiler error
|
|
||||||
from happening.
|
|
||||||
- **from_str**: Added a hint comment about string error message conversion with
|
|
||||||
`Box<dyn Error>`.
|
|
||||||
- **try_from_into**: Fixed the function name in comment.
|
|
||||||
|
|
||||||
#### Removed
|
|
||||||
|
|
||||||
- Removed the legacy LSP feature that was using `mod.rs` files.
|
|
||||||
- Removed `quiz4`.
|
|
||||||
- Removed `advanced_errs`. These were the last exercises in the recommended
|
|
||||||
order, and I've always felt like they didn't quite fit in with the mostly
|
|
||||||
simple, book-following style we've had in Rustlings.
|
|
||||||
|
|
||||||
#### Housekeeping
|
|
||||||
|
|
||||||
- Added missing exercises to the book index.
|
|
||||||
- Updated spacing in Cargo.toml.
|
|
||||||
- Added a GitHub actions config so that tests run on every PR/commit.
|
|
||||||
|
|
||||||
<a name="4.8.0"></a>
|
|
||||||
|
|
||||||
## 4.8.0 (2022-07-01)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Added a progress indicator for `rustlings watch`.
|
|
||||||
- The installation script now checks for Rustup being installed.
|
|
||||||
- Added a `rustlings lsp` command to enable `rust-analyzer`.
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- **move_semantics5**: Replaced "in vogue" with "in scope" in hint.
|
|
||||||
- **if2**: Fixed a typo in the hint.
|
|
||||||
- **variables1**: Fixed an incorrect line reference in the hint.
|
|
||||||
- Fixed an out of bounds check in the installation Bash script.
|
|
||||||
|
|
||||||
#### Housekeeping
|
|
||||||
|
|
||||||
- Replaced the git.io URL with the fully qualified URL because of git.io's sunsetting.
|
|
||||||
- Removed the deprecated Rust GitPod extension.
|
|
||||||
|
|
||||||
<a name="4.7.1"></a>
|
|
||||||
|
|
||||||
## 4.7.1 (2022-04-20)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- The amount of dependency crates that need to be compiled went down from ~65 to
|
|
||||||
~45 by bumping dependency versions.
|
|
||||||
- The minimum Rust version in the install scripts has been bumped to 1.56.0 (this isn't in
|
|
||||||
the release itself, since install scripts don't really get versioned)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- **arc1**: A small part has been rewritten using a more functional code style (#968).
|
|
||||||
- **using_as**: A small part has been refactored to use `sum` instead of `fold`, resulting
|
|
||||||
in better readability.
|
|
||||||
|
|
||||||
#### Housekeeping
|
|
||||||
|
|
||||||
- The changelog will now be manually written instead of being automatically generated by the
|
|
||||||
Git log.
|
|
||||||
|
|
||||||
<a name="4.7.0"></a>
|
|
||||||
|
|
||||||
## 4.7.0 (2022-04-14)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Add move_semantics6.rs exercise (#908) ([3f0e1303](https://github.com/rust-lang/rustlings/commit/3f0e1303e0b3bf3fecc0baced3c8b8a37f83c184))
|
|
||||||
- **intro:** Add intro section. ([21c9f441](https://github.com/rust-lang/rustlings/commit/21c9f44168394e08338fd470b5f49b1fd235986f))
|
|
||||||
- Include exercises folder in the project structure behind a feature, enabling rust-analyzer to work (#917) ([179a75a6](https://github.com/rust-lang/rustlings/commit/179a75a68d03ac9518dec2297fb17f91a4fc506b))
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Fix a few spelling mistakes ([1c0fe3cb](https://github.com/rust-lang/rustlings/commit/1c0fe3cbcca85f90b3985985b8e265ee872a2ab2))
|
|
||||||
- **cli:**
|
|
||||||
- Move long text strings into constants. ([f78c4802](https://github.com/rust-lang/rustlings/commit/f78c48020830d7900dd8d81f355606581670446d))
|
|
||||||
- Replace `filter_map()` with `find_map()` ([9b27e8d](https://github.com/rust-lang/rustlings/commit/9b27e8d993ca20232fe38a412750c3f845a83b65))
|
|
||||||
- **clippy1:**
|
|
||||||
- Set clippy::float_cmp lint to deny (#907) ([71a06044](https://github.com/rust-lang/rustlings/commit/71a06044e6a96ff756dc31d7b0ed665ae4badb57))
|
|
||||||
- Updated code to test correctness clippy lint with approx_constant lint rule ([f2650de3](https://github.com/rust-lang/rustlings/commit/f2650de369810867d2763e935ac0963c32ec420e))
|
|
||||||
- **errors1:**
|
|
||||||
- Add a comment to make the purpose more clear (#486) ([cbcde345](https://github.com/rust-lang/rustlings/commit/cbcde345409c3e550112e449242848eaa3391bb6))
|
|
||||||
- Don't modify tests (#958) ([60bb7cc](https://github.com/rust-lang/rustlings/commit/60bb7cc3931d21d3986ad52b2b302e632a93831c))
|
|
||||||
- **errors6:** Remove existing answer code ([43d0623](https://github.com/rust-lang/rustlings/commit/43d0623086edbc46fe896ba59c7afa22c3da9f7a))
|
|
||||||
- **functions5:** Remove wrong new line and small English improvements (#885) ([8ef4869b](https://github.com/rust-lang/rustlings/commit/8ef4869b264094e5a9b50452b4534823a9df19c3))
|
|
||||||
- **install:** protect path with whitespaces using quotes and stop at the first error ([d114847f](https://github.com/rust-lang/rustlings/commit/d114847f256c5f571c0b4c87e04b04bce3435509))
|
|
||||||
- **intro1:** Add compiler error explanation. ([9b8de655](https://github.com/rust-lang/rustlings/commit/9b8de65525a5576b78cf0c8e4098cdd34296338f))
|
|
||||||
- **iterators1:** reorder TODO steps ([0bd7a063](https://github.com/rust-lang/rustlings/commit/0bd7a0631a17a9d69af5746795a30efc9cf64e6e))
|
|
||||||
- **move_semantics2:** Add comment ([89650f80](https://github.com/rust-lang/rustlings/commit/89650f808af23a32c9a2c6d46592b77547a6a464))
|
|
||||||
- **move_semantics5:** correct typo (#857) ([46c28d5c](https://github.com/rust-lang/rustlings/commit/46c28d5cef3d8446b5a356b19d8dbc725f91a3a0))
|
|
||||||
- **quiz1:** update to say quiz covers "If" ([1622e8c1](https://github.com/rust-lang/rustlings/commit/1622e8c198d89739765c915203efff0091bdeb78))
|
|
||||||
- **structs3:**
|
|
||||||
- Add a hint for panic (#608) ([4f7ff5d9](https://github.com/rust-lang/rustlings/commit/4f7ff5d9c7b2d8b045194c1a9469d37e30257c4a))
|
|
||||||
- remove redundant 'return' (#852) ([bf33829d](https://github.com/rust-lang/rustlings/commit/bf33829da240375d086f96267fc2e02fa6b07001))
|
|
||||||
- Assigned value to `cents_per_gram` in test ([d1ee2da](https://github.com/rust-lang/rustlings/commit/d1ee2daf14f19105e6db3f9c610f44293d688532))
|
|
||||||
- **structs3.rs:** assigned value to cents_per_gram in test ([d1ee2daf](https://github.com/rust-lang/rustlings/commit/d1ee2daf14f19105e6db3f9c610f44293d688532))
|
|
||||||
- **traits1:** rename test functions to snake case (#854) ([1663a16e](https://github.com/rust-lang/rustlings/commit/1663a16eade6ca646b6ed061735f7982434d530d))
|
|
||||||
|
|
||||||
#### Documentation improvements
|
|
||||||
|
|
||||||
- Add hints on how to get GCC installed (#741) ([bc56861](https://github.com/rust-lang/rustlings/commit/bc5686174463ad6f4f6b824b0e9b97c3039d4886))
|
|
||||||
- Fix some code blocks that were not highlighted ([17f9d74](https://github.com/rust-lang/rustlings/commit/17f9d7429ccd133a72e815fb5618e0ce79560929))
|
|
||||||
|
|
||||||
<a name="4.6.0"></a>
|
|
||||||
|
|
||||||
## 4.6.0 (2021-09-25)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- add advanced_errs2 ([abd6b70c](https://github.com/rust-lang/rustlings/commit/abd6b70c72dc6426752ff41f09160b839e5c449e))
|
|
||||||
- add advanced_errs1 ([882d535b](https://github.com/rust-lang/rustlings/commit/882d535ba8628d5e0b37e8664b3e2f26260b2671))
|
|
||||||
- Add a farewell message when quitting `watch` ([1caef0b4](https://github.com/rust-lang/rustlings/commit/1caef0b43494c8b8cdd6c9260147e70d510f1aca))
|
|
||||||
- add more watch commands ([a7dc080b](https://github.com/rust-lang/rustlings/commit/a7dc080b95e49146fbaafe6922a6de2f8cb1582a), closes [#842](https://github.com/rust-lang/rustlings/issues/842))
|
|
||||||
- **modules:** update exercises, add modules3 (#822) ([dfd2fab4](https://github.com/rust-lang/rustlings/commit/dfd2fab4f33d1bf59e2e5ee03123c0c9a67a9481))
|
|
||||||
- **quiz1:** add default function name in comment (#838) ([0a11bad7](https://github.com/rust-lang/rustlings/commit/0a11bad71402b5403143d642f439f57931278c07))
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Correct small typo in exercises/conversions/from_str.rs ([86cc8529](https://github.com/rust-lang/rustlings/commit/86cc85295ae36948963ae52882e285d7e3e29323))
|
|
||||||
- **cli:** typo in exercise.rs (#848) ([06d5c097](https://github.com/rust-lang/rustlings/commit/06d5c0973a3dffa3c6c6f70acb775d4c6630323c))
|
|
||||||
- **from_str, try_from_into:** custom error types ([2dc93cad](https://github.com/rust-lang/rustlings/commit/2dc93caddad43821743e4903d89b355df58d7a49))
|
|
||||||
- **modules2:** fix typo (#835) ([1c3beb0a](https://github.com/rust-lang/rustlings/commit/1c3beb0a59178c950dc05fe8ee2346b017429ae0))
|
|
||||||
- **move_semantics5:**
|
|
||||||
- change &mut \*y to &mut x (#814) ([d75759e8](https://github.com/rust-lang/rustlings/commit/d75759e829fdcd64ef071cf4b6eae2a011a7718b))
|
|
||||||
- Clarify instructions ([df25684c](https://github.com/rust-lang/rustlings/commit/df25684cb79f8413915e00b5efef29369849cef1))
|
|
||||||
- **quiz1:** Fix inconsistent wording (#826) ([03131a3d](https://github.com/rust-lang/rustlings/commit/03131a3d35d9842598150f9da817f7cc26e2669a))
|
|
||||||
|
|
||||||
<a name="4.5.0"></a>
|
|
||||||
|
|
||||||
## 4.5.0 (2021-07-07)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Add move_semantics5 exercise. (#746) ([399ab328](https://github.com/rust-lang/rustlings/commit/399ab328d8d407265c09563aa4ef4534b2503ff2))
|
|
||||||
- **cli:** Add "next" to run the next unsolved exercise. (#785) ([d20e413a](https://github.com/rust-lang/rustlings/commit/d20e413a68772cd493561f2651cf244e822b7ca5))
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- rename result1 to errors4 ([50ab289d](https://github.com/rust-lang/rustlings/commit/50ab289da6b9eb19a7486c341b00048c516b88c0))
|
|
||||||
- move_semantics5 hints ([1b858285](https://github.com/rust-lang/rustlings/commit/1b85828548f46f58b622b5e0c00f8c989f928807))
|
|
||||||
- remove trailing whitespaces from iterators1 ([4d4fa774](https://github.com/rust-lang/rustlings/commit/4d4fa77459392acd3581c6068aa8be9a02de12fc))
|
|
||||||
- add hints to generics1 and generics2 exercises ([31457940](https://github.com/rust-lang/rustlings/commit/31457940846b3844d78d4a4d2b074bc8d6aaf1eb))
|
|
||||||
- remove trailing whitespace ([d9b69bd1](https://github.com/rust-lang/rustlings/commit/d9b69bd1a0a7a99f2c0d80933ad2eea44c8c71b2))
|
|
||||||
- **installation:** first PowerShell command ([aa9a943d](https://github.com/rust-lang/rustlings/commit/aa9a943ddf3ae260782e73c26bcc9db60e5894b6))
|
|
||||||
- **iterators5:** derive Clone, Copy ([91fc9e31](https://github.com/rust-lang/rustlings/commit/91fc9e3118f4af603c9911698cc2a234725cb032))
|
|
||||||
- **quiz1:** Updated question description (#794) ([d8766496](https://github.com/rust-lang/rustlings/commit/d876649616cc8a8dd5f539f8bc1a5434b960b1e9))
|
|
||||||
- **try_from_into, from_str:** hints for dyn Error ([11d2cf0d](https://github.com/rust-lang/rustlings/commit/11d2cf0d604dee3f5023c17802d69438e69fa50e))
|
|
||||||
- **variables5:** confine the answer further ([48ffcbd2](https://github.com/rust-lang/rustlings/commit/48ffcbd2c4cc4d936c2c7480019190f179813cc5))
|
|
||||||
|
|
||||||
<a name="4.4.0"></a>
|
|
||||||
|
|
||||||
## 4.4.0 (2021-04-24)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Fix spelling error in main.rs ([91ee27f2](https://github.com/rust-lang/rustlings/commit/91ee27f22bd3797a9db57e5fd430801c170c5db8))
|
|
||||||
- typo in default out text ([644c49f1](https://github.com/rust-lang/rustlings/commit/644c49f1e04cbb24e95872b3a52b07d692ae3bc8))
|
|
||||||
- **collections:** Naming exercises for vectors and hashmap ([bef39b12](https://github.com/rust-lang/rustlings/commit/bef39b125961310b34b34871e480a82e82af4678))
|
|
||||||
- **from_str:**
|
|
||||||
- Correct typos ([5f7c89f8](https://github.com/rust-lang/rustlings/commit/5f7c89f85db1f33da01911eaa479c3a2d4721678))
|
|
||||||
- test for error instead of unwrap/should_panic ([15e71535](https://github.com/rust-lang/rustlings/commit/15e71535f37cfaed36e22eb778728d186e2104ab))
|
|
||||||
- use trait objects for from_str ([c3e7b831](https://github.com/rust-lang/rustlings/commit/c3e7b831786c9172ed8bd5d150f3c432f242fba9))
|
|
||||||
- **functions3:** improve function argument type (#687) ([a6509cc4](https://github.com/rust-lang/rustlings/commit/a6509cc4d545d8825f01ddf7ee37823b372154dd))
|
|
||||||
- **hashmap2:** Update incorrect assertion (#660) ([72aaa15e](https://github.com/rust-lang/rustlings/commit/72aaa15e6ab4b72b3422f1c6356396e20a2a2bb8))
|
|
||||||
- **info:** Fix typo (#635) ([cddc1e86](https://github.com/rust-lang/rustlings/commit/cddc1e86e7ec744ee644cc774a4887b1a0ded3e8))
|
|
||||||
- **iterators2:** Moved errors out of tests. ([baf4ba17](https://github.com/rust-lang/rustlings/commit/baf4ba175ba6eb92989e3dd54ecbec4bedc9a863), closes [#359](https://github.com/rust-lang/rustlings/issues/359))
|
|
||||||
- **iterators3:** Enabled iterators3.rs to run without commented out tests. ([c6712dfc](https://github.com/rust-lang/rustlings/commit/c6712dfccd1a093e590ad22bbc4f49edc417dac0))
|
|
||||||
- **main:** Let find_exercise work with borrows ([347f30bd](https://github.com/rust-lang/rustlings/commit/347f30bd867343c5ace1097e085a1f7e356553f7))
|
|
||||||
- **move_semantics4:**
|
|
||||||
- Remove redundant "instead" (#640) ([cc266d7d](https://github.com/rust-lang/rustlings/commit/cc266d7d80b91e79df3f61984f231b7f1587218e))
|
|
||||||
- Small readbility improvement (#617) ([10965920](https://github.com/rust-lang/rustlings/commit/10965920fbdf8a1efc85bed869e55a1787006404))
|
|
||||||
- **option2:** Rename uninformative variables (#675) ([b4de6594](https://github.com/rust-lang/rustlings/commit/b4de6594380636817d13c2677ec6f472a964cf43))
|
|
||||||
- **quiz3:** Force an answer to Q2 (#672) ([0d894e6f](https://github.com/rust-lang/rustlings/commit/0d894e6ff739943901e1ae8c904582e5c2f843bd))
|
|
||||||
- **structs:** Add 5.3 to structs/README (#652) ([6bd791f2](https://github.com/rust-lang/rustlings/commit/6bd791f2f44aa7f0ad926df767f6b1fa8f12a9a9))
|
|
||||||
- **structs2:** correct grammar in hint (#663) ([ebdb66c7](https://github.com/rust-lang/rustlings/commit/ebdb66c7bfb6d687a14cc511a559a222e6fc5de4))
|
|
||||||
- **structs3:**
|
|
||||||
- reword heading comment (#664) ([9f3e8c2d](https://github.com/rust-lang/rustlings/commit/9f3e8c2dde645e5264c2d2200e68842b5f47bfa3))
|
|
||||||
- add check to prevent naive implementation of is_international ([05a753fe](https://github.com/rust-lang/rustlings/commit/05a753fe6333d36dbee5f68c21dec04eacdc75df))
|
|
||||||
- **threads1:** line number correction ([7857b0a6](https://github.com/rust-lang/rustlings/commit/7857b0a689b0847f48d8c14cbd1865e3b812d5ca))
|
|
||||||
- **try_from_into:** use trait objects ([2e93a588](https://github.com/rust-lang/rustlings/commit/2e93a588e0abe8badb7eafafb9e7d073c2be5df8))
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Replace clap with argh ([7928122f](https://github.com/rust-lang/rustlings/commit/7928122fcef9ca7834d988b1ec8ca0687478beeb))
|
|
||||||
- Replace emojis when NO_EMOJI env variable present ([8d62a996](https://github.com/rust-lang/rustlings/commit/8d62a9963708dbecd9312e8bcc4b47049c72d155))
|
|
||||||
- Added iterators5.rs exercise. ([b29ea17e](https://github.com/rust-lang/rustlings/commit/b29ea17ea94d1862114af2cf5ced0e09c197dc35))
|
|
||||||
- **arc1:** Add more details to description and hint (#710) ([81be4044](https://github.com/rust-lang/rustlings/commit/81be40448777fa338ebced3b0bfc1b32d6370313))
|
|
||||||
- **cli:** Improve the list command with options, and then some ([8bbe4ff1](https://github.com/rust-lang/rustlings/commit/8bbe4ff1385c5c169c90cd3ff9253f9a91daaf8e))
|
|
||||||
- **list:**
|
|
||||||
- updated progress percentage ([1c6f7e4b](https://github.com/rust-lang/rustlings/commit/1c6f7e4b7b9b3bd36f4da2bb2b69c549cc8bd913))
|
|
||||||
- added progress info ([c0e3daac](https://github.com/rust-lang/rustlings/commit/c0e3daacaf6850811df5bc57fa43e0f249d5cfa4))
|
|
||||||
|
|
||||||
<a name="4.3.0"></a>
|
|
||||||
|
|
||||||
## 4.3.0 (2020-12-29)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Rewrite default out text ([44d39112](https://github.com/rust-lang/rustlings/commit/44d39112ff122b29c9793fe52e605df1612c6490))
|
|
||||||
- match exercise order to book chapters (#541) ([033bf119](https://github.com/rust-lang/rustlings/commit/033bf1198fc8bfce1b570e49da7cde010aa552e3))
|
|
||||||
- Crab? (#586) ([fa9f522b](https://github.com/rust-lang/rustlings/commit/fa9f522b7f043d7ef73a39f003a9272dfe72c4f4))
|
|
||||||
- add "rustlings list" command ([838f9f30](https://github.com/rust-lang/rustlings/commit/838f9f30083d0b23fd67503dcf0fbeca498e6647))
|
|
||||||
- **try_from_into:** remove duplicate annotation ([04f1d079](https://github.com/rust-lang/rustlings/commit/04f1d079aa42a2f49af694bc92c67d731d31a53f))
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- update structs README ([bcf14cf6](https://github.com/rust-lang/rustlings/commit/bcf14cf677adb3a38a3ac3ca53f3c69f61153025))
|
|
||||||
- added missing exercises to info.toml ([90cfb6ff](https://github.com/rust-lang/rustlings/commit/90cfb6ff28377531bfc34acb70547bdb13374f6b))
|
|
||||||
- gives a bit more context to magic number ([30644c9a](https://github.com/rust-lang/rustlings/commit/30644c9a062b825c0ea89435dc59f0cad86b110e))
|
|
||||||
- **functions2:** Change signature to trigger precise error message: (#605) ([0ef95947](https://github.com/rust-lang/rustlings/commit/0ef95947cc30482e63a7045be6cc2fb6f6dcb4cc))
|
|
||||||
- **structs1:** Adjust wording (#573) ([9334783d](https://github.com/rust-lang/rustlings/commit/9334783da31d821cc59174fbe8320df95828926c))
|
|
||||||
- **try_from_into:**
|
|
||||||
- type error ([4f4cfcf3](https://github.com/rust-lang/rustlings/commit/4f4cfcf3c36c8718c7c170c9c3a6935e6ef0618c))
|
|
||||||
- Update description (#584) ([96347df9](https://github.com/rust-lang/rustlings/commit/96347df9df294f01153b29d9ad4ba361f665c755))
|
|
||||||
- **vec1:** Have test compare every element in a and v ([9b6c6293](https://github.com/rust-lang/rustlings/commit/9b6c629397b24b944f484f5b2bbd8144266b5695))
|
|
||||||
|
|
||||||
<a name="4.2.0"></a>
|
|
||||||
|
|
||||||
## 4.2.0 (2020-11-07)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Add HashMap exercises ([633c00cf](https://github.com/rust-lang/rustlings/commit/633c00cf8071e1e82959a3010452a32f34f29fc9))
|
|
||||||
- Add Vec exercises ([0c12fa31](https://github.com/rust-lang/rustlings/commit/0c12fa31c57c03c6287458a0a8aca7afd057baf6))
|
|
||||||
- **primitive_types6:** Add a test (#548) ([2b1fb2b7](https://github.com/rust-lang/rustlings/commit/2b1fb2b739bf9ad8d6b7b12af25fee173011bfc4))
|
|
||||||
- **try_from_into:** Add tests (#571) ([95ccd926](https://github.com/rust-lang/rustlings/commit/95ccd92616ae79ba287cce221101e0bbe4f68cdc))
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- log error output when inotify limit is exceeded ([d61b4e5a](https://github.com/rust-lang/rustlings/commit/d61b4e5a13b44d72d004082f523fa1b6b24c1aca))
|
|
||||||
- more unique temp_file ([5643ef05](https://github.com/rust-lang/rustlings/commit/5643ef05bc81e4a840e9456f4406a769abbe1392))
|
|
||||||
- **installation:** Update the MinRustVersion ([21bfb2d4](https://github.com/rust-lang/rustlings/commit/21bfb2d4777429c87d8d3b5fbf0ce66006dcd034))
|
|
||||||
- **iterators2:** Update description (#578) ([197d3a3d](https://github.com/rust-lang/rustlings/commit/197d3a3d8961b2465579218a6749b2b2cefa8ddd))
|
|
||||||
- **primitive_types6:**
|
|
||||||
- remove 'unused doc comment' warning ([472d8592](https://github.com/rust-lang/rustlings/commit/472d8592d65c8275332a20dfc269e7ac0d41bc88))
|
|
||||||
- missing comma in test ([4fb230da](https://github.com/rust-lang/rustlings/commit/4fb230daf1251444fcf29e085cee222a91f8a37e))
|
|
||||||
- **quiz3:** Second test is for odd numbers, not even. (#553) ([18e0bfef](https://github.com/rust-lang/rustlings/commit/18e0bfef1de53071e353ba1ec5837002ff7290e6))
|
|
||||||
|
|
||||||
<a name="4.1.0"></a>
|
|
||||||
|
|
||||||
## 4.1.0 (2020-10-05)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Update rustlings version in Cargo.lock ([1cc40bc9](https://github.com/rust-lang/rustlings/commit/1cc40bc9ce95c23d56f6d91fa1c4deb646231fef))
|
|
||||||
- **arc1:** index mod should equal thread count ([b4062ef6](https://github.com/rust-lang/rustlings/commit/b4062ef6993e80dac107c4093ea85166ad3ee0fa))
|
|
||||||
- **enums3:** Update Message::ChangeColor to take a tuple. (#457) ([4b6540c7](https://github.com/rust-lang/rustlings/commit/4b6540c71adabad647de8a09e57295e7c7c7d794))
|
|
||||||
- **exercises:** adding question mark to quiz2 ([101072ab](https://github.com/rust-lang/rustlings/commit/101072ab9f8c80b40b8b88cb06cbe38aca2481c5))
|
|
||||||
- **generics3:** clarify grade change ([47f7672c](https://github.com/rust-lang/rustlings/commit/47f7672c0307732056e7426e81d351f0dd7e22e5))
|
|
||||||
- **structs3:** Small adjustment of variable name ([114b54cb](https://github.com/rust-lang/rustlings/commit/114b54cbdb977234b39e5f180d937c14c78bb8b2))
|
|
||||||
- **using_as:** Add test so that proper type is returned. (#512) ([3286c5ec](https://github.com/rust-lang/rustlings/commit/3286c5ec19ea5fb7ded81d047da5f8594108a490))
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Added iterators1.rs exercise ([9642f5a3](https://github.com/rust-lang/rustlings/commit/9642f5a3f686270a4f8f6ba969919ddbbc4f7fdd))
|
|
||||||
- Add ability to run rustlings on repl.it (#471) ([8f7b5bd0](https://github.com/rust-lang/rustlings/commit/8f7b5bd00eb83542b959830ef55192d2d76db90a))
|
|
||||||
- Add gitpod support (#473) ([4821a8be](https://github.com/rust-lang/rustlings/commit/4821a8be94af4f669042a06ab917934cfacd032f))
|
|
||||||
- Remind the user of the hint option (#425) ([816b1f5e](https://github.com/rust-lang/rustlings/commit/816b1f5e85d6cc6e72673813a85d0ada2a8f84af))
|
|
||||||
- Remind the user of the hint option (#425) ([9f61db5d](https://github.com/rust-lang/rustlings/commit/9f61db5dbe38538cf06571fcdd5f806e7901e83a))
|
|
||||||
- **cli:** Added 'cls' command to 'watch' mode (#474) ([4f2468e1](https://github.com/rust-lang/rustlings/commit/4f2468e14f574a93a2e9b688367b5752ed96ae7b))
|
|
||||||
- **try_from_into:** Add insufficient length test (#469) ([523d18b8](https://github.com/rust-lang/rustlings/commit/523d18b873a319f7c09262f44bd40e2fab1830e5))
|
|
||||||
|
|
||||||
<a name="4.0.0"></a>
|
|
||||||
|
|
||||||
## 4.0.0 (2020-07-08)
|
|
||||||
|
|
||||||
#### Breaking Changes
|
|
||||||
|
|
||||||
- Add a --nocapture option to display test harnesses' outputs ([8ad5f9bf](https://github.com/rust-lang/rustlings/commit/8ad5f9bf531a4848b1104b7b389a20171624c82f))
|
|
||||||
- Rename test to quiz, fixes #244 ([010a0456](https://github.com/rust-lang/rustlings/commit/010a04569282149cea7f7a76fc4d7f4c9f0f08dd))
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Add traits README ([173bb141](https://github.com/rust-lang/rustlings/commit/173bb14140c5530cbdb59e53ace3991a99d804af))
|
|
||||||
- Add box1.rs exercise ([7479a473](https://github.com/rust-lang/rustlings/commit/7479a4737bdcac347322ad0883ca528c8675e720))
|
|
||||||
- Rewrite try_from_into (#393) ([763aa6e3](https://github.com/rust-lang/rustlings/commit/763aa6e378a586caae2d8d63755a85eeba227933))
|
|
||||||
- Add if2 exercise ([1da84b5f](https://github.com/rust-lang/rustlings/commit/1da84b5f7c489f65bd683c244f13c7d1ee812df0))
|
|
||||||
- Added exercise structs3.rs ([b66e2e09](https://github.com/rust-lang/rustlings/commit/b66e2e09622243e086a0f1258dd27e1a2d61c891))
|
|
||||||
- Add exercise variables6 covering const (#352) ([5999acd2](https://github.com/rust-lang/rustlings/commit/5999acd24a4f203292be36e0fd18d385887ec481))
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Change then to than ([ddd98ad7](https://github.com/rust-lang/rustlings/commit/ddd98ad75d3668fbb10eff74374148aa5ed2344d))
|
|
||||||
- rename quiz1 to tests1 in info (#420) ([0dd1c6ca](https://github.com/rust-lang/rustlings/commit/0dd1c6ca6b389789e0972aa955fe17aa15c95f29))
|
|
||||||
- fix quiz naming inconsistency (#421) ([5563adbb](https://github.com/rust-lang/rustlings/commit/5563adbb890587fc48fbbc9c4028642687f1e85b))
|
|
||||||
- confine the user further in variable exercises ([06ef4cc6](https://github.com/rust-lang/rustlings/commit/06ef4cc654e75d22a526812919ee49b8956280bf))
|
|
||||||
- update iterator and macro text for typos and clarity ([95900828](https://github.com/rust-lang/rustlings/commit/959008284834bece0196a01e17ac69a7e3590116))
|
|
||||||
- update generics2 closes #362 ([964c974a](https://github.com/rust-lang/rustlings/commit/964c974a0274199d755073b917c2bc5da0c9b4f1))
|
|
||||||
- confusing comment in conversions/try_from_into.rs ([c9e4f2cf](https://github.com/rust-lang/rustlings/commit/c9e4f2cfb4c48d0b7451263cfb43b9426438122d))
|
|
||||||
- **arc1:** Passively introduce attributes (#429) ([113cdae2](https://github.com/rust-lang/rustlings/commit/113cdae2d4e4c55905e8056ad326ede7fd7de356))
|
|
||||||
- **box1:** fix comment typo (#426) ([bb2ca251](https://github.com/rust-lang/rustlings/commit/bb2ca251106b27a7272d9a30872904dd1376654c))
|
|
||||||
- **errorsn:** Try harder to confine the user. (#388) ([2b20c8a0](https://github.com/rust-lang/rustlings/commit/2b20c8a0f5774d07c58d110d75879f33fc6273b5))
|
|
||||||
- **from_into.rs:** typo ([a901499e](https://github.com/rust-lang/rustlings/commit/a901499ededd3ce1995164700514fe4e9a0373ea))
|
|
||||||
- **generics2:** Guide students to the answer (#430) ([e6bd8021](https://github.com/rust-lang/rustlings/commit/e6bd8021d9a7dd06feebc30c9d5f953901d7b419))
|
|
||||||
- **installation:**
|
|
||||||
- Provide a backup git reference when tag can't be curl ([9e4fb100](https://github.com/rust-lang/rustlings/commit/9e4fb1009f1c9e3433915c03e22c2af422e5c5fe))
|
|
||||||
- Check if python is available while checking for git,rustc and cargo ([9cfb617d](https://github.com/rust-lang/rustlings/commit/9cfb617d5b0451b4b51644a1298965390cda9884))
|
|
||||||
- **option1:**
|
|
||||||
- Don't add only zeros to the numbers array ([cce6a442](https://github.com/rust-lang/rustlings/commit/cce6a4427718724a9096800754cd3abeca6a1580))
|
|
||||||
- Add cast to usize, as it is confusing in the context of an exercise about Option ([f6cffc7e](https://github.com/rust-lang/rustlings/commit/f6cffc7e487b42f15a6f958e49704c93a8d4465b))
|
|
||||||
- **option2:** Add TODO to comments (#400) ([10967bce](https://github.com/rust-lang/rustlings/commit/10967bce57682812dc0891a9f9757da1a9d87404))
|
|
||||||
- **options1:** Add hint about Array Initialization (#389) ([9f75554f](https://github.com/rust-lang/rustlings/commit/9f75554f2a30295996f03f0160b98c0458305502))
|
|
||||||
- **test2:** name of type String and &str (#394) ([d6c0a688](https://github.com/rust-lang/rustlings/commit/d6c0a688e6a96f93ad60d540d4b326f342fc0d45))
|
|
||||||
- **variables6:** minor typo (#419) ([524e17df](https://github.com/rust-lang/rustlings/commit/524e17df10db95f7b90a0f75cc8997182a8a4094))
|
|
||||||
|
|
||||||
<a name="3.0.0"></a>
|
|
||||||
|
|
||||||
## 3.0.0 (2020-04-11)
|
|
||||||
|
|
||||||
#### Breaking Changes
|
|
||||||
|
|
||||||
- make "compile" exercises print output (#278) ([3b6d5c](https://github.com/fmoko/rustlings/commit/3b6d5c3aaa27a242a832799eb66e96897d26fde3))
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- **primitive_types:** revert primitive_types4 (#296) ([b3a3351e](https://github.com/rust-lang/rustlings/commit/b3a3351e8e6a0bdee07077d7b0382953821649ae))
|
|
||||||
- **run:** compile clippy exercise files (#295) ([3ab084a4](https://github.com/rust-lang/rustlings/commit/3ab084a421c0f140ae83bf1fc3f47b39342e7373))
|
|
||||||
- **conversions:**
|
|
||||||
- add additional test to meet exercise rules (#284) ([bc22ec3](https://github.com/fmoko/rustlings/commit/bc22ec382f843347333ef1301fc1bad773657f38))
|
|
||||||
- remove duplicate not done comment (#292) ([dab90f](https://github.com/fmoko/rustlings/commit/dab90f7b91a6000fe874e3d664f244048e5fa342))
|
|
||||||
- don't hardcode documentation version for traits (#288) ([30e6af](https://github.com/fmoko/rustlings/commit/30e6af60690c326fb5d3a9b7335f35c69c09137d))
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- add Option2 exercise (#290) ([86b5c08b](https://github.com/rust-lang/rustlings/commit/86b5c08b9bea1576127a7c5f599f5752072c087d))
|
|
||||||
- add exercise for option (#282) ([135e5d47](https://github.com/rust-lang/rustlings/commit/135e5d47a7c395aece6f6022117fb20c82f2d3d4))
|
|
||||||
- add new exercises for generics (#280) ([76be5e4e](https://github.com/rust-lang/rustlings/commit/76be5e4e991160f5fd9093f03ee2ba260e8f7229))
|
|
||||||
- **ci:** add buildkite config ([b049fa2c](https://github.com/rust-lang/rustlings/commit/b049fa2c84dba0f0c8906ac44e28fd45fba51a71))
|
|
||||||
|
|
||||||
<a name="2.2.1"></a>
|
|
||||||
|
|
||||||
### 2.2.1 (2020-02-27)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Re-add cloning the repo to install scripts ([3d9b03c5](https://github.com/rust-lang/rustlings/commit/3d9b03c52b8dc51b140757f6fd25ad87b5782ef5))
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Add clippy lints (#269) ([1e2fd9c9](https://github.com/rust-lang/rustlings/commit/1e2fd9c92f8cd6e389525ca1a999fca4c90b5921))
|
|
||||||
|
|
||||||
<a name="2.2.0"></a>
|
|
||||||
|
|
||||||
## 2.2.0 (2020-02-25)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Update deps to version compatable with aarch64-pc-windows (#263) ([19a93428](https://github.com/rust-lang/rustlings/commit/19a93428b3c73d994292671f829bdc8e5b7b3401))
|
|
||||||
- **docs:**
|
|
||||||
- Added a necessary step to Windows installation process (#242) ([3906efcd](https://github.com/rust-lang/rustlings/commit/3906efcd52a004047b460ed548037093de3f523f))
|
|
||||||
- Fixed mangled sentence from book; edited for clarity (#266) ([ade52ff](https://github.com/rust-lang/rustlings/commit/ade52ffb739987287ddd5705944c8777705faed9))
|
|
||||||
- Updated iterators readme to account for iterators4 exercise (#273) ([bec8e3a](https://github.com/rust-lang/rustlings/commit/bec8e3a644cbd88db1c73ea5f1d8a364f4a34016))
|
|
||||||
- **installation:** make fatal errors more obvious (#272) ([17d0951e](https://github.com/rust-lang/rustlings/commit/17d0951e66fda8e11b204d5c4c41a0d5e22e78f7))
|
|
||||||
- **iterators2:**
|
|
||||||
- Remove reference to missing iterators2.rs (#245) ([419f7797](https://github.com/rust-lang/rustlings/commit/419f7797f294e4ce6a2b883199731b5bde77d262))
|
|
||||||
- **as_ref_mut:** Enable a test and improve per clippy's suggestion (#256) ([dfdf809](https://github.com/rust-lang/rustlings/commit/dfdf8093ebbd4145864995627b812780de52f902))
|
|
||||||
- **tests1:**
|
|
||||||
- Change test command ([fe10e06c](https://github.com/rust-lang/rustlings/commit/fe10e06c3733ddb4a21e90d09bf79bfe618e97ce)
|
|
||||||
- Correct test command in tests1.rs comment (#263) ([39fa7ae](https://github.com/rust-lang/rustlings/commit/39fa7ae8b70ad468da49b06f11b2383135a63bcf))
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Add variables5.rs exercise (#264) ([0c73609e](https://github.com/rust-lang/rustlings/commit/0c73609e6f2311295e95d6f96f8c747cfc4cba03))
|
|
||||||
- Show a completion message when watching (#253) ([d25ee55a](https://github.com/rust-lang/rustlings/commit/d25ee55a3205882d35782e370af855051b39c58c))
|
|
||||||
- Add type conversion and parsing exercises (#249) ([0c85dc11](https://github.com/rust-lang/rustlings/commit/0c85dc1193978b5165491b99cc4922caf8d14a65))
|
|
||||||
- Created consistent money unit (#258) ([fd57f8f](https://github.com/rust-lang/rustlings/commit/fd57f8f2c1da2af8ddbebbccec214e6f40f4dbab))
|
|
||||||
- Enable test for exercise test4 (#276) ([8b971ff](https://github.com/rust-lang/rustlings/commit/8b971ffab6079a706ac925f5917f987932b55c07))
|
|
||||||
- Added traits exercises (#274 but specifically #216, which originally added
|
|
||||||
this :heart:) ([b559cdd](https://github.com/rust-lang/rustlings/commit/b559cdd73f32c0d0cfc1feda39f82b3e3583df17))
|
|
||||||
|
|
||||||
<a name="2.1.0"></a>
|
|
||||||
|
|
||||||
## 2.1.0 (2019-11-27)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- add line numbers in several exercises and hints ([b565c4d3](https://github.com/rust-lang/rustlings/commit/b565c4d3e74e8e110bef201a082fa1302722a7c3))
|
|
||||||
- **arc1:** Fix some words in the comment ([c42c3b21](https://github.com/rust-lang/rustlings/commit/c42c3b2101df9164c8cd7bb344def921e5ba3e61))
|
|
||||||
- **enums:** Add link to chapter on pattern syntax (#242) ([615ce327](https://github.com/rust-lang/rustlings/commit/615ce3279800c56d89f19d218ccb7ef576624feb))
|
|
||||||
- **primitive_types4:**
|
|
||||||
- update outdated hint ([4c5189df](https://github.com/rust-lang/rustlings/commit/4c5189df2bdd9a231f6b2611919ba5aa14da0d3f))
|
|
||||||
- update outdated comment ([ded2c034](https://github.com/rust-lang/rustlings/commit/ded2c034ba93fa1e3c2c2ea16b83abc1a57265e8))
|
|
||||||
- **strings2:** update line number in hint ([a09f684f](https://github.com/rust-lang/rustlings/commit/a09f684f05c58d239a6fc59ec5f81c2533e8b820))
|
|
||||||
- **variables1:** Correct wrong word in comment ([fda5a470](https://github.com/rust-lang/rustlings/commit/fda5a47069e0954f16a04e8e50945e03becb71a5))
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- **watch:** show hint while watching ([8143d57b](https://github.com/rust-lang/rustlings/commit/8143d57b4e88c51341dd4a18a14c536042cc009c))
|
|
||||||
|
|
||||||
<a name="2.0.0"></a>
|
|
||||||
|
|
||||||
## 2.0.0 (2019-11-12)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- **default:** Clarify the installation procedure ([c371b853](https://github.com/rust-lang/rustlings/commit/c371b853afa08947ddeebec0edd074b171eeaae0))
|
|
||||||
- **info:** Fix trailing newlines for hints ([795b6e34](https://github.com/rust-lang/rustlings/commit/795b6e348094a898e9227a14f6232f7bb94c8d31))
|
|
||||||
- **run:** make `run` never prompt ([4b265465](https://github.com/rust-lang/rustlings/commit/4b26546589f7d2b50455429482cf1f386ceae8b3))
|
|
||||||
|
|
||||||
#### Breaking Changes
|
|
||||||
|
|
||||||
- Refactor hint system ([9bdb0a12](https://github.com/rust-lang/rustlings/commit/9bdb0a12e45a8e9f9f6a4bd4a9c172c5376c7f60))
|
|
||||||
- improve `watch` execution mode ([2cdd6129](https://github.com/rust-lang/rustlings/commit/2cdd61294f0d9a53775ee24ad76435bec8a21e60))
|
|
||||||
- Index exercises by name ([627cdc07](https://github.com/rust-lang/rustlings/commit/627cdc07d07dfe6a740e885e0ddf6900e7ec336b))
|
|
||||||
- **run:** makes `run` never prompt ([4b265465](https://github.com/rust-lang/rustlings/commit/4b26546589f7d2b50455429482cf1f386ceae8b3))
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- **cli:** check for rustc before doing anything ([36a033b8](https://github.com/rust-lang/rustlings/commit/36a033b87a6549c1e5639c908bf7381c84f4f425))
|
|
||||||
- **hint:** Add test for hint ([ce9fa6eb](https://github.com/rust-lang/rustlings/commit/ce9fa6ebbfdc3e7585d488d9409797285708316f))
|
|
||||||
|
|
||||||
<a name="1.5.1"></a>
|
|
||||||
|
|
||||||
### 1.5.1 (2019-11-11)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- **errors3:** Update hint ([dcfb427b](https://github.com/rust-lang/rustlings/commit/dcfb427b09585f0193f0a294443fdf99f11c64cb), closes [#185](https://github.com/rust-lang/rustlings/issues/185))
|
|
||||||
- **if1:** Remove `return` reference ([ad03d180](https://github.com/rust-lang/rustlings/commit/ad03d180c9311c0093e56a3531eec1a9a70cdb45))
|
|
||||||
- **strings:** Move Strings before Structs ([6dcecb38](https://github.com/rust-lang/rustlings/commit/6dcecb38a4435593beb87c8e12d6314143631482), closes [#204](https://github.com/rust-lang/rustlings/issues/204))
|
|
||||||
- **structs1:** Remove misleading comment ([f72e5a8f](https://github.com/rust-lang/rustlings/commit/f72e5a8f05568dde04eaeac10b9a69872f21cb37))
|
|
||||||
- **threads:** Move Threads behind SLT ([fbe91a67](https://github.com/rust-lang/rustlings/commit/fbe91a67a482bfe64cbcdd58d06ba830a0f39da3), closes [#205](https://github.com/rust-lang/rustlings/issues/205))
|
|
||||||
- **watch:** clear screen before each `verify()` ([3aff590](https://github.com/rust-lang/rustlings/commit/3aff59085586c24196a547c2693adbdcf4432648))
|
|
||||||
|
|
||||||
<a name="1.5.0"></a>
|
|
||||||
|
|
||||||
## 1.5.0 (2019-11-09)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- **test1:** Rewrite logic ([79a56942](https://github.com/rust-lang/rustlings/commit/79a569422c8309cfc9e4aed25bf4ab3b3859996b))
|
|
||||||
- **installation:** Fix rustlings installation check ([7a252c47](https://github.com/rust-lang/rustlings/commit/7a252c475551486efb52f949b8af55803b700bc6))
|
|
||||||
- **iterators:** Rename iterator3.rs ([433d2115](https://github.com/rust-lang/rustlings/commit/433d2115bc1c04b6d34a335a18c9a8f3e2672bc6))
|
|
||||||
- **iterators2:** Remove syntax resulting in misleading error message ([4cde8664](https://github.com/rust-lang/rustlings/commit/4cde86643e12db162a66e62f23b78962986046ac))
|
|
||||||
- **option1:**
|
|
||||||
- Fix arguments passed to assert! macro (#222) ([4c2cf6da](https://github.com/rust-lang/rustlings/commit/4c2cf6da755efe02725e05ecc3a303304c10a6da))
|
|
||||||
- Fix arguments passed to assert! macro ([ead4f7af](https://github.com/rust-lang/rustlings/commit/ead4f7af9e10e53418efdde5c359159347282afd))
|
|
||||||
- Add test for prematurely passing exercise ([a750e4a1](https://github.com/rust-lang/rustlings/commit/a750e4a1a3006227292bb17d57d78ce84da6bfc6))
|
|
||||||
- **primitive_types4:** Fail on a slice covering the wrong area ([5b1e673c](https://github.com/rust-lang/rustlings/commit/5b1e673cec1658afc4ebbbc800213847804facf5))
|
|
||||||
- **readme:** http to https ([70946b85](https://github.com/rust-lang/rustlings/commit/70946b85e536e80e70ed9505cb650ca0a3a1fbb5))
|
|
||||||
- **test1:**
|
|
||||||
- Swap assertion parameter order ([4086d463](https://github.com/rust-lang/rustlings/commit/4086d463a981e81d97781851d17db2ced290f446))
|
|
||||||
- renamed function name to snake case closes #180 ([89d5186c](https://github.com/rust-lang/rustlings/commit/89d5186c0dae8135ecabf90ee8bb35949bc2d29b))
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Add enums exercises ([dc150321](https://github.com/rust-lang/rustlings/commit/dc15032112fc485226a573a18139e5ce928b1755))
|
|
||||||
- Added exercise for struct update syntax ([1c4c8764](https://github.com/rust-lang/rustlings/commit/1c4c8764ed118740cd4cee73272ddc6cceb9d959))
|
|
||||||
- **iterators2:** adds iterators2 exercise including config ([9288fccf](https://github.com/rust-lang/rustlings/commit/9288fccf07a2c5043b76d0fd6491e4cf72d76031))
|
|
||||||
|
|
||||||
<a name="1.4.1"></a>
|
|
||||||
|
|
||||||
### 1.4.1 (2019-08-13)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- **iterators2:** Remove syntax resulting in misleading error message ([4cde8664](https://github.com/rust-lang/rustlings/commit/4cde86643e12db162a66e62f23b78962986046ac))
|
|
||||||
- **option1:** Add test for prematurely passing exercise ([a750e4a1](https://github.com/rust-lang/rustlings/commit/a750e4a1a3006227292bb17d57d78ce84da6bfc6))
|
|
||||||
- **test1:** Swap assertion parameter order ([4086d463](https://github.com/rust-lang/rustlings/commit/4086d463a981e81d97781851d17db2ced290f446))
|
|
||||||
|
|
||||||
<a name="1.4.0"></a>
|
|
||||||
|
|
||||||
## 1.4.0 (2019-07-13)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- **installation:** Fix rustlings installation check ([7a252c47](https://github.com/rust-lang/rustlings/commit/7a252c475551486efb52f949b8af55803b700bc6))
|
|
||||||
- **iterators:** Rename iterator3.rs ([433d2115](https://github.com/rust-lang/rustlings/commit/433d2115bc1c04b6d34a335a18c9a8f3e2672bc6))
|
|
||||||
- **readme:** http to https ([70946b85](https://github.com/rust-lang/rustlings/commit/70946b85e536e80e70ed9505cb650ca0a3a1fbb5))
|
|
||||||
- **test1:** renamed function name to snake case ([89d5186c](https://github.com/rust-lang/rustlings/commit/89d5186c0dae8135ecabf90ee8bb35949bc2d29b))
|
|
||||||
- **cli:** Check if changed exercise file exists before calling verify ([ba85ca3](https://github.com/rust-lang/rustlings/commit/ba85ca32c4cfc61de46851ab89f9c58a28f33c88))
|
|
||||||
- **structs1:** Fix the irrefutable let pattern warning ([cc6a141](https://github.com/rust-lang/rustlings/commit/cc6a14104d7c034eadc98297eaaa972d09c50b1f))
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- **changelog:** Use clog for changelogs ([34e31232](https://github.com/rust-lang/rustlings/commit/34e31232dfddde284a341c9609b33cd27d9d5724))
|
|
||||||
- **iterators2:** adds iterators2 exercise including config ([9288fccf](https://github.com/rust-lang/rustlings/commit/9288fccf07a2c5043b76d0fd6491e4cf72d76031))
|
|
||||||
|
|
||||||
<a name="1.3.0"></a>
|
|
||||||
|
|
||||||
### 1.3.0 (2019-06-05)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Adds a simple exercise for structures (#163, @briankung)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Add Result type signature as it is difficult for new comers to understand Generics and Error all at once. (#157, @veggiemonk)
|
|
||||||
- Rustfmt and whitespace fixes (#161, @eddyp)
|
|
||||||
- errorsn.rs: Separate also the hints from each other to avoid accidental viewing (#162, @eddyp)
|
|
||||||
- fixed outdated links (#165, @gushroom)
|
|
||||||
- Fix broken link (#164, @HanKruiger)
|
|
||||||
- Remove highlighting and syntect (#167, @komaeda)
|
|
||||||
|
|
||||||
<a name="1.2.2"></a>
|
|
||||||
|
|
||||||
### 1.2.2 (2019-05-07)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Reverted `--nocapture` flag since it was causing tests to pass unconditionally
|
|
||||||
|
|
||||||
<a name="1.2.1"></a>
|
|
||||||
|
|
||||||
### 1.2.1 (2019-04-22)
|
|
||||||
|
|
||||||
#### Bug Fixes
|
|
||||||
|
|
||||||
- Fix the `--nocapture` feature (@komaeda)
|
|
||||||
- Provide a nicer error message for when you're in the wrong directory
|
|
||||||
|
|
||||||
<a name="1.2.0"></a>
|
|
||||||
|
|
||||||
### 1.2.0 (2019-04-22)
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
|
|
||||||
- Add errors to exercises that compile without user changes (@yvan-sraka)
|
|
||||||
- Use --nocapture when testing, enabling `println!` when running (@komaeda)
|
|
||||||
|
|
||||||
<a name="1.1.1"></a>
|
|
||||||
|
|
||||||
### 1.1.1 (2019-04-14)
|
|
||||||
|
|
||||||
#### Bug fixes
|
|
||||||
|
|
||||||
- Fix permissions on exercise files (@zacanger, #133)
|
|
||||||
- Make installation checks more thorough (@komaeda, 1b3469f236bc6979c27f6e1a04e4138a88e55de3)
|
|
||||||
- Fix order of true/false in tests for executables (@mgeier, #137)
|
|
||||||
- Stop run from panicking when compile fails (@cjpearce, #141)
|
|
||||||
- Fix intermittent test failure caused by race condition (@cjpearce, #140)
|
|
||||||
- Fix links by deleting book version (@diodfr, #142)
|
|
||||||
- Canonicalize paths to fix path matching (@cjpearce, #143)
|
|
||||||
|
|
||||||
<a name="1.1.0"></a>
|
|
||||||
|
|
||||||
### 1.1.0 (2019-03-20)
|
|
||||||
|
|
||||||
- errors2.rs: update link to Rust book (#124)
|
|
||||||
- Start verification at most recently modified file (#120)
|
|
||||||
- Watch for file creation events in watch mode (#117)
|
|
||||||
- Add standard library types to exercises suite (#119)
|
|
||||||
- Give a warning when Rustlings isn't run from the right directory (#123)
|
|
||||||
- Verify that rust version is recent enough to install Rustlings (#131)
|
|
||||||
|
|
||||||
<a name="1.0.1"></a>
|
|
||||||
|
|
||||||
### 1.0.1 (2019-03-06)
|
|
||||||
|
|
||||||
- Adds a way to install Rustlings in one command (`curl -L https://git.io/rustlings | bash`)
|
|
||||||
- Makes `rustlings watch` react to create file events (@shaunbennett, #117)
|
|
||||||
- Reworks the exercise management to use an external TOML file instead of just listing them in the code
|
|
||||||
|
|
||||||
<a name="1.0.0"></a>
|
|
||||||
|
|
||||||
### 1.0.0 (2019-03-06)
|
|
||||||
|
|
||||||
Initial release.
|
|
130
CONTRIBUTING.md
130
CONTRIBUTING.md
|
@ -1,130 +0,0 @@
|
||||||
## Contributing to Rustlings
|
|
||||||
|
|
||||||
First off, thanks for taking the time to contribute!! ❤️
|
|
||||||
|
|
||||||
### Quick Reference
|
|
||||||
|
|
||||||
I want to...
|
|
||||||
|
|
||||||
_add an exercise! ➡️ [read this](#addex) and then [open a Pull Request](#prs)_
|
|
||||||
|
|
||||||
_update an outdated exercise! ➡️ [open a Pull Request](#prs)_
|
|
||||||
|
|
||||||
_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).
|
|
||||||
If you're reporting a bug, please include the output of the following commands:
|
|
||||||
|
|
||||||
- `rustc --version`
|
|
||||||
- `rustlings --version`
|
|
||||||
- `ls -la`
|
|
||||||
- Your OS name and version
|
|
||||||
|
|
||||||
<a name="prs"></a>
|
|
||||||
### Pull Requests
|
|
||||||
|
|
||||||
Opening a pull request is as easy as forking the repository and committing your
|
|
||||||
changes. There's a couple of things to watch out for:
|
|
||||||
|
|
||||||
#### Write correct commit messages
|
|
||||||
|
|
||||||
We follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4/)
|
|
||||||
specification.
|
|
||||||
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:
|
|
||||||
|
|
||||||
```
|
|
||||||
feat: add foobar1.rs exercise
|
|
||||||
```
|
|
||||||
|
|
||||||
If you're just fixing a bug, please use the `fix` type:
|
|
||||||
|
|
||||||
```
|
|
||||||
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!
|
|
File diff suppressed because it is too large
Load Diff
30
Cargo.toml
30
Cargo.toml
|
@ -1,30 +1,20 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rustlings"
|
name = "rustlings"
|
||||||
description = "Small exercises to get you used to reading and writing Rust code!"
|
version = "1.2.2"
|
||||||
version = "5.6.1"
|
authors = ["Olivia <819880950@qq.com>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com"]
|
||||||
authors = [
|
edition = "2018"
|
||||||
"Liv <mokou@fastmail.com>",
|
|
||||||
"Carol (Nichols || Goulding) <carol.nichols@gmail.com>",
|
|
||||||
]
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
indicatif = "0.17.6"
|
clap = "2.32.0"
|
||||||
console = "0.15"
|
indicatif = "0.9.0"
|
||||||
notify = "4.0"
|
console = "0.6.2"
|
||||||
toml = "0.7.6"
|
notify = "4.0.0"
|
||||||
regex = "1.5"
|
toml = "0.4.10"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = {version = "1.0.10", features = ["derive"]}
|
||||||
serde_json = "1.0.81"
|
|
||||||
home = "0.5.3"
|
|
||||||
glob = "0.3.0"
|
|
||||||
clap = { version = "4.4.0", features = ["derive"] }
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "rustlings"
|
name = "rustlings"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_cmd = "2.0.12"
|
assert_cmd = "0.11.0"
|
||||||
predicates = "3.0.3"
|
|
||||||
glob = "0.3.0"
|
|
||||||
|
|
182
README.md
182
README.md
|
@ -1,14 +1,12 @@
|
||||||
<div class="oranda-hide">
|
![crab pet](http://i.imgur.com/LbZJgmm.gif)
|
||||||
|
|
||||||
# rustlings 🦀❤️
|
# rustlings 🦀❤️
|
||||||
|
|
||||||
</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)_
|
_...looking for the old, web-based version of Rustlings? Try [here](https://github.com/rust-lang/rustlings/tree/rustlings-1)_
|
||||||
|
|
||||||
Alternatively, for a first-time Rust learner, there are several other resources:
|
Alternatively, for a first-time Rust learner, there's several other resources:
|
||||||
|
|
||||||
- [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!
|
- [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
|
- [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
|
||||||
|
@ -16,165 +14,113 @@ Alternatively, for a first-time Rust learner, there are several other resources:
|
||||||
## 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`._
|
_Note: If you're on MacOS, make sure you've installed Xcode and its developer tools by typing `xcode-select --install`._
|
||||||
_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.
|
_Note: If you have Xcode 10+ installed, you also need to install the package file found at `/Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg`._
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
## MacOS/Linux
|
## MacOS/Linux
|
||||||
|
|
||||||
Just run:
|
Just run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -L https://raw.githubusercontent.com/rust-lang/rustlings/main/install.sh | bash
|
curl -L https://git.io/rustlings | bash
|
||||||
```
|
# Or if you want it to be installed to a different path:
|
||||||
|
curl -L https://git.io/rustlings | bash -s mypath/
|
||||||
Or if you want it to be installed to a different path:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -L https://raw.githubusercontent.com/rust-lang/rustlings/main/install.sh | bash -s mypath/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This will install Rustlings and give you access to the `rustlings` command. Run it to get started!
|
This will install Rustlings and give you access to the `rustlings` command. Run it to get started!
|
||||||
|
|
||||||
### Nix
|
## Windows/Manually
|
||||||
|
|
||||||
Basically: Clone the repository at the latest tag, finally run `nix develop` or `nix-shell`.
|
Basically: Clone the repository, checkout to the latest tag, run `cargo install`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.6.1)
|
git clone https://github.com/rust-lang/rustlings
|
||||||
git clone -b 5.6.1 --depth 1 https://github.com/rust-lang/rustlings
|
|
||||||
cd rustlings
|
|
||||||
# if nix version > 2.3
|
|
||||||
nix develop
|
|
||||||
# if nix version <= 2.3
|
|
||||||
nix-shell
|
|
||||||
```
|
|
||||||
|
|
||||||
## Windows
|
|
||||||
|
|
||||||
In PowerShell (Run as Administrator), set `ExecutionPolicy` to `RemoteSigned`:
|
|
||||||
|
|
||||||
```ps1
|
|
||||||
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, you can run:
|
|
||||||
|
|
||||||
```ps1
|
|
||||||
Start-BitsTransfer -Source https://raw.githubusercontent.com/rust-lang/rustlings/main/install.ps1 -Destination $env:TMP/install_rustlings.ps1; Unblock-File $env:TMP/install_rustlings.ps1; Invoke-Expression $env:TMP/install_rustlings.ps1
|
|
||||||
```
|
|
||||||
|
|
||||||
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
|
cd rustlings
|
||||||
|
git checkout tags/1.0.0 # or whatever the latest version is (find out at https://github.com/rust-lang/rustlings/releases/latest)
|
||||||
cargo install --force --path .
|
cargo install --force --path .
|
||||||
```
|
```
|
||||||
|
|
||||||
If there are installation errors, ensure that your toolchain is up to date. For the latest, run:
|
Same as above, run `rustlings` to get started.
|
||||||
|
|
||||||
```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 `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 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:
|
The task is simple. Most exercises contain an error that keep it from compiling, and it's up to you to fix it! Some exercises are also ran as tests, but rustlings handles them all the same. To run the exercises in the recommended order, execute:
|
||||||
|
|
||||||
```bash
|
|
||||||
rustlings watch
|
|
||||||
```
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rustlings verify
|
rustlings verify
|
||||||
```
|
```
|
||||||
|
|
||||||
This will do the same as watch, but it'll quit after running.
|
This will try to verify the completion of every exercise in a predetermined order (what we think is best for newcomers). If you don't want to rerun `verify` every time you change a file, you can run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rustlings watch
|
||||||
|
```
|
||||||
|
|
||||||
|
This will do the same as verify, but won't quit after running and instead automatically rerun as soon as you change a 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:
|
In case you want to go by your own order, or want to only verify a single exercise, you can run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rustlings run myExercise1
|
rustlings run exercises/path/to/exercise.rs
|
||||||
```
|
```
|
||||||
|
|
||||||
Or simply use the following command to run the next unsolved exercise in the course:
|
In case you get stuck, there is usually a hint at the bottom of each exercise.
|
||||||
|
|
||||||
```bash
|
|
||||||
rustlings run next
|
|
||||||
```
|
|
||||||
|
|
||||||
In case you get stuck, you can run the following command to get a hint for your
|
|
||||||
exercise:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rustlings hint myExercise1
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also get the hint for the next unsolved exercise with the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rustlings hint next
|
|
||||||
```
|
|
||||||
|
|
||||||
To check your progress, you can run the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rustlings list
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing yourself
|
## 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`.
|
After every couple of sections, there will be a test that'll test your knowledge on a bunch of sections at once. These tests are found in `exercises/testN.rs`.
|
||||||
|
|
||||||
## Enabling `rust-analyzer`
|
## Completion
|
||||||
|
|
||||||
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.
|
Rustlings isn't done; there are a couple of sections that are very experimental and don't have proper documentation. These include:
|
||||||
|
|
||||||
## Continuing On
|
- Errors (`exercises/errors/`)
|
||||||
|
- Option (`exercises/option/`)
|
||||||
|
- Result (`exercises/result/`)
|
||||||
|
- Move Semantics (could still be improved, `exercises/move_semantics/`)
|
||||||
|
|
||||||
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.
|
Additionally, we could use exercises on a couple of topics:
|
||||||
|
|
||||||
## Uninstalling Rustlings
|
- Structs
|
||||||
|
- Better ownership stuff
|
||||||
|
- `impl`
|
||||||
|
- ??? probably more
|
||||||
|
|
||||||
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 are interested in improving or adding new ones, please feel free to contribute! Read on for more information :)
|
||||||
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
|
|
||||||
cargo uninstall rustlings
|
|
||||||
```
|
|
||||||
|
|
||||||
Now you should be done!
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
See [CONTRIBUTING.md](https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md).
|
### Adding an exercise
|
||||||
|
|
||||||
## Contributors ✨
|
First step is to add the exercise! Call it `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 you want to make sure it runs when using `rustlings`. All exercises are stored in `info.toml`, under the `exercises` array. They're ordered by the order they're ran when using `rustlings verify`.
|
||||||
|
|
||||||
|
You want to make sure where in the file you add your exercise. If you're not sure, add it at the bottom and ask in your pull request. To add an exercise, edit the file like this:
|
||||||
|
```diff
|
||||||
|
...
|
||||||
|
+ [[exercises]]
|
||||||
|
+ path = "exercises/yourTopic/yourTopicN.rs"
|
||||||
|
+ mode = "compile"
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
That's all! Feel free to put up a pull request.
|
||||||
|
|
||||||
|
### 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 `clap` CLI that loads from `src/verify.rs` and `src/run.rs`.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
`rustlings` was originally written by [Carol](https://github.com/carols10cents)!
|
||||||
|
|
||||||
Thanks goes to the wonderful people listed in [AUTHORS.md](https://github.com/rust-lang/rustlings/blob/main/AUTHORS.md) 🎉
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
Thanks for installing Rustlings!
|
||||||
|
|
||||||
|
Is this your first time?
|
||||||
|
|
||||||
|
Let's make sure you're up to speed:
|
||||||
|
- You have Rust installed, preferably via `rustup`
|
||||||
|
- You have `~/.cargo/bin` added to your PATH variable
|
||||||
|
- You have cloned this repository (https://github.com/rust-lang/rustlings)
|
||||||
|
- You have installed Rust language support for your editor
|
||||||
|
- You have locally installed the `rustlings` command by running:
|
||||||
|
|
||||||
|
cargo install --path .
|
||||||
|
|
||||||
|
If you've done all of this (or even most of it), congrats! You're ready
|
||||||
|
to start working with Rust.
|
||||||
|
|
||||||
|
To get started, run `rustlings verify` in order to get the first exercise.
|
||||||
|
Make sure to have your editor open!
|
|
@ -1,27 +0,0 @@
|
||||||
# Exercise to Book Chapter mapping
|
|
||||||
|
|
||||||
| Exercise | Book Chapter |
|
|
||||||
| ---------------------- | ------------------- |
|
|
||||||
| variables | §3.1 |
|
|
||||||
| functions | §3.3 |
|
|
||||||
| if | §3.5 |
|
|
||||||
| primitive_types | §3.2, §4.3 |
|
|
||||||
| vecs | §8.1 |
|
|
||||||
| move_semantics | §4.1-2 |
|
|
||||||
| structs | §5.1, §5.3 |
|
|
||||||
| enums | §6, §18.3 |
|
|
||||||
| strings | §8.2 |
|
|
||||||
| modules | §7 |
|
|
||||||
| hashmaps | §8.3 |
|
|
||||||
| options | §10.1 |
|
|
||||||
| error_handling | §9 |
|
|
||||||
| generics | §10 |
|
|
||||||
| traits | §10.2 |
|
|
||||||
| tests | §11.1 |
|
|
||||||
| lifetimes | §10.3 |
|
|
||||||
| iterators | §13.2-4 |
|
|
||||||
| threads | §16.1-3 |
|
|
||||||
| smart_pointers | §15, §16.3 |
|
|
||||||
| macros | §19.6 |
|
|
||||||
| clippy | §21.4 |
|
|
||||||
| conversions | n/a |
|
|
|
@ -1,10 +0,0 @@
|
||||||
# Clippy
|
|
||||||
|
|
||||||
The Clippy tool is a collection of lints to analyze your code so you can catch common mistakes and improve your Rust code.
|
|
||||||
|
|
||||||
If you used the installation script for Rustlings, Clippy should be already installed.
|
|
||||||
If not you can install it manually via `rustup component add clippy`.
|
|
||||||
|
|
||||||
## Further information
|
|
||||||
|
|
||||||
- [GitHub Repository](https://github.com/rust-lang/rust-clippy).
|
|
|
@ -1,26 +0,0 @@
|
||||||
// clippy1.rs
|
|
||||||
//
|
|
||||||
// The Clippy tool is a collection of lints to analyze your code so you can
|
|
||||||
// catch common mistakes and improve your Rust code.
|
|
||||||
//
|
|
||||||
// For these exercises the code will fail to compile when there are clippy
|
|
||||||
// warnings check clippy's suggestions from the output to solve the exercise.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::f32;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let pi = 3.14f32;
|
|
||||||
let radius = 5.00f32;
|
|
||||||
|
|
||||||
let area = pi * f32::powi(radius, 2);
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"The area of a circle with radius {:.2} is {:.5}!",
|
|
||||||
radius, area
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
// clippy2.rs
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut res = 42;
|
|
||||||
let option = Some(12);
|
|
||||||
for x in option {
|
|
||||||
res += x;
|
|
||||||
}
|
|
||||||
println!("{}", res);
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
// clippy3.rs
|
|
||||||
//
|
|
||||||
// Here's a couple more easy Clippy fixes, so you can see its utility.
|
|
||||||
// No hints.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[allow(unused_variables, unused_assignments)]
|
|
||||||
fn main() {
|
|
||||||
let my_option: Option<()> = None;
|
|
||||||
if my_option.is_none() {
|
|
||||||
my_option.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let my_arr = &[
|
|
||||||
-1, -2, -3
|
|
||||||
-4, -5, -6
|
|
||||||
];
|
|
||||||
println!("My array! Here it is: {:?}", my_arr);
|
|
||||||
|
|
||||||
let my_empty_vec = vec![1, 2, 3, 4, 5].resize(0, 5);
|
|
||||||
println!("This Vec is empty, see? {:?}", my_empty_vec);
|
|
||||||
|
|
||||||
let mut value_a = 45;
|
|
||||||
let mut value_b = 66;
|
|
||||||
// Let's swap these two!
|
|
||||||
value_a = value_b;
|
|
||||||
value_b = value_a;
|
|
||||||
println!("value a: {}; value b: {}", value_a, value_b);
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
# Type conversions
|
|
||||||
|
|
||||||
Rust offers a multitude of ways to convert a value of a given type into another type.
|
|
||||||
|
|
||||||
The simplest form of type conversion is a type cast expression. It is denoted with the binary operator `as`. For instance, `println!("{}", 1 + 1.0);` would not compile, since `1` is an integer while `1.0` is a float. However, `println!("{}", 1 as f32 + 1.0)` should compile. The exercise [`using_as`](using_as.rs) tries to cover this.
|
|
||||||
|
|
||||||
Rust also offers traits that facilitate type conversions upon implementation. These traits can be found under the [`convert`](https://doc.rust-lang.org/std/convert/index.html) module.
|
|
||||||
The traits are the following:
|
|
||||||
|
|
||||||
- `From` and `Into` covered in [`from_into`](from_into.rs)
|
|
||||||
- `TryFrom` and `TryInto` covered in [`try_from_into`](try_from_into.rs)
|
|
||||||
- `AsRef` and `AsMut` covered in [`as_ref_mut`](as_ref_mut.rs)
|
|
||||||
|
|
||||||
Furthermore, the `std::str` module offers a trait called [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) which helps with converting strings into target types via the `parse` method on strings. If properly implemented for a given type `Person`, then `let p: Person = "Mark,20".parse().unwrap()` should both compile and run without panicking.
|
|
||||||
|
|
||||||
These should be the main ways ***within the standard library*** to convert data into your desired types.
|
|
||||||
|
|
||||||
## Further information
|
|
||||||
|
|
||||||
These are not directly covered in the book, but the standard library has a great documentation for it.
|
|
||||||
|
|
||||||
- [conversions](https://doc.rust-lang.org/std/convert/index.html)
|
|
||||||
- [`FromStr` trait](https://doc.rust-lang.org/std/str/trait.FromStr.html)
|
|
|
@ -1,65 +0,0 @@
|
||||||
// as_ref_mut.rs
|
|
||||||
//
|
|
||||||
// AsRef and AsMut allow for cheap reference-to-reference conversions. Read more
|
|
||||||
// about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html and
|
|
||||||
// https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
// Obtain the number of bytes (not characters) in the given argument.
|
|
||||||
// TODO: Add the AsRef trait appropriately as a trait bound.
|
|
||||||
fn byte_counter<T>(arg: T) -> usize {
|
|
||||||
arg.as_ref().as_bytes().len()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain the number of characters (not bytes) in the given argument.
|
|
||||||
// TODO: Add the AsRef trait appropriately as a trait bound.
|
|
||||||
fn char_counter<T>(arg: T) -> usize {
|
|
||||||
arg.as_ref().chars().count()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Squares a number using as_mut().
|
|
||||||
// TODO: Add the appropriate trait bound.
|
|
||||||
fn num_sq<T>(arg: &mut T) {
|
|
||||||
// TODO: Implement the function body.
|
|
||||||
???
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn different_counts() {
|
|
||||||
let s = "Café au lait";
|
|
||||||
assert_ne!(char_counter(s), byte_counter(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn same_counts() {
|
|
||||||
let s = "Cafe au lait";
|
|
||||||
assert_eq!(char_counter(s), byte_counter(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn different_counts_using_string() {
|
|
||||||
let s = String::from("Café au lait");
|
|
||||||
assert_ne!(char_counter(s.clone()), byte_counter(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn same_counts_using_string() {
|
|
||||||
let s = String::from("Cafe au lait");
|
|
||||||
assert_eq!(char_counter(s.clone()), byte_counter(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn mut_box() {
|
|
||||||
let mut num: Box<u32> = Box::new(3);
|
|
||||||
num_sq(&mut num);
|
|
||||||
assert_eq!(*num, 9);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,140 +0,0 @@
|
||||||
// from_into.rs
|
|
||||||
//
|
|
||||||
// The From trait is used for value-to-value conversions. If From is implemented
|
|
||||||
// correctly for a type, the Into trait should work conversely. You can read
|
|
||||||
// more about it at https://doc.rust-lang.org/std/convert/trait.From.html
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint from_into` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Person {
|
|
||||||
name: String,
|
|
||||||
age: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
// We implement the Default trait to use it as a fallback
|
|
||||||
// when the provided string is not convertible into a Person object
|
|
||||||
impl Default for Person {
|
|
||||||
fn default() -> Person {
|
|
||||||
Person {
|
|
||||||
name: String::from("John"),
|
|
||||||
age: 30,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Your task is to complete this implementation in order for the line `let p =
|
|
||||||
// Person::from("Mark,20")` to compile Please note that you'll need to parse the
|
|
||||||
// age component into a `usize` with something like `"4".parse::<usize>()`. The
|
|
||||||
// outcome of this needs to be handled appropriately.
|
|
||||||
//
|
|
||||||
// Steps:
|
|
||||||
// 1. If the length of the provided string is 0, then return the default of
|
|
||||||
// Person.
|
|
||||||
// 2. Split the given string on the commas present in it.
|
|
||||||
// 3. Extract the first element from the split operation and use it as the name.
|
|
||||||
// 4. If the name is empty, then return the default of Person.
|
|
||||||
// 5. Extract the other element from the split operation and parse it into a
|
|
||||||
// `usize` as the age.
|
|
||||||
// If while parsing the age, something goes wrong, then return the default of
|
|
||||||
// Person Otherwise, then return an instantiated Person object with the results
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
impl From<&str> for Person {
|
|
||||||
fn from(s: &str) -> Person {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// Use the `from` function
|
|
||||||
let p1 = Person::from("Mark,20");
|
|
||||||
// Since From is implemented for Person, we should be able to use Into
|
|
||||||
let p2: Person = "Gerald,70".into();
|
|
||||||
println!("{:?}", p1);
|
|
||||||
println!("{:?}", p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
#[test]
|
|
||||||
fn test_default() {
|
|
||||||
// Test that the default person is 30 year old John
|
|
||||||
let dp = Person::default();
|
|
||||||
assert_eq!(dp.name, "John");
|
|
||||||
assert_eq!(dp.age, 30);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_bad_convert() {
|
|
||||||
// Test that John is returned when bad string is provided
|
|
||||||
let p = Person::from("");
|
|
||||||
assert_eq!(p.name, "John");
|
|
||||||
assert_eq!(p.age, 30);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_good_convert() {
|
|
||||||
// Test that "Mark,20" works
|
|
||||||
let p = Person::from("Mark,20");
|
|
||||||
assert_eq!(p.name, "Mark");
|
|
||||||
assert_eq!(p.age, 20);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_bad_age() {
|
|
||||||
// Test that "Mark,twenty" will return the default person due to an
|
|
||||||
// error in parsing age
|
|
||||||
let p = Person::from("Mark,twenty");
|
|
||||||
assert_eq!(p.name, "John");
|
|
||||||
assert_eq!(p.age, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_missing_comma_and_age() {
|
|
||||||
let p: Person = Person::from("Mark");
|
|
||||||
assert_eq!(p.name, "John");
|
|
||||||
assert_eq!(p.age, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_missing_age() {
|
|
||||||
let p: Person = Person::from("Mark,");
|
|
||||||
assert_eq!(p.name, "John");
|
|
||||||
assert_eq!(p.age, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_missing_name() {
|
|
||||||
let p: Person = Person::from(",1");
|
|
||||||
assert_eq!(p.name, "John");
|
|
||||||
assert_eq!(p.age, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_missing_name_and_age() {
|
|
||||||
let p: Person = Person::from(",");
|
|
||||||
assert_eq!(p.name, "John");
|
|
||||||
assert_eq!(p.age, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_missing_name_and_invalid_age() {
|
|
||||||
let p: Person = Person::from(",one");
|
|
||||||
assert_eq!(p.name, "John");
|
|
||||||
assert_eq!(p.age, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_trailing_comma() {
|
|
||||||
let p: Person = Person::from("Mike,32,");
|
|
||||||
assert_eq!(p.name, "Mike");
|
|
||||||
assert_eq!(p.age, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_trailing_comma_and_some_string() {
|
|
||||||
let p: Person = Person::from("Mike,32,man");
|
|
||||||
assert_eq!(p.name, "Mike");
|
|
||||||
assert_eq!(p.age, 32);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,133 +0,0 @@
|
||||||
// from_str.rs
|
|
||||||
//
|
|
||||||
// This is similar to from_into.rs, but this time we'll implement `FromStr` and
|
|
||||||
// return errors instead of falling back to a default value. Additionally, upon
|
|
||||||
// implementing FromStr, you can use the `parse` method on strings to generate
|
|
||||||
// an object of the implementor type. You can read more about it at
|
|
||||||
// https://doc.rust-lang.org/std/str/trait.FromStr.html
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint from_str` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
use std::num::ParseIntError;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
struct Person {
|
|
||||||
name: String,
|
|
||||||
age: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
// We will use this error type for the `FromStr` implementation.
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
enum ParsePersonError {
|
|
||||||
// Empty input string
|
|
||||||
Empty,
|
|
||||||
// Incorrect number of fields
|
|
||||||
BadLen,
|
|
||||||
// Empty name field
|
|
||||||
NoName,
|
|
||||||
// Wrapped error from parse::<usize>()
|
|
||||||
ParseInt(ParseIntError),
|
|
||||||
}
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
// Steps:
|
|
||||||
// 1. If the length of the provided string is 0, an error should be returned
|
|
||||||
// 2. Split the given string on the commas present in it
|
|
||||||
// 3. Only 2 elements should be returned from the split, otherwise return an
|
|
||||||
// error
|
|
||||||
// 4. Extract the first element from the split operation and use it as the name
|
|
||||||
// 5. Extract the other element from the split operation and parse it into a
|
|
||||||
// `usize` as the age with something like `"4".parse::<usize>()`
|
|
||||||
// 6. If while extracting the name and the age something goes wrong, an error
|
|
||||||
// should be returned
|
|
||||||
// If everything goes well, then return a Result of a Person object
|
|
||||||
//
|
|
||||||
// As an aside: `Box<dyn Error>` implements `From<&'_ str>`. This means that if
|
|
||||||
// you want to return a string error message, you can do so via just using
|
|
||||||
// return `Err("my error message".into())`.
|
|
||||||
|
|
||||||
impl FromStr for Person {
|
|
||||||
type Err = ParsePersonError;
|
|
||||||
fn from_str(s: &str) -> Result<Person, Self::Err> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let p = "Mark,20".parse::<Person>().unwrap();
|
|
||||||
println!("{:?}", p);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn empty_input() {
|
|
||||||
assert_eq!("".parse::<Person>(), Err(ParsePersonError::Empty));
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn good_input() {
|
|
||||||
let p = "John,32".parse::<Person>();
|
|
||||||
assert!(p.is_ok());
|
|
||||||
let p = p.unwrap();
|
|
||||||
assert_eq!(p.name, "John");
|
|
||||||
assert_eq!(p.age, 32);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn missing_age() {
|
|
||||||
assert!(matches!(
|
|
||||||
"John,".parse::<Person>(),
|
|
||||||
Err(ParsePersonError::ParseInt(_))
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn invalid_age() {
|
|
||||||
assert!(matches!(
|
|
||||||
"John,twenty".parse::<Person>(),
|
|
||||||
Err(ParsePersonError::ParseInt(_))
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn missing_comma_and_age() {
|
|
||||||
assert_eq!("John".parse::<Person>(), Err(ParsePersonError::BadLen));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn missing_name() {
|
|
||||||
assert_eq!(",1".parse::<Person>(), Err(ParsePersonError::NoName));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn missing_name_and_age() {
|
|
||||||
assert!(matches!(
|
|
||||||
",".parse::<Person>(),
|
|
||||||
Err(ParsePersonError::NoName | ParsePersonError::ParseInt(_))
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn missing_name_and_invalid_age() {
|
|
||||||
assert!(matches!(
|
|
||||||
",one".parse::<Person>(),
|
|
||||||
Err(ParsePersonError::NoName | ParsePersonError::ParseInt(_))
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn trailing_comma() {
|
|
||||||
assert_eq!("John,32,".parse::<Person>(), Err(ParsePersonError::BadLen));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn trailing_comma_and_some_string() {
|
|
||||||
assert_eq!(
|
|
||||||
"John,32,man".parse::<Person>(),
|
|
||||||
Err(ParsePersonError::BadLen)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,193 +0,0 @@
|
||||||
// try_from_into.rs
|
|
||||||
//
|
|
||||||
// TryFrom is a simple and safe type conversion that may fail in a controlled
|
|
||||||
// way under some circumstances. Basically, this is the same as From. The main
|
|
||||||
// difference is that this should return a Result type instead of the target
|
|
||||||
// type itself. You can read more about it at
|
|
||||||
// https://doc.rust-lang.org/std/convert/trait.TryFrom.html
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint try_from_into` or use the `hint` watch subcommand for
|
|
||||||
// a hint.
|
|
||||||
|
|
||||||
use std::convert::{TryFrom, TryInto};
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
struct Color {
|
|
||||||
red: u8,
|
|
||||||
green: u8,
|
|
||||||
blue: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
// We will use this error type for these `TryFrom` conversions.
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
enum IntoColorError {
|
|
||||||
// Incorrect length of slice
|
|
||||||
BadLen,
|
|
||||||
// Integer conversion error
|
|
||||||
IntConversion,
|
|
||||||
}
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
// Your task is to complete this implementation and return an Ok result of inner
|
|
||||||
// type Color. You need to create an implementation for a tuple of three
|
|
||||||
// integers, an array of three integers, and a slice of integers.
|
|
||||||
//
|
|
||||||
// Note that the implementation for tuple and array will be checked at compile
|
|
||||||
// time, but the slice implementation needs to check the slice length! Also note
|
|
||||||
// that correct RGB color values must be integers in the 0..=255 range.
|
|
||||||
|
|
||||||
// Tuple implementation
|
|
||||||
impl TryFrom<(i16, i16, i16)> for Color {
|
|
||||||
type Error = IntoColorError;
|
|
||||||
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array implementation
|
|
||||||
impl TryFrom<[i16; 3]> for Color {
|
|
||||||
type Error = IntoColorError;
|
|
||||||
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slice implementation
|
|
||||||
impl TryFrom<&[i16]> for Color {
|
|
||||||
type Error = IntoColorError;
|
|
||||||
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// Use the `try_from` function
|
|
||||||
let c1 = Color::try_from((183, 65, 14));
|
|
||||||
println!("{:?}", c1);
|
|
||||||
|
|
||||||
// Since TryFrom is implemented for Color, we should be able to use TryInto
|
|
||||||
let c2: Result<Color, _> = [183, 65, 14].try_into();
|
|
||||||
println!("{:?}", c2);
|
|
||||||
|
|
||||||
let v = vec![183, 65, 14];
|
|
||||||
// With slice we should use `try_from` function
|
|
||||||
let c3 = Color::try_from(&v[..]);
|
|
||||||
println!("{:?}", c3);
|
|
||||||
// or take slice within round brackets and use TryInto
|
|
||||||
let c4: Result<Color, _> = (&v[..]).try_into();
|
|
||||||
println!("{:?}", c4);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tuple_out_of_range_positive() {
|
|
||||||
assert_eq!(
|
|
||||||
Color::try_from((256, 1000, 10000)),
|
|
||||||
Err(IntoColorError::IntConversion)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_tuple_out_of_range_negative() {
|
|
||||||
assert_eq!(
|
|
||||||
Color::try_from((-1, -10, -256)),
|
|
||||||
Err(IntoColorError::IntConversion)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_tuple_sum() {
|
|
||||||
assert_eq!(
|
|
||||||
Color::try_from((-1, 255, 255)),
|
|
||||||
Err(IntoColorError::IntConversion)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_tuple_correct() {
|
|
||||||
let c: Result<Color, _> = (183, 65, 14).try_into();
|
|
||||||
assert!(c.is_ok());
|
|
||||||
assert_eq!(
|
|
||||||
c.unwrap(),
|
|
||||||
Color {
|
|
||||||
red: 183,
|
|
||||||
green: 65,
|
|
||||||
blue: 14
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_array_out_of_range_positive() {
|
|
||||||
let c: Result<Color, _> = [1000, 10000, 256].try_into();
|
|
||||||
assert_eq!(c, Err(IntoColorError::IntConversion));
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_array_out_of_range_negative() {
|
|
||||||
let c: Result<Color, _> = [-10, -256, -1].try_into();
|
|
||||||
assert_eq!(c, Err(IntoColorError::IntConversion));
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_array_sum() {
|
|
||||||
let c: Result<Color, _> = [-1, 255, 255].try_into();
|
|
||||||
assert_eq!(c, Err(IntoColorError::IntConversion));
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_array_correct() {
|
|
||||||
let c: Result<Color, _> = [183, 65, 14].try_into();
|
|
||||||
assert!(c.is_ok());
|
|
||||||
assert_eq!(
|
|
||||||
c.unwrap(),
|
|
||||||
Color {
|
|
||||||
red: 183,
|
|
||||||
green: 65,
|
|
||||||
blue: 14
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_slice_out_of_range_positive() {
|
|
||||||
let arr = [10000, 256, 1000];
|
|
||||||
assert_eq!(
|
|
||||||
Color::try_from(&arr[..]),
|
|
||||||
Err(IntoColorError::IntConversion)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_slice_out_of_range_negative() {
|
|
||||||
let arr = [-256, -1, -10];
|
|
||||||
assert_eq!(
|
|
||||||
Color::try_from(&arr[..]),
|
|
||||||
Err(IntoColorError::IntConversion)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_slice_sum() {
|
|
||||||
let arr = [-1, 255, 255];
|
|
||||||
assert_eq!(
|
|
||||||
Color::try_from(&arr[..]),
|
|
||||||
Err(IntoColorError::IntConversion)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_slice_correct() {
|
|
||||||
let v = vec![183, 65, 14];
|
|
||||||
let c: Result<Color, _> = Color::try_from(&v[..]);
|
|
||||||
assert!(c.is_ok());
|
|
||||||
assert_eq!(
|
|
||||||
c.unwrap(),
|
|
||||||
Color {
|
|
||||||
red: 183,
|
|
||||||
green: 65,
|
|
||||||
blue: 14
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_slice_excess_length() {
|
|
||||||
let v = vec![0, 0, 0, 0];
|
|
||||||
assert_eq!(Color::try_from(&v[..]), Err(IntoColorError::BadLen));
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_slice_insufficient_length() {
|
|
||||||
let v = vec![0, 0];
|
|
||||||
assert_eq!(Color::try_from(&v[..]), Err(IntoColorError::BadLen));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
// using_as.rs
|
|
||||||
//
|
|
||||||
// Type casting in Rust is done via the usage of the `as` operator. Please note
|
|
||||||
// that the `as` operator is not only used when type casting. It also helps with
|
|
||||||
// renaming imports.
|
|
||||||
//
|
|
||||||
// The goal is to make sure that the division does not fail to compile and
|
|
||||||
// returns the proper type.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint using_as` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn average(values: &[f64]) -> f64 {
|
|
||||||
let total = values.iter().sum::<f64>();
|
|
||||||
total / values.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let values = [3.5, 0.3, 13.0, 11.7];
|
|
||||||
println!("{}", average(&values));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn returns_proper_type_and_value() {
|
|
||||||
assert_eq!(average(&[3.5, 0.3, 13.0, 11.7]), 7.125);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
# Enums
|
|
||||||
|
|
||||||
Rust allows you to define types called "enums" which enumerate possible values.
|
|
||||||
Enums are a feature in many languages, but their capabilities differ in each language. Rust’s enums are most similar to algebraic data types in functional languages, such as F#, OCaml, and Haskell.
|
|
||||||
Useful in combination with enums is Rust's "pattern matching" facility, which makes it easy to run different code for different values of an enumeration.
|
|
||||||
|
|
||||||
## Further information
|
|
||||||
|
|
||||||
- [Enums](https://doc.rust-lang.org/book/ch06-00-enums.html)
|
|
||||||
- [Pattern syntax](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html)
|
|
|
@ -1,17 +0,0 @@
|
||||||
// enums1.rs
|
|
||||||
//
|
|
||||||
// No hints this time! ;)
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum Message {
|
|
||||||
// TODO: define a few types of messages as used below
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("{:?}", Message::Quit);
|
|
||||||
println!("{:?}", Message::Echo);
|
|
||||||
println!("{:?}", Message::Move);
|
|
||||||
println!("{:?}", Message::ChangeColor);
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
// enums2.rs
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint enums2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum Message {
|
|
||||||
// TODO: define the different variants used below
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Message {
|
|
||||||
fn call(&self) {
|
|
||||||
println!("{:?}", self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let messages = [
|
|
||||||
Message::Move { x: 10, y: 30 },
|
|
||||||
Message::Echo(String::from("hello world")),
|
|
||||||
Message::ChangeColor(200, 255, 255),
|
|
||||||
Message::Quit,
|
|
||||||
];
|
|
||||||
|
|
||||||
for message in &messages {
|
|
||||||
message.call();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
// enums3.rs
|
|
||||||
//
|
|
||||||
// Address all the TODOs to make the tests pass!
|
|
||||||
//
|
|
||||||
// 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 {
|
|
||||||
x: u8,
|
|
||||||
y: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct State {
|
|
||||||
color: (u8, u8, u8),
|
|
||||||
position: Point,
|
|
||||||
quit: bool,
|
|
||||||
message: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl State {
|
|
||||||
fn change_color(&mut self, color: (u8, u8, u8)) {
|
|
||||||
self.color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn quit(&mut self) {
|
|
||||||
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) {
|
|
||||||
// TODO: create a match expression to process the different message variants
|
|
||||||
// Remember: When passing a tuple as a function argument, you'll need extra parentheses:
|
|
||||||
// fn function((t, u, p, l, e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_match_message_call() {
|
|
||||||
let mut state = State {
|
|
||||||
quit: false,
|
|
||||||
position: Point { x: 0, y: 0 },
|
|
||||||
color: (0, 0, 0),
|
|
||||||
message: "hello world".to_string(),
|
|
||||||
};
|
|
||||||
state.process(Message::ChangeColor(255, 0, 255));
|
|
||||||
state.process(Message::Echo(String::from("Hello world!")));
|
|
||||||
state.process(Message::Move(Point { x: 10, y: 15 }));
|
|
||||||
state.process(Message::Quit);
|
|
||||||
|
|
||||||
assert_eq!(state.color, (255, 0, 255));
|
|
||||||
assert_eq!(state.position.x, 10);
|
|
||||||
assert_eq!(state.position.y, 15);
|
|
||||||
assert_eq!(state.quit, true);
|
|
||||||
assert_eq!(state.message, "Hello world!");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +1,5 @@
|
||||||
# Error handling
|
For this exercise check out the sections:
|
||||||
|
|
||||||
Most errors aren’t serious enough to require the program to stop entirely.
|
|
||||||
Sometimes, when a function fails, it’s for a reason that you can easily interpret and respond to.
|
|
||||||
For example, if you try to open a file and that operation fails because the file doesn’t exist, you might want to create the file instead of terminating the process.
|
|
||||||
|
|
||||||
## Further information
|
|
||||||
|
|
||||||
- [Error Handling](https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html)
|
- [Error Handling](https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html)
|
||||||
- [Generics](https://doc.rust-lang.org/book/ch10-01-syntax.html)
|
- [Generics](https://doc.rust-lang.org/book/ch10-01-syntax.html)
|
||||||
- [Result](https://doc.rust-lang.org/rust-by-example/error/result.html)
|
|
||||||
- [Boxing errors](https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/boxing_errors.html)
|
of the Rust Book.
|
||||||
|
|
|
@ -1,22 +1,17 @@
|
||||||
// errors1.rs
|
// errors1.rs
|
||||||
//
|
// This function refuses to generate text to be printed on a nametag if
|
||||||
// This function refuses to generate text to be printed on a nametag if you pass
|
// you pass it an empty string. It'd be nicer if it explained what the problem
|
||||||
// it an empty string. It'd be nicer if it explained what the problem was,
|
// was, instead of just sometimes returning `None`. The 2nd test currently
|
||||||
// instead of just sometimes returning `None`. Thankfully, Rust has a similar
|
// does not compile or pass, but it illustrates the behavior we would like
|
||||||
// construct to `Option` that can be used to express error conditions. Let's use
|
// this function to have.
|
||||||
// it!
|
// Scroll down for hints!!!
|
||||||
//
|
|
||||||
// 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> {
|
pub fn generate_nametag_text(name: String) -> Option<String> {
|
||||||
if name.is_empty() {
|
if name.len() > 0 {
|
||||||
|
Some(format!("Hi! My name is {}", name))
|
||||||
|
} else {
|
||||||
// Empty names aren't allowed.
|
// Empty names aren't allowed.
|
||||||
None
|
None
|
||||||
} else {
|
|
||||||
Some(format!("Hi! My name is {}", name))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,11 +19,14 @@ pub fn generate_nametag_text(name: String) -> Option<String> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
// This test passes initially if you comment out the 2nd test.
|
||||||
|
// You'll need to update what this test expects when you change
|
||||||
|
// the function under test!
|
||||||
#[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é".into()),
|
||||||
Ok("Hi! My name is Beyoncé".into())
|
Some("Hi! My name is Beyoncé".into())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +34,40 @@ mod tests {
|
||||||
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("".into()),
|
||||||
// Don't change this line
|
|
||||||
Err("`name` was empty; it must be nonempty.".into())
|
Err("`name` was empty; it must be nonempty.".into())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// `Err` is one of the variants of `Result`, so what the 2nd test is saying
|
||||||
|
// is that `generate_nametag_text` should return a `Result` instead of an
|
||||||
|
// `Option`.
|
||||||
|
|
||||||
|
// To make this change, you'll need to:
|
||||||
|
// - update the return type in the function signature to be a Result<String, String> that
|
||||||
|
// could be the variants `Ok(String)` and `Err(String)`
|
||||||
|
// - change the body of the function to return `Ok(stuff)` where it currently
|
||||||
|
// returns `Some(stuff)`
|
||||||
|
// - change the body of the function to return `Err(error message)` where it
|
||||||
|
// currently returns `None`
|
||||||
|
// - change the first test to expect `Ok(stuff)` where it currently expects
|
||||||
|
// `Some(stuff)`.
|
||||||
|
|
|
@ -1,25 +1,20 @@
|
||||||
// errors2.rs
|
// 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,
|
||||||
// the `total_cost` function will calculate the total cost of the tokens. Since
|
// and the `total_cost` function will calculate the total number of tokens.
|
||||||
// the player typed in the quantity, though, we get it as a string-- and they
|
// Since the player typed in the quantity, though, we get it as a string-- and
|
||||||
// might have typed anything, not just numbers!
|
// they might have typed anything, not just numbers!
|
||||||
//
|
|
||||||
// Right now, this function isn't handling the error case at all (and isn't
|
|
||||||
// handling the success case properly either). What we want to do is: if we call
|
|
||||||
// the `total_cost` function on a string that is not a number, that function
|
|
||||||
// will return a `ParseIntError`, and in that case, we want to immediately
|
|
||||||
// return that error from our function and not try to multiply and add.
|
|
||||||
//
|
|
||||||
// There are at least two ways to implement this that are both correct-- but one
|
|
||||||
// is a lot shorter!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint errors2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
// Right now, this function isn't handling the error case at all (and isn't
|
||||||
|
// handling the success case properly either). What we want to do is:
|
||||||
|
// if we call the `parse` function on a string that is not a number, that
|
||||||
|
// function will return a `ParseIntError`, and in that case, we want to
|
||||||
|
// immediately return that error from our function and not try to multiply
|
||||||
|
// and add.
|
||||||
|
|
||||||
|
// There are at least two ways to implement this that are both correct-- but
|
||||||
|
// one is a lot shorter! Scroll down for hints to both ways.
|
||||||
|
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
|
@ -48,3 +43,27 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// One way to handle this is using a `match` statement on
|
||||||
|
// `item_quantity.parse::<i32>()` where the cases are `Ok(something)` and
|
||||||
|
// `Err(something)`. This pattern is very common in Rust, though, so there's
|
||||||
|
// a `?` operator that does pretty much what you would make that match statement
|
||||||
|
// do for you! Take a look at this section of the Error Handling chapter:
|
||||||
|
// https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
|
||||||
|
// and give it a try!
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
// errors3.rs
|
// 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?
|
// we can't use the `?` operator in the `main()` function! Why not?
|
||||||
//
|
// What should we do instead? Scroll for hints!
|
||||||
// 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;
|
||||||
|
|
||||||
|
@ -32,3 +27,36 @@ pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
|
||||||
|
|
||||||
Ok(qty * cost_per_item + processing_fee)
|
Ok(qty * cost_per_item + processing_fee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Since the `?` operator returns an `Err` early if the thing it's trying to
|
||||||
|
// do fails, you can only use the `?` operator in functions that have a
|
||||||
|
// `Result` as their return type.
|
||||||
|
|
||||||
|
// Hence the error that you get if you run this code is:
|
||||||
|
|
||||||
|
// ```
|
||||||
|
// error[E0277]: the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`)
|
||||||
|
// ```
|
||||||
|
|
||||||
|
// So we have to use another way of handling a `Result` within `main`.
|
||||||
|
|
||||||
|
// Decide what we should do if `pretend_user_input` has a string value that does
|
||||||
|
// not parse to an integer, and implement that instead of using the `?`
|
||||||
|
// operator.
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
// errors5.rs
|
|
||||||
//
|
|
||||||
// This program uses an altered version of the code from errors4.
|
|
||||||
//
|
|
||||||
// This exercise uses some concepts that we won't get to until later in the
|
|
||||||
// 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
|
|
||||||
// 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
|
|
||||||
// the trait the compiler looks for on any value used in that context. For this
|
|
||||||
// exercise, that context is the potential errors which 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;
|
|
||||||
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)]
|
|
||||||
enum CreationError {
|
|
||||||
Negative,
|
|
||||||
Zero,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PositiveNonzeroInteger {
|
|
||||||
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 {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
let description = match *self {
|
|
||||||
CreationError::Negative => "number is negative",
|
|
||||||
CreationError::Zero => "number is zero",
|
|
||||||
};
|
|
||||||
f.write_str(description)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for CreationError {}
|
|
|
@ -1,94 +0,0 @@
|
||||||
// errors6.rs
|
|
||||||
//
|
|
||||||
// Using catch-all error types like `Box<dyn error::Error>` isn't recommended
|
|
||||||
// for library code, where callers might want to make decisions based on the
|
|
||||||
// error content, instead of printing it out or propagating it further. Here, we
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// 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)]
|
|
||||||
enum CreationError {
|
|
||||||
Negative,
|
|
||||||
Zero,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PositiveNonzeroInteger {
|
|
||||||
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)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_error() {
|
|
||||||
// We can't construct a ParseIntError, so we have to pattern match.
|
|
||||||
assert!(matches!(
|
|
||||||
parse_pos_nonzero("not a number"),
|
|
||||||
Err(ParsePosNonzeroError::ParseInt(_))
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_negative() {
|
|
||||||
assert_eq!(
|
|
||||||
parse_pos_nonzero("-555"),
|
|
||||||
Err(ParsePosNonzeroError::Creation(CreationError::Negative))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_zero() {
|
|
||||||
assert_eq!(
|
|
||||||
parse_pos_nonzero("0"),
|
|
||||||
Err(ParsePosNonzeroError::Creation(CreationError::Zero))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_positive() {
|
|
||||||
let x = PositiveNonzeroInteger::new(42);
|
|
||||||
assert!(x.is_ok());
|
|
||||||
assert_eq!(parse_pos_nonzero("42"), Ok(x.unwrap()));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,247 @@
|
||||||
|
// errorsn.rs
|
||||||
|
// This is a bigger error exercise than the previous ones!
|
||||||
|
// You can do it! :)
|
||||||
|
//
|
||||||
|
// Edit the `read_and_validate` function so that it compiles and
|
||||||
|
// passes the tests... so many things could go wrong!
|
||||||
|
//
|
||||||
|
// - Reading from stdin could produce an io::Error
|
||||||
|
// - Parsing the input could produce a num::ParseIntError
|
||||||
|
// - Validating the input could produce a CreationError (defined below)
|
||||||
|
//
|
||||||
|
// How can we lump these errors into one general error? That is, what
|
||||||
|
// type goes where the question marks are, and how do we return
|
||||||
|
// that type from the body of read_and_validate?
|
||||||
|
//
|
||||||
|
// Scroll down for hints :)
|
||||||
|
|
||||||
|
use std::error;
|
||||||
|
use std::fmt;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
// PositiveNonzeroInteger is a struct defined below the tests.
|
||||||
|
fn read_and_validate(b: &mut io::BufRead) -> Result<PositiveNonzeroInteger, ???> {
|
||||||
|
let mut line = String::new();
|
||||||
|
b.read_line(&mut line);
|
||||||
|
let num: i64 = line.trim().parse();
|
||||||
|
let answer = PositiveNonzeroInteger::new(num);
|
||||||
|
answer
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a test helper function that turns a &str into a BufReader.
|
||||||
|
fn test_with_str(s: &str) -> Result<PositiveNonzeroInteger, Box<error::Error>> {
|
||||||
|
let mut b = io::BufReader::new(s.as_bytes());
|
||||||
|
read_and_validate(&mut b)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_success() {
|
||||||
|
let x = test_with_str("42\n");
|
||||||
|
assert_eq!(PositiveNonzeroInteger(42), x.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_not_num() {
|
||||||
|
let x = test_with_str("eleven billion\n");
|
||||||
|
assert!(x.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_non_positive() {
|
||||||
|
let x = test_with_str("-40\n");
|
||||||
|
assert!(x.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ioerror() {
|
||||||
|
struct Broken;
|
||||||
|
impl io::Read for Broken {
|
||||||
|
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
|
||||||
|
Err(io::Error::new(io::ErrorKind::BrokenPipe, "uh-oh!"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut b = io::BufReader::new(Broken);
|
||||||
|
assert!(read_and_validate(&mut b).is_err());
|
||||||
|
assert_eq!("uh-oh!", read_and_validate(&mut b).unwrap_err().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
struct PositiveNonzeroInteger(u64);
|
||||||
|
|
||||||
|
impl PositiveNonzeroInteger {
|
||||||
|
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
|
||||||
|
if value == 0 {
|
||||||
|
Err(CreationError::Zero)
|
||||||
|
} else if value < 0 {
|
||||||
|
Err(CreationError::Negative)
|
||||||
|
} else {
|
||||||
|
Ok(PositiveNonzeroInteger(value as u64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_positive_nonzero_integer_creation() {
|
||||||
|
assert!(PositiveNonzeroInteger::new(10).is_ok());
|
||||||
|
assert_eq!(
|
||||||
|
Err(CreationError::Negative),
|
||||||
|
PositiveNonzeroInteger::new(-10)
|
||||||
|
);
|
||||||
|
assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
enum CreationError {
|
||||||
|
Negative,
|
||||||
|
Zero,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for CreationError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.write_str((self as &error::Error).description())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for CreationError {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
CreationError::Negative => "Negative",
|
||||||
|
CreationError::Zero => "Zero",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// First hint: To figure out what type should go where the ??? is, take a look
|
||||||
|
// at the test helper function `test_with_str`, since it returns whatever
|
||||||
|
// `read_and_validate` returns and`test_with_str` has its signature fully
|
||||||
|
// specified.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Next hint: There are three places in `read_and_validate` that we call a
|
||||||
|
// function that returns a `Result` (that is, the functions might fail).
|
||||||
|
// Apply the `?` operator on those calls so that we return immediately from
|
||||||
|
// `read_and_validate` if those function calls fail.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Another hint: under the hood, the `?` operator calls `From::from`
|
||||||
|
// on the error value to convert it to a boxed trait object, a Box<error::Error>,
|
||||||
|
// which is polymorphic-- that means that lots of different kinds of errors
|
||||||
|
// can be returned from the same function because all errors act the same
|
||||||
|
// since they all implement the `error::Error` trait.
|
||||||
|
// Check out this section of the book:
|
||||||
|
// https://doc.rust-lang.org/stable/book/second-edition/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Another another hint: Note that because the `?` operator returns
|
||||||
|
// the *unwrapped* value in the `Ok` case, if we want to return a `Result` from
|
||||||
|
// `read_and_validate` for *its* success case, we'll have to rewrap a value
|
||||||
|
// that we got from the return value of a `?`ed call in an `Ok`-- this will
|
||||||
|
// look like `Ok(something)`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Another another another hint: `Result`s must be "used", that is, you'll
|
||||||
|
// get a warning if you don't handle a `Result` that you get in your
|
||||||
|
// function. Read more about that in the `std::result` module docs:
|
||||||
|
// https://doc.rust-lang.org/std/result/#results-must-be-used
|
|
@ -0,0 +1,48 @@
|
||||||
|
// option1.rs
|
||||||
|
// This example panics because the second time it calls `pop`, the `vec`
|
||||||
|
// is empty, so `pop` returns `None`, and `unwrap` panics if it's called
|
||||||
|
// on `None`. Handle this in a more graceful way than calling `unwrap`!
|
||||||
|
// Scroll down for hints :)
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut list = vec![3];
|
||||||
|
|
||||||
|
let last = list.pop().unwrap();
|
||||||
|
println!("The last item in the list is {:?}", last);
|
||||||
|
|
||||||
|
let second_to_last = list.pop().unwrap();
|
||||||
|
println!(
|
||||||
|
"The second-to-last item in the list is {:?}",
|
||||||
|
second_to_last
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Try using a `match` statement where the arms are `Some(thing)` and `None`.
|
||||||
|
// Or set a default value to print out if you get `None` by using the
|
||||||
|
// function `unwrap_or`.
|
||||||
|
// Or use an `if let` statement on the result of `pop()` to both destructure
|
||||||
|
// a `Some` value and only print out something if we have a value!
|
|
@ -1,9 +1,5 @@
|
||||||
// errors4.rs
|
// result1.rs
|
||||||
//
|
// Make this test pass! Scroll down for hints :)
|
||||||
// Execute `rustlings hint errors4` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
struct PositiveNonzeroInteger(u64);
|
struct PositiveNonzeroInteger(u64);
|
||||||
|
@ -16,7 +12,6 @@ enum CreationError {
|
||||||
|
|
||||||
impl PositiveNonzeroInteger {
|
impl PositiveNonzeroInteger {
|
||||||
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
|
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
|
||||||
// Hmm... Why is this always returning an Ok value?
|
|
||||||
Ok(PositiveNonzeroInteger(value as u64))
|
Ok(PositiveNonzeroInteger(value as u64))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,3 +25,22 @@ fn test_creation() {
|
||||||
);
|
);
|
||||||
assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
|
assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// `PositiveNonzeroInteger::new` is always creating a new instance and returning an `Ok` result.
|
||||||
|
// It should be doing some checking, returning an `Err` result if those checks fail, and only
|
||||||
|
// returning an `Ok` result if those checks determine that everything is... okay :)
|
|
@ -1,8 +1,7 @@
|
||||||
# Functions
|
### Functions
|
||||||
|
|
||||||
Here, you'll learn how to write functions and how the Rust compiler can help you debug errors even
|
Here, you'll learn how to write functions and how Rust's compiler can trace things way back.
|
||||||
in more complex code.
|
|
||||||
|
|
||||||
## Further information
|
#### Book Sections
|
||||||
|
|
||||||
- [How Functions Work](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html)
|
- [How Functions Work](https://doc.rust-lang.org/stable/book/ch03-03-how-functions-work.html)
|
||||||
|
|
|
@ -1,10 +1,44 @@
|
||||||
// functions1.rs
|
// functions1.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This main function is calling a function that it expects to exist, but the
|
||||||
|
// function doesn't exist. It expects this function to have the name `call_me`.
|
||||||
|
// It expects this function to not take any arguments and not return a value.
|
||||||
|
// Sounds a lot like `main`, doesn't it?
|
||||||
|
|
|
@ -1,16 +1,42 @@
|
||||||
// functions2.rs
|
// functions2.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// Execute `rustlings hint functions2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
call_me(3);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Rust requires that all parts of a function's signature have type annotations,
|
||||||
|
// but `call_me` is missing the type annotation of `num`.
|
||||||
|
|
|
@ -1,16 +1,42 @@
|
||||||
// functions3.rs
|
// functions3.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// Execute `rustlings hint functions3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
call_me();
|
call_me();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_me(num: u32) {
|
fn call_me(num: i32) {
|
||||||
for i in 0..num {
|
for i in 0..num {
|
||||||
println!("Ring! Call number {}", i + 1);
|
println!("Ring! Call number {}", i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This time, the function *declaration* is okay, but there's something wrong
|
||||||
|
// with the place where we're calling the function.
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
// functions4.rs
|
// functions4.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// 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
|
|
||||||
// about the function bodies themselves, we're only interested in the signatures
|
|
||||||
// for now. If anything, this is a good way to peek ahead to future exercises!)
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint functions4` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
// This store is having a sale where if the price is an even number, you get
|
||||||
|
// 10 (money unit) off, but if it's an odd number, it's 3 (money unit) less.
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let original_price = 51;
|
let original_price = 51;
|
||||||
|
@ -26,3 +20,25 @@ fn sale_price(price: i32) -> {
|
||||||
fn is_even(num: i32) -> bool {
|
fn is_even(num: i32) -> bool {
|
||||||
num % 2 == 0
|
num % 2 == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The error message points to line 12 and says it expects a type after the
|
||||||
|
// `->`. This is where the function's return type should be-- take a look at
|
||||||
|
// the `is_even` function for an example!
|
||||||
|
|
|
@ -1,15 +1,47 @@
|
||||||
// functions5.rs
|
// functions5.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// Execute `rustlings hint functions5` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let answer = square(3);
|
let answer = square(3);
|
||||||
println!("The square of 3 is {}", answer);
|
println!("The answer is {}", answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn square(num: i32) -> i32 {
|
fn square(num: i32) -> i32 {
|
||||||
num * num;
|
num * num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This is a really common error that can be fixed by removing one character.
|
||||||
|
// It happens because Rust distinguishes between expressions and statements: expressions return
|
||||||
|
// a value based on its operand, and statements simply return a () type which behaves just like `void` in C/C++ language.
|
||||||
|
// We want to return a value of `i32` type from the `square` function, but it is returning a `()` type...
|
||||||
|
// They are not the same. There are two solutions:
|
||||||
|
// 1. Add a `return` ahead of `num * num;`
|
||||||
|
// 2. remove `;`, make it to be `num * num`
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
# Generics
|
|
||||||
|
|
||||||
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.
|
|
||||||
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.
|
|
||||||
|
|
||||||
## Further information
|
|
||||||
|
|
||||||
- [Generic Data Types](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html)
|
|
||||||
- [Bounds](https://doc.rust-lang.org/rust-by-example/generics/bounds.html)
|
|
|
@ -1,14 +0,0 @@
|
||||||
// generics1.rs
|
|
||||||
//
|
|
||||||
// This shopping list program isn't compiling! Use your knowledge of generics to
|
|
||||||
// fix it.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint generics1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut shopping_list: Vec<?> = Vec::new();
|
|
||||||
shopping_list.push("milk");
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
// generics2.rs
|
|
||||||
//
|
|
||||||
// This powerful wrapper provides the ability to store a positive integer value.
|
|
||||||
// Rewrite it using generics 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 {
|
|
||||||
value: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Wrapper {
|
|
||||||
pub fn new(value: u32) -> Self {
|
|
||||||
Wrapper { value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn store_u32_in_wrapper() {
|
|
||||||
assert_eq!(Wrapper::new(42).value, 42);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn store_str_in_wrapper() {
|
|
||||||
assert_eq!(Wrapper::new("Foo").value, "Foo");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
# Hashmaps
|
|
||||||
|
|
||||||
A *hash map* allows you to associate a value with a particular key.
|
|
||||||
You may also know this by the names [*unordered map* in C++](https://en.cppreference.com/w/cpp/container/unordered_map),
|
|
||||||
[*dictionary* in Python](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) or an *associative array* in other languages.
|
|
||||||
|
|
||||||
This is the other data structure that we've been talking about before, when
|
|
||||||
talking about Vecs.
|
|
||||||
|
|
||||||
## Further information
|
|
||||||
|
|
||||||
- [Storing Keys with Associated Values in Hash Maps](https://doc.rust-lang.org/book/ch08-03-hash-maps.html)
|
|
|
@ -1,44 +0,0 @@
|
||||||
// hashmaps1.rs
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
// particular fruit is in the basket. You have to put at least three different
|
|
||||||
// types of fruits (e.g apple, banana, mango) in the basket and the total count
|
|
||||||
// of all the fruits should be at least five.
|
|
||||||
//
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
fn fruit_basket() -> HashMap<String, u32> {
|
|
||||||
let mut basket = // TODO: declare your hash map here.
|
|
||||||
|
|
||||||
// Two bananas are already given for you :)
|
|
||||||
basket.insert(String::from("banana"), 2);
|
|
||||||
|
|
||||||
// TODO: Put more fruits in your basket here.
|
|
||||||
|
|
||||||
basket
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn at_least_three_types_of_fruits() {
|
|
||||||
let basket = fruit_basket();
|
|
||||||
assert!(basket.len() >= 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn at_least_five_fruits() {
|
|
||||||
let basket = fruit_basket();
|
|
||||||
assert!(basket.values().sum::<u32>() >= 5);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
// hashmaps2.rs
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
// represents the name of each fruit we collect and the value represents how
|
|
||||||
// many of that particular fruit we have collected. Three types of fruits -
|
|
||||||
// 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
|
|
||||||
// more than 11 in total - we have a lot of mouths to feed. You are not allowed
|
|
||||||
// to insert any more of these fruits!
|
|
||||||
//
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
#[derive(Hash, PartialEq, Eq)]
|
|
||||||
enum Fruit {
|
|
||||||
Apple,
|
|
||||||
Banana,
|
|
||||||
Mango,
|
|
||||||
Lychee,
|
|
||||||
Pineapple,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
|
|
||||||
let fruit_kinds = vec![
|
|
||||||
Fruit::Apple,
|
|
||||||
Fruit::Banana,
|
|
||||||
Fruit::Mango,
|
|
||||||
Fruit::Lychee,
|
|
||||||
Fruit::Pineapple,
|
|
||||||
];
|
|
||||||
|
|
||||||
for fruit in fruit_kinds {
|
|
||||||
// TODO: Insert new fruits if they are not already present in the
|
|
||||||
// basket. Note that you are not allowed to put any type of fruit that's
|
|
||||||
// already present!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
// Don't modify this function!
|
|
||||||
fn get_fruit_basket() -> HashMap<Fruit, u32> {
|
|
||||||
let mut basket = HashMap::<Fruit, u32>::new();
|
|
||||||
basket.insert(Fruit::Apple, 4);
|
|
||||||
basket.insert(Fruit::Mango, 2);
|
|
||||||
basket.insert(Fruit::Lychee, 5);
|
|
||||||
|
|
||||||
basket
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_given_fruits_are_not_modified() {
|
|
||||||
let mut basket = get_fruit_basket();
|
|
||||||
fruit_basket(&mut basket);
|
|
||||||
assert_eq!(*basket.get(&Fruit::Apple).unwrap(), 4);
|
|
||||||
assert_eq!(*basket.get(&Fruit::Mango).unwrap(), 2);
|
|
||||||
assert_eq!(*basket.get(&Fruit::Lychee).unwrap(), 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn at_least_five_types_of_fruits() {
|
|
||||||
let mut basket = get_fruit_basket();
|
|
||||||
fruit_basket(&mut basket);
|
|
||||||
let count_fruit_kinds = basket.len();
|
|
||||||
assert!(count_fruit_kinds >= 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn greater_than_eleven_fruits() {
|
|
||||||
let mut basket = get_fruit_basket();
|
|
||||||
fruit_basket(&mut basket);
|
|
||||||
let count = basket.values().sum::<u32>();
|
|
||||||
assert!(count > 11);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn all_fruit_types_in_basket() {
|
|
||||||
let mut basket = get_fruit_basket();
|
|
||||||
fruit_basket(&mut basket);
|
|
||||||
for amount in basket.values() {
|
|
||||||
assert_ne!(amount, &0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
// hashmaps3.rs
|
|
||||||
//
|
|
||||||
// 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>"
|
|
||||||
// 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
|
|
||||||
// team scored, and goals the team conceded. One approach to build the scores
|
|
||||||
// table is to use a Hashmap. The solution is partially written to use a
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// A structure to store the goal details of a team.
|
|
||||||
struct Team {
|
|
||||||
goals_scored: u8,
|
|
||||||
goals_conceded: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_scores_table(results: String) -> HashMap<String, Team> {
|
|
||||||
// The name of the team is the key and its associated struct is the value.
|
|
||||||
let mut scores: HashMap<String, Team> = HashMap::new();
|
|
||||||
|
|
||||||
for r in results.lines() {
|
|
||||||
let v: Vec<&str> = r.split(',').collect();
|
|
||||||
let team_1_name = v[0].to_string();
|
|
||||||
let team_1_score: u8 = v[2].parse().unwrap();
|
|
||||||
let team_2_name = v[1].to_string();
|
|
||||||
let team_2_score: u8 = v[3].parse().unwrap();
|
|
||||||
// TODO: Populate the scores table with details extracted from the
|
|
||||||
// current line. Keep in mind that goals scored by team_1
|
|
||||||
// will be the number of goals conceded from team_2, and similarly
|
|
||||||
// goals scored by team_2 will be the number of goals conceded by
|
|
||||||
// team_1.
|
|
||||||
}
|
|
||||||
scores
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
fn get_results() -> String {
|
|
||||||
let results = "".to_string()
|
|
||||||
+ "England,France,4,2\n"
|
|
||||||
+ "France,Italy,3,1\n"
|
|
||||||
+ "Poland,Spain,2,0\n"
|
|
||||||
+ "Germany,England,2,1\n";
|
|
||||||
results
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn build_scores() {
|
|
||||||
let scores = build_scores_table(get_results());
|
|
||||||
|
|
||||||
let mut keys: Vec<&String> = scores.keys().collect();
|
|
||||||
keys.sort();
|
|
||||||
assert_eq!(
|
|
||||||
keys,
|
|
||||||
vec!["England", "France", "Germany", "Italy", "Poland", "Spain"]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn validate_team_score_1() {
|
|
||||||
let scores = build_scores_table(get_results());
|
|
||||||
let team = scores.get("England").unwrap();
|
|
||||||
assert_eq!(team.goals_scored, 5);
|
|
||||||
assert_eq!(team.goals_conceded, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn validate_team_score_2() {
|
|
||||||
let scores = build_scores_table(get_results());
|
|
||||||
let team = scores.get("Spain").unwrap();
|
|
||||||
assert_eq!(team.goals_scored, 0);
|
|
||||||
assert_eq!(team.goals_conceded, 2);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
# If
|
### If
|
||||||
|
|
||||||
`if`, the most basic (but still surprisingly versatile!) type of control flow, is what you'll learn here.
|
`if`, the most basic type of control flow, is what you'll learn here.
|
||||||
|
|
||||||
## Further information
|
#### Book Sections
|
||||||
|
|
||||||
- [Control Flow - if expressions](https://doc.rust-lang.org/book/ch03-05-control-flow.html#if-expressions)
|
- [Control Flow - if expressions](https://doc.rust-lang.org/stable/book/ch03-05-control-flow.html#if-expressions)
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
// if1.rs
|
// if1.rs
|
||||||
//
|
|
||||||
// Execute `rustlings hint if1` or use the `hint` watch subcommand for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub fn bigger(a: i32, b:i32) -> i32 {
|
pub fn bigger(a: i32, b:i32) -> i32 {
|
||||||
// Complete this function to return the bigger number!
|
// Complete this function to return the bigger number!
|
||||||
// Do not use:
|
// Do not use:
|
||||||
|
// - return
|
||||||
// - another function call
|
// - another function call
|
||||||
// - additional variables
|
// - additional variables
|
||||||
|
// Scroll down for hints.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't mind this for now :)
|
// Don't mind this for now :)
|
||||||
|
@ -25,9 +23,37 @@ mod tests {
|
||||||
fn fortytwo_is_bigger_than_thirtytwo() {
|
fn fortytwo_is_bigger_than_thirtytwo() {
|
||||||
assert_eq!(42, bigger(32, 42));
|
assert_eq!(42, bigger(32, 42));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn equal_numbers() {
|
|
||||||
assert_eq!(42, bigger(42, 42));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// It's possible to do this in one line if you would like!
|
||||||
|
// Some similar examples from other languages:
|
||||||
|
// - In C(++) this would be: `a > b ? a : b`
|
||||||
|
// - In Python this would be: `a if a > b else b`
|
||||||
|
// Remember in Rust that:
|
||||||
|
// - the `if` condition does not need to be surrounded by parentheses
|
||||||
|
// - `if`/`else` conditionals are expressions
|
||||||
|
// - Each condition is followed by a `{}` block.
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
// if2.rs
|
|
||||||
//
|
|
||||||
// Step 1: Make me compile!
|
|
||||||
// Step 2: Get the bar_for_fuzz and default_to_baz tests passing!
|
|
||||||
//
|
|
||||||
// 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 {
|
|
||||||
1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No test changes needed!
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn foo_for_fizz() {
|
|
||||||
assert_eq!(foo_if_fizz("fizz"), "foo")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn bar_for_fuzz() {
|
|
||||||
assert_eq!(foo_if_fizz("fuzz"), "bar")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn default_to_baz() {
|
|
||||||
assert_eq!(foo_if_fizz("literally anything"), "baz")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
// if3.rs
|
|
||||||
//
|
|
||||||
// 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" {
|
|
||||||
1
|
|
||||||
} else if animal == "gopher" {
|
|
||||||
2.0
|
|
||||||
} else if animal == "snake" {
|
|
||||||
3
|
|
||||||
} else {
|
|
||||||
"Unknown"
|
|
||||||
};
|
|
||||||
|
|
||||||
// DO NOT CHANGE THIS STATEMENT BELOW
|
|
||||||
let habitat = if identifier == 1 {
|
|
||||||
"Beach"
|
|
||||||
} else if identifier == 2 {
|
|
||||||
"Burrow"
|
|
||||||
} else if identifier == 3 {
|
|
||||||
"Desert"
|
|
||||||
} else {
|
|
||||||
"Unknown"
|
|
||||||
};
|
|
||||||
|
|
||||||
habitat
|
|
||||||
}
|
|
||||||
|
|
||||||
// No test changes needed.
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gopher_lives_in_burrow() {
|
|
||||||
assert_eq!(animal_habitat("gopher"), "Burrow")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn snake_lives_in_desert() {
|
|
||||||
assert_eq!(animal_habitat("snake"), "Desert")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn crab_lives_on_beach() {
|
|
||||||
assert_eq!(animal_habitat("crab"), "Beach")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn unknown_animal() {
|
|
||||||
assert_eq!(animal_habitat("dinosaur"), "Unknown")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
# Intro
|
|
||||||
|
|
||||||
Rust uses the `print!` and `println!` macros to print text to the console.
|
|
||||||
|
|
||||||
## Further information
|
|
||||||
|
|
||||||
- [Hello World](https://doc.rust-lang.org/rust-by-example/hello.html)
|
|
||||||
- [Formatted print](https://doc.rust-lang.org/rust-by-example/hello/print.html)
|
|
|
@ -1,41 +0,0 @@
|
||||||
// intro1.rs
|
|
||||||
//
|
|
||||||
// About this `I AM NOT DONE` thing:
|
|
||||||
// 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, 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() {
|
|
||||||
println!("Hello and");
|
|
||||||
println!(r#" welcome to... "#);
|
|
||||||
println!(r#" _ _ _ "#);
|
|
||||||
println!(r#" _ __ _ _ ___| |_| (_)_ __ __ _ ___ "#);
|
|
||||||
println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
|
|
||||||
println!(r#" | | | |_| \__ \ |_| | | | | | (_| \__ \ "#);
|
|
||||||
println!(r#" |_| \__,_|___/\__|_|_|_| |_|\__, |___/ "#);
|
|
||||||
println!(r#" |___/ "#);
|
|
||||||
println!();
|
|
||||||
println!("This exercise compiles successfully. The remaining exercises contain a compiler");
|
|
||||||
println!("or logic error. The central concept behind Rustlings is to fix these errors and");
|
|
||||||
println!("solve the exercises. Good luck!");
|
|
||||||
println!();
|
|
||||||
println!("The source for this exercise is in `exercises/intro/intro1.rs`. Have a look!");
|
|
||||||
println!(
|
|
||||||
"Going forward, the source of the exercises will always be in the success/failure output."
|
|
||||||
);
|
|
||||||
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 +0,0 @@
|
||||||
// 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() {
|
|
||||||
println!("Hello {}!");
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
# Iterators
|
|
||||||
|
|
||||||
This section will teach you about Iterators.
|
|
||||||
|
|
||||||
## Further information
|
|
||||||
|
|
||||||
- [Iterator](https://doc.rust-lang.org/book/ch13-02-iterators.html)
|
|
||||||
- [Iterator documentation](https://doc.rust-lang.org/stable/std/iter/)
|
|
|
@ -1,26 +0,0 @@
|
||||||
// iterators1.rs
|
|
||||||
//
|
|
||||||
// When performing operations on elements within a collection, iterators are
|
|
||||||
// essential. This module helps you get familiar with the structure of using an
|
|
||||||
// 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() {
|
|
||||||
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
|
|
||||||
|
|
||||||
let mut my_iterable_fav_fruits = ???; // TODO: Step 1
|
|
||||||
|
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana"));
|
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2
|
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"avocado"));
|
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 3
|
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry"));
|
|
||||||
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 4
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
// iterators2.rs
|
|
||||||
//
|
|
||||||
// In this exercise, you'll learn some of the unique advantages that iterators
|
|
||||||
// can offer. Follow the steps to complete the exercise.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
// Step 1.
|
|
||||||
// Complete the `capitalize_first` function.
|
|
||||||
// "hello" -> "Hello"
|
|
||||||
pub fn capitalize_first(input: &str) -> String {
|
|
||||||
let mut c = input.chars();
|
|
||||||
match c.next() {
|
|
||||||
None => String::new(),
|
|
||||||
Some(first) => ???,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2.
|
|
||||||
// Apply the `capitalize_first` function to a slice of string slices.
|
|
||||||
// Return a vector of strings.
|
|
||||||
// ["hello", "world"] -> ["Hello", "World"]
|
|
||||||
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3.
|
|
||||||
// Apply the `capitalize_first` function again to a slice of string slices.
|
|
||||||
// Return a single string.
|
|
||||||
// ["hello", " ", "world"] -> "Hello World"
|
|
||||||
pub fn capitalize_words_string(words: &[&str]) -> String {
|
|
||||||
String::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_success() {
|
|
||||||
assert_eq!(capitalize_first("hello"), "Hello");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_empty() {
|
|
||||||
assert_eq!(capitalize_first(""), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_iterate_string_vec() {
|
|
||||||
let words = vec!["hello", "world"];
|
|
||||||
assert_eq!(capitalize_words_vector(&words), ["Hello", "World"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_iterate_into_string() {
|
|
||||||
let words = vec!["hello", " ", "world"];
|
|
||||||
assert_eq!(capitalize_words_string(&words), "Hello World");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
// 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)]
|
|
||||||
pub enum DivisionError {
|
|
||||||
NotDivisible(NotDivisibleError),
|
|
||||||
DivideByZero,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
pub struct NotDivisibleError {
|
|
||||||
dividend: i32,
|
|
||||||
divisor: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
|
|
||||||
// Otherwise, return a suitable error.
|
|
||||||
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complete the function and return a value of the correct type so the test
|
|
||||||
// passes.
|
|
||||||
// Desired output: Ok([1, 11, 1426, 3])
|
|
||||||
fn result_with_list() -> () {
|
|
||||||
let numbers = vec![27, 297, 38502, 81];
|
|
||||||
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
|
|
||||||
// passes.
|
|
||||||
// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)]
|
|
||||||
fn list_of_results() -> () {
|
|
||||||
let numbers = vec![27, 297, 38502, 81];
|
|
||||||
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_success() {
|
|
||||||
assert_eq!(divide(81, 9), Ok(9));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_not_divisible() {
|
|
||||||
assert_eq!(
|
|
||||||
divide(81, 6),
|
|
||||||
Err(DivisionError::NotDivisible(NotDivisibleError {
|
|
||||||
dividend: 81,
|
|
||||||
divisor: 6
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_divide_by_0() {
|
|
||||||
assert_eq!(divide(81, 0), Err(DivisionError::DivideByZero));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_divide_0_by_something() {
|
|
||||||
assert_eq!(divide(0, 81), Ok(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_result_with_list() {
|
|
||||||
assert_eq!(format!("{:?}", result_with_list()), "Ok([1, 11, 1426, 3])");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_list_of_results() {
|
|
||||||
assert_eq!(
|
|
||||||
format!("{:?}", list_of_results()),
|
|
||||||
"[Ok(1), Ok(11), Ok(1426), Ok(3)]"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,156 +0,0 @@
|
||||||
// iterators5.rs
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
// the progress is the value. Two counting functions were created to count the
|
|
||||||
// number of exercises with a given progress. Recreate this counting
|
|
||||||
// functionality using iterators. Try not to 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;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
|
||||||
enum Progress {
|
|
||||||
None,
|
|
||||||
Some,
|
|
||||||
Complete,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
|
|
||||||
let mut count = 0;
|
|
||||||
for val in map.values() {
|
|
||||||
if val == &value {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
count
|
|
||||||
}
|
|
||||||
|
|
||||||
fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
|
|
||||||
// map is a hashmap with String keys and Progress values.
|
|
||||||
// map = { "variables1": Complete, "from_str": None, ... }
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
|
|
||||||
let mut count = 0;
|
|
||||||
for map in collection {
|
|
||||||
for val in map.values() {
|
|
||||||
if val == &value {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
count
|
|
||||||
}
|
|
||||||
|
|
||||||
fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
|
|
||||||
// collection is a slice of hashmaps.
|
|
||||||
// collection = [{ "variables1": Complete, "from_str": None, ... },
|
|
||||||
// { "variables2": Complete, ... }, ... ]
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
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> {
|
|
||||||
use Progress::*;
|
|
||||||
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
map.insert(String::from("variables1"), Complete);
|
|
||||||
map.insert(String::from("functions1"), Complete);
|
|
||||||
map.insert(String::from("hashmap1"), Complete);
|
|
||||||
map.insert(String::from("arc1"), Some);
|
|
||||||
map.insert(String::from("as_ref_mut"), None);
|
|
||||||
map.insert(String::from("from_str"), None);
|
|
||||||
|
|
||||||
map
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_vec_map() -> Vec<HashMap<String, Progress>> {
|
|
||||||
use Progress::*;
|
|
||||||
|
|
||||||
let map = get_map();
|
|
||||||
|
|
||||||
let mut other = HashMap::new();
|
|
||||||
other.insert(String::from("variables2"), Complete);
|
|
||||||
other.insert(String::from("functions2"), Complete);
|
|
||||||
other.insert(String::from("if1"), Complete);
|
|
||||||
other.insert(String::from("from_into"), None);
|
|
||||||
other.insert(String::from("try_from_into"), None);
|
|
||||||
|
|
||||||
vec![map, other]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Lifetimes
|
|
||||||
|
|
||||||
Lifetimes tell the compiler how to check whether references live long
|
|
||||||
enough to be valid in any given situation. For example lifetimes say
|
|
||||||
"make sure parameter 'a' lives as long as parameter 'b' so that the return
|
|
||||||
value is valid".
|
|
||||||
|
|
||||||
They are only necessary on borrows, i.e. references,
|
|
||||||
since copied parameters or moves are owned in their scope and cannot
|
|
||||||
be referenced outside. Lifetimes mean that calling code of e.g. functions
|
|
||||||
can be checked to make sure their arguments are valid. Lifetimes are
|
|
||||||
restrictive of their callers.
|
|
||||||
|
|
||||||
If you'd like to learn more about lifetime annotations, the
|
|
||||||
[lifetimekata](https://tfpk.github.io/lifetimekata/) project
|
|
||||||
has a similar style of exercises to Rustlings, but is all about
|
|
||||||
learning to write lifetime annotations.
|
|
||||||
|
|
||||||
## Further information
|
|
||||||
|
|
||||||
- [Lifetimes (in Rust By Example)](https://doc.rust-lang.org/stable/rust-by-example/scope/lifetime.html)
|
|
||||||
- [Validating References with Lifetimes](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html)
|
|
|
@ -1,27 +0,0 @@
|
||||||
// lifetimes1.rs
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
// 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?
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn longest(x: &str, y: &str) -> &str {
|
|
||||||
if x.len() > y.len() {
|
|
||||||
x
|
|
||||||
} else {
|
|
||||||
y
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let string1 = String::from("abcd");
|
|
||||||
let string2 = "xyz";
|
|
||||||
|
|
||||||
let result = longest(string1.as_str(), string2);
|
|
||||||
println!("The longest string is '{}'", result);
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
// lifetimes2.rs
|
|
||||||
//
|
|
||||||
// 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 {
|
|
||||||
if x.len() > y.len() {
|
|
||||||
x
|
|
||||||
} else {
|
|
||||||
y
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let string1 = String::from("long string is long");
|
|
||||||
let result;
|
|
||||||
{
|
|
||||||
let string2 = String::from("xyz");
|
|
||||||
result = longest(string1.as_str(), string2.as_str());
|
|
||||||
}
|
|
||||||
println!("The longest string is '{}'", result);
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
// lifetimes3.rs
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
|
|
||||||
struct Book {
|
|
||||||
author: &str,
|
|
||||||
title: &str,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let name = String::from("Jill Smith");
|
|
||||||
let title = String::from("Fish Flying");
|
|
||||||
let book = Book { author: &name, title: &title };
|
|
||||||
|
|
||||||
println!("{} by {}", book.title, book.author);
|
|
||||||
}
|
|
|
@ -1,14 +1,10 @@
|
||||||
# Macros
|
### Macros
|
||||||
|
|
||||||
Rust's macro system is very powerful, but also kind of difficult to wrap your
|
Rust's macro system is very powerful, but also kind of difficult to wrap your
|
||||||
head around. We're not going to teach you how to write your own fully-featured
|
head around. We're not going to teach you how to write your own fully-featured
|
||||||
macros. Instead, we'll show you how to use and create them.
|
modules, instead we'll show you how to use and create them.
|
||||||
|
|
||||||
If you'd like to learn more about writing your own macros, the
|
#### Book Sections
|
||||||
[macrokata](https://github.com/tfpk/macrokata) project has a similar style
|
|
||||||
of exercises to Rustlings, but is all about learning to write Macros.
|
|
||||||
|
|
||||||
## Further information
|
- [Macros](https://doc.rust-lang.org/stable/book/ch19-06-macros.html)
|
||||||
|
- [The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html)
|
||||||
- [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html)
|
|
||||||
- [The Little Book of Rust Macros](https://veykril.github.io/tlborm/)
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
// macros1.rs
|
// macros1.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// Execute `rustlings hint macros1` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
macro_rules! my_macro {
|
macro_rules! my_macro {
|
||||||
() => {
|
() => {
|
||||||
|
@ -14,3 +10,55 @@ macro_rules! my_macro {
|
||||||
fn main() {
|
fn main() {
|
||||||
my_macro();
|
my_macro();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// When you call a macro, you need to add something special compared to a
|
||||||
|
// regular function call. If you're stuck, take a look at what's inside
|
||||||
|
// `my_macro`.
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
// macros2.rs
|
// macros2.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// Execute `rustlings hint macros2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
my_macro!();
|
my_macro!();
|
||||||
|
@ -14,3 +10,64 @@ macro_rules! my_macro {
|
||||||
println!("Check out my macro!");
|
println!("Check out my macro!");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Macros don't quite play by the same rules as the rest of Rust, in terms of
|
||||||
|
// what's available where.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Unlike other things in Rust, the order of "where you define a macro" versus
|
||||||
|
// "where you use it" actually matters.
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
// macros3.rs
|
// macros3.rs
|
||||||
//
|
// Make me compile, without taking the macro out of the module! Scroll down for hints :)
|
||||||
// Make me compile, without taking the macro out of the module!
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint macros3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
mod macros {
|
mod macros {
|
||||||
macro_rules! my_macro {
|
macro_rules! my_macro {
|
||||||
|
@ -18,3 +12,64 @@ mod macros {
|
||||||
fn main() {
|
fn main() {
|
||||||
my_macro!();
|
my_macro!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// In order to use a macro outside of its module, you need to do something
|
||||||
|
// special to the module to lift the macro out into its parent.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The same trick also works on "extern crate" statements for crates that have
|
||||||
|
// exported macros, if you've seen any of those around.
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
// macros4.rs
|
// macros4.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
macro_rules! my_macro {
|
macro_rules! my_macro {
|
||||||
() => {
|
() => {
|
||||||
println!("Check out my macro!");
|
println!("Check out my macro!");
|
||||||
|
@ -19,3 +14,64 @@ fn main() {
|
||||||
my_macro!();
|
my_macro!();
|
||||||
my_macro!(7777);
|
my_macro!(7777);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// You only need to add a single character to make this compile.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The way macros are written, it wants to see something between each
|
||||||
|
// "macro arm", so it can separate them.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Modules
|
### Modules
|
||||||
|
|
||||||
In this section we'll give you an introduction to Rust's module system.
|
In this section we'll give you an introduction to Rust's module system.
|
||||||
|
|
||||||
## Further information
|
#### Book Sections
|
||||||
|
|
||||||
- [The Module System](https://doc.rust-lang.org/book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html)
|
- [The Module System](https://doc.rust-lang.org/stable/book/ch07-02-defining-modules-to-control-scope-and-privacy.html)
|
||||||
|
|
|
@ -1,18 +1,8 @@
|
||||||
// modules1.rs
|
// modules1.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// 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!
|
|
||||||
fn get_secret_recipe() -> String {
|
|
||||||
String::from("Ginger")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_sausage() {
|
fn make_sausage() {
|
||||||
get_secret_recipe();
|
|
||||||
println!("sausage!");
|
println!("sausage!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,3 +10,34 @@ mod sausage_factory {
|
||||||
fn main() {
|
fn main() {
|
||||||
sausage_factory::make_sausage();
|
sausage_factory::make_sausage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Everything is private in Rust by default-- but there's a keyword we can use
|
||||||
|
// to make something public! The compiler error should point to the thing that
|
||||||
|
// needs to be public.
|
||||||
|
|
|
@ -1,18 +1,9 @@
|
||||||
// modules2.rs
|
// modules2.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// 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
|
|
||||||
// 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
|
use self::fruits::PEAR as fruit;
|
||||||
use self::fruits::PEAR as ???
|
use self::veggies::CUCUMBER as veggie;
|
||||||
use self::veggies::CUCUMBER as ???
|
|
||||||
|
|
||||||
mod fruits {
|
mod fruits {
|
||||||
pub const PEAR: &'static str = "Pear";
|
pub const PEAR: &'static str = "Pear";
|
||||||
|
@ -26,9 +17,29 @@ mod delicious_snacks {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!(
|
println!("favorite snacks: {} and {}",
|
||||||
"favorite snacks: {} and {}",
|
|
||||||
delicious_snacks::fruit,
|
delicious_snacks::fruit,
|
||||||
delicious_snacks::veggie
|
delicious_snacks::veggie);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The delicious_snacks module is trying to present an external
|
||||||
|
// interface (the `fruit` and `veggie` constants) that is different than
|
||||||
|
// its internal structure (the `fruits` and `veggies` modules and
|
||||||
|
// associated constants). It's almost there except for one keyword missing for
|
||||||
|
// each constant.
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
// modules3.rs
|
|
||||||
//
|
|
||||||
// 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: Complete this use statement
|
|
||||||
use ???
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
match SystemTime::now().duration_since(UNIX_EPOCH) {
|
|
||||||
Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()),
|
|
||||||
Err(_) => panic!("SystemTime before UNIX EPOCH!"),
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Move Semantics
|
### Move Semantics
|
||||||
|
|
||||||
These exercises are adapted from [pnkfelix](https://github.com/pnkfelix)'s [Rust Tutorial](https://pnkfelix.github.io/rust-examples-icfp2014/) -- Thank you Felix!!!
|
These exercises are adapted from [pnkfelix](https://github.com/pnkfelix)'s [Rust Tutorial](https://pnkfelix.github.io/rust-examples-icfp2014/) -- Thank you Felix!!!
|
||||||
|
|
||||||
## Further information
|
#### Book Sections
|
||||||
|
|
||||||
For this section, the book links are especially important.
|
For this section, the book links are especially important.
|
||||||
|
|
||||||
- [Ownership](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html)
|
- [Ownership](https://doc.rust-lang.org/stable/book/ch04-01-what-is-ownership.html)
|
||||||
- [Reference and borrowing](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html)
|
- [Reference and borrowing](https://doc.rust-lang.org/stable/book/ch04-02-references-and-borrowing.html)
|
||||||
|
|
|
@ -1,23 +1,43 @@
|
||||||
// move_semantics1.rs
|
// move_semantics1.rs
|
||||||
//
|
// Make me compile! Scroll down for hints :)
|
||||||
// Execute `rustlings hint move_semantics1` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = vec![22, 44, 66];
|
let vec0 = Vec::new();
|
||||||
|
|
||||||
let vec1 = fill_vec(vec0);
|
let vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
|
|
||||||
|
vec1.push(88);
|
||||||
|
|
||||||
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||||
let vec = vec;
|
let mut vec = vec;
|
||||||
|
|
||||||
vec.push(88);
|
vec.push(22);
|
||||||
|
vec.push(44);
|
||||||
|
vec.push(66);
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// So you've got the "cannot borrow immutable local variable `vec1` as mutable" error on line 11,
|
||||||
|
// right? The fix for this is going to be adding one keyword, and the addition is NOT on line 11
|
||||||
|
// where the error is.
|
||||||
|
|
|
@ -1,26 +1,54 @@
|
||||||
// move_semantics2.rs
|
// move_semantics2.rs
|
||||||
//
|
// Make me compile without changing line 10! Scroll down for hints :)
|
||||||
// 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() {
|
fn main() {
|
||||||
let vec0 = vec![22, 44, 66];
|
let vec0 = Vec::new();
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
assert_eq!(vec0, vec![22, 44, 66]);
|
// Do not change the following line!
|
||||||
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);
|
||||||
|
|
||||||
|
vec1.push(88);
|
||||||
|
|
||||||
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||||
let mut vec = vec;
|
let mut vec = vec;
|
||||||
|
|
||||||
vec.push(88);
|
vec.push(22);
|
||||||
|
vec.push(44);
|
||||||
|
vec.push(66);
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// So `vec0` is being *moved* into the function `fill_vec` when we call it on
|
||||||
|
// line 7, which means it gets dropped at the end of `fill_vec`, which means we
|
||||||
|
// can't use `vec0` again on line 10 (or anywhere else in `main` after the
|
||||||
|
// `fill_vec` call for that matter). We could fix this in a few ways, try them
|
||||||
|
// all!
|
||||||
|
// 1. Make another, separate version of the data that's in `vec0` and pass that
|
||||||
|
// to `fill_vec` instead.
|
||||||
|
// 2. Make `fill_vec` borrow its argument instead of taking ownership of it,
|
||||||
|
// and then copy the data within the function in order to return an owned
|
||||||
|
// `Vec<i32>`
|
||||||
|
// 3. Make `fill_vec` *mutably* borrow its argument (which will need to be
|
||||||
|
// mutable), modify it directly, then not return anything. Then you can get rid
|
||||||
|
// of `vec1` entirely -- note that this will change what gets printed by the
|
||||||
|
// first `println!`
|
||||||
|
|
|
@ -1,24 +1,46 @@
|
||||||
// move_semantics3.rs
|
// move_semantics3.rs
|
||||||
//
|
// Make me compile without adding new lines-- just changing existing lines!
|
||||||
// Make me compile without adding new lines -- just changing existing lines! (no
|
// (no lines with multiple semicolons necessary!)
|
||||||
// lines with multiple semicolons necessary!)
|
// Scroll down for hints :)
|
||||||
//
|
|
||||||
// Execute `rustlings hint move_semantics3` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = vec![22, 44, 66];
|
let vec0 = Vec::new();
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
|
|
||||||
|
vec1.push(88);
|
||||||
|
|
||||||
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||||
vec.push(88);
|
vec.push(22);
|
||||||
|
vec.push(44);
|
||||||
|
vec.push(66);
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The difference between this one and the previous ones is that the first line
|
||||||
|
// of `fn fill_vec` that had `let mut vec = vec;` is no longer there. You can,
|
||||||
|
// instead of adding that line back, add `mut` in one place that will change
|
||||||
|
// an existing binding to be a mutable binding instead of an immutable one :)
|
||||||
|
|
|
@ -1,29 +1,49 @@
|
||||||
// move_semantics4.rs
|
// move_semantics4.rs
|
||||||
//
|
// Refactor this code so that instead of having `vec0` and creating the vector
|
||||||
// Refactor this code so that instead of passing `vec0` into the `fill_vec`
|
// in `fn main`, we instead create it within `fn fill_vec` and transfer the
|
||||||
// function, the Vector gets created in the function itself and passed back to
|
// freshly created vector from fill_vec to its caller. Scroll for hints!
|
||||||
// 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];
|
let vec0 = Vec::new();
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
|
|
||||||
|
vec1.push(88);
|
||||||
|
|
||||||
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// `fill_vec()` no longer takes `vec: Vec<i32>` as argument - don't change this!
|
// `fill_vec()` no longer take `vec: Vec<i32>` as argument
|
||||||
fn fill_vec() -> Vec<i32> {
|
fn fill_vec() -> Vec<i32> {
|
||||||
// Instead, let's create and fill the Vec in here - how do you do that?
|
|
||||||
let mut vec = vec;
|
let mut vec = vec;
|
||||||
|
|
||||||
vec.push(88);
|
vec.push(22);
|
||||||
|
vec.push(44);
|
||||||
|
vec.push(66);
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Stop reading whenever you feel like you have enough direction :) Or try
|
||||||
|
// doing one step and then fixing the compiler errors that result!
|
||||||
|
// So the end goal is to:
|
||||||
|
// - get rid of the first line in main that creates the new vector
|
||||||
|
// - so then `vec0` doesn't exist, so we can't pass it to `fill_vec`
|
||||||
|
// - we don't want to pass anything to `fill_vec`, so its signature should
|
||||||
|
// reflect that it does not take any arguments
|
||||||
|
// - since we're not creating a new vec in `main` anymore, we need to create
|
||||||
|
// a new vec in `fill_vec`, similarly to the way we did in `main`
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
// move_semantics5.rs
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn main() {
|
|
||||||
let mut x = 100;
|
|
||||||
let y = &mut x;
|
|
||||||
let z = &mut x;
|
|
||||||
*y += 100;
|
|
||||||
*z += 1000;
|
|
||||||
assert_eq!(x, 1200);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
// move_semantics6.rs
|
|
||||||
//
|
|
||||||
// You can't change anything except adding or removing references.
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint move_semantics6` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let data = "Rust is great!".to_string();
|
|
||||||
|
|
||||||
get_char(data);
|
|
||||||
|
|
||||||
string_uppercase(&data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should not take ownership
|
|
||||||
fn get_char(data: String) -> char {
|
|
||||||
data.chars().last().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should take ownership
|
|
||||||
fn string_uppercase(mut data: &String) {
|
|
||||||
data = &data.to_uppercase();
|
|
||||||
|
|
||||||
println!("{}", data);
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
# Options
|
|
||||||
|
|
||||||
Type Option represents an optional value: every Option is either Some and contains a value, or None, and does not.
|
|
||||||
Option types are very common in Rust code, as they have a number of uses:
|
|
||||||
|
|
||||||
- Initial values
|
|
||||||
- Return values for functions that are not defined over their entire input range (partial functions)
|
|
||||||
- Return value for otherwise reporting simple errors, where None is returned on error
|
|
||||||
- Optional struct fields
|
|
||||||
- Struct fields that can be loaned or "taken"
|
|
||||||
- Optional function arguments
|
|
||||||
- Nullable pointers
|
|
||||||
- Swapping things out of difficult situations
|
|
||||||
|
|
||||||
## Further Information
|
|
||||||
|
|
||||||
- [Option Enum Format](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-enum-definitions)
|
|
||||||
- [Option Module Documentation](https://doc.rust-lang.org/std/option/)
|
|
||||||
- [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)
|
|
||||||
- [while let](https://doc.rust-lang.org/rust-by-example/flow_control/while_let.html)
|
|
|
@ -1,39 +0,0 @@
|
||||||
// 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.
|
|
||||||
// If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them
|
|
||||||
// all, so there'll be no more left :(
|
|
||||||
fn maybe_icecream(time_of_day: u16) -> Option<u16> {
|
|
||||||
// We use the 24-hour system here, so 10PM is a value of 22 and 12AM is a
|
|
||||||
// value of 0 The Option output should gracefully handle cases where
|
|
||||||
// time_of_day > 23.
|
|
||||||
// TODO: Complete the function body - remember to return an Option!
|
|
||||||
???
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn check_icecream() {
|
|
||||||
assert_eq!(maybe_icecream(9), Some(5));
|
|
||||||
assert_eq!(maybe_icecream(10), Some(5));
|
|
||||||
assert_eq!(maybe_icecream(23), Some(0));
|
|
||||||
assert_eq!(maybe_icecream(22), Some(0));
|
|
||||||
assert_eq!(maybe_icecream(25), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn raw_value() {
|
|
||||||
// TODO: Fix this test. How do you get at the value contained in the
|
|
||||||
// Option?
|
|
||||||
let icecreams = maybe_icecream(12);
|
|
||||||
assert_eq!(icecreams, 5);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
// options2.rs
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint options2` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
#[test]
|
|
||||||
fn simple_option() {
|
|
||||||
let target = "rustlings";
|
|
||||||
let optional_target = Some(target);
|
|
||||||
|
|
||||||
// TODO: Make this an if let statement whose value is "Some" type
|
|
||||||
word = optional_target {
|
|
||||||
assert_eq!(word, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn layered_option() {
|
|
||||||
let range = 10;
|
|
||||||
let mut optional_integers: Vec<Option<i8>> = vec![None];
|
|
||||||
|
|
||||||
for i in 1..(range + 1) {
|
|
||||||
optional_integers.push(Some(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut cursor = range;
|
|
||||||
|
|
||||||
// TODO: make this a while let statement - remember that vector.pop also
|
|
||||||
// adds another layer of Option<T>. You can stack `Option<T>`s into
|
|
||||||
// while let and if let.
|
|
||||||
integer = optional_integers.pop() {
|
|
||||||
assert_eq!(integer, cursor);
|
|
||||||
cursor -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(cursor, 0);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
// options3.rs
|
|
||||||
//
|
|
||||||
// Execute `rustlings hint options3` or use the `hint` watch subcommand for a
|
|
||||||
// hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
struct Point {
|
|
||||||
x: i32,
|
|
||||||
y: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let y: Option<Point> = Some(Point { x: 100, y: 200 });
|
|
||||||
|
|
||||||
match y {
|
|
||||||
Some(p) => println!("Co-ordinates are {},{} ", p.x, p.y),
|
|
||||||
_ => panic!("no match!"),
|
|
||||||
}
|
|
||||||
y; // Fix without deleting this line.
|
|
||||||
}
|
|
|
@ -1,9 +1,8 @@
|
||||||
# Primitive Types
|
### Primitive Types
|
||||||
|
|
||||||
Rust has a couple of basic types that are directly implemented into the
|
Rust has a couple of basic types that are directly implemented into the
|
||||||
compiler. In this section, we'll go through the most important ones.
|
compiler. In this section, we'll go through the most important ones.
|
||||||
|
|
||||||
## Further information
|
#### Book Sections
|
||||||
|
|
||||||
- [Data Types](https://doc.rust-lang.org/stable/book/ch03-02-data-types.html)
|
- [Data Types](https://doc.rust-lang.org/stable/book/ch03-02-data-types.html)
|
||||||
- [The Slice Type](https://doc.rust-lang.org/stable/book/ch04-03-slices.html)
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
// primitive_types1.rs
|
// primitive_types1.rs
|
||||||
//
|
// Fill in the rest of the line that has code missing!
|
||||||
// Fill in the rest of the line that has code missing! No hints, there's no
|
// No hints, there's no tricks, just get used to typing these :)
|
||||||
// tricks, just get used to typing these :)
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Booleans (`bool`)
|
// Booleans (`bool`)
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
// primitive_types2.rs
|
// primitive_types2.rs
|
||||||
//
|
// Fill in the rest of the line that has code missing!
|
||||||
// Fill in the rest of the line that has code missing! No hints, there's no
|
// No hints, there's no tricks, just get used to typing these :)
|
||||||
// tricks, just get used to typing these :)
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Characters (`char`)
|
// Characters (`char`)
|
||||||
|
|
||||||
// Note the _single_ quotes, these are different from the double quotes
|
|
||||||
// you've been seeing around.
|
|
||||||
let my_first_initial = 'C';
|
let my_first_initial = 'C';
|
||||||
if my_first_initial.is_alphabetic() {
|
if my_first_initial.is_alphabetic() {
|
||||||
println!("Alphabetical!");
|
println!("Alphabetical!");
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
// primitive_types3.rs
|
// primitive_types3.rs
|
||||||
//
|
|
||||||
// Create an array with at least 100 elements in it where the ??? is.
|
// Create an array with at least 100 elements in it where the ??? is.
|
||||||
//
|
// Scroll down for hints!
|
||||||
// Execute `rustlings hint primitive_types3` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = ???
|
let a = ???
|
||||||
|
@ -14,6 +9,39 @@ fn main() {
|
||||||
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")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// There's a shorthand to initialize Arrays with a certain size that does not
|
||||||
|
// require you to type in 100 items (but you certainly can if you want!).
|
||||||
|
// For example, you can do:
|
||||||
|
// let array = ["Are we there yet?"; 10];
|
||||||
|
|
||||||
|
// Bonus: what are some other things you could have that would return true
|
||||||
|
// for `a.len() >= 100`?
|
||||||
|
|
|
@ -1,17 +1,49 @@
|
||||||
// primitive_types4.rs
|
// primitive_types4.rs
|
||||||
//
|
// Get a slice out of Array a where the ??? is so that the `if` statement
|
||||||
// Get a slice out of Array a where the ??? is so that the test passes.
|
// returns true. Scroll down for hints!!
|
||||||
//
|
|
||||||
// Execute `rustlings hint primitive_types4` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
fn main() {
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn slice_out_of_array() {
|
|
||||||
let a = [1, 2, 3, 4, 5];
|
let a = [1, 2, 3, 4, 5];
|
||||||
|
|
||||||
let nice_slice = ???
|
let nice_slice = ???
|
||||||
|
|
||||||
assert_eq!([2, 3, 4], nice_slice)
|
if nice_slice == [2, 3, 4] {
|
||||||
|
println!("Nice slice!");
|
||||||
|
} else {
|
||||||
|
println!("Not quite what I was expecting... I see: {:?}", nice_slice);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Take a look at the Understanding Ownership -> Slices -> Other Slices section of the book:
|
||||||
|
// https://doc.rust-lang.org/book/ch04-03-slices.html
|
||||||
|
// and use the starting and ending indices of the items in the Array
|
||||||
|
// that you want to end up in the slice.
|
||||||
|
|
||||||
|
// If you're curious why the right hand of the `==` comparison does not
|
||||||
|
// have an ampersand for a reference since the left hand side is a
|
||||||
|
// reference, take a look at the Deref coercions section of the book:
|
||||||
|
// https://doc.rust-lang.org/book/ch15-02-deref.html
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
// primitive_types5.rs
|
// primitive_types5.rs
|
||||||
//
|
|
||||||
// Destructure the `cat` tuple so that the println will work.
|
// Destructure the `cat` tuple so that the println will work.
|
||||||
//
|
// Scroll down for hints!
|
||||||
// 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);
|
||||||
|
@ -13,3 +8,38 @@ fn main() {
|
||||||
|
|
||||||
println!("{} is {} years old.", name, age);
|
println!("{} is {} years old.", name, age);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Take a look at the Data Types -> The Tuple Type section of the book:
|
||||||
|
// https://doc.rust-lang.org/stable/book/ch03-02-data-types.html#the-tuple-type
|
||||||
|
// Particularly the part about destructuring (second to last example in the section).
|
||||||
|
// You'll need to make a pattern to bind `name` and `age` to the appropriate parts
|
||||||
|
// of the tuple. You can do it!!
|
||||||
|
|
|
@ -1,19 +1,45 @@
|
||||||
// primitive_types6.rs
|
// primitive_types6.rs
|
||||||
//
|
// Use a tuple index to access the second element of `numbers`.
|
||||||
// Use a tuple index to access the second element of `numbers`. You can put the
|
// You can put this right into the `println!` where the ??? is.
|
||||||
// expression for the second element where ??? is so that the test passes.
|
// Scroll down for hints!
|
||||||
//
|
|
||||||
// Execute `rustlings hint primitive_types6` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
fn main() {
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn indexing_tuple() {
|
|
||||||
let numbers = (1, 2, 3);
|
let numbers = (1, 2, 3);
|
||||||
// Replace below ??? with the tuple indexing syntax.
|
println!("The second number is {}", ???);
|
||||||
let second = ???;
|
|
||||||
|
|
||||||
assert_eq!(2, second,
|
|
||||||
"This is not the 2nd number in the tuple!")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// While you could use a destructuring `let` for the tuple here, try
|
||||||
|
// indexing into it instead, as explained in the last example of the
|
||||||
|
// Data Types -> The Tuple Type section of the book:
|
||||||
|
// https://doc.rust-lang.org/stable/book/ch03-02-data-types.html#the-tuple-type
|
||||||
|
// Now you have another tool in your toolbox!
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
// quiz1.rs
|
|
||||||
//
|
|
||||||
// This is a quiz for the following sections:
|
|
||||||
// - Variables
|
|
||||||
// - Functions
|
|
||||||
// - If
|
|
||||||
//
|
|
||||||
// Mary is buying apples. The price of an apple is calculated as follows:
|
|
||||||
// - An apple costs 2 rustbucks.
|
|
||||||
// - If Mary buys more than 40 apples, each apple only costs 1 rustbuck!
|
|
||||||
// Write a function that calculates the price of an order of apples given the
|
|
||||||
// quantity bought.
|
|
||||||
//
|
|
||||||
// No hints this time ;)
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
// Put your function here!
|
|
||||||
// fn calculate_price_of_apples {
|
|
||||||
|
|
||||||
// Don't modify this function!
|
|
||||||
#[test]
|
|
||||||
fn verify_test() {
|
|
||||||
let price1 = calculate_price_of_apples(35);
|
|
||||||
let price2 = calculate_price_of_apples(40);
|
|
||||||
let price3 = calculate_price_of_apples(41);
|
|
||||||
let price4 = calculate_price_of_apples(65);
|
|
||||||
|
|
||||||
assert_eq!(70, price1);
|
|
||||||
assert_eq!(80, price2);
|
|
||||||
assert_eq!(41, price3);
|
|
||||||
assert_eq!(65, price4);
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue