style(tui): apply rustfmt and clippy formatting across crate
Mechanical formatting pass to satisfy rustfmt line-width limits and clippy pedantic/nursery lints. No behavioral changes. Formatting (rustfmt line wrapping): - action/sync.rs: multiline tuple destructure, function call args in tests - state/sync.rs: if-let chain formatting, remove unnecessary Vec collect - view/sync.rs: multiline array entries, format!(), vec! literals - view/doctor.rs: multiline floor_char_boundary chain - view/scope_picker.rs: multiline format!() with floor_char_boundary - view/stats.rs: multiline render_stat_row call - view/mod.rs: multiline assert!() in test - app/update.rs: multiline enum variant destructure - entity_cache.rs: multiline assert_eq!() with messages - render_cache.rs: multiline retain() closure - session.rs: multiline serde_json/File::create/parent() chains Clippy: - action/sync.rs: #[allow(clippy::too_many_arguments)] on test helper Import/module ordering (alphabetical): - state/mod.rs: move scope_picker mod + pub use to sorted position - view/mod.rs: move scope_picker, stats, sync mod + use to sorted position - view/scope_picker.rs: sort use imports (ScopeContext before ScopePickerState)
This commit is contained in:
@@ -172,7 +172,15 @@ pub fn fetch_recent_runs(conn: &Connection, limit: usize) -> Result<Vec<SyncRunI
|
||||
let run_id: Option<String> = row.get(8)?;
|
||||
|
||||
Ok((
|
||||
id, status, command, started_at, finished_at, items, errors, error, run_id,
|
||||
id,
|
||||
status,
|
||||
command,
|
||||
started_at,
|
||||
finished_at,
|
||||
items,
|
||||
errors,
|
||||
error,
|
||||
run_id,
|
||||
))
|
||||
})
|
||||
.context("querying sync runs")?;
|
||||
@@ -265,6 +273,7 @@ mod tests {
|
||||
.expect("insert project");
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn insert_sync_run(
|
||||
conn: &Connection,
|
||||
started_at: i64,
|
||||
@@ -314,8 +323,26 @@ mod tests {
|
||||
create_sync_schema(&conn);
|
||||
|
||||
let now = 1_700_000_000_000_i64;
|
||||
insert_sync_run(&conn, now - 60_000, Some(now - 30_000), "succeeded", "sync", 100, 0, None);
|
||||
insert_sync_run(&conn, now - 120_000, Some(now - 90_000), "failed", "sync", 50, 2, Some("timeout"));
|
||||
insert_sync_run(
|
||||
&conn,
|
||||
now - 60_000,
|
||||
Some(now - 30_000),
|
||||
"succeeded",
|
||||
"sync",
|
||||
100,
|
||||
0,
|
||||
None,
|
||||
);
|
||||
insert_sync_run(
|
||||
&conn,
|
||||
now - 120_000,
|
||||
Some(now - 90_000),
|
||||
"failed",
|
||||
"sync",
|
||||
50,
|
||||
2,
|
||||
Some("timeout"),
|
||||
);
|
||||
|
||||
let clock = FakeClock::from_ms(now);
|
||||
let result = detect_running_sync(&conn, &clock).unwrap();
|
||||
@@ -386,8 +413,26 @@ mod tests {
|
||||
create_sync_schema(&conn);
|
||||
|
||||
let now = 1_700_000_000_000_i64;
|
||||
insert_sync_run(&conn, now - 120_000, Some(now - 90_000), "succeeded", "sync", 100, 0, None);
|
||||
insert_sync_run(&conn, now - 60_000, Some(now - 30_000), "succeeded", "sync", 200, 0, None);
|
||||
insert_sync_run(
|
||||
&conn,
|
||||
now - 120_000,
|
||||
Some(now - 90_000),
|
||||
"succeeded",
|
||||
"sync",
|
||||
100,
|
||||
0,
|
||||
None,
|
||||
);
|
||||
insert_sync_run(
|
||||
&conn,
|
||||
now - 60_000,
|
||||
Some(now - 30_000),
|
||||
"succeeded",
|
||||
"sync",
|
||||
200,
|
||||
0,
|
||||
None,
|
||||
);
|
||||
|
||||
let runs = fetch_recent_runs(&conn, 10).unwrap();
|
||||
assert_eq!(runs.len(), 2);
|
||||
@@ -425,7 +470,16 @@ mod tests {
|
||||
create_sync_schema(&conn);
|
||||
|
||||
let now = 1_700_000_000_000_i64;
|
||||
insert_sync_run(&conn, now - 60_000, Some(now - 15_000), "succeeded", "sync", 0, 0, None);
|
||||
insert_sync_run(
|
||||
&conn,
|
||||
now - 60_000,
|
||||
Some(now - 15_000),
|
||||
"succeeded",
|
||||
"sync",
|
||||
0,
|
||||
0,
|
||||
None,
|
||||
);
|
||||
|
||||
let runs = fetch_recent_runs(&conn, 10).unwrap();
|
||||
assert_eq!(runs[0].duration_ms, Some(45_000));
|
||||
@@ -517,8 +571,26 @@ mod tests {
|
||||
|
||||
let now = 1_700_000_000_000_i64;
|
||||
insert_project(&conn, 1, "group/repo");
|
||||
insert_sync_run(&conn, now - 120_000, Some(now - 90_000), "succeeded", "sync", 150, 0, None);
|
||||
insert_sync_run(&conn, now - 60_000, Some(now - 30_000), "failed", "sync", 50, 2, Some("db locked"));
|
||||
insert_sync_run(
|
||||
&conn,
|
||||
now - 120_000,
|
||||
Some(now - 90_000),
|
||||
"succeeded",
|
||||
"sync",
|
||||
150,
|
||||
0,
|
||||
None,
|
||||
);
|
||||
insert_sync_run(
|
||||
&conn,
|
||||
now - 60_000,
|
||||
Some(now - 30_000),
|
||||
"failed",
|
||||
"sync",
|
||||
50,
|
||||
2,
|
||||
Some("db locked"),
|
||||
);
|
||||
|
||||
let clock = FakeClock::from_ms(now);
|
||||
let overview = fetch_sync_overview(&conn, &clock).unwrap();
|
||||
@@ -542,7 +614,16 @@ mod tests {
|
||||
insert_project(&conn, 1, "group/repo");
|
||||
|
||||
// A completed run.
|
||||
insert_sync_run(&conn, now - 600_000, Some(now - 570_000), "succeeded", "sync", 200, 0, None);
|
||||
insert_sync_run(
|
||||
&conn,
|
||||
now - 600_000,
|
||||
Some(now - 570_000),
|
||||
"succeeded",
|
||||
"sync",
|
||||
200,
|
||||
0,
|
||||
None,
|
||||
);
|
||||
|
||||
// A currently running sync.
|
||||
conn.execute(
|
||||
|
||||
@@ -590,7 +590,10 @@ impl LoreApp {
|
||||
}
|
||||
|
||||
// --- Search ---
|
||||
Msg::SearchExecuted { generation, results } => {
|
||||
Msg::SearchExecuted {
|
||||
generation,
|
||||
results,
|
||||
} => {
|
||||
if self
|
||||
.supervisor
|
||||
.is_current(&TaskKey::LoadScreen(Screen::Search), generation)
|
||||
|
||||
@@ -154,8 +154,16 @@ mod tests {
|
||||
// Insert a 4th item: should evict issue(2) (tick 2, lowest).
|
||||
cache.put(issue(4), "d"); // tick 5
|
||||
|
||||
assert_eq!(cache.get(&issue(1)), Some(&"a"), "issue(1) should survive (recently accessed)");
|
||||
assert_eq!(cache.get(&issue(2)), None, "issue(2) should be evicted (LRU)");
|
||||
assert_eq!(
|
||||
cache.get(&issue(1)),
|
||||
Some(&"a"),
|
||||
"issue(1) should survive (recently accessed)"
|
||||
);
|
||||
assert_eq!(
|
||||
cache.get(&issue(2)),
|
||||
None,
|
||||
"issue(2) should be evicted (LRU)"
|
||||
);
|
||||
assert_eq!(cache.get(&issue(3)), Some(&"c"), "issue(3) should survive");
|
||||
assert_eq!(cache.get(&issue(4)), Some(&"d"), "issue(4) just inserted");
|
||||
}
|
||||
|
||||
@@ -104,8 +104,7 @@ impl<V> RenderCache<V> {
|
||||
///
|
||||
/// After a resize, only entries rendered at the new width are still valid.
|
||||
pub fn invalidate_width(&mut self, keep_width: u16) {
|
||||
self.entries
|
||||
.retain(|k, _| k.terminal_width == keep_width);
|
||||
self.entries.retain(|k, _| k.terminal_width == keep_width);
|
||||
}
|
||||
|
||||
/// Clear the entire cache (theme change — all colors invalidated).
|
||||
|
||||
@@ -95,8 +95,8 @@ pub fn save_session(state: &SessionState, path: &Path) -> Result<(), SessionErro
|
||||
fs::create_dir_all(parent).map_err(|e| SessionError::Io(e.to_string()))?;
|
||||
}
|
||||
|
||||
let json = serde_json::to_string_pretty(state)
|
||||
.map_err(|e| SessionError::Serialize(e.to_string()))?;
|
||||
let json =
|
||||
serde_json::to_string_pretty(state).map_err(|e| SessionError::Serialize(e.to_string()))?;
|
||||
|
||||
// Check size before writing.
|
||||
if json.len() as u64 > MAX_SESSION_SIZE {
|
||||
@@ -112,8 +112,7 @@ pub fn save_session(state: &SessionState, path: &Path) -> Result<(), SessionErro
|
||||
|
||||
// Write to temp file, fsync, rename.
|
||||
let tmp_path = path.with_extension("tmp");
|
||||
let mut file =
|
||||
fs::File::create(&tmp_path).map_err(|e| SessionError::Io(e.to_string()))?;
|
||||
let mut file = fs::File::create(&tmp_path).map_err(|e| SessionError::Io(e.to_string()))?;
|
||||
file.write_all(payload.as_bytes())
|
||||
.map_err(|e| SessionError::Io(e.to_string()))?;
|
||||
file.sync_all()
|
||||
@@ -179,10 +178,7 @@ pub fn load_session(path: &Path) -> Result<SessionState, SessionError> {
|
||||
|
||||
/// Move a corrupt session file to `.quarantine/` instead of deleting it.
|
||||
fn quarantine(path: &Path) -> Result<(), SessionError> {
|
||||
let quarantine_dir = path
|
||||
.parent()
|
||||
.unwrap_or(Path::new("."))
|
||||
.join(".quarantine");
|
||||
let quarantine_dir = path.parent().unwrap_or(Path::new(".")).join(".quarantine");
|
||||
fs::create_dir_all(&quarantine_dir).map_err(|e| SessionError::Io(e.to_string()))?;
|
||||
|
||||
let filename = path
|
||||
|
||||
@@ -22,13 +22,13 @@ pub mod issue_detail;
|
||||
pub mod issue_list;
|
||||
pub mod mr_detail;
|
||||
pub mod mr_list;
|
||||
pub mod scope_picker;
|
||||
pub mod search;
|
||||
pub mod stats;
|
||||
pub mod sync;
|
||||
pub mod sync_delta_ledger;
|
||||
pub mod timeline;
|
||||
pub mod trace;
|
||||
pub mod scope_picker;
|
||||
pub mod who;
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
@@ -45,12 +45,12 @@ pub use issue_detail::IssueDetailState;
|
||||
pub use issue_list::IssueListState;
|
||||
pub use mr_detail::MrDetailState;
|
||||
pub use mr_list::MrListState;
|
||||
pub use scope_picker::ScopePickerState;
|
||||
pub use search::SearchState;
|
||||
pub use stats::StatsState;
|
||||
pub use sync::SyncState;
|
||||
pub use timeline::TimelineState;
|
||||
pub use trace::TraceState;
|
||||
pub use scope_picker::ScopePickerState;
|
||||
pub use who::WhoState;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -356,15 +356,15 @@ impl SyncState {
|
||||
self.bytes_synced = bytes;
|
||||
self.items_synced = items;
|
||||
// Compute actual throughput from elapsed time since sync start.
|
||||
if items > 0 {
|
||||
if let Some(started) = self.started_at {
|
||||
if items > 0
|
||||
&& let Some(started) = self.started_at
|
||||
{
|
||||
let elapsed_secs = started.elapsed().as_secs_f64();
|
||||
if elapsed_secs > 0.0 {
|
||||
self.items_per_sec = items as f64 / elapsed_secs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether sync is currently running.
|
||||
#[must_use]
|
||||
@@ -375,8 +375,7 @@ impl SyncState {
|
||||
/// Overall progress fraction (average of all lanes).
|
||||
#[must_use]
|
||||
pub fn overall_progress(&self) -> f64 {
|
||||
let active_lanes: Vec<&LaneProgress> =
|
||||
self.lanes.iter().filter(|l| l.total > 0).collect();
|
||||
let active_lanes: Vec<&LaneProgress> = self.lanes.iter().filter(|l| l.total > 0).collect();
|
||||
if active_lanes.is_empty() {
|
||||
return 0.0;
|
||||
}
|
||||
@@ -537,10 +536,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
// With ~0ms between calls, at most 0-1 additional emits expected.
|
||||
assert!(
|
||||
emitted <= 1,
|
||||
"Expected at most 1 emit, got {emitted}"
|
||||
);
|
||||
assert!(emitted <= 1, "Expected at most 1 emit, got {emitted}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -127,7 +127,9 @@ pub fn render_doctor(frame: &mut Frame<'_>, state: &DoctorState, area: Rect) {
|
||||
let detail = if check.detail.len() > max_detail {
|
||||
format!(
|
||||
"{}...",
|
||||
&check.detail[..check.detail.floor_char_boundary(max_detail.saturating_sub(3))]
|
||||
&check.detail[..check
|
||||
.detail
|
||||
.floor_char_boundary(max_detail.saturating_sub(3))]
|
||||
)
|
||||
} else {
|
||||
check.detail.clone()
|
||||
|
||||
@@ -16,12 +16,12 @@ pub mod issue_detail;
|
||||
pub mod issue_list;
|
||||
pub mod mr_detail;
|
||||
pub mod mr_list;
|
||||
pub mod search;
|
||||
pub mod timeline;
|
||||
pub mod trace;
|
||||
pub mod scope_picker;
|
||||
pub mod search;
|
||||
pub mod stats;
|
||||
pub mod sync;
|
||||
pub mod timeline;
|
||||
pub mod trace;
|
||||
pub mod who;
|
||||
|
||||
use ftui::layout::{Constraint, Flex};
|
||||
@@ -43,12 +43,12 @@ use issue_detail::render_issue_detail;
|
||||
use issue_list::render_issue_list;
|
||||
use mr_detail::render_mr_detail;
|
||||
use mr_list::render_mr_list;
|
||||
use search::render_search;
|
||||
use timeline::render_timeline;
|
||||
use trace::render_trace;
|
||||
use scope_picker::render_scope_picker;
|
||||
use search::render_search;
|
||||
use stats::render_stats;
|
||||
use sync::render_sync;
|
||||
use timeline::render_timeline;
|
||||
use trace::render_trace;
|
||||
use who::render_who;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -261,10 +261,7 @@ mod tests {
|
||||
let has_content = (20..60u16).any(|x| {
|
||||
(8..16u16).any(|y| frame.buffer.get(x, y).is_some_and(|cell| !cell.is_empty()))
|
||||
});
|
||||
assert!(
|
||||
has_content,
|
||||
"Expected sync idle content in center area"
|
||||
);
|
||||
assert!(has_content, "Expected sync idle content in center area");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ use ftui::render::cell::{Cell, PackedRgba};
|
||||
use ftui::render::drawing::{BorderChars, Draw};
|
||||
use ftui::render::frame::Frame;
|
||||
|
||||
use crate::state::scope_picker::ScopePickerState;
|
||||
use crate::state::ScopeContext;
|
||||
use crate::state::scope_picker::ScopePickerState;
|
||||
|
||||
use super::{ACCENT, BG_SURFACE, BORDER, TEXT, TEXT_MUTED};
|
||||
|
||||
@@ -131,7 +131,10 @@ pub fn render_scope_picker(
|
||||
// Truncate label to fit.
|
||||
let max_label_len = content_width.saturating_sub(2) as usize; // 2 for prefix
|
||||
let display = if label.len() > max_label_len {
|
||||
format!("{prefix}{}...", &label[..label.floor_char_boundary(max_label_len.saturating_sub(3))])
|
||||
format!(
|
||||
"{prefix}{}...",
|
||||
&label[..label.floor_char_boundary(max_label_len.saturating_sub(3))]
|
||||
)
|
||||
} else {
|
||||
format!("{prefix}{label}")
|
||||
};
|
||||
|
||||
@@ -93,7 +93,15 @@ pub fn render_stats(frame: &mut Frame<'_>, state: &StatsState, area: Rect) {
|
||||
if y >= area.bottom().saturating_sub(2) {
|
||||
break;
|
||||
}
|
||||
render_stat_row(frame, area.x + 2, y, label, &format_count(*count), label_width, max_x);
|
||||
render_stat_row(
|
||||
frame,
|
||||
area.x + 2,
|
||||
y,
|
||||
label,
|
||||
&format_count(*count),
|
||||
label_width,
|
||||
max_x,
|
||||
);
|
||||
y += 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -262,8 +262,16 @@ fn render_summary(frame: &mut Frame<'_>, state: &SyncState, area: Rect) {
|
||||
// Summary rows.
|
||||
let rows = [
|
||||
("Issues", summary.issues.new, summary.issues.updated),
|
||||
("MRs", summary.merge_requests.new, summary.merge_requests.updated),
|
||||
("Discussions", summary.discussions.new, summary.discussions.updated),
|
||||
(
|
||||
"MRs",
|
||||
summary.merge_requests.new,
|
||||
summary.merge_requests.updated,
|
||||
),
|
||||
(
|
||||
"Discussions",
|
||||
summary.discussions.new,
|
||||
summary.discussions.updated,
|
||||
),
|
||||
("Notes", summary.notes.new, summary.notes.updated),
|
||||
];
|
||||
|
||||
@@ -404,7 +412,10 @@ fn render_failed(frame: &mut Frame<'_>, area: Rect, error: &str) {
|
||||
// Truncate error to fit screen.
|
||||
let max_len = area.width.saturating_sub(4) as usize;
|
||||
let display_err = if error.len() > max_len {
|
||||
format!("{}...", &error[..error.floor_char_boundary(max_len.saturating_sub(3))])
|
||||
format!(
|
||||
"{}...",
|
||||
&error[..error.floor_char_boundary(max_len.saturating_sub(3))]
|
||||
)
|
||||
} else {
|
||||
error.to_string()
|
||||
};
|
||||
@@ -541,9 +552,7 @@ mod tests {
|
||||
state.complete(3000);
|
||||
state.summary = Some(SyncSummary {
|
||||
elapsed_ms: 3000,
|
||||
project_errors: vec![
|
||||
("grp/repo".into(), "timeout".into()),
|
||||
],
|
||||
project_errors: vec![("grp/repo".into(), "timeout".into())],
|
||||
..Default::default()
|
||||
});
|
||||
let area = frame.bounds();
|
||||
|
||||
Reference in New Issue
Block a user