summaryrefslogtreecommitdiffstats
path: root/software/rust.page
blob: 4e8aa447403a7f91b3ab66ed221930f0f5198dc8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Rust
==================

## Resources

- <http://xion.io/post/code/rust-iter-patterns.html>
- <https://deterministic.space/rust-cli-tips.htm>
- <https://manishearth.github.io/blog/2018/01/10/whats-tokio-and-async-io-all-about/>
- <https://saghm.github.io/five-rust-things/>

Optimization: use `RUSTFLAGS="-C target-cpu=native"` to take advantage of CPU
special features.

(via http://vfoley.xyz/rust-compilation-tip/)

For local rust/std documentation, do `rustup doc`.

## Little tricks

Run tests with stdout output:

    cargo test -- --nocapture

To run tests with logging enabled (eg, with `env_logger`), make sure you add
`env_logger::init()` to the test function itself.


## map() and Result Ergonomics

`.collect()` has some magical features! In addition to turning an iterator of
`Item` into `Vec<Item>`, it will turn an iterator of `Result<Item>` into
`Result<Vec<Item>>`. This makes it really useful for the end of functions.

This is particularly useful for resolving some categories of "error handling in
map closures": you can use `?` in the map closure as long as you wrap the happy
path with `Ok()` and call collect on the outside. Eg:

    let list: Vec<Item> = junk
        .iter()
        .map(|thing| Ok(Item {
            a: thing.a,
            b: fixup(thing.widget)?,
        }))
        .collect::Result<Vec<Item>>()?;

What about when `map` over an `Option`? Eg:

    let toy = Shiny {
        a: 123,
        b: component.map(|v| paint(v).expect("paint to succeed"),
    };

Should use match in this case:

    let toy = Shiny {
        a: 123,
        b: match component {
            None => None,
            Some(v) => Some(paint(v)?),
        },
    };