Skip to main content

zerovec_derive/
make_ule.rs

1// This file is part of ICU4X. For terms of use, please see the file
2// called LICENSE at the top level of the ICU4X source tree
3// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5use proc_macro2::TokenStream as TokenStream2;
6use quote::quote;
7
8use crate::utils::{self, FieldInfo, ZeroVecAttrs};
9
10use syn::spanned::Spanned;
11use syn::{parse_quote, Data, DataEnum, DataStruct, DeriveInput, Error, Expr, Fields, Ident, Lit};
12
13pub fn make_ule_impl(ule_name: Ident, mut input: DeriveInput) -> TokenStream2 {
14    if input.generics.type_params().next().is_some()
15        || input.generics.lifetimes().next().is_some()
16        || input.generics.const_params().next().is_some()
17    {
18        return Error::new(
19            input.generics.span(),
20            "#[make_ule] must be applied to a struct without any generics",
21        )
22        .to_compile_error();
23    }
24    let sp = input.span();
25    let attrs = match utils::extract_attributes_common(&mut input.attrs, sp, false) {
26        Ok(val) => val,
27        Err(e) => return e.to_compile_error(),
28    };
29
30    let name = &input.ident;
31
32    let ule_stuff = match input.data {
33        Data::Struct(ref s) => make_ule_struct_impl(name, &ule_name, &input, s, &attrs),
34        Data::Enum(ref e) => make_ule_enum_impl(name, &ule_name, &input, e, &attrs),
35        _ => {
36            return Error::new(input.span(), "#[make_ule] must be applied to a struct")
37                .to_compile_error();
38        }
39    };
40
41    let zmkv = if attrs.skip_kv {
42        ::quote::__private::TokenStream::new()quote!()
43    } else {
44        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "zerovec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "maps");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ZeroMapKV");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "Container");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "zerovec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ZeroVec");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_lifetime(&mut _s, "\'a");
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "Slice");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "zerovec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ZeroSlice");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "GetType");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "OwnedType");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote!(
45            impl<'a> zerovec::maps::ZeroMapKV<'a> for #name {
46                type Container = zerovec::ZeroVec<'a, #name>;
47                type Slice = zerovec::ZeroSlice<#name>;
48                type GetType = #ule_name;
49                type OwnedType = #name;
50            }
51        )
52    };
53
54    let maybe_debug = if attrs.debug {
55        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "fmt");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Debug");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "fmt");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "f");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "fmt");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Formatter");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "fmt");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "this");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&name, &mut _s);
                    ::quote::__private::push_ident(&mut _s, "as");
                    ::quote::__private::push_ident(&mut _s, "zerovec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ule");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "AsULE");
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "from_unaligned");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_star(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "self");
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&name, &mut _s);
                    ::quote::__private::push_ident(&mut _s, "as");
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "fmt");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Debug");
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "fmt");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_and(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "this");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "f");
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote!(
56            impl core::fmt::Debug for #ule_name {
57                fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
58                    let this = <#name as zerovec::ule::AsULE>::from_unaligned(*self);
59                    <#name as core::fmt::Debug>::fmt(&this, f)
60                }
61            }
62        )
63    } else {
64        ::quote::__private::TokenStream::new()quote!()
65    };
66
67    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&input, &mut _s);
    ::quote::ToTokens::to_tokens(&ule_stuff, &mut _s);
    ::quote::ToTokens::to_tokens(&maybe_debug, &mut _s);
    ::quote::ToTokens::to_tokens(&zmkv, &mut _s);
    _s
}quote!(
68        #input
69
70        #ule_stuff
71
72        #maybe_debug
73
74        #zmkv
75    )
76}
77
78fn make_ule_enum_impl(
79    name: &Ident,
80    ule_name: &Ident,
81    input: &DeriveInput,
82    enu: &DataEnum,
83    attrs: &ZeroVecAttrs,
84) -> TokenStream2 {
85    // We could support more int reprs in the future if needed
86    if !utils::ReprInfo::compute(&input.attrs).u8 {
87        return Error::new(
88            input.span(),
89            "#[make_ule] can only be applied to #[repr(u8)] enums",
90        )
91        .to_compile_error();
92    }
93
94    if enu.variants.is_empty() {
95        return Error::new(input.span(), "#[make_ule] cannot be applied to empty enums")
96            .to_compile_error();
97    }
98
99    let mut discriminants = std::collections::BTreeSet::new();
100
101    for variant in enu.variants.iter() {
102        if !#[allow(non_exhaustive_omitted_patterns)] match variant.fields {
    Fields::Unit => true,
    _ => false,
}matches!(variant.fields, Fields::Unit) {
103            // This can be supported in the future, see zerovec/design_doc.md
104            return Error::new(
105                variant.span(),
106                "#[make_ule] can only be applied to enums with dataless variants",
107            )
108            .to_compile_error();
109        }
110
111        if let Some((_, ref discr)) = variant.discriminant {
112            if let Some(n) = get_expr_int(discr) {
113                let n = match u8::try_from(n) {
114                    Ok(n) => n,
115                    Err(_) => {
116                        return Error::new(
117                            variant.span(),
118                            "#[make_ule] only supports discriminants from 0 to 255",
119                        )
120                        .to_compile_error();
121                    }
122                };
123                discriminants.insert(n);
124            } else {
125                return Error::new(
126                    discr.span(),
127                    "#[make_ule] must be applied to enums with explicit integer discriminants",
128                )
129                .to_compile_error();
130            }
131        } else {
132            return Error::new(
133                variant.span(),
134                "#[make_ule] must be applied to enums with explicit discriminants",
135            )
136            .to_compile_error();
137        }
138    }
139
140    let match_arms = discriminants
141        .iter()
142        .map(|d| {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&d, &mut _s);
    _s
}quote::quote!(#d))
143        .collect::<Vec<_>>();
144
145    let maybe_ord_derives = if attrs.skip_ord {
146        ::quote::__private::TokenStream::new()quote!()
147    } else {
148        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "derive");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "Ord");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "PartialOrd");
                    _s
                });
            _s
        });
    _s
}quote!(#[derive(Ord, PartialOrd)])
149    };
150
151    let vis = &input.vis;
152
153    let doc = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("[`ULE`](zerovec::ule::ULE) type for {0}",
                name))
    })format!("[`ULE`](zerovec::ule::ULE) type for {name}");
