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 end == MEMORY_MANAGER_INVALID_ID {
28 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: end });
29 }
30 Ok(Self { start, end })
31 }
32
33 #[must_use]
35 pub const fn all_usable() -> Self {
36 Self {
37 start: MEMORY_MANAGER_MIN_ID,
38 end: MEMORY_MANAGER_MAX_ID,
39 }
40 }
41
42 #[must_use]
44 pub const fn contains(&self, id: u8) -> bool {
45 id >= self.start && id <= self.end
46 }
47
48 pub const fn validate(&self) -> Result<(), MemoryManagerRangeError> {
50 match Self::new(self.start, self.end) {
51 Ok(_) => Ok(()),
52 Err(err) => Err(err),
53 }
54 }
55
56 #[must_use]
58 pub const fn start(&self) -> u8 {
59 self.start
60 }
61
62 #[must_use]
64 pub const fn end(&self) -> u8 {
65 self.end
66 }
67}
68
69#[non_exhaustive]
74#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
75pub enum MemoryManagerRangeError {
76 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
78 InvalidRange {
79 start: u8,
81 end: u8,
83 },
84 #[error("MemoryManager ID {id} is not a usable allocation slot")]
86 InvalidMemoryManagerId {
87 id: u8,
89 },
90}
91
92#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
104pub enum MemoryManagerRangeMode {
105 Reserved,
109 Allowed,
113}
114
115#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
122#[serde(deny_unknown_fields)]
123pub struct MemoryManagerAuthorityRecord {
124 pub(crate) range: MemoryManagerIdRange,
126 pub(crate) authority: String,
128 pub(crate) mode: MemoryManagerRangeMode,
130 #[serde(deserialize_with = "crate::cbor::deserialize_present_option")]
132 pub(crate) purpose: Option<String>,
133}
134
135impl MemoryManagerAuthorityRecord {
136 pub fn new(
138 range: MemoryManagerIdRange,
139 authority: impl Into<String>,
140 mode: MemoryManagerRangeMode,
141 purpose: Option<String>,
142 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
143 let record = Self {
144 range,
145 authority: authority.into(),
146 mode,
147 purpose,
148 };
149 validate_authority_record(&record)?;
150 Ok(record)
151 }
152
153 #[must_use]
155 pub const fn range(&self) -> MemoryManagerIdRange {
156 self.range
157 }
158
159 #[must_use]
161 pub fn authority(&self) -> &str {
162 &self.authority
163 }
164
165 #[must_use]
167 pub const fn mode(&self) -> MemoryManagerRangeMode {
168 self.mode
169 }
170
171 #[must_use]
173 pub fn purpose(&self) -> Option<&str> {
174 self.purpose.as_deref()
175 }
176
177 pub fn validate(&self) -> Result<(), MemoryManagerRangeAuthorityError> {
179 validate_authority_record(self)
180 }
181}
182
183#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
202pub struct MemoryManagerRangeAuthority {
203 authorities: Vec<MemoryManagerAuthorityRecord>,
204}
205
206#[derive(Deserialize)]
207#[serde(deny_unknown_fields)]
208struct MemoryManagerRangeAuthorityDto {
209 authorities: Vec<MemoryManagerAuthorityRecord>,
210}
211
212impl<'de> Deserialize<'de> for MemoryManagerRangeAuthority {
213 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
214 let dto = MemoryManagerRangeAuthorityDto::deserialize(deserializer)?;
215 Self::from_records(dto.authorities).map_err(D::Error::custom)
216 }
217}
218
219impl MemoryManagerRangeAuthority {
220 #[must_use]
222 pub const fn new() -> Self {
223 Self {
224 authorities: Vec::new(),
225 }
226 }
227
228 pub fn from_records(
234 records: Vec<MemoryManagerAuthorityRecord>,
235 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
236 let mut authorities: Vec<MemoryManagerAuthorityRecord> = Vec::new();
237 for record in records {
238 validate_authority_record(&record)?;
239 let insertion = authorities
240 .partition_point(|existing| existing.range.start() < record.range.start());
241 let neighbours = insertion.saturating_sub(1)..(insertion + 1).min(authorities.len());
244 for existing in &authorities[neighbours] {
245 if ranges_overlap(existing.range, record.range) {
246 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
247 existing_start: existing.range.start(),
248 existing_end: existing.range.end(),
249 candidate_start: record.range.start(),
250 candidate_end: record.range.end(),
251 });
252 }
253 }
254 authorities.insert(insertion, record);
255 }
256 Ok(Self { authorities })
257 }
258
259 pub fn validate_slot_authority(
261 &self,
262 slot: &AllocationSlotDescriptor,
263 expected_authority: &str,
264 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
265 let id = slot
266 .memory_manager_id()
267 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
268 self.validate_id_authority(id, expected_authority)
269 }
270
271 pub fn validate_slot_authority_mode(
273 &self,
274 slot: &AllocationSlotDescriptor,
275 expected_authority: &str,
276 expected_mode: MemoryManagerRangeMode,
277 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
278 let id = slot
279 .memory_manager_id()
280 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
281 self.validate_id_authority_mode(id, expected_authority, expected_mode)
282 }
283
284 pub fn validate_id_authority(
286 &self,
287 id: u8,
288 expected_authority: &str,
289 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
290 validate_diagnostic_string("expected_authority", expected_authority)?;
291 let record = self.covering_record(id)?;
292
293 if record.authority != expected_authority {
294 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
295 id,
296 expected_authority: expected_authority.to_string(),
297 actual_authority: record.authority.clone(),
298 });
299 }
300
301 Ok(record)
302 }
303
304 pub fn validate_id_authority_mode(
306 &self,
307 id: u8,
308 expected_authority: &str,
309 expected_mode: MemoryManagerRangeMode,
310 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
311 let record = self.validate_id_authority(id, expected_authority)?;
312 if record.mode != expected_mode {
313 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
314 id,
315 authority: record.authority.clone(),
316 expected_mode,
317 actual_mode: record.mode,
318 });
319 }
320 Ok(record)
321 }
322
323 pub fn authority_for_id(
325 &self,
326 id: u8,
327 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
328 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
329 Ok(self
330 .authorities
331 .iter()
332 .find(|record| record.range.contains(id)))
333 }
334
335 #[must_use]
341 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
342 &self.authorities
343 }
344
345 pub fn validate_complete_coverage(
351 &self,
352 target: MemoryManagerIdRange,
353 ) -> Result<(), MemoryManagerRangeAuthorityError> {
354 if self.authorities.is_empty() {
355 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
356 start: target.start(),
357 end: target.end(),
358 });
359 }
360
361 for record in &self.authorities {
362 if record.range.start() < target.start() || record.range.end() > target.end() {
363 return Err(
364 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
365 start: record.range.start(),
366 end: record.range.end(),
367 target_start: target.start(),
368 target_end: target.end(),
369 },
370 );
371 }
372 }
373
374 let mut next_uncovered = target.start();
375 for record in &self.authorities {
376 if record.range.start() > next_uncovered {
377 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
378 start: next_uncovered,
379 end: record.range.start() - 1,
380 });
381 }
382 next_uncovered = record.range.end() + 1;
385 }
386
387 if next_uncovered <= target.end() {
388 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
389 start: next_uncovered,
390 end: target.end(),
391 });
392 }
393
394 Ok(())
395 }
396
397 fn covering_record(
398 &self,
399 id: u8,
400 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
401 let Some(record) = self.authority_for_id(id)? else {
402 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
403 };
404 Ok(record)
405 }
406}
407
408fn validate_authority_record(
409 record: &MemoryManagerAuthorityRecord,
410) -> Result<(), MemoryManagerRangeAuthorityError> {
411 record.range.validate()?;
412 validate_diagnostic_string("authority", &record.authority)?;
413 if let Some(purpose) = &record.purpose {
414 validate_diagnostic_string("purpose", purpose)?;
415 }
416 Ok(())
417}
418
419#[non_exhaustive]
424#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
425pub enum MemoryManagerRangeAuthorityError {
426 #[error(transparent)]
428 Range(#[from] MemoryManagerRangeError),
429 #[error("{0}")]
431 Slot(#[from] MemoryManagerSlotError),
432 #[error(
434 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
435 )]
436 OverlappingRanges {
437 existing_start: u8,
439 existing_end: u8,
441 candidate_start: u8,
443 candidate_end: u8,
445 },
446 #[error("{field} {reason}")]
448 InvalidDiagnosticString {
449 field: &'static str,
451 reason: &'static str,
453 },
454 #[error("MemoryManager ID {id} is not covered by an authority range")]
456 UnclaimedId {
457 id: u8,
459 },
460 #[error(
462 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
463 )]
464 AuthorityMismatch {
465 id: u8,
467 expected_authority: String,
469 actual_authority: String,
471 },
472 #[error(
474 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
475 )]
476 ModeMismatch {
477 id: u8,
479 authority: String,
481 expected_mode: MemoryManagerRangeMode,
483 actual_mode: MemoryManagerRangeMode,
485 },
486 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
488 MissingCoverage {
489 start: u8,
491 end: u8,
493 },
494 #[error(
496 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
497 )]
498 RangeOutsideCoverageTarget {
499 start: u8,
501 end: u8,
503 target_start: u8,
505 target_end: u8,
507 },
508}
509
510const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
511 left.start() <= right.end() && right.start() <= left.end()
512}
513
514fn validate_diagnostic_string(
515 field: &'static str,
516 value: &str,
517) -> Result<(), MemoryManagerRangeAuthorityError> {
518 validate_diagnostic_text(value).map_err(|error| {
519 MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
520 field,
521 reason: error.reason(),
522 }
523 })
524}