From 79ec6878877f0fd9246d67d3cd4f8cc2d1200150 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Fri, 17 Jul 2026 11:08:07 +0800 Subject: refactor: rename `mingling_picker` to `arg_picker` --- arg_picker/src/builtin/pick_numbers.rs | 80 ++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 arg_picker/src/builtin/pick_numbers.rs (limited to 'arg_picker/src/builtin/pick_numbers.rs') diff --git a/arg_picker/src/builtin/pick_numbers.rs b/arg_picker/src/builtin/pick_numbers.rs new file mode 100644 index 0000000..a5ab0a9 --- /dev/null +++ b/arg_picker/src/builtin/pick_numbers.rs @@ -0,0 +1,80 @@ +use crate::{BoundaryCheck, SinglePickable, pickable_needed::*}; + +macro_rules! impl_single_pickable_num { + ($($t:ty),+ $(,)?) => { + $(impl SinglePickable for $t { + fn pick_single(str: Option<&str>) -> PickerArgResult { + match str { + Some(s) => s.parse::<$t>().map(PickerArgResult::Parsed).unwrap_or(PickerArgResult::NotFound), + None => PickerArgResult::NotFound, + } + } + })+ + }; +} + +/// Returns `true` if `raw` looks like an integer (digits, optional `+`/`-` prefix, +/// no decimal point or exponent). +fn is_int_like(raw: &str) -> bool { + let s = raw.trim(); + let bytes = s.as_bytes(); + if bytes.is_empty() { + return false; + } + let mut i = 0; + if bytes[0] == b'-' || bytes[0] == b'+' { + i = 1; + } + if i >= bytes.len() { + return false; + } + for &b in &bytes[i..] { + if !b.is_ascii_digit() { + return false; + } + } + true +} + +/// Returns `true` if `raw` looks like a float (contains `.`, `e`, or `E`). +fn is_float_like(raw: &str) -> bool { + let s = raw.trim(); + s.contains('.') || s.contains('e') || s.contains('E') +} + +impl_single_pickable_num! { + i8, i16, i32, i64, i128, isize, + u8, u16, u32, u64, u128, usize, + f32, f64, +} + +// Integer boundary: only accept strings that look like integers. +// Float-like strings trigger a boundary. +macro_rules! impl_boundary_check_int { + ($($t:ty),+ $(,)?) => { + $(impl BoundaryCheck for $t { + fn check_boundary(raw: &str) -> bool { + !is_int_like(raw) + } + })+ + }; +} + +impl_boundary_check_int! { + i8, i16, i32, i64, i128, isize, + u8, u16, u32, u64, u128, usize, +} + +// Float boundary: only accept strings that look like floats. +// Integer-like strings trigger a boundary. +impl BoundaryCheck for f32 { + fn check_boundary(raw: &str) -> bool { + !is_float_like(raw) || raw.parse::().is_err() + } +} + +impl BoundaryCheck for f64 { + fn check_boundary(raw: &str) -> bool { + !is_float_like(raw) || raw.parse::().is_err() + } +} -- cgit