├── .env.template
├── .gitignore
├── .gitlab-ci.yml
├── .idea
├── misc.xml
├── modules.xml
└── vcs.xml
├── Cargo.lock
├── Cargo.toml
├── README.md
├── build.rs
├── geofancy-rust.iml
├── proto
└── geofancy.proto
└── src
├── geofancy.rs
├── geofancy_server.rs
├── main.rs
└── tile38_client.rs
/.env.template:
--------------------------------------------------------------------------------
1 | # grpc server
2 | GRPC_SERVER_PORT=xxxx
3 | GRPC_SERVER_USE_TLS=false
4 |
5 | #tile38 connection
6 | TILE38_CONNECTION=redis://xxxxxxx:xxxx/x
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### JetBrains template
2 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
3 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
4 |
5 | # User-specific stuff:
6 | .idea/**/workspace.xml
7 | .idea/**/tasks.xml
8 | .idea/dictionaries
9 |
10 | # Sensitive or high-churn files:
11 | .idea/**/dataSources/
12 | .idea/**/dataSources.ids
13 | .idea/**/dataSources.local.xml
14 | .idea/**/sqlDataSources.xml
15 | .idea/**/dynamic.xml
16 | .idea/**/uiDesigner.xml
17 |
18 | # JIRA plugin
19 | atlassian-ide-plugin.xml
20 |
21 | ### Rust template
22 | # Generated by Cargo
23 | # will have compiled files and executables
24 | /target/
25 | **/*.rs.bk
26 | .env
27 |
28 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
29 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
30 | # Cargo.lock
31 |
32 | # These are backup files generated by rustfmt
33 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | # Official language image. Look for the different tagged releases at:
2 | # https://hub.docker.com/r/library/rust/tags/
3 | image: "rust:latest"
4 |
5 | # Optional: Pick zero or more services to be used on all builds.
6 | # Only needed when using a docker container to run your tests in.
7 | # Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service
8 | services:
9 | - tile38/tile38:latest
10 | # - redis:latest
11 | # - postgres:latest
12 |
13 | before_script:
14 | # install unzip
15 | - apt update -yqq
16 | - apt install -yqq unzip
17 | # install protoc
18 | - curl -OL https://github.com/google/protobuf/releases/download/v3.5.1/protoc-3.5.1-linux-x86_64.zip
19 | - unzip protoc-3.5.1-linux-x86_64.zip -d protoc3
20 | - mv protoc3/bin/* /usr/local/bin/
21 | - mv protoc3/include/* /usr/local/include/
22 |
23 | # Use cargo to test the project
24 | test:cargo:
25 | script:
26 | - rustc --version && cargo --version # Print version info for debugging
27 | - cargo test --all --verbose
28 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "addr2line"
7 | version = "0.22.0"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
10 | dependencies = [
11 | "gimli",
12 | ]
13 |
14 | [[package]]
15 | name = "adler"
16 | version = "1.0.2"
17 | source = "registry+https://github.com/rust-lang/crates.io-index"
18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
19 |
20 | [[package]]
21 | name = "aho-corasick"
22 | version = "1.1.3"
23 | source = "registry+https://github.com/rust-lang/crates.io-index"
24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
25 | dependencies = [
26 | "memchr",
27 | ]
28 |
29 | [[package]]
30 | name = "anyhow"
31 | version = "1.0.86"
32 | source = "registry+https://github.com/rust-lang/crates.io-index"
33 | checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
34 |
35 | [[package]]
36 | name = "async-stream"
37 | version = "0.3.5"
38 | source = "registry+https://github.com/rust-lang/crates.io-index"
39 | checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
40 | dependencies = [
41 | "async-stream-impl",
42 | "futures-core",
43 | "pin-project-lite",
44 | ]
45 |
46 | [[package]]
47 | name = "async-stream-impl"
48 | version = "0.3.5"
49 | source = "registry+https://github.com/rust-lang/crates.io-index"
50 | checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
51 | dependencies = [
52 | "proc-macro2",
53 | "quote",
54 | "syn",
55 | ]
56 |
57 | [[package]]
58 | name = "async-trait"
59 | version = "0.1.80"
60 | source = "registry+https://github.com/rust-lang/crates.io-index"
61 | checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
62 | dependencies = [
63 | "proc-macro2",
64 | "quote",
65 | "syn",
66 | ]
67 |
68 | [[package]]
69 | name = "autocfg"
70 | version = "1.3.0"
71 | source = "registry+https://github.com/rust-lang/crates.io-index"
72 | checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
73 |
74 | [[package]]
75 | name = "axum"
76 | version = "0.6.20"
77 | source = "registry+https://github.com/rust-lang/crates.io-index"
78 | checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
79 | dependencies = [
80 | "async-trait",
81 | "axum-core",
82 | "bitflags 1.3.2",
83 | "bytes",
84 | "futures-util",
85 | "http",
86 | "http-body",
87 | "hyper",
88 | "itoa",
89 | "matchit",
90 | "memchr",
91 | "mime",
92 | "percent-encoding",
93 | "pin-project-lite",
94 | "rustversion",
95 | "serde",
96 | "sync_wrapper",
97 | "tower",
98 | "tower-layer",
99 | "tower-service",
100 | ]
101 |
102 | [[package]]
103 | name = "axum-core"
104 | version = "0.3.4"
105 | source = "registry+https://github.com/rust-lang/crates.io-index"
106 | checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
107 | dependencies = [
108 | "async-trait",
109 | "bytes",
110 | "futures-util",
111 | "http",
112 | "http-body",
113 | "mime",
114 | "rustversion",
115 | "tower-layer",
116 | "tower-service",
117 | ]
118 |
119 | [[package]]
120 | name = "backtrace"
121 | version = "0.3.73"
122 | source = "registry+https://github.com/rust-lang/crates.io-index"
123 | checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
124 | dependencies = [
125 | "addr2line",
126 | "cc",
127 | "cfg-if",
128 | "libc",
129 | "miniz_oxide",
130 | "object",
131 | "rustc-demangle",
132 | ]
133 |
134 | [[package]]
135 | name = "base64"
136 | version = "0.21.7"
137 | source = "registry+https://github.com/rust-lang/crates.io-index"
138 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
139 |
140 | [[package]]
141 | name = "bitflags"
142 | version = "1.3.2"
143 | source = "registry+https://github.com/rust-lang/crates.io-index"
144 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
145 |
146 | [[package]]
147 | name = "bitflags"
148 | version = "2.5.0"
149 | source = "registry+https://github.com/rust-lang/crates.io-index"
150 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
151 |
152 | [[package]]
153 | name = "bytes"
154 | version = "1.6.0"
155 | source = "registry+https://github.com/rust-lang/crates.io-index"
156 | checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
157 |
158 | [[package]]
159 | name = "cc"
160 | version = "1.0.99"
161 | source = "registry+https://github.com/rust-lang/crates.io-index"
162 | checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
163 |
164 | [[package]]
165 | name = "cfg-if"
166 | version = "1.0.0"
167 | source = "registry+https://github.com/rust-lang/crates.io-index"
168 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
169 |
170 | [[package]]
171 | name = "combine"
172 | version = "4.6.7"
173 | source = "registry+https://github.com/rust-lang/crates.io-index"
174 | checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
175 | dependencies = [
176 | "bytes",
177 | "futures-core",
178 | "memchr",
179 | "pin-project-lite",
180 | "tokio",
181 | "tokio-util",
182 | ]
183 |
184 | [[package]]
185 | name = "dotenv"
186 | version = "0.15.0"
187 | source = "registry+https://github.com/rust-lang/crates.io-index"
188 | checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
189 |
190 | [[package]]
191 | name = "either"
192 | version = "1.12.0"
193 | source = "registry+https://github.com/rust-lang/crates.io-index"
194 | checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
195 |
196 | [[package]]
197 | name = "equivalent"
198 | version = "1.0.1"
199 | source = "registry+https://github.com/rust-lang/crates.io-index"
200 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
201 |
202 | [[package]]
203 | name = "errno"
204 | version = "0.3.9"
205 | source = "registry+https://github.com/rust-lang/crates.io-index"
206 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
207 | dependencies = [
208 | "libc",
209 | "windows-sys 0.52.0",
210 | ]
211 |
212 | [[package]]
213 | name = "fastrand"
214 | version = "2.1.0"
215 | source = "registry+https://github.com/rust-lang/crates.io-index"
216 | checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
217 |
218 | [[package]]
219 | name = "fixedbitset"
220 | version = "0.4.2"
221 | source = "registry+https://github.com/rust-lang/crates.io-index"
222 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
223 |
224 | [[package]]
225 | name = "fnv"
226 | version = "1.0.7"
227 | source = "registry+https://github.com/rust-lang/crates.io-index"
228 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
229 |
230 | [[package]]
231 | name = "form_urlencoded"
232 | version = "1.2.1"
233 | source = "registry+https://github.com/rust-lang/crates.io-index"
234 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
235 | dependencies = [
236 | "percent-encoding",
237 | ]
238 |
239 | [[package]]
240 | name = "futures"
241 | version = "0.3.30"
242 | source = "registry+https://github.com/rust-lang/crates.io-index"
243 | checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
244 | dependencies = [
245 | "futures-channel",
246 | "futures-core",
247 | "futures-executor",
248 | "futures-io",
249 | "futures-sink",
250 | "futures-task",
251 | "futures-util",
252 | ]
253 |
254 | [[package]]
255 | name = "futures-channel"
256 | version = "0.3.30"
257 | source = "registry+https://github.com/rust-lang/crates.io-index"
258 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
259 | dependencies = [
260 | "futures-core",
261 | "futures-sink",
262 | ]
263 |
264 | [[package]]
265 | name = "futures-core"
266 | version = "0.3.30"
267 | source = "registry+https://github.com/rust-lang/crates.io-index"
268 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
269 |
270 | [[package]]
271 | name = "futures-executor"
272 | version = "0.3.30"
273 | source = "registry+https://github.com/rust-lang/crates.io-index"
274 | checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
275 | dependencies = [
276 | "futures-core",
277 | "futures-task",
278 | "futures-util",
279 | ]
280 |
281 | [[package]]
282 | name = "futures-io"
283 | version = "0.3.30"
284 | source = "registry+https://github.com/rust-lang/crates.io-index"
285 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
286 |
287 | [[package]]
288 | name = "futures-macro"
289 | version = "0.3.30"
290 | source = "registry+https://github.com/rust-lang/crates.io-index"
291 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
292 | dependencies = [
293 | "proc-macro2",
294 | "quote",
295 | "syn",
296 | ]
297 |
298 | [[package]]
299 | name = "futures-sink"
300 | version = "0.3.30"
301 | source = "registry+https://github.com/rust-lang/crates.io-index"
302 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
303 |
304 | [[package]]
305 | name = "futures-task"
306 | version = "0.3.30"
307 | source = "registry+https://github.com/rust-lang/crates.io-index"
308 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
309 |
310 | [[package]]
311 | name = "futures-util"
312 | version = "0.3.30"
313 | source = "registry+https://github.com/rust-lang/crates.io-index"
314 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
315 | dependencies = [
316 | "futures-channel",
317 | "futures-core",
318 | "futures-io",
319 | "futures-macro",
320 | "futures-sink",
321 | "futures-task",
322 | "memchr",
323 | "pin-project-lite",
324 | "pin-utils",
325 | "slab",
326 | ]
327 |
328 | [[package]]
329 | name = "geofancy-rust"
330 | version = "0.1.0"
331 | dependencies = [
332 | "bytes",
333 | "dotenv",
334 | "futures",
335 | "log",
336 | "prost",
337 | "redis",
338 | "tokio",
339 | "tonic",
340 | "tonic-build",
341 | ]
342 |
343 | [[package]]
344 | name = "getrandom"
345 | version = "0.2.15"
346 | source = "registry+https://github.com/rust-lang/crates.io-index"
347 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
348 | dependencies = [
349 | "cfg-if",
350 | "libc",
351 | "wasi",
352 | ]
353 |
354 | [[package]]
355 | name = "gimli"
356 | version = "0.29.0"
357 | source = "registry+https://github.com/rust-lang/crates.io-index"
358 | checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
359 |
360 | [[package]]
361 | name = "h2"
362 | version = "0.3.26"
363 | source = "registry+https://github.com/rust-lang/crates.io-index"
364 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
365 | dependencies = [
366 | "bytes",
367 | "fnv",
368 | "futures-core",
369 | "futures-sink",
370 | "futures-util",
371 | "http",
372 | "indexmap 2.2.6",
373 | "slab",
374 | "tokio",
375 | "tokio-util",
376 | "tracing",
377 | ]
378 |
379 | [[package]]
380 | name = "hashbrown"
381 | version = "0.12.3"
382 | source = "registry+https://github.com/rust-lang/crates.io-index"
383 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
384 |
385 | [[package]]
386 | name = "hashbrown"
387 | version = "0.14.5"
388 | source = "registry+https://github.com/rust-lang/crates.io-index"
389 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
390 |
391 | [[package]]
392 | name = "heck"
393 | version = "0.5.0"
394 | source = "registry+https://github.com/rust-lang/crates.io-index"
395 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
396 |
397 | [[package]]
398 | name = "hermit-abi"
399 | version = "0.3.9"
400 | source = "registry+https://github.com/rust-lang/crates.io-index"
401 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
402 |
403 | [[package]]
404 | name = "http"
405 | version = "0.2.12"
406 | source = "registry+https://github.com/rust-lang/crates.io-index"
407 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
408 | dependencies = [
409 | "bytes",
410 | "fnv",
411 | "itoa",
412 | ]
413 |
414 | [[package]]
415 | name = "http-body"
416 | version = "0.4.6"
417 | source = "registry+https://github.com/rust-lang/crates.io-index"
418 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
419 | dependencies = [
420 | "bytes",
421 | "http",
422 | "pin-project-lite",
423 | ]
424 |
425 | [[package]]
426 | name = "httparse"
427 | version = "1.9.4"
428 | source = "registry+https://github.com/rust-lang/crates.io-index"
429 | checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
430 |
431 | [[package]]
432 | name = "httpdate"
433 | version = "1.0.3"
434 | source = "registry+https://github.com/rust-lang/crates.io-index"
435 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
436 |
437 | [[package]]
438 | name = "hyper"
439 | version = "0.14.29"
440 | source = "registry+https://github.com/rust-lang/crates.io-index"
441 | checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33"
442 | dependencies = [
443 | "bytes",
444 | "futures-channel",
445 | "futures-core",
446 | "futures-util",
447 | "h2",
448 | "http",
449 | "http-body",
450 | "httparse",
451 | "httpdate",
452 | "itoa",
453 | "pin-project-lite",
454 | "socket2",
455 | "tokio",
456 | "tower-service",
457 | "tracing",
458 | "want",
459 | ]
460 |
461 | [[package]]
462 | name = "hyper-timeout"
463 | version = "0.4.1"
464 | source = "registry+https://github.com/rust-lang/crates.io-index"
465 | checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
466 | dependencies = [
467 | "hyper",
468 | "pin-project-lite",
469 | "tokio",
470 | "tokio-io-timeout",
471 | ]
472 |
473 | [[package]]
474 | name = "idna"
475 | version = "0.5.0"
476 | source = "registry+https://github.com/rust-lang/crates.io-index"
477 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
478 | dependencies = [
479 | "unicode-bidi",
480 | "unicode-normalization",
481 | ]
482 |
483 | [[package]]
484 | name = "indexmap"
485 | version = "1.9.3"
486 | source = "registry+https://github.com/rust-lang/crates.io-index"
487 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
488 | dependencies = [
489 | "autocfg",
490 | "hashbrown 0.12.3",
491 | ]
492 |
493 | [[package]]
494 | name = "indexmap"
495 | version = "2.2.6"
496 | source = "registry+https://github.com/rust-lang/crates.io-index"
497 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
498 | dependencies = [
499 | "equivalent",
500 | "hashbrown 0.14.5",
501 | ]
502 |
503 | [[package]]
504 | name = "itertools"
505 | version = "0.12.1"
506 | source = "registry+https://github.com/rust-lang/crates.io-index"
507 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
508 | dependencies = [
509 | "either",
510 | ]
511 |
512 | [[package]]
513 | name = "itoa"
514 | version = "1.0.11"
515 | source = "registry+https://github.com/rust-lang/crates.io-index"
516 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
517 |
518 | [[package]]
519 | name = "libc"
520 | version = "0.2.155"
521 | source = "registry+https://github.com/rust-lang/crates.io-index"
522 | checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
523 |
524 | [[package]]
525 | name = "linux-raw-sys"
526 | version = "0.4.14"
527 | source = "registry+https://github.com/rust-lang/crates.io-index"
528 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
529 |
530 | [[package]]
531 | name = "lock_api"
532 | version = "0.4.12"
533 | source = "registry+https://github.com/rust-lang/crates.io-index"
534 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
535 | dependencies = [
536 | "autocfg",
537 | "scopeguard",
538 | ]
539 |
540 | [[package]]
541 | name = "log"
542 | version = "0.4.21"
543 | source = "registry+https://github.com/rust-lang/crates.io-index"
544 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
545 |
546 | [[package]]
547 | name = "matchit"
548 | version = "0.7.3"
549 | source = "registry+https://github.com/rust-lang/crates.io-index"
550 | checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
551 |
552 | [[package]]
553 | name = "memchr"
554 | version = "2.7.4"
555 | source = "registry+https://github.com/rust-lang/crates.io-index"
556 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
557 |
558 | [[package]]
559 | name = "mime"
560 | version = "0.3.17"
561 | source = "registry+https://github.com/rust-lang/crates.io-index"
562 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
563 |
564 | [[package]]
565 | name = "miniz_oxide"
566 | version = "0.7.4"
567 | source = "registry+https://github.com/rust-lang/crates.io-index"
568 | checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
569 | dependencies = [
570 | "adler",
571 | ]
572 |
573 | [[package]]
574 | name = "mio"
575 | version = "0.8.11"
576 | source = "registry+https://github.com/rust-lang/crates.io-index"
577 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
578 | dependencies = [
579 | "libc",
580 | "wasi",
581 | "windows-sys 0.48.0",
582 | ]
583 |
584 | [[package]]
585 | name = "multimap"
586 | version = "0.10.0"
587 | source = "registry+https://github.com/rust-lang/crates.io-index"
588 | checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
589 |
590 | [[package]]
591 | name = "num_cpus"
592 | version = "1.16.0"
593 | source = "registry+https://github.com/rust-lang/crates.io-index"
594 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
595 | dependencies = [
596 | "hermit-abi",
597 | "libc",
598 | ]
599 |
600 | [[package]]
601 | name = "object"
602 | version = "0.36.0"
603 | source = "registry+https://github.com/rust-lang/crates.io-index"
604 | checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434"
605 | dependencies = [
606 | "memchr",
607 | ]
608 |
609 | [[package]]
610 | name = "once_cell"
611 | version = "1.19.0"
612 | source = "registry+https://github.com/rust-lang/crates.io-index"
613 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
614 |
615 | [[package]]
616 | name = "parking_lot"
617 | version = "0.12.3"
618 | source = "registry+https://github.com/rust-lang/crates.io-index"
619 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
620 | dependencies = [
621 | "lock_api",
622 | "parking_lot_core",
623 | ]
624 |
625 | [[package]]
626 | name = "parking_lot_core"
627 | version = "0.9.10"
628 | source = "registry+https://github.com/rust-lang/crates.io-index"
629 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
630 | dependencies = [
631 | "cfg-if",
632 | "libc",
633 | "redox_syscall",
634 | "smallvec",
635 | "windows-targets 0.52.5",
636 | ]
637 |
638 | [[package]]
639 | name = "percent-encoding"
640 | version = "2.3.1"
641 | source = "registry+https://github.com/rust-lang/crates.io-index"
642 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
643 |
644 | [[package]]
645 | name = "petgraph"
646 | version = "0.6.5"
647 | source = "registry+https://github.com/rust-lang/crates.io-index"
648 | checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
649 | dependencies = [
650 | "fixedbitset",
651 | "indexmap 2.2.6",
652 | ]
653 |
654 | [[package]]
655 | name = "pin-project"
656 | version = "1.1.5"
657 | source = "registry+https://github.com/rust-lang/crates.io-index"
658 | checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
659 | dependencies = [
660 | "pin-project-internal",
661 | ]
662 |
663 | [[package]]
664 | name = "pin-project-internal"
665 | version = "1.1.5"
666 | source = "registry+https://github.com/rust-lang/crates.io-index"
667 | checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
668 | dependencies = [
669 | "proc-macro2",
670 | "quote",
671 | "syn",
672 | ]
673 |
674 | [[package]]
675 | name = "pin-project-lite"
676 | version = "0.2.14"
677 | source = "registry+https://github.com/rust-lang/crates.io-index"
678 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
679 |
680 | [[package]]
681 | name = "pin-utils"
682 | version = "0.1.0"
683 | source = "registry+https://github.com/rust-lang/crates.io-index"
684 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
685 |
686 | [[package]]
687 | name = "ppv-lite86"
688 | version = "0.2.17"
689 | source = "registry+https://github.com/rust-lang/crates.io-index"
690 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
691 |
692 | [[package]]
693 | name = "prettyplease"
694 | version = "0.2.20"
695 | source = "registry+https://github.com/rust-lang/crates.io-index"
696 | checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e"
697 | dependencies = [
698 | "proc-macro2",
699 | "syn",
700 | ]
701 |
702 | [[package]]
703 | name = "proc-macro2"
704 | version = "1.0.86"
705 | source = "registry+https://github.com/rust-lang/crates.io-index"
706 | checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
707 | dependencies = [
708 | "unicode-ident",
709 | ]
710 |
711 | [[package]]
712 | name = "prost"
713 | version = "0.12.6"
714 | source = "registry+https://github.com/rust-lang/crates.io-index"
715 | checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
716 | dependencies = [
717 | "bytes",
718 | "prost-derive",
719 | ]
720 |
721 | [[package]]
722 | name = "prost-build"
723 | version = "0.12.6"
724 | source = "registry+https://github.com/rust-lang/crates.io-index"
725 | checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4"
726 | dependencies = [
727 | "bytes",
728 | "heck",
729 | "itertools",
730 | "log",
731 | "multimap",
732 | "once_cell",
733 | "petgraph",
734 | "prettyplease",
735 | "prost",
736 | "prost-types",
737 | "regex",
738 | "syn",
739 | "tempfile",
740 | ]
741 |
742 | [[package]]
743 | name = "prost-derive"
744 | version = "0.12.6"
745 | source = "registry+https://github.com/rust-lang/crates.io-index"
746 | checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
747 | dependencies = [
748 | "anyhow",
749 | "itertools",
750 | "proc-macro2",
751 | "quote",
752 | "syn",
753 | ]
754 |
755 | [[package]]
756 | name = "prost-types"
757 | version = "0.12.6"
758 | source = "registry+https://github.com/rust-lang/crates.io-index"
759 | checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0"
760 | dependencies = [
761 | "prost",
762 | ]
763 |
764 | [[package]]
765 | name = "quote"
766 | version = "1.0.36"
767 | source = "registry+https://github.com/rust-lang/crates.io-index"
768 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
769 | dependencies = [
770 | "proc-macro2",
771 | ]
772 |
773 | [[package]]
774 | name = "rand"
775 | version = "0.8.5"
776 | source = "registry+https://github.com/rust-lang/crates.io-index"
777 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
778 | dependencies = [
779 | "libc",
780 | "rand_chacha",
781 | "rand_core",
782 | ]
783 |
784 | [[package]]
785 | name = "rand_chacha"
786 | version = "0.3.1"
787 | source = "registry+https://github.com/rust-lang/crates.io-index"
788 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
789 | dependencies = [
790 | "ppv-lite86",
791 | "rand_core",
792 | ]
793 |
794 | [[package]]
795 | name = "rand_core"
796 | version = "0.6.4"
797 | source = "registry+https://github.com/rust-lang/crates.io-index"
798 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
799 | dependencies = [
800 | "getrandom",
801 | ]
802 |
803 | [[package]]
804 | name = "redis"
805 | version = "0.25.4"
806 | source = "registry+https://github.com/rust-lang/crates.io-index"
807 | checksum = "e0d7a6955c7511f60f3ba9e86c6d02b3c3f144f8c24b288d1f4e18074ab8bbec"
808 | dependencies = [
809 | "async-trait",
810 | "bytes",
811 | "combine",
812 | "futures-util",
813 | "itoa",
814 | "percent-encoding",
815 | "pin-project-lite",
816 | "ryu",
817 | "sha1_smol",
818 | "socket2",
819 | "tokio",
820 | "tokio-util",
821 | "url",
822 | ]
823 |
824 | [[package]]
825 | name = "redox_syscall"
826 | version = "0.5.2"
827 | source = "registry+https://github.com/rust-lang/crates.io-index"
828 | checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
829 | dependencies = [
830 | "bitflags 2.5.0",
831 | ]
832 |
833 | [[package]]
834 | name = "regex"
835 | version = "1.10.5"
836 | source = "registry+https://github.com/rust-lang/crates.io-index"
837 | checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
838 | dependencies = [
839 | "aho-corasick",
840 | "memchr",
841 | "regex-automata",
842 | "regex-syntax",
843 | ]
844 |
845 | [[package]]
846 | name = "regex-automata"
847 | version = "0.4.7"
848 | source = "registry+https://github.com/rust-lang/crates.io-index"
849 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
850 | dependencies = [
851 | "aho-corasick",
852 | "memchr",
853 | "regex-syntax",
854 | ]
855 |
856 | [[package]]
857 | name = "regex-syntax"
858 | version = "0.8.4"
859 | source = "registry+https://github.com/rust-lang/crates.io-index"
860 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
861 |
862 | [[package]]
863 | name = "rustc-demangle"
864 | version = "0.1.24"
865 | source = "registry+https://github.com/rust-lang/crates.io-index"
866 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
867 |
868 | [[package]]
869 | name = "rustix"
870 | version = "0.38.34"
871 | source = "registry+https://github.com/rust-lang/crates.io-index"
872 | checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
873 | dependencies = [
874 | "bitflags 2.5.0",
875 | "errno",
876 | "libc",
877 | "linux-raw-sys",
878 | "windows-sys 0.52.0",
879 | ]
880 |
881 | [[package]]
882 | name = "rustversion"
883 | version = "1.0.17"
884 | source = "registry+https://github.com/rust-lang/crates.io-index"
885 | checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
886 |
887 | [[package]]
888 | name = "ryu"
889 | version = "1.0.18"
890 | source = "registry+https://github.com/rust-lang/crates.io-index"
891 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
892 |
893 | [[package]]
894 | name = "scopeguard"
895 | version = "1.2.0"
896 | source = "registry+https://github.com/rust-lang/crates.io-index"
897 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
898 |
899 | [[package]]
900 | name = "serde"
901 | version = "1.0.203"
902 | source = "registry+https://github.com/rust-lang/crates.io-index"
903 | checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
904 | dependencies = [
905 | "serde_derive",
906 | ]
907 |
908 | [[package]]
909 | name = "serde_derive"
910 | version = "1.0.203"
911 | source = "registry+https://github.com/rust-lang/crates.io-index"
912 | checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
913 | dependencies = [
914 | "proc-macro2",
915 | "quote",
916 | "syn",
917 | ]
918 |
919 | [[package]]
920 | name = "sha1_smol"
921 | version = "1.0.0"
922 | source = "registry+https://github.com/rust-lang/crates.io-index"
923 | checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
924 |
925 | [[package]]
926 | name = "signal-hook-registry"
927 | version = "1.4.2"
928 | source = "registry+https://github.com/rust-lang/crates.io-index"
929 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
930 | dependencies = [
931 | "libc",
932 | ]
933 |
934 | [[package]]
935 | name = "slab"
936 | version = "0.4.9"
937 | source = "registry+https://github.com/rust-lang/crates.io-index"
938 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
939 | dependencies = [
940 | "autocfg",
941 | ]
942 |
943 | [[package]]
944 | name = "smallvec"
945 | version = "1.13.2"
946 | source = "registry+https://github.com/rust-lang/crates.io-index"
947 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
948 |
949 | [[package]]
950 | name = "socket2"
951 | version = "0.5.7"
952 | source = "registry+https://github.com/rust-lang/crates.io-index"
953 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
954 | dependencies = [
955 | "libc",
956 | "windows-sys 0.52.0",
957 | ]
958 |
959 | [[package]]
960 | name = "syn"
961 | version = "2.0.67"
962 | source = "registry+https://github.com/rust-lang/crates.io-index"
963 | checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90"
964 | dependencies = [
965 | "proc-macro2",
966 | "quote",
967 | "unicode-ident",
968 | ]
969 |
970 | [[package]]
971 | name = "sync_wrapper"
972 | version = "0.1.2"
973 | source = "registry+https://github.com/rust-lang/crates.io-index"
974 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
975 |
976 | [[package]]
977 | name = "tempfile"
978 | version = "3.10.1"
979 | source = "registry+https://github.com/rust-lang/crates.io-index"
980 | checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
981 | dependencies = [
982 | "cfg-if",
983 | "fastrand",
984 | "rustix",
985 | "windows-sys 0.52.0",
986 | ]
987 |
988 | [[package]]
989 | name = "tinyvec"
990 | version = "1.6.0"
991 | source = "registry+https://github.com/rust-lang/crates.io-index"
992 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
993 | dependencies = [
994 | "tinyvec_macros",
995 | ]
996 |
997 | [[package]]
998 | name = "tinyvec_macros"
999 | version = "0.1.1"
1000 | source = "registry+https://github.com/rust-lang/crates.io-index"
1001 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
1002 |
1003 | [[package]]
1004 | name = "tokio"
1005 | version = "1.38.0"
1006 | source = "registry+https://github.com/rust-lang/crates.io-index"
1007 | checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
1008 | dependencies = [
1009 | "backtrace",
1010 | "bytes",
1011 | "libc",
1012 | "mio",
1013 | "num_cpus",
1014 | "parking_lot",
1015 | "pin-project-lite",
1016 | "signal-hook-registry",
1017 | "socket2",
1018 | "tokio-macros",
1019 | "windows-sys 0.48.0",
1020 | ]
1021 |
1022 | [[package]]
1023 | name = "tokio-io-timeout"
1024 | version = "1.2.0"
1025 | source = "registry+https://github.com/rust-lang/crates.io-index"
1026 | checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
1027 | dependencies = [
1028 | "pin-project-lite",
1029 | "tokio",
1030 | ]
1031 |
1032 | [[package]]
1033 | name = "tokio-macros"
1034 | version = "2.3.0"
1035 | source = "registry+https://github.com/rust-lang/crates.io-index"
1036 | checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
1037 | dependencies = [
1038 | "proc-macro2",
1039 | "quote",
1040 | "syn",
1041 | ]
1042 |
1043 | [[package]]
1044 | name = "tokio-stream"
1045 | version = "0.1.15"
1046 | source = "registry+https://github.com/rust-lang/crates.io-index"
1047 | checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af"
1048 | dependencies = [
1049 | "futures-core",
1050 | "pin-project-lite",
1051 | "tokio",
1052 | ]
1053 |
1054 | [[package]]
1055 | name = "tokio-util"
1056 | version = "0.7.11"
1057 | source = "registry+https://github.com/rust-lang/crates.io-index"
1058 | checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
1059 | dependencies = [
1060 | "bytes",
1061 | "futures-core",
1062 | "futures-sink",
1063 | "pin-project-lite",
1064 | "tokio",
1065 | ]
1066 |
1067 | [[package]]
1068 | name = "tonic"
1069 | version = "0.11.0"
1070 | source = "registry+https://github.com/rust-lang/crates.io-index"
1071 | checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13"
1072 | dependencies = [
1073 | "async-stream",
1074 | "async-trait",
1075 | "axum",
1076 | "base64",
1077 | "bytes",
1078 | "h2",
1079 | "http",
1080 | "http-body",
1081 | "hyper",
1082 | "hyper-timeout",
1083 | "percent-encoding",
1084 | "pin-project",
1085 | "prost",
1086 | "tokio",
1087 | "tokio-stream",
1088 | "tower",
1089 | "tower-layer",
1090 | "tower-service",
1091 | "tracing",
1092 | ]
1093 |
1094 | [[package]]
1095 | name = "tonic-build"
1096 | version = "0.11.0"
1097 | source = "registry+https://github.com/rust-lang/crates.io-index"
1098 | checksum = "be4ef6dd70a610078cb4e338a0f79d06bc759ff1b22d2120c2ff02ae264ba9c2"
1099 | dependencies = [
1100 | "prettyplease",
1101 | "proc-macro2",
1102 | "prost-build",
1103 | "quote",
1104 | "syn",
1105 | ]
1106 |
1107 | [[package]]
1108 | name = "tower"
1109 | version = "0.4.13"
1110 | source = "registry+https://github.com/rust-lang/crates.io-index"
1111 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
1112 | dependencies = [
1113 | "futures-core",
1114 | "futures-util",
1115 | "indexmap 1.9.3",
1116 | "pin-project",
1117 | "pin-project-lite",
1118 | "rand",
1119 | "slab",
1120 | "tokio",
1121 | "tokio-util",
1122 | "tower-layer",
1123 | "tower-service",
1124 | "tracing",
1125 | ]
1126 |
1127 | [[package]]
1128 | name = "tower-layer"
1129 | version = "0.3.2"
1130 | source = "registry+https://github.com/rust-lang/crates.io-index"
1131 | checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
1132 |
1133 | [[package]]
1134 | name = "tower-service"
1135 | version = "0.3.2"
1136 | source = "registry+https://github.com/rust-lang/crates.io-index"
1137 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
1138 |
1139 | [[package]]
1140 | name = "tracing"
1141 | version = "0.1.40"
1142 | source = "registry+https://github.com/rust-lang/crates.io-index"
1143 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
1144 | dependencies = [
1145 | "pin-project-lite",
1146 | "tracing-attributes",
1147 | "tracing-core",
1148 | ]
1149 |
1150 | [[package]]
1151 | name = "tracing-attributes"
1152 | version = "0.1.27"
1153 | source = "registry+https://github.com/rust-lang/crates.io-index"
1154 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
1155 | dependencies = [
1156 | "proc-macro2",
1157 | "quote",
1158 | "syn",
1159 | ]
1160 |
1161 | [[package]]
1162 | name = "tracing-core"
1163 | version = "0.1.32"
1164 | source = "registry+https://github.com/rust-lang/crates.io-index"
1165 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
1166 | dependencies = [
1167 | "once_cell",
1168 | ]
1169 |
1170 | [[package]]
1171 | name = "try-lock"
1172 | version = "0.2.5"
1173 | source = "registry+https://github.com/rust-lang/crates.io-index"
1174 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
1175 |
1176 | [[package]]
1177 | name = "unicode-bidi"
1178 | version = "0.3.15"
1179 | source = "registry+https://github.com/rust-lang/crates.io-index"
1180 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
1181 |
1182 | [[package]]
1183 | name = "unicode-ident"
1184 | version = "1.0.12"
1185 | source = "registry+https://github.com/rust-lang/crates.io-index"
1186 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
1187 |
1188 | [[package]]
1189 | name = "unicode-normalization"
1190 | version = "0.1.23"
1191 | source = "registry+https://github.com/rust-lang/crates.io-index"
1192 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
1193 | dependencies = [
1194 | "tinyvec",
1195 | ]
1196 |
1197 | [[package]]
1198 | name = "url"
1199 | version = "2.5.2"
1200 | source = "registry+https://github.com/rust-lang/crates.io-index"
1201 | checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
1202 | dependencies = [
1203 | "form_urlencoded",
1204 | "idna",
1205 | "percent-encoding",
1206 | ]
1207 |
1208 | [[package]]
1209 | name = "want"
1210 | version = "0.3.1"
1211 | source = "registry+https://github.com/rust-lang/crates.io-index"
1212 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
1213 | dependencies = [
1214 | "try-lock",
1215 | ]
1216 |
1217 | [[package]]
1218 | name = "wasi"
1219 | version = "0.11.0+wasi-snapshot-preview1"
1220 | source = "registry+https://github.com/rust-lang/crates.io-index"
1221 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
1222 |
1223 | [[package]]
1224 | name = "windows-sys"
1225 | version = "0.48.0"
1226 | source = "registry+https://github.com/rust-lang/crates.io-index"
1227 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
1228 | dependencies = [
1229 | "windows-targets 0.48.5",
1230 | ]
1231 |
1232 | [[package]]
1233 | name = "windows-sys"
1234 | version = "0.52.0"
1235 | source = "registry+https://github.com/rust-lang/crates.io-index"
1236 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
1237 | dependencies = [
1238 | "windows-targets 0.52.5",
1239 | ]
1240 |
1241 | [[package]]
1242 | name = "windows-targets"
1243 | version = "0.48.5"
1244 | source = "registry+https://github.com/rust-lang/crates.io-index"
1245 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
1246 | dependencies = [
1247 | "windows_aarch64_gnullvm 0.48.5",
1248 | "windows_aarch64_msvc 0.48.5",
1249 | "windows_i686_gnu 0.48.5",
1250 | "windows_i686_msvc 0.48.5",
1251 | "windows_x86_64_gnu 0.48.5",
1252 | "windows_x86_64_gnullvm 0.48.5",
1253 | "windows_x86_64_msvc 0.48.5",
1254 | ]
1255 |
1256 | [[package]]
1257 | name = "windows-targets"
1258 | version = "0.52.5"
1259 | source = "registry+https://github.com/rust-lang/crates.io-index"
1260 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
1261 | dependencies = [
1262 | "windows_aarch64_gnullvm 0.52.5",
1263 | "windows_aarch64_msvc 0.52.5",
1264 | "windows_i686_gnu 0.52.5",
1265 | "windows_i686_gnullvm",
1266 | "windows_i686_msvc 0.52.5",
1267 | "windows_x86_64_gnu 0.52.5",
1268 | "windows_x86_64_gnullvm 0.52.5",
1269 | "windows_x86_64_msvc 0.52.5",
1270 | ]
1271 |
1272 | [[package]]
1273 | name = "windows_aarch64_gnullvm"
1274 | version = "0.48.5"
1275 | source = "registry+https://github.com/rust-lang/crates.io-index"
1276 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
1277 |
1278 | [[package]]
1279 | name = "windows_aarch64_gnullvm"
1280 | version = "0.52.5"
1281 | source = "registry+https://github.com/rust-lang/crates.io-index"
1282 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
1283 |
1284 | [[package]]
1285 | name = "windows_aarch64_msvc"
1286 | version = "0.48.5"
1287 | source = "registry+https://github.com/rust-lang/crates.io-index"
1288 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
1289 |
1290 | [[package]]
1291 | name = "windows_aarch64_msvc"
1292 | version = "0.52.5"
1293 | source = "registry+https://github.com/rust-lang/crates.io-index"
1294 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
1295 |
1296 | [[package]]
1297 | name = "windows_i686_gnu"
1298 | version = "0.48.5"
1299 | source = "registry+https://github.com/rust-lang/crates.io-index"
1300 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
1301 |
1302 | [[package]]
1303 | name = "windows_i686_gnu"
1304 | version = "0.52.5"
1305 | source = "registry+https://github.com/rust-lang/crates.io-index"
1306 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
1307 |
1308 | [[package]]
1309 | name = "windows_i686_gnullvm"
1310 | version = "0.52.5"
1311 | source = "registry+https://github.com/rust-lang/crates.io-index"
1312 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
1313 |
1314 | [[package]]
1315 | name = "windows_i686_msvc"
1316 | version = "0.48.5"
1317 | source = "registry+https://github.com/rust-lang/crates.io-index"
1318 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
1319 |
1320 | [[package]]
1321 | name = "windows_i686_msvc"
1322 | version = "0.52.5"
1323 | source = "registry+https://github.com/rust-lang/crates.io-index"
1324 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
1325 |
1326 | [[package]]
1327 | name = "windows_x86_64_gnu"
1328 | version = "0.48.5"
1329 | source = "registry+https://github.com/rust-lang/crates.io-index"
1330 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
1331 |
1332 | [[package]]
1333 | name = "windows_x86_64_gnu"
1334 | version = "0.52.5"
1335 | source = "registry+https://github.com/rust-lang/crates.io-index"
1336 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
1337 |
1338 | [[package]]
1339 | name = "windows_x86_64_gnullvm"
1340 | version = "0.48.5"
1341 | source = "registry+https://github.com/rust-lang/crates.io-index"
1342 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
1343 |
1344 | [[package]]
1345 | name = "windows_x86_64_gnullvm"
1346 | version = "0.52.5"
1347 | source = "registry+https://github.com/rust-lang/crates.io-index"
1348 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
1349 |
1350 | [[package]]
1351 | name = "windows_x86_64_msvc"
1352 | version = "0.48.5"
1353 | source = "registry+https://github.com/rust-lang/crates.io-index"
1354 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
1355 |
1356 | [[package]]
1357 | name = "windows_x86_64_msvc"
1358 | version = "0.52.5"
1359 | source = "registry+https://github.com/rust-lang/crates.io-index"
1360 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
1361 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "geofancy-rust"
3 | version = "0.1.0"
4 | build = "build.rs"
5 | edition = "2021"
6 |
7 | [dependencies]
8 | log = "0.4.3"
9 | redis = { version = "0.25", features = ["tokio-comp"] }
10 | prost = "0.12"
11 | tonic = "0.11"
12 | futures = "0.3"
13 | bytes = "1"
14 | dotenv = "0.15"
15 | tokio = { version = "1", features = ["full"] }
16 |
17 | [build-dependencies]
18 | tonic-build = "0.11"
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # geofancy-rs
2 |
3 | Geofancy is a (hopefully) simple [gRPC](http://grpc.io) service that implements a subset of [Tile38](http://tile38.com).
4 |
5 | This repository contains the Rust implementation.
6 |
7 | There is also another repository ([geofancy-java](https://github.com/MovingGauteng/geofancy-java)), which contains the Java/Kotlin implementation of the server.
8 |
9 | ## Why Geofancy?
10 |
11 | Tile38 is a great program, that amongst others, allows one to set geofences between moving and static geospatial objects; with the ability to trigger webhooks when conditions are met.
12 |
13 | While we have tried out Tile38, we didn't want to implement all the logic that we wanted within some of our services, so we decided to create a separate service instead.
14 |
15 | Geofancy is a stand-alone microservice that connects with Tile38, and exposes a subset of its API via a gRPC service.
16 |
17 | ### Implemented Methods
18 |
19 | You can view the `geofancy.proto` , which lists the RPCs that are supported.
20 |
21 | At the time of writing (imagine a blog post with no date having this line) ... The API is still unstable, and can evolve.
22 | We have
23 |
24 | ```proto
25 | service GeofancyService {
26 | rpc CreateWebHook (GeoFence) returns (CommandResult) {}
27 | rpc DeleteWebHook (SearchString) returns (CommandResult) {}
28 | rpc SetDocument (Document) returns (CommandResult) {}
29 | rpc DeleteDocument (Document) returns (CommandResult) {}
30 | rpc DeleteCollection (Document) returns (CommandResult) {}
31 | }
32 | ```
33 |
34 | Notice that we return a very simple `CommandResult` message. Contributions are welcome, if anyone would like to return something more solid as a result.
--------------------------------------------------------------------------------
/build.rs:
--------------------------------------------------------------------------------
1 | fn main() -> Result<(), Box> {
2 | println!("cargo:rerun-if-changed=proto/geofancy.proto");
3 | std::env::set_var("OUT_DIR", "src");
4 | tonic_build::configure()
5 | .build_server(true)
6 | .compile(&["proto/geofancy.proto"], &["proto/"])?;
7 | Ok(())
8 | }
9 |
--------------------------------------------------------------------------------
/geofancy-rust.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/proto/geofancy.proto:
--------------------------------------------------------------------------------
1 | // version = 0.0.1
2 |
3 | // Version Changelog:
4 | //
5 | // v0.0.1
6 | // - initial message stubs, shape of messages not fully defined
7 |
8 | syntax = "proto3";
9 |
10 | package geofancy;
11 |
12 | option java_multiple_files = true;
13 | option java_package = "za.co.movinggauteng.protos.geofancy";
14 | option java_outer_classname = "GeofancyProto";
15 |
16 | service GeofancyService {
17 | // CUD on entries
18 | rpc CreateWebHook (GeoFence) returns (CommandResult) {}
19 | rpc DeleteWebHook (SearchString) returns (CommandResult) {}
20 | rpc SetDocument (Document) returns (CommandResult) {}
21 | rpc DeleteDocument (Document) returns (CommandResult) {}
22 | rpc DeleteCollection (Document) returns (CommandResult) {}
23 | }
24 |
25 | message CommandResult {
26 |
27 | enum CommandStatus {
28 | COMMAND_OK = 0;
29 | COMMAND_FAILURE = 1;
30 | }
31 |
32 | CommandStatus status = 1;
33 | string message = 2;
34 | }
35 |
36 | message Document {
37 | string collection = 1;
38 | string id = 2;
39 | // TODO add FIELD data as a map/set
40 | oneof geo {
41 | Point point = 4;
42 | LineString line = 5;
43 | Bounds bounds = 6;
44 | string geojson = 7;
45 | }
46 | uint64 expiry = 10; // EX
47 | bool notExist = 11; // NX
48 | bool alreadyExist = 12; // XX
49 | }
50 |
51 | message Bounds {
52 | Coordinate southWest = 1;
53 | Coordinate northEast = 2;
54 | }
55 |
56 | message GeoFence {
57 | string id = 1;
58 | string endpoint = 2;
59 | oneof query {
60 | QueryNearby nearby = 3;
61 | QueryWithin within = 4;
62 | QueryIntersects intersects = 5;
63 | }
64 | string match = 6;
65 | repeated Detect detect = 7;
66 | repeated Commands commands = 8;
67 | // fence
68 | // TODO support more types per spec if we need them
69 | Point point = 9;
70 | uint64 distance = 10;
71 |
72 | message QueryNearby {
73 | string collection = 1;
74 | }
75 | message QueryWithin {
76 | string collection = 1;
77 | }
78 | message QueryIntersects {
79 | string collection = 1;
80 | }
81 |
82 | enum Detect {
83 | INSIDE = 0;
84 | OUTSIDE = 1;
85 | ENTER = 2;
86 | EXIT = 3;
87 | CROSS = 4;
88 | }
89 |
90 | enum Commands {
91 | SET = 0;
92 | DEL = 1;
93 | DROP = 2;
94 | }
95 | }
96 |
97 | message Point {
98 | Coordinate coord = 1;
99 | }
100 |
101 | message LineString {
102 | repeated Coordinate coords = 1;
103 | }
104 |
105 | message Coordinate {
106 | double lat = 1;
107 | double lng = 2;
108 | }
109 |
110 | message SearchString {
111 | string value = 1;
112 | }
--------------------------------------------------------------------------------
/src/geofancy.rs:
--------------------------------------------------------------------------------
1 | // This file is @generated by prost-build.
2 | #[allow(clippy::derive_partial_eq_without_eq)]
3 | #[derive(Clone, PartialEq, ::prost::Message)]
4 | pub struct CommandResult {
5 | #[prost(enumeration = "command_result::CommandStatus", tag = "1")]
6 | pub status: i32,
7 | #[prost(string, tag = "2")]
8 | pub message: ::prost::alloc::string::String,
9 | }
10 | /// Nested message and enum types in `CommandResult`.
11 | pub mod command_result {
12 | #[derive(
13 | Clone,
14 | Copy,
15 | Debug,
16 | PartialEq,
17 | Eq,
18 | Hash,
19 | PartialOrd,
20 | Ord,
21 | ::prost::Enumeration
22 | )]
23 | #[repr(i32)]
24 | pub enum CommandStatus {
25 | CommandOk = 0,
26 | CommandFailure = 1,
27 | }
28 | impl CommandStatus {
29 | /// String value of the enum field names used in the ProtoBuf definition.
30 | ///
31 | /// The values are not transformed in any way and thus are considered stable
32 | /// (if the ProtoBuf definition does not change) and safe for programmatic use.
33 | pub fn as_str_name(&self) -> &'static str {
34 | match self {
35 | CommandStatus::CommandOk => "COMMAND_OK",
36 | CommandStatus::CommandFailure => "COMMAND_FAILURE",
37 | }
38 | }
39 | /// Creates an enum from field names used in the ProtoBuf definition.
40 | pub fn from_str_name(value: &str) -> ::core::option::Option {
41 | match value {
42 | "COMMAND_OK" => Some(Self::CommandOk),
43 | "COMMAND_FAILURE" => Some(Self::CommandFailure),
44 | _ => None,
45 | }
46 | }
47 | }
48 | }
49 | #[allow(clippy::derive_partial_eq_without_eq)]
50 | #[derive(Clone, PartialEq, ::prost::Message)]
51 | pub struct Document {
52 | #[prost(string, tag = "1")]
53 | pub collection: ::prost::alloc::string::String,
54 | #[prost(string, tag = "2")]
55 | pub id: ::prost::alloc::string::String,
56 | /// EX
57 | #[prost(uint64, tag = "10")]
58 | pub expiry: u64,
59 | /// NX
60 | #[prost(bool, tag = "11")]
61 | pub not_exist: bool,
62 | /// XX
63 | #[prost(bool, tag = "12")]
64 | pub already_exist: bool,
65 | /// TODO add FIELD data as a map/set
66 | #[prost(oneof = "document::Geo", tags = "4, 5, 6, 7")]
67 | pub geo: ::core::option::Option,
68 | }
69 | /// Nested message and enum types in `Document`.
70 | pub mod document {
71 | /// TODO add FIELD data as a map/set
72 | #[allow(clippy::derive_partial_eq_without_eq)]
73 | #[derive(Clone, PartialEq, ::prost::Oneof)]
74 | pub enum Geo {
75 | #[prost(message, tag = "4")]
76 | Point(super::Point),
77 | #[prost(message, tag = "5")]
78 | Line(super::LineString),
79 | #[prost(message, tag = "6")]
80 | Bounds(super::Bounds),
81 | #[prost(string, tag = "7")]
82 | Geojson(::prost::alloc::string::String),
83 | }
84 | }
85 | #[allow(clippy::derive_partial_eq_without_eq)]
86 | #[derive(Clone, PartialEq, ::prost::Message)]
87 | pub struct Bounds {
88 | #[prost(message, optional, tag = "1")]
89 | pub south_west: ::core::option::Option,
90 | #[prost(message, optional, tag = "2")]
91 | pub north_east: ::core::option::Option,
92 | }
93 | #[allow(clippy::derive_partial_eq_without_eq)]
94 | #[derive(Clone, PartialEq, ::prost::Message)]
95 | pub struct GeoFence {
96 | #[prost(string, tag = "1")]
97 | pub id: ::prost::alloc::string::String,
98 | #[prost(string, tag = "2")]
99 | pub endpoint: ::prost::alloc::string::String,
100 | #[prost(string, tag = "6")]
101 | pub r#match: ::prost::alloc::string::String,
102 | #[prost(enumeration = "geo_fence::Detect", repeated, tag = "7")]
103 | pub detect: ::prost::alloc::vec::Vec,
104 | #[prost(enumeration = "geo_fence::Commands", repeated, tag = "8")]
105 | pub commands: ::prost::alloc::vec::Vec,
106 | /// fence
107 | /// TODO support more types per spec if we need them
108 | #[prost(message, optional, tag = "9")]
109 | pub point: ::core::option::Option,
110 | #[prost(uint64, tag = "10")]
111 | pub distance: u64,
112 | #[prost(oneof = "geo_fence::Query", tags = "3, 4, 5")]
113 | pub query: ::core::option::Option,
114 | }
115 | /// Nested message and enum types in `GeoFence`.
116 | pub mod geo_fence {
117 | #[allow(clippy::derive_partial_eq_without_eq)]
118 | #[derive(Clone, PartialEq, ::prost::Message)]
119 | pub struct QueryNearby {
120 | #[prost(string, tag = "1")]
121 | pub collection: ::prost::alloc::string::String,
122 | }
123 | #[allow(clippy::derive_partial_eq_without_eq)]
124 | #[derive(Clone, PartialEq, ::prost::Message)]
125 | pub struct QueryWithin {
126 | #[prost(string, tag = "1")]
127 | pub collection: ::prost::alloc::string::String,
128 | }
129 | #[allow(clippy::derive_partial_eq_without_eq)]
130 | #[derive(Clone, PartialEq, ::prost::Message)]
131 | pub struct QueryIntersects {
132 | #[prost(string, tag = "1")]
133 | pub collection: ::prost::alloc::string::String,
134 | }
135 | #[derive(
136 | Clone,
137 | Copy,
138 | Debug,
139 | PartialEq,
140 | Eq,
141 | Hash,
142 | PartialOrd,
143 | Ord,
144 | ::prost::Enumeration
145 | )]
146 | #[repr(i32)]
147 | pub enum Detect {
148 | Inside = 0,
149 | Outside = 1,
150 | Enter = 2,
151 | Exit = 3,
152 | Cross = 4,
153 | }
154 | impl Detect {
155 | /// String value of the enum field names used in the ProtoBuf definition.
156 | ///
157 | /// The values are not transformed in any way and thus are considered stable
158 | /// (if the ProtoBuf definition does not change) and safe for programmatic use.
159 | pub fn as_str_name(&self) -> &'static str {
160 | match self {
161 | Detect::Inside => "INSIDE",
162 | Detect::Outside => "OUTSIDE",
163 | Detect::Enter => "ENTER",
164 | Detect::Exit => "EXIT",
165 | Detect::Cross => "CROSS",
166 | }
167 | }
168 | /// Creates an enum from field names used in the ProtoBuf definition.
169 | pub fn from_str_name(value: &str) -> ::core::option::Option {
170 | match value {
171 | "INSIDE" => Some(Self::Inside),
172 | "OUTSIDE" => Some(Self::Outside),
173 | "ENTER" => Some(Self::Enter),
174 | "EXIT" => Some(Self::Exit),
175 | "CROSS" => Some(Self::Cross),
176 | _ => None,
177 | }
178 | }
179 | }
180 | #[derive(
181 | Clone,
182 | Copy,
183 | Debug,
184 | PartialEq,
185 | Eq,
186 | Hash,
187 | PartialOrd,
188 | Ord,
189 | ::prost::Enumeration
190 | )]
191 | #[repr(i32)]
192 | pub enum Commands {
193 | Set = 0,
194 | Del = 1,
195 | Drop = 2,
196 | }
197 | impl Commands {
198 | /// String value of the enum field names used in the ProtoBuf definition.
199 | ///
200 | /// The values are not transformed in any way and thus are considered stable
201 | /// (if the ProtoBuf definition does not change) and safe for programmatic use.
202 | pub fn as_str_name(&self) -> &'static str {
203 | match self {
204 | Commands::Set => "SET",
205 | Commands::Del => "DEL",
206 | Commands::Drop => "DROP",
207 | }
208 | }
209 | /// Creates an enum from field names used in the ProtoBuf definition.
210 | pub fn from_str_name(value: &str) -> ::core::option::Option {
211 | match value {
212 | "SET" => Some(Self::Set),
213 | "DEL" => Some(Self::Del),
214 | "DROP" => Some(Self::Drop),
215 | _ => None,
216 | }
217 | }
218 | }
219 | #[allow(clippy::derive_partial_eq_without_eq)]
220 | #[derive(Clone, PartialEq, ::prost::Oneof)]
221 | pub enum Query {
222 | #[prost(message, tag = "3")]
223 | Nearby(QueryNearby),
224 | #[prost(message, tag = "4")]
225 | Within(QueryWithin),
226 | #[prost(message, tag = "5")]
227 | Intersects(QueryIntersects),
228 | }
229 | }
230 | #[allow(clippy::derive_partial_eq_without_eq)]
231 | #[derive(Clone, PartialEq, ::prost::Message)]
232 | pub struct Point {
233 | #[prost(message, optional, tag = "1")]
234 | pub coord: ::core::option::Option,
235 | }
236 | #[allow(clippy::derive_partial_eq_without_eq)]
237 | #[derive(Clone, PartialEq, ::prost::Message)]
238 | pub struct LineString {
239 | #[prost(message, repeated, tag = "1")]
240 | pub coords: ::prost::alloc::vec::Vec,
241 | }
242 | #[allow(clippy::derive_partial_eq_without_eq)]
243 | #[derive(Clone, PartialEq, ::prost::Message)]
244 | pub struct Coordinate {
245 | #[prost(double, tag = "1")]
246 | pub lat: f64,
247 | #[prost(double, tag = "2")]
248 | pub lng: f64,
249 | }
250 | #[allow(clippy::derive_partial_eq_without_eq)]
251 | #[derive(Clone, PartialEq, ::prost::Message)]
252 | pub struct SearchString {
253 | #[prost(string, tag = "1")]
254 | pub value: ::prost::alloc::string::String,
255 | }
256 | /// Generated client implementations.
257 | pub mod geofancy_service_client {
258 | #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
259 | use tonic::codegen::*;
260 | use tonic::codegen::http::Uri;
261 | #[derive(Debug, Clone)]
262 | pub struct GeofancyServiceClient {
263 | inner: tonic::client::Grpc,
264 | }
265 | impl GeofancyServiceClient {
266 | /// Attempt to create a new client by connecting to a given endpoint.
267 | pub async fn connect(dst: D) -> Result
268 | where
269 | D: TryInto,
270 | D::Error: Into,
271 | {
272 | let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
273 | Ok(Self::new(conn))
274 | }
275 | }
276 | impl GeofancyServiceClient
277 | where
278 | T: tonic::client::GrpcService,
279 | T::Error: Into,
280 | T::ResponseBody: Body + Send + 'static,
281 | ::Error: Into + Send,
282 | {
283 | pub fn new(inner: T) -> Self {
284 | let inner = tonic::client::Grpc::new(inner);
285 | Self { inner }
286 | }
287 | pub fn with_origin(inner: T, origin: Uri) -> Self {
288 | let inner = tonic::client::Grpc::with_origin(inner, origin);
289 | Self { inner }
290 | }
291 | pub fn with_interceptor(
292 | inner: T,
293 | interceptor: F,
294 | ) -> GeofancyServiceClient>
295 | where
296 | F: tonic::service::Interceptor,
297 | T::ResponseBody: Default,
298 | T: tonic::codegen::Service<
299 | http::Request,
300 | Response = http::Response<
301 | >::ResponseBody,
302 | >,
303 | >,
304 | ,
306 | >>::Error: Into + Send + Sync,
307 | {
308 | GeofancyServiceClient::new(InterceptedService::new(inner, interceptor))
309 | }
310 | /// Compress requests with the given encoding.
311 | ///
312 | /// This requires the server to support it otherwise it might respond with an
313 | /// error.
314 | #[must_use]
315 | pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
316 | self.inner = self.inner.send_compressed(encoding);
317 | self
318 | }
319 | /// Enable decompressing responses.
320 | #[must_use]
321 | pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
322 | self.inner = self.inner.accept_compressed(encoding);
323 | self
324 | }
325 | /// Limits the maximum size of a decoded message.
326 | ///
327 | /// Default: `4MB`
328 | #[must_use]
329 | pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
330 | self.inner = self.inner.max_decoding_message_size(limit);
331 | self
332 | }
333 | /// Limits the maximum size of an encoded message.
334 | ///
335 | /// Default: `usize::MAX`
336 | #[must_use]
337 | pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
338 | self.inner = self.inner.max_encoding_message_size(limit);
339 | self
340 | }
341 | /// CUD on entries
342 | pub async fn create_web_hook(
343 | &mut self,
344 | request: impl tonic::IntoRequest,
345 | ) -> std::result::Result, tonic::Status> {
346 | self.inner
347 | .ready()
348 | .await
349 | .map_err(|e| {
350 | tonic::Status::new(
351 | tonic::Code::Unknown,
352 | format!("Service was not ready: {}", e.into()),
353 | )
354 | })?;
355 | let codec = tonic::codec::ProstCodec::default();
356 | let path = http::uri::PathAndQuery::from_static(
357 | "/geofancy.GeofancyService/CreateWebHook",
358 | );
359 | let mut req = request.into_request();
360 | req.extensions_mut()
361 | .insert(GrpcMethod::new("geofancy.GeofancyService", "CreateWebHook"));
362 | self.inner.unary(req, path, codec).await
363 | }
364 | pub async fn delete_web_hook(
365 | &mut self,
366 | request: impl tonic::IntoRequest,
367 | ) -> std::result::Result, tonic::Status> {
368 | self.inner
369 | .ready()
370 | .await
371 | .map_err(|e| {
372 | tonic::Status::new(
373 | tonic::Code::Unknown,
374 | format!("Service was not ready: {}", e.into()),
375 | )
376 | })?;
377 | let codec = tonic::codec::ProstCodec::default();
378 | let path = http::uri::PathAndQuery::from_static(
379 | "/geofancy.GeofancyService/DeleteWebHook",
380 | );
381 | let mut req = request.into_request();
382 | req.extensions_mut()
383 | .insert(GrpcMethod::new("geofancy.GeofancyService", "DeleteWebHook"));
384 | self.inner.unary(req, path, codec).await
385 | }
386 | pub async fn set_document(
387 | &mut self,
388 | request: impl tonic::IntoRequest,
389 | ) -> std::result::Result, tonic::Status> {
390 | self.inner
391 | .ready()
392 | .await
393 | .map_err(|e| {
394 | tonic::Status::new(
395 | tonic::Code::Unknown,
396 | format!("Service was not ready: {}", e.into()),
397 | )
398 | })?;
399 | let codec = tonic::codec::ProstCodec::default();
400 | let path = http::uri::PathAndQuery::from_static(
401 | "/geofancy.GeofancyService/SetDocument",
402 | );
403 | let mut req = request.into_request();
404 | req.extensions_mut()
405 | .insert(GrpcMethod::new("geofancy.GeofancyService", "SetDocument"));
406 | self.inner.unary(req, path, codec).await
407 | }
408 | pub async fn delete_document(
409 | &mut self,
410 | request: impl tonic::IntoRequest,
411 | ) -> std::result::Result, tonic::Status> {
412 | self.inner
413 | .ready()
414 | .await
415 | .map_err(|e| {
416 | tonic::Status::new(
417 | tonic::Code::Unknown,
418 | format!("Service was not ready: {}", e.into()),
419 | )
420 | })?;
421 | let codec = tonic::codec::ProstCodec::default();
422 | let path = http::uri::PathAndQuery::from_static(
423 | "/geofancy.GeofancyService/DeleteDocument",
424 | );
425 | let mut req = request.into_request();
426 | req.extensions_mut()
427 | .insert(GrpcMethod::new("geofancy.GeofancyService", "DeleteDocument"));
428 | self.inner.unary(req, path, codec).await
429 | }
430 | pub async fn delete_collection(
431 | &mut self,
432 | request: impl tonic::IntoRequest,
433 | ) -> std::result::Result, tonic::Status> {
434 | self.inner
435 | .ready()
436 | .await
437 | .map_err(|e| {
438 | tonic::Status::new(
439 | tonic::Code::Unknown,
440 | format!("Service was not ready: {}", e.into()),
441 | )
442 | })?;
443 | let codec = tonic::codec::ProstCodec::default();
444 | let path = http::uri::PathAndQuery::from_static(
445 | "/geofancy.GeofancyService/DeleteCollection",
446 | );
447 | let mut req = request.into_request();
448 | req.extensions_mut()
449 | .insert(GrpcMethod::new("geofancy.GeofancyService", "DeleteCollection"));
450 | self.inner.unary(req, path, codec).await
451 | }
452 | }
453 | }
454 | /// Generated server implementations.
455 | pub mod geofancy_service_server {
456 | #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
457 | use tonic::codegen::*;
458 | /// Generated trait containing gRPC methods that should be implemented for use with GeofancyServiceServer.
459 | #[async_trait]
460 | pub trait GeofancyService: Send + Sync + 'static {
461 | /// CUD on entries
462 | async fn create_web_hook(
463 | &self,
464 | request: tonic::Request,
465 | ) -> std::result::Result, tonic::Status>;
466 | async fn delete_web_hook(
467 | &self,
468 | request: tonic::Request,
469 | ) -> std::result::Result, tonic::Status>;
470 | async fn set_document(
471 | &self,
472 | request: tonic::Request,
473 | ) -> std::result::Result, tonic::Status>;
474 | async fn delete_document(
475 | &self,
476 | request: tonic::Request,
477 | ) -> std::result::Result, tonic::Status>;
478 | async fn delete_collection(
479 | &self,
480 | request: tonic::Request,
481 | ) -> std::result::Result, tonic::Status>;
482 | }
483 | #[derive(Debug)]
484 | pub struct GeofancyServiceServer {
485 | inner: _Inner,
486 | accept_compression_encodings: EnabledCompressionEncodings,
487 | send_compression_encodings: EnabledCompressionEncodings,
488 | max_decoding_message_size: Option,
489 | max_encoding_message_size: Option,
490 | }
491 | struct _Inner(Arc);
492 | impl GeofancyServiceServer {
493 | pub fn new(inner: T) -> Self {
494 | Self::from_arc(Arc::new(inner))
495 | }
496 | pub fn from_arc(inner: Arc) -> Self {
497 | let inner = _Inner(inner);
498 | Self {
499 | inner,
500 | accept_compression_encodings: Default::default(),
501 | send_compression_encodings: Default::default(),
502 | max_decoding_message_size: None,
503 | max_encoding_message_size: None,
504 | }
505 | }
506 | pub fn with_interceptor(
507 | inner: T,
508 | interceptor: F,
509 | ) -> InterceptedService
510 | where
511 | F: tonic::service::Interceptor,
512 | {
513 | InterceptedService::new(Self::new(inner), interceptor)
514 | }
515 | /// Enable decompressing requests with the given encoding.
516 | #[must_use]
517 | pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
518 | self.accept_compression_encodings.enable(encoding);
519 | self
520 | }
521 | /// Compress responses with the given encoding, if the client supports it.
522 | #[must_use]
523 | pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
524 | self.send_compression_encodings.enable(encoding);
525 | self
526 | }
527 | /// Limits the maximum size of a decoded message.
528 | ///
529 | /// Default: `4MB`
530 | #[must_use]
531 | pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
532 | self.max_decoding_message_size = Some(limit);
533 | self
534 | }
535 | /// Limits the maximum size of an encoded message.
536 | ///
537 | /// Default: `usize::MAX`
538 | #[must_use]
539 | pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
540 | self.max_encoding_message_size = Some(limit);
541 | self
542 | }
543 | }
544 | impl tonic::codegen::Service> for GeofancyServiceServer
545 | where
546 | T: GeofancyService,
547 | B: Body + Send + 'static,
548 | B::Error: Into + Send + 'static,
549 | {
550 | type Response = http::Response;
551 | type Error = std::convert::Infallible;
552 | type Future = BoxFuture;
553 | fn poll_ready(
554 | &mut self,
555 | _cx: &mut Context<'_>,
556 | ) -> Poll> {
557 | Poll::Ready(Ok(()))
558 | }
559 | fn call(&mut self, req: http::Request) -> Self::Future {
560 | let inner = self.inner.clone();
561 | match req.uri().path() {
562 | "/geofancy.GeofancyService/CreateWebHook" => {
563 | #[allow(non_camel_case_types)]
564 | struct CreateWebHookSvc(pub Arc);
565 | impl tonic::server::UnaryService
566 | for CreateWebHookSvc {
567 | type Response = super::CommandResult;
568 | type Future = BoxFuture<
569 | tonic::Response,
570 | tonic::Status,
571 | >;
572 | fn call(
573 | &mut self,
574 | request: tonic::Request,
575 | ) -> Self::Future {
576 | let inner = Arc::clone(&self.0);
577 | let fut = async move {
578 | ::create_web_hook(&inner, request)
579 | .await
580 | };
581 | Box::pin(fut)
582 | }
583 | }
584 | let accept_compression_encodings = self.accept_compression_encodings;
585 | let send_compression_encodings = self.send_compression_encodings;
586 | let max_decoding_message_size = self.max_decoding_message_size;
587 | let max_encoding_message_size = self.max_encoding_message_size;
588 | let inner = self.inner.clone();
589 | let fut = async move {
590 | let inner = inner.0;
591 | let method = CreateWebHookSvc(inner);
592 | let codec = tonic::codec::ProstCodec::default();
593 | let mut grpc = tonic::server::Grpc::new(codec)
594 | .apply_compression_config(
595 | accept_compression_encodings,
596 | send_compression_encodings,
597 | )
598 | .apply_max_message_size_config(
599 | max_decoding_message_size,
600 | max_encoding_message_size,
601 | );
602 | let res = grpc.unary(method, req).await;
603 | Ok(res)
604 | };
605 | Box::pin(fut)
606 | }
607 | "/geofancy.GeofancyService/DeleteWebHook" => {
608 | #[allow(non_camel_case_types)]
609 | struct DeleteWebHookSvc(pub Arc);
610 | impl<
611 | T: GeofancyService,
612 | > tonic::server::UnaryService
613 | for DeleteWebHookSvc {
614 | type Response = super::CommandResult;
615 | type Future = BoxFuture<
616 | tonic::Response,
617 | tonic::Status,
618 | >;
619 | fn call(
620 | &mut self,
621 | request: tonic::Request,
622 | ) -> Self::Future {
623 | let inner = Arc::clone(&self.0);
624 | let fut = async move {
625 | ::delete_web_hook(&inner, request)
626 | .await
627 | };
628 | Box::pin(fut)
629 | }
630 | }
631 | let accept_compression_encodings = self.accept_compression_encodings;
632 | let send_compression_encodings = self.send_compression_encodings;
633 | let max_decoding_message_size = self.max_decoding_message_size;
634 | let max_encoding_message_size = self.max_encoding_message_size;
635 | let inner = self.inner.clone();
636 | let fut = async move {
637 | let inner = inner.0;
638 | let method = DeleteWebHookSvc(inner);
639 | let codec = tonic::codec::ProstCodec::default();
640 | let mut grpc = tonic::server::Grpc::new(codec)
641 | .apply_compression_config(
642 | accept_compression_encodings,
643 | send_compression_encodings,
644 | )
645 | .apply_max_message_size_config(
646 | max_decoding_message_size,
647 | max_encoding_message_size,
648 | );
649 | let res = grpc.unary(method, req).await;
650 | Ok(res)
651 | };
652 | Box::pin(fut)
653 | }
654 | "/geofancy.GeofancyService/SetDocument" => {
655 | #[allow(non_camel_case_types)]
656 | struct SetDocumentSvc(pub Arc);
657 | impl tonic::server::UnaryService
658 | for SetDocumentSvc {
659 | type Response = super::CommandResult;
660 | type Future = BoxFuture<
661 | tonic::Response,
662 | tonic::Status,
663 | >;
664 | fn call(
665 | &mut self,
666 | request: tonic::Request,
667 | ) -> Self::Future {
668 | let inner = Arc::clone(&self.0);
669 | let fut = async move {
670 | ::set_document(&inner, request).await
671 | };
672 | Box::pin(fut)
673 | }
674 | }
675 | let accept_compression_encodings = self.accept_compression_encodings;
676 | let send_compression_encodings = self.send_compression_encodings;
677 | let max_decoding_message_size = self.max_decoding_message_size;
678 | let max_encoding_message_size = self.max_encoding_message_size;
679 | let inner = self.inner.clone();
680 | let fut = async move {
681 | let inner = inner.0;
682 | let method = SetDocumentSvc(inner);
683 | let codec = tonic::codec::ProstCodec::default();
684 | let mut grpc = tonic::server::Grpc::new(codec)
685 | .apply_compression_config(
686 | accept_compression_encodings,
687 | send_compression_encodings,
688 | )
689 | .apply_max_message_size_config(
690 | max_decoding_message_size,
691 | max_encoding_message_size,
692 | );
693 | let res = grpc.unary(method, req).await;
694 | Ok(res)
695 | };
696 | Box::pin(fut)
697 | }
698 | "/geofancy.GeofancyService/DeleteDocument" => {
699 | #[allow(non_camel_case_types)]
700 | struct DeleteDocumentSvc(pub Arc);
701 | impl tonic::server::UnaryService
702 | for DeleteDocumentSvc {
703 | type Response = super::CommandResult;
704 | type Future = BoxFuture<
705 | tonic::Response,
706 | tonic::Status,
707 | >;
708 | fn call(
709 | &mut self,
710 | request: tonic::Request,
711 | ) -> Self::Future {
712 | let inner = Arc::clone(&self.0);
713 | let fut = async move {
714 | ::delete_document(&inner, request)
715 | .await
716 | };
717 | Box::pin(fut)
718 | }
719 | }
720 | let accept_compression_encodings = self.accept_compression_encodings;
721 | let send_compression_encodings = self.send_compression_encodings;
722 | let max_decoding_message_size = self.max_decoding_message_size;
723 | let max_encoding_message_size = self.max_encoding_message_size;
724 | let inner = self.inner.clone();
725 | let fut = async move {
726 | let inner = inner.0;
727 | let method = DeleteDocumentSvc(inner);
728 | let codec = tonic::codec::ProstCodec::default();
729 | let mut grpc = tonic::server::Grpc::new(codec)
730 | .apply_compression_config(
731 | accept_compression_encodings,
732 | send_compression_encodings,
733 | )
734 | .apply_max_message_size_config(
735 | max_decoding_message_size,
736 | max_encoding_message_size,
737 | );
738 | let res = grpc.unary(method, req).await;
739 | Ok(res)
740 | };
741 | Box::pin(fut)
742 | }
743 | "/geofancy.GeofancyService/DeleteCollection" => {
744 | #[allow(non_camel_case_types)]
745 | struct DeleteCollectionSvc(pub Arc);
746 | impl tonic::server::UnaryService
747 | for DeleteCollectionSvc {
748 | type Response = super::CommandResult;
749 | type Future = BoxFuture<
750 | tonic::Response,
751 | tonic::Status,
752 | >;
753 | fn call(
754 | &mut self,
755 | request: tonic::Request,
756 | ) -> Self::Future {
757 | let inner = Arc::clone(&self.0);
758 | let fut = async move {
759 | ::delete_collection(&inner, request)
760 | .await
761 | };
762 | Box::pin(fut)
763 | }
764 | }
765 | let accept_compression_encodings = self.accept_compression_encodings;
766 | let send_compression_encodings = self.send_compression_encodings;
767 | let max_decoding_message_size = self.max_decoding_message_size;
768 | let max_encoding_message_size = self.max_encoding_message_size;
769 | let inner = self.inner.clone();
770 | let fut = async move {
771 | let inner = inner.0;
772 | let method = DeleteCollectionSvc(inner);
773 | let codec = tonic::codec::ProstCodec::default();
774 | let mut grpc = tonic::server::Grpc::new(codec)
775 | .apply_compression_config(
776 | accept_compression_encodings,
777 | send_compression_encodings,
778 | )
779 | .apply_max_message_size_config(
780 | max_decoding_message_size,
781 | max_encoding_message_size,
782 | );
783 | let res = grpc.unary(method, req).await;
784 | Ok(res)
785 | };
786 | Box::pin(fut)
787 | }
788 | _ => {
789 | Box::pin(async move {
790 | Ok(
791 | http::Response::builder()
792 | .status(200)
793 | .header("grpc-status", "12")
794 | .header("content-type", "application/grpc")
795 | .body(empty_body())
796 | .unwrap(),
797 | )
798 | })
799 | }
800 | }
801 | }
802 | }
803 | impl Clone for GeofancyServiceServer {
804 | fn clone(&self) -> Self {
805 | let inner = self.inner.clone();
806 | Self {
807 | inner,
808 | accept_compression_encodings: self.accept_compression_encodings,
809 | send_compression_encodings: self.send_compression_encodings,
810 | max_decoding_message_size: self.max_decoding_message_size,
811 | max_encoding_message_size: self.max_encoding_message_size,
812 | }
813 | }
814 | }
815 | impl Clone for _Inner {
816 | fn clone(&self) -> Self {
817 | Self(Arc::clone(&self.0))
818 | }
819 | }
820 | impl std::fmt::Debug for _Inner {
821 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
822 | write!(f, "{:?}", self.0)
823 | }
824 | }
825 | impl tonic::server::NamedService for GeofancyServiceServer {
826 | const NAME: &'static str = "geofancy.GeofancyService";
827 | }
828 | }
829 |
--------------------------------------------------------------------------------
/src/geofancy_server.rs:
--------------------------------------------------------------------------------
1 |
2 | use tonic::{Request, Response, Status};
3 |
4 |
5 | use crate::geofancy::*;
6 | use crate::tile38_client::*;
7 |
8 | #[derive(Clone)]
9 | pub struct GeofancyImpl {}
10 |
11 | #[tonic::async_trait]
12 | impl geofancy_service_server::GeofancyService for GeofancyImpl {
13 | async fn create_web_hook(
14 | &self,
15 | request: Request,
16 | ) -> Result, Status> {
17 | set_webhook(request.into_inner())
18 | .await
19 | .map(Response::new)
20 | .map_err(|e| Status::internal(e.to_string()))
21 | }
22 |
23 | async fn delete_web_hook(
24 | &self,
25 | request: Request,
26 | ) -> Result, Status> {
27 | delete_webhook(request.into_inner())
28 | .await
29 | .map(Response::new)
30 | .map_err(|e| Status::internal(e.to_string()))
31 | }
32 |
33 | async fn set_document(
34 | &self,
35 | request: Request,
36 | ) -> Result, Status> {
37 | let doc = request.into_inner();
38 | let id = &doc.id;
39 | let collection = &doc.collection;
40 |
41 | match doc.geo.unwrap() {
42 | document::Geo::Bounds(_bounds) => {
43 | unimplemented!()
44 | }
45 | document::Geo::Geojson(_geo_json) => {
46 | unimplemented!()
47 | }
48 | document::Geo::Line(_line) => {
49 | unimplemented!()
50 | }
51 | document::Geo::Point(point) => set_point(collection, id, point)
52 | .await
53 | .map(Response::new)
54 | .map_err(|e| Status::internal(e.to_string())),
55 | }
56 | }
57 |
58 | async fn delete_document(
59 | &self,
60 | request: Request,
61 | ) -> Result, Status> {
62 | let doc = request.into_inner();
63 | delete_document(&doc.collection, &doc.id)
64 | .await
65 | .map(Response::new)
66 | .map_err(|e| Status::internal(e.to_string()))
67 | }
68 |
69 | async fn delete_collection(
70 | &self,
71 | request: Request,
72 | ) -> Result, Status> {
73 | let doc = request.into_inner();
74 | delete_collection(&doc.collection)
75 | .await
76 | .map(Response::new)
77 | .map_err(|e| Status::internal(e.to_string()))
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main.rs:
--------------------------------------------------------------------------------
1 | use std::env;
2 |
3 | use tonic::transport::Server;
4 |
5 | use dotenv::dotenv;
6 |
7 | use geofancy_server::GeofancyImpl;
8 |
9 | #[tokio::main]
10 | async fn main() -> Result<(), Box> {
11 | let _ = dotenv();
12 |
13 | let grpc_uri = env::var("GRPC_SERVER_URI")?;
14 |
15 | let handler = GeofancyImpl {};
16 |
17 | let addr = &grpc_uri.parse().unwrap();
18 | let new_service = geofancy::geofancy_service_server::GeofancyServiceServer::new(handler);
19 |
20 | println!("listening on {:?}", addr);
21 |
22 | Server::builder()
23 | .add_service(new_service)
24 | .serve(*addr)
25 | .await?;
26 |
27 | Ok(())
28 | }
29 |
30 | mod geofancy;
31 | mod geofancy_server;
32 | mod tile38_client;
33 |
--------------------------------------------------------------------------------
/src/tile38_client.rs:
--------------------------------------------------------------------------------
1 | use std::env;
2 |
3 | use redis::RedisError;
4 |
5 | use crate::geofancy::{self, *};
6 |
7 | async fn connect() -> Result {
8 | let host = env::var("TILE38_CONNECTION").unwrap();
9 | redis::Client::open(host.as_str())?
10 | .get_multiplexed_async_connection_with_timeouts(
11 | std::time::Duration::from_secs(5),
12 | std::time::Duration::from_secs(5),
13 | )
14 | .await
15 | }
16 |
17 | pub async fn set_point(
18 | collection: &str,
19 | id: &str,
20 | point: Point,
21 | ) -> Result {
22 | let mut connection = connect().await?;
23 |
24 | let coordinates = point.coord.unwrap();
25 |
26 | redis::cmd("SET")
27 | .arg(collection)
28 | .arg(id)
29 | .arg("POINT")
30 | .arg(coordinates.lat)
31 | .arg(coordinates.lng)
32 | .query_async(&mut connection)
33 | .await?;
34 |
35 | let success = CommandResult {
36 | status: 0,
37 | ..Default::default()
38 | };
39 |
40 | Ok(success)
41 | }
42 |
43 | pub async fn set_webhook(geofence: GeoFence) -> Result {
44 | let mut connection = connect().await?;
45 |
46 | let mut q = redis::cmd("SETHOOK");
47 | q.arg(geofence.id.as_str()).arg(geofence.endpoint.as_str());
48 |
49 | match geofence.query.clone().unwrap() {
50 | geofancy::geo_fence::Query::Nearby(x) => {
51 | q.arg("NEARBY").arg(x.collection);
52 | }
53 | _ => {
54 | unimplemented!()
55 | }
56 | }
57 |
58 | q.arg("MATCH").arg(geofence.r#match.as_str()).arg("FENCE");
59 |
60 | // detect
61 | let detect: Vec<&str> = geofence
62 | .detect
63 | .clone()
64 | .into_iter()
65 | .map(|d| match d {
66 | 0 => "INSIDE",
67 | 1 => "OUTSIDE",
68 | 2 => "ENTER",
69 | 3 => "EXIT",
70 | 4 => "CROSS",
71 | _ => "",
72 | })
73 | .collect();
74 |
75 | if !detect.is_empty() {
76 | let mut detect_str: Vec<&str> = Vec::new();
77 |
78 | for x in detect {
79 | detect_str.push(x);
80 | }
81 | q.arg("DETECT").arg(detect_str.as_slice().join(","));
82 | }
83 |
84 | // commands
85 | let commands: Vec<&str> = geofence
86 | .commands
87 | .clone()
88 | .into_iter()
89 | .map(|c| match c {
90 | 0 => "SET",
91 | 1 => "DEL",
92 | 2 => "DROP",
93 | _ => "",
94 | })
95 | .collect();
96 |
97 | if !commands.is_empty() {
98 | let mut commands_str: Vec<&str> = Vec::new();
99 |
100 | commands_str.push("");
101 |
102 | for x in commands {
103 | commands_str.push(x);
104 | }
105 | q.arg("COMMANDS").arg(commands_str.as_slice().join(","));
106 | }
107 |
108 | let point = geofence.point.unwrap();
109 | let coordinate = &point.coord.unwrap();
110 |
111 | q.arg("POINT")
112 | .arg(coordinate.lat)
113 | .arg(coordinate.lng)
114 | .arg(geofence.distance);
115 |
116 | q.query_async(&mut connection).await?;
117 |
118 | let success = CommandResult {
119 | status: 0,
120 | ..Default::default()
121 | };
122 |
123 | Ok(success)
124 | }
125 |
126 | pub async fn delete_webhook(search_string: SearchString) -> Result {
127 | let mut connection = connect().await?;
128 |
129 | redis::cmd("PDELHOOK")
130 | .arg(search_string.value)
131 | .query_async(&mut connection)
132 | .await?;
133 |
134 | let success = CommandResult {
135 | status: 0,
136 | ..Default::default()
137 | };
138 |
139 | Ok(success)
140 | }
141 |
142 | pub async fn delete_document(collection: &str, id: &str) -> Result {
143 | let mut connection = connect().await?;
144 |
145 | redis::cmd("DEL")
146 | .arg(collection)
147 | .arg(id)
148 | .query_async(&mut connection)
149 | .await?;
150 |
151 | let success = CommandResult {
152 | status: 0,
153 | ..Default::default()
154 | };
155 |
156 | Ok(success)
157 | }
158 |
159 | pub async fn delete_collection(collection: &str) -> Result {
160 | let mut connection = connect().await?;
161 |
162 | redis::cmd("DROP")
163 | .arg(collection)
164 | .query_async(&mut connection)
165 | .await?;
166 |
167 | let success = CommandResult {
168 | status: 0,
169 | ..Default::default()
170 | };
171 |
172 | Ok(success)
173 | }
174 |
175 | #[cfg(test)]
176 | mod tests {
177 | use super::*;
178 |
179 | #[tokio::test]
180 | async fn set_point_test() {
181 | env::set_var("TILE38_CONNECTION", "redis://tile38-tile38:9851/0");
182 | let point = Point {
183 | coord: Some(Coordinate {
184 | lat: 12.355,
185 | lng: -26.215,
186 | }),
187 | };
188 | let result = set_point("test-collection", "test-id", point).await;
189 | // println!("{:?}", point);
190 | match result {
191 | Ok(result) => {
192 | assert!(result.status == 0);
193 | }
194 | Err(_e) => {}
195 | }
196 | }
197 | }
198 |
--------------------------------------------------------------------------------