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    Add { path: String, value: Value },
13    Remove { path: String },
14    Replace { path: String, value: Value },
15    Move { from: String, path: String },
16    Copy { from: String, path: String },
17    Test { path: String, value: Value },
18}
19
20impl JsonPatchOperation {
21    pub fn add(path: impl Into<String>, value: Value) -> Self {
22        Self::Add {
23            path: path.into(),
24            value,
25        }
26    }
27
28    pub fn remove(path: impl Into<String>) -> Self {
29        Self::Remove { path: path.into() }
30    }
31
32    pub fn replace(path: impl Into<String>, value: Value) -> Self {
33        Self::Replace {
34            path: path.into(),
35            value,
36        }
37    }
38
39    pub fn move_op(from: impl Into<String>, path: impl Into<String>) -> Self {
40        Self::Move {
41            from: from.into(),
42            path: path.into(),
43        }
44    }
45
46    pub fn copy(from: impl Into<String>, path: impl Into<String>) -> Self {
47        Self::Copy {
48            from: from.into(),
49            path: path.into(),
50        }
51    }
52
53    pub fn test(path: impl Into<String>, value: Value) -> Self {
54        Self::Test {
55            path: path.into(),
56            value,
57        }
58    }
59}
60
61#[derive(Debug)]
62pub struct StateDeltaBuilder {
63    operations: Vec<JsonPatchOperation>,
64}
65
66impl StateDeltaBuilder {
67    pub const fn new() -> Self {
68        Self {
69            operations: Vec::new(),
70        }
71    }
72
73    pub fn add(mut self, path: &str, value: Value) -> Self {
74        self.operations.push(JsonPatchOperation::add(path, value));
75        self
76    }
77
78    pub fn replace(mut self, path: &str, value: Value) -> Self {
79        self.operations
80            .push(JsonPatchOperation::replace(path, value));
81        self
82    }
83
84    pub fn remove(mut self, path: &str) -> Self {
85        self.operations.push(JsonPatchOperation::remove(path));
86        self
87    }
88
89    pub fn build(self) -> Vec<JsonPatchOperation> {
90        self.operations
91    }
92}
93
94impl Default for StateDeltaBuilder {
95    fn default() -> Self {
96        Self::new()
97    }
98}