You've already forked comprehensive-rust
mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-06-16 06:10:26 +02:00
Format all Markdown files with dprint
(#1157)
This is the result of running `dprint fmt` after removing `src/` from the list of excluded directories. This also reformats the Rust code: we might want to tweak this a bit in the future since some of the changes removes the hand-formatting. Of course, this formatting can be seen as a mis-feature, so maybe this is good overall. Thanks to mdbook-i18n-helpers 0.2, the POT file is nearly unchanged after this, meaning that all existing translations remain valid! A few messages were changed because of stray whitespace characters: msgid "" "Slices always borrow from another object. In this example, `a` has to remain " -"'alive' (in scope) for at least as long as our slice. " +"'alive' (in scope) for at least as long as our slice." msgstr "" The formatting is enforced in CI and we will have to see how annoying this is in practice for the many contributors. If it becomes annoying, we should look into fixing dprint/check#11 so that `dprint` can annotate the lines that need fixing directly, then I think we can consider more strict formatting checks. I added more customization to `rustfmt.toml`. This is to better emulate the dense style used in the course: - `max_width = 85` allows lines to take up the full width available in our code blocks (when taking margins and the line numbers into account). - `wrap_comments = true` ensures that we don't show very long comments in the code examples. I edited some comments to shorten them and avoid unnecessary line breaks — please trim other unnecessarily long comments when you see them! Remember we're writing code for slides 😄 - `use_small_heuristics = "Max"` allows for things like struct literals and if-statements to take up the full line width configured above. The formatting settings apply to all our Rust code right now — I think we could improve this with https://github.com/dprint/dprint/issues/711 which lets us add per-directory `dprint` configuration files. However, the `inherit: true` setting is not yet implemented (as far as I can tell), so a nested configuration file will have to copy most or all of the top-level file.
This commit is contained in:
@ -10,17 +10,17 @@ The [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) is used to
|
||||
validate credit card numbers. The algorithm takes a string as input and does the
|
||||
following to validate the credit card number:
|
||||
|
||||
* Ignore all spaces. Reject number with less than two digits.
|
||||
- Ignore all spaces. Reject number with less than two digits.
|
||||
|
||||
* Moving from **right to left**, double every second digit: for the number `1234`,
|
||||
we double `3` and `1`. For the number `98765`, we double `6` and `8`.
|
||||
- Moving from **right to left**, double every second digit: for the number
|
||||
`1234`, we double `3` and `1`. For the number `98765`, we double `6` and `8`.
|
||||
|
||||
* After doubling a digit, sum the digits if the result is greater than 9. So doubling `7` becomes `14` which
|
||||
becomes `1 + 4 = 5`.
|
||||
- After doubling a digit, sum the digits if the result is greater than 9. So
|
||||
doubling `7` becomes `14` which becomes `1 + 4 = 5`.
|
||||
|
||||
* Sum all the undoubled and doubled digits.
|
||||
- Sum all the undoubled and doubled digits.
|
||||
|
||||
* The credit card number is valid if the sum ends with `0`.
|
||||
- The credit card number is valid if the sum ends with `0`.
|
||||
|
||||
The provided code provides a buggy implementation of the luhn algorithm, along
|
||||
with two basic unit tests that confirm that most the algorithm is implemented
|
||||
|
@ -24,11 +24,8 @@ pub fn luhn(cc_number: &str) -> bool {
|
||||
if let Some(digit) = c.to_digit(10) {
|
||||
if double {
|
||||
let double_digit = digit * 2;
|
||||
sum += if double_digit > 9 {
|
||||
double_digit - 9
|
||||
} else {
|
||||
double_digit
|
||||
};
|
||||
sum +=
|
||||
if double_digit > 9 { double_digit - 9 } else { double_digit };
|
||||
} else {
|
||||
sum += digit;
|
||||
}
|
||||
@ -53,11 +50,8 @@ pub fn luhn(cc_number: &str) -> bool {
|
||||
digits += 1;
|
||||
if double {
|
||||
let double_digit = digit * 2;
|
||||
sum += if double_digit > 9 {
|
||||
double_digit - 9
|
||||
} else {
|
||||
double_digit
|
||||
};
|
||||
sum +=
|
||||
if double_digit > 9 { double_digit - 9 } else { double_digit };
|
||||
} else {
|
||||
sum += digit;
|
||||
}
|
||||
|
@ -47,21 +47,22 @@ Error: See failure output above
|
||||
{{#include googletest.rs:test_multiline_string_diff}}
|
||||
```
|
||||
|
||||
shows a color-coded diff (colors not shown here):
|
||||
shows a color-coded diff (colors not shown here):
|
||||
|
||||
<!-- mdbook-xgettext: skip -->
|
||||
```text
|
||||
Value of: haiku
|
||||
Expected: is equal to "Memory safety found,\nRust's silly humor guides the way,\nSecure code you'll write."
|
||||
Actual: "Memory safety found,\nRust's strong typing guides the way,\nSecure code you'll write.",
|
||||
which isn't equal to "Memory safety found,\nRust's silly humor guides the way,\nSecure code you'll write."
|
||||
Difference(-actual / +expected):
|
||||
Memory safety found,
|
||||
-Rust's strong typing guides the way,
|
||||
+Rust's silly humor guides the way,
|
||||
Secure code you'll write.
|
||||
at src/testing/googletest.rs:17:5
|
||||
```
|
||||
<!-- mdbook-xgettext: skip -->
|
||||
|
||||
```text
|
||||
Value of: haiku
|
||||
Expected: is equal to "Memory safety found,\nRust's silly humor guides the way,\nSecure code you'll write."
|
||||
Actual: "Memory safety found,\nRust's strong typing guides the way,\nSecure code you'll write.",
|
||||
which isn't equal to "Memory safety found,\nRust's silly humor guides the way,\nSecure code you'll write."
|
||||
Difference(-actual / +expected):
|
||||
Memory safety found,
|
||||
-Rust's strong typing guides the way,
|
||||
+Rust's silly humor guides the way,
|
||||
Secure code you'll write.
|
||||
at src/testing/googletest.rs:17:5
|
||||
```
|
||||
|
||||
- The crate is a Rust port of
|
||||
[GoogleTest for C++](https://google.github.io/googletest/).
|
||||
|
@ -4,9 +4,9 @@ minutes: 5
|
||||
|
||||
# Compiler Lints and Clippy
|
||||
|
||||
The Rust compiler produces fantastic error messages, as well as helpful
|
||||
built-in lints. [Clippy](https://doc.rust-lang.org/clippy/) provides even more
|
||||
lints, organized into groups that can be enabled per-project.
|
||||
The Rust compiler produces fantastic error messages, as well as helpful built-in
|
||||
lints. [Clippy](https://doc.rust-lang.org/clippy/) provides even more lints,
|
||||
organized into groups that can be enabled per-project.
|
||||
|
||||
```rust,editable,should_panic
|
||||
#[deny(clippy::cast_possible_truncation)]
|
||||
|
@ -4,8 +4,8 @@ minutes: 5
|
||||
|
||||
# Mocking
|
||||
|
||||
For mocking, [Mockall] is a widely used library. You need to refactor your
|
||||
code to use traits, which you can then quickly mock:
|
||||
For mocking, [Mockall] is a widely used library. You need to refactor your code
|
||||
to use traits, which you can then quickly mock:
|
||||
|
||||
```rust,ignore
|
||||
{{#include mockall.rs:simple_example}}
|
||||
@ -15,16 +15,17 @@ code to use traits, which you can then quickly mock:
|
||||
|
||||
<details>
|
||||
|
||||
- The advice here is for Android (AOSP) where Mockall is the recommended mocking library.
|
||||
There are other [mocking libraries available on crates.io](https://crates.io/keywords/mock),
|
||||
in particular in the area of mocking HTTP services. The other mocking libraries work
|
||||
in a similar fashion as Mockall, meaning that they make it easy to get a mock implementation
|
||||
of a given trait.
|
||||
- The advice here is for Android (AOSP) where Mockall is the recommended mocking
|
||||
library. There are other
|
||||
[mocking libraries available on crates.io](https://crates.io/keywords/mock),
|
||||
in particular in the area of mocking HTTP services. The other mocking
|
||||
libraries work in a similar fashion as Mockall, meaning that they make it easy
|
||||
to get a mock implementation of a given trait.
|
||||
|
||||
- Note that mocking is somewhat *controversial*: mocks allow you to completely isolate a
|
||||
test from its dependencies. The immediate result is faster and more stable
|
||||
test execution. On the other hand, the mocks can be configured wrongly and
|
||||
return output different from what the real dependencies would do.
|
||||
- Note that mocking is somewhat _controversial_: mocks allow you to completely
|
||||
isolate a test from its dependencies. The immediate result is faster and more
|
||||
stable test execution. On the other hand, the mocks can be configured wrongly
|
||||
and return output different from what the real dependencies would do.
|
||||
|
||||
If at all possible, it is recommended that you use the real dependencies. As
|
||||
an example, many databases allow you to configure an in-memory backend. This
|
||||
|
@ -26,7 +26,7 @@ These tests only have access to the public API of your crate.
|
||||
|
||||
Rust has built-in support for documentation tests:
|
||||
|
||||
```rust
|
||||
````rust
|
||||
/// Shortens a string to the given length.
|
||||
///
|
||||
/// ```
|
||||
@ -37,9 +37,11 @@ Rust has built-in support for documentation tests:
|
||||
pub fn shorten_string(s: &str, length: usize) -> &str {
|
||||
&s[..std::cmp::min(length, s.len())]
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
* Code blocks in `///` comments are automatically seen as Rust code.
|
||||
* The code will be compiled and executed as part of `cargo test`.
|
||||
* Adding `# ` in the code will hide it from the docs, but will still compile/run it.
|
||||
* Test the above code on the [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3ce2ad13ea1302f6572cb15cd96becf0).
|
||||
- Code blocks in `///` comments are automatically seen as Rust code.
|
||||
- The code will be compiled and executed as part of `cargo test`.
|
||||
- Adding `#` in the code will hide it from the docs, but will still compile/run
|
||||
it.
|
||||
- Test the above code on the
|
||||
[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3ce2ad13ea1302f6572cb15cd96becf0).
|
||||
|
@ -6,11 +6,11 @@ minutes: 5
|
||||
|
||||
Rust and Cargo come with a simple unit test framework:
|
||||
|
||||
* Unit tests are supported throughout your code.
|
||||
- Unit tests are supported throughout your code.
|
||||
|
||||
* Integration tests are supported via the `tests/` directory.
|
||||
- Integration tests are supported via the `tests/` directory.
|
||||
|
||||
Tests are marked with `#[test]`. Unit tests are often put in a nested `tests`
|
||||
Tests are marked with `#[test]`. Unit tests are often put in a nested `tests`
|
||||
module, using `#[cfg(test)]` to conditionally compile them only when building
|
||||
tests.
|
||||
|
||||
@ -43,8 +43,8 @@ mod test {
|
||||
}
|
||||
```
|
||||
|
||||
* This lets you unit test private helpers.
|
||||
* The `#[cfg(test)]` attribute is only active when you run `cargo test`.
|
||||
- This lets you unit test private helpers.
|
||||
- The `#[cfg(test)]` attribute is only active when you run `cargo test`.
|
||||
|
||||
<details>
|
||||
|
||||
|
@ -8,6 +8,8 @@ Rust comes with only basic support for writing tests.
|
||||
|
||||
Here are some additional crates which we recommend for writing tests:
|
||||
|
||||
* [googletest](https://docs.rs/googletest): Comprehensive test assertion library in the tradition of GoogleTest for C++.
|
||||
* [proptest](https://docs.rs/proptest): Property-based testing for Rust.
|
||||
* [rstest](https://docs.rs/rstest): Support for fixtures and parameterised tests.
|
||||
- [googletest](https://docs.rs/googletest): Comprehensive test assertion library
|
||||
in the tradition of GoogleTest for C++.
|
||||
- [proptest](https://docs.rs/proptest): Property-based testing for Rust.
|
||||
- [rstest](https://docs.rs/rstest): Support for fixtures and parameterised
|
||||
tests.
|
||||
|
Reference in New Issue
Block a user