Skip to content

Commit

Permalink
refactor!: Abstract away file location in its own struct
Browse files Browse the repository at this point in the history
We want to make Configy more generic, and to do that an obvious step
is to decouple it from the D-YAML struct used to represent location
in a file.
  • Loading branch information
Geod24 committed Sep 18, 2024
1 parent 99f4f70 commit 9eb9f7c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 27 deletions.
48 changes: 32 additions & 16 deletions source/configy/Exceptions.d
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,19 @@ import std.string : soundexer;
public abstract class ConfigException : Exception
{
/// Position at which the error happened
public Mark yamlPosition;
public Location loc;

/// The path in the configuration structure at which the error resides
public string path;

/// Constructor
public this (string path, Mark position,
public this (string path, Location position,
string file = __FILE__, size_t line = __LINE__)
@safe pure nothrow @nogc
{
super(null, file, line);
this.path = path;
this.yamlPosition = position;
this.loc = position;
}

/***************************************************************************
Expand Down Expand Up @@ -109,16 +109,16 @@ public abstract class ConfigException : Exception
char[20] buffer = void;

if (useColors) sink(Yellow);
sink(this.yamlPosition.name);
sink(this.loc.file);
if (useColors) sink(Reset);

sink("(");
if (useColors) sink(Cyan);
sink(unsignedToTempString(this.yamlPosition.line, buffer));
sink(unsignedToTempString(this.loc.line, buffer));
if (useColors) sink(Reset);
sink(":");
if (useColors) sink(Cyan);
sink(unsignedToTempString(this.yamlPosition.column, buffer));
sink(unsignedToTempString(this.loc.column, buffer));
if (useColors) sink(Reset);
sink("): ");

Expand Down Expand Up @@ -168,14 +168,14 @@ public abstract class ConfigException : Exception
/// A configuration exception that is only a single message
package final class ConfigExceptionImpl : ConfigException
{
public this (string msg, Mark position,
public this (string msg, Location position,
string file = __FILE__, size_t line = __LINE__)
@safe pure nothrow @nogc
{
this(msg, null, position, file, line);
}

public this (string msg, string path, Mark position,
public this (string msg, string path, Location position,
string file = __FILE__, size_t line = __LINE__)
@safe pure nothrow @nogc
{
Expand Down Expand Up @@ -205,13 +205,13 @@ package final class TypeConfigException : ConfigException
string file = __FILE__, size_t line = __LINE__)
@safe nothrow
{
this(node.nodeTypeString(), expected, path, node.startMark(),
this(node.nodeTypeString(), expected, path, Location.get(node),
file, line);
}

/// Ditto
public this (string actual, string expected, string path, Mark position,
string file = __FILE__, size_t line = __LINE__)
public this (string actual, string expected, string path,
Location position, string file = __FILE__, size_t line = __LINE__)
@safe pure nothrow @nogc
{
super(path, position, file, line);
Expand Down Expand Up @@ -251,7 +251,7 @@ package final class DurationTypeConfigException : ConfigException
public this (Node node, string path, string file = __FILE__, size_t line = __LINE__)
@safe nothrow
{
super(path, node.startMark(), file, line);
super(path, Location.get(node), file, line);
this.actual = node.nodeTypeString();
}

Expand Down Expand Up @@ -282,7 +282,7 @@ public class UnknownKeyConfigException : ConfigException

/// Constructor
public this (string path, string key, immutable string[] fieldNames,
Mark position, string file = __FILE__, size_t line = __LINE__)
Location position, string file = __FILE__, size_t line = __LINE__)
@safe pure nothrow
{
super(path.addPath(key), position, file, line);
Expand Down Expand Up @@ -329,7 +329,7 @@ public class UnknownKeyConfigException : ConfigException
public class MissingKeyException : ConfigException
{
/// Constructor
public this (string path, Mark position,
public this (string path, Location position,
string file = __FILE__, size_t line = __LINE__)
@safe pure nothrow @nogc
{
Expand All @@ -349,7 +349,7 @@ public class MissingKeyException : ConfigException
public class ConstructionException : ConfigException
{
/// Constructor
public this (Exception next, string path, Mark position,
public this (Exception next, string path, Location position,
string file = __FILE__, size_t line = __LINE__)
@safe pure nothrow @nogc
{
Expand Down Expand Up @@ -377,7 +377,7 @@ public class ArrayLengthException : ConfigException

/// Constructor
public this (size_t actual, size_t expected,
string path, Mark position,
string path, Location position,
string file = __FILE__, size_t line = __LINE__)
@safe pure nothrow @nogc
{
Expand All @@ -403,3 +403,19 @@ public class ArrayLengthException : ConfigException
sink(unsignedToTempString(this.actual, buffer));
}
}

// Helper struct to abstract away the YAML type
package struct Location {
/// File from which this `Node` originates, or `null`
public string file;
/// Line in `file` at which this `Node` is located, or `0`
public size_t line;
/// Column in `line` of `file` at which this `Node` originates, or `0`
public size_t column;

/// Helper function
package static Location get (Node n) @safe pure nothrow @nogc {
auto m = n.startMark();
return Location(m.name, m.line, m.column);
}
}
22 changes: 11 additions & 11 deletions source/configy/Read.d
Original file line number Diff line number Diff line change
Expand Up @@ -522,12 +522,12 @@ private TLFR.Type parseMapping (alias TLFR)
if (ctx.strict == StrictMode.Warn)
{
scope exc = new UnknownKeyConfigException(
path, key.as!string, fieldNames, key.startMark());
path, key.as!string, fieldNames, Location.get(key));
exc.printException();
}
else
throw new UnknownKeyConfigException(
path, key.as!string, fieldNames, key.startMark());
path, key.as!string, fieldNames, Location.get(key));
}
}
}
Expand Down Expand Up @@ -571,7 +571,7 @@ private TLFR.Type parseMapping (alias TLFR)

if (ctx.strict && FR.FieldName in node)
throw new ConfigExceptionImpl("'Key' field is specified twice",
path.addPath(FR.FieldName), node.startMark());
path.addPath(FR.FieldName), Location.get(node));
return (*ptr).parseField!(FR)(path.addPath(FR.FieldName), default_, ctx)
.dbgWriteRet("Using value '%s' from fieldDefaults for field '%s'",
FR.FieldName.paint(Cyan));
Expand Down Expand Up @@ -613,7 +613,7 @@ private TLFR.Type parseMapping (alias TLFR)
return Node(aa).parseMapping!(FR)(npath, default_, ctx, null);
}
else
throw new MissingKeyException(path.addPath(FR.Name), node.startMark());
throw new MissingKeyException(path.addPath(FR.Name), Location.get(node));
}

FR.Type convert (alias FR) ()
Expand Down Expand Up @@ -709,19 +709,19 @@ package FR.Type parseField (alias FR)
true);

else static if (hasConverter!(FR.Ref))
return wrapConstruct(node.viaConverter!(FR), path, node.startMark());
return wrapConstruct(node.viaConverter!(FR), path, Location.get(node));

else static if (hasFromYAML!(FR.Type))
{
scope impl = new ConfigParserImpl!(FR.Type)(node, path, ctx);
return wrapConstruct(FR.Type.fromYAML(impl), path, node.startMark());
return wrapConstruct(FR.Type.fromYAML(impl), path, Location.get(node));
}

else static if (hasFromString!(FR.Type))
return wrapConstruct(FR.Type.fromString(node.as!string), path, node.startMark());
return wrapConstruct(FR.Type.fromString(node.as!string), path, Location.get(node));

else static if (hasStringCtor!(FR.Type))
return wrapConstruct(FR.Type(node.as!string), path, node.startMark());
return wrapConstruct(FR.Type(node.as!string), path, Location.get(node));

else static if (is(immutable(FR.Type) == immutable(core.time.Duration)))
{
Expand Down Expand Up @@ -786,7 +786,7 @@ package FR.Type parseField (alias FR)
throw new TypeConfigException(
"sequence of " ~ pair.value.nodeTypeString(),
"sequence of mapping (array of objects)",
path, node.startMark());
path, Location.get(node));

return pair.value.parseMapping!(StructFieldRef!E)(
path.addPath(pair.key.as!string),
Expand All @@ -804,7 +804,7 @@ package FR.Type parseField (alias FR)
{
if (res.length != k)
throw new ArrayLengthException(
res.length, k, path, node.startMark());
res.length, k, path, Location.get(node));
return res[0 .. k];
}
else
Expand Down Expand Up @@ -867,7 +867,7 @@ private T parseScalar (T) (Node node, lazy string path)
*******************************************************************************/

private T wrapConstruct (T) (lazy T exp, string path, Mark position,
private T wrapConstruct (T) (lazy T exp, string path, Location position,
string file = __FILE__, size_t line = __LINE__)
{
try
Expand Down

0 comments on commit 9eb9f7c

Please sign in to comment.