vmotherboard/chipset/builder/
errors.rs1use crate::chipset::PciConflict;
5use crate::chipset::io_ranges::IoRangeConflict;
6use std::fmt::Debug;
7use thiserror::Error;
8
9#[derive(Debug, Error)]
13#[expect(clippy::enum_variant_names)] pub enum ChipsetBuilderError {
15 #[error("static mmio intercept region conflict: {0}")]
17 MmioConflict(IoRangeConflict<u64>),
18 #[error("static pio intercept region conflict: {0}")]
20 PioConflict(IoRangeConflict<u16>),
21 #[error("static pci conflict: {0}")]
23 PciConflict(PciConflict),
24}
25
26#[derive(Debug, Error)]
27#[error("detected one or more errors during vmotherboard init:")]
28pub struct FinalChipsetBuilderError(#[source] pub ErrorList);
29
30#[derive(Debug)]
31pub struct ErrorList {
32 err: ChipsetBuilderError,
33 next: Option<Box<Self>>,
34}
35
36impl std::fmt::Display for ErrorList {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 write!(f, "{}", self.err)
39 }
40}
41
42impl ErrorList {
43 fn new(err: ChipsetBuilderError) -> Self {
44 Self { err, next: None }
45 }
46
47 fn chain(self: Box<Self>, err: ChipsetBuilderError) -> Self {
48 Self {
49 err,
50 next: Some(self),
51 }
52 }
53}
54
55pub trait ErrorListExt {
56 fn append(&mut self, err: ChipsetBuilderError);
57}
58
59impl ErrorListExt for Option<ErrorList> {
60 fn append(&mut self, err: ChipsetBuilderError) {
61 *self = Some(match self.take() {
62 Some(existing) => Box::new(existing).chain(err),
63 None => ErrorList::new(err),
64 })
65 }
66}
67
68impl std::error::Error for ErrorList {
69 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
70 self.next.as_ref().map(|x| x as _)
71 }
72}