Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

convert Resolver to struct #229

Merged
merged 1 commit into from
Feb 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions examples/resolver/main.d
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
4 changes: 2 additions & 2 deletions examples/yaml_bench/yaml_bench.d
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,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();

Expand All @@ -111,7 +111,7 @@ void main(string[] args) //@safe
return;
}

loader.resolver = resolver;
loader.resolver = resolver;
nodes = loader.array;
}
void runDumpBenchmark() @safe
Expand Down
1 change: 0 additions & 1 deletion source/dyaml/composer.d
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ struct Composer
pure @safe nothrow ~this()
{
parser_ = null;
resolver_ = null;
anchors_.destroy();
anchors_ = null;
}
Expand Down
10 changes: 5 additions & 5 deletions source/dyaml/dumper.d
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct Dumper(Range)
*/
this(Range stream) @safe
{
resolver_ = new Resolver();
resolver_ = Resolver.withDefaultResolvers;
stream_ = stream;
}

Expand All @@ -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?
Expand Down Expand Up @@ -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
Expand Down
23 changes: 8 additions & 15 deletions source/dyaml/loader.d
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ struct Loader
/// Ditto
private this(ubyte[] yamlData) @safe
{
resolver_ = Resolver.withDefaultResolvers;
try
{
reader_ = new Reader(yamlData);
Expand All @@ -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.
Expand Down Expand Up @@ -221,7 +222,6 @@ struct Loader
static Composer composer;
if (!rangeInitialized)
{
lazyInitConstructorResolver();
composer = Composer(parser_, resolver_);
rangeInitialized = true;
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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();
}
116 changes: 55 additions & 61 deletions source/dyaml/resolver.d
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
*
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -156,7 +192,7 @@ final class Resolver
}
@safe unittest
{
auto resolver = new Resolver();
auto resolver = Resolver.withDefaultResolvers;

bool tagMatch(string tag, string[] values) @safe
{
Expand Down Expand Up @@ -202,46 +238,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"^(?:!|&|\*)$"), "!&*");
}
}
1 change: 0 additions & 1 deletion source/dyaml/test/constructor.d
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
3 changes: 0 additions & 3 deletions source/dyaml/test/emitter.d
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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));
}
Expand Down