5 ms·
Rust API Guidelines Checklist
- codetrotter 5y agoAbout the guidelines, from https://rust-lang.github.io/api-guidelines/about.html https://rust-lang.github.io/api-guidelines/about.html > 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 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 5y agoWish the checkboxes weren't disabled. You can give this a run in console to enable them all (If you trust random code): document.querySelectorAll('input:disabled').forEach((el) => el.disabled = false)
- davidkunz 5y agoAs someone who doesn't write Rust professionally, this list scares me a bit. Even though many items apply to other programming languages as well (and some are even handled more easily in Rust), it appears to be quite easy to forget something of great importance to some of your users. What if you forgot to derive the Debug/Display trait and someone wants to print your struct, or you forgot to implement PartialEq and someone wants to write unit tests? Maybe this doesn't really happen in practice, I would be very interested if some experienced Rustaceans could share their experience.
- deleted 5y ago[deleted]
- loa_in_ 5y agoThis does happen in practice. Usually it is remedied by submitting an issue or a PR to your dependency upstream and getting them to fix it. 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.
- duped 5y agoNot everything is printable, comparable, or equalable (#[derive(Debug PartialEq)] isn't guaranteed to work - it has a few preconditions). 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.
- AaronFriel 5y agoIn cases like this, since everything is on GitHub it turns out to be pretty easy to make a PR to fix - it's usually only a few characters of code change. 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.
- davidkunz 5y agoI just found an interesting reddit thread discussing must-have traits: https://teddit.net/r/rust/comments/p5vsjl/is_there_any_reason_not_to_derive_every_possible/ https://teddit.net/r/rust/comments/p5vsjl/is_there_any_reaso...
- AaronFriel 5y agoThese are the guidelines that the Rust language standard library holds itself too, and tend to be good advice for authors of libraries. 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 5y ago> Following this list for a hobby, side project, or for the 0.1.0 release of a new library is entirely unnecessary. 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.
- seoaeu 5y agoSure you shouldn't go out of your way to violate the suggestions on the list, but you also shouldn't be afraid to publish a project just because you haven't meticulously gone through it and checked off every item
- tialaramex 5y ago> Releasing known-bad code is something nobody would do Mmm. I guess it depends how mischievous people are. Is https://crates.io/crates/misfortunate 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 https://crates.io/crates/whichever-compiles or https://crates.io/crates/nightly-crimes 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?
- kvark 5y agoThe presence of this list is very helpful. Unfortunately, some of the points are controversial. > 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 :/
- volta83 5y ago> 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. 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 5y agoThen you are at mercy of Rust optimizer. I don't want to always think about Rust optimizer when looking at or reviewing the code. I want to see the costs explicitly in the code. Once Copy/Debug/PartialEq are derived, it will be tempting to use them, so the compile time cost will apply.
- tialaramex 5y agoThis is an API guide. So what you're talking about is deliberately making libraries you provide worse so that people aren't tempted to use them, that ought to be ringing some alarm bells.
- volta83 5y agoThese are guidelines that the standard library aims to follow. It does not blindly follow them, and they only represent the values and trade-offs that make sense for the standard library. If your projects have different values and trade-offs, just do your own thing (Rust's makes it easier than all other languages I know). 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.
- Zababa 5y agoThe part about the naming conventions (https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv https://rust-lang.github.io/api-guidelines/naming.html#ad-ho...) reminds me of Elixir's size and length (https://hexdocs.pm/elixir/naming-conventions.html#length-and-size https://hexdocs.pm/elixir/naming-conventions.html#length-and...). I wonder if there is a way to enforce those conventions with a compiler/linter?
- codys 5y agoclippy can be used to check some of these conventions. See https://rust-lang.github.io/rust-clippy/master/#wrong_self_convention https://rust-lang.github.io/rust-clippy/master/#wrong_self_c..., for example. On projects I work on, I include clippy as part of the CI process to check these types of things.