1use crate::handle::{Handle, Id};
2use crate::reflect::DecorationValue;
3use spirv_cross_sys as sys;
4use spirv_cross_sys::{spvc_context_s, spvc_result};
5use std::ffi::CStr;
6use std::ptr::NonNull;
7
8pub type Result<T> = std::result::Result<T, SpirvCrossError>;
10
11#[derive(Debug, thiserror::Error)]
13pub enum SpirvCrossError {
14 #[error("The SPIR-V is invalid: {0}.")]
15 InvalidSpirv(String),
17 #[error("The SPIR-V operation is unsupported: {0}.")]
18 UnsupportedSpirv(String),
20 #[error("Allocation failure: {0}.")]
21 OutOfMemory(String),
23 #[error("The argument is invalid: {0}.")]
24 InvalidArgument(String),
26 #[error("The tag of the handle does not match the compiler instance: {0:?}")]
27 InvalidHandle(Handle<Box<dyn Id>>),
29 #[error("The operation is invalid: {0:?}")]
30 InvalidOperation(String),
32 #[error("The decoration value is invalid for the given decoration: {0:?} = {1}")]
33 InvalidDecorationOutput(spirv::Decoration, u32),
38 #[error("The decoration value is invalid for the given decoration: {0:?} = {1:?}")]
39 InvalidDecorationInput(spirv::Decoration, DecorationValue<'static>),
41 #[error("The string is invalid: {0:?}")]
42 InvalidString(String),
46 #[error("The provided index was out of bounds for the resource: ({row}, {column}).")]
47 IndexOutOfBounds {
52 row: u32,
54 column: u32,
56 },
57 #[error("An unexpected enum value was found.")]
58 InvalidEnum,
60}
61
62pub(crate) trait ToContextError {
63 fn ok(self, context: impl ContextRooted) -> Result<()>;
64}
65
66fn get_last_error(context: NonNull<spvc_context_s>) -> String {
67 let cstr = unsafe { CStr::from_ptr(sys::spvc_context_get_last_error_string(context.as_ptr())) };
68
69 cstr.to_string_lossy().to_string()
70}
71
72impl ToContextError for spvc_result {
73 fn ok(self, context: impl ContextRooted) -> Result<()> {
74 match self {
75 spvc_result::SPVC_SUCCESS => Ok(()),
76 spvc_result::SPVC_ERROR_INVALID_SPIRV => Err(SpirvCrossError::InvalidSpirv(
77 get_last_error(context.context()),
78 )),
79 spvc_result::SPVC_ERROR_UNSUPPORTED_SPIRV => Err(SpirvCrossError::UnsupportedSpirv(
80 get_last_error(context.context()),
81 )),
82 spvc_result::SPVC_ERROR_OUT_OF_MEMORY => Err(SpirvCrossError::OutOfMemory(
83 get_last_error(context.context()),
84 )),
85 spvc_result::SPVC_ERROR_INVALID_ARGUMENT => Err(SpirvCrossError::InvalidArgument(
86 get_last_error(context.context()),
87 )),
88 }
89 }
90}
91
92pub(crate) use crate::sealed::ContextRooted;