Skip to content

Commit e3f60cc

Browse files
authored
cuprated: Fix config flatten (Cuprate#495)
* Fix config flatten * add back docs on fields * add bach addressbook config
1 parent f882eb2 commit e3f60cc

File tree

7 files changed

+291
-251
lines changed

7 files changed

+291
-251
lines changed

binaries/cuprated/src/config.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ mod macros;
3939
use fs::FileSystemConfig;
4040
use p2p::P2PConfig;
4141
use rayon::RayonConfig;
42-
pub use rpc::{RpcConfig, SharedRpcConfig};
42+
pub use rpc::RpcConfig;
4343
use storage::StorageConfig;
4444
use tokio::TokioConfig;
4545
use tracing_config::TracingConfig;
@@ -213,16 +213,16 @@ impl Config {
213213
cuprate_p2p::P2PConfig {
214214
network: self.network,
215215
seeds: p2p::clear_net_seed_nodes(self.network),
216-
outbound_connections: self.p2p.clear_net.general.outbound_connections,
217-
extra_outbound_connections: self.p2p.clear_net.general.extra_outbound_connections,
218-
max_inbound_connections: self.p2p.clear_net.general.max_inbound_connections,
219-
gray_peers_percent: self.p2p.clear_net.general.gray_peers_percent,
220-
p2p_port: self.p2p.clear_net.general.p2p_port,
216+
outbound_connections: self.p2p.clear_net.outbound_connections,
217+
extra_outbound_connections: self.p2p.clear_net.extra_outbound_connections,
218+
max_inbound_connections: self.p2p.clear_net.max_inbound_connections,
219+
gray_peers_percent: self.p2p.clear_net.gray_peers_percent,
220+
p2p_port: self.p2p.clear_net.p2p_port,
221221
rpc_port: self.rpc.restricted.port_for_p2p(),
222222
address_book_config: self
223223
.p2p
224224
.clear_net
225-
.general
225+
.address_book_config
226226
.address_book_config(&self.fs.cache_directory, self.network),
227227
}
228228
}
@@ -244,7 +244,7 @@ impl Config {
244244
cuprate_blockchain::config::ConfigBuilder::default()
245245
.network(self.network)
246246
.data_directory(self.fs.data_directory.clone())
247-
.sync_mode(blockchain.shared.sync_mode)
247+
.sync_mode(blockchain.sync_mode)
248248
.build()
249249
}
250250

@@ -256,7 +256,7 @@ impl Config {
256256
cuprate_txpool::config::ConfigBuilder::default()
257257
.network(self.network)
258258
.data_directory(self.fs.data_directory.clone())
259-
.sync_mode(txpool.shared.sync_mode)
259+
.sync_mode(txpool.sync_mode)
260260
.build()
261261
}
262262

binaries/cuprated/src/config/args.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl Args {
7474
config.fast_sync = config.fast_sync && !self.no_fast_sync;
7575

7676
if let Some(outbound_connections) = self.outbound_connections {
77-
config.p2p.clear_net.general.outbound_connections = outbound_connections;
77+
config.p2p.clear_net.outbound_connections = outbound_connections;
7878
}
7979

8080
config

binaries/cuprated/src/config/macros.rs

Lines changed: 122 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
6875
macro_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

Comments
 (0)