diff options
Diffstat (limited to 'autogen/errors.rs')
-rw-r--r-- | autogen/errors.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/autogen/errors.rs b/autogen/errors.rs new file mode 100644 index 0000000..920b9b3 --- /dev/null +++ b/autogen/errors.rs @@ -0,0 +1,84 @@ +// Copyright (c) 2022 The Vulkano developers +// Licensed under the Apache License, Version 2.0 +// <LICENSE-APACHE or +// https://www.apache.org/licenses/LICENSE-2.0> or the MIT +// license <LICENSE-MIT or https://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. + +use super::{write_file, VkRegistryData}; +use heck::ToUpperCamelCase; +use proc_macro2::{Ident, TokenStream}; +use quote::{format_ident, quote}; + +pub fn write(vk_data: &VkRegistryData) { + write_file( + "errors.rs", + format!( + "vk.xml header version {}.{}.{}", + vk_data.header_version.0, vk_data.header_version.1, vk_data.header_version.2 + ), + errors_output(&errors_members(&vk_data.errors)), + ); +} + +#[derive(Clone, Debug)] +struct ErrorsMember { + name: Ident, + ffi_name: Ident, +} + +fn errors_output(members: &[ErrorsMember]) -> TokenStream { + let enum_items = members.iter().map(|ErrorsMember { name, .. }| { + quote! { #name, } + }); + let try_from_items = members.iter().map(|ErrorsMember { name, ffi_name }| { + quote! { ash::vk::Result::#ffi_name => Self::#name, } + }); + + quote! { + /// An enumeration of runtime errors that can be returned by Vulkan. + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] + #[repr(i32)] + #[non_exhaustive] + pub enum VulkanError { + #(#enum_items)* + Unnamed(ash::vk::Result), + } + + impl From<ash::vk::Result> for VulkanError { + fn from(val: ash::vk::Result) -> VulkanError { + match val { + #(#try_from_items)* + x => Self::Unnamed(x), + } + } + } + } +} + +fn errors_members(errors: &[&str]) -> Vec<ErrorsMember> { + errors + .iter() + .map(|error| { + let ffi_name = error.strip_prefix("VK_").unwrap(); + + let mut parts = ffi_name.split('_').collect::<Vec<_>>(); + + assert!(parts[0] == "ERROR"); + parts.remove(0); + + if ["EXT", "KHR", "NV"].contains(parts.last().unwrap()) { + parts.pop(); + } + + let name = parts.join("_").to_upper_camel_case(); + + ErrorsMember { + name: format_ident!("{}", name), + ffi_name: format_ident!("{}", ffi_name), + } + }) + .collect() +} |