Skip to main content

bounded_static_derive_more/
lib.rs

1//! Provides the `ToStatic` derive macro.
2//!
3//! The [`ToStatic`] derive macro implements the [`ToBoundedStatic`](https://docs.rs/bounded-static/0.8.0/bounded_static/trait.ToBoundedStatic.html)
4//! and [`IntoBoundedStatic`](https://docs.rs/bounded-static/0.8.0/bounded_static/trait.IntoBoundedStatic.html) traits for any `struct`
5//! and `enum` that can be converted to a form that is bounded by `'static`.
6//!
7//! The [`ToStatic`] macro should be used via the [`bounded-static`](https://docs.rs/bounded-static/0.8.0) crate
8//! rather than using this crate directly.
9#![warn(clippy::all, clippy::pedantic, clippy::nursery, rust_2018_idioms)]
10#![allow(clippy::redundant_pub_crate, clippy::needless_for_each)]
11#![forbid(unsafe_code)]
12
13use proc_macro2::TokenStream;
14use syn::{Data, DataStruct, DeriveInput, Fields};
15
16mod common;
17mod data_enum;
18mod data_struct;
19
20/// The `ToStatic` derive macro.
21///
22/// Generate [`ToBoundedStatic`](https://docs.rs/bounded-static/0.8.0/bounded_static/trait.ToBoundedStatic.html) and
23/// [`IntoBoundedStatic`](https://docs.rs/bounded-static/0.8.0/bounded_static/trait.IntoBoundedStatic.html) impls for the data item deriving
24/// `ToStatic`.
25#[proc_macro_derive(ToStatic)]
26pub fn to_static(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
27    let input = syn::parse_macro_input!(input as syn::DeriveInput);
28    proc_macro::TokenStream::from(generate_traits(&input))
29}
30
31fn generate_traits(input: &DeriveInput) -> TokenStream {
32    if input.generics.lifetimes().next().is_none() && input.generics.type_params().next().is_none()
33    {
34        let def_type = match &input.data {
35            Data::Struct(_) => "struct",
36            Data::Enum(_) => "enum",
37            Data::Union(_) => unimplemented!("union is not yet supported"),
38        };
39
40        panic!("cannot derive instance for a {def_type} with no lifetime parameter");
41    }
42
43    match &input.data {
44        Data::Struct(DataStruct {
45            fields: Fields::Named(fields_named),
46            ..
47        }) => data_struct::generate_struct_named(&input.ident, &input.generics, fields_named),
48        Data::Struct(DataStruct {
49            fields: Fields::Unnamed(fields_unnamed),
50            ..
51        }) => data_struct::generate_struct_unnamed(&input.ident, &input.generics, fields_unnamed),
52        Data::Struct(DataStruct {
53            fields: Fields::Unit,
54            ..
55        }) => data_struct::generate_struct_unit(&input.ident),
56        Data::Enum(data_enum) => data_enum::generate_enum(
57            &input.ident,
58            &input.generics,
59            data_enum.variants.iter().collect::<Vec<_>>().as_slice(),
60        ),
61        Data::Union(_) => unimplemented!("union is not yet supported"),
62    }
63}