1 /** 2 * Methods to generate `severs.d`, which allows control over the servers used to contact the API. 3 */ 4 module openapi_client.servers; 5 6 import std.array : appender, split, Appender; 7 import std.file : mkdir, mkdirRecurse, write; 8 import std.path : buildNormalizedPath, dirName; 9 import std.string : tr; 10 11 import openapi : OasDocument, OasServer, OasServerVariable; 12 import openapi_client.util : wordWrapText, toUpperCamelCase; 13 14 /** 15 * Writes a utility class containing information about the REST API servers to contact. 16 */ 17 void writeServerFiles(OasDocument oasDocument, string targetDir, string packageRoot) { 18 auto buffer = appender!string(); 19 string moduleName = packageRoot ~ ".servers"; 20 with (buffer) { 21 put("// File automatically generated from OpenAPI spec.\n"); 22 put("module " ~ moduleName ~ ";\n\n"); 23 put("import openapi_client.util : resolveTemplate;\n"); 24 put("import std.stdio : writeln;\n"); 25 put("\n"); 26 put("class Servers {\n"); 27 // For now, only support a single URL, because it is unclear what to do if each server has 28 // different parameters. 29 put(" /**\n"); 30 put(" * The server URLs to contact the service with.\n"); 31 put(" * The URL may use named path-parameters within curly braces,\n"); 32 put(" * e.g. \"https://example.com/{version}/\".\n"); 33 put(" */\n"); 34 put(" static string serverUrl = \""); 35 put(oasDocument.servers[0].url); 36 put("\";\n\n"); 37 38 // Parameters that will be substituted into the serverURL. 39 put(" /**\n"); 40 put(" * Parameters that will be substituted into the serverURL.\n"); 41 put(" */\n"); 42 put(" static string[string] serverParams;\n\n"); 43 put(" static this() {\n"); 44 put(" serverParams = [\n"); 45 put(" \"none\": \"none\",\n"); 46 foreach (string name, OasServerVariable variable; oasDocument.servers[0].variables) { 47 put(" \"" ~ name ~ "\": \"" ~ variable.default_ ~ "\",\n"); 48 } 49 put(" ];\n"); 50 put(" }\n\n"); 51 // Documented methods to set the values for these parameters. 52 foreach (string name, OasServerVariable variable; oasDocument.servers[0].variables) { 53 put(" /**\n"); 54 put(" * Server URL Parameter: " ~ name ~ "\n"); 55 foreach (string line; wordWrapText(variable.description, 95)) { 56 put(" * "); 57 put(line); 58 put("\n"); 59 } 60 put(" * Valid values include:\n"); 61 foreach (string validValue; variable.enum_) { 62 put(" * - " ~ validValue ~ "\n"); 63 } 64 put(" */\n"); 65 put(" static void setParam" ~ toUpperCamelCase(name) ~ "(string value) {\n"); 66 put(" serverParams[\"" ~ name ~ "\"] = value;\n"); 67 put(" }\n\n"); 68 } 69 // Resolve the server URL using the current values of its parameters. 70 put(" /**\n"); 71 put(" * Chooses a url an OasPathItem given both path-specific and general servers.\n"); 72 put(" */\n"); 73 put(" static string getServerUrl() {\n"); 74 put(" return resolveTemplate(serverUrl, serverParams);\n"); 75 put(" }\n\n"); 76 put("}\n"); 77 } 78 string fileName = buildNormalizedPath(targetDir, tr(moduleName, ".", "/") ~ ".d"); 79 mkdirRecurse(dirName(fileName)); 80 write(fileName, buffer[]); 81 }