k8s_openapi_codegen_common/templates/
impl_deserialize.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 resource_metadata: Option<&super::ResourceMetadata<'_>>,
8) -> Result<(), crate::Error> {
9 use std::fmt::Write;
10
11 let local = crate::map_namespace_local_to_string(map_namespace)?;
12
13 let type_generics_impl: std::borrow::Cow<'_, str> = match generics.type_part {
14 Some(part) => format!("<'de, {part}>").into(),
15 None => "<'de>".into(),
16 };
17 let type_generics_type = generics.type_part.map(|part| format!("<{part}>")).unwrap_or_default();
18 let type_generics_where = generics.where_part.map(|part| format!(" where {part}")).unwrap_or_default();
19
20 let (visitor_field, visitor_create_field) =
21 if type_generics_type.is_empty() {
22 (String::new(), "")
23 }
24 else {
25 (format!("(core::marker::PhantomData{type_generics_type})"), "(Default::default())")
26 };
27
28 let mut fields_string = String::new();
29 let mut str_to_field_match_arms = String::new();
30 let mut field_value_defs = String::new();
31 let mut field_value_match_arms = String::new();
32 let mut field_name_list = String::new();
33 let mut field_value_assignment = String::new();
34
35 let mut flattened_field = None;
36
37 if resource_metadata.is_some() {
38 writeln!(fields_string, " Key_api_version,")?;
39 writeln!(fields_string, " Key_kind,")?;
40
41 writeln!(str_to_field_match_arms, r#" "apiVersion" => Field::Key_api_version,"#)?;
42 writeln!(str_to_field_match_arms, r#" "kind" => Field::Key_kind,"#)?;
43
44 writeln!(field_value_match_arms, r#" Field::Key_api_version => {{"#)?;
45 writeln!(field_value_match_arms, r#" let value_api_version: std::string::String = {local}serde::de::MapAccess::next_value(&mut map)?;"#)?;
46 writeln!(field_value_match_arms, r#" if value_api_version != <Self::Value as {local}Resource>::API_VERSION {{"#)?;
47 writeln!(field_value_match_arms,
48 r#" return Err({local}serde::de::Error::invalid_value({local}serde::de::Unexpected::Str(&value_api_version), &<Self::Value as {local}Resource>::API_VERSION));"#)?;
49 writeln!(field_value_match_arms, r#" }}"#)?;
50 writeln!(field_value_match_arms, r#" }},"#)?;
51
52 writeln!(field_value_match_arms, r#" Field::Key_kind => {{"#)?;
53 writeln!(field_value_match_arms, r#" let value_kind: std::string::String = {local}serde::de::MapAccess::next_value(&mut map)?;"#)?;
54 writeln!(field_value_match_arms, r#" if value_kind != <Self::Value as {local}Resource>::KIND {{"#)?;
55 writeln!(field_value_match_arms,
56 r#" return Err({local}serde::de::Error::invalid_value({local}serde::de::Unexpected::Str(&value_kind), &<Self::Value as {local}Resource>::KIND));"#)?;
57 writeln!(field_value_match_arms, r#" }}"#)?;
58 writeln!(field_value_match_arms, r#" }},"#)?;
59
60 writeln!(field_name_list, r#" "apiVersion","#)?;
61 writeln!(field_name_list, r#" "kind","#)?;
62 }
63 for super::Property { name, field_name, field_type_name, required, is_flattened, .. } in fields {
64 if *is_flattened {
65 if flattened_field.is_some() {
66 return Err(format!("{type_name} has two flattened fields").into());
67 }
68
69 flattened_field = Some((field_name, field_type_name));
70
71 writeln!(field_value_defs,
72 r#" let mut value_{field_name}: {local}serde_json::Map<std::string::String, {local}serde_json::Value> = Default::default();"#)?;
73 }
74 else {
75 writeln!(fields_string, " Key_{field_name},")?;
76
77 writeln!(str_to_field_match_arms, r#" {name:?} => Field::Key_{field_name},"#)?;
78
79 match required {
80 super::PropertyRequired::Required { is_default } => {
81 writeln!(field_value_defs, r#" let mut value_{field_name}: Option<{field_type_name}> = None;"#)?;
82
83 if *is_default {
93 writeln!(field_value_match_arms,
94 r#" Field::Key_{field_name} => value_{field_name} = {local}serde::de::MapAccess::next_value(&mut map)?,"#)?;
95
96 writeln!(field_value_assignment, " {field_name}: value_{field_name}.unwrap_or_default(),")?;
97 }
98 else {
99 writeln!(field_value_match_arms,
100 r#" Field::Key_{field_name} => value_{field_name} = Some({local}serde::de::MapAccess::next_value(&mut map)?),"#)?;
101
102 writeln!(field_value_assignment,
103 " {field_name}: value_{field_name}.ok_or_else(|| {local}serde::de::Error::missing_field({name:?}))?,")?;
104 }
105 },
106
107 super::PropertyRequired::Optional => {
108 writeln!(field_value_defs, r#" let mut value_{field_name}: {field_type_name} = None;"#)?;
109
110 writeln!(field_value_match_arms,
111 r#" Field::Key_{field_name} => value_{field_name} = {local}serde::de::MapAccess::next_value(&mut map)?,"#)?;
112
113 writeln!(field_value_assignment, " {field_name}: value_{field_name},")?;
114 },
115
116 super::PropertyRequired::OptionalDefault => {
117 writeln!(field_value_defs, r#" let mut value_{field_name}: Option<{field_type_name}> = None;"#)?;
118
119 writeln!(field_value_match_arms,
120 r#" Field::Key_{field_name} => value_{field_name} = {local}serde::de::MapAccess::next_value(&mut map)?,"#)?;
121
122 writeln!(field_value_assignment, " {field_name}: value_{field_name}.unwrap_or_default(),")?;
123 },
124 }
125
126 writeln!(field_name_list, r#" {name:?},"#)?;
127 }
128 }
129
130 if let Some((field_name, _)) = flattened_field {
131 writeln!(fields_string, " Other(String),")?;
132
133 writeln!(str_to_field_match_arms, " v => Field::Other(v.into()),")?;
134
135 writeln!(field_value_match_arms,
136 " Field::Other(key) => {{ value_{field_name}.insert(key, {local}serde::de::MapAccess::next_value(&mut map)?); }},")?;
137
138 writeln!(field_value_assignment,
139 " {field_name}: {{")?;
140 writeln!(field_value_assignment,
141 " let value_{field_name} = {local}serde::Deserialize::deserialize(value_{field_name}).map_err({local}serde::de::Error::custom)?;")?;
142 writeln!(field_value_assignment,
143 " value_{field_name}")?;
144 writeln!(field_value_assignment,
145 " }},")?;
146 }
147 else {
148 writeln!(fields_string, " Other,")?;
149
150 writeln!(str_to_field_match_arms, " _ => Field::Other,")?;
151
152 writeln!(field_value_match_arms,
153 " Field::Other => {{ let _: {local}serde::de::IgnoredAny = {local}serde::de::MapAccess::next_value(&mut map)?; }},")?;
154 }
155
156 let deserialize_type_name =
157 if resource_metadata.is_some() {
158 format!("<Self as {local}Resource>::KIND")
159 }
160 else {
161 format!("{type_name:?}")
162 };
163
164 let visitor_expecting_type_name =
165 if resource_metadata.is_some() {
166 format!("<Self::Value as {local}Resource>::KIND")
167 }
168 else {
169 format!("{type_name:?}")
170 };
171
172 writeln!(
173 writer,
174 include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/impl_deserialize.rs")),
175 local = local,
176 type_name = type_name,
177 type_generics_impl = type_generics_impl,
178 type_generics_type = type_generics_type,
179 type_generics_where = type_generics_where,
180 fields = fields_string,
181 str_to_field_match_arms = str_to_field_match_arms,
182 field_value_defs = field_value_defs,
183 field_value_match_arms = field_value_match_arms,
184 field_value_assignment = field_value_assignment,
185 field_name_list = field_name_list,
186 visitor_field = visitor_field,
187 visitor_create_field = visitor_create_field,
188 deserialize_type_name = deserialize_type_name,
189 visitor_expecting_type_name = visitor_expecting_type_name,
190 )?;
191
192 Ok(())
193}