MCPcopy Create free account
hub / github.com/Lymia/enumset / create_enum_conversions

Function create_enum_conversions

enumset_derive/src/gen.rs:473–623  ·  view source on GitHub ↗
(info: &EnumSetInfo, paths: &Paths)

Source from the content-addressed store, hash-verified

471}
472
473fn create_enum_conversions(info: &EnumSetInfo, paths: &Paths) -> SynTokenStream {
474 let name = &info.name;
475 let core = &paths.core;
476 let enum_repr = info.enum_repr();
477
478 let hint_is_transmute = quote! {
479 #[cfg(target_endian = "little")]
480 let r = *(&r as *const #enum_repr as *const #name);
481
482 #[cfg(target_endian = "big")]
483 let r = {
484 let offset =
485 #core::mem::size_of::<#enum_repr>() - #core::mem::size_of::<#name>();
486 let r = r << ((offset as #enum_repr) * 8);
487 *(&r as *const #enum_repr as *const u8 as *const #name)
488 };
489 };
490
491 if info.variants.is_empty() {
492 // Uninhabited types have no values.
493 quote! {
494 fn enum_into_u32(self) -> u32 {
495 #core::panic!(concat!(stringify!(#name), " is uninhabited."))
496 }
497 unsafe fn enum_from_u32(val: u32) -> Self {
498 #core::panic!(concat!(stringify!(#name), " is uninhabited."))
499 }
500 }
501 } else if info.variants.len() == 1 {
502 // Single-variant enums are generally ZSTs in #[repr(Rust)], and can use simpler code.
503 let variant = &info.variants[0].name;
504 quote! {
505 fn enum_into_u32(self) -> u32 {
506 self as u32
507 }
508 unsafe fn enum_from_u32(val: u32) -> Self {
509 #name::#variant
510 }
511 }
512 } else if info.uses_lsb_encoding() || info.uses_msb_encoding().is_some() {
513 // Prepares output for MSB mode.
514 let process_output = if let Some(msb_repr) = info.uses_msb_encoding() {
515 quote! {
516 let r = (#msb_repr as #enum_repr) - 1 - r;
517 }
518 } else {
519 quote!()
520 };
521
522 let (names, values) = if info.bit_width() >= 1000 {
523 // This worsens codegen quality, but avoids creating big tables for no good reason.
524 let variant_bits: Vec<_> = info.variants.iter().map(|x| x.variant_bit).collect();
525 let variant_names: Vec<_> = info
526 .variants
527 .iter()
528 .map(|x| {
529 let variant_name = &x.name;
530 quote! { #name::#variant_name }

Callers 1

generate_codeFunction · 0.85

Calls 9

newFunction · 0.85
enum_reprMethod · 0.80
is_emptyMethod · 0.80
uses_lsb_encodingMethod · 0.80
uses_msb_encodingMethod · 0.80
uses_mask_encodingMethod · 0.80
uses_compact_encodingMethod · 0.80
bit_widthMethod · 0.45
iterMethod · 0.45

Tested by

no test coverage detected