1use super::*;
4
5impl RoleParam {
7 pub fn validate(&self) -> RoleValidationResult<()> {
9 match self {
10 RoleParam::Static(count) => {
11 if *count > MAX_ROLE_COUNT {
12 return Err(RoleValidationError::CountOverflow {
13 count: *count,
14 max: MAX_ROLE_COUNT,
15 });
16 }
17 Ok(())
18 }
19 RoleParam::Symbolic(_) => Ok(()),
20 RoleParam::Runtime => Ok(()),
21 }
22 }
23
24 pub fn validate_with_index(&self, index: &RoleIndex) -> RoleValidationResult<()> {
26 match (self, index) {
27 (RoleParam::Static(count), RoleIndex::Concrete(idx)) => {
28 if *idx >= *count {
29 return Err(RoleValidationError::IndexOverflow {
30 index: *idx,
31 max: *count - 1,
32 });
33 }
34 Ok(())
35 }
36 (RoleParam::Static(count), RoleIndex::Range(range)) => {
37 if let (RangeExpr::Concrete(_), RangeExpr::Concrete(end)) =
38 (&range.start, &range.end)
39 {
40 if *end > *count {
41 return Err(RoleValidationError::IndexOverflow {
42 index: *end,
43 max: *count,
44 });
45 }
46 }
47 Ok(())
48 }
49 _ => Ok(()),
50 }
51 }
52
53 pub fn safe_static(count: u32) -> RoleValidationResult<Self> {
55 if count > MAX_ROLE_COUNT {
56 return Err(RoleValidationError::CountOverflow {
57 count,
58 max: MAX_ROLE_COUNT,
59 });
60 }
61 Ok(RoleParam::Static(count))
62 }
63}
64
65impl RoleIndex {
66 pub fn validate(&self) -> RoleValidationResult<()> {
68 match self {
69 RoleIndex::Concrete(index) => {
70 if *index > MAX_ROLE_INDEX {
71 return Err(RoleValidationError::IndexOverflow {
72 index: *index,
73 max: MAX_ROLE_INDEX,
74 });
75 }
76 Ok(())
77 }
78 RoleIndex::Symbolic(_) | RoleIndex::Wildcard => Ok(()),
79 RoleIndex::Range(range) => range.validate(),
80 }
81 }
82
83 pub fn safe_concrete(index: u32) -> RoleValidationResult<Self> {
85 if index > MAX_ROLE_INDEX {
86 return Err(RoleValidationError::IndexOverflow {
87 index,
88 max: MAX_ROLE_INDEX,
89 });
90 }
91 Ok(RoleIndex::Concrete(index))
92 }
93}
94
95impl RoleRange {
96 pub fn validate(&self) -> RoleValidationResult<()> {
98 self.start.validate()?;
99 self.end.validate()?;
100
101 if let (RangeExpr::Concrete(start), RangeExpr::Concrete(end)) = (&self.start, &self.end) {
102 if start >= end {
103 return Err(RoleValidationError::InvalidRange {
104 start: *start,
105 end: *end,
106 });
107 }
108
109 let range_size = end - start;
110 if range_size > MAX_RANGE_COUNT {
111 return Err(RoleValidationError::RangeSizeOverflow {
112 size: range_size,
113 max: MAX_RANGE_COUNT,
114 });
115 }
116 }
117
118 Ok(())
119 }
120
121 pub fn safe_concrete(start: u32, end: u32) -> RoleValidationResult<Self> {
123 let range = RoleRange {
124 start: RangeExpr::Concrete(start),
125 end: RangeExpr::Concrete(end),
126 };
127 range.validate()?;
128 Ok(range)
129 }
130}
131
132impl RangeExpr {
133 pub fn validate(&self) -> RoleValidationResult<()> {
135 match self {
136 RangeExpr::Concrete(value) => {
137 if *value > MAX_ROLE_INDEX {
138 return Err(RoleValidationError::IndexOverflow {
139 index: *value,
140 max: MAX_ROLE_INDEX,
141 });
142 }
143 Ok(())
144 }
145 RangeExpr::Symbolic(_) => Ok(()),
146 }
147 }
148}
149
150pub struct RoleBoundsChecker {
152 max_count: u32,
153 max_index: u32,
154}
155
156impl Default for RoleBoundsChecker {
157 fn default() -> Self {
158 Self {
159 max_count: MAX_ROLE_COUNT,
160 max_index: MAX_ROLE_INDEX,
161 }
162 }
163}
164
165impl RoleBoundsChecker {
166 pub fn new(max_count: u32, max_index: u32) -> Self {
168 Self {
169 max_count,
170 max_index,
171 }
172 }
173
174 pub fn check_count(&self, count: u32) -> RoleValidationResult<()> {
176 if count > self.max_count {
177 return Err(RoleValidationError::CountOverflow {
178 count,
179 max: self.max_count,
180 });
181 }
182 Ok(())
183 }
184
185 pub fn check_index(&self, index: u32) -> RoleValidationResult<()> {
187 if index > self.max_index {
188 return Err(RoleValidationError::IndexOverflow {
189 index,
190 max: self.max_index,
191 });
192 }
193 Ok(())
194 }
195
196 pub fn check_range(&self, start: u32, end: u32) -> RoleValidationResult<()> {
198 if start >= end {
199 return Err(RoleValidationError::InvalidRange { start, end });
200 }
201
202 if end > self.max_index {
203 return Err(RoleValidationError::IndexOverflow {
204 index: end,
205 max: self.max_index,
206 });
207 }
208
209 let range_size = end - start;
210 if range_size > MAX_RANGE_COUNT {
211 return Err(RoleValidationError::RangeSizeOverflow {
212 size: range_size,
213 max: MAX_RANGE_COUNT,
214 });
215 }
216
217 Ok(())
218 }
219}
220
221impl std::fmt::Display for RoleIndex {
222 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223 match self {
224 RoleIndex::Concrete(index) => write!(f, "{}", index),
225 RoleIndex::Symbolic(name) => write!(f, "{}", name),
226 RoleIndex::Wildcard => write!(f, "*"),
227 RoleIndex::Range(range) => write!(f, "{}", range),
228 }
229 }
230}
231
232impl std::fmt::Display for RoleRange {
233 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
234 write!(f, "{}..{}", self.start, self.end)
235 }
236}
237
238impl std::fmt::Display for RangeExpr {
239 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240 match self {
241 RangeExpr::Concrete(value) => write!(f, "{}", value),
242 RangeExpr::Symbolic(name) => write!(f, "{}", name),
243 }
244 }
245}
246
247impl std::fmt::Display for RoleParam {
248 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249 match self {
250 RoleParam::Static(count) => write!(f, "{}", count),
251 RoleParam::Symbolic(name) => write!(f, "{}", name),
252 RoleParam::Runtime => write!(f, "*"),
253 }
254 }
255}