diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f733406..9eccc22 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -169,7 +169,10 @@ jobs: run: cargo fmt --all -- --check - name: Run cargo clippy - run: cargo clippy --all-features + run: | + cargo clippy --tests --all-features + # See PR#75: https://github.com/asynchronics/nexosim/pull/75 + cargo clippy --examples --all-features -- -A clippy::new_without_default -A clippy::manual_async_fn docs: name: Docs diff --git a/nexosim-util/examples/observables.rs b/nexosim-util/examples/observables.rs index 16e598c..c80f2b0 100644 --- a/nexosim-util/examples/observables.rs +++ b/nexosim-util/examples/observables.rs @@ -48,18 +48,14 @@ pub enum ModeId { } /// Processor state. +#[derive(Default)] pub enum State { + #[default] Off, Idle, Processing(AutoActionKey), } -impl Default for State { - fn default() -> Self { - State::Off - } -} - impl Observable for State { fn observe(&self) -> ModeId { match *self { diff --git a/nexosim/src/channel/queue.rs b/nexosim/src/channel/queue.rs index 57747de..6c15c58 100644 --- a/nexosim/src/channel/queue.rs +++ b/nexosim/src/channel/queue.rs @@ -482,7 +482,7 @@ mod tests { assert!(matches!(c.pop(), Err(PopError::Empty))); - assert!(matches!(p.push(|b| RecycleBox::recycle(b, 42)), Ok(_))); + assert!(p.push(|b| RecycleBox::recycle(b, 42)).is_ok()); p.close(); assert_eq!(*c.pop().unwrap(), 42); @@ -493,12 +493,12 @@ mod tests { fn queue_closed_by_consumer() { let (p, mut c) = queue(3); - assert_eq!(p.is_closed(), false); - assert!(matches!(p.push(|b| RecycleBox::recycle(b, 42)), Ok(_))); + assert!(!p.is_closed()); + assert!(p.push(|b| RecycleBox::recycle(b, 42)).is_ok()); c.close(); - assert_eq!(p.is_closed(), true); + assert!(p.is_closed()); assert!(matches!( p.push(|b| RecycleBox::recycle(b, 13)), Err(PushError::Closed) diff --git a/nexosim/src/executor.rs b/nexosim/src/executor.rs index 90f8884..b2d145c 100644 --- a/nexosim/src/executor.rs +++ b/nexosim/src/executor.rs @@ -173,7 +173,9 @@ mod tests { } impl Drop for RunOnDrop { fn drop(&mut self) { - self.drop_fn.take().map(|f| f()); + if let Some(f) = self.drop_fn.take() { + f() + } } } diff --git a/nexosim/src/executor/task/tests/general.rs b/nexosim/src/executor/task/tests/general.rs index 00c42b7..0937ac9 100644 --- a/nexosim/src/executor/task/tests/general.rs +++ b/nexosim/src/executor/task/tests/general.rs @@ -164,13 +164,13 @@ fn task_schedule() { let (future, future_is_alive, output_is_alive) = MonitoredFuture::new(async move { 42 }); let (promise, runnable, _cancel_token) = spawn(future, schedule_runnable, ()); - assert_eq!(future_is_alive.get(), true); - assert_eq!(output_is_alive.get(), false); + assert!(future_is_alive.get()); + assert!(!output_is_alive.get()); // The task should complete immediately when ran. runnable.run(); - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), true); + assert!(!future_is_alive.get()); + assert!(output_is_alive.get()); assert_eq!(promise.poll().map(|v| *v), Stage::Ready(42)); } @@ -200,13 +200,13 @@ fn task_schedule_and_forget() { let (future, future_is_alive, output_is_alive) = MonitoredFuture::new(async {}); let (runnable, _cancel_token) = spawn_and_forget(future, schedule_runnable, ()); - assert_eq!(future_is_alive.get(), true); - assert_eq!(output_is_alive.get(), false); + assert!(future_is_alive.get()); + assert!(!output_is_alive.get()); // The task should complete immediately when ran. runnable.run(); - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), true); + assert!(!future_is_alive.get()); + assert!(output_is_alive.get()); } #[test] @@ -215,25 +215,23 @@ fn task_wake() { let (sender, receiver) = oneshot::channel(); - let (future, future_is_alive, output_is_alive) = MonitoredFuture::new(async move { - let result = receiver.await.unwrap(); - result - }); + let (future, future_is_alive, output_is_alive) = + MonitoredFuture::new(async move { receiver.await.unwrap() }); let (promise, runnable, _cancel_token) = spawn(future, schedule_runnable, ()); runnable.run(); // The future should have been polled but should not have completed. - assert_eq!(output_is_alive.get(), false); + assert!(!output_is_alive.get()); assert!(promise.poll().is_pending()); // Wake the task. sender.send(42).unwrap(); // The task should have been scheduled by the channel sender. - assert_eq!(run_scheduled_runnable(), true); - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), true); + assert!(run_scheduled_runnable()); + assert!(!future_is_alive.get()); + assert!(output_is_alive.get()); assert_eq!(promise.poll().map(|v| *v), Stage::Ready(42)); } @@ -244,10 +242,7 @@ fn task_wake_mt() { let (sender, receiver) = oneshot::channel(); let (promise, runnable, _cancel_token) = spawn( - async move { - let result = receiver.await.unwrap(); - result - }, + async move { receiver.await.unwrap() }, schedule_runnable, (), ); @@ -284,15 +279,15 @@ fn task_wake_and_forget() { runnable.run(); // The future should have been polled but should not have completed. - assert_eq!(output_is_alive.get(), false); + assert!(!output_is_alive.get()); // Wake the task. sender.send(42).unwrap(); // The task should have been scheduled by the channel sender. - assert_eq!(run_scheduled_runnable(), true); - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), true); + assert!(run_scheduled_runnable()); + assert!(!future_is_alive.get()); + assert!(output_is_alive.get()); } #[test] @@ -321,7 +316,7 @@ fn task_multiple_wake() { sender.try_send(3).unwrap(); // The task should have been scheduled by the channel sender. - assert_eq!(run_scheduled_runnable(), true); + assert!(run_scheduled_runnable()); assert!(promise.poll().is_pending()); // The channel should be empty. Wake the task 2 more times. @@ -329,11 +324,11 @@ fn task_multiple_wake() { sender.try_send(5).unwrap(); // The task should have been scheduled by the channel sender. - assert_eq!(run_scheduled_runnable(), true); + assert!(run_scheduled_runnable()); // The task should have completed. - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), true); + assert!(!future_is_alive.get()); + assert!(output_is_alive.get()); assert_eq!(promise.poll().map(|v| *v), Stage::Ready(15)); } @@ -401,13 +396,13 @@ fn task_cancel_scheduled() { // The future should not be dropped while the `Runnable` exists, even if the // task is cancelled, but the task should be seen as cancelled. - assert_eq!(future_is_alive.get(), true); + assert!(future_is_alive.get()); assert!(promise.poll().is_cancelled()); // An attempt to run the task should now drop the future without polling it. runnable.run(); - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), false); + assert!(!future_is_alive.get()); + assert!(!output_is_alive.get()); } #[test] @@ -422,8 +417,8 @@ fn task_cancel_unscheduled() { let (promise, runnable, cancel_token) = spawn(future, schedule_runnable, ()); runnable.run(); - assert_eq!(future_is_alive.get(), true); - assert_eq!(output_is_alive.get(), false); + assert!(future_is_alive.get()); + assert!(!output_is_alive.get()); // Cancel the task while no `Runnable` exists (the task is not scheduled as // it needs to be woken by the channel sender first). @@ -433,8 +428,8 @@ fn task_cancel_unscheduled() { // The future should be dropped immediately upon cancellation without // completing. - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), false); + assert!(!future_is_alive.get()); + assert!(!output_is_alive.get()); } #[test] @@ -445,12 +440,12 @@ fn task_cancel_completed() { let (promise, runnable, cancel_token) = spawn(future, schedule_runnable, ()); runnable.run(); - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), true); + assert!(!future_is_alive.get()); + assert!(output_is_alive.get()); // Cancel the already completed task. cancel_token.cancel(); - assert_eq!(output_is_alive.get(), true); + assert!(output_is_alive.get()); assert_eq!(promise.poll().map(|v| *v), Stage::Ready(42)); } @@ -479,8 +474,8 @@ fn task_drop_promise_scheduled() { // The task should complete immediately when ran. runnable.run(); - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), true); + assert!(!future_is_alive.get()); + assert!(output_is_alive.get()); } #[test] @@ -504,9 +499,9 @@ fn task_drop_promise_unscheduled() { assert!(sender.send(()).is_ok()); // The task should have been scheduled by the channel sender. - assert_eq!(run_scheduled_runnable(), true); - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), true); + assert!(run_scheduled_runnable()); + assert!(!future_is_alive.get()); + assert!(output_is_alive.get()); } #[test] @@ -538,9 +533,9 @@ fn task_drop_runnable() { assert!(sender.send(()).is_ok()); // Drop the task scheduled by the channel sender. - assert_eq!(drop_runnable(), true); - assert_eq!(future_is_alive.get(), false); - assert_eq!(output_is_alive.get(), false); + assert!(drop_runnable()); + assert!(!future_is_alive.get()); + assert!(!output_is_alive.get()); assert!(promise.poll().is_cancelled()); } diff --git a/nexosim/src/ports/output/broadcaster.rs b/nexosim/src/ports/output/broadcaster.rs index 4da1d4a..0a2f9a4 100644 --- a/nexosim/src/ports/output/broadcaster.rs +++ b/nexosim/src/ports/output/broadcaster.rs @@ -672,9 +672,8 @@ mod tests { let th_broadcast = thread::spawn(move || { let iter = block_on(broadcaster.broadcast(MESSAGE)).unwrap(); - let sum = iter.fold(0, |acc, val| acc + val); - sum + iter.sum::() }); let th_recv: Vec<_> = mailboxes @@ -727,11 +726,7 @@ mod tests { // Send messages reaching only one receiver each. for id in 0..N_RECV { - sum += broadcaster - .broadcast(id) - .await - .unwrap() - .fold(0, |acc, val| acc + val); + sum += broadcaster.broadcast(id).await.unwrap().sum::(); } // Broadcast the special value to all receivers. @@ -739,15 +734,11 @@ mod tests { .broadcast(BROADCAST_ALL) .await .unwrap() - .fold(0, |acc, val| acc + val); + .sum::(); // Send again messages reaching only one receiver each. for id in 0..N_RECV { - sum += broadcaster - .broadcast(id) - .await - .unwrap() - .fold(0, |acc, val| acc + val); + sum += broadcaster.broadcast(id).await.unwrap().sum::(); } sum diff --git a/nexosim/src/ports/source/broadcaster.rs b/nexosim/src/ports/source/broadcaster.rs index 69c91ed..107b96a 100644 --- a/nexosim/src/ports/source/broadcaster.rs +++ b/nexosim/src/ports/source/broadcaster.rs @@ -567,9 +567,8 @@ mod tests { let th_broadcast = thread::spawn(move || { let iter = block_on(broadcaster.broadcast(MESSAGE)).unwrap(); - let sum = iter.fold(0, |acc, val| acc + val); - sum + iter.sum::() }); let th_recv: Vec<_> = mailboxes @@ -622,11 +621,7 @@ mod tests { // Send messages reaching only one receiver each. for id in 0..N_RECV { - sum += broadcaster - .broadcast(id) - .await - .unwrap() - .fold(0, |acc, val| acc + val); + sum += broadcaster.broadcast(id).await.unwrap().sum::(); } // Broadcast the special value to all receivers. @@ -634,15 +629,11 @@ mod tests { .broadcast(BROADCAST_ALL) .await .unwrap() - .fold(0, |acc, val| acc + val); + .sum::(); // Send again messages reaching only one receiver each. for id in 0..N_RECV { - sum += broadcaster - .broadcast(id) - .await - .unwrap() - .fold(0, |acc, val| acc + val); + sum += broadcaster.broadcast(id).await.unwrap().sum::(); } sum diff --git a/nexosim/src/util/indexed_priority_queue.rs b/nexosim/src/util/indexed_priority_queue.rs index 7b28ca5..c2d8967 100644 --- a/nexosim/src/util/indexed_priority_queue.rs +++ b/nexosim/src/util/indexed_priority_queue.rs @@ -649,14 +649,12 @@ mod tests { let delete_marked_fn = |queue: &mut IndexedPriorityQueue, shadow_queue: &mut BTreeMap<(u64, usize), u64>| { - let success = match marked.take() { - Some(delete_key) => Some(queue.extract(delete_key).is_some()), - None => None, - }; - let shadow_success = match shadow_marked.take() { - Some(delete_key) => Some(shadow_queue.remove(&delete_key).is_some()), - None => None, - }; + let success = marked + .take() + .map(|delete_key| queue.extract(delete_key).is_some()); + let shadow_success = shadow_marked + .take() + .map(|delete_key| shadow_queue.remove(&delete_key).is_some()); assert_eq!(success, shadow_success); };