cratestack_axum/query/
computed_params.rs1use std::collections::BTreeMap;
5
6use cratestack_core::CratestackError;
7
8pub fn parse_computed_params_object(
18 raw: &str,
19) -> Result<BTreeMap<String, serde_json::Value>, CratestackError> {
20 let value: serde_json::Value = serde_json::from_str(raw).map_err(|error| {
21 CratestackError::Validation(format!("computedParams must be valid JSON: {error}"))
22 })?;
23 match value {
24 serde_json::Value::Object(map) => Ok(map.into_iter().collect()),
25 _ => Err(CratestackError::Validation(
26 "computedParams must be a JSON object".to_owned(),
27 )),
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn parses_a_valid_computed_params_object() {
37 let map = parse_computed_params_object(r#"{"proxyUrl":{"width":800}}"#)
38 .expect("object should parse");
39 assert_eq!(
40 map.get("proxyUrl"),
41 Some(&serde_json::json!({ "width": 800 }))
42 );
43 }
44
45 #[test]
46 fn rejects_malformed_json() {
47 let error = parse_computed_params_object("{not json").unwrap_err();
48 assert!(matches!(error, CratestackError::Validation(_)));
49 }
50
51 #[test]
52 fn rejects_non_object_json() {
53 let error = parse_computed_params_object("[1,2,3]").unwrap_err();
54 assert!(matches!(error, CratestackError::Validation(_)));
55 }
56
57 #[test]
58 fn accepts_an_empty_object() {
59 let map = parse_computed_params_object("{}").expect("empty object should parse");
60 assert!(map.is_empty());
61 }
62}