Skip to content

Commit 4741ddb

Browse files
apollo_config: update config map by pointers skip optional values
1 parent 3f28fa2 commit 4741ddb

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

crates/apollo_config/src/dumping.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,37 @@ pub fn generate_struct_pointer<T: SerializeConfig>(
8686
res
8787
}
8888

89+
/// Generates pointers for an optional struct:
90+
/// - All fields under `target_prefix` (using `default_instance.dump()`), pointed to by each prefix
91+
/// in `pointer_prefixes`.
92+
/// - The optional flag `<target_prefix>.#is_none`, pointed to by `<prefix>.#is_none` for each
93+
/// prefix in `pointer_prefixes`.
94+
pub fn generate_optional_struct_pointer<T: SerializeConfig>(
95+
target_prefix: ParamPath,
96+
default_instance: &T,
97+
pointer_prefixes: HashSet<ParamPath>,
98+
is_none_default: bool,
99+
is_none_description: &str,
100+
) -> ConfigPointers {
101+
let mut res =
102+
generate_struct_pointer(target_prefix.clone(), default_instance, pointer_prefixes.clone());
103+
104+
// Add a pointer target and pointing params for the optional flag.
105+
let target_is_none_param = format!("{target_prefix}{FIELD_SEPARATOR}{IS_NONE_MARK}");
106+
let pointer_target = ser_pointer_target_param(
107+
target_is_none_param.as_str(),
108+
&is_none_default,
109+
is_none_description,
110+
);
111+
let pointing_params: Pointers = pointer_prefixes
112+
.into_iter()
113+
.map(|prefix| format!("{prefix}{FIELD_SEPARATOR}{IS_NONE_MARK}"))
114+
.collect();
115+
res.push((pointer_target, pointing_params));
116+
117+
res
118+
}
119+
89120
// Converts a serialized param to a pointer target.
90121
fn serialized_param_to_pointer_target(
91122
target_prefix: ParamPath,

crates/apollo_config/src/loading.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,26 @@ pub(crate) fn update_config_map_by_pointers(
204204
pointers_map: &BTreeMap<ParamPath, ParamPath>,
205205
) -> Result<(), ConfigError> {
206206
for (param_path, target_param_path) in pointers_map {
207+
// 1) Resolve flags first: these populate "<prefix>.#is_none" into the config_map.
208+
if param_path.ends_with(&format!("{FIELD_SEPARATOR}{IS_NONE_MARK}")) {
209+
let Some(target_value) = config_map.get(target_param_path) else {
210+
return Err(ConfigError::PointerTargetNotFound {
211+
target_param: target_param_path.to_owned(),
212+
});
213+
};
214+
config_map.insert(param_path.to_owned(), target_value.clone());
215+
continue;
216+
}
217+
218+
// 2) If the optional prefix is already marked as disabled, skip resolving nested pointers.
219+
if let Some((prefix, _)) = param_path.rsplit_once('.') {
220+
if config_map.get(&format!("{prefix}{FIELD_SEPARATOR}{IS_NONE_MARK}"))
221+
== Some(&json!(true))
222+
{
223+
continue;
224+
}
225+
}
226+
207227
let Some(target_value) = config_map.get(target_param_path) else {
208228
return Err(ConfigError::PointerTargetNotFound {
209229
target_param: target_param_path.to_owned(),

0 commit comments

Comments
 (0)