Skip to content

Commit

Permalink
Support DMD 2.108 string interpolation in log.level()
Browse files Browse the repository at this point in the history
  • Loading branch information
FeepingCreature committed Jun 13, 2024
1 parent 8679b7d commit d38ab58
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
7 changes: 7 additions & 0 deletions example.d
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ name "example"
dependency "log" path="."
+/

import std.compiler : version_minor;
import util.log;

string details()
Expand All @@ -30,8 +31,14 @@ void main()
log.warn("mostly harmless"d);
log.info("the answer is %s", 42);
log.info!"the answer is %s"(42);
static if (version_minor >= 108)
{
// mixin so that it passes the lexer on older dmd
mixin(`log.info(i"the answer is $(42)");`);
}
log.trace(details);


version (Posix)
{
Log syslog = Log(syslogLogger);
Expand Down
63 changes: 62 additions & 1 deletion src/util/log.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,23 @@ module util.log;

import std.algorithm;
import std.array;
import std.compiler : version_minor;
import std.conv;
import std.datetime;
import std.format;
import std.format : formattedWrite;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.typecons;

private enum supportsStringInterpolation = version_minor >= 108;

static if (supportsStringInterpolation)
{
import core.interpolation;
}

/// Defines the importance of a log message.
enum LogLevel
{
Expand Down Expand Up @@ -165,6 +173,24 @@ struct Log
}
}
}

static if (supportsStringInterpolation)
{
void append(Fence _ = Fence(), string file = __FILE__, size_t line = __LINE__, A...)
(InterpolationHeader header, lazy A args, InterpolationFooter footer)
{
static if (!level.disabled)
{
if (level & levels)
{
A evaluatedArgs = args;

_append(level, file, line,
(scope Sink sink) { sink.formattedWrite(header, evaluatedArgs, footer); });
}
}
}
}
}

private void _append(LogLevel level, string file, size_t line,
Expand Down Expand Up @@ -622,3 +648,38 @@ unittest
(-90).minutes._toISOString(writer);
assert(writer.data == "-01:30");
}

static if (supportsStringInterpolation)
{
// Placeholder pending https://issues.dlang.org/show_bug.cgi?id=24550
private void formattedWrite(Sink, Args...)(ref Sink sink, InterpolationHeader _header, Args args,
InterpolationFooter _footer)
{
import std.format : formattedWrite;
import std.meta : aliasSeqOf, Filter, staticMap;

// Translate interpolation string to classic format string
enum string formatString = [staticMap!(toFormatStringFragment, Args)].join;
enum bool isFormatValueArgument(size_t i) = toFormatStringFragment!(Args[i]) == "";
enum size_t[] valueArgIndexes = [Filter!(isFormatValueArgument, aliasSeqOf!(Args.length.iota))];
enum string valueArgs = valueArgIndexes.map!(a => format!"args[%s]"(a)).join;

mixin("sink.formattedWrite!formatString(" ~ valueArgs ~ ");");
}

private template toFormatStringFragment(alias A)
{
static if (is(A : InterpolatedLiteral!str, string str))
{
enum toFormatStringFragment = str;
}
else static if (is(A : InterpolatedExpression!str, string str))
{
enum toFormatStringFragment = "%s";
}
else
{
enum toFormatStringFragment = "";
}
}
}

0 comments on commit d38ab58

Please sign in to comment.