1 /** 2 * The custom text transformer that implements the gogga-stylised 3 * logging messages 4 */ 5 module gogga.transform; 6 7 import dlog; 8 import gogga.context; 9 import std.conv : to; 10 11 /** 12 * The gogga styles supported 13 */ 14 public enum GoggaMode 15 { 16 /** 17 * TwoKTwenty3 is: `[<file>] (<module>:<lineNumber>) <message>` 18 */ 19 TwoKTwenty3, 20 21 /** 22 * Simple mode is just: `[<LEVEL>] <message>` 23 */ 24 SIMPLE, 25 26 /** 27 * Rustacean mode is: `[<LEVEL>] (<filePath>/<functionName>:<lineNumber>) <message>` 28 */ 29 RUSTACEAN, 30 31 /** 32 * Simple rustacean mode is: `[<LEVEL>] (<functionName>:<lineNumber>) <message>` 33 */ 34 RUSTACEAN_SIMPLE 35 } 36 37 /** 38 * The custom gogga text transformer 39 */ 40 public class GoggaTransform : MessageTransform 41 { 42 /** 43 * Current style 44 */ 45 private GoggaMode mode; 46 47 /** 48 * Transforms the provided text 49 * 50 * Params: 51 * text = text to transform 52 * ctx = the context passed in 53 * Returns: a string of transformed text 54 */ 55 public override string transform(string text, Context ctx) 56 { 57 /* The generated output string */ 58 string finalOutput; 59 60 61 /* Get the GoggaContext */ 62 GoggaContext gCtx = cast(GoggaContext)ctx; 63 64 /* Extract the line information */ 65 CompilationInfo compInfo = gCtx.getLineInfo(); 66 string[] context = compInfo.toArray(); 67 68 /* Extract the Level */ 69 Level level = gCtx.getLevel(); 70 71 72 /** 73 * Simple mode is just: `[<LEVEL>] <message>` 74 */ 75 if(mode == GoggaMode.SIMPLE) 76 { 77 finalOutput = cast(string)debugColor("["~to!(string)(level)~"] ", level); 78 79 finalOutput ~= text~"\n"; 80 } 81 /** 82 * TwoKTwenty3 is: `[<file>] (<module>:<lineNumber>) <message>` 83 */ 84 else if(mode == GoggaMode.TwoKTwenty3) 85 { 86 /* Module information (and status debugColoring) */ 87 string moduleInfo = cast(string)debugColor("["~context[1]~"]", level); 88 89 /* Function and line number info */ 90 string funcInfo = cast(string)(colorSrc("("~context[4]~":"~context[2]~")")); 91 92 finalOutput = moduleInfo~" "~funcInfo~" "~text~"\n"; 93 } 94 /** 95 * Rustacean mode is: `[<LEVEL>] (<filePath>/<functionName>:<lineNumber>) <message>` 96 */ 97 else if(mode == GoggaMode.RUSTACEAN) 98 { 99 finalOutput = cast(string)debugColor(to!(string)(level)~"\t", level); 100 finalOutput ~= cast(string)(colorSrc(context[1]~"/"~context[4]~":"~context[2]~" ")); 101 finalOutput ~= text~"\n"; 102 } 103 /** 104 * Simple rustacean mode is: `[<LEVEL>] (<functionName>:<lineNumber>) <message>` 105 */ 106 else if(mode == GoggaMode.RUSTACEAN_SIMPLE) 107 { 108 finalOutput = cast(string)debugColor(to!(string)(level)~"\t", level); 109 finalOutput ~= cast(string)(colorSrc(context[4]~":"~context[2]~" ")); 110 finalOutput ~= text~"\n"; 111 } 112 113 return finalOutput; 114 } 115 116 /** 117 * Set the gogga style 118 * 119 * Params: 120 * mode = the GoggaMode to use 121 */ 122 public void setMode(GoggaMode mode) 123 { 124 this.mode = mode; 125 } 126 } 127 128 /** 129 * Colorise the text provided accoridng to the level and then 130 * reset the colors at the end 131 * 132 * Params: 133 * text = the text to colorise 134 * level = the color to use 135 * Returns: the byte sequence of characters and controls 136 */ 137 private byte[] debugColor(string text, Level level) 138 { 139 /* The generated message */ 140 byte[] messageBytes; 141 142 /* If INFO, set green */ 143 if(level == Level.INFO) 144 { 145 messageBytes = cast(byte[])[27, '[','3','2','m']; 146 } 147 /* If WARN, set yellow */ 148 else if(level == Level.WARN) 149 { 150 messageBytes = cast(byte[])[27, '[','3','1', ';', '9', '3', 'm']; 151 } 152 /* If ERROR, set red */ 153 else if(level == Level.ERROR) 154 { 155 messageBytes = cast(byte[])[27, '[','3','1','m']; 156 } 157 /* If DEBUG, set pink */ 158 else 159 { 160 messageBytes = cast(byte[])[27, '[','3','5','m']; 161 } 162 163 /* Add the message */ 164 messageBytes ~= cast(byte[])text; 165 166 /* Switch back debugColor */ 167 messageBytes ~= cast(byte[])[27, '[', '3', '9', 'm']; 168 169 /* Reset coloring */ 170 messageBytes ~= [27, '[', 'm']; 171 172 return messageBytes; 173 } 174 175 /** 176 * Colors the provided text in a gray fashion and then 177 * resets back to normal 178 * 179 * Params: 180 * text = the text to gray color 181 * Returns: the byte sequence of characters and controls 182 */ 183 private byte[] colorSrc(string text) 184 { 185 /* The generated message */ 186 byte[] messageBytes; 187 188 /* Reset coloring */ 189 messageBytes ~= [27, '[', 'm']; 190 191 /* Color gray */ 192 messageBytes ~= [27, '[', '3', '9', ';', '2', 'm']; 193 194 /* Append the message */ 195 messageBytes ~= text; 196 197 /* Reset coloring */ 198 messageBytes ~= [27, '[', 'm']; 199 200 return messageBytes; 201 }