max / alloy_tui
4 files changed,
+45 insertions,
-4 deletions
| @@ -11,3 +11,35 @@ authors = ["Max Johnson <me@maxj.phd>"] | |||
| 11 | 11 | [dependencies] | |
| 12 | 12 | ratatui = "0.30" | |
| 13 | 13 | makeover = "1.1.0" | |
| 14 | + | ||
| 15 | + | [lints.rust] | |
| 16 | + | unused = "warn" | |
| 17 | + | unreachable_pub = "warn" | |
| 18 | + | ||
| 19 | + | [lints.clippy] | |
| 20 | + | pedantic = { level = "warn", priority = -1 } | |
| 21 | + | # Allow-list tuned from a measured breakdown across server/multithreaded/pter | |
| 22 | + | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 23 | + | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 24 | + | module_name_repetitions = "allow" | |
| 25 | + | # Doc lints — no docs-completeness push underway. | |
| 26 | + | missing_errors_doc = "allow" | |
| 27 | + | missing_panics_doc = "allow" | |
| 28 | + | doc_markdown = "allow" | |
| 29 | + | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 30 | + | cast_possible_truncation = "allow" | |
| 31 | + | cast_sign_loss = "allow" | |
| 32 | + | cast_precision_loss = "allow" | |
| 33 | + | cast_possible_wrap = "allow" | |
| 34 | + | cast_lossless = "allow" | |
| 35 | + | # Subjective structure/style nags — high churn, low signal. | |
| 36 | + | must_use_candidate = "allow" | |
| 37 | + | too_many_lines = "allow" | |
| 38 | + | struct_excessive_bools = "allow" | |
| 39 | + | similar_names = "allow" | |
| 40 | + | items_after_statements = "allow" | |
| 41 | + | single_match_else = "allow" | |
| 42 | + | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 43 | + | match_same_arms = "allow" | |
| 44 | + | unnecessary_wraps = "allow" | |
| 45 | + | type_complexity = "allow" |
| @@ -59,7 +59,7 @@ pub fn classify(key: KeyEvent) -> Action { | |||
| 59 | 59 | let shift = key.modifiers.contains(KeyModifiers::SHIFT); | |
| 60 | 60 | ||
| 61 | 61 | match key.code { | |
| 62 | - | KeyCode::Char('s') | KeyCode::Char('S') if ctrl => Action::Save, | |
| 62 | + | KeyCode::Char('s' | 'S') if ctrl => Action::Save, | |
| 63 | 63 | KeyCode::BackTab => Action::PrevFocus, | |
| 64 | 64 | KeyCode::Tab if shift => Action::PrevFocus, | |
| 65 | 65 | KeyCode::Tab => Action::NextFocus, |
| @@ -207,6 +207,7 @@ impl Theme { | |||
| 207 | 207 | /// rather than on its own, so a border stays a border and text stays | |
| 208 | 208 | /// readable. The surfaces themselves are quantized plainly: they are what | |
| 209 | 209 | /// the others are measured against. | |
| 210 | + | #[must_use] | |
| 210 | 211 | pub fn for_terminal(self, depth: ColorDepth) -> Theme { | |
| 211 | 212 | if depth == ColorDepth::Full { | |
| 212 | 213 | return self; | |
| @@ -284,7 +285,7 @@ fn channel_to_linear(c: u8) -> f32 { | |||
| 284 | 285 | } | |
| 285 | 286 | ||
| 286 | 287 | fn channel_to_srgb(c: f32) -> u8 { | |
| 287 | - | let v = if c <= 0.0031308 { | |
| 288 | + | let v = if c <= 0.003_130_8 { | |
| 288 | 289 | c * 12.92 | |
| 289 | 290 | } else { | |
| 290 | 291 | 1.055 * c.powf(1.0 / 2.4) - 0.055 |
| @@ -39,6 +39,7 @@ impl<'a> AlloyBlock<'a> { | |||
| 39 | 39 | } | |
| 40 | 40 | } | |
| 41 | 41 | ||
| 42 | + | #[must_use] | |
| 42 | 43 | pub fn focused(mut self, focused: bool) -> Self { | |
| 43 | 44 | self.focused = focused; | |
| 44 | 45 | self | |
| @@ -131,6 +132,7 @@ impl<'a> AlloyStatusBar<'a> { | |||
| 131 | 132 | } | |
| 132 | 133 | ||
| 133 | 134 | /// Attach a transient status message (busy, error, dirty) to the right end. | |
| 135 | + | #[must_use] | |
| 134 | 136 | pub fn status(mut self, severity: Severity, message: impl Into<String>) -> Self { | |
| 135 | 137 | self.status = Some((severity, message.into())); | |
| 136 | 138 | self | |
| @@ -198,6 +200,7 @@ impl<'a> AlloyList<'a> { | |||
| 198 | 200 | } | |
| 199 | 201 | } | |
| 200 | 202 | ||
| 203 | + | #[must_use] | |
| 201 | 204 | pub fn selected(mut self, selected: Option<usize>) -> Self { | |
| 202 | 205 | self.selected = selected; | |
| 203 | 206 | self | |
| @@ -317,6 +320,7 @@ impl<'a> AlloyTabs<'a> { | |||
| 317 | 320 | /// Select a tab. Out-of-range indices select nothing, matching | |
| 318 | 321 | /// [`FocusRing::focus`](crate::FocusRing::focus): landing on a neighbouring | |
| 319 | 322 | /// tab is worse than showing none as current. | |
| 323 | + | #[must_use] | |
| 320 | 324 | pub fn selected(mut self, selected: usize) -> Self { | |
| 321 | 325 | self.selected = selected; | |
| 322 | 326 | self | |
| @@ -383,6 +387,7 @@ impl<'a> AlloyModal<'a> { | |||
| 383 | 387 | } | |
| 384 | 388 | } | |
| 385 | 389 | ||
| 390 | + | #[must_use] | |
| 386 | 391 | pub fn severity(mut self, severity: Severity) -> Self { | |
| 387 | 392 | self.severity = severity; | |
| 388 | 393 | self | |
| @@ -623,7 +628,10 @@ mod tests { | |||
| 623 | 628 | AlloyTabs::new(&theme, ["installed", "boxes", "system"]) | |
| 624 | 629 | .selected(selected) | |
| 625 | 630 | .render(Rect::new(0, 0, width, 1), &mut buf); | |
| 626 | - | buf.content().iter().map(|cell| cell.symbol()).collect() | |
| 631 | + | buf.content() | |
| 632 | + | .iter() | |
| 633 | + | .map(ratatui::buffer::Cell::symbol) | |
| 634 | + | .collect() | |
| 627 | 635 | } | |
| 628 | 636 | ||
| 629 | 637 | #[test] | |
| @@ -730,7 +738,7 @@ mod tests { | |||
| 730 | 738 | let rendered = buf | |
| 731 | 739 | .content() | |
| 732 | 740 | .iter() | |
| 733 | - | .map(|cell| cell.symbol()) | |
| 741 | + | .map(ratatui::buffer::Cell::symbol) | |
| 734 | 742 | .collect::<String>(); | |
| 735 | 743 | assert!( | |
| 736 | 744 | rendered.contains("nmcli run 9"), |