zeebe_rs/set_variables.rs
1use crate::{Client, ClientError, proto};
2use serde::Serialize;
3
4pub struct Initial;
5pub struct WithInstanceKey;
6pub struct WithVariables;
7
8pub trait SetVariablesRequestState {}
9impl SetVariablesRequestState for Initial {}
10impl SetVariablesRequestState for WithInstanceKey {}
11impl SetVariablesRequestState for WithVariables {}
12
13/// Request to update variables for a particular scope
14///
15/// # Variable Scoping
16/// Variables can be set either locally or hierarchically:
17/// - Local: Variables only visible in specified scope
18/// - Hierarchical: Variables propagate up to parent scopes
19///
20/// # Examples
21/// Two scopes with variables:
22/// - Scope 1: `{ "foo": 2 }`
23/// - Scope 2: `{ "bar": 1 }`
24///
25/// Setting `{ "foo": 5 }` in scope 2:
26/// - Local=true: Scope 2 becomes `{ "bar": 1, "foo": 5 }`, Scope 1 unchanged
27/// - Local=false: Scope 1 becomes `{ "foo": 5 }`, Scope 2 unchanged
28///
29/// ```ignore
30///
31/// #[derive(Serialize)]
32/// struct Foo {
33/// bar: String
34/// }
35///
36/// client
37/// .set_variables()
38/// .with_element_instance_key(123456)
39/// .with_variable(Foo {bar: String::from("foobar")})
40/// .send()
41/// .await?;
42/// ```
43#[derive(Debug, Clone)]
44pub struct SetVariablesRequest<T: SetVariablesRequestState> {
45 client: Client,
46 element_instance_key: i64,
47 variables: serde_json::Value,
48 local: bool,
49 operation_reference: Option<u64>,
50 _state: std::marker::PhantomData<T>,
51}
52
53impl<T: SetVariablesRequestState> SetVariablesRequest<T> {
54 pub(crate) fn new(client: Client) -> SetVariablesRequest<Initial> {
55 SetVariablesRequest {
56 client,
57 element_instance_key: 0,
58 variables: serde_json::Value::default(),
59 local: false,
60 operation_reference: None,
61 _state: std::marker::PhantomData,
62 }
63 }
64
65 fn transition<NewState: SetVariablesRequestState>(self) -> SetVariablesRequest<NewState> {
66 SetVariablesRequest {
67 client: self.client,
68 element_instance_key: self.element_instance_key,
69 variables: self.variables,
70 local: self.local,
71 operation_reference: self.operation_reference,
72 _state: std::marker::PhantomData,
73 }
74 }
75}
76
77impl SetVariablesRequest<Initial> {
78 /// Sets the element instance key identifying the scope
79 ///
80 /// # Arguments
81 /// * `element_instance_key` - Key of element instance to update variables for
82 ///
83 /// # Returns
84 /// A `SetVariablesRequest` in the `WithInstanceKey` state
85 pub fn with_element_instance_key(
86 mut self,
87 element_instance_key: i64,
88 ) -> SetVariablesRequest<WithInstanceKey> {
89 self.element_instance_key = element_instance_key;
90 self.transition()
91 }
92}
93
94impl SetVariablesRequest<WithInstanceKey> {
95 /// Sets the variables to update in the scope
96 ///
97 /// # Arguments
98 /// * `data` - Variables as serializable type that will be converted to JSON
99 ///
100 /// # Errors
101 /// Returns `ClientError` if serialization fails
102 ///
103 /// # Returns
104 /// A `SetVariablesRequest` in the `WithVariables` state
105 pub fn with_variable<T: Serialize>(
106 mut self,
107 data: T,
108 ) -> Result<SetVariablesRequest<WithVariables>, ClientError> {
109 self.variables = serde_json::to_value(data)
110 .map_err(|e| ClientError::SerializationFailed { source: e })?;
111 Ok(self.transition())
112 }
113}
114
115impl SetVariablesRequest<WithVariables> {
116 /// Sends the set variables request to the gateway
117 ///
118 /// # Returns
119 /// Response containing the unique key for this operation
120 ///
121 /// # Errors
122 /// - `NOT_FOUND`: No element exists with given key
123 /// - `ClientError`: If the request fails
124 pub async fn send(mut self) -> Result<SetVariablesResponse, ClientError> {
125 let res = self
126 .client
127 .gateway_client
128 .set_variables(proto::SetVariablesRequest {
129 element_instance_key: self.element_instance_key,
130 variables: self.variables.to_string(),
131 local: self.local,
132 operation_reference: self.operation_reference,
133 })
134 .await?;
135
136 Ok(res.into_inner().into())
137 }
138
139 /// Sets a reference ID to correlate this operation with other events
140 ///
141 /// # Arguments
142 /// * `operation_reference` - Unique identifier for correlation
143 ///
144 /// # Returns
145 /// The updated `SetVariablesRequest` with the operation reference set
146 pub fn with_operation_reference(mut self, operation_reference: u64) -> Self {
147 self.operation_reference = Some(operation_reference);
148 self
149 }
150
151 /// Controls variable scope visibility
152 ///
153 /// # Arguments
154 /// * `is_local_scope` - If true, variables only visible in target scope
155 /// If false, variables propagate up to parent scopes
156 ///
157 /// # Returns
158 /// The updated `SetVariablesRequest` with the local scope flag set
159 pub fn set_local_scope(mut self, is_local_scope: bool) -> Self {
160 self.local = is_local_scope;
161 self
162 }
163}
164
165/// Response from setting variables containing the operation key
166///
167/// The key uniquely identifies this set variables operation and can be used
168/// to correlate this operation with other events
169#[derive(Debug, Clone)]
170pub struct SetVariablesResponse {
171 key: i64,
172}
173
174impl From<proto::SetVariablesResponse> for SetVariablesResponse {
175 fn from(value: proto::SetVariablesResponse) -> SetVariablesResponse {
176 SetVariablesResponse { key: value.key }
177 }
178}
179
180impl SetVariablesResponse {
181 /// Returns the unique key identifying this set variables operation
182 ///
183 /// # Returns
184 /// The unique key for this operation
185 pub fn key(&self) -> i64 {
186 self.key
187 }
188}