Skip to main content

singe_npp/
error.rs

1#![allow(deprecated)]
2
3use std::{ffi::NulError, fmt};
4
5use singe_cuda::error::Error as CudaError;
6use singe_npp_sys as sys;
7use thiserror::Error;
8
9use crate::types::Size;
10
11macro_rules! npp_statuses {
12    ($($variant:ident => $raw:ident,)*) => {
13        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14        #[non_exhaustive]
15        pub enum Status {
16            $($variant,)*
17            Unknown(i32),
18        }
19
20        impl Status {
21            pub fn description(self) -> String {
22                match sys::NppStatus::try_from(self.raw()) {
23                    Ok(status) => format!("{status:?}")
24                        .trim_start_matches("NPP_")
25                        .replace('_', " ")
26                        .to_ascii_lowercase(),
27                    Err(_) => String::from("unknown npp error"),
28                }
29            }
30
31            pub const fn raw(self) -> i32 {
32                match self {
33                    $(Self::$variant => sys::NppStatus::$raw as _,)*
34                    Self::Unknown(code) => code,
35                }
36            }
37        }
38
39        impl TryFrom<i32> for Status {
40            type Error = i32;
41
42            fn try_from(code: i32) -> std::result::Result<Self, i32> {
43                match code {
44                    $(code if code == sys::NppStatus::$raw as i32 => Ok(Self::$variant),)*
45                    code => Err(code),
46                }
47            }
48        }
49
50        impl From<sys::NppStatus> for Status {
51            fn from(status: sys::NppStatus) -> Self {
52                Self::try_from(status as i32).unwrap_or_else(Self::Unknown)
53            }
54        }
55
56        impl TryFrom<Status> for sys::NppStatus {
57            type Error = Status;
58
59            fn try_from(status: Status) -> std::result::Result<Self, Status> {
60                match status {
61                    $(Status::$variant => Ok(Self::$raw),)*
62                    Status::Unknown(_) => Err(status),
63                }
64            }
65        }
66
67        impl fmt::Display for Status {
68            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69                match self {
70                    $(Self::$variant => f.write_str(stringify!($raw)),)*
71                    Self::Unknown(code) => write!(f, "UNKNOWN_NPP_STATUS({code})"),
72                }
73            }
74        }
75    };
76}
77
78npp_statuses! {
79    Success => NPP_SUCCESS,
80    NotSupportedModeError => NPP_NOT_SUPPORTED_MODE_ERROR,
81    LibraryVersionMismatchError => NPP_LIBRARY_VERSION_MISMATCH_ERROR,
82    InvalidHostPointerError => NPP_INVALID_HOST_POINTER_ERROR,
83    InvalidDevicePointerError => NPP_INVALID_DEVICE_POINTER_ERROR,
84    LutPaletteBitsizeError => NPP_LUT_PALETTE_BITSIZE_ERROR,
85    ZeroCrossingModeNotSupportedError => NPP_ZC_MODE_NOT_SUPPORTED_ERROR,
86    NotSufficientComputeCapability => NPP_NOT_SUFFICIENT_COMPUTE_CAPABILITY,
87    TextureBindError => NPP_TEXTURE_BIND_ERROR,
88    WrongIntersectionRoiError => NPP_WRONG_INTERSECTION_ROI_ERROR,
89    HaarClassifierPixelMatchError => NPP_HAAR_CLASSIFIER_PIXEL_MATCH_ERROR,
90    MemfreeError => NPP_MEMFREE_ERROR,
91    MemsetError => NPP_MEMSET_ERROR,
92    MemcpyError => NPP_MEMCPY_ERROR,
93    AlignmentError => NPP_ALIGNMENT_ERROR,
94    CudaKernelExecutionError => NPP_CUDA_KERNEL_EXECUTION_ERROR,
95    StreamContextError => NPP_STREAM_CTX_ERROR,
96    RoundModeNotSupportedError => NPP_ROUND_MODE_NOT_SUPPORTED_ERROR,
97    QualityIndexError => NPP_QUALITY_INDEX_ERROR,
98    ResizeNoOperationError => NPP_RESIZE_NO_OPERATION_ERROR,
99    OverflowError => NPP_OVERFLOW_ERROR,
100    NotEvenStepError => NPP_NOT_EVEN_STEP_ERROR,
101    HistogramNumberOfLevelsError => NPP_HISTOGRAM_NUMBER_OF_LEVELS_ERROR,
102    LutNumberOfLevelsError => NPP_LUT_NUMBER_OF_LEVELS_ERROR,
103    CorruptedDataError => NPP_CORRUPTED_DATA_ERROR,
104    ChannelOrderError => NPP_CHANNEL_ORDER_ERROR,
105    ZeroMaskValueError => NPP_ZERO_MASK_VALUE_ERROR,
106    QuadrangleError => NPP_QUADRANGLE_ERROR,
107    RectangleError => NPP_RECTANGLE_ERROR,
108    CoefficientError => NPP_COEFFICIENT_ERROR,
109    NumberOfChannelsError => NPP_NUMBER_OF_CHANNELS_ERROR,
110    ChannelOfInterestError => NPP_COI_ERROR,
111    DivisorError => NPP_DIVISOR_ERROR,
112    ChannelError => NPP_CHANNEL_ERROR,
113    StrideError => NPP_STRIDE_ERROR,
114    ResizeFactorError => NPP_RESIZE_FACTOR_ERROR,
115    InterpolationError => NPP_INTERPOLATION_ERROR,
116    MirrorFlipError => NPP_MIRROR_FLIP_ERROR,
117    BadArgumentError => NPP_BAD_ARGUMENT_ERROR,
118    NoMemoryError => NPP_NO_MEMORY_ERROR,
119    NotImplementedError => NPP_NOT_IMPLEMENTED_ERROR,
120    Error => NPP_ERROR,
121    ErrorReserved => NPP_ERROR_RESERVED,
122    NullPointerError => NPP_NULL_POINTER_ERROR,
123    RangeError => NPP_RANGE_ERROR,
124    SizeError => NPP_SIZE_ERROR,
125    StepError => NPP_STEP_ERROR,
126    AnchorError => NPP_ANCHOR_ERROR,
127    MaskSizeError => NPP_MASK_SIZE_ERROR,
128    Moment00ZeroError => NPP_MOMENT_00_ZERO_ERROR,
129    ThresholdNegativeLevelError => NPP_THRESHOLD_NEGATIVE_LEVEL_ERROR,
130    ThresholdError => NPP_THRESHOLD_ERROR,
131    ContextMatchError => NPP_CONTEXT_MATCH_ERROR,
132    FftFlagError => NPP_FFT_FLAG_ERROR,
133    FftOrderError => NPP_FFT_ORDER_ERROR,
134    ScaleRangeError => NPP_SCALE_RANGE_ERROR,
135    DataTypeError => NPP_DATA_TYPE_ERROR,
136    OutOfRangeError => NPP_OUT_OFF_RANGE_ERROR,
137    DivideByZeroError => NPP_DIVIDE_BY_ZERO_ERROR,
138    MemoryAllocationErr => NPP_MEMORY_ALLOCATION_ERR,
139    NoOperationWarning => NPP_NO_OPERATION_WARNING,
140    DivideByZeroWarning => NPP_DIVIDE_BY_ZERO_WARNING,
141    AffineQuadIncorrectWarning => NPP_AFFINE_QUAD_INCORRECT_WARNING,
142    WrongIntersectionRoiWarning => NPP_WRONG_INTERSECTION_ROI_WARNING,
143    WrongIntersectionQuadWarning => NPP_WRONG_INTERSECTION_QUAD_WARNING,
144    DoubleSizeWarning => NPP_DOUBLE_SIZE_WARNING,
145    MisalignedDstRoiWarning => NPP_MISALIGNED_DST_ROI_WARNING,
146}
147
148#[derive(Error, Debug)]
149#[non_exhaustive]
150pub enum Error {
151    #[error("cuda error: {0}")]
152    Cuda(#[from] CudaError),
153
154    #[error("npp error ({code}): {message}")]
155    Npp { code: Status, message: String },
156
157    #[error("string contains interior nul byte")]
158    InteriorNul,
159
160    #[error("unexpected null handle")]
161    NullHandle,
162
163    #[error("`{name}` is out of range")]
164    OutOfRange { name: String },
165
166    #[error("`{name}` must be greater than 0")]
167    ValueNotPositive { name: String },
168
169    #[error("`{name}` length mismatch (expected {expected}, got {actual})")]
170    LengthMismatch {
171        name: String,
172        expected: usize,
173        actual: usize,
174    },
175
176    #[error("`{name}` size mismatch (expected {expected}, got {actual})")]
177    SizeMismatch {
178        name: String,
179        expected: Size,
180        actual: Size,
181    },
182
183    #[error("stream belongs to a different cuda context")]
184    StreamContextMismatch,
185
186    #[error("unsupported operation: `{name}`")]
187    UnsupportedOperation { name: String },
188
189    #[error("missing required parameter: `{name}`")]
190    MissingParameter { name: String },
191}
192
193pub type Result<T> = std::result::Result<T, Error>;
194
195impl From<sys::NppStatus> for Error {
196    fn from(status: sys::NppStatus) -> Self {
197        let code = Status::from(status);
198        Self::from(code)
199    }
200}
201
202impl From<Status> for Error {
203    fn from(code: Status) -> Self {
204        Self::Npp {
205            code,
206            message: code.description(),
207        }
208    }
209}
210
211impl From<NulError> for Error {
212    fn from(_: NulError) -> Self {
213        Self::InteriorNul
214    }
215}
216
217#[macro_export]
218macro_rules! try_ffi {
219    ($expr:expr) => {{
220        let status = { $expr };
221        if status != singe_npp_sys::NppStatus::NPP_SUCCESS {
222            Err($crate::error::Error::from(status))
223        } else {
224            Ok(())
225        }
226    }};
227}