From 8565135320c1c54892a3ceac3b2839cff92c2307 Mon Sep 17 00:00:00 2001 From: dadaa Date: Fri, 16 May 2025 02:52:01 +0000 Subject: [PATCH] Bug 1966784: Vendor application-services fa8a72a r=adw Differential Revision: https://phabricator.services.mozilla.com/D249694 --- .cargo/config.toml.in | 4 +- Cargo.lock | 32 +-- Cargo.toml | 18 +- .../QuickSuggestTestUtils.sys.mjs | 3 + docs/rust-components/api/js/suggest.md | 4 + .../rust/remote_settings/.cargo-checksum.json | 2 +- .../rust/remote_settings/src/client.rs | 218 +++++++++++------- .../rust/remote_settings/src/config.rs | 4 + .../rust/remote_settings/src/service.rs | 96 +++++++- third_party/rust/search/.cargo-checksum.json | 2 +- third_party/rust/search/src/selector.rs | 49 +++- third_party/rust/search/src/sort_helpers.rs | 61 ++--- third_party/rust/suggest/.cargo-checksum.json | 2 +- third_party/rust/suggest/src/rs.rs | 2 + third_party/rust/suggest/src/schema.rs | 17 +- third_party/rust/suggest/src/store.rs | 20 ++ third_party/rust/suggest/src/suggestion.rs | 11 + third_party/rust/suggest/src/testing/data.rs | 4 +- third_party/rust/suggest/src/testing/mod.rs | 36 ++- third_party/rust/suggest/src/yelp.rs | 214 +++++++++++++---- .../components/generated/RustSuggest.sys.mjs | 62 +++++ 21 files changed, 652 insertions(+), 209 deletions(-) diff --git a/.cargo/config.toml.in b/.cargo/config.toml.in index 718e4df9cba2..1bb763ed5292 100644 --- a/.cargo/config.toml.in +++ b/.cargo/config.toml.in @@ -70,9 +70,9 @@ git = "https://github.com/jfkthame/mapped_hyph.git" rev = "eff105f6ad7ec9b79816cfc1985a28e5340ad14b" replace-with = "vendored-sources" -[source."git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197"] +[source."git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285"] git = "https://github.com/mozilla/application-services" -rev = "40ae79e2825fa242a349e17fcfc84fb99fd92197" +rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" replace-with = "vendored-sources" [source."git+https://github.com/mozilla/audioipc?rev=e6f44a2bd1e57d11dfc737632a9e849077632330"] diff --git a/Cargo.lock b/Cargo.lock index 3029f451671a..bc0a46115880 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1894,7 +1894,7 @@ dependencies = [ [[package]] name = "error-support" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "error-support-macros", "lazy_static", @@ -1906,7 +1906,7 @@ dependencies = [ [[package]] name = "error-support-macros" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "proc-macro2", "quote", @@ -2025,7 +2025,7 @@ dependencies = [ [[package]] name = "firefox-versioning" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "serde_json", "thiserror 1.999.999", @@ -3365,7 +3365,7 @@ dependencies = [ [[package]] name = "interrupt-support" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "lazy_static", "parking_lot", @@ -5086,7 +5086,7 @@ checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" [[package]] name = "payload-support" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "serde", "serde_derive", @@ -5589,7 +5589,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "relevancy" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "anyhow", "base64 0.21.999", @@ -5614,7 +5614,7 @@ dependencies = [ [[package]] name = "remote_settings" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "anyhow", "camino", @@ -5916,7 +5916,7 @@ dependencies = [ [[package]] name = "search" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "error-support", "firefox-versioning", @@ -6208,7 +6208,7 @@ dependencies = [ [[package]] name = "sql-support" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "interrupt-support", "lazy_static", @@ -6414,7 +6414,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "suggest" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "anyhow", "chrono", @@ -6466,7 +6466,7 @@ dependencies = [ [[package]] name = "sync-guid" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "base64 0.21.999", "rand", @@ -6477,7 +6477,7 @@ dependencies = [ [[package]] name = "sync15" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "anyhow", "error-support", @@ -6517,7 +6517,7 @@ dependencies = [ [[package]] name = "tabs" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "anyhow", "error-support", @@ -6861,7 +6861,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "types" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "rusqlite 0.33.0", "serde", @@ -7264,7 +7264,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "viaduct" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "ffi-support", "log", @@ -7434,7 +7434,7 @@ dependencies = [ [[package]] name = "webext-storage" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=40ae79e2825fa242a349e17fcfc84fb99fd92197#40ae79e2825fa242a349e17fcfc84fb99fd92197" +source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" dependencies = [ "anyhow", "error-support", diff --git a/Cargo.toml b/Cargo.toml index 569a8862c364..39dc0af03f4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -262,14 +262,14 @@ wr_malloc_size_of = { path = "gfx/wr/wr_malloc_size_of" } objc = { git = "https://github.com/glandium/rust-objc", rev = "4de89f5aa9851ceca4d40e7ac1e2759410c04324" } # application-services overrides to make updating them all simpler. -interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "40ae79e2825fa242a349e17fcfc84fb99fd92197" } -relevancy = { git = "https://github.com/mozilla/application-services", rev = "40ae79e2825fa242a349e17fcfc84fb99fd92197" } -search = { git = "https://github.com/mozilla/application-services", rev = "40ae79e2825fa242a349e17fcfc84fb99fd92197" } -sql-support = { git = "https://github.com/mozilla/application-services", rev = "40ae79e2825fa242a349e17fcfc84fb99fd92197" } -suggest = { git = "https://github.com/mozilla/application-services", rev = "40ae79e2825fa242a349e17fcfc84fb99fd92197" } -sync15 = { git = "https://github.com/mozilla/application-services", rev = "40ae79e2825fa242a349e17fcfc84fb99fd92197" } -tabs = { git = "https://github.com/mozilla/application-services", rev = "40ae79e2825fa242a349e17fcfc84fb99fd92197" } -viaduct = { git = "https://github.com/mozilla/application-services", rev = "40ae79e2825fa242a349e17fcfc84fb99fd92197" } -webext-storage = { git = "https://github.com/mozilla/application-services", rev = "40ae79e2825fa242a349e17fcfc84fb99fd92197" } +interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } +relevancy = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } +search = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } +sql-support = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } +suggest = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } +sync15 = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } +tabs = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } +viaduct = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } +webext-storage = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } allocator-api2 = { path = "third_party/rust/allocator-api2" } diff --git a/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs b/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs index 104c2556459c..484b9474c997 100644 --- a/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs +++ b/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs @@ -18,6 +18,7 @@ ChromeUtils.defineESModuleGetters(lazy, { TestUtils: "resource://testing-common/TestUtils.sys.mjs", UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs", UrlbarUtils: "resource:///modules/UrlbarUtils.sys.mjs", + YelpSubjectType: "resource://gre/modules/RustSuggest.sys.mjs", setTimeout: "resource://gre/modules/Timer.sys.mjs", }); @@ -960,6 +961,7 @@ class _QuickSuggestTestUtils { isSuggestedIndexRelativeToGroup = true, originalUrl = undefined, displayUrl = undefined, + suggestedType = lazy.YelpSubjectType.SERVICE, }) { const utmParameters = "&utm_medium=partner&utm_source=mozilla"; @@ -1012,6 +1014,7 @@ class _QuickSuggestTestUtils { 0.2, // score false, // hasLocationSign false, // subjectExactMatch + suggestedType, // subjectType "find_loc" // locationParam ); } diff --git a/docs/rust-components/api/js/suggest.md b/docs/rust-components/api/js/suggest.md index 14d36164d8d4..470c195e80c7 100644 --- a/docs/rust-components/api/js/suggest.md +++ b/docs/rust-components/api/js/suggest.md @@ -68,6 +68,10 @@ :members: :exclude-members: SuggestionProvider ``` +```{js:autoclass} RustSuggest.sys.YelpSubjectType + :members: + :exclude-members: YelpSubjectType +``` ```{js:autoclass} RustSuggest.sys.Network :members: :exclude-members: Network diff --git a/third_party/rust/remote_settings/.cargo-checksum.json b/third_party/rust/remote_settings/.cargo-checksum.json index f6ac63d5bce3..e38f22f858f2 100644 --- a/third_party/rust/remote_settings/.cargo-checksum.json +++ b/third_party/rust/remote_settings/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"00d8e28963e324f906faf95b3891030103f4486b8491e8d8228b0778d3fa143f","dumps/main/attachments/regions/world":"00b308033d44f61612b962f572765d14a3999586d92fc8b9fff2217a1ae070e8","dumps/main/attachments/regions/world-buffered":"1d3ed6954fac2a5b31302f5d3e8186c5fa08a20239afc0643ca5dfbb4d8a86fc","dumps/main/attachments/regions/world-buffered.meta.json":"914a71376a152036aceccb6877e079fbb9e3373c6219f24f00dd30e901a72cce","dumps/main/attachments/regions/world.meta.json":"2a47d77834997b98e563265d299723e7f7fd64c8c7a5731afc722862333d6fbd","dumps/main/attachments/search-config-icons/001500a9-1a6c-3f5a-ba15-a5f5a075d256":"fdadf15c6eae7933c3d254ae6311112e0bc8a422c38c758189dbe6a4d7f6b718","dumps/main/attachments/search-config-icons/001500a9-1a6c-3f5a-ba15-a5f5a075d256.meta.json":"6ed1e1c390a45360590e5a1e6d7823218e7b10860581646ddb5e368143aa72fc","dumps/main/attachments/search-config-icons/06cf7432-efd7-f244-927b-5e423005e1ea":"b75ef04a805325e303c4195833cdd077d3d406f360b25b72502fc55880b9150b","dumps/main/attachments/search-config-icons/06cf7432-efd7-f244-927b-5e423005e1ea.meta.json":"0d4cce0ed0dc6b2c46651bea32fc3cc2facfe8b341e1022b65f2cd2231f6b713","dumps/main/attachments/search-config-icons/0a57b0cf-34f0-4d09-96e4-dbd6e3355410":"a7493c6a9d70d60acccf73f62dcbc127a580469570aee60b7482cd42cdb59f69","dumps/main/attachments/search-config-icons/0a57b0cf-34f0-4d09-96e4-dbd6e3355410.meta.json":"d33a128c92b96af2e643158ed3b861d3726bd67a59907fed0795ab2210c82b96","dumps/main/attachments/search-config-icons/0d7668a8-c3f4-cfee-cbc8-536511528937":"7042293af6b04e421cb7b68dc599ac644b76939cdcf5970159e44f658dd6a0cc","dumps/main/attachments/search-config-icons/0d7668a8-c3f4-cfee-cbc8-536511528937.meta.json":"d6523508334a67b201326591606d7e225a04fc53fdce2c1b4d8afac1b41af6b0","dumps/main/attachments/search-config-icons/0eec5640-6fde-d6fe-322a-c72c6d5bd5a2":"64800e32b24b2c8c0582750e1657426d56abd74b65682e20e892f82710d120b6","dumps/main/attachments/search-config-icons/0eec5640-6fde-d6fe-322a-c72c6d5bd5a2.meta.json":"56fb61a078cc45abf7bc3b8fe89b60ef75f3b86ea61d63084749607c4662bbef","dumps/main/attachments/search-config-icons/101ce01d-2691-b729-7f16-9d389803384b":"62d2faa3a8322b1f643aab6e045837500ebe3049c5cb140cb44c4dfc7290337a","dumps/main/attachments/search-config-icons/101ce01d-2691-b729-7f16-9d389803384b.meta.json":"de134ed423a2bd92b4ad8cdf631aad6a83cc2c30f8df9ee251a435ee9f46f28f","dumps/main/attachments/search-config-icons/177aba42-9bed-4078-e36b-580e8794cd7f":"3b88f3ef3cbfaed127d679ec7e44a44fe8dcad688feb89a70a1a9447c1460d15","dumps/main/attachments/search-config-icons/177aba42-9bed-4078-e36b-580e8794cd7f.meta.json":"c35210da5afc11b3af156baf46c23fa523dafac7e8cb2738b4caef80ed48c72e","dumps/main/attachments/search-config-icons/25de0352-aabb-d31f-15f7-bf9299fb004c":"828c3ca82e9be483ae583e5a705dde57b24fd8431e192e3a2d0809871992afa5","dumps/main/attachments/search-config-icons/25de0352-aabb-d31f-15f7-bf9299fb004c.meta.json":"aa5483b5c65427c028a676b2fc13892f6fcaf602613183962744c43ca146d86a","dumps/main/attachments/search-config-icons/2bbe48f4-d3b8-c9e0-86e3-a54c37ec3335":"723ac3228124926537d5a61284d60e198a52895195f9f69b967c578ef7a012ad","dumps/main/attachments/search-config-icons/2bbe48f4-d3b8-c9e0-86e3-a54c37ec3335.meta.json":"d754b38d7e2f79e651d5fe110a7bb9855e0f7269e177be6d047453a36a52a4c5","dumps/main/attachments/search-config-icons/2e835b0e-9709-d1bb-9725-87f59f3445ca":"16ea89d4baa39529d7a84d5152867a4c6ed6867198c4dfa1648b1f43ce6a3f6f","dumps/main/attachments/search-config-icons/2e835b0e-9709-d1bb-9725-87f59f3445ca.meta.json":"7edb361a6610fdabb431a58bc170b7df3f179ca1fadebae6f2e98777b64b35c5","dumps/main/attachments/search-config-icons/2ecca3f8-c1ef-43cc-b053-886d1ae46c36":"774f0a7a613c6c5bea642e3628fa7436851de79e7da9713ad0c96d5db7f44300","dumps/main/attachments/search-config-icons/2ecca3f8-c1ef-43cc-b053-886d1ae46c36.meta.json":"194cb07dd29fd66121f05bbef38291e894291adcbc4c63c373b5f72f6f2e245e","dumps/main/attachments/search-config-icons/32d26d19-aeb0-5c01-32e8-f8970be9246f":"a64f553b79fbb8c45734310dac401ad253ccd05aeabfa58bb5541daa6d8caf70","dumps/main/attachments/search-config-icons/32d26d19-aeb0-5c01-32e8-f8970be9246f.meta.json":"6e56cf6a9470f575b283e40ed6a049e9dbffadcb59fa74a0f941b431c444d795","dumps/main/attachments/search-config-icons/39d0b17d-c020-4890-932f-83c0f6ed130b":"4f409c3ffc67cfa870b05e4089b6ffc3fc81448fa60afba447f0177cd1192b1e","dumps/main/attachments/search-config-icons/39d0b17d-c020-4890-932f-83c0f6ed130b.meta.json":"686c72d6cd220285d8b97af55474198027eab1b1af7ed89508c8935c9e00e7d4","dumps/main/attachments/search-config-icons/41135a88-093d-4077-873b-9de1ae133427":"c2718c5e416670426475dd8cc496f5464bf95224e8f8f0a72b695360ddc917c0","dumps/main/attachments/search-config-icons/41135a88-093d-4077-873b-9de1ae133427.meta.json":"a941fc27ca88b56eccbdec380ce2d3b911f4c62e4aba1f5399bc4498c6601d94","dumps/main/attachments/search-config-icons/41f0d805-3775-4988-8d8c-5ad8ccd86d1c":"755b8939c63b1fcc9acd05cd33ffed675397516d37b5bd8f3a03875e25d3fb43","dumps/main/attachments/search-config-icons/41f0d805-3775-4988-8d8c-5ad8ccd86d1c.meta.json":"25cafe7d629c6b006e15dee98987c26ef509f348ed0350a3ccf1f06838db86f3","dumps/main/attachments/search-config-icons/47da97b5-600f-c450-fd15-a52bb2169c11":"d7fdfd971d874f2ec6f209df6f6b8173d126cd3f7a25daacb94de4259efbcf16","dumps/main/attachments/search-config-icons/47da97b5-600f-c450-fd15-a52bb2169c11.meta.json":"e6b95ca29bf3e750819cf890ae8e879ac506d54b918c3c0ab065adc16a131188","dumps/main/attachments/search-config-icons/48c72361-cd67-412e-bd7f-f81a43c10791":"92da7ef030e1d3ed97235748156383e5d75fa6d2744bd124334ab47dc0b689a1","dumps/main/attachments/search-config-icons/48c72361-cd67-412e-bd7f-f81a43c10791.meta.json":"21d1320d60c981b9c9248b9b186fc49f9d95046a817d7a3145f48465236087e8","dumps/main/attachments/search-config-icons/4e271681-3e0f-91ac-9750-03f665efc171":"189ed3031a2cefd3150c9e5b37bee1ffbc1f7850f7ac0621e4b8d262f2c1048c","dumps/main/attachments/search-config-icons/4e271681-3e0f-91ac-9750-03f665efc171.meta.json":"0a401871b82f1c1cbca91232fd643be1cc1a76c07a48830eaa2a47cdfafb1f14","dumps/main/attachments/search-config-icons/50f6171f-8e7a-b41b-862e-f97397038fb2":"9140bd1b30953f41bc758d2c0ecc873f5163e4f51126c278991eccd38589c541","dumps/main/attachments/search-config-icons/50f6171f-8e7a-b41b-862e-f97397038fb2.meta.json":"805d8ce33bac4611ce12d1f84ef431313555d76bf996264736e401ceb6dabe98","dumps/main/attachments/search-config-icons/5203dd03-2c55-4b53-9c60-58258d587be1":"adb29f6fd95956401630d94967381ac473f57215d96a5bcf500a00e747731380","dumps/main/attachments/search-config-icons/5203dd03-2c55-4b53-9c60-58258d587be1.meta.json":"27a6f994c2c7653a33d380ac13c4cfbc00f543a92f229426aa71d85b1f968357","dumps/main/attachments/search-config-icons/5914932e-66ba-4126-8be5-d37beadd9532":"02f54211387baa59e4246356dc7344e48f39a412f2e5993d7f403aa538df7276","dumps/main/attachments/search-config-icons/5914932e-66ba-4126-8be5-d37beadd9532.meta.json":"2df77daeeef5892fdb7fdeecffb804638bd0d2f7da5b9e617f01303d786dcd09","dumps/main/attachments/search-config-icons/5ded611d-44b2-dc46-fd67-fb116888d75d":"877fb3aca13d2a7c656df1f94df3fa052afbb40b65c99ba5382392ff5499016e","dumps/main/attachments/search-config-icons/5ded611d-44b2-dc46-fd67-fb116888d75d.meta.json":"d1c75915fdc86461e755cd08e670b01da41cd3d76688afe692f841733a9b7ee0","dumps/main/attachments/search-config-icons/5e03d6f4-6ee9-8bc8-cf22-7a5f2cf55c41":"9cd3da38e3938549434d1c3cba6fed249ffa7d91d9a6d7ffb5f4184f527cac76","dumps/main/attachments/search-config-icons/5e03d6f4-6ee9-8bc8-cf22-7a5f2cf55c41.meta.json":"8506d9438825f2dc34875e04e0212e22a2652c5c43aa93e4d184d59ec765316f","dumps/main/attachments/search-config-icons/6644f26f-28ea-4222-929d-5d43a02dae05":"4f1bfbfec1441bd9a304ca7f3b8fd54130e94df185f7b28bb17c86ba517e13b7","dumps/main/attachments/search-config-icons/6644f26f-28ea-4222-929d-5d43a02dae05.meta.json":"f7d37f9c8b87480539cd981f463790c99ed15b2ffc5e3ff4786dd11c25228df4","dumps/main/attachments/search-config-icons/6d10d702-7bd6-1452-90a5-3df665a38f66":"f895a965b68d02e7391cc4504d9be75e1ba7f9b50a1dd59af77bb44a7769c08c","dumps/main/attachments/search-config-icons/6d10d702-7bd6-1452-90a5-3df665a38f66.meta.json":"d782d80f8187cf8051be89c6b8a1ef4700e0b84dcda006843d1fd2f266c4419b","dumps/main/attachments/search-config-icons/6e36a151-e4f4-4117-9067-1ca82c47d01a":"e9849089ffced59563896974afee0fceedac7fc8455bbeaa5bae230f54c933d9","dumps/main/attachments/search-config-icons/6e36a151-e4f4-4117-9067-1ca82c47d01a.meta.json":"0e5a64c06ea0ae875e8e0fdc850feddf5a8714b8290293dcd100d455de32ace0","dumps/main/attachments/search-config-icons/6f4da442-d31e-28f8-03af-797d16bbdd27":"dd5cab3711f778677859e86000a127ed07a6175e8e58aecb0fba71b825ce76d7","dumps/main/attachments/search-config-icons/6f4da442-d31e-28f8-03af-797d16bbdd27.meta.json":"0a947797180fdaf031a9c2d2f841b88243c90ff85f0af873f99ddd770fc59e8b","dumps/main/attachments/search-config-icons/7072564d-a573-4750-bf33-f0a07631c9eb":"0a653ea57472694ac05623d9b237e479232a0d65683d05f89661f996054e3276","dumps/main/attachments/search-config-icons/7072564d-a573-4750-bf33-f0a07631c9eb.meta.json":"bb8a256f72b37166fea2ecd4c3a59f49615854a7210e6963f2571f8dcb3d3a3f","dumps/main/attachments/search-config-icons/70fdd651-6c50-b7bb-09ec-7e85da259173":"31a793dad95b5ffd02d39ebf14fc40877596f418f5926247487265034181dc8f","dumps/main/attachments/search-config-icons/70fdd651-6c50-b7bb-09ec-7e85da259173.meta.json":"8c744e9d2f218256e63f1b1a2193f2fc4a7b980e72464e8d57fbe150446f2efc","dumps/main/attachments/search-config-icons/71f41a0c-5b70-4116-b30f-e62089083522":"5aad083bfcef256d433c1ffa571b814d16f61832bcd7565bf03909011f6a0bfc","dumps/main/attachments/search-config-icons/71f41a0c-5b70-4116-b30f-e62089083522.meta.json":"4a8f0c4e4ee643faa2f8d8cc4ddb8f87d14c740e8c9252223f826181c0117741","dumps/main/attachments/search-config-icons/74793ce1-a918-a5eb-d3c0-2aadaff3c88c":"ca8f102ac4f35189ebcb786d080843b603b234f89b8d8b1c0ef27a0ab7148182","dumps/main/attachments/search-config-icons/74793ce1-a918-a5eb-d3c0-2aadaff3c88c.meta.json":"60a7975cd79156623b0ca58be4110d152e50b6e9caaaa211dad1cd37eabb0345","dumps/main/attachments/search-config-icons/74f94dc2-caf6-4b90-b3d2-f3e2f7714d88":"3376e14529ed2e96c7dc491b3bf11914d7c8ff47a068311b2432c086c2ae0f28","dumps/main/attachments/search-config-icons/74f94dc2-caf6-4b90-b3d2-f3e2f7714d88.meta.json":"3a94a78a846f312c85c0609971b153aaba9819e2b657f25e3b0648a3956933d1","dumps/main/attachments/search-config-icons/764e3b14-fe16-4feb-8384-124c516a5afa":"71413ef23ac14ce2b7bb76f7f5d16b2df267239841a88ddab36b129481e00616","dumps/main/attachments/search-config-icons/764e3b14-fe16-4feb-8384-124c516a5afa.meta.json":"2f16dd51ade97a327d4e5f14d689f822a5c9061b9b27810bbccbf2f406a5e56f","dumps/main/attachments/search-config-icons/7bbe6c5c-fdb8-2845-a4f4-e1382e708a0e":"24daa27a3234d01b5add42e027b0a34000d0ab47c17fe3924c2ca267b7b61c19","dumps/main/attachments/search-config-icons/7bbe6c5c-fdb8-2845-a4f4-e1382e708a0e.meta.json":"308d345dbcfd7583e5f7460d34caf3b63d01b747a6e060a2b0971bf00ed2b22c","dumps/main/attachments/search-config-icons/7bf4ca37-e2b8-4d31-a1c3-979bc0e85131":"912d20feefcba57d43bffff5e245b8c1e3865155ed686d8ad253bbab71116e83","dumps/main/attachments/search-config-icons/7bf4ca37-e2b8-4d31-a1c3-979bc0e85131.meta.json":"3ec071b0a2940cd8892a72bd28d44237aecfd20d88303661348257ddb98aee43","dumps/main/attachments/search-config-icons/7c81cf98-7c11-4afd-8279-db89118a6dfb":"e988445d87afe0d285bea251705fc23eb70ac42426ab0d7a69d9276585c5573c","dumps/main/attachments/search-config-icons/7c81cf98-7c11-4afd-8279-db89118a6dfb.meta.json":"273dd09cad2a62459cc062e3b39b835d55a06b10cb7d5149aad77dd55451821f","dumps/main/attachments/search-config-icons/7cb4d88a-d4df-45b2-87e4-f896eaf1bbdb":"8dc2e75e6792b8374b20621fa2151ac24b4626e5c1f6a1abec4f912746441859","dumps/main/attachments/search-config-icons/7cb4d88a-d4df-45b2-87e4-f896eaf1bbdb.meta.json":"21d2522ab4e47477e72da3a2d2223e50e55fef442e2ba736d56df1e09593d76f","dumps/main/attachments/search-config-icons/7edaf4fe-a8a0-432b-86d2-bf75ebe80851":"27541cb376bdda829a6cf9cefd13da112728881e3daa4ac3c1178d4ce15f1e8b","dumps/main/attachments/search-config-icons/7edaf4fe-a8a0-432b-86d2-bf75ebe80851.meta.json":"3aea5d0652172940ac33e32628dcc6a03b79fe686c6de752482c8e3ae5cd70eb","dumps/main/attachments/search-config-icons/7efbed51-813c-581d-d8d3-f8758434e451":"b0c6d1850265e3c946917232ca6c6ace3dad23347bfab4f81351eac569326d34","dumps/main/attachments/search-config-icons/7efbed51-813c-581d-d8d3-f8758434e451.meta.json":"5a723c8f04bffa33a69a7054d30a4816caf1a3924081c85e1d9770126f761a96","dumps/main/attachments/search-config-icons/84bb4962-e571-227a-9ef6-2ac5f2aac361":"a1fd5d127a5f2590ddcd439b7a2abb3456b48217ea11daf0345b26e108f520e6","dumps/main/attachments/search-config-icons/84bb4962-e571-227a-9ef6-2ac5f2aac361.meta.json":"5cb0ebdde367b9754ddf6cbd01150414d27977b2d4c5f65cd6bbb89989388f3b","dumps/main/attachments/search-config-icons/87ac4cde-f581-398b-1e32-eb4079183b36":"33ca72f1eac56793d1fd811189cedef98004a067c85b1143083b564814a4b0db","dumps/main/attachments/search-config-icons/87ac4cde-f581-398b-1e32-eb4079183b36.meta.json":"d97eca8063cc17b99c81c55d4ff121d765c793e006ed252fec5f9539bd0fc339","dumps/main/attachments/search-config-icons/8831ce10-b1e4-6eb4-4975-83c67457288e":"ca3cc8786977f6ffeb0546ff8f3bb2b7fd240d1956fbf86777dbf0e8bec9c03b","dumps/main/attachments/search-config-icons/8831ce10-b1e4-6eb4-4975-83c67457288e.meta.json":"45274d848d1f6d398563bb46a2bfa3eee40ff16a5dbf0bbc8904db442f80702c","dumps/main/attachments/search-config-icons/890de5c4-0941-a116-473a-5d240e79497a":"6ba1f0fd1d12014cab32f74daab24dfa16fb26613ace20a1e595267621038a07","dumps/main/attachments/search-config-icons/890de5c4-0941-a116-473a-5d240e79497a.meta.json":"107547059360c3658dcf187a546ffb52bb23fa385e1338151043bebe82bbf640","dumps/main/attachments/search-config-icons/8abb10a7-212f-46b5-a7b4-244f414e3810":"f8780adb4d7b28f2f881db4ca7b697d8fc916cd9fa834ccc445fe7d4b72a6cc7","dumps/main/attachments/search-config-icons/8abb10a7-212f-46b5-a7b4-244f414e3810.meta.json":"5401603c7abbc6ca5bdddb8f9cca7eee2e26e5721cc73f23d95f600d5421d431","dumps/main/attachments/search-config-icons/91a9672d-e945-8e1e-0996-aefdb0190716":"5d53ef1866a08cc29011f5f2a9ce99bbf37cf42e80de7f0e8cc30d13337e8187","dumps/main/attachments/search-config-icons/91a9672d-e945-8e1e-0996-aefdb0190716.meta.json":"4e8ea36e3d659eb22ac7c86498003ca8885bab9c40685bb8ca7796a8230201da","dumps/main/attachments/search-config-icons/94a84724-c30f-4767-ba42-01cc37fc31a4":"98dca7e24cad0a1be96ef2c323e9759beb63c72440756f887e2482d9ce8e8969","dumps/main/attachments/search-config-icons/94a84724-c30f-4767-ba42-01cc37fc31a4.meta.json":"1070966901fe9db82b71bfa74ddeedd4f23ab2ed1eddaf201634e06a604e6006","dumps/main/attachments/search-config-icons/95ed201d-4ab8-4cb8-831d-454f53cab0f8":"3426b5100a6bdb45f8039f0c71a6b68193750ba7bae5b36e5ed31b2b7f372cda","dumps/main/attachments/search-config-icons/95ed201d-4ab8-4cb8-831d-454f53cab0f8.meta.json":"3447cd050619c1d2e5859147ab894a43da75235a580219306d8629e28a7a3eb5","dumps/main/attachments/search-config-icons/96327a73-c433-5eb4-a16d-b090cadfb80b":"ca6e972004f62355c1ea97656bc2328e1643971bdecab9c6b563d45593b8122e","dumps/main/attachments/search-config-icons/96327a73-c433-5eb4-a16d-b090cadfb80b.meta.json":"c4e3c9e6426e6f35410c287eef95b3e2134e54409e462f02dd440876c06b1bb4","dumps/main/attachments/search-config-icons/9802e63d-05ec-48ba-93f9-746e0981ad98":"6b1b073183eb0012daea0dce351a94d395c8a0b531b610e56eac52b3d1d1da0e","dumps/main/attachments/search-config-icons/9802e63d-05ec-48ba-93f9-746e0981ad98.meta.json":"cceb55c68db8dddd23d064364a281e982069bfe2bb55eba7d282fffcec2aa89f","dumps/main/attachments/search-config-icons/a06db97d-1210-ea2e-5474-0e2f7d295bfd":"617dec5d635efb0a12d0de935c6999ef0249f4a63c62bdcb96551518bc3d1812","dumps/main/attachments/search-config-icons/a06db97d-1210-ea2e-5474-0e2f7d295bfd.meta.json":"06cf576ca882bd7c2d54c18329e21e5b1a9cb7732d4954b52cbfa52979a67765","dumps/main/attachments/search-config-icons/a06dc3fd-4bdb-41f3-2ebc-4cbed06a9bd3":"d994f806b1e4225b50be5ab681b2cecf845cc216a19a432d878cea3cb815bafd","dumps/main/attachments/search-config-icons/a06dc3fd-4bdb-41f3-2ebc-4cbed06a9bd3.meta.json":"67524e18799023a017c7d9db1b9ba5c9cc3090d20f8154449a8f44ba22719104","dumps/main/attachments/search-config-icons/a2c7d4e9-f770-51e1-0963-3c2c8401631d":"1bf68aca7bfc75ca8485c3dac9a1daa13c1a3eb480688c32262096af6076adfa","dumps/main/attachments/search-config-icons/a2c7d4e9-f770-51e1-0963-3c2c8401631d.meta.json":"4ab103bba0f8fde581c3950c6c08cfcf6786104d8cbcba240499308f26958d04","dumps/main/attachments/search-config-icons/a83f24e4-602c-47bd-930c-ad0947ee1adf":"66612f999921d892645c8a2b37aa5dad17b134e7fdaed375a683baec7fc10697","dumps/main/attachments/search-config-icons/a83f24e4-602c-47bd-930c-ad0947ee1adf.meta.json":"f985ffbde6cf6ef972b6798c9336922dcfa29ca9a31e3aa4fae1962e069bdb0c","dumps/main/attachments/search-config-icons/b64f09fd-52d1-c48e-af23-4ce918e7bf3b":"c3e8300801c5c585662f14fd8e819d635efd9830783dc3c631212927866e9898","dumps/main/attachments/search-config-icons/b64f09fd-52d1-c48e-af23-4ce918e7bf3b.meta.json":"f7fd846d6717131e75865f8f5ed562e88f40be3dcf1603f2660b425dedabc7d1","dumps/main/attachments/search-config-icons/b882b24d-1776-4ef9-9016-0bdbd935eda3":"076352591c7077af4af5771918f80b5da9c6bf479327cc68390abdb158f3ec03","dumps/main/attachments/search-config-icons/b882b24d-1776-4ef9-9016-0bdbd935eda3.meta.json":"229139bca53bc63bd59b8f261f36c11fbe76b2b45dfeac2580261cf290c41365","dumps/main/attachments/search-config-icons/b8ca5a94-8fff-27ad-6e00-96e244a32e21":"1474c93e49c209aca2a2df2acb61b64574805106bead6edebd67287de21920e0","dumps/main/attachments/search-config-icons/b8ca5a94-8fff-27ad-6e00-96e244a32e21.meta.json":"6fd72c11afb4249d0166d8d98c552ee02d73c0e07f0578bfd3d7e67d70bcaee3","dumps/main/attachments/search-config-icons/b9424309-f601-4a69-98ca-ca68e65633e6":"601d72e7abde5ec864b3d8ca0031896f769107670b84c66053062481a56d8665","dumps/main/attachments/search-config-icons/b9424309-f601-4a69-98ca-ca68e65633e6.meta.json":"f299a7d56c5552fc592c66073d3e1e1d16ce4a99e935dcc0cad7dafcad6b9e3b","dumps/main/attachments/search-config-icons/c411adc1-9661-4fb5-a4c1-8cfe74911943":"150765e8e9b985ba5b820ac9b8e7623023d5a0e24f94663d5e9203d8d7598059","dumps/main/attachments/search-config-icons/c411adc1-9661-4fb5-a4c1-8cfe74911943.meta.json":"c5cc89d5f24ef1fa40b1c47c2e97eaeb01439b8d3b186b9c2fe716c94ead30f2","dumps/main/attachments/search-config-icons/cbf9e891-d079-2b28-5617-283450d463dd":"5b2c34b3c4e8dd898b664dba6c3786e2ff9869eff55d673aa48361f11325ed07","dumps/main/attachments/search-config-icons/cbf9e891-d079-2b28-5617-283450d463dd.meta.json":"b757806fd1b922d81bbecab94c73d3db98cfc2aa2791a4d5137112f795a732ee","dumps/main/attachments/search-config-icons/d87f251c-3e12-a8bf-e2d0-afd43d36c5f9":"865d76c8175a8f11dedc93f0bc212242a97a8a76adac870e8249368cecc81402","dumps/main/attachments/search-config-icons/d87f251c-3e12-a8bf-e2d0-afd43d36c5f9.meta.json":"22594c8870cbabe5fc5d2637509235202502661b466e9e37c5878716f323a34f","dumps/main/attachments/search-config-icons/db0e1627-ae89-4c25-8944-a9481d8512d9":"97a68f0b948b68bbf389a9ef43e2fe6c31ff8dc7889c939fdfdea79378576c67","dumps/main/attachments/search-config-icons/db0e1627-ae89-4c25-8944-a9481d8512d9.meta.json":"1eccc999dcd377af84cf63ed60b7ef23d5d4b936a1e465d12349a5366b1b012d","dumps/main/attachments/search-config-icons/e02f23df-8d48-2b1b-3b5c-6dd27302c61c":"247aa26993083705ce99a8e5612cdf262aca98cde86ba19afc964329ba95986a","dumps/main/attachments/search-config-icons/e02f23df-8d48-2b1b-3b5c-6dd27302c61c.meta.json":"06fc893d29cf406519611da9d1993a13bd9134192940c12bf64536ea571db4f0","dumps/main/attachments/search-config-icons/e718e983-09aa-e8f6-b25f-cd4b395d4785":"809697f48848e7c3638d5f3e0b224ea60b3800504e7bd8417854d55989b85196","dumps/main/attachments/search-config-icons/e718e983-09aa-e8f6-b25f-cd4b395d4785.meta.json":"0d9baef39747776500e5b83e72cd9d901fc09ac08247368dd2117bb4ec011f54","dumps/main/attachments/search-config-icons/e7547f62-187b-b641-d462-e54a3f813d9a":"c971ee33b8c0a57349669d957bf73070b0632b128c94748e845b57d5e15221a4","dumps/main/attachments/search-config-icons/e7547f62-187b-b641-d462-e54a3f813d9a.meta.json":"8ec4f6a7826966f2ff82632ef527366db3452ebc40c90a557602111f0ea956c9","dumps/main/attachments/search-config-icons/eb62e768-151b-45d1-9fe5-9e1d2a5991c5":"aa46b3d1ed8557e5bc7e71988cc6c46b00363b890d2a781973f9dc9073f8dd31","dumps/main/attachments/search-config-icons/eb62e768-151b-45d1-9fe5-9e1d2a5991c5.meta.json":"a06682b589df8dd63b1f25c01630ead55a89217f72c0bc04b391829af3fef59f","dumps/main/attachments/search-config-icons/f312610a-ebfb-a106-ea92-fd643c5d3636":"91d17ba44192a6430ffdb447ff3a11533ef964628f67c13480cc9470212d3d65","dumps/main/attachments/search-config-icons/f312610a-ebfb-a106-ea92-fd643c5d3636.meta.json":"ce26ab2382a7a67a55688330dd74127b4a980610f4030bde8eaaa20b81306559","dumps/main/attachments/search-config-icons/fa0fc42c-d91d-fca7-34eb-806ff46062dc":"6da5620880159634213e197fafca1dde0272153be3e4590818533fab8d040770","dumps/main/attachments/search-config-icons/fa0fc42c-d91d-fca7-34eb-806ff46062dc.meta.json":"0c3c0eb832be884f25186395b8bf08cdbe0a6e2845b9e55e7cbea5d0f183ed7d","dumps/main/attachments/search-config-icons/fca3e3ee-56cd-f474-dc31-307fd24a891d":"c4d88cfa5262f6d2cf76b167281d25821c9e1770684b739ed6ad3cf7277a121b","dumps/main/attachments/search-config-icons/fca3e3ee-56cd-f474-dc31-307fd24a891d.meta.json":"a40c37a5150e3745849f67305fe2fe1e06ef1c3901f6dc604a8e3f6c94e7b624","dumps/main/attachments/search-config-icons/fe75ce3f-1545-400c-b28c-ad771054e69f":"3a9d06951c7c9d2c19cd00533a760b0f8755b1e2e718af81c710297d030fbe44","dumps/main/attachments/search-config-icons/fe75ce3f-1545-400c-b28c-ad771054e69f.meta.json":"3f353e083d7a885f6d59d36c9276a2d325686a533cf8c502cd41a10172e763ea","dumps/main/attachments/search-config-icons/fed4f021-ff3e-942a-010e-afa43fda2136":"d7fdfd971d874f2ec6f209df6f6b8173d126cd3f7a25daacb94de4259efbcf16","dumps/main/attachments/search-config-icons/fed4f021-ff3e-942a-010e-afa43fda2136.meta.json":"740f77dcc93ece89fd55557baf399a4464373c81154b0a9758b8622f6c458253","dumps/main/regions.json":"e8990158373f82d3f89fed5089cf29e4177cc85904479128728e05025e9a0c0c","dumps/main/search-config-icons.json":"76955459bdcd7ea46a67737309ed65c3497b9dd71c66a8f978aa3448001ad33b","dumps/main/search-config-v2.json":"299a8f3f0b9a7ba4330fc8bd8e1b2ce65804cdb452b86d7e40ec30a1bd02d6a2","dumps/main/search-telemetry-v2.json":"b0f3ba5c0b4d9051e87b84ebb90abf4477a56b1999c033deca3ce3c8e4a3f7f9","src/cache.rs":"c6179802017b43885136e7d64004890cc13e8c2d4742e04073cf404b578f63db","src/client.rs":"a1f613e49d8c0218b6b9b3f6d1bd5507756f97ad43b84e177da0c03fcfd1d750","src/config.rs":"722cee4b4787e61ba9aca695466660b88dfda12de919097b763f0b2c2e1e4041","src/context.rs":"43bab81026b6f1a2509d129e806fffd09ba80110d656798a02589985017a3c21","src/error.rs":"80aeb1093682acea7350f4876e1501d70c5daa822d26babace80d004e2a34bce","src/jexl_filter.rs":"48a9d960e05dae444421f7c4ceeb45eab656f03f1e7071215c8e8d39aab56b54","src/lib.rs":"5555139a8fcb77f91e67946ec4284e1e945a4de1f97b1b95112bca36b846a61a","src/macros.rs":"6b06d0ba42ee95235bfd71bac1a0eed02f60c894775ebee64165648b10e932c4","src/schema.rs":"348e0d5ad1840aaae796b537d21381ef91bd75be262138bfec376d9f88d205b3","src/service.rs":"f86b9b2ba34942d232262de40c25e2139e9ab85753a87d21dd55c989fd057d83","src/signatures.rs":"baa2dae76abd8166158fea4676e67e17c17b65af6968de52768350409dbd7092","src/storage.rs":"c33dd92914770e96d3d44dbb9e95f512ce54261710a42c7cf4a896be348c529e","uniffi.toml":"bd7cc0e7c1981f53938f429c4f2541ac454ed4160a8a0b4670659e38acd23ee5"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"00d8e28963e324f906faf95b3891030103f4486b8491e8d8228b0778d3fa143f","dumps/main/attachments/regions/world":"00b308033d44f61612b962f572765d14a3999586d92fc8b9fff2217a1ae070e8","dumps/main/attachments/regions/world-buffered":"1d3ed6954fac2a5b31302f5d3e8186c5fa08a20239afc0643ca5dfbb4d8a86fc","dumps/main/attachments/regions/world-buffered.meta.json":"914a71376a152036aceccb6877e079fbb9e3373c6219f24f00dd30e901a72cce","dumps/main/attachments/regions/world.meta.json":"2a47d77834997b98e563265d299723e7f7fd64c8c7a5731afc722862333d6fbd","dumps/main/attachments/search-config-icons/001500a9-1a6c-3f5a-ba15-a5f5a075d256":"fdadf15c6eae7933c3d254ae6311112e0bc8a422c38c758189dbe6a4d7f6b718","dumps/main/attachments/search-config-icons/001500a9-1a6c-3f5a-ba15-a5f5a075d256.meta.json":"6ed1e1c390a45360590e5a1e6d7823218e7b10860581646ddb5e368143aa72fc","dumps/main/attachments/search-config-icons/06cf7432-efd7-f244-927b-5e423005e1ea":"b75ef04a805325e303c4195833cdd077d3d406f360b25b72502fc55880b9150b","dumps/main/attachments/search-config-icons/06cf7432-efd7-f244-927b-5e423005e1ea.meta.json":"0d4cce0ed0dc6b2c46651bea32fc3cc2facfe8b341e1022b65f2cd2231f6b713","dumps/main/attachments/search-config-icons/0a57b0cf-34f0-4d09-96e4-dbd6e3355410":"a7493c6a9d70d60acccf73f62dcbc127a580469570aee60b7482cd42cdb59f69","dumps/main/attachments/search-config-icons/0a57b0cf-34f0-4d09-96e4-dbd6e3355410.meta.json":"d33a128c92b96af2e643158ed3b861d3726bd67a59907fed0795ab2210c82b96","dumps/main/attachments/search-config-icons/0d7668a8-c3f4-cfee-cbc8-536511528937":"7042293af6b04e421cb7b68dc599ac644b76939cdcf5970159e44f658dd6a0cc","dumps/main/attachments/search-config-icons/0d7668a8-c3f4-cfee-cbc8-536511528937.meta.json":"d6523508334a67b201326591606d7e225a04fc53fdce2c1b4d8afac1b41af6b0","dumps/main/attachments/search-config-icons/0eec5640-6fde-d6fe-322a-c72c6d5bd5a2":"64800e32b24b2c8c0582750e1657426d56abd74b65682e20e892f82710d120b6","dumps/main/attachments/search-config-icons/0eec5640-6fde-d6fe-322a-c72c6d5bd5a2.meta.json":"56fb61a078cc45abf7bc3b8fe89b60ef75f3b86ea61d63084749607c4662bbef","dumps/main/attachments/search-config-icons/101ce01d-2691-b729-7f16-9d389803384b":"62d2faa3a8322b1f643aab6e045837500ebe3049c5cb140cb44c4dfc7290337a","dumps/main/attachments/search-config-icons/101ce01d-2691-b729-7f16-9d389803384b.meta.json":"de134ed423a2bd92b4ad8cdf631aad6a83cc2c30f8df9ee251a435ee9f46f28f","dumps/main/attachments/search-config-icons/177aba42-9bed-4078-e36b-580e8794cd7f":"3b88f3ef3cbfaed127d679ec7e44a44fe8dcad688feb89a70a1a9447c1460d15","dumps/main/attachments/search-config-icons/177aba42-9bed-4078-e36b-580e8794cd7f.meta.json":"c35210da5afc11b3af156baf46c23fa523dafac7e8cb2738b4caef80ed48c72e","dumps/main/attachments/search-config-icons/25de0352-aabb-d31f-15f7-bf9299fb004c":"828c3ca82e9be483ae583e5a705dde57b24fd8431e192e3a2d0809871992afa5","dumps/main/attachments/search-config-icons/25de0352-aabb-d31f-15f7-bf9299fb004c.meta.json":"aa5483b5c65427c028a676b2fc13892f6fcaf602613183962744c43ca146d86a","dumps/main/attachments/search-config-icons/2bbe48f4-d3b8-c9e0-86e3-a54c37ec3335":"723ac3228124926537d5a61284d60e198a52895195f9f69b967c578ef7a012ad","dumps/main/attachments/search-config-icons/2bbe48f4-d3b8-c9e0-86e3-a54c37ec3335.meta.json":"d754b38d7e2f79e651d5fe110a7bb9855e0f7269e177be6d047453a36a52a4c5","dumps/main/attachments/search-config-icons/2e835b0e-9709-d1bb-9725-87f59f3445ca":"16ea89d4baa39529d7a84d5152867a4c6ed6867198c4dfa1648b1f43ce6a3f6f","dumps/main/attachments/search-config-icons/2e835b0e-9709-d1bb-9725-87f59f3445ca.meta.json":"7edb361a6610fdabb431a58bc170b7df3f179ca1fadebae6f2e98777b64b35c5","dumps/main/attachments/search-config-icons/2ecca3f8-c1ef-43cc-b053-886d1ae46c36":"774f0a7a613c6c5bea642e3628fa7436851de79e7da9713ad0c96d5db7f44300","dumps/main/attachments/search-config-icons/2ecca3f8-c1ef-43cc-b053-886d1ae46c36.meta.json":"194cb07dd29fd66121f05bbef38291e894291adcbc4c63c373b5f72f6f2e245e","dumps/main/attachments/search-config-icons/32d26d19-aeb0-5c01-32e8-f8970be9246f":"a64f553b79fbb8c45734310dac401ad253ccd05aeabfa58bb5541daa6d8caf70","dumps/main/attachments/search-config-icons/32d26d19-aeb0-5c01-32e8-f8970be9246f.meta.json":"6e56cf6a9470f575b283e40ed6a049e9dbffadcb59fa74a0f941b431c444d795","dumps/main/attachments/search-config-icons/39d0b17d-c020-4890-932f-83c0f6ed130b":"4f409c3ffc67cfa870b05e4089b6ffc3fc81448fa60afba447f0177cd1192b1e","dumps/main/attachments/search-config-icons/39d0b17d-c020-4890-932f-83c0f6ed130b.meta.json":"686c72d6cd220285d8b97af55474198027eab1b1af7ed89508c8935c9e00e7d4","dumps/main/attachments/search-config-icons/41135a88-093d-4077-873b-9de1ae133427":"c2718c5e416670426475dd8cc496f5464bf95224e8f8f0a72b695360ddc917c0","dumps/main/attachments/search-config-icons/41135a88-093d-4077-873b-9de1ae133427.meta.json":"a941fc27ca88b56eccbdec380ce2d3b911f4c62e4aba1f5399bc4498c6601d94","dumps/main/attachments/search-config-icons/41f0d805-3775-4988-8d8c-5ad8ccd86d1c":"755b8939c63b1fcc9acd05cd33ffed675397516d37b5bd8f3a03875e25d3fb43","dumps/main/attachments/search-config-icons/41f0d805-3775-4988-8d8c-5ad8ccd86d1c.meta.json":"25cafe7d629c6b006e15dee98987c26ef509f348ed0350a3ccf1f06838db86f3","dumps/main/attachments/search-config-icons/47da97b5-600f-c450-fd15-a52bb2169c11":"d7fdfd971d874f2ec6f209df6f6b8173d126cd3f7a25daacb94de4259efbcf16","dumps/main/attachments/search-config-icons/47da97b5-600f-c450-fd15-a52bb2169c11.meta.json":"e6b95ca29bf3e750819cf890ae8e879ac506d54b918c3c0ab065adc16a131188","dumps/main/attachments/search-config-icons/48c72361-cd67-412e-bd7f-f81a43c10791":"92da7ef030e1d3ed97235748156383e5d75fa6d2744bd124334ab47dc0b689a1","dumps/main/attachments/search-config-icons/48c72361-cd67-412e-bd7f-f81a43c10791.meta.json":"21d1320d60c981b9c9248b9b186fc49f9d95046a817d7a3145f48465236087e8","dumps/main/attachments/search-config-icons/4e271681-3e0f-91ac-9750-03f665efc171":"189ed3031a2cefd3150c9e5b37bee1ffbc1f7850f7ac0621e4b8d262f2c1048c","dumps/main/attachments/search-config-icons/4e271681-3e0f-91ac-9750-03f665efc171.meta.json":"0a401871b82f1c1cbca91232fd643be1cc1a76c07a48830eaa2a47cdfafb1f14","dumps/main/attachments/search-config-icons/50f6171f-8e7a-b41b-862e-f97397038fb2":"9140bd1b30953f41bc758d2c0ecc873f5163e4f51126c278991eccd38589c541","dumps/main/attachments/search-config-icons/50f6171f-8e7a-b41b-862e-f97397038fb2.meta.json":"805d8ce33bac4611ce12d1f84ef431313555d76bf996264736e401ceb6dabe98","dumps/main/attachments/search-config-icons/5203dd03-2c55-4b53-9c60-58258d587be1":"adb29f6fd95956401630d94967381ac473f57215d96a5bcf500a00e747731380","dumps/main/attachments/search-config-icons/5203dd03-2c55-4b53-9c60-58258d587be1.meta.json":"27a6f994c2c7653a33d380ac13c4cfbc00f543a92f229426aa71d85b1f968357","dumps/main/attachments/search-config-icons/5914932e-66ba-4126-8be5-d37beadd9532":"02f54211387baa59e4246356dc7344e48f39a412f2e5993d7f403aa538df7276","dumps/main/attachments/search-config-icons/5914932e-66ba-4126-8be5-d37beadd9532.meta.json":"2df77daeeef5892fdb7fdeecffb804638bd0d2f7da5b9e617f01303d786dcd09","dumps/main/attachments/search-config-icons/5ded611d-44b2-dc46-fd67-fb116888d75d":"877fb3aca13d2a7c656df1f94df3fa052afbb40b65c99ba5382392ff5499016e","dumps/main/attachments/search-config-icons/5ded611d-44b2-dc46-fd67-fb116888d75d.meta.json":"d1c75915fdc86461e755cd08e670b01da41cd3d76688afe692f841733a9b7ee0","dumps/main/attachments/search-config-icons/5e03d6f4-6ee9-8bc8-cf22-7a5f2cf55c41":"9cd3da38e3938549434d1c3cba6fed249ffa7d91d9a6d7ffb5f4184f527cac76","dumps/main/attachments/search-config-icons/5e03d6f4-6ee9-8bc8-cf22-7a5f2cf55c41.meta.json":"8506d9438825f2dc34875e04e0212e22a2652c5c43aa93e4d184d59ec765316f","dumps/main/attachments/search-config-icons/6644f26f-28ea-4222-929d-5d43a02dae05":"4f1bfbfec1441bd9a304ca7f3b8fd54130e94df185f7b28bb17c86ba517e13b7","dumps/main/attachments/search-config-icons/6644f26f-28ea-4222-929d-5d43a02dae05.meta.json":"f7d37f9c8b87480539cd981f463790c99ed15b2ffc5e3ff4786dd11c25228df4","dumps/main/attachments/search-config-icons/6d10d702-7bd6-1452-90a5-3df665a38f66":"f895a965b68d02e7391cc4504d9be75e1ba7f9b50a1dd59af77bb44a7769c08c","dumps/main/attachments/search-config-icons/6d10d702-7bd6-1452-90a5-3df665a38f66.meta.json":"d782d80f8187cf8051be89c6b8a1ef4700e0b84dcda006843d1fd2f266c4419b","dumps/main/attachments/search-config-icons/6e36a151-e4f4-4117-9067-1ca82c47d01a":"e9849089ffced59563896974afee0fceedac7fc8455bbeaa5bae230f54c933d9","dumps/main/attachments/search-config-icons/6e36a151-e4f4-4117-9067-1ca82c47d01a.meta.json":"0e5a64c06ea0ae875e8e0fdc850feddf5a8714b8290293dcd100d455de32ace0","dumps/main/attachments/search-config-icons/6f4da442-d31e-28f8-03af-797d16bbdd27":"dd5cab3711f778677859e86000a127ed07a6175e8e58aecb0fba71b825ce76d7","dumps/main/attachments/search-config-icons/6f4da442-d31e-28f8-03af-797d16bbdd27.meta.json":"0a947797180fdaf031a9c2d2f841b88243c90ff85f0af873f99ddd770fc59e8b","dumps/main/attachments/search-config-icons/7072564d-a573-4750-bf33-f0a07631c9eb":"0a653ea57472694ac05623d9b237e479232a0d65683d05f89661f996054e3276","dumps/main/attachments/search-config-icons/7072564d-a573-4750-bf33-f0a07631c9eb.meta.json":"bb8a256f72b37166fea2ecd4c3a59f49615854a7210e6963f2571f8dcb3d3a3f","dumps/main/attachments/search-config-icons/70fdd651-6c50-b7bb-09ec-7e85da259173":"31a793dad95b5ffd02d39ebf14fc40877596f418f5926247487265034181dc8f","dumps/main/attachments/search-config-icons/70fdd651-6c50-b7bb-09ec-7e85da259173.meta.json":"8c744e9d2f218256e63f1b1a2193f2fc4a7b980e72464e8d57fbe150446f2efc","dumps/main/attachments/search-config-icons/71f41a0c-5b70-4116-b30f-e62089083522":"5aad083bfcef256d433c1ffa571b814d16f61832bcd7565bf03909011f6a0bfc","dumps/main/attachments/search-config-icons/71f41a0c-5b70-4116-b30f-e62089083522.meta.json":"4a8f0c4e4ee643faa2f8d8cc4ddb8f87d14c740e8c9252223f826181c0117741","dumps/main/attachments/search-config-icons/74793ce1-a918-a5eb-d3c0-2aadaff3c88c":"ca8f102ac4f35189ebcb786d080843b603b234f89b8d8b1c0ef27a0ab7148182","dumps/main/attachments/search-config-icons/74793ce1-a918-a5eb-d3c0-2aadaff3c88c.meta.json":"60a7975cd79156623b0ca58be4110d152e50b6e9caaaa211dad1cd37eabb0345","dumps/main/attachments/search-config-icons/74f94dc2-caf6-4b90-b3d2-f3e2f7714d88":"3376e14529ed2e96c7dc491b3bf11914d7c8ff47a068311b2432c086c2ae0f28","dumps/main/attachments/search-config-icons/74f94dc2-caf6-4b90-b3d2-f3e2f7714d88.meta.json":"3a94a78a846f312c85c0609971b153aaba9819e2b657f25e3b0648a3956933d1","dumps/main/attachments/search-config-icons/764e3b14-fe16-4feb-8384-124c516a5afa":"71413ef23ac14ce2b7bb76f7f5d16b2df267239841a88ddab36b129481e00616","dumps/main/attachments/search-config-icons/764e3b14-fe16-4feb-8384-124c516a5afa.meta.json":"2f16dd51ade97a327d4e5f14d689f822a5c9061b9b27810bbccbf2f406a5e56f","dumps/main/attachments/search-config-icons/7bbe6c5c-fdb8-2845-a4f4-e1382e708a0e":"24daa27a3234d01b5add42e027b0a34000d0ab47c17fe3924c2ca267b7b61c19","dumps/main/attachments/search-config-icons/7bbe6c5c-fdb8-2845-a4f4-e1382e708a0e.meta.json":"308d345dbcfd7583e5f7460d34caf3b63d01b747a6e060a2b0971bf00ed2b22c","dumps/main/attachments/search-config-icons/7bf4ca37-e2b8-4d31-a1c3-979bc0e85131":"912d20feefcba57d43bffff5e245b8c1e3865155ed686d8ad253bbab71116e83","dumps/main/attachments/search-config-icons/7bf4ca37-e2b8-4d31-a1c3-979bc0e85131.meta.json":"3ec071b0a2940cd8892a72bd28d44237aecfd20d88303661348257ddb98aee43","dumps/main/attachments/search-config-icons/7c81cf98-7c11-4afd-8279-db89118a6dfb":"e988445d87afe0d285bea251705fc23eb70ac42426ab0d7a69d9276585c5573c","dumps/main/attachments/search-config-icons/7c81cf98-7c11-4afd-8279-db89118a6dfb.meta.json":"273dd09cad2a62459cc062e3b39b835d55a06b10cb7d5149aad77dd55451821f","dumps/main/attachments/search-config-icons/7cb4d88a-d4df-45b2-87e4-f896eaf1bbdb":"8dc2e75e6792b8374b20621fa2151ac24b4626e5c1f6a1abec4f912746441859","dumps/main/attachments/search-config-icons/7cb4d88a-d4df-45b2-87e4-f896eaf1bbdb.meta.json":"21d2522ab4e47477e72da3a2d2223e50e55fef442e2ba736d56df1e09593d76f","dumps/main/attachments/search-config-icons/7edaf4fe-a8a0-432b-86d2-bf75ebe80851":"27541cb376bdda829a6cf9cefd13da112728881e3daa4ac3c1178d4ce15f1e8b","dumps/main/attachments/search-config-icons/7edaf4fe-a8a0-432b-86d2-bf75ebe80851.meta.json":"3aea5d0652172940ac33e32628dcc6a03b79fe686c6de752482c8e3ae5cd70eb","dumps/main/attachments/search-config-icons/7efbed51-813c-581d-d8d3-f8758434e451":"b0c6d1850265e3c946917232ca6c6ace3dad23347bfab4f81351eac569326d34","dumps/main/attachments/search-config-icons/7efbed51-813c-581d-d8d3-f8758434e451.meta.json":"5a723c8f04bffa33a69a7054d30a4816caf1a3924081c85e1d9770126f761a96","dumps/main/attachments/search-config-icons/84bb4962-e571-227a-9ef6-2ac5f2aac361":"a1fd5d127a5f2590ddcd439b7a2abb3456b48217ea11daf0345b26e108f520e6","dumps/main/attachments/search-config-icons/84bb4962-e571-227a-9ef6-2ac5f2aac361.meta.json":"5cb0ebdde367b9754ddf6cbd01150414d27977b2d4c5f65cd6bbb89989388f3b","dumps/main/attachments/search-config-icons/87ac4cde-f581-398b-1e32-eb4079183b36":"33ca72f1eac56793d1fd811189cedef98004a067c85b1143083b564814a4b0db","dumps/main/attachments/search-config-icons/87ac4cde-f581-398b-1e32-eb4079183b36.meta.json":"d97eca8063cc17b99c81c55d4ff121d765c793e006ed252fec5f9539bd0fc339","dumps/main/attachments/search-config-icons/8831ce10-b1e4-6eb4-4975-83c67457288e":"ca3cc8786977f6ffeb0546ff8f3bb2b7fd240d1956fbf86777dbf0e8bec9c03b","dumps/main/attachments/search-config-icons/8831ce10-b1e4-6eb4-4975-83c67457288e.meta.json":"45274d848d1f6d398563bb46a2bfa3eee40ff16a5dbf0bbc8904db442f80702c","dumps/main/attachments/search-config-icons/890de5c4-0941-a116-473a-5d240e79497a":"6ba1f0fd1d12014cab32f74daab24dfa16fb26613ace20a1e595267621038a07","dumps/main/attachments/search-config-icons/890de5c4-0941-a116-473a-5d240e79497a.meta.json":"107547059360c3658dcf187a546ffb52bb23fa385e1338151043bebe82bbf640","dumps/main/attachments/search-config-icons/8abb10a7-212f-46b5-a7b4-244f414e3810":"f8780adb4d7b28f2f881db4ca7b697d8fc916cd9fa834ccc445fe7d4b72a6cc7","dumps/main/attachments/search-config-icons/8abb10a7-212f-46b5-a7b4-244f414e3810.meta.json":"5401603c7abbc6ca5bdddb8f9cca7eee2e26e5721cc73f23d95f600d5421d431","dumps/main/attachments/search-config-icons/91a9672d-e945-8e1e-0996-aefdb0190716":"5d53ef1866a08cc29011f5f2a9ce99bbf37cf42e80de7f0e8cc30d13337e8187","dumps/main/attachments/search-config-icons/91a9672d-e945-8e1e-0996-aefdb0190716.meta.json":"4e8ea36e3d659eb22ac7c86498003ca8885bab9c40685bb8ca7796a8230201da","dumps/main/attachments/search-config-icons/94a84724-c30f-4767-ba42-01cc37fc31a4":"98dca7e24cad0a1be96ef2c323e9759beb63c72440756f887e2482d9ce8e8969","dumps/main/attachments/search-config-icons/94a84724-c30f-4767-ba42-01cc37fc31a4.meta.json":"1070966901fe9db82b71bfa74ddeedd4f23ab2ed1eddaf201634e06a604e6006","dumps/main/attachments/search-config-icons/95ed201d-4ab8-4cb8-831d-454f53cab0f8":"3426b5100a6bdb45f8039f0c71a6b68193750ba7bae5b36e5ed31b2b7f372cda","dumps/main/attachments/search-config-icons/95ed201d-4ab8-4cb8-831d-454f53cab0f8.meta.json":"3447cd050619c1d2e5859147ab894a43da75235a580219306d8629e28a7a3eb5","dumps/main/attachments/search-config-icons/96327a73-c433-5eb4-a16d-b090cadfb80b":"ca6e972004f62355c1ea97656bc2328e1643971bdecab9c6b563d45593b8122e","dumps/main/attachments/search-config-icons/96327a73-c433-5eb4-a16d-b090cadfb80b.meta.json":"c4e3c9e6426e6f35410c287eef95b3e2134e54409e462f02dd440876c06b1bb4","dumps/main/attachments/search-config-icons/9802e63d-05ec-48ba-93f9-746e0981ad98":"6b1b073183eb0012daea0dce351a94d395c8a0b531b610e56eac52b3d1d1da0e","dumps/main/attachments/search-config-icons/9802e63d-05ec-48ba-93f9-746e0981ad98.meta.json":"cceb55c68db8dddd23d064364a281e982069bfe2bb55eba7d282fffcec2aa89f","dumps/main/attachments/search-config-icons/a06db97d-1210-ea2e-5474-0e2f7d295bfd":"617dec5d635efb0a12d0de935c6999ef0249f4a63c62bdcb96551518bc3d1812","dumps/main/attachments/search-config-icons/a06db97d-1210-ea2e-5474-0e2f7d295bfd.meta.json":"06cf576ca882bd7c2d54c18329e21e5b1a9cb7732d4954b52cbfa52979a67765","dumps/main/attachments/search-config-icons/a06dc3fd-4bdb-41f3-2ebc-4cbed06a9bd3":"d994f806b1e4225b50be5ab681b2cecf845cc216a19a432d878cea3cb815bafd","dumps/main/attachments/search-config-icons/a06dc3fd-4bdb-41f3-2ebc-4cbed06a9bd3.meta.json":"67524e18799023a017c7d9db1b9ba5c9cc3090d20f8154449a8f44ba22719104","dumps/main/attachments/search-config-icons/a2c7d4e9-f770-51e1-0963-3c2c8401631d":"1bf68aca7bfc75ca8485c3dac9a1daa13c1a3eb480688c32262096af6076adfa","dumps/main/attachments/search-config-icons/a2c7d4e9-f770-51e1-0963-3c2c8401631d.meta.json":"4ab103bba0f8fde581c3950c6c08cfcf6786104d8cbcba240499308f26958d04","dumps/main/attachments/search-config-icons/a83f24e4-602c-47bd-930c-ad0947ee1adf":"66612f999921d892645c8a2b37aa5dad17b134e7fdaed375a683baec7fc10697","dumps/main/attachments/search-config-icons/a83f24e4-602c-47bd-930c-ad0947ee1adf.meta.json":"f985ffbde6cf6ef972b6798c9336922dcfa29ca9a31e3aa4fae1962e069bdb0c","dumps/main/attachments/search-config-icons/b64f09fd-52d1-c48e-af23-4ce918e7bf3b":"c3e8300801c5c585662f14fd8e819d635efd9830783dc3c631212927866e9898","dumps/main/attachments/search-config-icons/b64f09fd-52d1-c48e-af23-4ce918e7bf3b.meta.json":"f7fd846d6717131e75865f8f5ed562e88f40be3dcf1603f2660b425dedabc7d1","dumps/main/attachments/search-config-icons/b882b24d-1776-4ef9-9016-0bdbd935eda3":"076352591c7077af4af5771918f80b5da9c6bf479327cc68390abdb158f3ec03","dumps/main/attachments/search-config-icons/b882b24d-1776-4ef9-9016-0bdbd935eda3.meta.json":"229139bca53bc63bd59b8f261f36c11fbe76b2b45dfeac2580261cf290c41365","dumps/main/attachments/search-config-icons/b8ca5a94-8fff-27ad-6e00-96e244a32e21":"1474c93e49c209aca2a2df2acb61b64574805106bead6edebd67287de21920e0","dumps/main/attachments/search-config-icons/b8ca5a94-8fff-27ad-6e00-96e244a32e21.meta.json":"6fd72c11afb4249d0166d8d98c552ee02d73c0e07f0578bfd3d7e67d70bcaee3","dumps/main/attachments/search-config-icons/b9424309-f601-4a69-98ca-ca68e65633e6":"601d72e7abde5ec864b3d8ca0031896f769107670b84c66053062481a56d8665","dumps/main/attachments/search-config-icons/b9424309-f601-4a69-98ca-ca68e65633e6.meta.json":"f299a7d56c5552fc592c66073d3e1e1d16ce4a99e935dcc0cad7dafcad6b9e3b","dumps/main/attachments/search-config-icons/c411adc1-9661-4fb5-a4c1-8cfe74911943":"150765e8e9b985ba5b820ac9b8e7623023d5a0e24f94663d5e9203d8d7598059","dumps/main/attachments/search-config-icons/c411adc1-9661-4fb5-a4c1-8cfe74911943.meta.json":"c5cc89d5f24ef1fa40b1c47c2e97eaeb01439b8d3b186b9c2fe716c94ead30f2","dumps/main/attachments/search-config-icons/cbf9e891-d079-2b28-5617-283450d463dd":"5b2c34b3c4e8dd898b664dba6c3786e2ff9869eff55d673aa48361f11325ed07","dumps/main/attachments/search-config-icons/cbf9e891-d079-2b28-5617-283450d463dd.meta.json":"b757806fd1b922d81bbecab94c73d3db98cfc2aa2791a4d5137112f795a732ee","dumps/main/attachments/search-config-icons/d87f251c-3e12-a8bf-e2d0-afd43d36c5f9":"865d76c8175a8f11dedc93f0bc212242a97a8a76adac870e8249368cecc81402","dumps/main/attachments/search-config-icons/d87f251c-3e12-a8bf-e2d0-afd43d36c5f9.meta.json":"22594c8870cbabe5fc5d2637509235202502661b466e9e37c5878716f323a34f","dumps/main/attachments/search-config-icons/db0e1627-ae89-4c25-8944-a9481d8512d9":"97a68f0b948b68bbf389a9ef43e2fe6c31ff8dc7889c939fdfdea79378576c67","dumps/main/attachments/search-config-icons/db0e1627-ae89-4c25-8944-a9481d8512d9.meta.json":"1eccc999dcd377af84cf63ed60b7ef23d5d4b936a1e465d12349a5366b1b012d","dumps/main/attachments/search-config-icons/e02f23df-8d48-2b1b-3b5c-6dd27302c61c":"247aa26993083705ce99a8e5612cdf262aca98cde86ba19afc964329ba95986a","dumps/main/attachments/search-config-icons/e02f23df-8d48-2b1b-3b5c-6dd27302c61c.meta.json":"06fc893d29cf406519611da9d1993a13bd9134192940c12bf64536ea571db4f0","dumps/main/attachments/search-config-icons/e718e983-09aa-e8f6-b25f-cd4b395d4785":"809697f48848e7c3638d5f3e0b224ea60b3800504e7bd8417854d55989b85196","dumps/main/attachments/search-config-icons/e718e983-09aa-e8f6-b25f-cd4b395d4785.meta.json":"0d9baef39747776500e5b83e72cd9d901fc09ac08247368dd2117bb4ec011f54","dumps/main/attachments/search-config-icons/e7547f62-187b-b641-d462-e54a3f813d9a":"c971ee33b8c0a57349669d957bf73070b0632b128c94748e845b57d5e15221a4","dumps/main/attachments/search-config-icons/e7547f62-187b-b641-d462-e54a3f813d9a.meta.json":"8ec4f6a7826966f2ff82632ef527366db3452ebc40c90a557602111f0ea956c9","dumps/main/attachments/search-config-icons/eb62e768-151b-45d1-9fe5-9e1d2a5991c5":"aa46b3d1ed8557e5bc7e71988cc6c46b00363b890d2a781973f9dc9073f8dd31","dumps/main/attachments/search-config-icons/eb62e768-151b-45d1-9fe5-9e1d2a5991c5.meta.json":"a06682b589df8dd63b1f25c01630ead55a89217f72c0bc04b391829af3fef59f","dumps/main/attachments/search-config-icons/f312610a-ebfb-a106-ea92-fd643c5d3636":"91d17ba44192a6430ffdb447ff3a11533ef964628f67c13480cc9470212d3d65","dumps/main/attachments/search-config-icons/f312610a-ebfb-a106-ea92-fd643c5d3636.meta.json":"ce26ab2382a7a67a55688330dd74127b4a980610f4030bde8eaaa20b81306559","dumps/main/attachments/search-config-icons/fa0fc42c-d91d-fca7-34eb-806ff46062dc":"6da5620880159634213e197fafca1dde0272153be3e4590818533fab8d040770","dumps/main/attachments/search-config-icons/fa0fc42c-d91d-fca7-34eb-806ff46062dc.meta.json":"0c3c0eb832be884f25186395b8bf08cdbe0a6e2845b9e55e7cbea5d0f183ed7d","dumps/main/attachments/search-config-icons/fca3e3ee-56cd-f474-dc31-307fd24a891d":"c4d88cfa5262f6d2cf76b167281d25821c9e1770684b739ed6ad3cf7277a121b","dumps/main/attachments/search-config-icons/fca3e3ee-56cd-f474-dc31-307fd24a891d.meta.json":"a40c37a5150e3745849f67305fe2fe1e06ef1c3901f6dc604a8e3f6c94e7b624","dumps/main/attachments/search-config-icons/fe75ce3f-1545-400c-b28c-ad771054e69f":"3a9d06951c7c9d2c19cd00533a760b0f8755b1e2e718af81c710297d030fbe44","dumps/main/attachments/search-config-icons/fe75ce3f-1545-400c-b28c-ad771054e69f.meta.json":"3f353e083d7a885f6d59d36c9276a2d325686a533cf8c502cd41a10172e763ea","dumps/main/attachments/search-config-icons/fed4f021-ff3e-942a-010e-afa43fda2136":"d7fdfd971d874f2ec6f209df6f6b8173d126cd3f7a25daacb94de4259efbcf16","dumps/main/attachments/search-config-icons/fed4f021-ff3e-942a-010e-afa43fda2136.meta.json":"740f77dcc93ece89fd55557baf399a4464373c81154b0a9758b8622f6c458253","dumps/main/regions.json":"e8990158373f82d3f89fed5089cf29e4177cc85904479128728e05025e9a0c0c","dumps/main/search-config-icons.json":"76955459bdcd7ea46a67737309ed65c3497b9dd71c66a8f978aa3448001ad33b","dumps/main/search-config-v2.json":"299a8f3f0b9a7ba4330fc8bd8e1b2ce65804cdb452b86d7e40ec30a1bd02d6a2","dumps/main/search-telemetry-v2.json":"b0f3ba5c0b4d9051e87b84ebb90abf4477a56b1999c033deca3ce3c8e4a3f7f9","src/cache.rs":"c6179802017b43885136e7d64004890cc13e8c2d4742e04073cf404b578f63db","src/client.rs":"04e47a0d01215dc83ac234b4f740b63a53daa0431eba2b8a4702a95e18a95737","src/config.rs":"e042741248e7e501b4a97745bebb681006a45e0cc243225a05b9fca2f8126e82","src/context.rs":"43bab81026b6f1a2509d129e806fffd09ba80110d656798a02589985017a3c21","src/error.rs":"80aeb1093682acea7350f4876e1501d70c5daa822d26babace80d004e2a34bce","src/jexl_filter.rs":"48a9d960e05dae444421f7c4ceeb45eab656f03f1e7071215c8e8d39aab56b54","src/lib.rs":"5555139a8fcb77f91e67946ec4284e1e945a4de1f97b1b95112bca36b846a61a","src/macros.rs":"6b06d0ba42ee95235bfd71bac1a0eed02f60c894775ebee64165648b10e932c4","src/schema.rs":"348e0d5ad1840aaae796b537d21381ef91bd75be262138bfec376d9f88d205b3","src/service.rs":"a02cd02f251b73e160c019f8144d2ad9b4a17da525c492b4450ecfa126241cb7","src/signatures.rs":"baa2dae76abd8166158fea4676e67e17c17b65af6968de52768350409dbd7092","src/storage.rs":"c33dd92914770e96d3d44dbb9e95f512ce54261710a42c7cf4a896be348c529e","uniffi.toml":"bd7cc0e7c1981f53938f429c4f2541ac454ed4160a8a0b4670659e38acd23ee5"},"package":null} \ No newline at end of file diff --git a/third_party/rust/remote_settings/src/client.rs b/third_party/rust/remote_settings/src/client.rs index da6ed475b9d5..35279410c283 100644 --- a/third_party/rust/remote_settings/src/client.rs +++ b/third_party/rust/remote_settings/src/client.rs @@ -294,6 +294,12 @@ impl RemoteSettingsClient { }) } + pub fn get_last_modified_timestamp(&self) -> Result> { + let mut inner = self.inner.lock(); + let collection_url = inner.api_client.collection_url(); + inner.storage.get_last_modified_timestamp(&collection_url) + } + /// Synchronizes the local collection with the remote server by performing the following steps: /// 1. Fetches the last modified timestamp of the collection from local storage. /// 2. Fetches the changeset from the remote server based on the last modified timestamp. @@ -507,9 +513,15 @@ impl RemoteSettingsClient { Self::new_from_parts(collection_name, storage, jexl_filter, api_client) } - pub fn update_config(&self, server_url: BaseUrl, bucket_name: String) -> Result<()> { + pub fn update_config( + &self, + server_url: BaseUrl, + bucket_name: String, + context: Option, + ) -> Result<()> { let mut inner = self.inner.lock(); inner.api_client = ViaductApiClient::new(server_url, &bucket_name, &self.collection_name); + inner.jexl_filter = JexlFilter::new(context); inner.storage.empty() } } @@ -554,12 +566,12 @@ impl ViaductApiClient { fn make_request(&mut self, url: Url) -> Result { log::trace!("make_request: {url}"); - self.ensure_no_backoff()?; + self.remote_state.ensure_no_backoff()?; let req = Request::get(url); let resp = req.send()?; - self.handle_backoff_hint(&resp)?; + self.remote_state.handle_backoff_hint(&resp)?; if resp.is_success() { Ok(resp) @@ -570,46 +582,6 @@ impl ViaductApiClient { ))) } } - - fn ensure_no_backoff(&mut self) -> Result<()> { - if let BackoffState::Backoff { - observed_at, - duration, - } = self.remote_state.backoff - { - let elapsed_time = observed_at.elapsed(); - if elapsed_time >= duration { - self.remote_state.backoff = BackoffState::Ok; - } else { - let remaining = duration - elapsed_time; - return Err(Error::BackoffError(remaining.as_secs())); - } - } - Ok(()) - } - - fn handle_backoff_hint(&mut self, response: &Response) -> Result<()> { - let extract_backoff_header = |header| -> Result { - Ok(response - .headers - .get_as::(header) - .transpose() - .unwrap_or_default() // Ignore number parsing errors. - .unwrap_or(0)) - }; - // In practice these two headers are mutually exclusive. - let backoff = extract_backoff_header(HEADER_BACKOFF)?; - let retry_after = extract_backoff_header(HEADER_RETRY_AFTER)?; - let max_backoff = backoff.max(retry_after); - - if max_backoff > 0 { - self.remote_state.backoff = BackoffState::Backoff { - observed_at: Instant::now(), - duration: Duration::from_secs(max_backoff), - }; - } - Ok(()) - } } impl ApiClient for ViaductApiClient { @@ -803,14 +775,14 @@ impl Client { fn make_request(&self, url: Url) -> Result { let mut current_remote_state = self.remote_state.lock(); - self.ensure_no_backoff(&mut current_remote_state.backoff)?; + current_remote_state.ensure_no_backoff()?; drop(current_remote_state); let req = Request::get(url); let resp = req.send()?; let mut current_remote_state = self.remote_state.lock(); - self.handle_backoff_hint(&resp, &mut current_remote_state.backoff)?; + current_remote_state.handle_backoff_hint(&resp)?; if resp.is_success() { Ok(resp) @@ -821,50 +793,6 @@ impl Client { ))) } } - - fn ensure_no_backoff(&self, current_state: &mut BackoffState) -> Result<()> { - if let BackoffState::Backoff { - observed_at, - duration, - } = *current_state - { - let elapsed_time = observed_at.elapsed(); - if elapsed_time >= duration { - *current_state = BackoffState::Ok; - } else { - let remaining = duration - elapsed_time; - return Err(Error::BackoffError(remaining.as_secs())); - } - } - Ok(()) - } - - fn handle_backoff_hint( - &self, - response: &Response, - current_state: &mut BackoffState, - ) -> Result<()> { - let extract_backoff_header = |header| -> Result { - Ok(response - .headers - .get_as::(header) - .transpose() - .unwrap_or_default() // Ignore number parsing errors. - .unwrap_or(0)) - }; - // In practice these two headers are mutually exclusive. - let backoff = extract_backoff_header(HEADER_BACKOFF)?; - let retry_after = extract_backoff_header(HEADER_RETRY_AFTER)?; - let max_backoff = backoff.max(retry_after); - - if max_backoff > 0 { - *current_state = BackoffState::Backoff { - observed_at: Instant::now(), - duration: Duration::from_secs(max_backoff), - }; - } - Ok(()) - } } /// Stores all the endpoints for a Remote Settings server @@ -1027,6 +955,48 @@ impl Default for RemoteState { } } +impl RemoteState { + pub fn handle_backoff_hint(&mut self, response: &Response) -> Result<()> { + let extract_backoff_header = |header| -> Result { + Ok(response + .headers + .get_as::(header) + .transpose() + .unwrap_or_default() // Ignore number parsing errors. + .unwrap_or(0)) + }; + // In practice these two headers are mutually exclusive. + let backoff = extract_backoff_header(HEADER_BACKOFF)?; + let retry_after = extract_backoff_header(HEADER_RETRY_AFTER)?; + let max_backoff = backoff.max(retry_after); + + if max_backoff > 0 { + self.backoff = BackoffState::Backoff { + observed_at: Instant::now(), + duration: Duration::from_secs(max_backoff), + }; + } + Ok(()) + } + + pub fn ensure_no_backoff(&mut self) -> Result<()> { + if let BackoffState::Backoff { + observed_at, + duration, + } = self.backoff + { + let elapsed_time = observed_at.elapsed(); + if elapsed_time >= duration { + self.backoff = BackoffState::Ok; + } else { + let remaining = duration - elapsed_time; + return Err(Error::BackoffError(remaining.as_secs())); + } + } + Ok(()) + } +} + /// Used in handling backoff responses from the Remote Settings server. #[derive(Clone, Copy, Debug)] pub(crate) enum BackoffState { @@ -2040,6 +2010,76 @@ mod jexl_tests { Some(vec![]) ); } + + #[test] + fn test_update_jexl_context() { + let mut api_client = MockApiClient::new(); + let records = vec![RemoteSettingsRecord { + id: "record-0001".into(), + last_modified: 100, + deleted: false, + attachment: None, + fields: serde_json::json!({ + "filter_expression": "env.country == \"US\"" + }) + .as_object() + .unwrap() + .clone(), + }]; + let changeset = ChangesetResponse { + changes: records.clone(), + timestamp: 42, + metadata: CollectionMetadata::default(), + }; + api_client.expect_collection_url().returning(|| { + "http://rs.example.com/v1/buckets/main/collections/test-collection".into() + }); + api_client.expect_fetch_changeset().returning({ + let changeset = changeset.clone(); + move |timestamp| { + assert_eq!(timestamp, None); + Ok(changeset.clone()) + } + }); + api_client.expect_is_prod_server().returning(|| Ok(false)); + + let context = RemoteSettingsContext { + country: Some("US".to_string()), + ..Default::default() + }; + + let mut storage = Storage::new(":memory:".into()); + let _ = storage.insert_collection_content( + "http://rs.example.com/v1/buckets/main/collections/test-collection", + &records, + 42, + CollectionMetadata::default(), + ); + + let rs_client = RemoteSettingsClient::new_from_parts( + "test-collection".into(), + storage, + JexlFilter::new(Some(context)), + api_client, + ); + + assert_eq!( + rs_client.get_records(false).expect("Error getting records"), + Some(records) + ); + + // We can't call `update_config` directly, since that only works with a real API client. + // Instead, just execute the code from that method that updates the JEXL filter. + rs_client.inner.lock().jexl_filter = JexlFilter::new(Some(RemoteSettingsContext { + country: Some("UK".to_string()), + ..Default::default() + })); + + assert_eq!( + rs_client.get_records(false).expect("Error getting records"), + Some(vec![]) + ); + } } #[cfg(feature = "signatures")] diff --git a/third_party/rust/remote_settings/src/config.rs b/third_party/rust/remote_settings/src/config.rs index a4c491692e9c..fec12e62df3c 100644 --- a/third_party/rust/remote_settings/src/config.rs +++ b/third_party/rust/remote_settings/src/config.rs @@ -165,4 +165,8 @@ impl BaseUrl { // error for cannot-be-a-base URLs. self.url.path_segments_mut().unwrap() } + + pub fn query_pairs_mut(&mut self) -> url::form_urlencoded::Serializer<'_, url::UrlQuery<'_>> { + self.url.query_pairs_mut() + } } diff --git a/third_party/rust/remote_settings/src/service.rs b/third_party/rust/remote_settings/src/service.rs index 8f2c3f052164..5c4e7f2e4d6c 100644 --- a/third_party/rust/remote_settings/src/service.rs +++ b/third_party/rust/remote_settings/src/service.rs @@ -3,16 +3,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::{ - collections::HashSet, + collections::{HashMap, HashSet}, sync::{Arc, Weak}, }; use camino::Utf8PathBuf; use parking_lot::Mutex; +use serde::Deserialize; +use viaduct::Request; use crate::{ - config::BaseUrl, storage::Storage, RemoteSettingsClient, RemoteSettingsConfig2, - RemoteSettingsContext, RemoteSettingsServer, Result, + client::RemoteState, config::BaseUrl, error::Error, storage::Storage, RemoteSettingsClient, + RemoteSettingsConfig2, RemoteSettingsContext, RemoteSettingsServer, Result, }; /// Internal Remote settings service API @@ -25,6 +27,7 @@ struct RemoteSettingsServiceInner { base_url: BaseUrl, bucket_name: String, app_context: Option, + remote_state: RemoteState, /// Weakrefs for all clients that we've created. Note: this stores the /// top-level/public `RemoteSettingsClient` structs rather than `client::RemoteSettingsClient`. /// The reason for this is that we return Arcs to the public struct to the foreign code, so we @@ -51,6 +54,7 @@ impl RemoteSettingsService { base_url, bucket_name, app_context: config.app_context, + remote_state: RemoteState::default(), clients: vec![], }), } @@ -81,13 +85,30 @@ impl RemoteSettingsService { // Make sure we only sync each collection once, even if there are multiple clients let mut synced_collections = HashSet::new(); - // TODO: poll the server using `/buckets/monitor/collections/changes/changeset` to fetch - // the current timestamp for all collections. That way we can avoid fetching collections - // we know haven't changed and also pass the `?_expected{ts}` param to the server. + let mut inner = self.inner.lock(); + let changes = inner.fetch_changes()?; + let change_map: HashMap<_, _> = changes + .changes + .iter() + .map(|c| ((c.collection.as_str(), &c.bucket), c.last_modified)) + .collect(); + let bucket_name = inner.bucket_name.clone(); - for client in self.inner.lock().active_clients() { - if synced_collections.insert(client.collection_name()) { - client.internal.sync()?; + for client in inner.active_clients() { + let client = &client.internal; + let collection_name = client.collection_name(); + if let Some(client_last_modified) = client.get_last_modified_timestamp()? { + if let Some(server_last_modified) = change_map.get(&(collection_name, &bucket_name)) + { + if client_last_modified != *server_last_modified { + log::trace!("skipping up-to-date collection: {collection_name}"); + continue; + } + } + } + if synced_collections.insert(collection_name.to_string()) { + log::trace!("syncing collection: {collection_name}"); + client.sync()?; } } Ok(synced_collections.into_iter().collect()) @@ -105,12 +126,15 @@ impl RemoteSettingsService { let bucket_name = config.bucket_name.unwrap_or_else(|| String::from("main")); let mut inner = self.inner.lock(); for client in inner.active_clients() { - client - .internal - .update_config(base_url.clone(), bucket_name.clone())?; + client.internal.update_config( + base_url.clone(), + bucket_name.clone(), + config.app_context.clone(), + )?; } inner.base_url = base_url; inner.bucket_name = bucket_name; + inner.app_context = config.app_context; Ok(()) } } @@ -131,4 +155,52 @@ impl RemoteSettingsServiceInner { }); active_clients } + + fn fetch_changes(&mut self) -> Result { + let mut url = self.base_url.clone(); + url.path_segments_mut() + .push("buckets") + .push("monitor") + .push("collections") + .push("changes") + .push("changeset"); + // For now, always use `0` for the expected value. This means we'll get updates based on + // the default TTL of 1 hour. + // + // Eventually, we should add support for push notifications and use the timestamp from the + // notification. + url.query_pairs_mut().append_pair("_expected", "0"); + let url = url.into_inner(); + log::trace!("make_request: {url}"); + self.remote_state.ensure_no_backoff()?; + + let req = Request::get(url); + let resp = req.send()?; + + self.remote_state.handle_backoff_hint(&resp)?; + + if resp.is_success() { + Ok(resp.json()?) + } else { + Err(Error::ResponseError(format!( + "status code: {}", + resp.status + ))) + } + } +} + +/// Data from the changes endpoint +/// +/// https://remote-settings.readthedocs.io/en/latest/client-specifications.html#endpoints +#[derive(Debug, Deserialize)] +struct Changes { + changes: Vec, +} + +#[derive(Debug, Deserialize)] +struct ChangesCollection { + collection: String, + bucket: String, + last_modified: u64, } diff --git a/third_party/rust/search/.cargo-checksum.json b/third_party/rust/search/.cargo-checksum.json index 130024d66932..4cd2dd8ccc0b 100644 --- a/third_party/rust/search/.cargo-checksum.json +++ b/third_party/rust/search/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"ac0ac2103375f1c3906436b53627f88515da74864dd3f86ebb2a18952ba72b30","README.md":"d59a6ad6232a86a7bd3632ca62c44ba8bd466615c5d47ce0d836b270bac5562c","android/build.gradle":"e3b617d653aa0221f2229bb16c2fd635003fe82d0274c4b9a6f2d8154851985a","android/proguard-rules.pro":"1cf8c57e8f79c250b0af9c1a5a4edad71a5c348a79ab70243b6bae086c150ad2","android/src/main/AndroidManifest.xml":"0a05039a6124be0296764c2b0f41e863b5538d75e6164dd9ae945b59d983c318","src/configuration_overrides_types.rs":"220a5e12ee3deb309a1571c5820ec5132c959f56667c4c48f997bbe2be0c7eeb","src/configuration_types.rs":"a495199fc19cf9ce1aefe41058a38a0ffad4eb6f719fac11c11dcc3cfe4f234a","src/environment_matching.rs":"5a1ade9a900942c62e8740597528a34df6fb3fdb72c801a647a3386acd42fcc8","src/error.rs":"d3c1eda7a8da15446a321139d4d29dd9ceee99e916519690d5eb2d45ed628598","src/filter.rs":"88a39e594397708db888726cac00ad1e5b4a892c5a121c96cc11d20f41851b45","src/lib.rs":"9c83780a74048fbbc7bbba5706067b9dc5db2ae25a0cc751687d2738903723b4","src/selector.rs":"e065e05aec54e01fd106d453ece2cfee72793c8a47569cc32ac016aef3ac265b","src/sort_helpers.rs":"12d41c34fc2ca5387edc248189335fb11702618b7253f8b486f0c84576084faa","src/types.rs":"8721ccf9443b28435ba211d5705f4a6c82eb0354ba1d100045438800c7e2bf9a","uniffi.toml":"96f1cd569483ff59e3c73852f085a03889fa24a2ce20ff7a3003799a9f48a51e"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"ac0ac2103375f1c3906436b53627f88515da74864dd3f86ebb2a18952ba72b30","README.md":"d59a6ad6232a86a7bd3632ca62c44ba8bd466615c5d47ce0d836b270bac5562c","android/build.gradle":"e3b617d653aa0221f2229bb16c2fd635003fe82d0274c4b9a6f2d8154851985a","android/proguard-rules.pro":"1cf8c57e8f79c250b0af9c1a5a4edad71a5c348a79ab70243b6bae086c150ad2","android/src/main/AndroidManifest.xml":"0a05039a6124be0296764c2b0f41e863b5538d75e6164dd9ae945b59d983c318","src/configuration_overrides_types.rs":"220a5e12ee3deb309a1571c5820ec5132c959f56667c4c48f997bbe2be0c7eeb","src/configuration_types.rs":"a495199fc19cf9ce1aefe41058a38a0ffad4eb6f719fac11c11dcc3cfe4f234a","src/environment_matching.rs":"5a1ade9a900942c62e8740597528a34df6fb3fdb72c801a647a3386acd42fcc8","src/error.rs":"d3c1eda7a8da15446a321139d4d29dd9ceee99e916519690d5eb2d45ed628598","src/filter.rs":"88a39e594397708db888726cac00ad1e5b4a892c5a121c96cc11d20f41851b45","src/lib.rs":"9c83780a74048fbbc7bbba5706067b9dc5db2ae25a0cc751687d2738903723b4","src/selector.rs":"6585b4d487179353f4dc8bae396cc18a97e5fcde58f6afa09373cd04510daa03","src/sort_helpers.rs":"5bcae57c230e1d1123d3c5be1ae38b481c6a1fc5096bc0fdede6f7a7c8d27032","src/types.rs":"8721ccf9443b28435ba211d5705f4a6c82eb0354ba1d100045438800c7e2bf9a","uniffi.toml":"96f1cd569483ff59e3c73852f085a03889fa24a2ce20ff7a3003799a9f48a51e"},"package":null} \ No newline at end of file diff --git a/third_party/rust/search/src/selector.rs b/third_party/rust/search/src/selector.rs index cf453e9d7750..303c297e4149 100644 --- a/third_party/rust/search/src/selector.rs +++ b/third_party/rust/search/src/selector.rs @@ -1592,7 +1592,7 @@ mod tests { "recordType": "engine", "identifier": "b-engine", "base": { - "name": "b-engine", + "name": "First Alphabetical", "classification": "general", "urls": { "search": { @@ -1611,7 +1611,7 @@ mod tests { "recordType": "engine", "identifier": "a-engine", "base": { - "name": "a-engine", + "name": "Last Alphabetical", "classification": "general", "urls": { "search": { @@ -1731,10 +1731,10 @@ mod tests { "default-engine".to_string(), "default-private-engine".to_string(), "after-defaults".to_string(), - "a-engine".to_string(), "b-engine".to_string(), + "a-engine".to_string(), ], - "Should order the default engine first, default private engine second, and the rest of the engines based on order hint then alphabetically." + "Should order the default engine first, default private engine second, and the rest of the engines based on order hint then alphabetically by name." ); let starts_with_wiki_config = Arc::clone(&selector).set_search_config( @@ -1919,6 +1919,18 @@ mod tests { selector } + fn mock_changes_endpoint() -> mockito::Mock { + mock( + "GET", + "/v1/buckets/monitor/collections/changes/changeset?_expected=0", + ) + .with_body(response_body_changes()) + .with_status(200) + .with_header("content-type", "application/json") + .with_header("etag", "\"1000\"") + .create() + } + fn response_body() -> String { json!({ "metadata": { @@ -2021,6 +2033,20 @@ mod tests { .to_string() } + fn response_body_changes() -> String { + json!({ + "timestamp": 1000, + "changes": [ + { + "collection": "search-config-v2", + "bucket": "main", + "last_modified": 1000, + } + ], + }) + .to_string() + } + fn response_body_locales() -> String { json!({ "metadata": { @@ -2129,6 +2155,7 @@ mod tests { #[test] fn test_remote_settings_empty_search_config_records_throws_error() { + let changes_mock = mock_changes_endpoint(); let m = mock( "GET", "/v1/buckets/main/collections/search-config-v2/changeset?_expected=0", @@ -2168,11 +2195,13 @@ mod tests { .unwrap_err() .to_string() .contains("No search config v2 records received from remote settings")); + changes_mock.expect(1).assert(); m.expect(1).assert(); } #[test] fn test_remote_settings_search_config_records_is_none_throws_error() { + let changes_mock = mock_changes_endpoint(); let m1 = mock( "GET", "/v1/buckets/main/collections/search-config-v2/changeset?_expected=0", @@ -2197,11 +2226,13 @@ mod tests { .unwrap_err() .to_string() .contains("No search config v2 records received from remote settings")); + changes_mock.expect(1).assert(); m1.expect(1).assert(); } #[test] fn test_remote_settings_empty_search_config_overrides_filtered_without_error() { + let changes_mock = mock_changes_endpoint(); let m1 = mock( "GET", "/v1/buckets/main/collections/search-config-v2/changeset?_expected=0", @@ -2248,12 +2279,14 @@ mod tests { "Should have filtered the configuration using an empty search config overrides without causing an error. {:?}", result ); + changes_mock.expect(1).assert(); m1.expect(1).assert(); m2.expect(1).assert(); } #[test] fn test_remote_settings_search_config_overrides_records_is_none_throws_error() { + let changes_mock = mock_changes_endpoint(); let m1 = mock( "GET", "/v1/buckets/main/collections/search-config-v2/changeset?_expected=0", @@ -2288,12 +2321,14 @@ mod tests { .unwrap_err() .to_string() .contains("No search config overrides v2 records received from remote settings")); + changes_mock.expect(1).assert(); m1.expect(1).assert(); m2.expect(1).assert(); } #[test] fn test_filter_with_remote_settings_overrides() { + let changes_mock = mock_changes_endpoint(); let m1 = mock( "GET", "/v1/buckets/main/collections/search-config-v2/changeset?_expected=0", @@ -2355,12 +2390,15 @@ mod tests { test_engine.clone(), "Should have applied the overrides to the matching engine" ); + changes_mock.expect(1).assert(); m1.expect(1).assert(); m2.expect(1).assert(); } #[test] fn test_filter_with_remote_settings() { + let changes_mock = mock_changes_endpoint(); + let m = mock( "GET", "/v1/buckets/main/collections/search-config-v2/changeset?_expected=0", @@ -2468,11 +2506,13 @@ mod tests { }, "Should have selected the private default engine for the matching specific default" ); + changes_mock.expect(1).assert(); m.expect(1).assert(); } #[test] fn test_filter_with_remote_settings_negotiate_locales() { + let changes_mock = mock_changes_endpoint(); let m = mock( "GET", "/v1/buckets/main/collections/search-config-v2/changeset?_expected=0", @@ -2551,6 +2591,7 @@ mod tests { }, "Should have selected the en-us engine when given another english locale we don't support" ); + changes_mock.expect(1).assert(); m.expect(1).assert(); } diff --git a/third_party/rust/search/src/sort_helpers.rs b/third_party/rust/search/src/sort_helpers.rs index a4ebc37cc18c..7d09a977624f 100644 --- a/third_party/rust/search/src/sort_helpers.rs +++ b/third_party/rust/search/src/sort_helpers.rs @@ -32,7 +32,7 @@ pub(crate) fn sort( // See Bug 1945295: https://bugzilla.mozilla.org/show_bug.cgi?id=1945295 // If order is equal and order_hint is None for both, fall back to alphabetical sorting if order == std::cmp::Ordering::Equal { - return a.identifier.cmp(&b.identifier); + return a.name.cmp(&b.name); } order @@ -76,9 +76,14 @@ mod tests { use crate::types::*; use pretty_assertions::assert_eq; - fn create_engine(engine_id: &str, order_hint: Option) -> SearchEngineDefinition { + fn create_engine( + engine_id: &str, + order_hint: Option, + name: Option<&str>, + ) -> SearchEngineDefinition { SearchEngineDefinition { identifier: engine_id.to_string(), + name: name.unwrap_or(engine_id).to_string(), order_hint, ..Default::default() } @@ -87,9 +92,9 @@ mod tests { #[test] fn test_find_engine_with_match_mut_starts_with() { let mut engines = vec![ - create_engine("wiki-ca", None), - create_engine("wiki-uk", None), - create_engine("test-engine", None), + create_engine("wiki-ca", None, None), + create_engine("wiki-uk", None, None), + create_engine("test-engine", None, None), ]; let found_engine = find_engine_with_match_mut(&mut engines, &"wiki*".to_string()); @@ -103,9 +108,9 @@ mod tests { #[test] fn test_set_engine_order_full_list() { let mut engines = vec![ - create_engine("last-engine", None), - create_engine("secondary-engine", None), - create_engine("primary-engine", None), + create_engine("last-engine", None, None), + create_engine("secondary-engine", None, None), + create_engine("primary-engine", None, None), ]; let ordered_engines_list = vec![ "primary-engine".to_string(), @@ -133,9 +138,9 @@ mod tests { #[test] fn test_set_engine_order_partial_list() { let mut engines = vec![ - create_engine("secondary-engine", None), - create_engine("primary-engine", None), - create_engine("no-order-hint-engine", None), + create_engine("secondary-engine", None, None), + create_engine("primary-engine", None, None), + create_engine("no-order-hint-engine", None, None), ]; let ordered_engines_list = vec!["primary-engine".to_string(), "secondary-engine".to_string()]; @@ -161,9 +166,9 @@ mod tests { let default_engine_id = None; let default_private_engine_id = None; let mut engines = vec![ - create_engine("c-engine", Some(3)), - create_engine("b-engine", Some(2)), - create_engine("a-engine", Some(1)), + create_engine("c-engine", Some(3), None), + create_engine("b-engine", Some(2), None), + create_engine("a-engine", Some(1), None), ]; engines.sort_by(|a, b| { sort( @@ -187,9 +192,9 @@ mod tests { let default_engine_id = None; let default_private_engine_id = None; let mut engines = vec![ - create_engine("c-engine", None), - create_engine("b-engine", None), - create_engine("a-engine", None), + create_engine("c-engine", None, None), + create_engine("b-engine", None, None), + create_engine("a-engine", None, None), ]; engines.sort_by(|a, b| { sort( @@ -213,12 +218,14 @@ mod tests { let default_engine_id = None; let default_private_engine_id = None; let mut engines = vec![ - create_engine("f-engine", None), - create_engine("e-engine", None), - create_engine("d-engine", None), - create_engine("c-engine", Some(4)), - create_engine("b-engine", Some(5)), - create_engine("a-engine", Some(6)), + // Identifiers are the opposite order to the names, so that we + // can show that we are sorting alphabetically by name. + create_engine("d-engine", None, Some("Charlie")), + create_engine("e-engine", None, Some("Beta")), + create_engine("f-engine", None, Some("Alpha")), + create_engine("c-engine", Some(4), None), + create_engine("b-engine", Some(5), None), + create_engine("a-engine", Some(6), None), ]; engines.sort_by(|a, b| { sort( @@ -231,7 +238,7 @@ mod tests { let actual_order: Vec<&str> = engines.iter().map(|e| e.identifier.as_str()).collect(); let expected_order = vec![ - "a-engine", "b-engine", "c-engine", "d-engine", "e-engine", "f-engine", + "a-engine", "b-engine", "c-engine", "f-engine", "e-engine", "d-engine", ]; assert_eq!( actual_order, expected_order, @@ -244,9 +251,9 @@ mod tests { let default_engine_id = Some("a-engine".to_string()); let default_private_engine_id = Some("b-engine".to_string()); let mut engines = vec![ - create_engine("c-engine", Some(3)), - create_engine("a-engine", Some(1)), // Default engine should be first - create_engine("b-engine", Some(2)), // Default private engine should be second + create_engine("c-engine", Some(3), None), + create_engine("a-engine", Some(1), None), // Default engine should be first + create_engine("b-engine", Some(2), None), // Default private engine should be second ]; engines.sort_by(|a, b| { sort( diff --git a/third_party/rust/suggest/.cargo-checksum.json b/third_party/rust/suggest/.cargo-checksum.json index 1e91d9b40f09..c5366b7c9bbc 100644 --- a/third_party/rust/suggest/.cargo-checksum.json +++ b/third_party/rust/suggest/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"922b2e4d85f325dbef99d5e439558a75dbfda82e1d263c2dd3bfadac9879df18","README.md":"5e28baf874b643d756228bdab345e287bf107d3182dfe6a18aafadcc4b9a3fc9","benches/benchmark_all.rs":"5909dfb1e62793afb1f2bc15b75914527a4d14fce6796307c04a309e45c0598c","metrics.yaml":"0540ab2271aeab7f07335c7ceec12acde942995f9dcb3c29070489aa61899d56","src/benchmarks/README.md":"ccee8dbddba8762d0453fa855bd6984137b224b8c019f3dd8e86a3c303f51d71","src/benchmarks/client.rs":"e5897d4e2eda06809fa6dc6db4e780b9ef266f613fb113aa6613b83f7005dd0b","src/benchmarks/geoname.rs":"00fab05cf9465cf8e22e143cde75a81885411001b240af00efda4071975d0563","src/benchmarks/ingest.rs":"1f3b5eca704c51bc8f972e7a3492a518516461e5834f97a5f7d1855a048ab16b","src/benchmarks/mod.rs":"2c9a39b7a5144674d2475f4d7d69d77c4545f9aa5f123968cb32574e76f10b1a","src/benchmarks/query.rs":"d54946063e72cf98e7f46d94665c17c66af637774c2bb50cd5798dbe63d74f3c","src/bin/debug_ingestion_sizes.rs":"ce6e810be7b3fc19e826d75b622b82cfab5a1a99397a6d0833c2c4eebff2d364","src/config.rs":"0ca876e845841bb6429862c0904c82265003f53b55aea053fac60aed278586a7","src/db.rs":"c22aab621ae8c1b70595c2073e62ff766272400be13f393327c27451bce10498","src/error.rs":"e2ef3ec0e0b2b8ecbb8f2f1717d4cb753af06913b8395d086b7643098ad100a7","src/fakespot.rs":"f501c9fe5296e7c130a9fcb532b861465717652cb5ef688230bc7a3b94df91b1","src/geoname.rs":"77376dbc7d06532a7797a93b863f150317df7f31d9200d375c8ea489ac8bee6f","src/lib.rs":"a4c0989a01a7c13184049c1f11bc7813cd3cbfb6354fcca1f5a7204e45a0dc9c","src/metrics.rs":"871f0d834efbbc9e26d61f66fa31f0021dcf41444746cd7c082f93ba9628e399","src/pocket.rs":"1316668840ec9b4ea886223921dc9d3b5a1731d1a5206c0b1089f2a6c45c1b7b","src/provider.rs":"e85d606e98a8ba37557072f91c6906b1a4d7c5586a9913bf3570ef25106b007f","src/query.rs":"66f229272c9245eb8ee0cab237071627aec599f145f64da8894bcaeb1ed7c6f9","src/rs.rs":"ad2edb0301c0510fb31b12c2f2eb65c5aee596caaee39ed5f98c1de3149afcdf","src/schema.rs":"4fe542fc6572780679854e238ee6b03baa72ca810767c935b435f79d096d3b9b","src/store.rs":"167fc224c1f56a3e3f29ec6a74091b060556993a2e010e6099b095e89df41d57","src/suggestion.rs":"bd4acd1d7f0bfd4ceebd52d44d4ea6ac639d32ef43819e217fbffaa9346b50f2","src/testing/client.rs":"47a32fd84c733001f11e8bfff94dc8c060b6b0780346dca5ddc7a5f5489c1d85","src/testing/data.rs":"6b3dad0414dd862d939f31672547e33a852056e8f891cfec9c1a9cc9fb91d54d","src/testing/mod.rs":"34120abb160a913069c3f7df03c4f52815be3461dbbf08fb0fcc4251a517ba71","src/util.rs":"52c6ec405637afa2d1a89f29fbbb7dcc341546b6deb97d326c4490bbf8713cb0","src/weather.rs":"7cc9167dcdfca49d6ad91eba6fba4d5fd49f45052f25a7fe3ad6749d3e6783fb","src/yelp.rs":"f147608a27030a0e7821d3fd050dc54a41305dc29431970733cafd59e4e5ace6","uniffi.toml":"8205e4679ac26d53e70af0f85c013fd27cda1119f4322aebf5f2b9403d45a611"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"922b2e4d85f325dbef99d5e439558a75dbfda82e1d263c2dd3bfadac9879df18","README.md":"5e28baf874b643d756228bdab345e287bf107d3182dfe6a18aafadcc4b9a3fc9","benches/benchmark_all.rs":"5909dfb1e62793afb1f2bc15b75914527a4d14fce6796307c04a309e45c0598c","metrics.yaml":"0540ab2271aeab7f07335c7ceec12acde942995f9dcb3c29070489aa61899d56","src/benchmarks/README.md":"ccee8dbddba8762d0453fa855bd6984137b224b8c019f3dd8e86a3c303f51d71","src/benchmarks/client.rs":"e5897d4e2eda06809fa6dc6db4e780b9ef266f613fb113aa6613b83f7005dd0b","src/benchmarks/geoname.rs":"00fab05cf9465cf8e22e143cde75a81885411001b240af00efda4071975d0563","src/benchmarks/ingest.rs":"1f3b5eca704c51bc8f972e7a3492a518516461e5834f97a5f7d1855a048ab16b","src/benchmarks/mod.rs":"2c9a39b7a5144674d2475f4d7d69d77c4545f9aa5f123968cb32574e76f10b1a","src/benchmarks/query.rs":"d54946063e72cf98e7f46d94665c17c66af637774c2bb50cd5798dbe63d74f3c","src/bin/debug_ingestion_sizes.rs":"ce6e810be7b3fc19e826d75b622b82cfab5a1a99397a6d0833c2c4eebff2d364","src/config.rs":"0ca876e845841bb6429862c0904c82265003f53b55aea053fac60aed278586a7","src/db.rs":"c22aab621ae8c1b70595c2073e62ff766272400be13f393327c27451bce10498","src/error.rs":"e2ef3ec0e0b2b8ecbb8f2f1717d4cb753af06913b8395d086b7643098ad100a7","src/fakespot.rs":"f501c9fe5296e7c130a9fcb532b861465717652cb5ef688230bc7a3b94df91b1","src/geoname.rs":"77376dbc7d06532a7797a93b863f150317df7f31d9200d375c8ea489ac8bee6f","src/lib.rs":"a4c0989a01a7c13184049c1f11bc7813cd3cbfb6354fcca1f5a7204e45a0dc9c","src/metrics.rs":"871f0d834efbbc9e26d61f66fa31f0021dcf41444746cd7c082f93ba9628e399","src/pocket.rs":"1316668840ec9b4ea886223921dc9d3b5a1731d1a5206c0b1089f2a6c45c1b7b","src/provider.rs":"e85d606e98a8ba37557072f91c6906b1a4d7c5586a9913bf3570ef25106b007f","src/query.rs":"66f229272c9245eb8ee0cab237071627aec599f145f64da8894bcaeb1ed7c6f9","src/rs.rs":"3e2310d069b4cbc7447c2bb625f03bb49439b218a1e8f04190015a31cde22842","src/schema.rs":"68dbdc960097cc3421247cd9f705f6dcf74c9d357b37a5824b80e37837cbf053","src/store.rs":"76e6e2134d1d0e6f8dcf30ed65fe18eb093531bdddec461ad708b1eb4ac6a01c","src/suggestion.rs":"33dd2fb8e966a72f9843476bc006c8dfb1326ed1268ad88aa91801356f2623a1","src/testing/client.rs":"47a32fd84c733001f11e8bfff94dc8c060b6b0780346dca5ddc7a5f5489c1d85","src/testing/data.rs":"ad710b31532a9540491a73cba33a54db02e85dd5ec0a4f2260430f144c3d7380","src/testing/mod.rs":"fe930be25229517831111fb6d7796ae957ec0eb1b9a190c59cf538ac41ae27f5","src/util.rs":"52c6ec405637afa2d1a89f29fbbb7dcc341546b6deb97d326c4490bbf8713cb0","src/weather.rs":"7cc9167dcdfca49d6ad91eba6fba4d5fd49f45052f25a7fe3ad6749d3e6783fb","src/yelp.rs":"1fe3b7eb6b3f7462e9758b6eb62457dfa26f7549a8290cdff7637d2fb3ffea4f","uniffi.toml":"8205e4679ac26d53e70af0f85c013fd27cda1119f4322aebf5f2b9403d45a611"},"package":null} \ No newline at end of file diff --git a/third_party/rust/suggest/src/rs.rs b/third_party/rust/suggest/src/rs.rs index a189744fb34d..6d68c3499ed5 100644 --- a/third_party/rust/suggest/src/rs.rs +++ b/third_party/rust/suggest/src/rs.rs @@ -474,6 +474,8 @@ impl ToSql for DownloadedYelpLocationSign { #[derive(Clone, Debug, Deserialize)] pub(crate) struct DownloadedYelpSuggestion { pub subjects: Vec, + #[serde(rename = "businessSubjects")] + pub business_subjects: Option>, #[serde(rename = "preModifiers")] pub pre_modifiers: Vec, #[serde(rename = "postModifiers")] diff --git a/third_party/rust/suggest/src/schema.rs b/third_party/rust/suggest/src/schema.rs index 6915fe496983..bc51ca666c5e 100644 --- a/third_party/rust/suggest/src/schema.rs +++ b/third_party/rust/suggest/src/schema.rs @@ -23,7 +23,7 @@ use sql_support::{ /// `clear_database()` by adding their names to `conditional_tables`, unless /// they are cleared via a deletion trigger or there's some other good /// reason not to do so. -pub const VERSION: u32 = 37; +pub const VERSION: u32 = 38; /// The current Suggest database schema. pub const SQL: &str = " @@ -161,6 +161,7 @@ CREATE TABLE icons( CREATE TABLE yelp_subjects( keyword TEXT PRIMARY KEY, + subject_type INTEGER NOT NULL DEFAULT 0, record_id TEXT NOT NULL ) WITHOUT ROWID; @@ -647,6 +648,20 @@ impl ConnectionInitializer for SuggestConnectionInitializer<'_> { tx.execute_batch("DROP TABLE IF EXISTS yelp_location_signs;")?; Ok(()) } + 37 => { + clear_database(tx)?; + tx.execute_batch( + " + DROP TABLE yelp_subjects; + CREATE TABLE yelp_subjects( + keyword TEXT PRIMARY KEY, + subject_type INTEGER NOT NULL DEFAULT 0, + record_id TEXT NOT NULL + ) WITHOUT ROWID; + ", + )?; + Ok(()) + } _ => Err(open_database::Error::IncompatibleVersion(version)), } } diff --git a/third_party/rust/suggest/src/store.rs b/third_party/rust/suggest/src/store.rs index 0a3d48c237f5..0766f96e44ea 100644 --- a/third_party/rust/suggest/src/store.rs +++ b/third_party/rust/suggest/src/store.rs @@ -975,6 +975,7 @@ impl SuggestStoreDbs { #[cfg(test)] pub(crate) mod tests { use super::*; + use crate::suggestion::YelpSubjectType; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -2247,6 +2248,25 @@ pub(crate) mod tests { ) .has_location_sign(false)], ); + // Business subject. + assert_eq!( + store.fetch_suggestions(SuggestionQuery::yelp("the shop tokyo")), + vec![ramen_suggestion( + "the shop tokyo", + "https://www.yelp.com/search?find_desc=the+shop&find_loc=tokyo" + ) + .has_location_sign(false) + .subject_type(YelpSubjectType::Business)] + ); + assert_eq!( + store.fetch_suggestions(SuggestionQuery::yelp("the sho")), + vec![ + ramen_suggestion("the shop", "https://www.yelp.com/search?find_desc=the+shop") + .has_location_sign(false) + .subject_exact_match(false) + .subject_type(YelpSubjectType::Business) + ] + ); Ok(()) } diff --git a/third_party/rust/suggest/src/suggestion.rs b/third_party/rust/suggest/src/suggestion.rs index 3d96d01b4df5..28be46d0ea41 100644 --- a/third_party/rust/suggest/src/suggestion.rs +++ b/third_party/rust/suggest/src/suggestion.rs @@ -16,6 +16,16 @@ const TIMESTAMP_TEMPLATE: &str = "%YYYYMMDDHH%"; /// 2 bytes shorter than [`TIMESTAMP_TEMPLATE`]. const TIMESTAMP_LENGTH: usize = 10; +/// Subject type for Yelp suggestion. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, uniffi::Enum)] +#[repr(u8)] +pub enum YelpSubjectType { + // Service such as sushi, ramen, yoga etc. + Service = 0, + // Specific business such as the shop name. + Business = 1, +} + /// A suggestion from the database to show in the address bar. #[derive(Clone, Debug, PartialEq, uniffi::Enum)] pub enum Suggestion { @@ -66,6 +76,7 @@ pub enum Suggestion { score: f64, has_location_sign: bool, subject_exact_match: bool, + subject_type: YelpSubjectType, location_param: String, }, Mdn { diff --git a/third_party/rust/suggest/src/testing/data.rs b/third_party/rust/suggest/src/testing/data.rs index f1d699cc99f0..a2d154e0fb4a 100644 --- a/third_party/rust/suggest/src/testing/data.rs +++ b/third_party/rust/suggest/src/testing/data.rs @@ -4,7 +4,7 @@ //! Test data that we use in many tests -use crate::{suggestion::FtsMatchInfo, testing::MockIcon, Suggestion}; +use crate::{suggestion::FtsMatchInfo, suggestion::YelpSubjectType, testing::MockIcon, Suggestion}; use serde_json::json; use serde_json::Value as JsonValue; @@ -294,6 +294,7 @@ pub fn burnout_suggestion(is_top_pick: bool) -> Suggestion { pub fn ramen_yelp() -> JsonValue { json!({ "subjects": ["ramen", "spicy ramen", "spicy random ramen", "rats", "raven", "raccoon", "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789Z"], + "businessSubjects": ["the shop"], "preModifiers": ["best", "super best", "same_modifier"], "postModifiers": ["delivery", "super delivery", "same_modifier"], "locationSigns": [ @@ -319,6 +320,7 @@ pub fn ramen_suggestion(title: &str, url: &str) -> Suggestion { score: 0.5, has_location_sign: true, subject_exact_match: true, + subject_type: YelpSubjectType::Service, location_param: "find_loc".into(), } } diff --git a/third_party/rust/suggest/src/testing/mod.rs b/third_party/rust/suggest/src/testing/mod.rs index 66894719baaa..50715796838d 100644 --- a/third_party/rust/suggest/src/testing/mod.rs +++ b/third_party/rust/suggest/src/testing/mod.rs @@ -8,7 +8,8 @@ mod data; pub use client::{MockAttachment, MockIcon, MockRecord, MockRemoteSettingsClient}; pub use data::*; -use crate::Suggestion; +use crate::{suggestion::YelpSubjectType, Suggestion}; + use parking_lot::Once; use serde_json::Value as JsonValue; @@ -79,6 +80,7 @@ impl Suggestion { icon_mimetype, score, subject_exact_match, + subject_type, location_param, .. } => Self::Yelp { @@ -88,6 +90,7 @@ impl Suggestion { icon_mimetype, score, subject_exact_match, + subject_type, location_param, has_location_sign, }, @@ -103,6 +106,7 @@ impl Suggestion { icon, icon_mimetype, score, + subject_type, has_location_sign, location_param, .. @@ -113,10 +117,38 @@ impl Suggestion { icon_mimetype, score, subject_exact_match, + subject_type, location_param, has_location_sign, }, - _ => panic!("has_location_sign only valid for yelp suggestions"), + _ => panic!("subject_exact_match only valid for yelp suggestions"), + } + } + + pub fn subject_type(self, subject_type: YelpSubjectType) -> Self { + match self { + Self::Yelp { + title, + url, + icon, + icon_mimetype, + score, + subject_exact_match, + has_location_sign, + location_param, + .. + } => Self::Yelp { + title, + url, + icon, + icon_mimetype, + score, + subject_exact_match, + subject_type, + location_param, + has_location_sign, + }, + _ => panic!("subject_type only valid for yelp suggestions"), } } } diff --git a/third_party/rust/suggest/src/yelp.rs b/third_party/rust/suggest/src/yelp.rs index dc5266b6ffb5..59fe24557fdd 100644 --- a/third_party/rust/suggest/src/yelp.rs +++ b/third_party/rust/suggest/src/yelp.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use rusqlite::types::ToSqlOutput; +use rusqlite::types::{FromSql, FromSqlResult, ToSqlOutput, ValueRef}; use rusqlite::{named_params, Result as RusqliteResult, ToSql}; use sql_support::ConnExt; use url::form_urlencoded; @@ -13,6 +13,7 @@ use crate::{ provider::SuggestionProvider, rs::{DownloadedYelpSuggestion, SuggestRecordId}, suggestion::Suggestion, + suggestion::YelpSubjectType, Result, SuggestionQuery, }; @@ -31,6 +32,22 @@ impl ToSql for Modifier { } } +impl ToSql for YelpSubjectType { + fn to_sql(&self) -> RusqliteResult> { + Ok(ToSqlOutput::from(*self as u8)) + } +} + +impl FromSql for YelpSubjectType { + fn column_result(value: ValueRef<'_>) -> FromSqlResult { + if value.as_i64().unwrap_or_default() == 0 { + Ok(YelpSubjectType::Service) + } else { + Ok(YelpSubjectType::Business) + } + } +} + #[derive(Clone, Copy, Eq, PartialEq)] enum FindFrom { First, @@ -57,6 +74,18 @@ const MAX_MODIFIER_WORDS_NUMBER: usize = 2; /// At least this many characters must be typed for a subject to be matched. const SUBJECT_PREFIX_MATCH_THRESHOLD: usize = 2; +#[derive(Debug, PartialEq)] +struct FindSubjectData<'a> { + // The keyword in DB (but the case is inherited by query). + subject: String, + // Whether or not the keyword is exact match. + exact_match: bool, + // The subject type. + subject_type: YelpSubjectType, + // Words after removed matching subject. + rest: &'a [&'a str], +} + impl SuggestDao<'_> { /// Inserts the suggestions for Yelp attachment into the database. pub(crate) fn insert_yelp_suggestions( @@ -67,10 +96,23 @@ impl SuggestDao<'_> { for keyword in &suggestion.subjects { self.scope.err_if_interrupted()?; self.conn.execute_cached( - "INSERT INTO yelp_subjects(record_id, keyword) VALUES(:record_id, :keyword)", + "INSERT INTO yelp_subjects(record_id, keyword, subject_type) VALUES(:record_id, :keyword, :subject_type)", named_params! { ":record_id": record_id.as_str(), ":keyword": keyword, + ":subject_type": YelpSubjectType::Service, + }, + )?; + } + + for keyword in suggestion.business_subjects.as_ref().unwrap_or(&vec![]) { + self.scope.err_if_interrupted()?; + self.conn.execute_cached( + "INSERT INTO yelp_subjects(record_id, keyword, subject_type) VALUES(:record_id, :keyword, :subject_type)", + named_params! { + ":record_id": record_id.as_str(), + ":keyword": keyword, + ":subject_type": YelpSubjectType::Business, }, )?; } @@ -163,10 +205,10 @@ impl SuggestDao<'_> { query_words = rest; } - let Some(subject_tuple) = self.find_subject(query_words)? else { + let Some(subject_data) = self.find_subject(query_words)? else { return Ok(vec![]); }; - query_words = subject_tuple.2; + query_words = subject_data.rest; let post_modifier_tuple = self.find_modifier(query_words, Modifier::Post, FindFrom::First)?; @@ -194,8 +236,9 @@ impl SuggestDao<'_> { let (icon, icon_mimetype, score) = self.fetch_custom_details()?; let builder = SuggestionBuilder { - subject: &subject_tuple.0, - subject_exact_match: subject_tuple.1, + subject: &subject_data.subject, + subject_exact_match: subject_data.exact_match, + subject_type: subject_data.subject_type, pre_modifier: pre_modifier_tuple.map(|(words, _)| words.to_string()), post_modifier: post_modifier_tuple.map(|(words, _)| words.to_string()), location_sign: location_sign_tuple.map(|(words, _)| words.to_string()), @@ -266,16 +309,8 @@ impl SuggestDao<'_> { } /// Find the subject for given query. - /// It returns Option as follows: - /// ( - /// String: The keyword in DB (but the case is inherited by query). - /// bool: Whether or not the keyword is exact match. - /// &[&str]: Words after removed matching subject. - /// ) - fn find_subject<'a>( - &self, - query_words: &'a [&'a str], - ) -> Result> { + /// It returns Option. + fn find_subject<'a>(&self, query_words: &'a [&'a str]) -> Result>> { if query_words.is_empty() { return Ok(None); } @@ -283,8 +318,8 @@ impl SuggestDao<'_> { let mut query_string = query_words.join(" "); // This checks if keyword is a substring of the query. - if let Some(keyword_lowercase) = self.conn.try_query_one::( - "SELECT keyword + if let Ok((keyword_lowercase, subject_type)) = self.conn.query_row_and_then_cachable( + "SELECT keyword, subject_type FROM yelp_subjects WHERE :query BETWEEN keyword AND keyword || ' ' || x'FFFF' ORDER BY LENGTH(keyword) ASC, keyword ASC @@ -292,16 +327,20 @@ impl SuggestDao<'_> { named_params! { ":query": query_string.to_lowercase(), }, + |row| -> Result<_> { + Ok((row.get::<_, String>(0)?, row.get::<_, YelpSubjectType>(1)?)) + }, true, - )? { + ) { // Preserve the query as the user typed it including its case. return Ok(query_string.get(0..keyword_lowercase.len()).map(|keyword| { let count = keyword.split_whitespace().count(); - ( - keyword.to_string(), - true, - query_words.get(count..).unwrap_or_default(), - ) + FindSubjectData { + subject: keyword.to_string(), + exact_match: true, + subject_type, + rest: query_words.get(count..).unwrap_or_default(), + } })); }; @@ -310,8 +349,8 @@ impl SuggestDao<'_> { } // Oppositely, this checks if the query is a substring of keyword. - if let Some(keyword_lowercase) = self.conn.try_query_one::( - "SELECT keyword + if let Ok((keyword_lowercase, subject_type)) = self.conn.query_row_and_then_cachable( + "SELECT keyword, subject_type FROM yelp_subjects WHERE keyword BETWEEN :query AND :query || x'FFFF' ORDER BY LENGTH(keyword) ASC, keyword ASC @@ -319,8 +358,11 @@ impl SuggestDao<'_> { named_params! { ":query": query_string.to_lowercase(), }, + |row| -> Result<_> { + Ok((row.get::<_, String>(0)?, row.get::<_, YelpSubjectType>(1)?)) + }, true, - )? { + ) { // Preserve the query as the user typed it including its case. return Ok(keyword_lowercase .get(query_string.len()..) @@ -328,11 +370,12 @@ impl SuggestDao<'_> { query_string.push_str(keyword_rest); let count = std::cmp::min(query_words.len(), query_string.split_whitespace().count()); - ( - query_string, - false, - query_words.get(count..).unwrap_or_default(), - ) + FindSubjectData { + subject: query_string, + exact_match: false, + subject_type, + rest: query_words.get(count..).unwrap_or_default(), + } })); }; @@ -383,6 +426,7 @@ impl SuggestDao<'_> { struct SuggestionBuilder<'a> { subject: &'a str, subject_exact_match: bool, + subject_type: YelpSubjectType, pre_modifier: Option, post_modifier: Option, location_sign: Option, @@ -435,6 +479,7 @@ impl<'a> From> for Suggestion { score: builder.score, has_location_sign: builder.location_sign.is_some(), subject_exact_match: builder.subject_exact_match, + subject_type: builder.subject_type, location_param: "find_loc".to_string(), } } @@ -645,31 +690,114 @@ mod tests { ); } - type FindSubjectTestCase<'a> = (&'a str, Option<(String, bool, &'a [&'a str])>); + type FindSubjectTestCase<'a> = (&'a str, Option>); let find_subject_tests: &[FindSubjectTestCase] = &[ // Query, Expected result. ("", None), ("r", None), - ("ra", Some(("rats".to_string(), false, &[]))), - ("ram", Some(("ramen".to_string(), false, &[]))), - ("rame", Some(("ramen".to_string(), false, &[]))), - ("ramen", Some(("ramen".to_string(), true, &[]))), - ("spi", Some(("spicy ramen".to_string(), false, &[]))), - ("spicy ra ", Some(("spicy ramen".to_string(), false, &[]))), - ("spicy ramen", Some(("spicy ramen".to_string(), true, &[]))), + ( + "ra", + Some(FindSubjectData { + subject: "rats".to_string(), + exact_match: false, + subject_type: YelpSubjectType::Service, + rest: &[], + }), + ), + ( + "ram", + Some(FindSubjectData { + subject: "ramen".to_string(), + exact_match: false, + subject_type: YelpSubjectType::Service, + rest: &[], + }), + ), + ( + "rame", + Some(FindSubjectData { + subject: "ramen".to_string(), + exact_match: false, + subject_type: YelpSubjectType::Service, + rest: &[], + }), + ), + ( + "ramen", + Some(FindSubjectData { + subject: "ramen".to_string(), + exact_match: true, + subject_type: YelpSubjectType::Service, + rest: &[], + }), + ), + ( + "spi", + Some(FindSubjectData { + subject: "spicy ramen".to_string(), + exact_match: false, + subject_type: YelpSubjectType::Service, + rest: &[], + }), + ), + ( + "spicy ra ", + Some(FindSubjectData { + subject: "spicy ramen".to_string(), + exact_match: false, + subject_type: YelpSubjectType::Service, + rest: &[], + }), + ), + ( + "spicy ramen", + Some(FindSubjectData { + subject: "spicy ramen".to_string(), + exact_match: true, + subject_type: YelpSubjectType::Service, + rest: &[], + }), + ), ( "spicy ramen gogo", - Some(("spicy ramen".to_string(), true, &["gogo"])), + Some(FindSubjectData { + subject: "spicy ramen".to_string(), + exact_match: true, + subject_type: YelpSubjectType::Service, + rest: &["gogo"], + }), ), ( "SpIcY rAmEn GoGo", - Some(("SpIcY rAmEn".to_string(), true, &["GoGo"])), + Some(FindSubjectData { + subject: "SpIcY rAmEn".to_string(), + exact_match: true, + subject_type: YelpSubjectType::Service, + rest: &["GoGo"], + }), ), ("ramenabc", None), ("ramenabc xyz", None), ("spicy ramenabc", None), ("spicy ramenabc xyz", None), - ("ramen abc", Some(("ramen".to_string(), true, &["abc"]))), + ( + "ramen abc", + Some(FindSubjectData { + subject: "ramen".to_string(), + exact_match: true, + subject_type: YelpSubjectType::Service, + rest: &["abc"], + }), + ), + ( + "the shop", + Some(FindSubjectData { + subject: "the shop".to_string(), + exact_match: true, + subject_type: YelpSubjectType::Business, + rest: &[], + }), + ), ]; for (query, expected) in find_subject_tests { assert_eq!( diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs index 7c966e6e394e..7a816edbf063 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs @@ -2945,6 +2945,7 @@ Suggestion.Yelp = class extends Suggestion{ score, hasLocationSign, subjectExactMatch, + subjectType, locationParam ) { super(); @@ -2955,6 +2956,7 @@ Suggestion.Yelp = class extends Suggestion{ this.score = score; this.hasLocationSign = hasLocationSign; this.subjectExactMatch = subjectExactMatch; + this.subjectType = subjectType; this.locationParam = locationParam; } } @@ -3100,6 +3102,7 @@ export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer { FfiConverterF64.read(dataStream), FfiConverterBool.read(dataStream), FfiConverterBool.read(dataStream), + FfiConverterTypeYelpSubjectType.read(dataStream), FfiConverterString.read(dataStream) ); case 6: @@ -3200,6 +3203,7 @@ export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer { FfiConverterF64.write(dataStream, value.score); FfiConverterBool.write(dataStream, value.hasLocationSign); FfiConverterBool.write(dataStream, value.subjectExactMatch); + FfiConverterTypeYelpSubjectType.write(dataStream, value.subjectType); FfiConverterString.write(dataStream, value.locationParam); return; } @@ -3300,6 +3304,7 @@ export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer { totalSize += FfiConverterF64.computeSize(value.score); totalSize += FfiConverterBool.computeSize(value.hasLocationSign); totalSize += FfiConverterBool.computeSize(value.subjectExactMatch); + totalSize += FfiConverterTypeYelpSubjectType.computeSize(value.subjectType); totalSize += FfiConverterString.computeSize(value.locationParam); return totalSize; } @@ -3477,6 +3482,63 @@ export class FfiConverterTypeSuggestionProvider extends FfiConverterArrayBuffer } + +/** + * Subject type for Yelp suggestion. + */ +export const YelpSubjectType = { + /** + * SERVICE + */ + SERVICE:0, + /** + * BUSINESS + */ + BUSINESS:1, +}; + +Object.freeze(YelpSubjectType); +// Export the FFIConverter object to make external types work. +export class FfiConverterTypeYelpSubjectType extends FfiConverterArrayBuffer { + static #validValues = Object.values(YelpSubjectType); + + static read(dataStream) { + // Use sequential indices (1-based) for the wire format to match Python bindings + switch (dataStream.readInt32()) { + case 1: + return YelpSubjectType.SERVICE + case 2: + return YelpSubjectType.BUSINESS + default: + throw new UniFFITypeError("Unknown YelpSubjectType variant"); + } + } + + static write(dataStream, value) { + if (value === YelpSubjectType.SERVICE) { + dataStream.writeInt32(1); + return; + } + if (value === YelpSubjectType.BUSINESS) { + dataStream.writeInt32(2); + return; + } + throw new UniFFITypeError("Unknown YelpSubjectType variant"); + } + + static computeSize(value) { + return 4; + } + + static checkType(value) { + // Check that the value is a valid enum variant + if (!this.#validValues.includes(value)) { + throw new UniFFITypeError(`${value} is not a valid value for YelpSubjectType`); + } + } +} + + // Export the FFIConverter object to make external types work. export class FfiConverterOptionali32 extends FfiConverterArrayBuffer { static checkType(value) {