1 module graphql.testschema;
2 
3 import std.algorithm.iteration : map;
4 import std.datetime : DateTime, Date;
5 import std.typecons : Nullable;
6 import std.format : format;
7 
8 import vibe.data.json;
9 import nullablestore;
10 
11 import graphql.schema.directives;
12 import graphql.helper;
13 
14 import graphql.uda;
15 
16 @safe:
17 
18 Json datetimeToJson(DateTime dt) {
19 	return Json(dt.toISOExtString());
20 }
21 
22 // The Schema used by graphqld
23 
24 union SearchResult {
25 	Android android;
26 	Humanoid humanoid;
27 	Starship ship;
28 }
29 
30 string dtToString(DateTime dt) {
31 	return dt.toISOExtString();
32 }
33 
34 DateTime stringToDT(string s) {
35 	return DateTime.fromISOExtString(s);
36 }
37 
38 struct Input {
39 	size_t first;
40 	@optional
41 	Nullable!string after;
42 }
43 
44 @GQLDUda(TypeKind.OBJECT)
45 struct Query {
46 	@GQLDUda(
47 		GQLDDescription("Get the captain by Series")
48 	)
49 	Character captain(Series series);
50 	@GQLDUda(
51 		GQLDDeprecated(IsDeprecated.yes, "To complex")
52 	)
53 	SearchResult search(string name);
54 	Nullable!Starship starship(long id);
55 	Starship starshipDoesNotExist();
56 	Starship[] starships(float overSize = 100.0);
57 	Starship[] shipsselection(long[] ids);
58 	Nullable!Character character(long id);
59 	Character[] character(Series series);
60 	Humanoid[] humanoids();
61 	Android[] androids();
62 	Android[] resolverWillThrow();
63 	GQLDCustomLeaf!(DateTime, dtToString, stringToDT) currentTime();
64 	int currentTime();
65 	Starship numberBetween(Input searchInput);
66 
67 	NullableStore!(Starship[]) alwaysEmpty();
68 
69 	@GQLDUda(Ignore.yes)
70 	void ignoreMe() {
71 	}
72 }
73 
74 unittest {
75 	Query d;
76 }
77 
78 @GQLDUda(TypeKind.INPUT_OBJECT) struct Vector { float x, y; }
79 @GQLDUda(TypeKind.INPUT_OBJECT)
80 struct AddCrewmanData {
81 	string name;
82 	long shipId;
83 	Vector location;
84 	Series[] series;
85 }
86 
87 /*@GQLDUda(TypeKind.INPUT_OBJECT)
88 struct AddCrewmanComplexInput {
89 	Character crewman;
90 	Starship starship;
91 }*/
92 
93 interface Mutation {
94 	Character addCrewman(AddCrewmanData input);
95 	Character getStupidestCrewman();
96 	//Starship addCrewmanCompley(AddCrewmanComplexInput input);
97 }
98 
99 interface Subscription {
100 	Starship[] starships();
101 }
102 
103 class Schema {
104 	Query queryType;
105 	Mutation mutationType;
106 	Subscription subscriptionType;
107 	DefaultDirectives directives;
108 }
109 
110 enum Series {
111 	TheOriginalSeries,
112 	TheNextGeneration,
113 	DeepSpaceNine,
114 	Voyager,
115 	Enterprise,
116 	Discovery
117 }
118 
119 @GQLDUda(TypeKind.INTERFACE)
120 abstract class Character {
121 	long id;
122 	string name;
123 	Series[] series;
124 	Character[] commands;
125 	Nullable!Starship ship;
126 	NullableStore!Starship ships;
127 	Character[] commanders;
128 	Nullable!Starship allwaysNull;
129 	Nullable!int alsoAllwaysNull;
130 	const bool isDead;
131 
132 	//NullableStore!AddCrewmanData data;
133 }
134 
135 class Humanoid : Character {
136 	string species;
137 	GQLDCustomLeaf!(Date, dToString, stringToDT) dateOfBirth;
138 }
139 
140 class Android : Character {
141 	string primaryFunction;
142 
143 	@GQLDUda(Ignore.yes)
144 	void ignoreMeToo() {
145 	}
146 }
147 
148 @GQLDUda(
149 	GQLDDescription("The thing Chracters fly around in")
150 )
151 class Starship {
152 	long id;
153 	string name;
154 
155 	@GQLDUda(
156 		GQLDDescription("The name used when speaking about the ship")
157 	)
158 	string designation;
159 	double size;
160 
161 	@GQLDUda(
162 		GQLDDescription("The person in charge")
163 	)
164 	Character commander;
165 	Nullable!(Series)[] series;
166 	Character[] crew;
167 
168 	this(long id, string designation, double size, string name) {
169 		this.id = id;
170 		this.designation = designation;
171 		this.size = size;
172 		this.name = name;
173 	}
174 
175 	override string toString() const @safe {
176 		return format("Ship(id(%d), designation(%s), size(%.2f), name(%s)"
177 					~ "commander(%s), series[%(%s,%)], crew[%(%s,%)])",
178 				 id, designation, size, name, commander.name, series,
179 				 crew.map!(a => a.name)
180 			);
181 	}
182 }