Creates an atomic wrapper around a C-style enum. The generated type is a wrapper around `AtomicUsize` that transparently converts between the stored integer and the enum type. This attribute also automatically derives the `Debug`, `Copy` and `Clone` traits on the enum type. The name of the atomic type is the name of the enum type, prefixed with `Atomic`. ``` # use atomic_enum::atomic_enum; #[at
(args: TokenStream, input: TokenStream)
| 378 | /// let state = StateAtomic::new(State::Off); |
| 379 | /// ``` |
| 380 | pub fn atomic_enum(args: TokenStream, input: TokenStream) -> TokenStream { |
| 381 | // Parse the input |
| 382 | let ItemEnum { |
| 383 | attrs, |
| 384 | vis, |
| 385 | ident, |
| 386 | generics, |
| 387 | variants, |
| 388 | .. |
| 389 | } = parse_macro_input!(input as ItemEnum); |
| 390 | |
| 391 | // We only support C-style enums: No generics, no fields |
| 392 | if !generics.params.is_empty() { |
| 393 | let span = generics.span(); |
| 394 | let err = quote_spanned! {span=> compile_error!("Expected an enum without generics."); }; |
| 395 | return err.into(); |
| 396 | } |
| 397 | |
| 398 | for variant in variants.iter() { |
| 399 | if !matches!(variant.fields, syn::Fields::Unit) { |
| 400 | let span = variant.fields.span(); |
| 401 | let err = |
| 402 | quote_spanned! {span=> compile_error!("Expected a variant without fields."); }; |
| 403 | return err.into(); |
| 404 | } |
| 405 | } |
| 406 | |
| 407 | // Define the enum |
| 408 | let mut output = enum_definition(attrs, &vis, &ident, &variants); |
| 409 | |
| 410 | // Define the atomic wrapper |
| 411 | let atomic_ident = parse_macro_input!(args as Option<Ident>) |
| 412 | .unwrap_or_else(|| Ident::new(&format!("Atomic{}", ident), ident.span())); |
| 413 | output.extend(atomic_enum_definition(&vis, &ident, &atomic_ident)); |
| 414 | |
| 415 | // Write the impl block for the atomic wrapper |
| 416 | let enum_to_usize = enum_to_usize(&ident); |
| 417 | let enum_from_usize = enum_from_usize(&ident, variants); |
| 418 | let atomic_enum_new = atomic_enum_new(&ident, &atomic_ident); |
| 419 | let atomic_enum_into_inner = atomic_enum_into_inner(&ident); |
| 420 | let atomic_enum_set = atomic_enum_set(&ident); |
| 421 | let atomic_enum_get = atomic_enum_get(&ident); |
| 422 | let atomic_enum_swap_mut = atomic_enum_swap_mut(&ident); |
| 423 | let atomic_enum_load = atomic_enum_load(&ident); |
| 424 | let atomic_enum_store = atomic_enum_store(&ident); |
| 425 | |
| 426 | output.extend(quote! { |
| 427 | impl #atomic_ident { |
| 428 | #enum_to_usize |
| 429 | #enum_from_usize |
| 430 | #atomic_enum_new |
| 431 | #atomic_enum_into_inner |
| 432 | #atomic_enum_set |
| 433 | #atomic_enum_get |
| 434 | #atomic_enum_swap_mut |
| 435 | #atomic_enum_load |
| 436 | #atomic_enum_store |
| 437 | } |
nothing calls this directly
no test coverage detected