use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use serde_json::Value;
pub fn serialize_as_urlenc(value: &Value) -> String {
    match value {
        Value::Null => "null".to_string(),
        Value::Bool(b) => b.to_string(),
        Value::Number(n) => utf8_percent_encode(&n.to_string(), NON_ALPHANUMERIC).to_string(),
        Value::String(s) => utf8_percent_encode(s, NON_ALPHANUMERIC).to_string(),
        Value::Array(arr) => {
            let pairs = arr
                .iter()
                .map(|k| {
                    utf8_percent_encode(
                        &if matches!(k, Value::Array(_) | Value::Object(_)) {
                            utf8_percent_encode(&serialize_as_urlenc(k), NON_ALPHANUMERIC)
                                .to_string()
                        } else {
                            serialize_as_urlenc(k)
                        },
                        NON_ALPHANUMERIC,
                    )
                    .to_string()
                })
                .collect::<Vec<_>>();

            pairs.join("&")
        }
        Value::Object(entries) => {
            let pairs = entries
                .iter()
                .map(|(k, v)| {
                    format!(
                        "{}={}",
                        utf8_percent_encode(k, NON_ALPHANUMERIC),
                        if matches!(v, Value::Array(_) | Value::Object(_)) {
                            utf8_percent_encode(&serialize_as_urlenc(v), NON_ALPHANUMERIC)
                                .to_string()
                        } else {
                            serialize_as_urlenc(v)
                        }
                    )
                })
                .collect::<Vec<_>>();

            pairs.join("&")
        }
    }
}
