1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
//! A macro for generating a merged struct from multiple sub-structs. //! //! # Example //! //! ``` //! use multi_structs::multi_structs; //! //! multi_structs! { //! /// The merged struct. //! #[derive(Debug)] //! struct Merged { //! /// Foo //! #[derive(Debug)] //! foo: struct Foo { //! /// a //! a: i32, //! /// b //! b: i64, //! } //! /// Bar //! #[derive(Debug)] //! bar: struct Bar { //! /// c //! c: usize, //! /// d //! d: String, //! } //! } //! } //! //! fn main() { //! let foo = Foo { a: 1, b: 2 }; //! let bar = Bar { c: 3, d: "aaa".to_string() }; //! println!("{:?}, {:?}", foo, bar); //! let merged = Merged::new(foo, bar); //! println!("{:?}", merged); //! let (foo, bar) = merged.split(); //! println!("{:?}, {:?}", foo, bar); //! } //! ``` //! //! See [`example_generated`](./example_generated/index.html) for //! documentation of code generated by the above `multi_structs!` //! expansion. //! //! # Attributes //! //! Attributes can be attached to any struct and field involved. //! //! # Methods //! //! The following methods are defined for the merged struct: //! //! - `new`: create the new merged struct from multiple sub-structs. //! - `split`: split the merged struct into the sub-structs. //! //! # Visibility //! //! The visibility of structs and fields is taken directly from their definitions. For the //! generated methods `new` and `split`, the visibility of the merged struct is assumed. #![no_std] #[cfg(feature = "example_generated")] extern crate std; #[macro_export] macro_rules! multi_structs { { $(#[$($meta:tt)+])* $multi_vis:vis struct $name:ident { $( $(#[$($sub_meta:tt)+])* $sub_vis:vis $var:ident: struct $sub:ident { $( $(#[$($field_meta:tt)+])* $field_vis:vis $field:ident: $ty:ty ),+ $(,)? } )+ } } => { $( $(#[$($sub_meta)+])* $sub_vis struct $sub { $( $(#[$($field_meta)+])* $field_vis $field: $ty, )+ } )+ $(#[$($meta)+])* $multi_vis struct $name { $( $( $(#[$($field_meta)+])* $field_vis $field: $ty, )+ )+ } impl $name { /// Create this struct from sub-structs. $multi_vis fn new( $($var: $sub,)+ ) -> Self { Self { $( $($field: $var.$field,)+ )+ } } /// Split this struct into its sub-structs. $multi_vis fn split(self) -> ($($sub,)+) { ( $( $sub { $($field: self.$field,)+ }, )+ ) } } } } #[cfg(feature = "example_generated")] pub mod example_generated;