1use crate::{u64_to_i64, unix_timestamp_millis};
4
5pub const DEFAULT_QUEUE_LEASE_MS: u64 = 30_000;
7
8#[derive(
10 Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize,
11)]
12#[serde(rename_all = "camelCase")]
13pub struct ObjectKey {
14 pub collection: String,
16 pub id: String,
18}
19
20impl ObjectKey {
21 pub fn new(collection: impl Into<String>, id: impl Into<String>) -> Self {
23 Self {
24 collection: collection.into(),
25 id: id.into(),
26 }
27 }
28}
29
30#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct MemoryObject {
34 pub key: ObjectKey,
36 pub body: String,
38 pub version: u64,
40 pub created_at: String,
42 pub updated_at: String,
44 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub vector: Option<Vec<f32>>,
47}
48
49impl MemoryObject {
50 pub fn new(
52 collection: impl Into<String>,
53 id: impl Into<String>,
54 body: impl Into<String>,
55 ) -> Self {
56 Self {
57 key: ObjectKey::new(collection, id),
58 body: body.into(),
59 version: 0,
60 created_at: String::new(),
61 updated_at: String::new(),
62 vector: None,
63 }
64 }
65
66 #[must_use]
68 pub fn with_vector(mut self, vector: Vec<f32>) -> Self {
69 self.vector = Some(vector);
70 self
71 }
72}
73
74#[derive(Clone, Debug, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
76#[serde(rename_all = "camelCase")]
77pub struct MemoryEvent {
78 pub stream: String,
80 pub event_type: String,
82 pub body: String,
84 pub sequence: u64,
86 pub created_at: String,
88 pub idempotency_key: String,
92}
93
94impl MemoryEvent {
95 pub fn new(
97 stream: impl Into<String>,
98 event_type: impl Into<String>,
99 body: impl Into<String>,
100 ) -> Self {
101 Self {
102 stream: stream.into(),
103 event_type: event_type.into(),
104 body: body.into(),
105 sequence: 0,
106 created_at: String::new(),
107 idempotency_key: String::new(),
108 }
109 }
110}
111
112#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
114#[serde(rename_all = "camelCase")]
115pub enum QueueJobStatus {
116 Ready,
118 Leased,
120 Completed,
122 Dead,
124}
125
126#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
128#[serde(rename_all = "camelCase")]
129pub struct QueueJob {
130 pub queue: String,
132 pub id: String,
134 pub body: String,
136 pub attempts: u32,
138 pub max_attempts: u32,
140 pub status: QueueJobStatus,
142 pub available_at_ms: i64,
144 pub leased_at_ms: Option<i64>,
146 pub lease_expires_at_ms: Option<i64>,
148 pub completed_at_ms: Option<i64>,
150 pub dead_at_ms: Option<i64>,
152 pub created_at: String,
154 pub last_error: String,
156 pub priority: i32,
158}
159
160impl QueueJob {
161 pub fn new(
163 queue: impl Into<String>,
164 id: impl Into<String>,
165 body: impl Into<String>,
166 max_attempts: u32,
167 ) -> Self {
168 Self {
169 queue: queue.into(),
170 id: id.into(),
171 body: body.into(),
172 attempts: 0,
173 max_attempts,
174 status: QueueJobStatus::Ready,
175 available_at_ms: 0,
176 leased_at_ms: None,
177 lease_expires_at_ms: None,
178 completed_at_ms: None,
179 dead_at_ms: None,
180 created_at: String::new(),
181 last_error: String::new(),
182 priority: 0,
183 }
184 }
185
186 #[must_use]
188 pub const fn with_priority(mut self, priority: i32) -> Self {
189 self.priority = priority;
190 self
191 }
192
193 #[must_use]
195 pub fn delay_by_ms(mut self, delay_ms: u64) -> Self {
196 self.available_at_ms = unix_timestamp_millis().saturating_add(u64_to_i64(delay_ms));
197 self
198 }
199
200 #[must_use]
202 pub const fn available_at_ms(mut self, available_at_ms: i64) -> Self {
203 self.available_at_ms = available_at_ms;
204 self
205 }
206}
207
208#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
210#[serde(rename_all = "camelCase")]
211pub struct ListEventsOptions {
212 pub from_sequence: Option<u64>,
214 pub limit: Option<u64>,
216 pub since: Option<String>,
218}
219
220#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
222#[serde(rename_all = "camelCase")]
223pub enum SortDirection {
224 #[default]
226 Asc,
227 Desc,
229}
230
231#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
233#[serde(rename_all = "camelCase")]
234pub struct SortBy {
235 pub field: String,
237 pub direction: SortDirection,
239}
240
241impl SortBy {
242 pub fn asc(field: impl Into<String>) -> Self {
244 Self {
245 field: field.into(),
246 direction: SortDirection::Asc,
247 }
248 }
249
250 pub fn desc(field: impl Into<String>) -> Self {
252 Self {
253 field: field.into(),
254 direction: SortDirection::Desc,
255 }
256 }
257}
258
259#[derive(Clone, Debug, Default)]
261pub struct ListObjectsOptions {
262 pub filter: Vec<(String, serde_json::Value)>,
266 pub sort_by: Option<SortBy>,
268 pub limit: Option<u64>,
270 pub offset: Option<u64>,
272}
273
274#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
276#[serde(rename_all = "camelCase")]
277pub struct PutObjectOptions {
278 pub index: bool,
282 pub expected_version: Option<u64>,
287}
288
289impl Default for PutObjectOptions {
290 fn default() -> Self {
291 Self {
292 index: true,
293 expected_version: None,
294 }
295 }
296}
297
298#[derive(Clone, Copy, Debug, Eq, PartialEq)]
300pub struct QueueClaimOptions {
301 pub lease_ms: u64,
303}
304
305impl Default for QueueClaimOptions {
306 fn default() -> Self {
307 Self {
308 lease_ms: DEFAULT_QUEUE_LEASE_MS,
309 }
310 }
311}
312
313impl QueueClaimOptions {
314 #[must_use]
316 pub const fn new(lease_ms: u64) -> Self {
317 Self { lease_ms }
318 }
319}
320
321#[derive(Clone, Debug, Eq, PartialEq, Default)]
323pub struct QueueNackOptions {
324 pub delay_ms: u64,
326 pub error: String,
328}
329
330impl QueueNackOptions {
331 #[must_use]
333 pub const fn new(delay_ms: u64) -> Self {
334 Self {
335 delay_ms,
336 error: String::new(),
337 }
338 }
339
340 #[must_use]
342 pub fn with_error(delay_ms: u64, error: impl Into<String>) -> Self {
343 Self {
344 delay_ms,
345 error: error.into(),
346 }
347 }
348}
349
350#[derive(Clone, Debug, Eq, PartialEq, Default)]
352pub struct SearchOptions {
353 pub collections: Option<Vec<String>>,
355 pub limit: Option<usize>,
357 pub filter: Option<serde_json::Value>,
359}
360
361#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
363#[serde(rename_all = "camelCase")]
364pub struct SearchHit {
365 pub kind: String,
367 pub collection: String,
369 pub id: String,
371 pub text: String,
373 pub score: f64,
375 pub body: String,
377 pub version: Option<u64>,
379 pub created_at: String,
381 pub updated_at: Option<String>,
383 pub event_type: Option<String>,
385}
386
387#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
389#[serde(rename_all = "camelCase")]
390pub struct VectorSearchHit {
391 pub id: String,
393 pub score: f64,
395 pub value: MemoryObject,
397}
398
399#[derive(Clone, Debug, Default)]
401pub struct VectorSearchOptions {
402 pub top_k: Option<usize>,
404 pub filter: Option<serde_json::Value>,
406}
407
408#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
410#[serde(rename_all = "camelCase")]
411pub struct Link {
412 pub id: String,
414 pub from_ref: String,
416 pub link_type: String,
418 pub to_ref: String,
420 pub weight: Option<f64>,
422 pub metadata_json: String,
424 pub created_at: String,
426}
427
428impl Link {
429 pub fn new(
431 from_ref: impl Into<String>,
432 link_type: impl Into<String>,
433 to_ref: impl Into<String>,
434 ) -> Self {
435 Self {
436 id: String::new(),
437 from_ref: from_ref.into(),
438 link_type: link_type.into(),
439 to_ref: to_ref.into(),
440 weight: None,
441 metadata_json: "{}".to_string(),
442 created_at: String::new(),
443 }
444 }
445
446 #[must_use]
448 pub const fn with_weight(mut self, weight: f64) -> Self {
449 self.weight = Some(weight);
450 self
451 }
452
453 #[must_use]
455 pub fn with_metadata(mut self, metadata: impl Into<String>) -> Self {
456 self.metadata_json = metadata.into();
457 self
458 }
459}
460
461#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
463#[serde(rename_all = "camelCase")]
464pub struct LinkQueryOptions {
465 pub link_type: Option<String>,
467 pub limit: Option<usize>,
469}
470
471#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
473#[serde(rename_all = "camelCase")]
474pub enum LinkDirection {
475 Outgoing,
477 Incoming,
479 #[default]
481 Both,
482}
483
484#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
486#[serde(rename_all = "camelCase")]
487pub enum AggregateFunction {
488 #[default]
490 Count,
491 Sum,
493 Avg,
495 Min,
497 Max,
499}
500
501impl AggregateFunction {
502 pub const fn sql_func(&self) -> &str {
504 match self {
505 Self::Count => "COUNT(*)",
506 Self::Sum => "SUM",
507 Self::Avg => "AVG",
508 Self::Min => "MIN",
509 Self::Max => "MAX",
510 }
511 }
512}
513
514#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
516#[serde(rename_all = "camelCase")]
517pub struct AggregateOptions {
518 pub filter: Vec<(String, serde_json::Value)>,
520 pub group_by: Option<String>,
522 pub function: AggregateFunction,
524 pub field: Option<String>,
526}
527
528#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
530#[serde(rename_all = "camelCase")]
531pub struct AggregateResult {
532 pub total: f64,
534 pub groups: Vec<AggregateGroupResult>,
536}
537
538#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
540#[serde(rename_all = "camelCase")]
541pub struct AggregateGroupResult {
542 pub key: String,
544 pub value: f64,
546}
547
548#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
550#[serde(rename_all = "camelCase")]
551pub enum TimeBucket {
552 Hour,
554 #[default]
556 Day,
557 Week,
559 Month,
561}
562
563impl TimeBucket {
564 pub const fn strftime_format(&self) -> &str {
566 match self {
567 Self::Hour => "%Y-%m-%dT%H:00:00Z",
568 Self::Day => "%Y-%m-%d",
569 Self::Week => "%Y-W%W",
570 Self::Month => "%Y-%m",
571 }
572 }
573}
574
575#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
577#[serde(rename_all = "camelCase")]
578pub struct TimeSeriesOptions {
579 pub filter: Vec<(String, serde_json::Value)>,
581 pub bucket: TimeBucket,
583 pub function: AggregateFunction,
585 pub field: Option<String>,
587 pub from: Option<String>,
589 pub to: Option<String>,
591}
592
593#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
595#[serde(rename_all = "camelCase")]
596pub struct TimeSeriesResult {
597 pub buckets: Vec<TimeSeriesBucket>,
599}
600
601#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
603#[serde(rename_all = "camelCase")]
604pub struct TimeSeriesBucket {
605 pub label: String,
607 pub value: f64,
609}
610
611#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
613#[serde(rename_all = "camelCase")]
614pub struct FieldSchema {
615 pub name: String,
617 pub field_type: String,
619 pub nullable: bool,
621 pub sample_values: Vec<serde_json::Value>,
623}
624
625#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
627#[serde(rename_all = "camelCase")]
628pub struct CollectionSchema {
629 pub name: String,
631 pub object_count: u64,
633 pub fields: Vec<FieldSchema>,
635}
636
637#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
639#[serde(rename_all = "camelCase")]
640pub struct SchemaOptions {
641 pub sample_size: Option<usize>,
643}
644
645#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
647#[serde(rename_all = "camelCase")]
648pub struct StoredSchema {
649 pub schema_json: String,
651 pub hash: String,
653 pub updated_at: String,
655}
656
657#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
659#[serde(rename_all = "camelCase")]
660pub struct MigrationRecord {
661 pub id: String,
663 pub hash: String,
665 pub applied_at: String,
667}
668
669#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
671#[serde(rename_all = "camelCase")]
672pub struct IndexDefinition {
673 pub collection: String,
675 pub field: String,
677 #[serde(default)]
679 pub unique: bool,
680}
681
682impl Default for SchemaOptions {
683 fn default() -> Self {
684 Self {
685 sample_size: Some(50),
686 }
687 }
688}