Skip to main content

pbf_derive/
lib.rs

1#![forbid(unsafe_code)]
2
3use darling::{self, FromField, FromVariant};
4use proc_macro::TokenStream;
5use proc_macro_crate::{FoundCrate, crate_name};
6use proc_macro2::Span;
7use syn::{Data, DeriveInput, Ident, parse_macro_input};
8
9mod bitcast;
10mod read;
11mod write;
12
13use bitcast::expand_bitcast;
14use read::{derive_proto_read_enum, derive_proto_read_struct};
15use write::{derive_proto_write_enum, derive_proto_write_struct};
16
17#[derive(Debug, FromField, FromVariant)]
18#[darling(attributes(pbf))]
19struct FieldAttributes {
20    tag: Option<u64>,
21    #[darling(default)]
22    signed: bool,
23    #[darling(default)]
24    fixed: bool,
25    #[darling(default)]
26    nested: bool,
27    #[darling(default)]
28    ignore: bool,
29}
30
31/// Derive the `BitCast` trait for an enum.
32#[proc_macro_derive(BitCast)]
33pub fn derive_bit_cast(input: TokenStream) -> TokenStream {
34    expand_bitcast(input)
35}
36
37#[proc_macro_derive(ProtoWrite, attributes(pbf))]
38pub fn derive_proto_write(input: TokenStream) -> TokenStream {
39    let input = parse_macro_input!(input as DeriveInput);
40    let name = &input.ident;
41
42    let crate_name = match crate_name("pbf") {
43        Ok(FoundCrate::Itself) => "pbf".to_string(),
44        Ok(FoundCrate::Name(name)) => name,
45        Err(_) => "pbf_core".to_string(), // Fallback if resolution fails (happens for testing)
46    };
47    let pbf_core = Ident::new(&crate_name, Span::call_site());
48
49    match &input.data {
50        Data::Struct(data_struct) => derive_proto_write_struct(data_struct, name, &pbf_core),
51        Data::Enum(data_enum) => derive_proto_write_enum(data_enum, name, &pbf_core),
52        _ => panic!("ProtoWrite can only be derived for structs and enums"),
53    }
54}
55
56#[proc_macro_derive(ProtoRead, attributes(pbf))]
57pub fn derive_proto_read(input: TokenStream) -> TokenStream {
58    let input = parse_macro_input!(input as DeriveInput);
59    let name = &input.ident;
60
61    let crate_name = match crate_name("pbf") {
62        Ok(FoundCrate::Itself) => "pbf".to_string(),
63        Ok(FoundCrate::Name(name)) => name,
64        Err(_) => "pbf_core".to_string(), // Fallback if resolution fails (happens for testing)
65    };
66    let pbf_core = Ident::new(&crate_name, Span::call_site());
67
68    match &input.data {
69        Data::Struct(data_struct) => derive_proto_read_struct(data_struct, name, &pbf_core),
70        Data::Enum(data_enum) => derive_proto_read_enum(data_enum, name, &pbf_core),
71        _ => panic!("ProtoRead can only be derived for structs and enums"),
72    }
73}