Bug 1929082 - Vendor application-services df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3 for city-based weather. r=nanj
Differential Revision: https://phabricator.services.mozilla.com/D227858
This commit is contained in:
@@ -60,9 +60,9 @@ git = "https://github.com/mozilla-spidermonkey/jsparagus"
|
|||||||
rev = "61f399c53a641ebd3077c1f39f054f6d396a633c"
|
rev = "61f399c53a641ebd3077c1f39f054f6d396a633c"
|
||||||
replace-with = "vendored-sources"
|
replace-with = "vendored-sources"
|
||||||
|
|
||||||
[source."git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce"]
|
[source."git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"]
|
||||||
git = "https://github.com/mozilla/application-services"
|
git = "https://github.com/mozilla/application-services"
|
||||||
rev = "892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
rev = "df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
replace-with = "vendored-sources"
|
replace-with = "vendored-sources"
|
||||||
|
|
||||||
[source."git+https://github.com/mozilla/audioipc?rev=e6f44a2bd1e57d11dfc737632a9e849077632330"]
|
[source."git+https://github.com/mozilla/audioipc?rev=e6f44a2bd1e57d11dfc737632a9e849077632330"]
|
||||||
|
|||||||
30
Cargo.lock
generated
30
Cargo.lock
generated
@@ -1767,7 +1767,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "error-support"
|
name = "error-support"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"error-support-macros",
|
"error-support-macros",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@@ -1779,7 +1779,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "error-support-macros"
|
name = "error-support-macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -3143,7 +3143,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "interrupt-support"
|
name = "interrupt-support"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
@@ -4451,7 +4451,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nss_build_common"
|
name = "nss_build_common"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nsstring"
|
name = "nsstring"
|
||||||
@@ -4664,7 +4664,7 @@ checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "payload-support"
|
name = "payload-support"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
@@ -5150,7 +5150,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "relevancy"
|
name = "relevancy"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.21.3",
|
"base64 0.21.3",
|
||||||
@@ -5173,7 +5173,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "remote_settings"
|
name = "remote_settings"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"camino",
|
"camino",
|
||||||
"error-support",
|
"error-support",
|
||||||
@@ -5741,7 +5741,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "sql-support"
|
name = "sql-support"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"interrupt-support",
|
"interrupt-support",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@@ -5920,7 +5920,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "suggest"
|
name = "suggest"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -5972,7 +5972,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "sync-guid"
|
name = "sync-guid"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.3",
|
"base64 0.21.3",
|
||||||
"rand",
|
"rand",
|
||||||
@@ -5983,7 +5983,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "sync15"
|
name = "sync15"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"error-support",
|
"error-support",
|
||||||
@@ -6023,7 +6023,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tabs"
|
name = "tabs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"error-support",
|
"error-support",
|
||||||
@@ -6347,7 +6347,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "types"
|
name = "types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -6722,7 +6722,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "viaduct"
|
name = "viaduct"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ffi-support",
|
"ffi-support",
|
||||||
"log",
|
"log",
|
||||||
@@ -6870,7 +6870,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "webext-storage"
|
name = "webext-storage"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=892d31a9cbc3d3fff30fb70f63beacb92f0157ce#892d31a9cbc3d3fff30fb70f63beacb92f0157ce"
|
source = "git+https://github.com/mozilla/application-services?rev=df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3#df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"error-support",
|
"error-support",
|
||||||
|
|||||||
16
Cargo.toml
16
Cargo.toml
@@ -216,13 +216,13 @@ midir = { git = "https://github.com/mozilla/midir.git", rev = "85156e360a37d8517
|
|||||||
malloc_size_of_derive = { path = "xpcom/rust/malloc_size_of_derive" }
|
malloc_size_of_derive = { path = "xpcom/rust/malloc_size_of_derive" }
|
||||||
|
|
||||||
# application-services overrides to make updating them all simpler.
|
# application-services overrides to make updating them all simpler.
|
||||||
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "892d31a9cbc3d3fff30fb70f63beacb92f0157ce" }
|
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3" }
|
||||||
relevancy = { git = "https://github.com/mozilla/application-services", rev = "892d31a9cbc3d3fff30fb70f63beacb92f0157ce" }
|
relevancy = { git = "https://github.com/mozilla/application-services", rev = "df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3" }
|
||||||
sql-support = { git = "https://github.com/mozilla/application-services", rev = "892d31a9cbc3d3fff30fb70f63beacb92f0157ce" }
|
sql-support = { git = "https://github.com/mozilla/application-services", rev = "df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3" }
|
||||||
suggest = { git = "https://github.com/mozilla/application-services", rev = "892d31a9cbc3d3fff30fb70f63beacb92f0157ce" }
|
suggest = { git = "https://github.com/mozilla/application-services", rev = "df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3" }
|
||||||
sync15 = { git = "https://github.com/mozilla/application-services", rev = "892d31a9cbc3d3fff30fb70f63beacb92f0157ce" }
|
sync15 = { git = "https://github.com/mozilla/application-services", rev = "df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3" }
|
||||||
tabs = { git = "https://github.com/mozilla/application-services", rev = "892d31a9cbc3d3fff30fb70f63beacb92f0157ce" }
|
tabs = { git = "https://github.com/mozilla/application-services", rev = "df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3" }
|
||||||
viaduct = { git = "https://github.com/mozilla/application-services", rev = "892d31a9cbc3d3fff30fb70f63beacb92f0157ce" }
|
viaduct = { git = "https://github.com/mozilla/application-services", rev = "df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3" }
|
||||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "892d31a9cbc3d3fff30fb70f63beacb92f0157ce" }
|
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "df8c16859ebeff46cb4fcfb65d7ca9dd6d4fa6d3" }
|
||||||
|
|
||||||
allocator-api2 = { path = "third_party/rust/allocator-api2" }
|
allocator-api2 = { path = "third_party/rust/allocator-api2" }
|
||||||
|
|||||||
@@ -702,6 +702,7 @@ class _QuickSuggestTestUtils {
|
|||||||
admin1_code: "AL",
|
admin1_code: "AL",
|
||||||
population: 200,
|
population: 200,
|
||||||
alternate_names: ["waterloo"],
|
alternate_names: ["waterloo"],
|
||||||
|
alternate_names_2: [{ name: "waterloo" }],
|
||||||
},
|
},
|
||||||
// AL
|
// AL
|
||||||
{
|
{
|
||||||
@@ -715,6 +716,10 @@ class _QuickSuggestTestUtils {
|
|||||||
admin1_code: "AL",
|
admin1_code: "AL",
|
||||||
population: 4530315,
|
population: 4530315,
|
||||||
alternate_names: ["al", "alabama"],
|
alternate_names: ["al", "alabama"],
|
||||||
|
alternate_names_2: [
|
||||||
|
{ name: "alabama" },
|
||||||
|
{ name: "al", iso_language: "abbr" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// Waterloo, IA
|
// Waterloo, IA
|
||||||
{
|
{
|
||||||
@@ -728,6 +733,7 @@ class _QuickSuggestTestUtils {
|
|||||||
admin1_code: "IA",
|
admin1_code: "IA",
|
||||||
population: 68460,
|
population: 68460,
|
||||||
alternate_names: ["waterloo"],
|
alternate_names: ["waterloo"],
|
||||||
|
alternate_names_2: [{ name: "waterloo" }],
|
||||||
},
|
},
|
||||||
// IA
|
// IA
|
||||||
{
|
{
|
||||||
@@ -741,6 +747,10 @@ class _QuickSuggestTestUtils {
|
|||||||
admin1_code: "IA",
|
admin1_code: "IA",
|
||||||
population: 2955010,
|
population: 2955010,
|
||||||
alternate_names: ["ia", "iowa"],
|
alternate_names: ["ia", "iowa"],
|
||||||
|
alternate_names_2: [
|
||||||
|
{ name: "iowa" },
|
||||||
|
{ name: "ia", iso_language: "abbr" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// Made-up cities with the same name in the US and CA. The CA city has a
|
// Made-up cities with the same name in the US and CA. The CA city has a
|
||||||
// larger population.
|
// larger population.
|
||||||
@@ -755,6 +765,7 @@ class _QuickSuggestTestUtils {
|
|||||||
admin1_code: "IA",
|
admin1_code: "IA",
|
||||||
population: 1,
|
population: 1,
|
||||||
alternate_names: ["us ca city"],
|
alternate_names: ["us ca city"],
|
||||||
|
alternate_names_2: [{ name: "us ca city" }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 101,
|
id: 101,
|
||||||
@@ -767,6 +778,7 @@ class _QuickSuggestTestUtils {
|
|||||||
admin1_code: "08",
|
admin1_code: "08",
|
||||||
population: 2,
|
population: 2,
|
||||||
alternate_names: ["us ca city"],
|
alternate_names: ["us ca city"],
|
||||||
|
alternate_names_2: [{ name: "us ca city" }],
|
||||||
},
|
},
|
||||||
// Made-up cities that are only ~1.5 km apart.
|
// Made-up cities that are only ~1.5 km apart.
|
||||||
{
|
{
|
||||||
@@ -780,6 +792,7 @@ class _QuickSuggestTestUtils {
|
|||||||
admin1_code: "GA",
|
admin1_code: "GA",
|
||||||
population: 1,
|
population: 1,
|
||||||
alternate_names: ["twin city a"],
|
alternate_names: ["twin city a"],
|
||||||
|
alternate_names_2: [{ name: "twin city a" }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 103,
|
id: 103,
|
||||||
@@ -792,6 +805,7 @@ class _QuickSuggestTestUtils {
|
|||||||
admin1_code: "GA",
|
admin1_code: "GA",
|
||||||
population: 2,
|
population: 2,
|
||||||
alternate_names: ["twin city b"],
|
alternate_names: ["twin city b"],
|
||||||
|
alternate_names_2: [{ name: "twin city b" }],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
let [maxLen, maxWordCount] = geonames.reduce(
|
let [maxLen, maxWordCount] = geonames.reduce(
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"files":{"Cargo.toml":"2ac3a843e4d5e3945a8ae61d2267c067a59bdca39bc82ea2e66057eef59791ba","README.md":"5e28baf874b643d756228bdab345e287bf107d3182dfe6a18aafadcc4b9a3fc9","benches/benchmark_all.rs":"3582f21af9758766ff32ed95f90b69984b32091b1e31e0c0bef307c22fd82f18","metrics.yaml":"0540ab2271aeab7f07335c7ceec12acde942995f9dcb3c29070489aa61899d56","src/benchmarks/README.md":"ccee8dbddba8762d0453fa855bd6984137b224b8c019f3dd8e86a3c303f51d71","src/benchmarks/client.rs":"a777c0b876a481a21f9d5fbb696b42672ed0b4af359f62f047ac8240d3e35853","src/benchmarks/ingest.rs":"504d00f09e88e01676ee2de3787b942a538e1ae7b46919e937df3f5b8edd8be9","src/benchmarks/mod.rs":"2d7c20d47d6c7e17bc738255a31119bd0c4a4e495419a00c7b10b251ace9ef6b","src/benchmarks/query.rs":"ce78057e0ed43a419cc92d2bceb0bbef8aad9b113ef0341cf5f1d8d1578848e0","src/bin/debug_ingestion_sizes.rs":"ce6e810be7b3fc19e826d75b622b82cfab5a1a99397a6d0833c2c4eebff2d364","src/config.rs":"0ca876e845841bb6429862c0904c82265003f53b55aea053fac60aed278586a7","src/db.rs":"7801af3ba446774dd067c374ac034bee2416bc20ed49e8ac7ff6ec98a44768ff","src/error.rs":"e2ef3ec0e0b2b8ecbb8f2f1717d4cb753af06913b8395d086b7643098ad100a7","src/fakespot.rs":"03d3aac07b3a3a9ceb8d2c452d4a122bfebf04579829e62e83487877055312d4","src/geoname.rs":"0bbe296fe5726411d9c10bdc6cf632fa90b670f92cb399ae0eb2684da043c964","src/lib.rs":"1c82651061b9a17909c0f05390ee643328cc9d3026f2ebff10798183c09a7d6e","src/metrics.rs":"871f0d834efbbc9e26d61f66fa31f0021dcf41444746cd7c082f93ba9628e399","src/pocket.rs":"1316668840ec9b4ea886223921dc9d3b5a1731d1a5206c0b1089f2a6c45c1b7b","src/provider.rs":"2bca934214366c59c4628cf88313057ce7256c167aabe77119f1703bd65a4cc6","src/query.rs":"84b97997036a3a597b0574e719e7407ddf0f18bd55c07a704bd2cacd549e8509","src/rs.rs":"953f978b30ca6ebaf18dab5ba8fa02dd076851e83d5f936ea8ab6016e7e17db9","src/schema.rs":"050504a7d108b5808d74dfdfbb861a1bb6a700d6b02b07db13af403c95c9353c","src/store.rs":"8b261dc52f9fb85f1a2c6443b0592a4bb9d4ee1d3fb6b1449f813b12c15cfb6f","src/suggestion.rs":"cf4b457d7499dc8dabedbc14536fe915969378a25cc45ca9f25139843558b68d","src/testing/client.rs":"f8c9bd32d0f4cf364daebe114d580c7e36a83b69c07884d14170969620d9a437","src/testing/data.rs":"d4fc5227996a8b115d93243fdbd83bc57d73a8c2d4c0b20dffa15bbec27925cb","src/testing/mod.rs":"4d2781c77ed9ace9d80d6d00c63a06bf28a4156f223616fffe3c07e64a8041db","src/util.rs":"2de919f66ea12dea8558d5793e6a165a515b1cead3da466398693fd9753622e1","src/weather.rs":"ca809d80f29d1677218b4b3ea66fa6ca2c99f3ac50e3569500d86f3a50deaac5","src/yelp.rs":"bc036ff71b438d53ce8811acd8d650d83ef03faeea476f5b659b403c1e64ff2b","uniffi.toml":"19ea9cfd30d2e57ffad125b7eeef7f9228d43347fceb8bb9a54a0e66177eb2e5"},"package":null}
|
{"files":{"Cargo.toml":"2ac3a843e4d5e3945a8ae61d2267c067a59bdca39bc82ea2e66057eef59791ba","README.md":"5e28baf874b643d756228bdab345e287bf107d3182dfe6a18aafadcc4b9a3fc9","benches/benchmark_all.rs":"3582f21af9758766ff32ed95f90b69984b32091b1e31e0c0bef307c22fd82f18","metrics.yaml":"0540ab2271aeab7f07335c7ceec12acde942995f9dcb3c29070489aa61899d56","src/benchmarks/README.md":"ccee8dbddba8762d0453fa855bd6984137b224b8c019f3dd8e86a3c303f51d71","src/benchmarks/client.rs":"a777c0b876a481a21f9d5fbb696b42672ed0b4af359f62f047ac8240d3e35853","src/benchmarks/ingest.rs":"504d00f09e88e01676ee2de3787b942a538e1ae7b46919e937df3f5b8edd8be9","src/benchmarks/mod.rs":"2d7c20d47d6c7e17bc738255a31119bd0c4a4e495419a00c7b10b251ace9ef6b","src/benchmarks/query.rs":"ce78057e0ed43a419cc92d2bceb0bbef8aad9b113ef0341cf5f1d8d1578848e0","src/bin/debug_ingestion_sizes.rs":"ce6e810be7b3fc19e826d75b622b82cfab5a1a99397a6d0833c2c4eebff2d364","src/config.rs":"0ca876e845841bb6429862c0904c82265003f53b55aea053fac60aed278586a7","src/db.rs":"7801af3ba446774dd067c374ac034bee2416bc20ed49e8ac7ff6ec98a44768ff","src/error.rs":"e2ef3ec0e0b2b8ecbb8f2f1717d4cb753af06913b8395d086b7643098ad100a7","src/fakespot.rs":"03d3aac07b3a3a9ceb8d2c452d4a122bfebf04579829e62e83487877055312d4","src/geoname.rs":"a422f9a150b2c27faa014cf69969eb037f4c26022f4b67d0bdc5ec0151e0eed7","src/lib.rs":"1c82651061b9a17909c0f05390ee643328cc9d3026f2ebff10798183c09a7d6e","src/metrics.rs":"871f0d834efbbc9e26d61f66fa31f0021dcf41444746cd7c082f93ba9628e399","src/pocket.rs":"1316668840ec9b4ea886223921dc9d3b5a1731d1a5206c0b1089f2a6c45c1b7b","src/provider.rs":"2bca934214366c59c4628cf88313057ce7256c167aabe77119f1703bd65a4cc6","src/query.rs":"84b97997036a3a597b0574e719e7407ddf0f18bd55c07a704bd2cacd549e8509","src/rs.rs":"953f978b30ca6ebaf18dab5ba8fa02dd076851e83d5f936ea8ab6016e7e17db9","src/schema.rs":"cbd43eb803942dd606285137c2d2144c9f8a1b3829217002bb6badb7f76d2c29","src/store.rs":"8b261dc52f9fb85f1a2c6443b0592a4bb9d4ee1d3fb6b1449f813b12c15cfb6f","src/suggestion.rs":"cf4b457d7499dc8dabedbc14536fe915969378a25cc45ca9f25139843558b68d","src/testing/client.rs":"f8c9bd32d0f4cf364daebe114d580c7e36a83b69c07884d14170969620d9a437","src/testing/data.rs":"d4fc5227996a8b115d93243fdbd83bc57d73a8c2d4c0b20dffa15bbec27925cb","src/testing/mod.rs":"4d2781c77ed9ace9d80d6d00c63a06bf28a4156f223616fffe3c07e64a8041db","src/util.rs":"52c6ec405637afa2d1a89f29fbbb7dcc341546b6deb97d326c4490bbf8713cb0","src/weather.rs":"2bf5f4b23b8b7e8e7e2d372b8589179e4f94e02747d9c09b383f824647eb4b6e","src/yelp.rs":"bc036ff71b438d53ce8811acd8d650d83ef03faeea476f5b659b403c1e64ff2b","uniffi.toml":"19ea9cfd30d2e57ffad125b7eeef7f9228d43347fceb8bb9a54a0e66177eb2e5"},"package":null}
|
||||||
589
third_party/rust/suggest/src/geoname.rs
vendored
589
third_party/rust/suggest/src/geoname.rs
vendored
@@ -82,6 +82,33 @@ impl Hash for Geoname {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Value returned by `fetch_geonames()`.
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub struct GeonameMatch {
|
||||||
|
pub geoname: Geoname,
|
||||||
|
pub match_type: GeonameMatchType,
|
||||||
|
pub prefix: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum GeonameMatchType {
|
||||||
|
/// For U.S. states, abbreviations are the usual two-letter codes ("CA").
|
||||||
|
Abbreviation,
|
||||||
|
AirportCode,
|
||||||
|
/// This includes any names that aren't abbreviations or airport codes.
|
||||||
|
Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GeonameMatchType {
|
||||||
|
pub fn is_abbreviation(&self) -> bool {
|
||||||
|
matches!(self, GeonameMatchType::Abbreviation)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_name(&self) -> bool {
|
||||||
|
matches!(self, GeonameMatchType::Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This data is used to service every query handled by the weather provider and
|
/// This data is used to service every query handled by the weather provider and
|
||||||
/// potentially other providers, so we cache it from the DB.
|
/// potentially other providers, so we cache it from the DB.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
@@ -135,24 +162,38 @@ pub(crate) struct DownloadedGeoname {
|
|||||||
/// Longitude in decimal degrees. Expected to be a string in the RS data.
|
/// Longitude in decimal degrees. Expected to be a string in the RS data.
|
||||||
#[serde(deserialize_with = "deserialize_f64_or_default")]
|
#[serde(deserialize_with = "deserialize_f64_or_default")]
|
||||||
pub longitude: f64,
|
pub longitude: f64,
|
||||||
/// List of lowercase names that the place is known by. Despite the word
|
/// List of names that the place is known by. Despite the word "alternate",
|
||||||
/// "alternate", this often includes the place's proper name. This list is
|
/// this often includes the place's proper name. This list is pulled from
|
||||||
/// pulled from the "alternate names" table described in the GeoNames
|
/// the "alternate names" table described in the GeoNames documentation and
|
||||||
/// documentation and included here inline.
|
/// included here inline.
|
||||||
///
|
///
|
||||||
/// NOTE: For ease of implementation, this list should always include a
|
/// NOTE: For ease of implementation, this list should always include a
|
||||||
/// lowercase version of `name` even if the original GeoNames data doesn't
|
/// lowercase version of `name` even if the original GeoNames record doesn't
|
||||||
/// include it as an alternate.
|
/// include it as an alternate.
|
||||||
pub alternate_names: Vec<String>,
|
///
|
||||||
|
/// Version 1 of this field was a `Vec<String>`.
|
||||||
|
pub alternate_names_2: Vec<DownloadedGeonameAlternate>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
pub(crate) struct DownloadedGeonameAlternate {
|
||||||
|
/// Lowercase alternate name.
|
||||||
|
name: String,
|
||||||
|
/// The value of the `iso_language` field for the alternate. This will be
|
||||||
|
/// `None` for the alternate we artificially create for the `name` in the
|
||||||
|
/// corresponding geoname record.
|
||||||
|
iso_language: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SuggestDao<'_> {
|
impl SuggestDao<'_> {
|
||||||
/// Fetches geonames that have at least one name matching the `query`
|
/// Fetches geonames that have at least one name matching the `query`
|
||||||
/// string.
|
/// string.
|
||||||
///
|
///
|
||||||
/// `prefix` determines whether prefix matching is performed. If `true`,
|
/// `match_name_prefix` determines whether prefix matching is performed on
|
||||||
/// returned geonames will have at least one name prefixed by `query`. If
|
/// names that aren't abbreviations and airport codes. When `true`, names
|
||||||
/// `false`, returned geonames will have at least one name equal to `query`.
|
/// that start with `query` will match. When false, names that equal `query`
|
||||||
|
/// will match. Prefix matching is never performed on abbreviations and
|
||||||
|
/// airport codes because we don't currently have a use case for that.
|
||||||
///
|
///
|
||||||
/// `geoname_type` restricts returned geonames to the specified type. `None`
|
/// `geoname_type` restricts returned geonames to the specified type. `None`
|
||||||
/// restricts geonames to cities and regions. There's no way to return
|
/// restricts geonames to cities and regions. There's no way to return
|
||||||
@@ -166,13 +207,20 @@ impl SuggestDao<'_> {
|
|||||||
/// since city and region names are not unique. `filter` is disjunctive: If
|
/// since city and region names are not unique. `filter` is disjunctive: If
|
||||||
/// any item in `filter` matches a geoname, the geoname will be filtered in.
|
/// any item in `filter` matches a geoname, the geoname will be filtered in.
|
||||||
/// If `filter` is empty, all geonames will be filtered out.
|
/// If `filter` is empty, all geonames will be filtered out.
|
||||||
|
///
|
||||||
|
/// The returned matches will include all matching types for a geoname, one
|
||||||
|
/// match per type per geoname. For example, if the query matches both a
|
||||||
|
/// geoname's name and abbreviation, two matches for that geoname will be
|
||||||
|
/// returned: one with a `match_type` of `GeonameMatchType::Name` and one
|
||||||
|
/// with a `match_type` of `GeonameMatchType::Abbreviation`. `prefix` is set
|
||||||
|
/// according to whether the query matched a prefix of the given type.
|
||||||
pub fn fetch_geonames(
|
pub fn fetch_geonames(
|
||||||
&self,
|
&self,
|
||||||
query: &str,
|
query: &str,
|
||||||
prefix: bool,
|
match_name_prefix: bool,
|
||||||
geoname_type: Option<GeonameType>,
|
geoname_type: Option<GeonameType>,
|
||||||
filter: Option<Vec<&Geoname>>,
|
filter: Option<Vec<&Geoname>>,
|
||||||
) -> Result<Vec<Geoname>> {
|
) -> Result<Vec<GeonameMatch>> {
|
||||||
let city_pred = "(g.feature_class = 'P')";
|
let city_pred = "(g.feature_class = 'P')";
|
||||||
let region_pred = "(g.feature_class = 'A' AND g.feature_code = 'ADM1')";
|
let region_pred = "(g.feature_class = 'A' AND g.feature_code = 'ADM1')";
|
||||||
let type_pred = match geoname_type {
|
let type_pred = match geoname_type {
|
||||||
@@ -193,47 +241,67 @@ impl SuggestDao<'_> {
|
|||||||
g.feature_class,
|
g.feature_class,
|
||||||
g.country_code,
|
g.country_code,
|
||||||
g.admin1_code,
|
g.admin1_code,
|
||||||
g.population
|
g.population,
|
||||||
|
a.name != :name AS prefix,
|
||||||
|
(SELECT CASE
|
||||||
|
-- abbreviation
|
||||||
|
WHEN a.iso_language = 'abbr' THEN 1
|
||||||
|
-- airport code
|
||||||
|
WHEN a.iso_language IN ('iata', 'icao', 'faac') THEN 2
|
||||||
|
-- name
|
||||||
|
ELSE 3
|
||||||
|
END
|
||||||
|
) AS match_type
|
||||||
FROM
|
FROM
|
||||||
geonames g
|
geonames g
|
||||||
|
JOIN
|
||||||
|
geonames_alternates a ON g.id = a.geoname_id
|
||||||
WHERE
|
WHERE
|
||||||
g.id IN (
|
{}
|
||||||
SELECT DISTINCT
|
AND CASE :prefix
|
||||||
geoname_id
|
WHEN FALSE THEN a.name = :name
|
||||||
FROM
|
ELSE (a.name = :name OR (
|
||||||
geonames_alternates
|
(a.name BETWEEN :name AND :name || X'FFFF')
|
||||||
WHERE
|
AND match_type = 3
|
||||||
CASE :prefix WHEN FALSE THEN name = :name
|
))
|
||||||
ELSE (name BETWEEN :name AND :name || X'FFFF') END
|
END
|
||||||
)
|
GROUP BY
|
||||||
AND {}
|
g.id, match_type
|
||||||
ORDER BY
|
ORDER BY
|
||||||
g.feature_class = 'P' DESC, g.population DESC, g.id ASC
|
g.feature_class = 'P' DESC, g.population DESC, g.id ASC, a.iso_language ASC
|
||||||
"#,
|
"#,
|
||||||
type_pred
|
type_pred
|
||||||
),
|
),
|
||||||
named_params! {
|
named_params! {
|
||||||
":name": query.to_lowercase(),
|
":name": query.to_lowercase(),
|
||||||
":prefix": prefix,
|
":prefix": match_name_prefix,
|
||||||
},
|
},
|
||||||
|row| -> Result<Option<Geoname>> {
|
|row| -> Result<Option<GeonameMatch>> {
|
||||||
let geoname = Geoname {
|
let g_match = GeonameMatch {
|
||||||
geoname_id: row.get("id")?,
|
geoname: Geoname {
|
||||||
name: row.get("name")?,
|
geoname_id: row.get("id")?,
|
||||||
latitude: row.get("latitude")?,
|
name: row.get("name")?,
|
||||||
longitude: row.get("longitude")?,
|
latitude: row.get("latitude")?,
|
||||||
country_code: row.get("country_code")?,
|
longitude: row.get("longitude")?,
|
||||||
admin1_code: row.get("admin1_code")?,
|
country_code: row.get("country_code")?,
|
||||||
population: row.get("population")?,
|
admin1_code: row.get("admin1_code")?,
|
||||||
|
population: row.get("population")?,
|
||||||
|
},
|
||||||
|
prefix: row.get("prefix")?,
|
||||||
|
match_type: match row.get::<_, i32>("match_type")? {
|
||||||
|
1 => GeonameMatchType::Abbreviation,
|
||||||
|
2 => GeonameMatchType::AirportCode,
|
||||||
|
_ => GeonameMatchType::Name,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
if let Some(geonames) = &filter {
|
if let Some(geonames) = &filter {
|
||||||
geonames
|
geonames
|
||||||
.iter()
|
.iter()
|
||||||
.find(|g| g.has_same_region(&geoname))
|
.find(|g| g.has_same_region(&g_match.geoname))
|
||||||
.map(|_| Ok(Some(geoname)))
|
.map(|_| Ok(Some(g_match)))
|
||||||
.unwrap_or(Ok(None))
|
.unwrap_or(Ok(None))
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(geoname))
|
Ok(Some(g_match))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)?
|
)?
|
||||||
@@ -257,7 +325,7 @@ impl SuggestDao<'_> {
|
|||||||
for attach in attachments {
|
for attach in attachments {
|
||||||
for geoname in &attach.geonames {
|
for geoname in &attach.geonames {
|
||||||
geoname_insert.execute(record_id, geoname)?;
|
geoname_insert.execute(record_id, geoname)?;
|
||||||
for alt in &geoname.alternate_names {
|
for alt in &geoname.alternate_names_2 {
|
||||||
alt_insert.execute(alt, geoname.id)?;
|
alt_insert.execute(alt, geoname.id)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,16 +434,17 @@ impl<'conn> GeonameAlternateInsertStatement<'conn> {
|
|||||||
Ok(Self(conn.prepare(
|
Ok(Self(conn.prepare(
|
||||||
"INSERT INTO geonames_alternates(
|
"INSERT INTO geonames_alternates(
|
||||||
name,
|
name,
|
||||||
geoname_id
|
geoname_id,
|
||||||
|
iso_language
|
||||||
)
|
)
|
||||||
VALUES(?, ?)
|
VALUES(?, ?, ?)
|
||||||
",
|
",
|
||||||
)?))
|
)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute(&mut self, name: &str, geoname_id: i64) -> Result<()> {
|
fn execute(&mut self, a: &DownloadedGeonameAlternate, geoname_id: i64) -> Result<()> {
|
||||||
self.0
|
self.0
|
||||||
.execute((name, geoname_id))
|
.execute((&a.name, geoname_id, &a.iso_language))
|
||||||
.with_context("geoname alternate insert")?;
|
.with_context("geoname alternate insert")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -439,6 +508,9 @@ pub(crate) mod tests {
|
|||||||
"admin1_code": "AL",
|
"admin1_code": "AL",
|
||||||
"population": 200,
|
"population": 200,
|
||||||
"alternate_names": ["waterloo"],
|
"alternate_names": ["waterloo"],
|
||||||
|
"alternate_names_2": [
|
||||||
|
{ "name": "waterloo" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// AL
|
// AL
|
||||||
{
|
{
|
||||||
@@ -452,6 +524,10 @@ pub(crate) mod tests {
|
|||||||
"admin1_code": "AL",
|
"admin1_code": "AL",
|
||||||
"population": 4530315,
|
"population": 4530315,
|
||||||
"alternate_names": ["al", "alabama"],
|
"alternate_names": ["al", "alabama"],
|
||||||
|
"alternate_names_2": [
|
||||||
|
{ "name": "alabama" },
|
||||||
|
{ "name": "al", "iso_language": "abbr" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// Waterloo, IA
|
// Waterloo, IA
|
||||||
{
|
{
|
||||||
@@ -465,6 +541,9 @@ pub(crate) mod tests {
|
|||||||
"admin1_code": "IA",
|
"admin1_code": "IA",
|
||||||
"population": 68460,
|
"population": 68460,
|
||||||
"alternate_names": ["waterloo"],
|
"alternate_names": ["waterloo"],
|
||||||
|
"alternate_names_2": [
|
||||||
|
{ "name": "waterloo" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// IA
|
// IA
|
||||||
{
|
{
|
||||||
@@ -478,6 +557,10 @@ pub(crate) mod tests {
|
|||||||
"admin1_code": "IA",
|
"admin1_code": "IA",
|
||||||
"population": 2955010,
|
"population": 2955010,
|
||||||
"alternate_names": ["ia", "iowa"],
|
"alternate_names": ["ia", "iowa"],
|
||||||
|
"alternate_names_2": [
|
||||||
|
{ "name": "iowa" },
|
||||||
|
{ "name": "ia", "iso_language": "abbr" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// Waterloo (Lake, not a city or region)
|
// Waterloo (Lake, not a city or region)
|
||||||
{
|
{
|
||||||
@@ -490,7 +573,10 @@ pub(crate) mod tests {
|
|||||||
"country_code": "US",
|
"country_code": "US",
|
||||||
"admin1_code": "TX",
|
"admin1_code": "TX",
|
||||||
"population": 0,
|
"population": 0,
|
||||||
"alternate_names": ["waterloo", "waterloo lake"],
|
"alternate_names_2": [
|
||||||
|
{ "name": "waterloo lake" },
|
||||||
|
{ "name": "waterloo", "iso_language": "en" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// New York City
|
// New York City
|
||||||
{
|
{
|
||||||
@@ -503,7 +589,12 @@ pub(crate) mod tests {
|
|||||||
"country_code": "US",
|
"country_code": "US",
|
||||||
"admin1_code": "NY",
|
"admin1_code": "NY",
|
||||||
"population": 8804190,
|
"population": 8804190,
|
||||||
"alternate_names": ["new york city", "new york", "nyc", "ny"],
|
"alternate_names_2": [
|
||||||
|
{ "name": "new york city" },
|
||||||
|
{ "name": "new york", "iso_language": "en" },
|
||||||
|
{ "name": "nyc", "iso_language": "abbr" },
|
||||||
|
{ "name": "ny", "iso_language": "abbr" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// Rochester, NY
|
// Rochester, NY
|
||||||
{
|
{
|
||||||
@@ -516,7 +607,10 @@ pub(crate) mod tests {
|
|||||||
"country_code": "US",
|
"country_code": "US",
|
||||||
"admin1_code": "NY",
|
"admin1_code": "NY",
|
||||||
"population": 209802,
|
"population": 209802,
|
||||||
"alternate_names": ["rochester", "roc"],
|
"alternate_names_2": [
|
||||||
|
{ "name": "rochester" },
|
||||||
|
{ "name": "roc", "iso_language": "iata" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// NY state
|
// NY state
|
||||||
{
|
{
|
||||||
@@ -529,7 +623,43 @@ pub(crate) mod tests {
|
|||||||
"country_code": "US",
|
"country_code": "US",
|
||||||
"admin1_code": "NY",
|
"admin1_code": "NY",
|
||||||
"population": 19274244,
|
"population": 19274244,
|
||||||
"alternate_names": ["ny", "new york"],
|
"alternate_names_2": [
|
||||||
|
{ "name": "new york" },
|
||||||
|
{ "name": "ny", "iso_language": "abbr" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Waco, TX: Has a surprising IATA airport code that's a
|
||||||
|
// common English word and not a prefix of the city name
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"name": "Waco",
|
||||||
|
"latitude": "31.54933",
|
||||||
|
"longitude": "-97.14667",
|
||||||
|
"feature_class": "P",
|
||||||
|
"feature_code": "PPLA2",
|
||||||
|
"country_code": "US",
|
||||||
|
"admin1_code": "TX",
|
||||||
|
"population": 132356,
|
||||||
|
"alternate_names_2": [
|
||||||
|
{ "name": "waco" },
|
||||||
|
{ "name": "act", "iso_language": "iata" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// TX
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"name": "Texas",
|
||||||
|
"latitude": "31.25044",
|
||||||
|
"longitude": "-99.25061",
|
||||||
|
"feature_class": "A",
|
||||||
|
"feature_code": "ADM1",
|
||||||
|
"country_code": "US",
|
||||||
|
"admin1_code": "TX",
|
||||||
|
"population": 22875689,
|
||||||
|
"alternate_names_2": [
|
||||||
|
{ "name": "texas" },
|
||||||
|
{ "name": "tx", "iso_language": "abbr" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// Made-up city with a long name
|
// Made-up city with a long name
|
||||||
{
|
{
|
||||||
@@ -542,7 +672,10 @@ pub(crate) mod tests {
|
|||||||
"country_code": "US",
|
"country_code": "US",
|
||||||
"admin1_code": "NY",
|
"admin1_code": "NY",
|
||||||
"population": 2,
|
"population": 2,
|
||||||
"alternate_names": ["long name", LONG_NAME],
|
"alternate_names_2": [
|
||||||
|
{ "name": "long name" },
|
||||||
|
{ "name": LONG_NAME, "iso_language": "en" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@@ -597,6 +730,18 @@ pub(crate) mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn waco() -> Geoname {
|
||||||
|
Geoname {
|
||||||
|
geoname_id: 9,
|
||||||
|
name: "Waco".to_string(),
|
||||||
|
latitude: 31.54933,
|
||||||
|
longitude: -97.14667,
|
||||||
|
country_code: "US".to_string(),
|
||||||
|
admin1_code: "TX".to_string(),
|
||||||
|
population: 132356,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn long_name_city() -> Geoname {
|
pub(crate) fn long_name_city() -> Geoname {
|
||||||
Geoname {
|
Geoname {
|
||||||
geoname_id: 999,
|
geoname_id: 999,
|
||||||
@@ -657,277 +802,455 @@ pub(crate) mod tests {
|
|||||||
..SuggestIngestionConstraints::all_providers()
|
..SuggestIngestionConstraints::all_providers()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct Test {
|
struct Test {
|
||||||
query: &'static str,
|
query: &'static str,
|
||||||
prefix: bool,
|
match_name_prefix: bool,
|
||||||
geoname_type: Option<GeonameType>,
|
geoname_type: Option<GeonameType>,
|
||||||
filter: Option<Vec<Geoname>>,
|
filter: Option<Vec<Geoname>>,
|
||||||
expected: Vec<Geoname>,
|
expected: Vec<GeonameMatch>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let tests = [
|
let tests = [
|
||||||
Test {
|
Test {
|
||||||
query: "ia",
|
query: "ia",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![ia()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: ia(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ia",
|
query: "ia",
|
||||||
prefix: true,
|
match_name_prefix: true,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![ia()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: ia(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ia",
|
query: "ia",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: Some(vec![waterloo_ia(), waterloo_al()]),
|
filter: Some(vec![waterloo_ia(), waterloo_al()]),
|
||||||
expected: vec![ia()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: ia(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ia",
|
query: "ia",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: Some(vec![waterloo_ia()]),
|
filter: Some(vec![waterloo_ia()]),
|
||||||
expected: vec![ia()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: ia(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ia",
|
query: "ia",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: Some(vec![waterloo_al()]),
|
filter: Some(vec![waterloo_al()]),
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ia",
|
query: "ia",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: Some(GeonameType::City),
|
geoname_type: Some(GeonameType::City),
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ia",
|
query: "ia",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: Some(GeonameType::Region),
|
geoname_type: Some(GeonameType::Region),
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![ia()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: ia(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "iowa",
|
query: "iowa",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![ia()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: ia(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "al",
|
query: "al",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![al()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: al(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
|
// "al" is both a name prefix and an abbreviation.
|
||||||
Test {
|
Test {
|
||||||
query: "al",
|
query: "al",
|
||||||
prefix: true,
|
match_name_prefix: true,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![al()],
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: al(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: true,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: al(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "waterloo",
|
query: "waterloo",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: Some(vec![ia()]),
|
filter: Some(vec![ia()]),
|
||||||
expected: vec![waterloo_ia()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: waterloo_ia(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "waterloo",
|
query: "waterloo",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: Some(vec![al()]),
|
filter: Some(vec![al()]),
|
||||||
expected: vec![waterloo_al()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: waterloo_al(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "waterloo",
|
query: "waterloo",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: Some(vec![ny_state()]),
|
filter: Some(vec![ny_state()]),
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "waterloo",
|
query: "waterloo",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
// Waterloo, IA should be first since it has a larger
|
// Waterloo, IA should be first since it has a larger
|
||||||
// population.
|
// population.
|
||||||
expected: vec![waterloo_ia(), waterloo_al()],
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: waterloo_ia(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: waterloo_al(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "water",
|
query: "water",
|
||||||
prefix: true,
|
match_name_prefix: true,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![waterloo_ia(), waterloo_al()],
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: waterloo_ia(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: true,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: waterloo_al(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "water",
|
query: "water",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ny",
|
query: "ny",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
// NYC should be first since cities are ordered before regions.
|
// NYC should be first since cities are ordered before regions.
|
||||||
expected: vec![nyc(), ny_state()],
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: nyc(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: ny_state(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ny",
|
query: "ny",
|
||||||
prefix: true,
|
match_name_prefix: true,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![nyc(), ny_state()],
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: nyc(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: ny_state(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ny",
|
query: "ny",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: Some(vec![nyc()]),
|
filter: Some(vec![nyc()]),
|
||||||
expected: vec![nyc(), ny_state()],
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: nyc(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: ny_state(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ny",
|
query: "ny",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: Some(vec![ny_state()]),
|
filter: Some(vec![ny_state()]),
|
||||||
expected: vec![nyc(), ny_state()],
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: nyc(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: ny_state(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ny",
|
query: "ny",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: Some(GeonameType::City),
|
geoname_type: Some(GeonameType::City),
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![nyc()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: nyc(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "ny",
|
query: "ny",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: Some(GeonameType::Region),
|
geoname_type: Some(GeonameType::Region),
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![ny_state()],
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: ny_state(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "NeW YoRk",
|
query: "NeW YoRk",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![nyc(), ny_state()],
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: nyc(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: ny_state(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "NY",
|
query: "NY",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![nyc(), ny_state()],
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: nyc(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: ny_state(),
|
||||||
|
match_type: GeonameMatchType::Abbreviation,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "new",
|
query: "new",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "new",
|
query: "new",
|
||||||
prefix: true,
|
match_name_prefix: true,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![nyc(), ny_state()],
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: nyc(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: true,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: ny_state(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "new york foo",
|
query: "new york foo",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "new york foo",
|
query: "new york foo",
|
||||||
prefix: true,
|
match_name_prefix: true,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "new foo",
|
query: "new foo",
|
||||||
prefix: true,
|
match_name_prefix: true,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "foo new york",
|
query: "foo new york",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "foo new york",
|
query: "foo new york",
|
||||||
prefix: true,
|
match_name_prefix: true,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "foo new",
|
query: "foo new",
|
||||||
prefix: true,
|
match_name_prefix: true,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![],
|
expected: vec![],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: "long name",
|
query: "roc",
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![Geoname {
|
expected: vec![GeonameMatch {
|
||||||
geoname_id: 999,
|
geoname: rochester(),
|
||||||
name: "Long Name".to_string(),
|
match_type: GeonameMatchType::AirportCode,
|
||||||
latitude: 38.06084,
|
prefix: false,
|
||||||
longitude: -97.92977,
|
}],
|
||||||
country_code: "US".to_string(),
|
},
|
||||||
admin1_code: "NY".to_string(),
|
// "roc" is both a name prefix and an airport code.
|
||||||
population: 2,
|
Test {
|
||||||
|
query: "roc",
|
||||||
|
match_name_prefix: true,
|
||||||
|
geoname_type: None,
|
||||||
|
filter: None,
|
||||||
|
expected: vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: rochester(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: true,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: rochester(),
|
||||||
|
match_type: GeonameMatchType::AirportCode,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Test {
|
||||||
|
query: "long name",
|
||||||
|
match_name_prefix: false,
|
||||||
|
geoname_type: None,
|
||||||
|
filter: None,
|
||||||
|
expected: vec![GeonameMatch {
|
||||||
|
geoname: long_name_city(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: false,
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
query: LONG_NAME,
|
query: LONG_NAME,
|
||||||
prefix: false,
|
match_name_prefix: false,
|
||||||
geoname_type: None,
|
geoname_type: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
expected: vec![Geoname {
|
expected: vec![GeonameMatch {
|
||||||
geoname_id: 999,
|
geoname: long_name_city(),
|
||||||
name: "Long Name".to_string(),
|
match_type: GeonameMatchType::Name,
|
||||||
latitude: 38.06084,
|
prefix: false,
|
||||||
longitude: -97.92977,
|
|
||||||
country_code: "US".to_string(),
|
|
||||||
admin1_code: "NY".to_string(),
|
|
||||||
population: 2,
|
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
store.read(|dao| {
|
store.read(|dao| {
|
||||||
for t in tests {
|
for t in tests {
|
||||||
let gs = t.filter.unwrap_or_default();
|
let gs = t.filter.clone().unwrap_or_default();
|
||||||
let gs_refs: Vec<_> = gs.iter().collect();
|
let gs_refs: Vec<_> = gs.iter().collect();
|
||||||
let filters = if gs_refs.is_empty() {
|
let filters = if gs_refs.is_empty() {
|
||||||
None
|
None
|
||||||
@@ -935,8 +1258,15 @@ pub(crate) mod tests {
|
|||||||
Some(gs_refs)
|
Some(gs_refs)
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dao.fetch_geonames(t.query, t.prefix, t.geoname_type, filters)?,
|
dao.fetch_geonames(
|
||||||
t.expected
|
t.query,
|
||||||
|
t.match_name_prefix,
|
||||||
|
t.geoname_type.clone(),
|
||||||
|
filters
|
||||||
|
)?,
|
||||||
|
t.expected,
|
||||||
|
"Test: {:?}",
|
||||||
|
t
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1040,7 +1370,18 @@ pub(crate) mod tests {
|
|||||||
store.read(|dao| {
|
store.read(|dao| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dao.fetch_geonames("waterloo", false, None, None)?,
|
dao.fetch_geonames("waterloo", false, None, None)?,
|
||||||
vec![waterloo_ia(), waterloo_al()],
|
vec![
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: waterloo_ia(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
GeonameMatch {
|
||||||
|
geoname: waterloo_al(),
|
||||||
|
match_type: GeonameMatchType::Name,
|
||||||
|
prefix: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|||||||
27
third_party/rust/suggest/src/schema.rs
vendored
27
third_party/rust/suggest/src/schema.rs
vendored
@@ -19,7 +19,7 @@ use sql_support::{
|
|||||||
/// [`SuggestConnectionInitializer::upgrade_from`].
|
/// [`SuggestConnectionInitializer::upgrade_from`].
|
||||||
/// a. If suggestions should be re-ingested after the migration, call `clear_database()` inside
|
/// a. If suggestions should be re-ingested after the migration, call `clear_database()` inside
|
||||||
/// the migration.
|
/// the migration.
|
||||||
pub const VERSION: u32 = 28;
|
pub const VERSION: u32 = 29;
|
||||||
|
|
||||||
/// The current Suggest database schema.
|
/// The current Suggest database schema.
|
||||||
pub const SQL: &str = "
|
pub const SQL: &str = "
|
||||||
@@ -207,6 +207,10 @@ CREATE INDEX geonames_feature_code ON geonames(feature_code);
|
|||||||
CREATE TABLE geonames_alternates(
|
CREATE TABLE geonames_alternates(
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
geoname_id INTEGER NOT NULL,
|
geoname_id INTEGER NOT NULL,
|
||||||
|
-- The value of the `iso_language` field for the alternate. This will be
|
||||||
|
-- null for the alternate we artificially create for the `name` in the
|
||||||
|
-- corresponding geoname record.
|
||||||
|
iso_language TEXT,
|
||||||
PRIMARY KEY (name, geoname_id),
|
PRIMARY KEY (name, geoname_id),
|
||||||
FOREIGN KEY(geoname_id) REFERENCES geonames(id) ON DELETE CASCADE
|
FOREIGN KEY(geoname_id) REFERENCES geonames(id) ON DELETE CASCADE
|
||||||
) WITHOUT ROWID;
|
) WITHOUT ROWID;
|
||||||
@@ -550,6 +554,27 @@ CREATE INDEX geonames_feature_code ON geonames(feature_code);
|
|||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
28 => {
|
||||||
|
// Add `iso_language` column to `geonames_alternates`. Clear the
|
||||||
|
// database so geonames are reingested.
|
||||||
|
clear_database(tx)?;
|
||||||
|
tx.execute_batch(
|
||||||
|
"
|
||||||
|
DROP TABLE geonames_alternates;
|
||||||
|
CREATE TABLE geonames_alternates(
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
geoname_id INTEGER NOT NULL,
|
||||||
|
-- The value of the `iso_language` field for the alternate. This will be
|
||||||
|
-- null for the alternate we artificially create for the `name` in the
|
||||||
|
-- corresponding geoname record.
|
||||||
|
iso_language TEXT,
|
||||||
|
PRIMARY KEY (name, geoname_id),
|
||||||
|
FOREIGN KEY(geoname_id) REFERENCES geonames(id) ON DELETE CASCADE
|
||||||
|
) WITHOUT ROWID;
|
||||||
|
",
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
_ => Err(open_database::Error::IncompatibleVersion(version)),
|
_ => Err(open_database::Error::IncompatibleVersion(version)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
third_party/rust/suggest/src/util.rs
vendored
16
third_party/rust/suggest/src/util.rs
vendored
@@ -47,7 +47,7 @@ pub fn full_keyword(query: &str, keywords: &[impl AsRef<str>]) -> String {
|
|||||||
/// "Chunks" are non-overlapping subslices of the parent slice as described in
|
/// "Chunks" are non-overlapping subslices of the parent slice as described in
|
||||||
/// [`slice::chunks()`].
|
/// [`slice::chunks()`].
|
||||||
///
|
///
|
||||||
/// IMPORTANT: This function potentially does an exponential amount of work! You
|
/// WARNING: This function potentially does an exponential amount of work! You
|
||||||
/// should always be careful to prune the traversal space by returning `None`
|
/// should always be careful to prune the traversal space by returning `None`
|
||||||
/// from your mappper function, as described further below, when a chunk does
|
/// from your mappper function, as described further below, when a chunk does
|
||||||
/// not match what you are searching for.
|
/// not match what you are searching for.
|
||||||
@@ -55,15 +55,17 @@ pub fn full_keyword(query: &str, keywords: &[impl AsRef<str>]) -> String {
|
|||||||
/// `max_chunk_size` controls the maximum chunk size (in number of words), which
|
/// `max_chunk_size` controls the maximum chunk size (in number of words), which
|
||||||
/// influences the branching factor at each step in the traversal.
|
/// influences the branching factor at each step in the traversal.
|
||||||
///
|
///
|
||||||
/// At each traversal step, the filter-map function is passed the chunk at that
|
/// At each traversal step, the filter-map function is called like:
|
||||||
/// step and the chunk's index in the parent `words` slice. The function can map
|
/// `f(chunk, chunk_index, chunk_size, path)`.
|
||||||
|
///
|
||||||
|
/// `chunk` is the chunk at that step, `chunk_index` is its index in the parent
|
||||||
|
/// `words` slice, and `chunk_size` is its size in words. The function can map
|
||||||
/// the chunk to one or more values. Each value expands the branching factor at
|
/// the chunk to one or more values. Each value expands the branching factor at
|
||||||
/// the current step by `max_chunk_size`. In other words, the branching factor
|
/// the current step by `max_chunk_size`. In other words, the branching factor
|
||||||
/// at a given traversal step is `max_chunk_size` multiplied by the number of
|
/// at a given traversal step is `max_chunk_size` multiplied by the number of
|
||||||
/// values returned by the filter-map function at that step. The traversed path
|
/// values returned by the filter-map function at that step. `path` is the path
|
||||||
/// of mapped values at that step is also passed to the filter-map function.
|
/// of mapped values that has been travsersed at that step: a sequence of mapped
|
||||||
/// Each path is a sequence of chunks in the parent `words` slice except the
|
/// values corresponding to chunks in the parent `words` slice.
|
||||||
/// chunks have been replaced by mapped values from the filter-map function.
|
|
||||||
///
|
///
|
||||||
/// The filter-map function can return `None` to halt traversal at the current
|
/// The filter-map function can return `None` to halt traversal at the current
|
||||||
/// step. Returning `None` sets the branching factor at that step to zero,
|
/// step. Returning `None` sets the branching factor at that step to zero,
|
||||||
|
|||||||
508
third_party/rust/suggest/src/weather.rs
vendored
508
third_party/rust/suggest/src/weather.rs
vendored
@@ -15,7 +15,7 @@ use crate::{
|
|||||||
KeywordInsertStatement, KeywordMetricsInsertStatement, SuggestDao,
|
KeywordInsertStatement, KeywordMetricsInsertStatement, SuggestDao,
|
||||||
SuggestionInsertStatement, DEFAULT_SUGGESTION_SCORE,
|
SuggestionInsertStatement, DEFAULT_SUGGESTION_SCORE,
|
||||||
},
|
},
|
||||||
geoname::{Geoname, GeonameType},
|
geoname::{GeonameMatch, GeonameType},
|
||||||
metrics::MetricsContext,
|
metrics::MetricsContext,
|
||||||
provider::SuggestionProvider,
|
provider::SuggestionProvider,
|
||||||
rs::{Client, Record, SuggestRecordId},
|
rs::{Client, Record, SuggestRecordId},
|
||||||
@@ -101,6 +101,7 @@ impl SuggestDao<'_> {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut matches =
|
let mut matches =
|
||||||
|
// Step 2: Parse the query words into a list of token paths.
|
||||||
filter_map_chunks::<Token>(&words, max_chunk_size, |chunk, chunk_i, path| {
|
filter_map_chunks::<Token>(&words, max_chunk_size, |chunk, chunk_i, path| {
|
||||||
// Match the chunk to token types that haven't already been matched
|
// Match the chunk to token types that haven't already been matched
|
||||||
// in this path. `all_tokens` will remain `None` until a token is
|
// in this path. `all_tokens` will remain `None` until a token is
|
||||||
@@ -112,10 +113,7 @@ impl SuggestDao<'_> {
|
|||||||
TokenType::WeatherKeyword,
|
TokenType::WeatherKeyword,
|
||||||
] {
|
] {
|
||||||
if !path.iter().any(|t| t.token_type() == tt) {
|
if !path.iter().any(|t| t.token_type() == tt) {
|
||||||
// Allow prefix matching if this isn't the first chunk in
|
let mut tokens = self.match_weather_tokens(tt, path, chunk, chunk_i == 0)?;
|
||||||
// the path.
|
|
||||||
let mut tokens =
|
|
||||||
self.match_weather_tokens(tt, path, chunk, chunk_i == 0)?;
|
|
||||||
if !tokens.is_empty() {
|
if !tokens.is_empty() {
|
||||||
let mut ts = all_tokens.take().unwrap_or_default();
|
let mut ts = all_tokens.take().unwrap_or_default();
|
||||||
ts.append(&mut tokens);
|
ts.append(&mut tokens);
|
||||||
@@ -127,8 +125,8 @@ impl SuggestDao<'_> {
|
|||||||
Ok(all_tokens)
|
Ok(all_tokens)
|
||||||
})?
|
})?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
// Map each token path to a tuple that represents a matched city,
|
// Step 3: Map each token path to a tuple that represents a matched
|
||||||
// region, and keyword (each optional). Since paths are vecs,
|
// city, region, and keyword (each optional). Since paths are vecs,
|
||||||
// they're ordered, so we may end up with duplicate tuples after
|
// they're ordered, so we may end up with duplicate tuples after
|
||||||
// this step. e.g., the paths `[<Waterloo IA>, <IA>]` and `[<IA>,
|
// this step. e.g., the paths `[<Waterloo IA>, <IA>]` and `[<IA>,
|
||||||
// <Waterloo IA>]` map to the same match.
|
// <Waterloo IA>]` map to the same match.
|
||||||
@@ -149,17 +147,34 @@ impl SuggestDao<'_> {
|
|||||||
match_tuple
|
match_tuple
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
// Dedupe the matches by collecting them into a set.
|
// Step 4: Discard matches that don't have the right combination of
|
||||||
|
// tokens or that are otherwise invalid. Along with step 2, this is
|
||||||
|
// the core of the matching logic. In general, allow a match if it
|
||||||
|
// has (a) a city name typed in full or (b) a weather keyword at
|
||||||
|
// least as long as the config's min keyword length, since that
|
||||||
|
// indicates a weather intent.
|
||||||
|
.filter(|(city_match, region_match, kw_match)| {
|
||||||
|
match (city_match, region_match, kw_match) {
|
||||||
|
(None, None, Some(_)) => true,
|
||||||
|
(None, _, None) | (None, Some(_), Some(_)) => false,
|
||||||
|
(Some(city), region, kw) => {
|
||||||
|
(city.match_type.is_name() && !city.prefix)
|
||||||
|
// Allow city abbreviations without a weather
|
||||||
|
// keyword but only if the region was typed in full.
|
||||||
|
|| (city.match_type.is_abbreviation()
|
||||||
|
&& !city.prefix
|
||||||
|
&& region.as_ref().map(|r| !r.prefix).unwrap_or(false))
|
||||||
|
|| kw.as_ref().map(|k| k.is_min_keyword_length).unwrap_or(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Step 5: Map the match objects to their underlying values.
|
||||||
|
.map(|(city, region, kw)| {
|
||||||
|
(city.map(|c| c.geoname), region.map(|r| r.geoname), kw.map(|k| k.keyword))
|
||||||
|
})
|
||||||
|
// Step 6: Dedupe the values by collecting them into a set.
|
||||||
.collect::<HashSet<_>>()
|
.collect::<HashSet<_>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
// Filter out matches that don't have the right combination of
|
|
||||||
// tokens.
|
|
||||||
.filter(|(city, region, kw)| {
|
|
||||||
!matches!(
|
|
||||||
(city, region, kw),
|
|
||||||
(None, _, None) | (None, Some(_), Some(_))
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// Sort the matches so cities with larger populations are first.
|
// Sort the matches so cities with larger populations are first.
|
||||||
@@ -201,9 +216,11 @@ impl SuggestDao<'_> {
|
|||||||
match token_type {
|
match token_type {
|
||||||
TokenType::City => {
|
TokenType::City => {
|
||||||
// Fetch matching cities, and filter them to regions we've
|
// Fetch matching cities, and filter them to regions we've
|
||||||
// already matched in this path. Allow prefix matching for
|
// already matched in this path.
|
||||||
// chunks after the first.
|
let regions: Vec<_> = path
|
||||||
let regions: Vec<_> = path.iter().filter_map(|t| t.region()).collect();
|
.iter()
|
||||||
|
.filter_map(|t| t.region().map(|m| &m.geoname))
|
||||||
|
.collect();
|
||||||
Ok(self
|
Ok(self
|
||||||
.fetch_geonames(
|
.fetch_geonames(
|
||||||
candidate,
|
candidate,
|
||||||
@@ -221,9 +238,11 @@ impl SuggestDao<'_> {
|
|||||||
}
|
}
|
||||||
TokenType::Region => {
|
TokenType::Region => {
|
||||||
// Fetch matching regions, and filter them to cities we've
|
// Fetch matching regions, and filter them to cities we've
|
||||||
// already matched in this patch. Allow prefix matching for
|
// already matched in this patch.
|
||||||
// chunks after the first.
|
let cities: Vec<_> = path
|
||||||
let cities: Vec<_> = path.iter().filter_map(|t| t.city()).collect();
|
.iter()
|
||||||
|
.filter_map(|t| t.city().map(|m| &m.geoname))
|
||||||
|
.collect();
|
||||||
Ok(self
|
Ok(self
|
||||||
.fetch_geonames(
|
.fetch_geonames(
|
||||||
candidate,
|
candidate,
|
||||||
@@ -240,18 +259,29 @@ impl SuggestDao<'_> {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
TokenType::WeatherKeyword => {
|
TokenType::WeatherKeyword => {
|
||||||
// Fetch matching keywords.
|
// Fetch matching keywords. `min_keyword_length == 0` in the
|
||||||
|
// config means that the config doesn't allow prefix matching.
|
||||||
|
// `min_keyword_length > 0` means that the keyword must be at
|
||||||
|
// least that long when there's not already a city name present
|
||||||
|
// in the query.
|
||||||
let len = self.weather_cache().min_keyword_length;
|
let len = self.weather_cache().min_keyword_length;
|
||||||
if is_first_chunk && (candidate.len() as i32) < len {
|
if is_first_chunk && (candidate.len() as i32) < len {
|
||||||
// The chunk is first and it's too short.
|
// The candidate is the first term in the query and it's too
|
||||||
|
// short.
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
} else {
|
} else {
|
||||||
// Allow arbitrary prefix matching if the chunk isn't first
|
// Do arbitrary prefix matching if the candidate isn't the
|
||||||
// or if prefix matching is allowed.
|
// first term in the query or if the config allows prefix
|
||||||
|
// matching.
|
||||||
Ok(self
|
Ok(self
|
||||||
.match_weather_keywords(candidate, !is_first_chunk || len > 0)?
|
.match_weather_keywords(candidate, !is_first_chunk || len > 0)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Token::WeatherKeyword)
|
.map(|keyword| {
|
||||||
|
Token::WeatherKeyword(WeatherKeywordMatch {
|
||||||
|
keyword,
|
||||||
|
is_min_keyword_length: (len as usize) <= candidate.len(),
|
||||||
|
})
|
||||||
|
})
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,7 +293,8 @@ impl SuggestDao<'_> {
|
|||||||
r#"
|
r#"
|
||||||
SELECT
|
SELECT
|
||||||
k.keyword,
|
k.keyword,
|
||||||
s.score
|
s.score,
|
||||||
|
k.keyword != :keyword AS matched_prefix
|
||||||
FROM
|
FROM
|
||||||
suggestions s
|
suggestions s
|
||||||
JOIN
|
JOIN
|
||||||
@@ -401,20 +432,20 @@ enum TokenType {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum Token {
|
enum Token {
|
||||||
City(Geoname),
|
City(GeonameMatch),
|
||||||
Region(Geoname),
|
Region(GeonameMatch),
|
||||||
WeatherKeyword(String),
|
WeatherKeyword(WeatherKeywordMatch),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Token {
|
impl Token {
|
||||||
fn city(&self) -> Option<&Geoname> {
|
fn city(&self) -> Option<&GeonameMatch> {
|
||||||
match self {
|
match self {
|
||||||
Self::City(g) => Some(g),
|
Self::City(g) => Some(g),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn region(&self) -> Option<&Geoname> {
|
fn region(&self) -> Option<&GeonameMatch> {
|
||||||
match self {
|
match self {
|
||||||
Self::Region(g) => Some(g),
|
Self::Region(g) => Some(g),
|
||||||
_ => None,
|
_ => None,
|
||||||
@@ -430,10 +461,18 @@ impl Token {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
|
||||||
|
struct WeatherKeywordMatch {
|
||||||
|
keyword: String,
|
||||||
|
is_min_keyword_length: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{geoname, store::tests::TestStore, testing::*, SuggestIngestionConstraints};
|
use crate::{
|
||||||
|
geoname, geoname::Geoname, store::tests::TestStore, testing::*, SuggestIngestionConstraints,
|
||||||
|
};
|
||||||
|
|
||||||
impl From<Geoname> for Suggestion {
|
impl From<Geoname> for Suggestion {
|
||||||
fn from(g: Geoname) -> Self {
|
fn from(g: Geoname) -> Self {
|
||||||
@@ -485,8 +524,8 @@ mod tests {
|
|||||||
"weather-1",
|
"weather-1",
|
||||||
json!({
|
json!({
|
||||||
// min_keyword_length > 0 means prefixes are allowed.
|
// min_keyword_length > 0 means prefixes are allowed.
|
||||||
"min_keyword_length": 3,
|
"min_keyword_length": 5,
|
||||||
"keywords": ["ab", "xyz", "weather"],
|
"keywords": ["ab", "xyz", "cdefg", "weather"],
|
||||||
"max_keyword_length": "weather".len(),
|
"max_keyword_length": "weather".len(),
|
||||||
"max_keyword_word_count": 1,
|
"max_keyword_word_count": 1,
|
||||||
"score": 0.24
|
"score": 0.24
|
||||||
@@ -500,30 +539,36 @@ mod tests {
|
|||||||
|
|
||||||
let no_matches = [
|
let no_matches = [
|
||||||
// doesn't match any keyword
|
// doesn't match any keyword
|
||||||
"xab",
|
"ab123",
|
||||||
"abx",
|
"123ab",
|
||||||
"xxyz",
|
"xyz12",
|
||||||
"xyzx",
|
"12xyz",
|
||||||
|
"xcdefg",
|
||||||
|
"cdefgx",
|
||||||
|
"x cdefg",
|
||||||
|
"cdefg x",
|
||||||
"weatherx",
|
"weatherx",
|
||||||
"xweather",
|
"xweather",
|
||||||
"xwea",
|
"xweat",
|
||||||
|
"weatx",
|
||||||
"x weather",
|
"x weather",
|
||||||
" weather x",
|
" weather x",
|
||||||
"weather foo",
|
"weather foo",
|
||||||
"foo weather",
|
"foo weather",
|
||||||
// too short
|
// too short
|
||||||
"xy",
|
|
||||||
"ab",
|
"ab",
|
||||||
|
"xyz",
|
||||||
|
"cdef",
|
||||||
"we",
|
"we",
|
||||||
|
"wea",
|
||||||
|
"weat",
|
||||||
];
|
];
|
||||||
for q in no_matches {
|
for q in no_matches {
|
||||||
assert_eq!(store.fetch_suggestions(SuggestionQuery::weather(q)), vec![]);
|
assert_eq!(store.fetch_suggestions(SuggestionQuery::weather(q)), vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let matches = [
|
let matches = [
|
||||||
"xyz",
|
"cdefg",
|
||||||
"wea",
|
|
||||||
"weat",
|
|
||||||
"weath",
|
"weath",
|
||||||
"weathe",
|
"weathe",
|
||||||
"weather",
|
"weather",
|
||||||
@@ -602,7 +647,7 @@ mod tests {
|
|||||||
"weather-1",
|
"weather-1",
|
||||||
json!({
|
json!({
|
||||||
"keywords": ["ab", "xyz", "weather"],
|
"keywords": ["ab", "xyz", "weather"],
|
||||||
"min_keyword_length": 3,
|
"min_keyword_length": 5,
|
||||||
"max_keyword_length": "weather".len(),
|
"max_keyword_length": "weather".len(),
|
||||||
"max_keyword_word_count": 1,
|
"max_keyword_word_count": 1,
|
||||||
"score": 0.24
|
"score": 0.24
|
||||||
@@ -615,6 +660,244 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let tests: &[(&str, Vec<Suggestion>)] = &[
|
let tests: &[(&str, Vec<Suggestion>)] = &[
|
||||||
|
(
|
||||||
|
"act",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act w",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act we",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act wea",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act weat",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
// `min_keyword_length` = 5, so there should be a match.
|
||||||
|
"act weath",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act weathe",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act weather",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"weather a",
|
||||||
|
// The made-up long-name city starts with A.
|
||||||
|
vec![geoname::tests::long_name_city().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"weather ac",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"weather act",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act t",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act tx",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act tx w",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act tx we",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act tx wea",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act tx weat",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
// `min_keyword_length` = 5, so there should be a match.
|
||||||
|
"act tx weath",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act tx weathe",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act tx weather",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tx a",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tx ac",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tx act",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tx act w",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tx act we",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tx act wea",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tx act weat",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
// `min_keyword_length` = 5, so there should be a match.
|
||||||
|
"tx act weath",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tx act weathe",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tx act weather",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act te",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act tex",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act texa",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act texas",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act texas w",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act texas we",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act texas wea",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act texas weat",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
// `min_keyword_length` = 5, so there should be a match.
|
||||||
|
"act texas weath",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act texas weathe",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"act texas weather",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"texas a",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"texas ac",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"texas act",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"texas act w",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"texas act we",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"texas act wea",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"texas act weat",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
// `min_keyword_length` = 5, so there should be a match.
|
||||||
|
"texas act weath",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"texas act weathe",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"texas act weather",
|
||||||
|
vec![geoname::tests::waco().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ia w",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ia wa",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ia wat",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ia wate",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ia water",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ia waterl",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ia waterlo",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"waterloo",
|
"waterloo",
|
||||||
vec![
|
vec![
|
||||||
@@ -624,10 +907,26 @@ mod tests {
|
|||||||
geoname::tests::waterloo_al().into(),
|
geoname::tests::waterloo_al().into(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"waterloo i",
|
||||||
|
vec![geoname::tests::waterloo_ia().into()],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"waterloo ia",
|
"waterloo ia",
|
||||||
vec![geoname::tests::waterloo_ia().into()],
|
vec![geoname::tests::waterloo_ia().into()],
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"waterloo io",
|
||||||
|
vec![geoname::tests::waterloo_ia().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"waterloo iow",
|
||||||
|
vec![geoname::tests::waterloo_ia().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"waterloo iowa",
|
||||||
|
vec![geoname::tests::waterloo_ia().into()],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"ia waterloo",
|
"ia waterloo",
|
||||||
vec![geoname::tests::waterloo_ia().into()],
|
vec![geoname::tests::waterloo_ia().into()],
|
||||||
@@ -642,6 +941,22 @@ mod tests {
|
|||||||
),
|
),
|
||||||
("waterloo ia al", vec![]),
|
("waterloo ia al", vec![]),
|
||||||
("waterloo ny", vec![]),
|
("waterloo ny", vec![]),
|
||||||
|
(
|
||||||
|
"ia",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"iowa",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"al",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"alabama",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"new york",
|
"new york",
|
||||||
vec![geoname::tests::nyc().into()],
|
vec![geoname::tests::nyc().into()],
|
||||||
@@ -655,6 +970,34 @@ mod tests {
|
|||||||
vec![geoname::tests::nyc().into()],
|
vec![geoname::tests::nyc().into()],
|
||||||
),
|
),
|
||||||
("ny ny ny", vec![]),
|
("ny ny ny", vec![]),
|
||||||
|
(
|
||||||
|
"ny n",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny ne",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny new",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny new ",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny new y",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny new yo",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny new yor",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"ny new york",
|
"ny new york",
|
||||||
vec![geoname::tests::nyc().into()],
|
vec![geoname::tests::nyc().into()],
|
||||||
@@ -671,6 +1014,31 @@ mod tests {
|
|||||||
"ny weather",
|
"ny weather",
|
||||||
vec![geoname::tests::nyc().into()],
|
vec![geoname::tests::nyc().into()],
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"ny w",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny we",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny wea",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny weat",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
// `min_keyword_length` = 5, so there should be a match.
|
||||||
|
"ny weath",
|
||||||
|
vec![geoname::tests::nyc().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny weathe",
|
||||||
|
vec![geoname::tests::nyc().into()],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"weather ny ny",
|
"weather ny ny",
|
||||||
vec![geoname::tests::nyc().into()],
|
vec![geoname::tests::nyc().into()],
|
||||||
@@ -764,6 +1132,50 @@ mod tests {
|
|||||||
("waterloo weather foo", vec![]),
|
("waterloo weather foo", vec![]),
|
||||||
("foo waterloo", vec![]),
|
("foo waterloo", vec![]),
|
||||||
("foo waterloo weather", vec![]),
|
("foo waterloo weather", vec![]),
|
||||||
|
(
|
||||||
|
"ny",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"nyc",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"roc",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"nyc ny",
|
||||||
|
vec![geoname::tests::nyc().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny nyc",
|
||||||
|
vec![geoname::tests::nyc().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"roc ny",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ny roc",
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"nyc weather",
|
||||||
|
vec![geoname::tests::nyc().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"weather nyc",
|
||||||
|
vec![geoname::tests::nyc().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"roc weather",
|
||||||
|
vec![geoname::tests::rochester().into()],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"weather roc",
|
||||||
|
vec![geoname::tests::rochester().into()],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
geoname::tests::LONG_NAME,
|
geoname::tests::LONG_NAME,
|
||||||
vec![geoname::tests::long_name_city().into()],
|
vec![geoname::tests::long_name_city().into()],
|
||||||
@@ -1044,7 +1456,9 @@ mod tests {
|
|||||||
for (query, expected_suggestions) in tests {
|
for (query, expected_suggestions) in tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&store.fetch_suggestions(SuggestionQuery::weather(query)),
|
&store.fetch_suggestions(SuggestionQuery::weather(query)),
|
||||||
expected_suggestions
|
expected_suggestions,
|
||||||
|
"Query: {:?}",
|
||||||
|
query
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user