1use super::memory_manager::{
2 MEMORY_MANAGER_INVALID_ID, MEMORY_MANAGER_MAX_ID, MEMORY_MANAGER_MIN_ID, MemoryManagerSlot,
3 MemoryManagerSlotError, validate_memory_manager_id,
4};
5use crate::text::validate_diagnostic_text;
6use serde::{Deserialize, Deserializer, Serialize, de::Error as _};
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
16pub struct MemoryManagerIdRange {
17 start: u8,
18 end: u8,
19}
20
21impl<'de> Deserialize<'de> for MemoryManagerIdRange {
22 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
23 #[derive(Deserialize)]
24 #[serde(rename = "MemoryManagerIdRange", deny_unknown_fields)]
25 struct Bounds {
26 start: u8,
27 end: u8,
28 }
29
30 let bounds = Bounds::deserialize(deserializer)?;
31 Self::new(bounds.start, bounds.end).map_err(D::Error::custom)
32 }
33}
34
35impl MemoryManagerIdRange {
36 pub const fn new(start: u8, end: u8) -> Result<Self, MemoryManagerRangeError> {
38 if start > end {
39 return Err(MemoryManagerRangeError::InvalidRange { start, end });
40 }
41 if end == MEMORY_MANAGER_INVALID_ID {
43 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: end });
44 }
45 Ok(Self { start, end })
46 }
47
48 #[must_use]
50 pub const fn all_usable() -> Self {
51 Self {
52 start: MEMORY_MANAGER_MIN_ID,
53 end: MEMORY_MANAGER_MAX_ID,
54 }
55 }
56
57 #[must_use]
59 pub const fn contains(&self, id: u8) -> bool {
60 id >= self.start && id <= self.end
61 }
62
63 #[must_use]
65 pub const fn start(&self) -> u8 {
66 self.start
67 }
68
69 #[must_use]
71 pub const fn end(&self) -> u8 {
72 self.end
73 }
74}
75
76#[non_exhaustive]
81#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
82pub enum MemoryManagerRangeError {
83 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
85 InvalidRange {
86 start: u8,
88 end: u8,
90 },
91 #[error("MemoryManager ID {id} is not a usable allocation slot")]
93 InvalidMemoryManagerId {
94 id: u8,
96 },
97}
98
99#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
111pub enum MemoryManagerRangeMode {
112 Reserved,
116 Allowed,
120}
121
122#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
129#[serde(deny_unknown_fields)]
130pub struct MemoryManagerAuthorityRecord {
131 pub(crate) range: MemoryManagerIdRange,
133 pub(crate) authority: String,
135 pub(crate) mode: MemoryManagerRangeMode,
137 #[serde(deserialize_with = "crate::cbor::deserialize_present_option")]
139 pub(crate) purpose: Option<String>,
140}
141
142impl MemoryManagerAuthorityRecord {
143 pub fn new(
145 range: MemoryManagerIdRange,
146 authority: impl Into<String>,
147 mode: MemoryManagerRangeMode,
148 purpose: Option<String>,
149 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
150 let record = Self {
151 range,
152 authority: authority.into(),
153 mode,
154 purpose,
155 };
156 validate_authority_record(&record)?;
157 Ok(record)
158 }
159
160 #[must_use]
162 pub const fn range(&self) -> MemoryManagerIdRange {
163 self.range
164 }
165
166 #[must_use]
168 pub fn authority(&self) -> &str {
169 &self.authority
170 }
171
172 #[must_use]
174 pub const fn mode(&self) -> MemoryManagerRangeMode {
175 self.mode
176 }
177
178 #[must_use]
180 pub fn purpose(&self) -> Option<&str> {
181 self.purpose.as_deref()
182 }
183
184 pub fn validate(&self) -> Result<(), MemoryManagerRangeAuthorityError> {
187 validate_authority_record(self)
188 }
189}
190
191#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
210pub struct MemoryManagerRangeAuthority {
211 authorities: Vec<MemoryManagerAuthorityRecord>,
212}
213
214#[derive(Deserialize)]
215#[serde(deny_unknown_fields)]
216struct MemoryManagerRangeAuthorityDto {
217 authorities: Vec<MemoryManagerAuthorityRecord>,
218}
219
220impl<'de> Deserialize<'de> for MemoryManagerRangeAuthority {
221 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
222 let dto = MemoryManagerRangeAuthorityDto::deserialize(deserializer)?;
223 Self::from_records(dto.authorities).map_err(D::Error::custom)
224 }
225}
226
227impl MemoryManagerRangeAuthority {
228 #[must_use]
230 pub const fn new() -> Self {
231 Self {
232 authorities: Vec::new(),
233 }
234 }
235
236 pub fn from_records(
242 mut records: Vec<MemoryManagerAuthorityRecord>,
243 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
244 for index in 0..records.len() {
245 let record = &records[index];
246 validate_authority_record(record)?;
247 let accepted = &records[..index];
248 let insertion =
249 accepted.partition_point(|existing| existing.range.start() < record.range.start());
250 let neighbours = insertion.saturating_sub(1)..(insertion + 1).min(accepted.len());
253 for existing in &accepted[neighbours] {
254 if ranges_overlap(existing.range, record.range) {
255 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
256 existing_start: existing.range.start(),
257 existing_end: existing.range.end(),
258 candidate_start: record.range.start(),
259 candidate_end: record.range.end(),
260 });
261 }
262 }
263 records[insertion..=index].rotate_right(1);
266 }
267 Ok(Self {
268 authorities: records,
269 })
270 }
271
272 pub fn validate_slot_authority(
274 &self,
275 slot: &MemoryManagerSlot,
276 expected_authority: &str,
277 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
278 let id = slot.id();
279 self.validate_id_authority(id, expected_authority)
280 }
281
282 pub fn validate_slot_authority_mode(
284 &self,
285 slot: &MemoryManagerSlot,
286 expected_authority: &str,
287 expected_mode: MemoryManagerRangeMode,
288 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
289 let id = slot.id();
290 self.validate_id_authority_mode(id, expected_authority, expected_mode)
291 }
292
293 pub fn validate_id_authority(
295 &self,
296 id: u8,
297 expected_authority: &str,
298 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
299 validate_diagnostic_string("expected_authority", expected_authority)?;
300 let record = self
301 .authority_for_id(id)?
302 .ok_or(MemoryManagerRangeAuthorityError::UnclaimedId { id })?;
303
304 if record.authority != expected_authority {
305 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
306 id,
307 expected_authority: expected_authority.to_string(),
308 actual_authority: record.authority.clone(),
309 });
310 }
311
312 Ok(record)
313 }
314
315 pub fn validate_id_authority_mode(
317 &self,
318 id: u8,
319 expected_authority: &str,
320 expected_mode: MemoryManagerRangeMode,
321 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
322 let record = self.validate_id_authority(id, expected_authority)?;
323 if record.mode != expected_mode {
324 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
325 id,
326 authority: record.authority.clone(),
327 expected_mode,
328 actual_mode: record.mode,
329 });
330 }
331 Ok(record)
332 }
333
334 pub fn authority_for_id(
336 &self,
337 id: u8,
338 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
339 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
340 let index = self
344 .authorities
345 .partition_point(|record| record.range.end() < id);
346 Ok(self
347 .authorities
348 .get(index)
349 .filter(|record| record.range.start() <= id))
350 }
351
352 #[must_use]
358 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
359 &self.authorities
360 }
361
362 pub fn validate_complete_coverage(
368 &self,
369 target: MemoryManagerIdRange,
370 ) -> Result<(), MemoryManagerRangeAuthorityError> {
371 if self.authorities.is_empty() {
372 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
373 start: target.start(),
374 end: target.end(),
375 });
376 }
377
378 for record in &self.authorities {
379 if record.range.start() < target.start() || record.range.end() > target.end() {
380 return Err(
381 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
382 start: record.range.start(),
383 end: record.range.end(),
384 target_start: target.start(),
385 target_end: target.end(),
386 },
387 );
388 }
389 }
390
391 let mut next_uncovered = target.start();
392 for record in &self.authorities {
393 if record.range.start() > next_uncovered {
394 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
395 start: next_uncovered,
396 end: record.range.start() - 1,
397 });
398 }
399 next_uncovered = record.range.end() + 1;
402 }
403
404 if next_uncovered <= target.end() {
405 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
406 start: next_uncovered,
407 end: target.end(),
408 });
409 }
410
411 Ok(())
412 }
413}
414
415fn validate_authority_record(
416 record: &MemoryManagerAuthorityRecord,
417) -> Result<(), MemoryManagerRangeAuthorityError> {
418 validate_diagnostic_string("authority", &record.authority)?;
419 if let Some(purpose) = &record.purpose {
420 validate_diagnostic_string("purpose", purpose)?;
421 }
422 Ok(())
423}
424
425#[non_exhaustive]
430#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
431pub enum MemoryManagerRangeAuthorityError {
432 #[error(transparent)]
434 Range(#[from] MemoryManagerRangeError),
435 #[error("{0}")]
437 Slot(#[from] MemoryManagerSlotError),
438 #[error(
440 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
441 )]
442 OverlappingRanges {
443 existing_start: u8,
445 existing_end: u8,
447 candidate_start: u8,
449 candidate_end: u8,
451 },
452 #[error("{field} {reason}")]
454 InvalidDiagnosticString {
455 field: &'static str,
457 reason: &'static str,
459 },
460 #[error("MemoryManager ID {id} is not covered by an authority range")]
462 UnclaimedId {
463 id: u8,
465 },
466 #[error(
468 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
469 )]
470 AuthorityMismatch {
471 id: u8,
473 expected_authority: String,
475 actual_authority: String,
477 },
478 #[error(
480 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
481 )]
482 ModeMismatch {
483 id: u8,
485 authority: String,
487 expected_mode: MemoryManagerRangeMode,
489 actual_mode: MemoryManagerRangeMode,
491 },
492 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
494 MissingCoverage {
495 start: u8,
497 end: u8,
499 },
500 #[error(
502 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
503 )]
504 RangeOutsideCoverageTarget {
505 start: u8,
507 end: u8,
509 target_start: u8,
511 target_end: u8,
513 },
514}
515
516const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
517 left.start() <= right.end() && right.start() <= left.end()
518}
519
520fn validate_diagnostic_string(
521 field: &'static str,
522 value: &str,
523) -> Result<(), MemoryManagerRangeAuthorityError> {
524 validate_diagnostic_text(value).map_err(|error| {
525 MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
526 field,
527 reason: error.reason(),
528 }
529 })
530}