packages feed

temporal-sdk-core (empty) → 2025.10.1.0

raw patch · 22 files changed

+10619/−0 lines, 22 filesdep +aesondep +asyncdep +basebuild-type:Customsetup-changed

Dependencies added: aeson, async, base, bytestring, containers, lens-family, monad-logger, mtl, network-bsd, proto-lens, stm, temporal-api-protos, text, unix, unliftio, unordered-containers, uuid, vector

Files

+ LICENSE view
@@ -0,0 +1,29 @@+BSD 3-Clause License++Copyright (c) 2023-2025, Ian Duncan & Mercury Technologies++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this+   list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice,+   this list of conditions and the following disclaimer in the documentation+   and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its+   contributors may be used to endorse or promote products derived from+   this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ Setup.hs view
@@ -0,0 +1,177 @@+import Control.Monad+import Data.Char (toLower)+import Data.Functor (($>))+import Data.Maybe (fromMaybe)+import Distribution.PackageDescription+import Distribution.Simple+import Distribution.Simple.LocalBuildInfo (+  InstallDirs (..),+  LocalBuildInfo (..),+  absoluteInstallDirs,+  buildDir,+  localPkgDescr,+ )+import Distribution.Simple.Program.Find (+  defaultProgramSearchPath,+  findProgramOnSearchPath,+ )+import Distribution.Simple.Setup+import Distribution.Simple.Utils (+  IODataMode (IODataModeBinary),+  installExecutableFile,+  maybeExit,+  rawSystemStdInOut,+ )+import Distribution.System+import Distribution.Verbosity (Verbosity)+import qualified Distribution.Verbosity as Verbosity+import System.Directory (+  getCurrentDirectory,+ )+import System.Environment (getEnv)+import System.FilePath ((</>))+import System.Posix.Files (createSymbolicLink)+++main :: IO ()+main = defaultMainWithHooks hooks+  where+    hooks =+      simpleUserHooks+        { preConf = \_ flags -> do+            unlessFlagM externalLibFlag flags $ rsMake (fromFlag $ configVerbosity flags)+            pure emptyHookedBuildInfo+        , confHook = \a flags -> do+            lbi <- confHook simpleUserHooks a flags >>= rsAddLibraryInfo flags+            unless (cabalFlag externalLibFlag flags) $ do+              copyTemporalBridge lbi (buildDir lbi)+            pure lbi+        , postClean = \_ flags _ _ ->+            rsClean (fromFlag $ cleanVerbosity flags)+        , postCopy =+            installTemporalBridge+        }+++rsFolder :: FilePath+rsFolder = "rust"+++externalLibFlagStr :: String+externalLibFlagStr = "external_lib"+++externalLibFlag :: FlagName+externalLibFlag = mkFlagName externalLibFlagStr+++execCargo :: Verbosity -> String -> [String] -> IO ()+execCargo verbosity command args = do+  cargoPath <- findProgramOnSearchPath Verbosity.silent defaultProgramSearchPath "cargo"+  dir <- getCurrentDirectory+  let cargoExec = case cargoPath of+        Just (p, _) -> p+        Nothing -> "cargo"+      cargoArgs = command : args+      workingDir = Just (dir </> rsFolder)+      thirdComponent (_, _, c) = c+  maybeExit . fmap thirdComponent $ rawSystemStdInOut verbosity cargoExec cargoArgs workingDir Nothing Nothing IODataModeBinary+++rsMake :: Verbosity -> IO ()+rsMake verbosity = execCargo verbosity "build" ["--release", "--lib"]+++rsAddLibraryInfo :: ConfigFlags -> LocalBuildInfo -> IO LocalBuildInfo+rsAddLibraryInfo fl lbi' = do+  dir <- getCurrentDirectory+  let external = getCabalFlag externalLibFlagStr fl+  let updateLbi lbi =+        lbi+          { localPkgDescr = updatePkgDescr (localPkgDescr lbi)+          }+      updatePkgDescr pkgDescr =+        pkgDescr+          { library = updateLib <$> library pkgDescr+          }+      updateLib lib =+        lib+          { libBuildInfo = updateLibBi (libBuildInfo lib)+          }+      updateLibBi libBuild =+        libBuild+          { extraLibDirs =+              if external+                then extraLibDirs libBuild+                else (dir </> buildDir lbi') : extraLibDirs libBuild+          }+  pure $ updateLbi lbi'+++rsClean :: Verbosity -> IO ()+rsClean verbosity = execCargo verbosity "clean" []+++cabalFlag :: FlagName -> ConfigFlags -> Bool+cabalFlag name = fromMaybe False . lookupFlagAssignment name . configConfigurationsFlags+++unlessFlagM :: FlagName -> ConfigFlags -> IO () -> IO ()+unlessFlagM name flags action+  | cabalFlag name flags = do+      putStrLn "Skipping cargo action because external_lib flag is set"+      pure ()+  | otherwise = do+      putStrLn ("Running cargo action because we don't have the flag: " ++ show name)+      action+++copyLib :: ConfigFlags -> FilePath -> Bool -> IO ()+copyLib fl libPref shared = do+  libraryPath <- getLibraryPath+  installExecutableFile+    verb+    libraryPath+    (libPref ++ "/libtemporal_bridge." ++ ext)+  where+    verb = fromFlag $ configVerbosity fl+    external = getCabalFlag externalLibFlagStr fl+    ext =+      if shared+        then case buildOS of+          Windows -> "dll"+          OSX -> "dylib"+          _ -> "so"+        else "a"+    getLibraryPath =+      pure ("rust/target/release/libtemporal_bridge." ++ ext)+++copyTemporalBridge :: LocalBuildInfo -> FilePath -> IO ()+copyTemporalBridge lbi fp = do+  copyLib config fp False+  where+    config = configFlags lbi+++installTemporalBridge :: Args -> CopyFlags -> PackageDescription -> LocalBuildInfo -> IO ()+installTemporalBridge _ flags pkg_descr lbi = do+  let+    libPref =+      libdir+        . absoluteInstallDirs pkg_descr lbi+        . fromFlag+        . copyDest+        $ flags+    config = configFlags lbi++  unless (cabalFlag externalLibFlag $ configFlags lbi) $ do+    copyLib config libPref True+    copyLib config libPref False+++getCabalFlag :: String -> ConfigFlags -> Bool+getCabalFlag name flags = fromMaybe False (lookupFlagAssignment (mkFlagName name') allFlags)+  where+    allFlags = configConfigurationsFlags flags+    name' = map toLower name
+ rust/Cargo.lock view
@@ -0,0 +1,3701 @@+# This file is automatically @generated by Cargo.+# It is not intended for manual editing.+version = 4++[[package]]+name = "addr2line"+version = "0.24.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"+dependencies = [+ "gimli",+]++[[package]]+name = "adler2"+version = "2.0.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"++[[package]]+name = "aes"+version = "0.8.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"+dependencies = [+ "cfg-if",+ "cipher",+ "cpufeatures",+]++[[package]]+name = "aho-corasick"+version = "1.1.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"+dependencies = [+ "memchr",+]++[[package]]+name = "allocator-api2"+version = "0.2.21"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"++[[package]]+name = "anstyle"+version = "1.0.10"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"++[[package]]+name = "anyhow"+version = "1.0.98"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"++[[package]]+name = "arbitrary"+version = "1.4.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"+dependencies = [+ "derive_arbitrary",+]++[[package]]+name = "async-stream"+version = "0.3.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"+dependencies = [+ "async-stream-impl",+ "futures-core",+ "pin-project-lite",+]++[[package]]+name = "async-stream-impl"+version = "0.3.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "async-trait"+version = "0.1.88"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "atomic-waker"+version = "1.1.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"++[[package]]+name = "autocfg"+version = "1.4.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"++[[package]]+name = "axum"+version = "0.7.9"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"+dependencies = [+ "async-trait",+ "axum-core",+ "bytes",+ "futures-util",+ "http",+ "http-body",+ "http-body-util",+ "itoa",+ "matchit",+ "memchr",+ "mime",+ "percent-encoding",+ "pin-project-lite",+ "rustversion",+ "serde",+ "sync_wrapper",+ "tower 0.5.2",+ "tower-layer",+ "tower-service",+]++[[package]]+name = "axum-core"+version = "0.4.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"+dependencies = [+ "async-trait",+ "bytes",+ "futures-util",+ "http",+ "http-body",+ "http-body-util",+ "mime",+ "pin-project-lite",+ "rustversion",+ "sync_wrapper",+ "tower-layer",+ "tower-service",+]++[[package]]+name = "backoff"+version = "0.4.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1"+dependencies = [+ "getrandom 0.2.16",+ "instant",+ "rand 0.8.5",+]++[[package]]+name = "backtrace"+version = "0.3.74"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"+dependencies = [+ "addr2line",+ "cfg-if",+ "libc",+ "miniz_oxide",+ "object",+ "rustc-demangle",+ "windows-targets 0.52.6",+]++[[package]]+name = "base64"+version = "0.22.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"++[[package]]+name = "bitflags"+version = "2.9.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"++[[package]]+name = "block-buffer"+version = "0.10.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"+dependencies = [+ "generic-array",+]++[[package]]+name = "bumpalo"+version = "3.17.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"++[[package]]+name = "byteorder"+version = "1.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"++[[package]]+name = "bytes"+version = "1.10.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"++[[package]]+name = "bzip2"+version = "0.5.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47"+dependencies = [+ "bzip2-sys",+]++[[package]]+name = "bzip2-sys"+version = "0.1.13+1.0.8"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14"+dependencies = [+ "cc",+ "pkg-config",+]++[[package]]+name = "cc"+version = "1.2.19"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362"+dependencies = [+ "jobserver",+ "libc",+ "shlex",+]++[[package]]+name = "cfg-if"+version = "1.0.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"++[[package]]+name = "cfg_aliases"+version = "0.2.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"++[[package]]+name = "chrono"+version = "0.4.40"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"+dependencies = [+ "num-traits",+ "serde",+]++[[package]]+name = "cipher"+version = "0.4.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"+dependencies = [+ "crypto-common",+ "inout",+]++[[package]]+name = "constant_time_eq"+version = "0.3.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"++[[package]]+name = "core-foundation"+version = "0.10.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63"+dependencies = [+ "core-foundation-sys",+ "libc",+]++[[package]]+name = "core-foundation-sys"+version = "0.8.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"++[[package]]+name = "cpufeatures"+version = "0.2.17"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"+dependencies = [+ "libc",+]++[[package]]+name = "crc"+version = "3.2.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"+dependencies = [+ "crc-catalog",+]++[[package]]+name = "crc-catalog"+version = "2.4.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"++[[package]]+name = "crc32fast"+version = "1.4.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"+dependencies = [+ "cfg-if",+]++[[package]]+name = "crossbeam-channel"+version = "0.5.15"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"+dependencies = [+ "crossbeam-utils",+]++[[package]]+name = "crossbeam-queue"+version = "0.3.12"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"+dependencies = [+ "crossbeam-utils",+]++[[package]]+name = "crossbeam-utils"+version = "0.8.21"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"++[[package]]+name = "crypto-common"+version = "0.1.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"+dependencies = [+ "generic-array",+ "typenum",+]++[[package]]+name = "darling"+version = "0.20.11"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"+dependencies = [+ "darling_core",+ "darling_macro",+]++[[package]]+name = "darling_core"+version = "0.20.11"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"+dependencies = [+ "fnv",+ "ident_case",+ "proc-macro2",+ "quote",+ "strsim",+ "syn 2.0.100",+]++[[package]]+name = "darling_macro"+version = "0.20.11"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"+dependencies = [+ "darling_core",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "dashmap"+version = "6.1.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"+dependencies = [+ "cfg-if",+ "crossbeam-utils",+ "hashbrown 0.14.5",+ "lock_api",+ "once_cell",+ "parking_lot_core",+]++[[package]]+name = "deflate64"+version = "0.1.9"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b"++[[package]]+name = "deranged"+version = "0.4.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"+dependencies = [+ "powerfmt",+]++[[package]]+name = "derive_arbitrary"+version = "1.4.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "derive_builder"+version = "0.20.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947"+dependencies = [+ "derive_builder_macro",+]++[[package]]+name = "derive_builder_core"+version = "0.20.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8"+dependencies = [+ "darling",+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "derive_builder_macro"+version = "0.20.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"+dependencies = [+ "derive_builder_core",+ "syn 2.0.100",+]++[[package]]+name = "derive_more"+version = "2.0.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"+dependencies = [+ "derive_more-impl",+]++[[package]]+name = "derive_more-impl"+version = "2.0.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+ "unicode-xid",+]++[[package]]+name = "digest"+version = "0.10.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"+dependencies = [+ "block-buffer",+ "crypto-common",+ "subtle",+]++[[package]]+name = "displaydoc"+version = "0.2.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "downcast"+version = "0.11.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1"++[[package]]+name = "either"+version = "1.15.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"++[[package]]+name = "enum-iterator"+version = "2.1.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635"+dependencies = [+ "enum-iterator-derive",+]++[[package]]+name = "enum-iterator-derive"+version = "1.4.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "enum_dispatch"+version = "0.3.13"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd"+dependencies = [+ "once_cell",+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "equivalent"+version = "1.0.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"++[[package]]+name = "erased-serde"+version = "0.4.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"+dependencies = [+ "serde",+ "typeid",+]++[[package]]+name = "errno"+version = "0.3.11"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"+dependencies = [+ "libc",+ "windows-sys 0.59.0",+]++[[package]]+name = "fastrand"+version = "2.3.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"++[[package]]+name = "ffi-convert"+version = "0.6.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "88d96fa39640e119d4bc9898672ab63d9c575810dbad8806683a993fa8de0a8b"+dependencies = [+ "ffi-convert-derive",+ "libc",+ "thiserror 2.0.12",+]++[[package]]+name = "ffi-convert-derive"+version = "0.6.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "480d55e4c9442832b168701bcc7f2e3282608f841791224ea1ed6ae35d450175"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 1.0.109",+]++[[package]]+name = "filetime"+version = "0.2.25"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"+dependencies = [+ "cfg-if",+ "libc",+ "libredox",+ "windows-sys 0.59.0",+]++[[package]]+name = "fixedbitset"+version = "0.5.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"++[[package]]+name = "flate2"+version = "1.1.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"+dependencies = [+ "crc32fast",+ "miniz_oxide",+]++[[package]]+name = "fnv"+version = "1.0.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"++[[package]]+name = "foldhash"+version = "0.1.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"++[[package]]+name = "form_urlencoded"+version = "1.2.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"+dependencies = [+ "percent-encoding",+]++[[package]]+name = "fragile"+version = "2.0.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619"++[[package]]+name = "futures"+version = "0.3.31"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"+dependencies = [+ "futures-channel",+ "futures-core",+ "futures-executor",+ "futures-io",+ "futures-sink",+ "futures-task",+ "futures-util",+]++[[package]]+name = "futures-channel"+version = "0.3.31"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"+dependencies = [+ "futures-core",+ "futures-sink",+]++[[package]]+name = "futures-core"+version = "0.3.31"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"++[[package]]+name = "futures-executor"+version = "0.3.31"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"+dependencies = [+ "futures-core",+ "futures-task",+ "futures-util",+]++[[package]]+name = "futures-io"+version = "0.3.31"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"++[[package]]+name = "futures-macro"+version = "0.3.31"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "futures-retry"+version = "0.6.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "fde5a672a61f96552aa5ed9fd9c81c3fbdae4be9b1e205d6eaf17c83705adc0f"+dependencies = [+ "futures",+ "pin-project-lite",+ "tokio",+]++[[package]]+name = "futures-sink"+version = "0.3.31"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"++[[package]]+name = "futures-task"+version = "0.3.31"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"++[[package]]+name = "futures-timer"+version = "3.0.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"++[[package]]+name = "futures-util"+version = "0.3.31"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"+dependencies = [+ "futures-channel",+ "futures-core",+ "futures-io",+ "futures-macro",+ "futures-sink",+ "futures-task",+ "memchr",+ "pin-project-lite",+ "pin-utils",+ "slab",+]++[[package]]+name = "generic-array"+version = "0.14.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"+dependencies = [+ "typenum",+ "version_check",+]++[[package]]+name = "getrandom"+version = "0.2.16"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"+dependencies = [+ "cfg-if",+ "js-sys",+ "libc",+ "wasi 0.11.0+wasi-snapshot-preview1",+ "wasm-bindgen",+]++[[package]]+name = "getrandom"+version = "0.3.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"+dependencies = [+ "cfg-if",+ "js-sys",+ "libc",+ "r-efi",+ "wasi 0.14.2+wasi-0.2.4",+ "wasm-bindgen",+]++[[package]]+name = "gimli"+version = "0.31.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"++[[package]]+name = "glob"+version = "0.3.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"++[[package]]+name = "governor"+version = "0.8.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "be93b4ec2e4710b04d9264c0c7350cdd62a8c20e5e4ac732552ebb8f0debe8eb"+dependencies = [+ "cfg-if",+ "dashmap",+ "futures-sink",+ "futures-timer",+ "futures-util",+ "getrandom 0.3.2",+ "no-std-compat",+ "nonzero_ext",+ "parking_lot",+ "portable-atomic",+ "quanta",+ "rand 0.9.1",+ "smallvec",+ "spinning_top",+ "web-time",+]++[[package]]+name = "h2"+version = "0.4.9"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633"+dependencies = [+ "atomic-waker",+ "bytes",+ "fnv",+ "futures-core",+ "futures-sink",+ "http",+ "indexmap 2.9.0",+ "slab",+ "tokio",+ "tokio-util",+ "tracing",+]++[[package]]+name = "hashbrown"+version = "0.12.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"++[[package]]+name = "hashbrown"+version = "0.14.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"++[[package]]+name = "hashbrown"+version = "0.15.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"+dependencies = [+ "allocator-api2",+ "equivalent",+ "foldhash",+]++[[package]]+name = "heck"+version = "0.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"++[[package]]+name = "hmac"+version = "0.12.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"+dependencies = [+ "digest",+]++[[package]]+name = "http"+version = "1.3.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"+dependencies = [+ "bytes",+ "fnv",+ "itoa",+]++[[package]]+name = "http-body"+version = "1.0.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"+dependencies = [+ "bytes",+ "http",+]++[[package]]+name = "http-body-util"+version = "0.1.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"+dependencies = [+ "bytes",+ "futures-core",+ "http",+ "http-body",+ "pin-project-lite",+]++[[package]]+name = "httparse"+version = "1.10.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"++[[package]]+name = "httpdate"+version = "1.0.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"++[[package]]+name = "hyper"+version = "1.6.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"+dependencies = [+ "bytes",+ "futures-channel",+ "futures-util",+ "h2",+ "http",+ "http-body",+ "httparse",+ "httpdate",+ "itoa",+ "pin-project-lite",+ "smallvec",+ "tokio",+ "want",+]++[[package]]+name = "hyper-rustls"+version = "0.27.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2"+dependencies = [+ "futures-util",+ "http",+ "hyper",+ "hyper-util",+ "rustls",+ "rustls-native-certs",+ "rustls-pki-types",+ "tokio",+ "tokio-rustls",+ "tower-service",+]++[[package]]+name = "hyper-timeout"+version = "0.5.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"+dependencies = [+ "hyper",+ "hyper-util",+ "pin-project-lite",+ "tokio",+ "tower-service",+]++[[package]]+name = "hyper-util"+version = "0.1.11"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"+dependencies = [+ "bytes",+ "futures-channel",+ "futures-util",+ "http",+ "http-body",+ "hyper",+ "libc",+ "pin-project-lite",+ "socket2",+ "tokio",+ "tower-service",+ "tracing",+]++[[package]]+name = "icu_collections"+version = "1.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"+dependencies = [+ "displaydoc",+ "yoke",+ "zerofrom",+ "zerovec",+]++[[package]]+name = "icu_locid"+version = "1.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"+dependencies = [+ "displaydoc",+ "litemap",+ "tinystr",+ "writeable",+ "zerovec",+]++[[package]]+name = "icu_locid_transform"+version = "1.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"+dependencies = [+ "displaydoc",+ "icu_locid",+ "icu_locid_transform_data",+ "icu_provider",+ "tinystr",+ "zerovec",+]++[[package]]+name = "icu_locid_transform_data"+version = "1.5.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"++[[package]]+name = "icu_normalizer"+version = "1.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"+dependencies = [+ "displaydoc",+ "icu_collections",+ "icu_normalizer_data",+ "icu_properties",+ "icu_provider",+ "smallvec",+ "utf16_iter",+ "utf8_iter",+ "write16",+ "zerovec",+]++[[package]]+name = "icu_normalizer_data"+version = "1.5.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"++[[package]]+name = "icu_properties"+version = "1.5.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"+dependencies = [+ "displaydoc",+ "icu_collections",+ "icu_locid_transform",+ "icu_properties_data",+ "icu_provider",+ "tinystr",+ "zerovec",+]++[[package]]+name = "icu_properties_data"+version = "1.5.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"++[[package]]+name = "icu_provider"+version = "1.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"+dependencies = [+ "displaydoc",+ "icu_locid",+ "icu_provider_macros",+ "stable_deref_trait",+ "tinystr",+ "writeable",+ "yoke",+ "zerofrom",+ "zerovec",+]++[[package]]+name = "icu_provider_macros"+version = "1.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "ident_case"+version = "1.0.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"++[[package]]+name = "idna"+version = "1.0.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"+dependencies = [+ "idna_adapter",+ "smallvec",+ "utf8_iter",+]++[[package]]+name = "idna_adapter"+version = "1.2.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"+dependencies = [+ "icu_normalizer",+ "icu_properties",+]++[[package]]+name = "indexmap"+version = "1.9.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"+dependencies = [+ "autocfg",+ "hashbrown 0.12.3",+]++[[package]]+name = "indexmap"+version = "2.9.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"+dependencies = [+ "equivalent",+ "hashbrown 0.15.2",+]++[[package]]+name = "inout"+version = "0.1.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"+dependencies = [+ "generic-array",+]++[[package]]+name = "instant"+version = "0.1.13"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"+dependencies = [+ "cfg-if",+]++[[package]]+name = "inventory"+version = "0.3.20"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83"+dependencies = [+ "rustversion",+]++[[package]]+name = "ipnet"+version = "2.11.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"++[[package]]+name = "itertools"+version = "0.14.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"+dependencies = [+ "either",+]++[[package]]+name = "itoa"+version = "1.0.15"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"++[[package]]+name = "jobserver"+version = "0.1.33"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"+dependencies = [+ "getrandom 0.3.2",+ "libc",+]++[[package]]+name = "js-sys"+version = "0.3.77"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"+dependencies = [+ "once_cell",+ "wasm-bindgen",+]++[[package]]+name = "lazy_static"+version = "1.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"++[[package]]+name = "libc"+version = "0.2.172"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"++[[package]]+name = "libredox"+version = "0.1.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"+dependencies = [+ "bitflags",+ "libc",+ "redox_syscall",+]++[[package]]+name = "linux-raw-sys"+version = "0.9.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"++[[package]]+name = "litemap"+version = "0.7.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"++[[package]]+name = "lock_api"+version = "0.4.12"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"+dependencies = [+ "autocfg",+ "scopeguard",+]++[[package]]+name = "log"+version = "0.4.27"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"++[[package]]+name = "lru"+version = "0.13.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465"+dependencies = [+ "hashbrown 0.15.2",+]++[[package]]+name = "lzma-rs"+version = "0.3.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e"+dependencies = [+ "byteorder",+ "crc",+]++[[package]]+name = "lzma-sys"+version = "0.1.20"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27"+dependencies = [+ "cc",+ "libc",+ "pkg-config",+]++[[package]]+name = "matchers"+version = "0.1.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"+dependencies = [+ "regex-automata 0.1.10",+]++[[package]]+name = "matchit"+version = "0.7.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"++[[package]]+name = "memchr"+version = "2.7.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"++[[package]]+name = "mime"+version = "0.3.17"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"++[[package]]+name = "miniz_oxide"+version = "0.8.8"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"+dependencies = [+ "adler2",+]++[[package]]+name = "mio"+version = "1.0.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"+dependencies = [+ "libc",+ "wasi 0.11.0+wasi-snapshot-preview1",+ "windows-sys 0.52.0",+]++[[package]]+name = "mockall"+version = "0.13.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2"+dependencies = [+ "cfg-if",+ "downcast",+ "fragile",+ "mockall_derive",+ "predicates",+ "predicates-tree",+]++[[package]]+name = "mockall_derive"+version = "0.13.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898"+dependencies = [+ "cfg-if",+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "multimap"+version = "0.10.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"++[[package]]+name = "no-std-compat"+version = "0.4.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"++[[package]]+name = "nonzero_ext"+version = "0.3.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21"++[[package]]+name = "ntapi"+version = "0.4.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"+dependencies = [+ "winapi",+]++[[package]]+name = "nu-ansi-term"+version = "0.46.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"+dependencies = [+ "overload",+ "winapi",+]++[[package]]+name = "num-conv"+version = "0.1.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"++[[package]]+name = "num-traits"+version = "0.2.19"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"+dependencies = [+ "autocfg",+]++[[package]]+name = "object"+version = "0.36.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"+dependencies = [+ "memchr",+]++[[package]]+name = "once_cell"+version = "1.21.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"++[[package]]+name = "openssl-probe"+version = "0.1.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"++[[package]]+name = "opentelemetry"+version = "0.26.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "570074cc999d1a58184080966e5bd3bf3a9a4af650c3b05047c2621e7405cd17"+dependencies = [+ "futures-core",+ "futures-sink",+ "js-sys",+ "once_cell",+ "pin-project-lite",+ "thiserror 1.0.69",+]++[[package]]+name = "opentelemetry-http"+version = "0.26.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6351496aeaa49d7c267fb480678d85d1cd30c5edb20b497c48c56f62a8c14b99"+dependencies = [+ "async-trait",+ "bytes",+ "http",+ "opentelemetry",+ "reqwest",+]++[[package]]+name = "opentelemetry-otlp"+version = "0.26.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "29e1f9c8b032d4f635c730c0efcf731d5e2530ea13fa8bef7939ddc8420696bd"+dependencies = [+ "async-trait",+ "futures-core",+ "http",+ "opentelemetry",+ "opentelemetry-http",+ "opentelemetry-proto",+ "opentelemetry_sdk",+ "prost",+ "reqwest",+ "thiserror 1.0.69",+ "tokio",+ "tonic",+]++[[package]]+name = "opentelemetry-prometheus"+version = "0.17.0"+source = "git+https://github.com/open-telemetry/opentelemetry-rust.git?rev=e911383#e91138351a689cd21923c15eb48f5fbc95ded807"+dependencies = [+ "once_cell",+ "opentelemetry",+ "opentelemetry_sdk",+ "prometheus",+ "protobuf",+]++[[package]]+name = "opentelemetry-proto"+version = "0.26.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c9d3968ce3aefdcca5c27e3c4ea4391b37547726a70893aab52d3de95d5f8b34"+dependencies = [+ "opentelemetry",+ "opentelemetry_sdk",+ "prost",+ "tonic",+]++[[package]]+name = "opentelemetry_sdk"+version = "0.26.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d2c627d9f4c9cdc1f21a29ee4bfbd6028fcb8bcf2a857b43f3abdf72c9c862f3"+dependencies = [+ "async-trait",+ "futures-channel",+ "futures-executor",+ "futures-util",+ "glob",+ "once_cell",+ "opentelemetry",+ "percent-encoding",+ "rand 0.8.5",+ "serde_json",+ "thiserror 1.0.69",+ "tokio",+ "tokio-stream",+]++[[package]]+name = "overload"+version = "0.1.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"++[[package]]+name = "parking_lot"+version = "0.12.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"+dependencies = [+ "lock_api",+ "parking_lot_core",+]++[[package]]+name = "parking_lot_core"+version = "0.9.10"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"+dependencies = [+ "cfg-if",+ "libc",+ "redox_syscall",+ "smallvec",+ "windows-targets 0.52.6",+]++[[package]]+name = "pbkdf2"+version = "0.12.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"+dependencies = [+ "digest",+ "hmac",+]++[[package]]+name = "percent-encoding"+version = "2.3.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"++[[package]]+name = "petgraph"+version = "0.7.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772"+dependencies = [+ "fixedbitset",+ "indexmap 2.9.0",+]++[[package]]+name = "pid"+version = "4.0.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d7c931ef9756cd5e3fa3d395bfe09df4dfa6f0612c6ca8f6b12927d17ca34e36"+dependencies = [+ "num-traits",+]++[[package]]+name = "pin-project"+version = "1.1.10"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"+dependencies = [+ "pin-project-internal",+]++[[package]]+name = "pin-project-internal"+version = "1.1.10"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "pin-project-lite"+version = "0.2.16"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"++[[package]]+name = "pin-utils"+version = "0.1.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"++[[package]]+name = "pkg-config"+version = "0.3.32"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"++[[package]]+name = "portable-atomic"+version = "1.11.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"++[[package]]+name = "portable-atomic-util"+version = "0.2.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"+dependencies = [+ "portable-atomic",+]++[[package]]+name = "powerfmt"+version = "0.2.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"++[[package]]+name = "ppv-lite86"+version = "0.2.21"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"+dependencies = [+ "zerocopy",+]++[[package]]+name = "predicates"+version = "3.1.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573"+dependencies = [+ "anstyle",+ "predicates-core",+]++[[package]]+name = "predicates-core"+version = "1.0.9"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa"++[[package]]+name = "predicates-tree"+version = "1.0.12"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c"+dependencies = [+ "predicates-core",+ "termtree",+]++[[package]]+name = "prettyplease"+version = "0.2.32"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6"+dependencies = [+ "proc-macro2",+ "syn 2.0.100",+]++[[package]]+name = "proc-macro2"+version = "1.0.95"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"+dependencies = [+ "unicode-ident",+]++[[package]]+name = "prometheus"+version = "0.13.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1"+dependencies = [+ "cfg-if",+ "fnv",+ "lazy_static",+ "memchr",+ "parking_lot",+ "protobuf",+ "thiserror 1.0.69",+]++[[package]]+name = "prost"+version = "0.13.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"+dependencies = [+ "bytes",+ "prost-derive",+]++[[package]]+name = "prost-build"+version = "0.13.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf"+dependencies = [+ "heck",+ "itertools",+ "log",+ "multimap",+ "once_cell",+ "petgraph",+ "prettyplease",+ "prost",+ "prost-types",+ "regex",+ "syn 2.0.100",+ "tempfile",+]++[[package]]+name = "prost-derive"+version = "0.13.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"+dependencies = [+ "anyhow",+ "itertools",+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "prost-types"+version = "0.13.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16"+dependencies = [+ "prost",+]++[[package]]+name = "prost-wkt"+version = "0.6.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "a8d84e2bee181b04c2bac339f2bfe818c46a99750488cc6728ce4181d5aa8299"+dependencies = [+ "chrono",+ "inventory",+ "prost",+ "serde",+ "serde_derive",+ "serde_json",+ "typetag",+]++[[package]]+name = "prost-wkt-build"+version = "0.6.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8a669d5acbe719010c6f62a64e6d7d88fdedc1fe46e419747949ecb6312e9b14"+dependencies = [+ "heck",+ "prost",+ "prost-build",+ "prost-types",+ "quote",+]++[[package]]+name = "prost-wkt-types"+version = "0.6.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "01ef068e9b82e654614b22e6b13699bd545b6c0e2e721736008b00b38aeb4f64"+dependencies = [+ "chrono",+ "prost",+ "prost-build",+ "prost-types",+ "prost-wkt",+ "prost-wkt-build",+ "regex",+ "serde",+ "serde_derive",+ "serde_json",+]++[[package]]+name = "protobuf"+version = "2.28.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"++[[package]]+name = "quanta"+version = "0.12.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e"+dependencies = [+ "crossbeam-utils",+ "libc",+ "once_cell",+ "raw-cpuid",+ "wasi 0.11.0+wasi-snapshot-preview1",+ "web-sys",+ "winapi",+]++[[package]]+name = "quinn"+version = "0.11.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012"+dependencies = [+ "bytes",+ "cfg_aliases",+ "pin-project-lite",+ "quinn-proto",+ "quinn-udp",+ "rustc-hash",+ "rustls",+ "socket2",+ "thiserror 2.0.12",+ "tokio",+ "tracing",+ "web-time",+]++[[package]]+name = "quinn-proto"+version = "0.11.11"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "bcbafbbdbb0f638fe3f35f3c56739f77a8a1d070cb25603226c83339b391472b"+dependencies = [+ "bytes",+ "getrandom 0.3.2",+ "rand 0.9.1",+ "ring",+ "rustc-hash",+ "rustls",+ "rustls-pki-types",+ "slab",+ "thiserror 2.0.12",+ "tinyvec",+ "tracing",+ "web-time",+]++[[package]]+name = "quinn-udp"+version = "0.5.11"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5"+dependencies = [+ "cfg_aliases",+ "libc",+ "once_cell",+ "socket2",+ "tracing",+ "windows-sys 0.59.0",+]++[[package]]+name = "quote"+version = "1.0.40"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"+dependencies = [+ "proc-macro2",+]++[[package]]+name = "r-efi"+version = "5.2.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"++[[package]]+name = "rand"+version = "0.8.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"+dependencies = [+ "libc",+ "rand_chacha 0.3.1",+ "rand_core 0.6.4",+]++[[package]]+name = "rand"+version = "0.9.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"+dependencies = [+ "rand_chacha 0.9.0",+ "rand_core 0.9.3",+]++[[package]]+name = "rand_chacha"+version = "0.3.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"+dependencies = [+ "ppv-lite86",+ "rand_core 0.6.4",+]++[[package]]+name = "rand_chacha"+version = "0.9.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"+dependencies = [+ "ppv-lite86",+ "rand_core 0.9.3",+]++[[package]]+name = "rand_core"+version = "0.6.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"+dependencies = [+ "getrandom 0.2.16",+]++[[package]]+name = "rand_core"+version = "0.9.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"+dependencies = [+ "getrandom 0.3.2",+]++[[package]]+name = "raw-cpuid"+version = "11.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146"+dependencies = [+ "bitflags",+]++[[package]]+name = "redox_syscall"+version = "0.5.11"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"+dependencies = [+ "bitflags",+]++[[package]]+name = "regex"+version = "1.11.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"+dependencies = [+ "aho-corasick",+ "memchr",+ "regex-automata 0.4.9",+ "regex-syntax 0.8.5",+]++[[package]]+name = "regex-automata"+version = "0.1.10"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"+dependencies = [+ "regex-syntax 0.6.29",+]++[[package]]+name = "regex-automata"+version = "0.4.9"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"+dependencies = [+ "aho-corasick",+ "memchr",+ "regex-syntax 0.8.5",+]++[[package]]+name = "regex-syntax"+version = "0.6.29"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"++[[package]]+name = "regex-syntax"+version = "0.8.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"++[[package]]+name = "reqwest"+version = "0.12.15"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"+dependencies = [+ "base64",+ "bytes",+ "futures-channel",+ "futures-core",+ "futures-util",+ "http",+ "http-body",+ "http-body-util",+ "hyper",+ "hyper-rustls",+ "hyper-util",+ "ipnet",+ "js-sys",+ "log",+ "mime",+ "once_cell",+ "percent-encoding",+ "pin-project-lite",+ "quinn",+ "rustls",+ "rustls-native-certs",+ "rustls-pemfile",+ "rustls-pki-types",+ "serde",+ "serde_json",+ "serde_urlencoded",+ "sync_wrapper",+ "tokio",+ "tokio-rustls",+ "tokio-util",+ "tower 0.5.2",+ "tower-service",+ "url",+ "wasm-bindgen",+ "wasm-bindgen-futures",+ "wasm-streams",+ "web-sys",+ "windows-registry",+]++[[package]]+name = "ring"+version = "0.17.14"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"+dependencies = [+ "cc",+ "cfg-if",+ "getrandom 0.2.16",+ "libc",+ "untrusted",+ "windows-sys 0.52.0",+]++[[package]]+name = "ringbuf"+version = "0.4.8"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "fe47b720588c8702e34b5979cb3271a8b1842c7cb6f57408efa70c779363488c"+dependencies = [+ "crossbeam-utils",+ "portable-atomic",+ "portable-atomic-util",+]++[[package]]+name = "rustc-demangle"+version = "0.1.24"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"++[[package]]+name = "rustc-hash"+version = "2.1.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"++[[package]]+name = "rustfsm"+version = "0.1.0"+source = "git+https://github.com/temporalio/sdk-core?rev=97093c5ea4b0d933513f4c8999f7960f0c16f05f#97093c5ea4b0d933513f4c8999f7960f0c16f05f"+dependencies = [+ "rustfsm_procmacro",+ "rustfsm_trait",+]++[[package]]+name = "rustfsm_procmacro"+version = "0.1.0"+source = "git+https://github.com/temporalio/sdk-core?rev=97093c5ea4b0d933513f4c8999f7960f0c16f05f#97093c5ea4b0d933513f4c8999f7960f0c16f05f"+dependencies = [+ "derive_more",+ "proc-macro2",+ "quote",+ "rustfsm_trait",+ "syn 2.0.100",+]++[[package]]+name = "rustfsm_trait"+version = "0.1.0"+source = "git+https://github.com/temporalio/sdk-core?rev=97093c5ea4b0d933513f4c8999f7960f0c16f05f#97093c5ea4b0d933513f4c8999f7960f0c16f05f"++[[package]]+name = "rustix"+version = "1.0.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"+dependencies = [+ "bitflags",+ "errno",+ "libc",+ "linux-raw-sys",+ "windows-sys 0.59.0",+]++[[package]]+name = "rustls"+version = "0.23.26"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0"+dependencies = [+ "log",+ "once_cell",+ "ring",+ "rustls-pki-types",+ "rustls-webpki",+ "subtle",+ "zeroize",+]++[[package]]+name = "rustls-native-certs"+version = "0.8.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3"+dependencies = [+ "openssl-probe",+ "rustls-pki-types",+ "schannel",+ "security-framework",+]++[[package]]+name = "rustls-pemfile"+version = "2.2.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"+dependencies = [+ "rustls-pki-types",+]++[[package]]+name = "rustls-pki-types"+version = "1.11.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"+dependencies = [+ "web-time",+]++[[package]]+name = "rustls-webpki"+version = "0.103.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"+dependencies = [+ "ring",+ "rustls-pki-types",+ "untrusted",+]++[[package]]+name = "rustversion"+version = "1.0.20"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"++[[package]]+name = "ryu"+version = "1.0.20"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"++[[package]]+name = "schannel"+version = "0.1.27"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"+dependencies = [+ "windows-sys 0.59.0",+]++[[package]]+name = "scopeguard"+version = "1.2.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"++[[package]]+name = "security-framework"+version = "3.2.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316"+dependencies = [+ "bitflags",+ "core-foundation",+ "core-foundation-sys",+ "libc",+ "security-framework-sys",+]++[[package]]+name = "security-framework-sys"+version = "2.14.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"+dependencies = [+ "core-foundation-sys",+ "libc",+]++[[package]]+name = "serde"+version = "1.0.219"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"+dependencies = [+ "serde_derive",+]++[[package]]+name = "serde_derive"+version = "1.0.219"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "serde_json"+version = "1.0.140"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"+dependencies = [+ "itoa",+ "memchr",+ "ryu",+ "serde",+]++[[package]]+name = "serde_urlencoded"+version = "0.7.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"+dependencies = [+ "form_urlencoded",+ "itoa",+ "ryu",+ "serde",+]++[[package]]+name = "sha1"+version = "0.10.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"+dependencies = [+ "cfg-if",+ "cpufeatures",+ "digest",+]++[[package]]+name = "sharded-slab"+version = "0.1.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"+dependencies = [+ "lazy_static",+]++[[package]]+name = "shlex"+version = "1.3.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"++[[package]]+name = "signal-hook-registry"+version = "1.4.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"+dependencies = [+ "libc",+]++[[package]]+name = "simd-adler32"+version = "0.3.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"++[[package]]+name = "siphasher"+version = "1.0.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"++[[package]]+name = "slab"+version = "0.4.9"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"+dependencies = [+ "autocfg",+]++[[package]]+name = "slotmap"+version = "1.0.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a"+dependencies = [+ "version_check",+]++[[package]]+name = "smallvec"+version = "1.15.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"++[[package]]+name = "socket2"+version = "0.5.9"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef"+dependencies = [+ "libc",+ "windows-sys 0.52.0",+]++[[package]]+name = "spinning_top"+version = "0.3.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300"+dependencies = [+ "lock_api",+]++[[package]]+name = "stable_deref_trait"+version = "1.2.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"++[[package]]+name = "strsim"+version = "0.11.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"++[[package]]+name = "subtle"+version = "2.6.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"++[[package]]+name = "syn"+version = "1.0.109"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"+dependencies = [+ "proc-macro2",+ "quote",+ "unicode-ident",+]++[[package]]+name = "syn"+version = "2.0.100"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"+dependencies = [+ "proc-macro2",+ "quote",+ "unicode-ident",+]++[[package]]+name = "sync_wrapper"+version = "1.0.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"+dependencies = [+ "futures-core",+]++[[package]]+name = "synstructure"+version = "0.13.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "sysinfo"+version = "0.33.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "4fc858248ea01b66f19d8e8a6d55f41deaf91e9d495246fd01368d99935c6c01"+dependencies = [+ "core-foundation-sys",+ "libc",+ "memchr",+ "ntapi",+ "windows",+]++[[package]]+name = "tar"+version = "0.4.44"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a"+dependencies = [+ "filetime",+ "libc",+ "xattr",+]++[[package]]+name = "tempfile"+version = "3.19.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"+dependencies = [+ "fastrand",+ "getrandom 0.3.2",+ "once_cell",+ "rustix",+ "windows-sys 0.59.0",+]++[[package]]+name = "temporal-client"+version = "0.1.0"+source = "git+https://github.com/temporalio/sdk-core?rev=97093c5ea4b0d933513f4c8999f7960f0c16f05f#97093c5ea4b0d933513f4c8999f7960f0c16f05f"+dependencies = [+ "anyhow",+ "async-trait",+ "backoff",+ "base64",+ "derive_builder",+ "derive_more",+ "futures-retry",+ "futures-util",+ "http",+ "http-body-util",+ "hyper",+ "hyper-util",+ "parking_lot",+ "slotmap",+ "temporal-sdk-core-api",+ "temporal-sdk-core-protos",+ "thiserror 2.0.12",+ "tokio",+ "tonic",+ "tower 0.5.2",+ "tracing",+ "url",+ "uuid",+]++[[package]]+name = "temporal-sdk-core"+version = "0.1.0"+source = "git+https://github.com/temporalio/sdk-core?rev=97093c5ea4b0d933513f4c8999f7960f0c16f05f#97093c5ea4b0d933513f4c8999f7960f0c16f05f"+dependencies = [+ "anyhow",+ "async-trait",+ "crossbeam-channel",+ "crossbeam-queue",+ "crossbeam-utils",+ "dashmap",+ "derive_builder",+ "derive_more",+ "enum-iterator",+ "enum_dispatch",+ "flate2",+ "futures-channel",+ "futures-util",+ "governor",+ "http-body-util",+ "hyper",+ "hyper-util",+ "itertools",+ "lru",+ "mockall",+ "opentelemetry",+ "opentelemetry-otlp",+ "opentelemetry-prometheus",+ "opentelemetry_sdk",+ "parking_lot",+ "pid",+ "pin-project",+ "prometheus",+ "prost",+ "prost-wkt-types",+ "rand 0.9.1",+ "reqwest",+ "ringbuf",+ "rustfsm",+ "serde",+ "serde_json",+ "siphasher",+ "slotmap",+ "sysinfo",+ "tar",+ "temporal-client",+ "temporal-sdk-core-api",+ "temporal-sdk-core-protos",+ "thiserror 2.0.12",+ "tokio",+ "tokio-stream",+ "tokio-util",+ "tonic",+ "tracing",+ "tracing-subscriber",+ "url",+ "uuid",+ "zip",+]++[[package]]+name = "temporal-sdk-core-api"+version = "0.1.0"+source = "git+https://github.com/temporalio/sdk-core?rev=97093c5ea4b0d933513f4c8999f7960f0c16f05f#97093c5ea4b0d933513f4c8999f7960f0c16f05f"+dependencies = [+ "async-trait",+ "derive_builder",+ "derive_more",+ "opentelemetry",+ "prost",+ "serde_json",+ "temporal-sdk-core-protos",+ "thiserror 2.0.12",+ "tonic",+ "tracing-core",+ "url",+]++[[package]]+name = "temporal-sdk-core-protos"+version = "0.1.0"+source = "git+https://github.com/temporalio/sdk-core?rev=97093c5ea4b0d933513f4c8999f7960f0c16f05f#97093c5ea4b0d933513f4c8999f7960f0c16f05f"+dependencies = [+ "anyhow",+ "base64",+ "derive_more",+ "prost",+ "prost-build",+ "prost-wkt",+ "prost-wkt-build",+ "prost-wkt-types",+ "rand 0.9.1",+ "serde",+ "serde_json",+ "thiserror 2.0.12",+ "tonic",+ "tonic-build",+ "uuid",+]++[[package]]+name = "temporal_bridge"+version = "0.1.0"+dependencies = [+ "ffi-convert",+ "libc",+ "prost",+ "prost-types",+ "rustfsm",+ "serde",+ "serde_json",+ "temporal-client",+ "temporal-sdk-core",+ "temporal-sdk-core-api",+ "temporal-sdk-core-protos",+ "tokio",+ "tokio-stream",+ "tonic",+ "tracing",+ "url",+]++[[package]]+name = "termtree"+version = "0.5.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"++[[package]]+name = "thiserror"+version = "1.0.69"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"+dependencies = [+ "thiserror-impl 1.0.69",+]++[[package]]+name = "thiserror"+version = "2.0.12"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"+dependencies = [+ "thiserror-impl 2.0.12",+]++[[package]]+name = "thiserror-impl"+version = "1.0.69"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "thiserror-impl"+version = "2.0.12"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "thread_local"+version = "1.1.8"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"+dependencies = [+ "cfg-if",+ "once_cell",+]++[[package]]+name = "time"+version = "0.3.41"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"+dependencies = [+ "deranged",+ "num-conv",+ "powerfmt",+ "serde",+ "time-core",+]++[[package]]+name = "time-core"+version = "0.1.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"++[[package]]+name = "tinystr"+version = "0.7.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"+dependencies = [+ "displaydoc",+ "zerovec",+]++[[package]]+name = "tinyvec"+version = "1.9.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71"+dependencies = [+ "tinyvec_macros",+]++[[package]]+name = "tinyvec_macros"+version = "0.1.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"++[[package]]+name = "tokio"+version = "1.44.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"+dependencies = [+ "backtrace",+ "bytes",+ "libc",+ "mio",+ "parking_lot",+ "pin-project-lite",+ "signal-hook-registry",+ "socket2",+ "tokio-macros",+ "windows-sys 0.52.0",+]++[[package]]+name = "tokio-macros"+version = "2.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "tokio-rustls"+version = "0.26.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b"+dependencies = [+ "rustls",+ "tokio",+]++[[package]]+name = "tokio-stream"+version = "0.1.17"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"+dependencies = [+ "futures-core",+ "pin-project-lite",+ "tokio",+]++[[package]]+name = "tokio-util"+version = "0.7.14"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034"+dependencies = [+ "bytes",+ "futures-core",+ "futures-sink",+ "pin-project-lite",+ "tokio",+]++[[package]]+name = "tonic"+version = "0.12.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52"+dependencies = [+ "async-stream",+ "async-trait",+ "axum",+ "base64",+ "bytes",+ "h2",+ "http",+ "http-body",+ "http-body-util",+ "hyper",+ "hyper-timeout",+ "hyper-util",+ "percent-encoding",+ "pin-project",+ "prost",+ "rustls-native-certs",+ "rustls-pemfile",+ "socket2",+ "tokio",+ "tokio-rustls",+ "tokio-stream",+ "tower 0.4.13",+ "tower-layer",+ "tower-service",+ "tracing",+]++[[package]]+name = "tonic-build"+version = "0.12.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11"+dependencies = [+ "prettyplease",+ "proc-macro2",+ "prost-build",+ "prost-types",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "tower"+version = "0.4.13"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"+dependencies = [+ "futures-core",+ "futures-util",+ "indexmap 1.9.3",+ "pin-project",+ "pin-project-lite",+ "rand 0.8.5",+ "slab",+ "tokio",+ "tokio-util",+ "tower-layer",+ "tower-service",+ "tracing",+]++[[package]]+name = "tower"+version = "0.5.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"+dependencies = [+ "futures-core",+ "futures-util",+ "pin-project-lite",+ "sync_wrapper",+ "tokio",+ "tower-layer",+ "tower-service",+]++[[package]]+name = "tower-layer"+version = "0.3.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"++[[package]]+name = "tower-service"+version = "0.3.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"++[[package]]+name = "tracing"+version = "0.1.41"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"+dependencies = [+ "pin-project-lite",+ "tracing-attributes",+ "tracing-core",+]++[[package]]+name = "tracing-attributes"+version = "0.1.28"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "tracing-core"+version = "0.1.33"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"+dependencies = [+ "once_cell",+ "valuable",+]++[[package]]+name = "tracing-subscriber"+version = "0.3.19"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"+dependencies = [+ "matchers",+ "nu-ansi-term",+ "once_cell",+ "parking_lot",+ "regex",+ "sharded-slab",+ "thread_local",+ "tracing",+ "tracing-core",+]++[[package]]+name = "try-lock"+version = "0.2.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"++[[package]]+name = "typeid"+version = "1.0.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"++[[package]]+name = "typenum"+version = "1.18.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"++[[package]]+name = "typetag"+version = "0.2.20"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "73f22b40dd7bfe8c14230cf9702081366421890435b2d625fa92b4acc4c3de6f"+dependencies = [+ "erased-serde",+ "inventory",+ "once_cell",+ "serde",+ "typetag-impl",+]++[[package]]+name = "typetag-impl"+version = "0.2.20"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "unicode-ident"+version = "1.0.18"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"++[[package]]+name = "unicode-xid"+version = "0.2.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"++[[package]]+name = "untrusted"+version = "0.9.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"++[[package]]+name = "url"+version = "2.5.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"+dependencies = [+ "form_urlencoded",+ "idna",+ "percent-encoding",+]++[[package]]+name = "utf16_iter"+version = "1.0.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"++[[package]]+name = "utf8_iter"+version = "1.0.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"++[[package]]+name = "uuid"+version = "1.16.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"+dependencies = [+ "getrandom 0.3.2",+]++[[package]]+name = "valuable"+version = "0.1.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"++[[package]]+name = "version_check"+version = "0.9.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"++[[package]]+name = "want"+version = "0.3.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"+dependencies = [+ "try-lock",+]++[[package]]+name = "wasi"+version = "0.11.0+wasi-snapshot-preview1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"++[[package]]+name = "wasi"+version = "0.14.2+wasi-0.2.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"+dependencies = [+ "wit-bindgen-rt",+]++[[package]]+name = "wasm-bindgen"+version = "0.2.100"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"+dependencies = [+ "cfg-if",+ "once_cell",+ "rustversion",+ "wasm-bindgen-macro",+]++[[package]]+name = "wasm-bindgen-backend"+version = "0.2.100"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"+dependencies = [+ "bumpalo",+ "log",+ "proc-macro2",+ "quote",+ "syn 2.0.100",+ "wasm-bindgen-shared",+]++[[package]]+name = "wasm-bindgen-futures"+version = "0.4.50"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"+dependencies = [+ "cfg-if",+ "js-sys",+ "once_cell",+ "wasm-bindgen",+ "web-sys",+]++[[package]]+name = "wasm-bindgen-macro"+version = "0.2.100"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"+dependencies = [+ "quote",+ "wasm-bindgen-macro-support",+]++[[package]]+name = "wasm-bindgen-macro-support"+version = "0.2.100"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+ "wasm-bindgen-backend",+ "wasm-bindgen-shared",+]++[[package]]+name = "wasm-bindgen-shared"+version = "0.2.100"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"+dependencies = [+ "unicode-ident",+]++[[package]]+name = "wasm-streams"+version = "0.4.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"+dependencies = [+ "futures-util",+ "js-sys",+ "wasm-bindgen",+ "wasm-bindgen-futures",+ "web-sys",+]++[[package]]+name = "web-sys"+version = "0.3.77"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"+dependencies = [+ "js-sys",+ "wasm-bindgen",+]++[[package]]+name = "web-time"+version = "1.1.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"+dependencies = [+ "js-sys",+ "wasm-bindgen",+]++[[package]]+name = "winapi"+version = "0.3.9"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"+dependencies = [+ "winapi-i686-pc-windows-gnu",+ "winapi-x86_64-pc-windows-gnu",+]++[[package]]+name = "winapi-i686-pc-windows-gnu"+version = "0.4.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"++[[package]]+name = "winapi-x86_64-pc-windows-gnu"+version = "0.4.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"++[[package]]+name = "windows"+version = "0.57.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"+dependencies = [+ "windows-core",+ "windows-targets 0.52.6",+]++[[package]]+name = "windows-core"+version = "0.57.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"+dependencies = [+ "windows-implement",+ "windows-interface",+ "windows-result 0.1.2",+ "windows-targets 0.52.6",+]++[[package]]+name = "windows-implement"+version = "0.57.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "windows-interface"+version = "0.57.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "windows-link"+version = "0.1.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"++[[package]]+name = "windows-registry"+version = "0.4.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"+dependencies = [+ "windows-result 0.3.2",+ "windows-strings",+ "windows-targets 0.53.0",+]++[[package]]+name = "windows-result"+version = "0.1.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"+dependencies = [+ "windows-targets 0.52.6",+]++[[package]]+name = "windows-result"+version = "0.3.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"+dependencies = [+ "windows-link",+]++[[package]]+name = "windows-strings"+version = "0.3.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"+dependencies = [+ "windows-link",+]++[[package]]+name = "windows-sys"+version = "0.52.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"+dependencies = [+ "windows-targets 0.52.6",+]++[[package]]+name = "windows-sys"+version = "0.59.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"+dependencies = [+ "windows-targets 0.52.6",+]++[[package]]+name = "windows-targets"+version = "0.52.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"+dependencies = [+ "windows_aarch64_gnullvm 0.52.6",+ "windows_aarch64_msvc 0.52.6",+ "windows_i686_gnu 0.52.6",+ "windows_i686_gnullvm 0.52.6",+ "windows_i686_msvc 0.52.6",+ "windows_x86_64_gnu 0.52.6",+ "windows_x86_64_gnullvm 0.52.6",+ "windows_x86_64_msvc 0.52.6",+]++[[package]]+name = "windows-targets"+version = "0.53.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"+dependencies = [+ "windows_aarch64_gnullvm 0.53.0",+ "windows_aarch64_msvc 0.53.0",+ "windows_i686_gnu 0.53.0",+ "windows_i686_gnullvm 0.53.0",+ "windows_i686_msvc 0.53.0",+ "windows_x86_64_gnu 0.53.0",+ "windows_x86_64_gnullvm 0.53.0",+ "windows_x86_64_msvc 0.53.0",+]++[[package]]+name = "windows_aarch64_gnullvm"+version = "0.52.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"++[[package]]+name = "windows_aarch64_gnullvm"+version = "0.53.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"++[[package]]+name = "windows_aarch64_msvc"+version = "0.52.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"++[[package]]+name = "windows_aarch64_msvc"+version = "0.53.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"++[[package]]+name = "windows_i686_gnu"+version = "0.52.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"++[[package]]+name = "windows_i686_gnu"+version = "0.53.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"++[[package]]+name = "windows_i686_gnullvm"+version = "0.52.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"++[[package]]+name = "windows_i686_gnullvm"+version = "0.53.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"++[[package]]+name = "windows_i686_msvc"+version = "0.52.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"++[[package]]+name = "windows_i686_msvc"+version = "0.53.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"++[[package]]+name = "windows_x86_64_gnu"+version = "0.52.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"++[[package]]+name = "windows_x86_64_gnu"+version = "0.53.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"++[[package]]+name = "windows_x86_64_gnullvm"+version = "0.52.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"++[[package]]+name = "windows_x86_64_gnullvm"+version = "0.53.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"++[[package]]+name = "windows_x86_64_msvc"+version = "0.52.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"++[[package]]+name = "windows_x86_64_msvc"+version = "0.53.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"++[[package]]+name = "wit-bindgen-rt"+version = "0.39.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"+dependencies = [+ "bitflags",+]++[[package]]+name = "write16"+version = "1.0.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"++[[package]]+name = "writeable"+version = "0.5.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"++[[package]]+name = "xattr"+version = "1.5.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e"+dependencies = [+ "libc",+ "rustix",+]++[[package]]+name = "xz2"+version = "0.1.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2"+dependencies = [+ "lzma-sys",+]++[[package]]+name = "yoke"+version = "0.7.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"+dependencies = [+ "serde",+ "stable_deref_trait",+ "yoke-derive",+ "zerofrom",+]++[[package]]+name = "yoke-derive"+version = "0.7.5"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+ "synstructure",+]++[[package]]+name = "zerocopy"+version = "0.8.24"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"+dependencies = [+ "zerocopy-derive",+]++[[package]]+name = "zerocopy-derive"+version = "0.8.24"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "zerofrom"+version = "0.1.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"+dependencies = [+ "zerofrom-derive",+]++[[package]]+name = "zerofrom-derive"+version = "0.1.6"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+ "synstructure",+]++[[package]]+name = "zeroize"+version = "1.8.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"+dependencies = [+ "zeroize_derive",+]++[[package]]+name = "zeroize_derive"+version = "1.4.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "zerovec"+version = "0.10.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"+dependencies = [+ "yoke",+ "zerofrom",+ "zerovec-derive",+]++[[package]]+name = "zerovec-derive"+version = "0.10.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"+dependencies = [+ "proc-macro2",+ "quote",+ "syn 2.0.100",+]++[[package]]+name = "zip"+version = "2.6.1"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "1dcb24d0152526ae49b9b96c1dcf71850ca1e0b882e4e28ed898a93c41334744"+dependencies = [+ "aes",+ "arbitrary",+ "bzip2",+ "constant_time_eq",+ "crc32fast",+ "crossbeam-utils",+ "deflate64",+ "flate2",+ "getrandom 0.3.2",+ "hmac",+ "indexmap 2.9.0",+ "lzma-rs",+ "memchr",+ "pbkdf2",+ "sha1",+ "time",+ "xz2",+ "zeroize",+ "zopfli",+ "zstd",+]++[[package]]+name = "zopfli"+version = "0.8.2"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7"+dependencies = [+ "bumpalo",+ "crc32fast",+ "log",+ "simd-adler32",+]++[[package]]+name = "zstd"+version = "0.13.3"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"+dependencies = [+ "zstd-safe",+]++[[package]]+name = "zstd-safe"+version = "7.2.4"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"+dependencies = [+ "zstd-sys",+]++[[package]]+name = "zstd-sys"+version = "2.0.15+zstd.1.5.7"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237"+dependencies = [+ "cc",+ "pkg-config",+]
+ rust/Cargo.toml view
@@ -0,0 +1,33 @@+[package]+name = "temporal_bridge"+version = "0.1.0"+edition = "2024"++# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html++[lib]+crate-type = ["cdylib", "staticlib"]++[dependencies]+temporal-client = { git = "https://github.com/temporalio/sdk-core", rev = "97093c5ea4b0d933513f4c8999f7960f0c16f05f" }+temporal-sdk-core = { git = "https://github.com/temporalio/sdk-core", rev = "97093c5ea4b0d933513f4c8999f7960f0c16f05f", features = ["ephemeral-server"] }+temporal-sdk-core-api = { git = "https://github.com/temporalio/sdk-core", rev = "97093c5ea4b0d933513f4c8999f7960f0c16f05f" }+temporal-sdk-core-protos = { git = "https://github.com/temporalio/sdk-core", rev = "97093c5ea4b0d933513f4c8999f7960f0c16f05f" }+rustfsm = { git = "https://github.com/temporalio/sdk-core", rev = "97093c5ea4b0d933513f4c8999f7960f0c16f05f" }+tokio = "~1.44"+tokio-stream = "~0.1"+tonic = "~0.12"+tracing = "~0.1"+url = "~2.5"+ffi-convert = "~0.6"+serde = { version = "~1.0", features = ["derive"] }+serde_json = "~1.0"+prost = "~0.13"+prost-types = "~0.13"+libc = "0.2.172"++[profile.release]+opt-level = 3+debug = false+lto = true+incremental = true
+ rust/src/client.rs view
@@ -0,0 +1,334 @@+use crate::runtime::{self, Capability, HsCallback, MVar};+use ffi_convert::*;+use serde::{Deserialize, Serialize};+use std::collections::HashMap;+use std::ffi::CStr;+use std::str::{from_utf8_unchecked, FromStr};+use std::time::Duration;+use temporal_client::{+    ClientOptions, ClientOptionsBuilder, ClientOptionsBuilderError, ConfiguredClient, RetryClient,+    RetryConfig, TemporalServiceClientWithMetrics, TlsConfig,+};+use tonic::metadata::{errors::InvalidMetadataValue, MetadataKey};+use url::Url;++type Client = RetryClient<ConfiguredClient<TemporalServiceClientWithMetrics>>;++#[derive(Serialize, Deserialize)]+pub struct ClientConfig {+    target_url: String,+    client_name: String,+    client_version: String,+    metadata: HashMap<String, String>,+    identity: String,+    tls_config: Option<ClientTlsConfig>,+    retry_config: Option<ClientRetryConfig>,+    api_key: Option<String>,+}++#[derive(Serialize, Deserialize)]+struct ClientTlsConfig {+    server_root_ca_cert: Option<Vec<u8>>,+    domain: Option<String>,+    client_cert: Option<Vec<u8>>,+    client_private_key: Option<Vec<u8>>,+}++#[derive(Serialize, Deserialize)]+struct ClientRetryConfig {+    pub initial_interval_millis: u64,+    pub randomization_factor: f64,+    pub multiplier: f64,+    pub max_interval_millis: u64,+    pub max_elapsed_time_millis: Option<u64>,+    pub max_retries: usize,+}++fn client_config_to_options(+    client_config: ClientConfig,+) -> Result<ClientOptions, ClientOptionsBuilderError> {+    let mut defaults = ClientOptionsBuilder::default();+    let mut options_builder = defaults+        .target_url(Url::parse(&client_config.target_url).unwrap())+        .client_name(client_config.client_name)+        .client_version(client_config.client_version)+        .identity(client_config.identity);++    if let Some(tls_config) = client_config.tls_config {+        let tls_config = TlsConfig {+            server_root_ca_cert: tls_config.server_root_ca_cert,+            domain: tls_config.domain,+            client_tls_config: match (tls_config.client_cert, tls_config.client_private_key) {+                (Some(client_cert), Some(client_private_key)) => {+                    Some(temporal_client::ClientTlsConfig {+                        client_cert,+                        client_private_key,+                    })+                }+                _ => None,+            },+        };+        options_builder = options_builder.tls_cfg(tls_config);+    }++    if let Some(retry_config) = client_config.retry_config {+        options_builder = options_builder.retry_config(RetryConfig {+            initial_interval: Duration::from_millis(retry_config.initial_interval_millis),+            randomization_factor: retry_config.randomization_factor,+            multiplier: retry_config.multiplier,+            max_interval: Duration::from_millis(retry_config.max_interval_millis),+            max_elapsed_time: retry_config+                .max_elapsed_time_millis+                .map(Duration::from_millis),+            max_retries: retry_config.max_retries,+        });+    }++    if client_config.api_key.is_some() {+        options_builder = options_builder.api_key(client_config.api_key)+    }++    options_builder.build()+}++#[repr(C)]+pub struct HaskellHashMapEntries {+    key: *const u8,+    key_len: usize,+    value: *const u8,+    value_len: usize,+    next: *const HaskellHashMapEntries,+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+pub unsafe fn convert_hashmap(hashmap: *const HaskellHashMapEntries) -> HashMap<String, String> {+    let mut map = HashMap::new();+    if hashmap.is_null() {+        return map;+    }++    let mut hashmap_ptr = hashmap;+    while !hashmap_ptr.is_null() {+        let hashmap_val = unsafe { &*hashmap_ptr };+        let key = unsafe {+            from_utf8_unchecked(std::slice::from_raw_parts(+                hashmap_val.key,+                hashmap_val.key_len,+            ))+        };+        let value = unsafe {+            from_utf8_unchecked(std::slice::from_raw_parts(+                hashmap_val.value,+                hashmap_val.value_len,+            ))+        };+        map.insert(key.to_string(), value.to_string());+        hashmap_ptr = unsafe { (*hashmap).next };+    }++    map+}+#[repr(C)]+pub struct RpcCall {+    req: *const CArray<u8>,+    retry: bool,+    metadata: *const HaskellHashMapEntries,+    // nullable+    timeout_millis: *const u64,+}++pub(crate) struct TemporalCall {+    pub(crate) req: Vec<u8>,+    pub(crate) retry: bool,+    pub(crate) metadata: HashMap<String, String>,+    pub(crate) timeout_millis: Option<u64>,+}++impl From<&RpcCall> for TemporalCall {+    fn from(rpc_call: &RpcCall) -> Self {+        TemporalCall {+            req: unsafe {+                let req_array = rpc_call.req;+                let rust_vec = (*req_array).as_rust();+                rust_vec.unwrap().clone()+            },+            retry: rpc_call.retry,+            metadata: unsafe { convert_hashmap(rpc_call.metadata) },+            timeout_millis: if rpc_call.timeout_millis.is_null() {+                None+            } else {+                Some(unsafe { *rpc_call.timeout_millis })+            },+        }+    }+}++pub struct ClientRef {+    pub(crate) retry_client: Client,+    pub(crate) runtime: runtime::Runtime,+}++impl RawPointerConverter<ClientRef> for ClientRef {+    fn into_raw_pointer(self) -> *const ClientRef {+        convert_into_raw_pointer(self)+    }++    fn into_raw_pointer_mut(self) -> *mut ClientRef {+        convert_into_raw_pointer_mut(self)+    }++    unsafe fn from_raw_pointer(ptr: *const ClientRef) -> Result<Self, UnexpectedNullPointerError> {+        unsafe { take_back_from_raw_pointer(ptr) }+    }++    unsafe fn from_raw_pointer_mut(+        ptr: *mut ClientRef,+    ) -> Result<Self, UnexpectedNullPointerError> {+        unsafe { take_back_from_raw_pointer_mut(ptr) }+    }+}++pub fn connect_client(+    runtime_ref: &runtime::RuntimeRef,+    config: ClientConfig,+    hs_callback: HsCallback<ClientRef, CArray<u8>>,+) {+    let opts: ClientOptions = client_config_to_options(config).unwrap();+    let runtime = runtime_ref.runtime.clone();+    runtime_ref+        .runtime+        .future_result_into_hs(hs_callback, async move {+            let retry_client_result = opts+                .connect_no_namespace(runtime.core.as_ref().telemetry().get_metric_meter())+                .await;++            match retry_client_result {+                Ok(retry_client) => Ok(ClientRef {+                    retry_client,+                    runtime,+                }),+                Err(e) => {+                    let err_message = e.to_string().into_bytes();+                    Err(CArray::c_repr_of(err_message).unwrap())+                }+            }+        })+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_connect_client(+    runtime_ref: *const runtime::RuntimeRef,+    config_json: *const libc::c_char,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CArray<u8>,+    result_slot: *mut *mut ClientRef,+) {+    let runtime_ref = unsafe { &*runtime_ref };+    let config_json = unsafe { CStr::from_ptr(config_json) };+    let config: ClientConfig = serde_json::from_slice(config_json.to_bytes()).unwrap();+    let hs_callback = runtime::HsCallback {+        cap,+        mvar,+        error_slot,+        result_slot,+    };+    connect_client(runtime_ref, config, hs_callback);+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_drop_client(client: *mut ClientRef) {+    unsafe {+        drop(Box::from_raw(client));+    }+}++pub(crate) fn rpc_req<P: prost::Message + Default>(+    call: TemporalCall,+) -> Result<tonic::Request<P>, String> {+    let buf = call.req.as_slice();+    let proto = P::decode(buf).map_err(|err| err.to_string())?;+    let mut req = tonic::Request::new(proto);+    let metadata = &call.metadata;+    for (k, v) in metadata {+        req.metadata_mut().insert(+            MetadataKey::from_str(k.as_str()).map_err(|err| err.to_string())?,+            v.parse()+                .map_err(|err: InvalidMetadataValue| err.to_string())?,+        );+    }+    if let Some(timeout_millis) = call.timeout_millis {+        req.set_timeout(Duration::from_millis(timeout_millis));+    }+    Ok(req)+}++#[derive(Debug)]+pub struct RPCError {+    pub code: u32,+    pub message: String,+    pub details: Vec<u8>,+}++#[repr(C)]+#[derive(CReprOf, AsRust, CDrop, RawPointerConverter)]+#[target_type(RPCError)]+pub struct CRPCError {+    code: u32,+    message: *const libc::c_char,+    details: *const CArray<u8>,+}++impl From<String> for CRPCError {+    fn from(err: String) -> Self {+        CRPCError::c_repr_of(RPCError {+            code: 0,+            message: err,+            details: vec![],+        })+        .unwrap()+    }+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_drop_rpc_error(error: *mut CRPCError) {+    unsafe {+        CRPCError::drop_raw_pointer(error).unwrap();+    }+}++pub(crate) fn rpc_resp<P>(+    res: Result<tonic::Response<P>, tonic::Status>,+) -> Result<Vec<u8>, CRPCError>+where+    P: prost::Message,+    P: Default,+{+    match res {+        Ok(resp) => Ok(resp.get_ref().encode_to_vec()),+        Err(err) => {+            eprintln!("Error: {:?}", err);+            Err(CRPCError::c_repr_of(RPCError {+                code: err.code() as u32,+                message: err.message().to_owned(),+                details: err.details().into(),+            })+            .unwrap())+        }+    }+}
+ rust/src/ephemeral_server.rs view
@@ -0,0 +1,216 @@+use crate::runtime::{Capability, HsCallback, MVar, Runtime, RuntimeRef};+use crate::worker::{CUnit, Unit};+use ffi_convert::*;+use serde::Deserialize;+use std::ffi::{c_char, CStr};+use std::time::Duration;+use temporal_sdk_core::ephemeral_server::*;++pub struct EphemeralServerRef {+    pub(crate) server: EphemeralServer,+    runtime: Runtime,+}++impl RawPointerConverter<EphemeralServerRef> for EphemeralServerRef {+    fn into_raw_pointer(self) -> *const EphemeralServerRef {+        convert_into_raw_pointer(self)+    }++    fn into_raw_pointer_mut(self) -> *mut EphemeralServerRef {+        convert_into_raw_pointer_mut(self)+    }++    unsafe fn from_raw_pointer(+        ptr: *const EphemeralServerRef,+    ) -> Result<Self, UnexpectedNullPointerError> {+        unsafe { take_back_from_raw_pointer(ptr) }+    }++    unsafe fn from_raw_pointer_mut(+        ptr: *mut EphemeralServerRef,+    ) -> Result<Self, UnexpectedNullPointerError> {+        unsafe { take_back_from_raw_pointer_mut(ptr) }+    }+}++/// Where to find an executable. Can be a path or download.+#[derive(Deserialize)]+#[serde(tag = "type", content = "contents", remote = "EphemeralExe")]+pub enum EphemeralExeDef {+    /// Existing path on the filesystem for the executable.+    ExistingPath(String),+    /// Download the executable if not already there.+    CachedDownload {+        /// Which version to download.+        #[serde(with = "EphemeralExeVersionDef")]+        version: EphemeralExeVersion,+        /// Destination directory or the user temp directory if none set.+        dest_dir: Option<String>,+        ttl: Option<Duration>+    },+}++/// Which version of the exe to download.+#[derive(Deserialize)]+#[serde(tag = "type", content = "contents", remote = "EphemeralExeVersion")]+pub enum EphemeralExeVersionDef {+    /// Use a default version for the given SDK name and version.+    SDKDefault {+        /// Name of the SDK to get the default for.+        sdk_name: String,+        /// Version of the SDK to get the default for.+        sdk_version: String,+    },+    /// Specific version.+    Fixed(String),+}++#[derive(Deserialize)]+#[serde(remote = "TemporalDevServerConfig")]+pub struct TemporalDevServerConfigDef {+    /// Required path to executable or download info.+    #[serde(with = "EphemeralExeDef")]+    pub exe: EphemeralExe,+    /// Namespace to use.+    pub namespace: String,+    /// IP to bind to.+    pub ip: String,+    /// Port to use or obtains a free one if none given.+    pub port: Option<u16>,+    /// Sqlite DB filename if persisting or non-persistent if none.+    pub db_filename: Option<String>,+    /// Whether to enable the UI.+    pub ui: bool,+    /// What port to run the UI on.+    pub ui_port: Option<u16>,+    /// Log format and level+    pub log: (String, String),+    /// Additional arguments to Temporalite.+    pub extra_args: Vec<String>,+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_start_dev_server(+    runtime: *mut RuntimeRef,+    json_string: *const c_char,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CArray<u8>,+    result_slot: *mut *mut EphemeralServerRef,+) {+    let runtime_ref = unsafe { runtime.as_ref().unwrap() };+    let runtime = &runtime_ref.runtime;+    let mut de = serde_json::Deserializer::from_str(unsafe {+        std::str::from_utf8_unchecked(CStr::from_ptr(json_string).to_bytes())+    });+    let conf =+        TemporalDevServerConfigDef::deserialize(&mut de).expect("Failed to deserialize config");+    let hs: HsCallback<EphemeralServerRef, CArray<u8>> = HsCallback {+        cap,+        mvar,+        error_slot,+        result_slot,+    };+    runtime.future_result_into_hs(hs, async move {+        let result = conf.start_server().await;+        match result {+            Ok(server) => Ok(EphemeralServerRef {+                server,+                runtime: runtime.clone(),+            }),+            Err(e) => Err(+                CArray::c_repr_of(format!("Failed to start server: {}", e).into_bytes())+                    .expect("Failed to convert error to CArray"),+            ),+        }+    })+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_shutdown_ephemeral_server(+    server: *mut EphemeralServerRef,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CArray<u8>,+    result_slot: *mut *mut CUnit,+) {+    let server_ref = unsafe { Box::from_raw(server) };+    let mut server = server_ref.server;+    let hs: HsCallback<CUnit, CArray<u8>> = HsCallback {+        cap,+        mvar,+        error_slot,+        result_slot,+    };+    server_ref.runtime.future_result_into_hs(hs, async move {+        let result = server.shutdown().await;+        match result {+            Ok(()) => Ok(CUnit::c_repr_of(Unit {}).unwrap()),+            Err(e) => Err(CArray::c_repr_of(+                format!("Failed to shutdown server: {}", e).into_bytes(),+            )+            .expect("Failed to convert error to CArray")),+        }+    })+}++/// Configuration for the test server.+#[derive(Deserialize)]+#[serde(remote = "TestServerConfig")]+pub struct TestServerConfigDef {+    /// Required path to executable or download info.+    #[serde(with = "EphemeralExeDef")]+    pub exe: EphemeralExe,+    /// Port to use or obtains a free one if none given.+    pub port: Option<u16>,+    /// Additional arguments to the test server.+    pub extra_args: Vec<String>,+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_start_test_server(+    runtime: *mut RuntimeRef,+    json_string: *const c_char,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CArray<u8>,+    result_slot: *mut *mut EphemeralServerRef,+) {+    let runtime_ref = unsafe { runtime.as_ref().unwrap() };+    let runtime = &runtime_ref.runtime;+    let mut de = serde_json::Deserializer::from_str(unsafe {+        std::str::from_utf8_unchecked(CStr::from_ptr(json_string).to_bytes())+    });+    let conf = TestServerConfigDef::deserialize(&mut de).expect("Failed to deserialize config");+    let hs: HsCallback<EphemeralServerRef, CArray<u8>> = HsCallback {+        cap,+        mvar,+        error_slot,+        result_slot,+    };+    runtime.future_result_into_hs(hs, async move {+        let result = conf.start_server().await;+        match result {+            Ok(server) => Ok(EphemeralServerRef {+                server,+                runtime: runtime.clone(),+            }),+            Err(e) => Err(+                CArray::c_repr_of(format!("Failed to start server: {}", e).into_bytes())+                    .expect("Failed to convert error to CArray"),+            ),+        }+    })+}
+ rust/src/lib.rs view
@@ -0,0 +1,5 @@+pub mod client;+pub mod ephemeral_server;+pub mod rpc;+pub mod runtime;+pub mod worker;
+ rust/src/rpc.rs view
@@ -0,0 +1,2017 @@+use crate::client::{rpc_req, rpc_resp, CRPCError, ClientRef, RPCError, RpcCall, TemporalCall};+use crate::runtime::{Capability, HsCallback, MVar};+use ffi_convert::{CArray, CReprOf};+use temporal_client::OperatorService;+use temporal_client::TestService;+use temporal_client::WorkflowService;++macro_rules! rpc_call {+    ($retry_client:ident, $call:ident, $call_name:ident) => {{+        if $call.retry {+            let req = rpc_req($call).map_err(|err| {+                CRPCError::c_repr_of(RPCError {+                    code: 0,+                    message: err,+                    details: vec![],+                })+                .unwrap()+            })?;+            rpc_resp($retry_client.$call_name(req).await)+        } else {+            let req = rpc_req($call).map_err(|err| {+                CRPCError::c_repr_of(RPCError {+                    code: 0,+                    message: err,+                    details: vec![],+                })+                .unwrap()+            })?;+            rpc_resp($retry_client.into_inner().$call_name(req).await)+        }+    }};+}++// TODO, these are all quite repetitive, can we generate them?+// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_count_workflow_executions(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, count_workflow_executions) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_create_schedule(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, create_schedule) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_delete_schedule(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, delete_schedule) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_deprecate_namespace(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, deprecate_namespace) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_describe_namespace(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, describe_namespace) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_describe_schedule(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, describe_schedule) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_describe_task_queue(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, describe_task_queue) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_describe_workflow_execution(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, describe_workflow_execution) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_get_cluster_info(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, get_cluster_info) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_get_search_attributes(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, get_search_attributes) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_get_system_info(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, get_system_info) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_get_worker_build_id_compatibility(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, get_worker_build_id_compatibility) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_get_workflow_execution_history(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, get_workflow_execution_history) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_get_workflow_execution_history_reverse(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, get_workflow_execution_history_reverse) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_list_archived_workflow_executions(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, list_archived_workflow_executions) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_list_closed_workflow_executions(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, list_closed_workflow_executions) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_list_namespaces(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, list_namespaces) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_list_open_workflow_executions(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, list_open_workflow_executions) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_list_schedule_matching_times(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, list_schedule_matching_times) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_list_schedules(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, list_schedules) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_list_task_queue_partitions(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, list_task_queue_partitions) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_list_workflow_executions(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, list_workflow_executions) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_patch_schedule(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, patch_schedule) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_poll_activity_task_queue(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, poll_activity_task_queue) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_poll_workflow_execution_update(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, poll_workflow_execution_update) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_poll_workflow_task_queue(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, poll_workflow_task_queue) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_query_workflow(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, query_workflow) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_record_activity_task_heartbeat(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, record_activity_task_heartbeat) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_record_activity_task_heartbeat_by_id(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, record_activity_task_heartbeat_by_id) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_register_namespace(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, register_namespace) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_request_cancel_workflow_execution(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, request_cancel_workflow_execution) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_reset_sticky_task_queue(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, reset_sticky_task_queue) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_reset_workflow_execution(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, reset_workflow_execution) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_respond_activity_task_canceled(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, respond_activity_task_canceled) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_respond_activity_task_canceled_by_id(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, respond_activity_task_canceled_by_id) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_respond_activity_task_completed(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, respond_activity_task_completed) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_respond_activity_task_completed_by_id(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, respond_activity_task_completed_by_id) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_respond_activity_task_failed(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, respond_activity_task_failed) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_respond_activity_task_failed_by_id(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, respond_activity_task_failed_by_id) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_respond_query_task_completed(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, respond_query_task_completed) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_respond_workflow_task_completed(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, respond_workflow_task_completed) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_respond_workflow_task_failed(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, respond_workflow_task_failed) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_scan_workflow_executions(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, scan_workflow_executions) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_signal_with_start_workflow_execution(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, signal_with_start_workflow_execution) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_signal_workflow_execution(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, signal_workflow_execution) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_start_workflow_execution(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, start_workflow_execution) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_terminate_workflow_execution(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, terminate_workflow_execution) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_update_namespace(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, update_namespace) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_update_schedule(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, update_schedule) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_update_workflow_execution(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, update_workflow_execution) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_update_worker_build_id_compatibility(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, update_worker_build_id_compatibility) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_get_current_time(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, get_current_time) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_lock_time_skipping(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, lock_time_skipping) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_sleep_until(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, sleep_until) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_sleep(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, sleep) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_unlock_time_skipping_with_sleep(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, unlock_time_skipping_with_sleep) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_unlock_time_skipping(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, unlock_time_skipping) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_add_or_update_remote_cluster(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, add_or_update_remote_cluster) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_add_search_attributes(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, add_search_attributes) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_delete_namespace(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, delete_namespace) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_list_clusters(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, list_clusters) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_list_search_attributes(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, list_search_attributes) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_remove_remote_cluster(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, remove_remote_cluster) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_remove_search_attributes(+    client: *mut ClientRef,+    c_call: *const RpcCall,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CRPCError,+    result_slot: *mut *mut CArray<u8>,+) {+    let client = unsafe { &mut *client };+    let mut retry_client = client.retry_client.clone();+    let call: TemporalCall = unsafe { (&*c_call).into() };++    let callback: HsCallback<CArray<u8>, CRPCError> = HsCallback {+        cap,+        mvar,+        result_slot,+        error_slot,+    };+    client.runtime.future_result_into_hs(callback, async move {+        match rpc_call!(retry_client, call, remove_search_attributes) {+            Ok(resp) => Ok(CArray::c_repr_of(resp).unwrap()),+            Err(err) => Err(err),+        }+    });+}
+ rust/src/runtime.rs view
@@ -0,0 +1,277 @@+use ffi_convert::*;+use serde::{Deserialize, Serialize};+use std::collections::HashMap;+use std::future::Future;+use std::net::SocketAddr;+use std::os::raw::c_int;+use std::sync::Arc;+use std::time::{Duration, SystemTime};+use temporal_sdk_core::telemetry::{+    build_otlp_metric_exporter, construct_filter_string, start_prometheus_metric_exporter,+};+use temporal_sdk_core::{CoreRuntime, TokioRuntimeBuilder};+use temporal_sdk_core_api::telemetry::metrics::{CoreMeter, NoOpCoreMeter};+use temporal_sdk_core_api::telemetry::{+    CoreTelemetry, Logger, OtelCollectorOptionsBuilder, PrometheusExporterOptionsBuilder,+    TelemetryOptions, TelemetryOptionsBuilder,+};+use tracing::Level;++pub struct RuntimeRef {+    pub(crate) runtime: Runtime,+}++#[derive(Clone)]+pub(crate) struct Runtime {+    pub(crate) core: Arc<CoreRuntime>,+    pub(crate) try_put_mvar: extern "C" fn(capability: Capability, mvar: *mut MVar) -> (),+}++fn init_runtime(+    telemetry_config: TelemetryOptions,+    late_telemetry_options: HsTelemetryOptions,+    try_put_mvar: extern "C" fn(capability: Capability, mvar: *mut MVar) -> (),+) -> Box<RuntimeRef> {+    let mut runtime = CoreRuntime::new(telemetry_config, TokioRuntimeBuilder::default()).unwrap();++    let _guard = runtime.tokio_handle().enter();+    let core_meter: Arc<dyn CoreMeter> = match late_telemetry_options {+        HsTelemetryOptions::NoTelemetry => Arc::new(NoOpCoreMeter) as Arc<dyn CoreMeter>,+        HsTelemetryOptions::OtelTelemetryOptions {+            url,+            headers,+            metric_periodicity,+            global_tags,+        } => Arc::new(+            build_otlp_metric_exporter(+                OtelCollectorOptionsBuilder::default()+                    .url(url.parse().expect("Invalid URL"))+                    .metric_periodicity(metric_periodicity.unwrap_or_else(|| Duration::new(1, 0)))+                    .headers(headers)+                    .global_tags(global_tags)+                    .build()+                    .expect("Invalid OTEl configuration"),+            )+            .expect("Otel Metric exporter"),+        ) as Arc<dyn CoreMeter>,+        HsTelemetryOptions::PrometheusTelemetryOptions {+            socket_addr,+            global_tags,+            counters_total_suffix,+            unit_suffix,+        } => {+            let srv = start_prometheus_metric_exporter(+                PrometheusExporterOptionsBuilder::default()+                    .socket_addr(socket_addr)+                    .unit_suffix(unit_suffix)+                    .global_tags(global_tags)+                    .counters_total_suffix(counters_total_suffix)+                    .build()+                    .expect("Invalid Prometheus configuration"),+            )+            .expect("Failed to start prometheus exporter");+            srv.meter as Arc<dyn CoreMeter>+        }+    };+    runtime.telemetry_mut().attach_late_init_metrics(core_meter);++    // TODO need to figure out how to handle errors here+    Box::new(RuntimeRef {+        runtime: Runtime {+            core: Arc::new(runtime),+            try_put_mvar,+        },+    })+}++#[derive(Serialize, Deserialize)]+#[serde(tag = "tag")]+pub enum HsTelemetryOptions {+    OtelTelemetryOptions {+        url: String,+        headers: HashMap<String, String>,+        metric_periodicity: Option<Duration>,+        global_tags: HashMap<String, String>,+    },+    PrometheusTelemetryOptions {+        socket_addr: SocketAddr,+        global_tags: HashMap<String, String>,+        counters_total_suffix: bool,+        unit_suffix: bool,+    },+    NoTelemetry,+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_init_runtime(+    telemetry_opts: *const CArray<u8>,+    try_put_mvar: extern "C" fn(Capability, *mut MVar) -> (),+) -> *mut RuntimeRef {+    let telemetry_opts = unsafe {+        CArray::raw_borrow(telemetry_opts)+            .unwrap()+            .as_rust()+            .unwrap()+            .clone()+    };+    let telemetry_opts: HsTelemetryOptions =+        serde_json::from_slice(telemetry_opts.as_slice()).expect("Failed to parse");++    let early_options = TelemetryOptionsBuilder::default()+        .logging(Logger::Forward {+            filter: construct_filter_string(Level::INFO, Level::ERROR),+        })+        .attach_service_name(true)+        // .metrics(core_meter)+        .build()+        .expect("Invalid TelemetryOptions");+    let rt = init_runtime(early_options, telemetry_opts, try_put_mvar);+    Box::into_raw(rt)+}++fn safe_drop_runtime(runtime: Box<RuntimeRef>) {+    drop(runtime)+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_free_runtime(runtime: *mut RuntimeRef) {+    unsafe { safe_drop_runtime(Box::from_raw(runtime)) };+}++#[repr(C)]+pub struct MVar {+    _data: [u8; 0],+    _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,+}++#[repr(C)]+pub struct Capability {+    pub cap_num: c_int,+}++pub struct HsCallback<A, E> {+    pub cap: Capability,+    pub mvar: *mut MVar,+    pub result_slot: *mut *mut A,+    pub error_slot: *mut *mut E,+}++impl<A, E> HsCallback<A, E> {+    pub(crate) fn put_success(self, runtime: &Runtime, result: A)+    where+        A: RawPointerConverter<A>,+    {+        unsafe {+            *self.result_slot = result.into_raw_pointer_mut();+            *self.error_slot = std::ptr::null_mut();+            runtime.put_mvar(self.cap, self.mvar);+        }+    }++    pub(crate) fn put_failure(self, runtime: &Runtime, error: E)+    where+        E: RawPointerConverter<E>,+    {+        unsafe {+            *self.error_slot = error.into_raw_pointer_mut();+            *self.result_slot = std::ptr::null_mut();+            runtime.put_mvar(self.cap, self.mvar);+        }+    }++    pub(crate) fn put_result(self, runtime: &Runtime, result: Result<A, E>)+    where+        A: RawPointerConverter<A>,+        E: RawPointerConverter<E>,+    {+        match result {+            Ok(result) => self.put_success(runtime, result),+            Err(error) => self.put_failure(runtime, error),+        }+    }+}++impl Runtime {+    pub fn future_result_into_hs<F, T, E>(&self, callback: HsCallback<T, E>, fut: F)+    where+        F: Future<Output = Result<T, E>> + Send + 'static,+        T: RawPointerConverter<T>,+        E: RawPointerConverter<E>,+    {+        let handle = self.core.tokio_handle();+        let _guard = handle.enter();+        let result = handle.block_on(fut);+        callback.put_result(self, result);+    }++    pub fn put_mvar(&self, capability: Capability, mvar: *mut MVar) {+        (self.try_put_mvar)(capability, mvar);+    }+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_drop_byte_array(str: *const CArray<u8>) {+    unsafe {+        drop(CArray::from_raw_pointer(str));+    }+}++#[derive(Serialize)]+pub struct CoreLogDef {+    pub target: String,+    pub message: String,+    pub timestamp: SystemTime,+    pub level: String,+    pub fields: HashMap<String, serde_json::Value>,+    pub span_contexts: Vec<String>,+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_runtime_fetch_logs(+    runtime: *mut RuntimeRef,+) -> *const CArray<CArray<u8>> {+    let runtime = unsafe { &*runtime };+    let logs = runtime.runtime.core.telemetry().fetch_buffered_logs();+    let hs_logs: Vec<Vec<u8>> = logs+        .iter()+        .map(|log| {+            let log = CoreLogDef {+                target: log.target.clone(),+                message: log.message.clone(),+                timestamp: log.timestamp,+                level: String::from(log.level.as_str()),+                fields: log.fields.clone(),+                span_contexts: log.span_contexts.clone(),+            };+            serde_json::to_vec(&log).expect("Failed to serialize log line")+        })+        .collect();+    CArray::c_repr_of(hs_logs).unwrap().into_raw_pointer()+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_runtime_free_logs(logs: *const CArray<CArray<u8>>) {+    unsafe {+        drop(CArray::from_raw_pointer(logs));+    }+}
+ rust/src/worker.rs view
@@ -0,0 +1,823 @@+use ffi_convert::{AsRust, CArray, CDrop, CDropError, CReprOf, RawBorrow, RawPointerConverter};+use libc::c_char;+use prost::Message;+use std::collections::{HashMap, HashSet};+use std::str;+use std::sync::Arc;+use std::time::Duration;+use temporal_sdk_core::replay::{HistoryForReplay, ReplayWorkerInput};+use temporal_sdk_core_api::errors::{PollError, WorkflowErrorType};+use temporal_sdk_core_api::Worker;+use temporal_sdk_core_protos::coresdk::workflow_completion::WorkflowActivationCompletion;+use temporal_sdk_core_protos::coresdk::{ActivityHeartbeat, ActivityTaskCompletion};+use temporal_sdk_core_protos::temporal::api::history::v1::History;+use tokio::sync::mpsc::{channel, Sender};+use tokio_stream::wrappers::ReceiverStream;++use crate::client;+use crate::runtime::{self, Capability, HsCallback, MVar};+use serde::{Deserialize, Serialize};++pub struct WorkerRef {+    worker: Option<Arc<temporal_sdk_core::Worker>>,+    runtime: runtime::Runtime,+}++#[derive(Serialize, Deserialize)]+pub struct WorkerConfig {+    namespace: String,+    task_queue: String,+    build_id: String,+    identity_override: Option<String>,+    max_cached_workflows: usize,+    max_outstanding_workflow_tasks: usize,+    max_outstanding_activities: usize,+    max_outstanding_local_activities: usize,+    max_concurrent_workflow_task_polls: usize,+    nonsticky_to_sticky_poll_ratio: f32,+    max_concurrent_activity_task_polls: usize,+    no_remote_activities: bool,+    sticky_queue_schedule_to_start_timeout_millis: u64,+    max_heartbeat_throttle_interval_millis: u64,+    default_heartbeat_throttle_interval_millis: u64,+    max_activities_per_second: Option<f64>,+    max_task_queue_activities_per_second: Option<f64>,+    graceful_shutdown_period_millis: u64,+    nondeterminism_as_workflow_fail: bool,+    nondeterminism_as_workflow_fail_for_types: Vec<String>,+}++impl TryFrom<WorkerConfig> for temporal_sdk_core::WorkerConfig {+    type Error = WorkerError;++    fn try_from(conf: WorkerConfig) -> Result<Self, WorkerError> {+        temporal_sdk_core::WorkerConfigBuilder::default()+            .namespace(conf.namespace)+            .task_queue(conf.task_queue)+            .worker_build_id(conf.build_id)+            .client_identity_override(conf.identity_override)+            .max_cached_workflows(conf.max_cached_workflows)+            .max_outstanding_workflow_tasks(conf.max_outstanding_workflow_tasks)+            .max_outstanding_activities(conf.max_outstanding_activities)+            .max_outstanding_local_activities(conf.max_outstanding_local_activities)+            .max_concurrent_wft_polls(conf.max_concurrent_workflow_task_polls)+            .nonsticky_to_sticky_poll_ratio(conf.nonsticky_to_sticky_poll_ratio)+            .max_concurrent_at_polls(conf.max_concurrent_activity_task_polls)+            .no_remote_activities(conf.no_remote_activities)+            .sticky_queue_schedule_to_start_timeout(Duration::from_millis(+                conf.sticky_queue_schedule_to_start_timeout_millis,+            ))+            .max_heartbeat_throttle_interval(Duration::from_millis(+                conf.max_heartbeat_throttle_interval_millis,+            ))+            .default_heartbeat_throttle_interval(Duration::from_millis(+                conf.default_heartbeat_throttle_interval_millis,+            ))+            .max_worker_activities_per_second(conf.max_activities_per_second)+            .max_task_queue_activities_per_second(conf.max_task_queue_activities_per_second)+            // Even though grace period is optional, if it is not set then the+            // auto-cancel-activity behavior of shutdown will not occur, so we+            // always set it even if 0.+            .graceful_shutdown_period(Duration::from_millis(conf.graceful_shutdown_period_millis))+            .workflow_failure_errors(if conf.nondeterminism_as_workflow_fail {+                HashSet::from([WorkflowErrorType::Nondeterminism])+            } else {+                HashSet::new()+            })+            .workflow_types_to_failure_errors(+                conf.nondeterminism_as_workflow_fail_for_types+                    .iter()+                    .map(|s| {+                        (+                            s.to_owned(),+                            HashSet::from([WorkflowErrorType::Nondeterminism]),+                        )+                    })+                    .collect::<HashMap<String, HashSet<WorkflowErrorType>>>(),+            )+            .build()+            .map_err(|err| WorkerError {+                code: WorkerErrorCode::InvalidWorkerConfig,+                message: format!("{}", err),+            })+    }+}++macro_rules! enter_sync {+    ($runtime:expr) => {+        if let Some(subscriber) = $runtime.core.telemetry().trace_subscriber() {+            temporal_sdk_core::telemetry::set_trace_subscriber_for_current_thread(subscriber);+        }+        let _guard = $runtime.core.tokio_handle().enter();+    };+}++#[repr(u8)]+#[derive(Copy, Clone, Debug)]+pub enum WorkerErrorCode {+    SDKError = 1,+    InitWorkerFailed = 2,+    InitReplayWorkerFailed = 3,+    InvalidProto = 4,+    ReplayWorkerClosed = 5,+    PollShutdownError = 6,+    PollFailure = 7,+    CompletionFailure = 8,+    InvalidWorkerConfig = 9,+}++impl AsRust<WorkerErrorCode> for WorkerErrorCode {+    fn as_rust(&self) -> Result<WorkerErrorCode, ffi_convert::AsRustError> {+        Ok(*self)+    }+}++impl CDrop for WorkerErrorCode {+    fn do_drop(&mut self) -> Result<(), CDropError> {+        Ok(())+    }+}++impl CReprOf<WorkerErrorCode> for WorkerErrorCode {+    fn c_repr_of(input: WorkerErrorCode) -> Result<WorkerErrorCode, ffi_convert::CReprOfError> {+        Ok(input)+    }+}++#[derive(Debug)]+pub struct WorkerError {+    code: WorkerErrorCode,+    message: String,+}++#[repr(C)]+#[derive(CReprOf, AsRust, RawPointerConverter, CDrop)]+#[target_type(WorkerError)]+pub struct CWorkerError {+    code: WorkerErrorCode,+    message: *const c_char,+}++struct FormattedError {+    message: String,+}++#[repr(C)]+#[derive(CReprOf, AsRust, RawPointerConverter, CDrop)]+#[target_type(FormattedError)]+pub struct CWorkerValidationError {+    message: *const c_char,+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_drop_worker_validation_error(+    err: *mut CWorkerValidationError,+) {+    unsafe { drop(CWorkerValidationError::from_raw_pointer_mut(err)) }+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_drop_worker_error(err: *mut CWorkerError) {+    unsafe { drop(CWorkerError::from_raw_pointer_mut(err)) }+}++pub struct Unit {}+#[repr(C)]+#[derive(CReprOf, AsRust, RawPointerConverter, CDrop)]+#[target_type(Unit)]+pub struct CUnit {}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_drop_unit(unit: *mut CUnit) {+    unsafe { drop(CUnit::from_raw_pointer_mut(unit)) }+}++fn new_worker(client: &client::ClientRef, config: WorkerConfig) -> Result<WorkerRef, WorkerError> {+    enter_sync!(&client.runtime);+    let config: temporal_sdk_core::WorkerConfig = config.try_into()?;+    let worker = temporal_sdk_core::init_worker(+        &client.runtime.core,+        config,+        client.retry_client.clone().into_inner(),+    )+    .map_err(|err| WorkerError {+        code: WorkerErrorCode::InitWorkerFailed,+        message: format!("Failed creating worker: {}", err),+    })?;+    Ok(WorkerRef {+        worker: Some(Arc::new(worker)),+        runtime: client.runtime.clone(),+    })+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_drop_worker(worker: *mut WorkerRef) {+    unsafe { drop(Box::from_raw(worker)) }+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_new_worker(+    client: *mut client::ClientRef,+    config: *const CArray<u8>,+    result_slot: *mut *mut WorkerRef,+    error_slot: *mut *mut CWorkerError,+) {+    let client_ref = unsafe { client.as_ref() }.expect("client is null");+    let config_json = unsafe { CArray::raw_borrow(config).unwrap() };+    let config = serde_json::from_slice(&config_json.as_rust().unwrap().clone()).map_err(|err| {+        WorkerError {+            code: WorkerErrorCode::InvalidWorkerConfig,+            message: format!("{}", err),+        }+    });++    match config {+        Ok(config) => {+            let result = new_worker(client_ref, config);+            match result {+                Ok(worker_ref) => {+                    unsafe { *result_slot = Box::into_raw(Box::new(worker_ref)) };+                }+                Err(worker_error) => {+                    eprintln!("Error: {:?}", worker_error);+                    unsafe {+                        *error_slot = CWorkerError::c_repr_of(worker_error)+                            .unwrap()+                            .into_raw_pointer_mut()+                    };+                }+            }+        }+        Err(worker_error) => {+            eprintln!("Error: {:?}", worker_error);+            unsafe {+                *error_slot = CWorkerError::c_repr_of(worker_error)+                    .unwrap()+                    .into_raw_pointer_mut()+            };+        }+    }+}++fn new_replay_worker(+    runtime_ref: &runtime::RuntimeRef,+    config: WorkerConfig,+) -> Result<(WorkerRef, HistoryPusher), WorkerError> {+    enter_sync!(runtime_ref.runtime);+    let config: temporal_sdk_core::WorkerConfig = config.try_into()?;+    let (history_pusher, stream) = HistoryPusher::new(runtime_ref.runtime.clone());+    let worker = WorkerRef {+        worker: Some(Arc::new(+            temporal_sdk_core::init_replay_worker(ReplayWorkerInput::new(config, stream)).map_err(+                |err| WorkerError {+                    code: WorkerErrorCode::InitReplayWorkerFailed,+                    message: format!("Failed creating replay worker: {}", err),+                },+            )?,+        )),+        runtime: runtime_ref.runtime.clone(),+    };++    Ok((worker, history_pusher))+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_new_replay_worker(+    runtime: *mut runtime::RuntimeRef,+    config: *const CArray<u8>,+    worker_slot: *mut *mut WorkerRef,+    history_slot: *mut *mut HistoryPusher,+    error_slot: *mut *mut CWorkerError,+) {+    let runtime_ref = unsafe { runtime.as_ref() }.expect("client is null");+    let config_json = unsafe { CArray::raw_borrow(config).unwrap() };+    let config =+        serde_json::from_slice(&config_json.as_rust().unwrap()).map_err(|err| WorkerError {+            code: WorkerErrorCode::InvalidWorkerConfig,+            message: format!("{}", err),+        });++    match config {+        Ok(config) => {+            let result = new_replay_worker(runtime_ref, config);+            match result {+                Ok((worker_ref, history_pusher)) => unsafe {+                    *worker_slot = Box::into_raw(Box::new(worker_ref));+                    *history_slot = Box::into_raw(Box::new(history_pusher));+                },+                Err(worker_error) => {+                    unsafe {+                        *error_slot = CWorkerError::c_repr_of(worker_error)+                            .unwrap()+                            .into_raw_pointer_mut()+                    };+                }+            }+        }+        Err(worker_error) => {+            unsafe {+                *error_slot = CWorkerError::c_repr_of(worker_error)+                    .unwrap()+                    .into_raw_pointer_mut()+            };+        }+    }+}++impl WorkerRef {+    fn poll_workflow_activation(&self, hs: HsCallback<CArray<u8>, CWorkerError>) {+        let worker = self.worker.as_ref().unwrap().clone();+        self.runtime.future_result_into_hs(hs, async move {+            let bytes = match worker.poll_workflow_activation().await {+                Ok(act) => Ok(act.encode_to_vec()),+                Err(PollError::ShutDown) => Err(WorkerError {+                    code: WorkerErrorCode::PollShutdownError,+                    message: "Poll shutdown error".to_string(),+                }),+                Err(err) => Err(WorkerError {+                    code: WorkerErrorCode::PollFailure,+                    message: format!("{}", err),+                }),+            };+            Ok(+                CArray::c_repr_of(bytes.map_err(|err| CWorkerError::c_repr_of(err).unwrap())?)+                    .unwrap(),+            )+        })+    }++    fn poll_activity_task(&self, hs: HsCallback<CArray<u8>, CWorkerError>) {+        let worker = self.worker.as_ref().unwrap().clone();+        self.runtime.future_result_into_hs(hs, async move {+            let bytes = (match worker.poll_activity_task().await {+                Ok(task) => Ok(task.encode_to_vec()),+                Err(PollError::ShutDown) => Err(WorkerError {+                    code: WorkerErrorCode::PollShutdownError,+                    message: "Poll shutdown error".to_string(),+                }),+                Err(err) => Err(WorkerError {+                    code: WorkerErrorCode::PollFailure,+                    message: format!("Poll failure: {}", err),+                }),+            })+            .map_err(|err| CWorkerError::c_repr_of(err).unwrap());+            Ok(CArray::c_repr_of(bytes?).unwrap())+        })+    }++    fn complete_workflow_activation(+        &self,+        hs: HsCallback<CUnit, CWorkerError>,+        proto: &[u8],+    ) {+        let worker = self.worker.as_ref().unwrap().clone();+        let completion = WorkflowActivationCompletion::decode(proto);+        self.runtime.future_result_into_hs(hs, async move {+            let completion = completion.map_err(|err| {+                CWorkerError::c_repr_of(WorkerError {+                    code: WorkerErrorCode::InvalidProto,+                    message: format!("Invalid proto: {}", err),+                })+                .unwrap()+            })?;+            worker+                .complete_workflow_activation(completion)+                .await+                .map_err(|err| {+                    CWorkerError::c_repr_of(WorkerError {+                        code: WorkerErrorCode::CompletionFailure,+                        message: format!("{}", err),+                    })+                    .unwrap()+                })?;+            Ok(CUnit {})+        })+    }++    fn complete_activity_task(&self, hs: HsCallback<CUnit, CWorkerError>, proto: &[u8]) {+        let worker = self.worker.as_ref().unwrap().clone();+        let completion = ActivityTaskCompletion::decode(proto);+        self.runtime.future_result_into_hs(hs, async move {+            let completion = completion.map_err(|err| {+                CWorkerError::c_repr_of(WorkerError {+                    code: WorkerErrorCode::InvalidProto,+                    message: format!("{}", err),+                })+                .unwrap()+            })?;+            worker+                .complete_activity_task(completion)+                .await+                .map_err(|err| {+                    CWorkerError::c_repr_of(WorkerError {+                        code: WorkerErrorCode::CompletionFailure,+                        message: format!("{}", err),+                    })+                    .unwrap()+                })?;+            Ok(CUnit {})+        })+    }++    fn record_activity_heartbeat(&self, proto: &[u8]) -> Result<(), WorkerError> {+        enter_sync!(self.runtime);+        let heartbeat = ActivityHeartbeat::decode(proto).map_err(|err| WorkerError {+            code: WorkerErrorCode::InvalidProto,+            message: format!("{}", err),+        });++        match self.worker.as_ref() {+            None => Ok(()),+            Some(worker) => {+                worker.record_activity_heartbeat(heartbeat?);+                // TODO return error+                Ok(())+            }+        }+    }++    fn request_workflow_eviction(&self, run_id: &str) {+        enter_sync!(self.runtime);+        self.worker+            .as_ref()+            .unwrap()+            .request_workflow_eviction(run_id);+    }++    fn initiate_shutdown(&self) {+        let worker = self.worker.as_ref().unwrap().clone();+        worker.initiate_shutdown();+    }++    fn finalize_shutdown(&mut self, hs: HsCallback<CUnit, CWorkerError>) {+        // Take the worker out of the option and leave None. This should be the+        // only reference remaining to the worker so try_unwrap will work.+        let core_worker = match Arc::try_unwrap(self.worker.take().unwrap()) {+            Ok(core_worker) => Ok(core_worker),+            Err(arc) => Err(WorkerError {+                code: WorkerErrorCode::SDKError,+                message: format!(+                    "Cannot finalize, expected 1 reference, got {}",+                    Arc::strong_count(&arc)+                ),+            }),+        };+        self.runtime.clone().future_result_into_hs(hs, async move {+            match core_worker {+                Ok(worker) => {+                    worker.finalize_shutdown().await;+                    Ok(CUnit {})+                }+                Err(err) => Err(CWorkerError::c_repr_of(err).unwrap()),+            }+        })+    }+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_validate_worker(+    worker: *mut WorkerRef,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CWorkerValidationError,+    result_slot: *mut *mut CUnit,+) {+    let worker = unsafe { &mut *worker };+    let hs = HsCallback {+        mvar,+        cap,+        error_slot,+        result_slot,+    };++    let w = worker.worker.as_ref().unwrap().clone();+    worker.runtime.future_result_into_hs(hs, async move {+        let result = w.validate().await;+        match result {+            Ok(()) => Ok(CUnit {}),+            Err(err) => Err(CWorkerValidationError::c_repr_of(FormattedError {+                message: format!("{}", err),+            })+            .unwrap()),+        }+    })+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_worker_poll_workflow_activation(+    worker: *mut WorkerRef,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CWorkerError,+    result_slot: *mut *mut CArray<u8>,+) {+    let worker = unsafe { &*worker };+    let hs = HsCallback {+        mvar,+        cap,+        error_slot,+        result_slot,+    };+    worker.poll_workflow_activation(hs)+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_worker_poll_activity_task(+    worker: *mut WorkerRef,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CWorkerError,+    result_slot: *mut *mut CArray<u8>,+) {+    let worker = unsafe { &*worker };+    let hs = HsCallback {+        mvar,+        cap,+        error_slot,+        result_slot,+    };+    worker.poll_activity_task(hs)+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_worker_complete_workflow_activation(+    worker: *mut WorkerRef,+    proto: *const CArray<u8>,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CWorkerError,+    result_slot: *mut *mut CUnit,+) {+    let worker = unsafe { &*worker };+    let proto: &CArray<u8> = unsafe { CArray::raw_borrow(proto).unwrap() };+    let proto: &[u8] = &proto.as_rust().unwrap().clone();+    let hs = HsCallback {+        mvar,+        cap,+        error_slot,+        result_slot,+    };+    worker.complete_workflow_activation(hs, proto)+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_worker_complete_activity_task(+    worker: *mut WorkerRef,+    proto: *const CArray<u8>,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CWorkerError,+    result_slot: *mut *mut CUnit,+) {+    let worker = unsafe { &*worker };+    let proto: &CArray<u8> = unsafe { CArray::raw_borrow(proto).unwrap() };+    let proto: &[u8] = &proto.as_rust().unwrap().clone();+    let hs = HsCallback {+        mvar,+        cap,+        error_slot,+        result_slot,+    };+    worker.complete_activity_task(hs, proto)+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_worker_record_activity_heartbeat(+    worker: *mut WorkerRef,+    proto: *const CArray<u8>,+    error_slot: *mut *mut CWorkerError,+    result_slot: *mut *mut CUnit,+) {+    let worker = unsafe { &*worker };+    let proto: &CArray<u8> = unsafe { CArray::raw_borrow(proto).unwrap() };+    let proto: &[u8] = &proto.as_rust().unwrap().clone();+    let result = worker.record_activity_heartbeat(proto);+    match result {+        Ok(_) => unsafe {+            *error_slot = std::ptr::null_mut();+            *result_slot = std::ptr::null_mut();+        },+        Err(err) => {+            let err = CWorkerError::c_repr_of(err).unwrap();+            unsafe {+                *error_slot = err.into_raw_pointer_mut();+                *result_slot = std::ptr::null_mut();+            }+        }+    }+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_worker_request_workflow_eviction(+    worker: *mut WorkerRef,+    run_id: *const CArray<u8>,+) {+    let worker = unsafe { &*worker };+    let run_id: &CArray<u8> = unsafe { CArray::raw_borrow(run_id).unwrap() };+    let run_id: &[u8] = &run_id.as_rust().unwrap().clone();+    let run_id: &str = unsafe { str::from_utf8_unchecked(run_id) };+    worker.request_workflow_eviction(run_id)+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_worker_initiate_shutdown(worker: *mut WorkerRef) {+    let worker = unsafe { &*worker };+    worker.initiate_shutdown()+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_worker_finalize_shutdown(+    worker: *mut WorkerRef,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CWorkerError,+    result_slot: *mut *mut CUnit,+) {+    let worker = unsafe { &mut *worker };+    let hs = HsCallback {+        mvar,+        cap,+        error_slot,+        result_slot,+    };+    worker.finalize_shutdown(hs)+}++pub struct HistoryPusher {+    tx: Option<Sender<HistoryForReplay>>,+    runtime: runtime::Runtime,+}++impl HistoryPusher {+    fn new(runtime: runtime::Runtime) -> (Self, ReceiverStream<HistoryForReplay>) {+        let (tx, rx) = channel(1);+        (+            Self {+                tx: Some(tx),+                runtime,+            },+            ReceiverStream::new(rx),+        )+    }+}++impl HistoryPusher {+    fn push_history(+        &self,+        workflow_id: &str,+        history_proto: &[u8],+        hs: HsCallback<CUnit, CWorkerError>,+    ) {+        let history = History::decode(history_proto).map_err(|err| WorkerError {+            code: WorkerErrorCode::InvalidProto,+            message: format!("Invalid proto: {}", err),+        });+        let wfid = workflow_id.to_string();+        let tx = if let Some(tx) = self.tx.as_ref() {+            Ok(tx.clone())+        } else {+            Err(WorkerError {+                code: WorkerErrorCode::ReplayWorkerClosed,+                message: "Replay worker is no longer accepting new histories".to_string(),+            })+        };+        // We accept this doesn't have logging/tracing+        self.runtime.future_result_into_hs(hs, async move {+            let history = history.map_err(|err| CWorkerError::c_repr_of(err).unwrap())?;+            let tx = tx.map_err(|err| CWorkerError::c_repr_of(err).unwrap())?;++            tx.send(HistoryForReplay::new(history, wfid))+                .await+                .map_err(|_| {+                    CWorkerError::c_repr_of(WorkerError {+                        code: WorkerErrorCode::SDKError,+                        message: "Channel for history replay was dropped, this is an SDK bug.".to_string(),+                    })+                    .unwrap()+                })?;+            Ok(CUnit {})+        })+    }++    fn close(&mut self) {+        self.tx.take();+    }+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell <-> Tokio FFI bridge invariants.+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_history_pusher_push_history(+    history_pusher: *mut HistoryPusher,+    workflow_id: *const CArray<u8>,+    history_proto: *const CArray<u8>,+    mvar: *mut MVar,+    cap: Capability,+    error_slot: *mut *mut CWorkerError,+    result_slot: *mut *mut CUnit,+) {+    let history_pusher = unsafe { &mut *history_pusher };+    let workflow_id: &CArray<u8> = unsafe { CArray::raw_borrow(workflow_id).unwrap() };+    let workflow_id = workflow_id.as_rust().unwrap().clone();+    let workflow_id: &str = unsafe { str::from_utf8_unchecked(&workflow_id) };+    let history_proto: &CArray<u8> = unsafe { CArray::raw_borrow(history_proto).unwrap() };+    let history_proto: &[u8] = &history_proto.as_rust().unwrap().clone();+    history_pusher.push_history(+        workflow_id,+        history_proto,+        HsCallback {+            mvar,+            cap,+            error_slot,+            result_slot,+        },+    )+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+///+/// The caller must ensure that the argument is a live pointer to a [`HistoryPusher`], typically from across the FFI+/// boundary after having been constructed by [`hs_temporal_new_replay_worker`].+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_history_pusher_close(history_pusher: *mut HistoryPusher) {+    let history_pusher = unsafe { &mut *history_pusher };+    history_pusher.close()+}++// TODO: [publish-crate]+/// # Safety+///+/// Haskell FFI bridge invariants.+///+/// The caller must ensure that the argument is a live pointer to a [`HistoryPusher`], typically from across the FFI+/// boundary after having been constructed by [`hs_temporal_new_replay_worker`].+#[unsafe(no_mangle)]+pub unsafe extern "C" fn hs_temporal_history_pusher_drop(history_pusher: *mut HistoryPusher) {+    let history_pusher = unsafe { Box::from_raw(history_pusher) };+    drop(history_pusher)+}
+ rust/temporal_bridge.h view
@@ -0,0 +1,706 @@+/* Generated with cbindgen:0.27.0 */++/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */++#include <stdarg.h>+#include <stdbool.h>+#include <stdint.h>+#include <stdlib.h>++enum WorkerErrorCode {+  SDKError = 1,+  InitWorkerFailed = 2,+  InitReplayWorkerFailed = 3,+  InvalidProto = 4,+  ReplayWorkerClosed = 5,+  PollShutdownError = 6,+  PollFailure = 7,+  CompletionFailure = 8,+  InvalidWorkerConfig = 9,+};+typedef uint8_t WorkerErrorCode;++typedef struct ClientRef ClientRef;++typedef struct EphemeralServerRef EphemeralServerRef;++typedef struct HistoryPusher HistoryPusher;++typedef struct RuntimeRef RuntimeRef;++typedef struct WorkerRef WorkerRef;++/**+ * A utility type to represent arrays of the parametrized type.+ * Note that the parametrized type should have a C-compatible representation.+ *+ * # Example+ *+ * ```+ * use ffi_convert::{CReprOf, AsRust, CDrop, CArray};+ * use libc::c_char;+ *+ * pub struct PizzaTopping {+ *     pub ingredient: String,+ * }+ *+ * #[derive(CDrop, CReprOf, AsRust)]+ * #[target_type(PizzaTopping)]+ * pub struct CPizzaTopping {+ *     pub ingredient: *const c_char+ * }+ *+ * let toppings = vec![+ *         PizzaTopping { ingredient: "Cheese".to_string() },+ *         PizzaTopping { ingredient: "Ham".to_string() } ];+ *+ * let ctoppings = CArray::<CPizzaTopping>::c_repr_of(toppings);+ *+ * ```+ */+typedef struct CArray_u8 {+  const uint8_t *data_ptr;+  uintptr_t size;+} CArray_u8;++typedef struct Capability {+  int cap_num;+} Capability;++typedef struct MVar {+  uint8_t _data[0];+} MVar;++/**+ * A utility type to represent arrays of the parametrized type.+ * Note that the parametrized type should have a C-compatible representation.+ *+ * # Example+ *+ * ```+ * use ffi_convert::{CReprOf, AsRust, CDrop, CArray};+ * use libc::c_char;+ *+ * pub struct PizzaTopping {+ *     pub ingredient: String,+ * }+ *+ * #[derive(CDrop, CReprOf, AsRust)]+ * #[target_type(PizzaTopping)]+ * pub struct CPizzaTopping {+ *     pub ingredient: *const c_char+ * }+ *+ * let toppings = vec![+ *         PizzaTopping { ingredient: "Cheese".to_string() },+ *         PizzaTopping { ingredient: "Ham".to_string() } ];+ *+ * let ctoppings = CArray::<CPizzaTopping>::c_repr_of(toppings);+ *+ * ```+ */+typedef struct CArray_CArray_u8 {+  const struct CArray_u8 *data_ptr;+  uintptr_t size;+} CArray_CArray_u8;++typedef struct CRPCError {+  uint32_t code;+  const char *message;+  const struct CArray_u8 *details;+} CRPCError;++typedef struct HaskellHashMapEntries {+  const uint8_t *key;+  uintptr_t key_len;+  const uint8_t *value;+  uintptr_t value_len;+  const struct HaskellHashMapEntries *next;+} HaskellHashMapEntries;++typedef struct RpcCall {+  const struct CArray_u8 *req;+  bool retry;+  const struct HaskellHashMapEntries *metadata;+  const uint64_t *timeout_millis;+} RpcCall;++typedef struct CWorkerError {+  WorkerErrorCode code;+  const char *message;+} CWorkerError;++typedef struct CUnit {++} CUnit;++typedef struct CWorkerValidationError {+  const char *message;+} CWorkerValidationError;++struct RuntimeRef *hs_temporal_init_runtime(const struct CArray_u8 *telemetry_opts,+                                            void (*try_put_mvar)(struct Capability, struct MVar*));++void hs_temporal_free_runtime(struct RuntimeRef *runtime);++void hs_temporal_drop_byte_array(const struct CArray_u8 *str);++const struct CArray_CArray_u8 *hs_temporal_runtime_fetch_logs(struct RuntimeRef *runtime);++void hs_temporal_runtime_free_logs(const struct CArray_CArray_u8 *logs);++void hs_temporal_connect_client(const struct RuntimeRef *runtime_ref,+                                const char *config_json,+                                struct MVar *mvar,+                                struct Capability cap,+                                struct CArray_u8 **error_slot,+                                struct ClientRef **result_slot);++void hs_temporal_drop_client(struct ClientRef *client);++void hs_temporal_drop_rpc_error(struct CRPCError *error);++void hs_count_workflow_executions(struct ClientRef *client,+                                  const struct RpcCall *c_call,+                                  struct MVar *mvar,+                                  struct Capability cap,+                                  struct CRPCError **error_slot,+                                  struct CArray_u8 **result_slot);++void hs_create_schedule(struct ClientRef *client,+                        const struct RpcCall *c_call,+                        struct MVar *mvar,+                        struct Capability cap,+                        struct CRPCError **error_slot,+                        struct CArray_u8 **result_slot);++void hs_delete_schedule(struct ClientRef *client,+                        const struct RpcCall *c_call,+                        struct MVar *mvar,+                        struct Capability cap,+                        struct CRPCError **error_slot,+                        struct CArray_u8 **result_slot);++void hs_deprecate_namespace(struct ClientRef *client,+                            const struct RpcCall *c_call,+                            struct MVar *mvar,+                            struct Capability cap,+                            struct CRPCError **error_slot,+                            struct CArray_u8 **result_slot);++void hs_describe_namespace(struct ClientRef *client,+                           const struct RpcCall *c_call,+                           struct MVar *mvar,+                           struct Capability cap,+                           struct CRPCError **error_slot,+                           struct CArray_u8 **result_slot);++void hs_describe_schedule(struct ClientRef *client,+                          const struct RpcCall *c_call,+                          struct MVar *mvar,+                          struct Capability cap,+                          struct CRPCError **error_slot,+                          struct CArray_u8 **result_slot);++void hs_describe_task_queue(struct ClientRef *client,+                            const struct RpcCall *c_call,+                            struct MVar *mvar,+                            struct Capability cap,+                            struct CRPCError **error_slot,+                            struct CArray_u8 **result_slot);++void hs_describe_workflow_execution(struct ClientRef *client,+                                    const struct RpcCall *c_call,+                                    struct MVar *mvar,+                                    struct Capability cap,+                                    struct CRPCError **error_slot,+                                    struct CArray_u8 **result_slot);++void hs_get_cluster_info(struct ClientRef *client,+                         const struct RpcCall *c_call,+                         struct MVar *mvar,+                         struct Capability cap,+                         struct CRPCError **error_slot,+                         struct CArray_u8 **result_slot);++void hs_get_search_attributes(struct ClientRef *client,+                              const struct RpcCall *c_call,+                              struct MVar *mvar,+                              struct Capability cap,+                              struct CRPCError **error_slot,+                              struct CArray_u8 **result_slot);++void hs_get_system_info(struct ClientRef *client,+                        const struct RpcCall *c_call,+                        struct MVar *mvar,+                        struct Capability cap,+                        struct CRPCError **error_slot,+                        struct CArray_u8 **result_slot);++void hs_get_worker_build_id_compatibility(struct ClientRef *client,+                                          const struct RpcCall *c_call,+                                          struct MVar *mvar,+                                          struct Capability cap,+                                          struct CRPCError **error_slot,+                                          struct CArray_u8 **result_slot);++void hs_get_workflow_execution_history(struct ClientRef *client,+                                       const struct RpcCall *c_call,+                                       struct MVar *mvar,+                                       struct Capability cap,+                                       struct CRPCError **error_slot,+                                       struct CArray_u8 **result_slot);++void hs_get_workflow_execution_history_reverse(struct ClientRef *client,+                                               const struct RpcCall *c_call,+                                               struct MVar *mvar,+                                               struct Capability cap,+                                               struct CRPCError **error_slot,+                                               struct CArray_u8 **result_slot);++void hs_list_archived_workflow_executions(struct ClientRef *client,+                                          const struct RpcCall *c_call,+                                          struct MVar *mvar,+                                          struct Capability cap,+                                          struct CRPCError **error_slot,+                                          struct CArray_u8 **result_slot);++void hs_list_closed_workflow_executions(struct ClientRef *client,+                                        const struct RpcCall *c_call,+                                        struct MVar *mvar,+                                        struct Capability cap,+                                        struct CRPCError **error_slot,+                                        struct CArray_u8 **result_slot);++void hs_list_namespaces(struct ClientRef *client,+                        const struct RpcCall *c_call,+                        struct MVar *mvar,+                        struct Capability cap,+                        struct CRPCError **error_slot,+                        struct CArray_u8 **result_slot);++void hs_list_open_workflow_executions(struct ClientRef *client,+                                      const struct RpcCall *c_call,+                                      struct MVar *mvar,+                                      struct Capability cap,+                                      struct CRPCError **error_slot,+                                      struct CArray_u8 **result_slot);++void hs_list_schedule_matching_times(struct ClientRef *client,+                                     const struct RpcCall *c_call,+                                     struct MVar *mvar,+                                     struct Capability cap,+                                     struct CRPCError **error_slot,+                                     struct CArray_u8 **result_slot);++void hs_list_schedules(struct ClientRef *client,+                       const struct RpcCall *c_call,+                       struct MVar *mvar,+                       struct Capability cap,+                       struct CRPCError **error_slot,+                       struct CArray_u8 **result_slot);++void hs_list_task_queue_partitions(struct ClientRef *client,+                                   const struct RpcCall *c_call,+                                   struct MVar *mvar,+                                   struct Capability cap,+                                   struct CRPCError **error_slot,+                                   struct CArray_u8 **result_slot);++void hs_list_workflow_executions(struct ClientRef *client,+                                 const struct RpcCall *c_call,+                                 struct MVar *mvar,+                                 struct Capability cap,+                                 struct CRPCError **error_slot,+                                 struct CArray_u8 **result_slot);++void hs_patch_schedule(struct ClientRef *client,+                       const struct RpcCall *c_call,+                       struct MVar *mvar,+                       struct Capability cap,+                       struct CRPCError **error_slot,+                       struct CArray_u8 **result_slot);++void hs_poll_activity_task_queue(struct ClientRef *client,+                                 const struct RpcCall *c_call,+                                 struct MVar *mvar,+                                 struct Capability cap,+                                 struct CRPCError **error_slot,+                                 struct CArray_u8 **result_slot);++void hs_poll_workflow_execution_update(struct ClientRef *client,+                                       const struct RpcCall *c_call,+                                       struct MVar *mvar,+                                       struct Capability cap,+                                       struct CRPCError **error_slot,+                                       struct CArray_u8 **result_slot);++void hs_poll_workflow_task_queue(struct ClientRef *client,+                                 const struct RpcCall *c_call,+                                 struct MVar *mvar,+                                 struct Capability cap,+                                 struct CRPCError **error_slot,+                                 struct CArray_u8 **result_slot);++void hs_query_workflow(struct ClientRef *client,+                       const struct RpcCall *c_call,+                       struct MVar *mvar,+                       struct Capability cap,+                       struct CRPCError **error_slot,+                       struct CArray_u8 **result_slot);++void hs_record_activity_task_heartbeat(struct ClientRef *client,+                                       const struct RpcCall *c_call,+                                       struct MVar *mvar,+                                       struct Capability cap,+                                       struct CRPCError **error_slot,+                                       struct CArray_u8 **result_slot);++void hs_record_activity_task_heartbeat_by_id(struct ClientRef *client,+                                             const struct RpcCall *c_call,+                                             struct MVar *mvar,+                                             struct Capability cap,+                                             struct CRPCError **error_slot,+                                             struct CArray_u8 **result_slot);++void hs_register_namespace(struct ClientRef *client,+                           const struct RpcCall *c_call,+                           struct MVar *mvar,+                           struct Capability cap,+                           struct CRPCError **error_slot,+                           struct CArray_u8 **result_slot);++void hs_request_cancel_workflow_execution(struct ClientRef *client,+                                          const struct RpcCall *c_call,+                                          struct MVar *mvar,+                                          struct Capability cap,+                                          struct CRPCError **error_slot,+                                          struct CArray_u8 **result_slot);++void hs_reset_sticky_task_queue(struct ClientRef *client,+                                const struct RpcCall *c_call,+                                struct MVar *mvar,+                                struct Capability cap,+                                struct CRPCError **error_slot,+                                struct CArray_u8 **result_slot);++void hs_reset_workflow_execution(struct ClientRef *client,+                                 const struct RpcCall *c_call,+                                 struct MVar *mvar,+                                 struct Capability cap,+                                 struct CRPCError **error_slot,+                                 struct CArray_u8 **result_slot);++void hs_respond_activity_task_canceled(struct ClientRef *client,+                                       const struct RpcCall *c_call,+                                       struct MVar *mvar,+                                       struct Capability cap,+                                       struct CRPCError **error_slot,+                                       struct CArray_u8 **result_slot);++void hs_respond_activity_task_canceled_by_id(struct ClientRef *client,+                                             const struct RpcCall *c_call,+                                             struct MVar *mvar,+                                             struct Capability cap,+                                             struct CRPCError **error_slot,+                                             struct CArray_u8 **result_slot);++void hs_respond_activity_task_completed(struct ClientRef *client,+                                        const struct RpcCall *c_call,+                                        struct MVar *mvar,+                                        struct Capability cap,+                                        struct CRPCError **error_slot,+                                        struct CArray_u8 **result_slot);++void hs_respond_activity_task_completed_by_id(struct ClientRef *client,+                                              const struct RpcCall *c_call,+                                              struct MVar *mvar,+                                              struct Capability cap,+                                              struct CRPCError **error_slot,+                                              struct CArray_u8 **result_slot);++void hs_respond_activity_task_failed(struct ClientRef *client,+                                     const struct RpcCall *c_call,+                                     struct MVar *mvar,+                                     struct Capability cap,+                                     struct CRPCError **error_slot,+                                     struct CArray_u8 **result_slot);++void hs_respond_activity_task_failed_by_id(struct ClientRef *client,+                                           const struct RpcCall *c_call,+                                           struct MVar *mvar,+                                           struct Capability cap,+                                           struct CRPCError **error_slot,+                                           struct CArray_u8 **result_slot);++void hs_respond_query_task_completed(struct ClientRef *client,+                                     const struct RpcCall *c_call,+                                     struct MVar *mvar,+                                     struct Capability cap,+                                     struct CRPCError **error_slot,+                                     struct CArray_u8 **result_slot);++void hs_respond_workflow_task_completed(struct ClientRef *client,+                                        const struct RpcCall *c_call,+                                        struct MVar *mvar,+                                        struct Capability cap,+                                        struct CRPCError **error_slot,+                                        struct CArray_u8 **result_slot);++void hs_respond_workflow_task_failed(struct ClientRef *client,+                                     const struct RpcCall *c_call,+                                     struct MVar *mvar,+                                     struct Capability cap,+                                     struct CRPCError **error_slot,+                                     struct CArray_u8 **result_slot);++void hs_scan_workflow_executions(struct ClientRef *client,+                                 const struct RpcCall *c_call,+                                 struct MVar *mvar,+                                 struct Capability cap,+                                 struct CRPCError **error_slot,+                                 struct CArray_u8 **result_slot);++void hs_signal_with_start_workflow_execution(struct ClientRef *client,+                                             const struct RpcCall *c_call,+                                             struct MVar *mvar,+                                             struct Capability cap,+                                             struct CRPCError **error_slot,+                                             struct CArray_u8 **result_slot);++void hs_signal_workflow_execution(struct ClientRef *client,+                                  const struct RpcCall *c_call,+                                  struct MVar *mvar,+                                  struct Capability cap,+                                  struct CRPCError **error_slot,+                                  struct CArray_u8 **result_slot);++void hs_start_workflow_execution(struct ClientRef *client,+                                 const struct RpcCall *c_call,+                                 struct MVar *mvar,+                                 struct Capability cap,+                                 struct CRPCError **error_slot,+                                 struct CArray_u8 **result_slot);++void hs_terminate_workflow_execution(struct ClientRef *client,+                                     const struct RpcCall *c_call,+                                     struct MVar *mvar,+                                     struct Capability cap,+                                     struct CRPCError **error_slot,+                                     struct CArray_u8 **result_slot);++void hs_update_namespace(struct ClientRef *client,+                         const struct RpcCall *c_call,+                         struct MVar *mvar,+                         struct Capability cap,+                         struct CRPCError **error_slot,+                         struct CArray_u8 **result_slot);++void hs_update_schedule(struct ClientRef *client,+                        const struct RpcCall *c_call,+                        struct MVar *mvar,+                        struct Capability cap,+                        struct CRPCError **error_slot,+                        struct CArray_u8 **result_slot);++void hs_update_workflow_execution(struct ClientRef *client,+                                  const struct RpcCall *c_call,+                                  struct MVar *mvar,+                                  struct Capability cap,+                                  struct CRPCError **error_slot,+                                  struct CArray_u8 **result_slot);++void hs_update_worker_build_id_compatibility(struct ClientRef *client,+                                             const struct RpcCall *c_call,+                                             struct MVar *mvar,+                                             struct Capability cap,+                                             struct CRPCError **error_slot,+                                             struct CArray_u8 **result_slot);++void hs_get_current_time(struct ClientRef *client,+                         const struct RpcCall *c_call,+                         struct MVar *mvar,+                         struct Capability cap,+                         struct CRPCError **error_slot,+                         struct CArray_u8 **result_slot);++void hs_lock_time_skipping(struct ClientRef *client,+                           const struct RpcCall *c_call,+                           struct MVar *mvar,+                           struct Capability cap,+                           struct CRPCError **error_slot,+                           struct CArray_u8 **result_slot);++void hs_sleep_until(struct ClientRef *client,+                    const struct RpcCall *c_call,+                    struct MVar *mvar,+                    struct Capability cap,+                    struct CRPCError **error_slot,+                    struct CArray_u8 **result_slot);++void hs_sleep(struct ClientRef *client,+              const struct RpcCall *c_call,+              struct MVar *mvar,+              struct Capability cap,+              struct CRPCError **error_slot,+              struct CArray_u8 **result_slot);++void hs_unlock_time_skipping_with_sleep(struct ClientRef *client,+                                        const struct RpcCall *c_call,+                                        struct MVar *mvar,+                                        struct Capability cap,+                                        struct CRPCError **error_slot,+                                        struct CArray_u8 **result_slot);++void hs_unlock_time_skipping(struct ClientRef *client,+                             const struct RpcCall *c_call,+                             struct MVar *mvar,+                             struct Capability cap,+                             struct CRPCError **error_slot,+                             struct CArray_u8 **result_slot);++void hs_add_or_update_remote_cluster(struct ClientRef *client,+                                     const struct RpcCall *c_call,+                                     struct MVar *mvar,+                                     struct Capability cap,+                                     struct CRPCError **error_slot,+                                     struct CArray_u8 **result_slot);++void hs_add_search_attributes(struct ClientRef *client,+                              const struct RpcCall *c_call,+                              struct MVar *mvar,+                              struct Capability cap,+                              struct CRPCError **error_slot,+                              struct CArray_u8 **result_slot);++void hs_delete_namespace(struct ClientRef *client,+                         const struct RpcCall *c_call,+                         struct MVar *mvar,+                         struct Capability cap,+                         struct CRPCError **error_slot,+                         struct CArray_u8 **result_slot);++void hs_list_clusters(struct ClientRef *client,+                      const struct RpcCall *c_call,+                      struct MVar *mvar,+                      struct Capability cap,+                      struct CRPCError **error_slot,+                      struct CArray_u8 **result_slot);++void hs_list_search_attributes(struct ClientRef *client,+                               const struct RpcCall *c_call,+                               struct MVar *mvar,+                               struct Capability cap,+                               struct CRPCError **error_slot,+                               struct CArray_u8 **result_slot);++void hs_remove_remote_cluster(struct ClientRef *client,+                              const struct RpcCall *c_call,+                              struct MVar *mvar,+                              struct Capability cap,+                              struct CRPCError **error_slot,+                              struct CArray_u8 **result_slot);++void hs_remove_search_attributes(struct ClientRef *client,+                                 const struct RpcCall *c_call,+                                 struct MVar *mvar,+                                 struct Capability cap,+                                 struct CRPCError **error_slot,+                                 struct CArray_u8 **result_slot);++void hs_temporal_drop_worker_error(struct CWorkerError *err);++void hs_temporal_drop_unit(struct CUnit *unit);++void hs_temporal_drop_worker(struct WorkerRef *worker);++void hs_temporal_new_worker(struct ClientRef *client,+                            const struct CArray_u8 *config,+                            struct WorkerRef **result_slot,+                            struct CWorkerError **error_slot);++void hs_temporal_new_replay_worker(struct RuntimeRef *runtime,+                                   const struct CArray_u8 *config,+                                   struct WorkerRef **worker_slot,+                                   struct HistoryPusher **history_slot,+                                   struct CWorkerError **error_slot);++void hs_temporal_validate_worker(struct WorkerRef *worker,+                                 struct MVar *mvar,+                                 struct Capability cap,+                                 struct CWorkerValidationError **error_slot,+                                 struct CUnit **result_slot);++void hs_temporal_worker_poll_workflow_activation(struct WorkerRef *worker,+                                                 struct MVar *mvar,+                                                 struct Capability cap,+                                                 struct CWorkerError **error_slot,+                                                 struct CArray_u8 **result_slot);++void hs_temporal_worker_poll_activity_task(struct WorkerRef *worker,+                                           struct MVar *mvar,+                                           struct Capability cap,+                                           struct CWorkerError **error_slot,+                                           struct CArray_u8 **result_slot);++void hs_temporal_worker_complete_workflow_activation(struct WorkerRef *worker,+                                                     const struct CArray_u8 *proto,+                                                     struct MVar *mvar,+                                                     struct Capability cap,+                                                     struct CWorkerError **error_slot,+                                                     struct CUnit **result_slot);++void hs_temporal_worker_complete_activity_task(struct WorkerRef *worker,+                                               const struct CArray_u8 *proto,+                                               struct MVar *mvar,+                                               struct Capability cap,+                                               struct CWorkerError **error_slot,+                                               struct CUnit **result_slot);++void hs_temporal_worker_record_activity_heartbeat(struct WorkerRef *worker,+                                                  const struct CArray_u8 *proto,+                                                  struct CWorkerError **error_slot,+                                                  struct CUnit **result_slot);++void hs_temporal_worker_request_workflow_eviction(struct WorkerRef *worker,+                                                  const struct CArray_u8 *run_id);++void hs_temporal_worker_initiate_shutdown(struct WorkerRef *worker);++void hs_temporal_worker_finalize_shutdown(struct WorkerRef *worker,+                                          struct MVar *mvar,+                                          struct Capability cap,+                                          struct CWorkerError **error_slot,+                                          struct CUnit **result_slot);++void hs_temporal_history_pusher_push_history(struct HistoryPusher *history_pusher,+                                             const struct CArray_u8 *workflow_id,+                                             const struct CArray_u8 *history_proto,+                                             struct MVar *mvar,+                                             struct Capability cap,+                                             struct CWorkerError **error_slot,+                                             struct CUnit **result_slot);++void hs_temporal_history_pusher_close(struct HistoryPusher *history_pusher);++void hs_temporal_history_pusher_drop(struct HistoryPusher *history_pusher);++void hs_temporal_start_dev_server(struct RuntimeRef *runtime,+                                  const char *json_string,+                                  struct MVar *mvar,+                                  struct Capability cap,+                                  struct CArray_u8 **error_slot,+                                  struct EphemeralServerRef **result_slot);++void hs_temporal_shutdown_ephemeral_server(struct EphemeralServerRef *server,+                                           struct MVar *mvar,+                                           struct Capability cap,+                                           struct CArray_u8 **error_slot,+                                           struct CUnit **result_slot);++void hs_temporal_start_test_server(struct RuntimeRef *runtime,+                                   const char *json_string,+                                   struct MVar *mvar,+                                   struct Capability cap,+                                   struct CArray_u8 **error_slot,+                                   struct EphemeralServerRef **result_slot);
+ src/Temporal/Core/CTypes.hsc view
@@ -0,0 +1,329 @@+#include "temporal_bridge.h"++{-# LANGUAGE OverloadedRecordDot #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+module Temporal.Core.CTypes where+import Control.Exception+import Control.Concurrent.MVar (MVar)+import Data.Aeson+import Data.Aeson.TH+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import Data.Map.Strict (Map)+import qualified Data.Vector as V+import Data.Text (Text)+import Data.Text.Foreign+import Data.Word+import Foreign.C.String+import Foreign.C.Types+import Foreign.ForeignPtr+import Foreign.Ptr+import Foreign.Storable++data CArray a = CArray+  { dataPtr :: !(Ptr a)+  , size :: !(#{type uintptr_t})+  }+  deriving (Show)++cArrayToByteString :: CArray Word8 -> IO ByteString+cArrayToByteString CArray{..} = BS.packCStringLen (castPtr dataPtr, fromIntegral size)++cArrayToVector :: Storable a => (a -> IO b) -> CArray a -> IO (V.Vector b)+cArrayToVector f CArray{..} = do+  let len = fromIntegral size+  V.generateM len $ \i -> do+    x <- peekElemOff dataPtr i+    f x++cArrayToText :: CArray Word8 -> IO Text+cArrayToText CArray{..} = do+  let len = fromIntegral size+  fromPtr dataPtr len++instance Storable a => Storable (CArray a) where+  sizeOf _ = #{size CArray_u8}+  alignment _ = #{alignment CArray_u8}+  peek ptr = do+    dataPtr <- #{peek CArray_u8, data_ptr} ptr+    size <- #{peek CArray_u8, size} ptr+    pure CArray {..}+  poke ptr CArray {..} = do+    #{poke CArray_u8, data_ptr} ptr dataPtr+    #{poke CArray_u8, size} ptr size++foreign import ccall "&hs_temporal_drop_byte_array" rust_dropByteArray :: FinalizerPtr (CArray Word8)++type TryPutMVarFFI = FunPtr (Ptr CInt -> Ptr (MVar ()) -> IO ())+foreign import ccall "&hs_try_putmvar" tryPutMVarPtr :: TryPutMVarFFI++-- | A handle to the Rust Tokio runtime and thread-pool.+--+-- You almost always should use the 'globalRuntime' value, which is initialized+-- once for the entire process.+newtype Runtime = Runtime (ForeignPtr Runtime)++data Periodicity+  = Periodicity+    { seconds :: Word64+    , nanoseconds :: Word32+    }++instance ToJSON Periodicity where+  toJSON Periodicity{..} = object+    [ "secs" .= seconds+    , "nanos" .= nanoseconds+    ]++data TelemetryOptions+  = OtelTelemetryOptions+    { url :: Text+    , headers :: Map Text Text+    , metricPeriodicity :: Maybe Periodicity+    , globalTags :: Map Text Text+    }+  | PrometheusTelemetryOptions+    { socketAddr :: Text+    , globalTags :: Map Text Text+    , countersTotalSuffix :: Bool+    , unitSuffix :: Bool+    }+  | NoTelemetry++deriveToJSON (defaultOptions {fieldLabelModifier = camelTo2 '_'}) ''TelemetryOptions++foreign import ccall "hs_temporal_init_runtime" initRuntime :: Ptr (CArray Word8) -> TryPutMVarFFI -> IO (Ptr Runtime)+foreign import ccall "&hs_temporal_free_runtime" freeRuntime :: FinalizerPtr Runtime++data LogLevel+  = Trace+  | Debug+  | Info+  | Warn+  | Error+  deriving (Show)++instance ToJSON LogLevel where+  toJSON = \case+    Trace -> "TRACE"+    Debug -> "DEBUG"+    Info -> "INFO"+    Warn -> "WARN"+    Temporal.Core.CTypes.Error -> "ERROR"++instance FromJSON LogLevel where+  parseJSON = withText "LogLevel" $ \case+    "TRACE" -> pure Trace+    "DEBUG" -> pure Debug+    "INFO" -> pure Info+    "WARN" -> pure Warn+    "ERROR" -> pure Temporal.Core.CTypes.Error+    other -> fail $ "Invalid log level: " <> show other++data CoreLog = CoreLog+  { target :: Text+  , message :: Text+  , timestamp :: Value+  , level :: LogLevel+  , fields :: Object+  , spanContexts :: [Text]+  } deriving (Show)++deriveJSON (defaultOptions {fieldLabelModifier = camelTo2 '_'}) ''CoreLog++foreign import ccall "hs_temporal_runtime_fetch_logs" raw_fetchLogs :: Ptr Runtime -> IO (Ptr (CArray (CArray Word8)))+foreign import ccall "hs_temporal_runtime_free_logs" raw_freeLogs :: Ptr (CArray (CArray Word8)) -> IO ()++data RpcError = RpcError+  { code :: Word32+  , message :: Text+  , details :: ByteString+  }+  deriving (Show)++data CRPCError = CRPCError+  { code :: Word32+  , message :: CString+  , details :: Ptr (CArray Word8)+  }++instance Storable CRPCError where+  sizeOf _ = #{size CRPCError}+  alignment _ = #{alignment CRPCError}+  peek ptr = do+    code <- #{peek CRPCError, code} ptr+    message <- #{peek CRPCError, message} ptr+    details <- #{peek CRPCError, details} ptr+    pure CRPCError {..}+  poke ptr CRPCError {..} = do+    #{poke CRPCError, code} ptr code+    #{poke CRPCError, message} ptr message+    #{poke CRPCError, details} ptr details++foreign import ccall "&hs_temporal_drop_rpc_error" rust_drop_rpc_error :: FinalizerPtr CRPCError++peekCRPCError :: CRPCError -> IO RpcError+peekCRPCError CRPCError{..} = do+  message <- fromPtr0 $ castPtr message+  details <- cArrayToByteString =<< peek details+  pure RpcError{..}++newtype CoreClient = CoreClient+  { coreClientPtr :: ForeignPtr CoreClient+  }++-- TODO, this would be better as a pair of vectors instead of a linked list+data HashMapEntries = HashMapEntries+  { key :: CString+  , keyLen :: CSize+  , value :: CString+  , valueLen :: CSize+  , next :: Ptr HashMapEntries+  }++instance Storable HashMapEntries where+  sizeOf _ = #{size HaskellHashMapEntries}+  alignment _ = #{alignment HaskellHashMapEntries}+  peek ptr = do+    key <- #{peek HaskellHashMapEntries, key} ptr+    keyLen <- #{peek HaskellHashMapEntries, key_len} ptr+    value <- #{peek HaskellHashMapEntries, value} ptr+    valueLen <- #{peek HaskellHashMapEntries, value_len} ptr+    next <- #{peek HaskellHashMapEntries, next} ptr+    pure HashMapEntries {..}+  poke ptr HashMapEntries{..} = do+    #{poke HaskellHashMapEntries, key} ptr key+    #{poke HaskellHashMapEntries, key_len} ptr keyLen+    #{poke HaskellHashMapEntries, value} ptr value+    #{poke HaskellHashMapEntries, value_len} ptr valueLen+    #{poke HaskellHashMapEntries, next} ptr next++data CRpcCall = CRpcCall+  { rpcCallReq :: Ptr (CArray Word8)+  , rpcCallRetry :: Word8+  , rpcCallMetadata :: Ptr HashMapEntries+  , rpcCallTimeoutMillis :: Ptr Word64+  }++instance Storable CRpcCall where+  sizeOf _ = #{size RpcCall}+  alignment _ = #{alignment RpcCall}+  peek ptr = do+    rpcCallReq <- #{peek RpcCall, req} ptr+    rpcCallRetry <- #{peek RpcCall, retry} ptr+    rpcCallMetadata <- #{peek RpcCall, metadata} ptr+    rpcCallTimeoutMillis <- #{peek RpcCall, timeout_millis} ptr+    pure CRpcCall {..}+  poke ptr CRpcCall {..} = do+    #{poke RpcCall, req} ptr rpcCallReq+    #{poke RpcCall, retry} ptr rpcCallRetry+    #{poke RpcCall, metadata} ptr rpcCallMetadata+    #{poke RpcCall, timeout_millis} ptr rpcCallTimeoutMillis+++data WorkerErrorCode+  = SDKError+  | InitWorkerFailed+  | InitReplayWorkerFailed+  | InvalidProto+  | ReplayWorkerClosed+  | PollShutdown+  | PollFailure+  | CompletionFailure+  | InvalidWorkerConfig+  | UnknownError Word8+  deriving (Show, Eq)++instance Storable WorkerErrorCode where+  sizeOf _ = #{size WorkerErrorCode}+  alignment _ = #{alignment WorkerErrorCode}+  peek ptr = do+    code <- peek (castPtr ptr :: Ptr #{type WorkerErrorCode})+    case code of+      #{const SDKError} -> pure SDKError+      #{const InitWorkerFailed} -> pure InitWorkerFailed+      #{const InitReplayWorkerFailed} -> pure InitReplayWorkerFailed+      #{const InvalidProto} -> pure InvalidProto+      #{const ReplayWorkerClosed} -> pure ReplayWorkerClosed+      #{const PollShutdownError} -> pure PollShutdown+      #{const PollFailure} -> pure PollFailure+      #{const CompletionFailure} -> pure CompletionFailure+      #{const InvalidWorkerConfig} -> pure InvalidWorkerConfig+      _ -> pure $ UnknownError code+  poke ptr_ code = case code of+    SDKError -> poke ptr #{const SDKError}+    InitWorkerFailed -> poke ptr #{const InitWorkerFailed}+    InitReplayWorkerFailed -> poke ptr #{const InitReplayWorkerFailed}+    InvalidProto -> poke ptr #{const InvalidProto}+    ReplayWorkerClosed -> poke ptr #{const ReplayWorkerClosed}+    PollShutdown -> poke ptr #{const PollShutdownError}+    PollFailure -> poke ptr #{const PollFailure}+    CompletionFailure -> poke ptr #{const CompletionFailure}+    InvalidWorkerConfig -> poke ptr #{const InvalidWorkerConfig}+    (UnknownError code) -> poke ptr code+    where+      ptr = (castPtr ptr_ :: Ptr #{type WorkerErrorCode})++data CWorkerError = CWorkerError+  { code :: WorkerErrorCode+  , message :: CString+  }++instance Storable CWorkerError where+  sizeOf _ = #{size CWorkerError}+  alignment _ = #{alignment CWorkerError}+  peek ptr = do+    code <- #{peek CWorkerError, code} ptr+    message <- #{peek CWorkerError, message} ptr+    pure CWorkerError {..}+  poke ptr CWorkerError {..} = do+    #{poke CWorkerError, code} ptr code+    #{poke CWorkerError, message} ptr message++data WorkerError = WorkerError+  { code :: WorkerErrorCode+  , message :: Text+  } deriving (Show, Eq)++instance Exception WorkerError++peekWorkerError :: CWorkerError -> IO WorkerError+peekWorkerError CWorkerError{..} = do+  message <- fromPtr0 $ castPtr message+  pure WorkerError{..}++data CWorkerValidationError = CWorkerValidationError+  { message :: CString+  }++instance Storable CWorkerValidationError where+  sizeOf _ = #{size CWorkerValidationError}+  alignment _ = #{alignment CWorkerValidationError}+  peek ptr = do+    message <- #{peek CWorkerValidationError, message} ptr+    pure CWorkerValidationError {..}++data WorkerValidationError = WorkerValidationError+  { message :: Text+  } deriving (Show, Eq)++instance Exception WorkerValidationError++peekWorkerValidationError :: CWorkerValidationError -> IO WorkerValidationError+peekWorkerValidationError CWorkerValidationError{..} = do+  message <- fromPtr0 $ castPtr message+  pure WorkerValidationError{..}++foreign import ccall "hs_temporal_drop_worker_validation_error" rust_dropWorkerValidationError :: FinalizerPtr CWorkerValidationError++foreign import ccall "&hs_temporal_drop_worker_error" rust_dropWorkerError :: FinalizerPtr CWorkerError++data CUnit = CUnit++foreign import ccall "hs_temporal_drop_unit" rust_dropUnitNow :: Ptr CUnit -> IO ()+foreign import ccall "&hs_temporal_drop_unit" rust_dropUnit :: FinalizerPtr CUnit
+ src/Temporal/Core/Client.hs view
@@ -0,0 +1,323 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}++module Temporal.Core.Client (+  -- * Connecting to the server+  Client,+  clientConfig,+  connectClient,+  defaultClientConfig,+  closeClient,+  clientRuntime,+  touchClient,+  CoreClient,+  ClientConfig (..),+  ClientTlsConfig (..),+  ByteVector (..),+  ClientRetryConfig (..),+  APIKey (..),++  -- * Making calls to the server++  --+  -- Generally you should not need to use 'call' directly, but instead should+  -- use the supplied functions in 'Temporal.Core.Client.WorkflowService' and+  -- other service modules.+  --+  -- For higher-level access, see the@@temporal-sdk@ package for a more+  -- idiomatic Haskell API.+  call,+  RpcCall (..),+  RpcError (..),+  ClientError (..),++  -- * Primitive access+  CRpcCall,+  TokioCall,+  TokioResult,+  PrimRpcCall,+  -- | Use the underlying Rust client pointer+  withClient,+) where++import Control.Concurrent+import Control.Exception+import Control.Monad+import Control.Monad.IO.Class+import Control.Monad.Logger+import Data.Aeson+import Data.Aeson.TH+import Data.ByteString (ByteString)+import qualified Data.ByteString as BL+import qualified Data.ByteString as BS+import qualified Data.ByteString.Internal as BS+import Data.HashMap.Strict (HashMap)+import Data.ProtoLens.Encoding+import Data.ProtoLens.Service.Types+import Data.Text (Text)+import qualified Data.Text as T+import qualified Data.Vector.Storable as V+import Data.Word+import Foreign.C.String+import Foreign.ForeignPtr+import Foreign.Marshal+import Foreign.Ptr+import Foreign.Storable+import Network.BSD+import System.Posix.Process+import Temporal.Core.CTypes+import Temporal.Internal.FFI+import Temporal.Runtime+import UnliftIO (MonadUnliftIO, withRunInIO)+import qualified UnliftIO+++foreign import ccall "hs_temporal_connect_client" raw_connectClient :: Ptr Runtime -> CString -> TokioCall (CArray Word8) CoreClient+++foreign import ccall "&hs_temporal_drop_client" raw_freeClient :: FinalizerPtr CoreClient+++data ClientConfig = ClientConfig+  { targetUrl :: Text+  , clientName :: Text+  , clientVersion :: Text+  , metadata :: HashMap Text Text+  , identity :: Text+  , tlsConfig :: Maybe ClientTlsConfig+  , retryConfig :: Maybe ClientRetryConfig+  , apiKey :: Maybe APIKey+  }+++data ClientTlsConfig = ClientTlsConfig+  { serverRootCaCert :: Maybe ByteVector+  , domain :: Maybe Text+  , clientCert :: Maybe ByteVector+  , clientPrivateKey :: Maybe ByteVector+  }+++data ClientRetryConfig = ClientRetryConfig+  { initialIntervalMillis :: Word64+  , randomizationFactor :: Double+  , multiplier :: Double+  , maxIntervalMillis :: Word64+  , maxElapsedTimeMillis :: Maybe Word64+  , maxRetries :: Word64+  }+++newtype APIKey = APIKey {unAPIKey :: Text}+++instance ToJSON APIKey where+  toJSON (APIKey text) = toJSON text+++instance FromJSON APIKey where+  parseJSON = fmap APIKey . parseJSON+++{- | A client connection to the Temporal server.++The client is thread-safe and can be shared across threads.++Clients are expensive to create, so you should generally create one per+process and share it across your application..++The client doesn't have an explicit close method, but will be cleaned up+when it is garbage collected.+-}+data Client = Client+  { client :: MVar CoreClient+  , runtime :: Runtime+  , config :: ClientConfig+  }+++clientConfig :: Client -> ClientConfig+clientConfig = config+++clientRuntime :: Client -> Runtime+clientRuntime = runtime+++withClient :: Client -> (Ptr CoreClient -> IO a) -> IO a+withClient (Client cc r _) f =+  withMVar cc $ \(CoreClient c) ->+    withRuntime r $ \_ ->+      withForeignPtr c f+++touchClient :: Client -> IO ()+touchClient (Client cc _ _) = do+  mcc <- tryReadMVar cc+  case mcc of+    Nothing -> return ()+    Just (CoreClient c) -> touchForeignPtr c+++newtype ByteVector = ByteVector {byteVector :: ByteString}+++byteStringToVector :: BS.ByteString -> V.Vector Word8+byteStringToVector bs = vec+  where+    vec = V.unsafeFromForeignPtr (castForeignPtr fptr) off len+    (fptr, off, len) = BS.toForeignPtr bs+++vectorToByteString :: V.Vector Word8 -> BS.ByteString+vectorToByteString vec = BS.fromForeignPtr (castForeignPtr fptr) off len+  where+    (fptr, off, len) = V.unsafeToForeignPtr vec+++instance ToJSON ByteVector where+  toJSON = toJSON . byteStringToVector . byteVector+++instance FromJSON ByteVector where+  parseJSON = fmap (ByteVector . vectorToByteString) . parseJSON+++deriveJSON (defaultOptions {fieldLabelModifier = camelTo2 '_'}) ''ClientTlsConfig+++deriveJSON (defaultOptions {fieldLabelModifier = camelTo2 '_'}) ''ClientRetryConfig+++deriveJSON (defaultOptions {fieldLabelModifier = camelTo2 '_'}) ''ClientConfig+++data RpcCall a = RpcCall+  { req :: a+  , retry :: Bool+  , metadata :: HashMap Text Text+  , timeoutMillis :: Maybe Word64+  }+++data ClientError+  = ClientConnectionError Text+  | ClientClosedError+  deriving (Show)+++instance Exception ClientError+++defaultClientConfig :: ClientConfig+defaultClientConfig =+  ClientConfig+    { targetUrl = "http://localhost:7233"+    , clientName = "temporal-haskell"+    , clientVersion = "0.0.1"+    , metadata = mempty+    , identity = ""+    , tlsConfig = Nothing+    , retryConfig = Nothing+    , apiKey = Nothing+    }+++defaultClientIdentity :: IO Text+defaultClientIdentity = do+  pid <- getProcessID+  host <- getHostName+  pure (T.pack $ show pid <> "@" <> host)+++{- | Connect to the Temporal server using a given runtime.++Throws 'ClientConnectionError' if the connection fails.+-}+connectClient :: (MonadIO m, MonadLogger m, MonadUnliftIO m) => Runtime -> ClientConfig -> m Client+connectClient rt conf = do+  conf' <-+    if identity conf == ""+      then do+        ident <- liftIO defaultClientIdentity+        pure $ conf {identity = ident}+      else pure conf++  clientPtrSlot <- liftIO newEmptyMVar+  withRunInIO $ \runInIO -> do+    forkIO $ runInIO $ do+      liftIO $ withRuntime rt $ \rtPtr -> BS.useAsCString (BL.toStrict $ encode conf') $ \confPtr -> do+        let tryConnect =+              makeTokioAsyncCall+                (raw_connectClient rtPtr confPtr)+                (Just rust_dropByteArray)+                (Just raw_freeClient)+            go attempt = do+              result <- tryConnect+              case result of+                Left errFP -> do+                  err <- withForeignPtr errFP $ peek >=> cArrayToText+                  let err' = "Error connecting to Temporal server: " <> err+                  runInIO $ $(logWarn) err'+                  case retryConfig conf of+                    Nothing -> liftIO $ putMVar clientPtrSlot (throw $ ClientConnectionError err')+                    Just retryConf -> do+                      let delayMillis = fromIntegral (initialIntervalMillis retryConf) * multiplier retryConf ^ attempt+                          delayMicros = delayMillis * 1000+                      if (fmap fromIntegral (maxElapsedTimeMillis retryConf) < Just delayMillis) || (maxRetries retryConf <= attempt)+                        then liftIO $ putMVar clientPtrSlot (throw $ ClientConnectionError err')+                        else do+                          liftIO $ threadDelay $ round delayMicros+                          go (attempt + 1)+                Right client_ -> liftIO $ putMVar clientPtrSlot (CoreClient client_)+        go 1+  pure $ Client clientPtrSlot rt conf'+++reconnectClient :: (MonadIO m, MonadLogger m, MonadUnliftIO m) => Client -> m ()+reconnectClient (Client clientPtrSlot rt conf) = UnliftIO.mask $ \restore -> do+  (CoreClient clientPtr) <- liftIO $ takeMVar clientPtrSlot+  (Client newClientPtr _ _) <- restore (connectClient rt conf) `UnliftIO.catch` (\c -> liftIO $ putMVar clientPtrSlot (throw (c :: ClientError)) >> throwIO c)+  liftIO $ takeMVar newClientPtr >>= putMVar clientPtrSlot+++closeClient :: MonadIO m => Client -> m ()+closeClient (Client clientPtrSlot _ _) = liftIO $ mask_ $ do+  (CoreClient clientPtr) <- takeMVar clientPtrSlot+  finalizeForeignPtr clientPtr+  putMVar clientPtrSlot (throw ClientClosedError)+++type PrimRpcCall = Ptr CoreClient -> Ptr CRpcCall -> TokioCall CRPCError (CArray Word8)+++-- TODO how should we use mask here?+call :: forall svc t. (HasMethodImpl svc t) => PrimRpcCall -> Client -> MethodInput svc t -> IO (Either RpcError (MethodOutput svc t))+call f c req_ = withClient c $ \cPtr -> do+  let msgBytes = encodeMessage req_+  BS.useAsCStringLen msgBytes $ \(msgPtr, msgLen) -> do+    alloca $ \cArrayPtr -> do+      poke cArrayPtr (CArray msgPtr (fromIntegral msgLen))+      let rpcCall =+            CRpcCall+              { rpcCallReq = castPtr cArrayPtr+              , rpcCallRetry = if False then 0 else 1+              , rpcCallMetadata = nullPtr+              , rpcCallTimeoutMillis = nullPtr+              }+      alloca $ \rpcCallPtr -> do+        poke rpcCallPtr rpcCall+        result <-+          makeTokioAsyncCall+            (f cPtr rpcCallPtr)+            (Just rust_drop_rpc_error)+            (Just rust_dropByteArray)+        case result of+          Left err -> Left <$> withForeignPtr err (peek >=> peekCRPCError)+          Right r -> Right . decodeMessageOrDie <$> withForeignPtr r (peek >=> cArrayToByteString)
+ src/Temporal/Core/Client/HealthService.hs view
@@ -0,0 +1,9 @@+module Temporal.Core.Client.HealthService where++import Proto.Health.V1.Health+import Temporal.Core.Client+++-- foreign import ccall "hs_health_check" hs_health_check :: PrimRpcCall+-- -- healthCheck :: Client -> HealthCheckRequest -> IO (Either RpcError HealthCheckResponse)+-- -- healthCheck = call @HealthService @"healthCheck" hs_health_check
+ src/Temporal/Core/Client/OperatorService.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Temporal.Core.Client.OperatorService where++import Proto.Temporal.Api.Operatorservice.V1.RequestResponse+import Proto.Temporal.Api.Operatorservice.V1.Service+import Temporal.Core.Client+import Temporal.Internal.FFI+++foreign import ccall "hs_add_or_update_remote_cluster" hs_add_or_update_remote_cluster :: PrimRpcCall+++addOrUpdateRemoteCluster :: Client -> AddOrUpdateRemoteClusterRequest -> IO (Either RpcError AddOrUpdateRemoteClusterResponse)+addOrUpdateRemoteCluster = call @OperatorService @"addOrUpdateRemoteCluster" hs_add_or_update_remote_cluster+++foreign import ccall "hs_add_search_attributes" hs_add_search_attributes :: PrimRpcCall+++addSearchAttributes :: Client -> AddSearchAttributesRequest -> IO (Either RpcError AddSearchAttributesResponse)+addSearchAttributes = call @OperatorService @"addSearchAttributes" hs_add_search_attributes+++foreign import ccall "hs_delete_namespace" hs_delete_namespace :: PrimRpcCall+++deleteNamespace :: Client -> DeleteNamespaceRequest -> IO (Either RpcError DeleteNamespaceResponse)+deleteNamespace = call @OperatorService @"deleteNamespace" hs_delete_namespace+++foreign import ccall "hs_list_clusters" hs_list_clusters :: PrimRpcCall+++listClusters :: Client -> ListClustersRequest -> IO (Either RpcError ListClustersResponse)+listClusters = call @OperatorService @"listClusters" hs_list_clusters+++foreign import ccall "hs_list_search_attributes" hs_list_search_attributes :: PrimRpcCall+++listSearchAttributes :: Client -> ListSearchAttributesRequest -> IO (Either RpcError ListSearchAttributesResponse)+listSearchAttributes = call @OperatorService @"listSearchAttributes" hs_list_search_attributes+++foreign import ccall "hs_remove_remote_cluster" hs_remove_remote_cluster :: PrimRpcCall+++removeRemoteCluster :: Client -> RemoveRemoteClusterRequest -> IO (Either RpcError RemoveRemoteClusterResponse)+removeRemoteCluster = call @OperatorService @"removeRemoteCluster" hs_remove_remote_cluster+++foreign import ccall "hs_remove_search_attributes" hs_remove_search_attributes :: PrimRpcCall+++removeSearchAttributes :: Client -> RemoveSearchAttributesRequest -> IO (Either RpcError RemoveSearchAttributesResponse)+removeSearchAttributes = call @OperatorService @"removeSearchAttributes" hs_remove_search_attributes
+ src/Temporal/Core/Client/TestService.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Temporal.Core.Client.TestService where++import Data.ProtoLens (Message (defMessage))+import Proto.Temporal.Api.Testservice.V1.RequestResponse+import Proto.Temporal.Api.Testservice.V1.Service+import Temporal.Core.Client+import Temporal.Internal.FFI+++foreign import ccall "hs_get_current_time" hs_get_current_time :: PrimRpcCall+++{- | GetCurrentTime returns the current Temporal Test Server time++This time might not be equal to {@link System#currentTimeMillis()} due to time skipping.+-}+getCurrentTime :: Client -> IO (Either RpcError GetCurrentTimeResponse)+getCurrentTime client = call @TestService @"getCurrentTime" hs_get_current_time client defMessage+++foreign import ccall "hs_lock_time_skipping" hs_lock_time_skipping :: PrimRpcCall+++{- | lockTimeSkipping increments Time Locking Counter by one.++If Time Locking Counter is positive, time skipping is locked (disabled).+When time skipping is disabled, the time in test server is moving normally, with a real time pace.+Test Server is typically started with locked time skipping and Time Locking Counter = 1.++LockTimeSkipping and UnlockTimeSkipping calls are counted.+-}+lockTimeSkipping :: Client -> LockTimeSkippingRequest -> IO (Either RpcError LockTimeSkippingResponse)+lockTimeSkipping = call @TestService @"lockTimeSkipping" hs_lock_time_skipping+++foreign import ccall "hs_sleep_until" hs_sleep_until :: PrimRpcCall+++{- | This call returns only when the Test Server Time advances to the specified timestamp.++If the current Test Server Time is beyond the specified timestamp, returns immediately.+This is an EXPERIMENTAL API.+-}+sleepUntil :: Client -> SleepUntilRequest -> IO (Either RpcError SleepResponse)+sleepUntil = call @TestService @"sleepUntil" hs_sleep_until+++foreign import ccall "hs_sleep" hs_sleep :: PrimRpcCall+++{- | This call returns only when the Test Server Time advances by the specified duration.+This is an EXPERIMENTAL API.+-}+sleep :: Client -> SleepRequest -> IO (Either RpcError SleepResponse)+sleep = call @TestService @"sleep" hs_sleep+++foreign import ccall "hs_unlock_time_skipping_with_sleep" hs_unlock_time_skipping_with_sleep :: PrimRpcCall+++{- | UnlockTimeSkippingWhileSleep decreases time locking counter by one and increases it back+once the Test Server Time advances by the duration specified in the request.++This call returns only when the Test Server Time advances by the specified duration.++If it is called when Time Locking Counter is+  - more than 1 and no other unlocks are coming in, rpc call will block for the specified duration, time will not be fast forwarded.+  - 1, it will lead to fast forwarding of the time by the duration specified in the request and quick return of this rpc call.+  - 0 will lead to rpc call failure same way as an unbalanced UnlockTimeSkipping.+-}+unlockTimeSkippingWithSleep :: Client -> SleepRequest -> IO (Either RpcError SleepResponse)+unlockTimeSkippingWithSleep = call @TestService @"unlockTimeSkippingWithSleep" hs_unlock_time_skipping_with_sleep+++{- | UnlockTimeSkipping decrements Time Locking Counter by one.++If the counter reaches 0, it unlocks time skipping and fast forwards time.+LockTimeSkipping and UnlockTimeSkipping calls are counted. Calling UnlockTimeSkipping does not+guarantee that time is going to be fast forwarded as another lock can be holding it.++Time Locking Counter can't be negative, unbalanced calls to UnlockTimeSkipping will lead to rpc call failure+-}+foreign import ccall "hs_unlock_time_skipping" hs_unlock_time_skipping :: PrimRpcCall+++unlockTimeSkipping :: Client -> UnlockTimeSkippingRequest -> IO (Either RpcError UnlockTimeSkippingResponse)+unlockTimeSkipping = call @TestService @"unlockTimeSkipping" hs_unlock_time_skipping
+ src/Temporal/Core/Client/WorkflowService.hs view
@@ -0,0 +1,619 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeApplications #-}++module Temporal.Core.Client.WorkflowService (+  countWorkflowExecutions,+  createSchedule,+  deleteSchedule,+  deprecateNamespace,+  describeNamespace,+  describeSchedule,+  describeTaskQueue,+  describeWorkflowExecution,+  getClusterInfo,+  getSearchAttributes,+  getSystemInfo,+  getWorkerBuildIdCompatibility,+  getWorkflowExecutionHistory,+  getWorkflowExecutionHistoryReverse,+  listArchivedWorkflowExecutions,+  listClosedWorkflowExecutions,+  listNamespaces,+  listOpenWorkflowExecutions,+  listScheduleMatchingTimes,+  listSchedules,+  listTaskQueuePartitions,+  listWorkflowExecutions,+  patchSchedule,+  pollActivityTaskQueue,+  pollWorkflowExecutionUpdate,+  pollWorkflowTaskQueue,+  queryWorkflow,+  recordActivityTaskHeartbeat,+  recordActivityTaskHeartbeatById,+  registerNamespace,+  requestCancelWorkflowExecution,+  resetStickyTaskQueue,+  resetWorkflowExecution,+  respondActivityTaskCanceled,+  respondActivityTaskCanceledById,+  respondActivityTaskCompleted,+  respondActivityTaskCompletedById,+  respondActivityTaskFailed,+  respondActivityTaskFailedById,+  respondQueryTaskCompleted,+  respondWorkflowTaskCompleted,+  respondWorkflowTaskFailed,+  scanWorkflowExecutions,+  signalWithStartWorkflowExecution,+  signalWorkflowExecution,+  startWorkflowExecution,+  terminateWorkflowExecution,+  updateNamespace,+  updateSchedule,+  updateWorkflowExecution,+  updateWorkerBuildIdCompatibility,+) where++import Proto.Temporal.Api.Workflowservice.V1.RequestResponse+import Proto.Temporal.Api.Workflowservice.V1.Service+import Temporal.Core.Client+++-- TODO the way that the generated protobuf code is structured, it might be nicer to just have a single+-- workflow service call that ensures the protobuf in question is the right one.+foreign import ccall "hs_count_workflow_executions" hs_count_workflow_executions :: PrimRpcCall+++-- | CountWorkflowExecutions is a visibility API to count of workflow executions in a specific namespace.+countWorkflowExecutions :: Client -> CountWorkflowExecutionsRequest -> IO (Either RpcError CountWorkflowExecutionsResponse)+countWorkflowExecutions = call @WorkflowService @"countWorkflowExecutions" hs_count_workflow_executions+++foreign import ccall "hs_create_schedule" hs_create_schedule :: PrimRpcCall+++-- | Creates a new schedule.+createSchedule :: Client -> CreateScheduleRequest -> IO (Either RpcError CreateScheduleResponse)+createSchedule = call @WorkflowService @"createSchedule" hs_create_schedule+++foreign import ccall "hs_delete_schedule" hs_delete_schedule :: PrimRpcCall+++-- | Deletes a schedule, removing it from the system.+deleteSchedule :: Client -> DeleteScheduleRequest -> IO (Either RpcError DeleteScheduleResponse)+deleteSchedule = call @WorkflowService @"deleteSchedule" hs_delete_schedule+++foreign import ccall "hs_deprecate_namespace" hs_deprecate_namespace :: PrimRpcCall+++-- | Returns the schedule description and current state of an existing schedule.+deprecateNamespace :: Client -> DeprecateNamespaceRequest -> IO (Either RpcError DeprecateNamespaceResponse)+deprecateNamespace = call @WorkflowService @"deprecateNamespace" hs_deprecate_namespace+++foreign import ccall "hs_describe_namespace" hs_describe_namespace :: PrimRpcCall+++-- |  DescribeNamespace returns the information and configuration for a registered namespace.+describeNamespace :: Client -> DescribeNamespaceRequest -> IO (Either RpcError DescribeNamespaceResponse)+describeNamespace = call @WorkflowService @"describeNamespace" hs_describe_namespace+++foreign import ccall "hs_describe_schedule" hs_describe_schedule :: PrimRpcCall+++describeSchedule :: Client -> DescribeScheduleRequest -> IO (Either RpcError DescribeScheduleResponse)+describeSchedule = call @WorkflowService @"describeSchedule" hs_describe_schedule+++foreign import ccall "hs_describe_task_queue" hs_describe_task_queue :: PrimRpcCall+++-- | DescribeTaskQueue returns information about the target task queue.+describeTaskQueue :: Client -> DescribeTaskQueueRequest -> IO (Either RpcError DescribeTaskQueueResponse)+describeTaskQueue = call @WorkflowService @"describeTaskQueue" hs_describe_task_queue+++foreign import ccall "hs_describe_workflow_execution" hs_describe_workflow_execution :: PrimRpcCall+++-- | DescribeWorkflowExecution returns information about the specified workflow execution.+describeWorkflowExecution :: Client -> DescribeWorkflowExecutionRequest -> IO (Either RpcError DescribeWorkflowExecutionResponse)+describeWorkflowExecution = call @WorkflowService @"describeWorkflowExecution" hs_describe_workflow_execution+++foreign import ccall "hs_get_cluster_info" hs_get_cluster_info :: PrimRpcCall+++-- | GetClusterInfo returns information about temporal cluster+getClusterInfo :: Client -> GetClusterInfoRequest -> IO (Either RpcError GetClusterInfoResponse)+getClusterInfo = call @WorkflowService @"getClusterInfo" hs_get_cluster_info+++foreign import ccall "hs_get_search_attributes" hs_get_search_attributes :: PrimRpcCall+++-- | GetSearchAttributes is a visibility API to get all legal keys that could be used in list APIs+getSearchAttributes :: Client -> GetSearchAttributesRequest -> IO (Either RpcError GetSearchAttributesResponse)+getSearchAttributes = call @WorkflowService @"getSearchAttributes" hs_get_search_attributes+++foreign import ccall "hs_get_system_info" hs_get_system_info :: PrimRpcCall+++-- | GetSystemInfo returns information about the system.+getSystemInfo :: Client -> GetSystemInfoRequest -> IO (Either RpcError GetSystemInfoResponse)+getSystemInfo = call @WorkflowService @"getSystemInfo" hs_get_system_info+++foreign import ccall "hs_get_worker_build_id_compatibility" hs_get_worker_build_id_compatibility :: PrimRpcCall+++-- | Fetches the worker build id versioning sets for some task queue and related metadata.+getWorkerBuildIdCompatibility :: Client -> GetWorkerBuildIdCompatibilityRequest -> IO (Either RpcError GetWorkerBuildIdCompatibilityResponse)+getWorkerBuildIdCompatibility = call @WorkflowService @"getWorkerBuildIdCompatibility" hs_get_worker_build_id_compatibility+++foreign import ccall "hs_get_workflow_execution_history" hs_get_workflow_execution_history :: PrimRpcCall+++{- |+GetWorkflowExecutionHistory returns the history of specified workflow execution. Fails with+`NotFound` if the specified workflow execution is unknown to the service.+-}+getWorkflowExecutionHistory :: Client -> GetWorkflowExecutionHistoryRequest -> IO (Either RpcError GetWorkflowExecutionHistoryResponse)+getWorkflowExecutionHistory = call @WorkflowService @"getWorkflowExecutionHistory" hs_get_workflow_execution_history+++foreign import ccall "hs_get_workflow_execution_history_reverse" hs_get_workflow_execution_history_reverse :: PrimRpcCall+++{- |+GetWorkflowExecutionHistoryReverse returns the history of specified workflow execution in reverse+order (starting from last event). Fails with`NotFound` if the specified workflow execution is+unknown to the service.+-}+getWorkflowExecutionHistoryReverse :: Client -> GetWorkflowExecutionHistoryReverseRequest -> IO (Either RpcError GetWorkflowExecutionHistoryReverseResponse)+getWorkflowExecutionHistoryReverse = call @WorkflowService @"getWorkflowExecutionHistoryReverse" hs_get_workflow_execution_history_reverse+++foreign import ccall "hs_list_archived_workflow_executions" hs_list_archived_workflow_executions :: PrimRpcCall+++-- | ListArchivedWorkflowExecutions is a visibility API to list archived workflow executions in a specific namespace.+listArchivedWorkflowExecutions :: Client -> ListArchivedWorkflowExecutionsRequest -> IO (Either RpcError ListArchivedWorkflowExecutionsResponse)+listArchivedWorkflowExecutions = call @WorkflowService @"listArchivedWorkflowExecutions" hs_list_archived_workflow_executions+++foreign import ccall "hs_list_closed_workflow_executions" hs_list_closed_workflow_executions :: PrimRpcCall+++-- | ListClosedWorkflowExecutions is a visibility API to list the closed executions in a specific namespace.+listClosedWorkflowExecutions :: Client -> ListClosedWorkflowExecutionsRequest -> IO (Either RpcError ListClosedWorkflowExecutionsResponse)+listClosedWorkflowExecutions = call @WorkflowService @"listClosedWorkflowExecutions" hs_list_closed_workflow_executions+++foreign import ccall "hs_list_namespaces" hs_list_namespaces :: PrimRpcCall+++-- | ListNamespaces returns the information and configuration for all namespaces.+listNamespaces :: Client -> ListNamespacesRequest -> IO (Either RpcError ListNamespacesResponse)+listNamespaces = call @WorkflowService @"listNamespaces" hs_list_namespaces+++foreign import ccall "hs_list_open_workflow_executions" hs_list_open_workflow_executions :: PrimRpcCall+++-- | ListOpenWorkflowExecutions is a visibility API to list the open executions in a specific namespace.+listOpenWorkflowExecutions :: Client -> ListOpenWorkflowExecutionsRequest -> IO (Either RpcError ListOpenWorkflowExecutionsResponse)+listOpenWorkflowExecutions = call @WorkflowService @"listOpenWorkflowExecutions" hs_list_open_workflow_executions+++foreign import ccall "hs_list_schedule_matching_times" hs_list_schedule_matching_times :: PrimRpcCall+++-- | ListWorkflowExecutions is a visibility API to list workflow executions in a specific namespace.+listScheduleMatchingTimes :: Client -> ListScheduleMatchingTimesRequest -> IO (Either RpcError ListScheduleMatchingTimesResponse)+listScheduleMatchingTimes = call @WorkflowService @"listScheduleMatchingTimes" hs_list_schedule_matching_times+++foreign import ccall "hs_list_schedules" hs_list_schedules :: PrimRpcCall+++-- | Lists matching times within a range.+listSchedules :: Client -> ListSchedulesRequest -> IO (Either RpcError ListSchedulesResponse)+listSchedules = call @WorkflowService @"listSchedules" hs_list_schedules+++foreign import ccall "hs_list_task_queue_partitions" hs_list_task_queue_partitions :: PrimRpcCall+++listTaskQueuePartitions :: Client -> ListTaskQueuePartitionsRequest -> IO (Either RpcError ListTaskQueuePartitionsResponse)+listTaskQueuePartitions = call @WorkflowService @"listTaskQueuePartitions" hs_list_task_queue_partitions+++foreign import ccall "hs_list_workflow_executions" hs_list_workflow_executions :: PrimRpcCall+++-- |  ListWorkflowExecutions is a visibility API to list workflow executions in a specific namespace.+listWorkflowExecutions :: Client -> ListWorkflowExecutionsRequest -> IO (Either RpcError ListWorkflowExecutionsResponse)+listWorkflowExecutions = call @WorkflowService @"listWorkflowExecutions" hs_list_workflow_executions+++foreign import ccall "hs_patch_schedule" hs_patch_schedule :: PrimRpcCall+++-- | Makes a specific change to a schedule or triggers an immediate action.+patchSchedule :: Client -> PatchScheduleRequest -> IO (Either RpcError PatchScheduleResponse)+patchSchedule = call @WorkflowService @"patchSchedule" hs_patch_schedule+++foreign import ccall "hs_poll_activity_task_queue" hs_poll_activity_task_queue :: PrimRpcCall+++{- |+PollActivityTaskQueue is called by workers to process activity tasks from a specific task+queue.++The worker is expected to call one of the `RespondActivityTaskXXX` methods when it is done+processing the task.++An activity task is dispatched whenever a `SCHEDULE_ACTIVITY_TASK` command is produced during+workflow execution. An in memory `ACTIVITY_TASK_STARTED` event is written to mutable state+before the task is dispatched to the worker. The started event, and the final event+(`ACTIVITY_TASK_COMPLETED` / `ACTIVITY_TASK_FAILED` / `ACTIVITY_TASK_TIMED_OUT`) will both be+written permanently to Workflow execution history when Activity is finished. This is done to+avoid writing many events in the case of a failure/retry loop.+-}+pollActivityTaskQueue :: Client -> PollActivityTaskQueueRequest -> IO (Either RpcError PollActivityTaskQueueResponse)+pollActivityTaskQueue = call @WorkflowService @"pollActivityTaskQueue" hs_poll_activity_task_queue+++foreign import ccall "hs_poll_workflow_execution_update" hs_poll_workflow_execution_update :: PrimRpcCall+++pollWorkflowExecutionUpdate :: Client -> PollWorkflowExecutionUpdateRequest -> IO (Either RpcError PollWorkflowExecutionUpdateResponse)+pollWorkflowExecutionUpdate = call @WorkflowService @"pollWorkflowExecutionUpdate" hs_poll_workflow_execution_update+++foreign import ccall "hs_poll_workflow_task_queue" hs_poll_workflow_task_queue :: PrimRpcCall+++{- |+PollWorkflowTaskQueue is called by workers to make progress on workflows.++A WorkflowTask is dispatched to callers for active workflow executions with pending workflow+tasks. The worker is expected to call `RespondWorkflowTaskCompleted` when it is done+processing the task. The service will create a `WorkflowTaskStarted` event in the history for+this task before handing it to the worker.+-}+pollWorkflowTaskQueue :: Client -> PollWorkflowTaskQueueRequest -> IO (Either RpcError PollWorkflowTaskQueueResponse)+pollWorkflowTaskQueue = call @WorkflowService @"pollWorkflowTaskQueue" hs_poll_workflow_task_queue+++foreign import ccall "hs_query_workflow" hs_query_workflow :: PrimRpcCall+++{- |+QueryWorkflow requests a query be executed for a specified workflow execution.+-}+queryWorkflow :: Client -> QueryWorkflowRequest -> IO (Either RpcError QueryWorkflowResponse)+queryWorkflow = call @WorkflowService @"queryWorkflow" hs_query_workflow+++foreign import ccall "hs_record_activity_task_heartbeat" hs_record_activity_task_heartbeat :: PrimRpcCall+++{- |+RecordActivityTaskHeartbeat is optionally called by workers while they execute activities.++If worker fails to heartbeat within the `heartbeat_timeout` interval for the activity task,+then it will be marked as timed out and an `ACTIVITY_TASK_TIMED_OUT` event will be written to+the workflow history. Calling `RecordActivityTaskHeartbeat` will fail with `NotFound` in+such situations, in that event, the SDK should request cancellation of the activity.+-}+recordActivityTaskHeartbeat :: Client -> RecordActivityTaskHeartbeatRequest -> IO (Either RpcError RecordActivityTaskHeartbeatResponse)+recordActivityTaskHeartbeat = call @WorkflowService @"recordActivityTaskHeartbeat" hs_record_activity_task_heartbeat+++foreign import ccall "hs_record_activity_task_heartbeat_by_id" hs_record_activity_task_heartbeat_by_id :: PrimRpcCall+++{- |+See `RecordActivityTaskHeartbeat`. This version allows clients to record heartbeats by+namespace/workflow id/activity id instead of task token.+-}+recordActivityTaskHeartbeatById :: Client -> RecordActivityTaskHeartbeatByIdRequest -> IO (Either RpcError RecordActivityTaskHeartbeatByIdResponse)+recordActivityTaskHeartbeatById = call @WorkflowService @"recordActivityTaskHeartbeatById" hs_record_activity_task_heartbeat_by_id+++foreign import ccall "hs_register_namespace" hs_register_namespace :: PrimRpcCall+++{-+RegisterNamespace creates a new namespace which can be used as a container for all resources.++A Namespace is a top level entity within Temporal, and is used as a container for resources+like workflow executions, task queues, etc. A Namespace acts as a sandbox and provides+isolation for all resources within the namespace. All resources belongs to exactly one namespace.+-}+registerNamespace :: Client -> RegisterNamespaceRequest -> IO (Either RpcError RegisterNamespaceResponse)+registerNamespace = call @WorkflowService @"registerNamespace" hs_register_namespace+++foreign import ccall "hs_request_cancel_workflow_execution" hs_request_cancel_workflow_execution :: PrimRpcCall+++{- |+RequestCancelWorkflowExecution is called by workers when they want to request cancellation of+a workflow execution.++This results in a new `WORKFLOW_EXECUTION_CANCEL_REQUESTED` event being written to the+workflow history and a new workflow task created for the workflow. It returns success if the requested+workflow is already closed. It fails with 'NotFound' if the requested workflow doesn't exist.+-}+requestCancelWorkflowExecution :: Client -> RequestCancelWorkflowExecutionRequest -> IO (Either RpcError RequestCancelWorkflowExecutionResponse)+requestCancelWorkflowExecution = call @WorkflowService @"requestCancelWorkflowExecution" hs_request_cancel_workflow_execution+++foreign import ccall "hs_reset_sticky_task_queue" hs_reset_sticky_task_queue :: PrimRpcCall+++{- |+ResetStickyTaskQueue resets the sticky task queue related information in the mutable state of+a given workflow. This is prudent for workers to perform if a workflow has been paged out of+their cache.++Things cleared are:+1. StickyTaskQueue+2. StickyScheduleToStartTimeout+-}+resetStickyTaskQueue :: Client -> ResetStickyTaskQueueRequest -> IO (Either RpcError ResetStickyTaskQueueResponse)+resetStickyTaskQueue = call @WorkflowService @"resetStickyTaskQueue" hs_reset_sticky_task_queue+++foreign import ccall "hs_reset_workflow_execution" hs_reset_workflow_execution :: PrimRpcCall+++{- |+ResetWorkflowExecution will reset an existing workflow execution to a specified+`WORKFLOW_TASK_COMPLETED` event (exclusive). It will immediately terminate the current+execution instance.+-}++-- TODO: Does exclusive here mean *just* the completed event, or also WFT started? Otherwise the task is doomed to time out?+resetWorkflowExecution :: Client -> ResetWorkflowExecutionRequest -> IO (Either RpcError ResetWorkflowExecutionResponse)+resetWorkflowExecution = call @WorkflowService @"resetWorkflowExecution" hs_reset_workflow_execution+++foreign import ccall "hs_respond_activity_task_canceled" hs_respond_activity_task_canceled :: PrimRpcCall+++{- |+RespondActivityTaskFailed is called by workers when processing an activity task fails.++This results in a new `ACTIVITY_TASK_CANCELED` event being written to the workflow history+and a new workflow task created for the workflow. Fails with `NotFound` if the task token is+no longer valid due to activity timeout, already being completed, or never having existed.+-}+respondActivityTaskCanceled :: Client -> RespondActivityTaskCanceledRequest -> IO (Either RpcError RespondActivityTaskCanceledResponse)+respondActivityTaskCanceled = call @WorkflowService @"respondActivityTaskCanceled" hs_respond_activity_task_canceled+++foreign import ccall "hs_respond_activity_task_canceled_by_id" hs_respond_activity_task_canceled_by_id :: PrimRpcCall+++{- |+See `RecordActivityTaskCanceled`. This version allows clients to record failures by+namespace/workflow id/activity id instead of task token.+-}+respondActivityTaskCanceledById :: Client -> RespondActivityTaskCanceledByIdRequest -> IO (Either RpcError RespondActivityTaskCanceledByIdResponse)+respondActivityTaskCanceledById = call @WorkflowService @"respondActivityTaskCanceledById" hs_respond_activity_task_canceled_by_id+++foreign import ccall "hs_respond_activity_task_completed" hs_respond_activity_task_completed :: PrimRpcCall+++{- |+RespondActivityTaskCompleted is called by workers when they successfully complete an activity+task.++This results in a new `ACTIVITY_TASK_COMPLETED` event being written to the workflow history+and a new workflow task created for the workflow. Fails with `NotFound` if the task token is+no longer valid due to activity timeout, already being completed, or never having existed.+-}+respondActivityTaskCompleted :: Client -> RespondActivityTaskCompletedRequest -> IO (Either RpcError RespondActivityTaskCompletedResponse)+respondActivityTaskCompleted = call @WorkflowService @"respondActivityTaskCompleted" hs_respond_activity_task_completed+++foreign import ccall "hs_respond_activity_task_completed_by_id" hs_respond_activity_task_completed_by_id :: PrimRpcCall+++{- |+See `RecordActivityTaskCompleted`. This version allows clients to record completions by+namespace/workflow id/activity id instead of task token.+-}+respondActivityTaskCompletedById :: Client -> RespondActivityTaskCompletedByIdRequest -> IO (Either RpcError RespondActivityTaskCompletedByIdResponse)+respondActivityTaskCompletedById = call @WorkflowService @"respondActivityTaskCompletedById" hs_respond_activity_task_completed_by_id+++foreign import ccall "hs_respond_activity_task_failed" hs_respond_activity_task_failed :: PrimRpcCall+++{- |+RespondActivityTaskFailed is called by workers when processing an activity task fails.++This results in a new `ACTIVITY_TASK_FAILED` event being written to the workflow history and+a new workflow task created for the workflow. Fails with `NotFound` if the task token is no+longer valid due to activity timeout, already being completed, or never having existed.+-}+respondActivityTaskFailed :: Client -> RespondActivityTaskFailedRequest -> IO (Either RpcError RespondActivityTaskFailedResponse)+respondActivityTaskFailed = call @WorkflowService @"respondActivityTaskFailed" hs_respond_activity_task_failed+++foreign import ccall "hs_respond_activity_task_failed_by_id" hs_respond_activity_task_failed_by_id :: PrimRpcCall+++{- |+See `RecordActivityTaskCompleted`. This version allows clients to record completions by+namespace/workflow id/activity id instead of task token.+-}+respondActivityTaskFailedById :: Client -> RespondActivityTaskFailedByIdRequest -> IO (Either RpcError RespondActivityTaskFailedByIdResponse)+respondActivityTaskFailedById = call @WorkflowService @"respondActivityTaskFailedById" hs_respond_activity_task_failed_by_id+++foreign import ccall "hs_respond_query_task_completed" hs_respond_query_task_completed :: PrimRpcCall+++{- |+RespondQueryTaskCompleted is called by workers to complete queries which were delivered on+the `query` (not `queries`) field of a `PollWorkflowTaskQueueResponse`.++Completing the query will unblock the corresponding client call to `QueryWorkflow` and return+the query result a response.+-}+respondQueryTaskCompleted :: Client -> RespondQueryTaskCompletedRequest -> IO (Either RpcError RespondQueryTaskCompletedResponse)+respondQueryTaskCompleted = call @WorkflowService @"respondQueryTaskCompleted" hs_respond_query_task_completed+++foreign import ccall "hs_respond_workflow_task_completed" hs_respond_workflow_task_completed :: PrimRpcCall+++{- |+RespondWorkflowTaskCompleted is called by workers to successfully complete workflow tasks+they received from `PollWorkflowTaskQueue`.++Completing a WorkflowTask will write a `WORKFLOW_TASK_COMPLETED` event to the workflow's+history, along with events corresponding to whatever commands the SDK generated while+executing the task (ex timer started, activity task scheduled, etc).+-}+respondWorkflowTaskCompleted :: Client -> RespondWorkflowTaskCompletedRequest -> IO (Either RpcError RespondWorkflowTaskCompletedResponse)+respondWorkflowTaskCompleted = call @WorkflowService @"respondWorkflowTaskCompleted" hs_respond_workflow_task_completed+++foreign import ccall "hs_respond_workflow_task_failed" hs_respond_workflow_task_failed :: PrimRpcCall+++{- |+RespondWorkflowTaskFailed is called by workers to indicate the processing of a workflow task+failed.++This results in a `WORKFLOW_TASK_FAILED` event written to the history, and a new workflow+task will be scheduled. This API can be used to report unhandled failures resulting from+applying the workflow task.++Temporal will only append first WorkflowTaskFailed event to the history of workflow execution+for consecutive failures.+-}+respondWorkflowTaskFailed :: Client -> RespondWorkflowTaskFailedRequest -> IO (Either RpcError RespondWorkflowTaskFailedResponse)+respondWorkflowTaskFailed = call @WorkflowService @"respondWorkflowTaskFailed" hs_respond_workflow_task_failed+++foreign import ccall "hs_scan_workflow_executions" hs_scan_workflow_executions :: PrimRpcCall+++-- | ScanWorkflowExecutions is a visibility API to list large amount of workflow executions in a specific namespace without order.+scanWorkflowExecutions :: Client -> ScanWorkflowExecutionsRequest -> IO (Either RpcError ScanWorkflowExecutionsResponse)+scanWorkflowExecutions = call @WorkflowService @"scanWorkflowExecutions" hs_scan_workflow_executions+++foreign import ccall "hs_signal_with_start_workflow_execution" hs_signal_with_start_workflow_execution :: PrimRpcCall+++{- |+SignalWithStartWorkflowExecution is used to ensure a signal is sent to a workflow, even if+it isn't yet started.++If the workflow is running, a `WORKFLOW_EXECUTION_SIGNALED` event is recorded in the history+and a workflow task is generated.++If the workflow is not running or not found, then the workflow is created with+`WORKFLOW_EXECUTION_STARTED` and `WORKFLOW_EXECUTION_SIGNALED` events in its history, and a+workflow task is generated.+-}+signalWithStartWorkflowExecution :: Client -> SignalWithStartWorkflowExecutionRequest -> IO (Either RpcError SignalWithStartWorkflowExecutionResponse)+signalWithStartWorkflowExecution = call @WorkflowService @"signalWithStartWorkflowExecution" hs_signal_with_start_workflow_execution+++foreign import ccall "hs_signal_workflow_execution" hs_signal_workflow_execution :: PrimRpcCall+++{- |+SignalWorkflowExecution is used to send a signal to a running workflow execution.++This results in a `WORKFLOW_EXECUTION_SIGNALED` event recorded in the history and a workflow+task being created for the execution.+-}+signalWorkflowExecution :: Client -> SignalWorkflowExecutionRequest -> IO (Either RpcError SignalWorkflowExecutionResponse)+signalWorkflowExecution = call @WorkflowService @"signalWorkflowExecution" hs_signal_workflow_execution+++foreign import ccall "hs_start_workflow_execution" hs_start_workflow_execution :: PrimRpcCall+++{-+  Starts a new workflow execution.++  It will create the execution with a `WORKFLOW_EXECUTION_STARTED` event in its history and+  also schedule the first workflow task. Returns `WorkflowExecutionAlreadyStarted`, if an+  instance already exists with same workflow id.+-}+startWorkflowExecution :: Client -> StartWorkflowExecutionRequest -> IO (Either RpcError StartWorkflowExecutionResponse)+startWorkflowExecution = call @WorkflowService @"startWorkflowExecution" hs_start_workflow_execution+++foreign import ccall "hs_terminate_workflow_execution" hs_terminate_workflow_execution :: PrimRpcCall+++{- |+terminates an existing workflow execution by recording a+`WORKFLOW_EXECUTION_TERMINATED` event in the history and immediately terminating the+execution instance.+-}+terminateWorkflowExecution :: Client -> TerminateWorkflowExecutionRequest -> IO (Either RpcError TerminateWorkflowExecutionResponse)+terminateWorkflowExecution = call @WorkflowService @"terminateWorkflowExecution" hs_terminate_workflow_execution+++foreign import ccall "hs_update_namespace" hs_update_namespace :: PrimRpcCall+++{- | UpdateNamespace is used to update the information and configuration of a registered+namespace.+-}+updateNamespace :: Client -> UpdateNamespaceRequest -> IO (Either RpcError UpdateNamespaceResponse)+updateNamespace = call @WorkflowService @"updateNamespace" hs_update_namespace+++foreign import ccall "hs_update_schedule" hs_update_schedule :: PrimRpcCall+++-- |  Changes the configuration or state of an existing schedule.+updateSchedule :: Client -> UpdateScheduleRequest -> IO (Either RpcError UpdateScheduleResponse)+updateSchedule = call @WorkflowService @"updateSchedule" hs_update_schedule+++foreign import ccall "hs_update_workflow_execution" hs_update_workflow_execution :: PrimRpcCall+++-- | Invokes the specified update function on user workflow code.+updateWorkflowExecution :: Client -> UpdateWorkflowExecutionRequest -> IO (Either RpcError UpdateWorkflowExecutionResponse)+updateWorkflowExecution = call @WorkflowService @"updateWorkflowExecution" hs_update_workflow_execution+++foreign import ccall "hs_update_worker_build_id_compatibility" hs_update_worker_build_id_compatibility :: PrimRpcCall+++{- |+Allows users to specify sets of worker build id versions on a per task queue basis. Versions+are ordered, and may be either compatible with some extant version, or a new incompatible+version, forming sets of ids which are incompatible with each other, but whose contained+members are compatible with one another.+-}+updateWorkerBuildIdCompatibility :: Client -> UpdateWorkerBuildIdCompatibilityRequest -> IO (Either RpcError UpdateWorkerBuildIdCompatibilityResponse)+updateWorkerBuildIdCompatibility = call @WorkflowService @"updateWorkerBuildIdCompatibility" hs_update_worker_build_id_compatibility
+ src/Temporal/Core/EphemeralServer.hs view
@@ -0,0 +1,173 @@+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}++module Temporal.Core.EphemeralServer where++import Control.Monad+import Data.Aeson+import Data.Aeson.TH+import Data.ByteString (ByteString, useAsCString)+import qualified Data.ByteString.Lazy as BL+import Data.Word+import Foreign.C.String hiding (withCString)+import Foreign.ForeignPtr+import Foreign.Ptr+import Foreign.Storable+import Temporal.Core.CTypes+import Temporal.Internal.FFI+import Temporal.Runtime+++data SDKDefault = SDKDefault {sdkName :: String, sdkVersion :: String}+++data EphemeralExeVersion+  = -- | Use a default version for the given SDK name and version.+    Default SDKDefault+  | -- | Specific version.+    Fixed String+++instance ToJSON EphemeralExeVersion where+  toJSON (Default (SDKDefault name version)) =+    object+      [ "type" .= String "SDKDefault"+      , "contents"+          .= object+            [ "sdk_name" .= name+            , "sdk_version" .= version+            ]+      ]+  toJSON (Fixed version) =+    object+      [ "type" .= String "Fixed"+      , "contents" .= version+      ]+++data EphemeralExe+  = -- | Existing path on the filesystem for the executable.+    ExistingPath FilePath+  | -- | Download the executable if not already there.+    CachedDownload EphemeralExeVersion (Maybe FilePath) (Maybe Word64)+++instance ToJSON EphemeralExe where+  toJSON (ExistingPath path) =+    object+      [ "type" .= String "ExistingPath"+      , "contents" .= path+      ]+  toJSON (CachedDownload version destDir ttl) =+    object+      [ "type" .= String "CachedDownload"+      , "contents"+          .= object+            [ "version" .= version+            , "dest_dir" .= destDir+            ]+      , "ttl" .= ttl+      ]+++data TemporalDevServerConfig = TemporalDevServerConfig+  { exe :: EphemeralExe+  , namespace :: FilePath+  , ip :: String+  , port :: Maybe Word16+  , dbFilename :: Maybe FilePath+  , ui :: Bool+  , uiPort :: Maybe Word16+  , log :: (String, String)+  , extraArgs :: [String]+  }+++deriveToJSON (defaultOptions {fieldLabelModifier = camelTo2 '_'}) ''TemporalDevServerConfig+++defaultTemporalDevServerConfig :: TemporalDevServerConfig+defaultTemporalDevServerConfig =+  TemporalDevServerConfig+    { exe = CachedDownload (Default $ SDKDefault "community-haskell" "0.1.0.0") Nothing Nothing+    , namespace = "default"+    , ip = "127.0.0.1"+    , port = Nothing+    , dbFilename = Nothing+    , ui = False+    , uiPort = Nothing+    , log = ("pretty", "warn")+    , extraArgs = []+    }+++newtype EphemeralServer = EphemeralServer {ephemeralServerPtr :: ForeignPtr EphemeralServer}+++foreign import ccall "hs_temporal_start_dev_server"+  raw_startDevServer+    :: Ptr Runtime+    -> CString+    -> TokioCall (CArray Word8) EphemeralServer+++startDevServer :: Runtime -> TemporalDevServerConfig -> IO (Either ByteString EphemeralServer)+startDevServer r c = withRuntime r $ \rp -> useAsCString (BL.toStrict (encode c)) $ \cstr -> do+  res <-+    makeTokioAsyncCall+      (raw_startDevServer rp cstr)+      (Just rust_dropByteArray)+      Nothing+  case res of+    Left err -> Left <$> withForeignPtr err (peek >=> cArrayToByteString)+    Right srv -> pure $ Right $ EphemeralServer srv+++foreign import ccall "hs_temporal_shutdown_ephemeral_server" raw_shutdownEphemeralServer :: Ptr EphemeralServer -> TokioCall (CArray Word8) CUnit+++shutdownEphemeralServer :: EphemeralServer -> IO (Either ByteString ())+shutdownEphemeralServer (EphemeralServer e) = withForeignPtr e $ \ep -> do+  res <-+    makeTokioAsyncCall+      (raw_shutdownEphemeralServer ep)+      (Just rust_dropByteArray)+      (Just rust_dropUnit)+  case res of+    Left err -> Left <$> withForeignPtr err (peek >=> cArrayToByteString)+    Right _ -> pure $ Right ()+++-- TODO+-- startDevServerWithOutput++data TemporalTestServerConfig = TemporalTestServerConfig+  { exe :: EphemeralExe+  , port :: Maybe Word16+  , extraArgs :: [String]+  }+++deriveToJSON (defaultOptions {fieldLabelModifier = camelTo2 '_'}) ''TemporalTestServerConfig+++foreign import ccall "hs_temporal_start_test_server"+  raw_startTestServer+    :: Ptr Runtime+    -> CString+    -> TokioCall (CArray Word8) EphemeralServer+++startTestServer :: Runtime -> TemporalTestServerConfig -> IO (Either ByteString EphemeralServer)+startTestServer r conf = withRuntime r $ \rp -> useAsCString (BL.toStrict $ encode conf) $ \cstr -> do+  res <-+    makeTokioAsyncCall+      (raw_startTestServer rp cstr)+      (Just rust_dropByteArray)+      Nothing+  case res of+    Left err -> Left <$> withForeignPtr err (peek >=> cArrayToByteString)+    Right srv -> pure $ Right $ EphemeralServer srv
+ src/Temporal/Core/Worker.hs view
@@ -0,0 +1,433 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}++module Temporal.Core.Worker (+  Worker,+  getWorkerClient,+  WorkerConfig (..),+  getWorkerConfig,+  defaultWorkerConfig,+  WorkerError (..),+  WorkerErrorCode (..),+  WorkerType (..),+  SWorkerType (..),+  SomeWorkerType (..),+  newWorker,+  validateWorker,+  newReplayWorker,+  closeWorker,+  InactiveForReplay,+  WorkflowActivation,+  pollWorkflowActivation,+  ActivityTask,+  pollActivityTask,+  WorkflowActivationCompletion,+  completeWorkflowActivation,+  ActivityTaskCompletion,+  completeActivityTask,+  ActivityHeartbeat,+  recordActivityHeartbeat,+  requestWorkflowEviction,+  initiateShutdown,+  finalizeShutdown,+  HistoryPusher,+  History,+  pushHistory,+  closeHistory,+  KnownWorkerType (..),+) where++import Control.Exception+import Control.Monad+import Data.Aeson+import Data.Aeson.TH+import Data.ByteString (ByteString)+import qualified Data.ByteString.Lazy as BL+import Data.IORef+import Data.ProtoLens.Encoding (decodeMessageOrDie, encodeMessage)+import Data.Text (Text)+import Data.Void (Void)+import Data.Word+import Foreign.C.String+import Foreign.ForeignPtr+import Foreign.Marshal+import Foreign.Ptr+import Foreign.Storable+import Proto.Temporal.Api.History.V1.Message (History)+import Proto.Temporal.Sdk.Core.ActivityTask.ActivityTask (ActivityTask)+import Proto.Temporal.Sdk.Core.CoreInterface (ActivityHeartbeat, ActivityTaskCompletion)+import Proto.Temporal.Sdk.Core.WorkflowActivation.WorkflowActivation (WorkflowActivation)+import Proto.Temporal.Sdk.Core.WorkflowCompletion.WorkflowCompletion (WorkflowActivationCompletion)+import Temporal.Core.CTypes+import Temporal.Core.Client+import Temporal.Internal.FFI+import Temporal.Runtime+++data WorkerType = Real | Replay+++-- | A singleton type for 'WorkerType'.+data SWorkerType (ty :: WorkerType) where+  SReal :: SWorkerType 'Real+  SReplay :: SWorkerType 'Replay+++-- Promote a 'WorkerType' to a singleton type.+data SomeWorkerType where+  SomeWorkerType :: SWorkerType ty -> SomeWorkerType+++type family InactiveForReplay (ty :: WorkerType) a where+  InactiveForReplay 'Real a = a+  InactiveForReplay 'Replay _ = ()+++class KnownWorkerType (ty :: WorkerType) where+  knownWorkerType :: SWorkerType ty+++instance KnownWorkerType 'Real where+  knownWorkerType = SReal+++instance KnownWorkerType 'Replay where+  knownWorkerType = SReplay+++singFor :: KnownWorkerType ty => proxy ty -> SWorkerType ty+singFor _ = knownWorkerType+++data Worker (ty :: WorkerType) = Worker+  { workerPtr :: {-# UNPACK #-} !(IORef (ForeignPtr (Worker ty)))+  , workerConfig :: !WorkerConfig+  , workerClient :: !(InactiveForReplay ty Client)+  , workerRuntime :: {-# UNPACK #-} !Runtime+  }+++withWorker :: forall ty a. KnownWorkerType ty => Worker ty -> (Ptr (Worker ty) -> IO a) -> IO a+withWorker w@(Worker ptrRef _ c r) f = withRuntime r $ \_ ->+  let keepClientAlive :: IO a -> IO a+      keepClientAlive = case singFor w of+        SReal -> \m -> do+          a <- m+          touchClient c+          pure a+        SReplay -> id+  in keepClientAlive $ do+      ptr <- readIORef ptrRef+      withForeignPtr ptr f+++getWorkerClient :: Worker 'Real -> Client+getWorkerClient = workerClient+++getWorkerConfig :: Worker ty -> WorkerConfig+getWorkerConfig = workerConfig+++newtype HistoryPusher = HistoryPusher {historyPusher :: Ptr HistoryPusher}+++type Proto = ByteString+++type RunId = ByteString+++type WorkflowId = ByteString+++data WorkerConfig = WorkerConfig+  { namespace :: Text+  , taskQueue :: Text+  , buildId :: Text+  , identityOverride :: Maybe Text+  , maxCachedWorkflows :: Word64+  , maxOutstandingWorkflowTasks :: Word64+  , maxOutstandingActivities :: Word64+  , maxOutstandingLocalActivities :: Word64+  , maxConcurrentWorkflowTaskPolls :: Word64+  , nonstickyToStickyPollRatio :: Float+  , maxConcurrentActivityTaskPolls :: Word64+  , noRemoteActivities :: Bool+  , stickyQueueScheduleToStartTimeoutMillis :: Word64+  , maxHeartbeatThrottleIntervalMillis :: Word64+  , defaultHeartbeatThrottleIntervalMillis :: Word64+  , maxActivitiesPerSecond :: Maybe Double+  , maxTaskQueueActivitiesPerSecond :: Maybe Double+  , gracefulShutdownPeriodMillis :: Word64+  , nondeterminismAsWorkflowFail :: Bool+  , nondeterminismAsWorkflowFailForTypes :: [Text]+  -- TODO:+  -- useWorkerVersioning+  -- tuner+  }+++deriveJSON (defaultOptions {fieldLabelModifier = camelTo2 '_'}) ''WorkerConfig+++defaultWorkerConfig :: WorkerConfig+defaultWorkerConfig =+  WorkerConfig+    { namespace = "default"+    , taskQueue = "default"+    , buildId = ""+    , identityOverride = Nothing+    , maxCachedWorkflows = 100000+    , maxOutstandingWorkflowTasks = 1000+    , maxOutstandingActivities = 1000+    , maxOutstandingLocalActivities = 1000+    , maxConcurrentWorkflowTaskPolls = 5+    , nonstickyToStickyPollRatio = 0.85+    , maxConcurrentActivityTaskPolls = 5+    , noRemoteActivities = False+    , stickyQueueScheduleToStartTimeoutMillis = 60000+    , maxHeartbeatThrottleIntervalMillis = 300000+    , defaultHeartbeatThrottleIntervalMillis = 300000+    , maxActivitiesPerSecond = Nothing+    , maxTaskQueueActivitiesPerSecond = Nothing+    , gracefulShutdownPeriodMillis = 0+    , nondeterminismAsWorkflowFail = False+    , nondeterminismAsWorkflowFailForTypes = []+    }+++foreign import ccall "hs_temporal_new_worker" raw_newWorker :: Ptr CoreClient -> Ptr (CArray Word8) -> Ptr (Ptr (Worker 'Real)) -> Ptr (Ptr CWorkerError) -> IO ()+++foreign import ccall "hs_temporal_validate_worker" raw_validateWorker :: Ptr (Worker ty) -> TokioCall CWorkerValidationError CUnit+++validateWorker :: Worker 'Real -> IO (Either WorkerValidationError ())+validateWorker w = withWorker w $ \wp -> do+  res <- makeTokioAsyncCall (raw_validateWorker wp) (Just rust_dropWorkerValidationError) (Just rust_dropUnit)+  case res of+    Left err -> Left <$> withForeignPtr err (peek >=> peekWorkerValidationError)+    Right _ -> pure $ Right ()+++foreign import ccall "&hs_temporal_drop_worker" raw_closeWorker :: FinalizerPtr (Worker ty)+++getWorkerError :: Ptr CWorkerError -> IO WorkerError+getWorkerError errPtr = do+  fp <- newForeignPtr rust_dropWorkerError errPtr+  withForeignPtr fp (peek >=> peekWorkerError)+++-- note: removed the Runtime argument from the C function since the runtime can be accessed from the client. Might want to add it back later if+-- it is some sort of load-bearing memory management thing.+newWorker :: Client -> WorkerConfig -> IO (Either WorkerError (Worker 'Real))+newWorker c wc = withClient c $ \cPtr -> do+  withCArrayBS (BL.toStrict $ encode wc) $ \wcPtr -> do+    wPtrPtrFP <- mallocForeignPtr+    errPtrPtrFP <- mallocForeignPtr+    withForeignPtr wPtrPtrFP $ \wPtrPtr -> do+      withForeignPtr errPtrPtrFP $ \errPtrPtr -> do+        poke wPtrPtr nullPtr+        poke errPtrPtr nullPtr++        mask_ $ do+          raw_newWorker cPtr wcPtr wPtrPtr errPtrPtr+          errPtr <- peek errPtrPtr+          if errPtr == nullPtr+            then do+              wPtr <- peek wPtrPtr+              wPtrFP <- newForeignPtr raw_closeWorker wPtr+              wPtrRef <- newIORef wPtrFP+              pure $ Right $ Worker wPtrRef wc c (clientRuntime c)+            else Left <$> getWorkerError errPtr+++data WorkerAlreadyClosed = WorkerAlreadyClosed+  deriving stock (Show)+++instance Exception WorkerAlreadyClosed+++closeWorker :: Worker ty -> IO ()+closeWorker (Worker w _ _ _) = mask_ $ do+  wp <- atomicModifyIORef' w $ \wp -> (throw WorkerAlreadyClosed, wp)+  finalizeForeignPtr wp+++foreign import ccall "hs_temporal_new_replay_worker" raw_newReplayWorker :: Ptr Runtime -> Ptr (CArray Word8) -> Ptr (Ptr (Worker 'Replay)) -> Ptr (Ptr HistoryPusher) -> Ptr (Ptr CWorkerError) -> IO ()+++newReplayWorker :: Runtime -> WorkerConfig -> IO (Either WorkerError (Worker 'Replay, HistoryPusher))+newReplayWorker r conf = withRuntime r $ \rPtr -> do+  alloca $ \wPtrPtr -> do+    alloca $ \hpPtrPtr -> do+      withCArrayBS (BL.toStrict $ encode conf) $ \confPtr -> do+        alloca $ \errPtrPtr -> do+          poke wPtrPtr nullPtr+          poke hpPtrPtr nullPtr+          poke errPtrPtr nullPtr++          raw_newReplayWorker rPtr confPtr wPtrPtr hpPtrPtr errPtrPtr+          errPtr <- peek errPtrPtr+          if errPtr == nullPtr+            then do+              wPtr <- peek wPtrPtr+              hpPtr <- peek hpPtrPtr+              w <- newForeignPtr raw_closeWorker wPtr+              wRef <- newIORef w+              pure $ Right (Worker wRef conf () r, HistoryPusher hpPtr)+            else Left <$> getWorkerError errPtr+++foreign import ccall "hs_temporal_worker_poll_workflow_activation" raw_pollWorkflowActivation :: Ptr (Worker ty) -> TokioCall CWorkerError (CArray Word8)+++pollWorkflowActivation :: KnownWorkerType ty => Worker ty -> IO (Either WorkerError WorkflowActivation)+pollWorkflowActivation w = withWorker w $ \wp -> do+  res <-+    makeTokioAsyncCall+      (raw_pollWorkflowActivation wp)+      (Just rust_dropWorkerError)+      (Just rust_dropByteArray)+  case res of+    Left err -> Left <$> withForeignPtr err (peek >=> peekWorkerError)+    Right ok -> Right . decodeMessageOrDie <$> withForeignPtr ok (peek >=> cArrayToByteString)+++foreign import ccall "hs_temporal_worker_poll_activity_task" raw_pollActivityTask :: Ptr (Worker ty) -> TokioCall CWorkerError (CArray Word8)+++pollActivityTask :: KnownWorkerType ty => Worker ty -> IO (Either WorkerError ActivityTask)+pollActivityTask w = withWorker w $ \wp -> do+  res <-+    makeTokioAsyncCall+      (raw_pollActivityTask wp)+      (Just rust_dropWorkerError)+      (Just rust_dropByteArray)+  case res of+    Left err -> Left <$> withForeignPtr err (peek >=> peekWorkerError)+    Right res -> Right . decodeMessageOrDie <$> withForeignPtr res (peek >=> cArrayToByteString)+++foreign import ccall "hs_temporal_worker_complete_workflow_activation" raw_completeWorkflowActivation :: Ptr (Worker ty) -> Ptr (CArray Word8) -> TokioCall CWorkerError CUnit+++completeWorkflowActivation :: KnownWorkerType ty => Worker ty -> WorkflowActivationCompletion -> IO (Either WorkerError ())+completeWorkflowActivation w p = withWorker w $ \wp ->+  withCArrayBS (encodeMessage p) $ \pPtr -> do+    res <-+      makeTokioAsyncCall+        (raw_completeWorkflowActivation wp pPtr)+        (Just rust_dropWorkerError)+        (Just rust_dropUnit)+    case res of+      Left err -> Left <$> withForeignPtr err (peek >=> peekWorkerError)+      Right _ -> pure $ Right ()+++foreign import ccall "hs_temporal_worker_complete_activity_task" raw_completeActivityTask :: Ptr (Worker ty) -> Ptr (CArray Word8) -> TokioCall CWorkerError CUnit+++completeActivityTask :: KnownWorkerType ty => Worker ty -> ActivityTaskCompletion -> IO (Either WorkerError ())+completeActivityTask w p = withWorker w $ \wp ->+  withCArrayBS (encodeMessage p) $ \pPtr -> do+    res <-+      makeTokioAsyncCall+        (raw_completeActivityTask wp pPtr)+        (Just rust_dropWorkerError)+        (Just rust_dropUnit)+    case res of+      Left err -> Left <$> withForeignPtr err (peek >=> peekWorkerError)+      Right _ -> pure $ Right ()+++foreign import ccall "hs_temporal_worker_record_activity_heartbeat" raw_recordActivityHeartbeat :: Ptr (Worker ty) -> Ptr (CArray Word8) -> Ptr (Ptr CWorkerError) -> Ptr (Ptr CUnit) -> IO ()+++recordActivityHeartbeat :: KnownWorkerType ty => Worker ty -> ActivityHeartbeat -> IO (Either WorkerError ())+recordActivityHeartbeat w p = withWorker w $ \wp ->+  withCArrayBS (encodeMessage p) $ \pPtr -> do+    alloca $ \errPtrPtr -> do+      alloca $ \resPtrPtr -> mask_ $ do+        poke errPtrPtr nullPtr+        poke resPtrPtr nullPtr+        raw_recordActivityHeartbeat wp pPtr errPtrPtr resPtrPtr+        errPtr <- peek errPtrPtr+        if errPtr == nullPtr+          then do+            rust_dropUnitNow =<< peek resPtrPtr+            pure $ Right ()+          else Left <$> getWorkerError errPtr+++foreign import ccall "hs_temporal_worker_request_workflow_eviction" raw_requestWorkflowEviction :: Ptr (Worker ty) -> Ptr (CArray Word8) -> IO ()+++requestWorkflowEviction :: KnownWorkerType ty => Worker ty -> RunId -> IO ()+requestWorkflowEviction w r = withWorker w $ \wp ->+  withCArrayBS r $ \rPtr -> do+    raw_requestWorkflowEviction wp rPtr+++foreign import ccall "hs_temporal_worker_initiate_shutdown" raw_initiateShutdown :: Ptr (Worker ty) -> IO ()+++-- | Initiate shutdown.+initiateShutdown :: KnownWorkerType ty => Worker ty -> IO ()+initiateShutdown w = withWorker w raw_initiateShutdown+++foreign import ccall "hs_temporal_worker_finalize_shutdown" raw_finalizeShutdown :: Ptr (Worker ty) -> TokioCall CWorkerError CUnit+++{- |+Completes shutdown and frees all resources. You should avoid simply dropping workers, as+this does not allow async tasks to report any panics that may have occurred cleanly.++This should be called only after 'initiateShutdown' has resolved and/or both polling+functions have returned `ShutDown` errors.+-}+finalizeShutdown :: KnownWorkerType ty => Worker ty -> IO (Either WorkerError ())+finalizeShutdown w = withWorker w $ \wp -> do+  res <-+    makeTokioAsyncCall+      (raw_finalizeShutdown wp)+      (Just rust_dropWorkerError)+      (Just rust_dropUnit)+  case res of+    Left err -> Left <$> withForeignPtr err (peek >=> peekWorkerError)+    Right _ -> pure $ Right ()+++foreign import ccall "hs_temporal_history_pusher_push_history" raw_pushHistory :: Ptr HistoryPusher -> Ptr (CArray Word8) -> Ptr (CArray Word8) -> TokioCall CWorkerError CUnit+++pushHistory :: HistoryPusher -> WorkflowId -> Either ByteString History -> IO (Either WorkerError ())+pushHistory (HistoryPusher hp) wf p =+  withCArrayBS wf $ \wfPtr -> do+    withCArrayBS (either id encodeMessage p) $ \pPtr -> do+      res <-+        makeTokioAsyncCall+          (raw_pushHistory hp wfPtr pPtr)+          (Just rust_dropWorkerError)+          (Just rust_dropUnit)+      case res of+        Left err -> Left <$> withForeignPtr err (peek >=> peekWorkerError)+        Right _ -> pure $ Right ()+++foreign import ccall "hs_temporal_history_pusher_close" raw_closeHistoryPusher :: Ptr HistoryPusher -> IO ()+++closeHistory :: HistoryPusher -> IO ()+closeHistory (HistoryPusher hp) =+  raw_closeHistoryPusher hp
+ src/Temporal/Internal/FFI.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}++module Temporal.Internal.FFI where++import Control.Concurrent+import Control.Exception+import Control.Monad+import Data.ByteString (ByteString)+import qualified Data.ByteString as ByteString+import Data.Coerce+import Data.Kind (Type)+import Data.Proxy+import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.Text.Foreign as Text+import qualified Data.Vector.Storable as Vector+import Data.Word+import Foreign.C.String+import Foreign.C.Types+import Foreign.ForeignPtr+import Foreign.Marshal.Alloc+import qualified Foreign.Marshal.Utils as Marshal+import Foreign.Ptr+import Foreign.StablePtr+import Foreign.Storable+import GHC.Conc (PrimMVar, newStablePtrPrimMVar)+import Temporal.Core.CTypes+++withCArray :: Storable a => Vector.Vector a -> (Ptr (CArray a) -> IO b) -> IO b+withCArray v f = Vector.unsafeWith v $ \vPtr ->+  Marshal.with (CArray vPtr (fromIntegral (Vector.length v))) f+++withCArrayBS :: ByteString -> (Ptr (CArray Word8) -> IO b) -> IO b+withCArrayBS bs f = ByteString.useAsCStringLen bs $ \(bytes, len) ->+  Marshal.with (CArray (castPtr bytes) (fromIntegral len)) f+++withCArrayText :: Text -> (Ptr (CArray Word8) -> IO b) -> IO b+withCArrayText txt f = Text.withCStringLen txt $ \(bytes, len) ->+  Marshal.with (CArray (castPtr bytes) (fromIntegral len)) f+++withTokioResult :: TokioResult a -> (Ptr (Ptr a) -> IO b) -> IO b+withTokioResult fp f = withForeignPtr fp $ \ptr -> do+  poke ptr nullPtr+  f ptr+++peekTokioResult :: TokioSlot a -> Maybe (FinalizerPtr a) -> IO (Maybe (ForeignPtr a))+peekTokioResult slot mfp = do+  inner <- peek slot+  if inner == nullPtr+    then return Nothing+    else+      Just <$> case mfp of+        Nothing -> newForeignPtr_ inner+        Just fp -> newForeignPtr fp inner+++type TokioCall e a = StablePtr PrimMVar -> Int -> TokioSlot e -> TokioSlot a -> IO ()+++type TokioSlot a = Ptr (Ptr a)+++type TokioResult a = ForeignPtr (Ptr a)+++{- | Dropping can't be done automatically if the result is returned without async exceptions+intervening, because we don't want to drop things like `Client` while they're still in use.+So we should return ForeignPtrs for things that need to stay alive, and then we can drop when we're done.+-}+makeTokioAsyncCall+  :: TokioCall err res+  -> Maybe (FinalizerPtr err)+  -> Maybe (FinalizerPtr res)+  -> IO (Either (ForeignPtr err) (ForeignPtr res))+makeTokioAsyncCall call readErr readSuccess = uninterruptibleMask $ \restore -> do+  mvar <- newEmptyMVar+  sp <- newStablePtrPrimMVar mvar+  errorSlot <- mallocForeignPtr+  resultSlot <- mallocForeignPtr+  withTokioResult errorSlot $ \err -> withTokioResult resultSlot $ \res -> do+    let peekEither = do+          e <- peekTokioResult err readErr+          case e of+            Nothing -> do+              r <- peekTokioResult res readSuccess+              case r of+                Nothing -> error "Both error and result are null"+                Just r -> return (Right r)+            Just e -> return (Left e)++    (cap, _) <- threadCapability =<< myThreadId+    call sp cap err res+    let handleCleanup = forkIO $ do+          takeMVar mvar+          -- We still need to get the result out of the slot and into a ForeignPtr so that we can drop it+          void peekEither+    () <- restore (takeMVar mvar) `onException` handleCleanup+    peekEither
+ src/Temporal/Runtime.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE DuplicateRecordFields #-}++module Temporal.Runtime (+  Runtime,+  TelemetryOptions (..),+  Periodicity (..),+  initializeRuntime,+  withRuntime,+  fetchLogs,+  CoreLog (..),+  LogLevel (..),+) where++import Control.Concurrent+import Control.Exception+import Data.Aeson+import qualified Data.ByteString.Lazy as BL+import qualified Data.Vector as V+import Foreign.C.String+import Foreign.C.Types (CInt)+import Foreign.ForeignPtr+import Foreign.Marshal+import Foreign.Ptr+import Foreign.StablePtr+import Foreign.Storable+import System.IO.Unsafe+import Temporal.Core.CTypes+import Temporal.Internal.FFI+++-- | Initialize the Rust runtime and thread-pool.+initializeRuntime :: TelemetryOptions -> IO Runtime+initializeRuntime opts = withCArrayBS (BL.toStrict $ encode opts) $ \optsP ->+  mask_ $ do+    rtP <- initRuntime optsP tryPutMVarPtr+    Runtime <$> newForeignPtr freeRuntime rtP+++-- | Access the underlying 'Runtime' pointer for calling out to Rust.+withRuntime :: Runtime -> (Ptr Runtime -> IO a) -> IO a+withRuntime (Runtime rvar) = withForeignPtr rvar+++{- | The Rust runtime exports logs to the Haskell runtime. This function fetches+those logs so they can be fed through a logging framework.+-}+fetchLogs :: Runtime -> IO (V.Vector CoreLog)+fetchLogs r = withRuntime r $ \p -> do+  bracket (raw_fetchLogs p) raw_freeLogs $ \clogs -> do+    logs <- peek clogs+    vec <- cArrayToVector cArrayToByteString logs+    V.mapM throwDecodeStrict vec
+ temporal-sdk-core.cabal view
@@ -0,0 +1,109 @@+cabal-version: 3.0++-- This file has been generated from package.yaml by hpack version 0.36.1.+--+-- see: https://github.com/sol/hpack++name:           temporal-sdk-core+version:        2025.10.1.0+description:    Temporal is a durable execution system that transparently makes your code durable, fault-tolerant, and simple. This is the core FFI bindings for the high-level Temporal SDK. Note that it requires Rust/Cargo to build.+category:       Concurrency+author:         Ian Duncan+maintainer:     temporal@mercury.com+license:        BSD-3-Clause+license-file:   LICENSE+build-type:     Custom+extra-source-files:+    rust/Cargo.toml+    rust/Cargo.lock+    rust/src/client.rs+    rust/src/ephemeral_server.rs+    rust/src/lib.rs+    rust/src/rpc.rs+    rust/src/runtime.rs+    rust/src/worker.rs+    rust/temporal_bridge.h++custom-setup+  setup-depends:+      Cabal >=3.0.0.0 && <3.15.0.0+    , base >=4.7 && <5+    , directory >=1.3.6.0+    , filepath >=1.3.0.2+    , unix++flag external_lib+  description: Use external library (don't compile automatically)+  manual: True+  default: False++library+  exposed-modules:+      Temporal.Core.Client+      Temporal.Core.Client.OperatorService+      Temporal.Core.Client.TestService+      Temporal.Core.Client.WorkflowService+      Temporal.Core.EphemeralServer+      Temporal.Core.Worker+      Temporal.Runtime+  other-modules:+      Temporal.Core.CTypes+      Temporal.Core.Client.HealthService+      Temporal.Internal.FFI+  hs-source-dirs:+      src+  default-extensions:+      BangPatterns+      BlockArguments+      DataKinds+      DerivingStrategies+      FlexibleContexts+      FlexibleInstances+      GADTs+      GeneralizedNewtypeDeriving+      InstanceSigs+      LambdaCase+      MultiParamTypeClasses+      NamedFieldPuns+      NumericUnderscores+      RankNTypes+      OverloadedRecordDot+      OverloadedStrings+      RecordWildCards+      ScopedTypeVariables+      StandaloneDeriving+      TypeApplications+      TypeFamilies+      TypeOperators+      UndecidableInstances+      ViewPatterns+  ghc-options: -g -Wall+  include-dirs:+      rust+  extra-libraries:+      temporal_bridge+  build-depends:+      aeson+    , async+    , base >=4.14 && <5+    , bytestring+    , containers+    , lens-family+    , monad-logger+    , mtl+    , network-bsd+    , proto-lens+    , stm+    , temporal-api-protos+    , text+    , unix+    , unliftio+    , unordered-containers+    , uuid+    , vector+  default-language: Haskell2010+  if os(darwin)+    frameworks:+        Security+        CoreFoundation+        SystemConfiguration