re-enable cast_possible_truncation lint

This commit is contained in:
alice pellerin
2026-05-01 01:13:58 -05:00
parent 35a01b9128
commit 80c8c2ed81
7 changed files with 98 additions and 79 deletions
+1 -1
View File
@@ -383,7 +383,7 @@ mod tests {
#[test] #[test]
fn nybble_from_hex_digits_are_correct() { fn nybble_from_hex_digits_are_correct() {
for (index, character) in ('0'..='9').enumerate() { for (index, character) in ('0'..='9').enumerate() {
assert_eq!(nybble_from_hex(character), Some(index as u8)); assert_eq!(nybble_from_hex(character), Some(u8::try_from(index).unwrap()));
} }
} }
} }
+75 -60
View File
@@ -382,51 +382,12 @@ impl Buffer {
} }
fn jump_to_selected_offset(&mut self, window_size: WindowSize) { fn jump_to_selected_offset(&mut self, window_size: WindowSize) {
// check all cursors before modifying any
if !iter::once(&self.primary_cursor) if !iter::once(&self.primary_cursor)
.chain(&self.cursors) .chain(&self.cursors)
.all(|cursor| { .all(|cursor| {
bytes_to_nat(&self.contents[cursor.range()]) bytes_to_nat(&self.contents[cursor.range()])
.map(|nat| nat as usize) .and_then(|nat| usize::try_from(nat).ok())
.is_some_and(|offset| offset < self.contents.len())
})
{
if self.cursors.is_empty() {
self.alert_message = Span::from(
"selection is not a valid offset"
).red();
} else {
self.alert_message = Span::from(
"not all selections are valid offsets"
).red();
}
return;
}
self.primary_cursor = Cursor::at(
bytes_to_nat(&self.contents[self.primary_cursor.range()]).unwrap() as usize
);
for cursor in &mut self.cursors {
*cursor = Cursor::at(
bytes_to_nat(&self.contents[cursor.range()]).unwrap() as usize
);
}
self.cursors.sort_by_key(|cursor| cursor.head);
self.combine_cursors_if_overlapping();
self.clamp_screen_to_primary_cursor(window_size);
}
fn jump_to_selected_offset_relative_to_mark(&mut self, window_size: WindowSize) {
let mut sorted_marks: Vec<_> = self.marks.iter().copied().collect();
sorted_marks.sort_unstable();
if !iter::once(&self.primary_cursor)
.chain(&self.cursors)
.all(|cursor| {
bytes_to_nat(&self.contents[cursor.range()])
.map(|offset| mark_before(cursor.lower_bound(), &sorted_marks) + offset as usize)
.is_some_and(|offset| offset < self.contents.len()) .is_some_and(|offset| offset < self.contents.len())
}) })
{ {
@@ -444,19 +405,63 @@ impl Buffer {
self.primary_cursor = Cursor::at( self.primary_cursor = Cursor::at(
bytes_to_nat(&self.contents[self.primary_cursor.range()]) bytes_to_nat(&self.contents[self.primary_cursor.range()])
.map(|offset| {
mark_before(self.primary_cursor.lower_bound(), &sorted_marks) + offset as usize
})
.unwrap() .unwrap()
.try_into().unwrap()
); );
for cursor in &mut self.cursors { for cursor in &mut self.cursors {
*cursor = Cursor::at( *cursor = Cursor::at(
bytes_to_nat(&self.contents[cursor.range()]) bytes_to_nat(&self.contents[cursor.range()])
.map(|offset| {
mark_before(cursor.lower_bound(), &sorted_marks) + offset as usize
})
.unwrap() .unwrap()
.try_into().unwrap()
);
}
self.cursors.sort_by_key(|cursor| cursor.head);
self.combine_cursors_if_overlapping();
self.clamp_screen_to_primary_cursor(window_size);
}
fn jump_to_selected_offset_relative_to_mark(&mut self, window_size: WindowSize) {
let mut sorted_marks: Vec<_> = self.marks.iter().copied().collect();
sorted_marks.sort_unstable();
// check all cursors before modifying any
if !iter::once(&self.primary_cursor)
.chain(&self.cursors)
.all(|cursor| {
bytes_to_nat(&self.contents[cursor.range()])
.and_then(|offset| usize::try_from(offset).ok())
.map(|offset| mark_before(cursor.lower_bound(), &sorted_marks) + offset)
.is_some_and(|offset| offset < self.contents.len())
})
{
if self.cursors.is_empty() {
self.alert_message = Span::from(
"selection is not a valid offset"
).red();
} else {
self.alert_message = Span::from(
"not all selections are valid offsets"
).red();
}
return;
}
self.primary_cursor = Cursor::at(
mark_before(self.primary_cursor.lower_bound(), &sorted_marks) +
usize::try_from(
bytes_to_nat(&self.contents[self.primary_cursor.range()]).unwrap()
).unwrap()
);
for cursor in &mut self.cursors {
*cursor = Cursor::at(
mark_before(cursor.lower_bound(), &sorted_marks) +
usize::try_from(
bytes_to_nat(&self.contents[cursor.range()]).unwrap()
).unwrap()
); );
} }
@@ -658,6 +663,7 @@ impl Buffer {
} }
} }
#[allow(clippy::too_many_lines)]
fn inspect(selection: &[u8]) -> Vec<Span<'static>> { fn inspect(selection: &[u8]) -> Vec<Span<'static>> {
let nat = bytes_to_nat(selection); let nat = bytes_to_nat(selection);
@@ -680,7 +686,8 @@ fn inspect(selection: &[u8]) -> Vec<Span<'static>> {
let fixedpoint2012 = nat let fixedpoint2012 = nat
.filter(|_| selection.len() == 4) .filter(|_| selection.len() == 4)
.map(|nat| f64::from(nat as u32) / f64::from(1 << 12)) .map(|nat| u32::try_from(nat).unwrap())
.map(|nat| f64::from(nat) / f64::from(1 << 12))
.map(|fixedpoint2012| { .map(|fixedpoint2012| {
let two_decimals_is_enough = (fixedpoint2012 * 100.0).fract() == 0.0; let two_decimals_is_enough = (fixedpoint2012 * 100.0).fract() == 0.0;
let approximate_symbol = if two_decimals_is_enough { "" } else { "~" }; let approximate_symbol = if two_decimals_is_enough { "" } else { "~" };
@@ -690,7 +697,8 @@ fn inspect(selection: &[u8]) -> Vec<Span<'static>> {
let fixedpoint2012_signed = int let fixedpoint2012_signed = int
.filter(|_| selection.len() == 4) .filter(|_| selection.len() == 4)
.map(|int| f64::from(int as i32) / f64::from(1 << 12)) .map(|int| i32::try_from(int).unwrap())
.map(|int| f64::from(int) / f64::from(1 << 12))
.map(|fixedpoint2012_signed| { .map(|fixedpoint2012_signed| {
let two_decimals_is_enough = (fixedpoint2012_signed * 100.0).fract() == 0.0; let two_decimals_is_enough = (fixedpoint2012_signed * 100.0).fract() == 0.0;
let approximate_symbol = if two_decimals_is_enough { "" } else { "~" }; let approximate_symbol = if two_decimals_is_enough { "" } else { "~" };
@@ -700,7 +708,8 @@ fn inspect(selection: &[u8]) -> Vec<Span<'static>> {
let fixedpoint1616 = nat let fixedpoint1616 = nat
.filter(|_| selection.len() == 4) .filter(|_| selection.len() == 4)
.map(|nat| f64::from(nat as u32) / f64::from(1 << 16)) .map(|nat| u32::try_from(nat).unwrap())
.map(|nat| f64::from(nat) / f64::from(1 << 16))
.map(|fixedpoint1616| { .map(|fixedpoint1616| {
let two_decimals_is_enough = (fixedpoint1616 * 100.0).fract() == 0.0; let two_decimals_is_enough = (fixedpoint1616 * 100.0).fract() == 0.0;
let approximate_symbol = if two_decimals_is_enough { "" } else { "~" }; let approximate_symbol = if two_decimals_is_enough { "" } else { "~" };
@@ -710,7 +719,8 @@ fn inspect(selection: &[u8]) -> Vec<Span<'static>> {
let fixedpoint1616_signed = int let fixedpoint1616_signed = int
.filter(|_| selection.len() == 4) .filter(|_| selection.len() == 4)
.map(|int| f64::from(int as i32) / f64::from(1 << 16)) .map(|int| i32::try_from(int).unwrap())
.map(|int| f64::from(int) / f64::from(1 << 16))
.map(|fixedpoint1616_signed| { .map(|fixedpoint1616_signed| {
let two_decimals_is_enough = (fixedpoint1616_signed * 100.0).fract() == 0.0; let two_decimals_is_enough = (fixedpoint1616_signed * 100.0).fract() == 0.0;
let approximate_symbol = if two_decimals_is_enough { "" } else { "~" }; let approximate_symbol = if two_decimals_is_enough { "" } else { "~" };
@@ -720,7 +730,8 @@ fn inspect(selection: &[u8]) -> Vec<Span<'static>> {
let fixedpoint124 = nat let fixedpoint124 = nat
.filter(|_| selection.len() == 2) .filter(|_| selection.len() == 2)
.map(|nat| f64::from(nat as u16) / f64::from(1 << 4)) .map(|nat| u16::try_from(nat).unwrap())
.map(|nat| f64::from(nat) / f64::from(1 << 4))
.map(|fixedpoint124| { .map(|fixedpoint124| {
let two_decimals_is_enough = (fixedpoint124 * 100.0).fract() == 0.0; let two_decimals_is_enough = (fixedpoint124 * 100.0).fract() == 0.0;
let approximate_symbol = if two_decimals_is_enough { "" } else { "~" }; let approximate_symbol = if two_decimals_is_enough { "" } else { "~" };
@@ -730,7 +741,8 @@ fn inspect(selection: &[u8]) -> Vec<Span<'static>> {
let fixedpoint88 = nat let fixedpoint88 = nat
.filter(|_| selection.len() == 2) .filter(|_| selection.len() == 2)
.map(|nat| f64::from(nat as u16) / f64::from(1 << 8)) .map(|nat| u16::try_from(nat).unwrap())
.map(|nat| f64::from(nat) / f64::from(1 << 8))
.map(|fixedpoint88| { .map(|fixedpoint88| {
let two_decimals_is_enough = (fixedpoint88 * 100.0).fract() == 0.0; let two_decimals_is_enough = (fixedpoint88 * 100.0).fract() == 0.0;
let approximate_symbol = if two_decimals_is_enough { "" } else { "~" }; let approximate_symbol = if two_decimals_is_enough { "" } else { "~" };
@@ -740,7 +752,8 @@ fn inspect(selection: &[u8]) -> Vec<Span<'static>> {
let fixedpoint412 = nat let fixedpoint412 = nat
.filter(|_| selection.len() == 2) .filter(|_| selection.len() == 2)
.map(|nat| f64::from(nat as u16) / f64::from(1 << 12)) .map(|nat| u16::try_from(nat).unwrap())
.map(|nat| f64::from(nat) / f64::from(1 << 12))
.map(|fixedpoint412| { .map(|fixedpoint412| {
let two_decimals_is_enough = (fixedpoint412 * 100.0).fract() == 0.0; let two_decimals_is_enough = (fixedpoint412 * 100.0).fract() == 0.0;
let approximate_symbol = if two_decimals_is_enough { "" } else { "~" }; let approximate_symbol = if two_decimals_is_enough { "" } else { "~" };
@@ -759,7 +772,8 @@ fn inspect(selection: &[u8]) -> Vec<Span<'static>> {
let color555 = nat let color555 = nat
.filter(|_| selection.len() == 2) .filter(|_| selection.len() == 2)
.filter(|&nat| nat >> 15 == 0) .filter(|&nat| nat >> 15 == 0)
.map(|nat| color555_to_color888(nat as u16)) .map(|nat| u16::try_from(nat).unwrap())
.map(color555_to_color888)
.map(|[red, green, blue]| { .map(|[red, green, blue]| {
Span::from(format!("555: #{red:02X}{green:02X}{blue:02X}")) Span::from(format!("555: #{red:02X}{green:02X}{blue:02X}"))
.fg(Color::Rgb(red, green, blue)) .fg(Color::Rgb(red, green, blue))
@@ -797,7 +811,8 @@ fn inspect_color(selection: &[u8]) -> Vec<Span<'static>> {
let color555 = nat let color555 = nat
.filter(|_| selection.len() == 2) .filter(|_| selection.len() == 2)
.filter(|&nat| nat >> 15 == 0) .filter(|&nat| nat >> 15 == 0)
.map(|nat| color555_to_color888(nat as u16)) .map(|nat| u16::try_from(nat).unwrap())
.map(color555_to_color888)
.map(|[red, green, blue]| { .map(|[red, green, blue]| {
Span::from(format!("#{red:02X}{green:02X}{blue:02X}")) Span::from(format!("#{red:02X}{green:02X}{blue:02X}"))
.fg(Color::Rgb(red, green, blue)) .fg(Color::Rgb(red, green, blue))
@@ -874,11 +889,11 @@ pub fn bytes_to_nat(bytes: &[u8]) -> Option<u64> {
}) })
} }
const fn nat_to_int_if_different(nat: u64, bytes: usize) -> Option<i64> { fn nat_to_int_if_different(nat: u64, bytes: usize) -> Option<i64> {
match bytes { match bytes {
1 if nat > i8::MAX as u64 => Some((nat as u8).cast_signed() as i64), 1 if nat > i8::MAX as u64 => Some(i64::from(u8::try_from(nat).unwrap().cast_signed())),
2 if nat > i16::MAX as u64 => Some((nat as u16).cast_signed() as i64), 2 if nat > i16::MAX as u64 => Some(i64::from(u16::try_from(nat).unwrap().cast_signed())),
4 if nat > i32::MAX as u64 => Some((nat as u32).cast_signed() as i64), 4 if nat > i32::MAX as u64 => Some(i64::from(u32::try_from(nat).unwrap().cast_signed())),
8 if nat > i64::MAX as u64 => Some(nat.cast_signed()), 8 if nat > i64::MAX as u64 => Some(nat.cast_signed()),
_ => None, _ => None,
} }
+3 -3
View File
@@ -61,8 +61,8 @@ impl Widget for &Buffer {
let popup_area = popup let popup_area = popup
.area_at( .area_at(
area.x + byte_column_to_screen_column(hex_column) as u16, area.x + byte_column_to_screen_column(hex_column),
area.y + (position_on_screen / BYTES_PER_LINE) as u16 + 1 area.y + u16::try_from(position_on_screen / BYTES_PER_LINE).unwrap() + 1
) )
.clamp(hex_area); .clamp(hex_area);
@@ -108,7 +108,7 @@ impl Buffer {
} }
} }
fn byte_column_to_screen_column(byte_column: usize) -> usize { fn byte_column_to_screen_column(byte_column: usize) -> u16 {
match byte_column { match byte_column {
0 => 10, 0 => 10,
1 => 13, 1 => 13,
+6 -2
View File
@@ -39,11 +39,15 @@ const fn create_character_lookup_table() -> [Span<'static>; u8::CARDINALITY] {
let mut index = 0; let mut index = 0;
while index < u8::CARDINALITY { while index < u8::CARDINALITY {
result[index].style = style_for_character(index as u8); #[allow(clippy::cast_possible_truncation)]
let byte = index as u8;
result[index].style = style_for_character(byte);
mem::forget(mem::replace( mem::forget(mem::replace(
&mut result[index].content, &mut result[index].content,
content_for_character(index as u8) content_for_character(byte)
)); ));
index += 1; index += 1;
} }
+5 -2
View File
@@ -192,8 +192,11 @@ const fn create_byte_lookup_table() -> [Span<'static>; u8::CARDINALITY] {
let mut index = 0; let mut index = 0;
while index < u8::CARDINALITY { while index < u8::CARDINALITY {
result[index].style = style_for_byte(index as u8); #[allow(clippy::cast_possible_truncation)]
mem::forget(mem::replace(&mut result[index].content, content_for_byte(index as u8))); let byte = index as u8;
result[index].style = style_for_byte(byte);
mem::forget(mem::replace(&mut result[index].content, content_for_byte(byte)));
index += 1; index += 1;
} }
+1 -6
View File
@@ -1,12 +1,10 @@
#![warn(clippy::pedantic, clippy::nursery)] #![warn(clippy::pedantic, clippy::nursery)]
#![allow(clippy::cast_possible_truncation)]
#![allow(clippy::enum_glob_use)] #![allow(clippy::enum_glob_use)]
use arguments::Arguments; use arguments::Arguments;
use clap::Parser; use clap::Parser;
use app::App; use app::App;
use crossterm::{QueueableCommand, event::{DisableMouseCapture, EnableMouseCapture}}; use crossterm::{QueueableCommand, event::{DisableMouseCapture, EnableMouseCapture}};
use crate::config::Config; use crate::config::Config;
mod app; mod app;
@@ -50,10 +48,7 @@ const BYTES_OF_PADDING: usize = LINES_OF_PADDING * BYTES_PER_LINE;
// - replace-and-keep-going // - replace-and-keep-going
// - mode // - mode
// - change // - change
// - edit character panel // - A-r replaces with ASCII
// - modifier on existing keys like teehee? or jump to panel?
// - A-r replaces with ASCII ?
// - if jump to panel, space?
// - jumplist // - jumplist
// - p // - p
// - [/] to cycle view offset? // - [/] to cycle view offset?
+6 -4
View File
@@ -14,7 +14,7 @@ impl Popup {
at, at,
width: lines width: lines
.iter() .iter()
.map(|line| line.width() as u16) .map(|line| u16::try_from(line.width()).unwrap())
.max() .max()
.unwrap_or(0), .unwrap_or(0),
primary: false, primary: false,
@@ -22,12 +22,12 @@ impl Popup {
} }
} }
pub const fn area_at(&self, x: u16, y: u16) -> Rect { pub fn area_at(&self, x: u16, y: u16) -> Rect {
Rect { Rect {
x, x,
y, y,
width: self.width + 2, width: self.width + 2,
height: self.lines.len() as u16 height: u16::try_from(self.lines.len()).unwrap()
} }
} }
@@ -56,7 +56,9 @@ impl Widget for Popup {
for (line, area) in self.lines.iter().zip(area.rows()) { for (line, area) in self.lines.iter().zip(area.rows()) {
line.render( line.render(
area.centered_horizontally(Constraint::Length(line.width() as u16)), area.centered_horizontally(
Constraint::Length(u16::try_from(line.width()).unwrap())
),
buf buf
); );
} }