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::constants::DIAGNOSTIC_STRING_MAX_BYTES;
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)]
101pub enum MemoryManagerRangeMode {
102 Reserved,
106 Allowed,
110}
111
112#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
119#[serde(deny_unknown_fields)]
120pub struct MemoryManagerAuthorityRecord {
121 pub(crate) range: MemoryManagerIdRange,
123 pub(crate) authority: String,
125 pub(crate) mode: MemoryManagerRangeMode,
127 #[serde(deserialize_with = "crate::cbor::deserialize_present_option")]
129 pub(crate) purpose: Option<String>,
130}
131
132impl MemoryManagerAuthorityRecord {
133 pub fn new(
135 range: MemoryManagerIdRange,
136 authority: impl Into<String>,
137 mode: MemoryManagerRangeMode,
138 purpose: Option<String>,
139 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
140 let record = Self {
141 range,
142 authority: authority.into(),
143 mode,
144 purpose,
145 };
146 validate_authority_record(&record)?;
147 Ok(record)
148 }
149
150 #[must_use]
152 pub const fn range(&self) -> MemoryManagerIdRange {
153 self.range
154 }
155
156 #[must_use]
158 pub fn authority(&self) -> &str {
159 &self.authority
160 }
161
162 #[must_use]
164 pub const fn mode(&self) -> MemoryManagerRangeMode {
165 self.mode
166 }
167
168 #[must_use]
170 pub fn purpose(&self) -> Option<&str> {
171 self.purpose.as_deref()
172 }
173
174 pub fn validate(&self) -> Result<(), MemoryManagerRangeAuthorityError> {
176 validate_authority_record(self)
177 }
178}
179
180#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
195#[serde(deny_unknown_fields)]
196pub struct MemoryManagerRangeAuthority {
197 authorities: Vec<MemoryManagerAuthorityRecord>,
198}
199
200#[derive(Deserialize)]
201#[serde(deny_unknown_fields)]
202struct MemoryManagerRangeAuthorityDto {
203 authorities: Vec<MemoryManagerAuthorityRecord>,
204}
205
206impl<'de> Deserialize<'de> for MemoryManagerRangeAuthority {
207 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
208 let dto = MemoryManagerRangeAuthorityDto::deserialize(deserializer)?;
209 Self::from_records(dto.authorities).map_err(D::Error::custom)
210 }
211}
212
213impl MemoryManagerRangeAuthority {
214 #[must_use]
216 pub const fn new() -> Self {
217 Self {
218 authorities: Vec::new(),
219 }
220 }
221
222 pub fn from_records(
227 records: Vec<MemoryManagerAuthorityRecord>,
228 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
229 let mut authority = Self::new();
230 for record in records {
231 authority = authority.insert_record(record)?;
232 }
233 Ok(authority)
234 }
235
236 pub fn reserve(
241 self,
242 range: MemoryManagerIdRange,
243 authority: impl Into<String>,
244 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
245 self.reserve_with_purpose(range, authority, None)
246 }
247
248 pub fn reserve_ids(
253 self,
254 start: u8,
255 end: u8,
256 authority: impl Into<String>,
257 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
258 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
259 }
260
261 pub fn reserve_with_purpose(
266 self,
267 range: MemoryManagerIdRange,
268 authority: impl Into<String>,
269 purpose: Option<String>,
270 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
271 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
272 }
273
274 pub fn reserve_ids_with_purpose(
279 self,
280 start: u8,
281 end: u8,
282 authority: impl Into<String>,
283 purpose: Option<String>,
284 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
285 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
286 }
287
288 pub fn allow(
293 self,
294 range: MemoryManagerIdRange,
295 authority: impl Into<String>,
296 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
297 self.allow_with_purpose(range, authority, None)
298 }
299
300 pub fn allow_ids(
305 self,
306 start: u8,
307 end: u8,
308 authority: impl Into<String>,
309 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
310 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
311 }
312
313 pub fn allow_with_purpose(
318 self,
319 range: MemoryManagerIdRange,
320 authority: impl Into<String>,
321 purpose: Option<String>,
322 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
323 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
324 }
325
326 pub fn allow_ids_with_purpose(
331 self,
332 start: u8,
333 end: u8,
334 authority: impl Into<String>,
335 purpose: Option<String>,
336 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
337 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
338 }
339
340 pub fn validate_slot_authority(
342 &self,
343 slot: &AllocationSlotDescriptor,
344 expected_authority: &str,
345 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
346 let id = slot
347 .memory_manager_id()
348 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
349 self.validate_id_authority(id, expected_authority)
350 }
351
352 pub fn validate_slot_authority_mode(
354 &self,
355 slot: &AllocationSlotDescriptor,
356 expected_authority: &str,
357 expected_mode: MemoryManagerRangeMode,
358 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
359 let id = slot
360 .memory_manager_id()
361 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
362 self.validate_id_authority_mode(id, expected_authority, expected_mode)
363 }
364
365 pub fn validate_id_authority(
367 &self,
368 id: u8,
369 expected_authority: &str,
370 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
371 validate_diagnostic_string("expected_authority", expected_authority)?;
372 let record = self.covering_record(id)?;
373
374 if record.authority != expected_authority {
375 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
376 id,
377 expected_authority: expected_authority.to_string(),
378 actual_authority: record.authority.clone(),
379 });
380 }
381
382 Ok(record)
383 }
384
385 pub fn validate_id_authority_mode(
387 &self,
388 id: u8,
389 expected_authority: &str,
390 expected_mode: MemoryManagerRangeMode,
391 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
392 let record = self.validate_id_authority(id, expected_authority)?;
393 if record.mode != expected_mode {
394 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
395 id,
396 authority: record.authority.clone(),
397 expected_mode,
398 actual_mode: record.mode,
399 });
400 }
401 Ok(record)
402 }
403
404 pub fn authority_for_id(
406 &self,
407 id: u8,
408 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
409 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
410 Ok(self
411 .authorities
412 .iter()
413 .find(|record| record.range.contains(id)))
414 }
415
416 #[must_use]
422 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
423 &self.authorities
424 }
425
426 pub fn validate_complete_coverage(
432 &self,
433 target: MemoryManagerIdRange,
434 ) -> Result<(), MemoryManagerRangeAuthorityError> {
435 if self.authorities.is_empty() {
436 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
437 start: target.start(),
438 end: target.end(),
439 });
440 }
441
442 for record in &self.authorities {
443 if record.range.start() < target.start() || record.range.end() > target.end() {
444 return Err(
445 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
446 start: record.range.start(),
447 end: record.range.end(),
448 target_start: target.start(),
449 target_end: target.end(),
450 },
451 );
452 }
453 }
454
455 let mut next_uncovered = u16::from(target.start());
456 let target_end = u16::from(target.end());
457 for record in &self.authorities {
458 let record_start = u16::from(record.range.start());
459 let record_end = u16::from(record.range.end());
460
461 if record_start > next_uncovered {
462 let start = u8::try_from(next_uncovered).map_err(|_| {
463 MemoryManagerRangeAuthorityError::MissingCoverage {
464 start: target.start(),
465 end: target.end(),
466 }
467 })?;
468 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
469 start,
470 end: record.range.start() - 1,
471 });
472 }
473
474 if record_end >= next_uncovered {
475 next_uncovered = record_end + 1;
476 }
477 }
478
479 if next_uncovered <= target_end {
480 let start = u8::try_from(next_uncovered).map_err(|_| {
481 MemoryManagerRangeAuthorityError::MissingCoverage {
482 start: target.start(),
483 end: target.end(),
484 }
485 })?;
486 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
487 start,
488 end: target.end(),
489 });
490 }
491
492 Ok(())
493 }
494
495 fn insert(
496 self,
497 range: MemoryManagerIdRange,
498 authority: impl Into<String>,
499 mode: MemoryManagerRangeMode,
500 purpose: Option<String>,
501 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
502 let record = MemoryManagerAuthorityRecord {
503 range,
504 authority: authority.into(),
505 mode,
506 purpose,
507 };
508 self.insert_record(record)
509 }
510
511 fn insert_record(
512 mut self,
513 record: MemoryManagerAuthorityRecord,
514 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
515 validate_authority_record(&record)?;
516
517 for existing in &self.authorities {
518 if ranges_overlap(existing.range, record.range) {
519 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
520 existing_start: existing.range.start(),
521 existing_end: existing.range.end(),
522 candidate_start: record.range.start(),
523 candidate_end: record.range.end(),
524 });
525 }
526 }
527
528 self.authorities.push(record);
529 self.authorities.sort_by_key(|record| record.range.start());
530 Ok(self)
531 }
532
533 fn covering_record(
534 &self,
535 id: u8,
536 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
537 let Some(record) = self.authority_for_id(id)? else {
538 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
539 };
540 Ok(record)
541 }
542}
543
544fn validate_authority_record(
545 record: &MemoryManagerAuthorityRecord,
546) -> Result<(), MemoryManagerRangeAuthorityError> {
547 record.range.validate()?;
548 validate_diagnostic_string("authority", &record.authority)?;
549 if let Some(purpose) = &record.purpose {
550 validate_diagnostic_string("purpose", purpose)?;
551 }
552 Ok(())
553}
554
555#[non_exhaustive]
560#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
561pub enum MemoryManagerRangeAuthorityError {
562 #[error(transparent)]
564 Range(#[from] MemoryManagerRangeError),
565 #[error("{0}")]
567 Slot(#[from] MemoryManagerSlotError),
568 #[error(
570 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
571 )]
572 OverlappingRanges {
573 existing_start: u8,
575 existing_end: u8,
577 candidate_start: u8,
579 candidate_end: u8,
581 },
582 #[error("{field} {reason}")]
584 InvalidDiagnosticString {
585 field: &'static str,
587 reason: &'static str,
589 },
590 #[error("MemoryManager ID {id} is not covered by an authority range")]
592 UnclaimedId {
593 id: u8,
595 },
596 #[error(
598 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
599 )]
600 AuthorityMismatch {
601 id: u8,
603 expected_authority: String,
605 actual_authority: String,
607 },
608 #[error(
610 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
611 )]
612 ModeMismatch {
613 id: u8,
615 authority: String,
617 expected_mode: MemoryManagerRangeMode,
619 actual_mode: MemoryManagerRangeMode,
621 },
622 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
624 MissingCoverage {
625 start: u8,
627 end: u8,
629 },
630 #[error(
632 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
633 )]
634 RangeOutsideCoverageTarget {
635 start: u8,
637 end: u8,
639 target_start: u8,
641 target_end: u8,
643 },
644}
645
646const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
647 left.start() <= right.end() && right.start() <= left.end()
648}
649
650fn validate_diagnostic_string(
651 field: &'static str,
652 value: &str,
653) -> Result<(), MemoryManagerRangeAuthorityError> {
654 if value.is_empty() {
655 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
656 field,
657 reason: "must not be empty",
658 });
659 }
660 if value.len() > DIAGNOSTIC_STRING_MAX_BYTES {
661 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
662 field,
663 reason: "must be at most 256 bytes",
664 });
665 }
666 if !value.is_ascii() {
667 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
668 field,
669 reason: "must be ASCII",
670 });
671 }
672 if value.bytes().any(|byte| byte.is_ascii_control()) {
673 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
674 field,
675 reason: "must not contain ASCII control characters",
676 });
677 }
678 Ok(())
679}