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}