1use std::str::FromStr;
8
9use proc_macro::TokenStream;
10use proc_macro2::{Literal, Span, TokenStream as TokenStream2};
11use quote::{ToTokens, format_ident, quote};
12use syn::parse::{Error, Parse, ParseStream, Result};
13use syn::spanned::Spanned;
14use syn::{
15 Expr, ExprLit, Fields, GenericArgument, Ident, ItemStruct, Lit, Pat, Path,
16 PathArguments, Stmt, Type, braced, parse_macro_input, parse_quote,
17};
18
19#[proc_macro_attribute]
20pub fn bitfield_repr(attr: TokenStream, item: TokenStream) -> TokenStream {
21 let attr: TokenStream2 = attr.into();
22 let item: TokenStream2 = item.into();
23 quote! {
24 #[repr(#attr)]
25 #[derive(
26 Debug,
27 Eq,
28 PartialEq,
29 ::zerocopy::Immutable,
30 ::zerocopy::IntoBytes,
31 ::zerocopy::TryFromBytes,
32 )]
33 #item
34 }
35 .into()
36}
37
38#[proc_macro]
39pub fn layout(item: TokenStream) -> TokenStream {
40 parse_macro_input!(item as Bitfields)
41 .to_token_stream()
42 .into()
43}
44
45enum BaseType {
50 U8,
51 U16,
52 U32,
53 U64,
54 U128,
55}
56
57impl BaseType {
58 const fn high_bit(&self) -> usize {
59 match *self {
60 Self::U8 => 7,
61 Self::U16 => 15,
62 Self::U32 => 31,
63 Self::U64 => 63,
64 Self::U128 => 127,
65 }
66 }
67}
68
69struct BaseTypeDef {
70 def: Type,
71 ty: BaseType,
72}
73
74impl TryFrom<Type> for BaseTypeDef {
75 type Error = Error;
76
77 fn try_from(type_def: Type) -> Result<Self> {
78 const INVALID_BASE_TYPE: &str =
79 "base type must be an unsigned integral type";
80 let Type::Path(ref path_ty) = type_def else {
81 return Err(Error::new_spanned(type_def, INVALID_BASE_TYPE));
82 };
83 let path = &path_ty.path;
84 let ty = if path.is_ident("u8") {
85 BaseType::U8
86 } else if path.is_ident("u16") {
87 BaseType::U16
88 } else if path.is_ident("u32") {
89 BaseType::U32
90 } else if path.is_ident("u64") {
91 BaseType::U64
92 } else if path.is_ident("u128") {
93 BaseType::U128
94 } else {
95 return Err(Error::new_spanned(path, INVALID_BASE_TYPE));
96 };
97 Ok(Self { def: type_def, ty })
98 }
99}
100
101struct TypeDef {
102 def: ItemStruct,
103 base: BaseTypeDef,
104}
105
106impl Parse for TypeDef {
107 fn parse(input: ParseStream) -> Result<Self> {
108 let mut strct: ItemStruct = input.parse()?;
109
110 let mut repr = false;
113 for attr in &strct.attrs {
114 if attr.path().is_ident("derive") {
115 attr.parse_nested_meta(|meta| {
116 for t in &[
117 "Copy",
118 "Clone",
119 "Debug",
120 "Default",
121 "Eq",
122 "PartialEq",
123 ] {
124 if meta.path.is_ident(t) {
125 return Err(Error::new_spanned(
126 meta.path,
127 format!("layout! already derives {t}"),
128 ));
129 }
130 }
131 Ok(())
132 })?;
133 continue;
134 }
135
136 if attr.path().is_ident("repr") {
137 repr = true;
138 }
139 }
140 if !repr {
141 strct.attrs.push(parse_quote!(#[repr(transparent)]));
142 }
143
144 let base_type = if let Fields::Unnamed(fields) = &strct.fields {
146 if fields.unnamed.is_empty() {
147 return Err(Error::new_spanned(
148 &fields.unnamed,
149 "no base type provided",
150 ));
151 }
152 if fields.unnamed.len() > 1 {
153 return Err(Error::new_spanned(
154 &fields.unnamed,
155 "too many tuple fields; only the base type should be provided",
156 ));
157 }
158 BaseTypeDef::try_from(fields.unnamed.first().unwrap().ty.clone())?
159 } else {
160 return Err(Error::new_spanned(
161 &strct.fields,
162 "bitfld type must be defined as a tuple struct",
163 ));
164 };
165
166 Ok(Self {
167 def: strct,
168 base: base_type,
169 })
170 }
171}
172
173struct Bitfield {
178 span: Span,
179 name: Option<Ident>,
180 high_bit: usize,
181 low_bit: usize,
182 repr: Option<Type>,
183
184 default: Option<Box<Expr>>,
186
187 shifted_mask: TokenStream2,
189}
190
191impl Bitfield {
192 fn new(
193 span: Span,
194 name: Option<Ident>,
195 high_bit: usize,
196 low_bit: usize,
197 repr: Option<Type>,
198 default: Option<Box<Expr>>,
199 ) -> Self {
200 let shifted_mask = {
201 let num_ones = high_bit - low_bit + 1;
202 let mut mask_str = "0x".to_string();
203
204 if !num_ones.is_multiple_of(4) {
208 mask_str.push(match num_ones % 4 {
209 1 => '1',
210 2 => '3',
211 3 => '7',
212 _ => unreachable!(),
213 });
214 }
215
216 let mut remaining = num_ones / 4;
217 while remaining > 0 {
218 if mask_str.len() > 2 && remaining.is_multiple_of(4) {
219 mask_str.push('_');
220 }
221 mask_str.push('f');
222 remaining -= 1;
223 }
224 TokenStream2::from_str(&mask_str).unwrap()
225 };
226
227 Self {
228 span,
229 name,
230 high_bit,
231 low_bit,
232 repr,
233 default,
234 shifted_mask,
235 }
236 }
237
238 const fn is_reserved(&self) -> bool {
239 self.name.is_none()
240 }
241
242 const fn bit_width(&self) -> usize {
243 self.high_bit - self.low_bit + 1
244 }
245
246 fn minimum_width_integral_type(&self) -> TokenStream2 {
247 match self.bit_width() {
248 2..=8 => quote! {u8},
249 9..=16 => quote! {u16},
250 17..=32 => quote! {u32},
251 33..=64 => quote! {u64},
252 65..=128 => quote! {u128},
253 width => panic!("unexpected integral bit width: {width}"),
254 }
255 }
256
257 fn getter_and_setter(&self, ty: &TypeDef) -> TokenStream2 {
258 debug_assert!(!self.is_reserved());
259
260 let name = self.name.as_ref().unwrap();
261 let setter_name = format_ident!("set_{}", name);
262
263 let base_type = &ty.base.def;
264 let ty = &ty.def.ident;
265 let low_bit = Literal::usize_unsuffixed(self.low_bit);
266 let bit_width = self.bit_width();
267
268 if bit_width == 1 {
269 let get_doc = format!(
270 "Returns the value of the `{name}` bit (i.e., {ty}[{}]).",
271 self.low_bit,
272 );
273 let set_doc = format!(
274 "Sets the value of the `{name}` bit (i.e., {ty}[{}]).",
275 self.low_bit,
276 );
277 return quote! {
278 #[doc = #get_doc]
279 #[inline]
280 pub const fn #name(&self) -> bool {
281 (self.0 & (1 << #low_bit)) != 0
282 }
283
284 #[doc = #set_doc]
285 #[inline]
286 pub const fn #setter_name(&mut self, value: bool) -> &mut Self {
287 if value {
288 self.0 |= (1 << #low_bit);
289 } else {
290 self.0 &= (1 << #low_bit);
291 }
292 self
293 }
294 };
295 }
296
297 let get_doc = format!(
298 "Returns the value of the `{name}` field (i.e., `{ty}[{}:{}]`).",
299 self.high_bit, self.low_bit,
300 );
301 let set_doc = format!(
302 "Sets the value of the `{name}` field (i.e., `{ty}[{}:{}]`).",
303 self.high_bit, self.low_bit,
304 );
305
306 let min_width = self.minimum_width_integral_type();
307 let shifted_mask = &self.shifted_mask;
308 let get_value =
309 quote! { ((self.0 >> #low_bit) & #shifted_mask) as #min_width };
310 let getter = if let Some(repr) = &self.repr {
311 quote! {
312 #[doc = #get_doc]
313 #[inline]
314 pub fn #name(&self)
315 -> ::core::result::Result<#repr, ::bitfld::InvalidBits<#min_width>>
316 where
317 #repr: ::zerocopy::TryFromBytes,
318 {
319 use ::zerocopy::IntoBytes;
320 use ::zerocopy::TryFromBytes;
321 let value = #get_value;
322 #repr::try_read_from_bytes(value.as_bytes())
323 .map_err(|_| ::bitfld::InvalidBits(value))
324 }
325 }
326 } else {
327 quote! {
328 #[doc = #get_doc]
329 #[inline]
330 pub const fn #name(&self) -> #min_width {
331 #get_value
332 }
333 }
334 };
335
336 let set_value = {
337 let value_check = if bit_width >= 8 && bit_width.is_power_of_two() {
338 quote! {}
339 } else {
340 quote! { debug_assert!((value & !#shifted_mask) == 0); }
341 };
342 quote! {
343 #value_check
344 self.0 &= !(#shifted_mask << #low_bit);
345 self.0 |= ((value & #shifted_mask) as #base_type) << #low_bit;
346 }
347 };
348
349 let setter = if let Some(repr) = &self.repr {
350 quote! {
351 #[doc = #set_doc]
352 #[inline]
353 pub fn #setter_name(&mut self, value: #repr) -> &mut Self
354 where
355 #repr: ::zerocopy::IntoBytes + ::zerocopy::Immutable
356 {
357 use ::zerocopy::IntoBytes;
358 use ::zerocopy::FromBytes;
359 const { assert!(::core::mem::size_of::<#repr>() == ::core::mem::size_of::<#min_width>()) }
360 let value = #min_width::read_from_bytes(value.as_bytes()).unwrap();
361 #set_value
362 self
363 }
364 }
365 } else {
366 quote! {
367 #[doc = #set_doc]
368 #[inline]
369 pub const fn #setter_name(&mut self, value: #min_width) -> &mut Self {
370 #set_value
371 self
372 }
373 }
374 };
375
376 quote! {
377 #getter
378 #setter
379 }
380 }
381}
382
383impl Parse for Bitfield {
384 fn parse(input: ParseStream) -> Result<Self> {
385 const INVALID_BITFIELD_DECL_FORM: &str = "bitfield declaration should take one of the following forms:\n\
386 * `let $name: Bit<$bit> (= $default)?;`\n\
387 * `let $name: Bits<$high, $low (, $repr)?> (= $default)?;`\n\
388 * `let _: Bit<$bit> (= $value)?;`\n\
389 * `let _: Bits<$high, $low> (= $value)?;`";
390 let err = |spanned: &dyn ToTokens| {
391 Error::new_spanned(spanned, INVALID_BITFIELD_DECL_FORM)
392 };
393
394 let stmt = input.parse::<Stmt>()?;
395 let Stmt::Local(ref local) = stmt else {
396 return Err(err(&stmt));
397 };
398 let Pat::Type(ref pat_type) = local.pat else {
399 return Err(err(&local));
400 };
401
402 let name: Option<Ident> = match *pat_type.pat {
403 Pat::Ident(ref pat_ident) => {
404 if let Some(by_ref) = &pat_ident.by_ref {
405 return Err(err(by_ref));
406 }
407 if let Some(mutability) = &pat_ident.mutability {
408 return Err(err(mutability));
409 }
410 if let Some(subpat) = &pat_ident.subpat {
411 return Err(err(&subpat.0));
412 }
413 Some(pat_ident.ident.clone())
414 }
415 Pat::Wild(_) => None,
416 _ => return Err(err(&*pat_type.pat)),
417 };
418
419 let path: &Path = if let Type::Path(ref type_path) = *pat_type.ty {
420 if type_path.qself.is_some() {
421 return Err(err(&*pat_type.ty));
422 }
423 &type_path.path
424 } else {
425 return Err(err(&*pat_type.ty));
426 };
427
428 let get_bits_and_repr = |bits: &mut [usize]| -> Result<Option<Type>> {
429 let args = &path.segments.first().unwrap().arguments;
430 let args = if let PathArguments::AngleBracketed(bracketed) = args {
431 &bracketed.args
432 } else {
433 return Err(err(&args));
434 };
435 if args.len() < bits.len() || args.len() > bits.len() + 1 {
436 return Err(err(&args));
437 }
438 for (i, bit) in bits.iter_mut().enumerate() {
439 let arg = args.get(i).unwrap();
440 match arg {
441 GenericArgument::Const(Expr::Lit(ExprLit {
442 lit: Lit::Int(b),
443 ..
444 })) => {
445 *bit = b.base10_parse()?;
446 }
447 _ => return Err(err(&arg)),
448 }
449 }
450 if args.len() == bits.len() + 1 {
451 let arg = args.last().unwrap();
452 if let GenericArgument::Type(repr) = arg {
453 Ok(Some(repr.clone()))
454 } else {
455 Err(err(&arg))
456 }
457 } else {
458 Ok(None)
459 }
460 };
461
462 let type_ident = &path.segments.first().unwrap().ident;
463 let (high, low, repr) = if type_ident == "Bits" {
464 let mut bits = [0usize; 2];
465 let repr = get_bits_and_repr(&mut bits)?;
466 if bits[0] < bits[1] {
467 Err(Error::new_spanned(
468 &path.segments,
469 "first high bit, then low",
470 ))
471 } else {
472 Ok((bits[0], bits[1], repr))
473 }
474 } else if type_ident == "Bit" {
475 let mut bit = [0usize; 1];
476 let repr = get_bits_and_repr(&mut bit)?;
477 Ok((bit[0], bit[0], repr))
478 } else {
479 Err(err(path))
480 }?;
481
482 let default_or_value = if let Some(ref init) = local.init {
483 if init.diverge.is_some() {
484 return Err(err(local));
485 }
486 Some(init.expr.clone())
487 } else {
488 None
489 };
490
491 if repr.is_some() {
492 if name.is_none() {
493 return Err(Error::new_spanned(
494 repr,
495 "custom representations are not permitted for reserved fields",
496 ));
497 }
498 if high == low {
499 return Err(Error::new_spanned(
500 repr,
501 "custom representations are not permitted for bits",
502 ));
503 }
504 }
505
506 Ok(Bitfield::new(
507 stmt.span(),
508 name,
509 high,
510 low,
511 repr,
512 default_or_value,
513 ))
514 }
515}
516
517struct Bitfields {
518 ty: TypeDef,
519 named: Vec<Bitfield>,
520 reserved: Vec<Bitfield>,
521}
522
523impl Bitfields {
524 fn constants(&self) -> TokenStream2 {
525 let base = &self.ty.base.def;
526
527 let mut field_constants = Vec::new();
528 let mut field_metadata = Vec::new();
529 let mut checks = Vec::new();
530 let mut default_values = vec![quote! {Self::RSVD1_MASK}];
531
532 for field in &self.named {
533 let name_lower = field.name.as_ref().unwrap().to_string();
534 let name_upper = name_lower.clone().to_uppercase();
535 let low_bit = Literal::usize_unsuffixed(field.low_bit);
536 let shifted_mask = &field.shifted_mask;
537
538 if field.bit_width() == 1 {
539 let bit_name = format_ident!("{name_upper}_BIT");
540 let doc = format!("Bit position of the `{name_lower}` field.",);
541 field_constants.push(quote! {
542 #[doc = #doc]
543 pub const #bit_name: usize = #low_bit;
544 });
545 } else {
546 let mask_name = format_ident!("{name_upper}_MASK");
547 let shift_name = format_ident!("{name_upper}_SHIFT");
548 let mask_doc =
549 format!("Unshifted bitmask of the `{name_lower}` field.");
550 let shift_doc = format!(
551 "Bit shift (i.e., the low bit) of the `{name_lower}` field."
552 );
553 field_constants.push(quote! {
554 #[doc = #mask_doc]
555 pub const #mask_name: #base = #shifted_mask;
556 #[doc = #shift_doc]
557 pub const #shift_name: usize = #low_bit;
558 });
559 }
560
561 if let Some(default) = &field.default {
562 let default_name = format_ident!("{name_upper}_DEFAULT");
563 let doc = format!(
564 "Pre-shifted default value of the `{name_lower}` field.",
565 );
566 field_constants.push(quote! {
567 #[doc = #doc]
568 pub const #default_name: #base = ((#default) as #base) << #low_bit;
569 });
570 checks.push(quote! {
571 const { assert!(Self::#default_name & !(#shifted_mask << #low_bit) == 0) }
572 });
573 default_values.push(quote! { Self::#default_name });
574 }
575
576 let high_bit = Literal::usize_unsuffixed(field.high_bit);
577 let default = if let Some(default) = &field.default {
578 quote! { #default }
579 } else {
580 quote! { 0 }
581 };
582 field_metadata.push(quote! {
583 ::bitfld::FieldMetadata::<#base>{
584 name: #name_lower,
585 high_bit: #high_bit,
586 low_bit: #low_bit,
587 default: #default as #base,
588 },
589 });
590 }
591
592 let mut rsvd1_values = Vec::new();
593 let mut rsvd0_values = Vec::new();
594 for rsvd in &self.reserved {
595 let rsvd_value = rsvd.default.as_ref().unwrap();
596 let low_bit = Literal::usize_unsuffixed(rsvd.low_bit);
597 let shifted_mask = &rsvd.shifted_mask;
598 let name = format_ident!("RSVD_{}_{}", rsvd.high_bit, rsvd.low_bit);
599
600 field_constants.push(quote! {
601 const #name: #base = (#rsvd_value as #base) << #low_bit;
602 });
603 checks.push(quote! {
604 const { assert!(Self::#name & !(#shifted_mask << #low_bit) == 0) }
605 });
606 rsvd1_values.push(quote! { Self::#name });
607 rsvd0_values.push(quote! {
608 (!Self::#name & (#shifted_mask << #low_bit))
609 });
610 }
611
612 let num_fields = Literal::usize_unsuffixed(self.named.len());
613 let field_metadata = field_metadata.into_iter();
614 field_constants.push(
615 quote! {
616 pub const FIELDS: [::bitfld::FieldMetadata::<#base>; #num_fields] = [
618 #(#field_metadata)*
619 ];
620 }
621 );
622
623 let field_constants = field_constants.into_iter();
624
625 let check_fn = if checks.is_empty() {
626 quote! {}
627 } else {
628 let checks = checks.into_iter();
629 quote! {
630 #[forbid(overflowing_literals)]
631 const fn check_defaults() -> () {
632 #(#checks)*
633 }
634 }
635 };
636
637 if self.reserved.is_empty() {
638 rsvd1_values.push(quote! {0});
639 rsvd0_values.push(quote! {0});
640 }
641 let rsvd1_values = rsvd1_values.into_iter();
642 let rsvd0_values = rsvd0_values.into_iter();
643 let default_values = default_values.into_iter();
644
645 quote! {
646 pub const RSVD1_MASK: #base = #(#rsvd1_values)|* ;
648 pub const RSVD0_MASK: #base = #(#rsvd0_values)|* ;
650 pub const DEFAULT: #base = #(#default_values)|* ;
653
654 #(#field_constants)*
655
656 #check_fn
657 }
658 }
659
660 fn iter_impl(&self) -> TokenStream2 {
661 let ty = &self.ty.def.ident;
662 let base = &self.ty.base.def;
663 let iter_type = format_ident!("{}Iter", ty);
664 let vis = &self.ty.def.vis;
665 let num_fields = Literal::usize_unsuffixed(self.named.len());
666
667 quote! {
668 #[doc(hidden)]
669 #vis struct #iter_type(#base, usize);
670
671 impl ::core::iter::Iterator for #iter_type {
672 type Item = (&'static ::bitfld::FieldMetadata<#base>, #base);
673
674 fn next(&mut self) -> Option<Self::Item> {
675 if self.1 >= #num_fields {
676 return None;
677 }
678 let metadata = &#ty::FIELDS[self.1];
679 let shifted_mask = (1 << (metadata.high_bit - metadata.low_bit + 1)) - 1;
680 let value = (self.0 >> metadata.low_bit) & shifted_mask;
681 self.1 += 1;
682 Some((metadata, value))
683 }
684 }
685
686 impl #ty {
687 pub fn iter(&self) -> impl ::core::iter::Iterator<Item = (&'static ::bitfld::FieldMetadata<#base>, #base, )> {
690 #iter_type(self.0, 0)
691 }
692 }
693
694 impl ::core::iter::IntoIterator for #ty {
695 type Item = (&'static ::bitfld::FieldMetadata<#base>, #base);
696 type IntoIter = #iter_type;
697
698 fn into_iter(self) -> Self::IntoIter { #iter_type(self.0, 0) }
699 }
700
701 impl<'a> ::core::iter::IntoIterator for &'a #ty {
702 type Item = (&'static ::bitfld::FieldMetadata<#base>, #base);
703 type IntoIter = #iter_type;
704
705 fn into_iter(self) -> Self::IntoIter { #iter_type(self.0, 0) }
706 }
707 }
708 }
709
710 fn getters_and_setters(&self) -> impl Iterator<Item = TokenStream2> + '_ {
711 self.named
712 .iter()
713 .map(|field| field.getter_and_setter(&self.ty))
714 }
715
716 fn fmt_fn(&self, integral_specifier: &str) -> TokenStream2 {
717 let ty_str = &self.ty.def.ident.to_string();
718
719 let mut custom_repr_fields = self
720 .named
721 .iter()
722 .filter(|field| field.repr.is_some())
723 .peekable();
724
725 let where_clause = if custom_repr_fields.peek().is_some() {
726 let bounds = custom_repr_fields.map(|field| {
727 let repr = field.repr.as_ref().unwrap();
728 quote! {#repr: ::core::fmt::Debug,}
729 });
730 quote! {
731 where
732 #(#bounds)*
733 }
734 } else {
735 quote! {}
736 };
737
738 let fmt_fields = self.named.iter().enumerate().map(|(idx, field)| {
739 let name = &field.name;
740 let name_str = name.as_ref().unwrap().to_string();
741 let default_specifier = if field.bit_width() == 1 {
742 ""
743 } else {
744 integral_specifier
745 };
746 let comma = if idx < self.named.len() - 1 { "," } else { "" };
747 if field.repr.is_some() {
748 let ok_format_string = format!("{{indent}}{name_str}: {{:#?}}{comma}{{sep}}");
749 let ok_format_string = Literal::string(&ok_format_string);
750 let err_format_string = format!(
751 "{{indent}}{name_str}: InvalidBits({{{default_specifier}}}){comma}{{sep}}"
752 );
753 let err_format_string = Literal::string(&err_format_string);
754 quote! {
755 match self.#name() {
756 Ok(value) => write!(f, #ok_format_string, value),
757 Err(invalid) => write!(f, #err_format_string, invalid.0),
758 }?;
759 }
760 } else {
761 let format_string =
762 format!("{{indent}}{name_str}: {{{default_specifier}}}{comma}{{sep}}");
763 let format_string = Literal::string(&format_string);
764 quote! {write!(f, #format_string, self.#name())?;}
765 }
766 });
767
768 quote! {
769 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result
770 #where_clause
771 {
772 let (sep, indent) = if f.alternate() {
773 ('\n', " ")
774 } else {
775 (' ', "")
776 };
777 write!(f, "{} {{{sep}", #ty_str)?;
778 #(#fmt_fields)*
779 write!(f, "}}")
780 }
781 }
782 }
783
784 fn fmt_impls(&self) -> TokenStream2 {
785 let ty = &self.ty.def.ident;
786 let lower_hex_fmt = self.fmt_fn(":#x");
787 let upper_hex_fmt = self.fmt_fn(":#X");
788 let binary_fmt = self.fmt_fn(":#b");
789 let octal_fmt = self.fmt_fn(":#o");
790 quote! {
791 impl ::core::fmt::Debug for #ty {
792 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
793 ::core::fmt::LowerHex::fmt(self, f)
794 }
795 }
796
797 impl ::core::fmt::Binary for #ty {
798 #binary_fmt
799 }
800
801 impl ::core::fmt::LowerHex for #ty {
802 #lower_hex_fmt
803 }
804
805 impl ::core::fmt::UpperHex for #ty {
806 #upper_hex_fmt
807 }
808
809 impl ::core::fmt::Octal for #ty {
810 #octal_fmt
811 }
812 }
813 }
814}
815
816impl Parse for Bitfields {
817 fn parse(input: ParseStream) -> Result<Self> {
818 let input = {
819 let content;
820 braced!(content in input);
821 content
822 };
823
824 let ty = input.parse::<TypeDef>()?;
825
826 let input = {
827 let content;
828 braced!(content in input);
829 content
830 };
831
832 let mut fields = Vec::new();
833 while !input.is_empty() {
834 fields.push(input.parse::<Bitfield>()?);
835 }
836 fields.sort_by_key(|field| field.low_bit);
837
838 for i in 1..fields.len() {
839 let prev = &fields[i - 1];
840 let curr = &fields[i];
841 if prev.high_bit >= curr.low_bit {
842 return Err(Error::new(
846 curr.span,
847 format!(
848 "field overlaps with another: [{}:{}] vs. [{}:{}]",
849 prev.high_bit,
850 prev.low_bit,
851 curr.high_bit,
852 curr.low_bit
853 ),
854 ));
855 }
856 }
857
858 if let Some(highest) = fields.last() {
859 let highest_possible = ty.base.ty.high_bit();
860 if highest.high_bit > highest_possible {
861 return Err(Error::new(
862 highest.span,
863 format!(
864 "high bit {} exceeds the highest possible value of {highest_possible}",
865 highest.high_bit
866 ),
867 ));
868 }
869 }
870
871 let mut bitfld = Self {
872 ty,
873 named: vec![],
874 reserved: vec![],
875 };
876
877 while let Some(field) = fields.pop() {
878 if field.is_reserved() {
879 if field.default.is_some() {
880 bitfld.reserved.push(field);
881 }
882 } else {
883 bitfld.named.push(field);
884 }
885 }
886
887 Ok(bitfld)
888 }
889}
890
891impl ToTokens for Bitfields {
892 fn to_tokens(&self, tokens: &mut TokenStream2) {
893 let type_def = &self.ty.def;
894 let type_name = &type_def.ident;
895 let base = &self.ty.base.def;
896
897 let constants = self.constants();
898 let getters_and_setters = self.getters_and_setters();
899 let iter_impl = self.iter_impl();
900 let fmt_impls = self.fmt_impls();
901 quote! {
902 #[derive(Copy, Clone, Eq, PartialEq)]
903 #type_def
904
905 impl #type_name {
906 #constants
907
908 pub const fn new() -> Self {
912 Self(Self::RSVD1_MASK)
913 }
914
915 #(#getters_and_setters)*
916 }
917
918 impl ::core::default::Default for #type_name {
919 fn default() -> Self {
922 Self(Self::DEFAULT)
923 }
924 }
925
926 impl ::core::convert::From<#base> for #type_name {
927 #[allow(clippy::bad_bit_mask)]
930 fn from(value: #base) -> Self {
931 debug_assert!(
932 value & Self::RSVD1_MASK == Self::RSVD1_MASK,
933 "from(): Invalid base value ({value:#x}) has reserved-as-1 bits ({:#x}) unset",
934 Self::RSVD1_MASK,
935 );
936 debug_assert!(
937 !value & Self::RSVD0_MASK == Self::RSVD0_MASK,
938 "from(): Invalid base value ({value:#x}) has reserved-as-0 bits ({:#x}) set",
939 Self::RSVD0_MASK,
940 );
941 Self(value)
942 }
943 }
944
945 impl ::core::ops::Deref for #type_name {
946 type Target = #base;
947
948 fn deref(&self) -> &Self::Target {
949 &self.0
950 }
951 }
952
953 impl ::core::ops::DerefMut for #type_name {
954 fn deref_mut(&mut self) -> &mut Self::Target {
955 &mut self.0
956 }
957 }
958
959 #iter_impl
960
961 #fmt_impls
962 }
963 .to_tokens(tokens);
964 }
965}