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)]
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 #[must_use]
52 pub const fn start(&self) -> u8 {
53 self.start
54 }
55
56 #[must_use]
58 pub const fn end(&self) -> u8 {
59 self.end
60 }
61}
62
63#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
68pub enum MemoryManagerRangeError {
69 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
71 InvalidRange {
72 start: u8,
74 end: u8,
76 },
77 #[error("MemoryManager ID {id} is not a usable allocation slot")]
79 InvalidMemoryManagerId {
80 id: u8,
82 },
83}
84
85#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
92pub enum MemoryManagerRangeMode {
93 Reserved,
97 Allowed,
101}
102
103#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
108pub struct MemoryManagerAuthorityRecord {
109 pub range: MemoryManagerIdRange,
111 pub authority: String,
113 pub mode: MemoryManagerRangeMode,
115 pub purpose: Option<String>,
117}
118
119impl MemoryManagerAuthorityRecord {
120 pub fn new(
122 range: MemoryManagerIdRange,
123 authority: impl Into<String>,
124 mode: MemoryManagerRangeMode,
125 purpose: Option<String>,
126 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
127 let record = Self {
128 range,
129 authority: authority.into(),
130 mode,
131 purpose,
132 };
133 validate_authority_record(&record)?;
134 Ok(record)
135 }
136}
137
138#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
153pub struct MemoryManagerRangeAuthority {
154 authorities: Vec<MemoryManagerAuthorityRecord>,
155}
156
157impl MemoryManagerRangeAuthority {
158 #[must_use]
160 pub const fn new() -> Self {
161 Self {
162 authorities: Vec::new(),
163 }
164 }
165
166 pub fn from_records(
171 records: Vec<MemoryManagerAuthorityRecord>,
172 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
173 let mut authority = Self::new();
174 for record in records {
175 authority = authority.insert_record(record)?;
176 }
177 Ok(authority)
178 }
179
180 pub fn reserve(
185 self,
186 range: MemoryManagerIdRange,
187 authority: impl Into<String>,
188 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
189 self.reserve_with_purpose(range, authority, None)
190 }
191
192 pub fn reserve_ids(
197 self,
198 start: u8,
199 end: u8,
200 authority: impl Into<String>,
201 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
202 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
203 }
204
205 pub fn reserve_with_purpose(
210 self,
211 range: MemoryManagerIdRange,
212 authority: impl Into<String>,
213 purpose: Option<String>,
214 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
215 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
216 }
217
218 pub fn reserve_ids_with_purpose(
223 self,
224 start: u8,
225 end: u8,
226 authority: impl Into<String>,
227 purpose: Option<String>,
228 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
229 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
230 }
231
232 pub fn allow(
237 self,
238 range: MemoryManagerIdRange,
239 authority: impl Into<String>,
240 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
241 self.allow_with_purpose(range, authority, None)
242 }
243
244 pub fn allow_ids(
249 self,
250 start: u8,
251 end: u8,
252 authority: impl Into<String>,
253 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
254 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
255 }
256
257 pub fn allow_with_purpose(
262 self,
263 range: MemoryManagerIdRange,
264 authority: impl Into<String>,
265 purpose: Option<String>,
266 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
267 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
268 }
269
270 pub fn allow_ids_with_purpose(
275 self,
276 start: u8,
277 end: u8,
278 authority: impl Into<String>,
279 purpose: Option<String>,
280 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
281 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
282 }
283
284 pub fn validate_slot_authority(
286 &self,
287 slot: &AllocationSlotDescriptor,
288 expected_authority: &str,
289 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
290 let id = slot
291 .memory_manager_id()
292 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
293 self.validate_id_authority(id, expected_authority)
294 }
295
296 pub fn validate_slot_authority_mode(
298 &self,
299 slot: &AllocationSlotDescriptor,
300 expected_authority: &str,
301 expected_mode: MemoryManagerRangeMode,
302 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
303 let id = slot
304 .memory_manager_id()
305 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
306 self.validate_id_authority_mode(id, expected_authority, expected_mode)
307 }
308
309 pub fn validate_id_authority(
311 &self,
312 id: u8,
313 expected_authority: &str,
314 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
315 validate_diagnostic_string("expected_authority", expected_authority)?;
316 let record = self.covering_record(id)?;
317
318 if record.authority != expected_authority {
319 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
320 id,
321 expected_authority: expected_authority.to_string(),
322 actual_authority: record.authority.clone(),
323 });
324 }
325
326 Ok(record)
327 }
328
329 pub fn validate_id_authority_mode(
331 &self,
332 id: u8,
333 expected_authority: &str,
334 expected_mode: MemoryManagerRangeMode,
335 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
336 let record = self.validate_id_authority(id, expected_authority)?;
337 if record.mode != expected_mode {
338 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
339 id,
340 authority: record.authority.clone(),
341 expected_mode,
342 actual_mode: record.mode,
343 });
344 }
345 Ok(record)
346 }
347
348 pub fn authority_for_id(
350 &self,
351 id: u8,
352 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
353 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
354 Ok(self
355 .authorities
356 .iter()
357 .find(|record| record.range.contains(id)))
358 }
359
360 #[must_use]
366 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
367 &self.authorities
368 }
369
370 pub fn validate_complete_coverage(
376 &self,
377 target: MemoryManagerIdRange,
378 ) -> Result<(), MemoryManagerRangeAuthorityError> {
379 if self.authorities.is_empty() {
380 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
381 start: target.start(),
382 end: target.end(),
383 });
384 }
385
386 for record in &self.authorities {
387 if record.range.start() < target.start() || record.range.end() > target.end() {
388 return Err(
389 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
390 start: record.range.start(),
391 end: record.range.end(),
392 target_start: target.start(),
393 target_end: target.end(),
394 },
395 );
396 }
397 }
398
399 let mut next_uncovered = u16::from(target.start());
400 let target_end = u16::from(target.end());
401 for record in &self.authorities {
402 let record_start = u16::from(record.range.start());
403 let record_end = u16::from(record.range.end());
404
405 if record_start > next_uncovered {
406 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
407 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
408 end: record.range.start() - 1,
409 });
410 }
411
412 if record_end >= next_uncovered {
413 next_uncovered = record_end + 1;
414 }
415 }
416
417 if next_uncovered <= target_end {
418 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
419 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
420 end: target.end(),
421 });
422 }
423
424 Ok(())
425 }
426
427 fn insert(
428 self,
429 range: MemoryManagerIdRange,
430 authority: impl Into<String>,
431 mode: MemoryManagerRangeMode,
432 purpose: Option<String>,
433 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
434 let record = MemoryManagerAuthorityRecord {
435 range,
436 authority: authority.into(),
437 mode,
438 purpose,
439 };
440 self.insert_record(record)
441 }
442
443 fn insert_record(
444 mut self,
445 record: MemoryManagerAuthorityRecord,
446 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
447 validate_authority_record(&record)?;
448
449 for existing in &self.authorities {
450 if ranges_overlap(existing.range, record.range) {
451 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
452 existing_start: existing.range.start(),
453 existing_end: existing.range.end(),
454 candidate_start: record.range.start(),
455 candidate_end: record.range.end(),
456 });
457 }
458 }
459
460 self.authorities.push(record);
461 self.authorities.sort_by_key(|record| record.range.start());
462 Ok(self)
463 }
464
465 fn covering_record(
466 &self,
467 id: u8,
468 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
469 let Some(record) = self.authority_for_id(id)? else {
470 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
471 };
472 Ok(record)
473 }
474}
475
476fn validate_authority_record(
477 record: &MemoryManagerAuthorityRecord,
478) -> Result<(), MemoryManagerRangeAuthorityError> {
479 validate_diagnostic_string("authority", &record.authority)?;
480 if let Some(purpose) = &record.purpose {
481 validate_diagnostic_string("purpose", purpose)?;
482 }
483 Ok(())
484}
485
486#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
491pub enum MemoryManagerRangeAuthorityError {
492 #[error(transparent)]
494 Range(#[from] MemoryManagerRangeError),
495 #[error("{0}")]
497 Slot(#[from] MemoryManagerSlotError),
498 #[error(
500 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
501 )]
502 OverlappingRanges {
503 existing_start: u8,
505 existing_end: u8,
507 candidate_start: u8,
509 candidate_end: u8,
511 },
512 #[error("{field} {reason}")]
514 InvalidDiagnosticString {
515 field: &'static str,
517 reason: &'static str,
519 },
520 #[error("MemoryManager ID {id} is not covered by an authority range")]
522 UnclaimedId {
523 id: u8,
525 },
526 #[error(
528 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
529 )]
530 AuthorityMismatch {
531 id: u8,
533 expected_authority: String,
535 actual_authority: String,
537 },
538 #[error(
540 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
541 )]
542 ModeMismatch {
543 id: u8,
545 authority: String,
547 expected_mode: MemoryManagerRangeMode,
549 actual_mode: MemoryManagerRangeMode,
551 },
552 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
554 MissingCoverage {
555 start: u8,
557 end: u8,
559 },
560 #[error(
562 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
563 )]
564 RangeOutsideCoverageTarget {
565 start: u8,
567 end: u8,
569 target_start: u8,
571 target_end: u8,
573 },
574}
575
576const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
577 left.start() <= right.end() && right.start() <= left.end()
578}
579
580fn validate_diagnostic_string(
581 field: &'static str,
582 value: &str,
583) -> Result<(), MemoryManagerRangeAuthorityError> {
584 if value.is_empty() {
585 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
586 field,
587 reason: "must not be empty",
588 });
589 }
590 if value.len() > DIAGNOSTIC_STRING_MAX_BYTES {
591 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
592 field,
593 reason: "must be at most 256 bytes",
594 });
595 }
596 if !value.is_ascii() {
597 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
598 field,
599 reason: "must be ASCII",
600 });
601 }
602 if value.bytes().any(|byte| byte.is_ascii_control()) {
603 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
604 field,
605 reason: "must not contain ASCII control characters",
606 });
607 }
608 Ok(())
609}