Added support for null tag structs (used in parsing), using
the Tag struct throughout the code. Event struct size decreased to 48 bytes.
This commit is contained in:
parent
dde7d2f64f
commit
2c230751d2
|
@ -17,10 +17,10 @@ import std.typecons;
|
||||||
|
|
||||||
import dyaml.constructor;
|
import dyaml.constructor;
|
||||||
import dyaml.event;
|
import dyaml.event;
|
||||||
|
import dyaml.exception;
|
||||||
import dyaml.node;
|
import dyaml.node;
|
||||||
import dyaml.parser;
|
import dyaml.parser;
|
||||||
import dyaml.resolver;
|
import dyaml.resolver;
|
||||||
import dyaml.exception;
|
|
||||||
|
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
@ -291,7 +291,7 @@ final class Composer
|
||||||
Node composeMappingNode()
|
Node composeMappingNode()
|
||||||
{
|
{
|
||||||
Event startEvent = parser_.getEvent();
|
Event startEvent = parser_.getEvent();
|
||||||
string tag = resolver_.resolve(NodeID.Mapping, startEvent.tag, null,
|
const tag = resolver_.resolve(NodeID.Mapping, startEvent.tag, null,
|
||||||
startEvent.implicit);
|
startEvent.implicit);
|
||||||
|
|
||||||
Node.Pair[] children;
|
Node.Pair[] children;
|
||||||
|
|
|
@ -67,11 +67,11 @@ final class Constructor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
///Constructor functions from scalars.
|
///Constructor functions from scalars.
|
||||||
Node.Value delegate(Mark, Mark, string) [string] fromScalar_;
|
Node.Value delegate(Mark, Mark, string) [Tag] fromScalar_;
|
||||||
///Constructor functions from sequences.
|
///Constructor functions from sequences.
|
||||||
Node.Value delegate(Mark, Mark, Node[]) [string] fromSequence_;
|
Node.Value delegate(Mark, Mark, Node[]) [Tag] fromSequence_;
|
||||||
///Constructor functions from mappings.
|
///Constructor functions from mappings.
|
||||||
Node.Value delegate (Mark, Mark, Node.Pair[])[string] fromMapping_;
|
Node.Value delegate (Mark, Mark, Node.Pair[])[Tag] fromMapping_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -144,24 +144,26 @@ final class Constructor
|
||||||
deleg = (Mark s, Mark e, U p){return Node.userValue(ctor(s,e,p));};
|
deleg = (Mark s, Mark e, U p){return Node.userValue(ctor(s,e,p));};
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((tag in fromScalar_) is null &&
|
const Tag t = Tag(tag);
|
||||||
(tag in fromSequence_) is null &&
|
|
||||||
(tag in fromMapping_) is null,
|
assert((t in fromScalar_) is null &&
|
||||||
|
(t in fromSequence_) is null &&
|
||||||
|
(t in fromMapping_) is null,
|
||||||
"Constructor function for tag " ~ tag ~ " is already "
|
"Constructor function for tag " ~ tag ~ " is already "
|
||||||
"specified. Can't specify another one.");
|
"specified. Can't specify another one.");
|
||||||
|
|
||||||
|
|
||||||
static if(is(U == string))
|
static if(is(U == string))
|
||||||
{
|
{
|
||||||
fromScalar_[tag] = deleg;
|
fromScalar_[t] = deleg;
|
||||||
}
|
}
|
||||||
else static if(is(U == Node[]))
|
else static if(is(U == Node[]))
|
||||||
{
|
{
|
||||||
fromSequence_[tag] = deleg;
|
fromSequence_[t] = deleg;
|
||||||
}
|
}
|
||||||
else static if(is(U == Node.Pair[]))
|
else static if(is(U == Node.Pair[]))
|
||||||
{
|
{
|
||||||
fromMapping_[tag] = deleg;
|
fromMapping_[t] = deleg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,16 +173,17 @@ final class Constructor
|
||||||
*
|
*
|
||||||
* Params: start = Start position of the node.
|
* Params: start = Start position of the node.
|
||||||
* end = End position of the node.
|
* end = End position of the node.
|
||||||
|
* tag = Tag (data type) of the node.
|
||||||
* value = String value of the node.
|
* value = String value of the node.
|
||||||
*
|
*
|
||||||
* Returns: Constructed node.
|
* Returns: Constructed node.
|
||||||
*/
|
*/
|
||||||
Node node(in Mark start, in Mark end, in string tag, string value) const
|
Node node(in Mark start, in Mark end, in Tag tag, string value) const
|
||||||
{
|
{
|
||||||
enforce((tag in fromScalar_) !is null,
|
enforce((tag in fromScalar_) !is null,
|
||||||
new ConstructorException("Could not determine a constructor from "
|
new ConstructorException("Could not determine a constructor from "
|
||||||
"scalar for tag " ~ tag, start, end));
|
"scalar for tag " ~ tag.toString(), start, end));
|
||||||
return Node(fromScalar_[tag](start, end, value), start, Tag(tag));
|
return Node(fromScalar_[tag](start, end, value), start, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -188,16 +191,17 @@ final class Constructor
|
||||||
*
|
*
|
||||||
* Params: start = Start position of the node.
|
* Params: start = Start position of the node.
|
||||||
* end = End position of the node.
|
* end = End position of the node.
|
||||||
|
* tag = Tag (data type) of the node.
|
||||||
* value = Sequence to construct node from.
|
* value = Sequence to construct node from.
|
||||||
*
|
*
|
||||||
* Returns: Constructed node.
|
* Returns: Constructed node.
|
||||||
*/
|
*/
|
||||||
Node node(in Mark start, in Mark end, in string tag, Node[] value) const
|
Node node(in Mark start, in Mark end, in Tag tag, Node[] value) const
|
||||||
{
|
{
|
||||||
enforce((tag in fromSequence_) !is null,
|
enforce((tag in fromSequence_) !is null,
|
||||||
new ConstructorException("Could not determine a constructor from "
|
new ConstructorException("Could not determine a constructor from "
|
||||||
"sequence for tag " ~ tag, start, end));
|
"sequence for tag " ~ tag.toString(), start, end));
|
||||||
return Node(fromSequence_[tag](start, end, value), start, Tag(tag));
|
return Node(fromSequence_[tag](start, end, value), start, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -205,16 +209,17 @@ final class Constructor
|
||||||
*
|
*
|
||||||
* Params: start = Start position of the node.
|
* Params: start = Start position of the node.
|
||||||
* end = End position of the node.
|
* end = End position of the node.
|
||||||
|
* tag = Tag (data type) of the node.
|
||||||
* value = Mapping to construct node from.
|
* value = Mapping to construct node from.
|
||||||
*
|
*
|
||||||
* Returns: Constructed node.
|
* Returns: Constructed node.
|
||||||
*/
|
*/
|
||||||
Node node(in Mark start, in Mark end, in string tag, Node.Pair[] value) const
|
Node node(in Mark start, in Mark end, in Tag tag, Node.Pair[] value) const
|
||||||
{
|
{
|
||||||
enforce((tag in fromMapping_) !is null,
|
enforce((tag in fromMapping_) !is null,
|
||||||
new ConstructorException("Could not determine a constructor from "
|
new ConstructorException("Could not determine a constructor from "
|
||||||
"mapping for tag " ~ tag, start, end));
|
"mapping for tag " ~ tag.toString(), start, end));
|
||||||
return Node(fromMapping_[tag](start, end, value), start, Tag(tag));
|
return Node(fromMapping_[tag](start, end, value), start, tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,10 @@ import std.array;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
|
|
||||||
import dyaml.reader;
|
|
||||||
import dyaml.token;
|
|
||||||
import dyaml.exception;
|
import dyaml.exception;
|
||||||
|
import dyaml.reader;
|
||||||
|
import dyaml.tag;
|
||||||
|
import dyaml.token;
|
||||||
|
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
@ -39,7 +40,7 @@ enum EventID : ubyte
|
||||||
/**
|
/**
|
||||||
* YAML event produced by parser.
|
* YAML event produced by parser.
|
||||||
*
|
*
|
||||||
* 64 bytes on 64-bit.
|
* 48 bytes on 64bit.
|
||||||
*/
|
*/
|
||||||
immutable struct Event
|
immutable struct Event
|
||||||
{
|
{
|
||||||
|
@ -49,10 +50,10 @@ immutable struct Event
|
||||||
Mark endMark;
|
Mark endMark;
|
||||||
///Anchor of the event, if any.
|
///Anchor of the event, if any.
|
||||||
string anchor;
|
string anchor;
|
||||||
///Tag of the event, if any.
|
|
||||||
string tag;
|
|
||||||
///Value of the event, if any.
|
///Value of the event, if any.
|
||||||
string value;
|
string value;
|
||||||
|
///Tag of the event, if any.
|
||||||
|
Tag tag;
|
||||||
///Event type.
|
///Event type.
|
||||||
EventID id;
|
EventID id;
|
||||||
///Style of scalar event, if this is a scalar event.
|
///Style of scalar event, if this is a scalar event.
|
||||||
|
@ -76,7 +77,7 @@ immutable struct Event
|
||||||
*/
|
*/
|
||||||
Event event(EventID id)(in Mark start, in Mark end, in string anchor = null) pure
|
Event event(EventID id)(in Mark start, in Mark end, in string anchor = null) pure
|
||||||
{
|
{
|
||||||
return Event(start, end, anchor, null, null, id);
|
return Event(start, end, anchor, null, Tag(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,11 +90,11 @@ Event event(EventID id)(in Mark start, in Mark end, in string anchor = null) pur
|
||||||
* implicit = Should the tag be implicitly resolved?
|
* implicit = Should the tag be implicitly resolved?
|
||||||
*/
|
*/
|
||||||
Event collectionStartEvent(EventID id)(in Mark start, in Mark end, in string anchor,
|
Event collectionStartEvent(EventID id)(in Mark start, in Mark end, in string anchor,
|
||||||
in string tag, in bool implicit) pure
|
in Tag tag, in bool implicit)
|
||||||
{
|
{
|
||||||
static assert(id == EventID.SequenceStart || id == EventID.SequenceEnd ||
|
static assert(id == EventID.SequenceStart || id == EventID.SequenceEnd ||
|
||||||
id == EventID.MappingStart || id == EventID.MappingEnd);
|
id == EventID.MappingStart || id == EventID.MappingEnd);
|
||||||
return Event(start, end, anchor, tag, null, id, ScalarStyle.Invalid, implicit);
|
return Event(start, end, anchor, null, tag, id, ScalarStyle.Invalid, implicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Aliases for simple events.
|
///Aliases for simple events.
|
||||||
|
@ -117,7 +118,7 @@ alias collectionStartEvent!(EventID.MappingStart) mappingStartEvent;
|
||||||
*/
|
*/
|
||||||
Event documentStartEvent(Mark start, Mark end, bool explicit, string YAMLVersion) pure
|
Event documentStartEvent(Mark start, Mark end, bool explicit, string YAMLVersion) pure
|
||||||
{
|
{
|
||||||
return Event(start, end, null, null, YAMLVersion, EventID.DocumentStart,
|
return Event(start, end, null, YAMLVersion, Tag(), EventID.DocumentStart,
|
||||||
ScalarStyle.Invalid, explicit);
|
ScalarStyle.Invalid, explicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +131,7 @@ Event documentStartEvent(Mark start, Mark end, bool explicit, string YAMLVersion
|
||||||
*/
|
*/
|
||||||
Event documentEndEvent(Mark start, Mark end, bool explicit)
|
Event documentEndEvent(Mark start, Mark end, bool explicit)
|
||||||
{
|
{
|
||||||
return Event(start, end, null, null, null, EventID.DocumentEnd,
|
return Event(start, end, null, null, Tag(), EventID.DocumentEnd,
|
||||||
ScalarStyle.Invalid, explicit);
|
ScalarStyle.Invalid, explicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,9 +146,9 @@ Event documentEndEvent(Mark start, Mark end, bool explicit)
|
||||||
* value = String value of the scalar.
|
* value = String value of the scalar.
|
||||||
* style = Scalar style.
|
* style = Scalar style.
|
||||||
*/
|
*/
|
||||||
Event scalarEvent(in Mark start, in Mark end, in string anchor, in string tag,
|
Event scalarEvent(in Mark start, in Mark end, in string anchor, in Tag tag,
|
||||||
in bool implicit, in string value,
|
in bool implicit, in string value,
|
||||||
in ScalarStyle style = ScalarStyle.Invalid) pure
|
in ScalarStyle style = ScalarStyle.Invalid)
|
||||||
{
|
{
|
||||||
return Event(start, end, anchor, tag, value, EventID.Scalar, style, implicit);
|
return Event(start, end, anchor, value, tag, EventID.Scalar, style, implicit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,10 @@ import std.conv;
|
||||||
import std.exception;
|
import std.exception;
|
||||||
|
|
||||||
import dyaml.event;
|
import dyaml.event;
|
||||||
|
import dyaml.exception;
|
||||||
import dyaml.scanner;
|
import dyaml.scanner;
|
||||||
import dyaml.token;
|
import dyaml.token;
|
||||||
import dyaml.exception;
|
import dyaml.tag;
|
||||||
|
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
@ -447,7 +448,7 @@ final class Parser
|
||||||
{
|
{
|
||||||
state_ = &parseIndentlessSequenceEntry;
|
state_ = &parseIndentlessSequenceEntry;
|
||||||
return sequenceStartEvent(startMark, scanner_.peekToken().endMark,
|
return sequenceStartEvent(startMark, scanner_.peekToken().endMark,
|
||||||
anchor, tag, implicit);
|
anchor, Tag(tag), implicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scanner_.checkToken(TokenID.Scalar))
|
if(scanner_.checkToken(TokenID.Scalar))
|
||||||
|
@ -458,7 +459,7 @@ final class Parser
|
||||||
//is never used after that - so we don't use it.
|
//is never used after that - so we don't use it.
|
||||||
implicit = (token.style == ScalarStyle.Plain && tag is null) || tag == "!";
|
implicit = (token.style == ScalarStyle.Plain && tag is null) || tag == "!";
|
||||||
state_ = popState();
|
state_ = popState();
|
||||||
return scalarEvent(startMark, token.endMark, anchor, tag,
|
return scalarEvent(startMark, token.endMark, anchor, Tag(tag),
|
||||||
implicit, token.value, token.style);
|
implicit, token.value, token.style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,28 +467,28 @@ final class Parser
|
||||||
{
|
{
|
||||||
endMark = scanner_.peekToken().endMark;
|
endMark = scanner_.peekToken().endMark;
|
||||||
state_ = &parseFlowSequenceEntry!true;
|
state_ = &parseFlowSequenceEntry!true;
|
||||||
return sequenceStartEvent(startMark, endMark, anchor, tag, implicit);
|
return sequenceStartEvent(startMark, endMark, anchor, Tag(tag), implicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scanner_.checkToken(TokenID.FlowMappingStart))
|
if(scanner_.checkToken(TokenID.FlowMappingStart))
|
||||||
{
|
{
|
||||||
endMark = scanner_.peekToken().endMark;
|
endMark = scanner_.peekToken().endMark;
|
||||||
state_ = &parseFlowMappingKey!true;
|
state_ = &parseFlowMappingKey!true;
|
||||||
return mappingStartEvent(startMark, endMark, anchor, tag, implicit);
|
return mappingStartEvent(startMark, endMark, anchor, Tag(tag), implicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(block && scanner_.checkToken(TokenID.BlockSequenceStart))
|
if(block && scanner_.checkToken(TokenID.BlockSequenceStart))
|
||||||
{
|
{
|
||||||
endMark = scanner_.peekToken().endMark;
|
endMark = scanner_.peekToken().endMark;
|
||||||
state_ = &parseBlockSequenceEntry!true;
|
state_ = &parseBlockSequenceEntry!true;
|
||||||
return sequenceStartEvent(startMark, endMark, anchor, tag, implicit);
|
return sequenceStartEvent(startMark, endMark, anchor, Tag(tag), implicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(block && scanner_.checkToken(TokenID.BlockMappingStart))
|
if(block && scanner_.checkToken(TokenID.BlockMappingStart))
|
||||||
{
|
{
|
||||||
endMark = scanner_.peekToken().endMark;
|
endMark = scanner_.peekToken().endMark;
|
||||||
state_ = &parseBlockMappingKey!true;
|
state_ = &parseBlockMappingKey!true;
|
||||||
return mappingStartEvent(startMark, endMark, anchor, tag, implicit);
|
return mappingStartEvent(startMark, endMark, anchor, Tag(tag), implicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(anchor != null || tag !is null)
|
if(anchor != null || tag !is null)
|
||||||
|
@ -498,7 +499,7 @@ final class Parser
|
||||||
//but the second bool is never used after that - so we don't use it.
|
//but the second bool is never used after that - so we don't use it.
|
||||||
|
|
||||||
//Empty scalars are allowed even if a tag or an anchor is specified.
|
//Empty scalars are allowed even if a tag or an anchor is specified.
|
||||||
return scalarEvent(startMark, endMark, anchor, tag, implicit , "");
|
return scalarEvent(startMark, endMark, anchor, Tag(tag), implicit , "");
|
||||||
}
|
}
|
||||||
|
|
||||||
Token token = scanner_.peekToken();
|
Token token = scanner_.peekToken();
|
||||||
|
@ -698,7 +699,7 @@ final class Parser
|
||||||
{
|
{
|
||||||
Token token = scanner_.peekToken();
|
Token token = scanner_.peekToken();
|
||||||
state_ = &parseFlowSequenceEntryMappingKey;
|
state_ = &parseFlowSequenceEntryMappingKey;
|
||||||
return mappingStartEvent(token.startMark, token.endMark, null, null, true);
|
return mappingStartEvent(token.startMark, token.endMark, null, Tag(), true);
|
||||||
}
|
}
|
||||||
else if(!scanner_.checkToken(TokenID.FlowSequenceEnd))
|
else if(!scanner_.checkToken(TokenID.FlowSequenceEnd))
|
||||||
{
|
{
|
||||||
|
@ -837,6 +838,6 @@ final class Parser
|
||||||
{
|
{
|
||||||
//PyYAML uses a Tuple!(true, false) for the second last arg here,
|
//PyYAML uses a Tuple!(true, false) for the second last arg here,
|
||||||
//but the second bool is never used after that - so we don't use it.
|
//but the second bool is never used after that - so we don't use it.
|
||||||
return scalarEvent(mark, mark, null, null, true, "");
|
return scalarEvent(mark, mark, null, Tag(), true, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import std.utf;
|
||||||
|
|
||||||
import dyaml.node;
|
import dyaml.node;
|
||||||
import dyaml.exception;
|
import dyaml.exception;
|
||||||
|
import dyaml.tag;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,18 +35,19 @@ final class Resolver
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
///Default tag to use for scalars.
|
///Default tag to use for scalars.
|
||||||
static string defaultScalarTag_ = "tag:yaml.org,2002:str";
|
Tag defaultScalarTag_;
|
||||||
///Default tag to use for sequences.
|
///Default tag to use for sequences.
|
||||||
static string defaultSequenceTag_ = "tag:yaml.org,2002:seq";
|
Tag defaultSequenceTag_;
|
||||||
///Default tag to use for mappings.
|
///Default tag to use for mappings.
|
||||||
static string defaultMappingTag_ = "tag:yaml.org,2002:map";
|
Tag defaultMappingTag_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arrays of scalar resolver tuples indexed by starting character of a scalar.
|
* Arrays of scalar resolver tuples indexed by starting character of a scalar.
|
||||||
*
|
*
|
||||||
* Each tuple stores regular expression the scalar must match,
|
* Each tuple stores regular expression the scalar must match,
|
||||||
* and tag to assign to it if it matches.
|
* and tag to assign to it if it matches.
|
||||||
*/
|
*/
|
||||||
Tuple!(string, Regex!char)[][dchar] yamlImplicitResolvers_;
|
Tuple!(Tag, Regex!char)[][dchar] yamlImplicitResolvers_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -58,6 +60,9 @@ final class Resolver
|
||||||
*/
|
*/
|
||||||
this(in bool defaultImplicitResolvers = true)
|
this(in bool defaultImplicitResolvers = true)
|
||||||
{
|
{
|
||||||
|
defaultScalarTag_ = Tag("tag:yaml.org,2002:str");
|
||||||
|
defaultSequenceTag_ = Tag("tag:yaml.org,2002:seq");
|
||||||
|
defaultMappingTag_ = Tag("tag:yaml.org,2002:map");
|
||||||
if(defaultImplicitResolvers){addImplicitResolvers();}
|
if(defaultImplicitResolvers){addImplicitResolvers();}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +96,7 @@ final class Resolver
|
||||||
{
|
{
|
||||||
yamlImplicitResolvers_[c] = [];
|
yamlImplicitResolvers_[c] = [];
|
||||||
}
|
}
|
||||||
yamlImplicitResolvers_[c] ~= tuple(tag, regexp);
|
yamlImplicitResolvers_[c] ~= tuple(Tag(tag), regexp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,9 +114,9 @@ final class Resolver
|
||||||
*
|
*
|
||||||
* Returns: Resolved tag.
|
* Returns: Resolved tag.
|
||||||
*/
|
*/
|
||||||
string resolve(NodeID kind, string tag, string value, in bool implicit)
|
Tag resolve(NodeID kind, Tag tag, string value, in bool implicit)
|
||||||
{
|
{
|
||||||
if(tag !is null && tag != "!"){return tag;}
|
if(!tag.isNull() && tag.toString() != "!"){return tag;}
|
||||||
|
|
||||||
if(kind == NodeID.Scalar)
|
if(kind == NodeID.Scalar)
|
||||||
{
|
{
|
||||||
|
@ -126,9 +131,11 @@ final class Resolver
|
||||||
|
|
||||||
foreach(resolver; resolvers)
|
foreach(resolver; resolvers)
|
||||||
{
|
{
|
||||||
tag = resolver[0];
|
//If regexp matches, return tag.
|
||||||
auto regexp = resolver[1];
|
if(!(match(value, resolver[1]).empty))
|
||||||
if(!(match(value, regexp).empty)){return tag;}
|
{
|
||||||
|
return resolver[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return defaultScalarTag_;
|
return defaultScalarTag_;
|
||||||
|
@ -145,9 +152,11 @@ final class Resolver
|
||||||
|
|
||||||
bool tagMatch(string tag, string[] values)
|
bool tagMatch(string tag, string[] values)
|
||||||
{
|
{
|
||||||
|
Tag expected = Tag(tag);
|
||||||
foreach(value; values)
|
foreach(value; values)
|
||||||
{
|
{
|
||||||
if(tag != resolver.resolve(NodeID.Scalar, null, value, true))
|
Tag resolved = resolver.resolve(NodeID.Scalar, Tag(), value, true);
|
||||||
|
if(expected != resolved)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
13
dyaml/tag.d
13
dyaml/tag.d
|
@ -15,7 +15,7 @@ struct Tag
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
///Index of the tag in tags_.
|
///Index of the tag in tags_.
|
||||||
uint index_;
|
uint index_ = uint.max;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All known tags are in this array.
|
* All known tags are in this array.
|
||||||
|
@ -29,6 +29,12 @@ struct Tag
|
||||||
///Construct a tag from a string representation.
|
///Construct a tag from a string representation.
|
||||||
this(string tag)
|
this(string tag)
|
||||||
{
|
{
|
||||||
|
if(tag is null || tag == "")
|
||||||
|
{
|
||||||
|
index_ = uint.max;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach(uint index, knownTag; tags_)
|
foreach(uint index, knownTag; tags_)
|
||||||
{
|
{
|
||||||
if(tag == knownTag)
|
if(tag == knownTag)
|
||||||
|
@ -43,6 +49,8 @@ struct Tag
|
||||||
|
|
||||||
///Get string representation of the tag.
|
///Get string representation of the tag.
|
||||||
string toString() const
|
string toString() const
|
||||||
|
in{assert(!isNull());}
|
||||||
|
body
|
||||||
{
|
{
|
||||||
return tags_[index_];
|
return tags_[index_];
|
||||||
}
|
}
|
||||||
|
@ -52,4 +60,7 @@ struct Tag
|
||||||
{
|
{
|
||||||
return tag.index_ == index_;
|
return tag.index_ == index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Is this tag null (invalid)?
|
||||||
|
bool isNull() const {return index_ == uint.max;}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue