@@ -16,14 +16,17 @@ fn s_err(span: proc_macro2::Span, msg: impl fmt::Display) -> syn::Error {
16
16
17
17
/// Creates a bitfield for this struct.
18
18
///
19
- /// The arguments first, have to begin with the underlying type of the bitfield:
19
+ /// The arguments first, have to begin with the integer type of the bitfield:
20
20
/// For example: `#[bitfield(u64)]`.
21
21
///
22
- /// It can contain an extra `debug` argument for disabling the `Debug` trait
23
- /// generation (`#[bitfield(u64, debug = false)]`).
22
+ /// It can contain the following additional parameters, like the `debug` argument
23
+ /// for disabling the `Debug` trait generation (`#[bitfield(u64, debug = false)]`).
24
24
///
25
25
/// Parameters of the `bitfield` attribute:
26
- /// - the bitfield type
26
+ /// - the bitfield integer type (required)
27
+ /// - `repr` specifies the bitfield's representation in memory
28
+ /// - `from` to specify a conversion function from repr to the bitfield's integer type
29
+ /// - `into` to specify a conversion function from the bitfield's integer type to repr
27
30
/// - `debug` to disable the `Debug` trait generation
28
31
/// - `default` to disable the `Default` trait generation
29
32
/// - `order` to specify the bit order (Lsb, Msb)
@@ -47,7 +50,7 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
47
50
let input = syn:: parse2 :: < syn:: ItemStruct > ( input) ?;
48
51
let Params {
49
52
ty,
50
- inner ,
53
+ repr ,
51
54
into,
52
55
from,
53
56
bits,
@@ -133,11 +136,11 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
133
136
let conversion = if conversion {
134
137
quote ! {
135
138
/// Convert from bits.
136
- #vis const fn from_bits( bits: #inner ) -> Self {
139
+ #vis const fn from_bits( bits: #repr ) -> Self {
137
140
Self ( bits)
138
141
}
139
142
/// Convert into bits.
140
- #vis const fn into_bits( self ) -> #inner {
143
+ #vis const fn into_bits( self ) -> #repr {
141
144
self . 0
142
145
}
143
146
}
@@ -149,7 +152,7 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
149
152
#attrs
150
153
#[ derive( Copy , Clone ) ]
151
154
#[ repr( transparent) ]
152
- #vis struct #name( #inner ) ;
155
+ #vis struct #name( #repr ) ;
153
156
154
157
impl #name {
155
158
/// Creates a new default initialized bitfield.
@@ -165,13 +168,13 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
165
168
166
169
#default_impl
167
170
168
- impl From <#inner > for #name {
169
- fn from( v: #inner ) -> Self {
171
+ impl From <#repr > for #name {
172
+ fn from( v: #repr ) -> Self {
170
173
Self ( v)
171
174
}
172
175
}
173
- impl From <#name> for #inner {
174
- fn from( v: #name) -> #inner {
176
+ impl From <#name> for #repr {
177
+ fn from( v: #name) -> #repr {
175
178
v. 0
176
179
}
177
180
}
@@ -185,8 +188,8 @@ struct Member {
185
188
offset : usize ,
186
189
bits : usize ,
187
190
base_ty : syn:: Type ,
188
- inner_into : Option < syn:: Path > ,
189
- inner_from : Option < syn:: Path > ,
191
+ repr_into : Option < syn:: Path > ,
192
+ repr_from : Option < syn:: Path > ,
190
193
default : TokenStream ,
191
194
inner : Option < MemberInner > ,
192
195
}
@@ -204,8 +207,8 @@ impl Member {
204
207
fn new (
205
208
base_ty : syn:: Type ,
206
209
base_bits : usize ,
207
- inner_into : Option < syn:: Path > ,
208
- inner_from : Option < syn:: Path > ,
210
+ repr_into : Option < syn:: Path > ,
211
+ repr_from : Option < syn:: Path > ,
209
212
f : syn:: Field ,
210
213
offset : usize ,
211
214
order : Order ,
@@ -274,8 +277,8 @@ impl Member {
274
277
offset,
275
278
bits,
276
279
base_ty,
277
- inner_into ,
278
- inner_from ,
280
+ repr_into ,
281
+ repr_from ,
279
282
default,
280
283
inner : Some ( MemberInner {
281
284
ident,
@@ -295,8 +298,8 @@ impl Member {
295
298
offset,
296
299
bits,
297
300
base_ty,
298
- inner_into ,
299
- inner_from ,
301
+ repr_into ,
302
+ repr_from ,
300
303
default,
301
304
inner : None ,
302
305
} )
@@ -335,8 +338,8 @@ impl ToTokens for Member {
335
338
offset,
336
339
bits,
337
340
base_ty,
338
- inner_into ,
339
- inner_from ,
341
+ repr_into ,
342
+ repr_from ,
340
343
default : _,
341
344
inner :
342
345
Some ( MemberInner {
@@ -382,7 +385,7 @@ impl ToTokens for Member {
382
385
#[ doc = #location]
383
386
#vis const fn #ident( & self ) -> #ty {
384
387
let mask = #base_ty:: MAX >> ( #base_ty:: BITS - Self :: #bits_ident as u32 ) ;
385
- let this = ( #inner_into ( self . 0 ) >> Self :: #offset_ident) & mask;
388
+ let this = ( #repr_into ( self . 0 ) >> Self :: #offset_ident) & mask;
386
389
#from
387
390
}
388
391
} ) ;
@@ -399,8 +402,8 @@ impl ToTokens for Member {
399
402
let mask = #base_ty:: MAX >> ( #base_ty:: BITS - Self :: #bits_ident as u32 ) ;
400
403
#[ allow( unused_comparisons) ]
401
404
debug_assert!( value <= mask, "value out of bounds" ) ;
402
- let bits = #inner_into ( self . 0 ) & !( mask << Self :: #offset_ident) | ( value & mask) << Self :: #offset_ident;
403
- Self ( #inner_from ( bits) )
405
+ let bits = #repr_into ( self . 0 ) & !( mask << Self :: #offset_ident) | ( value & mask) << Self :: #offset_ident;
406
+ Self ( #repr_from ( bits) )
404
407
}
405
408
406
409
#doc
@@ -678,7 +681,7 @@ enum Order {
678
681
/// The bitfield macro parameters
679
682
struct Params {
680
683
ty : syn:: Type ,
681
- inner : syn:: Type ,
684
+ repr : syn:: Type ,
682
685
into : Option < syn:: Path > ,
683
686
from : Option < syn:: Path > ,
684
687
bits : usize ,
@@ -698,7 +701,7 @@ impl Parse for Params {
698
701
return Err ( s_err ( input. span ( ) , "unsupported type" ) ) ;
699
702
}
700
703
701
- let mut inner = ty . clone ( ) ;
704
+ let mut repr = None ;
702
705
let mut from = None ;
703
706
let mut into = None ;
704
707
let mut debug = true ;
@@ -711,8 +714,8 @@ impl Parse for Params {
711
714
let ident = Ident :: parse ( input) ?;
712
715
<Token ! [ =] >:: parse ( input) ?;
713
716
match ident. to_string ( ) . as_str ( ) {
714
- "inner " => {
715
- inner = input. parse ( ) ?;
717
+ "repr " => {
718
+ repr = Some ( input. parse ( ) ?) ;
716
719
}
717
720
"from" => {
718
721
from = Some ( input. parse ( ) ?) ;
@@ -740,9 +743,16 @@ impl Parse for Params {
740
743
} ;
741
744
}
742
745
746
+ if repr. is_some ( ) != from. is_some ( ) || repr. is_some ( ) != into. is_some ( ) {
747
+ return Err ( s_err (
748
+ input. span ( ) ,
749
+ "`repr` requires both `from` and `into`" ,
750
+ ) ) ;
751
+ }
752
+
743
753
Ok ( Self {
754
+ repr : repr. unwrap_or_else ( || ty. clone ( ) ) ,
744
755
ty,
745
- inner,
746
756
from,
747
757
into,
748
758
bits,
0 commit comments