k8s_openapi_codegen_common/templates/
struct_deep_merge.rs

1pub(crate) fn generate(
2    mut writer: impl std::io::Write,
3    type_name: &str,
4    generics: super::Generics<'_>,
5    fields: &[super::Property<'_>],
6    map_namespace: &impl crate::MapNamespace,
7) -> Result<(), crate::Error> {
8    let local = crate::map_namespace_local_to_string(map_namespace)?;
9
10    let type_generics_type = generics.type_part.map(|part| format!("<{part}>")).unwrap_or_default();
11    let type_generics_where = generics.where_part.map(|part| format!(" where {part}")).unwrap_or_default();
12
13    let mut merge_body = String::new();
14    for super::Property { field_name, merge_type, .. } in fields {
15        generate_field(
16            &mut merge_body,
17            &local,
18            &format!("&mut self.{field_name}"),
19            &format!("other.{field_name}"),
20            merge_type,
21            8,
22        )?;
23    }
24
25    writeln!(
26        writer,
27        include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/struct_deep_merge.rs")),
28        local = local,
29        type_name = type_name,
30        type_generics_type = type_generics_type,
31        type_generics_where = type_generics_where,
32        merge_body = merge_body,
33    )?;
34
35    Ok(())
36}
37
38fn generate_field(
39    writer: &mut impl std::fmt::Write,
40    local: &str,
41    self_name: &str,
42    other_name: &str,
43    merge_type: &crate::swagger20::MergeType,
44    indent: usize,
45) -> Result<(), crate::Error> {
46    const S: &str = "";
47
48    match merge_type {
49        crate::swagger20::MergeType::Default => writeln!(
50            writer,
51            "{S:indent$}{local}DeepMerge::merge_from({self_name}, {other_name});",
52        )?,
53
54        crate::swagger20::MergeType::List {
55            strategy: crate::swagger20::KubernetesListType::Atomic,
56            keys: _,
57            item_merge_type: _,
58        } => writeln!(
59            writer,
60            "{S:indent$}{local}merge_strategies::list::atomic({self_name}, {other_name});",
61        )?,
62
63        crate::swagger20::MergeType::List {
64            strategy: crate::swagger20::KubernetesListType::Map,
65            keys,
66            item_merge_type,
67        } => {
68            writeln!(writer, "{S:indent$}{local}merge_strategies::list::map(")?;
69            writeln!(writer, "{S:indent$}    {self_name},")?;
70            writeln!(writer, "{S:indent$}    {other_name},")?;
71            writeln!(
72                writer,
73                "{S:indent$}    &[{keys}],",
74                keys = keys.iter().map(|k| format!("|lhs, rhs| lhs.{k} == rhs.{k}", k = crate::get_rust_ident(k))).collect::<Vec<_>>().join(", "),
75            )?;
76            writeln!(writer, "{S:indent$}    |current_item, other_item| {{")?;
77            generate_field(writer, local, "current_item", "other_item", item_merge_type, indent + 8)?;
78            writeln!(writer, "{S:indent$}    }},")?;
79            writeln!(writer, "{S:indent$});")?;
80        },
81
82        crate::swagger20::MergeType::List {
83            strategy: crate::swagger20::KubernetesListType::Set,
84            keys: _,
85            item_merge_type: _,
86        } => writeln!(
87            writer,
88            "{S:indent$}{local}merge_strategies::list::set({self_name}, {other_name});",
89        )?,
90
91        crate::swagger20::MergeType::Map {
92            strategy: crate::swagger20::KubernetesMapType::Granular,
93            value_merge_type,
94        } => {
95            writeln!(
96                writer,
97                "{S:indent$}{local}merge_strategies::map::granular({self_name}, {other_name}, |current_item, other_item| {{",
98            )?;
99            generate_field(writer, local, "current_item", "other_item", value_merge_type, indent + 4)?;
100            writeln!(writer, "{S:indent$}}});")?;
101        },
102
103        crate::swagger20::MergeType::Map {
104            strategy: crate::swagger20::KubernetesMapType::Atomic,
105            value_merge_type: _,
106        } => writeln!(
107            writer,
108            "{S:indent$}{local}merge_strategies::map::atomic({self_name}, {other_name});",
109        )?,
110    }
111
112    Ok(())
113}