Rust API Guidelines Checklist
codetrotter 2021-08-18 16:42:11 +0000 UTC [ - ]
> This is a set of recommendations on how to design and present APIs for the Rust programming language. They are authored largely by the Rust library team, based on experiences building the Rust standard library and other crates in the Rust ecosystem.
GitHub repo for the guidelines:
https://github.com/rust-lang/api-guidelines
I am submitting the OP link to HN because I believe that these guidelines are useful to many people that have, or wish to, publish Rust crates that other people will then use.
Following these guidelines will make the crates we make feel "native to Rust" for other people that want to make use of our crates.
I found these guidelines just a couple of days ago for the first time, in spite of having written Rust for several years now. And I suspect that many others may not have read these guidelines and that others will benefit from reading them too.
Cicero22 2021-08-18 17:08:07 +0000 UTC [ - ]
document.querySelectorAll('input:disabled').forEach((el) => el.disabled = false)
davidkunz 2021-08-18 17:23:52 +0000 UTC [ - ]
loa_in_ 2021-08-18 17:30:35 +0000 UTC [ - ]
If you're really impatient you can implement the trait yourself (with some hacking involved): wrap the type in a new struct and implement the trait there.
Why hacking around like that? Rust requires at least one of: the type, or the trait; to be originated in your crate.
davidkunz 2021-08-18 20:15:08 +0000 UTC [ - ]
AaronFriel 2021-08-18 17:31:56 +0000 UTC [ - ]
API names and such are of course breaking changes, but unless you're authoring Tokio or Hyper or another huge, important crate in the ecosystem, it's really not worth it to do everything on this list.
duped 2021-08-18 17:31:18 +0000 UTC [ - ]
So you live with it. If you draw a comparison to C++, almost none of these things are implemented for dependencies and there's no easy helper to add it.
Zababa 2021-08-19 05:03:46 +0000 UTC [ - ]
kvark 2021-08-18 17:55:05 +0000 UTC [ - ]
> Types eagerly implement common traits
This is particularly concerning to me for multiple reasons. If my 4K structure can be copied, should it derive `Copy`? This leads to users implicitly copying it around instead of using references more aggressively.
If all my types implement `PartialEq`, `Debug`, and other stuff, that means a lot of code generation at compile time, which gets hopefully eliminated by LLVM passes. And then we are wondering why Rust compilation/linking is so slow :/
hcs 2021-08-18 20:45:41 +0000 UTC [ - ]
https://rust-lang.github.io/rust-clippy/master/#large_types_...
The default threshold is 256 bytes: https://github.com/rust-lang/rust-clippy/blob/1fc1aee7be6e7e...
So you might use that as a rule of thumb. But officially, "Generally speaking, if your type can implement Copy, it should." https://doc.rust-lang.org/std/marker/trait.Copy.html#when-sh...
kvark 2021-08-18 21:18:00 +0000 UTC [ - ]
volta83 2021-08-18 19:09:48 +0000 UTC [ - ]
Rust eliminates unnecessary memcpys, but this is a bit up to you. `Copy` as a synonym of "cheap to copy" is used by some crates, although this is not official AFAIK.
> If all my types implement `PartialEq`, `Debug`, and other stuff, that means a lot of code generation at compile time,
If you don't use these, no LLVM-IR is even generated for these. Rust compiles code "on demand".
kvark 2021-08-18 21:16:57 +0000 UTC [ - ]
Once Copy/Debug/PartialEq are derived, it will be tempting to use them, so the compile time cost will apply.
volta83 2021-08-19 10:22:31 +0000 UTC [ - ]
If you don't want to use a standard library that follows these, just fork it and change it. Rust makes this trivial, and projects that must do this go and just do it.
I really don't know what point you are trying to make. Implementing Copy for all types that are cheap to copy makes sense for most Rust programmers.
That does not mean that it makes sense for _you_, but if you disagree about this not making sense for most, then Rust is probably the wrong language for you, and you should consider using something else.
tialaramex 2021-08-18 22:47:04 +0000 UTC [ - ]
tialaramex 2021-08-18 19:28:20 +0000 UTC [ - ]
If you're exaggerating and the object is really 64 bytes, just suck it up and derive Copy, your estimate of how "expensive" it is may well be so wrong that you're defeating your own objectives.
I've never seen any indication that unneeded PartialEq or Debug for example aren't elided by the compiler. In contrast if I need Debug it sure is a pain in the backside to implement it manually in a wrapper type because the owner of the type decided unilaterally that nobody would need that.
kvark 2021-08-18 21:19:24 +0000 UTC [ - ]
AaronFriel 2021-08-18 17:28:58 +0000 UTC [ - ]
By no means should anyone be intimidated by this. This list is, well, something like a code review guide similar to what you'd find to make changes to Postgres or Python. New APIs that are part of the standard library need to be be consistent, performant, debuggable, documented, and so on.
Following this list for a hobby, side project, or for the 0.1.0 release of a new library is entirely unnecessary.
rdpintqogeogsaa 2021-08-18 18:35:07 +0000 UTC [ - ]
This may be a hot take, but I'll go and take my chances.
Following this list for a hobby or side project or even an initial release of a library is a very good idea. It's hard to tell what kinds of libraries will or won't catch on. As soon as you have downstream users, they will get annoyed by churn. If given a checklist, it seems reasonable to me to expect people to actually follow it out of obligation to your future downstream consumers of the library.
Not only that, but I believe that most of the things on that list boils down to good engineering. Following good practice early on even just in a hobby/side project will be rewarded as the project grows.
By releasing a library (even as a 0.1.0), you imply that you expect it to be at least usable for some kind of usage. Releasing known-bad code is something nobody would do, especially since every major Git repostory hoster lets you have private repositories.
tialaramex 2021-08-18 19:43:08 +0000 UTC [ - ]
Mmm. I guess it depends how mischievous people are.
Is https://crates.io/crates/misfortunate known-bad code? Take misfortunate::Comte which claims to be an ExactSizeIterator but lies and with a simple "tap" from your wand produces an infinite number of cloned Rabbits ?
OK, how about Mara's https://crates.io/crates/whichever-compiles or https://crates.io/crates/nightly-crimes ?
I mean, maybe I'm a bad person for writing misfortunate, but is Mara, Rust's library team lead, a bad person?
AaronFriel 2021-08-18 20:40:18 +0000 UTC [ - ]
Fortunately, these people are very clever, very good Rust developers and they are not maliciously dropping nightly crimes into widely used crates :)
seoaeu 2021-08-18 18:53:03 +0000 UTC [ - ]
stouset 2021-08-18 19:57:46 +0000 UTC [ - ]