diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 63492e468d..ecd663cff4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -21,6 +21,7 @@ datadog-sidecar @Datadog/libdatadog-php @Datadog/libdatadog-apm datadog-sidecar-ffi @Datadog/libdatadog-php @Datadog/libdatadog-apm data-pipeline*/ @Datadog/libdatadog-apm ddsketch @Datadog/libdatadog-apm @Datadog/libdatadog-telemetry +datadog-ffe @Datadog/feature-flagging-and-experimentation-sdk # Most of the bin_tests are owned by the profiling team, but some are owned by the core team bin_tests/ @Datadog/libdatadog-profiling diff --git a/Cargo.lock b/Cargo.lock index 69a150c245..086bc5c784 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -808,7 +808,7 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -1007,7 +1007,7 @@ dependencies = [ "mime", "mime_guess", "rand 0.8.5", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -1381,7 +1381,7 @@ dependencies = [ "symbolic-common", "symbolic-demangle", "tempfile", - "thiserror", + "thiserror 1.0.68", "tokio", "uuid", "windows 0.59.0", @@ -1415,6 +1415,26 @@ dependencies = [ "protoc-bin-vendored", ] +[[package]] +name = "datadog-ffe" +version = "0.1.0" +dependencies = [ + "chrono", + "criterion", + "derive_more", + "env_logger", + "faststr", + "log", + "md5", + "regex", + "serde", + "serde-bool", + "serde_json", + "serde_with", + "thiserror 2.0.17", + "url", +] + [[package]] name = "datadog-ipc" version = "0.1.0" @@ -1866,7 +1886,7 @@ dependencies = [ "serde", "static_assertions", "tempfile", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-rustls", "tower-service", @@ -1972,6 +1992,26 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "diff" version = "0.1.13" @@ -2066,12 +2106,36 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "259d404d09818dec19332e31d94558aeb442fea04c817006456c24b5460bbd4b" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + [[package]] name = "errno" version = "0.3.9" @@ -2121,6 +2185,17 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +[[package]] +name = "faststr" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baec6a0289d7f1fe5665586ef7340af82e3037207bef60f5785e57569776f0c8" +dependencies = [ + "bytes", + "serde", + "simdutf8", +] + [[package]] name = "filetime" version = "0.2.25" @@ -2645,7 +2720,7 @@ dependencies = [ "similar", "stringmetrics", "tabwriter", - "thiserror", + "thiserror 1.0.68", "tokio", "url", ] @@ -3152,6 +3227,7 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" dependencies = [ + "serde", "value-bag", ] @@ -3194,6 +3270,12 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + [[package]] name = "memchr" version = "2.7.4" @@ -3458,7 +3540,7 @@ dependencies = [ "percent-encoding", "pin-project", "rand 0.8.5", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", ] @@ -3473,7 +3555,7 @@ dependencies = [ "lazy_static", "opentelemetry", "opentelemetry-semantic-conventions", - "thiserror", + "thiserror 1.0.68", "thrift", "tokio", ] @@ -4258,7 +4340,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a15e661f0f9dac21f3494fe5d23a6338c0ac116a2d22c2b63010acd89467ffe" dependencies = [ "byteorder", - "thiserror", + "thiserror 1.0.68", "twox-hash", ] @@ -4380,13 +4462,23 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] +[[package]] +name = "serde-bool" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fdd050c9c2ed5ae1fb29e71be0a6efdd9df43c7cb13ea5826528cfe10c51db0" +dependencies = [ + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.15" @@ -4396,11 +4488,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -4418,6 +4519,15 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + [[package]] name = "serde_json" version = "1.0.132" @@ -4673,6 +4783,84 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "sval" +version = "2.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502b8906c4736190684646827fbab1e954357dfe541013bbd7994d033d53a1ca" + +[[package]] +name = "sval_buffer" +version = "2.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4b854348b15b6c441bdd27ce9053569b016a0723eab2d015b1fd8e6abe4f708" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bd9e8b74410ddad37c6962587c5f9801a2caadba9e11f3f916ee3f31ae4a1f" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe17b8deb33a9441280b4266c2d257e166bafbaea6e66b4b34ca139c91766d9" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854addb048a5bafb1f496c98e0ab5b9b581c3843f03ca07c034ae110d3b7c623" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_nested" +version = "2.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96cf068f482108ff44ae8013477cb047a1665d5f1a635ad7cf79582c1845dce9" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + +[[package]] +name = "sval_ref" +version = "2.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed02126365ffe5ab8faa0abd9be54fbe68d03d607cd623725b0a71541f8aaa6f" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a263383c6aa2076c4ef6011d3bae1b356edf6ea2613e3d8e8ebaa7b57dd707d5" +dependencies = [ + "serde_core", + "sval", + "sval_nested", +] + [[package]] name = "symbolic-common" version = "12.12.0" @@ -4816,7 +5004,7 @@ dependencies = [ "serde_bytes", "static_assertions", "tarpc-plugins", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-serde", "tokio-util", @@ -4900,7 +5088,16 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.68", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", ] [[package]] @@ -4914,6 +5111,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -5249,7 +5457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", - "thiserror", + "thiserror 1.0.68", "time", "tracing-subscriber", ] @@ -5361,6 +5569,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" version = "1.17.0" @@ -5465,6 +5679,36 @@ name = "value-bag" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35540706617d373b118d550d41f5dfe0b78a0c195dc13c6815e92e2638432306" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe7e140a2658cc16f7ee7a86e413e803fc8f9b5127adc8755c19f9fefa63a52" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] [[package]] name = "value-trait" diff --git a/Cargo.toml b/Cargo.toml index 75b9839ee6..7db0650c6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "datadog-alloc", "datadog-crashtracker", "datadog-crashtracker-ffi", + "datadog-ffe", "datadog-ipc", "datadog-ipc-macros", "datadog-library-config", diff --git a/LICENSE-3rdparty.yml b/LICENSE-3rdparty.yml index df6f0abc2c..1c5457de32 100644 --- a/LICENSE-3rdparty.yml +++ b/LICENSE-3rdparty.yml @@ -1,4 +1,4 @@ -root_name: builder, build_common, tools, datadog-alloc, datadog-crashtracker, ddcommon, ddtelemetry, datadog-ddsketch, cc_utils, datadog-crashtracker-ffi, ddcommon-ffi, datadog-ipc, datadog-ipc-macros, tarpc, tarpc-plugins, tinybytes, spawn_worker, datadog-library-config, datadog-library-config-ffi, datadog-live-debugger, datadog-live-debugger-ffi, datadog-profiling, datadog-profiling-protobuf, datadog-profiling-ffi, data-pipeline-ffi, data-pipeline, datadog-trace-protobuf, datadog-trace-stats, datadog-trace-utils, datadog-trace-normalization, dogstatsd-client, datadog-log, datadog-log-ffi, ddsketch-ffi, ddtelemetry-ffi, symbolizer-ffi, datadog-profiling-replayer, datadog-remote-config, datadog-sidecar, datadog-sidecar-macros, datadog-sidecar-ffi, datadog-trace-obfuscation, datadog-tracer-flare, sidecar_mockgen, test_spawn_from_lib +root_name: builder, build_common, tools, datadog-alloc, datadog-crashtracker, ddcommon, ddtelemetry, datadog-ddsketch, cc_utils, datadog-crashtracker-ffi, ddcommon-ffi, datadog-ffe, datadog-ipc, datadog-ipc-macros, tarpc, tarpc-plugins, tinybytes, spawn_worker, datadog-library-config, datadog-library-config-ffi, datadog-live-debugger, datadog-live-debugger-ffi, datadog-profiling, datadog-profiling-protobuf, datadog-profiling-ffi, data-pipeline-ffi, data-pipeline, datadog-trace-protobuf, datadog-trace-stats, datadog-trace-utils, datadog-trace-normalization, dogstatsd-client, datadog-log, datadog-log-ffi, ddsketch-ffi, ddtelemetry-ffi, symbolizer-ffi, datadog-profiling-replayer, datadog-remote-config, datadog-sidecar, datadog-sidecar-macros, datadog-sidecar-ffi, datadog-trace-obfuscation, datadog-tracer-flare, sidecar_mockgen, test_spawn_from_lib third_party_libraries: - package_name: addr2line package_version: 0.24.2 @@ -9392,6 +9392,62 @@ third_party_libraries: DEALINGS IN THE SOFTWARE. - license: Apache-2.0 text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" +- package_name: derive_more + package_version: 2.0.1 + repository: https://github.com/JelteF/derive_more + license: MIT + licenses: + - license: MIT + text: | + The MIT License (MIT) + + Copyright (c) 2016 Jelte Fennema + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: derive_more-impl + package_version: 2.0.1 + repository: https://github.com/JelteF/derive_more + license: MIT + licenses: + - license: MIT + text: | + The MIT License (MIT) + + Copyright (c) 2016 Jelte Fennema + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. - package_name: digest package_version: 0.10.7 repository: https://github.com/RustCrypto/traits @@ -9991,6 +10047,214 @@ third_party_libraries: OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- package_name: erased-serde + package_version: 0.4.8 + repository: https://github.com/dtolnay/erased-serde + license: MIT OR Apache-2.0 + licenses: + - license: MIT + text: | + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without + limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software + is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice + shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + - license: Apache-2.0 + text: |2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS - package_name: errno package_version: 0.3.9 repository: https://github.com/lambda-fairy/rust-errno @@ -10383,8 +10647,218 @@ third_party_libraries: OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- package_name: filetime - package_version: 0.2.25 +- package_name: faststr + package_version: 0.2.32 + repository: https://github.com/volo-rs/faststr + license: MIT OR Apache-2.0 + licenses: + - license: MIT + text: | + Copyright (c) 2022 Volo Contributors + + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without + limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software + is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice + shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + - license: Apache-2.0 + text: |2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS +- package_name: filetime + package_version: 0.2.25 repository: https://github.com/alexcrichton/filetime license: MIT/Apache-2.0 licenses: @@ -15468,6 +15942,113 @@ third_party_libraries: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- package_name: md5 + package_version: 0.7.0 + repository: https://github.com/stainless-steel/md5 + license: Apache-2.0/MIT + licenses: + - license: Apache-2.0 + text: | + # License + + The project is dual licensed under the terms of the Apache License, Version 2.0, + and the MIT License. You may obtain copies of the two licenses at + + * https://www.apache.org/licenses/LICENSE-2.0 and + * https://opensource.org/licenses/MIT, respectively. + + The following two notices apply to every file of the project. + + ## The Apache License + + ``` + Copyright 2015–2019 The md5 Developers + + Licensed under the Apache License, Version 2.0 (the “License”); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. See the License for the + specific language governing permissions and limitations under the License. + ``` + + ## The MIT License + + ``` + Copyright 2015–2019 The md5 Developers + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the “Software”), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ``` + - license: MIT + text: | + # License + + The project is dual licensed under the terms of the Apache License, Version 2.0, + and the MIT License. You may obtain copies of the two licenses at + + * https://www.apache.org/licenses/LICENSE-2.0 and + * https://opensource.org/licenses/MIT, respectively. + + The following two notices apply to every file of the project. + + ## The Apache License + + ``` + Copyright 2015–2019 The md5 Developers + + Licensed under the Apache License, Version 2.0 (the “License”); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. See the License for the + specific language governing permissions and limitations under the License. + ``` + + ## The MIT License + + ``` + Copyright 2015–2019 The md5 Developers + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the “Software”), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ``` - package_name: memchr package_version: 2.7.4 repository: https://github.com/BurntSushi/memchr @@ -23418,7 +23999,7 @@ third_party_libraries: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - package_name: serde - package_version: 1.0.219 + package_version: 1.0.228 repository: https://github.com/serde-rs/serde license: MIT OR Apache-2.0 licenses: @@ -23625,13 +24206,15 @@ third_party_libraries: of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS -- package_name: serde_bytes - package_version: 0.11.15 - repository: https://github.com/serde-rs/bytes +- package_name: serde-bool + package_version: 0.1.4 + repository: https://github.com/x52dev/serde-utils license: MIT OR Apache-2.0 licenses: - license: MIT text: | + Copyright (c) 2023-NOW Rob Ede + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the @@ -23657,11 +24240,244 @@ third_party_libraries: DEALINGS IN THE SOFTWARE. - license: Apache-2.0 text: |2 - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017-NOW Rob Ede + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +- package_name: serde_bytes + package_version: 0.11.15 + repository: https://github.com/serde-rs/bytes + license: MIT OR Apache-2.0 + licenses: + - license: MIT + text: | + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without + limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software + is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice + shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + - license: Apache-2.0 + text: |2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. @@ -23833,8 +24649,8 @@ third_party_libraries: of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS -- package_name: serde_derive - package_version: 1.0.219 +- package_name: serde_core + package_version: 1.0.228 repository: https://github.com/serde-rs/serde license: MIT OR Apache-2.0 licenses: @@ -24041,8 +24857,8 @@ third_party_libraries: of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS -- package_name: serde_derive_internals - package_version: 0.29.1 +- package_name: serde_derive + package_version: 1.0.228 repository: https://github.com/serde-rs/serde license: MIT OR Apache-2.0 licenses: @@ -24249,9 +25065,9 @@ third_party_libraries: of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS -- package_name: serde_json - package_version: 1.0.132 - repository: https://github.com/serde-rs/json +- package_name: serde_derive_internals + package_version: 0.29.1 + repository: https://github.com/serde-rs/serde license: MIT OR Apache-2.0 licenses: - license: MIT @@ -24457,14 +25273,252 @@ third_party_libraries: of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS -- package_name: serde_regex - package_version: 1.1.0 - repository: '' - license: MIT/Apache-2.0 +- package_name: serde_fmt + package_version: 1.0.3 + repository: https://github.com/KodrAus/serde_fmt.git + license: Apache-2.0 OR MIT licenses: + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" - license: MIT text: | - Copyright (c) 2017 The serde_regex Developers + MIT License + + Copyright (c) 2019 Ashley Mannix + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: serde_json + package_version: 1.0.132 + repository: https://github.com/serde-rs/json + license: MIT OR Apache-2.0 + licenses: + - license: MIT + text: | + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without + limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software + is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice + shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + - license: Apache-2.0 + text: |2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS +- package_name: serde_regex + package_version: 1.1.0 + repository: '' + license: MIT/Apache-2.0 + licenses: + - license: MIT + text: | + Copyright (c) 2017 The serde_regex Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -26749,25 +27803,244 @@ third_party_libraries: licenses: - license: BSD-3-Clause text: "Copyright (c) 2016-2017 Isis Agora Lovecruft, Henry de Valence. All rights reserved.\nCopyright (c) 2016-2024 Isis Agora Lovecruft. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n" -- package_name: symbolic-common - package_version: 12.12.0 - repository: https://github.com/getsentry/symbolic - license: MIT - licenses: - - license: MIT - text: NOT FOUND -- package_name: symbolic-demangle - package_version: 12.12.0 - repository: https://github.com/getsentry/symbolic - license: MIT +- package_name: sval + package_version: 2.16.0 + repository: https://github.com/sval-rs/sval + license: Apache-2.0 OR MIT licenses: + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" - license: MIT - text: NOT FOUND -- package_name: syn - package_version: 1.0.109 - repository: https://github.com/dtolnay/syn - license: MIT OR Apache-2.0 - licenses: + text: | + MIT License + + Copyright (c) 2020 sval-rs + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: sval_buffer + package_version: 2.16.0 + repository: https://github.com/sval-rs/sval + license: Apache-2.0 OR MIT + licenses: + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + - license: MIT + text: | + MIT License + + Copyright (c) 2020 sval-rs + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: sval_dynamic + package_version: 2.16.0 + repository: https://github.com/sval-rs/sval + license: Apache-2.0 OR MIT + licenses: + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + - license: MIT + text: | + MIT License + + Copyright (c) 2020 sval-rs + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: sval_fmt + package_version: 2.16.0 + repository: https://github.com/sval-rs/sval + license: Apache-2.0 OR MIT + licenses: + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + - license: MIT + text: | + MIT License + + Copyright (c) 2020 sval-rs + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: sval_json + package_version: 2.16.0 + repository: https://github.com/sval-rs/sval + license: Apache-2.0 OR MIT + licenses: + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + - license: MIT + text: | + MIT License + + Copyright (c) 2020 sval-rs + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: sval_nested + package_version: 2.16.0 + repository: https://github.com/sval-rs/sval + license: Apache-2.0 OR MIT + licenses: + - license: Apache-2.0 + text: ../LICENSE-APACHE + - license: MIT + text: ../LICENSE-MIT +- package_name: sval_ref + package_version: 2.16.0 + repository: https://github.com/sval-rs/sval + license: Apache-2.0 OR MIT + licenses: + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + - license: MIT + text: | + MIT License + + Copyright (c) 2020 sval-rs + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: sval_serde + package_version: 2.16.0 + repository: https://github.com/sval-rs/sval + license: Apache-2.0 OR MIT + licenses: + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + - license: MIT + text: | + MIT License + + Copyright (c) 2020 sval-rs + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: symbolic-common + package_version: 12.12.0 + repository: https://github.com/getsentry/symbolic + license: MIT + licenses: + - license: MIT + text: NOT FOUND +- package_name: symbolic-demangle + package_version: 12.12.0 + repository: https://github.com/getsentry/symbolic + license: MIT + licenses: + - license: MIT + text: NOT FOUND +- package_name: syn + package_version: 1.0.109 + repository: https://github.com/dtolnay/syn + license: MIT OR Apache-2.0 + licenses: - license: MIT text: | Permission is hereby granted, free of charge, to any @@ -27371,41 +28644,457 @@ third_party_libraries: of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS -- package_name: tempfile - package_version: 3.13.0 - repository: https://github.com/Stebalien/tempfile - license: MIT OR Apache-2.0 - licenses: - - license: MIT - text: | - Copyright (c) 2015 Steven Allen - - Permission is hereby granted, free of charge, to any - person obtaining a copy of this software and associated - documentation files (the "Software"), to deal in the - Software without restriction, including without - limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software - is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice - shall be included in all copies or substantial portions - of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - license: Apache-2.0 - text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" -- package_name: thiserror +- package_name: tempfile + package_version: 3.13.0 + repository: https://github.com/Stebalien/tempfile + license: MIT OR Apache-2.0 + licenses: + - license: MIT + text: | + Copyright (c) 2015 Steven Allen + + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without + limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software + is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice + shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" +- package_name: thiserror + package_version: 1.0.68 + repository: https://github.com/dtolnay/thiserror + license: MIT OR Apache-2.0 + licenses: + - license: MIT + text: | + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without + limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software + is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice + shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + - license: Apache-2.0 + text: |2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS +- package_name: thiserror + package_version: 2.0.17 + repository: https://github.com/dtolnay/thiserror + license: MIT OR Apache-2.0 + licenses: + - license: MIT + text: | + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without + limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software + is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice + shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + - license: Apache-2.0 + text: |2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS +- package_name: thiserror-impl package_version: 1.0.68 repository: https://github.com/dtolnay/thiserror license: MIT OR Apache-2.0 @@ -27614,7 +29303,7 @@ third_party_libraries: END OF TERMS AND CONDITIONS - package_name: thiserror-impl - package_version: 1.0.68 + package_version: 2.0.17 repository: https://github.com/dtolnay/thiserror license: MIT OR Apache-2.0 licenses: @@ -30205,117 +31894,325 @@ third_party_libraries: text: | Copyright (c) 2019 Tokio Contributors - Permission is hereby granted, free of charge, to any - person obtaining a copy of this software and associated - documentation files (the "Software"), to deal in the - Software without restriction, including without - limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software - is furnished to do so, subject to the following - conditions: + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without + limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software + is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice + shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +- package_name: tracing-subscriber + package_version: 0.3.19 + repository: https://github.com/tokio-rs/tracing + license: MIT + licenses: + - license: MIT + text: | + Copyright (c) 2019 Tokio Contributors + + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without + limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software + is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice + shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +- package_name: try-lock + package_version: 0.2.5 + repository: https://github.com/seanmonstar/try-lock + license: MIT + licenses: + - license: MIT + text: |+ + Copyright (c) 2018-2023 Sean McArthur + Copyright (c) 2016 Alex Crichton + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +- package_name: twox-hash + package_version: 1.6.3 + repository: https://github.com/shepmaster/twox-hash + license: MIT + licenses: + - license: MIT + text: | + The MIT License (MIT) + + Copyright (c) 2015 Jake Goulding + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: typeid + package_version: 1.0.3 + repository: https://github.com/dtolnay/typeid + license: MIT OR Apache-2.0 + licenses: + - license: MIT + text: | + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without + limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software + is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice + shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + - license: Apache-2.0 + text: |2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. - The above copyright notice and this permission notice - shall be included in all copies or substantial portions - of the Software. + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -- package_name: tracing-subscriber - package_version: 0.3.19 - repository: https://github.com/tokio-rs/tracing - license: MIT - licenses: - - license: MIT - text: | - Copyright (c) 2019 Tokio Contributors + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: - Permission is hereby granted, free of charge, to any - person obtaining a copy of this software and associated - documentation files (the "Software"), to deal in the - Software without restriction, including without - limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software - is furnished to do so, subject to the following - conditions: + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and - The above copyright notice and this permission notice - shall be included in all copies or substantial portions - of the Software. + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -- package_name: try-lock - package_version: 0.2.5 - repository: https://github.com/seanmonstar/try-lock - license: MIT - licenses: - - license: MIT - text: |+ - Copyright (c) 2018-2023 Sean McArthur - Copyright (c) 2016 Alex Crichton + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. -- package_name: twox-hash - package_version: 1.6.3 - repository: https://github.com/shepmaster/twox-hash - license: MIT - licenses: - - license: MIT - text: | - The MIT License (MIT) + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. - Copyright (c) 2015 Jake Goulding + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. + END OF TERMS AND CONDITIONS - package_name: typenum package_version: 1.17.0 repository: https://github.com/paholg/typenum @@ -31557,6 +33454,66 @@ third_party_libraries: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: value-bag-serde1 + package_version: 1.11.1 + repository: '' + license: Apache-2.0 OR MIT + licenses: + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + - license: MIT + text: | + MIT License + + Copyright (c) 2020 sval-rs + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- package_name: value-bag-sval2 + package_version: 1.11.1 + repository: '' + license: Apache-2.0 OR MIT + licenses: + - license: Apache-2.0 + text: " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + - license: MIT + text: | + MIT License + + Copyright (c) 2020 sval-rs + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/datadog-ffe/Cargo.toml b/datadog-ffe/Cargo.toml new file mode 100644 index 0000000000..dad975e63f --- /dev/null +++ b/datadog-ffe/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "datadog-ffe" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +autobenches = false + +[lib] +bench = false + +[dependencies] +faststr = { version = "0.2.23", default-features = false, features = ["serde"] } +serde = { version = "1.0", default-features = false, features = ["derive", "rc"] } +serde_json = { version = "1.0", default-features = false, features = ["std"] } +chrono = { version = "0.4.38", default-features = false, features = ["now", "serde"] } +derive_more = { version = "2.0.0", default-features = false, features = ["from", "into"] } +log = { version = "0.4.21", default-features = false, features = ["kv", "kv_serde"] } +md5 = { version = "0.7.0", default-features = false } +regex = "1.10.4" +serde-bool = { version = "0.1.3", default-features = false } +serde_with = { version = "3.11.0", default-features = false, features = ["base64", "hex", "macros"] } +thiserror = "2.0.3" +url = "2.5.0" + +[dev-dependencies] +env_logger = "0.10" +criterion = { version = "0.5", features = ["html_reports"] } + +[[bench]] +name = "ffe-eval" +harness = false +path = "benches/eval.rs" diff --git a/datadog-ffe/README.md b/datadog-ffe/README.md new file mode 100644 index 0000000000..a255d482f2 --- /dev/null +++ b/datadog-ffe/README.md @@ -0,0 +1,3 @@ +# Feature Flagging & Experimentation + +This is an internal DataDog library that supports Feature Flag evaluation. It is intended for use in tracers and DataDog services. Expect frequent breaking changes and major bumps before it's stabilized. diff --git a/datadog-ffe/benches/eval.rs b/datadog-ffe/benches/eval.rs new file mode 100644 index 0000000000..ab6da4733d --- /dev/null +++ b/datadog-ffe/benches/eval.rs @@ -0,0 +1,128 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use criterion::{black_box, criterion_group, criterion_main, Bencher, Criterion}; +use serde::{Deserialize, Serialize}; +use std::{collections::HashMap, fs, sync::Arc}; + +use datadog_ffe::rules_based::{ + get_assignment, Attribute, Configuration, EvaluationContext, Str, UniversalFlagConfig, +}; + +fn load_configuration_bytes() -> Vec { + fs::read("tests/data/flags-v1.json").expect("Failed to read flags-v1.json") +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +struct TestCase { + flag: String, + variation_type: String, + default_value: serde_json::Value, + targeting_key: Str, + attributes: HashMap, + result: TestResult, +} + +#[derive(Debug, Serialize, Deserialize)] +struct TestResult { + value: serde_json::Value, +} + +fn load_test_cases() -> Vec { + let mut test_cases = Vec::new(); + + if let Ok(entries) = fs::read_dir("tests/data/tests") { + for entry in entries.flatten() { + if let Some(path_str) = entry.path().to_str() { + if path_str.ends_with(".json") { + if let Ok(content) = fs::read_to_string(entry.path()) { + if let Ok(cases) = serde_json::from_str::>(&content) { + test_cases.extend(cases); + } + } + } + } + } + } + + test_cases +} + +fn bench_sdk_test_data_rules_based(b: &mut Bencher) { + let json_bytes = load_configuration_bytes(); + let test_cases = load_test_cases(); + let now = chrono::Utc::now(); + + // Prepare configuration outside the benchmark + let config = + UniversalFlagConfig::from_json(json_bytes).expect("Failed to parse UFC v1 configuration"); + let configuration = Configuration::from_server_response(config); + + let test_cases = test_cases + .into_iter() + .map(|test_case| { + ( + test_case.flag, + EvaluationContext::new(test_case.targeting_key, Arc::new(test_case.attributes)), + ) + }) + .collect::>(); + + b.iter(|| { + for (flag_key, context) in black_box(&test_cases) { + // Evaluate assignment + let _assignment = get_assignment(Some(&configuration), flag_key, context, None, now); + + let _ = black_box(_assignment); + } + }) +} + +fn bench_single_flag_rules_based(b: &mut Bencher) { + let json_bytes = load_configuration_bytes(); + let now = chrono::Utc::now(); + + // Prepare configuration outside the benchmark + let config = + UniversalFlagConfig::from_json(json_bytes).expect("Failed to parse UFC v1 configuration"); + let configuration = Configuration::from_server_response(config); + + let context = EvaluationContext::new( + "french_user".into(), + Arc::new( + [ + ("country".into(), "France".into()), + ("age".into(), 32.0.into()), + ] + .into_iter() + .collect(), + ), + ); + + b.iter(|| { + let _assignment = get_assignment( + black_box(Some(&configuration)), + black_box("kill-switch"), + black_box(&context), + None, + now, + ); + let _ = black_box(_assignment); + }) +} + +fn bench_sdk_test_data(c: &mut Criterion) { + let mut group = c.benchmark_group("sdk_test_data"); + group.bench_function("rules-based", bench_sdk_test_data_rules_based); + group.finish(); +} + +fn bench_single_flag(c: &mut Criterion) { + let mut group = c.benchmark_group("single_flag_killswitch"); + group.bench_function("rules-based", bench_single_flag_rules_based); + group.finish(); +} + +criterion_group!(benches, bench_sdk_test_data, bench_single_flag); +criterion_main!(benches); diff --git a/datadog-ffe/src/lib.rs b/datadog-ffe/src/lib.rs new file mode 100644 index 0000000000..1937810d61 --- /dev/null +++ b/datadog-ffe/src/lib.rs @@ -0,0 +1,4 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +pub mod rules_based; diff --git a/datadog-ffe/src/rules_based/attributes.rs b/datadog-ffe/src/rules_based/attributes.rs new file mode 100644 index 0000000000..5581d58d1e --- /dev/null +++ b/datadog-ffe/src/rules_based/attributes.rs @@ -0,0 +1,64 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use std::{borrow::Cow, sync::Arc}; + +use serde::{Deserialize, Serialize}; + +use crate::rules_based::Str; + +/// Attribute for evaluation context. See `From` implementations for initialization. +#[derive(Debug, Clone, PartialEq, PartialOrd, derive_more::From, Serialize, Deserialize)] +#[from(f64, bool, Str, String, &str, Arc, Arc, Cow<'_, str>)] +pub struct Attribute(AttributeValueImpl); +#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize, derive_more::From)] +#[serde(untagged)] +enum AttributeValueImpl { + #[from] + Number(f64), + #[from(forward)] + String(Str), + #[from] + Boolean(bool), + #[from(ignore)] + Null, +} + +impl Attribute { + pub(crate) fn is_null(&self) -> bool { + self == &Attribute(AttributeValueImpl::Null) + } + + /// Try coercing attribute to a number. + /// + /// Number attributes are returned as is. For string attributes, we try to parse them into a + /// number. + pub(crate) fn coerce_to_number(&self) -> Option { + match &self.0 { + AttributeValueImpl::Number(v) => Some(*v), + AttributeValueImpl::String(s) => s.parse().ok(), + _ => None, + } + } + + /// Try coercing attribute to a string. + /// + /// String attributes are returned as is. Number and boolean attributes are converted to string. + pub(crate) fn coerce_to_string(&self) -> Option> { + match &self.0 { + AttributeValueImpl::String(s) => Some(Cow::Borrowed(s)), + AttributeValueImpl::Number(v) => Some(Cow::Owned(v.to_string())), + AttributeValueImpl::Boolean(v) => { + Some(Cow::Borrowed(if *v { "true" } else { "false" })) + } + AttributeValueImpl::Null => None, + } + } + + pub(crate) fn as_str(&self) -> Option<&Str> { + match self { + Attribute(AttributeValueImpl::String(s)) => Some(s), + _ => None, + } + } +} diff --git a/datadog-ffe/src/rules_based/configuration.rs b/datadog-ffe/src/rules_based/configuration.rs new file mode 100644 index 0000000000..3479c32b88 --- /dev/null +++ b/datadog-ffe/src/rules_based/configuration.rs @@ -0,0 +1,53 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use std::borrow::Cow; + +use chrono::{DateTime, Utc}; + +use crate::rules_based::{ufc::UniversalFlagConfig, Str}; + +/// Remote configuration for the feature flagging client. It's a central piece that defines client +/// behavior. +#[derive(Debug)] +pub struct Configuration { + /// Timestamp when configuration was fetched by the SDK. + #[allow(dead_code)] + pub(crate) fetched_at: DateTime, + /// Flags configuration. + pub(crate) flags: UniversalFlagConfig, +} + +impl Configuration { + /// Create a new configuration from server responses. + pub fn from_server_response(config: UniversalFlagConfig) -> Configuration { + let now = Utc::now(); + + Configuration { + fetched_at: now, + flags: config, + } + } + + pub fn created_at(&self) -> DateTime { + self.flags.compiled.created_at + } + + pub fn environment(&self) -> &str { + &self.flags.compiled.environment.name + } + + /// Returns an iterator over all flag keys. Note that this may return both disabled flags and + /// flags with bad configuration. Mostly useful for debugging. + pub fn flag_keys(&self) -> impl Iterator { + self.flags.compiled.flags.keys() + } + + /// Returns bytes representing flags configuration. + /// + /// The return value should be treated as opaque and passed on to another feature flagging + /// client for initialization. + pub fn get_flags_configuration(&self) -> Option> { + Some(Cow::Borrowed(self.flags.to_json())) + } +} diff --git a/datadog-ffe/src/rules_based/error.rs b/datadog-ffe/src/rules_based/error.rs new file mode 100644 index 0000000000..53ed1cd80c --- /dev/null +++ b/datadog-ffe/src/rules_based/error.rs @@ -0,0 +1,108 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use std::sync::Arc; + +use serde::{Deserialize, Serialize}; + +use crate::rules_based::ufc::VariationType; + +/// Represents a result type for operations in the feature flagging SDK. +/// +/// This type alias is used throughout the SDK to indicate the result of operations that may return +/// errors specific to the feature flagging SDK. +/// +/// This `Result` type is a standard Rust `Result` type where the error variant is defined by the +/// ffe-specific [`Error`] enum. +pub type Result = std::result::Result; + +/// Enum representing possible errors that can occur in the feature flagging SDK. +#[derive(thiserror::Error, Debug, Clone)] +#[non_exhaustive] +pub enum Error { + /// Error evaluating a flag. + #[error(transparent)] + EvaluationError(EvaluationError), + + /// Invalid base URL configuration. + #[error("invalid base_url configuration")] + InvalidBaseUrl(#[source] url::ParseError), + + /// The request was unauthorized, possibly due to an invalid API key. + #[error("unauthorized, api_key is likely invalid")] + Unauthorized, + + /// Indicates that the poller thread panicked. This should normally never happen. + #[error("poller thread panicked")] + PollerThreadPanicked, + + /// An I/O error. + #[error(transparent)] + // std::io::Error is not clonable, so we're wrapping it in an Arc. + Io(Arc), +} + +impl From for Error { + fn from(value: std::io::Error) -> Self { + Self::Io(Arc::new(value)) + } +} + +/// Enum representing possible errors that can occur during evaluation. +#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] +#[non_exhaustive] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum EvaluationError { + /// Requested flag has invalid type. + #[error("invalid flag type (expected: {expected:?}, found: {found:?})")] + TypeMismatch { + /// Expected type of the flag. + expected: VariationType, + /// Actual type of the flag. + found: VariationType, + }, + + /// Configuration received from the server is invalid for the SDK. This should normally never + /// happen and is likely a signal that you should update SDK. + #[error("unexpected configuration received from the server")] + UnexpectedConfigurationError, +} + +/// Enum representing all possible reasons that could result in evaluation returning an error or +/// default assignment. +#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub(crate) enum EvaluationFailure { + /// True evaluation error that should be returned to the user. + #[error(transparent)] + Error(EvaluationError), + + /// Configuration has not been fetched yet. + #[error("configuration has not been fetched yet")] + ConfigurationMissing, + + /// The requested flag configuration was not found. It either does not exist or is disabled. + #[error("flag is missing in configuration, it is either unrecognized or disabled")] + FlagUnrecognizedOrDisabled, + + /// Flag is found in configuration but it is disabled. + #[error("flag is disabled")] + FlagDisabled, + + /// Default allocation is matched and is also serving `NULL`, resulting in the default value + /// being assigned. + #[error("default allocation is matched and is serving NULL")] + DefaultAllocationNull, + + #[error("flag resolved to a non-bandit variation")] + NonBanditVariation, + + #[error("no actions were supplied to bandit evaluation")] + NoActionsSuppliedForBandit, +} + +impl From for EvaluationFailure { + fn from(value: EvaluationError) -> EvaluationFailure { + EvaluationFailure::Error(value) + } +} diff --git a/datadog-ffe/src/rules_based/eval/eval_assignment.rs b/datadog-ffe/src/rules_based/eval/eval_assignment.rs new file mode 100644 index 0000000000..aec03e0ab0 --- /dev/null +++ b/datadog-ffe/src/rules_based/eval/eval_assignment.rs @@ -0,0 +1,300 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use chrono::{DateTime, Utc}; + +use crate::rules_based::{ + error::{EvaluationError, EvaluationFailure}, + ufc::{ + Allocation, Assignment, AssignmentReason, CompiledFlagsConfig, Flag, Shard, Split, + Timestamp, VariationType, + }, + Configuration, EvaluationContext, +}; + +/// Evaluate the specified feature flag for the given subject and return assigned variation and +/// an optional assignment event for logging. +pub fn get_assignment( + configuration: Option<&Configuration>, + flag_key: &str, + subject: &EvaluationContext, + expected_type: Option, + now: DateTime, +) -> Result, EvaluationError> { + let Some(config) = configuration else { + log::trace!( + flag_key, + targeting_key = subject.targeting_key(); + "returning default assignment because of: {}", EvaluationFailure::ConfigurationMissing); + return Ok(None); + }; + + config.eval_flag(flag_key, subject, expected_type, now) +} + +impl Configuration { + pub fn eval_flag( + &self, + flag_key: &str, + context: &EvaluationContext, + expected_type: Option, + now: DateTime, + ) -> Result, EvaluationError> { + let result = self + .flags + .compiled + .eval_flag(flag_key, context, expected_type, now); + + match result { + Ok(assignment) => { + log::trace!( + flag_key, + targeting_key = context.targeting_key(), + assignment:serde = assignment.value; + "evaluated a flag"); + Ok(Some(assignment)) + } + + Err(EvaluationFailure::ConfigurationMissing) => { + log::warn!( + flag_key, + targeting_key = context.targeting_key(); + "evaluating a flag before flags configuration has been fetched"); + Ok(None) + } + + Err(EvaluationFailure::Error(err)) => { + log::warn!( + flag_key, + targeting_key = context.targeting_key(); + "error occurred while evaluating a flag: {err}", + ); + Err(err) + } + + // Non-Error failures are considered normal conditions and usually don't need extra + // attention, so we remap them to Ok(None) before returning to the user. + Err(err) => { + log::trace!( + flag_key, + targeting_key = context.targeting_key(); + "returning default assignment because of: {err}"); + Ok(None) + } + } + } +} + +impl CompiledFlagsConfig { + /// Evaluate the flag for the given subject, expecting `expected_type` type. + fn eval_flag( + &self, + flag_key: &str, + subject: &EvaluationContext, + expected_type: Option, + now: DateTime, + ) -> Result { + let flag = self.get_flag(flag_key)?; + + if let Some(ty) = expected_type { + flag.verify_type(ty)?; + } + + flag.eval(subject, now) + } + + fn get_flag(&self, flag_key: &str) -> Result<&Flag, EvaluationFailure> { + self.flags + .get(flag_key) + .ok_or(EvaluationFailure::FlagUnrecognizedOrDisabled)? + .as_ref() + .map_err(Clone::clone) + } +} + +impl Flag { + fn verify_type(&self, ty: VariationType) -> Result<(), EvaluationFailure> { + if self.variation_type == ty { + Ok(()) + } else { + Err(EvaluationFailure::Error(EvaluationError::TypeMismatch { + expected: ty, + found: self.variation_type, + })) + } + } + + fn eval( + &self, + subject: &EvaluationContext, + now: DateTime, + ) -> Result { + let Some((allocation, (split, reason))) = self.allocations.iter().find_map(|allocation| { + let result = allocation.get_matching_split(subject, now); + result + .ok() + .map(|(split, reason)| (allocation, (split, reason))) + }) else { + return Err(EvaluationFailure::DefaultAllocationNull); + }; + + let value = split.value.clone(); + + Ok(Assignment { + value, + variation_key: split.variation_key.clone(), + allocation_key: allocation.key.clone(), + extra_logging: split.extra_logging.clone(), + reason, + do_log: allocation.do_log, + }) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub(super) enum AllocationNonMatchReason { + BeforeStartDate, + AfterEndDate, + FailingRule, + TrafficExposureMiss, +} + +impl Allocation { + fn get_matching_split( + &self, + subject: &EvaluationContext, + now: Timestamp, + ) -> Result<(&Split, AssignmentReason), AllocationNonMatchReason> { + if self.start_at.is_some_and(|t| now < t) { + return Err(AllocationNonMatchReason::BeforeStartDate); + } + if self.end_at.is_some_and(|t| now > t) { + return Err(AllocationNonMatchReason::AfterEndDate); + } + + let is_allowed_by_rules = + self.rules.is_empty() || self.rules.iter().any(|rule| rule.eval(subject)); + if !is_allowed_by_rules { + return Err(AllocationNonMatchReason::FailingRule); + } + + let split = self + .splits + .iter() + .find(|split| { + let matches = split.matches(subject.targeting_key()); + matches + }) + .ok_or(AllocationNonMatchReason::TrafficExposureMiss)?; + + // Determine the reason for assignment + let reason = if !self.rules.is_empty() || self.start_at.is_some() || self.end_at.is_some() { + AssignmentReason::TargetingMatch + } else if self.splits.len() == 1 && self.splits[0].shards.is_empty() { + AssignmentReason::Static + } else { + AssignmentReason::Split + }; + + Ok((split, reason)) + } +} + +impl Split { + /// Return `true` if `targeting_key` matches the given split. + /// + /// To match a split, subject must match all underlying shards. + fn matches(&self, targeting_key: &str) -> bool { + self.shards.iter().all(|shard| shard.matches(targeting_key)) + } +} + +impl Shard { + /// Return `true` if `targeting_key` matches the given shard. + fn matches(&self, targeting_key: &str) -> bool { + let h = self.sharder.shard(&[targeting_key]); + + self.ranges.iter().any(|range| range.contains(h)) + } +} + +#[cfg(test)] +mod tests { + use std::{ + collections::HashMap, + fs::{self, File}, + sync::Arc, + }; + + use chrono::Utc; + use serde::{Deserialize, Serialize}; + + use crate::rules_based::{ + eval::get_assignment, + ufc::{AssignmentValue, UniversalFlagConfig, VariationType}, + Attribute, Configuration, EvaluationContext, Str, + }; + + #[derive(Debug, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + struct TestCase { + flag: String, + variation_type: VariationType, + default_value: serde_json::Value, + targeting_key: Str, + attributes: Arc>, + result: TestResult, + } + + #[derive(Debug, Serialize, Deserialize)] + struct TestResult { + value: serde_json::Value, + } + + #[test] + fn evaluation_sdk_test_data() { + let _ = env_logger::builder().is_test(true).try_init(); + + let config = + UniversalFlagConfig::from_json(std::fs::read("tests/data/flags-v1.json").unwrap()) + .unwrap(); + let config = Configuration::from_server_response(config); + let now = Utc::now(); + + for entry in fs::read_dir("tests/data/tests/").unwrap() { + let entry = entry.unwrap(); + println!("Processing test file: {:?}", entry.path()); + + let f = File::open(entry.path()).unwrap(); + let test_cases: Vec = serde_json::from_reader(f).unwrap(); + + for test_case in test_cases { + let default_assignment = + AssignmentValue::from_wire(test_case.variation_type, test_case.default_value) + .unwrap(); + + print!("test subject {:?} ... ", test_case.targeting_key); + let subject = EvaluationContext::new(test_case.targeting_key, test_case.attributes); + let result = get_assignment( + Some(&config), + &test_case.flag, + &subject, + Some(test_case.variation_type), + now, + ) + .unwrap_or(None); + + let result_assingment = result + .as_ref() + .map(|assignment| &assignment.value) + .unwrap_or(&default_assignment); + let expected_assignment = + AssignmentValue::from_wire(test_case.variation_type, test_case.result.value) + .unwrap(); + + assert_eq!(result_assingment, &expected_assignment); + println!("ok"); + } + } + } +} diff --git a/datadog-ffe/src/rules_based/eval/eval_rules.rs b/datadog-ffe/src/rules_based/eval/eval_rules.rs new file mode 100644 index 0000000000..6b7b68efbe --- /dev/null +++ b/datadog-ffe/src/rules_based/eval/eval_rules.rs @@ -0,0 +1,292 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use crate::rules_based::{ + ufc::{ComparisonOperator, Condition, ConditionCheck, RuleWire, TryParse}, + Attribute, EvaluationContext, +}; + +impl RuleWire { + pub(super) fn eval(&self, subject: &EvaluationContext) -> bool { + self.conditions.iter().all(|condition| match condition { + TryParse::Parsed(condition) => condition.eval(subject), + TryParse::ParseFailed(_) => false, + }) + } +} + +impl Condition { + fn eval(&self, subject: &EvaluationContext) -> bool { + let attribute = subject.get_attribute(self.attribute.as_ref()); + self.check.eval(attribute) + } +} + +impl ConditionCheck { + /// Check if `attribute` matches. + fn eval(&self, attribute: Option<&Attribute>) -> bool { + self.try_eval(attribute).unwrap_or(false) + } + + /// Try applying `Operator` to the values, returning `None` if the operator cannot be applied. + fn try_eval(&self, attribute: Option<&Attribute>) -> Option { + let result = match self { + ConditionCheck::Comparison { + operator, + comparand, + } => { + let attribute = attribute?.clone(); + let attribute = attribute.coerce_to_number()?; + let ordering = attribute.partial_cmp(comparand)?; + match operator { + ComparisonOperator::Gte => ordering.is_gt() || ordering.is_eq(), + ComparisonOperator::Gt => ordering.is_gt(), + ComparisonOperator::Lte => ordering.is_lt() || ordering.is_eq(), + ComparisonOperator::Lt => ordering.is_lt(), + } + } + ConditionCheck::Regex { + expected_match, + regex, + } => regex.is_match(attribute?.coerce_to_string()?.as_ref()) == *expected_match, + ConditionCheck::Membership { + expected_membership, + values, + } => { + let s = attribute?.coerce_to_string()?; + let s = s.as_ref(); + values.into_iter().any(|it| it.as_ref() == s) == *expected_membership + } + ConditionCheck::Null { expected_null } => { + let is_present = attribute.is_some_and(|it| !it.is_null()); + let is_null = !is_present; + is_null == *expected_null + } + }; + + Some(result) + } +} + +#[cfg(test)] +mod tests { + use std::{collections::HashMap, sync::Arc}; + + use crate::rules_based::{ + ufc::{ComparisonOperator, Condition, ConditionCheck, RuleWire}, + EvaluationContext, + }; + + #[test] + fn matches_regex() { + let check = ConditionCheck::Regex { + expected_match: true, + regex: "^test.*".try_into().unwrap(), + }; + assert!(check.eval(Some(&"test@example.com".into()))); + assert!(!check.eval(Some(&"example@test.com".into()))); + assert!(!check.eval(None)); + } + + #[test] + fn not_matches_regex() { + let check = ConditionCheck::Regex { + expected_match: false, + regex: "^test.*".try_into().unwrap(), + }; + assert!(!check.eval(Some(&"test@example.com".into()))); + assert!(check.eval(Some(&"example@test.com".into()))); + assert!(!check.eval(None)); + } + + #[test] + fn one_of() { + let check = ConditionCheck::Membership { + expected_membership: true, + values: ["alice".into(), "bob".into()].into(), + }; + assert!(check.eval(Some(&"alice".into()))); + assert!(check.eval(Some(&"bob".into()))); + assert!(!check.eval(Some(&"charlie".into()))); + } + + #[test] + fn not_one_of() { + let check = ConditionCheck::Membership { + expected_membership: false, + values: ["alice".into(), "bob".into()].into(), + }; + assert!(!check.eval(Some(&"alice".into()))); + assert!(!check.eval(Some(&"bob".into()))); + assert!(check.eval(Some(&"charlie".into()))); + + // NOT_ONE_OF fails when attribute is not specified + assert!(!check.eval(None)); + } + + #[test] + fn one_of_int() { + assert!(ConditionCheck::Membership { + expected_membership: true, + values: ["42".into()].into() + } + .eval(Some(&42.0.into()))); + } + + #[test] + fn one_of_bool() { + let true_check = ConditionCheck::Membership { + expected_membership: true, + values: ["true".into()].into(), + }; + let false_check = ConditionCheck::Membership { + expected_membership: true, + values: ["false".into()].into(), + }; + assert!(true_check.eval(Some(&true.into()))); + assert!(false_check.eval(Some(&false.into()))); + assert!(!true_check.eval(Some(&1.0.into()))); + assert!(!false_check.eval(Some(&0.0.into()))); + assert!(!true_check.eval(None)); + assert!(!false_check.eval(None)); + } + + #[test] + fn is_null() { + assert!(ConditionCheck::Null { + expected_null: true + } + .eval(None)); + assert!(!ConditionCheck::Null { + expected_null: true + } + .eval(Some(&10.0.into()))); + } + + #[test] + fn is_not_null() { + assert!(!ConditionCheck::Null { + expected_null: false + } + .eval(None)); + assert!(ConditionCheck::Null { + expected_null: false + } + .eval(Some(&10.0.into()))); + } + + #[test] + fn gte() { + let check = ConditionCheck::Comparison { + operator: ComparisonOperator::Gte, + comparand: 18.0, + }; + assert!(check.eval(Some(&18.0.into()))); + assert!(!check.eval(Some(&17.0.into()))); + } + #[test] + fn gt() { + let check = ConditionCheck::Comparison { + operator: ComparisonOperator::Gt, + comparand: 18.0, + }; + assert!(check.eval(Some(&19.0.into()))); + assert!(!check.eval(Some(&18.0.into()))); + } + #[test] + fn lte() { + let check = ConditionCheck::Comparison { + operator: ComparisonOperator::Lte, + comparand: 18.0, + }; + assert!(check.eval(Some(&18.0.into()))); + assert!(!check.eval(Some(&19.0.into()))); + } + #[test] + fn lt() { + let check = ConditionCheck::Comparison { + operator: ComparisonOperator::Lt, + comparand: 18.0, + }; + assert!(check.eval(Some(&17.0.into()))); + assert!(!check.eval(Some(&18.0.into()))); + } + + #[test] + fn empty_rule() { + let rule = RuleWire { conditions: vec![] }; + assert!(rule.eval(&EvaluationContext::new("key".into(), Default::default()))); + } + + #[test] + fn single_condition_rule() { + let rule = RuleWire { + conditions: vec![Condition { + attribute: "age".into(), + check: ConditionCheck::Comparison { + operator: ComparisonOperator::Gt, + comparand: 10.0, + }, + } + .into()], + }; + assert!(rule.eval(&EvaluationContext::new( + "key".into(), + Arc::new(HashMap::from([("age".into(), 11.0.into())])) + ))); + } + + #[test] + fn two_condition_rule() { + let rule = RuleWire { + conditions: vec![ + Condition { + attribute: "age".into(), + check: ConditionCheck::Comparison { + operator: ComparisonOperator::Gt, + comparand: 18.0, + }, + } + .into(), + Condition { + attribute: "age".into(), + check: ConditionCheck::Comparison { + operator: ComparisonOperator::Lt, + comparand: 100.0, + }, + } + .into(), + ], + }; + assert!(rule.eval(&EvaluationContext::new( + "key".into(), + Arc::new(HashMap::from([("age".into(), 20.0.into())])) + ))); + assert!(!rule.eval(&EvaluationContext::new( + "key".into(), + Arc::new(HashMap::from([("age".into(), 17.0.into())])) + ))); + assert!(!rule.eval(&EvaluationContext::new( + "key".into(), + Arc::new(HashMap::from([("age".into(), 110.0.into())])) + ))); + } + + #[test] + fn missing_attribute() { + let rule = RuleWire { + conditions: vec![Condition { + attribute: "age".into(), + check: ConditionCheck::Comparison { + operator: ComparisonOperator::Gt, + comparand: 10.0, + }, + } + .into()], + }; + assert!(!rule.eval(&EvaluationContext::new( + "key".into(), + Arc::new(HashMap::from([("name".into(), "alice".into())])) + ))); + } +} diff --git a/datadog-ffe/src/rules_based/eval/evaluation_context.rs b/datadog-ffe/src/rules_based/eval/evaluation_context.rs new file mode 100644 index 0000000000..5e8b7bd83e --- /dev/null +++ b/datadog-ffe/src/rules_based/eval/evaluation_context.rs @@ -0,0 +1,51 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use std::collections::HashMap; +use std::sync::Arc; + +use crate::rules_based::Str; + +use crate::rules_based::Attribute; + +/// `Subject` is a bundle of subject attributes and a key. +#[derive(Debug)] +pub struct EvaluationContext { + /// Subject key encoded as attribute value. Known to be `AttributeValue::String`. This is + /// done to allow returning subject key as an attribute when rule references "id". + targeting_key: Attribute, + attributes: Arc>, +} + +impl EvaluationContext { + pub fn new(key: Str, attributes: Arc>) -> EvaluationContext { + EvaluationContext { + targeting_key: Attribute::from(key), + attributes, + } + } + + pub fn targeting_key(&self) -> &Str { + let Some(s) = self.targeting_key.as_str() else { + unreachable!("Subject::key is always encoded as string attribute"); + }; + s + } + + /// Get subject attribute. + /// + /// If attribute `name` is `"id"` and there's no explicit attribute with this name, return + /// subject key instead. + pub fn get_attribute(&self, name: &str) -> Option<&Attribute> { + let value = self.attributes.get(name); + if value.is_some() { + return value; + } + + if name == "id" { + return Some(&self.targeting_key); + } + + None + } +} diff --git a/datadog-ffe/src/rules_based/eval/mod.rs b/datadog-ffe/src/rules_based/eval/mod.rs new file mode 100644 index 0000000000..5cbd8dd44a --- /dev/null +++ b/datadog-ffe/src/rules_based/eval/mod.rs @@ -0,0 +1,9 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +mod eval_assignment; +mod eval_rules; +mod evaluation_context; + +pub use eval_assignment::get_assignment; +pub use evaluation_context::EvaluationContext; diff --git a/datadog-ffe/src/rules_based/mod.rs b/datadog-ffe/src/rules_based/mod.rs new file mode 100644 index 0000000000..1c2747f6a7 --- /dev/null +++ b/datadog-ffe/src/rules_based/mod.rs @@ -0,0 +1,19 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +mod attributes; +mod configuration; +mod error; +mod eval; +mod sharder; +mod str; +mod timestamp; +mod ufc; + +pub use attributes::Attribute; +pub use configuration::Configuration; +pub use error::{Error, EvaluationError, Result}; +pub use eval::{get_assignment, EvaluationContext}; +pub use str::Str; +pub use timestamp::{now, Timestamp}; +pub use ufc::{Assignment, AssignmentReason, AssignmentValue, UniversalFlagConfig, VariationType}; diff --git a/datadog-ffe/src/rules_based/sharder.rs b/datadog-ffe/src/rules_based/sharder.rs new file mode 100644 index 0000000000..996b2c9221 --- /dev/null +++ b/datadog-ffe/src/rules_based/sharder.rs @@ -0,0 +1,41 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +//! Sharder implementation. +use md5; + +/// A sharder that has part of its hash pre-computed with the given salt. +#[derive(Clone)] +pub struct PreSaltedSharder { + ctx: md5::Context, + total_shards: u32, +} + +impl PreSaltedSharder { + pub fn new(salt: &[impl AsRef<[u8]>], total_shards: u32) -> PreSaltedSharder { + let mut ctx = md5::Context::new(); + for s in salt { + ctx.consume(s); + } + PreSaltedSharder { ctx, total_shards } + } + + pub fn shard(&self, input: &[impl AsRef<[u8]>]) -> u32 { + let mut ctx = self.ctx.clone(); + for i in input { + ctx.consume(i); + } + let hash = ctx.compute(); + let value = u32::from_be_bytes(hash[0..4].try_into().unwrap()); + value % self.total_shards + } +} + +impl std::fmt::Debug for PreSaltedSharder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("PreSaltedSharder") + .field("ctx", &"...") + .field("total_shards", &self.total_shards) + .finish() + } +} diff --git a/datadog-ffe/src/rules_based/str.rs b/datadog-ffe/src/rules_based/str.rs new file mode 100644 index 0000000000..ae9a1b6404 --- /dev/null +++ b/datadog-ffe/src/rules_based/str.rs @@ -0,0 +1,113 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +//! Some string type helpers. +//! +//! Moved into a separate module, so we could experiment with different representations. + +use std::{borrow::Cow, string::FromUtf8Error, sync::Arc}; + +use faststr::FastStr; + +use serde::{Deserialize, Serialize}; + +/// `Str` is a string optimized for cheap cloning. The implementation is hidden, so we can update it +/// if we find faster implementation. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] +#[serde(transparent)] +pub struct Str(FastStr); + +impl Str { + pub fn new>(s: S) -> Str { + Str(FastStr::new(s)) + } + + pub fn from_static_str(s: &'static str) -> Str { + Str(FastStr::from_static_str(s)) + } + + pub fn as_str(&self) -> &str { + &self.0 + } +} + +impl std::fmt::Debug for Str { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl std::fmt::Display for Str { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.0) + } +} + +macro_rules! impl_from_faststr { + ($ty:ty) => { + impl From<$ty> for Str { + fn from(value: $ty) -> Str { + Str(value.into()) + } + } + }; +} + +impl_from_faststr!(Arc); +impl_from_faststr!(Arc); +impl_from_faststr!(String); + +impl<'a> From<&'a str> for Str { + fn from(value: &'a str) -> Str { + Str(FastStr::new(value)) + } +} + +impl<'a> From> for Str { + fn from(value: Cow<'a, str>) -> Str { + match value { + Cow::Borrowed(s) => s.into(), + Cow::Owned(s) => s.into(), + } + } +} + +impl TryFrom> for Str { + type Error = FromUtf8Error; + + fn try_from(value: Vec) -> Result { + String::from_utf8(value).map(Into::into) + } +} + +impl AsRef for Str { + fn as_ref(&self) -> &str { + &self.0 + } +} + +impl AsRef<[u8]> for Str { + fn as_ref(&self) -> &[u8] { + self.0.as_bytes() + } +} + +impl std::ops::Deref for Str { + type Target = str; + + fn deref(&self) -> &Self::Target { + self.as_ref() + } +} + +impl std::borrow::Borrow for Str { + fn borrow(&self) -> &str { + self.as_str() + } +} + +impl log::kv::ToValue for Str { + fn to_value(&self) -> log::kv::Value<'_> { + log::kv::Value::from_display(self) + } +} diff --git a/datadog-ffe/src/rules_based/timestamp.rs b/datadog-ffe/src/rules_based/timestamp.rs new file mode 100644 index 0000000000..f549418a35 --- /dev/null +++ b/datadog-ffe/src/rules_based/timestamp.rs @@ -0,0 +1,11 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +//! A simple wrapper around `chrono`, so users don’t have to depend on it directly. +use chrono::{DateTime, Utc}; + +pub type Timestamp = DateTime; + +pub fn now() -> Timestamp { + Utc::now() +} diff --git a/datadog-ffe/src/rules_based/ufc/assignment.rs b/datadog-ffe/src/rules_based/ufc/assignment.rs new file mode 100644 index 0000000000..18cefb96a3 --- /dev/null +++ b/datadog-ffe/src/rules_based/ufc/assignment.rs @@ -0,0 +1,301 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use std::collections::HashMap; +use std::sync::Arc; + +use serde::{Deserialize, Serialize}; + +use crate::rules_based::Str; + +use super::VariationType; + +/// Reason for assignment evaluation result. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum AssignmentReason { + /// Assignment was made based on targeting rules or time bounds. + TargetingMatch, + /// Assignment was made based on traffic split allocation. + Split, + /// Assignment was made as a static/default value. + Static, +} + +/// Result of assignment evaluation. +#[derive(Debug, Serialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Assignment { + /// Assignment value that should be returned to the user. + pub value: AssignmentValue, + /// The variation key that was selected for this assignment. + pub variation_key: Str, + /// The allocation key that was matched for this assignment. + pub allocation_key: Str, + /// The reason for this assignment. + pub reason: AssignmentReason, + + /// Whether this assignment is part of an experiment and should be logged. + pub do_log: bool, + /// Extra logging information for this assignment. + pub extra_logging: Arc>, +} + +/// Enum representing values assigned to a subject as a result of feature flag evaluation. +/// +/// # Serialization +/// +/// When serialized to JSON, serialized as a two-field object with `type` and `value`. Type is one +/// of "STRING", "INTEGER", "FLOAT", "BOOLEAN", or "JSON". Value is either string, number, +/// boolean, or arbitrary JSON value. +/// +/// Example: +/// ```json +/// {"type":"JSON","value":{"hello":"world"}} +/// ``` +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE", tag = "type", content = "value")] +pub enum AssignmentValue { + /// A string value. + String(Str), + /// An integer value. + Integer(i64), + /// A numeric value (floating-point). + Float(f64), + /// A boolean value. + Boolean(bool), + /// Arbitrary JSON value. + Json(Arc), +} + +impl AssignmentValue { + pub(crate) fn from_wire( + ty: VariationType, + value: serde_json::Value, + ) -> Option { + use serde_json::Value; + Some(match (ty, value) { + (VariationType::String, Value::String(s)) => AssignmentValue::String(s.into()), + (VariationType::Integer, Value::Number(n)) => AssignmentValue::Integer(n.as_i64()?), + (VariationType::Numeric, Value::Number(n)) => AssignmentValue::Float(n.as_f64()?), + (VariationType::Boolean, Value::Bool(v)) => AssignmentValue::Boolean(v), + (VariationType::Json, v) => AssignmentValue::Json(Arc::new(v)), + // Type mismatch + _ => return None, + }) + } + + /// Checks if the assignment value is of type String. + /// + /// # Returns + /// - `true` if the value is of type String, otherwise `false`. + /// + /// # Examples + /// ``` + /// # use datadog_ffe::rules_based::AssignmentValue; + /// let value = AssignmentValue::String("example".into()); + /// assert_eq!(value.is_string(), true); + /// ``` + pub fn is_string(&self) -> bool { + self.as_str().is_some() + } + /// Returns the assignment value as a string if it is of type String. + /// + /// # Returns + /// - The string value if the assignment value is of type String, otherwise `None`. + /// + /// # Examples + /// ``` + /// # use datadog_ffe::rules_based::AssignmentValue; + /// let value = AssignmentValue::String("example".into()); + /// assert_eq!(value.as_str(), Some("example")); + /// ``` + pub fn as_str(&self) -> Option<&str> { + match self { + AssignmentValue::String(s) => Some(s), + _ => None, + } + } + + /// Extracts the assignment value as a string if it is of type String. + /// + /// # Returns + /// - The string value if the assignment value is of type String, otherwise `None`. + /// + /// # Examples + /// ``` + /// # use datadog_ffe::rules_based::AssignmentValue; + /// let value = AssignmentValue::String("example".into()); + /// assert_eq!(value.to_string(), Some("example".into())); + /// ``` + pub fn to_string(self) -> Option { + match self { + AssignmentValue::String(s) => Some(s), + _ => None, + } + } + + /// Checks if the assignment value is of type Integer. + /// + /// # Returns + /// - `true` if the value is of type Integer, otherwise `false`. + /// + /// # Examples + /// ``` + /// # use datadog_ffe::rules_based::AssignmentValue; + /// let value = AssignmentValue::Integer(42); + /// assert_eq!(value.is_integer(), true); + /// ``` + pub fn is_integer(&self) -> bool { + self.as_integer().is_some() + } + /// Returns the assignment value as an integer if it is of type Integer. + /// + /// # Returns + /// - The integer value if the assignment value is of type Integer, otherwise `None`. + /// + /// # Examples + /// ``` + /// # use datadog_ffe::rules_based::AssignmentValue; + /// let value = AssignmentValue::Integer(42); + /// assert_eq!(value.as_integer(), Some(42)); + /// ``` + pub fn as_integer(&self) -> Option { + match self { + AssignmentValue::Integer(i) => Some(*i), + _ => None, + } + } + + /// Checks if the assignment value is of type Numeric. + /// + /// # Returns + /// - `true` if the value is of type Numeric, otherwise `false`. + /// + /// # Examples + /// ``` + /// # use datadog_ffe::rules_based::AssignmentValue; + /// let value = AssignmentValue::Float(3.14); + /// assert_eq!(value.is_float(), true); + /// ``` + pub fn is_float(&self) -> bool { + self.as_float().is_some() + } + /// Returns the assignment value as a numeric value if it is of type Numeric. + /// + /// # Returns + /// - The numeric value if the assignment value is of type Numeric, otherwise `None`. + /// + /// # Examples + /// ``` + /// # use datadog_ffe::rules_based::AssignmentValue; + /// let value = AssignmentValue::Float(3.14); + /// assert_eq!(value.as_float(), Some(3.14)); + /// ``` + pub fn as_float(&self) -> Option { + match self { + Self::Float(n) => Some(*n), + _ => None, + } + } + + /// Checks if the assignment value is of type Boolean. + /// + /// # Returns + /// - `true` if the value is of type Boolean, otherwise `false`. + /// + /// # Examples + /// ``` + /// # use datadog_ffe::rules_based::AssignmentValue; + /// let value = AssignmentValue::Boolean(true); + /// assert_eq!(value.is_boolean(), true); + /// ``` + pub fn is_boolean(&self) -> bool { + self.as_boolean().is_some() + } + /// Returns the assignment value as a boolean if it is of type Boolean. + /// + /// # Returns + /// - The boolean value if the assignment value is of type Boolean, otherwise `None`. + /// + /// # Examples + /// ``` + /// # use datadog_ffe::rules_based::AssignmentValue; + /// let value = AssignmentValue::Boolean(true); + /// assert_eq!(value.as_boolean(), Some(true)); + /// ``` + pub fn as_boolean(&self) -> Option { + match self { + AssignmentValue::Boolean(b) => Some(*b), + _ => None, + } + } + + /// Checks if the assignment value is of type Json. + /// + /// # Returns + /// - `true` if the value is of type Json, otherwise `false`. + pub fn is_json(&self) -> bool { + self.as_json().is_some() + } + /// Returns the assignment value as a JSON value if it is of type Json. + /// + /// # Returns + /// - The JSON value if the assignment value is of type Json, otherwise `None`. + pub fn as_json(&self) -> Option<&serde_json::Value> { + match self { + Self::Json(value) => Some(value), + _ => None, + } + } + /// Extracts the assignment value as a JSON value if it is of type Json. + /// + /// # Returns + /// - The JSON value if the assignment value is of type Json, otherwise `None`. + pub fn to_json(self) -> Option> { + match self { + Self::Json(value) => Some(value), + _ => None, + } + } + + /// Returns the type of the variation as a string. + /// + /// # Returns + /// - A string representing the type of the variation ("STRING", "INTEGER", "NUMERIC", + /// "BOOLEAN", or "JSON"). + /// + /// # Examples + /// ``` + /// # use datadog_ffe::rules_based::AssignmentValue; + /// # use datadog_ffe::rules_based::VariationType; + /// let value = AssignmentValue::String("example".into()); + /// assert_eq!(value.variation_type(), VariationType::String); + /// ``` + pub fn variation_type(&self) -> VariationType { + match self { + AssignmentValue::String(_) => VariationType::String, + AssignmentValue::Integer(_) => VariationType::Integer, + AssignmentValue::Float(_) => VariationType::Numeric, + AssignmentValue::Boolean(_) => VariationType::Boolean, + AssignmentValue::Json(_) => VariationType::Json, + } + } + + /// Returns the raw value of the variation. + /// + /// # Returns + /// - A JSON Value containing the variation value. + pub fn variation_value(&self) -> serde_json::Value { + use serde_json::{Number, Value}; + match self { + AssignmentValue::String(s) => Value::String(s.to_string()), + AssignmentValue::Integer(i) => Value::Number((*i).into()), + AssignmentValue::Float(n) => { + Value::Number(Number::from_f64(*n).expect("value should not be infinite/NaN")) + } + AssignmentValue::Boolean(b) => Value::Bool(*b), + AssignmentValue::Json(value) => value.as_ref().clone(), + } + } +} diff --git a/datadog-ffe/src/rules_based/ufc/compiled_flag_config.rs b/datadog-ffe/src/rules_based/ufc/compiled_flag_config.rs new file mode 100644 index 0000000000..93b906b79f --- /dev/null +++ b/datadog-ffe/src/rules_based/ufc/compiled_flag_config.rs @@ -0,0 +1,202 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use std::{collections::HashMap, sync::Arc}; + +use serde::Deserialize; + +use crate::rules_based::{ + error::EvaluationFailure, sharder::PreSaltedSharder, Error, EvaluationError, Str, +}; + +use super::{ + AllocationWire, AssignmentValue, Environment, FlagWire, RuleWire, ShardRange, ShardWire, + SplitWire, Timestamp, UniversalFlagConfigWire, VariationType, +}; + +#[derive(Debug)] +pub struct UniversalFlagConfig { + /// Original JSON the configuration was compiled from. + pub(crate) wire_json: Vec, + pub(crate) compiled: CompiledFlagsConfig, +} + +#[derive(Debug, Deserialize)] +#[serde(from = "UniversalFlagConfigWire")] +pub(crate) struct CompiledFlagsConfig { + /// When configuration was last updated. + #[allow(dead_code)] + pub created_at: Timestamp, + /// Environment this configuration belongs to. + pub environment: Environment, + /// Flags configuration. + /// + /// For flags that failed to parse or are disabled, we store the evaluation failure directly. + pub flags: HashMap>, +} + +#[derive(Debug)] +pub(crate) struct Flag { + pub variation_type: VariationType, + pub allocations: Box<[Allocation]>, +} + +#[derive(Debug)] +pub(crate) struct Allocation { + pub key: Str, + pub start_at: Option, + pub end_at: Option, + pub rules: Box<[RuleWire]>, + pub splits: Box<[Split]>, + pub do_log: bool, +} + +#[derive(Debug)] +pub(crate) struct Split { + pub shards: Vec, + pub variation_key: Str, + pub extra_logging: Arc>, + pub value: AssignmentValue, +} + +#[derive(Debug, Clone)] +pub(crate) struct Shard { + pub sharder: PreSaltedSharder, + pub ranges: Box<[ShardRange]>, +} + +impl UniversalFlagConfig { + pub fn from_json(json: Vec) -> Result { + let config: CompiledFlagsConfig = serde_json::from_slice(&json).map_err(|err| { + log::warn!("failed to compile flag configuration: {err:?}"); + Error::EvaluationError(EvaluationError::UnexpectedConfigurationError) + })?; + Ok(UniversalFlagConfig { + wire_json: json, + compiled: config, + }) + } + + pub fn to_json(&self) -> &[u8] { + &self.wire_json + } +} + +impl From for CompiledFlagsConfig { + fn from(config: UniversalFlagConfigWire) -> Self { + let flags = config + .data + .attributes + .flags + .into_iter() + .map(|(key, flag)| { + ( + key, + Option::from(flag) + .ok_or(EvaluationFailure::Error( + EvaluationError::UnexpectedConfigurationError, + )) + .and_then(compile_flag), + ) + }) + .collect(); + + CompiledFlagsConfig { + created_at: config.data.attributes.created_at.into(), + environment: config.data.attributes.environment, + flags, + } + } +} + +fn compile_flag(flag: FlagWire) -> Result { + if !flag.enabled { + return Err(EvaluationFailure::FlagDisabled); + } + + let variation_values = flag + .variations + .into_values() + .map(|variation| { + let assignment_value = AssignmentValue::from_wire(flag.variation_type, variation.value) + .ok_or(EvaluationError::UnexpectedConfigurationError)?; + + Ok((variation.key, assignment_value)) + }) + .collect::, EvaluationError>>()?; + + let allocations = flag + .allocations + .into_iter() + .map(|allocation| compile_allocation(allocation, &variation_values)) + .collect::>()?; + + Ok(Flag { + variation_type: flag.variation_type, + allocations, + }) +} + +fn compile_allocation( + allocation: AllocationWire, + variation_values: &HashMap, +) -> Result { + let splits = allocation + .splits + .into_iter() + .map(|split| compile_split(split, variation_values)) + .collect::>()?; + Ok(Allocation { + key: allocation.key, + start_at: allocation.start_at, + end_at: allocation.end_at, + rules: allocation.rules.unwrap_or_default(), + splits, + do_log: allocation.do_log, + }) +} + +fn compile_split( + split: SplitWire, + variation_values: &HashMap, +) -> Result { + let shards = split + .shards + .into_iter() + // `compile_shard` may return `None` for shards that are + // "insignificant", meaning that they *always* match, so they don't even + // need to be checked. We filter out such shards here with + // `.filter_map()`. + .filter_map(compile_shard) + .collect(); + + let extra_logging = split.extra_logging.unwrap_or_default(); + + let result = variation_values + .get(&split.variation_key) + .cloned() + .ok_or(EvaluationError::UnexpectedConfigurationError)?; + + Ok(Split { + shards, + variation_key: split.variation_key, + extra_logging, + value: result, + }) +} + +fn compile_shard(shard: ShardWire) -> Option { + if shard.ranges.contains(&ShardRange { + start: 0, + end: shard.total_shards, + }) { + // The shard is "insignificant" because it always matches, so we don't need to waste time + // checking it. + None + } else { + Some(Shard { + sharder: PreSaltedSharder::new(&[shard.salt.as_bytes(), b"-"], shard.total_shards), + ranges: shard.ranges, + }) + } +} diff --git a/datadog-ffe/src/rules_based/ufc/mod.rs b/datadog-ffe/src/rules_based/ufc/mod.rs new file mode 100644 index 0000000000..86d27b4b1c --- /dev/null +++ b/datadog-ffe/src/rules_based/ufc/mod.rs @@ -0,0 +1,11 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +//! Universal Flag Configuration. +mod assignment; +mod compiled_flag_config; +mod models; + +pub use assignment::{Assignment, AssignmentReason, AssignmentValue}; +pub use compiled_flag_config::*; +pub use models::*; diff --git a/datadog-ffe/src/rules_based/ufc/models.rs b/datadog-ffe/src/rules_based/ufc/models.rs new file mode 100644 index 0000000000..a884e0862d --- /dev/null +++ b/datadog-ffe/src/rules_based/ufc/models.rs @@ -0,0 +1,574 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use std::{collections::HashMap, sync::Arc}; + +use regex::Regex; +use serde::{Deserialize, Serialize}; + +use crate::rules_based::{Error, EvaluationError, Str}; + +#[allow(missing_docs)] +pub type Timestamp = crate::rules_based::timestamp::Timestamp; + +// Temporary workaround till we figure out one proper format +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(untagged)] +pub enum WireTimestamp { + Iso8601(Timestamp), + UnixMs(i64), +} + +impl From for Timestamp { + fn from(value: WireTimestamp) -> Self { + match value { + WireTimestamp::Iso8601(ts) => ts, + WireTimestamp::UnixMs(unix) => { + Timestamp::from_timestamp_millis(unix).expect("timestamp should be in range") + } + } + } +} + +/// JSON API wrapper for Universal Flag Configuration. +#[derive(Debug, Serialize, Deserialize, Clone)] +pub(crate) struct UniversalFlagConfigWire { + /// JSON API data envelope. + pub data: UniversalFlagConfigData, +} + +/// JSON API data structure for Universal Flag Configuration. +#[derive(Debug, Serialize, Deserialize, Clone)] +pub(crate) struct UniversalFlagConfigData { + /// JSON API type field. + #[serde(rename = "type")] + pub data_type: String, + /// JSON API id field. + pub id: String, + /// JSON API attributes containing the actual UFC data. + pub attributes: UniversalFlagConfigAttributes, +} + +/// Universal Flag Configuration attributes. This contains the actual flag configuration data. +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub(crate) struct UniversalFlagConfigAttributes { + /// When configuration was last updated. + pub created_at: WireTimestamp, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub format: Option, + /// Environment this configuration belongs to. + pub environment: Environment, + /// Flags configuration. + /// + /// Value is wrapped in `TryParse` so that if we fail to parse one flag (e.g., new server + /// format), we can still serve other flags. + pub flags: HashMap>, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum ConfigurationFormat { + Client, + Server, + Precomputed, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Environment { + /// Name of the environment. + pub name: Str, +} + +/// `TryParse` allows the subfield to fail parsing without failing the parsing of the whole +/// structure. +/// +/// This can be helpful to isolate errors in a subtree. e.g., if configuration for one flag parses, +/// the rest of the flags are still usable. +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(untagged)] +pub enum TryParse { + /// Successfully parsed. + Parsed(T), + /// Parsing failed. + ParseFailed(serde_json::Value), +} +impl From for TryParse { + fn from(value: T) -> TryParse { + TryParse::Parsed(value) + } +} +impl From> for Option { + fn from(value: TryParse) -> Self { + match value { + TryParse::Parsed(v) => Some(v), + TryParse::ParseFailed(_) => None, + } + } +} +impl<'a, T> From<&'a TryParse> for Option<&'a T> { + fn from(value: &TryParse) -> Option<&T> { + match value { + TryParse::Parsed(v) => Some(v), + TryParse::ParseFailed(_) => None, + } + } +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +#[allow(missing_docs)] +pub(crate) struct FlagWire { + pub key: Str, + pub enabled: bool, + pub variation_type: VariationType, + pub variations: HashMap, + pub allocations: Vec, +} + +/// Type of the variation. +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +#[allow(missing_docs)] +pub enum VariationType { + String, + Integer, + Numeric, + Boolean, + Json, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +#[allow(missing_docs)] +pub(crate) struct VariationWire { + pub key: Str, + pub value: serde_json::Value, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +#[allow(missing_docs)] +pub(crate) struct AllocationWire { + pub key: Str, + #[serde(default)] + pub rules: Option>, + #[serde(default)] + pub start_at: Option, + #[serde(default)] + pub end_at: Option, + pub splits: Vec, + #[serde(default = "default_do_log")] + pub do_log: bool, +} + +fn default_do_log() -> bool { + true +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[allow(missing_docs)] +pub(crate) struct RuleWire { + pub conditions: Vec>, +} + +/// `Condition` is a check that given user `attribute` matches the condition `value` under the given +/// `operator`. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(try_from = "ConditionWire", into = "ConditionWire")] +pub(crate) struct Condition { + pub attribute: Box, + pub check: ConditionCheck, +} + +#[derive(Debug, Clone)] +pub(crate) enum ConditionCheck { + Comparison { + operator: ComparisonOperator, + comparand: f64, + }, + Regex { + expected_match: bool, + // As regex is supplied by user, we allow regex parse failure to not fail parsing and + // evaluation. Invalid regexes are simply ignored. + regex: Regex, + }, + Membership { + expected_membership: bool, + values: Box<[Box]>, + }, + Null { + expected_null: bool, + }, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub(crate) enum ComparisonOperator { + Gte, + Gt, + Lte, + Lt, +} + +impl From for ConditionOperator { + fn from(value: ComparisonOperator) -> ConditionOperator { + match value { + ComparisonOperator::Gte => ConditionOperator::Gte, + ComparisonOperator::Gt => ConditionOperator::Gt, + ComparisonOperator::Lte => ConditionOperator::Lte, + ComparisonOperator::Lt => ConditionOperator::Lt, + } + } +} + +/// Wire (JSON) format for the `Condition`. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[allow(missing_docs)] +pub(crate) struct ConditionWire { + pub attribute: Box, + pub operator: ConditionOperator, + pub value: ConditionValue, +} + +impl From for ConditionWire { + fn from(condition: Condition) -> Self { + let (operator, value) = match condition.check { + ConditionCheck::Comparison { + operator, + comparand, + } => (operator.into(), comparand.into()), + ConditionCheck::Regex { + expected_match, + regex, + } => ( + if expected_match { + ConditionOperator::Matches + } else { + ConditionOperator::NotMatches + }, + ConditionValue::Single(SingleConditionValue::String(Str::from(regex.as_str()))), + ), + ConditionCheck::Membership { + expected_membership, + values, + } => ( + if expected_membership { + ConditionOperator::OneOf + } else { + ConditionOperator::NotOneOf + }, + ConditionValue::Multiple(values), + ), + ConditionCheck::Null { expected_null } => { + (ConditionOperator::IsNull, expected_null.into()) + } + }; + ConditionWire { + attribute: condition.attribute, + operator, + value, + } + } +} + +impl From for Option { + fn from(value: ConditionWire) -> Self { + Condition::try_from(value).ok() + } +} + +impl TryFrom for Condition { + type Error = Error; + + fn try_from(condition: ConditionWire) -> Result { + let attribute = condition.attribute; + let check = match condition.operator { + ConditionOperator::Matches | ConditionOperator::NotMatches => { + let expected_match = condition.operator == ConditionOperator::Matches; + + let regex_string = match condition.value.singleton() { + Some(SingleConditionValue::String(s)) => s, + _ => { + log::warn!( + "failed to parse condition: {:?} condition with non-string condition value", + condition.operator + ); + return Err(Error::EvaluationError( + EvaluationError::UnexpectedConfigurationError, + )); + } + }; + let regex = match Regex::new(®ex_string) { + Ok(regex) => regex, + Err(err) => { + log::warn!( + "failed to parse condition: failed to compile regex {regex_string:?}: {err:?}" + ); + return Err(Error::EvaluationError( + EvaluationError::UnexpectedConfigurationError, + )); + } + }; + + ConditionCheck::Regex { + expected_match, + regex, + } + } + ConditionOperator::Gte + | ConditionOperator::Gt + | ConditionOperator::Lte + | ConditionOperator::Lt => { + let operator = match condition.operator { + ConditionOperator::Gte => ComparisonOperator::Gte, + ConditionOperator::Gt => ComparisonOperator::Gt, + ConditionOperator::Lte => ComparisonOperator::Lte, + ConditionOperator::Lt => ComparisonOperator::Lt, + _ => unreachable!(), + }; + + // numeric comparison only + let Some(condition_value) = condition.value.singleton().and_then(|v| v.as_number()) + else { + log::warn!( + "failed to parse condition: comparison value is not a number: {:?}", + condition.value + ); + return Err(Error::EvaluationError( + EvaluationError::UnexpectedConfigurationError, + )); + }; + ConditionCheck::Comparison { + operator, + comparand: condition_value, + } + } + ConditionOperator::OneOf | ConditionOperator::NotOneOf => { + let expected_membership = condition.operator == ConditionOperator::OneOf; + let values = match condition.value { + ConditionValue::Multiple(v) => v, + _ => { + log::warn!( + "failed to parse condition: membership condition with non-array value: {:?}", + condition.value + ); + return Err(Error::EvaluationError( + EvaluationError::UnexpectedConfigurationError, + )); + } + }; + ConditionCheck::Membership { + expected_membership, + values, + } + } + ConditionOperator::IsNull => { + let Some(expected_null) = condition.value.singleton().and_then(|v| v.as_boolean()) + else { + log::warn!( + "failed to parse condition: IS_NULL condition with non-boolean condition value" + ); + return Err(Error::EvaluationError( + EvaluationError::UnexpectedConfigurationError, + )); + }; + ConditionCheck::Null { expected_null } + } + }; + Ok(Condition { attribute, check }) + } +} + +/// Possible condition types. +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub(crate) enum ConditionOperator { + /// Matches regex. Condition value must be a regex string. + Matches, + /// Regex does not match. Condition value must be a regex string. + NotMatches, + /// Greater than or equal. Attribute and condition value must be numbers. + Gte, + /// Greater than. Attribute and condition value must be numbers. + Gt, + /// Less than or equal. Attribute and condition value must be numbers. + Lte, + /// Less than. Attribute and condition value must be numbers. + Lt, + /// One of values. Condition value must be a list of strings. Match is case-sensitive. + OneOf, + /// Not one of values. Condition value must be a list of strings. Match is case-sensitive. + /// + /// Null/absent attributes fail this condition automatically. (i.e., `null NOT_ONE_OF + /// ["hello"]` is `false`) + NotOneOf, + /// Null check. + /// + /// Condition value must be a boolean. If it's `true`, this is a null check. If it's `false`, + /// this is a not null check. + IsNull, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +#[allow(missing_docs)] +pub(crate) enum ConditionValue { + Single(SingleConditionValue), + // Only string arrays are currently supported. + Multiple(Box<[Box]>), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, derive_more::From)] +#[serde(untagged)] +#[allow(missing_docs)] +pub(crate) enum SingleConditionValue { + Boolean(bool), + Number(f64), + String(Str), +} + +impl SingleConditionValue { + pub fn as_number(&self) -> Option { + if let Self::Number(n) = self { + Some(*n) + } else { + None + } + } + + pub fn as_boolean(&self) -> Option { + if let Self::Boolean(v) = self { + Some(*v) + } else { + None + } + } +} + +impl ConditionValue { + pub fn singleton(&self) -> Option { + match self { + ConditionValue::Single(v) => Some(v.clone()), + ConditionValue::Multiple(arr) if arr.len() == 1 => { + Some(SingleConditionValue::String(arr[0].as_ref().into())) + } + _ => None, + } + } +} + +impl> From for ConditionValue { + fn from(value: T) -> Self { + Self::Single(value.into()) + } +} +impl From> for ConditionValue { + fn from(value: Vec) -> Self { + Self::Multiple(value.into_iter().map(|it| it.into()).collect()) + } +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +#[allow(missing_docs)] +pub(crate) struct SplitWire { + pub shards: Vec, + pub variation_key: Str, + #[serde(default)] + pub extra_logging: Option>>, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[allow(missing_docs)] +pub(crate) struct ShardWire { + pub salt: String, + pub total_shards: u32, + pub ranges: Box<[ShardRange]>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[allow(missing_docs)] +pub struct ShardRange { + pub start: u32, + pub end: u32, +} +impl ShardRange { + pub(crate) fn contains(&self, v: u32) -> bool { + self.start <= v && v < self.end + } +} + +#[cfg(test)] +mod tests { + use super::{TryParse, UniversalFlagConfigWire}; + + #[test] + fn parse_flags_v1() { + let json_content = { + let path = if std::path::Path::new("tests/data/flags-v1.json").exists() { + "tests/data/flags-v1.json" + } else { + "domains/ffe/libs/flagging/rust/evaluation/tests/data/flags-v1.json" + }; + std::fs::read_to_string(path).unwrap() + }; + let _ufc: UniversalFlagConfigWire = serde_json::from_str(&json_content).unwrap(); + } + + #[test] + fn parse_partially_if_unexpected() { + let ufc: UniversalFlagConfigWire = serde_json::from_str( + r#" + { + "data": { + "type": "universal-flag-configuration", + "id": "1", + "attributes": { + "createdAt": "2024-07-18T00:00:00Z", + "format": "SERVER", + "environment": {"name": "test"}, + "flags": { + "success": { + "key": "success", + "enabled": true, + "variationType": "BOOLEAN", + "variations": {}, + "allocations": [] + }, + "fail_parsing": { + "key": "fail_parsing", + "enabled": true, + "variationType": "NEW_TYPE", + "variations": {}, + "allocations": [] + } + } + } + } + } + "#, + ) + .unwrap(); + assert!( + matches!( + ufc.data.attributes.flags.get("success").unwrap(), + TryParse::Parsed(_) + ), + "{:?} should match TryParse::Parsed(_)", + ufc.data.attributes.flags.get("success").unwrap() + ); + assert!( + matches!( + ufc.data.attributes.flags.get("fail_parsing").unwrap(), + TryParse::ParseFailed(_) + ), + "{:?} should match TryParse::ParseFailed(_)", + ufc.data.attributes.flags.get("fail_parsing").unwrap() + ); + } +} diff --git a/datadog-ffe/tests/data/flags-v1.json b/datadog-ffe/tests/data/flags-v1.json new file mode 100644 index 0000000000..e8e285b90b --- /dev/null +++ b/datadog-ffe/tests/data/flags-v1.json @@ -0,0 +1,3060 @@ +{ + "data": { + "type": "universal-flag-configuration", + "id": "1", + "attributes": { + "createdAt": "2024-04-17T19:40:53.716Z", + "format": "SERVER", + "environment": { + "name": "Test" + }, + "flags": { + "empty_flag": { + "key": "empty_flag", + "enabled": true, + "variationType": "STRING", + "variations": {}, + "allocations": [] + }, + "disabled_flag": { + "key": "disabled_flag", + "enabled": false, + "variationType": "INTEGER", + "variations": {}, + "allocations": [] + }, + "no_allocations_flag": { + "key": "no_allocations_flag", + "enabled": true, + "variationType": "JSON", + "variations": { + "control": { + "key": "control", + "value": {"variant": "control"} + }, + "treatment": { + "key": "treatment", + "value": {"variant": "treatment"} + } + }, + "allocations": [] + }, + "numeric_flag": { + "key": "numeric_flag", + "enabled": true, + "variationType": "NUMERIC", + "variations": { + "e": { + "key": "e", + "value": 2.7182818 + }, + "pi": { + "key": "pi", + "value": 3.1415926 + } + }, + "allocations": [ + { + "key": "rollout", + "splits": [ + { + "variationKey": "pi", + "shards": [] + } + ], + "doLog": true + } + ] + }, + "regex-flag": { + "key": "regex-flag", + "enabled": true, + "variationType": "STRING", + "variations": { + "partial-example": { + "key": "partial-example", + "value": "partial-example" + }, + "test": { + "key": "test", + "value": "test" + } + }, + "allocations": [ + { + "key": "partial-example", + "rules": [ + { + "conditions": [ + { + "attribute": "email", + "operator": "MATCHES", + "value": "@example\\.com" + } + ] + } + ], + "splits": [ + { + "variationKey": "partial-example", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "test", + "rules": [ + { + "conditions": [ + { + "attribute": "email", + "operator": "MATCHES", + "value": ".*@test\\.com" + } + ] + } + ], + "splits": [ + { + "variationKey": "test", + "shards": [] + } + ], + "doLog": true + } + ] + }, + "numeric-one-of": { + "key": "numeric-one-of", + "enabled": true, + "variationType": "INTEGER", + "variations": { + "1": { + "key": "1", + "value": 1 + }, + "2": { + "key": "2", + "value": 2 + }, + "3": { + "key": "3", + "value": 3 + } + }, + "allocations": [ + { + "key": "1-for-1", + "rules": [ + { + "conditions": [ + { + "attribute": "number", + "operator": "ONE_OF", + "value": [ + "1" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "1", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "2-for-123456789", + "rules": [ + { + "conditions": [ + { + "attribute": "number", + "operator": "ONE_OF", + "value": [ + "123456789" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "2", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "3-for-not-2", + "rules": [ + { + "conditions": [ + { + "attribute": "number", + "operator": "NOT_ONE_OF", + "value": [ + "2" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "3", + "shards": [] + } + ], + "doLog": true + } + ] + }, + "boolean-one-of-matches": { + "key": "boolean-one-of-matches", + "enabled": true, + "variationType": "INTEGER", + "variations": { + "1": { + "key": "1", + "value": 1 + }, + "2": { + "key": "2", + "value": 2 + }, + "3": { + "key": "3", + "value": 3 + }, + "4": { + "key": "4", + "value": 4 + }, + "5": { + "key": "5", + "value": 5 + } + }, + "allocations": [ + { + "key": "1-for-one-of", + "rules": [ + { + "conditions": [ + { + "attribute": "one_of_flag", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "1", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "2-for-matches", + "rules": [ + { + "conditions": [ + { + "attribute": "matches_flag", + "operator": "MATCHES", + "value": "true" + } + ] + } + ], + "splits": [ + { + "variationKey": "2", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "3-for-not-one-of", + "rules": [ + { + "conditions": [ + { + "attribute": "not_one_of_flag", + "operator": "NOT_ONE_OF", + "value": [ + "false" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "3", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "4-for-not-matches", + "rules": [ + { + "conditions": [ + { + "attribute": "not_matches_flag", + "operator": "NOT_MATCHES", + "value": "false" + } + ] + } + ], + "splits": [ + { + "variationKey": "4", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "5-for-matches-null", + "rules": [ + { + "conditions": [ + { + "attribute": "null_flag", + "operator": "ONE_OF", + "value": [ + "null" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "5", + "shards": [] + } + ], + "doLog": true + } + ] + }, + "empty_string_flag": { + "key": "empty_string_flag", + "enabled": true, + "comment": "Testing the empty string as a variation value", + "variationType": "STRING", + "variations": { + "empty_string": { + "key": "empty_string", + "value": "" + }, + "non_empty": { + "key": "non_empty", + "value": "non_empty" + } + }, + "allocations": [ + { + "key": "allocation-empty", + "rules": [ + { + "conditions": [ + { + "attribute": "country", + "operator": "MATCHES", + "value": "US" + } + ] + } + ], + "splits": [ + { + "variationKey": "empty_string", + "shards": [ + { + "salt": "allocation-empty-shards", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 10000 + } + ] + } + ] + } + ], + "doLog": true + }, + { + "key": "allocation-test", + "rules": [], + "splits": [ + { + "variationKey": "non_empty", + "shards": [ + { + "salt": "allocation-empty-shards", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 10000 + } + ] + } + ] + } + ], + "doLog": true + } + ] + }, + "kill-switch": { + "key": "kill-switch", + "enabled": true, + "variationType": "BOOLEAN", + "variations": { + "on": { + "key": "on", + "value": true + }, + "off": { + "key": "off", + "value": false + } + }, + "allocations": [ + { + "key": "on-for-NA", + "rules": [ + { + "conditions": [ + { + "attribute": "country", + "operator": "ONE_OF", + "value": [ + "US", + "Canada", + "Mexico" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "on", + "shards": [ + { + "salt": "some-salt", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 10000 + } + ] + } + ] + } + ], + "doLog": true + }, + { + "key": "on-for-age-50+", + "rules": [ + { + "conditions": [ + { + "attribute": "age", + "operator": "GTE", + "value": 50 + } + ] + } + ], + "splits": [ + { + "variationKey": "on", + "shards": [ + { + "salt": "some-salt", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 10000 + } + ] + } + ] + } + ], + "doLog": true + }, + { + "key": "off-for-all", + "rules": [], + "splits": [ + { + "variationKey": "off", + "shards": [] + } + ], + "doLog": true + } + ] + }, + "comparator-operator-test": { + "key": "comparator-operator-test", + "enabled": true, + "variationType": "STRING", + "variations": { + "small": { + "key": "small", + "value": "small" + }, + "medium": { + "key": "medium", + "value": "medium" + }, + "large": { + "key": "large", + "value": "large" + } + }, + "allocations": [ + { + "key": "small-size", + "rules": [ + { + "conditions": [ + { + "attribute": "size", + "operator": "LT", + "value": 10 + } + ] + } + ], + "splits": [ + { + "variationKey": "small", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "medum-size", + "rules": [ + { + "conditions": [ + { + "attribute": "size", + "operator": "GTE", + "value": 10 + }, + { + "attribute": "size", + "operator": "LTE", + "value": 20 + } + ] + } + ], + "splits": [ + { + "variationKey": "medium", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "large-size", + "rules": [ + { + "conditions": [ + { + "attribute": "size", + "operator": "GT", + "value": 25 + } + ] + } + ], + "splits": [ + { + "variationKey": "large", + "shards": [] + } + ], + "doLog": true + } + ] + }, + "start-and-end-date-test": { + "key": "start-and-end-date-test", + "enabled": true, + "variationType": "STRING", + "variations": { + "old": { + "key": "old", + "value": "old" + }, + "current": { + "key": "current", + "value": "current" + }, + "new": { + "key": "new", + "value": "new" + } + }, + "allocations": [ + { + "key": "old-versions", + "splits": [ + { + "variationKey": "old", + "shards": [] + } + ], + "endAt": "2002-10-31T09:00:00.594Z", + "doLog": true + }, + { + "key": "future-versions", + "splits": [ + { + "variationKey": "new", + "shards": [] + } + ], + "startAt": "2052-10-31T09:00:00.594Z", + "doLog": true + }, + { + "key": "current-versions", + "splits": [ + { + "variationKey": "current", + "shards": [] + } + ], + "startAt": "2022-10-31T09:00:00.594Z", + "endAt": "2050-10-31T09:00:00.594Z", + "doLog": true + } + ] + }, + "null-operator-test": { + "key": "null-operator-test", + "enabled": true, + "variationType": "STRING", + "variations": { + "old": { + "key": "old", + "value": "old" + }, + "new": { + "key": "new", + "value": "new" + } + }, + "allocations": [ + { + "key": "null-operator", + "rules": [ + { + "conditions": [ + { + "attribute": "size", + "operator": "IS_NULL", + "value": true + } + ] + }, + { + "conditions": [ + { + "attribute": "size", + "operator": "LT", + "value": 10 + } + ] + } + ], + "splits": [ + { + "variationKey": "old", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "not-null-operator", + "rules": [ + { + "conditions": [ + { + "attribute": "size", + "operator": "IS_NULL", + "value": false + } + ] + } + ], + "splits": [ + { + "variationKey": "new", + "shards": [] + } + ], + "doLog": true + } + ] + }, + "new-user-onboarding": { + "key": "new-user-onboarding", + "enabled": true, + "variationType": "STRING", + "variations": { + "control": { + "key": "control", + "value": "control" + }, + "red": { + "key": "red", + "value": "red" + }, + "blue": { + "key": "blue", + "value": "blue" + }, + "green": { + "key": "green", + "value": "green" + }, + "yellow": { + "key": "yellow", + "value": "yellow" + }, + "purple": { + "key": "purple", + "value": "purple" + } + }, + "allocations": [ + { + "key": "id rule", + "rules": [ + { + "conditions": [ + { + "attribute": "id", + "operator": "MATCHES", + "value": "zach" + } + ] + } + ], + "splits": [ + { + "variationKey": "purple", + "shards": [] + } + ], + "doLog": false + }, + { + "key": "internal users", + "rules": [ + { + "conditions": [ + { + "attribute": "email", + "operator": "MATCHES", + "value": "@mycompany.com" + } + ] + } + ], + "splits": [ + { + "variationKey": "green", + "shards": [] + } + ], + "doLog": false + }, + { + "key": "experiment", + "rules": [ + { + "conditions": [ + { + "attribute": "country", + "operator": "NOT_ONE_OF", + "value": [ + "US", + "Canada", + "Mexico" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "control", + "shards": [ + { + "salt": "traffic-new-user-onboarding-experiment", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 6000 + } + ] + }, + { + "salt": "split-new-user-onboarding-experiment", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 5000 + } + ] + } + ] + }, + { + "variationKey": "red", + "shards": [ + { + "salt": "traffic-new-user-onboarding-experiment", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 6000 + } + ] + }, + { + "salt": "split-new-user-onboarding-experiment", + "totalShards": 10000, + "ranges": [ + { + "start": 5000, + "end": 8000 + } + ] + } + ] + }, + { + "variationKey": "yellow", + "shards": [ + { + "salt": "traffic-new-user-onboarding-experiment", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 6000 + } + ] + }, + { + "salt": "split-new-user-onboarding-experiment", + "totalShards": 10000, + "ranges": [ + { + "start": 8000, + "end": 10000 + } + ] + } + ] + } + ], + "doLog": true + }, + { + "key": "rollout", + "rules": [ + { + "conditions": [ + { + "attribute": "country", + "operator": "ONE_OF", + "value": [ + "US", + "Canada", + "Mexico" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "blue", + "shards": [ + { + "salt": "split-new-user-onboarding-rollout", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 8000 + } + ] + } + ], + "extraLogging": { + "allocationvalue_type": "rollout", + "owner": "hippo" + } + } + ], + "doLog": true + } + ] + }, + "integer-flag": { + "key": "integer-flag", + "enabled": true, + "variationType": "INTEGER", + "variations": { + "one": { + "key": "one", + "value": 1 + }, + "two": { + "key": "two", + "value": 2 + }, + "three": { + "key": "three", + "value": 3 + } + }, + "allocations": [ + { + "key": "targeted allocation", + "rules": [ + { + "conditions": [ + { + "attribute": "country", + "operator": "ONE_OF", + "value": [ + "US", + "Canada", + "Mexico" + ] + } + ] + }, + { + "conditions": [ + { + "attribute": "email", + "operator": "MATCHES", + "value": ".*@example.com" + } + ] + } + ], + "splits": [ + { + "variationKey": "three", + "shards": [ + { + "salt": "full-range-salt", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 10000 + } + ] + } + ] + } + ], + "doLog": true + }, + { + "key": "50/50 split", + "rules": [], + "splits": [ + { + "variationKey": "one", + "shards": [ + { + "salt": "split-numeric-flag-some-allocation", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 5000 + } + ] + } + ] + }, + { + "variationKey": "two", + "shards": [ + { + "salt": "split-numeric-flag-some-allocation", + "totalShards": 10000, + "ranges": [ + { + "start": 5000, + "end": 10000 + } + ] + } + ] + } + ], + "doLog": true + } + ] + }, + "json-config-flag": { + "key": "json-config-flag", + "enabled": true, + "variationType": "JSON", + "variations": { + "one": { + "key": "one", + "value": { "integer": 1, "string": "one", "float": 1.0 } + }, + "two": { + "key": "two", + "value": { "integer": 2, "string": "two", "float": 2.0 } + }, + "empty": { + "key": "empty", + "value": {} + } + }, + "allocations": [ + { + "key": "Optionally Force Empty", + "rules": [ + { + "conditions": [ + { + "attribute": "Force Empty", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "empty", + "shards": [ + { + "salt": "full-range-salt", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 10000 + } + ] + } + ] + } + ], + "doLog": true + }, + { + "key": "50/50 split", + "rules": [], + "splits": [ + { + "variationKey": "one", + "shards": [ + { + "salt": "traffic-json-flag", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 10000 + } + ] + }, + { + "salt": "split-json-flag", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 5000 + } + ] + } + ] + }, + { + "variationKey": "two", + "shards": [ + { + "salt": "traffic-json-flag", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 10000 + } + ] + }, + { + "salt": "split-json-flag", + "totalShards": 10000, + "ranges": [ + { + "start": 5000, + "end": 10000 + } + ] + } + ] + } + ], + "doLog": true + } + ] + }, + "special-characters": { + "key": "special-characters", + "enabled": true, + "variationType": "JSON", + "variations": { + "de": { + "key": "de", + "value": {"a": "kümmert", "b": "schön"} + }, + "ua": { + "key": "ua", + "value": {"a": "піклуватися", "b": "любов"} + }, + "zh": { + "key": "zh", + "value": {"a": "照顾", "b": "漂亮"} + }, + "emoji": { + "key": "emoji", + "value": {"a": "🤗", "b": "🌸"} + } + }, + "allocations": [ + { + "key": "allocation-test", + "splits": [ + { + "variationKey": "de", + "shards": [ + { + "salt": "split-json-flag", + "totalShards": 10000, + "ranges": [ + { + "start": 0, + "end": 2500 + } + ] + } + ] + }, + { + "variationKey": "ua", + "shards": [ + { + "salt": "split-json-flag", + "totalShards": 10000, + "ranges": [ + { + "start": 2500, + "end": 5000 + } + ] + } + ] + }, + { + "variationKey": "zh", + "shards": [ + { + "salt": "split-json-flag", + "totalShards": 10000, + "ranges": [ + { + "start": 5000, + "end": 7500 + } + ] + } + ] + }, + { + "variationKey": "emoji", + "shards": [ + { + "salt": "split-json-flag", + "totalShards": 10000, + "ranges": [ + { + "start": 7500, + "end": 10000 + } + ] + } + ] + } + ], + "doLog": true + }, + { + "key": "allocation-default", + "splits": [ + { + "variationKey": "de", + "shards": [] + } + ], + "doLog": false + } + ] + }, + "string_flag_with_special_characters": { + "key": "string_flag_with_special_characters", + "enabled": true, + "comment": "Testing the string with special characters and spaces", + "variationType": "STRING", + "variations": { + "string_with_spaces": { + "key": "string_with_spaces", + "value": " a b c d e f " + }, + "string_with_only_one_space": { + "key": "string_with_only_one_space", + "value": " " + }, + "string_with_only_multiple_spaces": { + "key": "string_with_only_multiple_spaces", + "value": " " + }, + "string_with_dots": { + "key": "string_with_dots", + "value": ".a.b.c.d.e.f." + }, + "string_with_only_one_dot": { + "key": "string_with_only_one_dot", + "value": "." + }, + "string_with_only_multiple_dots": { + "key": "string_with_only_multiple_dots", + "value": "......." + }, + "string_with_comas": { + "key": "string_with_comas", + "value": ",a,b,c,d,e,f," + }, + "string_with_only_one_coma": { + "key": "string_with_only_one_coma", + "value": "," + }, + "string_with_only_multiple_comas": { + "key": "string_with_only_multiple_comas", + "value": ",,,,,,," + }, + "string_with_colons": { + "key": "string_with_colons", + "value": ":a:b:c:d:e:f:" + }, + "string_with_only_one_colon": { + "key": "string_with_only_one_colon", + "value": ":" + }, + "string_with_only_multiple_colons": { + "key": "string_with_only_multiple_colons", + "value": ":::::::" + }, + "string_with_semicolons": { + "key": "string_with_semicolons", + "value": ";a;b;c;d;e;f;" + }, + "string_with_only_one_semicolon": { + "key": "string_with_only_one_semicolon", + "value": ";" + }, + "string_with_only_multiple_semicolons": { + "key": "string_with_only_multiple_semicolons", + "value": ";;;;;;;" + }, + "string_with_slashes": { + "key": "string_with_slashes", + "value": "/a/b/c/d/e/f/" + }, + "string_with_only_one_slash": { + "key": "string_with_only_one_slash", + "value": "/" + }, + "string_with_only_multiple_slashes": { + "key": "string_with_only_multiple_slashes", + "value": "///////" + }, + "string_with_dashes": { + "key": "string_with_dashes", + "value": "-a-b-c-d-e-f-" + }, + "string_with_only_one_dash": { + "key": "string_with_only_one_dash", + "value": "-" + }, + "string_with_only_multiple_dashes": { + "key": "string_with_only_multiple_dashes", + "value": "-------" + }, + "string_with_underscores": { + "key": "string_with_underscores", + "value": "_a_b_c_d_e_f_" + }, + "string_with_only_one_underscore": { + "key": "string_with_only_one_underscore", + "value": "_" + }, + "string_with_only_multiple_underscores": { + "key": "string_with_only_multiple_underscores", + "value": "_______" + }, + "string_with_plus_signs": { + "key": "string_with_plus_signs", + "value": "+a+b+c+d+e+f+" + }, + "string_with_only_one_plus_sign": { + "key": "string_with_only_one_plus_sign", + "value": "+" + }, + "string_with_only_multiple_plus_signs": { + "key": "string_with_only_multiple_plus_signs", + "value": "+++++++" + }, + "string_with_equal_signs": { + "key": "string_with_equal_signs", + "value": "=a=b=c=d=e=f=" + }, + "string_with_only_one_equal_sign": { + "key": "string_with_only_one_equal_sign", + "value": "=" + }, + "string_with_only_multiple_equal_signs": { + "key": "string_with_only_multiple_equal_signs", + "value": "=======" + }, + "string_with_dollar_signs": { + "key": "string_with_dollar_signs", + "value": "$a$b$c$d$e$f$" + }, + "string_with_only_one_dollar_sign": { + "key": "string_with_only_one_dollar_sign", + "value": "$" + }, + "string_with_only_multiple_dollar_signs": { + "key": "string_with_only_multiple_dollar_signs", + "value": "$$$$$$$" + }, + "string_with_at_signs": { + "key": "string_with_at_signs", + "value": "@a@b@c@d@e@f@" + }, + "string_with_only_one_at_sign": { + "key": "string_with_only_one_at_sign", + "value": "@" + }, + "string_with_only_multiple_at_signs": { + "key": "string_with_only_multiple_at_signs", + "value": "@@@@@@@" + }, + "string_with_amp_signs": { + "key": "string_with_amp_signs", + "value": "&a&b&c&d&e&f&" + }, + "string_with_only_one_amp_sign": { + "key": "string_with_only_one_amp_sign", + "value": "&" + }, + "string_with_only_multiple_amp_signs": { + "key": "string_with_only_multiple_amp_signs", + "value": "&&&&&&&" + }, + "string_with_hash_signs": { + "key": "string_with_hash_signs", + "value": "#a#b#c#d#e#f#" + }, + "string_with_only_one_hash_sign": { + "key": "string_with_only_one_hash_sign", + "value": "#" + }, + "string_with_only_multiple_hash_signs": { + "key": "string_with_only_multiple_hash_signs", + "value": "#######" + }, + "string_with_percentage_signs": { + "key": "string_with_percentage_signs", + "value": "%a%b%c%d%e%f%" + }, + "string_with_only_one_percentage_sign": { + "key": "string_with_only_one_percentage_sign", + "value": "%" + }, + "string_with_only_multiple_percentage_signs": { + "key": "string_with_only_multiple_percentage_signs", + "value": "%%%%%%%" + }, + "string_with_tilde_signs": { + "key": "string_with_tilde_signs", + "value": "~a~b~c~d~e~f~" + }, + "string_with_only_one_tilde_sign": { + "key": "string_with_only_one_tilde_sign", + "value": "~" + }, + "string_with_only_multiple_tilde_signs": { + "key": "string_with_only_multiple_tilde_signs", + "value": "~~~~~~~" + }, + "string_with_asterix_signs": { + "key": "string_with_asterix_signs", + "value": "*a*b*c*d*e*f*" + }, + "string_with_only_one_asterix_sign": { + "key": "string_with_only_one_asterix_sign", + "value": "*" + }, + "string_with_only_multiple_asterix_signs": { + "key": "string_with_only_multiple_asterix_signs", + "value": "*******" + }, + "string_with_single_quotes": { + "key": "string_with_single_quotes", + "value": "'a'b'c'd'e'f'" + }, + "string_with_only_one_single_quote": { + "key": "string_with_only_one_single_quote", + "value": "'" + }, + "string_with_only_multiple_single_quotes": { + "key": "string_with_only_multiple_single_quotes", + "value": "'''''''" + }, + "string_with_question_marks": { + "key": "string_with_question_marks", + "value": "?a?b?c?d?e?f?" + }, + "string_with_only_one_question_mark": { + "key": "string_with_only_one_question_mark", + "value": "?" + }, + "string_with_only_multiple_question_marks": { + "key": "string_with_only_multiple_question_marks", + "value": "???????" + }, + "string_with_exclamation_marks": { + "key": "string_with_exclamation_marks", + "value": "!a!b!c!d!e!f!" + }, + "string_with_only_one_exclamation_mark": { + "key": "string_with_only_one_exclamation_mark", + "value": "!" + }, + "string_with_only_multiple_exclamation_marks": { + "key": "string_with_only_multiple_exclamation_marks", + "value": "!!!!!!!" + }, + "string_with_opening_parentheses": { + "key": "string_with_opening_parentheses", + "value": "(a(b(c(d(e(f(" + }, + "string_with_only_one_opening_parenthese": { + "key": "string_with_only_one_opening_parenthese", + "value": "(" + }, + "string_with_only_multiple_opening_parentheses": { + "key": "string_with_only_multiple_opening_parentheses", + "value": "(((((((" + }, + "string_with_closing_parentheses": { + "key": "string_with_closing_parentheses", + "value": ")a)b)c)d)e)f)" + }, + "string_with_only_one_closing_parenthese": { + "key": "string_with_only_one_closing_parenthese", + "value": ")" + }, + "string_with_only_multiple_closing_parentheses": { + "key": "string_with_only_multiple_closing_parentheses", + "value": ")))))))" + } + }, + "allocations": [ + { + "key": "allocation-test-string_with_spaces", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_spaces", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_spaces", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_space", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_space", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_space", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_spaces", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_spaces", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_spaces", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_dots", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_dots", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_dots", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_dot", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_dot", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_dot", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_dots", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_dots", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_dots", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_comas", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_comas", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_comas", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_coma", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_coma", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_coma", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_comas", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_comas", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_comas", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_colons", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_colons", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_colons", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_colon", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_colon", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_colon", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_colons", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_colons", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_colons", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_semicolons", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_semicolons", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_semicolons", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_semicolon", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_semicolon", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_semicolon", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_semicolons", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_semicolons", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_semicolons", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_slashes", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_slashes", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_slashes", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_slash", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_slash", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_slash", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_slashes", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_slashes", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_slashes", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_dashes", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_dashes", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_dashes", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_dash", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_dash", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_dash", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_dashes", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_dashes", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_dashes", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_underscores", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_underscores", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_underscores", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_underscore", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_underscore", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_underscore", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_underscores", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_underscores", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_underscores", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_plus_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_plus_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_plus_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_plus_sign", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_plus_sign", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_plus_sign", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_plus_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_plus_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_plus_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_equal_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_equal_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_equal_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_equal_sign", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_equal_sign", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_equal_sign", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_equal_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_equal_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_equal_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_dollar_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_dollar_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_dollar_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_dollar_sign", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_dollar_sign", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_dollar_sign", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_dollar_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_dollar_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_dollar_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_at_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_at_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_at_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_at_sign", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_at_sign", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_at_sign", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_at_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_at_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_at_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_amp_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_amp_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_amp_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_amp_sign", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_amp_sign", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_amp_sign", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_amp_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_amp_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_amp_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_hash_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_hash_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_hash_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_hash_sign", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_hash_sign", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_hash_sign", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_hash_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_hash_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_hash_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_percentage_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_percentage_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_percentage_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_percentage_sign", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_percentage_sign", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_percentage_sign", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_percentage_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_percentage_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_percentage_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_tilde_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_tilde_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_tilde_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_tilde_sign", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_tilde_sign", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_tilde_sign", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_tilde_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_tilde_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_tilde_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_asterix_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_asterix_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_asterix_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_asterix_sign", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_asterix_sign", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_asterix_sign", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_asterix_signs", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_asterix_signs", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_asterix_signs", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_single_quotes", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_single_quotes", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_single_quotes", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_single_quote", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_single_quote", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_single_quote", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_single_quotes", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_single_quotes", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_single_quotes", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_question_marks", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_question_marks", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_question_marks", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_question_mark", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_question_mark", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_question_mark", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_question_marks", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_question_marks", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_question_marks", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_exclamation_marks", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_exclamation_marks", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_exclamation_marks", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_exclamation_mark", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_exclamation_mark", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_exclamation_mark", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_exclamation_marks", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_exclamation_marks", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_exclamation_marks", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_opening_parentheses", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_opening_parentheses", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_opening_parentheses", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_opening_parenthese", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_opening_parenthese", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_opening_parenthese", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_opening_parentheses", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_opening_parentheses", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_opening_parentheses", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_closing_parentheses", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_closing_parentheses", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_closing_parentheses", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_one_closing_parenthese", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_one_closing_parenthese", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_one_closing_parenthese", + "shards": [] + } + ], + "doLog": true + }, + { + "key": "allocation-test-string_with_only_multiple_closing_parentheses", + "rules": [ + { + "conditions": [ + { + "attribute": "string_with_only_multiple_closing_parentheses", + "operator": "ONE_OF", + "value": [ + "true" + ] + } + ] + } + ], + "splits": [ + { + "variationKey": "string_with_only_multiple_closing_parentheses", + "shards": [] + } + ], + "doLog": true + } + ] + } + } + } + } +} diff --git a/datadog-ffe/tests/data/tests/test-case-boolean-one-of-matches.json b/datadog-ffe/tests/data/tests/test-case-boolean-one-of-matches.json new file mode 100644 index 0000000000..6bfbf0effa --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-boolean-one-of-matches.json @@ -0,0 +1,240 @@ +[ + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "alice", + "attributes": { + "one_of_flag": true + }, + "result": { + "value": 1, + "variant": "1", + "flagMetadata": { + "allocationKey": "1-for-one-of", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "bob", + "attributes": { + "one_of_flag": false + }, + "result": { + "value": 0 + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "charlie", + "attributes": { + "one_of_flag": "True" + }, + "result": { + "value": 0 + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "derek", + "attributes": { + "matches_flag": true + }, + "result": { + "value": 2, + "variant": "2", + "flagMetadata": { + "allocationKey": "2-for-matches", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "erica", + "attributes": { + "matches_flag": false + }, + "result": { + "value": 0 + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "frank", + "attributes": { + "not_matches_flag": false + }, + "result": { + "value": 0 + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "george", + "attributes": { + "not_matches_flag": true + }, + "result": { + "value": 4, + "variant": "4", + "flagMetadata": { + "allocationKey": "4-for-not-matches", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "haley", + "attributes": { + "not_matches_flag": "False" + }, + "result": { + "value": 4, + "variant": "4", + "flagMetadata": { + "allocationKey": "4-for-not-matches", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "ivy", + "attributes": { + "not_one_of_flag": true + }, + "result": { + "value": 3, + "variant": "3", + "flagMetadata": { + "allocationKey": "3-for-not-one-of", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "julia", + "attributes": { + "not_one_of_flag": false + }, + "result": { + "value": 0 + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "kim", + "attributes": { + "not_one_of_flag": "False" + }, + "result": { + "value": 3, + "variant": "3", + "flagMetadata": { + "allocationKey": "3-for-not-one-of", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "lucas", + "attributes": { + "not_one_of_flag": "true" + }, + "result": { + "value": 3, + "variant": "3", + "flagMetadata": { + "allocationKey": "3-for-not-one-of", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "mike", + "attributes": { + "not_one_of_flag": "false" + }, + "result": { + "value": 0 + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "nicole", + "attributes": { + "null_flag": "null" + }, + "result": { + "value": 5, + "variant": "5", + "flagMetadata": { + "allocationKey": "5-for-matches-null", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "owen", + "attributes": { + "null_flag": null + }, + "result": { + "value": 0 + } + }, + { + "flag": "boolean-one-of-matches", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "pete", + "attributes": {}, + "result": { + "value": 0 + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-comparator-operator-flag.json b/datadog-ffe/tests/data/tests/test-case-comparator-operator-flag.json new file mode 100644 index 0000000000..a5c8ef07cd --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-comparator-operator-flag.json @@ -0,0 +1,82 @@ +[ + { + "flag": "comparator-operator-test", + "variationType": "STRING", + "defaultValue": "unknown", + "targetingKey": "alice", + "attributes": { + "size": 5, + "country": "US" + }, + "result": { + "value": "small", + "variant": "small", + "flagMetadata": { + "allocationKey": "small-size", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "comparator-operator-test", + "variationType": "STRING", + "defaultValue": "unknown", + "targetingKey": "bob", + "attributes": { + "size": 10, + "country": "Canada" + }, + "result": { + "value": "medium", + "variant": "medium", + "flagMetadata": { + "allocationKey": "medum-size", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "comparator-operator-test", + "variationType": "STRING", + "defaultValue": "unknown", + "targetingKey": "charlie", + "attributes": { + "size": 25 + }, + "result": { + "value": "unknown" + } + }, + { + "flag": "comparator-operator-test", + "variationType": "STRING", + "defaultValue": "unknown", + "targetingKey": "david", + "attributes": { + "size": 26 + }, + "result": { + "value": "large", + "variant": "large", + "flagMetadata": { + "allocationKey": "large-size", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "comparator-operator-test", + "variationType": "STRING", + "defaultValue": "unknown", + "targetingKey": "elize", + "attributes": { + "country": "UK" + }, + "result": { + "value": "unknown" + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-disabled-flag.json b/datadog-ffe/tests/data/tests/test-case-disabled-flag.json new file mode 100644 index 0000000000..0da79189ad --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-disabled-flag.json @@ -0,0 +1,40 @@ +[ + { + "flag": "disabled_flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "alice", + "attributes": { + "email": "alice@mycompany.com", + "country": "US" + }, + "result": { + "value": 0 + } + }, + { + "flag": "disabled_flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "bob", + "attributes": { + "email": "bob@example.com", + "country": "Canada" + }, + "result": { + "value": 0 + } + }, + { + "flag": "disabled_flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "charlie", + "attributes": { + "age": 50 + }, + "result": { + "value": 0 + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-empty-flag.json b/datadog-ffe/tests/data/tests/test-case-empty-flag.json new file mode 100644 index 0000000000..52100b1fe4 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-empty-flag.json @@ -0,0 +1,40 @@ +[ + { + "flag": "empty_flag", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "alice", + "attributes": { + "email": "alice@mycompany.com", + "country": "US" + }, + "result": { + "value": "default_value" + } + }, + { + "flag": "empty_flag", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "bob", + "attributes": { + "email": "bob@example.com", + "country": "Canada" + }, + "result": { + "value": "default_value" + } + }, + { + "flag": "empty_flag", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "charlie", + "attributes": { + "age": 50 + }, + "result": { + "value": "default_value" + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-flag-with-empty-string.json b/datadog-ffe/tests/data/tests/test-case-flag-with-empty-string.json new file mode 100644 index 0000000000..32a1c1febb --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-flag-with-empty-string.json @@ -0,0 +1,36 @@ +[ + { + "flag": "empty_string_flag", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "alice", + "attributes": { + "country": "US" + }, + "result": { + "value": "", + "variant": "empty_string", + "flagMetadata": { + "allocationKey": "allocation-empty", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "empty_string_flag", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "bob", + "attributes": {}, + "result": { + "value": "non_empty", + "variant": "non_empty", + "flagMetadata": { + "allocationKey": "allocation-test", + "variationType": "string", + "doLog": true + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-integer-flag.json b/datadog-ffe/tests/data/tests/test-case-integer-flag.json new file mode 100644 index 0000000000..4a41d042f6 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-integer-flag.json @@ -0,0 +1,382 @@ +[ + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "alice", + "attributes": { + "email": "alice@mycompany.com", + "country": "US" + }, + "result": { + "value": 3, + "variant": "three", + "flagMetadata": { + "allocationKey": "targeted allocation", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "bob", + "attributes": { + "email": "bob@example.com", + "country": "Canada" + }, + "result": { + "value": 3, + "variant": "three", + "flagMetadata": { + "allocationKey": "targeted allocation", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "charlie", + "attributes": { + "age": 50 + }, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "debra", + "attributes": { + "email": "test@test.com", + "country": "Mexico", + "age": 25 + }, + "result": { + "value": 3, + "variant": "three", + "flagMetadata": { + "allocationKey": "targeted allocation", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "1", + "attributes": {}, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "2", + "attributes": {}, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "3", + "attributes": {}, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "4", + "attributes": {}, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "5", + "attributes": {}, + "result": { + "value": 1, + "variant": "one", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "6", + "attributes": {}, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "7", + "attributes": {}, + "result": { + "value": 1, + "variant": "one", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "8", + "attributes": {}, + "result": { + "value": 1, + "variant": "one", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "9", + "attributes": {}, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "10", + "attributes": {}, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "11", + "attributes": {}, + "result": { + "value": 1, + "variant": "one", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "12", + "attributes": {}, + "result": { + "value": 1, + "variant": "one", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "13", + "attributes": {}, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "14", + "attributes": {}, + "result": { + "value": 1, + "variant": "one", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "15", + "attributes": {}, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "16", + "attributes": {}, + "result": { + "value": 2, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "17", + "attributes": {}, + "result": { + "value": 1, + "variant": "one", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "18", + "attributes": {}, + "result": { + "value": 1, + "variant": "one", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "integer-flag", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "19", + "attributes": {}, + "result": { + "value": 1, + "variant": "one", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "number", + "doLog": true + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-kill-switch-flag.json b/datadog-ffe/tests/data/tests/test-case-kill-switch-flag.json new file mode 100644 index 0000000000..29e65ba5bb --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-kill-switch-flag.json @@ -0,0 +1,434 @@ +[ + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "alice", + "attributes": { + "email": "alice@mycompany.com", + "country": "US" + }, + "result": { + "value": true, + "variant": "on", + "flagMetadata": { + "allocationKey": "on-for-NA", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "bob", + "attributes": { + "email": "bob@example.com", + "country": "Canada" + }, + "result": { + "value": true, + "variant": "on", + "flagMetadata": { + "allocationKey": "on-for-NA", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "barbara", + "attributes": { + "email": "barbara@example.com", + "country": "canada" + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "charlie", + "attributes": { + "age": 40 + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "debra", + "attributes": { + "email": "test@test.com", + "country": "Mexico", + "age": 25 + }, + "result": { + "value": true, + "variant": "on", + "flagMetadata": { + "allocationKey": "on-for-NA", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "1", + "attributes": {}, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "2", + "attributes": { + "country": "Mexico" + }, + "result": { + "value": true, + "variant": "on", + "flagMetadata": { + "allocationKey": "on-for-NA", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "3", + "attributes": { + "country": "UK", + "age": 50 + }, + "result": { + "value": true, + "variant": "on", + "flagMetadata": { + "allocationKey": "on-for-age-50+", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "4", + "attributes": { + "country": "Germany" + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "5", + "attributes": { + "country": "Germany" + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "6", + "attributes": { + "country": "Germany" + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "7", + "attributes": { + "country": "US", + "age": 12 + }, + "result": { + "value": true, + "variant": "on", + "flagMetadata": { + "allocationKey": "on-for-NA", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "8", + "attributes": { + "country": "Italy", + "age": 60 + }, + "result": { + "value": true, + "variant": "on", + "flagMetadata": { + "allocationKey": "on-for-age-50+", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "9", + "attributes": { + "email": "email@email.com" + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "10", + "attributes": {}, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "11", + "attributes": {}, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "12", + "attributes": { + "country": "US" + }, + "result": { + "value": true, + "variant": "on", + "flagMetadata": { + "allocationKey": "on-for-NA", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "13", + "attributes": { + "country": "Canada" + }, + "result": { + "value": true, + "variant": "on", + "flagMetadata": { + "allocationKey": "on-for-NA", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "14", + "attributes": {}, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "15", + "attributes": { + "country": "Denmark" + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "16", + "attributes": { + "country": "Norway" + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "17", + "attributes": { + "country": "UK" + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "18", + "attributes": { + "country": "UK" + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + }, + { + "flag": "kill-switch", + "variationType": "BOOLEAN", + "defaultValue": false, + "targetingKey": "19", + "attributes": { + "country": "UK" + }, + "result": { + "value": false, + "variant": "off", + "flagMetadata": { + "allocationKey": "off-for-all", + "variationType": "boolean", + "doLog": true + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-new-user-onboarding-flag.json b/datadog-ffe/tests/data/tests/test-case-new-user-onboarding-flag.json new file mode 100644 index 0000000000..3845597270 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-new-user-onboarding-flag.json @@ -0,0 +1,420 @@ +[ + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "alice", + "attributes": { + "email": "alice@mycompany.com", + "country": "US" + }, + "result": { + "value": "green", + "variant": "green", + "flagMetadata": { + "allocationKey": "internal users", + "variationType": "string", + "doLog": false + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "bob", + "attributes": { + "email": "bob@example.com", + "country": "Canada" + }, + "result": { + "value": "default" + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "charlie", + "attributes": { + "age": 50 + }, + "result": { + "value": "default" + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "debra", + "attributes": { + "email": "test@test.com", + "country": "Mexico", + "age": 25 + }, + "result": { + "value": "blue", + "variant": "blue", + "flagMetadata": { + "allocationKey": "rollout", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "zach", + "attributes": { + "email": "test@test.com", + "country": "Mexico", + "age": 25 + }, + "result": { + "value": "purple", + "variant": "purple", + "flagMetadata": { + "allocationKey": "id rule", + "variationType": "string", + "doLog": false + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "zach", + "attributes": { + "id": "override-id", + "email": "test@test.com", + "country": "Mexico", + "age": 25 + }, + "result": { + "value": "blue", + "variant": "blue", + "flagMetadata": { + "allocationKey": "rollout", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "Zach", + "attributes": { + "email": "test@test.com", + "country": "Mexico", + "age": 25 + }, + "result": { + "value": "default" + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "1", + "attributes": {}, + "result": { + "value": "default" + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "2", + "attributes": { + "country": "Mexico" + }, + "result": { + "value": "blue", + "variant": "blue", + "flagMetadata": { + "allocationKey": "rollout", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "3", + "attributes": { + "country": "UK", + "age": 33 + }, + "result": { + "value": "control", + "variant": "control", + "flagMetadata": { + "allocationKey": "experiment", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "4", + "attributes": { + "country": "Germany" + }, + "result": { + "value": "red", + "variant": "red", + "flagMetadata": { + "allocationKey": "experiment", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "5", + "attributes": { + "country": "Germany" + }, + "result": { + "value": "yellow", + "variant": "yellow", + "flagMetadata": { + "allocationKey": "experiment", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "6", + "attributes": { + "country": "Germany" + }, + "result": { + "value": "yellow", + "variant": "yellow", + "flagMetadata": { + "allocationKey": "experiment", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "7", + "attributes": { + "country": "US" + }, + "result": { + "value": "blue", + "variant": "blue", + "flagMetadata": { + "allocationKey": "rollout", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "8", + "attributes": { + "country": "Italy" + }, + "result": { + "value": "red", + "variant": "red", + "flagMetadata": { + "allocationKey": "experiment", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "9", + "attributes": { + "email": "email@email.com" + }, + "result": { + "value": "default" + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "10", + "attributes": {}, + "result": { + "value": "default" + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "11", + "attributes": {}, + "result": { + "value": "default" + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "12", + "attributes": { + "country": "US" + }, + "result": { + "value": "blue", + "variant": "blue", + "flagMetadata": { + "allocationKey": "rollout", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "13", + "attributes": { + "country": "Canada" + }, + "result": { + "value": "blue", + "variant": "blue", + "flagMetadata": { + "allocationKey": "rollout", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "14", + "attributes": {}, + "result": { + "value": "default" + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "15", + "attributes": { + "country": "Denmark" + }, + "result": { + "value": "yellow", + "variant": "yellow", + "flagMetadata": { + "allocationKey": "experiment", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "16", + "attributes": { + "country": "Norway" + }, + "result": { + "value": "control", + "variant": "control", + "flagMetadata": { + "allocationKey": "experiment", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "17", + "attributes": { + "country": "UK" + }, + "result": { + "value": "control", + "variant": "control", + "flagMetadata": { + "allocationKey": "experiment", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "18", + "attributes": { + "country": "UK" + }, + "result": { + "value": "default" + } + }, + { + "flag": "new-user-onboarding", + "variationType": "STRING", + "defaultValue": "default", + "targetingKey": "19", + "attributes": { + "country": "UK" + }, + "result": { + "value": "red", + "variant": "red", + "flagMetadata": { + "allocationKey": "experiment", + "variationType": "string", + "doLog": true + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-no-allocations-flag.json b/datadog-ffe/tests/data/tests/test-case-no-allocations-flag.json new file mode 100644 index 0000000000..132c39db32 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-no-allocations-flag.json @@ -0,0 +1,52 @@ +[ + { + "flag": "no_allocations_flag", + "variationType": "JSON", + "defaultValue": { + "hello": "world" + }, + "targetingKey": "alice", + "attributes": { + "email": "alice@mycompany.com", + "country": "US" + }, + "result": { + "value": { + "hello": "world" + } + } + }, + { + "flag": "no_allocations_flag", + "variationType": "JSON", + "defaultValue": { + "hello": "world" + }, + "targetingKey": "bob", + "attributes": { + "email": "bob@example.com", + "country": "Canada" + }, + "result": { + "value": { + "hello": "world" + } + } + }, + { + "flag": "no_allocations_flag", + "variationType": "JSON", + "defaultValue": { + "hello": "world" + }, + "targetingKey": "charlie", + "attributes": { + "age": 50 + }, + "result": { + "value": { + "hello": "world" + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-null-operator-flag.json b/datadog-ffe/tests/data/tests/test-case-null-operator-flag.json new file mode 100644 index 0000000000..dd5c687b89 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-null-operator-flag.json @@ -0,0 +1,94 @@ +[ + { + "flag": "null-operator-test", + "variationType": "STRING", + "defaultValue": "default-null", + "targetingKey": "alice", + "attributes": { + "size": 5, + "country": "US" + }, + "result": { + "value": "old", + "variant": "old", + "flagMetadata": { + "allocationKey": "null-operator", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "null-operator-test", + "variationType": "STRING", + "defaultValue": "default-null", + "targetingKey": "bob", + "attributes": { + "size": 10, + "country": "Canada" + }, + "result": { + "value": "new", + "variant": "new", + "flagMetadata": { + "allocationKey": "not-null-operator", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "null-operator-test", + "variationType": "STRING", + "defaultValue": "default-null", + "targetingKey": "charlie", + "attributes": { + "size": null + }, + "result": { + "value": "old", + "variant": "old", + "flagMetadata": { + "allocationKey": "null-operator", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "null-operator-test", + "variationType": "STRING", + "defaultValue": "default-null", + "targetingKey": "david", + "attributes": { + "size": 26 + }, + "result": { + "value": "new", + "variant": "new", + "flagMetadata": { + "allocationKey": "not-null-operator", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "null-operator-test", + "variationType": "STRING", + "defaultValue": "default-null", + "targetingKey": "elize", + "attributes": { + "country": "UK" + }, + "result": { + "value": "old", + "variant": "old", + "flagMetadata": { + "allocationKey": "null-operator", + "variationType": "string", + "doLog": true + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-numeric-flag.json b/datadog-ffe/tests/data/tests/test-case-numeric-flag.json new file mode 100644 index 0000000000..0e6ed8b1b3 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-numeric-flag.json @@ -0,0 +1,58 @@ +[ + { + "flag": "numeric_flag", + "variationType": "NUMERIC", + "defaultValue": 0.0, + "targetingKey": "alice", + "attributes": { + "email": "alice@mycompany.com", + "country": "US" + }, + "result": { + "value": 3.1415926, + "variant": "pi", + "flagMetadata": { + "allocationKey": "rollout", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "numeric_flag", + "variationType": "NUMERIC", + "defaultValue": 0.0, + "targetingKey": "bob", + "attributes": { + "email": "bob@example.com", + "country": "Canada" + }, + "result": { + "value": 3.1415926, + "variant": "pi", + "flagMetadata": { + "allocationKey": "rollout", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "numeric_flag", + "variationType": "NUMERIC", + "defaultValue": 0.0, + "targetingKey": "charlie", + "attributes": { + "age": 50 + }, + "result": { + "value": 3.1415926, + "variant": "pi", + "flagMetadata": { + "allocationKey": "rollout", + "variationType": "number", + "doLog": true + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-numeric-one-of.json b/datadog-ffe/tests/data/tests/test-case-numeric-one-of.json new file mode 100644 index 0000000000..5ab68af519 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-numeric-one-of.json @@ -0,0 +1,122 @@ +[ + { + "flag": "numeric-one-of", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "alice", + "attributes": { + "number": 1 + }, + "result": { + "value": 1, + "variant": "1", + "flagMetadata": { + "allocationKey": "1-for-1", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "numeric-one-of", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "bob", + "attributes": { + "number": 2 + }, + "result": { + "value": 0 + } + }, + { + "flag": "numeric-one-of", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "charlie", + "attributes": { + "number": 3 + }, + "result": { + "value": 3, + "variant": "3", + "flagMetadata": { + "allocationKey": "3-for-not-2", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "numeric-one-of", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "derek", + "attributes": { + "number": 4 + }, + "result": { + "value": 3, + "variant": "3", + "flagMetadata": { + "allocationKey": "3-for-not-2", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "numeric-one-of", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "erica", + "attributes": { + "number": "1" + }, + "result": { + "value": 1, + "variant": "1", + "flagMetadata": { + "allocationKey": "1-for-1", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "numeric-one-of", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "frank", + "attributes": { + "number": 1 + }, + "result": { + "value": 1, + "variant": "1", + "flagMetadata": { + "allocationKey": "1-for-1", + "variationType": "number", + "doLog": true + } + } + }, + { + "flag": "numeric-one-of", + "variationType": "INTEGER", + "defaultValue": 0, + "targetingKey": "george", + "attributes": { + "number": 123456789 + }, + "result": { + "value": 2, + "variant": "2", + "flagMetadata": { + "allocationKey": "2-for-123456789", + "variationType": "number", + "doLog": true + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-regex-flag.json b/datadog-ffe/tests/data/tests/test-case-regex-flag.json new file mode 100644 index 0000000000..952a37aabc --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-regex-flag.json @@ -0,0 +1,65 @@ +[ + { + "flag": "regex-flag", + "variationType": "STRING", + "defaultValue": "none", + "targetingKey": "alice", + "attributes": { + "version": "1.15.0", + "email": "alice@example.com" + }, + "result": { + "value": "partial-example", + "variant": "partial-example", + "flagMetadata": { + "allocationKey": "partial-example", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "regex-flag", + "variationType": "STRING", + "defaultValue": "none", + "targetingKey": "bob", + "attributes": { + "version": "0.20.1", + "email": "bob@test.com" + }, + "result": { + "value": "test", + "variant": "test", + "flagMetadata": { + "allocationKey": "test", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "regex-flag", + "variationType": "STRING", + "defaultValue": "none", + "targetingKey": "charlie", + "attributes": { + "version": "2.1.13" + }, + "result": { + "value": "none" + } + }, + { + "flag": "regex-flag", + "variationType": "STRING", + "defaultValue": "none", + "targetingKey": "derek", + "attributes": { + "version": "2.1.13", + "email": "derek@gmail.com" + }, + "result": { + "value": "none" + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-case-start-and-end-date-flag.json b/datadog-ffe/tests/data/tests/test-case-start-and-end-date-flag.json new file mode 100644 index 0000000000..caf805d143 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-case-start-and-end-date-flag.json @@ -0,0 +1,58 @@ +[ + { + "flag": "start-and-end-date-test", + "variationType": "STRING", + "defaultValue": "unknown", + "targetingKey": "alice", + "attributes": { + "version": "1.15.0", + "country": "US" + }, + "result": { + "value": "current", + "variant": "current", + "flagMetadata": { + "allocationKey": "current-versions", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "start-and-end-date-test", + "variationType": "STRING", + "defaultValue": "unknown", + "targetingKey": "bob", + "attributes": { + "version": "0.20.1", + "country": "Canada" + }, + "result": { + "value": "current", + "variant": "current", + "flagMetadata": { + "allocationKey": "current-versions", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "start-and-end-date-test", + "variationType": "STRING", + "defaultValue": "unknown", + "targetingKey": "charlie", + "attributes": { + "version": "2.1.13" + }, + "result": { + "value": "current", + "variant": "current", + "flagMetadata": { + "allocationKey": "current-versions", + "variationType": "string", + "doLog": true + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-flag-that-does-not-exist.json b/datadog-ffe/tests/data/tests/test-flag-that-does-not-exist.json new file mode 100644 index 0000000000..7499bba1c5 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-flag-that-does-not-exist.json @@ -0,0 +1,40 @@ +[ + { + "flag": "flag-that-does-not-exist", + "variationType": "NUMERIC", + "defaultValue": 0.0, + "targetingKey": "alice", + "attributes": { + "email": "alice@mycompany.com", + "country": "US" + }, + "result": { + "value": 0.0 + } + }, + { + "flag": "flag-that-does-not-exist", + "variationType": "NUMERIC", + "defaultValue": 0.0, + "targetingKey": "bob", + "attributes": { + "email": "bob@example.com", + "country": "Canada" + }, + "result": { + "value": 0.0 + } + }, + { + "flag": "flag-that-does-not-exist", + "variationType": "NUMERIC", + "defaultValue": 0.0, + "targetingKey": "charlie", + "attributes": { + "age": 50 + }, + "result": { + "value": 0.0 + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-json-config-flag.json b/datadog-ffe/tests/data/tests/test-json-config-flag.json new file mode 100644 index 0000000000..3d4478ff71 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-json-config-flag.json @@ -0,0 +1,96 @@ +[ + { + "flag": "json-config-flag", + "variationType": "JSON", + "defaultValue": { + "foo": "bar" + }, + "targetingKey": "alice", + "attributes": { + "email": "alice@mycompany.com", + "country": "US" + }, + "result": { + "value": { + "integer": 1, + "string": "one", + "float": 1.0 + }, + "variant": "one", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "object", + "doLog": true + } + } + }, + { + "flag": "json-config-flag", + "variationType": "JSON", + "defaultValue": { + "foo": "bar" + }, + "targetingKey": "bob", + "attributes": { + "email": "bob@example.com", + "country": "Canada" + }, + "result": { + "value": { + "integer": 2, + "string": "two", + "float": 2.0 + }, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "object", + "doLog": true + } + } + }, + { + "flag": "json-config-flag", + "variationType": "JSON", + "defaultValue": { + "foo": "bar" + }, + "targetingKey": "charlie", + "attributes": { + "age": 50 + }, + "result": { + "value": { + "integer": 2, + "string": "two", + "float": 2.0 + }, + "variant": "two", + "flagMetadata": { + "allocationKey": "50/50 split", + "variationType": "object", + "doLog": true + } + } + }, + { + "flag": "json-config-flag", + "variationType": "JSON", + "defaultValue": { + "foo": "bar" + }, + "targetingKey": "diana", + "attributes": { + "Force Empty": true + }, + "result": { + "value": {}, + "variant": "empty", + "flagMetadata": { + "allocationKey": "Optionally Force Empty", + "variationType": "object", + "doLog": true + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-no-allocations-flag.json b/datadog-ffe/tests/data/tests/test-no-allocations-flag.json new file mode 100644 index 0000000000..45867e5897 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-no-allocations-flag.json @@ -0,0 +1,52 @@ +[ + { + "flag": "no_allocations_flag", + "variationType": "JSON", + "defaultValue": { + "message": "Hello, world!" + }, + "targetingKey": "alice", + "attributes": { + "email": "alice@mycompany.com", + "country": "US" + }, + "result": { + "value": { + "message": "Hello, world!" + } + } + }, + { + "flag": "no_allocations_flag", + "variationType": "JSON", + "defaultValue": { + "message": "Hello, world!" + }, + "targetingKey": "bob", + "attributes": { + "email": "bob@example.com", + "country": "Canada" + }, + "result": { + "value": { + "message": "Hello, world!" + } + } + }, + { + "flag": "no_allocations_flag", + "variationType": "JSON", + "defaultValue": { + "message": "Hello, world!" + }, + "targetingKey": "charlie", + "attributes": { + "age": 50 + }, + "result": { + "value": { + "message": "Hello, world!" + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-special-characters.json b/datadog-ffe/tests/data/tests/test-special-characters.json new file mode 100644 index 0000000000..59ef5cbe87 --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-special-characters.json @@ -0,0 +1,78 @@ +[ + { + "flag": "special-characters", + "variationType": "JSON", + "defaultValue": {}, + "targetingKey": "ash", + "attributes": {}, + "result": { + "value": { + "a": "kümmert", + "b": "schön" + }, + "variant": "de", + "flagMetadata": { + "allocationKey": "allocation-test", + "variationType": "object", + "doLog": true + } + } + }, + { + "flag": "special-characters", + "variationType": "JSON", + "defaultValue": {}, + "targetingKey": "ben", + "attributes": {}, + "result": { + "value": { + "a": "піклуватися", + "b": "любов" + }, + "variant": "ua", + "flagMetadata": { + "allocationKey": "allocation-test", + "variationType": "object", + "doLog": true + } + } + }, + { + "flag": "special-characters", + "variationType": "JSON", + "defaultValue": {}, + "targetingKey": "cameron", + "attributes": {}, + "result": { + "value": { + "a": "照顾", + "b": "漂亮" + }, + "variant": "zh", + "flagMetadata": { + "allocationKey": "allocation-test", + "variationType": "object", + "doLog": true + } + } + }, + { + "flag": "special-characters", + "variationType": "JSON", + "defaultValue": {}, + "targetingKey": "darryl", + "attributes": {}, + "result": { + "value": { + "a": "🤗", + "b": "🌸" + }, + "variant": "emoji", + "flagMetadata": { + "allocationKey": "allocation-test", + "variationType": "object", + "doLog": true + } + } + } +] diff --git a/datadog-ffe/tests/data/tests/test-string-with-special-characters.json b/datadog-ffe/tests/data/tests/test-string-with-special-characters.json new file mode 100644 index 0000000000..27d063122c --- /dev/null +++ b/datadog-ffe/tests/data/tests/test-string-with-special-characters.json @@ -0,0 +1,1190 @@ +[ + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_spaces", + "attributes": { + "string_with_spaces": true + }, + "result": { + "value": " a b c d e f ", + "variant": "string_with_spaces", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_spaces", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_space", + "attributes": { + "string_with_only_one_space": true + }, + "result": { + "value": " ", + "variant": "string_with_only_one_space", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_space", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_spaces", + "attributes": { + "string_with_only_multiple_spaces": true + }, + "result": { + "value": " ", + "variant": "string_with_only_multiple_spaces", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_spaces", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_dots", + "attributes": { + "string_with_dots": true + }, + "result": { + "value": ".a.b.c.d.e.f.", + "variant": "string_with_dots", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_dots", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_dot", + "attributes": { + "string_with_only_one_dot": true + }, + "result": { + "value": ".", + "variant": "string_with_only_one_dot", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_dot", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_dots", + "attributes": { + "string_with_only_multiple_dots": true + }, + "result": { + "value": ".......", + "variant": "string_with_only_multiple_dots", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_dots", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_comas", + "attributes": { + "string_with_comas": true + }, + "result": { + "value": ",a,b,c,d,e,f,", + "variant": "string_with_comas", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_comas", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_coma", + "attributes": { + "string_with_only_one_coma": true + }, + "result": { + "value": ",", + "variant": "string_with_only_one_coma", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_coma", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_comas", + "attributes": { + "string_with_only_multiple_comas": true + }, + "result": { + "value": ",,,,,,,", + "variant": "string_with_only_multiple_comas", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_comas", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_colons", + "attributes": { + "string_with_colons": true + }, + "result": { + "value": ":a:b:c:d:e:f:", + "variant": "string_with_colons", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_colons", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_colon", + "attributes": { + "string_with_only_one_colon": true + }, + "result": { + "value": ":", + "variant": "string_with_only_one_colon", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_colon", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_colons", + "attributes": { + "string_with_only_multiple_colons": true + }, + "result": { + "value": ":::::::", + "variant": "string_with_only_multiple_colons", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_colons", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_semicolons", + "attributes": { + "string_with_semicolons": true + }, + "result": { + "value": ";a;b;c;d;e;f;", + "variant": "string_with_semicolons", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_semicolons", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_semicolon", + "attributes": { + "string_with_only_one_semicolon": true + }, + "result": { + "value": ";", + "variant": "string_with_only_one_semicolon", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_semicolon", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_semicolons", + "attributes": { + "string_with_only_multiple_semicolons": true + }, + "result": { + "value": ";;;;;;;", + "variant": "string_with_only_multiple_semicolons", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_semicolons", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_slashes", + "attributes": { + "string_with_slashes": true + }, + "result": { + "value": "/a/b/c/d/e/f/", + "variant": "string_with_slashes", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_slashes", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_slash", + "attributes": { + "string_with_only_one_slash": true + }, + "result": { + "value": "/", + "variant": "string_with_only_one_slash", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_slash", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_slashes", + "attributes": { + "string_with_only_multiple_slashes": true + }, + "result": { + "value": "///////", + "variant": "string_with_only_multiple_slashes", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_slashes", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_dashes", + "attributes": { + "string_with_dashes": true + }, + "result": { + "value": "-a-b-c-d-e-f-", + "variant": "string_with_dashes", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_dashes", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_dash", + "attributes": { + "string_with_only_one_dash": true + }, + "result": { + "value": "-", + "variant": "string_with_only_one_dash", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_dash", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_dashes", + "attributes": { + "string_with_only_multiple_dashes": true + }, + "result": { + "value": "-------", + "variant": "string_with_only_multiple_dashes", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_dashes", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_underscores", + "attributes": { + "string_with_underscores": true + }, + "result": { + "value": "_a_b_c_d_e_f_", + "variant": "string_with_underscores", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_underscores", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_underscore", + "attributes": { + "string_with_only_one_underscore": true + }, + "result": { + "value": "_", + "variant": "string_with_only_one_underscore", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_underscore", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_underscores", + "attributes": { + "string_with_only_multiple_underscores": true + }, + "result": { + "value": "_______", + "variant": "string_with_only_multiple_underscores", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_underscores", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_plus_signs", + "attributes": { + "string_with_plus_signs": true + }, + "result": { + "value": "+a+b+c+d+e+f+", + "variant": "string_with_plus_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_plus_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_plus_sign", + "attributes": { + "string_with_only_one_plus_sign": true + }, + "result": { + "value": "+", + "variant": "string_with_only_one_plus_sign", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_plus_sign", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_plus_signs", + "attributes": { + "string_with_only_multiple_plus_signs": true + }, + "result": { + "value": "+++++++", + "variant": "string_with_only_multiple_plus_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_plus_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_equal_signs", + "attributes": { + "string_with_equal_signs": true + }, + "result": { + "value": "=a=b=c=d=e=f=", + "variant": "string_with_equal_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_equal_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_equal_sign", + "attributes": { + "string_with_only_one_equal_sign": true + }, + "result": { + "value": "=", + "variant": "string_with_only_one_equal_sign", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_equal_sign", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_equal_signs", + "attributes": { + "string_with_only_multiple_equal_signs": true + }, + "result": { + "value": "=======", + "variant": "string_with_only_multiple_equal_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_equal_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_dollar_signs", + "attributes": { + "string_with_dollar_signs": true + }, + "result": { + "value": "$a$b$c$d$e$f$", + "variant": "string_with_dollar_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_dollar_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_dollar_sign", + "attributes": { + "string_with_only_one_dollar_sign": true + }, + "result": { + "value": "$", + "variant": "string_with_only_one_dollar_sign", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_dollar_sign", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_dollar_signs", + "attributes": { + "string_with_only_multiple_dollar_signs": true + }, + "result": { + "value": "$$$$$$$", + "variant": "string_with_only_multiple_dollar_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_dollar_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_at_signs", + "attributes": { + "string_with_at_signs": true + }, + "result": { + "value": "@a@b@c@d@e@f@", + "variant": "string_with_at_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_at_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_at_sign", + "attributes": { + "string_with_only_one_at_sign": true + }, + "result": { + "value": "@", + "variant": "string_with_only_one_at_sign", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_at_sign", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_at_signs", + "attributes": { + "string_with_only_multiple_at_signs": true + }, + "result": { + "value": "@@@@@@@", + "variant": "string_with_only_multiple_at_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_at_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_amp_signs", + "attributes": { + "string_with_amp_signs": true + }, + "result": { + "value": "&a&b&c&d&e&f&", + "variant": "string_with_amp_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_amp_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_amp_sign", + "attributes": { + "string_with_only_one_amp_sign": true + }, + "result": { + "value": "&", + "variant": "string_with_only_one_amp_sign", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_amp_sign", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_amp_signs", + "attributes": { + "string_with_only_multiple_amp_signs": true + }, + "result": { + "value": "&&&&&&&", + "variant": "string_with_only_multiple_amp_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_amp_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_hash_signs", + "attributes": { + "string_with_hash_signs": true + }, + "result": { + "value": "#a#b#c#d#e#f#", + "variant": "string_with_hash_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_hash_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_hash_sign", + "attributes": { + "string_with_only_one_hash_sign": true + }, + "result": { + "value": "#", + "variant": "string_with_only_one_hash_sign", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_hash_sign", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_hash_signs", + "attributes": { + "string_with_only_multiple_hash_signs": true + }, + "result": { + "value": "#######", + "variant": "string_with_only_multiple_hash_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_hash_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_percentage_signs", + "attributes": { + "string_with_percentage_signs": true + }, + "result": { + "value": "%a%b%c%d%e%f%", + "variant": "string_with_percentage_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_percentage_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_percentage_sign", + "attributes": { + "string_with_only_one_percentage_sign": true + }, + "result": { + "value": "%", + "variant": "string_with_only_one_percentage_sign", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_percentage_sign", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_percentage_signs", + "attributes": { + "string_with_only_multiple_percentage_signs": true + }, + "result": { + "value": "%%%%%%%", + "variant": "string_with_only_multiple_percentage_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_percentage_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_tilde_signs", + "attributes": { + "string_with_tilde_signs": true + }, + "result": { + "value": "~a~b~c~d~e~f~", + "variant": "string_with_tilde_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_tilde_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_tilde_sign", + "attributes": { + "string_with_only_one_tilde_sign": true + }, + "result": { + "value": "~", + "variant": "string_with_only_one_tilde_sign", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_tilde_sign", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_tilde_signs", + "attributes": { + "string_with_only_multiple_tilde_signs": true + }, + "result": { + "value": "~~~~~~~", + "variant": "string_with_only_multiple_tilde_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_tilde_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_asterix_signs", + "attributes": { + "string_with_asterix_signs": true + }, + "result": { + "value": "*a*b*c*d*e*f*", + "variant": "string_with_asterix_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_asterix_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_asterix_sign", + "attributes": { + "string_with_only_one_asterix_sign": true + }, + "result": { + "value": "*", + "variant": "string_with_only_one_asterix_sign", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_asterix_sign", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_asterix_signs", + "attributes": { + "string_with_only_multiple_asterix_signs": true + }, + "result": { + "value": "*******", + "variant": "string_with_only_multiple_asterix_signs", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_asterix_signs", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_single_quotes", + "attributes": { + "string_with_single_quotes": true + }, + "result": { + "value": "'a'b'c'd'e'f'", + "variant": "string_with_single_quotes", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_single_quotes", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_single_quote", + "attributes": { + "string_with_only_one_single_quote": true + }, + "result": { + "value": "'", + "variant": "string_with_only_one_single_quote", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_single_quote", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_single_quotes", + "attributes": { + "string_with_only_multiple_single_quotes": true + }, + "result": { + "value": "'''''''", + "variant": "string_with_only_multiple_single_quotes", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_single_quotes", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_question_marks", + "attributes": { + "string_with_question_marks": true + }, + "result": { + "value": "?a?b?c?d?e?f?", + "variant": "string_with_question_marks", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_question_marks", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_question_mark", + "attributes": { + "string_with_only_one_question_mark": true + }, + "result": { + "value": "?", + "variant": "string_with_only_one_question_mark", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_question_mark", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_question_marks", + "attributes": { + "string_with_only_multiple_question_marks": true + }, + "result": { + "value": "???????", + "variant": "string_with_only_multiple_question_marks", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_question_marks", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_exclamation_marks", + "attributes": { + "string_with_exclamation_marks": true + }, + "result": { + "value": "!a!b!c!d!e!f!", + "variant": "string_with_exclamation_marks", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_exclamation_marks", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_exclamation_mark", + "attributes": { + "string_with_only_one_exclamation_mark": true + }, + "result": { + "value": "!", + "variant": "string_with_only_one_exclamation_mark", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_exclamation_mark", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_exclamation_marks", + "attributes": { + "string_with_only_multiple_exclamation_marks": true + }, + "result": { + "value": "!!!!!!!", + "variant": "string_with_only_multiple_exclamation_marks", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_exclamation_marks", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_opening_parentheses", + "attributes": { + "string_with_opening_parentheses": true + }, + "result": { + "value": "(a(b(c(d(e(f(", + "variant": "string_with_opening_parentheses", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_opening_parentheses", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_opening_parenthese", + "attributes": { + "string_with_only_one_opening_parenthese": true + }, + "result": { + "value": "(", + "variant": "string_with_only_one_opening_parenthese", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_opening_parenthese", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_opening_parentheses", + "attributes": { + "string_with_only_multiple_opening_parentheses": true + }, + "result": { + "value": "(((((((", + "variant": "string_with_only_multiple_opening_parentheses", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_opening_parentheses", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_closing_parentheses", + "attributes": { + "string_with_closing_parentheses": true + }, + "result": { + "value": ")a)b)c)d)e)f)", + "variant": "string_with_closing_parentheses", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_closing_parentheses", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_one_closing_parenthese", + "attributes": { + "string_with_only_one_closing_parenthese": true + }, + "result": { + "value": ")", + "variant": "string_with_only_one_closing_parenthese", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_one_closing_parenthese", + "variationType": "string", + "doLog": true + } + } + }, + { + "flag": "string_flag_with_special_characters", + "variationType": "STRING", + "defaultValue": "default_value", + "targetingKey": "string_with_only_multiple_closing_parentheses", + "attributes": { + "string_with_only_multiple_closing_parentheses": true + }, + "result": { + "value": ")))))))", + "variant": "string_with_only_multiple_closing_parentheses", + "flagMetadata": { + "allocationKey": "allocation-test-string_with_only_multiple_closing_parentheses", + "variationType": "string", + "doLog": true + } + } + } +] diff --git a/tools/docker/Dockerfile.build b/tools/docker/Dockerfile.build index a8ba704a4b..cb5153c6fa 100644 --- a/tools/docker/Dockerfile.build +++ b/tools/docker/Dockerfile.build @@ -114,6 +114,7 @@ COPY "data-pipeline-ffi/Cargo.toml" "data-pipeline-ffi/" COPY "bin_tests/Cargo.toml" "bin_tests/" COPY "tinybytes/Cargo.toml" "tinybytes/" COPY "builder/Cargo.toml" "builder/" +COPY "datadog-ffe/Cargo.toml" "datadog-ffe/" RUN find -name "Cargo.toml" | sed -e s#Cargo.toml#src/lib.rs#g | xargs -n 1 sh -c 'mkdir -p $(dirname $1); touch $1; echo $1' create_stubs RUN echo \ bin_tests/src/bin/crashtracker_bin_test.rs \