use std::collections::BTreeMap;
use serde_json::Value;
use serde_json::value::RawValue;
use crate::serve::storage::Failure;
fn json_error(error: &serde_json::Error) -> Failure {
Failure::new(
"query_parameters_invalid",
format!("query parameters are not JSON: {error}"),
)
}
fn write(value: &Value, bytes: &mut Vec<u8>) -> Result<(), Failure> {
match value {
Value::Object(object) => {
bytes.push(b'{');
let ordered: BTreeMap<_, _> = object.iter().collect();
for (index, (key, value)) in ordered.into_iter().enumerate() {
if index != 0 {
bytes.push(b',');
}
serde_json::to_writer(&mut *bytes, key).map_err(|error| json_error(&error))?;
bytes.push(b':');
write(value, bytes)?;
}
bytes.push(b'}');
}
Value::Array(array) => {
bytes.push(b'[');
for (index, value) in array.iter().enumerate() {
if index != 0 {
bytes.push(b',');
}
write(value, bytes)?;
}
bytes.push(b']');
}
scalar => serde_json::to_writer(bytes, scalar).map_err(|error| json_error(&error))?,
}
Ok(())
}
pub fn parameters(parameters: &BTreeMap<String, Box<RawValue>>) -> Result<Vec<u8>, Failure> {
let mut bytes = vec![b'{'];
for (index, (name, raw)) in parameters.iter().enumerate() {
if index != 0 {
bytes.push(b',');
}
serde_json::to_writer(&mut bytes, name).map_err(|error| json_error(&error))?;
bytes.push(b':');
let value: Value = serde_json::from_str(raw.get()).map_err(|error| json_error(&error))?;
write(&value, &mut bytes)?;
}
bytes.push(b'}');
Ok(bytes)
}