Convert a codex jhistory JSON object to a normalized DataRow
(json: &JsonValue)
| 394 | |
| 395 | /// Convert a codex jhistory JSON object to a normalized DataRow |
| 396 | fn jhistory_json_to_data_row(json: &JsonValue) -> Option<DataRow> { |
| 397 | let obj = json.as_object()?; |
| 398 | |
| 399 | let text = obj |
| 400 | .get("text") |
| 401 | .or_else(|| obj.get("display")) |
| 402 | .and_then(json_value_as_string) |
| 403 | .unwrap_or_default(); |
| 404 | |
| 405 | let session_id = obj |
| 406 | .get("session_id") |
| 407 | .or_else(|| obj.get("sessionId")) |
| 408 | .and_then(json_value_as_string) |
| 409 | .unwrap_or_default(); |
| 410 | |
| 411 | let ts_seconds = obj |
| 412 | .get("ts") |
| 413 | .and_then(json_value_as_i64) |
| 414 | .or_else(|| { |
| 415 | obj.get("timestamp") |
| 416 | .and_then(json_value_as_i64) |
| 417 | .map(normalize_ts_seconds) |
| 418 | }) |
| 419 | .unwrap_or(0); |
| 420 | |
| 421 | let timestamp_millis = ts_seconds.saturating_mul(1000); |
| 422 | |
| 423 | let mut map = BTreeMap::new(); |
| 424 | map.insert("display".to_string(), Value::Str(text.clone())); |
| 425 | map.insert("timestamp".to_string(), Value::I64(timestamp_millis)); |
| 426 | map.insert("session_id".to_string(), Value::Str(session_id.clone())); |
| 427 | map.insert("sessionId".to_string(), Value::Str(session_id)); |
| 428 | map.insert("text".to_string(), Value::Str(text)); |
| 429 | map.insert("ts".to_string(), Value::I64(ts_seconds)); |
| 430 | |
| 431 | // Preserve any extra fields from codex output. |
| 432 | for (key, value) in obj { |
| 433 | if matches!( |
| 434 | key.as_str(), |
| 435 | "display" | "timestamp" | "session_id" | "sessionId" | "text" | "ts" |
| 436 | ) { |
| 437 | continue; |
| 438 | } |
| 439 | map.insert(key.clone(), json_value_to_glue_value(value)); |
| 440 | } |
| 441 | |
| 442 | Some(DataRow::Map(map)) |
| 443 | } |
| 444 | |
| 445 | fn normalize_ts_seconds(raw_ts: i64) -> i64 { |
| 446 | // Convert epoch milliseconds into seconds when needed. |