1use std::fmt;
16use std::fmt::{Display, Formatter};
17use std::str::FromStr;
18
19pub mod bindings {
20 use wit_bindgen::generate;
21
22 generate!({
23 path: "wit",
24 world: "golem-rust",
25 generate_all,
26 generate_unused_types: true,
27 pub_export_macro: true,
28 with: {
29 "golem:rpc/types@0.2.2": golem_wasm::golem_rpc_0_2_x::types,
30 "wasi:io/poll@0.2.3": golem_wasm::wasi::io::poll,
31 "wasi:clocks/wall-clock@0.2.3": golem_wasm::wasi::clocks::wall_clock
32 }
33 });
34}
35
36#[cfg(feature = "export_load_snapshot")]
37pub mod load_snapshot {
38 use wit_bindgen::generate;
39
40 generate!({
41 path: "wit",
42 world: "golem-rust-load-snapshot",
43 generate_all,
44 generate_unused_types: true,
45 pub_export_macro: true,
46 with: {
47 "golem:rpc/types@0.2.2": golem_wasm::golem_rpc_0_2_x::types,
48 "wasi:io/poll@0.2.3": golem_wasm::wasi::io::poll,
49 "wasi:clocks/wall-clock@0.2.3": golem_wasm::wasi::clocks::wall_clock,
50
51 "golem:api/host@1.3.0": crate::bindings::golem::api::host,
52 "golem:api/oplog@1.3.0": crate::bindings::golem::api::oplog,
53 "golem:api/context@1.3.0": crate::bindings::golem::api::context,
54 "golem:durability/durability@1.3.0": crate::bindings::golem::durability::durability,
55 "golem:rdbms/mysql@0.0.1": crate::bindings::golem::rdbms::mysql,
56 "golem:rdbms/postgres@0.0.1": crate::bindings::golem::rdbms::postgres,
57 "golem:rdbms/types@0.0.1": crate::bindings::golem::rdbms::types,
58 "wasi:blobstore/blobstore": crate::bindings::wasi::blobstore::blobstore,
59 "wasi:blobstore/container": crate::bindings::wasi::blobstore::container,
60 "wasi:blobstore/types": crate::bindings::wasi::blobstore::types,
61 "wasi:clocks/monotonic-clock@0.2.3": crate::bindings::wasi::clocks::monotonic_clock,
62 "wasi:filesystem/preopens@0.2.3": crate::bindings::wasi::filesystem::preopens,
63 "wasi:filesystem/types@0.2.3": crate::bindings::wasi::filesystem::types,
64 "wasi:http/types@0.2.3": crate::bindings::wasi::http::types,
65 "wasi:http/outgoing-handler@0.2.3": crate::bindings::wasi::http::outgoing_handler,
66 "wasi:io/error@0.2.3": crate::bindings::wasi::io::error,
67 "wasi:io/streams@0.2.3": crate::bindings::wasi::io::streams,
68 "wasi:keyvalue/eventual-batch@0.1.0": crate::bindings::wasi::keyvalue::eventual_batch,
69 "wasi:keyvalue/eventual@0.1.0": crate::bindings::wasi::keyvalue::eventual,
70 "wasi:keyvalue/types@0.1.0": crate::bindings::wasi::keyvalue::types,
71 "wasi:keyvalue/wasi-keyvalue-error@0.1.0": crate::bindings::wasi::keyvalue::wasi_keyvalue_error,
72 "wasi:logging/logging": crate::bindings::wasi::logging::logging,
73 "wasi:sockets/ip-name-lookup@0.2.3": crate::bindings::wasi::sockets::ip_name_lookup,
74 "wasi:sockets/instance-network@0.2.3": crate::bindings::wasi::sockets::instance_network,
75 "wasi:sockets/network@0.2.3": crate::bindings::wasi::sockets::network,
76 }
77 });
78
79 pub use __export_golem_rust_load_snapshot_impl as export_load_snapshot;
80}
81
82#[cfg(feature = "export_save_snapshot")]
83pub mod save_snapshot {
84 use wit_bindgen::generate;
85
86 generate!({
87 path: "wit",
88 world: "golem-rust-save-snapshot",
89 generate_all,
90 generate_unused_types: true,
91 pub_export_macro: true,
92 with: {
93 "golem:rpc/types@0.2.2": golem_wasm::golem_rpc_0_2_x::types,
94 "wasi:io/poll@0.2.3": golem_wasm::wasi::io::poll,
95 "wasi:clocks/wall-clock@0.2.3": golem_wasm::wasi::clocks::wall_clock,
96
97 "golem:api/host@1.3.0": crate::bindings::golem::api::host,
98 "golem:api/oplog@1.3.0": crate::bindings::golem::api::oplog,
99 "golem:api/context@1.3.0": crate::bindings::golem::api::context,
100 "golem:durability/durability@1.3.0": crate::bindings::golem::durability::durability,
101 "golem:rdbms/mysql@0.0.1": crate::bindings::golem::rdbms::mysql,
102 "golem:rdbms/postgres@0.0.1": crate::bindings::golem::rdbms::postgres,
103 "golem:rdbms/types@0.0.1": crate::bindings::golem::rdbms::types,
104 "wasi:blobstore/blobstore": crate::bindings::wasi::blobstore::blobstore,
105 "wasi:blobstore/container": crate::bindings::wasi::blobstore::container,
106 "wasi:blobstore/types": crate::bindings::wasi::blobstore::types,
107 "wasi:clocks/monotonic-clock@0.2.3": crate::bindings::wasi::clocks::monotonic_clock,
108 "wasi:filesystem/preopens@0.2.3": crate::bindings::wasi::filesystem::preopens,
109 "wasi:filesystem/types@0.2.3": crate::bindings::wasi::filesystem::types,
110 "wasi:http/types@0.2.3": crate::bindings::wasi::http::types,
111 "wasi:http/outgoing-handler@0.2.3": crate::bindings::wasi::http::outgoing_handler,
112 "wasi:io/error@0.2.3": crate::bindings::wasi::io::error,
113 "wasi:io/streams@0.2.3": crate::bindings::wasi::io::streams,
114 "wasi:keyvalue/eventual-batch@0.1.0": crate::bindings::wasi::keyvalue::eventual_batch,
115 "wasi:keyvalue/eventual@0.1.0": crate::bindings::wasi::keyvalue::eventual,
116 "wasi:keyvalue/types@0.1.0": crate::bindings::wasi::keyvalue::types,
117 "wasi:keyvalue/wasi-keyvalue-error@0.1.0": crate::bindings::wasi::keyvalue::wasi_keyvalue_error,
118 "wasi:logging/logging": crate::bindings::wasi::logging::logging,
119 "wasi:sockets/ip-name-lookup@0.2.3": crate::bindings::wasi::sockets::ip_name_lookup,
120 "wasi:sockets/instance-network@0.2.3": crate::bindings::wasi::sockets::instance_network,
121 "wasi:sockets/network@0.2.3": crate::bindings::wasi::sockets::network,
122 }
123 });
124
125 pub use __export_golem_rust_save_snapshot_impl as export_save_snapshot;
126}
127
128#[cfg(feature = "export_golem_agentic")]
129pub mod golem_agentic {
130 use wit_bindgen::generate;
131
132 generate!({
133 path: "wit",
134 world: "golem-agentic",
135 generate_all,
136 generate_unused_types: true,
137 pub_export_macro: true,
138 with: {
139 "golem:rpc/types@0.2.2": golem_wasm::golem_rpc_0_2_x::types,
140 }
141 });
142
143 pub use __export_golem_agentic_impl as export_golem_agentic;
144}
145
146#[cfg(feature = "export_oplog_processor")]
147pub mod oplog_processor {
148 use wit_bindgen::generate;
149
150 generate!({
151 path: "wit",
152 world: "golem-rust-oplog-processor",
153 generate_all,
154 generate_unused_types: true,
155 pub_export_macro: true,
156 with: {
157 "golem:rpc/types@0.2.2": golem_wasm::golem_rpc_0_2_x::types,
158 "wasi:io/poll@0.2.3": golem_wasm::wasi::io::poll,
159 "wasi:clocks/wall-clock@0.2.3": golem_wasm::wasi::clocks::wall_clock,
160
161 "golem:api/host@1.3.0": crate::bindings::golem::api::host,
162 "golem:api/oplog@1.3.0": crate::bindings::golem::api::oplog,
163 "golem:api/context@1.3.0": crate::bindings::golem::api::context,
164 "golem:durability/durability@1.3.0": crate::bindings::golem::durability::durability,
165 "golem:rdbms/mysql@0.0.1": crate::bindings::golem::rdbms::mysql,
166 "golem:rdbms/postgres@0.0.1": crate::bindings::golem::rdbms::postgres,
167 "golem:rdbms/types@0.0.1": crate::bindings::golem::rdbms::types,
168 "wasi:blobstore/blobstore": crate::bindings::wasi::blobstore::blobstore,
169 "wasi:blobstore/container": crate::bindings::wasi::blobstore::container,
170 "wasi:blobstore/types": crate::bindings::wasi::blobstore::types,
171 "wasi:clocks/monotonic-clock@0.2.3": crate::bindings::wasi::clocks::monotonic_clock,
172 "wasi:filesystem/preopens@0.2.3": crate::bindings::wasi::filesystem::preopens,
173 "wasi:filesystem/types@0.2.3": crate::bindings::wasi::filesystem::types,
174 "wasi:http/types@0.2.3": crate::bindings::wasi::http::types,
175 "wasi:http/outgoing-handler@0.2.3": crate::bindings::wasi::http::outgoing_handler,
176 "wasi:io/error@0.2.3": crate::bindings::wasi::io::error,
177 "wasi:io/streams@0.2.3": crate::bindings::wasi::io::streams,
178 "wasi:keyvalue/eventual-batch@0.1.0": crate::bindings::wasi::keyvalue::eventual_batch,
179 "wasi:keyvalue/eventual@0.1.0": crate::bindings::wasi::keyvalue::eventual,
180 "wasi:keyvalue/types@0.1.0": crate::bindings::wasi::keyvalue::types,
181 "wasi:keyvalue/wasi-keyvalue-error@0.1.0": crate::bindings::wasi::keyvalue::wasi_keyvalue_error,
182 "wasi:logging/logging": crate::bindings::wasi::logging::logging,
183 "wasi:sockets/ip-name-lookup@0.2.3": crate::bindings::wasi::sockets::ip_name_lookup,
184 "wasi:sockets/instance-network@0.2.3": crate::bindings::wasi::sockets::instance_network,
185 "wasi:sockets/network@0.2.3": crate::bindings::wasi::sockets::network,
186 }
187 });
188
189 pub use __export_golem_rust_oplog_processor_impl as export_oplog_processor;
190}
191
192#[cfg(feature = "export_golem_agentic")]
193pub mod agentic;
194
195#[cfg(feature = "durability")]
196pub mod durability;
197
198#[cfg(feature = "json")]
199mod json;
200
201#[cfg(feature = "json")]
202pub use json::*;
203
204mod transaction;
205pub mod value_and_type;
206
207use bindings::golem::api::host::*;
208
209pub use golem_wasm as wasm_rpc;
210
211pub use bindings::golem::api::host::{fork, oplog_commit};
212pub use bindings::golem::api::host::{ForkResult, PersistenceLevel};
213
214pub use transaction::*;
215
216#[cfg(feature = "macro")]
217pub use golem_rust_macro::*;
218
219impl Display for PromiseId {
220 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
221 write!(f, "{}/{}", self.agent_id, self.oplog_idx)
222 }
223}
224
225impl FromStr for PromiseId {
226 type Err = String;
227
228 fn from_str(s: &str) -> Result<Self, Self::Err> {
229 let parts: Vec<&str> = s.split('/').collect();
230 if parts.len() == 2 {
231 let agent_id = AgentId::from_str(parts[0]).map_err(|_| {
232 format!("invalid agent id: {s} - expected format: <component_id>/<agent_id>")
233 })?;
234 let oplog_idx = parts[1]
235 .parse()
236 .map_err(|_| format!("invalid oplog index: {s} - expected integer"))?;
237 Ok(Self {
238 agent_id,
239 oplog_idx,
240 })
241 } else {
242 Err(format!(
243 "invalid promise id: {s} - expected format: <agent_id>/<oplog_idx>"
244 ))
245 }
246 }
247}
248
249#[derive(Clone, Debug, PartialEq)]
250pub struct RetryPolicy {
251 pub max_attempts: u32,
252 pub min_delay: std::time::Duration,
253 pub max_delay: std::time::Duration,
254 pub multiplier: f64,
255 pub max_jitter_factor: Option<f64>,
256}
257
258impl From<bindings::golem::api::host::RetryPolicy> for RetryPolicy {
259 fn from(value: bindings::golem::api::host::RetryPolicy) -> Self {
260 Self {
261 max_attempts: value.max_attempts,
262 min_delay: std::time::Duration::from_nanos(value.min_delay),
263 max_delay: std::time::Duration::from_nanos(value.max_delay),
264 multiplier: value.multiplier,
265 max_jitter_factor: value.max_jitter_factor,
266 }
267 }
268}
269
270impl From<RetryPolicy> for bindings::golem::api::host::RetryPolicy {
271 fn from(val: RetryPolicy) -> Self {
272 bindings::golem::api::host::RetryPolicy {
273 max_attempts: val.max_attempts,
274 min_delay: val.min_delay.as_nanos() as u64,
275 max_delay: val.max_delay.as_nanos() as u64,
276 multiplier: val.multiplier,
277 max_jitter_factor: val.max_jitter_factor,
278 }
279 }
280}
281
282pub struct PersistenceLevelGuard {
283 original_level: PersistenceLevel,
284}
285
286impl Drop for PersistenceLevelGuard {
287 fn drop(&mut self) {
288 set_oplog_persistence_level(self.original_level);
289 }
290}
291
292#[must_use]
296pub fn use_persistence_level(level: PersistenceLevel) -> PersistenceLevelGuard {
297 let original_level = get_oplog_persistence_level();
298 set_oplog_persistence_level(level);
299 PersistenceLevelGuard { original_level }
300}
301
302pub fn with_persistence_level<R>(level: PersistenceLevel, f: impl FnOnce() -> R) -> R {
304 let _guard = use_persistence_level(level);
305 f()
306}
307
308pub struct IdempotenceModeGuard {
309 original: bool,
310}
311
312impl Drop for IdempotenceModeGuard {
313 fn drop(&mut self) {
314 set_idempotence_mode(self.original);
315 }
316}
317
318#[must_use]
322pub fn use_idempotence_mode(mode: bool) -> IdempotenceModeGuard {
323 let original = get_idempotence_mode();
324 set_idempotence_mode(mode);
325 IdempotenceModeGuard { original }
326}
327
328pub fn with_idempotence_mode<R>(mode: bool, f: impl FnOnce() -> R) -> R {
330 let _guard = use_idempotence_mode(mode);
331 f()
332}
333
334pub fn generate_idempotency_key() -> uuid::Uuid {
338 Into::into(bindings::golem::api::host::generate_idempotency_key())
339}
340
341pub struct RetryPolicyGuard {
342 original: RetryPolicy,
343}
344
345impl Drop for RetryPolicyGuard {
346 fn drop(&mut self) {
347 set_retry_policy(Into::into(self.original.clone()));
348 }
349}
350
351#[must_use]
355pub fn use_retry_policy(policy: RetryPolicy) -> RetryPolicyGuard {
356 let original = Into::into(get_retry_policy());
357 set_retry_policy(Into::into(policy));
358 RetryPolicyGuard { original }
359}
360
361pub fn with_retry_policy<R>(policy: RetryPolicy, f: impl FnOnce() -> R) -> R {
363 let _guard = use_retry_policy(policy);
364 f()
365}
366
367pub struct AtomicOperationGuard {
368 begin: OplogIndex,
369}
370
371impl Drop for AtomicOperationGuard {
372 fn drop(&mut self) {
373 mark_end_operation(self.begin);
374 }
375}
376
377#[must_use]
382pub fn mark_atomic_operation() -> AtomicOperationGuard {
383 let begin = mark_begin_operation();
384 AtomicOperationGuard { begin }
385}
386
387pub fn atomically<T>(f: impl FnOnce() -> T) -> T {
391 let _guard = mark_atomic_operation();
392 f()
393}