use crate::canon::canonicalize_value;
use crate::error::AadError;
use crate::parse::parse_object;
use crate::profile::default::{parse_aad, AadContext};
pub fn parse_default(json: &str) -> Result<AadContext, AadError> {
let parsed = parse_aad(json)?;
AadContext::try_from(parsed)
}
pub fn validate_default(json: &str) -> Result<AadContext, AadError> {
parse_default(json)
}
pub fn canonicalize_default(json: &str) -> Result<Vec<u8>, AadError> {
parse_default(json)?.canonicalize()
}
pub fn canonicalize_default_string(json: &str) -> Result<String, AadError> {
parse_default(json)?.canonicalize_string()
}
pub fn canonicalize_object(json: &str) -> Result<Vec<u8>, AadError> {
let value = parse_object(json)?;
canonicalize_value(&value)
}
pub fn canonicalize_object_string(json: &str) -> Result<String, AadError> {
let bytes = canonicalize_object(json)?;
String::from_utf8(bytes).map_err(|e| AadError::InvalidJson {
message: format!("canonicalized output is not valid UTF-8: {e}"),
})
}
pub fn validate_object(json: &str) -> Result<(), AadError> {
parse_object(json).map(|_| ())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_and_canonicalize_default() {
let json = r#"{"v":1,"tenant":"org_abc","resource":"secrets/db","purpose":"encryption"}"#;
let canonical = canonicalize_default_string(json).unwrap();
assert_eq!(
canonical,
r#"{"purpose":"encryption","resource":"secrets/db","tenant":"org_abc","v":1}"#
);
}
#[test]
fn test_parse_default_roundtrip() {
let original =
r#"{"purpose":"encryption","resource":"secrets/db","tenant":"org_abc","v":1}"#;
let ctx = parse_default(original).unwrap();
let canonical = ctx.canonicalize_string().unwrap();
assert_eq!(canonical, original);
}
#[test]
fn test_validate_default_is_parse_default() {
let json = r#"{"v":1,"tenant":"org_abc","resource":"secrets/db","purpose":"encryption"}"#;
let via_parse = parse_default(json).unwrap();
let via_validate = validate_default(json).unwrap();
assert_eq!(via_parse, via_validate);
}
#[test]
fn test_canonicalize_object_sorts_keys() {
let json = r#"{"z":1,"a":2,"m":3}"#;
let canonical = canonicalize_object_string(json).unwrap();
assert_eq!(canonical, r#"{"a":2,"m":3,"z":1}"#);
}
#[test]
fn test_canonicalize_object_no_profile_fields_required() {
let json = r#"{"foo":"bar","baz":42}"#;
let result = canonicalize_object(json);
assert!(result.is_ok());
}
#[test]
fn test_validate_object_rejects_array() {
let json = r#"[1,2,3]"#;
let result = validate_object(json);
assert!(matches!(result, Err(AadError::InvalidJson { .. })));
}
#[test]
fn test_validate_object_rejects_duplicate_keys() {
let json = r#"{"a":1,"a":2}"#;
let result = validate_object(json);
assert!(matches!(result, Err(AadError::DuplicateKey { .. })));
}
}