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(
236 records: Vec<MemoryManagerAuthorityRecord>,
237 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
238 let mut authorities: Vec<MemoryManagerAuthorityRecord> = Vec::new();
239 for record in records {
240 validate_authority_record(&record)?;
241 let insertion = authorities
242 .partition_point(|existing| existing.range.start() < record.range.start());
243 let neighbours = insertion.saturating_sub(1)..(insertion + 1).min(authorities.len());
246 for existing in &authorities[neighbours] {
247 if ranges_overlap(existing.range, record.range) {
248 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
249 existing_start: existing.range.start(),
250 existing_end: existing.range.end(),
251 candidate_start: record.range.start(),
252 candidate_end: record.range.end(),
253 });
254 }
255 }
256 authorities.insert(insertion, record);
257 }
258 Ok(Self { authorities })
259 }
260
261 pub fn validate_slot_authority(
263 &self,
264 slot: &AllocationSlotDescriptor,
265 expected_authority: &str,
266 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
267 let id = slot
268 .memory_manager_id()
269 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
270 self.validate_id_authority(id, expected_authority)
271 }
272
273 pub fn validate_slot_authority_mode(
275 &self,
276 slot: &AllocationSlotDescriptor,
277 expected_authority: &str,
278 expected_mode: MemoryManagerRangeMode,
279 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
280 let id = slot
281 .memory_manager_id()
282 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
283 self.validate_id_authority_mode(id, expected_authority, expected_mode)
284 }
285
286 pub fn validate_id_authority(
288 &self,
289 id: u8,
290 expected_authority: &str,
291 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
292 validate_diagnostic_string("expected_authority", expected_authority)?;
293 let record = self.covering_record(id)?;
294
295 if record.authority != expected_authority {
296 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
297 id,
298 expected_authority: expected_authority.to_string(),
299 actual_authority: record.authority.clone(),
300 });
301 }
302
303 Ok(record)
304 }
305
306 pub fn validate_id_authority_mode(
308 &self,
309 id: u8,
310 expected_authority: &str,
311 expected_mode: MemoryManagerRangeMode,
312 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
313 let record = self.validate_id_authority(id, expected_authority)?;
314 if record.mode != expected_mode {
315 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
316 id,
317 authority: record.authority.clone(),
318 expected_mode,
319 actual_mode: record.mode,
320 });
321 }
322 Ok(record)
323 }
324
325 pub fn authority_for_id(
327 &self,
328 id: u8,
329 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
330 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
331 Ok(self
332 .authorities
333 .iter()
334 .find(|record| record.range.contains(id)))
335 }
336
337 #[must_use]
343 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
344 &self.authorities
345 }
346
347 pub fn validate_complete_coverage(
353 &self,
354 target: MemoryManagerIdRange,
355 ) -> Result<(), MemoryManagerRangeAuthorityError> {
356 if self.authorities.is_empty() {
357 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
358 start: target.start(),
359 end: target.end(),
360 });
361 }
362
363 for record in &self.authorities {
364 if record.range.start() < target.start() || record.range.end() > target.end() {
365 return Err(
366 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
367 start: record.range.start(),
368 end: record.range.end(),
369 target_start: target.start(),
370 target_end: target.end(),
371 },
372 );
373 }
374 }
375
376 let mut next_uncovered = u16::from(target.start());
377 let target_end = u16::from(target.end());
378 for record in &self.authorities {
379 let record_start = u16::from(record.range.start());
380 let record_end = u16::from(record.range.end());
381
382 if record_start > next_uncovered {
383 let start = u8::try_from(next_uncovered).map_err(|_| {
384 MemoryManagerRangeAuthorityError::MissingCoverage {
385 start: target.start(),
386 end: target.end(),
387 }
388 })?;
389 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
390 start,
391 end: record.range.start() - 1,
392 });
393 }
394
395 if record_end >= next_uncovered {
396 next_uncovered = record_end + 1;
397 }
398 }
399
400 if next_uncovered <= target_end {
401 let start = u8::try_from(next_uncovered).map_err(|_| {
402 MemoryManagerRangeAuthorityError::MissingCoverage {
403 start: target.start(),
404 end: target.end(),
405 }
406 })?;
407 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
408 start,
409 end: target.end(),
410 });
411 }
412
413 Ok(())
414 }
415
416 fn covering_record(
417 &self,
418 id: u8,
419 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
420 let Some(record) = self.authority_for_id(id)? else {
421 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
422 };
423 Ok(record)
424 }
425}
426
427fn validate_authority_record(
428 record: &MemoryManagerAuthorityRecord,
429) -> Result<(), MemoryManagerRangeAuthorityError> {
430 record.range.validate()?;
431 validate_diagnostic_string("authority", &record.authority)?;
432 if let Some(purpose) = &record.purpose {
433 validate_diagnostic_string("purpose", purpose)?;
434 }
435 Ok(())
436}
437
438#[non_exhaustive]
443#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
444pub enum MemoryManagerRangeAuthorityError {
445 #[error(transparent)]
447 Range(#[from] MemoryManagerRangeError),
448 #[error("{0}")]
450 Slot(#[from] MemoryManagerSlotError),
451 #[error(
453 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
454 )]
455 OverlappingRanges {
456 existing_start: u8,
458 existing_end: u8,
460 candidate_start: u8,
462 candidate_end: u8,
464 },
465 #[error("{field} {reason}")]
467 InvalidDiagnosticString {
468 field: &'static str,
470 reason: &'static str,
472 },
473 #[error("MemoryManager ID {id} is not covered by an authority range")]
475 UnclaimedId {
476 id: u8,
478 },
479 #[error(
481 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
482 )]
483 AuthorityMismatch {
484 id: u8,
486 expected_authority: String,
488 actual_authority: String,
490 },
491 #[error(
493 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
494 )]
495 ModeMismatch {
496 id: u8,
498 authority: String,
500 expected_mode: MemoryManagerRangeMode,
502 actual_mode: MemoryManagerRangeMode,
504 },
505 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
507 MissingCoverage {
508 start: u8,
510 end: u8,
512 },
513 #[error(
515 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
516 )]
517 RangeOutsideCoverageTarget {
518 start: u8,
520 end: u8,
522 target_start: u8,
524 target_end: u8,
526 },
527}
528
529const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
530 left.start() <= right.end() && right.start() <= left.end()
531}
532
533fn validate_diagnostic_string(
534 field: &'static str,
535 value: &str,
536) -> Result<(), MemoryManagerRangeAuthorityError> {
537 validate_diagnostic_text(value).map_err(|error| {
538 MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
539 field,
540 reason: error.reason(),
541 }
542 })
543}