1use ahash::AHashSet;
2use alef_core::ir::{CoreWrapper, PrimitiveType, TypeDef, TypeRef};
3use std::fmt::Write;
4
5use super::ConversionConfig;
6use super::binding_to_core::field_conversion_to_core;
7use super::helpers::is_newtype;
8use super::helpers::{binding_prim_str, core_type_path, needs_i64_cast};
9
10pub fn gen_from_core_to_binding(typ: &TypeDef, core_import: &str, opaque_types: &AHashSet<String>) -> String {
12 gen_from_core_to_binding_cfg(typ, core_import, opaque_types, &ConversionConfig::default())
13}
14
15pub fn gen_from_core_to_binding_cfg(
17 typ: &TypeDef,
18 core_import: &str,
19 opaque_types: &AHashSet<String>,
20 config: &ConversionConfig,
21) -> String {
22 let core_path = core_type_path(typ, core_import);
23 let binding_name = format!("{}{}", config.type_name_prefix, typ.name);
24 let mut out = String::with_capacity(256);
25 writeln!(out, "impl From<{core_path}> for {binding_name} {{").ok();
26 writeln!(out, " fn from(val: {core_path}) -> Self {{").ok();
27
28 if is_newtype(typ) {
30 let field = &typ.fields[0];
31 let inner_expr = match &field.ty {
32 TypeRef::Named(_) => "val.0.into()".to_string(),
33 TypeRef::Path => "val.0.to_string_lossy().to_string()".to_string(),
34 TypeRef::Duration => "val.0.as_millis() as u64".to_string(),
35 _ => "val.0".to_string(),
36 };
37 writeln!(out, " Self {{ _0: {inner_expr} }}").ok();
38 writeln!(out, " }}").ok();
39 write!(out, "}}").ok();
40 return out;
41 }
42
43 let optionalized = config.optionalize_defaults && typ.has_default;
44 writeln!(out, " Self {{").ok();
45 for field in &typ.fields {
46 if !config.exclude_types.is_empty()
48 && super::helpers::field_references_excluded_type(&field.ty, config.exclude_types)
49 {
50 continue;
51 }
52 let base_conversion = field_conversion_from_core_cfg(
53 &field.name,
54 &field.ty,
55 field.optional,
56 field.sanitized,
57 opaque_types,
58 config,
59 );
60 let base_conversion = if field.is_boxed && matches!(&field.ty, TypeRef::Named(_)) {
62 if field.optional {
63 let src = format!("{}: val.{}.map(Into::into)", field.name, field.name);
65 let dst = format!("{}: val.{}.map(|v| (*v).into())", field.name, field.name);
66 if base_conversion == src { dst } else { base_conversion }
67 } else {
68 base_conversion.replace(&format!("val.{}", field.name), &format!("(*val.{})", field.name))
70 }
71 } else {
72 base_conversion
73 };
74 let base_conversion = if field.newtype_wrapper.is_some() {
80 match &field.ty {
81 TypeRef::Optional(_) => {
82 base_conversion.replace(
84 &format!("val.{}", field.name),
85 &format!("val.{}.map(|v| v.0)", field.name),
86 )
87 }
88 TypeRef::Vec(_) => {
89 base_conversion.replace(
91 &format!("val.{}", field.name),
92 &format!("val.{}.iter().map(|v| v.0).collect::<Vec<_>>()", field.name),
93 )
94 }
95 _ if field.optional => base_conversion.replace(
98 &format!("val.{}", field.name),
99 &format!("val.{}.map(|v| v.0)", field.name),
100 ),
101 _ => {
102 base_conversion.replace(&format!("val.{}", field.name), &format!("val.{}.0", field.name))
104 }
105 }
106 } else {
107 base_conversion
108 };
109 let is_flattened_optional = field.optional && matches!(field.ty, TypeRef::Optional(_));
115 let base_conversion = if is_flattened_optional {
116 if let TypeRef::Optional(inner) = &field.ty {
117 let inner_conv = field_conversion_from_core_cfg(
119 &field.name,
120 inner.as_ref(),
121 true,
122 field.sanitized,
123 opaque_types,
124 config,
125 );
126 inner_conv.replace(&format!("val.{}", field.name), &format!("val.{}.flatten()", field.name))
128 } else {
129 base_conversion
130 }
131 } else {
132 base_conversion
133 };
134 let needs_some_wrap = !is_flattened_optional
138 && ((optionalized && !field.optional)
139 || (config.option_duration_on_defaults
140 && typ.has_default
141 && !field.optional
142 && matches!(field.ty, TypeRef::Duration)));
143 let conversion = if needs_some_wrap {
144 if let Some(expr) = base_conversion.strip_prefix(&format!("{}: ", field.name)) {
146 format!("{}: Some({})", field.name, expr)
147 } else {
148 base_conversion
149 }
150 } else {
151 base_conversion
152 };
153 let conversion = if !field.sanitized {
156 apply_core_wrapper_from_core(
157 &conversion,
158 &field.name,
159 &field.core_wrapper,
160 &field.vec_inner_core_wrapper,
161 field.optional,
162 )
163 } else {
164 conversion
165 };
166 if field.cfg.is_some() {
168 continue;
169 }
170 writeln!(out, " {conversion},").ok();
171 }
172
173 writeln!(out, " }}").ok();
174 writeln!(out, " }}").ok();
175 write!(out, "}}").ok();
176 out
177}
178
179pub fn field_conversion_from_core(
182 name: &str,
183 ty: &TypeRef,
184 optional: bool,
185 sanitized: bool,
186 opaque_types: &AHashSet<String>,
187) -> String {
188 if sanitized {
192 if let TypeRef::Map(k, v) = ty {
194 if matches!(k.as_ref(), TypeRef::String) && matches!(v.as_ref(), TypeRef::String) {
195 if optional {
196 return format!(
197 "{name}: val.{name}.as_ref().map(|m| m.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect())"
198 );
199 }
200 return format!(
201 "{name}: val.{name}.into_iter().map(|(k, v)| (k.to_string(), v.to_string())).collect()"
202 );
203 }
204 }
205 if let TypeRef::Vec(inner) = ty {
208 if matches!(inner.as_ref(), TypeRef::String) {
209 if optional {
210 return format!(
211 "{name}: val.{name}.as_ref().map(|v| v.iter().map(|i| format!(\"{{:?}}\", i)).collect())"
212 );
213 }
214 return format!("{name}: val.{name}.iter().map(|i| format!(\"{{:?}}\", i)).collect()");
215 }
216 }
217 if let TypeRef::Optional(opt_inner) = ty {
219 if let TypeRef::Vec(vec_inner) = opt_inner.as_ref() {
220 if matches!(vec_inner.as_ref(), TypeRef::String) {
221 return format!(
222 "{name}: val.{name}.as_ref().map(|v| v.iter().map(|i| format!(\"{{:?}}\", i)).collect())"
223 );
224 }
225 if matches!(vec_inner.as_ref(), TypeRef::Primitive(_)) {
229 return format!(
230 "{name}: val.{name}.as_ref().and_then(|v| serde_json::to_value(v).ok()).and_then(|v| serde_json::from_value(v).ok())"
231 );
232 }
233 }
234 }
235 if let TypeRef::Vec(inner) = ty {
239 if matches!(inner.as_ref(), TypeRef::Primitive(_)) {
240 if optional {
241 return format!(
242 "{name}: val.{name}.as_ref().and_then(|v| serde_json::to_value(v).ok()).and_then(|v| serde_json::from_value(v).ok())"
243 );
244 }
245 return format!(
246 "{name}: serde_json::to_value(&val.{name}).ok().and_then(|v| serde_json::from_value(v).ok()).unwrap_or_default()"
247 );
248 }
249 }
250 if matches!(ty, TypeRef::String) {
254 if optional {
255 return format!("{name}: val.{name}.as_ref().map(|v| format!(\"{{v:?}}\"))");
256 }
257 return format!("{name}: format!(\"{{:?}}\", val.{name})");
258 }
259 if matches!(ty, TypeRef::Named(_)) {
264 if optional {
265 return format!("{name}: None");
266 }
267 return format!("{name}: String::new()");
268 }
269 if let TypeRef::Optional(inner) = ty {
271 if matches!(inner.as_ref(), TypeRef::Named(_)) {
272 return format!("{name}: None");
273 }
274 }
275 if optional {
278 return format!("{name}: val.{name}.as_ref().map(|v| format!(\"{{v:?}}\"))");
279 }
280 return format!("{name}: format!(\"{{:?}}\", val.{name})");
281 }
282 match ty {
283 TypeRef::Duration => {
285 if optional {
286 return format!("{name}: val.{name}.map(|d| d.as_millis() as u64)");
287 }
288 format!("{name}: val.{name}.as_millis() as u64")
289 }
290 TypeRef::Path => {
292 if optional {
293 format!("{name}: val.{name}.map(|p| p.to_string_lossy().to_string())")
294 } else {
295 format!("{name}: val.{name}.to_string_lossy().to_string()")
296 }
297 }
298 TypeRef::Optional(inner) if matches!(inner.as_ref(), TypeRef::Path) => {
299 format!("{name}: val.{name}.map(|p| p.to_string_lossy().to_string())")
300 }
301 TypeRef::Char => {
303 if optional {
304 format!("{name}: val.{name}.map(|c| c.to_string())")
305 } else {
306 format!("{name}: val.{name}.to_string()")
307 }
308 }
309 TypeRef::Bytes => {
311 if optional {
312 format!("{name}: val.{name}.map(|v| v.to_vec())")
313 } else {
314 format!("{name}: val.{name}.to_vec()")
315 }
316 }
317 TypeRef::Named(n) if opaque_types.contains(n.as_str()) => {
319 if optional {
320 format!("{name}: val.{name}.map(|v| {n} {{ inner: Arc::new(v) }})")
321 } else {
322 format!("{name}: {n} {{ inner: Arc::new(val.{name}) }}")
323 }
324 }
325 TypeRef::Json => {
327 if optional {
328 format!("{name}: val.{name}.as_ref().map(ToString::to_string)")
329 } else {
330 format!("{name}: val.{name}.to_string()")
331 }
332 }
333 TypeRef::Optional(inner) if matches!(inner.as_ref(), TypeRef::Json) => {
334 format!("{name}: val.{name}.as_ref().map(ToString::to_string)")
335 }
336 TypeRef::Vec(inner) if matches!(inner.as_ref(), TypeRef::Json) => {
337 if optional {
338 format!("{name}: val.{name}.as_ref().map(|v| v.iter().map(|i| i.to_string()).collect())")
339 } else {
340 format!("{name}: val.{name}.iter().map(ToString::to_string).collect()")
341 }
342 }
343 TypeRef::Vec(inner) if matches!(inner.as_ref(), TypeRef::Optional(oi) if matches!(oi.as_ref(), TypeRef::Json)) => {
345 if optional {
346 format!(
347 "{name}: val.{name}.as_ref().map(|v| v.iter().map(|i| i.as_ref().map(ToString::to_string)).collect())"
348 )
349 } else {
350 format!("{name}: val.{name}.iter().map(|i| i.as_ref().map(ToString::to_string)).collect()")
351 }
352 }
353 TypeRef::Map(k, v) if matches!(v.as_ref(), TypeRef::Json) => {
355 let k_is_json = matches!(k.as_ref(), TypeRef::Json);
356 let k_expr = if k_is_json { "k.to_string()" } else { "k" };
357 if optional {
358 format!("{name}: val.{name}.map(|m| m.into_iter().map(|(k, v)| ({k_expr}, v.to_string())).collect())")
359 } else {
360 format!("{name}: val.{name}.into_iter().map(|(k, v)| ({k_expr}, v.to_string())).collect()")
361 }
362 }
363 TypeRef::Map(k, _v) if matches!(k.as_ref(), TypeRef::Json) => {
365 if optional {
366 format!("{name}: val.{name}.map(|m| m.into_iter().map(|(k, v)| (k.to_string(), v)).collect())")
367 } else {
368 format!("{name}: val.{name}.into_iter().map(|(k, v)| (k.to_string(), v)).collect()")
369 }
370 }
371 _ => field_conversion_to_core(name, ty, optional),
373 }
374}
375
376pub fn field_conversion_from_core_cfg(
378 name: &str,
379 ty: &TypeRef,
380 optional: bool,
381 sanitized: bool,
382 opaque_types: &AHashSet<String>,
383 config: &ConversionConfig,
384) -> String {
385 if sanitized {
390 if config.map_uses_jsvalue {
391 if let TypeRef::Map(k, v) = ty {
393 if matches!(k.as_ref(), TypeRef::String) && matches!(v.as_ref(), TypeRef::String) {
394 if optional {
395 return format!(
396 "{name}: val.{name}.as_ref().and_then(|v| serde_wasm_bindgen::to_value(v).ok())"
397 );
398 }
399 return format!("{name}: serde_wasm_bindgen::to_value(&val.{name}).unwrap_or(JsValue::NULL)");
400 }
401 }
402 if let TypeRef::Vec(inner) = ty {
404 if matches!(inner.as_ref(), TypeRef::Json) {
405 if optional {
406 return format!(
407 "{name}: val.{name}.as_ref().and_then(|v| serde_wasm_bindgen::to_value(v).ok())"
408 );
409 }
410 return format!("{name}: serde_wasm_bindgen::to_value(&val.{name}).unwrap_or(JsValue::NULL)");
411 }
412 }
413 }
414 return field_conversion_from_core(name, ty, optional, sanitized, opaque_types);
415 }
416
417 if config.vec_named_to_string {
421 if let TypeRef::Vec(_) = ty {
422 if optional {
423 return format!("{name}: val.{name}.as_ref().and_then(|v| serde_json::to_string(v).ok())");
424 }
425 return format!("{name}: serde_json::to_string(&val.{name}).unwrap_or_default()");
426 }
427 }
428
429 if config.map_uses_jsvalue {
431 let is_nested_vec = matches!(ty, TypeRef::Vec(inner) if matches!(inner.as_ref(), TypeRef::Vec(_)));
432 let is_map = matches!(ty, TypeRef::Map(_, _));
433 if is_nested_vec || is_map {
434 if optional {
435 return format!("{name}: val.{name}.as_ref().and_then(|v| serde_wasm_bindgen::to_value(v).ok())");
436 }
437 return format!("{name}: serde_wasm_bindgen::to_value(&val.{name}).unwrap_or(JsValue::NULL)");
438 }
439 if let TypeRef::Optional(inner) = ty {
440 let is_inner_nested = matches!(inner.as_ref(), TypeRef::Vec(vi) if matches!(vi.as_ref(), TypeRef::Vec(_)));
441 let is_inner_map = matches!(inner.as_ref(), TypeRef::Map(_, _));
442 if is_inner_nested || is_inner_map {
443 return format!("{name}: val.{name}.as_ref().and_then(|v| serde_wasm_bindgen::to_value(v).ok())");
444 }
445 }
446 }
447
448 let prefix = config.type_name_prefix;
449 let is_enum_string = |n: &str| -> bool { config.enum_string_names.as_ref().is_some_and(|names| names.contains(n)) };
450
451 match ty {
452 TypeRef::Primitive(p) if config.cast_large_ints_to_i64 && needs_i64_cast(p) => {
454 let cast_to = binding_prim_str(p);
455 if optional {
456 format!("{name}: val.{name}.map(|v| v as {cast_to})")
457 } else {
458 format!("{name}: val.{name} as {cast_to}")
459 }
460 }
461 TypeRef::Optional(inner)
463 if config.cast_large_ints_to_i64
464 && matches!(inner.as_ref(), TypeRef::Primitive(p) if needs_i64_cast(p)) =>
465 {
466 if let TypeRef::Primitive(p) = inner.as_ref() {
467 let cast_to = binding_prim_str(p);
468 format!("{name}: val.{name}.map(|v| v as {cast_to})")
469 } else {
470 field_conversion_from_core(name, ty, optional, sanitized, opaque_types)
471 }
472 }
473 TypeRef::Primitive(PrimitiveType::F32) if config.cast_f32_to_f64 => {
475 if optional {
476 format!("{name}: val.{name}.map(|v| v as f64)")
477 } else {
478 format!("{name}: val.{name} as f64")
479 }
480 }
481 TypeRef::Duration if config.cast_large_ints_to_i64 => {
483 if optional {
484 format!("{name}: val.{name}.map(|d| d.as_millis() as u64 as i64)")
485 } else {
486 format!("{name}: val.{name}.as_millis() as u64 as i64")
487 }
488 }
489 TypeRef::Named(n) if opaque_types.contains(n.as_str()) && !prefix.is_empty() => {
491 let prefixed = format!("{prefix}{n}");
492 if optional {
493 format!("{name}: val.{name}.map(|v| {prefixed} {{ inner: Arc::new(v) }})")
494 } else {
495 format!("{name}: {prefixed} {{ inner: Arc::new(val.{name}) }}")
496 }
497 }
498 TypeRef::Named(n) if is_enum_string(n) => {
500 if optional {
503 format!(
504 "{name}: val.{name}.as_ref().map(|v| serde_json::to_value(v).ok().and_then(|s| s.as_str().map(String::from)).unwrap_or_default())"
505 )
506 } else {
507 format!(
508 "{name}: serde_json::to_value(val.{name}).ok().and_then(|s| s.as_str().map(String::from)).unwrap_or_default()"
509 )
510 }
511 }
512 TypeRef::Vec(inner) if matches!(inner.as_ref(), TypeRef::Named(n) if is_enum_string(n)) => {
514 if optional {
515 format!(
516 "{name}: val.{name}.as_ref().map(|v| v.iter().map(|x| serde_json::to_value(x).ok().and_then(|s| s.as_str().map(String::from)).unwrap_or_default()).collect())"
517 )
518 } else {
519 format!(
520 "{name}: val.{name}.iter().map(|v| serde_json::to_value(v).ok().and_then(|s| s.as_str().map(String::from)).unwrap_or_default()).collect()"
521 )
522 }
523 }
524 TypeRef::Optional(inner) if matches!(inner.as_ref(), TypeRef::Vec(vi) if matches!(vi.as_ref(), TypeRef::Named(n) if is_enum_string(n))) =>
526 {
527 format!(
528 "{name}: val.{name}.as_ref().map(|v| v.iter().map(|x| serde_json::to_value(x).ok().and_then(|s| s.as_str().map(String::from)).unwrap_or_default()).collect())"
529 )
530 }
531 TypeRef::Vec(inner)
533 if config.cast_f32_to_f64 && matches!(inner.as_ref(), TypeRef::Primitive(PrimitiveType::F32)) =>
534 {
535 if optional {
536 format!("{name}: val.{name}.as_ref().map(|v| v.iter().map(|&x| x as f64).collect())")
537 } else {
538 format!("{name}: val.{name}.iter().map(|&v| v as f64).collect()")
539 }
540 }
541 TypeRef::Optional(inner)
543 if config.cast_f32_to_f64
544 && matches!(inner.as_ref(), TypeRef::Vec(vi) if matches!(vi.as_ref(), TypeRef::Primitive(PrimitiveType::F32))) =>
545 {
546 format!("{name}: val.{name}.as_ref().map(|v| v.iter().map(|&x| x as f64).collect())")
547 }
548 TypeRef::Vec(outer)
550 if config.cast_f32_to_f64
551 && matches!(outer.as_ref(), TypeRef::Vec(inner) if matches!(inner.as_ref(), TypeRef::Primitive(PrimitiveType::F32))) =>
552 {
553 if optional {
554 format!(
555 "{name}: val.{name}.as_ref().map(|v| v.iter().map(|inner| inner.iter().map(|&x| x as f64).collect()).collect())"
556 )
557 } else {
558 format!("{name}: val.{name}.iter().map(|inner| inner.iter().map(|&x| x as f64).collect()).collect()")
559 }
560 }
561 TypeRef::Optional(inner)
563 if config.cast_f32_to_f64
564 && matches!(inner.as_ref(), TypeRef::Vec(outer) if matches!(outer.as_ref(), TypeRef::Vec(prim) if matches!(prim.as_ref(), TypeRef::Primitive(PrimitiveType::F32)))) =>
565 {
566 format!(
567 "{name}: val.{name}.as_ref().map(|v| v.iter().map(|inner| inner.iter().map(|&x| x as f64).collect()).collect())"
568 )
569 }
570 TypeRef::Optional(inner)
572 if config.cast_large_ints_to_i64
573 && matches!(inner.as_ref(), TypeRef::Primitive(p) if needs_i64_cast(p)) =>
574 {
575 if let TypeRef::Primitive(p) = inner.as_ref() {
576 let cast_to = binding_prim_str(p);
577 format!("{name}: val.{name}.map(|v| v as {cast_to})")
578 } else {
579 field_conversion_from_core(name, ty, optional, sanitized, opaque_types)
580 }
581 }
582 TypeRef::Map(_k, v)
584 if config.cast_large_ints_to_i64 && matches!(v.as_ref(), TypeRef::Primitive(p) if needs_i64_cast(p)) =>
585 {
586 if let TypeRef::Primitive(p) = v.as_ref() {
587 let cast_to = binding_prim_str(p);
588 if optional {
589 format!(
590 "{name}: val.{name}.as_ref().map(|m| m.iter().map(|(k, v)| (k.clone(), *v as {cast_to})).collect())"
591 )
592 } else {
593 format!("{name}: val.{name}.iter().map(|(k, v)| (k.clone(), *v as {cast_to})).collect()")
594 }
595 } else {
596 field_conversion_from_core(name, ty, optional, sanitized, opaque_types)
597 }
598 }
599 TypeRef::Vec(inner)
601 if config.cast_large_ints_to_i64
602 && matches!(inner.as_ref(), TypeRef::Primitive(p) if needs_i64_cast(p)) =>
603 {
604 if let TypeRef::Primitive(p) = inner.as_ref() {
605 let cast_to = binding_prim_str(p);
606 if optional {
607 format!("{name}: val.{name}.as_ref().map(|v| v.iter().map(|&x| x as {cast_to}).collect())")
608 } else {
609 format!("{name}: val.{name}.iter().map(|&v| v as {cast_to}).collect()")
610 }
611 } else {
612 field_conversion_from_core(name, ty, optional, sanitized, opaque_types)
613 }
614 }
615 TypeRef::Vec(outer)
617 if config.cast_large_ints_to_i64
618 && matches!(outer.as_ref(), TypeRef::Vec(inner) if matches!(inner.as_ref(), TypeRef::Primitive(p) if needs_i64_cast(p))) =>
619 {
620 if let TypeRef::Vec(inner) = outer.as_ref() {
621 if let TypeRef::Primitive(p) = inner.as_ref() {
622 let cast_to = binding_prim_str(p);
623 if optional {
624 format!(
625 "{name}: val.{name}.as_ref().map(|v| v.iter().map(|inner| inner.iter().map(|&x| x as {cast_to}).collect()).collect())"
626 )
627 } else {
628 format!(
629 "{name}: val.{name}.iter().map(|inner| inner.iter().map(|&x| x as {cast_to}).collect()).collect()"
630 )
631 }
632 } else {
633 field_conversion_from_core(name, ty, optional, sanitized, opaque_types)
634 }
635 } else {
636 field_conversion_from_core(name, ty, optional, sanitized, opaque_types)
637 }
638 }
639 TypeRef::Json if config.json_to_string => {
641 if optional {
642 format!("{name}: val.{name}.as_ref().map(ToString::to_string)")
643 } else {
644 format!("{name}: val.{name}.to_string()")
645 }
646 }
647 TypeRef::Json if config.map_uses_jsvalue => {
649 if optional {
650 format!("{name}: val.{name}.as_ref().and_then(|v| serde_wasm_bindgen::to_value(v).ok())")
651 } else {
652 format!("{name}: serde_wasm_bindgen::to_value(&val.{name}).unwrap_or(JsValue::NULL)")
653 }
654 }
655 TypeRef::Vec(inner) if config.map_uses_jsvalue && matches!(inner.as_ref(), TypeRef::Json) => {
657 if optional {
658 format!("{name}: val.{name}.as_ref().and_then(|v| serde_wasm_bindgen::to_value(v).ok())")
659 } else {
660 format!("{name}: serde_wasm_bindgen::to_value(&val.{name}).unwrap_or(JsValue::NULL)")
661 }
662 }
663 TypeRef::Optional(inner)
665 if config.map_uses_jsvalue
666 && matches!(inner.as_ref(), TypeRef::Vec(vi) if matches!(vi.as_ref(), TypeRef::Json)) =>
667 {
668 format!("{name}: val.{name}.as_ref().and_then(|v| serde_wasm_bindgen::to_value(v).ok())")
669 }
670 _ => field_conversion_from_core(name, ty, optional, sanitized, opaque_types),
672 }
673}
674
675fn apply_core_wrapper_from_core(
678 conversion: &str,
679 name: &str,
680 core_wrapper: &CoreWrapper,
681 vec_inner_core_wrapper: &CoreWrapper,
682 optional: bool,
683) -> String {
684 if *vec_inner_core_wrapper == CoreWrapper::Arc {
686 return conversion
687 .replace(".map(Into::into).collect()", ".map(|v| (*v).clone().into()).collect()")
688 .replace(
689 "map(|v| v.into_iter().map(Into::into)",
690 "map(|v| v.into_iter().map(|v| (*v).clone().into())",
691 );
692 }
693
694 match core_wrapper {
695 CoreWrapper::None => conversion.to_string(),
696 CoreWrapper::Cow => {
697 if let Some(expr) = conversion.strip_prefix(&format!("{name}: ")) {
702 if optional {
703 conversion.to_string()
705 } else if expr == format!("val.{name}") {
706 format!("{name}: val.{name}.into_owned()")
707 } else {
708 conversion.to_string()
709 }
710 } else {
711 conversion.to_string()
712 }
713 }
714 CoreWrapper::Arc => {
715 if let Some(expr) = conversion.strip_prefix(&format!("{name}: ")) {
717 if optional {
718 format!("{name}: {expr}.map(|v| (*v).clone().into())")
719 } else {
720 let unwrapped = expr.replace(&format!("val.{name}"), &format!("(*val.{name}).clone()"));
721 format!("{name}: {unwrapped}")
722 }
723 } else {
724 conversion.to_string()
725 }
726 }
727 CoreWrapper::Bytes => {
728 if let Some(expr) = conversion.strip_prefix(&format!("{name}: ")) {
730 if optional {
731 format!("{name}: {expr}.map(|v| v.to_vec())")
732 } else if expr == format!("val.{name}") {
733 format!("{name}: val.{name}.to_vec()")
734 } else {
735 conversion.to_string()
736 }
737 } else {
738 conversion.to_string()
739 }
740 }
741 CoreWrapper::ArcMutex => {
742 if let Some(expr) = conversion.strip_prefix(&format!("{name}: ")) {
744 if optional {
745 format!("{name}: {expr}.map(|v| v.lock().unwrap().clone().into())")
746 } else if expr == format!("val.{name}") {
747 format!("{name}: val.{name}.lock().unwrap().clone().into()")
748 } else {
749 conversion.to_string()
750 }
751 } else {
752 conversion.to_string()
753 }
754 }
755 }
756}