typeql/query/
mod.rs

1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5 */
6
7use std::fmt;
8
9use self::pipeline::stage::{Match, Stage};
10pub use self::{
11    pipeline::{stage, Pipeline},
12    schema::SchemaQuery,
13};
14use crate::{
15    common::{error::TypeQLError::InvalidCasting, Span},
16    token,
17};
18
19pub mod pipeline;
20pub mod schema;
21
22#[derive(Debug, Eq, PartialEq)]
23pub struct Query {
24    pub span: Option<Span>,
25    pub structure: QueryStructure,
26    pub has_explicit_end: bool,
27}
28
29impl Query {
30    pub(crate) fn new(span: Option<Span>, structure: QueryStructure, has_explicit_end: bool) -> Self {
31        Self { span, structure, has_explicit_end }
32    }
33
34    pub fn has_explicit_end(&self) -> bool {
35        self.has_explicit_end
36    }
37
38    pub fn into_structure(self) -> QueryStructure {
39        self.structure
40    }
41}
42
43impl fmt::Display for Query {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        fmt::Display::fmt(&self.structure, f)?;
46        if self.has_explicit_end {
47            if f.alternate() {
48                write!(f, "\n{}", token::Clause::End)
49            } else {
50                write!(f, "{}", token::Clause::End)
51            }
52        } else {
53            Ok(())
54        }
55    }
56}
57
58#[derive(Debug, Eq, PartialEq)]
59pub enum QueryStructure {
60    Schema(SchemaQuery),
61    Pipeline(Pipeline),
62}
63
64impl QueryStructure {
65    fn variant_name(&self) -> &'static str {
66        match self {
67            Self::Schema(_) => "Schema",
68            Self::Pipeline(_) => "Pipeline",
69        }
70    }
71
72    pub fn into_schema(self) -> SchemaQuery {
73        match self {
74            Self::Schema(schema) => schema,
75            _ => panic!(
76                "{}",
77                InvalidCasting {
78                    enum_name: stringify!(QueryStructure),
79                    variant: self.variant_name(),
80                    expected_variant: stringify!(Schema),
81                    typename: stringify!(SchemaQuery),
82                }
83            ),
84        }
85    }
86
87    pub fn into_pipeline(self) -> Pipeline {
88        match self {
89            QueryStructure::Pipeline(pipeline) => pipeline,
90            _ => panic!(
91                "{}",
92                InvalidCasting {
93                    enum_name: stringify!(QueryStructure),
94                    variant: self.variant_name(),
95                    expected_variant: stringify!(Pipeline),
96                    typename: stringify!(Pipeline),
97                }
98            ),
99        }
100    }
101}
102
103impl fmt::Display for QueryStructure {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        match self {
106            Self::Schema(schema_query) => fmt::Display::fmt(schema_query, f),
107            Self::Pipeline(data_query) => fmt::Display::fmt(data_query, f),
108        }
109    }
110}
111
112impl From<Match> for Query {
113    fn from(value: Match) -> Self {
114        Self::new(None, QueryStructure::Pipeline(Pipeline::new(None, Vec::new(), vec![Stage::Match(value)])), false)
115    }
116}