1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use crate::*;
use crate::d3d::*;
use winapi::shared::winerror::*;
use winapi::um::d3dcommon::ID3DBlob;
use std::fmt::{self, Debug, Display, Formatter};
#[derive(Clone)]
pub struct MethodErrorBlob {
pub(crate) kind: ErrorKind,
pub(crate) method: Option<&'static str>,
pub(crate) errors: TextBlob,
}
impl MethodErrorBlob {
pub fn kind(&self) -> ErrorKind { self.kind }
pub(crate) fn new(method: &'static str, kind: impl Into<ErrorKind>) -> Self { Self { kind: kind.into(), method: Some(method), errors: Default::default() } }
pub(crate) unsafe fn check_blob(method: &'static str, hr: HRESULT, errors: *mut ID3DBlob) -> Result<(), Self> {
if !SUCCEEDED(hr) {
let errors = TextBlob::new(ReadOnlyBlob::from_raw_opt(errors));
Err(Self {
kind: ErrorKind(hr),
method: Some(method),
errors,
})
} else {
Ok(())
}
}
}
impl From<MethodErrorBlob> for ErrorKind { fn from(error: MethodErrorBlob ) -> ErrorKind { error.kind } }
impl From<MethodError> for MethodErrorBlob { fn from(error: MethodError) -> Self { Self { kind: error.kind(), method: Some(error.method()), errors: Default::default() } } }
impl std::error::Error for MethodErrorBlob {}
impl Debug for MethodErrorBlob {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
let mut ds = fmt.debug_struct("MethodErrorBlob");
ds.field("kind", &self.kind);
if let Some(method) = self.method.as_ref() {
ds.field("method", method);
}
if !self.errors.is_empty() {
ds.field("errors", &self.errors.to_utf8_lossy());
}
ds.finish()
}
}
impl Display for MethodErrorBlob {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
let method = self.method.unwrap_or("thindx method");
write!(fmt, "{} failed ({:?})", method, self.kind)?;
if !self.errors.is_empty() {
write!(fmt, "\n{}\n", self.errors.to_utf8_lossy())?;
}
Ok(())
}
}