Pinned oot
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.

The `.collect()` method on iterators can construct many different types, and is extensible via FromIterator trait.

Here's the list of supported types in the standard library:

doc.rust-lang.org/std/iter/tra

You read it as FromIterator</* type of items in the iterator */> for /* type it makes */

If you want to rush a function to return quicker, write:

fn foo() -> i32 {
return return return return return !!!!!!!!!!111;
}

reddit.com/r/rust/comments/g5r

borrow checker won't let you call a method that takes &mut self and a reference to something else in the same struct:

self.mutate_item(&self.item) // :(

There are a few workarounds for this:

smallcultfollowing.com/babyste

Rust tips boosted

async {} block in behaves like a closure. It does _not_ run any code automatically. It only creates an inactive object, which has to be spawned or awaited to start doing anything.

Example of incorrect usage:

fn main() {
async {
println!("closure");
return;
};
println!("surprise");
}

It prints "surprise", and nothing else!

Rust tips boosted

If you want to create an async stream, the easy solution is a generator macro:

lib.rs/async-stream

It lets you write the stream as a loop with `yield` instead of implementing traits and managing state manually.

If you're wondering why your project is pulling in a certain dependency, you can find out with:

cargo tree -i dependency_name

You can also find duplicate (usually outdated) dependencies with:

cargo tree -d

constants create a new temporary value every time you mention them.

You can do with whatever you want with the temporary value from a constant, even mutate it. But it only affects each temporary copy, not the constant.

```
use std::cell::Cell;

const C: Cell<bool> = Cell::new(false);

fn main() {
C.set(true);
assert_eq!(false, C.get());
}
```

If your project depends on a Nightly version of the compiler, you can create `rust-toolchain` file with the required version. It will make Cargo automatically switch to the right compiler for the build.

rust-lang.github.io/rustup/ove

If you're defining an alias for your crate's Result type, instead of:

type Result<T> = std::result::Result<T, MyError>;

use:

type Result<T, E = MyError> = std::result::Result<T, E>;

This still works as `Result<()>`, but doesn't cause errors when someone accidentally shadows std's Result with it. It also makes Rustdoc display the error type explicitly in the documentation.

Rust tips boosted

I've had a but of trouble with modules in #rust. It's different in style than what I'm used to in #python it #r.

This blog post has a good, clear explanation of what you need to do and what's going on, with some good simple examples

sheshbabu.com/posts/rust-modul

Rust tips boosted

cargo install cargo-edit

and you'll be able to add dependencies with just

cargo add <crate-name>

Rust tips boosted

If you have an iterator of `Result`s, you can collect and unwrap all values into a `Vec` on success or return the first `Err` found:

let files_contents = file_names.iter().map(read_file).collect::<Result<Vec<_>, _>>()?;

If you did `.collect::<Vec<_>>()` instead, you'd have an array of mixed `Ok`/`Err` values.

See in playground: is.gd/4GZ45I

If you want to create an async stream, the easy solution is a generator macro:

lib.rs/async-stream

It lets you write the stream as a loop with `yield` instead of implementing traits and managing state manually.

Rust tips boosted

When you create a function expecting an optional reference, use `Option<&Foo>` rather than `&Option<Foo>`.

fn optional(good: Option<&Foo>, bad: &Option<Foo>) {…}

Both optimize to the same representation, but `Option<&Foo>` is easier to work with, and is more universal, because it can be cheaply created from an owned option with `.as_ref()`.

Does your crate have optional features? Are you sure all combinations of the feature flags work correctly? You can verify this with this cargo plugin: lib.rs/cargo-all-features

In you can cast concrete type to an abstract trait object (e.g. `&i32` as `&dyn Debug`), but you can't (yet) cast a trait object as another trait (e.g. `dyn Error` can't be cast as `dyn Debug`).

The workaround is to add a method to the trait that asks for a different dyn type (e.g. `as_debug(&self) -> &dyn Debug`). That allows trait implementers to cast their concrete type.

This workaround can be automated: stackoverflow.com/a/28664881/2

async {} block in behaves like a closure. It does _not_ run any code automatically. It only creates an inactive object, which has to be spawned or awaited to start doing anything.

Example of incorrect usage:

fn main() {
async {
println!("closure");
return;
};
println!("surprise");
}

It prints "surprise", and nothing else!

Dropping of a stops its execution. There's also a higher-level wrapper that makes Futures cancellable on demand:

docs.rs/futures/0.3.4/futures/

Show older
Octodon

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