r is recursive limit
(t: &mut RValueWriter, v: &SBValue, mut r: usize)
| 33 | |
| 34 | /// r is recursive limit |
| 35 | pub(crate) fn write_value(t: &mut RValueWriter, v: &SBValue, mut r: usize) -> Result<Bytes> { |
| 36 | let vtype = v.type_(); |
| 37 | let typename = vtype.name(); |
| 38 | if r == 0 { |
| 39 | log::trace!("Recursive limit reached for {}", typename); |
| 40 | return Ok(t.opaque_v()); |
| 41 | } |
| 42 | r -= 1; |
| 43 | if typename == "&str" { |
| 44 | return Ok(t.strlit_v(&read_str(v)?)); |
| 45 | } |
| 46 | if let Some(ty) = get_union_type(&vtype) { |
| 47 | if (ty.name.starts_with(OPTION_BOX) |
| 48 | && ty.name.ends_with(">>") |
| 49 | && &ty.name[OPTION_BOX.len()..OPTION_BOX.len() + 4] != "dyn ") |
| 50 | || (ty.name.starts_with(RESULT_BOX) |
| 51 | && ty.name.ends_with(">, ()>") // Result<Box<T>, ()> is equivalent to Option<Box<T>> |
| 52 | && &ty.name[RESULT_BOX.len()..RESULT_BOX.len() + 4] != "dyn ") |
| 53 | { |
| 54 | let (none, none_inner, pointee) = if ty.name.starts_with(OPTION_BOX) { |
| 55 | (false, None, &ty.name[OPTION_BOX.len()..ty.name.len() - 2]) |
| 56 | } else { |
| 57 | ( |
| 58 | true, |
| 59 | Some(("0".to_owned(), t.unit_v())), |
| 60 | &ty.name[RESULT_BOX.len()..ty.name.len() - ">, ()>".len()], |
| 61 | ) |
| 62 | }; |
| 63 | let pointee = get_sb_type(&pointee).ok_or(WriteErr)?; |
| 64 | let addr = value_to_bytes::<8>(v)?; |
| 65 | let addr = u64::from_ne_bytes(addr); |
| 66 | return if addr == 0 { |
| 67 | Ok(t.union_v(&ty, none as usize, none_inner.into_iter())) |
| 68 | } else { |
| 69 | let value = t.pointer_to("Box", addr, &pointee, r)?; |
| 70 | Ok(t.union_v(&ty, !none as usize, [("0".to_owned(), value)].into_iter())) |
| 71 | }; |
| 72 | } else if (ty.name.starts_with(OPTION_RC) |
| 73 | && ty.name.ends_with(">>") |
| 74 | && &ty.name[OPTION_RC.len()..OPTION_RC.len() + 4] != "dyn ") |
| 75 | || (ty.name.starts_with(OPTION_ARC) |
| 76 | && ty.name.ends_with(">>") |
| 77 | && &ty.name[OPTION_ARC.len()..OPTION_ARC.len() + 4] != "dyn ") |
| 78 | { |
| 79 | let addr = value_to_bytes::<8>(v)?; |
| 80 | let addr = u64::from_ne_bytes(addr); |
| 81 | return if addr == 0 { |
| 82 | Ok(t.union_v(&ty, 0, [].into_iter())) |
| 83 | } else { |
| 84 | // shockingly we'd have to re-construct the layout manually but Option<Rc / Arc> breaks lldb |
| 85 | let (ptr_ty, pointee_name) = if ty.name.starts_with(OPTION_RC) { |
| 86 | ("rc", &ty.name[OPTION_RC.len()..ty.name.len() - 2]) |
| 87 | } else { |
| 88 | ("arc", &ty.name[OPTION_ARC.len()..ty.name.len() - 2]) |
| 89 | }; |
| 90 | let value = t.ref_counted_to(ptr_ty, addr, pointee_name, r)?; |
| 91 | Ok(t.union_v(&ty, 1, [("0".to_owned(), value)].into_iter())) |
| 92 | }; |
no test coverage detected