convert Resolver to struct (#229)
convert Resolver to struct merged-on-behalf-of: Basile-z <Basile-z@users.noreply.github.com>
This commit is contained in:
parent
fff8cead76
commit
8de1a45922
|
@ -12,12 +12,10 @@ int main(string[] args)
|
|||
|
||||
try
|
||||
{
|
||||
auto resolver = new Resolver;
|
||||
resolver.addImplicitResolver("!color", regex("[0-9a-fA-F]{6}"),
|
||||
"0123456789abcdefABCDEF");
|
||||
|
||||
auto loader = Loader.fromFile("input.yaml");
|
||||
loader.resolver = resolver;
|
||||
loader.resolver.addImplicitResolver("!color", regex("[0-9a-fA-F]{6}"),
|
||||
"0123456789abcdefABCDEF");
|
||||
|
||||
auto root = loader.load();
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ void main(string[] args) //@safe
|
|||
{
|
||||
// Instead of constructing a resolver/constructor with each Loader,
|
||||
// construct them once to remove noise when profiling.
|
||||
auto resolver = new Resolver();
|
||||
auto resolver = Resolver.withDefaultResolvers;
|
||||
|
||||
auto constructTime = stopWatch.peek();
|
||||
|
||||
|
|
|
@ -79,7 +79,6 @@ struct Composer
|
|||
pure @safe nothrow ~this()
|
||||
{
|
||||
parser_ = null;
|
||||
resolver_ = null;
|
||||
anchors_.destroy();
|
||||
anchors_ = null;
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ struct Dumper(Range)
|
|||
*/
|
||||
this(Range stream) @safe
|
||||
{
|
||||
resolver_ = new Resolver();
|
||||
resolver_ = Resolver.withDefaultResolvers;
|
||||
stream_ = stream;
|
||||
}
|
||||
|
||||
|
@ -110,9 +110,9 @@ struct Dumper(Range)
|
|||
}
|
||||
|
||||
///Specify custom Resolver to use.
|
||||
@property void resolver(Resolver resolver) @safe
|
||||
auto ref resolver() @safe
|
||||
{
|
||||
resolver_ = resolver;
|
||||
return resolver_;
|
||||
}
|
||||
|
||||
///Write scalars in _canonical form?
|
||||
|
@ -290,10 +290,10 @@ struct Dumper(Range)
|
|||
///Use a custom resolver to support custom data types and/or implicit tags
|
||||
@safe unittest
|
||||
{
|
||||
import std.regex : regex;
|
||||
auto node = Node([1, 2, 3, 4, 5]);
|
||||
auto resolver = new Resolver();
|
||||
auto dumper = dumper(new Appender!string());
|
||||
dumper.resolver = resolver;
|
||||
dumper.resolver.addImplicitResolver("!tag", regex("A.*"), "A");
|
||||
dumper.dump(node);
|
||||
}
|
||||
/// Set default scalar style
|
||||
|
|
|
@ -149,6 +149,7 @@ struct Loader
|
|||
/// Ditto
|
||||
private this(ubyte[] yamlData) @safe
|
||||
{
|
||||
resolver_ = Resolver.withDefaultResolvers;
|
||||
try
|
||||
{
|
||||
reader_ = new Reader(yamlData);
|
||||
|
@ -170,9 +171,9 @@ struct Loader
|
|||
}
|
||||
|
||||
/// Specify custom Resolver to use.
|
||||
void resolver(Resolver resolver) pure @safe nothrow @nogc
|
||||
auto ref resolver() pure @safe nothrow @nogc
|
||||
{
|
||||
resolver_ = resolver;
|
||||
return resolver_;
|
||||
}
|
||||
|
||||
/** Load single YAML document.
|
||||
|
@ -221,7 +222,6 @@ struct Loader
|
|||
static Composer composer;
|
||||
if (!rangeInitialized)
|
||||
{
|
||||
lazyInitConstructorResolver();
|
||||
composer = Composer(parser_, resolver_);
|
||||
rangeInitialized = true;
|
||||
}
|
||||
|
@ -290,13 +290,6 @@ struct Loader
|
|||
{
|
||||
return parser_;
|
||||
}
|
||||
|
||||
// Construct default constructor/resolver if the user has not yet specified
|
||||
// their own.
|
||||
void lazyInitConstructorResolver() @safe
|
||||
{
|
||||
if(resolver_ is null) { resolver_ = new Resolver(); }
|
||||
}
|
||||
}
|
||||
/// Load single YAML document from a file:
|
||||
@safe unittest
|
||||
|
@ -394,7 +387,7 @@ struct Loader
|
|||
writeln("Failed to read file 'example.yaml'");
|
||||
}
|
||||
}
|
||||
/// Use a custom constructor/resolver to support custom data types and/or implicit tags:
|
||||
/// Use a custom resolver to support custom data types and/or implicit tags:
|
||||
@safe unittest
|
||||
{
|
||||
import std.file : write;
|
||||
|
@ -404,11 +397,11 @@ struct Loader
|
|||
"Hello world!\n"~
|
||||
"...\n"
|
||||
);
|
||||
auto resolver = new Resolver();
|
||||
|
||||
// Add constructor functions / resolver expressions here...
|
||||
|
||||
auto loader = Loader.fromFile("example.yaml");
|
||||
loader.resolver = resolver;
|
||||
|
||||
// Add resolver expressions here...
|
||||
// loader.resolver.addImplicitResolver(...);
|
||||
|
||||
auto rootNode = loader.load();
|
||||
}
|
||||
|
|
|
@ -24,12 +24,53 @@ import dyaml.node;
|
|||
import dyaml.exception;
|
||||
|
||||
|
||||
static Tuple!(string, "tag", Regex!char, "regexp", string, "chars")[] regexes;
|
||||
|
||||
static this() @safe {
|
||||
regexes ~= tuple!("tag", "regexp", "chars")("tag:yaml.org,2002:bool",
|
||||
regex(r"^(?:yes|Yes|YES|no|No|NO|true|True|TRUE" ~
|
||||
"|false|False|FALSE|on|On|ON|off|Off|OFF)$"),
|
||||
"yYnNtTfFoO");
|
||||
regexes ~= tuple!("tag", "regexp", "chars")("tag:yaml.org,2002:float",
|
||||
regex(r"^(?:[-+]?([0-9][0-9_]*)\\.[0-9_]*" ~
|
||||
"(?:[eE][-+][0-9]+)?|[-+]?(?:[0-9][0-9_]" ~
|
||||
"*)?\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?" ~
|
||||
"[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]" ~
|
||||
"*|[-+]?\\.(?:inf|Inf|INF)|\\." ~
|
||||
"(?:nan|NaN|NAN))$"),
|
||||
"-+0123456789.");
|
||||
regexes ~= tuple!("tag", "regexp", "chars")("tag:yaml.org,2002:int",
|
||||
regex(r"^(?:[-+]?0b[0-1_]+" ~
|
||||
"|[-+]?0[0-7_]+" ~
|
||||
"|[-+]?(?:0|[1-9][0-9_]*)" ~
|
||||
"|[-+]?0x[0-9a-fA-F_]+" ~
|
||||
"|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$"),
|
||||
"-+0123456789");
|
||||
regexes ~= tuple!("tag", "regexp", "chars")("tag:yaml.org,2002:merge", regex(r"^<<$"), "<");
|
||||
regexes ~= tuple!("tag", "regexp", "chars")("tag:yaml.org,2002:null",
|
||||
regex(r"^$|^(?:~|null|Null|NULL)$"), "~nN\0");
|
||||
regexes ~= tuple!("tag", "regexp", "chars")("tag:yaml.org,2002:timestamp",
|
||||
regex(r"^[0-9][0-9][0-9][0-9]-[0-9][0-9]-" ~
|
||||
"[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9]" ~
|
||||
"[0-9]?-[0-9][0-9]?[Tt]|[ \t]+[0-9]" ~
|
||||
"[0-9]?:[0-9][0-9]:[0-9][0-9]" ~
|
||||
"(?:\\.[0-9]*)?(?:[ \t]*Z|[-+][0-9]" ~
|
||||
"[0-9]?(?::[0-9][0-9])?)?$"),
|
||||
"0123456789");
|
||||
regexes ~= tuple!("tag", "regexp", "chars")("tag:yaml.org,2002:value", regex(r"^=$"), "=");
|
||||
|
||||
|
||||
//The following resolver is only for documentation purposes. It cannot work
|
||||
//because plain scalars cannot start with '!', '&', or '*'.
|
||||
regexes ~= tuple!("tag", "regexp", "chars")("tag:yaml.org,2002:yaml", regex(r"^(?:!|&|\*)$"), "!&*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves YAML tags (data types).
|
||||
*
|
||||
* Can be used to implicitly resolve custom data types of scalar values.
|
||||
*/
|
||||
final class Resolver
|
||||
struct Resolver
|
||||
{
|
||||
private:
|
||||
// Default tag to use for scalars.
|
||||
|
@ -47,24 +88,21 @@ final class Resolver
|
|||
*/
|
||||
Tuple!(string, Regex!char)[][dchar] yamlImplicitResolvers_;
|
||||
|
||||
package:
|
||||
static auto withDefaultResolvers() @safe
|
||||
{
|
||||
Resolver resolver;
|
||||
foreach(pair; regexes)
|
||||
{
|
||||
resolver.addImplicitResolver(pair.tag, pair.regexp, pair.chars);
|
||||
}
|
||||
return resolver;
|
||||
}
|
||||
|
||||
public:
|
||||
@disable bool opEquals(ref Resolver);
|
||||
@disable int opCmp(ref Resolver);
|
||||
|
||||
/**
|
||||
* Construct a Resolver.
|
||||
*
|
||||
* If you don't want to implicitly resolve default YAML tags/data types,
|
||||
* you can use defaultImplicitResolvers to disable default resolvers.
|
||||
*
|
||||
* Params: defaultImplicitResolvers = Use default YAML implicit resolvers?
|
||||
*/
|
||||
this(Flag!"useDefaultImplicitResolvers" defaultImplicitResolvers = Yes.useDefaultImplicitResolvers)
|
||||
@safe
|
||||
{
|
||||
if(defaultImplicitResolvers){addImplicitResolvers();}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an implicit scalar resolver.
|
||||
*
|
||||
|
@ -105,9 +143,7 @@ final class Resolver
|
|||
write("example.yaml", "A");
|
||||
|
||||
auto loader = Loader.fromFile("example.yaml");
|
||||
auto resolver = new Resolver();
|
||||
resolver.addImplicitResolver("!tag", regex("A.*"), "A");
|
||||
loader.resolver = resolver;
|
||||
loader.resolver.addImplicitResolver("!tag", regex("A.*"), "A");
|
||||
|
||||
auto node = loader.load();
|
||||
assert(node.tag == "!tag");
|
||||
|
@ -169,7 +205,7 @@ final class Resolver
|
|||
}
|
||||
@safe unittest
|
||||
{
|
||||
auto resolver = new Resolver();
|
||||
auto resolver = Resolver.withDefaultResolvers;
|
||||
|
||||
bool tagMatch(string tag, string[] values) @safe
|
||||
{
|
||||
|
@ -215,46 +251,4 @@ final class Resolver
|
|||
|
||||
///Returns: Default mapping tag.
|
||||
@property string defaultMappingTag() const pure @safe nothrow {return defaultMappingTag_;}
|
||||
|
||||
private:
|
||||
// Add default implicit resolvers.
|
||||
void addImplicitResolvers() @safe
|
||||
{
|
||||
addImplicitResolver("tag:yaml.org,2002:bool",
|
||||
regex(r"^(?:yes|Yes|YES|no|No|NO|true|True|TRUE" ~
|
||||
"|false|False|FALSE|on|On|ON|off|Off|OFF)$"),
|
||||
"yYnNtTfFoO");
|
||||
addImplicitResolver("tag:yaml.org,2002:float",
|
||||
regex(r"^(?:[-+]?([0-9][0-9_]*)\\.[0-9_]*" ~
|
||||
"(?:[eE][-+][0-9]+)?|[-+]?(?:[0-9][0-9_]" ~
|
||||
"*)?\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?" ~
|
||||
"[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]" ~
|
||||
"*|[-+]?\\.(?:inf|Inf|INF)|\\." ~
|
||||
"(?:nan|NaN|NAN))$"),
|
||||
"-+0123456789.");
|
||||
addImplicitResolver("tag:yaml.org,2002:int",
|
||||
regex(r"^(?:[-+]?0b[0-1_]+" ~
|
||||
"|[-+]?0[0-7_]+" ~
|
||||
"|[-+]?(?:0|[1-9][0-9_]*)" ~
|
||||
"|[-+]?0x[0-9a-fA-F_]+" ~
|
||||
"|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$"),
|
||||
"-+0123456789");
|
||||
addImplicitResolver("tag:yaml.org,2002:merge", regex(r"^<<$"), "<");
|
||||
addImplicitResolver("tag:yaml.org,2002:null",
|
||||
regex(r"^$|^(?:~|null|Null|NULL)$"), "~nN\0");
|
||||
addImplicitResolver("tag:yaml.org,2002:timestamp",
|
||||
regex(r"^[0-9][0-9][0-9][0-9]-[0-9][0-9]-" ~
|
||||
"[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9]" ~
|
||||
"[0-9]?-[0-9][0-9]?[Tt]|[ \t]+[0-9]" ~
|
||||
"[0-9]?:[0-9][0-9]:[0-9][0-9]" ~
|
||||
"(?:\\.[0-9]*)?(?:[ \t]*Z|[-+][0-9]" ~
|
||||
"[0-9]?(?::[0-9][0-9])?)?$"),
|
||||
"0123456789");
|
||||
addImplicitResolver("tag:yaml.org,2002:value", regex(r"^=$"), "=");
|
||||
|
||||
|
||||
//The following resolver is only for documentation purposes. It cannot work
|
||||
//because plain scalars cannot start with '!', '&', or '*'.
|
||||
addImplicitResolver("tag:yaml.org,2002:yaml", regex(r"^(?:!|&|\*)$"), "!&*");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -935,7 +935,6 @@ void testConstructor(string dataFilename, string codeDummy) @safe
|
|||
new Exception("Unimplemented constructor test: " ~ base));
|
||||
|
||||
auto loader = Loader.fromFile(dataFilename);
|
||||
loader.resolver = new Resolver;
|
||||
|
||||
Node[] exp = expected[base];
|
||||
|
||||
|
|
|
@ -90,7 +90,6 @@ void testEmitterOnData(string dataFilename, string canonicalFilename) @safe
|
|||
|
||||
auto loader2 = Loader.fromString(emitStream.data);
|
||||
loader2.name = "TEST";
|
||||
loader2.resolver = new Resolver;
|
||||
auto newEvents = loader2.parse();
|
||||
assert(compareEvents(events, newEvents));
|
||||
}
|
||||
|
@ -118,7 +117,6 @@ void testEmitterOnCanonical(string canonicalFilename) @safe
|
|||
}
|
||||
auto loader2 = Loader.fromString(emitStream.data);
|
||||
loader2.name = "TEST";
|
||||
loader2.resolver = new Resolver;
|
||||
auto newEvents = loader2.parse();
|
||||
assert(compareEvents(events, newEvents));
|
||||
}
|
||||
|
@ -175,7 +173,6 @@ void testEmitterStyles(string dataFilename, string canonicalFilename) @safe
|
|||
}
|
||||
auto loader2 = Loader.fromString(emitStream.data);
|
||||
loader2.name = "TEST";
|
||||
loader2.resolver = new Resolver;
|
||||
auto newEvents = loader2.parse();
|
||||
assert(compareEvents(events, newEvents));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue