| // 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() |
| } |