mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-04-08 17:05:59 +02:00
other: add additional clamping functions on numeric types (#1324)
* other: add additional clamping functions on numeric types * add tests and replace one usage
This commit is contained in:
parent
7c14aa2666
commit
5a17212f89
@ -21,6 +21,8 @@ pub use data_type::*;
|
||||
pub mod sortable;
|
||||
pub use sortable::*;
|
||||
|
||||
use crate::utils::gen_util::ClampExt;
|
||||
|
||||
/// A [`DataTable`] is a component that displays data in a tabular form.
|
||||
///
|
||||
/// Note that [`DataTable`] takes a generic type `S`, bounded by [`SortType`]. This controls whether this table
|
||||
@ -120,7 +122,7 @@ impl<DataType: DataToCell<H>, H: ColumnHeader, S: SortType, C: DataTableColumn<H
|
||||
/// Updates the scroll position to a selected index.
|
||||
#[allow(clippy::comparison_chain)]
|
||||
pub fn set_position(&mut self, new_index: usize) {
|
||||
let new_index = new_index.clamp(0, self.data.len().saturating_sub(1));
|
||||
let new_index = new_index.clamp_upper(self.data.len().saturating_sub(1));
|
||||
if self.state.current_index < new_index {
|
||||
self.state.scroll_direction = ScrollDirection::Down;
|
||||
} else if self.state.current_index > new_index {
|
||||
|
@ -186,6 +186,43 @@ macro_rules! multi_eq_ignore_ascii_case {
|
||||
};
|
||||
}
|
||||
|
||||
/// A trait for additional clamping functions on numeric types.
|
||||
pub trait ClampExt {
|
||||
/// Restrict a value by a lower bound. If the current value is _lower_ than `lower_bound`,
|
||||
/// it will be set to `_lower_bound`.
|
||||
fn clamp_lower(&self, lower_bound: Self) -> Self;
|
||||
|
||||
/// Restrict a value by an upper bound. If the current value is _greater_ than `upper_bound`,
|
||||
/// it will be set to `upper_bound`.
|
||||
fn clamp_upper(&self, upper_bound: Self) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! clamp_num_impl {
|
||||
( $($NumType:ty),+ $(,)? ) => {
|
||||
$(
|
||||
impl ClampExt for $NumType {
|
||||
fn clamp_lower(&self, lower_bound: Self) -> Self {
|
||||
if *self < lower_bound {
|
||||
lower_bound
|
||||
} else {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
fn clamp_upper(&self, upper_bound: Self) -> Self {
|
||||
if *self > upper_bound {
|
||||
upper_bound
|
||||
} else {
|
||||
*self
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
clamp_num_impl!(u8, u16, u32, u64, usize);
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
@ -209,7 +246,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate() {
|
||||
fn test_truncate_str() {
|
||||
let cpu_header = "CPU(c)▲";
|
||||
|
||||
assert_eq!(
|
||||
@ -232,7 +269,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_cjk() {
|
||||
fn truncate_cjk() {
|
||||
let cjk = "施氏食獅史";
|
||||
|
||||
assert_eq!(
|
||||
@ -255,7 +292,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_mixed() {
|
||||
fn truncate_mixed() {
|
||||
let test = "Test (施氏食獅史) Test";
|
||||
|
||||
assert_eq!(
|
||||
@ -288,7 +325,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_flags() {
|
||||
fn truncate_flags() {
|
||||
let flag = "🇨🇦";
|
||||
assert_eq!(truncate_str(flag, 3_usize), flag);
|
||||
assert_eq!(truncate_str(flag, 2_usize), flag);
|
||||
@ -331,7 +368,7 @@ mod test {
|
||||
|
||||
/// This might not be the best way to handle it, but this at least tests that it doesn't crash...
|
||||
#[test]
|
||||
fn test_truncate_hindi() {
|
||||
fn truncate_hindi() {
|
||||
// cSpell:disable
|
||||
let test = "हिन्दी";
|
||||
assert_eq!(truncate_str(test, 10_usize), test);
|
||||
@ -346,7 +383,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_emoji() {
|
||||
fn truncate_emoji() {
|
||||
let heart = "❤️";
|
||||
assert_eq!(truncate_str(heart, 2_usize), heart);
|
||||
assert_eq!(truncate_str(heart, 1_usize), heart);
|
||||
@ -396,4 +433,28 @@ mod test {
|
||||
"multi non-matching should fail"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_upper() {
|
||||
let val: usize = 100;
|
||||
assert_eq!(val.clamp_upper(150), 100);
|
||||
|
||||
let val: usize = 100;
|
||||
assert_eq!(val.clamp_upper(100), 100);
|
||||
|
||||
let val: usize = 100;
|
||||
assert_eq!(val.clamp_upper(50), 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_lower() {
|
||||
let val: usize = 100;
|
||||
assert_eq!(val.clamp_lower(150), 150);
|
||||
|
||||
let val: usize = 100;
|
||||
assert_eq!(val.clamp_lower(100), 100);
|
||||
|
||||
let val: usize = 100;
|
||||
assert_eq!(val.clamp_lower(50), 100);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user