pci_info/error/
pci_info_enumeration_error.rs

1use crate::PciBusNumber;
2use crate::PciInfoError;
3use crate::PciInfoErrorString;
4use crate::PciLocation;
5use std::error::Error;
6use std::fmt::Debug;
7use std::fmt::Display;
8
9/// The location at which an enumeration error occurred
10#[derive(Copy, Clone, Debug)]
11pub enum PciDeviceEnumerationErrorLocation {
12    /// The PCI location where the error occurred is unknown
13    None,
14    /// The error occurred at the specified bus
15    Bus(PciBusNumber),
16    /// The error occurred at the specified PCI location
17    Device(PciLocation),
18}
19
20/// The impact of an enumeration error
21#[derive(Copy, Clone, Debug)]
22pub enum PciDeviceEnumerationErrorImpact {
23    /// The error might have caused an entire PCI bus to be missing
24    /// from the enumeration
25    Bus,
26    /// The error might have caused an entire PCI device to be missing
27    /// from the enumeration
28    Device,
29    /// The error might have caused some properties on a PCI device to be
30    /// missing from the enumeration. When these are generated it is
31    /// usually not possible to backtrack to which device caused the
32    /// properties to be missing. Missing properties will be reported as if
33    /// unsupported by the enumerator.
34    DeviceProperties,
35}
36
37/// A non-fatal error that impacted the enumeration of one or more devices.
38#[derive(Debug)]
39pub struct PciDeviceEnumerationError {
40    impact: PciDeviceEnumerationErrorImpact,
41    error: PciInfoError,
42    location: PciDeviceEnumerationErrorLocation,
43}
44
45impl Display for PciDeviceEnumerationError {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        let at: PciInfoErrorString = match self.location {
48            PciDeviceEnumerationErrorLocation::None => "".into(),
49            PciDeviceEnumerationErrorLocation::Bus(l) => format!(" at {l:?} ").into(),
50            PciDeviceEnumerationErrorLocation::Device(l) => format!(" at {l:?} ").into(),
51        };
52
53        match self.impact {
54            PciDeviceEnumerationErrorImpact::Bus => {
55                write!(f, "pci bus enumeration error{}: {}", at, self.error)
56            }
57            PciDeviceEnumerationErrorImpact::Device => {
58                write!(f, "pci device enumeration error{}: {}", at, self.error)
59            }
60            PciDeviceEnumerationErrorImpact::DeviceProperties => write!(
61                f,
62                "an error might have caused properties to be missing from a pci device{}: {}",
63                at, self.error
64            ),
65        }
66    }
67}
68
69impl PciDeviceEnumerationError {
70    #[allow(dead_code)]
71    pub(crate) fn new(impact: PciDeviceEnumerationErrorImpact, error: PciInfoError) -> Self {
72        Self {
73            impact,
74            error,
75            location: PciDeviceEnumerationErrorLocation::None,
76        }
77    }
78
79    #[allow(dead_code)]
80    pub(crate) fn new_at_bus(
81        bus: PciBusNumber,
82        impact: PciDeviceEnumerationErrorImpact,
83        error: PciInfoError,
84    ) -> Self {
85        Self {
86            impact,
87            error,
88            location: PciDeviceEnumerationErrorLocation::Bus(bus),
89        }
90    }
91
92    #[allow(dead_code)]
93    pub(crate) fn new_at_device(
94        loc: PciLocation,
95        impact: PciDeviceEnumerationErrorImpact,
96        error: PciInfoError,
97    ) -> Self {
98        Self {
99            impact,
100            error,
101            location: PciDeviceEnumerationErrorLocation::Device(loc),
102        }
103    }
104
105    /// The impact of this error
106    pub fn impact(&self) -> PciDeviceEnumerationErrorImpact {
107        self.impact
108    }
109
110    /// The underlying error that caused this issue (same as
111    /// `Error::source()` but more strongly typed)
112    pub fn error(&self) -> &PciInfoError {
113        &self.error
114    }
115
116    /// The location where the issue occurred, if available.
117    /// Note that errors often occur before a location can be
118    /// determined.
119    pub fn location(&self) -> PciDeviceEnumerationErrorLocation {
120        self.location
121    }
122}
123
124impl Error for PciDeviceEnumerationError {
125    fn source(&self) -> Option<&(dyn Error + 'static)> {
126        Some(self.error())
127    }
128}