diff --git a/dprint.json b/.dprint.json similarity index 69% rename from dprint.json rename to .dprint.json index 44cf571..d8a3551 100644 --- a/dprint.json +++ b/.dprint.json @@ -24,10 +24,17 @@ "theme/book.js", "target/**/*" ], + "exec": { + "commands": [{ + "command": "rustfmt --edition 2021", + "exts": ["rs"] + }] + }, "plugins": [ "https://plugins.dprint.dev/markdown-0.16.4.wasm", "https://plugins.dprint.dev/toml-0.6.1.wasm", "https://plugins.dprint.dev/json-0.19.2.wasm", - "https://plugins.dprint.dev/typescript-0.89.3.wasm" + "https://plugins.dprint.dev/typescript-0.89.3.wasm", + "https://plugins.dprint.dev/exec-0.4.4.json@c207bf9b9a4ee1f0ecb75c594f774924baf62e8e53a2ce9d873816a408cecbf7" ] } diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index df58397..47c570d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,4 +11,12 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: dprint/check@v2.2 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@1482605bfc5719782e1267fd0c0cc350fe7646b8 # v1 + with: + toolchain: stable + components: rustfmt + + - uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2 + + - uses: dprint/check@v2.2 \ No newline at end of file diff --git a/src/anti_patterns/deny-warnings.md b/src/anti_patterns/deny-warnings.md index e5ca5f9..a959e23 100644 --- a/src/anti_patterns/deny-warnings.md +++ b/src/anti_patterns/deny-warnings.md @@ -58,35 +58,39 @@ is a list of warning lints that is (hopefully) safe to deny (as of Rustc 1.48.0): ```rust,ignore -#![deny(bad_style, - const_err, - dead_code, - improper_ctypes, - non_shorthand_field_patterns, - no_mangle_generic_items, - overflowing_literals, - path_statements, - patterns_in_fns_without_body, - private_in_public, - unconditional_recursion, - unused, - unused_allocation, - unused_comparisons, - unused_parens, - while_true)] +#![deny( + bad_style, + const_err, + dead_code, + improper_ctypes, + non_shorthand_field_patterns, + no_mangle_generic_items, + overflowing_literals, + path_statements, + patterns_in_fns_without_body, + private_in_public, + unconditional_recursion, + unused, + unused_allocation, + unused_comparisons, + unused_parens, + while_true +)] ``` In addition, the following `allow`ed lints may be a good idea to `deny`: ```rust,ignore -#![deny(missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results)] +#![deny( + missing_debug_implementations, + missing_docs, + trivial_casts, + trivial_numeric_casts, + unused_extern_crates, + unused_import_braces, + unused_qualifications, + unused_results +)] ``` Some may also want to add `missing-copy-implementations` to their list. diff --git a/src/functional/generics-type-classes.md b/src/functional/generics-type-classes.md index 6723b3f..d4e16fc 100644 --- a/src/functional/generics-type-classes.md +++ b/src/functional/generics-type-classes.md @@ -120,8 +120,8 @@ mod bootp { // private module, lest outside users invent their own protocol kinds! mod proto_trait { - use std::path::{Path, PathBuf}; use super::{bootp, nfs}; + use std::path::{Path, PathBuf}; pub(crate) trait ProtoKind { type AuthInfo; @@ -157,7 +157,7 @@ mod proto_trait { } use proto_trait::ProtoKind; // keep internal to prevent impls -pub use proto_trait::{Nfs, Bootp}; // re-export so callers can see them +pub use proto_trait::{Bootp, Nfs}; // re-export so callers can see them struct FileDownloadRequest { file_name: PathBuf, diff --git a/src/functional/optics.md b/src/functional/optics.md index a29c825..ac8c6e4 100644 --- a/src/functional/optics.md +++ b/src/functional/optics.md @@ -185,8 +185,8 @@ use anyhow; use std::str::FromStr; struct TestStruct { - a: usize, - b: String, + a: usize, + b: String, } impl FromStr for TestStruct { @@ -203,7 +203,10 @@ impl ToString for TestStruct { } fn main() { - let a = TestStruct { a: 5, b: "hello".to_string() }; + let a = TestStruct { + a: 5, + b: "hello".to_string(), + }; println!("Our Test Struct as JSON: {}", a.to_string()); } ``` @@ -264,8 +267,8 @@ independent form, it is even possible to have code generation creating the ```rust,ignore #[derive(Default, Serde)] // the "Serde" derive creates the trait impl block struct TestStruct { - a: usize, - b: String, + a: usize, + b: String, } // user writes this macro to generate an associated visitor type diff --git a/src/idioms/coercion-arguments.md b/src/idioms/coercion-arguments.md index d3d8a54..8011587 100644 --- a/src/idioms/coercion-arguments.md +++ b/src/idioms/coercion-arguments.md @@ -36,10 +36,10 @@ fn three_vowels(word: &String) -> bool { 'a' | 'e' | 'i' | 'o' | 'u' => { vowel_count += 1; if vowel_count >= 3 { - return true + return true; } } - _ => vowel_count = 0 + _ => vowel_count = 0, } } false @@ -54,7 +54,6 @@ fn main() { // This works fine, but the following two lines would fail: // println!("Ferris: {}", three_vowels("Ferris")); // println!("Curious: {}", three_vowels("Curious")); - } ``` @@ -97,10 +96,10 @@ fn three_vowels(word: &str) -> bool { 'a' | 'e' | 'i' | 'o' | 'u' => { vowel_count += 1; if vowel_count >= 3 { - return true + return true; } } - _ => vowel_count = 0 + _ => vowel_count = 0, } } false diff --git a/src/idioms/ctor.md b/src/idioms/ctor.md index 78bab8d..c65b7ed 100644 --- a/src/idioms/ctor.md +++ b/src/idioms/ctor.md @@ -16,7 +16,7 @@ object: /// assert_eq!(42, s.value()); /// ``` pub struct Second { - value: u64 + value: u64, } impl Second { @@ -47,7 +47,7 @@ Rust supports default constructors with the [`Default`][std-default] trait: /// assert_eq!(0, s.value()); /// ``` pub struct Second { - value: u64 + value: u64, } impl Second { @@ -78,7 +78,7 @@ like they do with `Second`: /// ``` #[derive(Default)] pub struct Second { - value: u64 + value: u64, } impl Second { diff --git a/src/idioms/ffi/accepting-strings.md b/src/idioms/ffi/accepting-strings.md index f86873f..f4d83d5 100644 --- a/src/idioms/ffi/accepting-strings.md +++ b/src/idioms/ffi/accepting-strings.md @@ -44,10 +44,7 @@ pub mod unsafe_module { /// - points to memory ending in a null byte /// - won't be mutated for the duration of this function call #[no_mangle] - pub unsafe extern "C" fn mylib_log( - msg: *const libc::c_char, - level: libc::c_int - ) { + pub unsafe extern "C" fn mylib_log(msg: *const libc::c_char, level: libc::c_int) { let level: crate::LogLevel = match level { /* ... */ }; // SAFETY: The caller has already guaranteed this is okay (see the diff --git a/src/idioms/ffi/errors.md b/src/idioms/ffi/errors.md index 56900f7..3547b8f 100644 --- a/src/idioms/ffi/errors.md +++ b/src/idioms/ffi/errors.md @@ -20,8 +20,8 @@ in a usable way: ```rust,ignore enum DatabaseError { - IsReadOnly = 1, // user attempted a write operation - IOError = 2, // user should read the C errno() for what it was + IsReadOnly = 1, // user attempted a write operation + IOError = 2, // user should read the C errno() for what it was FileCorrupted = 3, // user should run a repair tool to recover it } @@ -57,10 +57,7 @@ pub mod c_api { use super::errors::DatabaseError; #[no_mangle] - pub extern "C" fn db_error_description( - e: *const DatabaseError - ) -> *mut libc::c_char { - + pub extern "C" fn db_error_description(e: *const DatabaseError) -> *mut libc::c_char { let error: &DatabaseError = unsafe { // SAFETY: pointer lifetime is greater than the current stack frame &*e @@ -107,17 +104,19 @@ pub mod c_api { struct ParseError { expected: char, line: u32, - ch: u16 + ch: u16, } -impl ParseError { /* ... */ } +impl ParseError { + /* ... */ +} /* Create a second version which is exposed as a C structure */ #[repr(C)] pub struct parse_error { pub expected: libc::c_char, pub line: u32, - pub ch: u16 + pub ch: u16, } impl From for parse_error { diff --git a/src/idioms/ffi/passing-strings.md b/src/idioms/ffi/passing-strings.md index 3b4056d..53bf11f 100644 --- a/src/idioms/ffi/passing-strings.md +++ b/src/idioms/ffi/passing-strings.md @@ -35,9 +35,7 @@ pub mod unsafe_module { fn geterr(buffer: *mut libc::c_char, size: libc::c_int) -> libc::c_int; } - fn report_error_to_ffi>( - err: S - ) -> Result<(), std::ffi::NulError>{ + fn report_error_to_ffi>(err: S) -> Result<(), std::ffi::NulError> { let c_err = std::ffi::CString::new(err.into())?; unsafe { diff --git a/src/idioms/mem-replace.md b/src/idioms/mem-replace.md index 28d0d27..3014173 100644 --- a/src/idioms/mem-replace.md +++ b/src/idioms/mem-replace.md @@ -15,7 +15,7 @@ use std::mem; enum MyEnum { A { name: String, x: u8 }, - B { name: String } + B { name: String }, } fn a_to_b(e: &mut MyEnum) { @@ -24,7 +24,9 @@ fn a_to_b(e: &mut MyEnum) { // (note that empty strings don't allocate). // Then, construct the new enum variant (which will // be assigned to `*e`). - *e = MyEnum::B { name: mem::take(name) } + *e = MyEnum::B { + name: mem::take(name), + } } } ``` @@ -38,7 +40,7 @@ enum MultiVariateEnum { A { name: String }, B { name: String }, C, - D + D, } fn swizzle(e: &mut MultiVariateEnum) { @@ -46,10 +48,14 @@ fn swizzle(e: &mut MultiVariateEnum) { *e = match e { // Ownership rules do not allow taking `name` by value, but we cannot // take the value out of a mutable reference, unless we replace it: - A { name } => B { name: mem::take(name) }, - B { name } => A { name: mem::take(name) }, + A { name } => B { + name: mem::take(name), + }, + B { name } => A { + name: mem::take(name), + }, C => D, - D => C + D => C, } } ``` diff --git a/src/idioms/priv-extend.md b/src/idioms/priv-extend.md index 452b661..165d275 100644 --- a/src/idioms/priv-extend.md +++ b/src/idioms/priv-extend.md @@ -25,21 +25,23 @@ mod a { pub struct S { pub foo: i32, } - + #[non_exhaustive] pub enum AdmitMoreVariants { VariantA, VariantB, #[non_exhaustive] - VariantC { a: String } + VariantC { + a: String, + }, } } fn print_matched_variants(s: a::S) { // Because S is `#[non_exhaustive]`, it cannot be named here and // we must use `..` in the pattern. - let a::S { foo: _, ..} = s; - + let a::S { foo: _, .. } = s; + let some_enum = a::AdmitMoreVariants::VariantA; match some_enum { a::AdmitMoreVariants::VariantA => println!("it's an A"), @@ -50,7 +52,7 @@ fn print_matched_variants(s: a::S) { // The wildcard match is required because more variants may be // added in the future - _ => println!("it's a new variant") + _ => println!("it's a new variant"), } } ``` @@ -78,7 +80,7 @@ pub struct S { pub a: i32, // Because `b` is private, you cannot match on `S` without using `..` and `S` // cannot be directly instantiated or matched against - _b: () + _b: (), } ``` diff --git a/src/idioms/return-consumed-arg-on-error.md b/src/idioms/return-consumed-arg-on-error.md index 652fd38..906714e 100644 --- a/src/idioms/return-consumed-arg-on-error.md +++ b/src/idioms/return-consumed-arg-on-error.md @@ -12,7 +12,9 @@ pub fn send(value: String) -> Result<(), SendError> { println!("using {value} in a meaningful way"); // Simulate non-deterministic fallible action. use std::time::SystemTime; - let period = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let period = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap(); if period.subsec_nanos() % 2 == 1 { Ok(()) } else { diff --git a/src/patterns/behavioural/RAII.md b/src/patterns/behavioural/RAII.md index 6a24788..e2eafec 100644 --- a/src/patterns/behavioural/RAII.md +++ b/src/patterns/behavioural/RAII.md @@ -63,8 +63,8 @@ impl<'a, T> Deref for MutexGuard<'a, T> { fn baz(x: Mutex) { let xx = x.lock(); xx.foo(); // foo is a method on Foo. - // The borrow checker ensures we can't store a reference to the underlying - // Foo which will outlive the guard xx. + // The borrow checker ensures we can't store a reference to the underlying + // Foo which will outlive the guard xx. // x is unlocked when we exit this function and xx's destructor is executed. } diff --git a/src/patterns/behavioural/interpreter.md b/src/patterns/behavioural/interpreter.md index fb80a66..b4ef0fb 100644 --- a/src/patterns/behavioural/interpreter.md +++ b/src/patterns/behavioural/interpreter.md @@ -59,7 +59,6 @@ pub struct Interpreter<'a> { } impl<'a> Interpreter<'a> { - pub fn new(infix: &'a str) -> Self { Self { it: infix.chars() } } diff --git a/src/patterns/behavioural/visitor.md b/src/patterns/behavioural/visitor.md index c164d2a..e327eee 100644 --- a/src/patterns/behavioural/visitor.md +++ b/src/patterns/behavioural/visitor.md @@ -42,13 +42,15 @@ mod visit { } } -use visit::*; use ast::*; +use visit::*; // An example concrete implementation - walks the AST interpreting it as code. struct Interpreter; impl Visitor for Interpreter { - fn visit_name(&mut self, n: &Name) -> i64 { panic!() } + fn visit_name(&mut self, n: &Name) -> i64 { + panic!() + } fn visit_stmt(&mut self, s: &Stmt) -> i64 { match *s { Stmt::Expr(ref e) => self.visit_expr(e), @@ -87,7 +89,7 @@ example, ```rust,ignore pub fn walk_expr(visitor: &mut Visitor, e: &Expr) { match *e { - Expr::IntLit(_) => {}, + Expr::IntLit(_) => {} Expr::Add(ref lhs, ref rhs) => { visitor.visit_expr(lhs); visitor.visit_expr(rhs); diff --git a/src/patterns/ffi/wrappers.md b/src/patterns/ffi/wrappers.md index 68dadc3..7a7d60a 100644 --- a/src/patterns/ffi/wrappers.md +++ b/src/patterns/ffi/wrappers.md @@ -113,14 +113,11 @@ pub mod unsafe_module { // other module content - pub fn myset_store( - myset: *mut MySetWrapper, - key: datum, - value: datum) -> libc::c_int { - + pub fn myset_store(myset: *mut MySetWrapper, key: datum, value: datum) -> libc::c_int { // DO NOT USE THIS CODE. IT IS UNSAFE TO DEMONSTRATE A PROLBEM. - let myset: &mut MySet = unsafe { // SAFETY: whoops, UB occurs in here! + let myset: &mut MySet = unsafe { + // SAFETY: whoops, UB occurs in here! &mut (*myset).myset }; @@ -128,7 +125,7 @@ pub mod unsafe_module { match myset.store(casted_key, casted_value) { Ok(_) => 0, - Err(e) => e.into() + Err(e) => e.into(), } } } diff --git a/src/patterns/structural/compose-structs.md b/src/patterns/structural/compose-structs.md index 4afe410..bbf8bd3 100644 --- a/src/patterns/structural/compose-structs.md +++ b/src/patterns/structural/compose-structs.md @@ -38,9 +38,9 @@ fn main() { }; let connection_string = &mut db.connection_string; - print_database(&db); // Immutable borrow of `db` happens here - // *connection_string = "new string".to_string(); // Mutable borrow is used - // here + print_database(&db); // Immutable borrow of `db` happens here + // *connection_string = "new string".to_string(); // Mutable borrow is used + // here } ``` @@ -67,9 +67,7 @@ struct Database { } // print_database can then take ConnectionString, Timeout and Poolsize struct instead -fn print_database(connection_str: ConnectionString, - timeout: Timeout, - pool_size: PoolSize) { +fn print_database(connection_str: ConnectionString, timeout: Timeout, pool_size: PoolSize) { println!("Connection string: {connection_str:?}"); println!("Timeout: {timeout:?}"); println!("Pool size: {pool_size:?}");