{"id":13465075,"url":"https://github.com/zkat/rust-notes","last_synced_at":"2025-06-15T03:03:43.184Z","repository":{"id":65998201,"uuid":"189667020","full_name":"zkat/rust-notes","owner":"zkat","description":"Personal notes while learning Rust. Mainly documenting pain points along the way.","archived":false,"fork":false,"pushed_at":"2019-06-02T17:36:37.000Z","size":11,"stargazers_count":146,"open_issues_count":1,"forks_count":2,"subscribers_count":12,"default_branch":"latest","last_synced_at":"2025-06-15T03:03:41.726Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zkat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":["zkat"]}},"created_at":"2019-05-31T22:48:55.000Z","updated_at":"2025-06-11T12:14:19.000Z","dependencies_parsed_at":"2023-03-13T20:31:24.178Z","dependency_job_id":null,"html_url":"https://github.com/zkat/rust-notes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zkat/rust-notes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkat%2Frust-notes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkat%2Frust-notes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkat%2Frust-notes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkat%2Frust-notes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zkat","download_url":"https://codeload.github.com/zkat/rust-notes/tar.gz/refs/heads/latest","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkat%2Frust-notes/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259914899,"owners_count":22931324,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T14:00:57.579Z","updated_at":"2025-06-15T03:03:43.157Z","avatar_url":"https://github.com/zkat.png","language":null,"funding_links":["https://github.com/sponsors/zkat"],"categories":["Others"],"sub_categories":[],"readme":"# Rust Bumps\n\nThis is a collection of notes I have on sharp edges I've encountered in my\njourney to learn Rust, in hopes that I can use them in the future to target\ncontributions to Rust proper, or to share with others who might be interested.\n\n## Contribution Process\n\nIt wasn't immediately clear what the process of actually contributing to Rust\nproper is.\n\n### Solutions\n\nI went to `#beginners` in the Rust discourse, and they pointed me at the\nforum, where I'd need to bring it up, try and get some buy-in around my change\nconcept, then put together an RFC when enough(?) people have shown interest,\nand then finally that RFC would point to an implementation.\n\n## Builders\n\nThe builder pattern is super common in Rust. Almost obnoxiously so. To the\npoint where I wonder if Rust should have some sort of first-class support or\nnew language feature that largely obsoletes the need for the pattern.\n\n### Solutions\n\nIn general the pattern is often replaced by things like variadic functions or\nad-hoc option arguments in other languages.\n\nThis isn't a terrible pattern, but even going as far as introducing\nhttps://crates.io/crates/derive_builder into the language or into the Book\nwould be nice.\n\n## Multi-type errors\n\nThe book doesn't really cover a pretty basic case in earnest: the situation\nwhere you have multiple different error returns and you want to use `?`.\n\n### Solutions\n\nEstablishing an error-definition pattern a-la https://crates.io/crates/failure\nin the Book would be super helpful, if not integrating `failure` itself.\n\nUpdate: I'm supposed to use `failure`, not `error-chain`, per @ag_dubs. SIGH\n\nUpdate: 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.\n\n## Returning iterators\n\nIterators are super duper useful! Infortunately, it's super hard to figure out\nhow to -return- them from functions. The compiler errors when you first try to\ndo this are incredibly opaque and confusing.\n\n### Solution\n\nIt turns out these days, you have `-\u003e impl Iterator` which makes this work,\nbut this was not very obvious and the compiler errors were SUPER CONFUSING\nabout how to fix this. It might go a long way to have the compiler be aware of\nat _least_ the Iterator case. Those compiler messages, wwhoo.\n\n## WTF is `AsRef`?\n\nI kept seeing this `AsRef` stuff while working with `Path`-related functionality and didn't really understand why folks were doing that instead of `path: \u0026Path` in function signatures.\n\n### Solutions\n\nThis 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.\n\nIt would be nice to make a note in the Book about this being a convention, or becoming one?\n\n## Weird File API\n\nThe 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.\n\nI 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!\n\n### Solutions\n\nidk. Changing this fundamentally would have a huge impact, unfortunately, and\nRust is very stability-oriented these days. I kinda wish there were a simpler,\nhigher-level, zero-cost crate for doing these things, optionally with\n`Future`s, and for the `fs` and `io` stuff to largely be considered \"internal\nuse only\" building blocks, if even that. I just plain don't like it and find\nit hard to work with. Maybe [`Tokio`](https://crates.io/crates/tokio) is the\nanswer, once it's updated with futures@0.3?\n\n## Literally no chown?\n\nSo the `fs` API has literally no `chown` functionality. I know it's pretty\nniche, but I needed it!\n\n### Solutions\n\nThis is exposed through direct bindings by\n[`nix`](https://crates.io/crates/nix). There's also a higher-level\n[`chownr`](https://crates.io/crates/chownr) crate by yours truly that does the\nrecursive bit.\n\n## Everyone uses `extern crate`\n\n...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.\n\n### Solutions\n\nHighlighting that `extern crate` isn't used anymore, in the Book, might be\nsuper helpful here. The rest is just waiting out the ecosystem. I'm not really\nsure what the actual expected alternative to `#![macro_use]` is supposed to\nbe, but I had some luck directly `use`-ing the macro into my scope like a\nfunction? So a macro named `foo` in crate `bar` would be imported with `use\nbar::foo;` and then the macro seemed to work...\n\n## No `cargo version` built-in\n\nComing from Node, this feels like a sharp corner: I have to manually edit\nCargo.toml, change the version, run `cargo build` to update the `Cargo.lock`\nso I don't end up with a random diff, then I have to manually `git ci -a -m\n'vX.Y.Z'`, `git tag -a vX.Y.Z`, fill in a message, `git push --follow-tags`,\nand **then** `cargo publish`. Just for a basic release. I'm used to at least\nhaving a baseline of `npm version patch \u0026\u0026 git push --follow-tags \u0026\u0026 npm pub`.\n\n### Solution\n\nHaving a _baseline_ `cargo version` built in would go a long way towards\nmaking publishing as a newbie a smoother process.\n\n## No `nyc` equivalent for coverage\n\nThere's no single coverage tool you can just install that integrates with\n`cargo test` and gives useful coverage feedback in the command line, works\nwith coveralls/codecov, etc. The best you get is something [as described in\nthis 3-year-old forum\nthread](https://users.rust-lang.org/t/howto-generating-a-branch-coverage-report/8524)\nwhich... honestly I'm not going to bother because this is an immense amount of\nfucking around with stuff just to get my percentages?\n\nI'm so used to having [`nyc`](https://npm.im/nyc) available :()\n\n### Solution\n\nRust -really- needs an `nyc` port.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzkat%2Frust-notes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzkat%2Frust-notes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzkat%2Frust-notes/lists"}