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)]
117#[serde(deny_unknown_fields)]
118pub struct MemoryManagerAuthorityRecord {
119 pub(crate) range: MemoryManagerIdRange,
121 pub(crate) authority: String,
123 pub(crate) mode: MemoryManagerRangeMode,
125 pub(crate) purpose: Option<String>,
127}
128
129impl MemoryManagerAuthorityRecord {
130 pub fn new(
132 range: MemoryManagerIdRange,
133 authority: impl Into<String>,
134 mode: MemoryManagerRangeMode,
135 purpose: Option<String>,
136 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
137 let record = Self {
138 range,
139 authority: authority.into(),
140 mode,
141 purpose,
142 };
143 validate_authority_record(&record)?;
144 Ok(record)
145 }
146
147 #[must_use]
149 pub const fn range(&self) -> MemoryManagerIdRange {
150 self.range
151 }
152
153 #[must_use]
155 pub fn authority(&self) -> &str {
156 &self.authority
157 }
158
159 #[must_use]
161 pub const fn mode(&self) -> MemoryManagerRangeMode {
162 self.mode
163 }
164
165 #[must_use]
167 pub fn purpose(&self) -> Option<&str> {
168 self.purpose.as_deref()
169 }
170
171 pub fn validate(&self) -> Result<(), MemoryManagerRangeAuthorityError> {
173 validate_authority_record(self)
174 }
175}
176
177#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
192#[serde(deny_unknown_fields)]
193pub struct MemoryManagerRangeAuthority {
194 authorities: Vec<MemoryManagerAuthorityRecord>,
195}
196
197#[derive(Deserialize)]
198#[serde(deny_unknown_fields)]
199struct MemoryManagerRangeAuthorityDto {
200 authorities: Vec<MemoryManagerAuthorityRecord>,
201}
202
203impl<'de> Deserialize<'de> for MemoryManagerRangeAuthority {
204 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
205 let dto = MemoryManagerRangeAuthorityDto::deserialize(deserializer)?;
206 Self::from_records(dto.authorities).map_err(D::Error::custom)
207 }
208}
209
210impl MemoryManagerRangeAuthority {
211 #[must_use]
213 pub const fn new() -> Self {
214 Self {
215 authorities: Vec::new(),
216 }
217 }
218
219 pub fn from_records(
224 records: Vec<MemoryManagerAuthorityRecord>,
225 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
226 let mut authority = Self::new();
227 for record in records {
228 authority = authority.insert_record(record)?;
229 }
230 Ok(authority)
231 }
232
233 pub fn reserve(
238 self,
239 range: MemoryManagerIdRange,
240 authority: impl Into<String>,
241 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
242 self.reserve_with_purpose(range, authority, None)
243 }
244
245 pub fn reserve_ids(
250 self,
251 start: u8,
252 end: u8,
253 authority: impl Into<String>,
254 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
255 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
256 }
257
258 pub fn reserve_with_purpose(
263 self,
264 range: MemoryManagerIdRange,
265 authority: impl Into<String>,
266 purpose: Option<String>,
267 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
268 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
269 }
270
271 pub fn reserve_ids_with_purpose(
276 self,
277 start: u8,
278 end: u8,
279 authority: impl Into<String>,
280 purpose: Option<String>,
281 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
282 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
283 }
284
285 pub fn allow(
290 self,
291 range: MemoryManagerIdRange,
292 authority: impl Into<String>,
293 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
294 self.allow_with_purpose(range, authority, None)
295 }
296
297 pub fn allow_ids(
302 self,
303 start: u8,
304 end: u8,
305 authority: impl Into<String>,
306 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
307 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
308 }
309
310 pub fn allow_with_purpose(
315 self,
316 range: MemoryManagerIdRange,
317 authority: impl Into<String>,
318 purpose: Option<String>,
319 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
320 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
321 }
322
323 pub fn allow_ids_with_purpose(
328 self,
329 start: u8,
330 end: u8,
331 authority: impl Into<String>,
332 purpose: Option<String>,
333 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
334 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
335 }
336
337 pub fn validate_slot_authority(
339 &self,
340 slot: &AllocationSlotDescriptor,
341 expected_authority: &str,
342 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
343 let id = slot
344 .memory_manager_id()
345 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
346 self.validate_id_authority(id, expected_authority)
347 }
348
349 pub fn validate_slot_authority_mode(
351 &self,
352 slot: &AllocationSlotDescriptor,
353 expected_authority: &str,
354 expected_mode: MemoryManagerRangeMode,
355 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
356 let id = slot
357 .memory_manager_id()
358 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
359 self.validate_id_authority_mode(id, expected_authority, expected_mode)
360 }
361
362 pub fn validate_id_authority(
364 &self,
365 id: u8,
366 expected_authority: &str,
367 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
368 validate_diagnostic_string("expected_authority", expected_authority)?;
369 let record = self.covering_record(id)?;
370
371 if record.authority != expected_authority {
372 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
373 id,
374 expected_authority: expected_authority.to_string(),
375 actual_authority: record.authority.clone(),
376 });
377 }
378
379 Ok(record)
380 }
381
382 pub fn validate_id_authority_mode(
384 &self,
385 id: u8,
386 expected_authority: &str,
387 expected_mode: MemoryManagerRangeMode,
388 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
389 let record = self.validate_id_authority(id, expected_authority)?;
390 if record.mode != expected_mode {
391 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
392 id,
393 authority: record.authority.clone(),
394 expected_mode,
395 actual_mode: record.mode,
396 });
397 }
398 Ok(record)
399 }
400
401 pub fn authority_for_id(
403 &self,
404 id: u8,
405 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
406 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
407 Ok(self
408 .authorities
409 .iter()
410 .find(|record| record.range.contains(id)))
411 }
412
413 #[must_use]
419 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
420 &self.authorities
421 }
422
423 pub fn validate_complete_coverage(
429 &self,
430 target: MemoryManagerIdRange,
431 ) -> Result<(), MemoryManagerRangeAuthorityError> {
432 if self.authorities.is_empty() {
433 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
434 start: target.start(),
435 end: target.end(),
436 });
437 }
438
439 for record in &self.authorities {
440 if record.range.start() < target.start() || record.range.end() > target.end() {
441 return Err(
442 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
443 start: record.range.start(),
444 end: record.range.end(),
445 target_start: target.start(),
446 target_end: target.end(),
447 },
448 );
449 }
450 }
451
452 let mut next_uncovered = u16::from(target.start());
453 let target_end = u16::from(target.end());
454 for record in &self.authorities {
455 let record_start = u16::from(record.range.start());
456 let record_end = u16::from(record.range.end());
457
458 if record_start > next_uncovered {
459 let start = u8::try_from(next_uncovered).map_err(|_| {
460 MemoryManagerRangeAuthorityError::MissingCoverage {
461 start: target.start(),
462 end: target.end(),
463 }
464 })?;
465 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
466 start,
467 end: record.range.start() - 1,
468 });
469 }
470
471 if record_end >= next_uncovered {
472 next_uncovered = record_end + 1;
473 }
474 }
475
476 if next_uncovered <= target_end {
477 let start = u8::try_from(next_uncovered).map_err(|_| {
478 MemoryManagerRangeAuthorityError::MissingCoverage {
479 start: target.start(),
480 end: target.end(),
481 }
482 })?;
483 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
484 start,
485 end: target.end(),
486 });
487 }
488
489 Ok(())
490 }
491
492 fn insert(
493 self,
494 range: MemoryManagerIdRange,
495 authority: impl Into<String>,
496 mode: MemoryManagerRangeMode,
497 purpose: Option<String>,
498 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
499 let record = MemoryManagerAuthorityRecord {
500 range,
501 authority: authority.into(),
502 mode,
503 purpose,
504 };
505 self.insert_record(record)
506 }
507
508 fn insert_record(
509 mut self,
510 record: MemoryManagerAuthorityRecord,
511 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
512 validate_authority_record(&record)?;
513
514 for existing in &self.authorities {
515 if ranges_overlap(existing.range, record.range) {
516 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
517 existing_start: existing.range.start(),
518 existing_end: existing.range.end(),
519 candidate_start: record.range.start(),
520 candidate_end: record.range.end(),
521 });
522 }
523 }
524
525 self.authorities.push(record);
526 self.authorities.sort_by_key(|record| record.range.start());
527 Ok(self)
528 }
529
530 fn covering_record(
531 &self,
532 id: u8,
533 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
534 let Some(record) = self.authority_for_id(id)? else {
535 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
536 };
537 Ok(record)
538 }
539}
540
541fn validate_authority_record(
542 record: &MemoryManagerAuthorityRecord,
543) -> Result<(), MemoryManagerRangeAuthorityError> {
544 record.range.validate()?;
545 validate_diagnostic_string("authority", &record.authority)?;
546 if let Some(purpose) = &record.purpose {
547 validate_diagnostic_string("purpose", purpose)?;
548 }
549 Ok(())
550}
551
552#[non_exhaustive]
557#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
558pub enum MemoryManagerRangeAuthorityError {
559 #[error(transparent)]
561 Range(#[from] MemoryManagerRangeError),
562 #[error("{0}")]
564 Slot(#[from] MemoryManagerSlotError),
565 #[error(
567 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
568 )]
569 OverlappingRanges {
570 existing_start: u8,
572 existing_end: u8,
574 candidate_start: u8,
576 candidate_end: u8,
578 },
579 #[error("{field} {reason}")]
581 InvalidDiagnosticString {
582 field: &'static str,
584 reason: &'static str,
586 },
587 #[error("MemoryManager ID {id} is not covered by an authority range")]
589 UnclaimedId {
590 id: u8,
592 },
593 #[error(
595 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
596 )]
597 AuthorityMismatch {
598 id: u8,
600 expected_authority: String,
602 actual_authority: String,
604 },
605 #[error(
607 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
608 )]
609 ModeMismatch {
610 id: u8,
612 authority: String,
614 expected_mode: MemoryManagerRangeMode,
616 actual_mode: MemoryManagerRangeMode,
618 },
619 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
621 MissingCoverage {
622 start: u8,
624 end: u8,
626 },
627 #[error(
629 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
630 )]
631 RangeOutsideCoverageTarget {
632 start: u8,
634 end: u8,
636 target_start: u8,
638 target_end: u8,
640 },
641}
642
643const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
644 left.start() <= right.end() && right.start() <= left.end()
645}
646
647fn validate_diagnostic_string(
648 field: &'static str,
649 value: &str,
650) -> Result<(), MemoryManagerRangeAuthorityError> {
651 if value.is_empty() {
652 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
653 field,
654 reason: "must not be empty",
655 });
656 }
657 if value.len() > DIAGNOSTIC_STRING_MAX_BYTES {
658 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
659 field,
660 reason: "must be at most 256 bytes",
661 });
662 }
663 if !value.is_ascii() {
664 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
665 field,
666 reason: "must be ASCII",
667 });
668 }
669 if value.bytes().any(|byte| byte.is_ascii_control()) {
670 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
671 field,
672 reason: "must not contain ASCII control characters",
673 });
674 }
675 Ok(())
676}