@@ -47,6 +47,9 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
47
47
let input = syn:: parse2 :: < syn:: ItemStruct > ( input) ?;
48
48
let Params {
49
49
ty,
50
+ inner,
51
+ into,
52
+ from,
50
53
bits,
51
54
debug,
52
55
default,
@@ -66,7 +69,15 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
66
69
let mut offset = 0 ;
67
70
let mut members = Vec :: with_capacity ( fields. named . len ( ) ) ;
68
71
for field in fields. named {
69
- let f = Member :: new ( ty. clone ( ) , bits, field, offset, order) ?;
72
+ let f = Member :: new (
73
+ ty. clone ( ) ,
74
+ bits,
75
+ into. clone ( ) ,
76
+ from. clone ( ) ,
77
+ field,
78
+ offset,
79
+ order,
80
+ ) ?;
70
81
offset += f. bits ;
71
82
members. push ( f) ;
72
83
}
@@ -122,11 +133,11 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
122
133
let conversion = if conversion {
123
134
quote ! {
124
135
/// Convert from bits.
125
- #vis const fn from_bits( bits: #ty ) -> Self {
136
+ #vis const fn from_bits( bits: #inner ) -> Self {
126
137
Self ( bits)
127
138
}
128
139
/// Convert into bits.
129
- #vis const fn into_bits( self ) -> #ty {
140
+ #vis const fn into_bits( self ) -> #inner {
130
141
self . 0
131
142
}
132
143
}
@@ -138,12 +149,12 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
138
149
#attrs
139
150
#[ derive( Copy , Clone ) ]
140
151
#[ repr( transparent) ]
141
- #vis struct #name( #ty ) ;
152
+ #vis struct #name( #inner ) ;
142
153
143
154
impl #name {
144
155
/// Creates a new default initialized bitfield.
145
156
#vis const fn new( ) -> Self {
146
- let mut this = Self ( 0 ) ;
157
+ let mut this = Self ( #from ( 0 ) ) ;
147
158
#( #defaults ) *
148
159
this
149
160
}
@@ -154,13 +165,13 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
154
165
155
166
#default_impl
156
167
157
- impl From <#ty > for #name {
158
- fn from( v: #ty ) -> Self {
168
+ impl From <#inner > for #name {
169
+ fn from( v: #inner ) -> Self {
159
170
Self ( v)
160
171
}
161
172
}
162
- impl From <#name> for #ty {
163
- fn from( v: #name) -> #ty {
173
+ impl From <#name> for #inner {
174
+ fn from( v: #name) -> #inner {
164
175
v. 0
165
176
}
166
177
}
@@ -174,6 +185,8 @@ struct Member {
174
185
offset : usize ,
175
186
bits : usize ,
176
187
base_ty : syn:: Type ,
188
+ inner_into : Option < syn:: Path > ,
189
+ inner_from : Option < syn:: Path > ,
177
190
default : TokenStream ,
178
191
inner : Option < MemberInner > ,
179
192
}
@@ -191,6 +204,8 @@ impl Member {
191
204
fn new (
192
205
base_ty : syn:: Type ,
193
206
base_bits : usize ,
207
+ inner_into : Option < syn:: Path > ,
208
+ inner_from : Option < syn:: Path > ,
194
209
f : syn:: Field ,
195
210
offset : usize ,
196
211
order : Order ,
@@ -259,6 +274,8 @@ impl Member {
259
274
offset,
260
275
bits,
261
276
base_ty,
277
+ inner_into,
278
+ inner_from,
262
279
default,
263
280
inner : Some ( MemberInner {
264
281
ident,
@@ -278,6 +295,8 @@ impl Member {
278
295
offset,
279
296
bits,
280
297
base_ty,
298
+ inner_into,
299
+ inner_from,
281
300
default,
282
301
inner : None ,
283
302
} )
@@ -316,6 +335,8 @@ impl ToTokens for Member {
316
335
offset,
317
336
bits,
318
337
base_ty,
338
+ inner_into,
339
+ inner_from,
319
340
default : _,
320
341
inner :
321
342
Some ( MemberInner {
@@ -361,7 +382,7 @@ impl ToTokens for Member {
361
382
#[ doc = #location]
362
383
#vis const fn #ident( & self ) -> #ty {
363
384
let mask = #base_ty:: MAX >> ( #base_ty:: BITS - Self :: #bits_ident as u32 ) ;
364
- let this = ( self . 0 >> Self :: #offset_ident) & mask;
385
+ let this = ( #inner_into ( self . 0 ) >> Self :: #offset_ident) & mask;
365
386
#from
366
387
}
367
388
} ) ;
@@ -378,7 +399,8 @@ impl ToTokens for Member {
378
399
let mask = #base_ty:: MAX >> ( #base_ty:: BITS - Self :: #bits_ident as u32 ) ;
379
400
#[ allow( unused_comparisons) ]
380
401
debug_assert!( value <= mask, "value out of bounds" ) ;
381
- Self ( self . 0 & !( mask << Self :: #offset_ident) | ( value & mask) << Self :: #offset_ident)
402
+ let bits = #inner_into( self . 0 ) & !( mask << Self :: #offset_ident) | ( value & mask) << Self :: #offset_ident;
403
+ Self ( #inner_from( bits) )
382
404
}
383
405
384
406
#doc
@@ -656,6 +678,9 @@ enum Order {
656
678
/// The bitfield macro parameters
657
679
struct Params {
658
680
ty : syn:: Type ,
681
+ inner : syn:: Type ,
682
+ into : Option < syn:: Path > ,
683
+ from : Option < syn:: Path > ,
659
684
bits : usize ,
660
685
debug : bool ,
661
686
default : bool ,
@@ -673,6 +698,9 @@ impl Parse for Params {
673
698
return Err ( s_err ( input. span ( ) , "unsupported type" ) ) ;
674
699
}
675
700
701
+ let mut inner = ty. clone ( ) ;
702
+ let mut from = None ;
703
+ let mut into = None ;
676
704
let mut debug = true ;
677
705
let mut default = true ;
678
706
let mut order = Order :: Lsb ;
@@ -683,6 +711,15 @@ impl Parse for Params {
683
711
let ident = Ident :: parse ( input) ?;
684
712
<Token ! [ =] >:: parse ( input) ?;
685
713
match ident. to_string ( ) . as_str ( ) {
714
+ "inner" => {
715
+ inner = input. parse ( ) ?;
716
+ }
717
+ "from" => {
718
+ from = Some ( input. parse ( ) ?) ;
719
+ }
720
+ "into" => {
721
+ into = Some ( input. parse ( ) ?) ;
722
+ }
686
723
"debug" => {
687
724
debug = syn:: LitBool :: parse ( input) ?. value ;
688
725
}
@@ -705,6 +742,9 @@ impl Parse for Params {
705
742
706
743
Ok ( Self {
707
744
ty,
745
+ inner,
746
+ from,
747
+ into,
708
748
bits,
709
749
debug,
710
750
default,
0 commit comments