Skip to main content

bilge_impl/
lib.rs

1use manyhow::manyhow;
2use proc_macro2::TokenStream;
3
4mod bitsize;
5mod bitsize_internal;
6mod debug_bits;
7mod default_bits;
8mod fmt_bits;
9mod from_bits;
10#[cfg(feature = "schemars")]
11#[cfg_attr(docsrs, doc(cfg(feature = "schemars")))]
12mod schemars_bits;
13#[cfg(feature = "serde")]
14#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
15mod serde_bits;
16mod try_from_bits;
17
18mod shared;
19
20/// Defines the bitsize of a struct or an enum.
21///
22/// e.g. `#[bitsize(4)]` represents the item as a u4, which is UInt<u8, 4> underneath.
23/// The size of structs is currently limited to 128 bits.
24/// The size of enums is limited to 64 bits.
25/// Please open an issue if you have a usecase for bigger bitfields.
26///
27/// After the size, structs may take extra options:
28/// - `hide_value`: place the generated struct in a private module so the raw
29///   `value` field cannot be read or written. To write the whole value, use `From`/`TryFrom` instead, which is more type-safe.
30///   Relative visibility (`pub(super)`, `pub(self)`, inherited) is shifted one `super`
31///   so it works like you wrote it.
32/// - `new = <vis>`: visibility of `new` (private by default, like other Rust items).
33/// Examples: `new = pub`, `new = pub(crate)`.
34///
35/// ```ignore
36/// #[bitsize(8, hide_value, new = pub(crate))]
37/// struct Register { ... }
38/// ```
39#[manyhow]
40#[proc_macro_attribute]
41pub fn bitsize(args: TokenStream, item: TokenStream) -> manyhow::Result {
42    bitsize::bitsize(args, item)
43}
44
45/// This is internally used, not to be used by anything besides `bitsize`.
46/// No guarantees are given.
47#[doc(hidden)]
48#[manyhow]
49#[proc_macro_attribute]
50pub fn bitsize_internal(args: TokenStream, item: TokenStream) -> manyhow::Result {
51    bitsize_internal::bitsize_internal(args, item)
52}
53
54/// Generate an `impl TryFrom<uN>` for unfilled bitfields.
55///
56/// This should be used when your enum or enums nested in
57/// a struct don't fill their given `bitsize`.
58#[manyhow]
59#[proc_macro_derive(TryFromBits, attributes(bitsize_internal, fallback))]
60pub fn derive_try_from_bits(item: TokenStream) -> manyhow::Result {
61    try_from_bits::try_from_bits(item)
62}
63
64/// Generate an `impl From<uN>` for filled bitfields.
65///
66/// This should be used when your enum or enums nested in
67/// a struct fill their given `bitsize` or if you're not
68/// using enums.
69#[manyhow]
70#[proc_macro_derive(FromBits, attributes(bitsize_internal, fallback))]
71pub fn derive_from_bits(item: TokenStream) -> manyhow::Result {
72    from_bits::from_bits(item)
73}
74
75/// Generate an `impl core::fmt::Debug` for bitfield structs.
76///
77/// Please use normal #[derive(Debug)] for enums.
78#[manyhow]
79#[proc_macro_derive(DebugBits, attributes(bitsize_internal))]
80pub fn debug_bits(item: TokenStream) -> manyhow::Result {
81    debug_bits::debug_bits(item)
82}
83
84/// Generate an `impl core::fmt::Binary` for bitfields.
85#[manyhow]
86#[proc_macro_derive(BinaryBits, attributes(bitsize_internal, fallback))]
87pub fn derive_binary_bits(item: TokenStream) -> manyhow::Result {
88    fmt_bits::binary(item)
89}
90
91/// Generate an `impl core::default::Default` for bitfield structs.
92#[manyhow]
93#[proc_macro_derive(DefaultBits, attributes(bitsize_internal))]
94pub fn derive_default_bits(item: TokenStream) -> manyhow::Result {
95    default_bits::default_bits(item)
96}
97
98/// Generate an `impl schemars::JsonSchema` for bitfield structs.
99///
100/// Please use normal #[derive(JsonSchema)] for enums.
101#[cfg(feature = "schemars")]
102#[manyhow]
103#[proc_macro_derive(JsonSchemaBits, attributes(bitsize_internal))]
104pub fn json_schema_bits(item: TokenStream) -> manyhow::Result {
105    schemars_bits::json_schema_bits(item)
106}
107
108/// Generate an `impl serde::Serialize` for bitfield structs.
109///
110/// Please use normal #[derive(Serialize)] for enums.
111#[cfg(feature = "serde")]
112#[manyhow]
113#[proc_macro_derive(SerializeBits, attributes(bitsize_internal))]
114pub fn serialize_bits(item: TokenStream) -> manyhow::Result {
115    serde_bits::serialize_bits(item)
116}
117
118/// Generate an `impl serde::Deserialize` for bitfield structs.
119///
120/// Please use normal #[derive(Deserialize)] for enums.
121#[cfg(feature = "serde")]
122#[manyhow]
123#[proc_macro_derive(DeserializeBits, attributes(bitsize_internal))]
124pub fn deserialize_bits(item: TokenStream) -> manyhow::Result {
125    serde_bits::deserialize_bits(item)
126}