1
0
mirror of https://github.com/rust-lang/rustlings.git synced 2025-05-27 22:57:45 +02:00

Add templates

This commit is contained in:
mo8it 2025-05-16 23:11:08 +02:00
parent 74ab9924b4
commit 7ec6986965
11 changed files with 392 additions and 8 deletions

View File

@ -7,6 +7,12 @@ build_search_index = false
[markdown]
highlight_code = true
highlight_theme = "ayu-mirage"
insert_anchor_links = "heading"
[extra]
logo_path = "images/happy_ferris.svg"
[[extra.menu_items]]
name = "Home"

143
website/content/_index.md Normal file
View File

@ -0,0 +1,143 @@
+++
+++
Greetings and welcome to Rustlings.
This project contains small exercises to get you used to reading and writing Rust code.
This includes reading and responding to compiler messages!
It is recommended to do the Rustlings exercises in parallel to reading [the official Rust book](https://doc.rust-lang.org/book/), the most comprehensive resource for learning Rust 📚️
<!-- toc -->
## Getting Started
### Installing Rust
Before installing Rustlings, you need to have the **latest version of Rust** installed.
Visit [www.rust-lang.org/tools/install](https://www.rust-lang.org/tools/install) for further instructions on installing Rust.
This will also install _Cargo_, Rust's package/project manager.
> 🐧 If you are on Linux, make sure you have installed `gcc` (for a linker).
>
> Deb: `sudo apt install gcc`
>
> Dnf: `sudo dnf install gcc`
> 🍎 If you are on MacOS, make sure you have installed Xcode and its developer tools by running `xcode-select --install`.
### Installing Rustlings
The following command will download and compile Rustlings:
```bash
cargo install rustlings
```
<details>
<summary><strong>If the installation fails…</strong> (<em>click to expand</em>)</summary>
- Make sure you have the latest Rust version by running `rustup update`
- Try adding the `--locked` flag: `cargo install rustlings --locked`
- Otherwise, please [report the issue](https://github.com/rust-lang/rustlings/issues/new)
</details>
### Initialization
After installing Rustlings, run the following command to initialize the `rustlings/` directory:
```bash
rustlings init
```
<details>
<summary><strong>If the command <code>rustlings</code> can't be found…</strong> (<em>click to expand</em>)</summary>
You are probably using Linux and installed Rust using your package manager.
Cargo installs binaries to the directory `~/.cargo/bin`.
Sadly, package managers often don't add `~/.cargo/bin` to your `PATH` environment variable.
The solution is to …
- either add `~/.cargo/bin` manually to `PATH`
- or to uninstall Rust from the package manager and install it using the official way with `rustup`: https://www.rust-lang.org/tools/install
</details>
Now, go into the newly initialized directory and launch Rustlings for further instructions on getting started with the exercises:
```bash
cd rustlings/
rustlings
```
## Working environment
### Editor
Our general recommendation is [VS Code](https://code.visualstudio.com/) with the [rust-analyzer plugin](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer).
But any editor that supports [rust-analyzer](https://rust-analyzer.github.io/) should be enough for working on the exercises.
### Terminal
While working with Rustlings, please use a modern terminal for the best user experience.
The default terminal on Linux and Mac should be sufficient.
On Windows, we recommend the [Windows Terminal](https://aka.ms/terminal).
## Doing exercises
The exercises are sorted by topic and can be found in the subdirectory `exercises/<topic>`.
For every topic, there is an additional `README.md` file with some resources to get you started on the topic.
We highly recommend that you have a look at them before you start 📚️
Most exercises contain an error that keeps them from compiling, and it's up to you to fix it!
Some exercises contain tests that need to pass for the exercise to be done ✅
Search for `TODO` and `todo!()` to find out what you need to change.
Ask for hints by entering `h` in the _watch mode_ 💡
### Watch Mode
After the [initialization](#initialization), Rustlings can be launched by simply running the command `rustlings`.
This will start the _watch mode_ which walks you through the exercises in a predefined order (what we think is best for newcomers).
It will rerun the current exercise automatically every time you change the exercise's file in the `exercises/` directory.
<details>
<summary><strong>If detecting file changes in the <code>exercises/</code> directory fails…</strong> (<em>click to expand</em>)</summary>
> You can add the **`--manual-run`** flag (`rustlings --manual-run`) to manually rerun the current exercise by entering `r` in the watch mode.
>
> Please [report the issue](https://github.com/rust-lang/rustlings/issues/new) with some information about your operating system and whether you run Rustlings in a container or virtual machine (e.g. WSL).
</details>
### Exercise List
In the [watch mode](#watch-mode) (after launching `rustlings`), you can enter `l` to open the interactive exercise list.
The list allows you to…
- See the status of all exercises (done or pending)
- `c`: Continue at another exercise (temporarily skip some exercises or go back to a previous one)
- `r`: Reset status and file of the selected exercise (you need to _reload/reopen_ its file in your editor afterwards)
See the footer of the list for all possible keys.
## Questions?
If you need any help while doing the exercises and the builtin-hints aren't helpful, feel free to ask in the [_Q&A_ category of the discussions](https://github.com/rust-lang/rustlings/discussions/categories/q-a?discussions_q=) if your question wasn't asked yet 💡
## Continuing On
Once you've completed Rustlings, put your new knowledge to good use!
Continue practicing your Rust skills by building your own projects, contributing to Rustlings, or finding other open-source projects to contribute to.
## Uninstalling Rustlings
If you want to remove Rustlings from your system, run the following command:
```bash
cargo uninstall rustlings
```

View File

@ -0,0 +1,66 @@
+++
title = "Custom Exercises"
+++
Custom exercises are a set of exercises maintained by the community.
You can use the same `rustlings` program that you installed with `cargo install rustlings` to run them:
- 🇯🇵 [Japanese Rustlings](https://github.com/sotanengel/rustlings-jp):A Japanese translation of the Rustlings exercises.
- 🇨🇳 [Simplified Chinese Rustlings](https://github.com/SandmeyerX/rustlings-zh-cn): A simplified Chinese translation of the Rustlings exercises.
Do you want to create your own set of Rustlings exercises to focus on some specific topic?
Or do you want to translate the original Rustlings exercises?
<!-- toc -->
The support of Rustlings for custom exercises allows you to create your own set of Rustlings exercises to focus on some specific topic.
You could also offer a translation of the original Rustlings exercises as custom exercises.
## Getting started
To create custom exercises, install Rustlings and run `rustlings dev new PROJECT_NAME`.
This command will, similar to `cargo new PROJECT_NAME`, create a template directory called `PROJECT_NAME` with all what you need to get started.
Read the comments in the generated `info.toml` file to understand its format.
It allows you to set a custom welcome and final message and specify the metadata of every exercise.
## Create an exercise
Here is an example of the metadata of one file:
```toml
[[exercises]]
name = "intro1"
hint = """
To finish this exercise, you need to …
This link might help you …"""
```
After entering this in `info.toml`, create the file `intro1.rs` in the `exercises/` directory.
The exercise needs to contain a `main` function, but it can be empty.
Adding tests is recommended.
Look at the official Rustlings exercises for inspiration.
You can optionally add a solution file `intro1.rs` to the `solutions/` directory.
Now, run `rustlings dev check`.
It will tell you about any issues with your exercises.
For example, it will tell you to run `rustlings dev update` to update the `Cargo.toml` file to include the new exercise `intro1`.
`rustlings dev check` will also run your solutions (if you have any) to make sure that they run successfully.
That's it!
You finished your first exercise 🎉
## Publish
Now, add more exercises and publish them as a Git repository.
Users just have to clone that repository and run `rustlings` in it to start working on your set of exercises just like the official ones.
One difference to the official exercises is that the solution files will not be hidden until the user finishes an exercise.
But you can trust the users to not look at the solution too early 😉
## Share
After publishing your set of exercises, open an issue or a pull request in the official Rustlings repository to link to your project in the README 😃

View File

@ -2,22 +2,22 @@
@layer base {
h1 {
@apply text-4xl mt-3 mb-3 text-gray-50 font-bold;
@apply text-4xl mt-3 mb-3 font-bold;
}
h2 {
@apply text-3xl mt-4 mb-1.5 text-gray-50 font-bold;
@apply text-3xl mt-4 mb-1.5 font-bold;
}
h3 {
@apply text-2xl mt-5 mb-1.5 text-gray-50 font-bold;
@apply text-2xl mt-5 mb-1.5 font-bold;
}
h4 {
@apply text-xl mt-6 mb-1.5 text-gray-50 font-bold;
@apply text-xl mt-6 mb-1.5 font-bold;
}
p {
@apply mb-2;
}
a {
@apply text-[#F74C00] underline hover:decoration-orange-400 transition duration-300;
@apply text-[#FFC832] underline hover:decoration-orange-400 transition duration-300;
}
ul {
@apply mt-2 mb-3 ml-1 list-disc list-inside marker:text-sky-600;
@ -41,11 +41,11 @@
@apply max-w-full w-full h-full mx-auto my-5 object-contain md:w-3/4 lg:w-3/5 rounded-sm shadow-sm;
}
blockquote {
@apply p-4 my-3 border-s-4 border-gray-300 bg-gray-800 italic;
@apply px-3 pt-2 pb-0.5 my-4 border-s-4 border-white/80 bg-white/7 rounded-sm italic;
}
pre {
@apply px-2 pt-2 pb-px overflow-x-auto text-sm sm:text-base rounded-sm mt-2 mb-4 after:content-[attr(data-lang)] after:text-[8px] after:opacity-40 selection:bg-gray-500/75;
@apply px-2 pt-2 pb-px overflow-x-auto text-sm sm:text-base rounded-sm mt-2 mb-4 after:content-[attr(data-lang)] after:text-[8px] after:opacity-40 selection:bg-white/15;
}
pre code mark {
@apply pb-0.5 pt-1 pr-px text-inherit rounded-xs;

View File

@ -2,4 +2,4 @@ zola:
zola serve --open
tailwind:
fnm exec --using latest npx @tailwindcss/cli -i input.css -o static/main.css
fnm exec --using latest npx @tailwindcss/cli -w -i input.css -o static/main.css

View File

@ -0,0 +1,16 @@
{% extends "base.html" %}
{% import "macros.html" as macros %}
{% block content %}
<div class="flex flex-col mx-auto text-center">
<h1>DON'T PANIC!</h1>
<h2>404: Page not found!</h2>
<img class="max-h-[50vh]"
src="{{ get_url(path='images/panic.svg') | safe }}"
alt="">
{{ macros::btn(link=get_url(path="/") , content="Back to the homepage") }}
</div>
{% endblock %}

View File

@ -0,0 +1,2 @@
<a class="text-white no-underline transition-none hover:underline"
href="#{{ id }}"></a>

View File

@ -0,0 +1,83 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{%- set timestamp = now(timestamp=true) -%}
{%- if page.title -%}
{% set_global title = page.title %}
{%- elif section.title -%}
{% set_global title = section.title %}
{%- else -%}
{% set_global title = config.title %}
{%- endif -%}
{%- if page.description -%}
{% set_global description = page.description %}
{%- elif section.description -%}
{% set_global description = section.description %}
{%- else -%}
{% set_global description = config.description %}
{%- endif -%}
{%- if page.permalink -%}
{% set_global permalink = page.permalink %}
{%- elif section.permalink -%}
{% set_global permalink = section.permalink %}
{%- endif %}
<title>{%- block title -%}{{- title -}}{%- endblock -%}</title>
<meta name="description"
content="{%- block description -%}{{- description -}}{%- endblock -%}">
<link rel="icon"
type="image/x-icon"
href="{{ get_url(path=config.extra.logo_path) | safe }}?v={{ timestamp }}">
<link href="{{ get_url(path='main.css') | safe }}?v={{ timestamp }}"
rel="stylesheet">
<meta property="og:title" content="{{ title }}">
<meta property="og:description" content="{{ description }}">
<meta property="og:image"
content="{{ get_url(path=config.extra.logo_path) | safe }}?v={{ timestamp }}">
{% if permalink %}<meta property="og:url" content="{{ permalink | safe }}">{% endif %}
</head>
<body class="flex flex-col p-3 mx-auto min-h-screen text-lg text-white break-words bg-[#2A3439] lg:px-5 2xl:container">
<header class="flex gap-x-6 items-center py-2 px-2.5 mb-1 bg-black/30 rounded-full">
<a class="transition duration-500 hover:scale-110"
href="{{ get_url(path='/') | safe }}"
aria-hidden="true">
<img class="m-0 w-12 h-12 rounded-full"
src="{{ get_url(path=config.extra.logo_path) | safe }}"
alt="">
</a>
<nav class="flex gap-x-6 items-center font-bold">
{% for menu_item in config.extra.menu_items %}
<a class="p-1 no-underline" href="{{ menu_item.url | safe }}">{{ menu_item.name }}</a>
{% endfor %}
</nav>
</header>
<main class="leading-relaxed">
{% block content %}{% endblock %}
</main>
<footer class="pt-2 pb-3 mt-auto">
<img class="m-0 mx-auto w-20 h-20"
src="{{ get_url(path='images/happy_ferris.svg') | safe }}"
alt="">
<nav class="flex flex-col gap-y-3 justify-around py-3 text-center bg-black/30 rounded-sm sm:flex-row sm:rounded-full">
{% for footer_item in config.extra.footer_items %}
<a class="text-sm no-underline" href="{{ footer_item.url | safe }}">{{ footer_item.name }}</a>
{% endfor %}
</nav>
</footer>
</body>
</html>

View File

@ -0,0 +1,11 @@
{% extends "base.html" %}
{% import "macros.html" as macros %}
{% block content %}
<div class="m-3">
<h1>Rustlings</h1>
{{ section.content | replace(from="<!-- toc -->", to=macros::toc() ) | safe }}
</div>
{% endblock %}

View File

@ -0,0 +1,46 @@
{% macro toc() %}
<p class="p-1 my-4 text-base rounded-sm sm:hidden bg-yellow-200/20">Landscape mode recommended on mobile devices</p>
{%- if page.toc -%}
{% set_global toc = page.toc %}
{%- else -%}
{% set_global toc = section.toc %}
{%- endif -%}
{% if toc %}
<div class="px-4 py-0.5 my-3 border-s-4 rounded-xl border-double">
<nav>
<ul class="ml-0 list-none">
{% for parent in toc %}
{% if parent.level == 2 %}
<li>
{#- -#}
<a href="{{ parent.permalink | safe }}">{{ parent.title }}</a>
{#- -#}
{% if parent.children %}
<ul class="my-0 ml-5 list-none">
{% for child in parent.children %}
{% if child.level == 3 %}
<li>
{#- -#}
<a class="text-base" href="{{ child.permalink | safe }}">{{ child.title }}</a>
{#- -#}
</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
{#- -#}
</li>
{% endif %}
{% endfor %}
</ul>
</nav>
</div>
{% endif %}
{% endmacro %}
{% macro btn(link, content) %}
<a class="py-1.5 px-3 my-2 no-underline bg-gray-800 rounded-xl transition duration-500 hover:scale-[1.02]"
href="{{ link | safe }}">{{ content | safe }}</a>
{% endmacro %}

View File

@ -0,0 +1,11 @@
{% extends "base.html" %}
{% import "macros.html" as macros %}
{% block content %}
<article>
<h1>{{ page.title }}</h1>
{{ page.content | replace(from="<!-- toc -->", to=macros::toc() ) | safe }}
</article>
{% endblock %}