Skip to content

Commit e5a28da

Browse files
committed
refactor: 提取正整数转换函数并优化参数验证逻辑
1 parent c0db93f commit e5a28da

File tree

1 file changed

+38
-16
lines changed

1 file changed

+38
-16
lines changed

src/utils/validation.rs

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,60 @@
11
use pyo3::prelude::*;
22
use std::time::Duration;
33

4-
/// 验证 `interval_ms` 参数并转换为 u64
4+
/// 将正整数 i64 转换为 u64,用于 DNS 解析超时等参数
55
///
6-
/// 由于 ping 命令的 -i 参数格式化为一位小数,所以 `interval_ms` 必须是 100ms 的倍数且不小于 100ms
7-
pub fn validate_interval_ms(value: i64, param_name: &str) -> PyResult<u64> {
8-
if value < 0 {
6+
/// 如果值为负数或零,返回错误
7+
pub fn i64_to_u64_positive(value: i64, param_name: &str) -> PyResult<u64> {
8+
if value <= 0 {
99
return Err(PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
10-
"{param_name} must be a non-negative integer"
10+
"{param_name} must be a positive integer, got {value}"
1111
)));
1212
}
13-
if value < 100 {
13+
// 已验证 value > 0,使用 try_from 进行类型转换
14+
u64::try_from(value).map_err(|e| {
15+
PyErr::new::<pyo3::exceptions::PyValueError, _>(format!("{param_name} ({value}) conversion to u64 failed: {e}"))
16+
})
17+
}
18+
19+
/// 将正整数 i32 转换为 usize,用于 count 等参数
20+
///
21+
/// 如果值为负数或零,返回错误
22+
pub fn i32_to_usize_positive(value: i32, param_name: &str) -> PyResult<usize> {
23+
if value <= 0 {
24+
return Err(PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
25+
"{param_name} ({value}) must be a positive integer"
26+
)));
27+
}
28+
// 已验证 value > 0,使用 try_from 进行类型转换
29+
usize::try_from(value).map_err(|e| {
30+
PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
31+
"{param_name} ({value}) conversion to usize failed: {e}"
32+
))
33+
})
34+
}
35+
36+
/// 验证 `interval_ms` 参数并转换为 u64
37+
///
38+
/// 由于 ping 命令的 -i 参数格式化为一位小数,所以 `interval_ms` 必须是 100ms 的倍数且不小于 100ms
39+
pub fn validate_interval_ms(value: i64, param_name: &str) -> PyResult<u64> {
40+
let value_u64 = i64_to_u64_positive(value, param_name)?;
41+
42+
if value_u64 < 100 {
1443
return Err(PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
1544
"{param_name} must be at least 100ms"
1645
)));
1746
}
18-
if value % 100 != 0 {
47+
if value_u64 % 100 != 0 {
1948
return Err(PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
2049
"{param_name} must be a multiple of 100ms due to ping command's decimal precision"
2150
)));
2251
}
23-
#[allow(clippy::cast_sign_loss)]
24-
Ok(value as u64)
52+
Ok(value_u64)
2553
}
2654

2755
/// 验证 count 参数并转换为 usize
2856
pub fn validate_count(count: i32, param_name: &str) -> PyResult<usize> {
29-
if count <= 0 {
30-
return Err(PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
31-
"{param_name} ({count}) must be a positive integer"
32-
)));
33-
}
34-
#[allow(clippy::cast_sign_loss)]
35-
Ok(count as usize)
57+
i32_to_usize_positive(count, param_name)
3658
}
3759

3860
/// 验证 `timeout_ms` 参数并转换为 Duration

0 commit comments

Comments
 (0)