From 7e438f347d75814897287dbfc18b01c59b5e694b Mon Sep 17 00:00:00 2001 From: Garance Date: Tue, 26 Nov 2024 17:31:35 -0500 Subject: [PATCH 01/13] feat: add integration test for mongo --- Cargo.lock | 509 ++++++++++++++++--------- rig-mongodb/Cargo.toml | 3 +- rig-mongodb/src/lib.rs | 14 +- rig-mongodb/tests/integration_tests.rs | 100 +++++ 4 files changed, 445 insertions(+), 181 deletions(-) create mode 100644 rig-mongodb/tests/integration_tests.rs diff --git a/Cargo.lock b/Cargo.lock index aefa6a32..577f6734 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -743,7 +743,7 @@ dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", "aws-smithy-types", - "rustc_version 0.4.1", + "rustc_version", "tracing", ] @@ -893,6 +893,56 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bollard" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41711ad46fda47cd701f6908e59d1bd6b9a2b7464c0d0aeab95c6d37096ff8a" +dependencies = [ + "base64 0.22.1", + "bollard-stubs", + "bytes", + "futures-core", + "futures-util", + "hex", + "home", + "http 1.1.0", + "http-body-util", + "hyper 1.4.1", + "hyper-named-pipe", + "hyper-rustls 0.27.3", + "hyper-util", + "hyperlocal", + "log", + "pin-project-lite", + "rustls 0.23.14", + "rustls-native-certs 0.7.3", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-util", + "tower-service", + "url", + "winapi", +] + +[[package]] +name = "bollard-stubs" +version = "1.45.0-rc.26.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7c5415e3a6bc6d3e99eff6268e488fd4ee25e7b28c10f08fa6760bd9de16e4" +dependencies = [ + "serde", + "serde_repr", + "serde_with", +] + [[package]] name = "bson" version = "2.13.0" @@ -993,7 +1043,7 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.23", + "semver", "serde", "serde_json", ] @@ -1240,38 +1290,14 @@ dependencies = [ "memchr", ] -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core 0.13.4", - "darling_macro 0.13.4", -] - [[package]] name = "darling" version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.20.10", - "darling_macro 0.20.10", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", + "darling_core", + "darling_macro", ] [[package]] @@ -1284,28 +1310,17 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim 0.11.1", + "strsim", "syn 2.0.79", ] -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core 0.13.4", - "quote", - "syn 1.0.109", -] - [[package]] name = "darling_macro" version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.20.10", + "darling_core", "quote", "syn 2.0.79", ] @@ -1708,7 +1723,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ - "darling 0.20.10", + "darling", "proc-macro2", "quote", "syn 2.0.79", @@ -1733,7 +1748,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.1", + "rustc_version", "syn 2.0.79", ] @@ -1781,6 +1796,17 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "docker_credential" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31951f49556e34d90ed28342e1df7e1cb7a229c4cab0aecc627b5d91edd41d07" +dependencies = [ + "base64 0.21.7", + "serde", + "serde_json", +] + [[package]] name = "downcast-rs" version = "1.2.1" @@ -1810,14 +1836,14 @@ dependencies = [ [[package]] name = "enum-as-inner" -version = "0.4.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.79", ] [[package]] @@ -1845,6 +1871,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1883,6 +1920,18 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -1896,7 +1945,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8add37afff2d4ffa83bc748a70b4b1370984f6980768554182424ef71447c35f" dependencies = [ "bitflags 1.3.2", - "rustc_version 0.4.1", + "rustc_version", ] [[package]] @@ -2233,6 +2282,51 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hickory-proto" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "hmac" version = "0.12.1" @@ -2242,6 +2336,15 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "hostname" version = "0.3.1" @@ -2378,6 +2481,21 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-named-pipe" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" +dependencies = [ + "hex", + "hyper 1.4.1", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", + "winapi", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -2458,6 +2576,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "hyperlocal" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986c5ce3b994526b3cd75578e62554abd09f0899d6206de48b3e96ab34ccc8c7" +dependencies = [ + "hex", + "http-body-util", + "hyper 1.4.1", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "hyperloglogplus" version = "0.4.1" @@ -2498,11 +2631,10 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -3057,7 +3189,7 @@ dependencies = [ "regex", "serde", "serde_json", - "serde_with 3.11.0", + "serde_with", "snafu", "tokio", "url", @@ -3159,6 +3291,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", + "redox_syscall 0.5.7", ] [[package]] @@ -3257,12 +3390,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "matchit" version = "0.7.3" @@ -3361,7 +3488,7 @@ dependencies = [ "once_cell", "parking_lot", "quanta", - "rustc_version 0.4.1", + "rustc_version", "scheduled-thread-pool", "skeptic", "smallvec", @@ -3373,9 +3500,9 @@ dependencies = [ [[package]] name = "mongodb" -version = "2.8.2" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef206acb1b72389b49bc9985efe7eb1f8a9bb18e5680d262fac26c07f44025f1" +checksum = "c857d71f918b38221baf2fdff7207fec9984b4504901544772b1edf0302d669f" dependencies = [ "async-trait", "base64 0.13.1", @@ -3389,9 +3516,12 @@ dependencies = [ "futures-io", "futures-util", "hex", + "hickory-proto", + "hickory-resolver", "hmac", - "lazy_static", "md-5", + "mongodb-internal-macros", + "once_cell", "pbkdf2", "percent-encoding", "rand", @@ -3400,24 +3530,33 @@ dependencies = [ "rustls-pemfile 1.0.4", "serde", "serde_bytes", - "serde_with 1.14.0", + "serde_with", "sha-1", "sha2", - "socket2 0.4.10", + "socket2 0.5.7", "stringprep", - "strsim 0.10.0", + "strsim", "take_mut", "thiserror", "tokio", "tokio-rustls 0.24.1", "tokio-util", - "trust-dns-proto", - "trust-dns-resolver", "typed-builder", "uuid", "webpki-roots 0.25.4", ] +[[package]] +name = "mongodb-internal-macros" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6dbc533e93429a71c44a14c04547ac783b56d3f22e6c4f12b1b994cf93844e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + [[package]] name = "multimap" version = "0.10.0" @@ -3751,11 +3890,36 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.7", "smallvec", "windows-targets 0.52.6", ] +[[package]] +name = "parse-display" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914a1c2265c98e2446911282c6ac86d8524f495792c38c5bd884f80499c7538a" +dependencies = [ + "parse-display-derive", + "regex", + "regex-syntax", +] + +[[package]] +name = "parse-display-derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae7800a4c974efd12df917266338e79a7a74415173caf7e70aa0a0707345281" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "regex-syntax", + "structmeta", + "syn 2.0.79", +] + [[package]] name = "parse-zoneinfo" version = "0.3.1" @@ -4245,6 +4409,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.5.7" @@ -4446,6 +4619,7 @@ dependencies = [ "rig-core", "serde", "serde_json", + "testcontainers", "tokio", "tracing", ] @@ -4531,32 +4705,23 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.23", + "semver", ] [[package]] name = "rustc_version_runtime" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d31b7153270ebf48bf91c65ae5b0c00e749c4cfad505f66530ac74950249582f" +checksum = "2dd18cd2bae1820af0b6ad5e54f4a51d0f3fcc53b05f845675074efcc7af071d" dependencies = [ - "rustc_version 0.2.3", - "semver 0.9.0", + "rustc_version", + "semver", ] [[package]] @@ -4798,15 +4963,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.23" @@ -4816,12 +4972,6 @@ dependencies = [ "serde", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.210" @@ -4875,6 +5025,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -4887,16 +5048,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" -dependencies = [ - "serde", - "serde_with_macros 1.5.2", -] - [[package]] name = "serde_with" version = "3.11.0" @@ -4911,29 +5062,17 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "serde_with_macros 3.11.0", + "serde_with_macros", "time", ] -[[package]] -name = "serde_with_macros" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" -dependencies = [ - "darling 0.13.4", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "serde_with_macros" version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ - "darling 0.20.10", + "darling", "proc-macro2", "quote", "syn 2.0.79", @@ -5151,15 +5290,32 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "strsim" -version = "0.11.1" +name = "structmeta" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "2e1575d8d40908d70f6fd05537266b90ae71b15dbbe7a8b7dffa2b759306d329" +dependencies = [ + "proc-macro2", + "quote", + "structmeta-derive", + "syn 2.0.79", +] + +[[package]] +name = "structmeta-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] [[package]] name = "strum" @@ -5435,6 +5591,35 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +[[package]] +name = "testcontainers" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f40cc2bd72e17f328faf8ca7687fe337e61bccd8acf9674fa78dd3792b045e1" +dependencies = [ + "async-trait", + "bollard", + "bollard-stubs", + "bytes", + "docker_credential", + "either", + "etcetera", + "futures", + "log", + "memchr", + "parse-display", + "pin-project-lite", + "serde", + "serde_json", + "serde_with", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tar", + "tokio-util", + "url", +] + [[package]] name = "textwrap" version = "0.16.1" @@ -5602,6 +5787,21 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tar" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5714c010ca3e5c27114c1cdeb9d14641ace49874aa5626d7149e47aedace75" +dependencies = [ + "filetime", + "futures-core", + "libc", + "redox_syscall 0.3.5", + "tokio", + "tokio-stream", + "xattr", +] + [[package]] name = "tokio-util" version = "0.7.12" @@ -5759,51 +5959,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" -[[package]] -name = "trust-dns-proto" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.2.3", - "ipnet", - "lazy_static", - "log", - "rand", - "smallvec", - "thiserror", - "tinyvec", - "tokio", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ba72c2ea84515690c9fcef4c6c660bb9df3036ed1051686de84605b74fd558" -dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lazy_static", - "log", - "lru-cache", - "parking_lot", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "trust-dns-proto", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -5906,6 +6061,7 @@ dependencies = [ "form_urlencoded", "idna 0.5.0", "percent-encoding", + "serde", ] [[package]] @@ -6339,6 +6495,17 @@ dependencies = [ "tap", ] +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys 0.4.14", + "rustix 0.38.37", +] + [[package]] name = "xmlparser" version = "0.13.6" diff --git a/rig-mongodb/Cargo.toml b/rig-mongodb/Cargo.toml index edb755e0..503d3a08 100644 --- a/rig-mongodb/Cargo.toml +++ b/rig-mongodb/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/0xPlaygrounds/rig" [dependencies] futures = "0.3.30" -mongodb = "2.8.2" +mongodb = "3.1.0" rig-core = { path = "../rig-core", version = "0.4.1" } serde = { version = "1.0.203", features = ["derive"] } serde_json = "1.0.117" @@ -19,4 +19,5 @@ tracing = "0.1.40" [dev-dependencies] anyhow = "1.0.86" +testcontainers = "0.23.1" tokio = { version = "1.38.0", features = ["macros"] } diff --git a/rig-mongodb/src/lib.rs b/rig-mongodb/src/lib.rs index 56c0009d..cf308960 100644 --- a/rig-mongodb/src/lib.rs +++ b/rig-mongodb/src/lib.rs @@ -27,10 +27,9 @@ struct SearchIndex { impl SearchIndex { async fn get_search_index( collection: mongodb::Collection, - index_name: &str, ) -> Result { collection - .list_search_indexes(index_name, None, None) + .list_search_indexes() .await .map_err(mongodb_to_rig_error)? .with_type::() @@ -70,7 +69,7 @@ impl VectorStore for MongoDbVectorStore { ) -> Result<(), VectorStoreError> { self.collection .clone_with_type::() - .insert_many(documents, None) + .insert_many(documents) .await .map_err(mongodb_to_rig_error)?; Ok(()) @@ -82,7 +81,7 @@ impl VectorStore for MongoDbVectorStore { ) -> Result, VectorStoreError> { self.collection .clone_with_type::() - .find_one(doc! { "_id": id }, None) + .find_one(doc! { "_id": id }) .await .map_err(mongodb_to_rig_error) } @@ -100,7 +99,6 @@ impl VectorStore for MongoDbVectorStore { doc! {"$project": { "document": 1 }}, doc! {"$replaceRoot": { "newRoot": "$document" }}, ], - None, ) .await .map_err(mongodb_to_rig_error)? @@ -119,7 +117,7 @@ impl VectorStore for MongoDbVectorStore { ) -> Result, VectorStoreError> { self.collection .clone_with_type::() - .find_one(query, None) + .find_one(query) .await .map_err(mongodb_to_rig_error) } @@ -195,7 +193,7 @@ impl MongoDbVectorIndex { index_name: &str, search_params: SearchParams, ) -> Result { - let search_index = SearchIndex::get_search_index(collection.clone(), index_name).await?; + let search_index = SearchIndex::get_search_index(collection.clone()).await?; if !search_index.queryable { return Err(VectorStoreError::DatastoreError( @@ -296,7 +294,6 @@ impl VectorStoreIndex for MongoDbV } }, ], - None, ) .await .map_err(mongodb_to_rig_error)? @@ -342,7 +339,6 @@ impl VectorStoreIndex for MongoDbV }, }, ], - None, ) .await .map_err(mongodb_to_rig_error)? diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs new file mode 100644 index 00000000..456aa63b --- /dev/null +++ b/rig-mongodb/tests/integration_tests.rs @@ -0,0 +1,100 @@ +use mongodb::{bson::{self, doc}, options::ClientOptions, Collection, SearchIndexModel}; +use rig::{embeddings::{DocumentEmbeddings, EmbeddingsBuilder}, providers::openai, vector_store::VectorStoreIndex}; +use rig_mongodb::MongoDbVectorIndex; +use testcontainers::{core::{IntoContainerPort, WaitFor}, runners::AsyncRunner, GenericImage, ImageExt}; + +const VECTOR_SEARCH_INDEX_NAME: &str = "vector_index"; + +#[tokio::test] +async fn integration_test() { + // Initialize OpenAI client + let openai_client = openai::Client::from_env(); + + // Setup local MongoDB Atlas + let container = GenericImage::new("mongodb/mongodb-atlas-local", "latest") + .with_exposed_port(27017.tcp()) + .with_wait_for(WaitFor::Duration { length: std::time::Duration::from_secs(10) }) + .with_env_var("MONGODB_INITDB_ROOT_USERNAME", "riguser") + .with_env_var("MONGODB_INITDB_ROOT_PASSWORD", "rigpassword") + .start() + .await + .expect("Failed to start MongoDB Atlas container"); + + let port = container.get_host_port_ipv4(27017).await.unwrap(); + + // Initialize MongoDB client + let options = ClientOptions::parse(format!("mongodb://riguser:rigpassword@localhost:{port}/?directConnection=true")) + .await + .expect("MongoDB connection string should be valid"); + + let mongodb_client = + mongodb::Client::with_options(options).expect("MongoDB client options should be valid"); + + // Initialize MongoDB vector store + mongodb_client + .database("rig") + .create_collection("fake_definitions") + .await + .expect("Collection should be created"); + + // Initialize MongoDB vector store + let collection: Collection = mongodb_client + .database("rig") + .collection("fake_definitions"); + + // Create a vector search index + collection.create_search_index( + SearchIndexModel::builder() + .name(Some(VECTOR_SEARCH_INDEX_NAME.to_string())) + .index_type(Some(mongodb::SearchIndexType::VectorSearch)) + .definition(doc! { + "fields": [{ + "numDimensions": 1536, + "path": "embeddings.vec", + "similarity": "cosine", + "type": "vector" + }] + }) + .build() + ).await + .expect("Failed to create search index"); + + // Select the embedding model and generate our embeddings + let model = openai_client.embedding_model(openai::TEXT_EMBEDDING_ADA_002); + + let embeddings = EmbeddingsBuilder::new(model.clone()) + .simple_document("doc0", "Definition of a *flurbo*: A flurbo is a green alien that lives on cold planets") + .simple_document("doc1", "Definition of a *glarb-glarb*: A glarb-glarb is a ancient tool used by the ancestors of the inhabitants of planet Jiro to farm the land.") + .simple_document("doc2", "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.") + .build() + .await + .expect("Failed to build embeddings"); + + // Add embeddings to vector store + collection + .clone_with_type::() + .insert_many(embeddings) + .await + .expect("Failed to insert embeddings"); + + // Create a vector index on our vector store + let vector_index = MongoDbVectorIndex::new( + collection, + model, + VECTOR_SEARCH_INDEX_NAME, + rig_mongodb::SearchParams::new(), + ).await.expect("Failed to create Rig vector index"); + + // Query the index + let results = vector_index + .top_n::("What is a linglingdong?", 1) + .await + .expect("Failed to query vector index"); + + let result_string = &results.first().unwrap().1; + + assert_eq!( + result_string, + "\"doc2\"" + ); +} \ No newline at end of file From 5f8333d664a254a6d01a7814d9766f58758ab3f8 Mon Sep 17 00:00:00 2001 From: Garance Date: Tue, 26 Nov 2024 17:34:12 -0500 Subject: [PATCH 02/13] style: cargo fmt --- rig-mongodb/src/lib.rs | 56 +++++++++---------- rig-mongodb/tests/integration_tests.rs | 77 ++++++++++++++++---------- 2 files changed, 72 insertions(+), 61 deletions(-) diff --git a/rig-mongodb/src/lib.rs b/rig-mongodb/src/lib.rs index cf308960..df555621 100644 --- a/rig-mongodb/src/lib.rs +++ b/rig-mongodb/src/lib.rs @@ -93,13 +93,11 @@ impl VectorStore for MongoDbVectorStore { Ok(self .collection .clone_with_type::() - .aggregate( - [ - doc! {"$match": { "_id": id}}, - doc! {"$project": { "document": 1 }}, - doc! {"$replaceRoot": { "newRoot": "$document" }}, - ], - ) + .aggregate([ + doc! {"$match": { "_id": id}}, + doc! {"$project": { "document": 1 }}, + doc! {"$replaceRoot": { "newRoot": "$document" }}, + ]) .await .map_err(mongodb_to_rig_error)? .with_type::() @@ -282,19 +280,17 @@ impl VectorStoreIndex for MongoDbV let mut cursor = self .collection - .aggregate( - [ - self.pipeline_search_stage(&prompt_embedding, n), - self.pipeline_score_stage(), - { - doc! { - "$project": { - self.embedded_field.clone(): 0, - }, - } - }, - ], - ) + .aggregate([ + self.pipeline_search_stage(&prompt_embedding, n), + self.pipeline_score_stage(), + { + doc! { + "$project": { + self.embedded_field.clone(): 0, + }, + } + }, + ]) .await .map_err(mongodb_to_rig_error)? .with_type::(); @@ -328,18 +324,16 @@ impl VectorStoreIndex for MongoDbV let mut cursor = self .collection - .aggregate( - [ - self.pipeline_search_stage(&prompt_embedding, n), - self.pipeline_score_stage(), - doc! { - "$project": { - "_id": 1, - "score": 1 - }, + .aggregate([ + self.pipeline_search_stage(&prompt_embedding, n), + self.pipeline_score_stage(), + doc! { + "$project": { + "_id": 1, + "score": 1 }, - ], - ) + }, + ]) .await .map_err(mongodb_to_rig_error)? .with_type::(); diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index 456aa63b..078f8e65 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -1,7 +1,19 @@ -use mongodb::{bson::{self, doc}, options::ClientOptions, Collection, SearchIndexModel}; -use rig::{embeddings::{DocumentEmbeddings, EmbeddingsBuilder}, providers::openai, vector_store::VectorStoreIndex}; +use mongodb::{ + bson::{self, doc}, + options::ClientOptions, + Collection, SearchIndexModel, +}; +use rig::{ + embeddings::{DocumentEmbeddings, EmbeddingsBuilder}, + providers::openai, + vector_store::VectorStoreIndex, +}; use rig_mongodb::MongoDbVectorIndex; -use testcontainers::{core::{IntoContainerPort, WaitFor}, runners::AsyncRunner, GenericImage, ImageExt}; +use testcontainers::{ + core::{IntoContainerPort, WaitFor}, + runners::AsyncRunner, + GenericImage, ImageExt, +}; const VECTOR_SEARCH_INDEX_NAME: &str = "vector_index"; @@ -9,11 +21,13 @@ const VECTOR_SEARCH_INDEX_NAME: &str = "vector_index"; async fn integration_test() { // Initialize OpenAI client let openai_client = openai::Client::from_env(); - + // Setup local MongoDB Atlas - let container = GenericImage::new("mongodb/mongodb-atlas-local", "latest") + let container = GenericImage::new("mongodb/mongodb-atlas-local", "latest") .with_exposed_port(27017.tcp()) - .with_wait_for(WaitFor::Duration { length: std::time::Duration::from_secs(10) }) + .with_wait_for(WaitFor::Duration { + length: std::time::Duration::from_secs(10), + }) .with_env_var("MONGODB_INITDB_ROOT_USERNAME", "riguser") .with_env_var("MONGODB_INITDB_ROOT_PASSWORD", "rigpassword") .start() @@ -23,9 +37,11 @@ async fn integration_test() { let port = container.get_host_port_ipv4(27017).await.unwrap(); // Initialize MongoDB client - let options = ClientOptions::parse(format!("mongodb://riguser:rigpassword@localhost:{port}/?directConnection=true")) - .await - .expect("MongoDB connection string should be valid"); + let options = ClientOptions::parse(format!( + "mongodb://riguser:rigpassword@localhost:{port}/?directConnection=true" + )) + .await + .expect("MongoDB connection string should be valid"); let mongodb_client = mongodb::Client::with_options(options).expect("MongoDB client options should be valid"); @@ -43,21 +59,23 @@ async fn integration_test() { .collection("fake_definitions"); // Create a vector search index - collection.create_search_index( - SearchIndexModel::builder() - .name(Some(VECTOR_SEARCH_INDEX_NAME.to_string())) - .index_type(Some(mongodb::SearchIndexType::VectorSearch)) - .definition(doc! { - "fields": [{ - "numDimensions": 1536, - "path": "embeddings.vec", - "similarity": "cosine", - "type": "vector" - }] - }) - .build() - ).await - .expect("Failed to create search index"); + collection + .create_search_index( + SearchIndexModel::builder() + .name(Some(VECTOR_SEARCH_INDEX_NAME.to_string())) + .index_type(Some(mongodb::SearchIndexType::VectorSearch)) + .definition(doc! { + "fields": [{ + "numDimensions": 1536, + "path": "embeddings.vec", + "similarity": "cosine", + "type": "vector" + }] + }) + .build(), + ) + .await + .expect("Failed to create search index"); // Select the embedding model and generate our embeddings let model = openai_client.embedding_model(openai::TEXT_EMBEDDING_ADA_002); @@ -83,7 +101,9 @@ async fn integration_test() { model, VECTOR_SEARCH_INDEX_NAME, rig_mongodb::SearchParams::new(), - ).await.expect("Failed to create Rig vector index"); + ) + .await + .expect("Failed to create Rig vector index"); // Query the index let results = vector_index @@ -93,8 +113,5 @@ async fn integration_test() { let result_string = &results.first().unwrap().1; - assert_eq!( - result_string, - "\"doc2\"" - ); -} \ No newline at end of file + assert_eq!(result_string, "\"doc2\""); +} From d1e465c0957cb9ae11353944978f02ef92172384 Mon Sep 17 00:00:00 2001 From: Garance Date: Tue, 26 Nov 2024 17:56:39 -0500 Subject: [PATCH 03/13] fix: failing test --- rig-mongodb/tests/integration_tests.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index 078f8e65..89ed44f1 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -106,11 +106,18 @@ async fn integration_test() { .expect("Failed to create Rig vector index"); // Query the index - let results = vector_index + let mut results = vector_index .top_n::("What is a linglingdong?", 1) .await .expect("Failed to query vector index"); + if results.is_empty() { + results = vector_index + .top_n::("What is a linglingdong?", 1) + .await + .expect("Failed to query vector index"); + } + let result_string = &results.first().unwrap().1; assert_eq!(result_string, "\"doc2\""); From f104e920250f4c9034dde39ae33978d315f1834f Mon Sep 17 00:00:00 2001 From: Garance Buricatu Date: Mon, 2 Dec 2024 11:04:14 -0500 Subject: [PATCH 04/13] fix: make PR requested changes --- rig-mongodb/src/lib.rs | 4 +++- rig-mongodb/tests/integration_tests.rs | 30 +++++++++++++++++--------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/rig-mongodb/src/lib.rs b/rig-mongodb/src/lib.rs index df555621..d2378399 100644 --- a/rig-mongodb/src/lib.rs +++ b/rig-mongodb/src/lib.rs @@ -27,9 +27,11 @@ struct SearchIndex { impl SearchIndex { async fn get_search_index( collection: mongodb::Collection, + index_name: &str, ) -> Result { collection .list_search_indexes() + .name(index_name) .await .map_err(mongodb_to_rig_error)? .with_type::() @@ -191,7 +193,7 @@ impl MongoDbVectorIndex { index_name: &str, search_params: SearchParams, ) -> Result { - let search_index = SearchIndex::get_search_index(collection.clone()).await?; + let search_index = SearchIndex::get_search_index(collection.clone(), index_name).await?; if !search_index.queryable { return Err(VectorStoreError::DatastoreError( diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index 89ed44f1..05c7ce62 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -16,15 +16,15 @@ use testcontainers::{ }; const VECTOR_SEARCH_INDEX_NAME: &str = "vector_index"; +const MONGODB_PORT: u16 = 27017; -#[tokio::test] -async fn integration_test() { - // Initialize OpenAI client - let openai_client = openai::Client::from_env(); - +/// Setup a local MongoDB Atlas container for testing. +/// This includes running the container with `testcontainers`, and creating a database and collection +/// that will be used by integration tests. +async fn setup_mongo_server() -> Collection { // Setup local MongoDB Atlas let container = GenericImage::new("mongodb/mongodb-atlas-local", "latest") - .with_exposed_port(27017.tcp()) + .with_exposed_port(MONGODB_PORT.tcp()) .with_wait_for(WaitFor::Duration { length: std::time::Duration::from_secs(10), }) @@ -34,7 +34,7 @@ async fn integration_test() { .await .expect("Failed to start MongoDB Atlas container"); - let port = container.get_host_port_ipv4(27017).await.unwrap(); + let port = container.get_host_port_ipv4(MONGODB_PORT).await.unwrap(); // Initialize MongoDB client let options = ClientOptions::parse(format!( @@ -46,19 +46,19 @@ async fn integration_test() { let mongodb_client = mongodb::Client::with_options(options).expect("MongoDB client options should be valid"); - // Initialize MongoDB vector store + // Initialize MongoDB database and collection mongodb_client .database("rig") .create_collection("fake_definitions") .await .expect("Collection should be created"); - // Initialize MongoDB vector store + // Get the created collection let collection: Collection = mongodb_client .database("rig") .collection("fake_definitions"); - // Create a vector search index + // Create a vector search index on the collection collection .create_search_index( SearchIndexModel::builder() @@ -77,6 +77,16 @@ async fn integration_test() { .await .expect("Failed to create search index"); + collection +} + +#[tokio::test] +async fn vector_search_test() { + // Initialize OpenAI client + let openai_client = openai::Client::from_env(); + + let collection = setup_mongo_server().await; + // Select the embedding model and generate our embeddings let model = openai_client.embedding_model(openai::TEXT_EMBEDDING_ADA_002); From d9c86eecef9a3f3e37c8226531a167443849c049 Mon Sep 17 00:00:00 2001 From: Garance Buricatu Date: Mon, 2 Dec 2024 12:23:32 -0500 Subject: [PATCH 05/13] refactor(rig-mongodb): use embeddings overhaul in integration test --- Cargo.lock | 337 ++++++++---------- rig-mongodb/Cargo.toml | 6 +- ...tor_search_mongodb.rs => vector_search.rs} | 51 ++- rig-mongodb/src/lib.rs | 8 +- rig-mongodb/tests/integration_tests.rs | 93 +++-- 5 files changed, 233 insertions(+), 262 deletions(-) rename rig-mongodb/examples/{vector_search_mongodb.rs => vector_search.rs} (75%) diff --git a/Cargo.lock b/Cargo.lock index 144c0b12..d18dfdcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,9 +42,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-tzdata" @@ -224,7 +224,7 @@ dependencies = [ "arrow-schema", "chrono", "half", - "indexmap 2.6.0", + "indexmap 2.7.0", "lexical-core", "num", "serde", @@ -361,7 +361,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -383,7 +383,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -394,7 +394,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -908,14 +908,14 @@ dependencies = [ "home", "http 1.1.0", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-named-pipe", "hyper-rustls 0.27.3", "hyper-util", "hyperlocal", "log", "pin-project-lite", - "rustls 0.23.14", + "rustls 0.23.19", "rustls-native-certs 0.7.3", "rustls-pemfile 2.2.0", "rustls-pki-types", @@ -924,7 +924,7 @@ dependencies = [ "serde_json", "serde_repr", "serde_urlencoded", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-util", "tower-service", @@ -953,7 +953,7 @@ dependencies = [ "base64 0.13.1", "bitvec", "hex", - "indexmap 2.6.0", + "indexmap 2.7.0", "js-sys", "once_cell", "rand", @@ -1000,9 +1000,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" dependencies = [ "serde", ] @@ -1028,9 +1028,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -1050,9 +1050,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "jobserver", "libc", @@ -1326,13 +1326,8 @@ dependencies = [ "ident_case", "proc-macro2", "quote", -<<<<<<< HEAD "strsim", - "syn 2.0.79", -======= - "strsim 0.11.1", - "syn 2.0.89", ->>>>>>> main + "syn 2.0.90", ] [[package]] @@ -1343,7 +1338,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1396,7 +1391,7 @@ dependencies = [ "glob", "half", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.12.1", "log", "num_cpus", @@ -1556,7 +1551,7 @@ dependencies = [ "datafusion-expr", "datafusion-physical-expr", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.12.1", "log", "paste", @@ -1585,7 +1580,7 @@ dependencies = [ "half", "hashbrown 0.14.5", "hex", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.12.1", "log", "paste", @@ -1631,7 +1626,7 @@ dependencies = [ "futures", "half", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.12.1", "log", "once_cell", @@ -1747,7 +1742,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1757,7 +1752,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1769,13 +1764,8 @@ dependencies = [ "convert_case", "proc-macro2", "quote", -<<<<<<< HEAD "rustc_version", - "syn 2.0.79", -======= - "rustc_version 0.4.1", - "syn 2.0.89", ->>>>>>> main + "syn 2.0.90", ] [[package]] @@ -1824,7 +1814,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1880,7 +1870,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -1891,12 +1881,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2127,7 +2117,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2231,7 +2221,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -2250,7 +2240,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -2286,9 +2276,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", @@ -2336,7 +2326,7 @@ dependencies = [ "ipnet", "once_cell", "rand", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tokio", "tracing", @@ -2359,7 +2349,7 @@ dependencies = [ "rand", "resolv-conf", "smallvec", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -2490,7 +2480,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tower-service", "tracing", @@ -2525,7 +2515,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" dependencies = [ "hex", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-util", "pin-project-lite", "tokio", @@ -2559,7 +2549,7 @@ dependencies = [ "http 1.1.0", "hyper 1.5.1", "hyper-util", - "rustls 0.23.18", + "rustls 0.23.19", "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", @@ -2607,7 +2597,7 @@ dependencies = [ "http-body 1.0.1", "hyper 1.5.1", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tower-service", "tracing", @@ -2621,7 +2611,7 @@ checksum = "986c5ce3b994526b3cd75578e62554abd09f0899d6206de48b3e96ab34ccc8c7" dependencies = [ "hex", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-util", "pin-project-lite", "tokio", @@ -2775,7 +2765,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2844,12 +2834,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "serde", ] @@ -2888,7 +2878,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.7", + "socket2 0.5.8", "widestring", "windows-sys 0.48.0", "winreg", @@ -2920,9 +2910,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jobserver" @@ -2935,10 +2925,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -3445,9 +3436,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.164" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libm" @@ -3515,7 +3506,7 @@ dependencies = [ "chrono", "encoding_rs", "flate2", - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "log", "md-5", @@ -3532,7 +3523,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.1", + "hashbrown 0.15.2", ] [[package]] @@ -3632,11 +3623,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi", "libc", "wasi", "windows-sys 0.52.0", @@ -3711,7 +3701,7 @@ dependencies = [ "serde_with", "sha-1", "sha2", - "socket2 0.5.7", + "socket2 0.5.8", "stringprep", "strsim", "take_mut", @@ -3732,7 +3722,7 @@ checksum = "3a6dbc533e93429a71c44a14c04547ac783b56d3f22e6c4f12b1b994cf93844e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -3799,7 +3789,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53a0d57c55d2d1dc62a2b1d16a0a1079eb78d67c36bdf468d582ab4482ec7002" dependencies = [ "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3987,7 +3977,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4095,7 +4085,7 @@ dependencies = [ "regex", "regex-syntax", "structmeta", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -4147,7 +4137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.6.0", + "indexmap 2.7.0", ] [[package]] @@ -4205,7 +4195,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4291,7 +4281,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4340,7 +4330,7 @@ dependencies = [ "prost 0.12.6", "prost-types 0.12.6", "regex", - "syn 2.0.89", + "syn 2.0.90", "tempfile", ] @@ -4354,7 +4344,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4367,7 +4357,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4459,9 +4449,9 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.0.0", - "rustls 0.23.18", - "socket2 0.5.7", + "rustc-hash 2.1.0", + "rustls 0.23.19", + "socket2 0.5.8", "thiserror 2.0.3", "tokio", "tracing", @@ -4477,8 +4467,8 @@ dependencies = [ "getrandom", "rand", "ring", - "rustc-hash 2.0.0", - "rustls 0.23.18", + "rustc-hash 2.1.0", + "rustls 0.23.19", "rustls-pki-types", "slab", "thiserror 2.0.3", @@ -4496,7 +4486,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.7", + "socket2 0.5.8", "tracing", "windows-sys 0.59.0", ] @@ -4720,7 +4710,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.18", + "rustls 0.23.19", "rustls-native-certs 0.8.1", "rustls-pemfile 2.2.0", "rustls-pki-types", @@ -4786,7 +4776,7 @@ dependencies = [ "indoc", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4863,9 +4853,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4b84ba6e838ceb47b41de5194a60244fac43d9fe03b71dbe8c5a201081d6d1" +checksum = "f81dc953b2244ddd5e7860cb0bb2a790494b898ef321d4aff8e260efab60cc88" dependencies = [ "bytemuck", "byteorder", @@ -4895,9 +4885,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustc_version" @@ -4959,9 +4949,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.18" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "log", "once_cell", @@ -5117,7 +5107,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5207,7 +5197,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5218,7 +5208,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5227,7 +5217,7 @@ version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "memchr", "ryu", @@ -5242,7 +5232,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -5267,7 +5257,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_derive", "serde_json", @@ -5284,7 +5274,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5427,9 +5417,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -5459,7 +5449,7 @@ checksum = "01b2e185515564f15375f593fb966b5718bc624ba77fe49fa4616ad619690554" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5512,7 +5502,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -5523,7 +5513,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -5545,7 +5535,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5567,9 +5557,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.89" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -5599,7 +5589,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5832,7 +5822,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-tar", @@ -5877,7 +5867,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5888,7 +5878,7 @@ checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5979,7 +5969,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2 0.5.8", "tokio-macros", "windows-sys 0.52.0", ] @@ -5992,7 +5982,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6021,7 +6011,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.18", + "rustls 0.23.19", "rustls-pki-types", "tokio", ] @@ -6038,7 +6028,6 @@ dependencies = [ ] [[package]] -<<<<<<< HEAD name = "tokio-tar" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6051,7 +6040,9 @@ dependencies = [ "tokio", "tokio-stream", "xattr", -======= +] + +[[package]] name = "tokio-test" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6062,7 +6053,6 @@ dependencies = [ "futures-core", "tokio", "tokio-stream", ->>>>>>> main ] [[package]] @@ -6103,7 +6093,7 @@ dependencies = [ "prost 0.13.3", "rustls-native-certs 0.8.1", "rustls-pemfile 2.2.0", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tokio-rustls 0.26.0", "tokio-stream", @@ -6161,9 +6151,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -6172,20 +6162,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -6204,9 +6194,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -6223,54 +6213,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" [[package]] -<<<<<<< HEAD -======= -name = "trust-dns-proto" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.2.3", - "ipnet", - "lazy_static", - "log", - "rand", - "smallvec", - "thiserror 1.0.69", - "tinyvec", - "tokio", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ba72c2ea84515690c9fcef4c6c660bb9df3036ed1051686de84605b74fd558" -dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lazy_static", - "log", - "lru-cache", - "parking_lot", - "resolv-conf", - "smallvec", - "thiserror 1.0.69", - "tokio", - "trust-dns-proto", -] - -[[package]] ->>>>>>> main name = "try-lock" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6469,9 +6411,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if", "once_cell", @@ -6480,36 +6422,37 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6517,22 +6460,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "wasm-streams" @@ -6549,9 +6492,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" dependencies = [ "js-sys", "wasm-bindgen", @@ -6851,7 +6794,7 @@ checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", "linux-raw-sys 0.4.14", - "rustix 0.38.37", + "rustix 0.38.41", ] [[package]] @@ -6880,7 +6823,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -6902,7 +6845,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6922,7 +6865,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -6951,7 +6894,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] diff --git a/rig-mongodb/Cargo.toml b/rig-mongodb/Cargo.toml index 43f2d30a..704abefd 100644 --- a/rig-mongodb/Cargo.toml +++ b/rig-mongodb/Cargo.toml @@ -23,5 +23,9 @@ testcontainers = "0.23.1" tokio = { version = "1.38.0", features = ["macros"] } [[example]] -name = "vector_search_mongodb" +name = "vector_search" +required-features = ["rig-core/derive"] + +[[test]] +name = "integration_tests" required-features = ["rig-core/derive"] \ No newline at end of file diff --git a/rig-mongodb/examples/vector_search_mongodb.rs b/rig-mongodb/examples/vector_search.rs similarity index 75% rename from rig-mongodb/examples/vector_search_mongodb.rs rename to rig-mongodb/examples/vector_search.rs index 5d0ed81b..c80a73b4 100644 --- a/rig-mongodb/examples/vector_search_mongodb.rs +++ b/rig-mongodb/examples/vector_search.rs @@ -1,6 +1,10 @@ -use mongodb::{bson::doc, options::ClientOptions, Client as MongoClient, Collection}; +use mongodb::{ + bson::{self, doc}, + options::ClientOptions, + Client as MongoClient, Collection, +}; use rig::providers::openai::TEXT_EMBEDDING_ADA_002; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; use std::env; use rig::{ @@ -11,28 +15,13 @@ use rig_mongodb::{MongoDbVectorIndex, SearchParams}; // Shape of data that needs to be RAG'ed. // The definition field will be used to generate embeddings. #[derive(Embed, Clone, Deserialize, Debug)] -struct WordDefinition { +struct FakeDefinition { #[serde(rename = "_id")] id: String, #[embed] definition: String, } -#[derive(Clone, Deserialize, Debug, Serialize)] -struct Link { - word: String, - link: String, -} - -// Shape of the document to be stored in MongoDB, with embeddings. -#[derive(Serialize, Debug)] -struct Document { - #[serde(rename = "_id")] - id: String, - definition: String, - embedding: Vec, -} - #[tokio::main] async fn main() -> Result<(), anyhow::Error> { // Initialize OpenAI client @@ -50,7 +39,7 @@ async fn main() -> Result<(), anyhow::Error> { MongoClient::with_options(options).expect("MongoDB client options should be valid"); // Initialize MongoDB vector store - let collection: Collection = mongodb_client + let collection: Collection = mongodb_client .database("knowledgebase") .collection("context"); @@ -58,15 +47,15 @@ async fn main() -> Result<(), anyhow::Error> { let model = openai_client.embedding_model(TEXT_EMBEDDING_ADA_002); let fake_definitions = vec![ - WordDefinition { + FakeDefinition { id: "doc0".to_string(), definition: "Definition of a *flurbo*: A flurbo is a green alien that lives on cold planets".to_string(), }, - WordDefinition { + FakeDefinition { id: "doc1".to_string(), definition: "Definition of a *glarb-glarb*: A glarb-glarb is a ancient tool used by the ancestors of the inhabitants of planet Jiro to farm the land.".to_string(), }, - WordDefinition { + FakeDefinition { id: "doc2".to_string(), definition: "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), } @@ -79,16 +68,16 @@ async fn main() -> Result<(), anyhow::Error> { let mongo_documents = embeddings .iter() - .map( - |(WordDefinition { id, definition, .. }, embedding)| Document { - id: id.clone(), - definition: definition.clone(), - embedding: embedding.first().vec.clone(), - }, - ) + .map(|(FakeDefinition { id, definition, .. }, embedding)| { + doc! { + "id": id.clone(), + "definition": definition.clone(), + "embedding": embedding.first().vec.clone(), + } + }) .collect::>(); - match collection.insert_many(mongo_documents, None).await { + match collection.insert_many(mongo_documents).await { Ok(_) => println!("Documents added successfully"), Err(e) => println!("Error adding documents: {:?}", e), }; @@ -101,7 +90,7 @@ async fn main() -> Result<(), anyhow::Error> { // Query the index let results = index - .top_n::("What is a linglingdong?", 1) + .top_n::("What is a linglingdong?", 1) .await?; println!("Results: {:?}", results); diff --git a/rig-mongodb/src/lib.rs b/rig-mongodb/src/lib.rs index d415a393..8953e2b5 100644 --- a/rig-mongodb/src/lib.rs +++ b/rig-mongodb/src/lib.rs @@ -20,7 +20,7 @@ struct SearchIndex { } impl SearchIndex { - async fn get_search_index( + async fn get_search_index( collection: mongodb::Collection, index_name: &str, ) -> Result { @@ -80,7 +80,7 @@ fn mongodb_to_rig_error(e: mongodb::error::Error) -> VectorStoreError { /// SearchParams::new("embedding"), // <-- field name in `Document` that contains the embeddings. /// ); /// ``` -pub struct MongoDbVectorIndex { +pub struct MongoDbVectorIndex { collection: mongodb::Collection, model: M, index_name: String, @@ -88,7 +88,7 @@ pub struct MongoDbVectorIndex { search_params: SearchParams, } -impl MongoDbVectorIndex { +impl MongoDbVectorIndex { /// Vector search stage of aggregation pipeline of mongoDB collection. /// To be used by implementations of top_n and top_n_ids methods on VectorStoreIndex trait for MongoDbVectorIndex. fn pipeline_search_stage(&self, prompt_embedding: &Embedding, n: usize) -> bson::Document { @@ -122,7 +122,7 @@ impl MongoDbVectorIndex { } } -impl MongoDbVectorIndex { +impl MongoDbVectorIndex { /// Create a new `MongoDbVectorIndex`. /// /// The index (of type "vector") must already exist for the MongoDB collection. diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index 05c7ce62..0f411cc7 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -4,22 +4,30 @@ use mongodb::{ Collection, SearchIndexModel, }; use rig::{ - embeddings::{DocumentEmbeddings, EmbeddingsBuilder}, - providers::openai, - vector_store::VectorStoreIndex, + embeddings::EmbeddingsBuilder, providers::openai, vector_store::VectorStoreIndex, Embed, }; -use rig_mongodb::MongoDbVectorIndex; +use rig_mongodb::{MongoDbVectorIndex, SearchParams}; use testcontainers::{ core::{IntoContainerPort, WaitFor}, runners::AsyncRunner, GenericImage, ImageExt, }; +#[derive(Embed, Clone, serde::Deserialize, serde::Serialize, Debug, PartialEq)] +struct FakeDefinition { + #[serde(rename = "_id")] + id: String, + #[embed] + definition: String, +} + const VECTOR_SEARCH_INDEX_NAME: &str = "vector_index"; const MONGODB_PORT: u16 = 27017; +const COLLECTION_NAME: &str = "fake_definitions"; +const DATABASE_NAME: &str = "rig"; -/// Setup a local MongoDB Atlas container for testing. -/// This includes running the container with `testcontainers`, and creating a database and collection +/// Setup a local MongoDB Atlas container for testing. NOTE: docker service must be running. +/// This includes running the container with `testcontainers`, and creating a database and collection /// that will be used by integration tests. async fn setup_mongo_server() -> Collection { // Setup local MongoDB Atlas @@ -48,15 +56,15 @@ async fn setup_mongo_server() -> Collection { // Initialize MongoDB database and collection mongodb_client - .database("rig") - .create_collection("fake_definitions") + .database(DATABASE_NAME) + .create_collection(COLLECTION_NAME) .await .expect("Collection should be created"); // Get the created collection let collection: Collection = mongodb_client - .database("rig") - .collection("fake_definitions"); + .database(DATABASE_NAME) + .collection(COLLECTION_NAME); // Create a vector search index on the collection collection @@ -90,45 +98,72 @@ async fn vector_search_test() { // Select the embedding model and generate our embeddings let model = openai_client.embedding_model(openai::TEXT_EMBEDDING_ADA_002); + let linglingdong = FakeDefinition { + id: "doc2".to_string(), + definition: "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), + }; + + let fake_definitions = vec![ + FakeDefinition { + id: "doc0".to_string(), + definition: "Definition of a *flurbo*: A flurbo is a green alien that lives on cold planets".to_string(), + }, + FakeDefinition { + id: "doc1".to_string(), + definition: "Definition of a *glarb-glarb*: A glarb-glarb is a ancient tool used by the ancestors of the inhabitants of planet Jiro to farm the land.".to_string(), + }, + linglingdong.clone() + ]; + let embeddings = EmbeddingsBuilder::new(model.clone()) - .simple_document("doc0", "Definition of a *flurbo*: A flurbo is a green alien that lives on cold planets") - .simple_document("doc1", "Definition of a *glarb-glarb*: A glarb-glarb is a ancient tool used by the ancestors of the inhabitants of planet Jiro to farm the land.") - .simple_document("doc2", "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.") + .documents(fake_definitions) + .unwrap() .build() .await - .expect("Failed to build embeddings"); + .unwrap(); + + let mongo_documents = embeddings + .iter() + .map(|(FakeDefinition { id, definition, .. }, embedding)| { + doc! { + "id": id.clone(), + "definition": definition.clone(), + "embedding": embedding.first().vec.clone(), + } + }) + .collect::>(); - // Add embeddings to vector store - collection - .clone_with_type::() - .insert_many(embeddings) - .await - .expect("Failed to insert embeddings"); + collection.insert_many(mongo_documents).await.unwrap(); - // Create a vector index on our vector store - let vector_index = MongoDbVectorIndex::new( + // Create a vector index on our vector store. + // Note: a vector index called "vector_index" must exist on the MongoDB collection you are querying. + // IMPORTANT: Reuse the same model that was used to generate the embeddings + let index = MongoDbVectorIndex::new( collection, model, VECTOR_SEARCH_INDEX_NAME, - rig_mongodb::SearchParams::new(), + SearchParams::new(), ) .await - .expect("Failed to create Rig vector index"); + .unwrap(); // Query the index - let mut results = vector_index + let mut results = index .top_n::("What is a linglingdong?", 1) .await - .expect("Failed to query vector index"); + .unwrap(); if results.is_empty() { - results = vector_index + results = index .top_n::("What is a linglingdong?", 1) .await .expect("Failed to query vector index"); } - let result_string = &results.first().unwrap().1; + let result_string = &results.first().unwrap(); - assert_eq!(result_string, "\"doc2\""); + assert_eq!( + result_string.2, + serde_json::to_value(&linglingdong).unwrap() + ); } From f71fd5def865ccd099c72341bfb249546bf8564e Mon Sep 17 00:00:00 2001 From: Garance Buricatu Date: Mon, 2 Dec 2024 13:38:13 -0500 Subject: [PATCH 06/13] fix: error caused by container coming out of scope --- rig-mongodb/tests/integration_tests.rs | 58 ++++++++++++-------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index 0f411cc7..eb48d956 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -7,6 +7,7 @@ use rig::{ embeddings::EmbeddingsBuilder, providers::openai, vector_store::VectorStoreIndex, Embed, }; use rig_mongodb::{MongoDbVectorIndex, SearchParams}; +use serde_json::json; use testcontainers::{ core::{IntoContainerPort, WaitFor}, runners::AsyncRunner, @@ -26,15 +27,13 @@ const MONGODB_PORT: u16 = 27017; const COLLECTION_NAME: &str = "fake_definitions"; const DATABASE_NAME: &str = "rig"; -/// Setup a local MongoDB Atlas container for testing. NOTE: docker service must be running. -/// This includes running the container with `testcontainers`, and creating a database and collection -/// that will be used by integration tests. -async fn setup_mongo_server() -> Collection { - // Setup local MongoDB Atlas +#[tokio::test] +async fn vector_search_test() { + // Setup a local MongoDB Atlas container for testing. NOTE: docker service must be running. let container = GenericImage::new("mongodb/mongodb-atlas-local", "latest") .with_exposed_port(MONGODB_PORT.tcp()) .with_wait_for(WaitFor::Duration { - length: std::time::Duration::from_secs(10), + length: std::time::Duration::from_secs(5), }) .with_env_var("MONGODB_INITDB_ROOT_USERNAME", "riguser") .with_env_var("MONGODB_INITDB_ROOT_PASSWORD", "rigpassword") @@ -42,11 +41,19 @@ async fn setup_mongo_server() -> Collection { .await .expect("Failed to start MongoDB Atlas container"); + // Initialize OpenAI client + let openai_client = openai::Client::from_env(); + + // Select the embedding model and generate our embeddings + let model = openai_client.embedding_model(openai::TEXT_EMBEDDING_ADA_002); + let port = container.get_host_port_ipv4(MONGODB_PORT).await.unwrap(); + let host = container.get_host().await.unwrap().to_string(); + // Initialize MongoDB client let options = ClientOptions::parse(format!( - "mongodb://riguser:rigpassword@localhost:{port}/?directConnection=true" + "mongodb://riguser:rigpassword@{host}:{port}/?directConnection=true" )) .await .expect("MongoDB connection string should be valid"); @@ -75,7 +82,7 @@ async fn setup_mongo_server() -> Collection { .definition(doc! { "fields": [{ "numDimensions": 1536, - "path": "embeddings.vec", + "path": "embedding", "similarity": "cosine", "type": "vector" }] @@ -85,24 +92,6 @@ async fn setup_mongo_server() -> Collection { .await .expect("Failed to create search index"); - collection -} - -#[tokio::test] -async fn vector_search_test() { - // Initialize OpenAI client - let openai_client = openai::Client::from_env(); - - let collection = setup_mongo_server().await; - - // Select the embedding model and generate our embeddings - let model = openai_client.embedding_model(openai::TEXT_EMBEDDING_ADA_002); - - let linglingdong = FakeDefinition { - id: "doc2".to_string(), - definition: "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), - }; - let fake_definitions = vec![ FakeDefinition { id: "doc0".to_string(), @@ -112,7 +101,10 @@ async fn vector_search_test() { id: "doc1".to_string(), definition: "Definition of a *glarb-glarb*: A glarb-glarb is a ancient tool used by the ancestors of the inhabitants of planet Jiro to farm the land.".to_string(), }, - linglingdong.clone() + FakeDefinition { + id: "doc2".to_string(), + definition: "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), + } ]; let embeddings = EmbeddingsBuilder::new(model.clone()) @@ -126,7 +118,7 @@ async fn vector_search_test() { .iter() .map(|(FakeDefinition { id, definition, .. }, embedding)| { doc! { - "id": id.clone(), + "_id": id.clone(), "definition": definition.clone(), "embedding": embedding.first().vec.clone(), } @@ -160,10 +152,14 @@ async fn vector_search_test() { .expect("Failed to query vector index"); } - let result_string = &results.first().unwrap(); + let (score, _, value) = &results.first().unwrap(); assert_eq!( - result_string.2, - serde_json::to_value(&linglingdong).unwrap() + *value, + json!({ + "_id": "doc2".to_string(), + "definition": "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), + "score": score + }) ); } From a29e37e601abe399c1b9c4aac5130b0e8e9132f6 Mon Sep 17 00:00:00 2001 From: Garance Buricatu Date: Mon, 2 Dec 2024 13:57:29 -0500 Subject: [PATCH 07/13] fix: failing test --- rig-mongodb/tests/integration_tests.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index eb48d956..e5a52a8f 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -145,11 +145,14 @@ async fn vector_search_test() { .await .unwrap(); - if results.is_empty() { + let mut i = 1; + + while results.is_empty() && i < 5 { results = index .top_n::("What is a linglingdong?", 1) .await - .expect("Failed to query vector index"); + .unwrap(); + i += 1; } let (score, _, value) = &results.first().unwrap(); From a0db8735c53d431d793a39a458478137eafb1a3e Mon Sep 17 00:00:00 2001 From: Garance Buricatu Date: Mon, 2 Dec 2024 14:00:56 -0500 Subject: [PATCH 08/13] fix: rename mongodb example for uniqueness --- rig-mongodb/Cargo.toml | 2 +- .../examples/{vector_search.rs => vector_search_mongodb.rs} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename rig-mongodb/examples/{vector_search.rs => vector_search_mongodb.rs} (100%) diff --git a/rig-mongodb/Cargo.toml b/rig-mongodb/Cargo.toml index 704abefd..8153a449 100644 --- a/rig-mongodb/Cargo.toml +++ b/rig-mongodb/Cargo.toml @@ -23,7 +23,7 @@ testcontainers = "0.23.1" tokio = { version = "1.38.0", features = ["macros"] } [[example]] -name = "vector_search" +name = "vector_search_mongodb" required-features = ["rig-core/derive"] [[test]] diff --git a/rig-mongodb/examples/vector_search.rs b/rig-mongodb/examples/vector_search_mongodb.rs similarity index 100% rename from rig-mongodb/examples/vector_search.rs rename to rig-mongodb/examples/vector_search_mongodb.rs From 5757187e58f5a43876c22e092c4d45fa38446b22 Mon Sep 17 00:00:00 2001 From: Garance Buricatu Date: Mon, 2 Dec 2024 15:20:48 -0500 Subject: [PATCH 09/13] refactor: cleanup integration test --- rig-mongodb/tests/integration_tests.rs | 116 ++++++++++++++----------- 1 file changed, 63 insertions(+), 53 deletions(-) diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index e5a52a8f..22a927ca 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -26,34 +26,35 @@ const VECTOR_SEARCH_INDEX_NAME: &str = "vector_index"; const MONGODB_PORT: u16 = 27017; const COLLECTION_NAME: &str = "fake_definitions"; const DATABASE_NAME: &str = "rig"; +const USERNAME: &str = "riguser"; +const PASSWORD: &str = "rigpassword"; #[tokio::test] async fn vector_search_test() { + // Initialize OpenAI client + let openai_client = openai::Client::from_env(); + + // Select the embedding model and generate our embeddings + let model = openai_client.embedding_model(openai::TEXT_EMBEDDING_ADA_002); + // Setup a local MongoDB Atlas container for testing. NOTE: docker service must be running. let container = GenericImage::new("mongodb/mongodb-atlas-local", "latest") .with_exposed_port(MONGODB_PORT.tcp()) .with_wait_for(WaitFor::Duration { length: std::time::Duration::from_secs(5), }) - .with_env_var("MONGODB_INITDB_ROOT_USERNAME", "riguser") - .with_env_var("MONGODB_INITDB_ROOT_PASSWORD", "rigpassword") + .with_env_var("MONGODB_INITDB_ROOT_USERNAME", USERNAME) + .with_env_var("MONGODB_INITDB_ROOT_PASSWORD", PASSWORD) .start() .await .expect("Failed to start MongoDB Atlas container"); - // Initialize OpenAI client - let openai_client = openai::Client::from_env(); - - // Select the embedding model and generate our embeddings - let model = openai_client.embedding_model(openai::TEXT_EMBEDDING_ADA_002); - let port = container.get_host_port_ipv4(MONGODB_PORT).await.unwrap(); - let host = container.get_host().await.unwrap().to_string(); // Initialize MongoDB client let options = ClientOptions::parse(format!( - "mongodb://riguser:rigpassword@{host}:{port}/?directConnection=true" + "mongodb://{USERNAME}:{PASSWORD}@{host}:{port}/?directConnection=true" )) .await .expect("MongoDB connection string should be valid"); @@ -61,6 +62,52 @@ async fn vector_search_test() { let mongodb_client = mongodb::Client::with_options(options).expect("MongoDB client options should be valid"); + let collection = setup_database(mongodb_client).await; + + let embeddings = create_embeddings(model.clone()).await; + + collection.insert_many(embeddings).await.unwrap(); + + // Create a vector index on our vector store. + // Note: a vector index called "vector_index" must exist on the MongoDB collection you are querying. + // IMPORTANT: Reuse the same model that was used to generate the embeddings + let index = MongoDbVectorIndex::new( + collection, + model, + VECTOR_SEARCH_INDEX_NAME, + SearchParams::new(), + ) + .await + .unwrap(); + + // Query the index + let mut results = index + .top_n::("What is a linglingdong?", 1) + .await + .unwrap(); + + let mut i = 1; + while results.is_empty() && i <= 3 { + results = index + .top_n::("What is a linglingdong?", 1) + .await + .unwrap(); + i += 1; + } + + let (score, _, value) = &results.first().unwrap(); + + assert_eq!( + *value, + json!({ + "_id": "doc2".to_string(), + "definition": "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), + "score": score + }) + ); +} + +async fn setup_database(mongodb_client: mongodb::Client) -> Collection { // Initialize MongoDB database and collection mongodb_client .database(DATABASE_NAME) @@ -92,6 +139,10 @@ async fn vector_search_test() { .await .expect("Failed to create search index"); + collection +} + +async fn create_embeddings(model: openai::EmbeddingModel) -> Vec { let fake_definitions = vec![ FakeDefinition { id: "doc0".to_string(), @@ -114,7 +165,7 @@ async fn vector_search_test() { .await .unwrap(); - let mongo_documents = embeddings + embeddings .iter() .map(|(FakeDefinition { id, definition, .. }, embedding)| { doc! { @@ -123,46 +174,5 @@ async fn vector_search_test() { "embedding": embedding.first().vec.clone(), } }) - .collect::>(); - - collection.insert_many(mongo_documents).await.unwrap(); - - // Create a vector index on our vector store. - // Note: a vector index called "vector_index" must exist on the MongoDB collection you are querying. - // IMPORTANT: Reuse the same model that was used to generate the embeddings - let index = MongoDbVectorIndex::new( - collection, - model, - VECTOR_SEARCH_INDEX_NAME, - SearchParams::new(), - ) - .await - .unwrap(); - - // Query the index - let mut results = index - .top_n::("What is a linglingdong?", 1) - .await - .unwrap(); - - let mut i = 1; - - while results.is_empty() && i < 5 { - results = index - .top_n::("What is a linglingdong?", 1) - .await - .unwrap(); - i += 1; - } - - let (score, _, value) = &results.first().unwrap(); - - assert_eq!( - *value, - json!({ - "_id": "doc2".to_string(), - "definition": "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), - "score": score - }) - ); + .collect() } From a29bb2c03b53ee9e14c48fe660ebec6e75aad459 Mon Sep 17 00:00:00 2001 From: Garance Buricatu Date: Mon, 2 Dec 2024 15:36:12 -0500 Subject: [PATCH 10/13] fix: remove unnecessary clone --- rig-mongodb/tests/integration_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index 22a927ca..6ceabcf4 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -158,7 +158,7 @@ async fn create_embeddings(model: openai::EmbeddingModel) -> Vec } ]; - let embeddings = EmbeddingsBuilder::new(model.clone()) + let embeddings = EmbeddingsBuilder::new(model) .documents(fake_definitions) .unwrap() .build() From 9effe2102206661e3a60aa656ef6b0db6104d130 Mon Sep 17 00:00:00 2001 From: Garance Date: Tue, 3 Dec 2024 11:55:06 -0500 Subject: [PATCH 11/13] refactor: rename FakeDefinition to Definition --- rig-mongodb/examples/vector_search_mongodb.rs | 12 ++--- rig-mongodb/tests/integration_tests.rs | 47 ++++++++----------- 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/rig-mongodb/examples/vector_search_mongodb.rs b/rig-mongodb/examples/vector_search_mongodb.rs index c80a73b4..911d160e 100644 --- a/rig-mongodb/examples/vector_search_mongodb.rs +++ b/rig-mongodb/examples/vector_search_mongodb.rs @@ -15,7 +15,7 @@ use rig_mongodb::{MongoDbVectorIndex, SearchParams}; // Shape of data that needs to be RAG'ed. // The definition field will be used to generate embeddings. #[derive(Embed, Clone, Deserialize, Debug)] -struct FakeDefinition { +struct Definition { #[serde(rename = "_id")] id: String, #[embed] @@ -47,15 +47,15 @@ async fn main() -> Result<(), anyhow::Error> { let model = openai_client.embedding_model(TEXT_EMBEDDING_ADA_002); let fake_definitions = vec![ - FakeDefinition { + Definition { id: "doc0".to_string(), definition: "Definition of a *flurbo*: A flurbo is a green alien that lives on cold planets".to_string(), }, - FakeDefinition { + Definition { id: "doc1".to_string(), definition: "Definition of a *glarb-glarb*: A glarb-glarb is a ancient tool used by the ancestors of the inhabitants of planet Jiro to farm the land.".to_string(), }, - FakeDefinition { + Definition { id: "doc2".to_string(), definition: "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), } @@ -68,7 +68,7 @@ async fn main() -> Result<(), anyhow::Error> { let mongo_documents = embeddings .iter() - .map(|(FakeDefinition { id, definition, .. }, embedding)| { + .map(|(Definition { id, definition, .. }, embedding)| { doc! { "id": id.clone(), "definition": definition.clone(), @@ -90,7 +90,7 @@ async fn main() -> Result<(), anyhow::Error> { // Query the index let results = index - .top_n::("What is a linglingdong?", 1) + .top_n::("What is a linglingdong?", 1) .await?; println!("Results: {:?}", results); diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index 6ceabcf4..12cd28f2 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -15,7 +15,7 @@ use testcontainers::{ }; #[derive(Embed, Clone, serde::Deserialize, serde::Serialize, Debug, PartialEq)] -struct FakeDefinition { +struct Definition { #[serde(rename = "_id")] id: String, #[embed] @@ -52,17 +52,7 @@ async fn vector_search_test() { let port = container.get_host_port_ipv4(MONGODB_PORT).await.unwrap(); let host = container.get_host().await.unwrap().to_string(); - // Initialize MongoDB client - let options = ClientOptions::parse(format!( - "mongodb://{USERNAME}:{PASSWORD}@{host}:{port}/?directConnection=true" - )) - .await - .expect("MongoDB connection string should be valid"); - - let mongodb_client = - mongodb::Client::with_options(options).expect("MongoDB client options should be valid"); - - let collection = setup_database(mongodb_client).await; + let collection = bootstrap_collection(host, port).await; let embeddings = create_embeddings(model.clone()).await; @@ -81,20 +71,11 @@ async fn vector_search_test() { .unwrap(); // Query the index - let mut results = index + let results = index .top_n::("What is a linglingdong?", 1) .await .unwrap(); - let mut i = 1; - while results.is_empty() && i <= 3 { - results = index - .top_n::("What is a linglingdong?", 1) - .await - .unwrap(); - i += 1; - } - let (score, _, value) = &results.first().unwrap(); assert_eq!( @@ -104,10 +85,20 @@ async fn vector_search_test() { "definition": "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), "score": score }) - ); + ) } -async fn setup_database(mongodb_client: mongodb::Client) -> Collection { +async fn bootstrap_collection(host: String, port: u16) -> Collection { + // Initialize MongoDB client + let options = ClientOptions::parse(format!( + "mongodb://{USERNAME}:{PASSWORD}@{host}:{port}/?directConnection=true" + )) + .await + .expect("MongoDB connection string should be valid"); + + let mongodb_client = + mongodb::Client::with_options(options).expect("MongoDB client options should be valid"); + // Initialize MongoDB database and collection mongodb_client .database(DATABASE_NAME) @@ -144,15 +135,15 @@ async fn setup_database(mongodb_client: mongodb::Client) -> Collection Vec { let fake_definitions = vec![ - FakeDefinition { + Definition { id: "doc0".to_string(), definition: "Definition of a *flurbo*: A flurbo is a green alien that lives on cold planets".to_string(), }, - FakeDefinition { + Definition { id: "doc1".to_string(), definition: "Definition of a *glarb-glarb*: A glarb-glarb is a ancient tool used by the ancestors of the inhabitants of planet Jiro to farm the land.".to_string(), }, - FakeDefinition { + Definition { id: "doc2".to_string(), definition: "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), } @@ -167,7 +158,7 @@ async fn create_embeddings(model: openai::EmbeddingModel) -> Vec embeddings .iter() - .map(|(FakeDefinition { id, definition, .. }, embedding)| { + .map(|(Definition { id, definition, .. }, embedding)| { doc! { "_id": id.clone(), "definition": definition.clone(), From 7e56301678fa89adce5a010fb5bd50911b5be221 Mon Sep 17 00:00:00 2001 From: Garance Date: Tue, 3 Dec 2024 12:06:02 -0500 Subject: [PATCH 12/13] fix: add sleep --- rig-mongodb/tests/integration_tests.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index 12cd28f2..8692a7c9 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -13,6 +13,7 @@ use testcontainers::{ runners::AsyncRunner, GenericImage, ImageExt, }; +use tokio::time::{sleep, Duration}; #[derive(Embed, Clone, serde::Deserialize, serde::Serialize, Debug, PartialEq)] struct Definition { @@ -70,6 +71,8 @@ async fn vector_search_test() { .await .unwrap(); + sleep(Duration::from_secs(5)).await; + // Query the index let results = index .top_n::("What is a linglingdong?", 1) From 24c92c965b05c08241a454373be6d3168faeb949 Mon Sep 17 00:00:00 2001 From: Garance Date: Tue, 3 Dec 2024 12:33:17 -0500 Subject: [PATCH 13/13] fix: rename struct to Word --- rig-mongodb/examples/vector_search_mongodb.rs | 18 ++++++++---------- rig-mongodb/tests/integration_tests.rs | 16 ++++++++-------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/rig-mongodb/examples/vector_search_mongodb.rs b/rig-mongodb/examples/vector_search_mongodb.rs index 911d160e..ca36a2e0 100644 --- a/rig-mongodb/examples/vector_search_mongodb.rs +++ b/rig-mongodb/examples/vector_search_mongodb.rs @@ -15,7 +15,7 @@ use rig_mongodb::{MongoDbVectorIndex, SearchParams}; // Shape of data that needs to be RAG'ed. // The definition field will be used to generate embeddings. #[derive(Embed, Clone, Deserialize, Debug)] -struct Definition { +struct Word { #[serde(rename = "_id")] id: String, #[embed] @@ -46,29 +46,29 @@ async fn main() -> Result<(), anyhow::Error> { // Select the embedding model and generate our embeddings let model = openai_client.embedding_model(TEXT_EMBEDDING_ADA_002); - let fake_definitions = vec![ - Definition { + let words = vec![ + Word { id: "doc0".to_string(), definition: "Definition of a *flurbo*: A flurbo is a green alien that lives on cold planets".to_string(), }, - Definition { + Word { id: "doc1".to_string(), definition: "Definition of a *glarb-glarb*: A glarb-glarb is a ancient tool used by the ancestors of the inhabitants of planet Jiro to farm the land.".to_string(), }, - Definition { + Word { id: "doc2".to_string(), definition: "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), } ]; let embeddings = EmbeddingsBuilder::new(model.clone()) - .documents(fake_definitions)? + .documents(words)? .build() .await?; let mongo_documents = embeddings .iter() - .map(|(Definition { id, definition, .. }, embedding)| { + .map(|(Word { id, definition, .. }, embedding)| { doc! { "id": id.clone(), "definition": definition.clone(), @@ -89,9 +89,7 @@ async fn main() -> Result<(), anyhow::Error> { MongoDbVectorIndex::new(collection, model, "vector_index", SearchParams::new()).await?; // Query the index - let results = index - .top_n::("What is a linglingdong?", 1) - .await?; + let results = index.top_n::("What is a linglingdong?", 1).await?; println!("Results: {:?}", results); diff --git a/rig-mongodb/tests/integration_tests.rs b/rig-mongodb/tests/integration_tests.rs index 8692a7c9..6968ec1a 100644 --- a/rig-mongodb/tests/integration_tests.rs +++ b/rig-mongodb/tests/integration_tests.rs @@ -16,7 +16,7 @@ use testcontainers::{ use tokio::time::{sleep, Duration}; #[derive(Embed, Clone, serde::Deserialize, serde::Serialize, Debug, PartialEq)] -struct Definition { +struct Word { #[serde(rename = "_id")] id: String, #[embed] @@ -25,7 +25,7 @@ struct Definition { const VECTOR_SEARCH_INDEX_NAME: &str = "vector_index"; const MONGODB_PORT: u16 = 27017; -const COLLECTION_NAME: &str = "fake_definitions"; +const COLLECTION_NAME: &str = "words"; const DATABASE_NAME: &str = "rig"; const USERNAME: &str = "riguser"; const PASSWORD: &str = "rigpassword"; @@ -137,23 +137,23 @@ async fn bootstrap_collection(host: String, port: u16) -> Collection Vec { - let fake_definitions = vec![ - Definition { + let words = vec![ + Word { id: "doc0".to_string(), definition: "Definition of a *flurbo*: A flurbo is a green alien that lives on cold planets".to_string(), }, - Definition { + Word { id: "doc1".to_string(), definition: "Definition of a *glarb-glarb*: A glarb-glarb is a ancient tool used by the ancestors of the inhabitants of planet Jiro to farm the land.".to_string(), }, - Definition { + Word { id: "doc2".to_string(), definition: "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(), } ]; let embeddings = EmbeddingsBuilder::new(model) - .documents(fake_definitions) + .documents(words) .unwrap() .build() .await @@ -161,7 +161,7 @@ async fn create_embeddings(model: openai::EmbeddingModel) -> Vec embeddings .iter() - .map(|(Definition { id, definition, .. }, embedding)| { + .map(|(Word { id, definition, .. }, embedding)| { doc! { "_id": id.clone(), "definition": definition.clone(),