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
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#![deny(rustdoc, missing_docs, warnings, clippy::pedantic)]
#![allow(
    missing_doc_code_examples,
    clippy::missing_errors_doc,
    clippy::inline_always
)]
#![doc(test(attr(deny(warnings))))]
//! Reimplementation of the private `std::sys::cvt()`, but as a trait method.
//!
//! ## Example
//! ```
//! use cvt_trait::prelude::*;
//! # use std::os::raw::c_int;
//! # #[cfg(unix)]
//! # unsafe fn os_api() -> c_int {
//! #     0
//! # }
//! # #[cfg(windows)]
//! # unsafe fn os_api() -> c_int {
//! #    1
//! # }
//! unsafe { os_api() }.cvt().expect("OS API failed");
//! ```

use sealed::Sealed;
use std::io;

mod unix;
mod windows;

mod sealed {
    pub trait Sealed {
        type Output;
    }
}

/// The main trait in this crate.
///
/// See also the [example in the crate-level documentation](crate#example).
pub trait Cvt: Sealed {
    /// Converts the "numeric" result returned by the native operating system's C
    /// API to [`io::Result`].
    fn cvt(self) -> io::Result<Self::Output>;
}

/// The trait for [NT APIs](https://docs.microsoft.com/en-us/sysinternals/resources/inside-native-applications#introduction).
///
/// ## Example (Windows-only)
#[cfg_attr(windows, doc = "```")]
#[cfg_attr(not(windows), doc = "```compile_fail")]
/// use cvt_trait::prelude::*;
/// # use std::os::raw::c_int;
/// # #[allow(non_snake_case)]
/// # unsafe fn NtDoSomething() -> c_int {
/// #     0
/// # }
/// unsafe { NtDoSomething() }.nt_cvt().expect("NT API failed");
/// ```
pub trait NtCvt: Sealed {
    /// Converts the "numeric" result returned by the NT API to [`io::Result`].
    fn nt_cvt(self) -> io::Result<Self::Output>;
}

/// The trait for [Winsock 2 APIs](https://docs.microsoft.com/windows/win32/winsock/windows-sockets-start-page-2).
///
/// ## Example (Windows-only)
#[cfg_attr(windows, doc = "```")]
#[cfg_attr(not(windows), doc = "```compile_fail")]
/// use cvt_trait::prelude::*;
/// # use std::os::raw::c_int;
/// # #[allow(non_snake_case)]
/// # unsafe fn WSADoSomething() -> c_int {
/// #     0
/// # }
/// unsafe { WSADoSomething() }.wsa_cvt().expect("Winsock API failed");
/// ```
pub trait WsaCvt: Sealed {
    /// Converts the "numeric" result returned by the Winsock 2 API to
    /// [`io::Result`].
    fn wsa_cvt(self) -> io::Result<Self::Output>;
}

/// Deprecated. Use [`WsaCvt`] instead.
///
/// ## Example
#[cfg_attr(windows, doc = "```")]
#[cfg_attr(not(windows), doc = "```compile_fail")]
/// #![allow(deprecated)]
/// use cvt_trait::WSACvt;
/// # use std::os::raw::c_int;
/// # #[allow(non_snake_case)]
/// # unsafe fn WSADoSomething() -> c_int {
/// #     0
/// # }
/// unsafe { WSADoSomething() }.wsa_cvt().expect("Winsock API failed");
/// ```
#[deprecated(since = "1.1.0", note = "this trait has been renamed to `WsaCvt`")]
#[allow(
    unknown_lints,
    renamed_and_removed_lints,
    clippy::unknown_clippy_lints,
    clippy::upper_case_acronyms
)]
pub trait WSACvt: Sealed {
    /// Deprecated. Use [`WsaCvt::wsa_cvt`] instead.
    #[deprecated(
        since = "1.1.0",
        note = "the `WSACvt` trait has been renamed to `WsaCvt`"
    )]
    fn wsa_cvt(self) -> io::Result<Self::Output>;
}

#[allow(deprecated)]
impl<T: WsaCvt> WSACvt for T {
    fn wsa_cvt(self) -> io::Result<Self::Output> {
        WsaCvt::wsa_cvt(self)
    }
}

/// The prelude.
/// ```
/// # #[allow(unused_imports)]
/// use cvt_trait::prelude::*;
/// ```
pub mod prelude {
    pub use crate::{Cvt as _, NtCvt as _, WsaCvt as _};
}