Skip to main content

systemprompt_models/agui/
json_patch.rs

1//! JSON Patch operations and the state-delta builder for AG-UI events.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(tag = "op", rename_all = "lowercase")]
11pub enum JsonPatchOperation {
12    // JSON: RFC 6902 JSON Patch operation value.
13    Add { path: String, value: Value },
14    Remove { path: String },
15    // JSON: RFC 6902 JSON Patch operation value.
16    Replace { path: String, value: Value },
17    Move { from: String, path: String },
18    Copy { from: String, path: String },
19    // JSON: RFC 6902 JSON Patch operation value.
20    Test { path: String, value: Value },
21}
22
23impl JsonPatchOperation {
24    // JSON: RFC 6902 JSON Patch operation value.
25    pub fn add(path: impl Into<String>, value: Value) -> Self {
26        Self::Add {
27            path: path.into(),
28            value,
29        }
30    }
31
32    pub fn remove(path: impl Into<String>) -> Self {
33        Self::Remove { path: path.into() }
34    }
35
36    // JSON: RFC 6902 JSON Patch operation value.
37    pub fn replace(path: impl Into<String>, value: Value) -> Self {
38        Self::Replace {
39            path: path.into(),
40            value,
41        }
42    }
43
44    pub fn move_op(from: impl Into<String>, path: impl Into<String>) -> Self {
45        Self::Move {
46            from: from.into(),
47            path: path.into(),
48        }
49    }
50
51    pub fn copy(from: impl Into<String>, path: impl Into<String>) -> Self {
52        Self::Copy {
53            from: from.into(),
54            path: path.into(),
55        }
56    }
57
58    // JSON: RFC 6902 JSON Patch operation value.
59    pub fn test(path: impl Into<String>, value: Value) -> Self {
60        Self::Test {
61            path: path.into(),
62            value,
63        }
64    }
65}
66
67#[derive(Debug)]
68pub struct StateDeltaBuilder {
69    operations: Vec<JsonPatchOperation>,
70}
71
72impl StateDeltaBuilder {
73    pub const fn new() -> Self {
74        Self {
75            operations: Vec::new(),
76        }
77    }
78
79    // JSON: RFC 6902 JSON Patch operation value.
80    pub fn add(mut self, path: &str, value: Value) -> Self {
81        self.operations.push(JsonPatchOperation::add(path, value));
82        self
83    }
84
85    // JSON: RFC 6902 JSON Patch operation value.
86    pub fn replace(mut self, path: &str, value: Value) -> Self {
87        self.operations
88            .push(JsonPatchOperation::replace(path, value));
89        self
90    }
91
92    pub fn remove(mut self, path: &str) -> Self {
93        self.operations.push(JsonPatchOperation::remove(path));
94        self
95    }
96
97    pub fn build(self) -> Vec<JsonPatchOperation> {
98        self.operations
99    }
100}
101
102impl Default for StateDeltaBuilder {
103    fn default() -> Self {
104        Self::new()
105    }
106}