Rust#
Development#
Install Rust via rustup rather than via Homebrew.
Preferences#
Prefer crates in the top 250 according to lib.rs
Read the
Cargo.toml
files of OCP projects for inspiration
See also
Code style#
Avoid matching an Option or Result. Instead, use Option and Result methods.
Don’t panic. This includes
panic!
,unreachable!
,unwrap()
andexpect()
.
See also
Macros#
Prefer functions, but use macros if you need:
Variadic arguments, like
println!
orvec!
.Code generation at the item level, like creating structs.
Code generation at the expression level, like accessing struct fields dynamically.
Troubleshooting#
If you’re getting confusing compile errors, especially any involving type annotations, check that:
You wrote enough code. If you produce results that you don’t use, the compiler still wants to determine their definite type. Adding more code to give the compiler a hint can spare adding optional type annotations.
Your annotations are correct. If you change your code but don’t change your annotations, the compiler might report errors that are distantly related to the misannotation.
You duck type using trait objects: for example,
Box<dyn Read>
to usestd::io:stdin()
andFile::open(file).unwrap()
interchangeably. The compiler can’t determine which traits are relevant across the two types.
If errors relate to ownership, try:
Continuous integration#
Create a .github/workflows/ci.yml
file. As a base, use:
name: CI
on: [push, pull_request]
jobs:
build:
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.os }}
# https://github.com/Swatinem/rust-cache/issues/93#issuecomment-1321064841
- run: cargo update
# https://github.com/taiki-e/cargo-llvm-cov#on-github-actions
- uses: taiki-e/install-action@cargo-llvm-cov
- run: cargo llvm-cov --lcov --output-path lcov.info
- if: matrix.os == 'ubuntu-latest'
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: lcov.info
Release process#
Ensure that you are on an up-to-date
main
branch:git checkout main git pull --rebase
Ensure that the package is ready for release:
All tests pass on continuous integration
The version number is correct in
Cargo.toml
The changelog is up-to-date and dated
Tag the release, replacing
x.y.z
twice:git tag -a x.y.z -m 'x.y.z release.'
Push the release:
git push --follow-tags
Edit the GitHub release that is created by GitHub Actions, to add the
description
value fromCargo.toml
followed by the relevant section of the changelog.If the software has a formula in our Homebrew tap, update the
url
andsha256
values. For example, from thehomebrew-tap
directory, after updating theurl
values, prepare thesha256
values for theocdscardinal
formula with:grep --only-matching -E 'https://.+zip' Formula/ocdscardinal.rb | xargs -I{} sh -c 'curl -sSL {} | shasum -a 256'
Then, push the changes.
Publish the crate:
cargo publish
Announce on the discussion group if relevant
Reference#
Rust has no:
Introductions#
The Rust Programming Language: Moving Captured Values Out of Closures and the Fn Traits
Exercism Rust Track: Read the most upvoted community solution after each exercise.
Unofficial community Discord, in particular
#rust-help
and#rust-beginners
Tip
Use Rust Playground to test code snippets.
I prefer Exercism to Rustlings (https://github.com/rust-lang/rustlings). Rustlings’ exercises often repeat examples from The Rust Programming Language, and are often solved by the compiler’s feedback.
I don’t find it useful to read the examples in Rust by Example (https://doc.rust-lang.org/rust-by-example/), but I occasionally read it when it’s a search result.
Topics#
Reference#
docs.rs for crate documentation
Tip
Scroll up after the page loads to access the within-crate search bar