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:
Cameron Ross 2019-02-05 05:30:48 -03:30 committed by The Dlang Bot
parent fff8cead76
commit 8de1a45922
8 changed files with 72 additions and 92 deletions

View file

@ -12,12 +12,10 @@ int main(string[] args)
try try
{ {
auto resolver = new Resolver;
resolver.addImplicitResolver("!color", regex("[0-9a-fA-F]{6}"),
"0123456789abcdefABCDEF");
auto loader = Loader.fromFile("input.yaml"); auto loader = Loader.fromFile("input.yaml");
loader.resolver = resolver; loader.resolver.addImplicitResolver("!color", regex("[0-9a-fA-F]{6}"),
"0123456789abcdefABCDEF");
auto root = loader.load(); auto root = loader.load();

View file

@ -101,7 +101,7 @@ void main(string[] args) //@safe
{ {
// Instead of constructing a resolver/constructor with each Loader, // Instead of constructing a resolver/constructor with each Loader,
// construct them once to remove noise when profiling. // construct them once to remove noise when profiling.
auto resolver = new Resolver(); auto resolver = Resolver.withDefaultResolvers;
auto constructTime = stopWatch.peek(); auto constructTime = stopWatch.peek();

View file

@ -79,7 +79,6 @@ struct Composer
pure @safe nothrow ~this() pure @safe nothrow ~this()
{ {
parser_ = null; parser_ = null;
resolver_ = null;
anchors_.destroy(); anchors_.destroy();
anchors_ = null; anchors_ = null;
} }

View file

@ -99,7 +99,7 @@ struct Dumper(Range)
*/ */
this(Range stream) @safe this(Range stream) @safe
{ {
resolver_ = new Resolver(); resolver_ = Resolver.withDefaultResolvers;
stream_ = stream; stream_ = stream;
} }
@ -110,9 +110,9 @@ struct Dumper(Range)
} }
///Specify custom Resolver to use. ///Specify custom Resolver to use.
@property void resolver(Resolver resolver) @safe auto ref resolver() @safe
{ {
resolver_ = resolver; return resolver_;
} }
///Write scalars in _canonical form? ///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 ///Use a custom resolver to support custom data types and/or implicit tags
@safe unittest @safe unittest
{ {
import std.regex : regex;
auto node = Node([1, 2, 3, 4, 5]); auto node = Node([1, 2, 3, 4, 5]);
auto resolver = new Resolver();
auto dumper = dumper(new Appender!string()); auto dumper = dumper(new Appender!string());
dumper.resolver = resolver; dumper.resolver.addImplicitResolver("!tag", regex("A.*"), "A");
dumper.dump(node); dumper.dump(node);
} }
/// Set default scalar style /// Set default scalar style

View file

@ -149,6 +149,7 @@ struct Loader
/// Ditto /// Ditto
private this(ubyte[] yamlData) @safe private this(ubyte[] yamlData) @safe
{ {
resolver_ = Resolver.withDefaultResolvers;
try try
{ {
reader_ = new Reader(yamlData); reader_ = new Reader(yamlData);
@ -170,9 +171,9 @@ struct Loader
} }
/// Specify custom Resolver to use. /// 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. /** Load single YAML document.
@ -221,7 +222,6 @@ struct Loader
static Composer composer; static Composer composer;
if (!rangeInitialized) if (!rangeInitialized)
{ {
lazyInitConstructorResolver();
composer = Composer(parser_, resolver_); composer = Composer(parser_, resolver_);
rangeInitialized = true; rangeInitialized = true;
} }
@ -290,13 +290,6 @@ struct Loader
{ {
return parser_; 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: /// Load single YAML document from a file:
@safe unittest @safe unittest
@ -394,7 +387,7 @@ struct Loader
writeln("Failed to read file 'example.yaml'"); 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 @safe unittest
{ {
import std.file : write; import std.file : write;
@ -404,11 +397,11 @@ struct Loader
"Hello world!\n"~ "Hello world!\n"~
"...\n" "...\n"
); );
auto resolver = new Resolver();
// Add constructor functions / resolver expressions here...
auto loader = Loader.fromFile("example.yaml"); auto loader = Loader.fromFile("example.yaml");
loader.resolver = resolver;
// Add resolver expressions here...
// loader.resolver.addImplicitResolver(...);
auto rootNode = loader.load(); auto rootNode = loader.load();
} }

View file

@ -24,12 +24,53 @@ import dyaml.node;
import dyaml.exception; 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). * Resolves YAML tags (data types).
* *
* Can be used to implicitly resolve custom data types of scalar values. * Can be used to implicitly resolve custom data types of scalar values.
*/ */
final class Resolver struct Resolver
{ {
private: private:
// Default tag to use for scalars. // Default tag to use for scalars.
@ -47,24 +88,21 @@ final class Resolver
*/ */
Tuple!(string, Regex!char)[][dchar] yamlImplicitResolvers_; 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: public:
@disable bool opEquals(ref Resolver); @disable bool opEquals(ref Resolver);
@disable int opCmp(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. * Add an implicit scalar resolver.
* *
@ -105,9 +143,7 @@ final class Resolver
write("example.yaml", "A"); write("example.yaml", "A");
auto loader = Loader.fromFile("example.yaml"); auto loader = Loader.fromFile("example.yaml");
auto resolver = new Resolver(); loader.resolver.addImplicitResolver("!tag", regex("A.*"), "A");
resolver.addImplicitResolver("!tag", regex("A.*"), "A");
loader.resolver = resolver;
auto node = loader.load(); auto node = loader.load();
assert(node.tag == "!tag"); assert(node.tag == "!tag");
@ -169,7 +205,7 @@ final class Resolver
} }
@safe unittest @safe unittest
{ {
auto resolver = new Resolver(); auto resolver = Resolver.withDefaultResolvers;
bool tagMatch(string tag, string[] values) @safe bool tagMatch(string tag, string[] values) @safe
{ {
@ -215,46 +251,4 @@ final class Resolver
///Returns: Default mapping tag. ///Returns: Default mapping tag.
@property string defaultMappingTag() const pure @safe nothrow {return defaultMappingTag_;} @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"^(?:!|&|\*)$"), "!&*");
}
} }

View file

@ -935,7 +935,6 @@ void testConstructor(string dataFilename, string codeDummy) @safe
new Exception("Unimplemented constructor test: " ~ base)); new Exception("Unimplemented constructor test: " ~ base));
auto loader = Loader.fromFile(dataFilename); auto loader = Loader.fromFile(dataFilename);
loader.resolver = new Resolver;
Node[] exp = expected[base]; Node[] exp = expected[base];

View file

@ -90,7 +90,6 @@ void testEmitterOnData(string dataFilename, string canonicalFilename) @safe
auto loader2 = Loader.fromString(emitStream.data); auto loader2 = Loader.fromString(emitStream.data);
loader2.name = "TEST"; loader2.name = "TEST";
loader2.resolver = new Resolver;
auto newEvents = loader2.parse(); auto newEvents = loader2.parse();
assert(compareEvents(events, newEvents)); assert(compareEvents(events, newEvents));
} }
@ -118,7 +117,6 @@ void testEmitterOnCanonical(string canonicalFilename) @safe
} }
auto loader2 = Loader.fromString(emitStream.data); auto loader2 = Loader.fromString(emitStream.data);
loader2.name = "TEST"; loader2.name = "TEST";
loader2.resolver = new Resolver;
auto newEvents = loader2.parse(); auto newEvents = loader2.parse();
assert(compareEvents(events, newEvents)); assert(compareEvents(events, newEvents));
} }
@ -175,7 +173,6 @@ void testEmitterStyles(string dataFilename, string canonicalFilename) @safe
} }
auto loader2 = Loader.fromString(emitStream.data); auto loader2 = Loader.fromString(emitStream.data);
loader2.name = "TEST"; loader2.name = "TEST";
loader2.resolver = new Resolver;
auto newEvents = loader2.parse(); auto newEvents = loader2.parse();
assert(compareEvents(events, newEvents)); assert(compareEvents(events, newEvents));
} }