futu_core/
qot_page_bounds.rs1use std::fmt;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub struct PageBounds {
19 pub begin: i32,
20 pub num: i32,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq)]
25pub struct PageBoundsError {
26 pub endpoint: String,
28 pub reason: PageBoundsErrorReason,
29}
30
31#[derive(Debug, Clone, PartialEq, Eq)]
32pub enum PageBoundsErrorReason {
33 BeginNegative {
34 begin: i32,
35 },
36 NumOutOfRange {
37 num: i32,
38 min: i32,
39 max: i32,
40 },
41 MaxCountNegative {
43 max_count: i32,
44 },
45 MaxCountTooLarge {
47 max_count: i32,
48 max_allowed: i32,
49 },
50}
51
52impl fmt::Display for PageBoundsError {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 match &self.reason {
55 PageBoundsErrorReason::BeginNegative { begin } => write!(
56 f,
57 "{}: begin={} 非法 (必须 >= 0)。begin 是分页起始 index, 0 表示第一页",
58 self.endpoint, begin
59 ),
60 PageBoundsErrorReason::NumOutOfRange { num, min, max } => write!(
61 f,
62 "{}: num={} 非法 (合法范围 [{}, {}])。num 必须显式在范围内, \
63 daemon 不再静默 clamp。如需更大 batch 请分页发多次。",
64 self.endpoint, num, min, max
65 ),
66 PageBoundsErrorReason::MaxCountNegative { max_count } => write!(
67 f,
68 "{}: max_count={} 负数非法。省略 (None) 或 0 = 不限制; \
69 否则必须正整数。",
70 self.endpoint, max_count
71 ),
72 PageBoundsErrorReason::MaxCountTooLarge {
73 max_count,
74 max_allowed,
75 } => write!(
76 f,
77 "{}: max_count={} 超上限 (合法上限 {})。\
78 更大 range 请分段查询或省略以使用默认值。",
79 self.endpoint, max_count, max_allowed
80 ),
81 }
82 }
83}
84
85impl std::error::Error for PageBoundsError {}
86
87pub fn validate_begin_num(
96 begin: i32,
97 num: i32,
98 max_num: i32,
99 endpoint: &str,
100) -> Result<PageBounds, PageBoundsError> {
101 if begin < 0 {
102 return Err(PageBoundsError {
103 endpoint: endpoint.to_string(),
104 reason: PageBoundsErrorReason::BeginNegative { begin },
105 });
106 }
107 if num < 0 || num > max_num {
108 return Err(PageBoundsError {
109 endpoint: endpoint.to_string(),
110 reason: PageBoundsErrorReason::NumOutOfRange {
111 num,
112 min: 0,
113 max: max_num,
114 },
115 });
116 }
117 Ok(PageBounds { begin, num })
118}
119
120pub fn validate_optional_max_count(
127 max_count: Option<i32>,
128 max_allowed: i32,
129 endpoint: &str,
130) -> Result<Option<i32>, PageBoundsError> {
131 match max_count {
132 None | Some(0) => Ok(None),
133 Some(n) if n < 0 => Err(PageBoundsError {
134 endpoint: endpoint.to_string(),
135 reason: PageBoundsErrorReason::MaxCountNegative { max_count: n },
136 }),
137 Some(n) if n > max_allowed => Err(PageBoundsError {
138 endpoint: endpoint.to_string(),
139 reason: PageBoundsErrorReason::MaxCountTooLarge {
140 max_count: n,
141 max_allowed,
142 },
143 }),
144 Some(n) => Ok(Some(n)),
145 }
146}