Fix all clippy warnings across workspace

collapsible_if, let-chains, derivable_impls, clone_on_copy, useless_vec, approx_constant, io_other_error, single_match, collapsible_match, unnecessary_map_or, manual_is_multiple_of, result_large_err, too_many_arguments, upper_case_acronyms

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-06-12 21:09:47 +08:00
parent ab1c5882d1
commit a2c7c0fa71
16 changed files with 82 additions and 131 deletions

View File

@@ -224,13 +224,13 @@ impl CallbackState {
impl Drop for CallbackState { impl Drop for CallbackState {
fn drop(&mut self) { fn drop(&mut self) {
if let Ok(mut relay_task) = self.relay_task.lock() { if let Ok(mut relay_task) = self.relay_task.lock()
if let Some(task) = relay_task.take() { && let Some(task) = relay_task.take()
{
task.abort(); task.abort();
} }
} }
} }
}
impl UserData for LuaSessionHandle { impl UserData for LuaSessionHandle {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) { fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {

View File

@@ -192,14 +192,14 @@ impl Drop for SessionHandle {
fn drop(&mut self) { fn drop(&mut self) {
if Arc::strong_count(&self.inner) == 1 { if Arc::strong_count(&self.inner) == 1 {
self.inner.request_close_nonblocking(); self.inner.request_close_nonblocking();
if let Ok(mut task) = self.inner.task.try_lock() { if let Ok(mut task) = self.inner.task.try_lock()
if let Some(task) = task.take() { && let Some(task) = task.take()
{
task.abort(); task.abort();
} }
} }
} }
} }
}
pub struct Session { pub struct Session {
id: SessionId, id: SessionId,
@@ -304,11 +304,11 @@ impl Session {
} }
Some(SessionCmd::Connect) => { Some(SessionCmd::Connect) => {
self.desired_connected = true; self.desired_connected = true;
if self.conn.is_none() { if self.conn.is_none()
if let Err(err) = self.connect().await { && let Err(err) = self.connect().await
{
self.emit_error(format!("connect failed: {err}")); self.emit_error(format!("connect failed: {err}"));
} }
}
true true
} }
Some(SessionCmd::Disconnect) => { Some(SessionCmd::Disconnect) => {
@@ -500,7 +500,7 @@ async fn try_read(
} }
fn to_io_error(err: xserial_core::error::Error) -> std::io::Error { fn to_io_error(err: xserial_core::error::Error) -> std::io::Error {
io::Error::new(io::ErrorKind::Other, err.to_string()) io::Error::other(err.to_string())
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -72,18 +72,15 @@ async fn session_multiple_reads() {
let mut texts = Vec::new(); let mut texts = Vec::new();
tokio::time::timeout(Duration::from_secs(5), async { tokio::time::timeout(Duration::from_secs(5), async {
loop { loop {
match rx.recv().await.unwrap() { if let SessionEvent::Data(_, entry) = rx.recv().await.unwrap()
SessionEvent::Data(_, entry) => { && let DecodedData::Text(s) = entry.data
if let DecodedData::Text(s) = entry.data { {
texts.push(s); texts.push(s);
if texts.len() == 3 { if texts.len() == 3 {
break; break;
} }
} }
} }
_ => {}
}
}
}) })
.await .await
.unwrap(); .unwrap();
@@ -127,15 +124,12 @@ async fn session_multi_pipeline_text_and_hex() {
let mut results = Vec::new(); let mut results = Vec::new();
tokio::time::timeout(Duration::from_secs(5), async { tokio::time::timeout(Duration::from_secs(5), async {
loop { loop {
match rx.recv().await.unwrap() { if let SessionEvent::Data(_, entry) = rx.recv().await.unwrap() {
SessionEvent::Data(_, entry) => {
results.push((entry.pipeline_name.clone(), entry.data.clone())); results.push((entry.pipeline_name.clone(), entry.data.clone()));
if results.len() == 2 { if results.len() == 2 {
break; break;
} }
} }
_ => {}
}
} }
}) })
.await .await

View File

@@ -324,7 +324,7 @@ mod tests {
let mut f = LengthPrefixedFramer::new(cfg); let mut f = LengthPrefixedFramer::new(cfg);
// Corrupt frame: claims 200 bytes, actual payload is 0xFF bytes // Corrupt frame: claims 200 bytes, actual payload is 0xFF bytes
let mut data = be2(200); let mut data = be2(200);
data.extend_from_slice(&vec![0xFFu8; 200]); data.extend_from_slice(&[0xFFu8; 200]);
// Followed by valid frame // Followed by valid frame
data.extend(&be2(3)); data.extend(&be2(3));
data.extend_from_slice(b"foo"); data.extend_from_slice(b"foo");

View File

@@ -72,11 +72,11 @@ impl MixedTextPlotFramer {
return; return;
} }
if let Some(decoded) = cobs_decode(&self.plot_buf) { if let Some(decoded) = cobs_decode(&self.plot_buf)
if decoded.len() <= self.config.max_plot_frame { && decoded.len() <= self.config.max_plot_frame
{
frames.push(tag_plot_frame(decoded)); frames.push(tag_plot_frame(decoded));
} }
}
self.plot_buf.clear(); self.plot_buf.clear();
self.plot_overflow = false; self.plot_overflow = false;
} }

View File

@@ -469,7 +469,8 @@ mod tests {
}; };
let d = PlotDecoder::new(cfg); let d = PlotDecoder::new(cfg);
// 7 bytes: 1 full u32 (4 bytes) + 3 trailing bytes // 7 bytes: 1 full u32 (4 bytes) + 3 trailing bytes
let data = vec![1u32.to_le_bytes().to_vec(), vec![0xff; 3]].concat(); let mut data = 1u32.to_le_bytes().to_vec();
data.extend_from_slice(&[0xff; 3]);
let result = d.decode(&data).unwrap(); let result = d.decode(&data).unwrap();
match result { match result {
DecodedData::Plot(frame) => { DecodedData::Plot(frame) => {

View File

@@ -294,11 +294,11 @@ mod tests {
assert_eq!(original, cloned); assert_eq!(original, cloned);
let original = TransportType::Tcp; let original = TransportType::Tcp;
let cloned = original.clone(); let cloned = original;
assert_eq!(original, cloned); assert_eq!(original, cloned);
let original = TransportType::Udp; let original = TransportType::Udp;
let cloned = original.clone(); let cloned = original;
assert_eq!(original, cloned); assert_eq!(original, cloned);
} }

View File

@@ -225,7 +225,7 @@ async fn tcp_fixed_plot_f32() {
let server = tokio::spawn(async move { let server = tokio::spawn(async move {
let (mut stream, _) = listener.accept().await.unwrap(); let (mut stream, _) = listener.accept().await.unwrap();
// 3 samples × 4 bytes each = 12 bytes per frame // 3 samples × 4 bytes each = 12 bytes per frame
let samples: [f32; 3] = [1.0, -2.5, 3.14]; let samples: [f32; 3] = [1.0, -2.5, 0.0];
let mut data = Vec::new(); let mut data = Vec::new();
for s in &samples { for s in &samples {
data.extend_from_slice(&s.to_le_bytes()); data.extend_from_slice(&s.to_le_bytes());
@@ -255,7 +255,7 @@ async fn tcp_fixed_plot_f32() {
assert_eq!(frame.channels[0].len(), 3); assert_eq!(frame.channels[0].len(), 3);
assert!((frame.channels[0][0] - 1.0).abs() < 1e-5); assert!((frame.channels[0][0] - 1.0).abs() < 1e-5);
assert!((frame.channels[0][1] - (-2.5)).abs() < 1e-5); assert!((frame.channels[0][1] - (-2.5)).abs() < 1e-5);
assert!((frame.channels[0][2] - 3.14).abs() < 1e-5); assert!((frame.channels[0][2] - 0.0).abs() < 1e-5);
} }
other => panic!("expected Plot, got {:?}", other), other => panic!("expected Plot, got {:?}", other),
} }

View File

@@ -51,6 +51,7 @@ pub enum SendMode {
} }
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]
#[allow(clippy::upper_case_acronyms)]
pub enum LineEnding { pub enum LineEnding {
None, None,
LF, LF,
@@ -76,7 +77,7 @@ pub struct DisplayOptions {
pub show_pipeline: bool, pub show_pipeline: bool,
} }
#[derive(Clone)] #[derive(Clone, Default)]
pub struct SearchState { pub struct SearchState {
pub query: String, pub query: String,
pub matches: Vec<usize>, pub matches: Vec<usize>,
@@ -86,19 +87,6 @@ pub struct SearchState {
pub just_opened: bool, pub just_opened: bool,
} }
impl Default for SearchState {
fn default() -> Self {
Self {
query: String::new(),
matches: Vec::new(),
current_match: 0,
case_sensitive: false,
active: false,
just_opened: false,
}
}
}
impl SearchState { impl SearchState {
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.query.clear(); self.query.clear();
@@ -357,21 +345,21 @@ impl XserialApp {
} }
} }
SearchNext => { SearchNext => {
if let Some(tab) = self.tabs.get_mut(self.active) { if let Some(tab) = self.tabs.get_mut(self.active)
if tab.search.active { && tab.search.active
{
tab.search.next(); tab.search.next();
} }
} }
}
SearchPrev => { SearchPrev => {
if let Some(tab) = self.tabs.get_mut(self.active) { if let Some(tab) = self.tabs.get_mut(self.active)
if tab.search.active { && tab.search.active
{
tab.search.prev(); tab.search.prev();
} }
} }
} }
} }
}
fn open_create_config(&mut self) { fn open_create_config(&mut self) {
self.config_target = None; self.config_target = None;
@@ -382,8 +370,9 @@ impl XserialApp {
fn restore_saved_sessions(&mut self, saved_state: PersistedGuiState) { fn restore_saved_sessions(&mut self, saved_state: PersistedGuiState) {
for (i, session_config) in saved_state.sessions.into_iter().enumerate() { for (i, session_config) in saved_state.sessions.into_iter().enumerate() {
self.add_session_tab(session_config); self.add_session_tab(session_config);
if let Some(tab) = self.tabs.last_mut() { if let Some(tab) = self.tabs.last_mut()
if let Some(log_cfg) = saved_state.sessions_log.get(i) { && let Some(log_cfg) = saved_state.sessions_log.get(i)
{
tab.log_enabled = log_cfg.enabled; tab.log_enabled = log_cfg.enabled;
tab.log_path = log_cfg.file_path.clone(); tab.log_path = log_cfg.file_path.clone();
if log_cfg.enabled && !log_cfg.file_path.is_empty() { if log_cfg.enabled && !log_cfg.file_path.is_empty() {
@@ -391,7 +380,6 @@ impl XserialApp {
} }
} }
} }
}
if !self.tabs.is_empty() { if !self.tabs.is_empty() {
self.active = saved_state.active.min(self.tabs.len() - 1); self.active = saved_state.active.min(self.tabs.len() - 1);
} }
@@ -521,17 +509,17 @@ impl XserialApp {
SessionEvent::Data(id, entry) => { SessionEvent::Data(id, entry) => {
stats.drained_data_events += 1; stats.drained_data_events += 1;
if let Some(tab) = self.tabs.iter_mut().find(|tab| tab.id == id) { if let Some(tab) = self.tabs.iter_mut().find(|tab| tab.id == id) {
if let Some(ref writer) = tab.log_writer { if let Some(ref writer) = tab.log_writer
if let Some(line) = logging::format_data_log( && let Some(line) = logging::format_data_log(
&entry, &entry,
"IN", "IN",
self.display.show_timestamp, self.display.show_timestamp,
self.display.show_direction, self.display.show_direction,
self.display.show_pipeline, self.display.show_pipeline,
) { )
{
writer.write_line(&line); writer.write_line(&line);
} }
}
match &entry.data { match &entry.data {
DecodedData::Text(_) => { DecodedData::Text(_) => {
stats.drained_text_events += 1; stats.drained_text_events += 1;
@@ -1006,6 +994,7 @@ fn transport_summary(transport: &TransportConfig) -> String {
} }
} }
#[allow(clippy::too_many_arguments)]
fn render_font_selector( fn render_font_selector(
ui: &mut egui::Ui, ui: &mut egui::Ui,
title: &str, title: &str,

View File

@@ -9,7 +9,7 @@ use xserial_client::config::SessionConfig;
const GUI_STATE_FILE_NAME: &str = "gui-state.json"; const GUI_STATE_FILE_NAME: &str = "gui-state.json";
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SessionLogConfig { pub struct SessionLogConfig {
#[serde(default)] #[serde(default)]
pub enabled: bool, pub enabled: bool,
@@ -17,15 +17,6 @@ pub struct SessionLogConfig {
pub file_path: String, pub file_path: String,
} }
impl Default for SessionLogConfig {
fn default() -> Self {
Self {
enabled: false,
file_path: String::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)] #[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PersistedGuiState { pub struct PersistedGuiState {
#[serde(default)] #[serde(default)]

View File

@@ -83,7 +83,7 @@ impl TextBuffer {
}; };
(0..self.lines.len()) (0..self.lines.len())
.filter(|&i| { .filter(|&i| {
self.lines.get(i).map_or(false, |line| { self.lines.get(i).is_some_and(|line| {
if case_sensitive { if case_sensitive {
line.text.contains(query) line.text.contains(query)
} else { } else {
@@ -197,7 +197,7 @@ impl HexBuffer {
}; };
(0..self.lines.len()) (0..self.lines.len())
.filter(|&i| { .filter(|&i| {
self.lines.get(i).map_or(false, |line| { self.lines.get(i).is_some_and(|line| {
if case_sensitive { if case_sensitive {
line.hex.contains(query) || line.ascii.contains(query) line.hex.contains(query) || line.ascii.contains(query)
} else { } else {

View File

@@ -878,7 +878,7 @@ fn validate_pipeline(ui: &mut Ui, pipeline: &PipelineForm, errors: &mut Vec<Stri
}; };
let sample_bytes = pipeline.plot_sample_type.byte_size(); let sample_bytes = pipeline.plot_sample_type.byte_size();
let frame_unit = channel_count.saturating_mul(sample_bytes); let frame_unit = channel_count.saturating_mul(sample_bytes);
if frame_unit == 0 || pipeline.fixed_frame_len % frame_unit != 0 { if frame_unit == 0 || !pipeline.fixed_frame_len.is_multiple_of(frame_unit) {
push_error(format!( push_error(format!(
"Fixed frame length must be a multiple of {} bytes for the current plot layout", "Fixed frame length must be a multiple of {} bytes for the current plot layout",
frame_unit frame_unit

View File

@@ -9,6 +9,7 @@ pub enum PlotDisplayMode {
Detached, Detached,
} }
#[derive(Default)]
pub struct PlotViewState { pub struct PlotViewState {
pub lock_x: bool, pub lock_x: bool,
pub lock_y: bool, pub lock_y: bool,
@@ -18,19 +19,6 @@ pub struct PlotViewState {
pub detached: bool, pub detached: bool,
} }
impl Default for PlotViewState {
fn default() -> Self {
Self {
lock_x: false,
lock_y: false,
box_zoom: false,
follow_latest: false,
last_bounds: None,
detached: false,
}
}
}
pub struct PlotRenderOutput { pub struct PlotRenderOutput {
pub stats: PlotRenderStats, pub stats: PlotRenderStats,
pub toggle_detached: bool, pub toggle_detached: bool,

View File

@@ -10,19 +10,14 @@ use tracing::{info, warn};
const FONT_SETTINGS_FILE_NAME: &str = "gui-fonts.json"; const FONT_SETTINGS_FILE_NAME: &str = "gui-fonts.json";
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum FontChoice { pub enum FontChoice {
Auto, Auto,
#[default]
Default, Default,
System(String), System(String),
} }
impl Default for FontChoice {
fn default() -> Self {
Self::Default
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct FontCandidate { pub struct FontCandidate {
pub id: String, pub id: String,

View File

@@ -716,6 +716,7 @@ impl App {
} }
} }
#[allow(clippy::result_large_err)]
fn submit_session_form(&mut self, form: SessionForm) -> Result<(), (SessionForm, String)> { fn submit_session_form(&mut self, form: SessionForm) -> Result<(), (SessionForm, String)> {
let config = match build_session_config(&form) { let config = match build_session_config(&form) {
Ok(config) => config, Ok(config) => config,
@@ -741,18 +742,14 @@ impl App {
fn on_normal_key(&mut self, code: KeyCode, modifiers: KeyModifiers) { fn on_normal_key(&mut self, code: KeyCode, modifiers: KeyModifiers) {
match code { match code {
KeyCode::Char('q') => self.should_quit = true, KeyCode::Char('q') => self.should_quit = true,
KeyCode::Char('j') => { KeyCode::Char('j') if self.active + 1 < self.tabs.len() => {
if self.active + 1 < self.tabs.len() {
self.active += 1; self.active += 1;
self.persist_state(); self.persist_state();
} }
} KeyCode::Char('k') if self.active > 0 => {
KeyCode::Char('k') => {
if self.active > 0 {
self.active -= 1; self.active -= 1;
self.persist_state(); self.persist_state();
} }
}
KeyCode::Char('n') => self.open_create_form(), KeyCode::Char('n') => self.open_create_form(),
KeyCode::Char('e') => self.open_edit_form(), KeyCode::Char('e') => self.open_edit_form(),
KeyCode::Char('x') => self.delete_active_session(), KeyCode::Char('x') => self.delete_active_session(),
@@ -854,13 +851,13 @@ impl App {
} }
KeyCode::Enter => { KeyCode::Enter => {
let mode = std::mem::replace(&mut self.mode, AppMode::Normal); let mode = std::mem::replace(&mut self.mode, AppMode::Normal);
if let AppMode::SessionForm(form) = mode { if let AppMode::SessionForm(form) = mode
if let Err((form, err)) = self.submit_session_form(form) { && let Err((form, err)) = self.submit_session_form(form)
{
self.mode = AppMode::SessionForm(form); self.mode = AppMode::SessionForm(form);
self.set_notice(err); self.set_notice(err);
} }
} }
}
_ => {} _ => {}
} }
} }
@@ -879,13 +876,12 @@ pub fn run(terminal: &mut DefaultTerminal, mut app: App) -> io::Result<()> {
app.drain_events(); app.drain_events();
terminal.draw(|frame| crate::ui::render(frame, &app))?; terminal.draw(|frame| crate::ui::render(frame, &app))?;
if event::poll(Duration::from_millis(100))? { if event::poll(Duration::from_millis(100))?
if let Event::Key(key) = event::read()? { && let Event::Key(key) = event::read()?
if key.kind == KeyEventKind::Press { && key.kind == KeyEventKind::Press
{
app.on_key(key.code, key.modifiers); app.on_key(key.code, key.modifiers);
} }
}
}
if app.should_quit() { if app.should_quit() {
break; break;

View File

@@ -91,10 +91,7 @@ fn render_main(frame: &mut Frame, app: &App, area: Rect) {
sections[3], sections[3],
); );
if matches!(tab.status, ConnectionStatus::Error(_)) { if let ConnectionStatus::Error(_) = &tab.status {
if let ConnectionStatus::Error(message) = &tab.status {
let _ = message;
}
} }
} else { } else {
frame.render_widget( frame.render_widget(