Pinned post

You can easily pass ownership of objects to C. There's no need to use `Box::into_raw()` or any unsafe trickery. Box is FFI-safe, and can be used as a return type directly:

Did you know has added new categories? Make your crate easier to find. Add categories to your Cargo.toml:

categories = ["insert category slugs here"]

Rust tips boosted

#TIL that you can disallow certain types in your #Rust code with #Clippy (since 1.55):

This is useful, if you e.g. want to use a faster HashMap (e.g. from ahash) and not the std HashMap.

Official docs:

#Lint #RustLang

Compare the uncomparable! enum variants can be compared with `==` only if they implement the `PartialEq` trait, but that isn't always available or convenient for enums with complex data.
However, the `match` expression always works, and there's a handy `matches!()` macro for one-off comparisons.

if value == SomeEnum::Variant(data) { /* maybe */ }
if matches!(value, SomeEnum::Variant(_)) { /* ok */ }

More examples:

If you're developing or applications, you can add dependencies to your projects using

cargo clippy --fix

will automatically apply code improvement suggestions from Clippy. Not every issue can be automatically corrected, so it's still worth running `cargo clippy` afterwards.

Common Rust Lifetime Misconceptions — very helpful resource that helps avoid fighting the borrow checker:

Rust tips boosted

Use the following to include your README in your `doctest`s (so that your examples in your README are also executed).

#[doc = include_str!("../")]
pub struct ReadmeDoctests;

See here:

#Rust #RustLang #RustDoc #Documentation #Docs #RustTip

You can convert a slice (or a `Vec`) to a fixed-length array using the `TryInto` trait:

let arr: [_; 4] = slice[..4].try_into().unwrap();

It's a bit verbose, but the `.try_into().unwrap()` part will be optimized out entirely whenever the compiler can see the slice is long enough.

"Unfortunately" this doesn't generalize to all attributes, so you can't have a cursed syntax like that:

struct Lol {
#![derive(Copy, Clone, Debug)]

fn nope() {

Show thread

has meta attributes that can apply to entire modules, like #[cfg(…)], #[allow(…)] and #[deny(…)].

The #[…] attribute syntax used outside of a module is equivalent to #![…] syntax inside it:

mod win {

mod win {

You have to use #![…] attribute syntax at the top of the file, because there's no outer file that has the `mod` declaration for

The `.get()` method on a `Vec` or `HashMap` will only temporarily borrow an item, and you won't be allowed to move it or use it outside of the scope of the `.get()` call.

If you want to get an _owned_, freely movable value, use `.remove()` instead.

If you need to have an owned value without removing elements from the collection, you're going to have to clone. Clone can be fast if items are wrapped in `Rc` or `Arc`.

Do you want io::Read::read_exact(), but read into a Vec instead?

let bytes_read = reader
.by_ref() // optional: avoids consuming the reader
.take(length_to_read) // limits number of bytes
.read_to_end(&mut vec)?; // reads up to the limit
// the file could have ended sooner, so needs a check
if bytes_read != length_to_read { return Err("EOF") }

A few design patterns/idioms that you need to change if you're switching from to :

Rust tips boosted

Cargo crate stats:

Number of #Rust users is growing exponentially. Downloads are more than doubling each year.

A quick way to update all your dependencies to their latest versions:

cargo install cargo-edit
cargo upgrade

It's worth bumping all versions to the latest regularly, because your code may be accidentally depending on newly-added features.
Cargo usually picks latest available versions, but not always. If you don't explicitly test with older versions of your dependencies, you can't promise they still work.

Try and weep:

cargo +nightly -Z minimal-versions generate-lockfile

Version numbers in Cargo mean this version *or later* that is semver-compatible.

nom = "6.0.0"

will actually use nom 6.1.2 (or any later version lower than 7.0.0).

Forcing an exact version requires a "=" prefix, but don't pin dependencies like that unless necessary: it can cause dependency conflicts.

Cargo may pick a less-than-latest verison to satisfy other dependencies or Cargo.lock, so make sure your project actually works with the versions you specify.

If you're implementing an Iterator for a complex custom collection in , implement optimized `try_fold`.

This method allows keeping state during iteration more efficiently than `.next()` allows, and may optimize better.

Rust tips boosted

`#[deny(warnings)]` will sooner or later break your code.

keeps adding new warnings and refining behavior of existing ones. If you're not prepared to deal with potential new compilation errors every 6 weeks, don't use #[deny(warnings)].

Rustc has a cap-lints feature to disable this footgun in dependencies, but it doesn't help macro-generated code and top-level crates.

Show older

The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!