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)]
148pub struct MemoryManagerRangeAuthority {
149 authorities: Vec<MemoryManagerAuthorityRecord>,
150}
151
152impl MemoryManagerRangeAuthority {
153 #[must_use]
155 pub const fn new() -> Self {
156 Self {
157 authorities: Vec::new(),
158 }
159 }
160
161 pub fn from_records(
166 records: Vec<MemoryManagerAuthorityRecord>,
167 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
168 let mut authority = Self::new();
169 for record in records {
170 authority = authority.insert_record(record)?;
171 }
172 Ok(authority)
173 }
174
175 pub fn reserve(
180 self,
181 range: MemoryManagerIdRange,
182 authority: impl Into<String>,
183 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
184 self.reserve_with_purpose(range, authority, None)
185 }
186
187 pub fn reserve_ids(
192 self,
193 start: u8,
194 end: u8,
195 authority: impl Into<String>,
196 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
197 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
198 }
199
200 pub fn reserve_with_purpose(
205 self,
206 range: MemoryManagerIdRange,
207 authority: impl Into<String>,
208 purpose: Option<String>,
209 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
210 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
211 }
212
213 pub fn reserve_ids_with_purpose(
218 self,
219 start: u8,
220 end: u8,
221 authority: impl Into<String>,
222 purpose: Option<String>,
223 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
224 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
225 }
226
227 pub fn allow(
232 self,
233 range: MemoryManagerIdRange,
234 authority: impl Into<String>,
235 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
236 self.allow_with_purpose(range, authority, None)
237 }
238
239 pub fn allow_ids(
244 self,
245 start: u8,
246 end: u8,
247 authority: impl Into<String>,
248 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
249 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
250 }
251
252 pub fn allow_with_purpose(
257 self,
258 range: MemoryManagerIdRange,
259 authority: impl Into<String>,
260 purpose: Option<String>,
261 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
262 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
263 }
264
265 pub fn allow_ids_with_purpose(
270 self,
271 start: u8,
272 end: u8,
273 authority: impl Into<String>,
274 purpose: Option<String>,
275 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
276 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
277 }
278
279 pub fn validate_slot_authority(
281 &self,
282 slot: &AllocationSlotDescriptor,
283 expected_authority: &str,
284 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
285 let id = slot
286 .memory_manager_id()
287 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
288 self.validate_id_authority(id, expected_authority)
289 }
290
291 pub fn validate_slot_authority_mode(
293 &self,
294 slot: &AllocationSlotDescriptor,
295 expected_authority: &str,
296 expected_mode: MemoryManagerRangeMode,
297 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
298 let id = slot
299 .memory_manager_id()
300 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
301 self.validate_id_authority_mode(id, expected_authority, expected_mode)
302 }
303
304 pub fn validate_id_authority(
306 &self,
307 id: u8,
308 expected_authority: &str,
309 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
310 validate_diagnostic_string("expected_authority", expected_authority)?;
311 let record = self.covering_record(id)?;
312
313 if record.authority != expected_authority {
314 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
315 id,
316 expected_authority: expected_authority.to_string(),
317 actual_authority: record.authority.clone(),
318 });
319 }
320
321 Ok(record)
322 }
323
324 pub fn validate_id_authority_mode(
326 &self,
327 id: u8,
328 expected_authority: &str,
329 expected_mode: MemoryManagerRangeMode,
330 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
331 let record = self.validate_id_authority(id, expected_authority)?;
332 if record.mode != expected_mode {
333 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
334 id,
335 authority: record.authority.clone(),
336 expected_mode,
337 actual_mode: record.mode,
338 });
339 }
340 Ok(record)
341 }
342
343 pub fn authority_for_id(
345 &self,
346 id: u8,
347 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
348 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
349 Ok(self
350 .authorities
351 .iter()
352 .find(|record| record.range.contains(id)))
353 }
354
355 #[must_use]
361 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
362 &self.authorities
363 }
364
365 pub fn validate_complete_coverage(
371 &self,
372 target: MemoryManagerIdRange,
373 ) -> Result<(), MemoryManagerRangeAuthorityError> {
374 if self.authorities.is_empty() {
375 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
376 start: target.start(),
377 end: target.end(),
378 });
379 }
380
381 for record in &self.authorities {
382 if record.range.start() < target.start() || record.range.end() > target.end() {
383 return Err(
384 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
385 start: record.range.start(),
386 end: record.range.end(),
387 target_start: target.start(),
388 target_end: target.end(),
389 },
390 );
391 }
392 }
393
394 let mut next_uncovered = u16::from(target.start());
395 let target_end = u16::from(target.end());
396 for record in &self.authorities {
397 let record_start = u16::from(record.range.start());
398 let record_end = u16::from(record.range.end());
399
400 if record_start > next_uncovered {
401 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
402 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
403 end: record.range.start() - 1,
404 });
405 }
406
407 if record_end >= next_uncovered {
408 next_uncovered = record_end + 1;
409 }
410 }
411
412 if next_uncovered <= target_end {
413 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
414 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
415 end: target.end(),
416 });
417 }
418
419 Ok(())
420 }
421
422 fn insert(
423 self,
424 range: MemoryManagerIdRange,
425 authority: impl Into<String>,
426 mode: MemoryManagerRangeMode,
427 purpose: Option<String>,
428 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
429 let record = MemoryManagerAuthorityRecord {
430 range,
431 authority: authority.into(),
432 mode,
433 purpose,
434 };
435 self.insert_record(record)
436 }
437
438 fn insert_record(
439 mut self,
440 record: MemoryManagerAuthorityRecord,
441 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
442 validate_authority_record(&record)?;
443
444 for existing in &self.authorities {
445 if ranges_overlap(existing.range, record.range) {
446 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
447 existing_start: existing.range.start(),
448 existing_end: existing.range.end(),
449 candidate_start: record.range.start(),
450 candidate_end: record.range.end(),
451 });
452 }
453 }
454
455 self.authorities.push(record);
456 self.authorities.sort_by_key(|record| record.range.start());
457 Ok(self)
458 }
459
460 fn covering_record(
461 &self,
462 id: u8,
463 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
464 let Some(record) = self.authority_for_id(id)? else {
465 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
466 };
467 Ok(record)
468 }
469}
470
471fn validate_authority_record(
472 record: &MemoryManagerAuthorityRecord,
473) -> Result<(), MemoryManagerRangeAuthorityError> {
474 validate_diagnostic_string("authority", &record.authority)?;
475 if let Some(purpose) = &record.purpose {
476 validate_diagnostic_string("purpose", purpose)?;
477 }
478 Ok(())
479}
480
481#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
486pub enum MemoryManagerRangeAuthorityError {
487 #[error(transparent)]
489 Range(#[from] MemoryManagerRangeError),
490 #[error("{0}")]
492 Slot(#[from] MemoryManagerSlotError),
493 #[error(
495 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
496 )]
497 OverlappingRanges {
498 existing_start: u8,
500 existing_end: u8,
502 candidate_start: u8,
504 candidate_end: u8,
506 },
507 #[error("{field} {reason}")]
509 InvalidDiagnosticString {
510 field: &'static str,
512 reason: &'static str,
514 },
515 #[error("MemoryManager ID {id} is not covered by an authority range")]
517 UnclaimedId {
518 id: u8,
520 },
521 #[error(
523 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
524 )]
525 AuthorityMismatch {
526 id: u8,
528 expected_authority: String,
530 actual_authority: String,
532 },
533 #[error(
535 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
536 )]
537 ModeMismatch {
538 id: u8,
540 authority: String,
542 expected_mode: MemoryManagerRangeMode,
544 actual_mode: MemoryManagerRangeMode,
546 },
547 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
549 MissingCoverage {
550 start: u8,
552 end: u8,
554 },
555 #[error(
557 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
558 )]
559 RangeOutsideCoverageTarget {
560 start: u8,
562 end: u8,
564 target_start: u8,
566 target_end: u8,
568 },
569}
570
571const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
572 left.start() <= right.end() && right.start() <= left.end()
573}
574
575fn validate_diagnostic_string(
576 field: &'static str,
577 value: &str,
578) -> Result<(), MemoryManagerRangeAuthorityError> {
579 if value.is_empty() {
580 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
581 field,
582 reason: "must not be empty",
583 });
584 }
585 if value.len() > DIAGNOSTIC_STRING_MAX_BYTES {
586 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
587 field,
588 reason: "must be at most 256 bytes",
589 });
590 }
591 if !value.is_ascii() {
592 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
593 field,
594 reason: "must be ASCII",
595 });
596 }
597 if value.bytes().any(|byte| byte.is_ascii_control()) {
598 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
599 field,
600 reason: "must not contain ASCII control characters",
601 });
602 }
603 Ok(())
604}