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 	@GQLDUda(Ignore.yes)
68 	void ignoreMe() {
69 	}
70 }
71 
72 unittest {
73 	Query d;
74 }
75 
76 @GQLDUda(TypeKind.INPUT_OBJECT)
77 struct AddCrewmanData {
78 	string name;
79 	long shipId;
80 	Series[] series;
81 }
82 
83 /*@GQLDUda(TypeKind.INPUT_OBJECT)
84 struct AddCrewmanComplexInput {
85 	Character crewman;
86 	Starship starship;
87 }*/
88 
89 interface Mutation {
90 	Character addCrewman(AddCrewmanData input);
91 	Character getStupidestCrewman();
92 	//Starship addCrewmanCompley(AddCrewmanComplexInput input);
93 }
94 
95 interface Subscription {
96 	Starship[] starships();
97 }
98 
99 class Schema {
100 	Query queryType;
101 	Mutation mutationType;
102 	Subscription subscriptionType;
103 	DefaultDirectives directives;
104 }
105 
106 enum Series {
107 	TheOriginalSeries,
108 	TheNextGeneration,
109 	DeepSpaceNine,
110 	Voyager,
111 	Enterprise,
112 	Discovery
113 }
114 
115 @GQLDUda(TypeKind.INTERFACE)
116 abstract class Character {
117 	long id;
118 	string name;
119 	Series[] series;
120 	Character[] commands;
121 	Nullable!Starship ship;
122 	NullableStore!Starship ships;
123 	Character[] commanders;
124 	Nullable!Starship allwaysNull;
125 	Nullable!int alsoAllwaysNull;
126 
127 	//NullableStore!AddCrewmanData data;
128 }
129 
130 class Humanoid : Character {
131 	string species;
132 	GQLDCustomLeaf!(Date, dToString, stringToDT) dateOfBirth;
133 }
134 
135 class Android : Character {
136 	string primaryFunction;
137 
138 	@GQLDUda(Ignore.yes)
139 	void ignoreMeToo() {
140 	}
141 }
142 
143 @GQLDUda(
144 	GQLDDescription("The thing Chracters fly around in")
145 )
146 class Starship {
147 	long id;
148 	string name;
149 
150 	@GQLDUda(
151 		GQLDDescription("The name used when speaking about the ship")
152 	)
153 	string designation;
154 	double size;
155 
156 	@GQLDUda(
157 		GQLDDescription("The person in charge")
158 	)
159 	Character commander;
160 	Nullable!(Series)[] series;
161 	Character[] crew;
162 
163 	this(long id, string designation, double size, string name) {
164 		this.id = id;
165 		this.designation = designation;
166 		this.size = size;
167 		this.name = name;
168 	}
169 
170 	override string toString() const @safe {
171 		return format("Ship(id(%d), designation(%s), size(%.2f), name(%s)"
172 					~ "commander(%s), series[%(%s,%)], crew[%(%s,%)])",
173 				 id, designation, size, name, commander.name, series,
174 				 crew.map!(a => a.name)
175 			);
176 	}
177 }