use sha2::{Digest, Sha256};
use super::error::Result;
pub fn canonicalize_json(json_str: &str) -> Result<String> {
let value: serde_json::Value = serde_json::from_str(json_str)?;
canonicalize_value(&value)
}
pub fn canonicalize_value(value: &serde_json::Value) -> Result<String> {
let canonical = serde_json_canonicalizer::to_string(value)
.map_err(|e| super::error::AcgError::Internal(format!("canonicalization failed: {e}")))?;
Ok(canonical)
}
pub fn normalize_whitespace(text: &str) -> String {
let trimmed = text.trim();
if trimmed.is_empty() {
return String::new();
}
let mut result = String::with_capacity(trimmed.len());
let mut in_whitespace_run = false;
for ch in trimmed.chars() {
if ch == '\n' {
if in_whitespace_run {
in_whitespace_run = false;
}
result.push('\n');
} else if ch.is_whitespace() {
in_whitespace_run = true;
} else {
if in_whitespace_run {
result.push(' ');
in_whitespace_run = false;
}
result.push(ch);
}
}
result
}
pub fn sha256_hex(input: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(input.as_bytes());
let result = hasher.finalize();
let hex: String = result.iter().map(|b| format!("{b:02x}")).collect();
format!("sha256:{hex}")
}
#[cfg(test)]
#[path = "../../tests/unit/acg/canonicalize_tests.rs"]
mod tests;