mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-30 09:04:57 +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 mod sortable;
|
||||||
pub use sortable::*;
|
pub use sortable::*;
|
||||||
|
|
||||||
|
use crate::utils::gen_util::ClampExt;
|
||||||
|
|
||||||
/// A [`DataTable`] is a component that displays data in a tabular form.
|
/// 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
|
/// 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.
|
/// Updates the scroll position to a selected index.
|
||||||
#[allow(clippy::comparison_chain)]
|
#[allow(clippy::comparison_chain)]
|
||||||
pub fn set_position(&mut self, new_index: usize) {
|
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 {
|
if self.state.current_index < new_index {
|
||||||
self.state.scroll_direction = ScrollDirection::Down;
|
self.state.scroll_direction = ScrollDirection::Down;
|
||||||
} else if self.state.current_index > new_index {
|
} 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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -209,7 +246,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_truncate() {
|
fn test_truncate_str() {
|
||||||
let cpu_header = "CPU(c)▲";
|
let cpu_header = "CPU(c)▲";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -232,7 +269,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_truncate_cjk() {
|
fn truncate_cjk() {
|
||||||
let cjk = "施氏食獅史";
|
let cjk = "施氏食獅史";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -255,7 +292,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_truncate_mixed() {
|
fn truncate_mixed() {
|
||||||
let test = "Test (施氏食獅史) Test";
|
let test = "Test (施氏食獅史) Test";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -288,7 +325,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_truncate_flags() {
|
fn truncate_flags() {
|
||||||
let flag = "🇨🇦";
|
let flag = "🇨🇦";
|
||||||
assert_eq!(truncate_str(flag, 3_usize), flag);
|
assert_eq!(truncate_str(flag, 3_usize), flag);
|
||||||
assert_eq!(truncate_str(flag, 2_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...
|
/// This might not be the best way to handle it, but this at least tests that it doesn't crash...
|
||||||
#[test]
|
#[test]
|
||||||
fn test_truncate_hindi() {
|
fn truncate_hindi() {
|
||||||
// cSpell:disable
|
// cSpell:disable
|
||||||
let test = "हिन्दी";
|
let test = "हिन्दी";
|
||||||
assert_eq!(truncate_str(test, 10_usize), test);
|
assert_eq!(truncate_str(test, 10_usize), test);
|
||||||
@ -346,7 +383,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_truncate_emoji() {
|
fn truncate_emoji() {
|
||||||
let heart = "❤️";
|
let heart = "❤️";
|
||||||
assert_eq!(truncate_str(heart, 2_usize), heart);
|
assert_eq!(truncate_str(heart, 2_usize), heart);
|
||||||
assert_eq!(truncate_str(heart, 1_usize), heart);
|
assert_eq!(truncate_str(heart, 1_usize), heart);
|
||||||
@ -396,4 +433,28 @@ mod test {
|
|||||||
"multi non-matching should fail"
|
"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