1#![cfg_attr(not(debug_assertions), deny(clippy::disallowed_methods))]
4#![cfg_attr(debug_assertions, warn(clippy::disallowed_methods))]
5#![allow(clippy::tabs_in_doc_comments)]
6
7#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
9pub enum WireFormat {
10 #[default]
11 Json,
12 Proto,
13 Rbcf,
14}
15
16#[cfg(any(feature = "ws", feature = "grpc"))]
17mod changes;
18#[cfg(any(feature = "ws", feature = "grpc"))]
19pub mod client;
20#[cfg(all(feature = "dst", reifydb_single_threaded))]
21pub mod dst;
22#[cfg(feature = "grpc")]
23pub mod grpc;
24#[cfg(feature = "http")]
25pub mod http;
26#[cfg(any(feature = "http", feature = "ws"))]
27mod session;
28#[cfg(any(feature = "ws", feature = "grpc", all(feature = "dst", reifydb_single_threaded)))]
29pub mod subscription;
30#[cfg(feature = "ws")]
31mod utils;
32#[cfg(feature = "ws")]
33pub mod ws;
34
35#[cfg(any(feature = "http", feature = "ws"))]
37use std::collections::HashMap;
38#[cfg(any(feature = "http", feature = "ws"))]
39use std::sync::Arc;
40
41#[cfg(all(feature = "dst", reifydb_single_threaded))]
42pub use dst::DstClient;
43#[cfg(feature = "grpc")]
44pub use grpc::{
45 BatchFramesEnvelope, BatchGrpcSubscription, BatchMemberHandle, BatchStreamEvent, GrpcChange, GrpcClient,
46 GrpcSubscription, RawChangePayload,
47};
48#[cfg(feature = "http")]
49pub use http::HttpClient;
50pub use reifydb_client_derive::FromFrame;
52pub use reifydb_value as value;
53pub use reifydb_value::{
54 params::Params,
55 value::{
56 Value,
57 frame::{
58 column::FrameColumn,
59 data::FrameColumnData,
60 extract::FrameError,
61 frame::Frame,
62 from_frame::FromFrameError,
63 row::{FrameRow, FrameRows},
64 },
65 iso::{IsoDate, IsoDateTime, IsoDuration, IsoTime},
66 ordered_f32::OrderedF32,
67 ordered_f64::OrderedF64,
68 try_from::{FromValueError, TryFromValue, TryFromValueCoerce},
69 value_type::ValueType,
70 },
71};
72#[cfg(any(feature = "http", feature = "ws"))]
73use serde::{Deserialize, Serialize};
74use serde_json::Value as JsonValue;
75#[cfg(any(feature = "ws", feature = "grpc", all(feature = "dst", reifydb_single_threaded)))]
76pub use subscription::{BatchItem, HydrationConfig, SubscriptionConfig, build_subscription_rql};
77#[cfg(feature = "ws")]
78pub use ws::{WsBatchSubscription, WsClient};
79
80#[cfg_attr(any(feature = "http", feature = "ws"), derive(Serialize, Deserialize))]
82#[derive(Debug, Clone)]
83pub struct ResponseMeta {
84 pub fingerprint: String,
85 pub duration: String,
86}
87
88#[derive(Debug)]
90pub struct AdminResult {
91 pub frames: Vec<Frame>,
92 pub meta: Option<ResponseMeta>,
93}
94
95#[derive(Debug)]
97pub struct CommandResult {
98 pub frames: Vec<Frame>,
99 pub meta: Option<ResponseMeta>,
100}
101
102#[derive(Debug)]
104pub struct QueryResult {
105 pub frames: Vec<Frame>,
106 pub meta: Option<ResponseMeta>,
107}
108
109#[derive(Debug, Clone)]
111pub struct LoginResult {
112 pub token: String,
114 pub identity: String,
116}
117
118#[cfg(any(feature = "http", feature = "ws"))]
119#[derive(Debug, Serialize, Deserialize)]
121pub struct WireValue {
122 #[serde(rename = "type")]
123 pub type_name: String,
124 pub value: String,
125}
126
127#[cfg(any(feature = "http", feature = "ws"))]
128#[derive(Debug, Serialize, Deserialize)]
134#[serde(untagged)]
135pub enum WireParams {
136 Positional(Vec<WireValue>),
137 Named(HashMap<String, WireValue>),
138}
139
140#[cfg(any(feature = "http", feature = "ws"))]
141fn value_to_wire(value: Value) -> WireValue {
142 let (type_name, value_str): (&str, String) = match &value {
143 Value::None {
144 ..
145 } => ("None", "\u{27EA}none\u{27EB}".to_string()),
146 Value::Boolean(b) => ("Boolean", b.to_string()),
147 Value::Float4(f) => ("Float4", f.to_string()),
148 Value::Float8(f) => ("Float8", f.to_string()),
149 Value::Int1(i) => ("Int1", i.to_string()),
150 Value::Int2(i) => ("Int2", i.to_string()),
151 Value::Int4(i) => ("Int4", i.to_string()),
152 Value::Int8(i) => ("Int8", i.to_string()),
153 Value::Int16(i) => ("Int16", i.to_string()),
154 Value::Utf8(s) => ("Utf8", s.clone()),
155 Value::Uint1(u) => ("Uint1", u.to_string()),
156 Value::Uint2(u) => ("Uint2", u.to_string()),
157 Value::Uint4(u) => ("Uint4", u.to_string()),
158 Value::Uint8(u) => ("Uint8", u.to_string()),
159 Value::Uint16(u) => ("Uint16", u.to_string()),
160 Value::Uuid4(u) => ("Uuid4", u.to_string()),
161 Value::Uuid7(u) => ("Uuid7", u.to_string()),
162 Value::Date(d) => ("Date", d.to_string()),
163 Value::DateTime(dt) => ("DateTime", dt.to_string()),
164 Value::Time(t) => ("Time", t.to_string()),
165 Value::Duration(d) => ("Duration", d.to_iso_string()),
166 Value::Blob(b) => ("Blob", b.to_hex()),
167 Value::IdentityId(id) => ("IdentityId", id.to_string()),
168 Value::Int(i) => ("Int", i.to_string()),
169 Value::Uint(u) => ("Uint", u.to_string()),
170 Value::Decimal(d) => ("Decimal", d.to_string()),
171 Value::Any(v) => return value_to_wire(*v.clone()),
172 Value::DictionaryId(id) => ("DictionaryId", id.to_string()),
173 Value::Type(t) => ("ValueType", t.to_string()),
174 Value::List(items) => ("List", format!("{}", Value::List(items.clone()))),
175 Value::Record(fields) => ("Record", format!("{}", Value::Record(fields.clone()))),
176 Value::Tuple(items) => ("Tuple", format!("{}", Value::Tuple(items.clone()))),
177 };
178 WireValue {
179 type_name: type_name.to_string(),
180 value: value_str,
181 }
182}
183
184#[cfg(any(feature = "http", feature = "ws"))]
185pub fn params_to_wire(params: Params) -> Option<WireParams> {
186 match params {
187 Params::None => None,
188 Params::Positional(values) => Some(WireParams::Positional(
189 Arc::unwrap_or_clone(values).into_iter().map(value_to_wire).collect(),
190 )),
191 Params::Named(map) => Some(WireParams::Named(
192 Arc::unwrap_or_clone(map).into_iter().map(|(k, v)| (k, value_to_wire(v))).collect(),
193 )),
194 }
195}
196
197#[cfg(any(feature = "http", feature = "ws"))]
198#[derive(Debug, Serialize, Deserialize)]
199pub struct Request {
200 pub id: String,
201 #[serde(flatten)]
202 pub payload: RequestPayload,
203}
204
205#[cfg(any(feature = "http", feature = "ws"))]
206#[derive(Debug, Serialize, Deserialize)]
207#[serde(tag = "type", content = "payload")]
208pub enum RequestPayload {
209 Auth(AuthRequest),
210 Admin(AdminRequest),
211 Command(CommandRequest),
212 Query(QueryRequest),
213 Subscribe(SubscribeRequest),
214 Unsubscribe(UnsubscribeRequest),
215 BatchSubscribe(BatchSubscribeRequest),
216 BatchUnsubscribe(BatchUnsubscribeRequest),
217 Call(CallRequest),
218 Logout,
219}
220
221#[cfg(any(feature = "http", feature = "ws"))]
222#[derive(Debug, Serialize, Deserialize)]
223pub struct AdminRequest {
224 pub rql: String,
225 pub params: Option<WireParams>,
226 #[serde(skip_serializing_if = "Option::is_none")]
227 pub format: Option<String>,
228}
229
230#[cfg(any(feature = "http", feature = "ws"))]
231#[derive(Debug, Serialize, Deserialize)]
232pub struct AuthRequest {
233 #[serde(skip_serializing_if = "Option::is_none")]
234 pub token: Option<String>,
235 #[serde(skip_serializing_if = "Option::is_none")]
236 pub method: Option<String>,
237 #[serde(skip_serializing_if = "Option::is_none")]
238 pub credentials: Option<HashMap<String, String>>,
239}
240
241#[cfg(any(feature = "http", feature = "ws"))]
242#[derive(Debug, Serialize, Deserialize)]
243pub struct CommandRequest {
244 pub rql: String,
245 pub params: Option<WireParams>,
246 #[serde(skip_serializing_if = "Option::is_none")]
247 pub format: Option<String>,
248}
249
250#[cfg(any(feature = "http", feature = "ws"))]
251#[derive(Debug, Serialize, Deserialize)]
252pub struct QueryRequest {
253 pub rql: String,
254 pub params: Option<WireParams>,
255 #[serde(skip_serializing_if = "Option::is_none")]
256 pub format: Option<String>,
257}
258
259#[cfg(any(feature = "http", feature = "ws"))]
260#[derive(Debug, Serialize, Deserialize)]
261pub struct SubscribeRequest {
262 pub rql: String,
263 #[serde(skip_serializing_if = "Option::is_none")]
264 pub format: Option<String>,
265}
266
267#[cfg(any(feature = "http", feature = "ws"))]
268#[derive(Debug, Serialize, Deserialize)]
269pub struct UnsubscribeRequest {
270 pub subscription_id: String,
271}
272
273#[cfg(any(feature = "http", feature = "ws"))]
274#[derive(Debug, Serialize, Deserialize)]
275pub struct BatchSubscribeRequest {
276 pub queries: Vec<String>,
277 #[serde(skip_serializing_if = "Option::is_none")]
278 pub format: Option<String>,
279}
280
281#[cfg(any(feature = "http", feature = "ws"))]
282#[derive(Debug, Serialize, Deserialize)]
283pub struct BatchUnsubscribeRequest {
284 pub batch_id: String,
285}
286
287#[cfg(any(feature = "http", feature = "ws"))]
288#[derive(Debug, Serialize, Deserialize)]
289pub struct CallRequest {
290 pub name: String,
291 pub params: Option<WireParams>,
292}
293
294#[cfg(any(feature = "http", feature = "ws"))]
295#[derive(Debug, Serialize, Deserialize)]
296pub struct Response {
297 pub id: String,
298 #[serde(flatten)]
299 pub payload: ResponsePayload,
300}
301
302#[cfg(any(feature = "http", feature = "ws"))]
303#[derive(Debug, Serialize, Deserialize)]
304#[serde(tag = "type", content = "payload")]
305pub enum ResponsePayload {
306 Auth(AuthResponse),
307 Err(ErrResponse),
308 Admin(AdminResponse),
309 Command(CommandResponse),
310 Query(QueryResponse),
311 Subscribed(SubscribedResponse),
312 Unsubscribed(UnsubscribedResponse),
313 BatchSubscribed(BatchSubscribedResponse),
314 BatchUnsubscribed(BatchUnsubscribedResponse),
315 Call(CallResponse),
316 Logout(LogoutResponsePayload),
317}
318
319#[cfg(any(feature = "http", feature = "ws"))]
320#[derive(Debug, Serialize, Deserialize)]
321pub struct AdminResponse {
322 pub content_type: String,
323 pub body: JsonValue,
324 #[serde(default)]
325 pub meta: Option<ResponseMeta>,
326}
327
328#[cfg(any(feature = "http", feature = "ws"))]
329use reifydb_value::error::Diagnostic;
330
331#[cfg(any(feature = "http", feature = "ws"))]
332#[derive(Debug, Serialize, Deserialize)]
333pub struct AuthResponse {
334 #[serde(skip_serializing_if = "Option::is_none")]
335 pub status: Option<String>,
336 #[serde(skip_serializing_if = "Option::is_none")]
337 pub token: Option<String>,
338 #[serde(skip_serializing_if = "Option::is_none")]
339 pub identity: Option<String>,
340}
341
342#[cfg(any(feature = "http", feature = "ws"))]
343#[derive(Debug, Serialize, Deserialize)]
344pub struct ErrResponse {
345 pub diagnostic: Diagnostic,
346}
347
348#[cfg(any(feature = "http", feature = "ws"))]
349#[derive(Debug, Serialize, Deserialize)]
350pub struct CommandResponse {
351 pub content_type: String,
352 pub body: JsonValue,
353 #[serde(default)]
354 pub meta: Option<ResponseMeta>,
355}
356
357#[cfg(any(feature = "http", feature = "ws"))]
358#[derive(Debug, Serialize, Deserialize)]
359pub struct QueryResponse {
360 pub content_type: String,
361 pub body: JsonValue,
362 #[serde(default)]
363 pub meta: Option<ResponseMeta>,
364}
365
366#[cfg(any(feature = "http", feature = "ws"))]
367#[derive(Debug, Serialize, Deserialize)]
368pub struct CallResponse {
369 pub content_type: String,
370 pub body: JsonValue,
371 #[serde(default)]
372 pub meta: Option<ResponseMeta>,
373}
374
375#[cfg(any(feature = "http", feature = "ws"))]
376#[derive(Debug, Serialize, Deserialize)]
377pub struct SubscribedResponse {
378 pub subscription_id: String,
379}
380
381#[cfg(any(feature = "http", feature = "ws"))]
382#[derive(Debug, Serialize, Deserialize)]
383pub struct UnsubscribedResponse {
384 pub subscription_id: String,
385}
386
387#[cfg(any(feature = "http", feature = "ws"))]
388#[derive(Debug, Serialize, Deserialize)]
389pub struct BatchSubscribedResponse {
390 pub batch_id: String,
391 pub members: Vec<BatchMemberInfo>,
392}
393
394#[cfg_attr(any(feature = "http", feature = "ws"), derive(Serialize, Deserialize))]
395#[derive(Debug, Clone)]
396pub struct BatchMemberInfo {
397 pub index: usize,
398 pub subscription_id: String,
399}
400
401#[cfg(any(feature = "http", feature = "ws"))]
402#[derive(Debug, Serialize, Deserialize)]
403pub struct BatchUnsubscribedResponse {
404 pub batch_id: String,
405}
406
407#[cfg(any(feature = "http", feature = "ws"))]
408#[derive(Debug, Serialize, Deserialize)]
409pub struct LogoutResponsePayload {
410 pub status: String,
411}
412
413#[cfg(any(feature = "http", feature = "ws"))]
414#[derive(Debug, Serialize, Deserialize)]
415#[serde(tag = "type", content = "payload")]
416pub enum ServerPush {
417 Change(WireChangePayload),
418 BatchChange(WireBatchChangePayload),
419 BatchMemberClosed(BatchMemberClosedPayload),
420 BatchClosed(BatchClosedPayload),
421}
422
423#[cfg(any(feature = "http", feature = "ws"))]
424#[derive(Debug, Clone, Serialize, Deserialize)]
425pub struct WireChangePayload {
426 pub subscription_id: String,
427 pub content_type: String,
428 pub body: JsonValue,
429}
430
431#[cfg(any(feature = "http", feature = "ws"))]
432#[derive(Debug, Clone, Serialize, Deserialize)]
433pub struct WireBatchChangePayload {
434 pub batch_id: String,
435 pub entries: Vec<WireBatchChangeEntry>,
436}
437
438#[cfg(any(feature = "http", feature = "ws"))]
439#[derive(Debug, Clone, Serialize, Deserialize)]
440pub struct WireBatchChangeEntry {
441 pub subscription_id: String,
442 pub content_type: String,
443 pub body: JsonValue,
444}
445
446#[cfg_attr(any(feature = "http", feature = "ws"), derive(Serialize, Deserialize))]
447#[derive(Debug, Clone, Copy, PartialEq, Eq)]
448pub enum ChangeKind {
449 Insert,
450 Update,
451 Remove,
452}
453
454#[cfg_attr(any(feature = "http", feature = "ws"), derive(Serialize, Deserialize))]
455#[derive(Debug, Clone)]
456pub struct ChangePayload {
457 pub subscription_id: String,
458 pub kind: ChangeKind,
459 pub content_type: String,
460 pub body: JsonValue,
461 #[cfg_attr(any(feature = "http", feature = "ws"), serde(skip, default))]
462 pub frames: Option<Vec<Frame>>,
463}
464
465#[cfg_attr(any(feature = "http", feature = "ws"), derive(Serialize, Deserialize))]
466#[derive(Debug, Clone)]
467pub struct BatchChangePayload {
468 pub batch_id: String,
469 pub entries: Vec<BatchChangeEntry>,
470}
471
472#[cfg_attr(any(feature = "http", feature = "ws"), derive(Serialize, Deserialize))]
473#[derive(Debug, Clone)]
474pub struct BatchChangeEntry {
475 pub subscription_id: String,
476 pub kind: ChangeKind,
477 pub content_type: String,
478 pub body: JsonValue,
479 #[cfg_attr(any(feature = "http", feature = "ws"), serde(skip, default))]
480 pub frames: Option<Vec<Frame>>,
481 #[cfg_attr(any(feature = "http", feature = "ws"), serde(skip, default))]
482 pub decode_error: Option<String>,
483}
484
485#[cfg_attr(any(feature = "http", feature = "ws"), derive(Serialize, Deserialize))]
486#[derive(Debug, Clone)]
487pub struct BatchMemberClosedPayload {
488 pub batch_id: String,
489 pub subscription_id: String,
490}
491
492#[cfg_attr(any(feature = "http", feature = "ws"), derive(Serialize, Deserialize))]
493#[derive(Debug, Clone)]
494pub struct BatchClosedPayload {
495 pub batch_id: String,
496}
497
498#[derive(Debug, Clone)]
499pub enum BatchPushEvent {
500 Change(BatchChangePayload),
501 MemberClosed(BatchMemberClosedPayload),
502 Closed(BatchClosedPayload),
503}