use crate::ast::InsertValues;
use crate::error::{Error, ParseError};
use serde_json::Value;
use std::collections::HashMap;
pub fn parse_json_body(body: &str) -> Result<Value, Error> {
serde_json::from_str(body).map_err(|e| {
Error::Parse(ParseError::InvalidJsonBody(format!(
"Failed to parse JSON body: {}",
e
)))
})
}
pub fn validate_insert_body(value: Value) -> Result<InsertValues, Error> {
match value {
Value::Object(map) => {
if map.is_empty() {
return Err(Error::Parse(ParseError::InvalidInsertBody(
"Insert body cannot be an empty object".to_string(),
)));
}
let mut hash_map = HashMap::new();
for (k, v) in map {
hash_map.insert(k, v);
}
Ok(InsertValues::Single(hash_map))
}
Value::Array(arr) => {
if arr.is_empty() {
return Err(Error::Parse(ParseError::InvalidInsertBody(
"Insert body cannot be an empty array".to_string(),
)));
}
let mut rows = Vec::new();
for (idx, item) in arr.into_iter().enumerate() {
match item {
Value::Object(map) => {
if map.is_empty() {
return Err(Error::Parse(ParseError::InvalidInsertBody(format!(
"Row {} is an empty object",
idx
))));
}
let mut hash_map = HashMap::new();
for (k, v) in map {
hash_map.insert(k, v);
}
rows.push(hash_map);
}
_ => {
return Err(Error::Parse(ParseError::InvalidInsertBody(format!(
"Row {} must be an object, got {:?}",
idx, item
))));
}
}
}
Ok(InsertValues::Bulk(rows))
}
_ => Err(Error::Parse(ParseError::InvalidInsertBody(
"Insert body must be an object or array of objects".to_string(),
))),
}
}
pub fn validate_update_body(value: Value) -> Result<HashMap<String, Value>, Error> {
match value {
Value::Object(map) => {
if map.is_empty() {
return Err(Error::Parse(ParseError::EmptyUpdateBody));
}
let mut hash_map = HashMap::new();
for (k, v) in map {
hash_map.insert(k, v);
}
Ok(hash_map)
}
_ => Err(Error::Parse(ParseError::InvalidUpdateBody(
"Update body must be an object".to_string(),
))),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_json_body_valid_object() {
let body = r#"{"name": "Alice", "age": 30}"#;
let result = parse_json_body(body);
assert!(result.is_ok());
let value = result.unwrap();
assert!(value.is_object());
}
#[test]
fn test_parse_json_body_valid_array() {
let body = r#"[{"name": "Alice"}, {"name": "Bob"}]"#;
let result = parse_json_body(body);
assert!(result.is_ok());
let value = result.unwrap();
assert!(value.is_array());
}
#[test]
fn test_parse_json_body_invalid_json() {
let body = r#"{"name": "Alice""#; let result = parse_json_body(body);
assert!(result.is_err());
}
#[test]
fn test_validate_insert_body_single_object() {
let value = serde_json::json!({"name": "Alice", "age": 30});
let result = validate_insert_body(value);
assert!(result.is_ok());
let insert_values = result.unwrap();
assert_eq!(insert_values.len(), 1);
}
#[test]
fn test_validate_insert_body_empty_object() {
let value = serde_json::json!({});
let result = validate_insert_body(value);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
Error::Parse(ParseError::InvalidInsertBody(_))
));
}
#[test]
fn test_validate_insert_body_array() {
let value = serde_json::json!([
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25}
]);
let result = validate_insert_body(value);
assert!(result.is_ok());
let insert_values = result.unwrap();
assert_eq!(insert_values.len(), 2);
}
#[test]
fn test_validate_insert_body_empty_array() {
let value = serde_json::json!([]);
let result = validate_insert_body(value);
assert!(result.is_err());
}
#[test]
fn test_validate_insert_body_array_with_empty_object() {
let value = serde_json::json!([{"name": "Alice"}, {}]);
let result = validate_insert_body(value);
assert!(result.is_err());
}
#[test]
fn test_validate_insert_body_array_with_non_object() {
let value = serde_json::json!([{"name": "Alice"}, "invalid"]);
let result = validate_insert_body(value);
assert!(result.is_err());
}
#[test]
fn test_validate_insert_body_invalid_type() {
let value = serde_json::json!("string");
let result = validate_insert_body(value);
assert!(result.is_err());
let value = serde_json::json!(123);
let result = validate_insert_body(value);
assert!(result.is_err());
let value = serde_json::json!(true);
let result = validate_insert_body(value);
assert!(result.is_err());
}
#[test]
fn test_validate_update_body_valid() {
let value = serde_json::json!({"status": "active", "updated_at": "2024-01-01"});
let result = validate_update_body(value);
assert!(result.is_ok());
let update_values = result.unwrap();
assert_eq!(update_values.len(), 2);
assert!(update_values.contains_key("status"));
assert!(update_values.contains_key("updated_at"));
}
#[test]
fn test_validate_update_body_empty_object() {
let value = serde_json::json!({});
let result = validate_update_body(value);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
Error::Parse(ParseError::EmptyUpdateBody)
));
}
#[test]
fn test_validate_update_body_invalid_type() {
let value = serde_json::json!([{"status": "active"}]);
let result = validate_update_body(value);
assert!(result.is_err());
let value = serde_json::json!("string");
let result = validate_update_body(value);
assert!(result.is_err());
}
#[test]
fn test_validate_update_body_nested_values() {
let value = serde_json::json!({
"user": {
"name": "Alice",
"age": 30
},
"metadata": ["tag1", "tag2"]
});
let result = validate_update_body(value);
assert!(result.is_ok());
let update_values = result.unwrap();
assert_eq!(update_values.len(), 2);
}
#[test]
fn test_bulk_insert_consistency() {
let value = serde_json::json!([
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 35}
]);
let result = validate_insert_body(value);
assert!(result.is_ok());
let insert_values = result.unwrap();
match insert_values {
InsertValues::Bulk(rows) => {
assert_eq!(rows.len(), 3);
for row in &rows {
assert!(row.contains_key("name"));
assert!(row.contains_key("age"));
}
}
_ => panic!("Expected Bulk insert"),
}
}
}