rusty_gql/types/
type_definition.rs1use graphql_parser::schema::TypeDefinition as ParserTypeDefinition;
2
3use crate::{FieldType, GqlDirective, Schema};
4
5use super::{
6 enum_type::EnumType, input_object::InputObjectType, interface::InterfaceType,
7 object::ObjectType, scalar::ScalarType, union_type::UnionType,
8};
9
10#[derive(Debug, Clone)]
11pub enum TypeDefinition {
12 Scalar(ScalarType),
13 Object(ObjectType),
14 Interface(InterfaceType),
15 Union(UnionType),
16 Enum(EnumType),
17 InputObject(InputObjectType),
18}
19
20impl ToString for TypeDefinition {
21 fn to_string(&self) -> String {
22 match self {
23 TypeDefinition::Scalar(_) => "Scalar".to_string(),
24 TypeDefinition::Object(_) => "Object".to_string(),
25 TypeDefinition::Interface(_) => "Interface".to_string(),
26 TypeDefinition::Union(_) => "Union".to_string(),
27 TypeDefinition::Enum(_) => "Enum".to_string(),
28 TypeDefinition::InputObject(_) => "InputObject".to_string(),
29 }
30 }
31}
32
33impl TypeDefinition {
34 pub fn from_schema_type_def(ty_def: &ParserTypeDefinition<'_, String>) -> Self {
35 match ty_def {
36 ParserTypeDefinition::Scalar(v) => TypeDefinition::Scalar(ScalarType::from(v.clone())),
37 ParserTypeDefinition::Object(v) => TypeDefinition::Object(ObjectType::from(v.clone())),
38 ParserTypeDefinition::Interface(v) => {
39 TypeDefinition::Interface(InterfaceType::from(v.clone()))
40 }
41 ParserTypeDefinition::Union(v) => TypeDefinition::Union(UnionType::from(v.clone())),
42 ParserTypeDefinition::Enum(v) => TypeDefinition::Enum(EnumType::from(v.clone())),
43 ParserTypeDefinition::InputObject(v) => {
44 TypeDefinition::InputObject(InputObjectType::from(v.clone()))
45 }
46 }
47 }
48
49 pub fn name(&self) -> &str {
50 match self {
51 TypeDefinition::Scalar(scalar) => &scalar.name,
52 TypeDefinition::Object(obj) => &obj.name,
53 TypeDefinition::Interface(interface) => &interface.name,
54 TypeDefinition::Union(uni) => &uni.name,
55 TypeDefinition::Enum(enu) => &enu.name,
56 TypeDefinition::InputObject(input_object) => &input_object.name,
57 }
58 }
59
60 pub fn description(&self) -> &Option<String> {
61 match self {
62 TypeDefinition::Scalar(scalar) => &scalar.description,
63 TypeDefinition::Object(obj) => &obj.description,
64 TypeDefinition::Interface(interface) => &interface.description,
65 TypeDefinition::Union(uni) => &uni.description,
66 TypeDefinition::Enum(enu) => &enu.description,
67 TypeDefinition::InputObject(input_object) => &input_object.description,
68 }
69 }
70
71 pub fn fields(&self) -> Option<&Vec<FieldType>> {
72 match self {
73 TypeDefinition::Object(obj) => Some(&obj.fields),
74 TypeDefinition::Interface(interface) => Some(&interface.fields),
75 _ => None,
76 }
77 }
78
79 pub fn get_field_by_name(&self, name: &str) -> Option<&FieldType> {
80 self.fields()
81 .and_then(|fields| fields.iter().find(|f| f.name == name))
82 }
83
84 pub fn is_composite_type(&self) -> bool {
85 matches!(
86 self,
87 &TypeDefinition::Object(_) | &TypeDefinition::Interface(_) | &TypeDefinition::Union(_)
88 )
89 }
90
91 pub fn is_input_type(&self) -> bool {
92 matches!(
93 self,
94 &TypeDefinition::Scalar(_) | &TypeDefinition::InputObject(_) | &TypeDefinition::Enum(_)
95 )
96 }
97 pub fn is_leaf_type(&self) -> bool {
98 matches!(self, &TypeDefinition::Enum(_) | &TypeDefinition::Scalar(_))
99 }
100
101 pub fn directives(&self) -> &[GqlDirective] {
102 match self {
103 TypeDefinition::Scalar(ty) => &ty.directives,
104 TypeDefinition::Object(ty) => &ty.directives,
105 TypeDefinition::Interface(ty) => &ty.directives,
106 TypeDefinition::Union(ty) => &ty.directives,
107 TypeDefinition::Enum(ty) => &ty.directives,
108 TypeDefinition::InputObject(ty) => &ty.directives,
109 }
110 }
111
112 pub fn field_directives(&self, field_name: &str) -> Vec<GqlDirective> {
113 let mut directives = vec![];
114
115 if let TypeDefinition::Object(obj) = self {
116 for field in &obj.fields {
117 if field.name == field_name {
118 directives.extend(field.directives.clone());
119 }
120 }
121 }
122 if let TypeDefinition::Interface(interface) = self {
123 for field in &interface.fields {
124 if field.name == field_name {
125 directives.extend(field.directives.clone());
126 }
127 }
128 }
129 directives
130 }
131
132 pub fn impl_interface_directives(&self, schema: &Schema) -> Vec<GqlDirective> {
133 let mut directives = vec![];
134
135 if let TypeDefinition::Object(obj) = self {
136 for impl_interface in &obj.implements_interfaces {
137 if let Some(interface) = &schema.interfaces.get(impl_interface) {
138 directives.extend(interface.directives.clone());
139 }
140 }
141 }
142 directives
143 }
144}