aboutsummaryrefslogtreecommitdiff
path: root/autogen/errors.rs
diff options
context:
space:
mode:
Diffstat (limited to 'autogen/errors.rs')
-rw-r--r--autogen/errors.rs84
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()
+}