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 crate::text::validate_diagnostic_text;
7use serde::{Deserialize, Deserializer, Serialize, de::Error as _};
8
9#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
14#[serde(deny_unknown_fields)]
15pub struct MemoryManagerIdRange {
16 pub(crate) start: u8,
17 pub(crate) end: u8,
18}
19
20impl MemoryManagerIdRange {
21 pub const fn new(start: u8, end: u8) -> Result<Self, MemoryManagerRangeError> {
23 if start > end {
24 return Err(MemoryManagerRangeError::InvalidRange { start, end });
25 }
26 if start == MEMORY_MANAGER_INVALID_ID {
27 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: start });
28 }
29 if end == MEMORY_MANAGER_INVALID_ID {
30 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: end });
31 }
32 Ok(Self { start, end })
33 }
34
35 #[must_use]
37 pub const fn all_usable() -> Self {
38 Self {
39 start: MEMORY_MANAGER_MIN_ID,
40 end: MEMORY_MANAGER_MAX_ID,
41 }
42 }
43
44 #[must_use]
46 pub const fn contains(&self, id: u8) -> bool {
47 id >= self.start && id <= self.end
48 }
49
50 pub const fn validate(&self) -> Result<(), MemoryManagerRangeError> {
52 match Self::new(self.start, self.end) {
53 Ok(_) => Ok(()),
54 Err(err) => Err(err),
55 }
56 }
57
58 #[must_use]
60 pub const fn start(&self) -> u8 {
61 self.start
62 }
63
64 #[must_use]
66 pub const fn end(&self) -> u8 {
67 self.end
68 }
69}
70
71#[non_exhaustive]
76#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
77pub enum MemoryManagerRangeError {
78 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
80 InvalidRange {
81 start: u8,
83 end: u8,
85 },
86 #[error("MemoryManager ID {id} is not a usable allocation slot")]
88 InvalidMemoryManagerId {
89 id: u8,
91 },
92}
93
94#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
106pub enum MemoryManagerRangeMode {
107 Reserved,
111 Allowed,
115}
116
117#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
124#[serde(deny_unknown_fields)]
125pub struct MemoryManagerAuthorityRecord {
126 pub(crate) range: MemoryManagerIdRange,
128 pub(crate) authority: String,
130 pub(crate) mode: MemoryManagerRangeMode,
132 #[serde(deserialize_with = "crate::cbor::deserialize_present_option")]
134 pub(crate) purpose: Option<String>,
135}
136
137impl MemoryManagerAuthorityRecord {
138 pub fn new(
140 range: MemoryManagerIdRange,
141 authority: impl Into<String>,
142 mode: MemoryManagerRangeMode,
143 purpose: Option<String>,
144 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
145 let record = Self {
146 range,
147 authority: authority.into(),
148 mode,
149 purpose,
150 };
151 validate_authority_record(&record)?;
152 Ok(record)
153 }
154
155 #[must_use]
157 pub const fn range(&self) -> MemoryManagerIdRange {
158 self.range
159 }
160
161 #[must_use]
163 pub fn authority(&self) -> &str {
164 &self.authority
165 }
166
167 #[must_use]
169 pub const fn mode(&self) -> MemoryManagerRangeMode {
170 self.mode
171 }
172
173 #[must_use]
175 pub fn purpose(&self) -> Option<&str> {
176 self.purpose.as_deref()
177 }
178
179 pub fn validate(&self) -> Result<(), MemoryManagerRangeAuthorityError> {
181 validate_authority_record(self)
182 }
183}
184
185#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
204pub struct MemoryManagerRangeAuthority {
205 authorities: Vec<MemoryManagerAuthorityRecord>,
206}
207
208#[derive(Deserialize)]
209#[serde(deny_unknown_fields)]
210struct MemoryManagerRangeAuthorityDto {
211 authorities: Vec<MemoryManagerAuthorityRecord>,
212}
213
214impl<'de> Deserialize<'de> for MemoryManagerRangeAuthority {
215 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
216 let dto = MemoryManagerRangeAuthorityDto::deserialize(deserializer)?;
217 Self::from_records(dto.authorities).map_err(D::Error::custom)
218 }
219}
220
221impl MemoryManagerRangeAuthority {
222 #[must_use]
224 pub const fn new() -> Self {
225 Self {
226 authorities: Vec::new(),
227 }
228 }
229
230 pub fn from_records(
235 records: Vec<MemoryManagerAuthorityRecord>,
236 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
237 let mut authority = Self::new();
238 for record in records {
239 authority = authority.insert_record(record)?;
240 }
241 Ok(authority)
242 }
243
244 pub fn reserve(
249 self,
250 range: MemoryManagerIdRange,
251 authority: impl Into<String>,
252 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
253 self.reserve_with_purpose(range, authority, None)
254 }
255
256 pub fn reserve_ids(
261 self,
262 start: u8,
263 end: u8,
264 authority: impl Into<String>,
265 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
266 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
267 }
268
269 pub fn reserve_with_purpose(
274 self,
275 range: MemoryManagerIdRange,
276 authority: impl Into<String>,
277 purpose: Option<String>,
278 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
279 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
280 }
281
282 pub fn reserve_ids_with_purpose(
287 self,
288 start: u8,
289 end: u8,
290 authority: impl Into<String>,
291 purpose: Option<String>,
292 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
293 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
294 }
295
296 pub fn allow(
301 self,
302 range: MemoryManagerIdRange,
303 authority: impl Into<String>,
304 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
305 self.allow_with_purpose(range, authority, None)
306 }
307
308 pub fn allow_ids(
313 self,
314 start: u8,
315 end: u8,
316 authority: impl Into<String>,
317 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
318 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
319 }
320
321 pub fn allow_with_purpose(
326 self,
327 range: MemoryManagerIdRange,
328 authority: impl Into<String>,
329 purpose: Option<String>,
330 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
331 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
332 }
333
334 pub fn allow_ids_with_purpose(
339 self,
340 start: u8,
341 end: u8,
342 authority: impl Into<String>,
343 purpose: Option<String>,
344 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
345 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
346 }
347
348 pub fn validate_slot_authority(
350 &self,
351 slot: &AllocationSlotDescriptor,
352 expected_authority: &str,
353 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
354 let id = slot
355 .memory_manager_id()
356 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
357 self.validate_id_authority(id, expected_authority)
358 }
359
360 pub fn validate_slot_authority_mode(
362 &self,
363 slot: &AllocationSlotDescriptor,
364 expected_authority: &str,
365 expected_mode: MemoryManagerRangeMode,
366 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
367 let id = slot
368 .memory_manager_id()
369 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
370 self.validate_id_authority_mode(id, expected_authority, expected_mode)
371 }
372
373 pub fn validate_id_authority(
375 &self,
376 id: u8,
377 expected_authority: &str,
378 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
379 validate_diagnostic_string("expected_authority", expected_authority)?;
380 let record = self.covering_record(id)?;
381
382 if record.authority != expected_authority {
383 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
384 id,
385 expected_authority: expected_authority.to_string(),
386 actual_authority: record.authority.clone(),
387 });
388 }
389
390 Ok(record)
391 }
392
393 pub fn validate_id_authority_mode(
395 &self,
396 id: u8,
397 expected_authority: &str,
398 expected_mode: MemoryManagerRangeMode,
399 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
400 let record = self.validate_id_authority(id, expected_authority)?;
401 if record.mode != expected_mode {
402 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
403 id,
404 authority: record.authority.clone(),
405 expected_mode,
406 actual_mode: record.mode,
407 });
408 }
409 Ok(record)
410 }
411
412 pub fn authority_for_id(
414 &self,
415 id: u8,
416 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
417 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
418 Ok(self
419 .authorities
420 .iter()
421 .find(|record| record.range.contains(id)))
422 }
423
424 #[must_use]
430 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
431 &self.authorities
432 }
433
434 pub fn validate_complete_coverage(
440 &self,
441 target: MemoryManagerIdRange,
442 ) -> Result<(), MemoryManagerRangeAuthorityError> {
443 if self.authorities.is_empty() {
444 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
445 start: target.start(),
446 end: target.end(),
447 });
448 }
449
450 for record in &self.authorities {
451 if record.range.start() < target.start() || record.range.end() > target.end() {
452 return Err(
453 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
454 start: record.range.start(),
455 end: record.range.end(),
456 target_start: target.start(),
457 target_end: target.end(),
458 },
459 );
460 }
461 }
462
463 let mut next_uncovered = u16::from(target.start());
464 let target_end = u16::from(target.end());
465 for record in &self.authorities {
466 let record_start = u16::from(record.range.start());
467 let record_end = u16::from(record.range.end());
468
469 if record_start > next_uncovered {
470 let start = u8::try_from(next_uncovered).map_err(|_| {
471 MemoryManagerRangeAuthorityError::MissingCoverage {
472 start: target.start(),
473 end: target.end(),
474 }
475 })?;
476 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
477 start,
478 end: record.range.start() - 1,
479 });
480 }
481
482 if record_end >= next_uncovered {
483 next_uncovered = record_end + 1;
484 }
485 }
486
487 if next_uncovered <= target_end {
488 let start = u8::try_from(next_uncovered).map_err(|_| {
489 MemoryManagerRangeAuthorityError::MissingCoverage {
490 start: target.start(),
491 end: target.end(),
492 }
493 })?;
494 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
495 start,
496 end: target.end(),
497 });
498 }
499
500 Ok(())
501 }
502
503 fn insert(
504 self,
505 range: MemoryManagerIdRange,
506 authority: impl Into<String>,
507 mode: MemoryManagerRangeMode,
508 purpose: Option<String>,
509 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
510 let record = MemoryManagerAuthorityRecord {
511 range,
512 authority: authority.into(),
513 mode,
514 purpose,
515 };
516 self.insert_record(record)
517 }
518
519 fn insert_record(
520 mut self,
521 record: MemoryManagerAuthorityRecord,
522 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
523 validate_authority_record(&record)?;
524
525 for existing in &self.authorities {
526 if ranges_overlap(existing.range, record.range) {
527 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
528 existing_start: existing.range.start(),
529 existing_end: existing.range.end(),
530 candidate_start: record.range.start(),
531 candidate_end: record.range.end(),
532 });
533 }
534 }
535
536 self.authorities.push(record);
537 self.authorities.sort_by_key(|record| record.range.start());
538 Ok(self)
539 }
540
541 fn covering_record(
542 &self,
543 id: u8,
544 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
545 let Some(record) = self.authority_for_id(id)? else {
546 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
547 };
548 Ok(record)
549 }
550}
551
552fn validate_authority_record(
553 record: &MemoryManagerAuthorityRecord,
554) -> Result<(), MemoryManagerRangeAuthorityError> {
555 record.range.validate()?;
556 validate_diagnostic_string("authority", &record.authority)?;
557 if let Some(purpose) = &record.purpose {
558 validate_diagnostic_string("purpose", purpose)?;
559 }
560 Ok(())
561}
562
563#[non_exhaustive]
568#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
569pub enum MemoryManagerRangeAuthorityError {
570 #[error(transparent)]
572 Range(#[from] MemoryManagerRangeError),
573 #[error("{0}")]
575 Slot(#[from] MemoryManagerSlotError),
576 #[error(
578 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
579 )]
580 OverlappingRanges {
581 existing_start: u8,
583 existing_end: u8,
585 candidate_start: u8,
587 candidate_end: u8,
589 },
590 #[error("{field} {reason}")]
592 InvalidDiagnosticString {
593 field: &'static str,
595 reason: &'static str,
597 },
598 #[error("MemoryManager ID {id} is not covered by an authority range")]
600 UnclaimedId {
601 id: u8,
603 },
604 #[error(
606 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
607 )]
608 AuthorityMismatch {
609 id: u8,
611 expected_authority: String,
613 actual_authority: String,
615 },
616 #[error(
618 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
619 )]
620 ModeMismatch {
621 id: u8,
623 authority: String,
625 expected_mode: MemoryManagerRangeMode,
627 actual_mode: MemoryManagerRangeMode,
629 },
630 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
632 MissingCoverage {
633 start: u8,
635 end: u8,
637 },
638 #[error(
640 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
641 )]
642 RangeOutsideCoverageTarget {
643 start: u8,
645 end: u8,
647 target_start: u8,
649 target_end: u8,
651 },
652}
653
654const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
655 left.start() <= right.end() && right.start() <= left.end()
656}
657
658fn validate_diagnostic_string(
659 field: &'static str,
660 value: &str,
661) -> Result<(), MemoryManagerRangeAuthorityError> {
662 validate_diagnostic_text(value).map_err(|error| {
663 MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
664 field,
665 reason: error.reason(),
666 }
667 })
668}