1use super::descriptor::AllocationSlotDescriptor;
2use super::memory_manager::{
3 MEMORY_MANAGER_INVALID_ID, MEMORY_MANAGER_MAX_ID, MEMORY_MANAGER_MIN_ID,
4 MemoryManagerSlotError, validate_memory_manager_id,
5};
6use serde::{Deserialize, Serialize};
7
8const DIAGNOSTIC_STRING_MAX_BYTES: usize = 256;
9
10#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
15#[serde(deny_unknown_fields)]
16pub struct MemoryManagerIdRange {
17 pub(crate) start: u8,
18 pub(crate) end: u8,
19}
20
21impl MemoryManagerIdRange {
22 pub const fn new(start: u8, end: u8) -> Result<Self, MemoryManagerRangeError> {
24 if start > end {
25 return Err(MemoryManagerRangeError::InvalidRange { start, end });
26 }
27 if start == MEMORY_MANAGER_INVALID_ID {
28 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: start });
29 }
30 if end == MEMORY_MANAGER_INVALID_ID {
31 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: end });
32 }
33 Ok(Self { start, end })
34 }
35
36 #[must_use]
38 pub const fn all_usable() -> Self {
39 Self {
40 start: MEMORY_MANAGER_MIN_ID,
41 end: MEMORY_MANAGER_MAX_ID,
42 }
43 }
44
45 #[must_use]
47 pub const fn contains(&self, id: u8) -> bool {
48 id >= self.start && id <= self.end
49 }
50
51 #[must_use]
53 pub const fn start(&self) -> u8 {
54 self.start
55 }
56
57 #[must_use]
59 pub const fn end(&self) -> u8 {
60 self.end
61 }
62}
63
64#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
69pub enum MemoryManagerRangeError {
70 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
72 InvalidRange {
73 start: u8,
75 end: u8,
77 },
78 #[error("MemoryManager ID {id} is not a usable allocation slot")]
80 InvalidMemoryManagerId {
81 id: u8,
83 },
84}
85
86#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
93pub enum MemoryManagerRangeMode {
94 Reserved,
98 Allowed,
102}
103
104#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
109#[serde(deny_unknown_fields)]
110pub struct MemoryManagerAuthorityRecord {
111 pub range: MemoryManagerIdRange,
113 pub authority: String,
115 pub mode: MemoryManagerRangeMode,
117 pub purpose: Option<String>,
119}
120
121impl MemoryManagerAuthorityRecord {
122 pub fn new(
124 range: MemoryManagerIdRange,
125 authority: impl Into<String>,
126 mode: MemoryManagerRangeMode,
127 purpose: Option<String>,
128 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
129 let record = Self {
130 range,
131 authority: authority.into(),
132 mode,
133 purpose,
134 };
135 validate_authority_record(&record)?;
136 Ok(record)
137 }
138}
139
140#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
155#[serde(deny_unknown_fields)]
156pub struct MemoryManagerRangeAuthority {
157 authorities: Vec<MemoryManagerAuthorityRecord>,
158}
159
160impl MemoryManagerRangeAuthority {
161 #[must_use]
163 pub const fn new() -> Self {
164 Self {
165 authorities: Vec::new(),
166 }
167 }
168
169 pub fn from_records(
174 records: Vec<MemoryManagerAuthorityRecord>,
175 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
176 let mut authority = Self::new();
177 for record in records {
178 authority = authority.insert_record(record)?;
179 }
180 Ok(authority)
181 }
182
183 pub fn reserve(
188 self,
189 range: MemoryManagerIdRange,
190 authority: impl Into<String>,
191 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
192 self.reserve_with_purpose(range, authority, None)
193 }
194
195 pub fn reserve_ids(
200 self,
201 start: u8,
202 end: u8,
203 authority: impl Into<String>,
204 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
205 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
206 }
207
208 pub fn reserve_with_purpose(
213 self,
214 range: MemoryManagerIdRange,
215 authority: impl Into<String>,
216 purpose: Option<String>,
217 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
218 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
219 }
220
221 pub fn reserve_ids_with_purpose(
226 self,
227 start: u8,
228 end: u8,
229 authority: impl Into<String>,
230 purpose: Option<String>,
231 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
232 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
233 }
234
235 pub fn allow(
240 self,
241 range: MemoryManagerIdRange,
242 authority: impl Into<String>,
243 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
244 self.allow_with_purpose(range, authority, None)
245 }
246
247 pub fn allow_ids(
252 self,
253 start: u8,
254 end: u8,
255 authority: impl Into<String>,
256 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
257 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
258 }
259
260 pub fn allow_with_purpose(
265 self,
266 range: MemoryManagerIdRange,
267 authority: impl Into<String>,
268 purpose: Option<String>,
269 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
270 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
271 }
272
273 pub fn allow_ids_with_purpose(
278 self,
279 start: u8,
280 end: u8,
281 authority: impl Into<String>,
282 purpose: Option<String>,
283 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
284 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
285 }
286
287 pub fn validate_slot_authority(
289 &self,
290 slot: &AllocationSlotDescriptor,
291 expected_authority: &str,
292 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
293 let id = slot
294 .memory_manager_id()
295 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
296 self.validate_id_authority(id, expected_authority)
297 }
298
299 pub fn validate_slot_authority_mode(
301 &self,
302 slot: &AllocationSlotDescriptor,
303 expected_authority: &str,
304 expected_mode: MemoryManagerRangeMode,
305 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
306 let id = slot
307 .memory_manager_id()
308 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
309 self.validate_id_authority_mode(id, expected_authority, expected_mode)
310 }
311
312 pub fn validate_id_authority(
314 &self,
315 id: u8,
316 expected_authority: &str,
317 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
318 validate_diagnostic_string("expected_authority", expected_authority)?;
319 let record = self.covering_record(id)?;
320
321 if record.authority != expected_authority {
322 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
323 id,
324 expected_authority: expected_authority.to_string(),
325 actual_authority: record.authority.clone(),
326 });
327 }
328
329 Ok(record)
330 }
331
332 pub fn validate_id_authority_mode(
334 &self,
335 id: u8,
336 expected_authority: &str,
337 expected_mode: MemoryManagerRangeMode,
338 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
339 let record = self.validate_id_authority(id, expected_authority)?;
340 if record.mode != expected_mode {
341 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
342 id,
343 authority: record.authority.clone(),
344 expected_mode,
345 actual_mode: record.mode,
346 });
347 }
348 Ok(record)
349 }
350
351 pub fn authority_for_id(
353 &self,
354 id: u8,
355 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
356 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
357 Ok(self
358 .authorities
359 .iter()
360 .find(|record| record.range.contains(id)))
361 }
362
363 #[must_use]
369 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
370 &self.authorities
371 }
372
373 pub fn validate_complete_coverage(
379 &self,
380 target: MemoryManagerIdRange,
381 ) -> Result<(), MemoryManagerRangeAuthorityError> {
382 if self.authorities.is_empty() {
383 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
384 start: target.start(),
385 end: target.end(),
386 });
387 }
388
389 for record in &self.authorities {
390 if record.range.start() < target.start() || record.range.end() > target.end() {
391 return Err(
392 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
393 start: record.range.start(),
394 end: record.range.end(),
395 target_start: target.start(),
396 target_end: target.end(),
397 },
398 );
399 }
400 }
401
402 let mut next_uncovered = u16::from(target.start());
403 let target_end = u16::from(target.end());
404 for record in &self.authorities {
405 let record_start = u16::from(record.range.start());
406 let record_end = u16::from(record.range.end());
407
408 if record_start > next_uncovered {
409 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
410 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
411 end: record.range.start() - 1,
412 });
413 }
414
415 if record_end >= next_uncovered {
416 next_uncovered = record_end + 1;
417 }
418 }
419
420 if next_uncovered <= target_end {
421 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
422 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
423 end: target.end(),
424 });
425 }
426
427 Ok(())
428 }
429
430 fn insert(
431 self,
432 range: MemoryManagerIdRange,
433 authority: impl Into<String>,
434 mode: MemoryManagerRangeMode,
435 purpose: Option<String>,
436 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
437 let record = MemoryManagerAuthorityRecord {
438 range,
439 authority: authority.into(),
440 mode,
441 purpose,
442 };
443 self.insert_record(record)
444 }
445
446 fn insert_record(
447 mut self,
448 record: MemoryManagerAuthorityRecord,
449 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
450 validate_authority_record(&record)?;
451
452 for existing in &self.authorities {
453 if ranges_overlap(existing.range, record.range) {
454 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
455 existing_start: existing.range.start(),
456 existing_end: existing.range.end(),
457 candidate_start: record.range.start(),
458 candidate_end: record.range.end(),
459 });
460 }
461 }
462
463 self.authorities.push(record);
464 self.authorities.sort_by_key(|record| record.range.start());
465 Ok(self)
466 }
467
468 fn covering_record(
469 &self,
470 id: u8,
471 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
472 let Some(record) = self.authority_for_id(id)? else {
473 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
474 };
475 Ok(record)
476 }
477}
478
479fn validate_authority_record(
480 record: &MemoryManagerAuthorityRecord,
481) -> Result<(), MemoryManagerRangeAuthorityError> {
482 validate_diagnostic_string("authority", &record.authority)?;
483 if let Some(purpose) = &record.purpose {
484 validate_diagnostic_string("purpose", purpose)?;
485 }
486 Ok(())
487}
488
489#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
494pub enum MemoryManagerRangeAuthorityError {
495 #[error(transparent)]
497 Range(#[from] MemoryManagerRangeError),
498 #[error("{0}")]
500 Slot(#[from] MemoryManagerSlotError),
501 #[error(
503 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
504 )]
505 OverlappingRanges {
506 existing_start: u8,
508 existing_end: u8,
510 candidate_start: u8,
512 candidate_end: u8,
514 },
515 #[error("{field} {reason}")]
517 InvalidDiagnosticString {
518 field: &'static str,
520 reason: &'static str,
522 },
523 #[error("MemoryManager ID {id} is not covered by an authority range")]
525 UnclaimedId {
526 id: u8,
528 },
529 #[error(
531 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
532 )]
533 AuthorityMismatch {
534 id: u8,
536 expected_authority: String,
538 actual_authority: String,
540 },
541 #[error(
543 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
544 )]
545 ModeMismatch {
546 id: u8,
548 authority: String,
550 expected_mode: MemoryManagerRangeMode,
552 actual_mode: MemoryManagerRangeMode,
554 },
555 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
557 MissingCoverage {
558 start: u8,
560 end: u8,
562 },
563 #[error(
565 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
566 )]
567 RangeOutsideCoverageTarget {
568 start: u8,
570 end: u8,
572 target_start: u8,
574 target_end: u8,
576 },
577}
578
579const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
580 left.start() <= right.end() && right.start() <= left.end()
581}
582
583fn validate_diagnostic_string(
584 field: &'static str,
585 value: &str,
586) -> Result<(), MemoryManagerRangeAuthorityError> {
587 if value.is_empty() {
588 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
589 field,
590 reason: "must not be empty",
591 });
592 }
593 if value.len() > DIAGNOSTIC_STRING_MAX_BYTES {
594 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
595 field,
596 reason: "must be at most 256 bytes",
597 });
598 }
599 if !value.is_ascii() {
600 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
601 field,
602 reason: "must be ASCII",
603 });
604 }
605 if value.bytes().any(|byte| byte.is_ascii_control()) {
606 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
607 field,
608 reason: "must not contain ASCII control characters",
609 });
610 }
611 Ok(())
612}