mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 02:38:04 +02:00
nak,compiler: Move FromVariants to common code
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41410>
This commit is contained in:
parent
933de407f6
commit
ccdcbde6dd
3 changed files with 44 additions and 29 deletions
42
src/compiler/rust/proc/from_variants.rs
Normal file
42
src/compiler/rust/proc/from_variants.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright © 2023 Collabora, Ltd.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use syn::*;
|
||||
|
||||
pub fn derive_from_variants(input: TokenStream) -> TokenStream {
|
||||
let DeriveInput { ident, data, .. } = parse_macro_input!(input);
|
||||
let enum_type = ident;
|
||||
|
||||
let mut impls = TokenStream2::new();
|
||||
|
||||
if let Data::Enum(e) = data {
|
||||
for v in e.variants {
|
||||
let var_ident = v.ident;
|
||||
let from_type = match v.fields {
|
||||
Fields::Named(_) => {
|
||||
panic!("FromVariants does not support named fields")
|
||||
}
|
||||
Fields::Unnamed(FieldsUnnamed { unnamed, .. }) => unnamed,
|
||||
Fields::Unit => continue,
|
||||
};
|
||||
|
||||
assert!(
|
||||
from_type.len() == 1,
|
||||
"FromVariants does not support multiple unnamed fields"
|
||||
);
|
||||
let from_type = &from_type.first().unwrap().ty;
|
||||
|
||||
impls.extend(quote! {
|
||||
impl From<#from_type> for #enum_type {
|
||||
fn from (v: #from_type) -> #enum_type {
|
||||
#enum_type::#var_ident(v)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impls.into()
|
||||
}
|
||||
|
|
@ -8,3 +8,4 @@ extern crate quote;
|
|||
extern crate syn;
|
||||
|
||||
pub mod as_slice;
|
||||
pub mod from_variants;
|
||||
|
|
|
|||
|
|
@ -147,33 +147,5 @@ pub fn enum_derive_display_op(input: TokenStream) -> TokenStream {
|
|||
|
||||
#[proc_macro_derive(FromVariants)]
|
||||
pub fn derive_from_variants(input: TokenStream) -> TokenStream {
|
||||
let DeriveInput { ident, data, .. } = parse_macro_input!(input);
|
||||
let enum_type = ident;
|
||||
|
||||
let mut impls = TokenStream2::new();
|
||||
|
||||
if let Data::Enum(e) = data {
|
||||
for v in e.variants {
|
||||
let var_ident = v.ident;
|
||||
let from_type = match v.fields {
|
||||
Fields::Unnamed(FieldsUnnamed { unnamed, .. }) => unnamed,
|
||||
_ => panic!("Expected Op(OpFoo)"),
|
||||
};
|
||||
|
||||
assert!(from_type.len() == 1, "Expected Op(OpFoo)");
|
||||
let from_type = &from_type.first().unwrap().ty;
|
||||
|
||||
let quote = quote! {
|
||||
impl From<#from_type> for #enum_type {
|
||||
fn from (op: #from_type) -> #enum_type {
|
||||
#enum_type::#var_ident(op)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
impls.extend(quote);
|
||||
}
|
||||
}
|
||||
|
||||
impls.into()
|
||||
compiler_proc::from_variants::derive_from_variants(input)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue