diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index 1ee9c3a7a..12489a4c3 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "637cc57519a29be8f7484c1bcc78ea5388e62ced676187c984be54a74b2f62c0", + "checksum": "59383291e269beaf4a9bcc1008b167fb5de6092d2ed7de0b0fc879f2a46eda4b", "crates": { "addr2line 0.24.2": { "name": "addr2line", @@ -1738,7 +1738,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-api" } @@ -1875,7 +1875,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-artifact-upload" } @@ -2004,7 +2004,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-bonjson" } @@ -2102,7 +2102,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-bounded-buffer" } @@ -2174,7 +2174,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-buffer" } @@ -2307,7 +2307,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-client-common" } @@ -2361,6 +2361,10 @@ "id": "flate2 1.1.2", "target": "flate2" }, + { + "id": "itertools 0.14.0", + "target": "itertools" + }, { "id": "log 0.4.28", "target": "log" @@ -2377,6 +2381,10 @@ "id": "protobuf 4.0.0-alpha.0", "target": "protobuf" }, + { + "id": "tempfile 3.21.0", + "target": "tempfile" + }, { "id": "thiserror 2.0.16", "target": "thiserror" @@ -2388,6 +2396,10 @@ { "id": "tokio 1.47.1", "target": "tokio" + }, + { + "id": "walkdir 2.5.0", + "target": "walkdir" } ], "selects": {} @@ -2416,7 +2428,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-client-stats" } @@ -2541,7 +2553,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-client-stats-store" } @@ -2621,7 +2633,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-completion" } @@ -2681,7 +2693,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-crash-handler" } @@ -2763,6 +2775,10 @@ "id": "log 0.4.28", "target": "log" }, + { + "id": "memmap2 0.9.8", + "target": "memmap2" + }, { "id": "mockall 0.13.1", "target": "mockall" @@ -2818,7 +2834,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-device" } @@ -2890,7 +2906,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-error-reporter" } @@ -2966,7 +2982,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-events" } @@ -3022,6 +3038,70 @@ "license_ids": [], "license_file": "../LICENSE" }, + "bd-feature-flags 1.0.0": { + "name": "bd-feature-flags", + "version": "1.0.0", + "package_url": null, + "repository": { + "Git": { + "remote": "https://github.com/bitdriftlabs/shared-core.git", + "commitish": { + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" + }, + "strip_prefix": "bd-feature-flags" + } + }, + "targets": [ + { + "Library": { + "crate_name": "bd_feature_flags", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "bd_feature_flags", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anyhow 1.0.99", + "target": "anyhow" + }, + { + "id": "bd-bonjson 1.0.0", + "target": "bd_bonjson" + }, + { + "id": "bd-client-common 1.0.0", + "target": "bd_client_common" + }, + { + "id": "bd-resilient-kv 1.0.0", + "target": "bd_resilient_kv" + }, + { + "id": "time 0.3.43", + "target": "time" + } + ], + "selects": {} + }, + "edition": "2024", + "version": "1.0.0" + }, + "license": null, + "license_ids": [], + "license_file": "../LICENSE" + }, "bd-grpc 1.0.0": { "name": "bd-grpc", "version": "1.0.0", @@ -3030,7 +3110,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-grpc" } @@ -3253,7 +3333,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-grpc-codec" } @@ -3328,7 +3408,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-hyper-network" } @@ -3456,7 +3536,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-internal-logging" } @@ -3512,7 +3592,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-key-value" } @@ -3588,7 +3668,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-log" } @@ -3668,7 +3748,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-log-filter" } @@ -3748,7 +3828,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-log-matcher" } @@ -3816,7 +3896,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-log-metadata" } @@ -3872,7 +3952,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-log-primitives" } @@ -3932,7 +4012,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-logger" } @@ -4161,7 +4241,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-metadata" } @@ -4200,7 +4280,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-network-quality" } @@ -4239,7 +4319,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-noop-network" } @@ -4304,7 +4384,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-panic" } @@ -4360,7 +4440,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-pgv" } @@ -4458,7 +4538,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-proto" } @@ -4564,7 +4644,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-report-writer" } @@ -4650,6 +4730,70 @@ "license_ids": [], "license_file": "../LICENSE" }, + "bd-resilient-kv 1.0.0": { + "name": "bd-resilient-kv", + "version": "1.0.0", + "package_url": null, + "repository": { + "Git": { + "remote": "https://github.com/bitdriftlabs/shared-core.git", + "commitish": { + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" + }, + "strip_prefix": "bd-resilient-kv" + } + }, + "targets": [ + { + "Library": { + "crate_name": "bd_resilient_kv", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "bd_resilient_kv", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anyhow 1.0.99", + "target": "anyhow" + }, + { + "id": "bd-bonjson 1.0.0", + "target": "bd_bonjson" + }, + { + "id": "bd-client-common 1.0.0", + "target": "bd_client_common" + }, + { + "id": "bytes 1.10.1", + "target": "bytes" + }, + { + "id": "memmap2 0.9.8", + "target": "memmap2" + } + ], + "selects": {} + }, + "edition": "2024", + "version": "1.0.0" + }, + "license": null, + "license_ids": [], + "license_file": "../LICENSE" + }, "bd-resource-utilization 1.0.0": { "name": "bd-resource-utilization", "version": "1.0.0", @@ -4658,7 +4802,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-resource-utilization" } @@ -4738,7 +4882,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-runtime" } @@ -4827,7 +4971,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-server-stats" } @@ -4919,7 +5063,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-session" } @@ -5007,7 +5151,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-session-replay" } @@ -5103,7 +5247,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-shutdown" } @@ -5155,7 +5299,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-stats-common" } @@ -5207,7 +5351,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-test-helpers" } @@ -5388,7 +5532,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-time" } @@ -5461,7 +5605,7 @@ "Git": { "remote": "https://github.com/bitdriftlabs/shared-core.git", "commitish": { - "Rev": "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" + "Rev": "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" }, "strip_prefix": "bd-workflows" } @@ -5539,6 +5683,10 @@ "id": "bd-stats-common 1.0.0", "target": "bd_stats_common" }, + { + "id": "bd-test-helpers 1.0.0", + "target": "bd_test_helpers" + }, { "id": "bd-time 1.0.0", "target": "bd_time" @@ -13451,6 +13599,10 @@ "id": "bd-api 1.0.0", "target": "bd_api" }, + { + "id": "bd-bonjson 1.0.0", + "target": "bd_bonjson" + }, { "id": "bd-client-common 1.0.0", "target": "bd_client_common" @@ -13463,6 +13615,10 @@ "id": "bd-error-reporter 1.0.0", "target": "bd_error_reporter" }, + { + "id": "bd-feature-flags 1.0.0", + "target": "bd_feature_flags" + }, { "id": "bd-log-primitives 1.0.0", "target": "bd_log_primitives" @@ -24640,6 +24796,7 @@ "bd-client-stats-store 1.0.0", "bd-device 1.0.0", "bd-error-reporter 1.0.0", + "bd-feature-flags 1.0.0", "bd-hyper-network 1.0.0", "bd-key-value 1.0.0", "bd-log 1.0.0", diff --git a/Cargo.lock b/Cargo.lock index fcdd54ffc..a9f7a0685 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -296,7 +296,7 @@ checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bd-api" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -325,7 +325,7 @@ dependencies = [ [[package]] name = "bd-artifact-upload" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -352,7 +352,7 @@ dependencies = [ [[package]] name = "bd-bonjson" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "bytes", "cbindgen", @@ -363,7 +363,7 @@ dependencies = [ [[package]] name = "bd-bounded-buffer" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "ahash", "bd-client-stats-store", @@ -377,7 +377,7 @@ dependencies = [ [[package]] name = "bd-buffer" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -405,7 +405,7 @@ dependencies = [ [[package]] name = "bd-client-common" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -415,19 +415,22 @@ dependencies = [ "crc32fast", "flatbuffers", "flate2", + "itertools 0.14.0", "log", "mockall", "parking_lot", "protobuf 4.0.0-alpha.0", + "tempfile", "thiserror 2.0.16", "time", "tokio", + "walkdir", ] [[package]] name = "bd-client-stats" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -453,7 +456,7 @@ dependencies = [ [[package]] name = "bd-client-stats-store" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-client-common", @@ -469,7 +472,7 @@ dependencies = [ [[package]] name = "bd-completion" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "log", @@ -480,7 +483,7 @@ dependencies = [ [[package]] name = "bd-crash-handler" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -497,6 +500,7 @@ dependencies = [ "flatbuffers", "itertools 0.14.0", "log", + "memmap2", "mockall", "regex", "serde", @@ -509,7 +513,7 @@ dependencies = [ [[package]] name = "bd-device" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-key-value", @@ -523,7 +527,7 @@ dependencies = [ [[package]] name = "bd-error-reporter" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-client-common", @@ -538,7 +542,7 @@ dependencies = [ [[package]] name = "bd-events" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-runtime", @@ -547,10 +551,22 @@ dependencies = [ "tokio", ] +[[package]] +name = "bd-feature-flags" +version = "1.0.0" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" +dependencies = [ + "anyhow", + "bd-bonjson", + "bd-client-common", + "bd-resilient-kv", + "time", +] + [[package]] name = "bd-grpc" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "assert_matches", @@ -591,7 +607,7 @@ dependencies = [ [[package]] name = "bd-grpc-codec" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "bd-stats-common", "bytes", @@ -604,7 +620,7 @@ dependencies = [ [[package]] name = "bd-hyper-network" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -629,7 +645,7 @@ dependencies = [ [[package]] name = "bd-internal-logging" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "bd-log-primitives", "bd-proto", @@ -639,7 +655,7 @@ dependencies = [ [[package]] name = "bd-key-value" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "base64", @@ -654,7 +670,7 @@ dependencies = [ [[package]] name = "bd-log" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "log", @@ -670,7 +686,7 @@ dependencies = [ [[package]] name = "bd-log-filter" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-client-stats-store", @@ -686,7 +702,7 @@ dependencies = [ [[package]] name = "bd-log-matcher" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-log-primitives", @@ -699,7 +715,7 @@ dependencies = [ [[package]] name = "bd-log-metadata" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-log-primitives", @@ -709,7 +725,7 @@ dependencies = [ [[package]] name = "bd-log-primitives" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "ahash", "bd-proto", @@ -720,7 +736,7 @@ dependencies = [ [[package]] name = "bd-logger" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -772,17 +788,17 @@ dependencies = [ [[package]] name = "bd-metadata" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" [[package]] name = "bd-network-quality" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" [[package]] name = "bd-noop-network" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -793,7 +809,7 @@ dependencies = [ [[package]] name = "bd-panic" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "color-backtrace", "log", @@ -803,7 +819,7 @@ dependencies = [ [[package]] name = "bd-pgv" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "log", "protobuf 4.0.0-alpha.0", @@ -814,7 +830,7 @@ dependencies = [ [[package]] name = "bd-proto" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "bd-pgv", "bytes", @@ -827,17 +843,29 @@ dependencies = [ [[package]] name = "bd-report-writer" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "bd-proto", "cbindgen", "flatbuffers", ] +[[package]] +name = "bd-resilient-kv" +version = "1.0.0" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" +dependencies = [ + "anyhow", + "bd-bonjson", + "bd-client-common", + "bytes", + "memmap2", +] + [[package]] name = "bd-resource-utilization" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-client-common", @@ -853,7 +881,7 @@ dependencies = [ [[package]] name = "bd-runtime" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -870,7 +898,7 @@ dependencies = [ [[package]] name = "bd-server-stats" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-stats-common", @@ -889,7 +917,7 @@ dependencies = [ [[package]] name = "bd-session" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-key-value", @@ -907,7 +935,7 @@ dependencies = [ [[package]] name = "bd-session-replay" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "bd-client-common", @@ -927,7 +955,7 @@ dependencies = [ [[package]] name = "bd-shutdown" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "log", "tokio", @@ -936,7 +964,7 @@ dependencies = [ [[package]] name = "bd-stats-common" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "sketches-rust", @@ -945,7 +973,7 @@ dependencies = [ [[package]] name = "bd-test-helpers" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "assert_matches", @@ -985,7 +1013,7 @@ dependencies = [ [[package]] name = "bd-time" version = "1.0.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "async-trait", "parking_lot", @@ -998,7 +1026,7 @@ dependencies = [ [[package]] name = "bd-workflows" version = "0.1.0" -source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=693e1e433eb7e531a7817cd0b6eb6722d1122ed2#693e1e433eb7e531a7817cd0b6eb6722d1122ed2" +source = "git+https://github.com/bitdriftlabs/shared-core.git?rev=e8d4e18b6870bcf04d786fd3971c0f46d99ac802#e8d4e18b6870bcf04d786fd3971c0f46d99ac802" dependencies = [ "anyhow", "async-trait", @@ -1014,6 +1042,7 @@ dependencies = [ "bd-runtime", "bd-shutdown", "bd-stats-common", + "bd-test-helpers", "bd-time", "bincode", "itertools 0.14.0", @@ -2236,9 +2265,11 @@ version = "1.0.0" dependencies = [ "anyhow", "bd-api", + "bd-bonjson", "bd-client-common", "bd-client-stats-store", "bd-error-reporter", + "bd-feature-flags", "bd-log-primitives", "bd-logger", "bd-runtime", @@ -2887,6 +2918,7 @@ dependencies = [ "bd-client-common", "bd-device", "bd-error-reporter", + "bd-feature-flags", "bd-key-value", "bd-log", "bd-log-primitives", diff --git a/Cargo.toml b/Cargo.toml index d146bc70f..d632b2730 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,29 +18,30 @@ android_logger = { version = "0.15.1", default-features = false } anyhow = "1.0.99" assert_matches = "1.5.0" async-trait = "0.1.89" -bd-api = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-bonjson = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-buffer = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-client-common = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-client-stats-store = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-crash-handler = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-device = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-error-reporter = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-grpc = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-hyper-network = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-key-value = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-log = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-log-metadata = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-log-primitives = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-logger = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-noop-network = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-proto = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-report-writer = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-runtime = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-session = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-shutdown = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } -bd-test-helpers = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2", default-features = false } -bd-time = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "693e1e433eb7e531a7817cd0b6eb6722d1122ed2" } +bd-api = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-bonjson = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-buffer = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-client-common = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-client-stats-store = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-crash-handler = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-device = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-error-reporter = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-feature-flags = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-grpc = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-hyper-network = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-key-value = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-log = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-log-metadata = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-log-primitives = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-logger = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-noop-network = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-proto = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-report-writer = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-runtime = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-session = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-shutdown = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } +bd-test-helpers = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802", default-features = false } +bd-time = { git = "https://github.com/bitdriftlabs/shared-core.git", rev = "e8d4e18b6870bcf04d786fd3971c0f46d99ac802" } clap = { version = "4.5.47", features = ["derive", "env"] } ctor = "0.5.0" env_logger = { version = "0.11.8", default-features = false } diff --git a/platform/shared/Cargo.toml b/platform/shared/Cargo.toml index 9afdd79ae..49623029d 100644 --- a/platform/shared/Cargo.toml +++ b/platform/shared/Cargo.toml @@ -8,9 +8,11 @@ version = "1.0.0" [dependencies] anyhow.workspace = true bd-api.workspace = true +bd-bonjson.workspace = true bd-client-common.workspace = true bd-client-stats-store.workspace = true bd-error-reporter.workspace = true +bd-feature-flags.workspace = true bd-log-primitives.workspace = true bd-logger.workspace = true bd-runtime.workspace = true diff --git a/platform/shared/src/feature_flags.rs b/platform/shared/src/feature_flags.rs new file mode 100644 index 000000000..cf6e9d275 --- /dev/null +++ b/platform/shared/src/feature_flags.rs @@ -0,0 +1,121 @@ +// capture-sdk - bitdrift's client SDK +// Copyright Bitdrift, Inc. All rights reserved. +// +// Use of this source code is governed by a source available license that can be found in the +// LICENSE file or at: +// https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt + +use bd_feature_flags::FeatureFlags; + +crate::ffi_id_for!(FeatureFlagsHolder, FeatureFlagsId); + +// +// FeatureFlagsHolder +// + +/// A wrapper around the feature flags. The platform code passes a pointer to this +/// struct as the feature flags ID, allowing the ffi functions to cast this to the correct type and access +/// these fields to support the feature flags API. +pub struct FeatureFlagsHolder { + feature_flags: FeatureFlags, +} + +crate::impl_holder_deref!(FeatureFlagsHolder, feature_flags, FeatureFlags); +crate::impl_holder_into_raw!(FeatureFlagsHolder, FeatureFlagsId); + +impl FeatureFlagsHolder { + #[must_use] + pub const fn new(feature_flags: FeatureFlags) -> Self { + Self { feature_flags } + } + + /// Given a valid feature flags ID, destroys the feature flags holder and frees the memory associated with it. + /// + /// # Safety + /// The provided id *must* correspond to the pointer of a valid `FeatureFlagsHolder` as returned by + /// `into_raw`. This function *cannot* be called multiple times for the same id. + pub unsafe fn destroy(id: i64) { + let holder = Box::from_raw(id as *mut Self); + drop(holder); + } + + /// Retrieves a feature flag by name. + /// + /// Returns the feature flag if it exists, or `None` if no flag + /// with the given name is found. + /// + /// # Arguments + /// + /// * `key` - The name of the feature flag to retrieve + #[must_use] + pub fn get(&self, key: &str) -> Option { + self.feature_flags.get(key) + } + + /// Sets or updates a feature flag. + /// + /// Creates a new feature flag with the given name and variant, or updates an existing flag. + /// The flag is immediately stored in persistent storage and receives + /// a timestamp indicating when it was last modified. + /// + /// # Arguments + /// + /// * `key` - The name of the feature flag to set or update + /// * `variant` - The variant value for the flag: + /// - `Some(string)` sets the flag with the specified variant + /// - `None` sets the flag without a variant (simple boolean-style flag) + /// + /// # Returns + /// + /// Returns `Ok(())` on success, or an error if the flag cannot be stored. + pub fn set(&mut self, key: &str, variant: Option<&str>) -> anyhow::Result<()> { + self.feature_flags.set(key, variant) + } + + /// Removes all feature flags from persistent storage. + /// + /// This method deletes all feature flags, clearing the persistent storage. + /// This operation cannot be undone. + /// + /// # Returns + /// + /// Returns `Ok(())` on success, or an error if the storage cannot be cleared. + pub fn clear(&mut self) -> anyhow::Result<()> { + self.feature_flags.clear() + } + + /// Synchronizes in-memory changes to persistent storage. + /// + /// This method ensures that all feature flag changes made since the last sync + /// are written to disk. While changes are typically persisted automatically, + /// calling this method guarantees that data is flushed to storage immediately. + /// + /// # Returns + /// + /// Returns `Ok(())` on successful synchronization, or an error if the write operation fails. + pub fn sync(&self) -> anyhow::Result<()> { + self.feature_flags.sync() + } + + /// Returns a `HashMap` containing all feature flags. + /// + /// This method provides access to all feature flags as a standard + /// Rust `HashMap`. This is useful for iterating over all flags or performing + /// bulk operations. The `HashMap` is generated on-demand from the persistent storage. + /// + /// # Returns + /// + /// A `HashMap` containing all flags. + #[must_use] + pub fn as_hashmap(&self) -> std::collections::HashMap { + self.feature_flags.as_hashmap() + } + + /// Returns a reference to the underlying key-value store's `HashMap`, + /// allowing direct access to the raw stored values. + /// This should only be used internally to avoid unnecessary cloning. + #[must_use] + pub fn underlying_hashmap(&self) -> &std::collections::HashMap { + self.feature_flags.underlying_hashmap() + } +} diff --git a/platform/shared/src/ffi_wrapper.rs b/platform/shared/src/ffi_wrapper.rs new file mode 100644 index 000000000..1b4535898 --- /dev/null +++ b/platform/shared/src/ffi_wrapper.rs @@ -0,0 +1,123 @@ +// capture-sdk - bitdrift's client SDK +// Copyright Bitdrift, Inc. All rights reserved. +// +// Use of this source code is governed by a source available license that can be found in the +// LICENSE file or at: +// https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt + +use std::ops::{Deref, DerefMut}; + +/// A generic FFI ID type that provides a type-safe wrapper around i64 pointers +/// for passing objects across FFI boundaries. +/// +/// This provides lifetime safety by preventing the ID from being sent across +/// thread boundaries when used as `FfiId<'_, T>` (note that `FfiId<'static, T>` +/// bypasses this protection). +#[repr(transparent)] +pub struct FfiId<'a, T> { + value: i64, + // A fake lifetime to allow us to link a non-static lifetime to the type, which allows us to + // limit its usage outside of the current function scope. + _lifetime: std::marker::PhantomData<&'a ()>, + // Phantom data to ensure the type parameter is part of the type system + _type: std::marker::PhantomData, +} + +impl FfiId<'_, T> { + /// Creates a new `FfiId` from a raw pointer to a holder object. Use this in cases where you + /// need a manual conversion from an i64 to an `FfiId`. + /// + /// # Safety + /// The provided pointer *must* be a valid pointer to a holder object of type T. + #[must_use] + pub const unsafe fn from_raw(value: i64) -> Self { + Self { + value, + _lifetime: std::marker::PhantomData, + _type: std::marker::PhantomData, + } + } + + /// Returns a reference to the holder object that this `FfiId` represents. + /// + /// # Safety + /// This is safe because all instances of `FfiId` are assumed to wrap a valid holder object. + const fn holder(&self) -> &T { + unsafe { &*(self.value as *const T) } + } + + /// Returns a mutable reference to the holder object that this `FfiId` represents. + fn holder_mut(&mut self) -> &mut T { + unsafe { &mut *(self.value as *mut T) } + } +} + +impl Deref for FfiId<'_, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.holder() + } +} + +impl DerefMut for FfiId<'_, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.holder_mut() + } +} + +impl From> for i64 { + fn from(id: FfiId<'_, T>) -> Self { + id.value + } +} + +/// Convenience macro for creating type-specific FFI ID aliases. +#[macro_export] +macro_rules! ffi_id_for { + ($holder_type:ty, $id_type:ident) => { + pub type $id_type<'a> = $crate::ffi_wrapper::FfiId<'a, $holder_type>; + }; +} + +/// Convenience macro for implementing `Deref` and `DerefMut` for holder types. +/// +/// This generates both `Deref` and `DerefMut` implementations that forward to a specific field. +#[macro_export] +macro_rules! impl_holder_deref { + ($holder_type:ty, $field_name:ident, $target_type:ty) => { + impl std::ops::Deref for $holder_type { + type Target = $target_type; + + fn deref(&self) -> &Self::Target { + &self.$field_name + } + } + + impl std::ops::DerefMut for $holder_type { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.$field_name + } + } + }; +} + +/// Convenience macro for implementing `into_raw` method for holder types. +/// +/// This generates an `into_raw` method that converts the holder into its corresponding +/// FFI ID type, following the standard pattern of boxing the holder and converting +/// the pointer to an i64. +#[macro_export] +macro_rules! impl_holder_into_raw { + ($holder_type:ty, $id_type:ident) => { + impl $holder_type { + /// Consumes the holder and returns the raw pointer to it as an FFI ID. This effectively leaks the object, so + /// in order to avoid leaks the caller must ensure that the `destroy` is called with the returned + /// value. + #[must_use] + pub fn into_raw<'a>(self) -> $id_type<'a> { + unsafe { $id_type::from_raw(Box::into_raw(Box::new(self)) as i64) } + } + } + }; +} diff --git a/platform/shared/src/lib.rs b/platform/shared/src/lib.rs index 728b41362..d6add7636 100644 --- a/platform/shared/src/lib.rs +++ b/platform/shared/src/lib.rs @@ -15,6 +15,8 @@ )] pub mod error; +pub mod feature_flags; +pub mod ffi_wrapper; pub mod metadata; use bd_error_reporter::reporter::handle_unexpected; @@ -29,78 +31,10 @@ use bd_logger::{ use bd_runtime::runtime::Snapshot; use parking_lot::Once; use std::future::Future; -use std::ops::{Deref, DerefMut}; use std::pin::Pin; use std::sync::Arc; - -/// This is the logger ID that is passed to the platform code. It is a typed wrapper around an i64 -/// that encodes the pointer to the `LoggerHolder` object. -/// -/// We use a fixed size representation to ensure that we can always fit a pointer in it regardless -/// of the platform (assuming 32 or 64 bit pointers). -/// -/// We use a signed type since the JVM doesn't support unsigned, though it doesn't matter too much -/// since it's really just an opaque 64 bit value. -/// -/// Thanks to the captured lifetime, it is not possible to send or outside of the current function -/// scope when provided as `LoggerId<'_>` (note that `LoggerId<'static>` bypasses this . -/// -/// ```compile_fail -/// fn f(logger: platform_shared::LoggerId<'_>) { -/// std::thread::spawn(move || { -/// logger.logger_holder().shutdown(false); -/// }); -/// } -/// ``` -/// -/// This means that it is relatively safe to use `LoggerId<'_>` in FFI functions, as it is treated -/// exactly like a `i64` in terms of memory layout and passing it around but we get an automatic -/// conversion to a `LoggerHolder` when we provide it over FFI. As the FFI calls are fundamentally -/// unsafe, this seems no worse than passing i64 and doing an unsafe call at the start of the -/// function. -#[repr(transparent)] -pub struct LoggerId<'a> { - value: i64, - // A fake lifetime to allow us to link a non-static lifetime to the type, which allows us to - // limit its usage outside of the current function scope. - _lifetime: std::marker::PhantomData<&'a ()>, -} - -impl LoggerId<'_> { - /// Creates a new `LoggerId` from a raw pointer to a `LoggerHolder`. Use this in cases where you - /// need a manual conversion from an i64 to a `LoggerId`. - /// - /// # Safety - /// The provided pointer *must* be a valid pointer to a `LoggerHolder` object. - #[must_use] - pub const unsafe fn from_raw(value: i64) -> Self { - Self { - value, - _lifetime: std::marker::PhantomData, - } - } - - /// Returns a reference to the `LoggerHolder` object that this `LoggerId` represents. This is - /// safe because all instances of `LoggerId` are assumed to wrap a valid `LoggerHolder` object. - const fn logger_holder(&self) -> &LoggerHolder { - unsafe { &*(self.value as *const LoggerHolder) } - } -} - -impl Deref for LoggerId<'_> { - type Target = LoggerHolder; - - fn deref(&self) -> &Self::Target { - self.logger_holder() - } -} - -impl DerefMut for LoggerId<'_> { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { &mut *(self.value as *mut LoggerHolder) } - } -} +crate::ffi_id_for!(LoggerHolder, LoggerId); pub type LoggerFuture = Pin> + 'static + std::marker::Send>>; @@ -119,13 +53,8 @@ pub struct LoggerHolder { app_launch_tti_log: Once, } -impl Deref for LoggerHolder { - type Target = bd_logger::LoggerHandle; - - fn deref(&self) -> &Self::Target { - &self.handle - } -} +crate::impl_holder_deref!(LoggerHolder, handle, bd_logger::LoggerHandle); +crate::impl_holder_into_raw!(LoggerHolder, LoggerId); impl LoggerHolder { pub fn new(logger: bd_logger::Logger, future: LoggerFuture) -> Self { @@ -138,6 +67,17 @@ impl LoggerHolder { } } + /// Given a valid logger ID, destroys the logger and frees the memory associated with it. + /// + /// # Safety + /// The provided id *must* correspond to the pointer of a valid `LoggerHolder` as returned by + /// `into_raw`. This function *cannot* be called multiple times for the same id. + pub unsafe fn destroy(id: i64) { + let holder = Box::from_raw(id as *mut Self); + holder.shutdown(false); + drop(holder); + } + pub fn start(&self) { let Some(future) = self.future.lock().take() else { return; @@ -147,16 +87,6 @@ impl LoggerHolder { handle_unexpected(LoggerBuilder::run_logger_runtime(future), "logger runtime"); } - /// Consumes the logger and returns the raw pointer to it. This effectively leaks the object, so - /// in order to avoid leaks the caller must ensure that the `destroy` is called with the returned - /// value. - pub fn into_raw<'a>(self) -> LoggerId<'a> { - LoggerId { - value: Box::into_raw(Box::new(self)) as i64, - _lifetime: std::marker::PhantomData, - } - } - /// Shuts down the logger, blocking until the logger has finished shutdown if `block` is true. pub fn shutdown(&self, block: bool) { self.logger.shutdown(block); @@ -167,17 +97,6 @@ impl LoggerHolder { self.logger.runtime_snapshot() } - /// Given a valid logger ID, destroys the logger and frees the memory associated with it. - /// - /// # Safety - /// The provided id *must* correspond to the pointer of a valid `LoggerHolder` as returned by - /// `into_raw`. This function *cannot* be called multiple times for the same id. - pub unsafe fn destroy(id: i64) { - let holder = Box::from_raw(id as *mut Self); - holder.shutdown(false); - drop(holder); - } - /// Logs an out-of-the-box app launch TTI log event. The method should be called only once. /// Consecutive calls have not effect. pub fn log_app_launch_tti(&self, duration: time::Duration) { @@ -235,9 +154,3 @@ impl LoggerHolder { ); } } - -impl<'a> From> for i64 { - fn from(logger: LoggerId<'a>) -> Self { - logger.value - } -} diff --git a/platform/swift/source/Cargo.toml b/platform/swift/source/Cargo.toml index 7e0d25fe4..0d337928d 100644 --- a/platform/swift/source/Cargo.toml +++ b/platform/swift/source/Cargo.toml @@ -15,6 +15,7 @@ bd-bonjson.workspace = true bd-client-common.workspace = true bd-device.workspace = true bd-error-reporter.workspace = true +bd-feature-flags.workspace = true bd-key-value.workspace = true bd-log.workspace = true bd-log-primitives.workspace = true diff --git a/platform/swift/source/src/bridge.rs b/platform/swift/source/src/bridge.rs index cafaf603f..9b8faf1a6 100644 --- a/platform/swift/source/src/bridge.rs +++ b/platform/swift/source/src/bridge.rs @@ -15,6 +15,7 @@ use crate::key_value_storage::UserDefaultsStorage; use crate::{events, ffi, resource_utilization, session_replay}; use anyhow::anyhow; use bd_api::{Platform, PlatformNetworkManager, PlatformNetworkStream, StreamEvent}; +use bd_feature_flags::FeatureFlags; use bd_error_reporter::reporter::{ handle_unexpected, with_handle_unexpected, @@ -37,6 +38,7 @@ use objc::rc::StrongPtr; use objc::runtime::Object; use platform_shared::metadata::{self, Mobile}; use platform_shared::{LoggerHolder, LoggerId}; +use platform_shared::feature_flags::{FeatureFlagsHolder, FeatureFlagsId}; use std::borrow::{Borrow, Cow}; use std::boxed::Box; use std::collections::HashMap; @@ -874,3 +876,174 @@ fn unix_milliseconds_to_date(millis_since_utc_epoch: i64) -> anyhow::Result FeatureFlagsId<'static> { + with_handle_unexpected_or( + || -> anyhow::Result> { + let base_path = unsafe { nsstring_into_string(base_path) }?; + let high_water_mark_ratio = if high_water_mark_ratio < 0.0 { + None + } else { + Some(high_water_mark_ratio) + }; + + let feature_flags = FeatureFlags::new( + base_path, + buffer_size, + high_water_mark_ratio, + )?; + + let holder = FeatureFlagsHolder::new(feature_flags); + Ok(holder.into_raw()) + }, + unsafe { FeatureFlagsId::from_raw(-1) }, + "swift create feature flags", + ) +} + +/// Destroys a feature flags holder and frees the memory associated with it. +/// +/// # Safety +/// The provided `feature_flags_id` *must* correspond to the pointer of a valid `FeatureFlagsHolder` +/// as returned by `into_raw`. This function *cannot* be called multiple times for the same id. +#[no_mangle] +extern "C" fn capture_destroy_feature_flags(feature_flags_id: i64) { + unsafe { + FeatureFlagsHolder::destroy(feature_flags_id); + } +} + +/// Retrieves a feature flag by name. +/// +/// Returns true if the flag exists, false otherwise. +/// If the flag exists and has a variant, the variant string is stored in the provided pointer. +/// If the flag exists but has no variant, NULL is stored in the provided pointer. +/// If the flag doesn't exist, the pointer is not modified. +/// +/// # Arguments +/// +/// * `feature_flags_id` - The feature flags ID +/// * `key` - The name of the feature flag to retrieve +/// * `variant_out` - Pointer to store the variant `NSString` (or NULL if no variant) +#[no_mangle] +extern "C" fn capture_feature_flags_get( + feature_flags_id: FeatureFlagsId<'_>, + key: *const Object, + variant_out: *mut *const Object, +) -> bool { + with_handle_unexpected_or( + move || { + let key = unsafe { nsstring_into_string(key) }?; + if let Some(flag) = feature_flags_id.get(&key) { + let variant_ptr = flag.variant.map_or(std::ptr::null(), |variant| { + make_nsstring(&variant) + .unwrap_or_else(|_| make_empty_nsstring()) + .autorelease() + }); + unsafe { + *variant_out = variant_ptr; + } + Ok(true) + } else { + Ok(false) + } + }, + false, + "swift feature flags get variant", + ) +} + +/// Sets or updates a feature flag. +/// +/// Creates a new feature flag with the given name and variant, or updates an existing flag. +/// The flag is immediately stored in persistent storage. +/// +/// # Arguments +/// +/// * `feature_flags_id` - The feature flags ID +/// * `key` - The name of the feature flag to set or update +/// * `variant` - The variant value for the flag (NULL for simple boolean flag) +#[no_mangle] +extern "C" fn capture_feature_flags_set( + mut feature_flags_id: FeatureFlagsId<'_>, + key: *const Object, + variant: *const Object, +) { + with_handle_unexpected( + move || -> anyhow::Result<()> { + let key = unsafe { nsstring_into_string(key) }?; + let variant = if variant.is_null() { + None + } else { + Some(unsafe { nsstring_into_string(variant) }?) + }; + feature_flags_id.deref_mut().set(&key, variant.as_deref())?; + Ok(()) + }, + "swift feature flags set", + ); +} + +/// Removes all feature flags from persistent storage. +/// +/// This method deletes all feature flags, clearing the persistent storage. +/// This operation cannot be undone. +/// +/// # Arguments +/// +/// * `feature_flags_id` - The feature flags ID +#[no_mangle] +extern "C" fn capture_feature_flags_clear(mut feature_flags_id: FeatureFlagsId<'_>) { + with_handle_unexpected( + move || -> anyhow::Result<()> { + feature_flags_id.deref_mut().clear()?; + Ok(()) + }, + "swift feature flags clear", + ); +} + +/// Synchronizes in-memory changes to persistent storage. +/// +/// This method ensures that all feature flag changes made since the last sync +/// are written to disk. +/// +/// # Arguments +/// +/// * `feature_flags_id` - The feature flags ID +#[no_mangle] +extern "C" fn capture_feature_flags_sync(feature_flags_id: FeatureFlagsId<'_>) { + with_handle_unexpected( + move || -> anyhow::Result<()> { + feature_flags_id.sync()?; + Ok(()) + }, + "swift feature flags sync", + ); +}