// Licensed under the Apache License, Version 2.0 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option. // All files in the project carrying such notice may not be copied, modified, or distributed // except according to those terms.
//! Wrap several flavors of Windows error into a `Result`.
use std::error::Error; use std::fmt;
use winapi::shared::minwindef::DWORD; use winapi::shared::winerror::{
ERROR_SUCCESS, FACILITY_WIN32, HRESULT, HRESULT_FROM_WIN32, SUCCEEDED, S_OK,
}; use winapi::um::errhandlingapi::GetLastError;
/// An error code, optionally with information about the failing call. #[derive(Clone, Debug, Eq, PartialEq)] pubstruct ErrorAndSource<T: ErrorCode> {
code: T,
function: Option<&'static str>,
file_line: Option<FileLine>,
}
/// A wrapper for an error code. pubtrait ErrorCode:
Copy + fmt::Debug + Eq + PartialEq + fmt::Display + Send + Sync + 'static
{ type InnerT: Copy + Eq + PartialEq;
fn get(&self) -> Self::InnerT;
}
impl<T> ErrorAndSource<T> where
T: ErrorCode,
{ /// Get the underlying error code. pubfn code(&self) -> T::InnerT { self.code.get()
}
/// Add the name of the failing function to the error. pubfn function(self, function: &'static str) -> Self { Self {
function: Some(function),
..self
}
}
/// Get the name of the failing function, if known. pubfn get_function(&self) -> Option<&'static str> { self.function
}
/// Add the source file name and line number of the call to the error. pubfn file_line(self, file: &'static str, line: u32) -> Self { Self {
file_line: Some(FileLine(file, line)),
..self
}
}
/// Get the source file name and line number of the failing call. pubfn get_file_line(&self) -> &Option<FileLine> {
&self.file_line
}
}
/// Get the result code portion of the `HRESULT` pubfn extract_code(&self) -> HRESULT { // from winerror.h HRESULT_CODE macro self.code.0 & 0xFFFF
}
/// Get the facility portion of the `HRESULT` pubfn extract_facility(&self) -> HRESULT { // from winerror.h HRESULT_FACILITY macro
(self.code.0 >> 16) & 0x1fff
}
/// If the `HResult` corresponds to a Win32 error, convert. /// /// Returns the original `HResult` as an error on failure. pubfn try_into_win32_err(self) -> Result<Win32Error, Self> { let code = ifself.code() == S_OK { // Special case, facility is not set.
ERROR_SUCCESS
} elseifself.extract_facility() == FACILITY_WIN32 { self.extract_code() as DWORD
} else { return Err(self);
};
/// Convert an `HRESULT` into a `Result`. pubfn succeeded_or_err(hr: HRESULT) -> Result<HRESULT, HResult> { if !SUCCEEDED(hr) {
Err(HResult::new(hr))
} else {
Ok(hr)
}
}
/// Call a function that returns an `HRESULT`, convert to a `Result`. /// /// The error will be augmented with the name of the function and the file and line number of /// the macro usage. /// /// # Example /// ```no_run /// # extern crate winapi; /// # use std::ptr; /// # use winapi::um::combaseapi::CoUninitialize; /// # use winapi::um::objbase::CoInitialize; /// # use comedy::{check_succeeded, HResult}; /// # /// fn coinit() -> Result<(), HResult> { /// unsafe { /// check_succeeded!(CoInitialize(ptr::null_mut()))?; /// /// CoUninitialize(); /// } /// Ok(()) /// } /// ``` #[macro_export]
macro_rules! check_succeeded {
($f:ident ( $($arg:expr),* )) => {
{ use $crate::error::ResultExt;
$crate::error::succeeded_or_err($f($($arg),*))
.function(stringify!($f))
.file_line(file!(), line!())
}
};
// support for trailing comma in argument list
($f:ident ( $($arg:expr),+ , )) => {
$crate::check_succeeded!($f($($arg),+))
};
}
/// Convert an integer return value into a `Result`, using `GetLastError()` if zero. pubfn true_or_last_err<T>(rv: T) -> Result<T, Win32Error> where
T: Eq,
T: From<bool>,
{ if rv == T::from(false) {
Err(Win32Error::get_last_error())
} else {
Ok(rv)
}
}
/// Call a function that returns a integer, convert to a `Result`, using `GetLastError()` if zero. /// /// The error will be augmented with the name of the function and the file and line number of /// the macro usage. /// /// # Example /// ```no_run /// # extern crate winapi; /// # use winapi::shared::minwindef::BOOL; /// # use winapi::um::fileapi::FlushFileBuffers; /// # use winapi::um::winnt::HANDLE; /// # use comedy::{check_true, Win32Error}; /// # /// fn flush(file: HANDLE) -> Result<(), Win32Error> { /// unsafe { /// check_true!(FlushFileBuffers(file))?; /// } /// Ok(()) /// } /// ``` #[macro_export]
macro_rules! check_true {
($f:ident ( $($arg:expr),* )) => {
{ use $crate::error::ResultExt;
$crate::error::true_or_last_err($f($($arg),*))
.function(stringify!($f))
.file_line(file!(), line!())
}
};
// support for trailing comma in argument list
($f:ident ( $($arg:expr),+ , )) => {
$crate::check_true!($f($($arg),+))
};
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-06-17)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.