Initial commit
This commit is contained in:
3
dscanner.ini
Normal file
3
dscanner.ini
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[analysis.config.StaticAnalysisConfig]
|
||||||
|
number_style_check="disabled"
|
||||||
|
long_line_check="disabled"
|
||||||
3
dub.sdl
Normal file
3
dub.sdl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name "thirdworld-common"
|
||||||
|
targetType "sourceLibrary"
|
||||||
|
dependency "vibe-core" version="~>2.14.0"
|
||||||
12
dub.selections.json
Normal file
12
dub.selections.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"fileVersion": 1,
|
||||||
|
"versions": {
|
||||||
|
"during": "0.3.0",
|
||||||
|
"eventcore": "0.9.39",
|
||||||
|
"silly": "1.1.1",
|
||||||
|
"stdx-allocator": "2.77.5",
|
||||||
|
"taggedalgebraic": "1.0.1",
|
||||||
|
"vibe-container": "1.7.1",
|
||||||
|
"vibe-core": "2.14.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
41
source/thirdworld/common/config.d
Normal file
41
source/thirdworld/common/config.d
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
module thirdworld.common.config;
|
||||||
|
|
||||||
|
import common.log;
|
||||||
|
|
||||||
|
import std.file : readText, exists, isFile, write;
|
||||||
|
import std.json;
|
||||||
|
import std.path : absolutePath;
|
||||||
|
|
||||||
|
JSONValue structToJSON(T)(T s) {
|
||||||
|
JSONValue json;
|
||||||
|
foreach (member; __traits(allMembers, T)) {
|
||||||
|
json[member] = JSONValue(__traits(getMember, s, member));
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createConfigFile(T)(string path) {
|
||||||
|
path = absolutePath(path);
|
||||||
|
if (exists(path) && isFile(path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logInfo("No config file found, creating default config file at '%s'", path);
|
||||||
|
|
||||||
|
T config;
|
||||||
|
auto json = structToJSON(config);
|
||||||
|
write(path, json.toPrettyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
T configFromFile(T)(string path) {
|
||||||
|
string text = readText(path);
|
||||||
|
JSONValue json = parseJSON(text);
|
||||||
|
|
||||||
|
T config;
|
||||||
|
|
||||||
|
foreach (member; __traits(allMembers, T)) {
|
||||||
|
config[member] = json[member];
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
92
source/thirdworld/common/log.d
Normal file
92
source/thirdworld/common/log.d
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
module thirdworld.common.log;
|
||||||
|
|
||||||
|
import std.stdio : File, stdout, stderr;
|
||||||
|
import vibe.core.log;
|
||||||
|
|
||||||
|
public import vibe.core.log : logCritical, logDebug, logDebugV, logDiagnostic,
|
||||||
|
logError, logException, logFatal, logInfo,
|
||||||
|
logTrace, logWarn, setLogLevel, LogLevel;
|
||||||
|
|
||||||
|
shared static this() {
|
||||||
|
auto logger = cast(shared) new ThirdworldLogger;
|
||||||
|
deregisterAllLoggers();
|
||||||
|
registerLogger(logger);
|
||||||
|
logger.minLevel = LogLevel.info;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class ThirdworldLogger : Logger {
|
||||||
|
private {
|
||||||
|
File infoFile;
|
||||||
|
File diagFile;
|
||||||
|
File curFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
this(File info, File diag) {
|
||||||
|
infoFile = info;
|
||||||
|
diagFile = diag;
|
||||||
|
}
|
||||||
|
|
||||||
|
this(string filename) {
|
||||||
|
auto f = File(filename, "ab");
|
||||||
|
this(f, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
this() {
|
||||||
|
infoFile = stdout;
|
||||||
|
diagFile = stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void beginLine(ref LogLine message) @trusted {
|
||||||
|
string level;
|
||||||
|
final switch (message.level) {
|
||||||
|
case LogLevel.trace: level = "Trace"; curFile = diagFile; break;
|
||||||
|
case LogLevel.debugV: level = "Debug"; curFile = diagFile; break;
|
||||||
|
case LogLevel.debug_: level = "Debug"; curFile = diagFile; break;
|
||||||
|
case LogLevel.diagnostic: level = "Diagnostic"; curFile = diagFile; break;
|
||||||
|
case LogLevel.info: level = "Info"; curFile = infoFile; break;
|
||||||
|
case LogLevel.warn: level = "Warn"; curFile = diagFile; break;
|
||||||
|
case LogLevel.error: level = "Error"; curFile = diagFile; break;
|
||||||
|
case LogLevel.critical: level = "Critical"; curFile = diagFile; break;
|
||||||
|
case LogLevel.fatal: level = "Fatal"; curFile = diagFile; break;
|
||||||
|
case LogLevel.none: assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dst = curFile.lockingTextWriter;
|
||||||
|
final switch (message.level) {
|
||||||
|
case LogLevel.trace: dst.put("\x1b[49;38;5;243m"); break;
|
||||||
|
case LogLevel.debugV: dst.put("\x1b[49;38;5;245m"); break;
|
||||||
|
case LogLevel.debug_: dst.put("\x1b[49;38;5;180m"); break;
|
||||||
|
case LogLevel.diagnostic: dst.put("\x1b[49;38;5;143m"); break;
|
||||||
|
case LogLevel.info: dst.put("\x1b[49;38;5;29m"); break;
|
||||||
|
case LogLevel.warn: dst.put("\x1b[49;38;5;220m"); break;
|
||||||
|
case LogLevel.error: dst.put("\x1b[49;38;5;9m"); break;
|
||||||
|
case LogLevel.critical: dst.put("\x1b[41;38;5;15m"); break;
|
||||||
|
case LogLevel.fatal: dst.put("\x1b[48;5;9;30m"); break;
|
||||||
|
case LogLevel.none: assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto time = message.time;
|
||||||
|
auto msecs = time.fracSecs.total!"msecs";
|
||||||
|
curFile.writef("%d-%02d-%02d %02d:%02d:%02d.%03d ", time.year, time.month, time.day, time.hour, time.minute, time.second, msecs);
|
||||||
|
dst.put('[');
|
||||||
|
dst.put(level);
|
||||||
|
dst.put("] ");
|
||||||
|
}
|
||||||
|
|
||||||
|
override void put(scope const(char)[] text) {
|
||||||
|
curFile.write(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void endLine() {
|
||||||
|
curFile.write("\x1b[0m");
|
||||||
|
curFile.writeln();
|
||||||
|
curFile.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deregisterAllLoggers() @trusted nothrow {
|
||||||
|
auto loggers = getLoggers();
|
||||||
|
foreach (logger; loggers) {
|
||||||
|
deregisterLogger(logger);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user