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, Deserialize, Eq, PartialEq, Serialize)]
13#[serde(deny_unknown_fields)]
14pub struct MemoryManagerIdRange {
15 pub(crate) start: u8,
16 pub(crate) end: u8,
17}
18
19impl MemoryManagerIdRange {
20 pub const fn new(start: u8, end: u8) -> Result<Self, MemoryManagerRangeError> {
22 if start > end {
23 return Err(MemoryManagerRangeError::InvalidRange { start, end });
24 }
25 if end == MEMORY_MANAGER_INVALID_ID {
27 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: end });
28 }
29 Ok(Self { start, end })
30 }
31
32 #[must_use]
34 pub const fn all_usable() -> Self {
35 Self {
36 start: MEMORY_MANAGER_MIN_ID,
37 end: MEMORY_MANAGER_MAX_ID,
38 }
39 }
40
41 #[must_use]
43 pub const fn contains(&self, id: u8) -> bool {
44 id >= self.start && id <= self.end
45 }
46
47 pub const fn validate(&self) -> Result<(), MemoryManagerRangeError> {
49 match Self::new(self.start, self.end) {
50 Ok(_) => Ok(()),
51 Err(err) => Err(err),
52 }
53 }
54
55 #[must_use]
57 pub const fn start(&self) -> u8 {
58 self.start
59 }
60
61 #[must_use]
63 pub const fn end(&self) -> u8 {
64 self.end
65 }
66}
67
68#[non_exhaustive]
73#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
74pub enum MemoryManagerRangeError {
75 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
77 InvalidRange {
78 start: u8,
80 end: u8,
82 },
83 #[error("MemoryManager ID {id} is not a usable allocation slot")]
85 InvalidMemoryManagerId {
86 id: u8,
88 },
89}
90
91#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
103pub enum MemoryManagerRangeMode {
104 Reserved,
108 Allowed,
112}
113
114#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
121#[serde(deny_unknown_fields)]
122pub struct MemoryManagerAuthorityRecord {
123 pub(crate) range: MemoryManagerIdRange,
125 pub(crate) authority: String,
127 pub(crate) mode: MemoryManagerRangeMode,
129 #[serde(deserialize_with = "crate::cbor::deserialize_present_option")]
131 pub(crate) purpose: Option<String>,
132}
133
134impl MemoryManagerAuthorityRecord {
135 pub fn new(
137 range: MemoryManagerIdRange,
138 authority: impl Into<String>,
139 mode: MemoryManagerRangeMode,
140 purpose: Option<String>,
141 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
142 let record = Self {
143 range,
144 authority: authority.into(),
145 mode,
146 purpose,
147 };
148 validate_authority_record(&record)?;
149 Ok(record)
150 }
151
152 #[must_use]
154 pub const fn range(&self) -> MemoryManagerIdRange {
155 self.range
156 }
157
158 #[must_use]
160 pub fn authority(&self) -> &str {
161 &self.authority
162 }
163
164 #[must_use]
166 pub const fn mode(&self) -> MemoryManagerRangeMode {
167 self.mode
168 }
169
170 #[must_use]
172 pub fn purpose(&self) -> Option<&str> {
173 self.purpose.as_deref()
174 }
175
176 pub fn validate(&self) -> Result<(), MemoryManagerRangeAuthorityError> {
178 validate_authority_record(self)
179 }
180}
181
182#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
201pub struct MemoryManagerRangeAuthority {
202 authorities: Vec<MemoryManagerAuthorityRecord>,
203}
204
205#[derive(Deserialize)]
206#[serde(deny_unknown_fields)]
207struct MemoryManagerRangeAuthorityDto {
208 authorities: Vec<MemoryManagerAuthorityRecord>,
209}
210
211impl<'de> Deserialize<'de> for MemoryManagerRangeAuthority {
212 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
213 let dto = MemoryManagerRangeAuthorityDto::deserialize(deserializer)?;
214 Self::from_records(dto.authorities).map_err(D::Error::custom)
215 }
216}
217
218impl MemoryManagerRangeAuthority {
219 #[must_use]
221 pub const fn new() -> Self {
222 Self {
223 authorities: Vec::new(),
224 }
225 }
226
227 pub fn from_records(
233 mut records: Vec<MemoryManagerAuthorityRecord>,
234 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
235 for index in 0..records.len() {
236 let record = &records[index];
237 validate_authority_record(record)?;
238 let accepted = &records[..index];
239 let insertion =
240 accepted.partition_point(|existing| existing.range.start() < record.range.start());
241 let neighbours = insertion.saturating_sub(1)..(insertion + 1).min(accepted.len());
244 for existing in &accepted[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 records[insertion..=index].rotate_right(1);
257 }
258 Ok(Self {
259 authorities: records,
260 })
261 }
262
263 pub fn validate_slot_authority(
265 &self,
266 slot: &MemoryManagerSlot,
267 expected_authority: &str,
268 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
269 let id = slot.id();
270 self.validate_id_authority(id, expected_authority)
271 }
272
273 pub fn validate_slot_authority_mode(
275 &self,
276 slot: &MemoryManagerSlot,
277 expected_authority: &str,
278 expected_mode: MemoryManagerRangeMode,
279 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
280 let id = slot.id();
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
292 .authority_for_id(id)?
293 .ok_or(MemoryManagerRangeAuthorityError::UnclaimedId { 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 let index = self
335 .authorities
336 .partition_point(|record| record.range.end() < id);
337 Ok(self
338 .authorities
339 .get(index)
340 .filter(|record| record.range.start() <= id))
341 }
342
343 #[must_use]
349 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
350 &self.authorities
351 }
352
353 pub fn validate_complete_coverage(
359 &self,
360 target: MemoryManagerIdRange,
361 ) -> Result<(), MemoryManagerRangeAuthorityError> {
362 if self.authorities.is_empty() {
363 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
364 start: target.start(),
365 end: target.end(),
366 });
367 }
368
369 for record in &self.authorities {
370 if record.range.start() < target.start() || record.range.end() > target.end() {
371 return Err(
372 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
373 start: record.range.start(),
374 end: record.range.end(),
375 target_start: target.start(),
376 target_end: target.end(),
377 },
378 );
379 }
380 }
381
382 let mut next_uncovered = target.start();
383 for record in &self.authorities {
384 if record.range.start() > next_uncovered {
385 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
386 start: next_uncovered,
387 end: record.range.start() - 1,
388 });
389 }
390 next_uncovered = record.range.end() + 1;
393 }
394
395 if next_uncovered <= target.end() {
396 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
397 start: next_uncovered,
398 end: target.end(),
399 });
400 }
401
402 Ok(())
403 }
404}
405
406fn validate_authority_record(
407 record: &MemoryManagerAuthorityRecord,
408) -> Result<(), MemoryManagerRangeAuthorityError> {
409 record.range.validate()?;
410 validate_diagnostic_string("authority", &record.authority)?;
411 if let Some(purpose) = &record.purpose {
412 validate_diagnostic_string("purpose", purpose)?;
413 }
414 Ok(())
415}
416
417#[non_exhaustive]
422#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
423pub enum MemoryManagerRangeAuthorityError {
424 #[error(transparent)]
426 Range(#[from] MemoryManagerRangeError),
427 #[error("{0}")]
429 Slot(#[from] MemoryManagerSlotError),
430 #[error(
432 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
433 )]
434 OverlappingRanges {
435 existing_start: u8,
437 existing_end: u8,
439 candidate_start: u8,
441 candidate_end: u8,
443 },
444 #[error("{field} {reason}")]
446 InvalidDiagnosticString {
447 field: &'static str,
449 reason: &'static str,
451 },
452 #[error("MemoryManager ID {id} is not covered by an authority range")]
454 UnclaimedId {
455 id: u8,
457 },
458 #[error(
460 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
461 )]
462 AuthorityMismatch {
463 id: u8,
465 expected_authority: String,
467 actual_authority: String,
469 },
470 #[error(
472 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
473 )]
474 ModeMismatch {
475 id: u8,
477 authority: String,
479 expected_mode: MemoryManagerRangeMode,
481 actual_mode: MemoryManagerRangeMode,
483 },
484 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
486 MissingCoverage {
487 start: u8,
489 end: u8,
491 },
492 #[error(
494 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
495 )]
496 RangeOutsideCoverageTarget {
497 start: u8,
499 end: u8,
501 target_start: u8,
503 target_end: u8,
505 },
506}
507
508const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
509 left.start() <= right.end() && right.start() <= left.end()
510}
511
512fn validate_diagnostic_string(
513 field: &'static str,
514 value: &str,
515) -> Result<(), MemoryManagerRangeAuthorityError> {
516 validate_diagnostic_text(value).map_err(|error| {
517 MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
518 field,
519 reason: error.reason(),
520 }
521 })
522}