Compare commits
132 Commits
all-contri
...
main
Author | SHA1 | Date |
---|---|---|
liv | 06f865307f | |
allcontributors[bot] | f86a3c5ddc | |
allcontributors[bot] | 666857dc4e | |
liv | 1552822404 | |
Ofir Lauber | 83ac243c00 | |
liv | 9a743f80c5 | |
liv | 170aaabe9b | |
liv | ef122c9973 | |
allcontributors[bot] | 8e8c74c6c0 | |
allcontributors[bot] | a38840ae92 | |
liv | 2e48fe9cc7 | |
liv | 3b451e4ab1 | |
allcontributors[bot] | 746180b153 | |
allcontributors[bot] | 62415f758b | |
liv | 0807353bf0 | |
liv | a808cf71a3 | |
liv | 8716558696 | |
Luka Krmpotic | eb84eaf151 | |
Jurglic | a0699bd917 | |
Jon Erling Hustadnes | 0ee9c5b776 | |
liv | 51c8da06b0 | |
allcontributors[bot] | 95640cba23 | |
allcontributors[bot] | 241889159a | |
liv | edb8813cc7 | |
Charles Hall | 4a1290cb66 | |
liv | d52ce2d354 | |
allcontributors[bot] | b33ef03ac6 | |
allcontributors[bot] | dceba07e82 | |
liv | e12504a61d | |
liv | 9de22c9afa | |
allcontributors[bot] | e17d603201 | |
allcontributors[bot] | 47fbd6d160 | |
liv | 9dc8f13925 | |
Oscar Bonilla | 33a4f4e454 | |
Jon Erling Hustadnes | a5e4133516 | |
liv | 4d04aad890 | |
liv | 847b57423f | |
liv | 58cabf2ebd | |
liv | ae28d2fa2d | |
liv | de45998f69 | |
liv | 0d36050b36 | |
liv | f31a18429b | |
liv | 3ad30308ec | |
liv | 6c0c397507 | |
liv | 42da308140 | |
allcontributors[bot] | 680a32a85c | |
allcontributors[bot] | 951dde4e94 | |
liv | 14fbdd20ac | |
liv | ad0fad4218 | |
liv | a5fe578e79 | |
allcontributors[bot] | d5525794f8 | |
allcontributors[bot] | 3f7ef6fe33 | |
liv | 992e5163d3 | |
liv | d03f624357 | |
allcontributors[bot] | b547321868 | |
allcontributors[bot] | 9a0e5bd003 | |
liv | c57ad35e5b | |
liv | f7ef198e3a | |
allcontributors[bot] | fcac2b553c | |
allcontributors[bot] | e8c2d27b4a | |
liv | 630cbf8f85 | |
liv | 0aa9418736 | |
liv | abc3013096 | |
liv | 51e237d5f9 | |
liv | 6eb9bde786 | |
allcontributors[bot] | dce89aefb9 | |
allcontributors[bot] | 47e14cff8d | |
liv | 4d9b68b377 | |
liv | a8f4994935 | |
allcontributors[bot] | 8ca60f2cbb | |
allcontributors[bot] | bb550497d5 | |
liv | 849e4a3647 | |
liv | c177507db3 | |
liv | a09a0c47ae | |
liv | a26c396335 | |
allcontributors[bot] | 4aa5ca2818 | |
allcontributors[bot] | 27881a83d4 | |
liv | 6378c2a81f | |
liv | 45cadcf020 | |
allcontributors[bot] | 7d53abdb0a | |
allcontributors[bot] | a059ded709 | |
liv | 4de3b4a635 | |
liv | 64162d3a24 | |
liv | 626e2749a6 | |
liv | b39d896db7 | |
allcontributors[bot] | 4a9699226a | |
allcontributors[bot] | 11f4ec93ac | |
liv | e57797a8ff | |
liv | 0b7975b195 | |
mo8it | 362318a6e0 | |
mo8it | 5a93f2a4f1 | |
x10an14 | e7bdc83a8f | |
x10an14 | 60b8487600 | |
x10an14 | 013f22c89c | |
liv | 2d1da2ab57 | |
mo8it | 9c0581bc0f | |
liv | d79984dbda | |
liv | c2eaa8f019 | |
liv | 6c517199bf | |
allcontributors[bot] | d258c30406 | |
allcontributors[bot] | 7bb69f8641 | |
liv | c1051f3f52 | |
mo8it | 193b600382 | |
mo8it | 16936d95d1 | |
mo8it | 64224d3918 | |
mo8it | c0b8af2c42 | |
mo8it | c655612d2d | |
mo8it | 3cc9be0d11 | |
mo8it | 571bab20c1 | |
liv | c663f06669 | |
allcontributors[bot] | 77f0e177e6 | |
allcontributors[bot] | e7ad540618 | |
liv | 38b4327f41 | |
Ivan Vasiunyk | fa0463b3b2 | |
Roi Gabay | af76794627 | |
liv | 464cb5566d | |
allcontributors[bot] | d670847308 | |
allcontributors[bot] | 33a45d0f89 | |
liv | da395fed20 | |
Kevin C | ad1c29c512 | |
Mate Kovacs | 720f33eee6 | |
liv | 64035f766f | |
Joshua Carlson | 828e724659 | |
Gabor Szabo | 7f9f897945 | |
Yamila Moreno | 662e5bddd7 | |
Will Hack | 37cdea9183 | |
Will Hack | 0ab781c7a7 | |
Will Hack | b99c7b8c37 | |
Mohammed Sadiq | c5231f0ce3 | |
bean5 | 15ae83f868 | |
bean5 | e6b1ef2049 | |
J.c | 8cb5cba775 |
|
@ -2271,6 +2271,168 @@
|
||||||
"contributions": [
|
"contributions": [
|
||||||
"content"
|
"content"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "shirts",
|
||||||
|
"name": "shirts",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/4952151?v=4",
|
||||||
|
"profile": "https://github.com/shirts",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "eLVas",
|
||||||
|
"name": "Ivan Vasiunyk",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/6797156?v=4",
|
||||||
|
"profile": "https://github.com/eLVas",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "mo8it",
|
||||||
|
"name": "Mo",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/76752051?v=4",
|
||||||
|
"profile": "https://mo8it.com",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "x10an14",
|
||||||
|
"name": "x10an14",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/710608?v=4",
|
||||||
|
"profile": "https://github.com/x10an14",
|
||||||
|
"contributions": [
|
||||||
|
"infra"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "gabay",
|
||||||
|
"name": "Roi Gabay",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/5773610?v=4",
|
||||||
|
"profile": "https://github.com/gabay",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "mkovaxx",
|
||||||
|
"name": "Máté Kovács",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/481354?v=4",
|
||||||
|
"profile": "https://github.com/mkovaxx",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "szabgab",
|
||||||
|
"name": "Gábor Szabó",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/48833?v=4",
|
||||||
|
"profile": "https://szabgab.com/",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "yamila-moreno",
|
||||||
|
"name": "Yamila Moreno",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/3340793?v=4",
|
||||||
|
"profile": "https://moduslaborandi.net",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "willhack",
|
||||||
|
"name": "Will Hack",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/18036720?v=4",
|
||||||
|
"profile": "https://github.com/willhack",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "bean5",
|
||||||
|
"name": "Michael",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/2052646?v=4",
|
||||||
|
"profile": "http://cancompute.tech",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "pksadiq",
|
||||||
|
"name": "Mohammed Sadiq",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/1289514?v=4",
|
||||||
|
"profile": "https://www.sadiqpk.org",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Jak-Ch-ll",
|
||||||
|
"name": "Jakob",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/56225668?v=4",
|
||||||
|
"profile": "https://github.com/Jak-Ch-ll",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "ob",
|
||||||
|
"name": "Oscar Bonilla",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/4950?v=4",
|
||||||
|
"profile": "http://oscarbonilla.com",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "husjon",
|
||||||
|
"name": "Jon Erling Hustadnes",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/554229?v=4",
|
||||||
|
"profile": "https://github.com/husjon",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "CobaltCause",
|
||||||
|
"name": "Charles Hall",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/7003738?v=4",
|
||||||
|
"profile": "https://github.com/CobaltCause",
|
||||||
|
"contributions": [
|
||||||
|
"infra"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "krmpotic",
|
||||||
|
"name": "Luka Krmpotić",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/10350645?v=4",
|
||||||
|
"profile": "https://github.com/krmpotic",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "jurglic",
|
||||||
|
"name": "Jurglic",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/112600?v=4",
|
||||||
|
"profile": "https://github.com/jurglic",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "OfirLauber",
|
||||||
|
"name": "Ofir Lauber",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/5631030?v=4",
|
||||||
|
"profile": "https://github.com/OfirLauber",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 8,
|
"contributorsPerLine": 8,
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Automatically Load nix devShell w/dotenv
|
||||||
|
use flake
|
|
@ -1,18 +0,0 @@
|
||||||
name: Lint
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: DavidAnson/markdownlint-cli2-action@v9
|
|
||||||
with:
|
|
||||||
globs: "exercises/**/*.md"
|
|
|
@ -10,13 +10,28 @@ env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
fmt:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Fetch & maybe update Cargo.lock
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
run: cargo fetch --locked
|
with:
|
||||||
- name: Build
|
components: rustfmt
|
||||||
run: cargo build --verbose
|
- uses: DavidAnson/markdownlint-cli2-action@v9
|
||||||
- name: Run tests
|
with:
|
||||||
run: cargo test --verbose
|
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
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
# 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
|
|
@ -12,6 +12,7 @@ rust-project.json
|
||||||
*.iml
|
*.iml
|
||||||
*.o
|
*.o
|
||||||
public/
|
public/
|
||||||
|
.direnv/
|
||||||
|
|
||||||
# Local Netlify folder
|
# Local Netlify folder
|
||||||
.netlify
|
.netlify
|
||||||
|
|
22
AUTHORS.md
22
AUTHORS.md
|
@ -322,6 +322,28 @@ authors.
|
||||||
</tr>
|
</tr>
|
||||||
<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/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>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
56
CHANGELOG.md
56
CHANGELOG.md
|
@ -1,3 +1,59 @@
|
||||||
|
<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>
|
<a name="5.5.1"></a>
|
||||||
## 5.5.1 (2023-05-17)
|
## 5.5.1 (2023-05-17)
|
||||||
|
|
||||||
|
|
|
@ -4,51 +4,74 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.0.2"
|
version = "0.7.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
|
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argh"
|
name = "anstream"
|
||||||
version = "0.1.10"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ab257697eb9496bf75526f0217b5ed64636a9cfafa78b8365c71bd283fcef93e"
|
checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argh_derive",
|
"anstyle",
|
||||||
"argh_shared",
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"utf8parse",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argh_derive"
|
name = "anstyle"
|
||||||
version = "0.1.10"
|
version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b382dbd3288e053331f03399e1db106c9fb0d8562ad62cb04859ae926f324fa6"
|
checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argh_shared",
|
"utf8parse",
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argh_shared"
|
name = "anstyle-query"
|
||||||
version = "0.1.10"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f"
|
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "assert_cmd"
|
name = "assert_cmd"
|
||||||
version = "0.11.1"
|
version = "2.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dc477793bd82ec39799b6f6b3df64938532fdf2ab0d49ef817eac65856a5a1e"
|
checksum = "88903cb14723e4d4003335bb7f8a14f27691649105346a0f0957466c096adfe6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"escargot",
|
"anstyle",
|
||||||
|
"bstr",
|
||||||
|
"doc-comment",
|
||||||
"predicates",
|
"predicates",
|
||||||
"predicates-core",
|
"predicates-core",
|
||||||
"predicates-tree",
|
"predicates-tree",
|
||||||
|
"wait-timeout",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -63,6 +86,17 @@ version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bstr"
|
||||||
|
version = "1.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
|
@ -76,23 +110,81 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console"
|
name = "clap"
|
||||||
version = "0.15.7"
|
version = "4.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
|
checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console"
|
||||||
|
version = "0.15.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"encode_unicode",
|
"encode_unicode",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"windows-sys 0.45.0",
|
"windows-sys 0.42.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "difference"
|
name = "difflib"
|
||||||
version = "2.0.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "doc-comment"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encode_unicode"
|
name = "encode_unicode"
|
||||||
|
@ -101,34 +193,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "escargot"
|
name = "equivalent"
|
||||||
version = "0.4.0"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ceb9adbf9874d5d028b5e4c5739d22b71988252b25c9c98fe7cf9738bee84597"
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
dependencies = [
|
|
||||||
"lazy_static",
|
|
||||||
"log",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.21"
|
version = "0.2.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153"
|
checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.45.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "float-cmp"
|
name = "float-cmp"
|
||||||
version = "0.8.0"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4"
|
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
@ -175,24 +261,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "home"
|
name = "hashbrown"
|
||||||
version = "0.5.5"
|
version = "0.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
|
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "home"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indicatif"
|
name = "indicatif"
|
||||||
version = "0.16.2"
|
version = "0.17.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b"
|
checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console",
|
"console",
|
||||||
"lazy_static",
|
"instant",
|
||||||
"number_prefix",
|
"number_prefix",
|
||||||
"regex",
|
"portable-atomic",
|
||||||
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -215,6 +324,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "instant"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iovec"
|
name = "iovec"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
|
@ -225,10 +343,19 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itertools"
|
||||||
version = "1.0.8"
|
version = "0.10.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
|
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel32-sys"
|
name = "kernel32-sys"
|
||||||
|
@ -254,21 +381,24 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.147"
|
version = "0.2.140"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.19"
|
version = "0.4.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "2.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
|
@ -315,9 +445,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "net2"
|
name = "net2"
|
||||||
version = "0.2.39"
|
version = "0.2.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac"
|
checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -364,13 +494,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "predicates"
|
name = "portable-atomic"
|
||||||
version = "1.0.8"
|
version = "1.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df"
|
checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "predicates"
|
||||||
|
version = "3.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09963355b9f467184c04017ced4a2ba2d75cbcb4e7462690d388233253d4b1a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"difference",
|
"anstyle",
|
||||||
|
"difflib",
|
||||||
"float-cmp",
|
"float-cmp",
|
||||||
|
"itertools",
|
||||||
"normalize-line-endings",
|
"normalize-line-endings",
|
||||||
"predicates-core",
|
"predicates-core",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -394,18 +532,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.64"
|
version = "1.0.53"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da"
|
checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.29"
|
version = "1.0.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
|
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -421,39 +559,33 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.9.1"
|
version = "1.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
|
checksum = "cce168fea28d3e05f158bda4576cf0c844d5045bc2cc3620fa0292ed5bb5814c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata",
|
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.3.3"
|
version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
|
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.7.4"
|
version = "0.6.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustlings"
|
name = "rustlings"
|
||||||
version = "5.5.1"
|
version = "5.6.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argh",
|
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
|
"clap",
|
||||||
"console",
|
"console",
|
||||||
"glob",
|
"glob",
|
||||||
"home",
|
"home",
|
||||||
|
@ -468,9 +600,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.14"
|
version = "1.0.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
|
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "same-file"
|
name = "same-file"
|
||||||
|
@ -483,35 +615,44 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.171"
|
version = "1.0.158"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
|
checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.171"
|
version = "1.0.158"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
|
checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.25",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.102"
|
version = "1.0.94"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed"
|
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.8"
|
version = "0.4.8"
|
||||||
|
@ -522,21 +663,16 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "strsim"
|
||||||
version = "1.0.109"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.25"
|
version = "2.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2"
|
checksum = "bcc02725fd69ab9f26eab07fad303e2497fad6fb9eba4f96c4d1687bdf704ad9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -551,18 +687,43 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.5.11"
|
version = "0.7.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "toml_edit"
|
||||||
version = "1.0.10"
|
version = "0.19.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
|
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
|
@ -570,6 +731,21 @@ version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wait-timeout"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.3.3"
|
version = "2.3.3"
|
||||||
|
@ -623,6 +799,21 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.42.2",
|
||||||
|
"windows_aarch64_msvc 0.42.2",
|
||||||
|
"windows_i686_gnu 0.42.2",
|
||||||
|
"windows_i686_msvc 0.42.2",
|
||||||
|
"windows_x86_64_gnu 0.42.2",
|
||||||
|
"windows_x86_64_gnullvm 0.42.2",
|
||||||
|
"windows_x86_64_msvc 0.42.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.45.0"
|
version = "0.45.0"
|
||||||
|
@ -638,7 +829,7 @@ version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets 0.48.1",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -658,17 +849,17 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.48.1"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm 0.48.0",
|
"windows_aarch64_gnullvm 0.48.5",
|
||||||
"windows_aarch64_msvc 0.48.0",
|
"windows_aarch64_msvc 0.48.5",
|
||||||
"windows_i686_gnu 0.48.0",
|
"windows_i686_gnu 0.48.5",
|
||||||
"windows_i686_msvc 0.48.0",
|
"windows_i686_msvc 0.48.5",
|
||||||
"windows_x86_64_gnu 0.48.0",
|
"windows_x86_64_gnu 0.48.5",
|
||||||
"windows_x86_64_gnullvm 0.48.0",
|
"windows_x86_64_gnullvm 0.48.5",
|
||||||
"windows_x86_64_msvc 0.48.0",
|
"windows_x86_64_msvc 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -679,9 +870,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.48.0"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
|
@ -691,9 +882,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.48.0"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
|
@ -703,9 +894,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.48.0"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
|
@ -715,9 +906,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.48.0"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
|
@ -727,9 +918,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.48.0"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
|
@ -739,9 +930,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.48.0"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
|
@ -751,9 +942,18 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.48.0"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.5.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ws2_32-sys"
|
name = "ws2_32-sys"
|
||||||
|
|
12
Cargo.toml
12
Cargo.toml
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rustlings"
|
name = "rustlings"
|
||||||
description = "Small exercises to get you used to reading and writing Rust code!"
|
description = "Small exercises to get you used to reading and writing Rust code!"
|
||||||
version = "5.5.1"
|
version = "5.6.1"
|
||||||
authors = [
|
authors = [
|
||||||
"Liv <mokou@fastmail.com>",
|
"Liv <mokou@fastmail.com>",
|
||||||
"Carol (Nichols || Goulding) <carol.nichols@gmail.com>",
|
"Carol (Nichols || Goulding) <carol.nichols@gmail.com>",
|
||||||
|
@ -9,22 +9,22 @@ authors = [
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
argh = "0.1"
|
indicatif = "0.17.6"
|
||||||
indicatif = "0.16"
|
|
||||||
console = "0.15"
|
console = "0.15"
|
||||||
notify = "4.0"
|
notify = "4.0"
|
||||||
toml = "0.5"
|
toml = "0.7.6"
|
||||||
regex = "1.5"
|
regex = "1.5"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0.81"
|
serde_json = "1.0.81"
|
||||||
home = "0.5.3"
|
home = "0.5.3"
|
||||||
glob = "0.3.0"
|
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 = "0.11.0"
|
assert_cmd = "2.0.12"
|
||||||
predicates = "1.0.1"
|
predicates = "3.0.3"
|
||||||
glob = "0.3.0"
|
glob = "0.3.0"
|
||||||
|
|
19
README.md
19
README.md
|
@ -18,7 +18,7 @@ Alternatively, for a first-time Rust learner, there are several other resources:
|
||||||
_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`._
|
_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.
|
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
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ Just run:
|
||||||
```bash
|
```bash
|
||||||
curl -L https://raw.githubusercontent.com/rust-lang/rustlings/main/install.sh | bash
|
curl -L https://raw.githubusercontent.com/rust-lang/rustlings/main/install.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
Or if you want it to be installed to a different path:
|
Or if you want it to be installed to a different path:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -40,8 +41,8 @@ This will install Rustlings and give you access to the `rustlings` command. Run
|
||||||
Basically: Clone the repository at the latest tag, finally run `nix develop` or `nix-shell`.
|
Basically: Clone the repository at the latest tag, finally run `nix develop` or `nix-shell`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.5.1)
|
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.6.1)
|
||||||
git clone -b 5.5.1 --depth 1 https://github.com/rust-lang/rustlings
|
git clone -b 5.6.1 --depth 1 https://github.com/rust-lang/rustlings
|
||||||
cd rustlings
|
cd rustlings
|
||||||
# if nix version > 2.3
|
# if nix version > 2.3
|
||||||
nix develop
|
nix develop
|
||||||
|
@ -78,8 +79,8 @@ If you get a permission denied message, you might have to exclude the directory
|
||||||
Basically: Clone the repository at the latest tag, run `cargo install --path .`.
|
Basically: Clone the repository at the latest tag, run `cargo install --path .`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.5.1)
|
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.6.1)
|
||||||
git clone -b 5.5.1 --depth 1 https://github.com/rust-lang/rustlings
|
git clone -b 5.6.1 --depth 1 https://github.com/rust-lang/rustlings
|
||||||
cd rustlings
|
cd rustlings
|
||||||
cargo install --force --path .
|
cargo install --force --path .
|
||||||
```
|
```
|
||||||
|
@ -172,12 +173,8 @@ Now you should be done!
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
See [CONTRIBUTING.md](./CONTRIBUTING.md).
|
See [CONTRIBUTING.md](https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
Development-focused discussion about Rustlings happens in the [**rustlings** stream](https://rust-lang.zulipchat.com/#narrow/stream/334454-rustlings)
|
|
||||||
on the [Rust Project Zulip](https://rust-lang.zulipchat.com). Feel free to start a new thread there
|
|
||||||
if you have ideas or suggestions!
|
|
||||||
|
|
||||||
## Contributors ✨
|
## Contributors ✨
|
||||||
|
|
||||||
Thanks goes to the wonderful people listed in [AUTHORS.md](./AUTHORS.md) 🎉
|
Thanks goes to the wonderful people listed in [AUTHORS.md](https://github.com/rust-lang/rustlings/blob/main/AUTHORS.md) 🎉
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
// clippy3.rs
|
// clippy3.rs
|
||||||
//
|
//
|
||||||
// Here's a couple more easy Clippy fixes, so you can see its utility.
|
// Here's a couple more easy Clippy fixes, so you can see its utility.
|
||||||
//
|
// No hints.
|
||||||
// Execute `rustlings hint clippy3` or use the `hint` watch subcommand for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mult_box() {
|
fn mut_box() {
|
||||||
let mut num: Box<u32> = Box::new(3);
|
let mut num: Box<u32> = Box::new(3);
|
||||||
num_sq(&mut num);
|
num_sq(&mut num);
|
||||||
assert_eq!(*num, 9);
|
assert_eq!(*num, 9);
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct State {
|
||||||
color: (u8, u8, u8),
|
color: (u8, u8, u8),
|
||||||
position: Point,
|
position: Point,
|
||||||
quit: bool,
|
quit: bool,
|
||||||
message: String
|
message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
|
@ -32,17 +32,18 @@ impl State {
|
||||||
self.quit = true;
|
self.quit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn echo(&mut self, s: String) { self.message = s }
|
fn echo(&mut self, s: String) {
|
||||||
|
self.message = s
|
||||||
|
}
|
||||||
|
|
||||||
fn move_position(&mut self, p: Point) {
|
fn move_position(&mut self, p: Point) {
|
||||||
self.position = p;
|
self.position = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, message: Message) {
|
fn process(&mut self, message: Message) {
|
||||||
// TODO: create a match expression to process the different message
|
// TODO: create a match expression to process the different message variants
|
||||||
// variants
|
// Remember: When passing a tuple as a function argument, you'll need extra parentheses:
|
||||||
// Remember: When passing a tuple as a function argument, you'll need
|
// fn function((t, u, p, l, e))
|
||||||
// extra parentheses: fn function((t, u, p, l, e))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ mod tests {
|
||||||
message: "hello world".to_string(),
|
message: "hello world".to_string(),
|
||||||
};
|
};
|
||||||
state.process(Message::ChangeColor(255, 0, 255));
|
state.process(Message::ChangeColor(255, 0, 255));
|
||||||
state.process(Message::Echo(String::from("hello world")));
|
state.process(Message::Echo(String::from("Hello world!")));
|
||||||
state.process(Message::Move(Point { x: 10, y: 15 }));
|
state.process(Message::Move(Point { x: 10, y: 15 }));
|
||||||
state.process(Message::Quit);
|
state.process(Message::Quit);
|
||||||
|
|
||||||
|
@ -67,6 +68,6 @@ mod tests {
|
||||||
assert_eq!(state.position.x, 10);
|
assert_eq!(state.position.x, 10);
|
||||||
assert_eq!(state.position.y, 15);
|
assert_eq!(state.position.y, 15);
|
||||||
assert_eq!(state.quit, true);
|
assert_eq!(state.quit, true);
|
||||||
assert_eq!(state.message, "hello world");
|
assert_eq!(state.message, "Hello world!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// This function refuses to generate text to be printed on a nametag if you pass
|
// This function refuses to generate text to be printed on a nametag if you pass
|
||||||
// it an empty string. It'd be nicer if it explained what the problem was,
|
// it an empty string. It'd be nicer if it explained what the problem was,
|
||||||
// instead of just sometimes returning `None`. Thankfully, Rust has a similar
|
// instead of just sometimes returning `None`. Thankfully, Rust has a similar
|
||||||
// construct to `Result` that can be used to express error conditions. Let's use
|
// construct to `Option` that can be used to express error conditions. Let's use
|
||||||
// it!
|
// it!
|
||||||
//
|
//
|
||||||
// Execute `rustlings hint errors1` or use the `hint` watch subcommand for a
|
// Execute `rustlings hint errors1` or use the `hint` watch subcommand for a
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
//
|
//
|
||||||
// Right now, this function isn't handling the error case at all (and isn't
|
// Right now, this function isn't handling the error case at all (and isn't
|
||||||
// handling the success case properly either). What we want to do is: if we call
|
// 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
|
// the `total_cost` function on a string that is not a number, that function
|
||||||
// return a `ParseIntError`, and in that case, we want to immediately return
|
// will return a `ParseIntError`, and in that case, we want to immediately
|
||||||
// that error from our function and not try to multiply and add.
|
// 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
|
// There are at least two ways to implement this that are both correct-- but one
|
||||||
// is a lot shorter!
|
// is a lot shorter!
|
||||||
|
|
|
@ -25,4 +25,9 @@ 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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ pub fn animal_habitat(animal: &str) -> &'static str {
|
||||||
habitat
|
habitat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No test changes needed.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
#[test]
|
||||||
fn main() {
|
fn main() {
|
||||||
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
|
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
|
||||||
|
|
||||||
|
|
|
@ -5,24 +5,19 @@
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
#[test]
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = Vec::new();
|
let vec0 = vec![22, 44, 66];
|
||||||
|
|
||||||
let vec1 = fill_vec(vec0);
|
let vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
||||||
|
|
||||||
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 vec = vec;
|
||||||
|
|
||||||
vec.push(22);
|
vec.push(88);
|
||||||
vec.push(44);
|
|
||||||
vec.push(66);
|
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,26 @@
|
||||||
// move_semantics2.rs
|
// move_semantics2.rs
|
||||||
//
|
//
|
||||||
// Expected output:
|
// Make the test pass by finding a way to keep both Vecs separate!
|
||||||
// vec0 has length 3, with contents `[22, 44, 66]`
|
|
||||||
// vec1 has length 4, with contents `[22, 44, 66, 88]`
|
|
||||||
//
|
//
|
||||||
// Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand
|
// Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand
|
||||||
// for a hint.
|
// for a hint.
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
#[test]
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = Vec::new();
|
let vec0 = vec![22, 44, 66];
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
println!("{} has length {}, with contents: `{:?}`", "vec0", vec0.len(), vec0);
|
assert_eq!(vec0, vec![22, 44, 66]);
|
||||||
|
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
||||||
vec1.push(88);
|
|
||||||
|
|
||||||
println!("{} has length {}, with contents `{:?}`", "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(22);
|
vec.push(88);
|
||||||
vec.push(44);
|
|
||||||
vec.push(66);
|
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// move_semantics3.rs
|
// move_semantics3.rs
|
||||||
//
|
//
|
||||||
// Make me compile without adding new lines-- just changing existing lines! (no
|
// Make me compile without adding new lines -- just changing existing lines! (no
|
||||||
// lines with multiple semicolons necessary!)
|
// lines with multiple semicolons necessary!)
|
||||||
//
|
//
|
||||||
// Execute `rustlings hint move_semantics3` or use the `hint` watch subcommand
|
// Execute `rustlings hint move_semantics3` or use the `hint` watch subcommand
|
||||||
|
@ -8,22 +8,17 @@
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
#[test]
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = Vec::new();
|
let vec0 = vec![22, 44, 66];
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
||||||
|
|
||||||
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(22);
|
vec.push(88);
|
||||||
vec.push(44);
|
|
||||||
vec.push(66);
|
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,25 +9,21 @@
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
#[test]
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = Vec::new();
|
let vec0 = vec![22, 44, 66];
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
||||||
|
|
||||||
vec1.push(88);
|
|
||||||
|
|
||||||
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// `fill_vec()` no longer takes `vec: Vec<i32>` as argument
|
// `fill_vec()` no longer takes `vec: Vec<i32>` as argument - don't change this!
|
||||||
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(22);
|
vec.push(88);
|
||||||
vec.push(44);
|
|
||||||
vec.push(66);
|
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
#[test]
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut x = 100;
|
let mut x = 100;
|
||||||
let y = &mut x;
|
let y = &mut x;
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
//
|
//
|
||||||
// Fill in the rest of the line that has code missing! No hints, there's no
|
// Fill in the rest of the line that has code missing! No hints, there's no
|
||||||
// tricks, just get used to typing these :)
|
// tricks, just get used to typing these :)
|
||||||
//
|
|
||||||
// Execute `rustlings hint primitive_types1` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
//
|
//
|
||||||
// Fill in the rest of the line that has code missing! No hints, there's no
|
// Fill in the rest of the line that has code missing! No hints, there's no
|
||||||
// tricks, just get used to typing these :)
|
// tricks, just get used to typing these :)
|
||||||
//
|
|
||||||
// Execute `rustlings hint primitive_types2` or use the `hint` watch subcommand
|
|
||||||
// for a hint.
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
|
|
@ -14,5 +14,6 @@ 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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,8 +67,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn owned_mutation() -> Result<(), &'static str> {
|
fn owned_mutation() -> Result<(), &'static str> {
|
||||||
// Of course this is also the case if a mutation does occur. In this
|
// Of course this is also the case if a mutation does occur. In this
|
||||||
// case the call to `to_mut()` returns a reference to the same data as
|
// case the call to `to_mut()` in the abs_all() function returns a
|
||||||
// before.
|
// reference to the same data as before.
|
||||||
let slice = vec![-1, 0, 1];
|
let slice = vec![-1, 0, 1];
|
||||||
let mut input = Cow::from(slice);
|
let mut input = Cow::from(slice);
|
||||||
match abs_all(&mut input) {
|
match abs_all(&mut input) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ impl Planet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
fn main() {
|
fn main() {
|
||||||
let sun = Rc::new(Sun {});
|
let sun = Rc::new(Sun {});
|
||||||
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
|
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
|
||||||
|
|
|
@ -13,13 +13,15 @@
|
||||||
struct Package {
|
struct Package {
|
||||||
sender_country: String,
|
sender_country: String,
|
||||||
recipient_country: String,
|
recipient_country: String,
|
||||||
weight_in_grams: i32,
|
weight_in_grams: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Package {
|
impl Package {
|
||||||
fn new(sender_country: String, recipient_country: String, weight_in_grams: i32) -> Package {
|
fn new(sender_country: String, recipient_country: String, weight_in_grams: u32) -> Package {
|
||||||
if weight_in_grams <= 0 {
|
if weight_in_grams < 10 {
|
||||||
panic!("Can not ship a weightless package.")
|
// This is not how you should handle errors in Rust,
|
||||||
|
// but we will learn about error handling later.
|
||||||
|
panic!("Can not ship a package with weight below 10 grams.")
|
||||||
} else {
|
} else {
|
||||||
Package {
|
Package {
|
||||||
sender_country,
|
sender_country,
|
||||||
|
@ -33,7 +35,7 @@ impl Package {
|
||||||
// Something goes here...
|
// Something goes here...
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_fees(&self, cents_per_gram: i32) -> ??? {
|
fn get_fees(&self, cents_per_gram: u32) -> ??? {
|
||||||
// Something goes here...
|
// Something goes here...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +50,7 @@ mod tests {
|
||||||
let sender_country = String::from("Spain");
|
let sender_country = String::from("Spain");
|
||||||
let recipient_country = String::from("Austria");
|
let recipient_country = String::from("Austria");
|
||||||
|
|
||||||
Package::new(sender_country, recipient_country, -2210);
|
Package::new(sender_country, recipient_country, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Threads
|
# Threads
|
||||||
|
|
||||||
In most current operating systems, an executed program’s code is run in a process, and the operating system manages multiple processes at once.
|
In most current operating systems, an executed program's code is run in a process, and the operating system manages multiple processes at once.
|
||||||
Within your program, you can also have independent parts that run simultaneously. The features that run these independent parts are called threads.
|
Within your program, you can also have independent parts that run simultaneously. The features that run these independent parts are called threads.
|
||||||
|
|
||||||
## Further information
|
## Further information
|
||||||
|
|
|
@ -48,6 +48,7 @@ fn send_tx(q: Queue, tx: mpsc::Sender<u32>) -> () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
fn main() {
|
fn main() {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let queue = Queue::new();
|
let queue = Queue::new();
|
||||||
|
|
36
flake.lock
36
flake.lock
|
@ -3,11 +3,11 @@
|
||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1650374568,
|
"lastModified": 1673956053,
|
||||||
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
|
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
|
||||||
"owner": "edolstra",
|
"owner": "edolstra",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-compat",
|
||||||
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
|
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -17,12 +17,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1659877975,
|
"lastModified": 1692799911,
|
||||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
"narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
"rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -33,11 +36,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1666629043,
|
"lastModified": 1694183432,
|
||||||
"narHash": "sha256-Yoq6Ut2F3Ol73yO9hG93x6ts5c4F5BhKTbcF3DtBEAw=",
|
"narHash": "sha256-YyPGNapgZNNj51ylQMw9lAgvxtM2ai1HZVUu3GS8Fng=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "b39fd6e4edef83cb4a135ebef98751ce23becc33",
|
"rev": "db9208ab987cdeeedf78ad9b4cf3c55f5ebd269b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -53,6 +56,21 @@
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|
16
flake.nix
16
flake.nix
|
@ -22,9 +22,10 @@
|
||||||
rustlings =
|
rustlings =
|
||||||
pkgs.rustPlatform.buildRustPackage {
|
pkgs.rustPlatform.buildRustPackage {
|
||||||
name = "rustlings";
|
name = "rustlings";
|
||||||
version = "5.5.1";
|
version = "5.6.1";
|
||||||
|
|
||||||
buildInputs = cargoBuildInputs;
|
buildInputs = cargoBuildInputs;
|
||||||
|
nativeBuildInputs = [pkgs.git];
|
||||||
|
|
||||||
src = with pkgs.lib; cleanSourceWith {
|
src = with pkgs.lib; cleanSourceWith {
|
||||||
src = self;
|
src = self;
|
||||||
|
@ -60,5 +61,18 @@
|
||||||
clippy
|
clippy
|
||||||
] ++ cargoBuildInputs;
|
] ++ cargoBuildInputs;
|
||||||
};
|
};
|
||||||
|
apps = let
|
||||||
|
rustlings-app = {
|
||||||
|
type = "app";
|
||||||
|
program = "${rustlings}/bin/rustlings";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
default = rustlings-app;
|
||||||
|
rustlings = rustlings-app;
|
||||||
|
};
|
||||||
|
packages = {
|
||||||
|
inherit rustlings;
|
||||||
|
default = rustlings;
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
66
info.toml
66
info.toml
|
@ -22,8 +22,8 @@ name = "variables1"
|
||||||
path = "exercises/variables/variables1.rs"
|
path = "exercises/variables/variables1.rs"
|
||||||
mode = "compile"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
The declaration on line 8 is missing a keyword that is needed in Rust
|
The declaration in the first line in the main function is missing a keyword
|
||||||
to create a new variable binding."""
|
that is needed in Rust to create a new variable binding."""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "variables2"
|
name = "variables2"
|
||||||
|
@ -32,7 +32,7 @@ mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
The compiler message is saying that Rust cannot infer the type that the
|
The compiler message is saying that Rust cannot infer the type that the
|
||||||
variable binding `x` has with what is given here.
|
variable binding `x` has with what is given here.
|
||||||
What happens if you annotate line 7 with a type annotation?
|
What happens if you annotate the first line in the main function with a type annotation?
|
||||||
What if you give x a value?
|
What if you give x a value?
|
||||||
What if you do both?
|
What if you do both?
|
||||||
What type should x be, anyway?
|
What type should x be, anyway?
|
||||||
|
@ -44,8 +44,9 @@ path = "exercises/variables/variables3.rs"
|
||||||
mode = "compile"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
Oops! In this exercise, we have a variable binding that we've created on
|
Oops! In this exercise, we have a variable binding that we've created on
|
||||||
line 7, and we're trying to use it on line 8, but we haven't given it a
|
in the first line in the main function, and we're trying to use it in the next line,
|
||||||
value. We can't print out something that isn't there; try giving x a value!
|
but we haven't given it a value.
|
||||||
|
We can't print out something that isn't there; try giving x a value!
|
||||||
This is an error that can cause bugs that's very easy to make in any
|
This is an error that can cause bugs that's very easy to make in any
|
||||||
programming language -- thankfully the Rust compiler has caught this for us!"""
|
programming language -- thankfully the Rust compiler has caught this for us!"""
|
||||||
|
|
||||||
|
@ -123,8 +124,8 @@ name = "functions4"
|
||||||
path = "exercises/functions/functions4.rs"
|
path = "exercises/functions/functions4.rs"
|
||||||
mode = "compile"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
The error message points to line 17 and says it expects a type after the
|
The error message points to the function `sale_price` and says it expects a type
|
||||||
`->`. This is where the function's return type should be -- take a look at
|
after the `->`. This is where the function's return type should be -- take a look at
|
||||||
the `is_even` function for an example!
|
the `is_even` function for an example!
|
||||||
|
|
||||||
Also: Did you figure out that, technically, u32 would be the more fitting type
|
Also: Did you figure out that, technically, u32 would be the more fitting type
|
||||||
|
@ -216,7 +217,7 @@ mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Take a look at the Understanding Ownership -> Slices -> Other Slices section of the book:
|
Take a look at the Understanding Ownership -> Slices -> Other Slices section of the book:
|
||||||
https://doc.rust-lang.org/book/ch04-03-slices.html
|
https://doc.rust-lang.org/book/ch04-03-slices.html
|
||||||
and use the starting and ending indices of the items in the Array
|
and use the starting and ending (plus one) indices of the items in the Array
|
||||||
that you want to end up in the slice.
|
that you want to end up in the slice.
|
||||||
|
|
||||||
If you're curious why the first argument of `assert_eq!` does not
|
If you're curious why the first argument of `assert_eq!` does not
|
||||||
|
@ -267,15 +268,14 @@ name = "vecs2"
|
||||||
path = "exercises/vecs/vecs2.rs"
|
path = "exercises/vecs/vecs2.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Hint 1: In the code, the variable `element` represents an item from the Vec as it is being iterated.
|
In the first function we are looping over the Vector and getting a reference to one `element` at a time.
|
||||||
Can you try multiplying this?
|
To modify the value of that `element` we need to use the * dereference operator. You can learn more in this chapter of the Rust book:
|
||||||
|
https://doc.rust-lang.org/stable/book/ch08-01-vectors.html#iterating-over-the-values-in-a-vector
|
||||||
|
|
||||||
Hint 2: For the first function, there's a way to directly access the numbers stored
|
In the second function this dereferencing is not necessary, because the map function expects the new value to be returned.
|
||||||
in the Vec, using the * dereference operator. You can both access and write to the
|
|
||||||
number that way.
|
|
||||||
|
|
||||||
After you've completed both functions, decide for yourself which approach you like
|
After you've completed both functions, decide for yourself which approach you like better.
|
||||||
better. What do you think is the more commonly used pattern under Rust developers?
|
What do you think is the more commonly used pattern under Rust developers?
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# MOVE SEMANTICS
|
# MOVE SEMANTICS
|
||||||
|
@ -283,18 +283,19 @@ better. What do you think is the more commonly used pattern under Rust developer
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "move_semantics1"
|
name = "move_semantics1"
|
||||||
path = "exercises/move_semantics/move_semantics1.rs"
|
path = "exercises/move_semantics/move_semantics1.rs"
|
||||||
mode = "compile"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
So you've got the "cannot borrow immutable local variable `vec1` as mutable" error on line 13,
|
So you've got the "cannot borrow immutable local variable `vec` as mutable" error on the line
|
||||||
right? The fix for this is going to be adding one keyword, and the addition is NOT on line 13
|
where we push an element to the vector, right?
|
||||||
where the error is.
|
The fix for this is going to be adding one keyword, and the addition is NOT on the line where
|
||||||
|
we push to the vector (where the error is).
|
||||||
|
|
||||||
Also: Try accessing `vec0` after having called `fill_vec()`. See what happens!"""
|
Also: Try accessing `vec0` after having called `fill_vec()`. See what happens!"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "move_semantics2"
|
name = "move_semantics2"
|
||||||
path = "exercises/move_semantics/move_semantics2.rs"
|
path = "exercises/move_semantics/move_semantics2.rs"
|
||||||
mode = "compile"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
When running this exercise for the first time, you'll notice an error about
|
When running this exercise for the first time, you'll notice an error about
|
||||||
"borrow of moved value". In Rust, when an argument is passed to a function and
|
"borrow of moved value". In Rust, when an argument is passed to a function and
|
||||||
|
@ -307,16 +308,12 @@ Rust provides a couple of different ways to mitigate this issue, feel free to tr
|
||||||
2. Make `fill_vec` borrow its argument instead of taking ownership of it,
|
2. Make `fill_vec` borrow its argument instead of taking ownership of it,
|
||||||
and then copy the data within the function (`vec.clone()`) in order to return an owned
|
and then copy the data within the function (`vec.clone()`) in order to return an owned
|
||||||
`Vec<i32>`.
|
`Vec<i32>`.
|
||||||
3. Or, you could make `fill_vec` *mutably* borrow a reference to its argument (which will need to be
|
|
||||||
mutable), modify it directly, then not return anything. This means that `vec0` will change over the
|
|
||||||
course of the function, and makes `vec1` redundant (make sure to change the parameters of the `println!`
|
|
||||||
statements if you go this route)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "move_semantics3"
|
name = "move_semantics3"
|
||||||
path = "exercises/move_semantics/move_semantics3.rs"
|
path = "exercises/move_semantics/move_semantics3.rs"
|
||||||
mode = "compile"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
The difference between this one and the previous ones is that the first line
|
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,
|
of `fn fill_vec` that had `let mut vec = vec;` is no longer there. You can,
|
||||||
|
@ -326,7 +323,7 @@ an existing binding to be a mutable binding instead of an immutable one :)"""
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "move_semantics4"
|
name = "move_semantics4"
|
||||||
path = "exercises/move_semantics/move_semantics4.rs"
|
path = "exercises/move_semantics/move_semantics4.rs"
|
||||||
mode = "compile"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Stop reading whenever you feel like you have enough direction :) Or try
|
Stop reading whenever you feel like you have enough direction :) Or try
|
||||||
doing one step and then fixing the compiler errors that result!
|
doing one step and then fixing the compiler errors that result!
|
||||||
|
@ -335,12 +332,12 @@ So the end goal is to:
|
||||||
- so then `vec0` doesn't exist, so we can't pass it to `fill_vec`
|
- so then `vec0` doesn't exist, so we can't pass it to `fill_vec`
|
||||||
- `fill_vec` has had its signature changed, which our call should reflect
|
- `fill_vec` has had its signature changed, which our call should reflect
|
||||||
- since we're not creating a new vec in `main` anymore, we need to create
|
- 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`"""
|
a new vec in `fill_vec`, and fill it with the expected values"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "move_semantics5"
|
name = "move_semantics5"
|
||||||
path = "exercises/move_semantics/move_semantics5.rs"
|
path = "exercises/move_semantics/move_semantics5.rs"
|
||||||
mode = "compile"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Carefully reason about the range in which each mutable reference is in
|
Carefully reason about the range in which each mutable reference is in
|
||||||
scope. Does it help to update the value of referent (x) immediately after
|
scope. Does it help to update the value of referent (x) immediately after
|
||||||
|
@ -445,8 +442,8 @@ path = "exercises/strings/strings2.rs"
|
||||||
mode = "compile"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
Yes, it would be really easy to fix this by just changing the value bound to `word` to be a
|
Yes, it would be really easy to fix this by just changing the value bound to `word` to be a
|
||||||
string slice instead of a `String`, wouldn't it?? There is a way to add one character to line
|
string slice instead of a `String`, wouldn't it?? There is a way to add one character to the
|
||||||
12, though, that will coerce the `String` into a string slice.
|
if statement, though, that will coerce the `String` into a string slice.
|
||||||
|
|
||||||
Side note: If you're interested in learning about how this kind of reference conversion works, you can jump ahead in the book and read this part in the smart pointers chapter: https://doc.rust-lang.org/stable/book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods"""
|
Side note: If you're interested in learning about how this kind of reference conversion works, you can jump ahead in the book and read this part in the smart pointers chapter: https://doc.rust-lang.org/stable/book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods"""
|
||||||
|
|
||||||
|
@ -825,13 +822,12 @@ To handle that you need to add a special attribute to the test function.
|
||||||
You can refer to the docs:
|
You can refer to the docs:
|
||||||
https://doc.rust-lang.org/stable/book/ch11-01-writing-tests.html#checking-for-panics-with-should_panic"""
|
https://doc.rust-lang.org/stable/book/ch11-01-writing-tests.html#checking-for-panics-with-should_panic"""
|
||||||
|
|
||||||
|
|
||||||
# STANDARD LIBRARY TYPES
|
# STANDARD LIBRARY TYPES
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "iterators1"
|
name = "iterators1"
|
||||||
path = "exercises/iterators/iterators1.rs"
|
path = "exercises/iterators/iterators1.rs"
|
||||||
mode = "compile"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Step 1:
|
Step 1:
|
||||||
We need to apply something to the collection `my_fav_fruits` before we start to go through
|
We need to apply something to the collection `my_fav_fruits` before we start to go through
|
||||||
|
@ -936,7 +932,7 @@ and try other types!
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "rc1"
|
name = "rc1"
|
||||||
path = "exercises/smart_pointers/rc1.rs"
|
path = "exercises/smart_pointers/rc1.rs"
|
||||||
mode = "compile"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
This is a straightforward exercise to use the Rc<T> type. Each Planet has
|
This is a straightforward exercise to use the Rc<T> type. Each Planet has
|
||||||
ownership of the Sun, and uses Rc::clone() to increment the reference count of the Sun.
|
ownership of the Sun, and uses Rc::clone() to increment the reference count of the Sun.
|
||||||
|
@ -1009,7 +1005,7 @@ and keep reading if you'd like more hints :)
|
||||||
Do you now have an `Arc` `Mutex` `JobStatus` at the beginning of main? Like:
|
Do you now have an `Arc` `Mutex` `JobStatus` at the beginning of main? Like:
|
||||||
`let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));`
|
`let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));`
|
||||||
Similar to the code in the example in the book that happens after the text
|
Similar to the code in the example in the book that happens after the text
|
||||||
that says "We can use Arc<T> to fix this.". If not, give that a try! If you
|
that says "Sharing a Mutex<T> Between Multiple Threads". If not, give that a try! If you
|
||||||
do and would like more hints, keep reading!!
|
do and would like more hints, keep reading!!
|
||||||
|
|
||||||
|
|
||||||
|
@ -1025,7 +1021,7 @@ what you've learned :)"""
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "threads3"
|
name = "threads3"
|
||||||
path = "exercises/threads/threads3.rs"
|
path = "exercises/threads/threads3.rs"
|
||||||
mode = "compile"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
An alternate way to handle concurrency between threads is to use
|
An alternate way to handle concurrency between threads is to use
|
||||||
a mpsc (multiple producer, single consumer) channel to communicate.
|
a mpsc (multiple producer, single consumer) channel to communicate.
|
||||||
|
|
|
@ -12,14 +12,13 @@
|
||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"artifacts": {
|
"artifacts": {
|
||||||
"cargo_dist": false,
|
"auto": true,
|
||||||
"package_managers": {
|
"package_managers": {
|
||||||
"preferred": {
|
"preferred": {
|
||||||
"macos/linux/unix": "curl -L https://raw.githubusercontent.com/rust-lang/rustlings/main/install.sh | bash",
|
"macos/linux/unix": "curl -L https://raw.githubusercontent.com/rust-lang/rustlings/main/install.sh | bash",
|
||||||
"windows": "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"
|
"windows": "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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"changelog": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,12 +110,12 @@ impl Exercise {
|
||||||
pub fn compile(&self) -> Result<CompiledExercise, ExerciseOutput> {
|
pub fn compile(&self) -> Result<CompiledExercise, ExerciseOutput> {
|
||||||
let cmd = match self.mode {
|
let cmd = match self.mode {
|
||||||
Mode::Compile => Command::new("rustc")
|
Mode::Compile => Command::new("rustc")
|
||||||
.args(&[self.path.to_str().unwrap(), "-o", &temp_file()])
|
.args([self.path.to_str().unwrap(), "-o", &temp_file()])
|
||||||
.args(RUSTC_COLOR_ARGS)
|
.args(RUSTC_COLOR_ARGS)
|
||||||
.args(RUSTC_EDITION_ARGS)
|
.args(RUSTC_EDITION_ARGS)
|
||||||
.output(),
|
.output(),
|
||||||
Mode::Test => Command::new("rustc")
|
Mode::Test => Command::new("rustc")
|
||||||
.args(&["--test", self.path.to_str().unwrap(), "-o", &temp_file()])
|
.args(["--test", self.path.to_str().unwrap(), "-o", &temp_file()])
|
||||||
.args(RUSTC_COLOR_ARGS)
|
.args(RUSTC_COLOR_ARGS)
|
||||||
.args(RUSTC_EDITION_ARGS)
|
.args(RUSTC_EDITION_ARGS)
|
||||||
.output(),
|
.output(),
|
||||||
|
@ -141,7 +141,7 @@ path = "{}.rs""#,
|
||||||
// compilation failure, this would silently fail. But we expect
|
// compilation failure, this would silently fail. But we expect
|
||||||
// clippy to reflect the same failure while compiling later.
|
// clippy to reflect the same failure while compiling later.
|
||||||
Command::new("rustc")
|
Command::new("rustc")
|
||||||
.args(&[self.path.to_str().unwrap(), "-o", &temp_file()])
|
.args([self.path.to_str().unwrap(), "-o", &temp_file()])
|
||||||
.args(RUSTC_COLOR_ARGS)
|
.args(RUSTC_COLOR_ARGS)
|
||||||
.args(RUSTC_EDITION_ARGS)
|
.args(RUSTC_EDITION_ARGS)
|
||||||
.output()
|
.output()
|
||||||
|
@ -151,14 +151,14 @@ path = "{}.rs""#,
|
||||||
// This is already fixed on Clippy's master branch. See this issue to track merging into Cargo:
|
// This is already fixed on Clippy's master branch. See this issue to track merging into Cargo:
|
||||||
// https://github.com/rust-lang/rust-clippy/issues/3837
|
// https://github.com/rust-lang/rust-clippy/issues/3837
|
||||||
Command::new("cargo")
|
Command::new("cargo")
|
||||||
.args(&["clean", "--manifest-path", CLIPPY_CARGO_TOML_PATH])
|
.args(["clean", "--manifest-path", CLIPPY_CARGO_TOML_PATH])
|
||||||
.args(RUSTC_COLOR_ARGS)
|
.args(RUSTC_COLOR_ARGS)
|
||||||
.output()
|
.output()
|
||||||
.expect("Failed to run 'cargo clean'");
|
.expect("Failed to run 'cargo clean'");
|
||||||
Command::new("cargo")
|
Command::new("cargo")
|
||||||
.args(&["clippy", "--manifest-path", CLIPPY_CARGO_TOML_PATH])
|
.args(["clippy", "--manifest-path", CLIPPY_CARGO_TOML_PATH])
|
||||||
.args(RUSTC_COLOR_ARGS)
|
.args(RUSTC_COLOR_ARGS)
|
||||||
.args(&["--", "-D", "warnings", "-D", "clippy::float_cmp"])
|
.args(["--", "-D", "warnings", "-D", "clippy::float_cmp"])
|
||||||
.output()
|
.output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ path = "{}.rs""#,
|
||||||
Mode::Test => "--show-output",
|
Mode::Test => "--show-output",
|
||||||
_ => "",
|
_ => "",
|
||||||
};
|
};
|
||||||
let cmd = Command::new(&temp_file())
|
let cmd = Command::new(temp_file())
|
||||||
.arg(arg)
|
.arg(arg)
|
||||||
.output()
|
.output()
|
||||||
.expect("Failed to run 'run' command");
|
.expect("Failed to run 'run' command");
|
||||||
|
@ -260,7 +260,7 @@ impl Display for Exercise {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clean() {
|
fn clean() {
|
||||||
let _ignored = remove_file(&temp_file());
|
let _ignored = remove_file(temp_file());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -270,7 +270,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_clean() {
|
fn test_clean() {
|
||||||
File::create(&temp_file()).unwrap();
|
File::create(temp_file()).unwrap();
|
||||||
let exercise = Exercise {
|
let exercise = Exercise {
|
||||||
name: String::from("example"),
|
name: String::from("example"),
|
||||||
path: PathBuf::from("tests/fixture/state/pending_exercise.rs"),
|
path: PathBuf::from("tests/fixture/state/pending_exercise.rs"),
|
||||||
|
|
207
src/main.rs
207
src/main.rs
|
@ -2,7 +2,7 @@ use crate::exercise::{Exercise, ExerciseList};
|
||||||
use crate::project::RustAnalyzerProject;
|
use crate::project::RustAnalyzerProject;
|
||||||
use crate::run::{reset, run};
|
use crate::run::{reset, run};
|
||||||
use crate::verify::verify;
|
use crate::verify::verify;
|
||||||
use argh::FromArgs;
|
use clap::{Parser, Subcommand};
|
||||||
use console::Emoji;
|
use console::Emoji;
|
||||||
use notify::DebouncedEvent;
|
use notify::DebouncedEvent;
|
||||||
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
|
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
|
||||||
|
@ -25,111 +25,69 @@ mod project;
|
||||||
mod run;
|
mod run;
|
||||||
mod verify;
|
mod verify;
|
||||||
|
|
||||||
// In sync with crate version
|
|
||||||
const VERSION: &str = "5.5.1";
|
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
|
||||||
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
|
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(version)]
|
||||||
struct Args {
|
struct Args {
|
||||||
/// show outputs from the test exercises
|
/// Show outputs from the test exercises
|
||||||
#[argh(switch)]
|
#[arg(long)]
|
||||||
nocapture: bool,
|
nocapture: bool,
|
||||||
/// show the executable version
|
#[command(subcommand)]
|
||||||
#[argh(switch, short = 'v')]
|
command: Option<Subcommands>,
|
||||||
version: bool,
|
|
||||||
#[argh(subcommand)]
|
|
||||||
nested: Option<Subcommands>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
#[derive(Subcommand)]
|
||||||
#[argh(subcommand)]
|
|
||||||
enum Subcommands {
|
enum Subcommands {
|
||||||
Verify(VerifyArgs),
|
/// Verify all exercises according to the recommended order
|
||||||
Watch(WatchArgs),
|
Verify,
|
||||||
Run(RunArgs),
|
/// Rerun `verify` when files were edited
|
||||||
Reset(ResetArgs),
|
Watch {
|
||||||
Hint(HintArgs),
|
/// Show hints on success
|
||||||
List(ListArgs),
|
#[arg(long)]
|
||||||
Lsp(LspArgs),
|
success_hints: bool,
|
||||||
}
|
},
|
||||||
|
/// Run/Test a single exercise
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
Run {
|
||||||
#[argh(subcommand, name = "verify")]
|
/// The name of the exercise
|
||||||
/// Verifies all exercises according to the recommended order
|
name: String,
|
||||||
struct VerifyArgs {}
|
},
|
||||||
|
/// Reset a single exercise using "git stash -- <filename>"
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
Reset {
|
||||||
#[argh(subcommand, name = "watch")]
|
/// The name of the exercise
|
||||||
/// Reruns `verify` when files were edited
|
name: String,
|
||||||
struct WatchArgs {
|
},
|
||||||
/// show hints on success
|
/// Return a hint for the given exercise
|
||||||
#[argh(switch)]
|
Hint {
|
||||||
success_hints: bool,
|
/// The name of the exercise
|
||||||
}
|
name: String,
|
||||||
|
},
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
/// List the exercises available in Rustlings
|
||||||
#[argh(subcommand, name = "run")]
|
List {
|
||||||
/// Runs/Tests a single exercise
|
/// Show only the paths of the exercises
|
||||||
struct RunArgs {
|
#[arg(short, long)]
|
||||||
#[argh(positional)]
|
paths: bool,
|
||||||
/// the name of the exercise
|
/// Show only the names of the exercises
|
||||||
name: String,
|
#[arg(short, long)]
|
||||||
}
|
names: bool,
|
||||||
|
/// Provide a string to match exercise names.
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
/// Comma separated patterns are accepted
|
||||||
#[argh(subcommand, name = "reset")]
|
#[arg(short, long)]
|
||||||
/// Resets a single exercise using "git stash -- <filename>"
|
filter: Option<String>,
|
||||||
struct ResetArgs {
|
/// Display only exercises not yet solved
|
||||||
#[argh(positional)]
|
#[arg(short, long)]
|
||||||
/// the name of the exercise
|
unsolved: bool,
|
||||||
name: String,
|
/// Display only exercises that have been solved
|
||||||
}
|
#[arg(short, long)]
|
||||||
|
solved: bool,
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
},
|
||||||
#[argh(subcommand, name = "hint")]
|
/// Enable rust-analyzer for exercises
|
||||||
/// Returns a hint for the given exercise
|
Lsp,
|
||||||
struct HintArgs {
|
|
||||||
#[argh(positional)]
|
|
||||||
/// the name of the exercise
|
|
||||||
name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
|
||||||
#[argh(subcommand, name = "lsp")]
|
|
||||||
/// Enable rust-analyzer for exercises
|
|
||||||
struct LspArgs {}
|
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
|
||||||
#[argh(subcommand, name = "list")]
|
|
||||||
/// Lists the exercises available in Rustlings
|
|
||||||
struct ListArgs {
|
|
||||||
#[argh(switch, short = 'p')]
|
|
||||||
/// show only the paths of the exercises
|
|
||||||
paths: bool,
|
|
||||||
#[argh(switch, short = 'n')]
|
|
||||||
/// show only the names of the exercises
|
|
||||||
names: bool,
|
|
||||||
#[argh(option, short = 'f')]
|
|
||||||
/// provide a string to match exercise names
|
|
||||||
/// comma separated patterns are acceptable
|
|
||||||
filter: Option<String>,
|
|
||||||
#[argh(switch, short = 'u')]
|
|
||||||
/// display only exercises not yet solved
|
|
||||||
unsolved: bool,
|
|
||||||
#[argh(switch, short = 's')]
|
|
||||||
/// display only exercises that have been solved
|
|
||||||
solved: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Args = argh::from_env();
|
let args = Args::parse();
|
||||||
|
|
||||||
if args.version {
|
if args.command.is_none() {
|
||||||
println!("v{VERSION}");
|
|
||||||
std::process::exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if args.nested.is_none() {
|
|
||||||
println!("\n{WELCOME}\n");
|
println!("\n{WELCOME}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,23 +111,30 @@ fn main() {
|
||||||
let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;
|
let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;
|
||||||
let verbose = args.nocapture;
|
let verbose = args.nocapture;
|
||||||
|
|
||||||
let command = args.nested.unwrap_or_else(|| {
|
let command = args.command.unwrap_or_else(|| {
|
||||||
println!("{DEFAULT_OUT}\n");
|
println!("{DEFAULT_OUT}\n");
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
match command {
|
match command {
|
||||||
Subcommands::List(subargs) => {
|
Subcommands::List {
|
||||||
if !subargs.paths && !subargs.names {
|
paths,
|
||||||
|
names,
|
||||||
|
filter,
|
||||||
|
unsolved,
|
||||||
|
solved,
|
||||||
|
} => {
|
||||||
|
if !paths && !names {
|
||||||
println!("{:<17}\t{:<46}\t{:<7}", "Name", "Path", "Status");
|
println!("{:<17}\t{:<46}\t{:<7}", "Name", "Path", "Status");
|
||||||
}
|
}
|
||||||
let mut exercises_done: u16 = 0;
|
let mut exercises_done: u16 = 0;
|
||||||
let filters = subargs.filter.clone().unwrap_or_default().to_lowercase();
|
let filters = filter.clone().unwrap_or_default().to_lowercase();
|
||||||
exercises.iter().for_each(|e| {
|
exercises.iter().for_each(|e| {
|
||||||
let fname = format!("{}", e.path.display());
|
let fname = format!("{}", e.path.display());
|
||||||
let filter_cond = filters
|
let filter_cond = filters
|
||||||
.split(',')
|
.split(',')
|
||||||
.filter(|f| !f.trim().is_empty())
|
.filter(|f| !f.trim().is_empty())
|
||||||
.any(|f| e.name.contains(&f) || fname.contains(&f));
|
.any(|f| e.name.contains(f) || fname.contains(f));
|
||||||
let status = if e.looks_done() {
|
let status = if e.looks_done() {
|
||||||
exercises_done += 1;
|
exercises_done += 1;
|
||||||
"Done"
|
"Done"
|
||||||
|
@ -177,14 +142,14 @@ fn main() {
|
||||||
"Pending"
|
"Pending"
|
||||||
};
|
};
|
||||||
let solve_cond = {
|
let solve_cond = {
|
||||||
(e.looks_done() && subargs.solved)
|
(e.looks_done() && solved)
|
||||||
|| (!e.looks_done() && subargs.unsolved)
|
|| (!e.looks_done() && unsolved)
|
||||||
|| (!subargs.solved && !subargs.unsolved)
|
|| (!solved && !unsolved)
|
||||||
};
|
};
|
||||||
if solve_cond && (filter_cond || subargs.filter.is_none()) {
|
if solve_cond && (filter_cond || filter.is_none()) {
|
||||||
let line = if subargs.paths {
|
let line = if paths {
|
||||||
format!("{fname}\n")
|
format!("{fname}\n")
|
||||||
} else if subargs.names {
|
} else if names {
|
||||||
format!("{}\n", e.name)
|
format!("{}\n", e.name)
|
||||||
} else {
|
} else {
|
||||||
format!("{:<17}\t{fname:<46}\t{status:<7}\n", e.name)
|
format!("{:<17}\t{fname:<46}\t{status:<7}\n", e.name)
|
||||||
|
@ -214,30 +179,30 @@ fn main() {
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Subcommands::Run(subargs) => {
|
Subcommands::Run { name } => {
|
||||||
let exercise = find_exercise(&subargs.name, &exercises);
|
let exercise = find_exercise(&name, &exercises);
|
||||||
|
|
||||||
run(exercise, verbose).unwrap_or_else(|_| std::process::exit(1));
|
run(exercise, verbose).unwrap_or_else(|_| std::process::exit(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
Subcommands::Reset(subargs) => {
|
Subcommands::Reset { name } => {
|
||||||
let exercise = find_exercise(&subargs.name, &exercises);
|
let exercise = find_exercise(&name, &exercises);
|
||||||
|
|
||||||
reset(exercise).unwrap_or_else(|_| std::process::exit(1));
|
reset(exercise).unwrap_or_else(|_| std::process::exit(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
Subcommands::Hint(subargs) => {
|
Subcommands::Hint { name } => {
|
||||||
let exercise = find_exercise(&subargs.name, &exercises);
|
let exercise = find_exercise(&name, &exercises);
|
||||||
|
|
||||||
println!("{}", exercise.hint);
|
println!("{}", exercise.hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
Subcommands::Verify(_subargs) => {
|
Subcommands::Verify => {
|
||||||
verify(&exercises, (0, exercises.len()), verbose, false)
|
verify(&exercises, (0, exercises.len()), verbose, false)
|
||||||
.unwrap_or_else(|_| std::process::exit(1));
|
.unwrap_or_else(|_| std::process::exit(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
Subcommands::Lsp(_subargs) => {
|
Subcommands::Lsp => {
|
||||||
let mut project = RustAnalyzerProject::new();
|
let mut project = RustAnalyzerProject::new();
|
||||||
project
|
project
|
||||||
.get_sysroot_src()
|
.get_sysroot_src()
|
||||||
|
@ -256,7 +221,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Subcommands::Watch(_subargs) => match watch(&exercises, verbose, _subargs.success_hints) {
|
Subcommands::Watch { success_hints } => match watch(&exercises, verbose, success_hints) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!(
|
println!(
|
||||||
"Error: Could not watch your progress. Error message was {:?}.",
|
"Error: Could not watch your progress. Error message was {:?}.",
|
||||||
|
@ -429,7 +394,7 @@ fn watch(
|
||||||
|
|
||||||
fn rustc_exists() -> bool {
|
fn rustc_exists() -> bool {
|
||||||
Command::new("rustc")
|
Command::new("rustc")
|
||||||
.args(&["--version"])
|
.args(["--version"])
|
||||||
.stdout(Stdio::null())
|
.stdout(Stdio::null())
|
||||||
.spawn()
|
.spawn()
|
||||||
.and_then(|mut child| child.wait())
|
.and_then(|mut child| child.wait())
|
||||||
|
@ -465,7 +430,7 @@ started, here's a couple of notes about how Rustlings operates:
|
||||||
Got all that? Great! To get started, run `rustlings watch` in order to get the first
|
Got all that? Great! To get started, run `rustlings watch` in order to get the first
|
||||||
exercise. Make sure to have your editor open!"#;
|
exercise. Make sure to have your editor open!"#;
|
||||||
|
|
||||||
const FENISH_LINE: &str = r#"+----------------------------------------------------+
|
const FENISH_LINE: &str = r"+----------------------------------------------------+
|
||||||
| You made it to the Fe-nish line! |
|
| You made it to the Fe-nish line! |
|
||||||
+-------------------------- ------------------------+
|
+-------------------------- ------------------------+
|
||||||
\\/
|
\\/
|
||||||
|
@ -490,12 +455,12 @@ If you noticed any issues, please don't hesitate to report them to our repo.
|
||||||
You can also contribute your own exercises to help the greater community!
|
You can also contribute your own exercises to help the greater community!
|
||||||
|
|
||||||
Before reporting an issue or contributing, please read our guidelines:
|
Before reporting an issue or contributing, please read our guidelines:
|
||||||
https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md"#;
|
https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md";
|
||||||
|
|
||||||
const WELCOME: &str = r#" welcome to...
|
const WELCOME: &str = r" welcome to...
|
||||||
_ _ _
|
_ _ _
|
||||||
_ __ _ _ ___| |_| (_)_ __ __ _ ___
|
_ __ _ _ ___| |_| (_)_ __ __ _ ___
|
||||||
| '__| | | / __| __| | | '_ \ / _` / __|
|
| '__| | | / __| __| | | '_ \ / _` / __|
|
||||||
| | | |_| \__ \ |_| | | | | | (_| \__ \
|
| | | |_| \__ \ |_| | | | | | (_| \__ \
|
||||||
|_| \__,_|___/\__|_|_|_| |_|\__, |___/
|
|_| \__,_|___/\__|_|_|_| |_|\__, |___/
|
||||||
|___/"#;
|
|___/";
|
||||||
|
|
|
@ -86,7 +86,7 @@ impl RustAnalyzerProject {
|
||||||
|
|
||||||
println!("Determined toolchain: {}\n", &toolchain);
|
println!("Determined toolchain: {}\n", &toolchain);
|
||||||
|
|
||||||
self.sysroot_src = (std::path::Path::new(&*toolchain)
|
self.sysroot_src = (std::path::Path::new(toolchain)
|
||||||
.join("lib")
|
.join("lib")
|
||||||
.join("rustlib")
|
.join("rustlib")
|
||||||
.join("src")
|
.join("src")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::exercise::{Exercise, Mode};
|
use crate::exercise::{Exercise, Mode};
|
||||||
use crate::verify::test;
|
use crate::verify::test;
|
||||||
|
@ -36,7 +37,7 @@ pub fn reset(exercise: &Exercise) -> Result<(), ()> {
|
||||||
fn compile_and_run(exercise: &Exercise) -> Result<(), ()> {
|
fn compile_and_run(exercise: &Exercise) -> Result<(), ()> {
|
||||||
let progress_bar = ProgressBar::new_spinner();
|
let progress_bar = ProgressBar::new_spinner();
|
||||||
progress_bar.set_message(format!("Compiling {exercise}..."));
|
progress_bar.set_message(format!("Compiling {exercise}..."));
|
||||||
progress_bar.enable_steady_tick(100);
|
progress_bar.enable_steady_tick(Duration::from_millis(100));
|
||||||
|
|
||||||
let compilation_result = exercise.compile();
|
let compilation_result = exercise.compile();
|
||||||
let compilation = match compilation_result {
|
let compilation = match compilation_result {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::exercise::{CompiledExercise, Exercise, Mode, State};
|
use crate::exercise::{CompiledExercise, Exercise, Mode, State};
|
||||||
use console::style;
|
use console::style;
|
||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use std::env;
|
use std::{env, time::Duration};
|
||||||
|
|
||||||
// Verify that the provided container of Exercise objects
|
// Verify that the provided container of Exercise objects
|
||||||
// can be compiled and run without any failures.
|
// can be compiled and run without any failures.
|
||||||
|
@ -17,9 +17,11 @@ pub fn verify<'a>(
|
||||||
let (num_done, total) = progress;
|
let (num_done, total) = progress;
|
||||||
let bar = ProgressBar::new(total as u64);
|
let bar = ProgressBar::new(total as u64);
|
||||||
let mut percentage = num_done as f32 / total as f32 * 100.0;
|
let mut percentage = num_done as f32 / total as f32 * 100.0;
|
||||||
bar.set_style(ProgressStyle::default_bar()
|
bar.set_style(
|
||||||
.template("Progress: [{bar:60.green/red}] {pos}/{len} {msg}")
|
ProgressStyle::default_bar()
|
||||||
.progress_chars("#>-")
|
.template("Progress: [{bar:60.green/red}] {pos}/{len} {msg}")
|
||||||
|
.expect("Progressbar template should be valid!")
|
||||||
|
.progress_chars("#>-"),
|
||||||
);
|
);
|
||||||
bar.set_position(num_done as u64);
|
bar.set_position(num_done as u64);
|
||||||
bar.set_message(format!("({:.1} %)", percentage));
|
bar.set_message(format!("({:.1} %)", percentage));
|
||||||
|
@ -55,7 +57,7 @@ pub fn test(exercise: &Exercise, verbose: bool) -> Result<(), ()> {
|
||||||
fn compile_only(exercise: &Exercise, success_hints: bool) -> Result<bool, ()> {
|
fn compile_only(exercise: &Exercise, success_hints: bool) -> Result<bool, ()> {
|
||||||
let progress_bar = ProgressBar::new_spinner();
|
let progress_bar = ProgressBar::new_spinner();
|
||||||
progress_bar.set_message(format!("Compiling {exercise}..."));
|
progress_bar.set_message(format!("Compiling {exercise}..."));
|
||||||
progress_bar.enable_steady_tick(100);
|
progress_bar.enable_steady_tick(Duration::from_millis(100));
|
||||||
|
|
||||||
let _ = compile(exercise, &progress_bar)?;
|
let _ = compile(exercise, &progress_bar)?;
|
||||||
progress_bar.finish_and_clear();
|
progress_bar.finish_and_clear();
|
||||||
|
@ -67,7 +69,7 @@ fn compile_only(exercise: &Exercise, success_hints: bool) -> Result<bool, ()> {
|
||||||
fn compile_and_run_interactively(exercise: &Exercise, success_hints: bool) -> Result<bool, ()> {
|
fn compile_and_run_interactively(exercise: &Exercise, success_hints: bool) -> Result<bool, ()> {
|
||||||
let progress_bar = ProgressBar::new_spinner();
|
let progress_bar = ProgressBar::new_spinner();
|
||||||
progress_bar.set_message(format!("Compiling {exercise}..."));
|
progress_bar.set_message(format!("Compiling {exercise}..."));
|
||||||
progress_bar.enable_steady_tick(100);
|
progress_bar.enable_steady_tick(Duration::from_millis(100));
|
||||||
|
|
||||||
let compilation = compile(exercise, &progress_bar)?;
|
let compilation = compile(exercise, &progress_bar)?;
|
||||||
|
|
||||||
|
@ -85,15 +87,24 @@ fn compile_and_run_interactively(exercise: &Exercise, success_hints: bool) -> Re
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(prompt_for_completion(exercise, Some(output.stdout), success_hints))
|
Ok(prompt_for_completion(
|
||||||
|
exercise,
|
||||||
|
Some(output.stdout),
|
||||||
|
success_hints,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile the given Exercise as a test harness and display
|
// Compile the given Exercise as a test harness and display
|
||||||
// the output if verbose is set to true
|
// the output if verbose is set to true
|
||||||
fn compile_and_test(exercise: &Exercise, run_mode: RunMode, verbose: bool, success_hints: bool) -> Result<bool, ()> {
|
fn compile_and_test(
|
||||||
|
exercise: &Exercise,
|
||||||
|
run_mode: RunMode,
|
||||||
|
verbose: bool,
|
||||||
|
success_hints: bool,
|
||||||
|
) -> Result<bool, ()> {
|
||||||
let progress_bar = ProgressBar::new_spinner();
|
let progress_bar = ProgressBar::new_spinner();
|
||||||
progress_bar.set_message(format!("Testing {exercise}..."));
|
progress_bar.set_message(format!("Testing {exercise}..."));
|
||||||
progress_bar.enable_steady_tick(100);
|
progress_bar.enable_steady_tick(Duration::from_millis(100));
|
||||||
|
|
||||||
let compilation = compile(exercise, &progress_bar)?;
|
let compilation = compile(exercise, &progress_bar)?;
|
||||||
let result = compilation.run();
|
let result = compilation.run();
|
||||||
|
@ -123,9 +134,9 @@ fn compile_and_test(exercise: &Exercise, run_mode: RunMode, verbose: bool, succe
|
||||||
|
|
||||||
// Compile the given Exercise and return an object with information
|
// Compile the given Exercise and return an object with information
|
||||||
// about the state of the compilation
|
// about the state of the compilation
|
||||||
fn compile<'a, 'b>(
|
fn compile<'a>(
|
||||||
exercise: &'a Exercise,
|
exercise: &'a Exercise,
|
||||||
progress_bar: &'b ProgressBar,
|
progress_bar: &ProgressBar,
|
||||||
) -> Result<CompiledExercise<'a>, ()> {
|
) -> Result<CompiledExercise<'a>, ()> {
|
||||||
let compilation_result = exercise.compile();
|
let compilation_result = exercise.compile();
|
||||||
|
|
||||||
|
@ -143,7 +154,11 @@ fn compile<'a, 'b>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt_for_completion(exercise: &Exercise, prompt_output: Option<String>, success_hints: bool) -> bool {
|
fn prompt_for_completion(
|
||||||
|
exercise: &Exercise,
|
||||||
|
prompt_output: Option<String>,
|
||||||
|
success_hints: bool,
|
||||||
|
) -> bool {
|
||||||
let context = match exercise.state() {
|
let context = match exercise.state() {
|
||||||
State::Done => return true,
|
State::Done => return true,
|
||||||
State::Pending(context) => context,
|
State::Pending(context) => context,
|
||||||
|
|
|
@ -44,7 +44,7 @@ fn verify_fails_if_some_fails() {
|
||||||
fn run_single_compile_success() {
|
fn run_single_compile_success() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["run", "compSuccess"])
|
.args(["run", "compSuccess"])
|
||||||
.current_dir("tests/fixture/success/")
|
.current_dir("tests/fixture/success/")
|
||||||
.assert()
|
.assert()
|
||||||
.success();
|
.success();
|
||||||
|
@ -54,7 +54,7 @@ fn run_single_compile_success() {
|
||||||
fn run_single_compile_failure() {
|
fn run_single_compile_failure() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["run", "compFailure"])
|
.args(["run", "compFailure"])
|
||||||
.current_dir("tests/fixture/failure/")
|
.current_dir("tests/fixture/failure/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(1);
|
||||||
|
@ -64,7 +64,7 @@ fn run_single_compile_failure() {
|
||||||
fn run_single_test_success() {
|
fn run_single_test_success() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["run", "testSuccess"])
|
.args(["run", "testSuccess"])
|
||||||
.current_dir("tests/fixture/success/")
|
.current_dir("tests/fixture/success/")
|
||||||
.assert()
|
.assert()
|
||||||
.success();
|
.success();
|
||||||
|
@ -74,7 +74,7 @@ fn run_single_test_success() {
|
||||||
fn run_single_test_failure() {
|
fn run_single_test_failure() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["run", "testFailure"])
|
.args(["run", "testFailure"])
|
||||||
.current_dir("tests/fixture/failure/")
|
.current_dir("tests/fixture/failure/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(1);
|
||||||
|
@ -84,7 +84,7 @@ fn run_single_test_failure() {
|
||||||
fn run_single_test_not_passed() {
|
fn run_single_test_not_passed() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["run", "testNotPassed.rs"])
|
.args(["run", "testNotPassed.rs"])
|
||||||
.current_dir("tests/fixture/failure/")
|
.current_dir("tests/fixture/failure/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(1);
|
||||||
|
@ -97,14 +97,17 @@ fn run_single_test_no_filename() {
|
||||||
.arg("run")
|
.arg("run")
|
||||||
.current_dir("tests/fixture/")
|
.current_dir("tests/fixture/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(2)
|
||||||
|
.stderr(predicates::str::contains(
|
||||||
|
"required arguments were not provided",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn run_single_test_no_exercise() {
|
fn run_single_test_no_exercise() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["run", "compNoExercise.rs"])
|
.args(["run", "compNoExercise.rs"])
|
||||||
.current_dir("tests/fixture/failure")
|
.current_dir("tests/fixture/failure")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(1);
|
||||||
|
@ -114,7 +117,7 @@ fn run_single_test_no_exercise() {
|
||||||
fn reset_single_exercise() {
|
fn reset_single_exercise() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["reset", "intro1"])
|
.args(["reset", "intro1"])
|
||||||
.assert()
|
.assert()
|
||||||
.code(0);
|
.code(0);
|
||||||
}
|
}
|
||||||
|
@ -125,9 +128,9 @@ fn reset_no_exercise() {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.arg("reset")
|
.arg("reset")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1)
|
.code(2)
|
||||||
.stderr(predicates::str::contains(
|
.stderr(predicates::str::contains(
|
||||||
"positional arguments not provided",
|
"required arguments were not provided",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +138,7 @@ fn reset_no_exercise() {
|
||||||
fn get_hint_for_single_test() {
|
fn get_hint_for_single_test() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["hint", "testFailure"])
|
.args(["hint", "testFailure"])
|
||||||
.current_dir("tests/fixture/failure")
|
.current_dir("tests/fixture/failure")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
|
@ -171,7 +174,7 @@ fn all_exercises_require_confirmation() {
|
||||||
fn run_compile_exercise_does_not_prompt() {
|
fn run_compile_exercise_does_not_prompt() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["run", "pending_exercise"])
|
.args(["run", "pending_exercise"])
|
||||||
.current_dir("tests/fixture/state")
|
.current_dir("tests/fixture/state")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
|
@ -182,7 +185,7 @@ fn run_compile_exercise_does_not_prompt() {
|
||||||
fn run_test_exercise_does_not_prompt() {
|
fn run_test_exercise_does_not_prompt() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["run", "pending_test_exercise"])
|
.args(["run", "pending_test_exercise"])
|
||||||
.current_dir("tests/fixture/state")
|
.current_dir("tests/fixture/state")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
|
@ -193,7 +196,7 @@ fn run_test_exercise_does_not_prompt() {
|
||||||
fn run_single_test_success_with_output() {
|
fn run_single_test_success_with_output() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["--nocapture", "run", "testSuccess"])
|
.args(["--nocapture", "run", "testSuccess"])
|
||||||
.current_dir("tests/fixture/success/")
|
.current_dir("tests/fixture/success/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
|
@ -204,7 +207,7 @@ fn run_single_test_success_with_output() {
|
||||||
fn run_single_test_success_without_output() {
|
fn run_single_test_success_without_output() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["run", "testSuccess"])
|
.args(["run", "testSuccess"])
|
||||||
.current_dir("tests/fixture/success/")
|
.current_dir("tests/fixture/success/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
|
@ -215,7 +218,7 @@ fn run_single_test_success_without_output() {
|
||||||
fn run_rustlings_list() {
|
fn run_rustlings_list() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["list"])
|
.args(["list"])
|
||||||
.current_dir("tests/fixture/success")
|
.current_dir("tests/fixture/success")
|
||||||
.assert()
|
.assert()
|
||||||
.success();
|
.success();
|
||||||
|
@ -225,7 +228,7 @@ fn run_rustlings_list() {
|
||||||
fn run_rustlings_list_no_pending() {
|
fn run_rustlings_list_no_pending() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["list"])
|
.args(["list"])
|
||||||
.current_dir("tests/fixture/success")
|
.current_dir("tests/fixture/success")
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
|
@ -236,7 +239,7 @@ fn run_rustlings_list_no_pending() {
|
||||||
fn run_rustlings_list_both_done_and_pending() {
|
fn run_rustlings_list_both_done_and_pending() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["list"])
|
.args(["list"])
|
||||||
.current_dir("tests/fixture/state")
|
.current_dir("tests/fixture/state")
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
|
@ -247,7 +250,7 @@ fn run_rustlings_list_both_done_and_pending() {
|
||||||
fn run_rustlings_list_without_pending() {
|
fn run_rustlings_list_without_pending() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["list", "--solved"])
|
.args(["list", "--solved"])
|
||||||
.current_dir("tests/fixture/state")
|
.current_dir("tests/fixture/state")
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
|
@ -258,7 +261,7 @@ fn run_rustlings_list_without_pending() {
|
||||||
fn run_rustlings_list_without_done() {
|
fn run_rustlings_list_without_done() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["list", "--unsolved"])
|
.args(["list", "--unsolved"])
|
||||||
.current_dir("tests/fixture/state")
|
.current_dir("tests/fixture/state")
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
|
|
Loading…
Reference in New Issue