154
155    // Safety (based on the safety checklist on the ULE trait):
156    //  1. ULE type does not include any uninitialized or padding bytes.
157    //     (achieved by `#[repr(transparent)]` on a type that satisfies this invariant
158    //  2. ULE type is aligned to 1 byte.
159    //     (achieved by `#[repr(transparent)]` on a type that satisfies this invariant)
160    //  3. The impl of validate_bytes() returns an error if any byte is not valid.
161    //     (Guarantees that the byte is in range of the corresponding enum.)
162    //  4. The impl of validate_bytes() returns an error if there are extra bytes.
163    //     (This does not happen since we are backed by 1 byte.)
164    //  5. The other ULE methods use the default impl.
165    //  6. ULE type byte equality is semantic equality
166    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "repr");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "transparent");
                    _s
                });
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "derive");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "Copy");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Clone");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "PartialEq");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Eq");
                    _s
                });
            _s
        });
    ::quote::ToTokens::to_tokens(&maybe_ord_derives, &mut _s);
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&doc, &mut _s);
            _s
        });
    ::quote::ToTokens::to_tokens(&vis, &mut _s);
    ::quote::__private::push_ident(&mut _s, "struct");
    ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "u8");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unsafe");
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_ident(&mut _s, "zerovec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ule");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ULE");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "inline");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "validate_bytes");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "bytes");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Bracket,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "u8");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "zerovec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ule");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "UleError");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "for");
                    ::quote::__private::push_ident(&mut _s, "byte");
                    ::quote::__private::push_ident(&mut _s, "in");
                    ::quote::__private::push_ident(&mut _s, "bytes");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "match");
                            ::quote::__private::push_star(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "byte");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Brace,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    {
                                        use ::quote::__private::ext::*;
                                        let mut _first = true;
                                        let has_iter = ::quote::__private::HasIterator::<false>;
                                        #[allow(unused_mut)]
                                        let (mut match_arms, i) = match_arms.quote_into_iter();
                                        let has_iter = has_iter | i;
                                        <_ as
                                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                        while true {
                                            let match_arms =
                                                match match_arms.next() {
                                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                                    None => break,
                                                };
                                            if !_first { ::quote::__private::push_or(&mut _s); }
                                            _first = false;
                                            ::quote::ToTokens::to_tokens(&match_arms, &mut _s);
                                        }
                                    }
                                    ::quote::__private::push_fat_arrow(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Brace,
                                        ::quote::__private::TokenStream::new());
                                    ::quote::__private::push_underscore(&mut _s);
                                    ::quote::__private::push_fat_arrow(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "return");
                                    ::quote::__private::push_ident(&mut _s, "Err");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_ident(&mut _s, "zerovec");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "ule");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "UleError");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "parse");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_lt(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "Self");
                                            ::quote::__private::push_gt(&mut _s);
                                            ::quote::__private::push_group(&mut _s,
                                                ::quote::__private::Delimiter::Parenthesis,
                                                ::quote::__private::TokenStream::new());
                                            _s
                                        });
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_ident(&mut _s, "Ok");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_ident(&mut _s, "zerovec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ule");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "AsULE");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "ULE");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "to_unaligned");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ULE");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "self");
                            ::quote::__private::push_ident(&mut _s, "as");
                            ::quote::__private::push_ident(&mut _s, "u8");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "from_unaligned");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "other");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Self");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ULE");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "unsafe");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "core");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "mem");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "transmute");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "u8");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Self");
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "other");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::parse(&mut _s, "0");
                                    _s
                                });
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::parse(&mut _s,
                        "r\" Attempt to construct the value from its corresponding integer,\"");
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::parse(&mut _s,
                        "r\" returning `None` if not possible\"");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "pub");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "crate");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "new_from_u8");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "value");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "u8");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Option");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "if");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
                    ::quote::__private::push_ident(&mut _s, "as");
                    ::quote::__private::push_ident(&mut _s, "zerovec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ule");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ULE");
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "validate_bytes");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_and(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Bracket,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "value");
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "is_ok");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "Some");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "zerovec");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "ule");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "AsULE");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "from_unaligned");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
                                            ::quote::__private::push_group(&mut _s,
                                                ::quote::__private::Delimiter::Parenthesis,
                                                {
                                                    let mut _s = ::quote::__private::TokenStream::new();
                                                    ::quote::__private::push_ident(&mut _s, "value");
                                                    _s
                                                });
                                            _s
                                        });
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_ident(&mut _s, "else");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "None");
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote!(
167        #[repr(transparent)]
168        #[derive(Copy, Clone, PartialEq, Eq)]
169        #maybe_ord_derives
170        #[doc = #doc]
171        #vis struct #ule_name(u8);
172
173        unsafe impl zerovec::ule::ULE for #ule_name {
174            #[inline]
175            fn validate_bytes(bytes: &[u8]) -> Result<(), zerovec::ule::UleError> {
176                for byte in bytes {
177                    match *byte {
178                        #( #match_arms )|* => {}
179                        _ => return Err(zerovec::ule::UleError::parse::<Self>())
180                    }
181                }
182                Ok(())
183            }
184        }
185
186        impl zerovec::ule::AsULE for #name {
187            type ULE = #ule_name;
188
189            fn to_unaligned(self) -> Self::ULE {
190                #ule_name(self as u8)
191            }
192
193            fn from_unaligned(other: Self::ULE) -> Self {
194                // safety: the enum is repr(u8) and can be cast from a u8,
195                // and `#ule_name` guarantees a valid value for this enum.
196                unsafe {
197                    ::core::mem::transmute::<u8, Self>(other.0)
198                }
199            }
200        }
201
202        impl #name {
203            /// Attempt to construct the value from its corresponding integer,
204            /// returning `None` if not possible
205            pub(crate) fn new_from_u8(value: u8) -> Option<Self> {
206                if <#ule_name as zerovec::ule::ULE>::validate_bytes(&[value]).is_ok() {
207                    Some(zerovec::ule::AsULE::from_unaligned(#ule_name(value)))
208                } else {
209                    None
210                }
211            }
212        }
213    )
214}
215
216fn get_expr_int(e: &Expr) -> Option<u64> {
217    if let Ok(Lit::Int(ref i)) = syn::parse2({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&e, &mut _s);
    _s
}quote!(#e)) {
218        return i.base10_parse().ok();
219    }
220
221    None
222}
223
224fn make_ule_struct_impl(
225    name: &Ident,
226    ule_name: &Ident,
227    input: &DeriveInput,
228    struc: &DataStruct,
229    attrs: &ZeroVecAttrs,
230) -> TokenStream2 {
231    if struc.fields.iter().next().is_none() {
232        return Error::new(
233            input.span(),
234            "#[make_ule] must be applied to a non-empty struct",
235        )
236        .to_compile_error();
237    }
238    let sized_fields = FieldInfo::make_list(struc.fields.iter());
239    let field_inits = crate::ule::make_ule_fields(&sized_fields);
240    let field_inits = utils::wrap_field_inits(&field_inits, &struc.fields);
241
242    let semi = utils::semi_for(&struc.fields);
243    let repr_attr = utils::repr_for(&struc.fields);
244    let vis = &input.vis;
245
246    let doc = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("[`ULE`](zerovec::ule::ULE) type for [`{0}`]",
                name))
    })format!("[`ULE`](zerovec::ule::ULE) type for [`{name}`]");
