Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/zkat/rust-notes
Personal notes while learning Rust. Mainly documenting pain points along the way.
https://github.com/zkat/rust-notes
Last synced: 13 days ago
JSON representation
Personal notes while learning Rust. Mainly documenting pain points along the way.
- Host: GitHub
- URL: https://github.com/zkat/rust-notes
- Owner: zkat
- Created: 2019-05-31T22:48:55.000Z (over 5 years ago)
- Default Branch: latest
- Last Pushed: 2019-06-02T17:36:37.000Z (over 5 years ago)
- Last Synced: 2024-10-17T16:34:08.023Z (17 days ago)
- Size: 10.7 KB
- Stars: 145
- Watchers: 13
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
Awesome Lists containing this project
README
# Rust Bumps
This is a collection of notes I have on sharp edges I've encountered in my
journey to learn Rust, in hopes that I can use them in the future to target
contributions to Rust proper, or to share with others who might be interested.## Contribution Process
It wasn't immediately clear what the process of actually contributing to Rust
proper is.### Solutions
I went to `#beginners` in the Rust discourse, and they pointed me at the
forum, where I'd need to bring it up, try and get some buy-in around my change
concept, then put together an RFC when enough(?) people have shown interest,
and then finally that RFC would point to an implementation.## Builders
The builder pattern is super common in Rust. Almost obnoxiously so. To the
point where I wonder if Rust should have some sort of first-class support or
new language feature that largely obsoletes the need for the pattern.### Solutions
In general the pattern is often replaced by things like variadic functions or
ad-hoc option arguments in other languages.This isn't a terrible pattern, but even going as far as introducing
https://crates.io/crates/derive_builder into the language or into the Book
would be nice.## Multi-type errors
The book doesn't really cover a pretty basic case in earnest: the situation
where you have multiple different error returns and you want to use `?`.### Solutions
Establishing an error-definition pattern a-la https://crates.io/crates/failure
in the Book would be super helpful, if not integrating `failure` itself.Update: I'm supposed to use `failure`, not `error-chain`, per @ag_dubs. SIGH
Update: The plot thickens! https://twitter.com/hoodie_de/status/1135192684916879360 claims I should not be returning failure::Error from public APIs but this is not clear at all and I'm not sure what the expected alternative is.
## Returning iterators
Iterators are super duper useful! Infortunately, it's super hard to figure out
how to -return- them from functions. The compiler errors when you first try to
do this are incredibly opaque and confusing.### Solution
It turns out these days, you have `-> impl Iterator` which makes this work,
but this was not very obvious and the compiler errors were SUPER CONFUSING
about how to fix this. It might go a long way to have the compiler be aware of
at _least_ the Iterator case. Those compiler messages, wwhoo.## WTF is `AsRef`?
I kept seeing this `AsRef` stuff while working with `Path`-related functionality and didn't really understand why folks were doing that instead of `path: &Path` in function signatures.
### Solutions
This isn't really covered in the Book, and maybe it should. A friend proceeded to explain the use and intent: It's used as a perf-cheap version of `From` to convert from one immutable ref to another immutable ref. In this **particular** case, it was being used so you could pass Paths, PathBufs, _or_ strings into the function and have it work with any of those types.
It would be nice to make a note in the Book about this being a convention, or becoming one?
## Weird File API
The File-related APIs are really strange and factored in such a way that I had a really hard time finding what I needed, compared to the relatively flat `fs` module in Node.js.
I think the biggest pain is that some things seem to live in `fs::`, some in `io::` and others in `fs::File`, and it wasn't clear when one vs the other was used. The toplevel `fs::` utilities are actually pretty handy, though!
### Solutions
idk. Changing this fundamentally would have a huge impact, unfortunately, and
Rust is very stability-oriented these days. I kinda wish there were a simpler,
higher-level, zero-cost crate for doing these things, optionally with
`Future`s, and for the `fs` and `io` stuff to largely be considered "internal
use only" building blocks, if even that. I just plain don't like it and find
it hard to work with. Maybe [`Tokio`](https://crates.io/crates/tokio) is the
answer, once it's updated with [email protected]?## Literally no chown?
So the `fs` API has literally no `chown` functionality. I know it's pretty
niche, but I needed it!### Solutions
This is exposed through direct bindings by
[`nix`](https://crates.io/crates/nix). There's also a higher-level
[`chownr`](https://crates.io/crates/chownr) crate by yours truly that does the
recursive bit.## Everyone uses `extern crate`
...but you're supposed to just use `use`. This is mostly an annoyance because everyone's docs are outdated and still refer people to importing using this. As an additional note, a lot of places combine this statement with `#![macro_use]` when importing macros.
### Solutions
Highlighting that `extern crate` isn't used anymore, in the Book, might be
super helpful here. The rest is just waiting out the ecosystem. I'm not really
sure what the actual expected alternative to `#![macro_use]` is supposed to
be, but I had some luck directly `use`-ing the macro into my scope like a
function? So a macro named `foo` in crate `bar` would be imported with `use
bar::foo;` and then the macro seemed to work...## No `cargo version` built-in
Coming from Node, this feels like a sharp corner: I have to manually edit
Cargo.toml, change the version, run `cargo build` to update the `Cargo.lock`
so I don't end up with a random diff, then I have to manually `git ci -a -m
'vX.Y.Z'`, `git tag -a vX.Y.Z`, fill in a message, `git push --follow-tags`,
and **then** `cargo publish`. Just for a basic release. I'm used to at least
having a baseline of `npm version patch && git push --follow-tags && npm pub`.### Solution
Having a _baseline_ `cargo version` built in would go a long way towards
making publishing as a newbie a smoother process.## No `nyc` equivalent for coverage
There's no single coverage tool you can just install that integrates with
`cargo test` and gives useful coverage feedback in the command line, works
with coveralls/codecov, etc. The best you get is something [as described in
this 3-year-old forum
thread](https://users.rust-lang.org/t/howto-generating-a-branch-coverage-report/8524)
which... honestly I'm not going to bother because this is an immense amount of
fucking around with stuff just to get my percentages?I'm so used to having [`nyc`](https://npm.im/nyc) available :()
### Solution
Rust -really- needs an `nyc` port.