nodedb_types/sync/wire/spatial.rs
1// SPDX-License-Identifier: Apache-2.0
2
3//! Spatial insert/delete sync messages (client → server / server → client).
4//!
5//! `SpatialInsertMsg` carries one geometry entry from a Lite client to
6//! Origin for R-tree indexing. `SpatialDeleteMsg` removes a document's
7//! geometry from Origin's R-tree.
8//!
9//! Wire opcodes:
10//! - `0xAA` — `SpatialInsert` (Lite → Origin)
11//! - `0xAB` — `SpatialInsertAck` (Origin → Lite)
12//! - `0xAC` — `SpatialDelete` (Lite → Origin)
13//! - `0xAD` — `SpatialDeleteAck` (Origin → Lite)
14
15use serde::{Deserialize, Serialize};
16
17/// Spatial insert request (Lite → Origin, 0xAA).
18///
19/// Requests that Origin index the geometry for `(collection, field, doc_id)` in
20/// its per-field R-tree. Origin assigns a surrogate for `doc_id`, computes the
21/// bounding box from the geometry, and inserts the entry into
22/// `CoreLoop::spatial_indexes`.
23///
24/// `geometry_bytes` is a MessagePack-serialised `nodedb_types::geometry::Geometry`
25/// value produced via `zerompk::to_msgpack_vec(&geometry)`.
26#[derive(
27 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
28)]
29pub struct SpatialInsertMsg {
30 /// Lite instance ID (for routing and dedup).
31 pub lite_id: String,
32 /// Target collection name.
33 pub collection: String,
34 /// Geometry field name within the collection.
35 pub field: String,
36 /// External document identifier.
37 pub doc_id: String,
38 /// MessagePack-serialised `Geometry` value.
39 pub geometry_bytes: Vec<u8>,
40 /// Monotonic batch ID (Lite-assigned, per-operation). Used for ACK correlation.
41 pub batch_id: u64,
42}
43
44/// Spatial insert acknowledgment (Origin → Lite, 0xAB).
45#[derive(
46 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
47)]
48pub struct SpatialInsertAckMsg {
49 /// Collection acknowledged.
50 pub collection: String,
51 /// Field acknowledged.
52 pub field: String,
53 /// Document ID from the originating `SpatialInsertMsg`.
54 pub doc_id: String,
55 /// Batch ID from the originating `SpatialInsertMsg`.
56 pub batch_id: u64,
57 /// `true` if the geometry was successfully indexed on Origin.
58 pub accepted: bool,
59 /// Rejection detail when `accepted == false`.
60 #[serde(default)]
61 pub reject_reason: Option<String>,
62}
63
64/// Spatial delete request (Lite → Origin, 0xAC).
65///
66/// Removes the document identified by `doc_id` from Origin's R-tree index
67/// for the given `(collection, field)`.
68#[derive(
69 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
70)]
71pub struct SpatialDeleteMsg {
72 /// Lite instance ID.
73 pub lite_id: String,
74 /// Target collection name.
75 pub collection: String,
76 /// Geometry field name within the collection.
77 pub field: String,
78 /// External document identifier to remove.
79 pub doc_id: String,
80 /// Monotonic batch ID for ACK correlation.
81 pub batch_id: u64,
82}
83
84/// Spatial delete acknowledgment (Origin → Lite, 0xAD).
85#[derive(
86 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
87)]
88pub struct SpatialDeleteAckMsg {
89 /// Collection acknowledged.
90 pub collection: String,
91 /// Field acknowledged.
92 pub field: String,
93 /// Document ID from the originating `SpatialDeleteMsg`.
94 pub doc_id: String,
95 /// Batch ID from the originating `SpatialDeleteMsg`.
96 pub batch_id: u64,
97 /// `true` if the document was successfully removed from Origin's R-tree.
98 pub accepted: bool,
99 /// Rejection detail when `accepted == false`.
100 #[serde(default)]
101 pub reject_reason: Option<String>,
102}