247
248    let ule_struct: DeriveInput = ::syn::__private::parse_quote({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_pound(&mut _s);
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Bracket,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "repr");
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::ToTokens::to_tokens(&repr_attr, &mut _s);
                        _s
                    });
                _s
            });
        ::quote::__private::push_pound(&mut _s);
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Bracket,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "derive");
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_ident(&mut _s, "Copy");
                        ::quote::__private::push_comma(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "Clone");
                        ::quote::__private::push_comma(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "PartialEq");
                        ::quote::__private::push_comma(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "Eq");
                        _s
                    });
                _s
            });
        ::quote::__private::push_pound(&mut _s);
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Bracket,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "doc");
                ::quote::__private::push_eq(&mut _s);
                ::quote::ToTokens::to_tokens(&doc, &mut _s);
                _s
            });
        ::quote::__private::push_pound(&mut _s);
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Bracket,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "allow");
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_ident(&mut _s, "missing_docs");
                        _s
                    });
                _s
            });
        ::quote::ToTokens::to_tokens(&vis, &mut _s);
        ::quote::__private::push_ident(&mut _s, "struct");
        ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
        ::quote::ToTokens::to_tokens(&field_inits, &mut _s);
        ::quote::ToTokens::to_tokens(&semi, &mut _s);
        _s
    })parse_quote!(
249        #[repr(#repr_attr)]
250        #[derive(Copy, Clone, PartialEq, Eq)]
251        #[doc = #doc]
252        // We suppress the `missing_docs` lint for the fields of the struct.
253        #[allow(missing_docs)]
254        #vis struct #ule_name #field_inits #semi
255    );
256    let derived = crate::ule::derive_impl(&ule_struct);
257
258    let mut as_ule_conversions = ::alloc::vec::Vec::new()vec![];
259    let mut from_ule_conversions = ::alloc::vec::Vec::new()vec![];
260
261    for (i, field) in struc.fields.iter().enumerate() {
262        let ty = &field.ty;
263        let i = syn::Index::from(i);
264        if let Some(ref ident) = field.ident {
265            as_ule_conversions
266                .push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&ident, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_ident(&mut _s, "as");
    ::quote::__private::push_ident(&mut _s, "zerovec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ule");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "AsULE");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "to_unaligned");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&ident, &mut _s);
            _s
        });
    _s
}quote!(#ident: <#ty as zerovec::ule::AsULE>::to_unaligned(self.#ident)));
267            from_ule_conversions.push(
268                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&ident, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_ident(&mut _s, "as");
    ::quote::__private::push_ident(&mut _s, "zerovec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ule");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "AsULE");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "from_unaligned");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "unaligned");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&ident, &mut _s);
            _s
        });
    _s
}quote!(#ident: <#ty as zerovec::ule::AsULE>::from_unaligned(unaligned.#ident)),
269            );
270        } else {
271            as_ule_conversions.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_ident(&mut _s, "as");
    ::quote::__private::push_ident(&mut _s, "zerovec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ule");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "AsULE");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "to_unaligned");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&i, &mut _s);
            _s
        });
    _s
}quote!(<#ty as zerovec::ule::AsULE>::to_unaligned(self.#i)));
272            from_ule_conversions
273                .push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_ident(&mut _s, "as");
    ::quote::__private::push_ident(&mut _s, "zerovec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ule");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "AsULE");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "from_unaligned");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "unaligned");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&i, &mut _s);
            _s
        });
    _s
}quote!(<#ty as zerovec::ule::AsULE>::from_unaligned(unaligned.#i)));
274        };
275    }
276
277    let as_ule_conversions = utils::wrap_field_inits(&as_ule_conversions, &struc.fields);
278    let from_ule_conversions = utils::wrap_field_inits(&from_ule_conversions, &struc.fields);
279    let asule_impl = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_ident(&mut _s, "zerovec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ule");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "AsULE");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "ULE");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "to_unaligned");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ULE");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
                    ::quote::ToTokens::to_tokens(&as_ule_conversions, &mut _s);
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "from_unaligned");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "unaligned");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Self");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ULE");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "Self");
                    ::quote::ToTokens::to_tokens(&from_ule_conversions,
                        &mut _s);
                    _s
                });
            _s
        });
    _s
}quote!(
280        impl zerovec::ule::AsULE for #name {
281            type ULE = #ule_name;
282            fn to_unaligned(self) -> Self::ULE {
283                #ule_name #as_ule_conversions
284            }
285            fn from_unaligned(unaligned: Self::ULE) -> Self {
286                Self #from_ule_conversions
287            }
288        }
289    );
290
291    let maybe_ord_impls = if attrs.skip_ord {
292        ::quote::__private::TokenStream::new()quote!()
293    } else {
294        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "cmp");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "PartialOrd");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "partial_cmp");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "other");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Option");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "cmp");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Ordering");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "Some");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "self");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "cmp");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "other");
                                    _s
                                });
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "cmp");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Ord");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "cmp");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "other");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "cmp");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Ordering");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "this");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&name, &mut _s);
                    ::quote::__private::push_ident(&mut _s, "as");
                    ::quote::__private::push_ident(&mut _s, "zerovec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ule");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "AsULE");
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "from_unaligned");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_star(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "self");
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "other");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&name, &mut _s);
                    ::quote::__private::push_ident(&mut _s, "as");
                    ::quote::__private::push_ident(&mut _s, "zerovec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ule");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "AsULE");
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "from_unaligned");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_star(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "other");
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&name, &mut _s);
                    ::quote::__private::push_ident(&mut _s, "as");
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "cmp");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Ord");
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "cmp");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_and(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "this");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_and(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "other");
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote!(
295            impl core::cmp::PartialOrd for #ule_name {
296                fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
297                    Some(self.cmp(other))
298                }
299            }
300
301            impl core::cmp::Ord for #ule_name {
302                fn cmp(&self, other: &Self) -> core::cmp::Ordering {
303                    let this = <#name as zerovec::ule::AsULE>::from_unaligned(*self);
304                    let other = <#name as zerovec::ule::AsULE>::from_unaligned(*other);
305                    <#name as core::cmp::Ord>::cmp(&this, &other)
306                }
307            }
308        )
309    };
310
311    let maybe_hash = if attrs.hash {
312        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "expect");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "clippy");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s,
                        "derive_hash_xor_eq");
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "hash");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Hash");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "hash");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "H");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "state");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "H");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "where");
            ::quote::__private::push_ident(&mut _s, "H");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "hash");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Hasher");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "state");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "write");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::ToTokens::to_tokens(&ule_name, &mut _s);
                            ::quote::__private::push_ident(&mut _s, "as");
                            ::quote::__private::push_ident(&mut _s, "zerovec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "ule");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "ULE");
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "slice_as_bytes");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_and(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Bracket,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_star(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "self");
                                            _s
                                        });
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    _s
                });
            _s
        });
    _s
}quote!(
313            #[expect(clippy::derive_hash_xor_eq)]
314            impl core::hash::Hash for #ule_name {
315                fn hash<H>(&self, state: &mut H) where H: core::hash::Hasher {
316                    state.write(<#ule_name as zerovec::ule::ULE>::slice_as_bytes(&[*self]));
317                }
318            }
319        )
320    } else {
321        ::quote::__private::TokenStream::new()quote!()
322    };
323
324    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&asule_impl, &mut _s);
    ::quote::ToTokens::to_tokens(&ule_struct, &mut _s);
    ::quote::ToTokens::to_tokens(&derived, &mut _s);
    ::quote::ToTokens::to_tokens(&maybe_ord_impls, &mut _s);
    ::quote::ToTokens::to_tokens(&maybe_hash, &mut _s);
    _s
}quote!(
325        #asule_impl
326
327        #ule_struct
328
329        #derived
330
331        #maybe_ord_impls
332
333        #maybe_hash
334    )
335}