aqara 0.1.1

Aqara SDK for Rust.
Documentation
use serde_json::{Map, Value};

pub(crate) fn redact_json(mut value: Value) -> Value {
    redact_value_in_place(&mut value);
    value
}

pub(crate) fn snippet_from_bytes(bytes: &[u8], max_len: usize) -> String {
    if max_len == 0 {
        return String::new();
    }

    let as_json = serde_json::from_slice::<Value>(bytes).ok();
    let mut s = match as_json {
        Some(v) => redact_json(v).to_string(),
        None => String::from_utf8_lossy(bytes).to_string(),
    };

    if s.len() > max_len {
        s.truncate(max_len);
    }
    s
}

fn redact_value_in_place(value: &mut Value) {
    match value {
        Value::Object(map) => redact_map_in_place(map),
        Value::Array(arr) => {
            for v in arr {
                redact_value_in_place(v);
            }
        }
        _ => {}
    }
}

fn redact_map_in_place(map: &mut Map<String, Value>) {
    for (k, v) in map.iter_mut() {
        if is_sensitive_key(k) {
            *v = Value::String("[REDACTED]".to_string());
            continue;
        }
        redact_value_in_place(v);
    }
}

fn is_sensitive_key(key: &str) -> bool {
    let key = key.trim().to_ascii_lowercase();
    matches!(
        key.as_str(),
        "accesstoken"
            | "access_token"
            | "access-token"
            | "token"
            | "refresh_token"
            | "refreshtoken"
            | "appkey"
            | "app_key"
            | "password"
            | "secret"
    ) || key.contains("token")
}