@@ -4,7 +4,6 @@ use toml_edit::TableLike;
44/// can insert toml comments created from doc comments on fields.
55///
66/// # Attributes
7- /// - `#[flatten = true]`: lets the writer know that the field is flattened into the parent struct.
87/// - `#[child = true]`: writes the doc comments for all fields in the child struct.
98/// - `#[inline = true]`: inlines the struct into `{}` instead of having a separate `[]` header.
109/// - `#[comment_out = true]`: comments out the field.
@@ -23,7 +22,7 @@ use toml_edit::TableLike;
2322/// /// BRIEF DESCRIPTION.
2423/// ///
2524/// /// (optional) LONGER DESCRIPTION.
26- // ///
25+ /// ///
2726/// /// Type | (optional) FIELD TYPE
2827/// /// Valid values | EXPRESSION REPRESENTING VALID VALUES
2928/// /// Examples | (optional) A FEW EXAMPLE VALUES
@@ -65,12 +64,46 @@ use toml_edit::TableLike;
6564/// add newlines when a documentation line crosses ~70 characters, around this long:
6665///
6766/// `----------------------------------------------------------------------`
67+ ///
68+ /// # Shared Values
69+ /// Sometimes multiple different configs will overlap in their fields. Manually duplicating the fields
70+ /// between the structs can lead to maintenance issues as the docs need to be kept in sync. Also using
71+ /// serde's `flatten` is not supported with `deny_unknown_fields`: <https://serde.rs/field-attrs.html#flatten>.
72+ ///
73+ /// So this macro provides a way to define shared fields between configs, just add a `Shared` object
74+ /// with the wanted fields at the top and all structs afterwards will have those fields inserted.
6875macro_rules! config_struct {
76+ (
77+ $(
78+ Shared {
79+ $(
80+ $( #[ child = $s_child: literal] ) ?
81+ $( #[ inline = $s_inline: literal] ) ?
82+ $( #[ comment_out = $s_comment_out: literal] ) ?
83+ $( #[ doc = $s_doc: expr] ) *
84+ $( ##[ $s_field_meta: meta] ) *
85+ pub $s_field: ident: $s_field_ty: ty,
86+ ) +
87+ }
88+ ) ?
89+ ) => { } ;
6990 (
91+ $(
92+ Shared {
93+ $(
94+ $( #[ child = $s_child: literal] ) ?
95+ $( #[ inline = $s_inline: literal] ) ?
96+ $( #[ comment_out = $s_comment_out: literal] ) ?
97+ $( #[ doc = $s_doc: expr] ) *
98+ $( ##[ $s_field_meta: meta] ) *
99+ pub $s_field: ident: $s_field_ty: ty,
100+ ) +
101+ }
102+ ) ?
103+
70104 $( #[ $meta: meta] ) *
71105 pub struct $name: ident {
72106 $(
73- $( #[ flatten = $flat: literal] ) ?
74107 $( #[ child = $child: literal] ) ?
75108 $( #[ inline = $inline: literal] ) ?
76109 $( #[ comment_out = $comment_out: literal] ) ?
@@ -79,6 +112,8 @@ macro_rules! config_struct {
79112 pub $field: ident: $field_ty: ty,
80113 ) *
81114 }
115+
116+ $( $tt: tt) *
82117 ) => {
83118 $( #[ $meta] ) *
84119 pub struct $name {
@@ -87,57 +122,105 @@ macro_rules! config_struct {
87122 $( #[ $field_meta] ) *
88123 pub $field: $field_ty,
89124 ) *
125+ $( $(
126+ $( #[ doc = $s_doc] ) *
127+ $( #[ $s_field_meta] ) *
128+ pub $s_field: $s_field_ty,
129+ ) +) ?
90130 }
91131
92132 impl $name {
93133 #[ allow( unused_labels, clippy:: allow_attributes) ]
94134 pub fn write_docs( doc: & mut dyn :: toml_edit:: TableLike ) {
95135 $(
136+ crate :: config:: macros:: __write_docs!(
137+ $( #[ child = $child] ) ?
138+ $( #[ inline = $inline] ) ?
139+ $( #[ comment_out = $comment_out] ) ?
140+ $( #[ doc = $doc] ) *
141+ $( ##[ $field_meta] ) *
142+ pub $field: $field_ty,
143+ doc,
144+ ) ;
145+ ) *
146+
147+ $( $(
148+ crate :: config:: macros:: __write_docs!(
149+ $( #[ child = $s_child] ) ?
150+ $( #[ inline = $s_inline] ) ?
151+ $( #[ comment_out = $s_comment_out] ) ?
152+ $( #[ doc = $s_doc] ) *
153+ $( ##[ $s_field_meta] ) *
154+ pub $s_field: $s_field_ty,
155+ doc,
156+ ) ;
157+ ) +) ?
158+ }
159+ }
160+
161+ crate :: config:: macros:: config_struct!{
162+ $(
163+ Shared {
164+ $(
165+ $( #[ child = $s_child] ) ?
166+ $( #[ inline = $s_inline] ) ?
167+ $( #[ comment_out = $s_comment_out] ) ?
168+ $( #[ doc = $s_doc] ) *
169+ $( ##[ $s_field_meta] ) *
170+ pub $s_field: $s_field_ty,
171+ ) +
172+ }
173+ ) ?
174+ $( $tt) *
175+ }
176+ } ;
177+ }
96178
97- ' write_field: {
98- let key_str = & stringify!( $field) ;
179+ macro_rules! __write_docs {
180+ (
181+ $( #[ child = $child: literal] ) ?
182+ $( #[ inline = $inline: literal] ) ?
183+ $( #[ comment_out = $comment_out: literal] ) ?
184+ $( #[ doc = $doc: expr] ) *
185+ $( ##[ $field_meta: meta] ) *
186+ pub $field: ident: $field_ty: ty,
99187
100- let mut field_prefix = [ $(
101- format!( "##{}\n " , $doc) ,
102- ) * ] . concat( ) ;
188+ $document: ident,
189+ ) => {
190+ ' write_field: {
191+ let key_str = & stringify!( $field) ;
103192
104- $(
105- if $comment_out {
106- field_prefix. push( '#' ) ;
107- }
108- ) ?
193+ let mut field_prefix = [ $(
194+ format!( "##{}\n " , $doc) ,
195+ ) * ] . concat( ) ;
109196
110- $(
111- if $flat {
112- <$field_ty>:: write_docs( doc) ;
113- break ' write_field;
114- }
115- ) ?
197+ $(
198+ if $comment_out {
199+ field_prefix. push( '#' ) ;
200+ }
201+ ) ?
116202
117- $(
118- if $child {
119- <$field_ty>:: write_docs( doc . get_key_value_mut( & key_str) . unwrap( ) . 1 . as_table_like_mut( ) . unwrap( ) ) ;
120- }
121- ) ?
203+ $(
204+ if $child {
205+ <$field_ty>:: write_docs( $document . get_key_value_mut( & key_str) . unwrap( ) . 1 . as_table_like_mut( ) . unwrap( ) ) ;
206+ }
207+ ) ?
122208
123- if let Some ( table) = doc. entry( & key_str) . or_insert_with( || panic!( ) ) . as_table_mut( ) {
124- $(
125- if $inline {
126- let mut table = table. clone( ) . into_inline_table( ) ;
127- doc. insert( & key_str, :: toml_edit:: Item :: Value ( :: toml_edit:: Value :: InlineTable ( table) ) ) ;
128- doc. key_mut( & key_str) . unwrap( ) . leaf_decor_mut( ) . set_prefix( field_prefix) ;
129- break ' write_field;
130- }
131- ) ?
132- table. decor_mut( ) . set_prefix( format!( "\n {}" , field_prefix) ) ;
133- } else {
134- doc. key_mut( & key_str) . unwrap( ) . leaf_decor_mut( ) . set_prefix( field_prefix) ;
135- }
209+ if let Some ( table) = $document. entry( & key_str) . or_insert_with( || panic!( ) ) . as_table_mut( ) {
210+ $(
211+ if $inline {
212+ let mut table = table. clone( ) . into_inline_table( ) ;
213+ $document. insert( & key_str, :: toml_edit:: Item :: Value ( :: toml_edit:: Value :: InlineTable ( table) ) ) ;
214+ $document. key_mut( & key_str) . unwrap( ) . leaf_decor_mut( ) . set_prefix( field_prefix) ;
215+ break ' write_field;
136216 }
137- ) *
217+ ) ?
218+ table. decor_mut( ) . set_prefix( format!( "\n {}" , field_prefix) ) ;
219+ } else {
220+ $document. key_mut( & key_str) . unwrap( ) . leaf_decor_mut( ) . set_prefix( field_prefix) ;
138221 }
139222 }
140223 } ;
141224}
142225
143- pub ( crate ) use config_struct;
226+ pub ( crate ) use { __write_docs , config_struct} ;
0 commit comments