1 /** 2 * Copyright © Yurai Web Framework 2021 3 * License: MIT (https://github.com/YuraiWeb/yurai/blob/main/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 */ 6 module yurai.controllers.controller; 7 8 import yurai.core; 9 import yurai.controllers.status; 10 import yurai.controllers.controlleraction; 11 import yurai.controllers.controlleractionset; 12 import yurai.external.iserver; 13 14 /// 15 public class Controller 16 { 17 private: 18 IHttpRequest _request; 19 IHttpResponse _response; 20 IServer _server; 21 ControllerActionSet[string] _actions; 22 23 void createMissingActionSet(string method) 24 { 25 import std.string : toLower; 26 27 method = method.toLower; 28 29 if (method !in _actions) 30 { 31 _actions[method] = new ControllerActionSet; 32 } 33 } 34 35 public: 36 this(IHttpRequest request, IHttpResponse response) 37 { 38 _request = request; 39 _response = response; 40 _server = _request.server; 41 } 42 43 final: 44 @property 45 { 46 IHttpRequest request() { return _request; } 47 48 IHttpResponse response() { return _response; } 49 50 IServer server() { return _server; } 51 } 52 53 void mapMandatoryAction(string method, ControllerAction action) 54 { 55 import std.string : toLower; 56 57 createMissingActionSet(method); 58 59 _actions[method.toLower].mandatoryAction = action; 60 } 61 62 void mapDefaultAction(string method, ControllerAction action) 63 { 64 import std.string : toLower; 65 66 createMissingActionSet(method); 67 68 _actions[method.toLower].defaultAction = action; 69 } 70 71 void mapRoutedAction(string method, string name, ControllerAction action) 72 { 73 import std.string : toLower; 74 75 createMissingActionSet(method); 76 77 _actions[method.toLower].mapRoutedAction(name.toLower, action); 78 } 79 80 Status json(T)(T o, bool pretty = true) 81 { 82 auto s = serializeJson(o, pretty); 83 84 return jsonString(s); 85 } 86 87 Status jsonString(string jsonString) 88 { 89 response.contentType = "application/json; charset=UTF-8"; 90 91 response.writeBody(jsonString); 92 93 return Status.end; 94 } 95 96 Status handle() 97 { 98 string actionRoute; 99 100 if (_request.path.length < 2) 101 { 102 actionRoute = "/"; 103 } 104 else 105 { 106 actionRoute = _request.path[1]; 107 } 108 109 if (!_actions) 110 { 111 return Status.notFound; 112 } 113 114 import std.string : toLower; 115 116 auto methodActions = _actions.get(_request.method.toLower, null); 117 118 if (!methodActions) 119 { 120 return Status.notFound; 121 } 122 123 if (methodActions.mandatoryAction) 124 { 125 ControllerAction mandatoryAction = methodActions.mandatoryAction; 126 Status mandatoryResult = mandatoryAction(); 127 128 if (mandatoryResult != Status.success) 129 { 130 return mandatoryResult; 131 } 132 } 133 134 if (actionRoute == "/" && methodActions.defaultAction) 135 { 136 ControllerAction defaultAction = methodActions.defaultAction; 137 Status defaultResult = defaultAction(); 138 139 return defaultResult; 140 } 141 142 ControllerAction routedAction = methodActions.getRoutedAction(actionRoute); 143 144 if (routedAction) 145 { 146 Status routedResult = routedAction(); 147 148 return routedResult; 149 } 150 151 return Status.notFound; 152 } 153 }