(value: &Handle, out: &mut String, ctx: &mut SerCtx, depth: usize)
| 136 | } |
| 137 | |
| 138 | fn serialize_object(value: &Handle, out: &mut String, ctx: &mut SerCtx, depth: usize) -> Result<()> { |
| 139 | if ctx.opts.check_circular && depth >= MAX_DEPTH { |
| 140 | return Err(Error::Value("Circular reference detected".into())); |
| 141 | } |
| 142 | out.push('{'); |
| 143 | let keys = value.iter()?; |
| 144 | let n = keys.len()?; |
| 145 | if n == 0 { |
| 146 | out.push('}'); |
| 147 | return Ok(()); |
| 148 | } |
| 149 | let mut pairs: Vec<(String, Handle)> = Vec::with_capacity(n as usize); |
| 150 | for i in 0..n { |
| 151 | let idx = encode(Value::Int(i as i128))?; |
| 152 | let key = keys.get_item(&idx)?; |
| 153 | let key_ty_handle = key.type_of()?; |
| 154 | let key_ty = String::from_handle(key_ty_handle.raw())?; |
| 155 | if key_ty != "str" { |
| 156 | if ctx.opts.skipkeys { continue; } |
| 157 | return Err(Error::Type(format!("keys must be str, not {}", key_ty))); |
| 158 | } |
| 159 | let key_str = match decode(key.raw())? { |
| 160 | Value::Bytes(b) => String::from_utf8(b).map_err(|e| Error::Value(format!("invalid utf-8 in key: {}", e)))?, |
| 161 | _ => return Err(Error::Type("str key decoded as non-bytes".into())), |
| 162 | }; |
| 163 | pairs.push((key_str, key)); |
| 164 | } |
| 165 | if ctx.opts.sort_keys { pairs.sort_by(|a, b| a.0.cmp(&b.0)); } |
| 166 | let indent_str = ctx.opts.indent.map(|n| " ".repeat(n.max(0) as usize)); |
| 167 | for (i, (key_str, key)) in pairs.iter().enumerate() { |
| 168 | let item = value.get_item(key)?; |
| 169 | if i > 0 { out.push_str(&ctx.opts.item_sep); } |
| 170 | write_indent(out, indent_str.as_deref(), depth + 1); |
| 171 | escape_string(key_str, out, ctx.opts.ensure_ascii); |
| 172 | out.push_str(&ctx.opts.key_sep); |
| 173 | serialize_into(&item, out, ctx, depth + 1)?; |
| 174 | } |
| 175 | write_indent(out, indent_str.as_deref(), depth); |
| 176 | out.push('}'); |
| 177 | Ok(()) |
| 178 | } |
| 179 | |
| 180 | fn write_indent(out: &mut String, unit: Option<&str>, depth: usize) { |
| 181 | if let Some(u) = unit { |
no test coverage detected