spikard_http/testing/
form.rs

1use serde_json::Value;
2
3/// Encode JSON form data as application/x-www-form-urlencoded bytes.
4pub fn encode_urlencoded_body(value: &Value) -> Result<Vec<u8>, String> {
5    match value {
6        Value::String(s) => Ok(s.as_bytes().to_vec()),
7        Value::Null => Ok(Vec::new()),
8        Value::Bool(b) => Ok(b.to_string().into_bytes()),
9        Value::Number(num) => Ok(num.to_string().into_bytes()),
10        Value::Object(_) | Value::Array(_) => serde_qs::to_string(value)
11            .map(|encoded| encoded.into_bytes())
12            .map_err(|err| err.to_string()),
13    }
14}
15
16#[cfg(test)]
17mod tests {
18    use super::*;
19    use serde_json::json;
20
21    #[test]
22    fn encodes_string_as_raw_bytes() {
23        let out = encode_urlencoded_body(&Value::String("a=b&c=d".to_string())).unwrap();
24        assert_eq!(out, b"a=b&c=d");
25    }
26
27    #[test]
28    fn encodes_null_as_empty_body() {
29        let out = encode_urlencoded_body(&Value::Null).unwrap();
30        assert!(out.is_empty());
31    }
32
33    #[test]
34    fn encodes_bool_as_text() {
35        assert_eq!(encode_urlencoded_body(&json!(true)).unwrap(), b"true");
36        assert_eq!(encode_urlencoded_body(&json!(false)).unwrap(), b"false");
37    }
38
39    #[test]
40    fn encodes_number_as_text() {
41        assert_eq!(encode_urlencoded_body(&json!(42)).unwrap(), b"42");
42        assert_eq!(encode_urlencoded_body(&json!(3.5)).unwrap(), b"3.5");
43    }
44
45    #[test]
46    fn encodes_object_using_querystring_format() {
47        let out = encode_urlencoded_body(&json!({"a": 1, "b": "x"})).unwrap();
48        let text = std::str::from_utf8(&out).unwrap();
49        assert!(text.contains("a=1"));
50        assert!(text.contains("b=x"));
51    }
52}