pub fn gen_dr_operand_kinds(grammar: &[structs::OperandKind]) -> TokenStream {
    let kinds: Vec<_> = grammar
        .iter()
        .map(|element| element.kind.as_str())
        .filter(|element| {
            // Pair kinds are not used in dr::Operand.
            // LiteralContextDependentNumber is replaced by suitable literals.
            // LiteralInteger is replaced by LiteralInt32.
            // IdResult and IdResultType are not stored as operands in `dr`.
            !(element.starts_with("Pair")
                || *element == "LiteralContextDependentNumber"
                || *element == "LiteralInteger"
                || *element == "IdResult"
                || *element == "IdResultType")
        })
        .map(as_ident)
        .collect();

    let kind_and_ty = {
        let id_kinds = kinds
            .iter()
            .filter(|element| element.to_string().starts_with("Id"))
            .map(|element| (element.clone(), quote! { spirv::Word }));

        let num_kinds = vec![
            (format_ident!("LiteralInt32"), quote! {u32}),
            (format_ident!("LiteralInt64"), quote! {u64}),
            (format_ident!("LiteralFloat32"), quote! {f32}),
            (format_ident!("LiteralFloat64"), quote! {f64}),
            (format_ident!("LiteralExtInstInteger"), quote! {u32}),
            (
                format_ident!("LiteralSpecConstantOpInteger"),
                quote! {spirv::Op},
            ),
        ];

        let str_kinds = kinds
            .iter()
            .filter(|element| element.to_string().ends_with("String"))
            .map(|element| (element.clone(), quote! {String}));

        let enum_kinds = kinds
            .iter()
            .filter(|element| {
                let element = element.to_string();
                !(element.starts_with("Id")
                    || element.ends_with("String")
                    || element.ends_with("Integer")
                    || element.ends_with("Number"))
            })
            .map(|element| (element.clone(), quote! {spirv::#element}));

        enum_kinds
            .chain(id_kinds)
            .chain(num_kinds.into_iter())
            .chain(str_kinds)
            .collect::<Vec<_>>()
    };

    let kind_enum = {
        let kinds = kind_and_ty.iter().map(|(kind, ty)| quote! {#kind(#ty)});
        quote! {
            #[doc = "Data representation of a SPIR-V operand."]
            #[derive(Clone, Debug, PartialEq, From)]
            pub enum Operand {
                #(#kinds,)*
            }
        }
    };

    let impl_code = {
        // impl fmt::Display for dr::Operand.
        let mut kinds = kinds;
        kinds.extend(
            [
                "LiteralInt32",
                "LiteralInt64",
                "LiteralFloat32",
                "LiteralFloat64",
            ]
            .iter()
            .cloned()
            .map(as_ident),
        );
        let cases = kinds.iter().map(|element| {
            if element == "Dim" {
                // Skip the "Dim" prefix, which is only used in the API to
                // avoid having an enumerant name starting with a number
                quote! {
                    Operand::#element(ref v) => write!(f, "{}", &format!("{:?}", v)[3..])
                }
            } else {
                quote! {
                    Operand::#element(ref v) => write!(f, "{:?}", v)
                }
            }
        });
        let unwraps = kind_and_ty.into_iter().map(|(kind, ty)| {
            let unwrap_kind = format_ident!("unwrap_{}", kind.to_string().to_snake_case());
            let (ret_ty, self_prefix) = if ty.to_string() == "String" {
                (quote! {&str}, quote! {})
            } else {
                (ty, quote!(*))
            };
            let panic_arg = format!("Expected Operand::{}, got {{}} instead", kind);
            quote! {
                pub fn #unwrap_kind(&self) -> #ret_ty {
                    match #self_prefix self {
                        Self::#kind(v) => v,
                        ref other => panic!(#panic_arg, other),
                    }
                }
            }
        });
        quote! {
            impl fmt::Display for Operand {
                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                    match *self {
                        #(#cases),*
                    }
                }
            }

            impl Operand {
                #(#unwraps)*
                pub fn id_ref_any(&self) -> Option<spirv::Word> {
                    match *self {
                        Self::IdRef(v) | Self::IdScope(v) | Self::IdMemorySemantics(v) => Some(v),
                        _ => None,
                    }
                }
                pub fn id_ref_any_mut(&mut self) -> Option<&mut spirv::Word> {
                    match self {
                        Self::IdRef(v) | Self::IdScope(v) | Self::IdMemorySemantics(v) => Some(v),
                        _ => None,
                    }
                }
            }
        }
    };

    quote! {
        #kind_enum
        #impl_code
    }
}
/// Returns the generated dr::Operand and its fmt::Display implementation by
/// walking the given SPIR-V operand kinds `grammar`.
Returns the generated dr::Operand and its fmt::Display implementation by
walking the given SPIR-V operand kinds `grammar`.
Returns the generated dr :: Operand and its fmt :: Display implementation by walking the given SPIR - V operand kinds ` grammar ` .
pub fn gen_dr_operand_kinds(grammar: &[structs::OperandKind]) -> TokenStream {
    let kinds: Vec<_> = grammar
        .iter()
        .map(|element| element.kind.as_str())
        .filter(|element| {
            // Pair kinds are not used in dr::Operand.
            // LiteralContextDependentNumber is replaced by suitable literals.
            // LiteralInteger is replaced by LiteralInt32.
            // IdResult and IdResultType are not stored as operands in `dr`.
            !(element.starts_with("Pair")
                || *element == "LiteralContextDependentNumber"
                || *element == "LiteralInteger"
                || *element == "IdResult"
                || *element == "IdResultType")
        })
        .map(as_ident)
        .collect();
    let kind_and_ty = {
        let id_kinds = kinds
            .iter()
            .filter(|element| element.to_string().starts_with("Id"))
            .map(|element| (element.clone(), quote! { spirv::Word }));
        let num_kinds = vec![
            (format_ident!("LiteralInt32"), quote! {u32}),
            (format_ident!("LiteralInt64"), quote! {u64}),
            (format_ident!("LiteralFloat32"), quote! {f32}),
            (format_ident!("LiteralFloat64"), quote! {f64}),
            (format_ident!("LiteralExtInstInteger"), quote! {u32}),
            (
                format_ident!("LiteralSpecConstantOpInteger"),
                quote! {spirv::Op},
            ),
        ];
        let str_kinds = kinds
            .iter()
            .filter(|element| element.to_string().ends_with("String"))
            .map(|element| (element.clone(), quote! {String}));
        let enum_kinds = kinds
            .iter()
            .filter(|element| {
                let element = element.to_string();
                !(element.starts_with("Id")
                    || element.ends_with("String")
                    || element.ends_with("Integer")
                    || element.ends_with("Number"))
            })
            .map(|element| (element.clone(), quote! {spirv::#element}));
        enum_kinds
            .chain(id_kinds)
            .chain(num_kinds.into_iter())
            .chain(str_kinds)
            .collect::<Vec<_>>()
    };
    let kind_enum = {
        let kinds = kind_and_ty.iter().map(|(kind, ty)| quote! {#kind(#ty)});
        quote! {
            #[doc = "Data representation of a SPIR-V operand."]
            #[derive(Clone, Debug, PartialEq, From)]
            pub enum Operand {
                #(#kinds,)*
            }
        }
    };
    let impl_code = {
        // impl fmt::Display for dr::Operand.
        let mut kinds = kinds;
        kinds.extend(
            [
                "LiteralInt32",
                "LiteralInt64",
                "LiteralFloat32",
                "LiteralFloat64",
            ]
            .iter()
            .cloned()
            .map(as_ident),
        );
        let cases = kinds.iter().map(|element| {
            if element == "Dim" {
                // Skip the "Dim" prefix, which is only used in the API to
                // avoid having an enumerant name starting with a number
                quote! {
                    Operand::#element(ref v) => write!(f, "{}", &format!("{:?}", v)[3..])
                }
            } else {
                quote! {
                    Operand::#element(ref v) => write!(f, "{:?}", v)
                }
            }
        });
        let unwraps = kind_and_ty.into_iter().map(|(kind, ty)| {
            let unwrap_kind = format_ident!("unwrap_{}", kind.to_string().to_snake_case());
            let (ret_ty, self_prefix) = if ty.to_string() == "String" {
                (quote! {&str}, quote! {})
            } else {
                (ty, quote!(*))
            };
            let panic_arg = format!("Expected Operand::{}, got {{}} instead", kind);
            quote! {
                pub fn #unwrap_kind(&self) -> #ret_ty {
                    match #self_prefix self {
                        Self::#kind(v) => v,
                        ref other => panic!(#panic_arg, other),
                    }
                }
            }
        });
        quote! {
            impl fmt::Display for Operand {
                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                    match *self {
                        #(#cases),*
                    }
                }
            }
            impl Operand {
                #(#unwraps)*
                pub fn id_ref_any(&self) -> Option<spirv::Word> {
                    match *self {
                        Self::IdRef(v) | Self::IdScope(v) | Self::IdMemorySemantics(v) => Some(v),
                        _ => None,
                    }
                }
                pub fn id_ref_any_mut(&mut self) -> Option<&mut spirv::Word> {
                    match self {
                        Self::IdRef(v) | Self::IdScope(v) | Self::IdMemorySemantics(v) => Some(v),
                        _ => None,
                    }
                }
            }
        }
    };
    quote! {
        #kind_enum
        #impl_code
    }
}
pub fn gen_dr_operand_kinds ( grammar : & [ structs :: OperandKind ] ) -> TokenStream { let kinds : Vec < _ > = grammar . iter ( ) . map ( | element | element . kind . as_str ( ) ) . filter ( | element | { // Pair kinds are not used in dr::Operand. // LiteralContextDependentNumber is replaced by suitable literals. // LiteralInteger is replaced by LiteralInt32. // IdResult and IdResultType are not stored as operands in `dr`. ! ( element . starts_with ( " " ) || * element == " " || * element == " " || * element == " " || * element == " " ) } ) . map ( as_ident ) . collect ( ) ; let kind_and_ty = { let id_kinds = kinds . iter ( ) . filter ( | element | element . to_string ( ) . starts_with ( " " ) ) . map ( | element | ( element . clone ( ) , quote ! { spirv Word } ) ) ; let num_kinds = vec ! [ ( format_ident ( " " ) quote { u32 } ) ( format_ident ( " " ) quote { u64 } ) ( format_ident ( " " ) quote { f32 } ) ( format_ident ( " " ) quote { f64 } ) ( format_ident ( " " ) quote { u32 } ) ( format_ident ( " " ) quote { spirv Op } ) ] ; let str_kinds = kinds . iter ( ) . filter ( | element | element . to_string ( ) . ends_with ( " " ) ) . map ( | element | ( element . clone ( ) , quote ! { String } ) ) ; let enum_kinds = kinds . iter ( ) . filter ( | element | { let element = element . to_string ( ) ; ! ( element . starts_with ( " " ) || element . ends_with ( " " ) || element . ends_with ( " " ) || element . ends_with ( " " ) ) } ) . map ( | element | ( element . clone ( ) , quote ! { spirv element } ) ) ; enum_kinds . chain ( id_kinds ) . chain ( num_kinds . into_iter ( ) ) . chain ( str_kinds ) . collect :: < Vec < _ > > ( ) } ; let kind_enum = { let kinds = kind_and_ty . iter ( ) . map ( | ( kind , ty ) | quote ! { kind ( ty ) } ) ; quote ! { [ doc " " ] [ derive ( Clone Debug PartialEq From ) ] pub enum Operand { ( kinds ) } } } ; let impl_code = { // impl fmt::Display for dr::Operand. let mut kinds = kinds ; kinds . extend ( [ " " , " " , " " , " " , ] . iter ( ) . cloned ( ) . map ( as_ident ) , ) ; let cases = kinds . iter ( ) . map ( | element | { if element == " " { // Skip the "Dim" prefix, which is only used in the API to // avoid having an enumerant name starting with a number quote ! { Operand element ( ref v ) write ( f " " format ( " " v ) [ 3 ] ) } } else { quote ! { Operand element ( ref v ) write ( f " " v ) } } } ) ; let unwraps = kind_and_ty . into_iter ( ) . map ( | ( kind , ty ) | { let unwrap_kind = format_ident ! ( " " kind to_string ( ) to_snake_case ( ) ) ; let ( ret_ty , self_prefix ) = if ty . to_string ( ) == " " { ( quote ! { str } , quote ! { } ) } else { ( ty , quote ! ( ) ) } ; let panic_arg = format ! ( " " kind ) ; quote ! { pub fn unwrap_kind ( self ) ret_ty { match self_prefix self { Self kind ( v ) v ref other panic ( panic_arg other ) } } } } ) ; quote ! { impl fmt Display for Operand { fn fmt ( self f mut fmt Formatter ) fmt Result { match self { ( cases ) } } } impl Operand { ( unwraps ) pub fn id_ref_any ( self ) Option spirv Word { match self { Self IdRef ( v ) Self IdScope ( v ) Self IdMemorySemantics ( v ) Some ( v ) None } } pub fn id_ref_any_mut ( mut self ) Option mut spirv Word { match self { Self IdRef ( v ) Self IdScope ( v ) Self IdMemorySemantics ( v ) Some ( v ) None } } } } } ; quote ! { kind_enum impl_code } }
Returns the generated dr::Operand and its fmt::Display implementation by
walking the given SPIR-V operand kinds `grammar`.
Returns the generated dr :: Operand and its fmt :: Display implementation by walking the given SPIR - V operand kinds ` grammar ` .
grammar
&[structs::OperandKind]
grammar
&[structs::OperandKind]