Skip to main content

aurora_db/network/
http_models.rs

1use crate::error::{AqlError, Result};
2use crate::types::{Document, Value};
3use serde::Deserialize;
4use serde_json::{Value as JsonValue, json};
5use std::collections::HashMap;
6use uuid::Uuid;
7
8// --- API Payload Structs ---
9// These define the shape of JSON the server expects.
10
11#[derive(Deserialize)]
12#[serde(rename_all = "camelCase")]
13pub enum FilterOperator {
14    Eq,
15    Ne,
16    Lt,
17    Lte,
18    Gt,
19    Gte,
20    Contains,
21}
22
23#[derive(Deserialize)]
24pub struct Filter {
25    pub field: String,
26    pub operator: FilterOperator,
27    pub value: JsonValue,
28}
29
30#[derive(Deserialize)]
31pub struct SortOptions {
32    pub field: String,
33    pub ascending: bool,
34}
35
36#[derive(Deserialize)]
37pub struct QueryPayload {
38    pub filters: Option<Vec<Filter>>,
39    pub sort: Option<SortOptions>,
40    pub limit: Option<usize>,
41    pub offset: Option<usize>,
42    pub select: Option<Vec<String>>,
43}
44
45// --- Data Conversion Functions ---
46
47/// Converts an internal `Document` into a clean, client-friendly `serde_json::Value`.
48pub fn document_to_json(doc: &Document) -> JsonValue {
49    let mut map = serde_json::Map::new();
50    // Always include the ID in the output
51    map.insert("id".to_string(), json!(doc.id));
52
53    for (key, value) in &doc.data {
54        map.insert(key.clone(), value_to_json(value));
55    }
56    JsonValue::Object(map)
57}
58
59/// Recursively converts an internal `Value` into a `serde_json::Value`.
60fn value_to_json(value: &Value) -> JsonValue {
61    match value {
62        Value::Null => JsonValue::Null,
63        Value::String(s) => json!(s),
64        Value::Int(i) => json!(i),
65        Value::Float(f) => json!(f),
66        Value::Bool(b) => json!(b),
67        Value::Uuid(u) => json!(u.to_string()),
68        Value::Array(arr) => JsonValue::Array(arr.iter().map(value_to_json).collect()),
69        Value::Object(obj) => {
70            let map = obj
71                .iter()
72                .map(|(k, v)| (k.clone(), value_to_json(v)))
73                .collect();
74            JsonValue::Object(map)
75        }
76    }
77}
78
79/// Converts an incoming `serde_json::Value` (from a request body) into the `HashMap<String, Value>`
80/// that our `insert_map` function expects.
81pub fn json_to_insert_data(json: JsonValue) -> Result<HashMap<String, Value>> {
82    let map = json.as_object().ok_or_else(|| {
83        AqlError::invalid_operation("Request body must be a JSON object".to_string())
84    })?;
85
86    let mut result = HashMap::new();
87    for (key, value) in map {
88        if key.to_lowercase() == "id" {
89            continue; // Ignore client-provided IDs on insert
90        }
91        result.insert(key.clone(), json_to_value(value)?);
92    }
93    Ok(result)
94}
95
96/// Recursively converts a `serde_json::Value` into an internal `Value`.
97pub fn json_to_value(json_value: &JsonValue) -> Result<Value> {
98    match json_value {
99        JsonValue::Null => Ok(Value::Null),
100        JsonValue::Bool(b) => Ok(Value::Bool(*b)),
101        JsonValue::Number(n) => {
102            if let Some(i) = n.as_i64() {
103                Ok(Value::Int(i))
104            } else if let Some(f) = n.as_f64() {
105                Ok(Value::Float(f))
106            } else {
107                Err(AqlError::invalid_operation("Invalid number value".to_string()))
108            }
109        }
110        JsonValue::String(s) => {
111            if let Ok(uuid) = Uuid::parse_str(s) {
112                Ok(Value::Uuid(uuid))
113            } else {
114                Ok(Value::String(s.clone()))
115            }
116        }
117        JsonValue::Array(arr) => {
118            let mut values = Vec::new();
119            for item in arr {
120                values.push(json_to_value(item)?);
121            }
122            Ok(Value::Array(values))
123        }
124        JsonValue::Object(obj) => {
125            let mut map = HashMap::new();
126            for (k, v) in obj {
127                map.insert(k.clone(), json_to_value(v)?);
128            }
129            Ok(Value::Object(map))
130        }
131    }
132}