///|
/// Canonicalize a value and return the lowercase hexadecimal SHA-256 digest
/// of its UTF-8 canonical representation. Hashing canonical bytes gives
/// semantically equivalent JSON documents a stable content identifier.
pub fn canonical_digest(value : JsonValue) -> Result[String, CanonicalError] {
let serialized = match canonicalize(value) {
Ok(serialized) => serialized
Err(error) => return Err(error)
}
let digest = @sha256.Digest::new()
for byte in @utf8.encode(serialized) {
digest.write(byte)
}
Ok(digest.check_sum())
}
///|
/// Hash a JSON document after parsing and canonicalizing it.
pub fn digest_json(input : String) -> Result[String, String] {
let value = match parse(input) {
Ok(value) => value
Err(error) => return Err(error.message())
}
match canonical_digest(value) {
Ok(digest) => Ok(digest)
Err(error) => Err(error.message())
}
}
///|
/// Hash untrusted input after enforcing resource limits during parsing.
pub fn digest_json_with_limits(
input : String,
limits : DocumentLimits,
) -> Result[String, String] {
let value = match parse_with_limits(input, limits) {
Ok(value) => value
Err(error) => return Err(error)
}
match canonical_digest(value) {
Ok(digest) => Ok(digest)
Err(error) => Err(error.message())
}
}