1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! Errors from parsing Trustfall queries
use async_graphql_parser::Pos;
use async_graphql_value::Value;
use serde::{ser::Error as SerError, Deserialize, Serialize, Serializer};

#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, thiserror::Error)]
pub enum ParseError {
    #[error("Unrecognized directive {0}")]
    UnrecognizedDirective(String, Pos),

    #[error("Directive in unsupported position {0}: {1}")]
    UnsupportedDirectivePosition(String, String, Pos),

    #[error("Directive {0} missing required argument {1}")]
    MissingRequiredDirectiveArgument(String, String, Pos),

    #[error("Directive {0} received unrecognized argument {1}")]
    UnrecognizedDirectiveArgument(String, String, Pos),

    #[error("Directive {0} received duplicated argument {1}")]
    DuplicatedDirectiveArgument(String, String, Pos),

    #[error("Directive {0} received value of inappropriate type for argument {1}")]
    InappropriateTypeForDirectiveArgument(String, String, Pos),

    #[error("Field {0} received an invalid value for argument {1}: {2}")]
    InvalidFieldArgument(String, String, Value, Pos),

    #[error("Input contains non-inline fragments, this is not supported")]
    DocumentContainsNonInlineFragments(Pos),

    #[error("Input contains multiple operation blocks, this is not supported")]
    MultipleOperationsInDocument(Pos),

    #[error(
        "Input contains multiple root vertices, which is not supported. \
        Please make sure that only a single field inside the outer-most curly braces is expanded."
    )]
    MultipleQueryRoots(Pos),

    #[error("Found {0} instead of a root vertex, which is not supported.")]
    UnsupportedQueryRoot(String, Pos),

    #[error("Found directive {0} applied on or outside the root vertex, which is not supported ")]
    DirectiveNotInsideQueryRoot(String, Pos),

    #[error("Input is not a query operation")]
    DocumentNotAQuery(Pos),

    #[error("Unrecognized filter operator: {0}")]
    UnsupportedFilterOperator(String, Pos),

    #[error("Unrecognized transform operator: {0}")]
    UnsupportedTransformOperator(String, Pos),

    #[error("Output name \"{0}\" contains invalid characters: {1:?}")]
    InvalidOutputName(String, Vec<char>, Pos),

    #[error("Tag name \"{0}\" contains invalid characters: {1:?}")]
    InvalidTagName(String, Vec<char>, Pos),

    #[serde(
        skip_deserializing,
        serialize_with = "fail_serialize_invalid_graphql_error"
    )]
    #[error("{0}")]
    InvalidGraphQL(async_graphql_parser::Error),

    #[error("Unsupported syntax feature found: {0}")]
    UnsupportedSyntax(String, Pos),

    #[error("Nested type coercion found. Please merge the type coercion blocks so that coercion is only performed once.")]
    NestedTypeCoercion(Pos),

    #[error("Properties and edges side-by-side with a coercion (`... on X`) are not supported. Please move them inside the type coercion instead.")]
    TypeCoercionWithSiblingFields(Pos),

    #[error("Directive \"{0}\" is applied more than once, this is not supported.")]
    UnsupportedDuplicatedDirective(String, Pos),

    #[error("Edge {1} specifies a duplicated parameter {0}")]
    DuplicatedEdgeParameter(String, String, Pos),

    #[error("Unexpected error: {0}")]
    OtherError(String, Pos),
}

fn fail_serialize_invalid_graphql_error<S: Serializer>(
    _: &async_graphql_parser::Error,
    _: S,
) -> Result<S::Ok, S::Error> {
    Err(S::Error::custom(
        "cannot serialize InvalidGraphQL error variant",
    ))
}

impl From<async_graphql_parser::Error> for ParseError {
    fn from(e: async_graphql_parser::Error) -> Self {
        Self::InvalidGraphQL(e)
    }
}