Skip to main content

edgebase_core/
field_ops.rs

1//! Atomic field operation helpers.
2//!
3//! ```rust,no_run,ignore,no_run
4//! use edgebase_core::field_ops;
5//! use serde_json::json;
6//!
7//! # async fn example(client: &edgebase_core::EdgeBase) -> Result<(), edgebase_core::Error> {
8//! client.table("posts").update("id1", &json!({
9//!     "views": field_ops::increment(1),
10//!     "temp":  field_ops::delete_field(),
11//! })).await?;
12//! # Ok(())
13//! # }
14//! ```
15
16use serde_json::{json, Value};
17
18/// A field operation marker value (e.g. increment, deleteField).
19/// Returned by [`increment`] and [`delete_field`]; passed in update bodies.
20/// Named type to allow `pub use field_ops::FieldOps` in lib.rs.
21pub type FieldOps = Value;
22
23/// Increment a numeric field atomically.
24/// Server interprets as: `field = COALESCE(field, 0) + n`.
25pub fn increment(n: impl Into<f64>) -> Value {
26    json!({ "$op": "increment", "value": n.into() })
27}
28
29/// Delete a field (set to NULL).
30/// Server interprets as: `field = NULL`.
31pub fn delete_field() -> Value {
32    json!({ "$op": "deleteField" })
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn increment_returns_correct_marker() {
41        let marker = increment(1);
42        assert_eq!(marker["$op"], "increment");
43        assert_eq!(marker["value"], 1.0);
44    }
45
46    #[test]
47    fn increment_negative() {
48        let marker = increment(-5);
49        assert_eq!(marker["value"], -5.0);
50    }
51
52    #[test]
53    fn increment_float() {
54        let marker = increment(1.5);
55        assert_eq!(marker["value"], 1.5);
56    }
57
58    #[test]
59    fn delete_field_returns_correct_marker() {
60        let marker = delete_field();
61        assert_eq!(marker["$op"], "deleteField");
62        assert!(marker.get("value").is_none());
63    }
64}