Codex Handbook
config/src/fingerprint.rs 67 lines
use codex_app_server_protocol::ConfigLayerMetadata;use serde_json::Value as JsonValue;use sha2::Digest;use sha2::Sha256;use std::collections::HashMap;use toml::Value as TomlValue;pub(super) fn record_origins(    value: &TomlValue,    meta: &ConfigLayerMetadata,    path: &mut Vec<String>,    origins: &mut HashMap<String, ConfigLayerMetadata>,) {    match value {        TomlValue::Table(table) => {            for (key, val) in table {                path.push(key.clone());                record_origins(val, meta, path, origins);                path.pop();            }        }        TomlValue::Array(items) => {            for (idx, item) in (0_i32..).zip(items.iter()) {                path.push(idx.to_string());                record_origins(item, meta, path, origins);                path.pop();            }        }        _ => {            if !path.is_empty() {                origins.insert(path.join("."), meta.clone());            }        }    }}pub fn version_for_toml(value: &TomlValue) -> String {    let json = serde_json::to_value(value).unwrap_or(JsonValue::Null);    let canonical = canonical_json(&json);    let serialized = serde_json::to_vec(&canonical).unwrap_or_default();    let mut hasher = Sha256::new();    hasher.update(serialized);    let hash = hasher.finalize();    let hex = hash        .iter()        .map(|byte| format!("{byte:02x}"))        .collect::<String>();    format!("sha256:{hex}")}fn canonical_json(value: &JsonValue) -> JsonValue {    match value {        JsonValue::Object(map) => {            let mut sorted = serde_json::Map::new();            let mut keys = map.keys().cloned().collect::<Vec<_>>();            keys.sort();            for key in keys {                if let Some(val) = map.get(&key) {                    sorted.insert(key, canonical_json(val));                }            }            JsonValue::Object(sorted)        }        JsonValue::Array(items) => JsonValue::Array(items.iter().map(canonical_json).collect()),        other => other.clone(),    }}