1use std::collections::HashMap;
4
5#[derive(Debug, Clone)]
7pub struct Document {
8 pub operations: Vec<Operation>,
9}
10
11#[derive(Debug, Clone)]
13pub enum Operation {
14 Query(Query),
15 Mutation(Mutation),
16 Subscription(Subscription),
17 Schema(Schema),
18 Migration(Migration),
19 FragmentDefinition(FragmentDef),
20 Introspection(IntrospectionQuery),
21 Handler(HandlerDef),
22}
23
24#[derive(Debug, Clone)]
26pub struct Query {
27 pub name: Option<String>,
28 pub variable_definitions: Vec<VariableDefinition>,
29 pub directives: Vec<Directive>,
30 pub selection_set: Vec<Selection>,
31 pub variables_values: HashMap<String, Value>,
32}
33
34#[derive(Debug, Clone)]
36pub struct Mutation {
37 pub name: Option<String>,
38 pub variable_definitions: Vec<VariableDefinition>,
39 pub directives: Vec<Directive>,
40 pub operations: Vec<MutationOperation>,
41 pub variables_values: HashMap<String, Value>,
42}
43
44#[derive(Debug, Clone)]
46pub struct Subscription {
47 pub name: Option<String>,
48 pub variable_definitions: Vec<VariableDefinition>,
49 pub directives: Vec<Directive>,
50 pub selection_set: Vec<Selection>,
51 pub variables_values: HashMap<String, Value>,
52}
53
54#[derive(Debug, Clone)]
55pub struct Schema {
56 pub operations: Vec<SchemaOp>,
57}
58
59#[derive(Debug, Clone)]
60pub enum SchemaOp {
61 DefineCollection {
62 name: String,
63 if_not_exists: bool,
64 fields: Vec<FieldDef>,
65 directives: Vec<Directive>,
66 },
67 AlterCollection {
68 name: String,
69 actions: Vec<AlterAction>,
70 },
71 DropCollection {
72 name: String,
73 if_exists: bool,
74 },
75}
76
77#[derive(Debug, Clone)]
78pub enum AlterAction {
79 AddField {
80 field: FieldDef,
81 default: Option<Value>,
82 },
83 DropField(String),
84 RenameField {
85 from: String,
86 to: String,
87 },
88 ModifyField(FieldDef),
89}
90
91#[derive(Debug, Clone)]
92pub struct Migration {
93 pub steps: Vec<MigrationStep>,
94}
95
96#[derive(Debug, Clone)]
97pub struct MigrationStep {
98 pub version: String,
99 pub actions: Vec<MigrationAction>,
100}
101
102#[derive(Debug, Clone)]
103pub enum MigrationAction {
104 Schema(SchemaOp),
105 DataMigration(DataMigration),
106}
107
108#[derive(Debug, Clone)]
109pub struct DataMigration {
110 pub collection: String,
111 pub transforms: Vec<DataTransform>,
112}
113
114#[derive(Debug, Clone)]
115pub struct DataTransform {
116 pub field: String,
117 pub expression: String, pub filter: Option<Filter>,
119}
120
121#[derive(Debug, Clone)]
123pub struct HandlerDef {
124 pub name: String,
125 pub trigger: HandlerTrigger,
126 pub action: MutationOperation,
127}
128
129#[derive(Debug, Clone, PartialEq)]
131pub enum HandlerTrigger {
132 JobCompleted,
134 JobFailed,
136 Insert { collection: Option<String> },
138 Update { collection: Option<String> },
140 Delete { collection: Option<String> },
142 Custom(String),
144}
145
146#[derive(Debug, Clone)]
148pub struct FieldDef {
149 pub name: String,
150 pub field_type: TypeAnnotation,
151 pub directives: Vec<Directive>,
152}
153
154#[derive(Debug, Clone)]
156pub struct VariableDefinition {
157 pub name: String,
158 pub var_type: TypeAnnotation,
159 pub default_value: Option<Value>,
160}
161
162#[derive(Debug, Clone)]
164pub struct TypeAnnotation {
165 pub name: String,
166 pub is_array: bool,
167 pub is_required: bool,
168}
169
170#[derive(Debug, Clone)]
172pub struct Directive {
173 pub name: String,
174 pub arguments: Vec<Argument>,
175}
176
177#[derive(Debug, Clone)]
179pub struct Field {
180 pub alias: Option<String>,
181 pub name: String,
182 pub arguments: Vec<Argument>,
183 pub directives: Vec<Directive>,
184 pub selection_set: Vec<Selection>,
185 pub computed_expression: Option<Expression>,
187}
188
189#[derive(Debug, Clone)]
191pub struct Argument {
192 pub name: String,
193 pub value: Value,
194}
195
196#[derive(Debug, Clone)]
198pub struct MutationOperation {
199 pub alias: Option<String>,
200 pub operation: MutationOp,
201 pub directives: Vec<Directive>,
202 pub selection_set: Vec<Selection>,
203}
204
205#[derive(Debug, Clone)]
207pub enum MutationOp {
208 Insert {
209 collection: String,
210 data: Value,
211 },
212 InsertMany {
213 collection: String,
214 data: Value,
215 },
216 Update {
217 collection: String,
218 filter: Option<Filter>,
219 data: Value,
220 },
221 Upsert {
222 collection: String,
223 filter: Option<Filter>,
224 data: Value,
225 },
226 Delete {
227 collection: String,
228 filter: Option<Filter>,
229 },
230 EnqueueJob {
231 job_type: String,
232 payload: Value,
233 priority: JobPriority,
234 scheduled_at: Option<String>,
235 max_retries: Option<u32>,
236 },
237 EnqueueJobs {
238 job_type: String,
239 payloads: Vec<Value>,
240 priority: JobPriority,
241 max_retries: Option<u32>,
242 },
243 Import {
244 collection: String,
245 data: Vec<Value>,
246 },
247 Export {
248 collection: String,
249 format: String,
250 },
251 Transaction {
252 operations: Vec<MutationOperation>,
253 },
254}
255
256#[derive(Debug, Clone, Copy, PartialEq, Eq)]
258pub enum JobPriority {
259 Low,
260 Normal,
261 High,
262 Critical,
263}
264
265#[derive(Debug, Clone)]
267pub enum Filter {
268 Eq(String, Value),
269 Ne(String, Value),
270 Gt(String, Value),
271 Gte(String, Value),
272 Lt(String, Value),
273 Lte(String, Value),
274 In(String, Value),
275 NotIn(String, Value),
276 Contains(String, Value),
277 ContainsAny(String, Value),
278 ContainsAll(String, Value),
279 StartsWith(String, Value),
280 EndsWith(String, Value),
281 Matches(String, Value),
282 IsNull(String),
283 IsNotNull(String),
284 And(Vec<Filter>),
285 Or(Vec<Filter>),
286 Not(Box<Filter>),
287}
288
289#[derive(Debug, Clone, PartialEq)]
291pub enum Value {
292 Null,
293 Boolean(bool),
294 Int(i64),
295 Float(f64),
296 String(String),
297 Array(Vec<Value>),
298 Object(HashMap<String, Value>),
299 Variable(String),
300 Enum(String),
301}
302
303impl From<bool> for Value {
304 fn from(v: bool) -> Self {
305 Value::Boolean(v)
306 }
307}
308
309impl From<i32> for Value {
310 fn from(v: i32) -> Self {
311 Value::Int(v as i64)
312 }
313}
314
315impl From<i64> for Value {
316 fn from(v: i64) -> Self {
317 Value::Int(v)
318 }
319}
320
321impl From<f32> for Value {
322 fn from(v: f32) -> Self {
323 Value::Float(v as f64)
324 }
325}
326
327impl From<f64> for Value {
328 fn from(v: f64) -> Self {
329 Value::Float(v)
330 }
331}
332
333impl From<String> for Value {
334 fn from(v: String) -> Self {
335 Value::String(v)
336 }
337}
338
339impl From<&str> for Value {
340 fn from(v: &str) -> Self {
341 Value::String(v.to_string())
342 }
343}
344
345impl From<uuid::Uuid> for Value {
346 fn from(v: uuid::Uuid) -> Self {
347 Value::String(v.to_string())
348 }
349}
350
351impl From<crate::types::Value> for Value {
352 fn from(v: crate::types::Value) -> Self {
353 match v {
354 crate::types::Value::Null => Value::Null,
355 crate::types::Value::Bool(b) => Value::Boolean(b),
356 crate::types::Value::Int(i) => Value::Int(i),
357 crate::types::Value::Float(f) => Value::Float(f),
358 crate::types::Value::String(s) => Value::String(s),
359 crate::types::Value::Uuid(u) => Value::String(u.to_string()),
360 crate::types::Value::DateTime(dt) => Value::String(dt.to_rfc3339()),
361 crate::types::Value::Array(arr) => {
362 Value::Array(arr.into_iter().map(Value::from).collect())
363 }
364 crate::types::Value::Object(obj) => {
365 let mut map = HashMap::new();
366 for (k, v) in obj {
367 map.insert(k, Value::from(v));
368 }
369 Value::Object(map)
370 }
371 }
372 }
373}
374
375#[derive(Debug, Clone)]
377pub struct FragmentDef {
378 pub name: String,
379 pub type_condition: String,
380 pub selection_set: Vec<Selection>,
381}
382
383#[derive(Debug, Clone)]
385pub struct IntrospectionQuery {
386 pub arguments: Vec<Argument>,
387 pub fields: Vec<String>,
388}
389
390#[derive(Debug, Clone)]
392pub enum Selection {
393 Field(Field),
394 FragmentSpread(String),
395 InlineFragment(InlineFragment),
396 ComputedField(ComputedField),
397}
398
399#[derive(Debug, Clone)]
401pub struct InlineFragment {
402 pub type_condition: String,
403 pub selection_set: Vec<Selection>,
404}
405
406#[derive(Debug, Clone)]
408pub struct ComputedField {
409 pub alias: String,
410 pub expression: ComputedExpression,
411}
412
413#[derive(Debug, Clone)]
415pub enum ComputedExpression {
416 TemplateString(String),
417 FunctionCall {
418 name: String,
419 args: Vec<Expression>,
420 },
421 PipeExpression {
422 base: Box<Expression>,
423 operations: Vec<PipeOp>,
424 },
425 SqlExpression(String),
426 AggregateFunction {
427 name: String,
428 field: String,
429 },
430 StandardExpression(Expression),
431}
432
433#[derive(Debug, Clone)]
435pub struct PipeOp {
436 pub function: String,
437 pub args: Vec<Expression>,
438}
439
440#[derive(Debug, Clone)]
442pub enum Expression {
443 Literal(Value),
444 FieldAccess(Vec<String>),
445 Variable(String),
446 FunctionCall {
447 name: String,
448 args: Vec<Expression>,
449 },
450 Binary {
451 op: BinaryOp,
452 left: Box<Expression>,
453 right: Box<Expression>,
454 },
455 Unary {
456 op: UnaryOp,
457 expr: Box<Expression>,
458 },
459 Ternary {
460 condition: Box<Expression>,
461 then_expr: Box<Expression>,
462 else_expr: Box<Expression>,
463 },
464}
465
466#[derive(Debug, Clone, Copy, PartialEq, Eq)]
468pub enum BinaryOp {
469 Add,
470 Sub,
471 Mul,
472 Div,
473 Mod,
474 Eq,
475 Ne,
476 Gt,
477 Gte,
478 Lt,
479 Lte,
480 And,
481 Or,
482}
483
484#[derive(Debug, Clone, Copy, PartialEq, Eq)]
486pub enum UnaryOp {
487 Not,
488 Neg,
489}
490
491#[derive(Debug, Clone)]
493pub enum SpecialSelection {
494 Aggregate(AggregateSelection),
495 GroupBy(GroupBySelection),
496 Lookup(LookupSelection),
497 PageInfo(PageInfoSelection),
498 Edges(EdgesSelection),
499 Downsample(DownsampleSelection),
500 WindowFunction(WindowFunctionSelection),
501}
502
503#[derive(Debug, Clone)]
505pub struct AggregateSelection {
506 pub fields: Vec<AggregateField>,
507}
508
509#[derive(Debug, Clone)]
511pub struct AggregateField {
512 pub function: String,
513 pub field: Option<String>,
514}
515
516#[derive(Debug, Clone)]
518pub struct GroupBySelection {
519 pub field: Option<String>,
520 pub fields: Option<Vec<String>>,
521 pub interval: Option<String>,
522 pub result_fields: Vec<String>,
523}
524
525#[derive(Debug, Clone)]
527pub struct LookupSelection {
528 pub collection: String,
529 pub local_field: String,
530 pub foreign_field: String,
531 pub filter: Option<Filter>,
532 pub selection_set: Vec<Selection>,
533}
534
535#[derive(Debug, Clone)]
537pub struct PageInfoSelection {
538 pub fields: Vec<String>,
539}
540
541#[derive(Debug, Clone)]
543pub struct EdgesSelection {
544 pub fields: Vec<EdgeField>,
545}
546
547#[derive(Debug, Clone)]
549pub enum EdgeField {
550 Cursor,
551 Node(Vec<Selection>),
552}
553
554#[derive(Debug, Clone)]
556pub struct DownsampleSelection {
557 pub interval: String,
558 pub aggregation: String,
559 pub selection_set: Vec<Selection>,
560}
561
562#[derive(Debug, Clone)]
564pub struct WindowFunctionSelection {
565 pub alias: String,
566 pub field: String,
567 pub function: String,
568 pub window_size: i64,
569}
570
571#[derive(Debug, Clone)]
577pub struct WhereClause {
578 pub filter: Filter,
579}
580
581#[derive(Debug, Clone)]
583pub struct OrderByClause {
584 pub orderings: Vec<Ordering>,
585}
586
587#[derive(Debug, Clone)]
589pub struct Ordering {
590 pub field: String,
591 pub direction: SortDirection,
592}
593
594#[derive(Debug, Clone, Copy, PartialEq, Eq)]
596pub enum SortDirection {
597 Asc,
598 Desc,
599}
600
601#[derive(Debug, Clone)]
603pub struct SearchArgs {
604 pub query: String,
605 pub fields: Vec<String>,
606 pub fuzzy: bool,
607 pub min_score: Option<f64>,
608}
609
610#[derive(Debug, Clone)]
612pub struct ValidateArgs {
613 pub rules: Vec<ValidationRule>,
614}
615
616#[derive(Debug, Clone)]
618pub struct ValidationRule {
619 pub field: String,
620 pub constraints: Vec<ValidationConstraint>,
621}
622
623#[derive(Debug, Clone)]
625pub enum ValidationConstraint {
626 Format(String),
627 Min(f64),
628 Max(f64),
629 MinLength(i64),
630 MaxLength(i64),
631 Pattern(String),
632}
633
634impl From<Vec<Value>> for Value {
635 fn from(v: Vec<Value>) -> Self {
636 Value::Array(v)
637 }
638}
639
640impl<const N: usize> From<[Value; N]> for Value {
641 fn from(v: [Value; N]) -> Self {
642 Value::Array(v.into_iter().collect())
643 }
644}