clean-rust's People
clean-rust's Issues
Use same name for Cargo package and directory in Cargo workspace
Use the same name for the Cargo package and directory in a Cargo workspace for easier understanding of the package structure
Clippy feature: Check for redundant async-await blocks
async (move) {
future.await;
}
blocks are redundant
Suggest replacing if-let which only checks for pattern matching with matches! macro
Cargo clippy: replace .cloned() with .clone()
Unnecessary reference in match target
Closure captures in Rust book
Use rich enums instead of C-style enums
Rust enums are true ADTs, so use them instead of embedding C-style enums into structs
Investigate cargo nextest
Decouple non-determinism using trait bounds
Examples of non-determinism:
- Randomness sources
- Clocks
They can be extracted to a trait and injected using trait bounds and PhantomData on injected structs. This is the equivalent of implicit parameters in Scala.
Cargo clippy: replace Vec.into_iter().rev().collect() with [T].reverse()
Web frameworks
Clippy style: prefer Result::map_err instead of match to reduce indentation
Document FuturesUnordered
Prefer static dispatch over dynamic dispatch
Static dispatch is both easier to understand and more efficient and should be preferred to dynamic dispatch as much as possible.
Cargo clippy: Use match guards to reduce indentation
Document 'static lifetime
Cargo clippy check for two merging two consecutive .map().map()
https://github.com/andreisilviudragnea/problems-rust/commit/e8ce9061270b5c73e5de3db5366aabb742c8a719
let nodes = s[1..s.len() - 1]
.split(',')
.map(|str| match str {
"null" => None,
v => Some(v.parse::<i32>().unwrap()),
})
.map(|it| {
it.map(|val| {
Rc::new(RefCell::new(TreeNode {
val,
left: None,
right: None,
}))
})
})
.collect::<Vec<_>>();
let nodes = s[1..s.len() - 1]
.split(',')
.map(|str| match str {
"null" => None,
v => Some(Rc::new(RefCell::new(TreeNode {
val: v.parse::<i32>().unwrap(),
left: None,
right: None,
}))),
})
.collect::<Vec<_>>();
Use Cargo features for marking module and crate extraction
Cargo features are a fast way of marking code to be later decoupled into separate modules and crates
Clones can be removed by returning earlier value from function
For example, returning captures of a closure instead of a tuple of cloned capture groups.
Re-use business logic between async and non-async app
- Use actix-web framework, which does not require Futures to be Send
- Use maybe_async crate for automatic rewriting of async code to its non-async variant
Cargo: Replace match with question mark
Clippy: Redundant 'static lifetime on owned type
Fail CI on missing coverage
Create Rust CI template
Less clone can lead to more code coupling - NOT true
Global config struct needs to be shared between application components between an Arc<T>
, even if only one field is needed, in order to avoid multiple Arc<T>
on each subfield.
Update:
This is not true because you can move struct fields to separate Arc<T>
as needed.
Detect matches replaceable with if let when None is first variant
Cargo clippy: redundant if
Replace if condition { true } else { false }
with condition
Try avoiding unnecessary indirection
Arc
s withoutclone
Rc
s withoutclone
Cargo clippy bug: Crate-private trait is not detected as unused
Investigate modular data models
Cargo feature: cargo fix dead_code
- Automatically remove unused items
Try using less Arc in general
The Arc is useless if there is no .clone
call on it in the codebase.
Prefer expect to unwrap
Having an error message is useful on panics.
Clippy feature: Unnecessary Clone derivation
Cargo clippy: replace .rev().collect::<Vec<_>>() and .pop() with .next()
https://github.com/andreisilviudragnea/problems-rust/commit/5a10d8e0e53486fc34073a3f4c898ade9f1ba85d
pub(crate) fn from_str(s: &str) -> Option<Rc<RefCell<TreeNode>>> {
if s == "[]" {
return None;
}
let nodes = s[1..s.len() - 1]
.split(',')
.map(|str| match str {
"null" => None,
v => Some(Rc::new(RefCell::new(TreeNode {
val: v.parse::<i32>().unwrap(),
left: None,
right: None,
}))),
})
.collect::<Vec<_>>();
let mut kids = nodes.iter().cloned().rev().collect::<Vec<_>>();
let root = kids.pop().unwrap();
for node in nodes.into_iter().flatten() {
if let Some(val) = kids.pop() {
node.borrow_mut().left = val;
}
if let Some(val) = kids.pop() {
node.borrow_mut().right = val;
}
}
root
}
pub(crate) fn from_str(s: &str) -> Option<Rc<RefCell<TreeNode>>> {
if s == "[]" {
return None;
}
let nodes = s[1..s.len() - 1]
.split(',')
.map(|str| match str {
"null" => None,
v => Some(Rc::new(RefCell::new(TreeNode {
val: v.parse::<i32>().unwrap(),
left: None,
right: None,
}))),
})
.collect::<Vec<_>>();
let mut kids = nodes.iter().cloned();
let root = kids.next().unwrap();
for node in nodes.iter().flatten() {
if let Some(val) = kids.next() {
node.borrow_mut().left = val;
}
if let Some(val) = kids.next() {
node.borrow_mut().right = val;
}
}
root
}
Cargo clippy: remove type arguments equal to defaults
Cargo clippy: Replace &Arc<T> with &T or Arc<T>
Replace &Arc with:
- &T if there is no clone inside the method
- Arc if there is a clone inside the method
Cargo clippy check for collect().iter() patterns
https://github.com/andreisilviudragnea/problems-rust/commit/a587070a62bdb5d94c32ec7fe0bad3c0805104e3
https://github.com/andreisilviudragnea/problems-rust/commit/bc425bb33048a9f99eca6cd12b05821fa5f804c5
let nodes = s[1..s.len() - 1]
.split(',')
.map(|str| match str {
"null" => None,
v => Some(v.parse::<i32>().unwrap()),
})
.collect::<Vec<_>>() // THIS CAN
.iter() // BE REMOVED
.map(|it| {
it.map(|val| {
Rc::new(RefCell::new(TreeNode {
val,
left: None,
right: None,
}))
})
})
.collect::<Vec<_>>();
Do not remove .collect()
calls if the collectors are used more than once.
RwLock deadlock
Lock read then write on the same thread results in deadlock
Cargo: Remove clone on moved struct fields
Use tracing instead of log crate
Removing .clone() calls can lead to cleaner code
Because it forces you to think about data ownership.
Strategy:
- First remove
#derive[(Clone)]
from as many types as possible. This usually results in manyArc
s on which.clone
is called instead. - Then check if those
Arc
s are really needed by looking if.clone()
on thoseArc
s is really needed.
Rust book: Document cargo test --nocapture
Inline function with only one usage
Keep variables with the same lifetime tied to the same struct
Use type-state pattern
Cargo clippy: Use &str instead of String
Replace .rev().collect::<Vec<_>>() and .pop() with .next()
Use Cargo workspace dependencies
In Cargo workspaces, specify dependencies only in root Cargo.toml
and refer them in other files to reduce duplication and centralize versions.
Cargo clippy: unused type parameter
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.