From 600c9264abc684cb9332879f1f74f718e3cb2a9e Mon Sep 17 00:00:00 2001 From: suirad Date: Thu, 24 Apr 2025 17:28:14 -0500 Subject: [PATCH] example c++ client --- cpp-client/client/.gitignore | 2 + cpp-client/client/Cargo.lock | 2024 +++++++++++++++++ cpp-client/client/Cargo.toml | 13 + cpp-client/client/README.md | 27 + cpp-client/client/client.cpp | 57 + cpp-client/client/justfile | 14 + cpp-client/client/src/lib.rs | 112 + .../client/src/module_bindings/add_reducer.rs | 101 + .../identity_connected_reducer.rs | 100 + .../identity_disconnected_reducer.rs | 102 + cpp-client/client/src/module_bindings/mod.rs | 726 ++++++ .../src/module_bindings/person_table.rs | 95 + .../client/src/module_bindings/person_type.rs | 15 + .../src/module_bindings/say_hello_reducer.rs | 99 + cpp-client/client/stdb.hpp | 1172 ++++++++++ cpp-client/server/.cargo/config.toml | 2 + cpp-client/server/.gitignore | 17 + cpp-client/server/Cargo.toml | 13 + cpp-client/server/src/lib.rs | 34 + 19 files changed, 4725 insertions(+) create mode 100644 cpp-client/client/.gitignore create mode 100644 cpp-client/client/Cargo.lock create mode 100644 cpp-client/client/Cargo.toml create mode 100644 cpp-client/client/README.md create mode 100644 cpp-client/client/client.cpp create mode 100644 cpp-client/client/justfile create mode 100644 cpp-client/client/src/lib.rs create mode 100644 cpp-client/client/src/module_bindings/add_reducer.rs create mode 100644 cpp-client/client/src/module_bindings/identity_connected_reducer.rs create mode 100644 cpp-client/client/src/module_bindings/identity_disconnected_reducer.rs create mode 100644 cpp-client/client/src/module_bindings/mod.rs create mode 100644 cpp-client/client/src/module_bindings/person_table.rs create mode 100644 cpp-client/client/src/module_bindings/person_type.rs create mode 100644 cpp-client/client/src/module_bindings/say_hello_reducer.rs create mode 100644 cpp-client/client/stdb.hpp create mode 100644 cpp-client/server/.cargo/config.toml create mode 100644 cpp-client/server/.gitignore create mode 100644 cpp-client/server/Cargo.toml create mode 100644 cpp-client/server/src/lib.rs diff --git a/cpp-client/client/.gitignore b/cpp-client/client/.gitignore new file mode 100644 index 0000000..a9980d8 --- /dev/null +++ b/cpp-client/client/.gitignore @@ -0,0 +1,2 @@ +target/ +client diff --git a/cpp-client/client/Cargo.lock b/cpp-client/client/Cargo.lock new file mode 100644 index 0000000..5e6c89f --- /dev/null +++ b/cpp-client/client/Cargo.lock @@ -0,0 +1,2024 @@ +# 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 = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom 0.2.16", + "once_cell", + "version_check", + "zerocopy 0.7.35", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[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 = "anymap" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344" + +[[package]] +name = "approx" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[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", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[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 = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[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 = "brotli" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "bytemuck" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "bytestring" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e465647ae23b2823b0753f50decb2d5a86d2bb2cac04788fafd1f80e45378e5f" +dependencies = [ + "bytes", + "serde", +] + +[[package]] +name = "cc" +version = "1.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + +[[package]] +name = "clap" +version = "4.5.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" +dependencies = [ + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "client" +version = "0.1.0" +dependencies = [ + "anyhow", + "cxx", + "spacetimedb-sdk", +] + +[[package]] +name = "codespan-reporting" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +dependencies = [ + "serde", + "termcolor", + "unicode-width", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +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 = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[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 = "cxx" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a71ea7f29c73f7ffa64c50b83c9fe4d3a6d4be89a86b009eb80d5a6d3429d741" +dependencies = [ + "cc", + "cxxbridge-cmd", + "cxxbridge-flags", + "cxxbridge-macro", + "foldhash", + "link-cplusplus", +] + +[[package]] +name = "cxxbridge-cmd" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f44296c8693e9ea226a48f6a122727f77aa9e9e338380cb021accaeeb7ee279" +dependencies = [ + "clap", + "codespan-reporting", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f69c181c176981ae44ba9876e2ea41ce8e574c296b38d06925ce9214fb8e4" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8faff5d4467e0709448187df29ccbf3b0982cc426ee444a193f87b11afb565a8" +dependencies = [ + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[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", +] + +[[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", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "decorum" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "281759d3c8a14f5c3f0c49363be56810fcd7f910422f97f2db850c2920fde5cf" +dependencies = [ + "approx", + "num-traits", +] + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[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 = "ethnum" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0939f82868b77ef93ce3c3c3daf2b3c526b456741da5a1a4559e590965b6026b" +dependencies = [ + "serde", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[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 = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[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", +] + +[[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-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", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "equivalent", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[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 = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "humantime" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[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", + "serde", +] + +[[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", + "serde", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[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 = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[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 = "link-cplusplus" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6f6da007f968f9def0d65a05b187e2960183de70c160204ecfccf0ee330212" +dependencies = [ + "cc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[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 = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[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 = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[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" +version = "0.10.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[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", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[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 = "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 0.8.24", +] + +[[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 = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" + +[[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.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[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", +] + +[[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 = "redox_syscall" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[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 = "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 = "second-stack" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4904c83c6e51f1b9b08bfa5a86f35a51798e8307186e6f5513852210a219c0bb" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +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 = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[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", +] + +[[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_with" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.9.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[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 = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[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 = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[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 = "spacetimedb-bindings-macro" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99d92f47ec82a929ef2b790c4e6a192929bb4b336447afbcff79d21f56a0c4" +dependencies = [ + "heck 0.4.1", + "humantime", + "proc-macro2", + "quote", + "spacetimedb-primitives", + "syn", +] + +[[package]] +name = "spacetimedb-client-api-messages" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e58198a00bba9b00c95431d7805a7cd3f026ca3fe759d0081579c6eb01743b" +dependencies = [ + "brotli", + "bytes", + "bytestring", + "chrono", + "derive_more", + "enum-as-inner", + "flate2", + "serde", + "serde_json", + "serde_with", + "smallvec", + "spacetimedb-lib", + "spacetimedb-primitives", + "spacetimedb-sats", + "strum", + "thiserror 1.0.69", +] + +[[package]] +name = "spacetimedb-data-structures" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2e73d36e70f961f10b337d8e1fc56a1b51520bf3dcfe19b9924c8ee157ed7a" +dependencies = [ + "ahash", + "hashbrown 0.15.2", + "nohash-hasher", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "spacetimedb-lib" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0daf9e273bff482f13df676f91670ce3eb22a980a0e8e000cb6be007df7f6f67" +dependencies = [ + "anyhow", + "bitflags", + "blake3", + "chrono", + "derive_more", + "enum-as-inner", + "hex", + "itertools", + "serde", + "spacetimedb-bindings-macro", + "spacetimedb-data-structures", + "spacetimedb-metrics", + "spacetimedb-primitives", + "spacetimedb-sats", + "thiserror 1.0.69", +] + +[[package]] +name = "spacetimedb-metrics" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3756d61c158aee43820540899e2e5acd6397bc4f9c8ca5678facddf161caabad" +dependencies = [ + "arrayvec", + "itertools", + "paste", + "prometheus", +] + +[[package]] +name = "spacetimedb-primitives" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e00f410fae725b19c85dee268bf75d498229e9fefa5dcc3595262a4eb48edf78" +dependencies = [ + "bitflags", + "either", + "itertools", + "nohash-hasher", +] + +[[package]] +name = "spacetimedb-sats" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bc6ace4942e4f477ddaef7e23204d8e8eed01e79119fb4e4f99d3eb3a462db3" +dependencies = [ + "anyhow", + "arrayvec", + "bitflags", + "bytemuck", + "bytes", + "bytestring", + "chrono", + "decorum", + "derive_more", + "enum-as-inner", + "ethnum", + "hex", + "itertools", + "second-stack", + "serde", + "sha3", + "smallvec", + "spacetimedb-bindings-macro", + "spacetimedb-metrics", + "spacetimedb-primitives", + "thiserror 1.0.69", +] + +[[package]] +name = "spacetimedb-sdk" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38a7ce9dbd42c366c6cec1a9361ab0eaf3bb5c9c1b634fc4f91820a3bf689245" +dependencies = [ + "anymap", + "base64 0.21.7", + "brotli", + "bytes", + "futures", + "futures-channel", + "home", + "http", + "log", + "once_cell", + "prometheus", + "rand", + "spacetimedb-client-api-messages", + "spacetimedb-data-structures", + "spacetimedb-lib", + "spacetimedb-metrics", + "spacetimedb-sats", + "thiserror 1.0.69", + "tokio", + "tokio-tungstenite", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[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 = "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 = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[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", +] + +[[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", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[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", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" +dependencies = [ + "futures-util", + "log", + "native-tls", + "tokio", + "tokio-native-tls", + "tungstenite", +] + +[[package]] +name = "tungstenite" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "native-tls", + "rand", + "sha1", + "thiserror 2.0.12", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[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", + "wasm-bindgen-shared", +] + +[[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", + "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 = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "windows-core" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[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.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +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", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[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_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[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_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[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_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[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 = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive 0.8.24", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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", +] diff --git a/cpp-client/client/Cargo.toml b/cpp-client/client/Cargo.toml new file mode 100644 index 0000000..2bd0d87 --- /dev/null +++ b/cpp-client/client/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "client" +version = "0.1.0" +edition = "2024" + +[lib] +name = "stdb_bridge" +crate-type = ["staticlib", "cdylib" ] + +[dependencies] +anyhow = "1.0.98" +cxx = "1.0.157" +spacetimedb-sdk = "1.1.1" diff --git a/cpp-client/client/README.md b/cpp-client/client/README.md new file mode 100644 index 0000000..1c586ef --- /dev/null +++ b/cpp-client/client/README.md @@ -0,0 +1,27 @@ +## STDB C++ Example client + +This project serves to demonstrate that it is possible to use rust <==> c++ bridge generation to quickly put together enough glue code between the two and enable a C++ client to be created and used from the rust client. + +### Notes: + +This project was make for linux however adjusting for other platforms shouldnt be too difficult. + +## Build Requirements + +* rust +* cxxbridge (`cargo install cxxbridge-cmd`) +* spacetime-cli +* openssl +* c++ compiler (g++ in this case) + +optional: + +* just (only if you want to run the build scripts directly, easily reproduced) + +## Usage + +The provided justfile has the following recipes: +* `generate` - Regenerates the rust client from the server using `spacetime generate` +* `build` - Builds the rust static library, re-generates the c++ header, builds the c++ client +* `run` - Builds and then runs the client + diff --git a/cpp-client/client/client.cpp b/cpp-client/client/client.cpp new file mode 100644 index 0000000..271fc69 --- /dev/null +++ b/cpp-client/client/client.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include + +#include "stdb.hpp" + +void on_applied() { + printf("Subscriptions completed \n"); +} + +void on_error(std::string& err) { + printf("Error Setting up subscriptions:\n%s\n", err.c_str()); + exit(1); +} + +int main () { + auto HOST = std::string("http://localhost:3000"); + auto DBNAME = std::string("test"); + + auto ctx = stdb::connect(HOST, DBNAME); + stdb::run_threaded(*ctx); + + std::vector subs = {"SELECT * FROM person"}; + stdb::subscribe(*ctx, subs, (std::size_t)reinterpret_cast(&on_applied), (std::size_t)reinterpret_cast(&on_error)); + + stdb::reducers::add(*ctx, std::string("Myname")); + stdb::reducers::say_hello(*ctx); + + auto counter = 0; + while (true) { + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + counter += 1; + + if (counter == 5) { + // print table + auto persons = stdb::tables::person::iter(*ctx); + if (persons.size() > 0) { + printf("Printing person table: %zu\n", persons.size()); + for (auto& p: persons) { + auto name = stdb::tables::person::name(p); + printf("-> %s\n", name.c_str()); + } + printf("Done Printing person table\n"); + + } else { + printf("Person table is empty\n"); + } + counter = 0; + } + } + + return 0; +} + diff --git a/cpp-client/client/justfile b/cpp-client/client/justfile new file mode 100644 index 0000000..8e6fc16 --- /dev/null +++ b/cpp-client/client/justfile @@ -0,0 +1,14 @@ +_default: + @just -l + +generate: + spacetime generate -o ./src/module_bindings/ -l rust -p ../server/ + +build: + @cargo build -r + @cxxbridge src/lib.rs > stdb.hpp + @g++ -Wall -Oz -o client client.cpp ./target/release/libstdb_bridge.a -lcrypto -lssl + +run: + @just build + ./client diff --git a/cpp-client/client/src/lib.rs b/cpp-client/client/src/lib.rs new file mode 100644 index 0000000..9c18982 --- /dev/null +++ b/cpp-client/client/src/lib.rs @@ -0,0 +1,112 @@ +mod module_bindings; + +use std::pin::Pin; + +use anyhow::{Error as AnyError, Result}; +use cxx::{let_cxx_string, CxxString, CxxVector}; +use module_bindings::{add, say_hello, PersonTableAccess}; +use spacetimedb_sdk::{DbContext, Table}; + +use crate::module_bindings::{DbConnection, Person}; + +#[cxx::bridge(namespace = "stdb")] +mod ffi { + + extern "Rust" { + type DbConnection; + fn connect(uri: &CxxString, db: &CxxString) -> Result>; + fn run_threaded(ctx: &DbConnection); + + // subscriptions + fn subscribe( + ctx: &DbConnection, + subs: &CxxVector, + on_applied_ptr: usize, + on_err_ptr: usize, + ); + fn subscribe_to_all(ctx: &DbConnection); + + // reducers + #[namespace = "stdb::reducers"] + fn say_hello(ctx: &DbConnection) -> Result<()>; + #[namespace = "stdb::reducers"] + fn add(ctx: &DbConnection, name: &CxxString) -> Result<()>; + + // tables + #[namespace = "stdb::tables"] + type Person; + #[namespace = "stdb::tables::person"] + #[rust_name = "person_name"] + fn name(p: &Person) -> String; + + #[namespace = "stdb::tables::person"] + #[rust_name = "person_iter"] + fn iter(ctx: &DbConnection) -> Vec; + } +} + +// Common stuff +fn connect(host_uri: &CxxString, db_name: &CxxString) -> Result> { + let uri = host_uri.to_string(); + let name = db_name.to_string(); + + Ok(Box::new( + DbConnection::builder() + .with_module_name(name) + .with_uri(uri) + .build()?, + )) +} + +fn run_threaded(ctx: &DbConnection) { + ctx.run_threaded(); +} + +fn subscribe( + ctx: &DbConnection, + subs: &CxxVector, + on_applied_ptr: usize, + on_err_ptr: usize, +) { + let rsubs: Vec = subs.iter().map(|s| s.to_string()).collect(); + ctx.subscription_builder() + .on_applied(move |_| { + if on_applied_ptr != 0 { + let func: fn() = unsafe { std::mem::transmute(on_applied_ptr) }; + + func(); + } + }) + .on_error(move |_, e| { + if on_err_ptr != 0 { + let func: fn(Pin<&mut CxxString>) = unsafe { std::mem::transmute(on_err_ptr) }; + + let_cxx_string!(err = e.to_string()); + func(err); + } + }) + .subscribe(rsubs); +} + +fn subscribe_to_all(ctx: &DbConnection) { + ctx.subscription_builder().subscribe_to_all_tables(); +} + +// reducers +fn say_hello(ctx: &DbConnection) -> Result<()> { + ctx.reducers.say_hello().map_err(AnyError::from) +} + +fn add(ctx: &DbConnection, name: &CxxString) -> Result<()> { + ctx.reducers.add(name.to_string()).map_err(AnyError::from) +} + +// tables + +fn person_name(p: &Person) -> String { + p.name.clone() +} + +fn person_iter(ctx: &DbConnection) -> Vec { + ctx.db.person().iter().collect() +} diff --git a/cpp-client/client/src/module_bindings/add_reducer.rs b/cpp-client/client/src/module_bindings/add_reducer.rs new file mode 100644 index 0000000..3b2af76 --- /dev/null +++ b/cpp-client/client/src/module_bindings/add_reducer.rs @@ -0,0 +1,101 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct AddArgs { + pub name: String, +} + +impl From for super::Reducer { + fn from(args: AddArgs) -> Self { + Self::Add { name: args.name } + } +} + +impl __sdk::InModule for AddArgs { + type Module = super::RemoteModule; +} + +pub struct AddCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `add`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait add { + /// Request that the remote module invoke the reducer `add` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_add`] callbacks. + fn add(&self, name: String) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `add`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`AddCallbackId`] can be passed to [`Self::remove_on_add`] + /// to cancel the callback. + fn on_add( + &self, + callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, + ) -> AddCallbackId; + /// Cancel a callback previously registered by [`Self::on_add`], + /// causing it not to run in the future. + fn remove_on_add(&self, callback: AddCallbackId); +} + +impl add for super::RemoteReducers { + fn add(&self, name: String) -> __sdk::Result<()> { + self.imp.call_reducer("add", AddArgs { name }) + } + fn on_add( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, + ) -> AddCallbackId { + AddCallbackId(self.imp.on_reducer( + "add", + Box::new(move |ctx: &super::ReducerEventContext| { + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::Add { name }, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx, name) + }), + )) + } + fn remove_on_add(&self, callback: AddCallbackId) { + self.imp.remove_on_reducer("add", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `add`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_add { + /// Set the call-reducer flags for the reducer `add` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn add(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_add for super::SetReducerFlags { + fn add(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("add", flags); + } +} diff --git a/cpp-client/client/src/module_bindings/identity_connected_reducer.rs b/cpp-client/client/src/module_bindings/identity_connected_reducer.rs new file mode 100644 index 0000000..d674295 --- /dev/null +++ b/cpp-client/client/src/module_bindings/identity_connected_reducer.rs @@ -0,0 +1,100 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct IdentityConnectedArgs {} + +impl From for super::Reducer { + fn from(args: IdentityConnectedArgs) -> Self { + Self::IdentityConnected + } +} + +impl __sdk::InModule for IdentityConnectedArgs { + type Module = super::RemoteModule; +} + +pub struct IdentityConnectedCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `identity_connected`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait identity_connected { + /// Request that the remote module invoke the reducer `identity_connected` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_identity_connected`] callbacks. + fn identity_connected(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `identity_connected`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`IdentityConnectedCallbackId`] can be passed to [`Self::remove_on_identity_connected`] + /// to cancel the callback. + fn on_identity_connected( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityConnectedCallbackId; + /// Cancel a callback previously registered by [`Self::on_identity_connected`], + /// causing it not to run in the future. + fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId); +} + +impl identity_connected for super::RemoteReducers { + fn identity_connected(&self) -> __sdk::Result<()> { + self.imp + .call_reducer("identity_connected", IdentityConnectedArgs {}) + } + fn on_identity_connected( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityConnectedCallbackId { + IdentityConnectedCallbackId(self.imp.on_reducer( + "identity_connected", + Box::new(move |ctx: &super::ReducerEventContext| { + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::IdentityConnected {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId) { + self.imp.remove_on_reducer("identity_connected", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `identity_connected`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_identity_connected { + /// Set the call-reducer flags for the reducer `identity_connected` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn identity_connected(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_identity_connected for super::SetReducerFlags { + fn identity_connected(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("identity_connected", flags); + } +} diff --git a/cpp-client/client/src/module_bindings/identity_disconnected_reducer.rs b/cpp-client/client/src/module_bindings/identity_disconnected_reducer.rs new file mode 100644 index 0000000..cbd1cc1 --- /dev/null +++ b/cpp-client/client/src/module_bindings/identity_disconnected_reducer.rs @@ -0,0 +1,102 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct IdentityDisconnectedArgs {} + +impl From for super::Reducer { + fn from(args: IdentityDisconnectedArgs) -> Self { + Self::IdentityDisconnected + } +} + +impl __sdk::InModule for IdentityDisconnectedArgs { + type Module = super::RemoteModule; +} + +pub struct IdentityDisconnectedCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `identity_disconnected`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait identity_disconnected { + /// Request that the remote module invoke the reducer `identity_disconnected` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_identity_disconnected`] callbacks. + fn identity_disconnected(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `identity_disconnected`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`IdentityDisconnectedCallbackId`] can be passed to [`Self::remove_on_identity_disconnected`] + /// to cancel the callback. + fn on_identity_disconnected( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityDisconnectedCallbackId; + /// Cancel a callback previously registered by [`Self::on_identity_disconnected`], + /// causing it not to run in the future. + fn remove_on_identity_disconnected(&self, callback: IdentityDisconnectedCallbackId); +} + +impl identity_disconnected for super::RemoteReducers { + fn identity_disconnected(&self) -> __sdk::Result<()> { + self.imp + .call_reducer("identity_disconnected", IdentityDisconnectedArgs {}) + } + fn on_identity_disconnected( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityDisconnectedCallbackId { + IdentityDisconnectedCallbackId(self.imp.on_reducer( + "identity_disconnected", + Box::new(move |ctx: &super::ReducerEventContext| { + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::IdentityDisconnected {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_identity_disconnected(&self, callback: IdentityDisconnectedCallbackId) { + self.imp + .remove_on_reducer("identity_disconnected", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `identity_disconnected`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_identity_disconnected { + /// Set the call-reducer flags for the reducer `identity_disconnected` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn identity_disconnected(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_identity_disconnected for super::SetReducerFlags { + fn identity_disconnected(&self, flags: __ws::CallReducerFlags) { + self.imp + .set_call_reducer_flags("identity_disconnected", flags); + } +} diff --git a/cpp-client/client/src/module_bindings/mod.rs b/cpp-client/client/src/module_bindings/mod.rs new file mode 100644 index 0000000..dbfe6b4 --- /dev/null +++ b/cpp-client/client/src/module_bindings/mod.rs @@ -0,0 +1,726 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +pub mod add_reducer; +pub mod identity_connected_reducer; +pub mod identity_disconnected_reducer; +pub mod person_table; +pub mod person_type; +pub mod say_hello_reducer; + +pub use add_reducer::{add, set_flags_for_add, AddCallbackId}; +pub use identity_connected_reducer::{ + identity_connected, set_flags_for_identity_connected, IdentityConnectedCallbackId, +}; +pub use identity_disconnected_reducer::{ + identity_disconnected, set_flags_for_identity_disconnected, IdentityDisconnectedCallbackId, +}; +pub use person_table::*; +pub use person_type::Person; +pub use say_hello_reducer::{say_hello, set_flags_for_say_hello, SayHelloCallbackId}; + +#[derive(Clone, PartialEq, Debug)] + +/// One of the reducers defined by this module. +/// +/// Contained within a [`__sdk::ReducerEvent`] in [`EventContext`]s for reducer events +/// to indicate which reducer caused the event. + +pub enum Reducer { + Add { name: String }, + IdentityConnected, + IdentityDisconnected, + SayHello, +} + +impl __sdk::InModule for Reducer { + type Module = RemoteModule; +} + +impl __sdk::Reducer for Reducer { + fn reducer_name(&self) -> &'static str { + match self { + Reducer::Add { .. } => "add", + Reducer::IdentityConnected => "identity_connected", + Reducer::IdentityDisconnected => "identity_disconnected", + Reducer::SayHello => "say_hello", + } + } +} +impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { + type Error = __sdk::Error; + fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result { + match &value.reducer_name[..] { + "add" => { + Ok(__sdk::parse_reducer_args::("add", &value.args)?.into()) + } + "identity_connected" => Ok(__sdk::parse_reducer_args::< + identity_connected_reducer::IdentityConnectedArgs, + >("identity_connected", &value.args)? + .into()), + "identity_disconnected" => Ok(__sdk::parse_reducer_args::< + identity_disconnected_reducer::IdentityDisconnectedArgs, + >("identity_disconnected", &value.args)? + .into()), + "say_hello" => Ok( + __sdk::parse_reducer_args::( + "say_hello", + &value.args, + )? + .into(), + ), + unknown => { + Err( + __sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo") + .into(), + ) + } + } + } +} + +#[derive(Default)] +#[allow(non_snake_case)] +#[doc(hidden)] +pub struct DbUpdate { + person: __sdk::TableUpdate, +} + +impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { + type Error = __sdk::Error; + fn try_from(raw: __ws::DatabaseUpdate<__ws::BsatnFormat>) -> Result { + let mut db_update = DbUpdate::default(); + for table_update in raw.tables { + match &table_update.table_name[..] { + "person" => db_update.person = person_table::parse_table_update(table_update)?, + + unknown => { + return Err(__sdk::InternalError::unknown_name( + "table", + unknown, + "DatabaseUpdate", + ) + .into()); + } + } + } + Ok(db_update) + } +} + +impl __sdk::InModule for DbUpdate { + type Module = RemoteModule; +} + +impl __sdk::DbUpdate for DbUpdate { + fn apply_to_client_cache( + &self, + cache: &mut __sdk::ClientCache, + ) -> AppliedDiff<'_> { + let mut diff = AppliedDiff::default(); + + diff.person = cache.apply_diff_to_table::("person", &self.person); + + diff + } +} + +#[derive(Default)] +#[allow(non_snake_case)] +#[doc(hidden)] +pub struct AppliedDiff<'r> { + person: __sdk::TableAppliedDiff<'r, Person>, +} + +impl __sdk::InModule for AppliedDiff<'_> { + type Module = RemoteModule; +} + +impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { + fn invoke_row_callbacks( + &self, + event: &EventContext, + callbacks: &mut __sdk::DbCallbacks, + ) { + callbacks.invoke_table_row_callbacks::("person", &self.person, event); + } +} + +#[doc(hidden)] +pub struct RemoteModule; + +impl __sdk::InModule for RemoteModule { + type Module = Self; +} + +/// The `reducers` field of [`EventContext`] and [`DbConnection`], +/// with methods provided by extension traits for each reducer defined by the module. +pub struct RemoteReducers { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteReducers { + type Module = RemoteModule; +} + +#[doc(hidden)] +/// The `set_reducer_flags` field of [`DbConnection`], +/// with methods provided by extension traits for each reducer defined by the module. +/// Each method sets the flags for the reducer with the same name. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub struct SetReducerFlags { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for SetReducerFlags { + type Module = RemoteModule; +} + +/// The `db` field of [`EventContext`] and [`DbConnection`], +/// with methods provided by extension traits for each table defined by the module. +pub struct RemoteTables { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteTables { + type Module = RemoteModule; +} + +/// A connection to a remote module, including a materialized view of a subset of the database. +/// +/// Connect to a remote module by calling [`DbConnection::builder`] +/// and using the [`__sdk::DbConnectionBuilder`] builder-pattern constructor. +/// +/// You must explicitly advance the connection by calling any one of: +/// +/// - [`DbConnection::frame_tick`]. +/// - [`DbConnection::run_threaded`]. +/// - [`DbConnection::run_async`]. +/// - [`DbConnection::advance_one_message`]. +/// - [`DbConnection::advance_one_message_blocking`]. +/// - [`DbConnection::advance_one_message_async`]. +/// +/// Which of these methods you should call depends on the specific needs of your application, +/// but you must call one of them, or else the connection will never progress. +pub struct DbConnection { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + #[doc(hidden)] + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for DbConnection { + type Module = RemoteModule; +} + +impl __sdk::DbContext for DbConnection { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } +} + +impl DbConnection { + /// Builder-pattern constructor for a connection to a remote module. + /// + /// See [`__sdk::DbConnectionBuilder`] for required and optional configuration for the new connection. + pub fn builder() -> __sdk::DbConnectionBuilder { + __sdk::DbConnectionBuilder::new() + } + + /// If any WebSocket messages are waiting, process one of them. + /// + /// Returns `true` if a message was processed, or `false` if the queue is empty. + /// Callers should invoke this message in a loop until it returns `false` + /// or for as much time is available to process messages. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::frame_tick`] each frame + /// to fully exhaust the queue whenever time is available. + pub fn advance_one_message(&self) -> __sdk::Result { + self.imp.advance_one_message() + } + + /// Process one WebSocket message, potentially blocking the current thread until one is received. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::run_threaded`] to spawn a thread + /// which advances the connection automatically. + pub fn advance_one_message_blocking(&self) -> __sdk::Result<()> { + self.imp.advance_one_message_blocking() + } + + /// Process one WebSocket message, `await`ing until one is received. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::run_async`] to run an `async` loop + /// which advances the connection when polled. + pub async fn advance_one_message_async(&self) -> __sdk::Result<()> { + self.imp.advance_one_message_async().await + } + + /// Process all WebSocket messages waiting in the queue, + /// then return without `await`ing or blocking the current thread. + pub fn frame_tick(&self) -> __sdk::Result<()> { + self.imp.frame_tick() + } + + /// Spawn a thread which processes WebSocket messages as they are received. + pub fn run_threaded(&self) -> std::thread::JoinHandle<()> { + self.imp.run_threaded() + } + + /// Run an `async` loop which processes WebSocket messages when polled. + pub async fn run_async(&self) -> __sdk::Result<()> { + self.imp.run_async().await + } +} + +impl __sdk::DbConnection for DbConnection { + fn new(imp: __sdk::DbContextImpl) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +/// A handle on a subscribed query. +// TODO: Document this better after implementing the new subscription API. +#[derive(Clone)] +pub struct SubscriptionHandle { + imp: __sdk::SubscriptionHandleImpl, +} + +impl __sdk::InModule for SubscriptionHandle { + type Module = RemoteModule; +} + +impl __sdk::SubscriptionHandle for SubscriptionHandle { + fn new(imp: __sdk::SubscriptionHandleImpl) -> Self { + Self { imp } + } + + /// Returns true if this subscription has been terminated due to an unsubscribe call or an error. + fn is_ended(&self) -> bool { + self.imp.is_ended() + } + + /// Returns true if this subscription has been applied and has not yet been unsubscribed. + fn is_active(&self) -> bool { + self.imp.is_active() + } + + /// Unsubscribe from the query controlled by this `SubscriptionHandle`, + /// then run `on_end` when its rows are removed from the client cache. + fn unsubscribe_then(self, on_end: __sdk::OnEndedCallback) -> __sdk::Result<()> { + self.imp.unsubscribe_then(Some(on_end)) + } + + fn unsubscribe(self) -> __sdk::Result<()> { + self.imp.unsubscribe_then(None) + } +} + +/// Alias trait for a [`__sdk::DbContext`] connected to this module, +/// with that trait's associated types bounded to this module's concrete types. +/// +/// Users can use this trait as a boundary on definitions which should accept +/// either a [`DbConnection`] or an [`EventContext`] and operate on either. +pub trait RemoteDbContext: + __sdk::DbContext< + DbView = RemoteTables, + Reducers = RemoteReducers, + SetReducerFlags = SetReducerFlags, + SubscriptionBuilder = __sdk::SubscriptionBuilder, +> +{ +} +impl< + Ctx: __sdk::DbContext< + DbView = RemoteTables, + Reducers = RemoteReducers, + SetReducerFlags = SetReducerFlags, + SubscriptionBuilder = __sdk::SubscriptionBuilder, + >, + > RemoteDbContext for Ctx +{ +} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::Event`], +/// passed to [`__sdk::Table::on_insert`], [`__sdk::Table::on_delete`] and [`__sdk::TableWithPrimaryKey::on_update`] callbacks. +pub struct EventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// The event which caused these callbacks to run. + pub event: __sdk::Event, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for EventContext { + type Event = __sdk::Event; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for EventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for EventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } +} + +impl __sdk::EventContext for EventContext {} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::ReducerEvent`], +/// passed to on-reducer callbacks. +pub struct ReducerEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// The event which caused these callbacks to run. + pub event: __sdk::ReducerEvent, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ReducerEventContext { + type Event = __sdk::ReducerEvent; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for ReducerEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ReducerEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } +} + +impl __sdk::ReducerEventContext for ReducerEventContext {} + +/// An [`__sdk::DbContext`] passed to [`__sdk::SubscriptionBuilder::on_applied`] and [`SubscriptionHandle::unsubscribe_then`] callbacks. +pub struct SubscriptionEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for SubscriptionEventContext { + type Event = (); + fn event(&self) -> &Self::Event { + &() + } + fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +impl __sdk::InModule for SubscriptionEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for SubscriptionEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } +} + +impl __sdk::SubscriptionEventContext for SubscriptionEventContext {} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::Error`], +/// passed to [`__sdk::DbConnectionBuilder::on_disconnect`], [`__sdk::DbConnectionBuilder::on_connect_error`] and [`__sdk::SubscriptionBuilder::on_error`] callbacks. +pub struct ErrorContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// The event which caused these callbacks to run. + pub event: Option<__sdk::Error>, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ErrorContext { + type Event = Option<__sdk::Error>; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for ErrorContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ErrorContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } +} + +impl __sdk::ErrorContext for ErrorContext {} + +impl __sdk::SpacetimeModule for RemoteModule { + type DbConnection = DbConnection; + type EventContext = EventContext; + type ReducerEventContext = ReducerEventContext; + type SubscriptionEventContext = SubscriptionEventContext; + type ErrorContext = ErrorContext; + type Reducer = Reducer; + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type SetReducerFlags = SetReducerFlags; + type DbUpdate = DbUpdate; + type AppliedDiff<'r> = AppliedDiff<'r>; + type SubscriptionHandle = SubscriptionHandle; + + fn register_tables(client_cache: &mut __sdk::ClientCache) { + person_table::register_table(client_cache); + } +} diff --git a/cpp-client/client/src/module_bindings/person_table.rs b/cpp-client/client/src/module_bindings/person_table.rs new file mode 100644 index 0000000..da3f64b --- /dev/null +++ b/cpp-client/client/src/module_bindings/person_table.rs @@ -0,0 +1,95 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use super::person_type::Person; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `person`. +/// +/// Obtain a handle from the [`PersonTableAccess::person`] method on [`super::RemoteTables`], +/// like `ctx.db.person()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.person().on_insert(...)`. +pub struct PersonTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `person`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait PersonTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`PersonTableHandle`], which mediates access to the table `person`. + fn person(&self) -> PersonTableHandle<'_>; +} + +impl PersonTableAccess for super::RemoteTables { + fn person(&self) -> PersonTableHandle<'_> { + PersonTableHandle { + imp: self.imp.get_table::("person"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct PersonInsertCallbackId(__sdk::CallbackId); +pub struct PersonDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for PersonTableHandle<'ctx> { + type Row = Person; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = PersonInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PersonInsertCallbackId { + PersonInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: PersonInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = PersonDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PersonDeleteCallbackId { + PersonDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: PersonDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("person"); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} diff --git a/cpp-client/client/src/module_bindings/person_type.rs b/cpp-client/client/src/module_bindings/person_type.rs new file mode 100644 index 0000000..56436ae --- /dev/null +++ b/cpp-client/client/src/module_bindings/person_type.rs @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct Person { + pub name: String, +} + +impl __sdk::InModule for Person { + type Module = super::RemoteModule; +} diff --git a/cpp-client/client/src/module_bindings/say_hello_reducer.rs b/cpp-client/client/src/module_bindings/say_hello_reducer.rs new file mode 100644 index 0000000..27758d0 --- /dev/null +++ b/cpp-client/client/src/module_bindings/say_hello_reducer.rs @@ -0,0 +1,99 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct SayHelloArgs {} + +impl From for super::Reducer { + fn from(args: SayHelloArgs) -> Self { + Self::SayHello + } +} + +impl __sdk::InModule for SayHelloArgs { + type Module = super::RemoteModule; +} + +pub struct SayHelloCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `say_hello`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait say_hello { + /// Request that the remote module invoke the reducer `say_hello` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_say_hello`] callbacks. + fn say_hello(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `say_hello`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`SayHelloCallbackId`] can be passed to [`Self::remove_on_say_hello`] + /// to cancel the callback. + fn on_say_hello( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> SayHelloCallbackId; + /// Cancel a callback previously registered by [`Self::on_say_hello`], + /// causing it not to run in the future. + fn remove_on_say_hello(&self, callback: SayHelloCallbackId); +} + +impl say_hello for super::RemoteReducers { + fn say_hello(&self) -> __sdk::Result<()> { + self.imp.call_reducer("say_hello", SayHelloArgs {}) + } + fn on_say_hello( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> SayHelloCallbackId { + SayHelloCallbackId(self.imp.on_reducer( + "say_hello", + Box::new(move |ctx: &super::ReducerEventContext| { + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::SayHello {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_say_hello(&self, callback: SayHelloCallbackId) { + self.imp.remove_on_reducer("say_hello", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `say_hello`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_say_hello { + /// Set the call-reducer flags for the reducer `say_hello` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn say_hello(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_say_hello for super::SetReducerFlags { + fn say_hello(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("say_hello", flags); + } +} diff --git a/cpp-client/client/stdb.hpp b/cpp-client/client/stdb.hpp new file mode 100644 index 0000000..f1a39ec --- /dev/null +++ b/cpp-client/client/stdb.hpp @@ -0,0 +1,1172 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if __cplusplus >= 202002L +#include +#endif + +namespace rust { +inline namespace cxxbridge1 { +// #include "rust/cxx.h" + +#ifndef CXXBRIDGE1_PANIC +#define CXXBRIDGE1_PANIC +template +void panic [[noreturn]] (const char *msg); +#endif // CXXBRIDGE1_PANIC + +struct unsafe_bitcopy_t; + +namespace { +template +class impl; +} // namespace + +template +::std::size_t size_of(); +template +::std::size_t align_of(); + +#ifndef CXXBRIDGE1_RUST_STRING +#define CXXBRIDGE1_RUST_STRING +class String final { +public: + String() noexcept; + String(const String &) noexcept; + String(String &&) noexcept; + ~String() noexcept; + + String(const std::string &); + String(const char *); + String(const char *, std::size_t); + String(const char16_t *); + String(const char16_t *, std::size_t); +#ifdef __cpp_char8_t + String(const char8_t *s); + String(const char8_t *s, std::size_t len); +#endif + + static String lossy(const std::string &) noexcept; + static String lossy(const char *) noexcept; + static String lossy(const char *, std::size_t) noexcept; + static String lossy(const char16_t *) noexcept; + static String lossy(const char16_t *, std::size_t) noexcept; + + String &operator=(const String &) & noexcept; + String &operator=(String &&) & noexcept; + + explicit operator std::string() const; + + const char *data() const noexcept; + std::size_t size() const noexcept; + std::size_t length() const noexcept; + bool empty() const noexcept; + + const char *c_str() noexcept; + + std::size_t capacity() const noexcept; + void reserve(size_t new_cap) noexcept; + + using iterator = char *; + iterator begin() noexcept; + iterator end() noexcept; + + using const_iterator = const char *; + const_iterator begin() const noexcept; + const_iterator end() const noexcept; + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + + bool operator==(const String &) const noexcept; + bool operator!=(const String &) const noexcept; + bool operator<(const String &) const noexcept; + bool operator<=(const String &) const noexcept; + bool operator>(const String &) const noexcept; + bool operator>=(const String &) const noexcept; + + void swap(String &) noexcept; + + String(unsafe_bitcopy_t, const String &) noexcept; + +private: + struct lossy_t; + String(lossy_t, const char *, std::size_t) noexcept; + String(lossy_t, const char16_t *, std::size_t) noexcept; + friend void swap(String &lhs, String &rhs) noexcept { lhs.swap(rhs); } + + std::array repr; +}; +#endif // CXXBRIDGE1_RUST_STRING + +#ifndef CXXBRIDGE1_RUST_SLICE +#define CXXBRIDGE1_RUST_SLICE +namespace detail { +template +struct copy_assignable_if {}; + +template <> +struct copy_assignable_if { + copy_assignable_if() noexcept = default; + copy_assignable_if(const copy_assignable_if &) noexcept = default; + copy_assignable_if &operator=(const copy_assignable_if &) & noexcept = delete; + copy_assignable_if &operator=(copy_assignable_if &&) & noexcept = default; +}; +} // namespace detail + +template +class Slice final + : private detail::copy_assignable_if::value> { +public: + using value_type = T; + + Slice() noexcept; + Slice(T *, std::size_t count) noexcept; + + template + explicit Slice(C &c) : Slice(c.data(), c.size()) {} + + Slice &operator=(const Slice &) & noexcept = default; + Slice &operator=(Slice &&) & noexcept = default; + + T *data() const noexcept; + std::size_t size() const noexcept; + std::size_t length() const noexcept; + bool empty() const noexcept; + + T &operator[](std::size_t n) const noexcept; + T &at(std::size_t n) const; + T &front() const noexcept; + T &back() const noexcept; + + Slice(const Slice &) noexcept = default; + ~Slice() noexcept = default; + + class iterator; + iterator begin() const noexcept; + iterator end() const noexcept; + + void swap(Slice &) noexcept; + +private: + class uninit; + Slice(uninit) noexcept; + friend impl; + friend void sliceInit(void *, const void *, std::size_t) noexcept; + friend void *slicePtr(const void *) noexcept; + friend std::size_t sliceLen(const void *) noexcept; + + std::array repr; +}; + +#ifdef __cpp_deduction_guides +template +explicit Slice(C &c) + -> Slice().data())>>; +#endif // __cpp_deduction_guides + +template +class Slice::iterator final { +public: +#if __cplusplus >= 202002L + using iterator_category = std::contiguous_iterator_tag; +#else + using iterator_category = std::random_access_iterator_tag; +#endif + using value_type = T; + using difference_type = std::ptrdiff_t; + using pointer = typename std::add_pointer::type; + using reference = typename std::add_lvalue_reference::type; + + reference operator*() const noexcept; + pointer operator->() const noexcept; + reference operator[](difference_type) const noexcept; + + iterator &operator++() noexcept; + iterator operator++(int) noexcept; + iterator &operator--() noexcept; + iterator operator--(int) noexcept; + + iterator &operator+=(difference_type) noexcept; + iterator &operator-=(difference_type) noexcept; + iterator operator+(difference_type) const noexcept; + friend inline iterator operator+(difference_type lhs, iterator rhs) noexcept { + return rhs + lhs; + } + iterator operator-(difference_type) const noexcept; + difference_type operator-(const iterator &) const noexcept; + + bool operator==(const iterator &) const noexcept; + bool operator!=(const iterator &) const noexcept; + bool operator<(const iterator &) const noexcept; + bool operator<=(const iterator &) const noexcept; + bool operator>(const iterator &) const noexcept; + bool operator>=(const iterator &) const noexcept; + +private: + friend class Slice; + void *pos; + std::size_t stride; +}; + +#if __cplusplus >= 202002L +static_assert(std::ranges::contiguous_range>); +static_assert(std::contiguous_iterator::iterator>); +#endif + +template +Slice::Slice() noexcept { + sliceInit(this, reinterpret_cast(align_of()), 0); +} + +template +Slice::Slice(T *s, std::size_t count) noexcept { + assert(s != nullptr || count == 0); + sliceInit(this, + s == nullptr && count == 0 + ? reinterpret_cast(align_of()) + : const_cast::type *>(s), + count); +} + +template +T *Slice::data() const noexcept { + return reinterpret_cast(slicePtr(this)); +} + +template +std::size_t Slice::size() const noexcept { + return sliceLen(this); +} + +template +std::size_t Slice::length() const noexcept { + return this->size(); +} + +template +bool Slice::empty() const noexcept { + return this->size() == 0; +} + +template +T &Slice::operator[](std::size_t n) const noexcept { + assert(n < this->size()); + auto ptr = static_cast(slicePtr(this)) + size_of() * n; + return *reinterpret_cast(ptr); +} + +template +T &Slice::at(std::size_t n) const { + if (n >= this->size()) { + panic("rust::Slice index out of range"); + } + return (*this)[n]; +} + +template +T &Slice::front() const noexcept { + assert(!this->empty()); + return (*this)[0]; +} + +template +T &Slice::back() const noexcept { + assert(!this->empty()); + return (*this)[this->size() - 1]; +} + +template +typename Slice::iterator::reference +Slice::iterator::operator*() const noexcept { + return *static_cast(this->pos); +} + +template +typename Slice::iterator::pointer +Slice::iterator::operator->() const noexcept { + return static_cast(this->pos); +} + +template +typename Slice::iterator::reference Slice::iterator::operator[]( + typename Slice::iterator::difference_type n) const noexcept { + auto ptr = static_cast(this->pos) + this->stride * n; + return *reinterpret_cast(ptr); +} + +template +typename Slice::iterator &Slice::iterator::operator++() noexcept { + this->pos = static_cast(this->pos) + this->stride; + return *this; +} + +template +typename Slice::iterator Slice::iterator::operator++(int) noexcept { + auto ret = iterator(*this); + this->pos = static_cast(this->pos) + this->stride; + return ret; +} + +template +typename Slice::iterator &Slice::iterator::operator--() noexcept { + this->pos = static_cast(this->pos) - this->stride; + return *this; +} + +template +typename Slice::iterator Slice::iterator::operator--(int) noexcept { + auto ret = iterator(*this); + this->pos = static_cast(this->pos) - this->stride; + return ret; +} + +template +typename Slice::iterator &Slice::iterator::operator+=( + typename Slice::iterator::difference_type n) noexcept { + this->pos = static_cast(this->pos) + this->stride * n; + return *this; +} + +template +typename Slice::iterator &Slice::iterator::operator-=( + typename Slice::iterator::difference_type n) noexcept { + this->pos = static_cast(this->pos) - this->stride * n; + return *this; +} + +template +typename Slice::iterator Slice::iterator::operator+( + typename Slice::iterator::difference_type n) const noexcept { + auto ret = iterator(*this); + ret.pos = static_cast(this->pos) + this->stride * n; + return ret; +} + +template +typename Slice::iterator Slice::iterator::operator-( + typename Slice::iterator::difference_type n) const noexcept { + auto ret = iterator(*this); + ret.pos = static_cast(this->pos) - this->stride * n; + return ret; +} + +template +typename Slice::iterator::difference_type +Slice::iterator::operator-(const iterator &other) const noexcept { + auto diff = std::distance(static_cast(other.pos), + static_cast(this->pos)); + return diff / static_cast::iterator::difference_type>( + this->stride); +} + +template +bool Slice::iterator::operator==(const iterator &other) const noexcept { + return this->pos == other.pos; +} + +template +bool Slice::iterator::operator!=(const iterator &other) const noexcept { + return this->pos != other.pos; +} + +template +bool Slice::iterator::operator<(const iterator &other) const noexcept { + return this->pos < other.pos; +} + +template +bool Slice::iterator::operator<=(const iterator &other) const noexcept { + return this->pos <= other.pos; +} + +template +bool Slice::iterator::operator>(const iterator &other) const noexcept { + return this->pos > other.pos; +} + +template +bool Slice::iterator::operator>=(const iterator &other) const noexcept { + return this->pos >= other.pos; +} + +template +typename Slice::iterator Slice::begin() const noexcept { + iterator it; + it.pos = slicePtr(this); + it.stride = size_of(); + return it; +} + +template +typename Slice::iterator Slice::end() const noexcept { + iterator it = this->begin(); + it.pos = static_cast(it.pos) + it.stride * this->size(); + return it; +} + +template +void Slice::swap(Slice &rhs) noexcept { + std::swap(*this, rhs); +} +#endif // CXXBRIDGE1_RUST_SLICE + +#ifndef CXXBRIDGE1_RUST_BOX +#define CXXBRIDGE1_RUST_BOX +template +class Box final { +public: + using element_type = T; + using const_pointer = + typename std::add_pointer::type>::type; + using pointer = typename std::add_pointer::type; + + Box() = delete; + Box(Box &&) noexcept; + ~Box() noexcept; + + explicit Box(const T &); + explicit Box(T &&); + + Box &operator=(Box &&) & noexcept; + + const T *operator->() const noexcept; + const T &operator*() const noexcept; + T *operator->() noexcept; + T &operator*() noexcept; + + template + static Box in_place(Fields &&...); + + void swap(Box &) noexcept; + + static Box from_raw(T *) noexcept; + + T *into_raw() noexcept; + + /* Deprecated */ using value_type = element_type; + +private: + class uninit; + class allocation; + Box(uninit) noexcept; + void drop() noexcept; + + friend void swap(Box &lhs, Box &rhs) noexcept { lhs.swap(rhs); } + + T *ptr; +}; + +template +class Box::uninit {}; + +template +class Box::allocation { + static T *alloc() noexcept; + static void dealloc(T *) noexcept; + +public: + allocation() noexcept : ptr(alloc()) {} + ~allocation() noexcept { + if (this->ptr) { + dealloc(this->ptr); + } + } + T *ptr; +}; + +template +Box::Box(Box &&other) noexcept : ptr(other.ptr) { + other.ptr = nullptr; +} + +template +Box::Box(const T &val) { + allocation alloc; + ::new (alloc.ptr) T(val); + this->ptr = alloc.ptr; + alloc.ptr = nullptr; +} + +template +Box::Box(T &&val) { + allocation alloc; + ::new (alloc.ptr) T(std::move(val)); + this->ptr = alloc.ptr; + alloc.ptr = nullptr; +} + +template +Box::~Box() noexcept { + if (this->ptr) { + this->drop(); + } +} + +template +Box &Box::operator=(Box &&other) & noexcept { + if (this->ptr) { + this->drop(); + } + this->ptr = other.ptr; + other.ptr = nullptr; + return *this; +} + +template +const T *Box::operator->() const noexcept { + return this->ptr; +} + +template +const T &Box::operator*() const noexcept { + return *this->ptr; +} + +template +T *Box::operator->() noexcept { + return this->ptr; +} + +template +T &Box::operator*() noexcept { + return *this->ptr; +} + +template +template +Box Box::in_place(Fields &&...fields) { + allocation alloc; + auto ptr = alloc.ptr; + ::new (ptr) T{std::forward(fields)...}; + alloc.ptr = nullptr; + return from_raw(ptr); +} + +template +void Box::swap(Box &rhs) noexcept { + using std::swap; + swap(this->ptr, rhs.ptr); +} + +template +Box Box::from_raw(T *raw) noexcept { + Box box = uninit{}; + box.ptr = raw; + return box; +} + +template +T *Box::into_raw() noexcept { + T *raw = this->ptr; + this->ptr = nullptr; + return raw; +} + +template +Box::Box(uninit) noexcept {} +#endif // CXXBRIDGE1_RUST_BOX + +#ifndef CXXBRIDGE1_RUST_BITCOPY_T +#define CXXBRIDGE1_RUST_BITCOPY_T +struct unsafe_bitcopy_t final { + explicit unsafe_bitcopy_t() = default; +}; +#endif // CXXBRIDGE1_RUST_BITCOPY_T + +#ifndef CXXBRIDGE1_RUST_VEC +#define CXXBRIDGE1_RUST_VEC +template +class Vec final { +public: + using value_type = T; + + Vec() noexcept; + Vec(std::initializer_list); + Vec(const Vec &); + Vec(Vec &&) noexcept; + ~Vec() noexcept; + + Vec &operator=(Vec &&) & noexcept; + Vec &operator=(const Vec &) &; + + std::size_t size() const noexcept; + bool empty() const noexcept; + const T *data() const noexcept; + T *data() noexcept; + std::size_t capacity() const noexcept; + + const T &operator[](std::size_t n) const noexcept; + const T &at(std::size_t n) const; + const T &front() const noexcept; + const T &back() const noexcept; + + T &operator[](std::size_t n) noexcept; + T &at(std::size_t n); + T &front() noexcept; + T &back() noexcept; + + void reserve(std::size_t new_cap); + void push_back(const T &value); + void push_back(T &&value); + template + void emplace_back(Args &&...args); + void truncate(std::size_t len); + void clear(); + + using iterator = typename Slice::iterator; + iterator begin() noexcept; + iterator end() noexcept; + + using const_iterator = typename Slice::iterator; + const_iterator begin() const noexcept; + const_iterator end() const noexcept; + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + + void swap(Vec &) noexcept; + + Vec(unsafe_bitcopy_t, const Vec &) noexcept; + +private: + void reserve_total(std::size_t new_cap) noexcept; + void set_len(std::size_t len) noexcept; + void drop() noexcept; + + friend void swap(Vec &lhs, Vec &rhs) noexcept { lhs.swap(rhs); } + + std::array repr; +}; + +template +Vec::Vec(std::initializer_list init) : Vec{} { + this->reserve_total(init.size()); + std::move(init.begin(), init.end(), std::back_inserter(*this)); +} + +template +Vec::Vec(const Vec &other) : Vec() { + this->reserve_total(other.size()); + std::copy(other.begin(), other.end(), std::back_inserter(*this)); +} + +template +Vec::Vec(Vec &&other) noexcept : repr(other.repr) { + new (&other) Vec(); +} + +template +Vec::~Vec() noexcept { + this->drop(); +} + +template +Vec &Vec::operator=(Vec &&other) & noexcept { + this->drop(); + this->repr = other.repr; + new (&other) Vec(); + return *this; +} + +template +Vec &Vec::operator=(const Vec &other) & { + if (this != &other) { + this->drop(); + new (this) Vec(other); + } + return *this; +} + +template +bool Vec::empty() const noexcept { + return this->size() == 0; +} + +template +T *Vec::data() noexcept { + return const_cast(const_cast *>(this)->data()); +} + +template +const T &Vec::operator[](std::size_t n) const noexcept { + assert(n < this->size()); + auto data = reinterpret_cast(this->data()); + return *reinterpret_cast(data + n * size_of()); +} + +template +const T &Vec::at(std::size_t n) const { + if (n >= this->size()) { + panic("rust::Vec index out of range"); + } + return (*this)[n]; +} + +template +const T &Vec::front() const noexcept { + assert(!this->empty()); + return (*this)[0]; +} + +template +const T &Vec::back() const noexcept { + assert(!this->empty()); + return (*this)[this->size() - 1]; +} + +template +T &Vec::operator[](std::size_t n) noexcept { + assert(n < this->size()); + auto data = reinterpret_cast(this->data()); + return *reinterpret_cast(data + n * size_of()); +} + +template +T &Vec::at(std::size_t n) { + if (n >= this->size()) { + panic("rust::Vec index out of range"); + } + return (*this)[n]; +} + +template +T &Vec::front() noexcept { + assert(!this->empty()); + return (*this)[0]; +} + +template +T &Vec::back() noexcept { + assert(!this->empty()); + return (*this)[this->size() - 1]; +} + +template +void Vec::reserve(std::size_t new_cap) { + this->reserve_total(new_cap); +} + +template +void Vec::push_back(const T &value) { + this->emplace_back(value); +} + +template +void Vec::push_back(T &&value) { + this->emplace_back(std::move(value)); +} + +template +template +void Vec::emplace_back(Args &&...args) { + auto size = this->size(); + this->reserve_total(size + 1); + ::new (reinterpret_cast(reinterpret_cast(this->data()) + + size * size_of())) + T(std::forward(args)...); + this->set_len(size + 1); +} + +template +void Vec::clear() { + this->truncate(0); +} + +template +typename Vec::iterator Vec::begin() noexcept { + return Slice(this->data(), this->size()).begin(); +} + +template +typename Vec::iterator Vec::end() noexcept { + return Slice(this->data(), this->size()).end(); +} + +template +typename Vec::const_iterator Vec::begin() const noexcept { + return this->cbegin(); +} + +template +typename Vec::const_iterator Vec::end() const noexcept { + return this->cend(); +} + +template +typename Vec::const_iterator Vec::cbegin() const noexcept { + return Slice(this->data(), this->size()).begin(); +} + +template +typename Vec::const_iterator Vec::cend() const noexcept { + return Slice(this->data(), this->size()).end(); +} + +template +void Vec::swap(Vec &rhs) noexcept { + using std::swap; + swap(this->repr, rhs.repr); +} + +template +Vec::Vec(unsafe_bitcopy_t, const Vec &bits) noexcept : repr(bits.repr) {} +#endif // CXXBRIDGE1_RUST_VEC + +#ifndef CXXBRIDGE1_RUST_ERROR +#define CXXBRIDGE1_RUST_ERROR +class Error final : public std::exception { +public: + Error(const Error &); + Error(Error &&) noexcept; + ~Error() noexcept override; + + Error &operator=(const Error &) &; + Error &operator=(Error &&) & noexcept; + + const char *what() const noexcept override; + +private: + Error() noexcept = default; + friend impl; + const char *msg; + std::size_t len; +}; +#endif // CXXBRIDGE1_RUST_ERROR + +#ifndef CXXBRIDGE1_RUST_OPAQUE +#define CXXBRIDGE1_RUST_OPAQUE +class Opaque { +public: + Opaque() = delete; + Opaque(const Opaque &) = delete; + ~Opaque() = delete; +}; +#endif // CXXBRIDGE1_RUST_OPAQUE + +#ifndef CXXBRIDGE1_IS_COMPLETE +#define CXXBRIDGE1_IS_COMPLETE +namespace detail { +namespace { +template +struct is_complete : std::false_type {}; +template +struct is_complete : std::true_type {}; +} // namespace +} // namespace detail +#endif // CXXBRIDGE1_IS_COMPLETE + +#ifndef CXXBRIDGE1_LAYOUT +#define CXXBRIDGE1_LAYOUT +class layout { + template + friend std::size_t size_of(); + template + friend std::size_t align_of(); + template + static typename std::enable_if::value, + std::size_t>::type + do_size_of() { + return T::layout::size(); + } + template + static typename std::enable_if::value, + std::size_t>::type + do_size_of() { + return sizeof(T); + } + template + static + typename std::enable_if::value, std::size_t>::type + size_of() { + return do_size_of(); + } + template + static typename std::enable_if::value, + std::size_t>::type + do_align_of() { + return T::layout::align(); + } + template + static typename std::enable_if::value, + std::size_t>::type + do_align_of() { + return alignof(T); + } + template + static + typename std::enable_if::value, std::size_t>::type + align_of() { + return do_align_of(); + } +}; + +template +std::size_t size_of() { + return layout::size_of(); +} + +template +std::size_t align_of() { + return layout::align_of(); +} +#endif // CXXBRIDGE1_LAYOUT + +namespace repr { +struct PtrLen final { + void *ptr; + ::std::size_t len; +}; +} // namespace repr + +namespace detail { +template +struct operator_new { + void *operator()(::std::size_t sz) { return ::operator new(sz); } +}; + +template +struct operator_new { + void *operator()(::std::size_t sz) { return T::operator new(sz); } +}; +} // namespace detail + +template +union MaybeUninit { + T value; + void *operator new(::std::size_t sz) { return detail::operator_new{}(sz); } + MaybeUninit() {} + ~MaybeUninit() {} +}; + +namespace { +template <> +class impl final { +public: + static Error error(repr::PtrLen repr) noexcept { + Error error; + error.msg = static_cast(repr.ptr); + error.len = repr.len; + return error; + } +}; +} // namespace +} // namespace cxxbridge1 +} // namespace rust + +namespace stdb { + struct DbConnection; + namespace tables { + struct Person; + } +} + +namespace stdb { +#ifndef CXXBRIDGE1_STRUCT_stdb$DbConnection +#define CXXBRIDGE1_STRUCT_stdb$DbConnection +struct DbConnection final : public ::rust::Opaque { + ~DbConnection() = delete; + +private: + friend ::rust::layout; + struct layout { + static ::std::size_t size() noexcept; + static ::std::size_t align() noexcept; + }; +}; +#endif // CXXBRIDGE1_STRUCT_stdb$DbConnection + +namespace tables { +#ifndef CXXBRIDGE1_STRUCT_stdb$tables$Person +#define CXXBRIDGE1_STRUCT_stdb$tables$Person +struct Person final : public ::rust::Opaque { + ~Person() = delete; + +private: + friend ::rust::layout; + struct layout { + static ::std::size_t size() noexcept; + static ::std::size_t align() noexcept; + }; +}; +#endif // CXXBRIDGE1_STRUCT_stdb$tables$Person +} // namespace tables + +extern "C" { +::std::size_t stdb$cxxbridge1$DbConnection$operator$sizeof() noexcept; +::std::size_t stdb$cxxbridge1$DbConnection$operator$alignof() noexcept; + +::rust::repr::PtrLen stdb$cxxbridge1$connect(::std::string const &uri, ::std::string const &db, ::rust::Box<::stdb::DbConnection> *return$) noexcept; + +void stdb$cxxbridge1$run_threaded(::stdb::DbConnection const &ctx) noexcept; + +void stdb$cxxbridge1$subscribe(::stdb::DbConnection const &ctx, ::std::vector<::std::string> const &subs, ::std::size_t on_applied_ptr, ::std::size_t on_err_ptr) noexcept; + +void stdb$cxxbridge1$subscribe_to_all(::stdb::DbConnection const &ctx) noexcept; +} // extern "C" + +namespace reducers { +extern "C" { +::rust::repr::PtrLen stdb$reducers$cxxbridge1$say_hello(::stdb::DbConnection const &ctx) noexcept; + +::rust::repr::PtrLen stdb$reducers$cxxbridge1$add(::stdb::DbConnection const &ctx, ::std::string const &name) noexcept; +} // extern "C" +} // namespace reducers + +namespace tables { +extern "C" { +::std::size_t stdb$tables$cxxbridge1$Person$operator$sizeof() noexcept; +::std::size_t stdb$tables$cxxbridge1$Person$operator$alignof() noexcept; +} // extern "C" + +namespace person { +extern "C" { +void stdb$tables$person$cxxbridge1$person_name(::stdb::tables::Person const &p, ::rust::String *return$) noexcept; + +void stdb$tables$person$cxxbridge1$person_iter(::stdb::DbConnection const &ctx, ::rust::Vec<::stdb::tables::Person> *return$) noexcept; +} // extern "C" +} // namespace person +} // namespace tables + +::std::size_t DbConnection::layout::size() noexcept { + return stdb$cxxbridge1$DbConnection$operator$sizeof(); +} + +::std::size_t DbConnection::layout::align() noexcept { + return stdb$cxxbridge1$DbConnection$operator$alignof(); +} + +::rust::Box<::stdb::DbConnection> connect(::std::string const &uri, ::std::string const &db) { + ::rust::MaybeUninit<::rust::Box<::stdb::DbConnection>> return$; + ::rust::repr::PtrLen error$ = stdb$cxxbridge1$connect(uri, db, &return$.value); + if (error$.ptr) { + throw ::rust::impl<::rust::Error>::error(error$); + } + return ::std::move(return$.value); +} + +void run_threaded(::stdb::DbConnection const &ctx) noexcept { + stdb$cxxbridge1$run_threaded(ctx); +} + +void subscribe(::stdb::DbConnection const &ctx, ::std::vector<::std::string> const &subs, ::std::size_t on_applied_ptr, ::std::size_t on_err_ptr) noexcept { + stdb$cxxbridge1$subscribe(ctx, subs, on_applied_ptr, on_err_ptr); +} + +void subscribe_to_all(::stdb::DbConnection const &ctx) noexcept { + stdb$cxxbridge1$subscribe_to_all(ctx); +} + +namespace reducers { +void say_hello(::stdb::DbConnection const &ctx) { + ::rust::repr::PtrLen error$ = stdb$reducers$cxxbridge1$say_hello(ctx); + if (error$.ptr) { + throw ::rust::impl<::rust::Error>::error(error$); + } +} + +void add(::stdb::DbConnection const &ctx, ::std::string const &name) { + ::rust::repr::PtrLen error$ = stdb$reducers$cxxbridge1$add(ctx, name); + if (error$.ptr) { + throw ::rust::impl<::rust::Error>::error(error$); + } +} +} // namespace reducers + +namespace tables { +::std::size_t Person::layout::size() noexcept { + return stdb$tables$cxxbridge1$Person$operator$sizeof(); +} + +::std::size_t Person::layout::align() noexcept { + return stdb$tables$cxxbridge1$Person$operator$alignof(); +} + +namespace person { +::rust::String name(::stdb::tables::Person const &p) noexcept { + ::rust::MaybeUninit<::rust::String> return$; + stdb$tables$person$cxxbridge1$person_name(p, &return$.value); + return ::std::move(return$.value); +} + +::rust::Vec<::stdb::tables::Person> iter(::stdb::DbConnection const &ctx) noexcept { + ::rust::MaybeUninit<::rust::Vec<::stdb::tables::Person>> return$; + stdb$tables$person$cxxbridge1$person_iter(ctx, &return$.value); + return ::std::move(return$.value); +} +} // namespace person +} // namespace tables +} // namespace stdb + +extern "C" { +::stdb::DbConnection *cxxbridge1$box$stdb$DbConnection$alloc() noexcept; +void cxxbridge1$box$stdb$DbConnection$dealloc(::stdb::DbConnection *) noexcept; +void cxxbridge1$box$stdb$DbConnection$drop(::rust::Box<::stdb::DbConnection> *ptr) noexcept; + +void cxxbridge1$rust_vec$stdb$tables$Person$new(::rust::Vec<::stdb::tables::Person> const *ptr) noexcept; +void cxxbridge1$rust_vec$stdb$tables$Person$drop(::rust::Vec<::stdb::tables::Person> *ptr) noexcept; +::std::size_t cxxbridge1$rust_vec$stdb$tables$Person$len(::rust::Vec<::stdb::tables::Person> const *ptr) noexcept; +::std::size_t cxxbridge1$rust_vec$stdb$tables$Person$capacity(::rust::Vec<::stdb::tables::Person> const *ptr) noexcept; +::stdb::tables::Person const *cxxbridge1$rust_vec$stdb$tables$Person$data(::rust::Vec<::stdb::tables::Person> const *ptr) noexcept; +void cxxbridge1$rust_vec$stdb$tables$Person$reserve_total(::rust::Vec<::stdb::tables::Person> *ptr, ::std::size_t new_cap) noexcept; +void cxxbridge1$rust_vec$stdb$tables$Person$set_len(::rust::Vec<::stdb::tables::Person> *ptr, ::std::size_t len) noexcept; +void cxxbridge1$rust_vec$stdb$tables$Person$truncate(::rust::Vec<::stdb::tables::Person> *ptr, ::std::size_t len) noexcept; +} // extern "C" + +namespace rust { +inline namespace cxxbridge1 { +template <> +::stdb::DbConnection *Box<::stdb::DbConnection>::allocation::alloc() noexcept { + return cxxbridge1$box$stdb$DbConnection$alloc(); +} +template <> +void Box<::stdb::DbConnection>::allocation::dealloc(::stdb::DbConnection *ptr) noexcept { + cxxbridge1$box$stdb$DbConnection$dealloc(ptr); +} +template <> +void Box<::stdb::DbConnection>::drop() noexcept { + cxxbridge1$box$stdb$DbConnection$drop(this); +} +template <> +Vec<::stdb::tables::Person>::Vec() noexcept { + cxxbridge1$rust_vec$stdb$tables$Person$new(this); +} +template <> +void Vec<::stdb::tables::Person>::drop() noexcept { + return cxxbridge1$rust_vec$stdb$tables$Person$drop(this); +} +template <> +::std::size_t Vec<::stdb::tables::Person>::size() const noexcept { + return cxxbridge1$rust_vec$stdb$tables$Person$len(this); +} +template <> +::std::size_t Vec<::stdb::tables::Person>::capacity() const noexcept { + return cxxbridge1$rust_vec$stdb$tables$Person$capacity(this); +} +template <> +::stdb::tables::Person const *Vec<::stdb::tables::Person>::data() const noexcept { + return cxxbridge1$rust_vec$stdb$tables$Person$data(this); +} +template <> +void Vec<::stdb::tables::Person>::reserve_total(::std::size_t new_cap) noexcept { + return cxxbridge1$rust_vec$stdb$tables$Person$reserve_total(this, new_cap); +} +template <> +void Vec<::stdb::tables::Person>::set_len(::std::size_t len) noexcept { + return cxxbridge1$rust_vec$stdb$tables$Person$set_len(this, len); +} +template <> +void Vec<::stdb::tables::Person>::truncate(::std::size_t len) { + return cxxbridge1$rust_vec$stdb$tables$Person$truncate(this, len); +} +} // namespace cxxbridge1 +} // namespace rust diff --git a/cpp-client/server/.cargo/config.toml b/cpp-client/server/.cargo/config.toml new file mode 100644 index 0000000..f4e8c00 --- /dev/null +++ b/cpp-client/server/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "wasm32-unknown-unknown" diff --git a/cpp-client/server/.gitignore b/cpp-client/server/.gitignore new file mode 100644 index 0000000..31b13f0 --- /dev/null +++ b/cpp-client/server/.gitignore @@ -0,0 +1,17 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# Spacetime ignore +/.spacetime \ No newline at end of file diff --git a/cpp-client/server/Cargo.toml b/cpp-client/server/Cargo.toml new file mode 100644 index 0000000..c265f6b --- /dev/null +++ b/cpp-client/server/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "spacetime-module" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib"] + +[dependencies] +spacetimedb = "1.1.0" +log = "0.4" diff --git a/cpp-client/server/src/lib.rs b/cpp-client/server/src/lib.rs new file mode 100644 index 0000000..b55824a --- /dev/null +++ b/cpp-client/server/src/lib.rs @@ -0,0 +1,34 @@ +use spacetimedb::{ReducerContext, Table}; + +#[spacetimedb::table(name = person, public)] +pub struct Person { + name: String, +} + +#[spacetimedb::reducer(init)] +pub fn init(_ctx: &ReducerContext) { + // Called when the module is initially published +} + +#[spacetimedb::reducer(client_connected)] +pub fn identity_connected(_ctx: &ReducerContext) { + // Called everytime a new client connects +} + +#[spacetimedb::reducer(client_disconnected)] +pub fn identity_disconnected(_ctx: &ReducerContext) { + // Called everytime a client disconnects +} + +#[spacetimedb::reducer] +pub fn add(ctx: &ReducerContext, name: String) { + ctx.db.person().insert(Person { name }); +} + +#[spacetimedb::reducer] +pub fn say_hello(ctx: &ReducerContext) { + for person in ctx.db.person().iter() { + log::info!("Hello, {}!", person.name); + } + log::info!("Hello, World!"); +}