Doc style change in node.d
This commit is contained in:
parent
7ae4de4776
commit
28979baa6c
|
@ -4,10 +4,8 @@
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
/**
|
/// Node of a YAML document. Used to read YAML data once it's loaded,
|
||||||
* Node of a YAML document. Used to read YAML data once it's loaded,
|
/// and to prepare data to emit.
|
||||||
* and to prepare data to emit.
|
|
||||||
*/
|
|
||||||
module dyaml.node;
|
module dyaml.node;
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,12 +32,10 @@ import dyaml.tag;
|
||||||
class NodeException : YAMLException
|
class NodeException : YAMLException
|
||||||
{
|
{
|
||||||
package:
|
package:
|
||||||
/*
|
// Construct a NodeException.
|
||||||
* Construct a NodeException.
|
//
|
||||||
*
|
// Params: msg = Error message.
|
||||||
* Params: msg = Error message.
|
// start = Start position of the node.
|
||||||
* start = Start position of the node.
|
|
||||||
*/
|
|
||||||
this(string msg, Mark start, string file = __FILE__, int line = __LINE__)
|
this(string msg, Mark start, string file = __FILE__, int line = __LINE__)
|
||||||
@safe
|
@safe
|
||||||
{
|
{
|
||||||
|
@ -121,13 +117,11 @@ package class YAMLContainer(T) if (!Node.allowed!T): YAMLObject
|
||||||
this(T value) @trusted {value_ = value;}
|
this(T value) @trusted {value_ = value;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// YAML node.
|
||||||
* YAML node.
|
///
|
||||||
*
|
/// This is a pseudo-dynamic type that can store any YAML value, including a
|
||||||
* This is a pseudo-dynamic type that can store any YAML value, including a
|
/// sequence or mapping of nodes. You can get data from a Node directly or
|
||||||
* sequence or mapping of nodes. You can get data from a Node directly or
|
/// iterate over it if it's a collection.
|
||||||
* iterate over it if it's a collection.
|
|
||||||
*/
|
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -170,12 +164,10 @@ struct Node
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
// Comparison with another Pair.
|
||||||
* Comparison with another Pair.
|
//
|
||||||
*
|
// useTag determines whether or not we consider node tags
|
||||||
* useTag determines whether or not we consider node tags
|
// in the comparison.
|
||||||
* in the comparison.
|
|
||||||
*/
|
|
||||||
int cmp(Flag!"useTag" useTag)(ref const(Pair) rhs) const @safe
|
int cmp(Flag!"useTag" useTag)(ref const(Pair) rhs) const @safe
|
||||||
{
|
{
|
||||||
const keyCmp = key.cmp!useTag(rhs.key);
|
const keyCmp = key.cmp!useTag(rhs.key);
|
||||||
|
@ -226,27 +218,25 @@ struct Node
|
||||||
static assert(Node.sizeof <= 48, "Unexpected YAML node size");
|
static assert(Node.sizeof <= 48, "Unexpected YAML node size");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/// Construct a Node from a value.
|
||||||
* Construct a Node from a value.
|
///
|
||||||
*
|
/// Any type except for Node can be stored in a Node, but default YAML
|
||||||
* Any type except for Node can be stored in a Node, but default YAML
|
/// types (integers, floats, strings, timestamps, etc.) will be stored
|
||||||
* types (integers, floats, strings, timestamps, etc.) will be stored
|
/// more efficiently. To create a node representing a null value,
|
||||||
* more efficiently. To create a node representing a null value,
|
/// construct it from YAMLNull.
|
||||||
* construct it from YAMLNull.
|
///
|
||||||
*
|
///
|
||||||
*
|
/// Note that to emit any non-default types you store
|
||||||
* Note that to emit any non-default types you store
|
/// in a node, you need a Representer to represent them in YAML -
|
||||||
* in a node, you need a Representer to represent them in YAML -
|
/// otherwise emitting will fail.
|
||||||
* otherwise emitting will fail.
|
///
|
||||||
*
|
/// Params: value = Value to store in the node.
|
||||||
* Params: value = Value to store in the node.
|
/// tag = Overrides tag of the node when emitted, regardless
|
||||||
* tag = Overrides tag of the node when emitted, regardless
|
/// of tag determined by Representer. Representer uses
|
||||||
* of tag determined by Representer. Representer uses
|
/// this to determine YAML data type when a D data type
|
||||||
* this to determine YAML data type when a D data type
|
/// maps to multiple different YAML data types. Tag must
|
||||||
* maps to multiple different YAML data types. Tag must
|
/// be in full form, e.g. "tag:yaml.org,2002:int", not
|
||||||
* be in full form, e.g. "tag:yaml.org,2002:int", not
|
/// a shortcut, like "!!int".
|
||||||
* a shortcut, like "!!int".
|
|
||||||
*/
|
|
||||||
this(T)(T value, const string tag = null) @trusted
|
this(T)(T value, const string tag = null) @trusted
|
||||||
if (isSomeString!T || (!isArray!T && !isAssociativeArray!T))
|
if (isSomeString!T || (!isArray!T && !isAssociativeArray!T))
|
||||||
{
|
{
|
||||||
|
@ -280,32 +270,30 @@ struct Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Construct a node from an _array.
|
||||||
* Construct a node from an _array.
|
///
|
||||||
*
|
/// If _array is an _array of nodes or pairs, it is stored directly.
|
||||||
* If _array is an _array of nodes or pairs, it is stored directly.
|
/// Otherwise, every value in the array is converted to a node, and
|
||||||
* Otherwise, every value in the array is converted to a node, and
|
/// those nodes are stored.
|
||||||
* those nodes are stored.
|
///
|
||||||
*
|
/// Params: array = Values to store in the node.
|
||||||
* Params: array = Values to store in the node.
|
/// tag = Overrides tag of the node when emitted, regardless
|
||||||
* tag = Overrides tag of the node when emitted, regardless
|
/// of tag determined by Representer. Representer uses
|
||||||
* of tag determined by Representer. Representer uses
|
/// this to determine YAML data type when a D data type
|
||||||
* this to determine YAML data type when a D data type
|
/// maps to multiple different YAML data types.
|
||||||
* maps to multiple different YAML data types.
|
/// This is used to differentiate between YAML sequences
|
||||||
* This is used to differentiate between YAML sequences
|
/// ("!!seq") and sets ("!!set"), which both are
|
||||||
* ("!!seq") and sets ("!!set"), which both are
|
/// internally represented as an array_ of nodes. Tag
|
||||||
* internally represented as an array_ of nodes. Tag
|
/// must be in full form, e.g. "tag:yaml.org,2002:set",
|
||||||
* must be in full form, e.g. "tag:yaml.org,2002:set",
|
/// not a shortcut, like "!!set".
|
||||||
* not a shortcut, like "!!set".
|
///
|
||||||
*
|
/// Examples:
|
||||||
* Examples:
|
/// --------------------
|
||||||
* --------------------
|
/// // Will be emitted as a sequence (default for arrays)
|
||||||
* //Will be emitted as a sequence (default for arrays)
|
/// auto seq = Node([1, 2, 3, 4, 5]);
|
||||||
* auto seq = Node([1, 2, 3, 4, 5]);
|
/// // Will be emitted as a set (overriden tag)
|
||||||
* //Will be emitted as a set (overriden tag)
|
/// auto set = Node([1, 2, 3, 4, 5], "tag:yaml.org,2002:set");
|
||||||
* auto set = Node([1, 2, 3, 4, 5], "tag:yaml.org,2002:set");
|
/// --------------------
|
||||||
* --------------------
|
|
||||||
*/
|
|
||||||
this(T)(T[] array, const string tag = null) @safe
|
this(T)(T[] array, const string tag = null) @safe
|
||||||
if (!isSomeString!(T[]))
|
if (!isSomeString!(T[]))
|
||||||
{
|
{
|
||||||
|
@ -343,34 +331,32 @@ struct Node
|
||||||
auto set = Node([1, 2, 3, 4, 5], "tag:yaml.org,2002:set");
|
auto set = Node([1, 2, 3, 4, 5], "tag:yaml.org,2002:set");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Construct a node from an associative _array.
|
||||||
* Construct a node from an associative _array.
|
///
|
||||||
*
|
/// If keys and/or values of _array are nodes, they stored directly.
|
||||||
* If keys and/or values of _array are nodes, they stored directly.
|
/// Otherwise they are converted to nodes and then stored.
|
||||||
* Otherwise they are converted to nodes and then stored.
|
///
|
||||||
*
|
/// Params: array = Values to store in the node.
|
||||||
* Params: array = Values to store in the node.
|
/// tag = Overrides tag of the node when emitted, regardless
|
||||||
* tag = Overrides tag of the node when emitted, regardless
|
/// of tag determined by Representer. Representer uses
|
||||||
* of tag determined by Representer. Representer uses
|
/// this to determine YAML data type when a D data type
|
||||||
* this to determine YAML data type when a D data type
|
/// maps to multiple different YAML data types.
|
||||||
* maps to multiple different YAML data types.
|
/// This is used to differentiate between YAML unordered
|
||||||
* This is used to differentiate between YAML unordered
|
/// mappings ("!!map"), ordered mappings ("!!omap"), and
|
||||||
* mappings ("!!map"), ordered mappings ("!!omap"), and
|
/// pairs ("!!pairs") which are all internally
|
||||||
* pairs ("!!pairs") which are all internally
|
/// represented as an _array of node pairs. Tag must be
|
||||||
* represented as an _array of node pairs. Tag must be
|
/// in full form, e.g. "tag:yaml.org,2002:omap", not a
|
||||||
* in full form, e.g. "tag:yaml.org,2002:omap", not a
|
/// shortcut, like "!!omap".
|
||||||
* shortcut, like "!!omap".
|
///
|
||||||
*
|
/// Examples:
|
||||||
* Examples:
|
/// --------------------
|
||||||
* --------------------
|
/// // Will be emitted as an unordered mapping (default for mappings)
|
||||||
* //Will be emitted as an unordered mapping (default for mappings)
|
/// auto map = Node([1 : "a", 2 : "b"]);
|
||||||
* auto map = Node([1 : "a", 2 : "b"]);
|
/// // Will be emitted as an ordered map (overriden tag)
|
||||||
* //Will be emitted as an ordered map (overriden tag)
|
/// auto omap = Node([1 : "a", 2 : "b"], "tag:yaml.org,2002:omap");
|
||||||
* auto omap = Node([1 : "a", 2 : "b"], "tag:yaml.org,2002:omap");
|
/// // Will be emitted as pairs (overriden tag)
|
||||||
* //Will be emitted as pairs (overriden tag)
|
/// auto pairs = Node([1 : "a", 2 : "b"], "tag:yaml.org,2002:pairs");
|
||||||
* auto pairs = Node([1 : "a", 2 : "b"], "tag:yaml.org,2002:pairs");
|
/// --------------------
|
||||||
* --------------------
|
|
||||||
*/
|
|
||||||
this(K, V)(V[K] array, const string tag = null) @safe
|
this(K, V)(V[K] array, const string tag = null) @safe
|
||||||
{
|
{
|
||||||
tag_ = Tag(tag);
|
tag_ = Tag(tag);
|
||||||
|
@ -399,43 +385,41 @@ struct Node
|
||||||
auto pairs = Node([1 : "a", 2 : "b"], "tag:yaml.org,2002:pairs");
|
auto pairs = Node([1 : "a", 2 : "b"], "tag:yaml.org,2002:pairs");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Construct a node from arrays of _keys and _values.
|
||||||
* Construct a node from arrays of _keys and _values.
|
///
|
||||||
*
|
/// Constructs a mapping node with key-value pairs from
|
||||||
* Constructs a mapping node with key-value pairs from
|
/// _keys and _values, keeping their order. Useful when order
|
||||||
* _keys and _values, keeping their order. Useful when order
|
/// is important (ordered maps, pairs).
|
||||||
* is important (ordered maps, pairs).
|
///
|
||||||
*
|
///
|
||||||
*
|
/// keys and values must have equal length.
|
||||||
* keys and values must have equal length.
|
///
|
||||||
*
|
///
|
||||||
*
|
/// If _keys and/or _values are nodes, they are stored directly/
|
||||||
* If _keys and/or _values are nodes, they are stored directly/
|
/// Otherwise they are converted to nodes and then stored.
|
||||||
* Otherwise they are converted to nodes and then stored.
|
///
|
||||||
*
|
/// Params: keys = Keys of the mapping, from first to last pair.
|
||||||
* Params: keys = Keys of the mapping, from first to last pair.
|
/// values = Values of the mapping, from first to last pair.
|
||||||
* values = Values of the mapping, from first to last pair.
|
/// tag = Overrides tag of the node when emitted, regardless
|
||||||
* tag = Overrides tag of the node when emitted, regardless
|
/// of tag determined by Representer. Representer uses
|
||||||
* of tag determined by Representer. Representer uses
|
/// this to determine YAML data type when a D data type
|
||||||
* this to determine YAML data type when a D data type
|
/// maps to multiple different YAML data types.
|
||||||
* maps to multiple different YAML data types.
|
/// This is used to differentiate between YAML unordered
|
||||||
* This is used to differentiate between YAML unordered
|
/// mappings ("!!map"), ordered mappings ("!!omap"), and
|
||||||
* mappings ("!!map"), ordered mappings ("!!omap"), and
|
/// pairs ("!!pairs") which are all internally
|
||||||
* pairs ("!!pairs") which are all internally
|
/// represented as an array of node pairs. Tag must be
|
||||||
* represented as an array of node pairs. Tag must be
|
/// in full form, e.g. "tag:yaml.org,2002:omap", not a
|
||||||
* in full form, e.g. "tag:yaml.org,2002:omap", not a
|
/// shortcut, like "!!omap".
|
||||||
* shortcut, like "!!omap".
|
///
|
||||||
*
|
/// Examples:
|
||||||
* Examples:
|
/// --------------------
|
||||||
* --------------------
|
/// // Will be emitted as an unordered mapping (default for mappings)
|
||||||
* //Will be emitted as an unordered mapping (default for mappings)
|
/// auto map = Node([1, 2], ["a", "b"]);
|
||||||
* auto map = Node([1, 2], ["a", "b"]);
|
/// // Will be emitted as an ordered map (overriden tag)
|
||||||
* //Will be emitted as an ordered map (overriden tag)
|
/// auto omap = Node([1, 2], ["a", "b"], "tag:yaml.org,2002:omap");
|
||||||
* auto omap = Node([1, 2], ["a", "b"], "tag:yaml.org,2002:omap");
|
/// // Will be emitted as pairs (overriden tag)
|
||||||
* //Will be emitted as pairs (overriden tag)
|
/// auto pairs = Node([1, 2], ["a", "b"], "tag:yaml.org,2002:pairs");
|
||||||
* auto pairs = Node([1, 2], ["a", "b"], "tag:yaml.org,2002:pairs");
|
/// --------------------
|
||||||
* --------------------
|
|
||||||
*/
|
|
||||||
this(K, V)(K[] keys, V[] values, const string tag = null) @safe
|
this(K, V)(K[] keys, V[] values, const string tag = null) @safe
|
||||||
if(!(isSomeString!(K[]) || isSomeString!(V[])))
|
if(!(isSomeString!(K[]) || isSomeString!(V[])))
|
||||||
in
|
in
|
||||||
|
@ -508,30 +492,28 @@ struct Node
|
||||||
/// Return tag of the node.
|
/// Return tag of the node.
|
||||||
@property string tag() const @safe nothrow {return tag_.get;}
|
@property string tag() const @safe nothrow {return tag_.get;}
|
||||||
|
|
||||||
/**
|
/// Equality test.
|
||||||
* Equality test.
|
///
|
||||||
*
|
/// If T is Node, recursively compare all subnodes.
|
||||||
* If T is Node, recursively compare all subnodes.
|
/// This might be quite expensive if testing entire documents.
|
||||||
* This might be quite expensive if testing entire documents.
|
///
|
||||||
*
|
/// If T is not Node, get a value if type T from the node and test
|
||||||
* If T is not Node, get a value if type T from the node and test
|
/// equality with that.
|
||||||
* equality with that.
|
///
|
||||||
*
|
/// To test equality with a null YAML value, use YAMLNull.
|
||||||
* To test equality with a null YAML value, use YAMLNull.
|
///
|
||||||
*
|
/// Examples:
|
||||||
* Examples:
|
/// --------------------
|
||||||
* --------------------
|
/// auto node = Node(42);
|
||||||
* auto node = Node(42);
|
///
|
||||||
*
|
/// assert(node == 42);
|
||||||
* assert(node == 42);
|
/// assert(node != "42");
|
||||||
* assert(node != "42");
|
/// assert(node != "43");
|
||||||
* assert(node != "43");
|
/// --------------------
|
||||||
* --------------------
|
///
|
||||||
*
|
/// Params: rhs = Variable to test equality with.
|
||||||
* Params: rhs = Variable to test equality with.
|
///
|
||||||
*
|
/// Returns: true if equal, false otherwise.
|
||||||
* Returns: true if equal, false otherwise.
|
|
||||||
*/
|
|
||||||
bool opEquals(T)(const auto ref T rhs) const @safe
|
bool opEquals(T)(const auto ref T rhs) const @safe
|
||||||
{
|
{
|
||||||
return equals!(Yes.useTag)(rhs);
|
return equals!(Yes.useTag)(rhs);
|
||||||
|
@ -551,50 +533,48 @@ struct Node
|
||||||
/// Shortcut for get().
|
/// Shortcut for get().
|
||||||
alias get as;
|
alias get as;
|
||||||
|
|
||||||
/**
|
/// Get the value of the node as specified type.
|
||||||
* Get the value of the node as specified type.
|
///
|
||||||
*
|
/// If the specifed type does not match type in the node,
|
||||||
* If the specifed type does not match type in the node,
|
/// conversion is attempted. The stringConversion template
|
||||||
* conversion is attempted. The stringConversion template
|
/// parameter can be used to disable conversion from non-string
|
||||||
* parameter can be used to disable conversion from non-string
|
/// types to strings.
|
||||||
* types to strings.
|
///
|
||||||
*
|
/// Numeric values are range checked, throwing if out of range of
|
||||||
* Numeric values are range checked, throwing if out of range of
|
/// requested type.
|
||||||
* requested type.
|
///
|
||||||
*
|
/// Timestamps are stored as std.datetime.SysTime.
|
||||||
* Timestamps are stored as std.datetime.SysTime.
|
/// Binary values are decoded and stored as ubyte[].
|
||||||
* Binary values are decoded and stored as ubyte[].
|
///
|
||||||
*
|
/// To get a null value, use get!YAMLNull . This is to
|
||||||
* To get a null value, use get!YAMLNull . This is to
|
/// prevent getting null values for types such as strings or classes.
|
||||||
* prevent getting null values for types such as strings or classes.
|
///
|
||||||
*
|
/// $(BR)$(B Mapping default values:)
|
||||||
* $(BR)$(B Mapping default values:)
|
///
|
||||||
*
|
/// $(PBR
|
||||||
* $(PBR
|
/// The '=' key can be used to denote the default value of a mapping.
|
||||||
* The '=' key can be used to denote the default value of a mapping.
|
/// This can be used when a node is scalar in early versions of a program,
|
||||||
* This can be used when a node is scalar in early versions of a program,
|
/// but is replaced by a mapping later. Even if the node is a mapping, the
|
||||||
* but is replaced by a mapping later. Even if the node is a mapping, the
|
/// get method can be used as if it was a scalar if it has a default value.
|
||||||
* get method can be used as if it was a scalar if it has a default value.
|
/// This way, new YAML files where the node is a mapping can still be read
|
||||||
* This way, new YAML files where the node is a mapping can still be read
|
/// by old versions of the program, which expect the node to be a scalar.
|
||||||
* by old versions of the program, which expect the node to be a scalar.
|
/// )
|
||||||
* )
|
///
|
||||||
*
|
/// Examples:
|
||||||
* Examples:
|
///
|
||||||
*
|
/// Automatic type conversion:
|
||||||
* Automatic type conversion:
|
/// --------------------
|
||||||
* --------------------
|
/// auto node = Node(42);
|
||||||
* auto node = Node(42);
|
///
|
||||||
*
|
/// assert(node.as!int == 42);
|
||||||
* assert(node.as!int == 42);
|
/// assert(node.as!string == "42");
|
||||||
* assert(node.as!string == "42");
|
/// assert(node.as!double == 42.0);
|
||||||
* assert(node.as!double == 42.0);
|
/// --------------------
|
||||||
* --------------------
|
///
|
||||||
*
|
/// Returns: Value of the node as specified type.
|
||||||
* Returns: Value of the node as specified type.
|
///
|
||||||
*
|
/// Throws: NodeException if unable to convert to specified type, or if
|
||||||
* Throws: NodeException if unable to convert to specified type, or if
|
/// the value is out of range of requested type.
|
||||||
* the value is out of range of requested type.
|
|
||||||
*/
|
|
||||||
@property T get(T, Flag!"stringConversion" stringConversion = Yes.stringConversion)()
|
@property T get(T, Flag!"stringConversion" stringConversion = Yes.stringConversion)()
|
||||||
@trusted if(!is(T == const))
|
@trusted if(!is(T == const))
|
||||||
{
|
{
|
||||||
|
@ -729,15 +709,13 @@ struct Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// If this is a collection, return its _length.
|
||||||
* If this is a collection, return its _length.
|
///
|
||||||
*
|
/// Otherwise, throw NodeException.
|
||||||
* Otherwise, throw NodeException.
|
///
|
||||||
*
|
/// Returns: Number of elements in a sequence or key-value pairs in a mapping.
|
||||||
* Returns: Number of elements in a sequence or key-value pairs in a mapping.
|
///
|
||||||
*
|
/// Throws: NodeException if this is not a sequence nor a mapping.
|
||||||
* Throws: NodeException if this is not a sequence nor a mapping.
|
|
||||||
*/
|
|
||||||
@property size_t length() const @safe
|
@property size_t length() const @safe
|
||||||
{
|
{
|
||||||
if(isSequence) {return value_.get!(const Node[]).length;}
|
if(isSequence) {return value_.get!(const Node[]).length;}
|
||||||
|
@ -746,25 +724,24 @@ struct Node
|
||||||
startMark_);
|
startMark_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Get the element at specified index.
|
||||||
* Get the element at specified index.
|
///
|
||||||
*
|
/// If the node is a sequence, index must be integral.
|
||||||
* If the node is a sequence, index must be integral.
|
///
|
||||||
*
|
///
|
||||||
*
|
/// If the node is a mapping, return the value corresponding to the first
|
||||||
* If the node is a mapping, return the value corresponding to the first
|
/// key equal to index. containsKey() can be used to determine if a mapping
|
||||||
* key equal to index.
|
/// has a specific key.
|
||||||
*
|
///
|
||||||
* To get element at a null index, use YAMLNull for index.
|
/// To get element at a null index, use YAMLNull for index.
|
||||||
*
|
///
|
||||||
* Params: index = Index to use.
|
/// Params: index = Index to use.
|
||||||
*
|
///
|
||||||
* Returns: Value corresponding to the index.
|
/// Returns: Value corresponding to the index.
|
||||||
*
|
///
|
||||||
* Throws: NodeException if the index could not be found,
|
/// Throws: NodeException if the index could not be found,
|
||||||
* non-integral index is used with a sequence or the node is
|
/// non-integral index is used with a sequence or the node is
|
||||||
* not a collection.
|
/// not a collection.
|
||||||
*/
|
|
||||||
ref Node opIndex(T)(T index) @trusted
|
ref Node opIndex(T)(T index) @trusted
|
||||||
{
|
{
|
||||||
if(isSequence)
|
if(isSequence)
|
||||||
|
@ -789,10 +766,10 @@ struct Node
|
||||||
}
|
}
|
||||||
throw new Error("Trying to index a " ~ nodeTypeString ~ " node", startMark_);
|
throw new Error("Trying to index a " ~ nodeTypeString ~ " node", startMark_);
|
||||||
}
|
}
|
||||||
|
///
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
writeln("D:YAML Node opIndex unittest");
|
writeln("D:YAML Node opIndex unittest");
|
||||||
|
|
||||||
alias Node.Value Value;
|
alias Node.Value Value;
|
||||||
alias Node.Pair Pair;
|
alias Node.Pair Pair;
|
||||||
Node n1 = Node(cast(long)11);
|
Node n1 = Node(cast(long)11);
|
||||||
|
@ -824,40 +801,36 @@ struct Node
|
||||||
assertThrown!NodeException(nmap[14]);
|
assertThrown!NodeException(nmap[14]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Determine if a collection contains specified value.
|
||||||
* Determine if a collection contains specified value.
|
///
|
||||||
*
|
/// If the node is a sequence, check if it contains the specified value.
|
||||||
* If the node is a sequence, check if it contains the specified value.
|
/// If it's a mapping, check if it has a value that matches specified value.
|
||||||
* If it's a mapping, check if it has a value that matches specified value.
|
///
|
||||||
*
|
/// To check for a null value, use YAMLNull for rhs.
|
||||||
* To check for a null value, use YAMLNull for rhs.
|
///
|
||||||
*
|
/// Params: rhs = Item to look for.
|
||||||
* Params: rhs = Item to look for.
|
///
|
||||||
*
|
/// Returns: true if rhs was found, false otherwise.
|
||||||
* Returns: true if rhs was found, false otherwise.
|
///
|
||||||
*
|
/// Throws: NodeException if the node is not a collection.
|
||||||
* Throws: NodeException if the node is not a collection.
|
|
||||||
*/
|
|
||||||
bool contains(T)(T rhs) const @safe
|
bool contains(T)(T rhs) const @safe
|
||||||
{
|
{
|
||||||
return contains_!(T, No.key, "contains")(rhs);
|
return contains_!(T, No.key, "contains")(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/// Determine if a collection contains specified key.
|
||||||
* Determine if a collection contains specified key.
|
///
|
||||||
*
|
/// If the node is a mapping, check if it has a key
|
||||||
* If the node is a mapping, check if it has a key
|
/// that matches specified key.
|
||||||
* that matches specified key.
|
///
|
||||||
*
|
/// To check for a null key, use YAMLNull for rhs.
|
||||||
* To check for a null key, use YAMLNull for rhs.
|
///
|
||||||
*
|
/// Params: rhs = Item to look for.
|
||||||
* Params: rhs = Item to look for.
|
///
|
||||||
*
|
/// Returns: true if rhs was found, false otherwise.
|
||||||
* Returns: true if rhs was found, false otherwise.
|
///
|
||||||
*
|
/// Throws: NodeException if the node is not a mapping.
|
||||||
* Throws: NodeException if the node is not a mapping.
|
|
||||||
*/
|
|
||||||
bool containsKey(T)(T rhs) const @safe
|
bool containsKey(T)(T rhs) const @safe
|
||||||
{
|
{
|
||||||
return contains_!(T, Yes.key, "containsKey")(rhs);
|
return contains_!(T, Yes.key, "containsKey")(rhs);
|
||||||
|
@ -942,28 +915,26 @@ struct Node
|
||||||
"Node.opAssign() doesn't produce an equivalent copy");
|
"Node.opAssign() doesn't produce an equivalent copy");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Set element at specified index in a collection.
|
||||||
* Set element at specified index in a collection.
|
///
|
||||||
*
|
/// This method can only be called on collection nodes.
|
||||||
* This method can only be called on collection nodes.
|
///
|
||||||
*
|
/// If the node is a sequence, index must be integral.
|
||||||
* If the node is a sequence, index must be integral.
|
///
|
||||||
*
|
/// If the node is a mapping, sets the _value corresponding to the first
|
||||||
* If the node is a mapping, sets the _value corresponding to the first
|
/// key matching index (including conversion, so e.g. "42" matches 42).
|
||||||
* key matching index (including conversion, so e.g. "42" matches 42).
|
///
|
||||||
*
|
/// If the node is a mapping and no key matches index, a new key-value
|
||||||
* If the node is a mapping and no key matches index, a new key-value
|
/// pair is added to the mapping. In sequences the index must be in
|
||||||
* pair is added to the mapping. In sequences the index must be in
|
/// range. This ensures behavior siilar to D arrays and associative
|
||||||
* range. This ensures behavior siilar to D arrays and associative
|
/// arrays.
|
||||||
* arrays.
|
///
|
||||||
*
|
/// To set element at a null index, use YAMLNull for index.
|
||||||
* To set element at a null index, use YAMLNull for index.
|
///
|
||||||
*
|
/// Params: index = Index of the value to set.
|
||||||
* Params: index = Index of the value to set.
|
///
|
||||||
*
|
/// Throws: NodeException if the node is not a collection, index is out
|
||||||
* Throws: NodeException if the node is not a collection, index is out
|
/// of range or if a non-integral index is used on a sequence node.
|
||||||
* of range or if a non-integral index is used on a sequence node.
|
|
||||||
*/
|
|
||||||
void opIndexAssign(K, V)(V value, K index) @safe
|
void opIndexAssign(K, V)(V value, K index) @safe
|
||||||
{
|
{
|
||||||
if(isSequence())
|
if(isSequence())
|
||||||
|
@ -1028,15 +999,13 @@ struct Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Foreach over a sequence, getting each element as T.
|
||||||
* Foreach over a sequence, getting each element as T.
|
///
|
||||||
*
|
/// If T is Node, simply iterate over the nodes in the sequence.
|
||||||
* If T is Node, simply iterate over the nodes in the sequence.
|
/// Otherwise, convert each node to T during iteration.
|
||||||
* Otherwise, convert each node to T during iteration.
|
///
|
||||||
*
|
/// Throws: NodeException if the node is not a sequence or an
|
||||||
* Throws: NodeException if the node is not a sequence or an
|
/// element could not be converted to specified type.
|
||||||
* element could not be converted to specified type.
|
|
||||||
*/
|
|
||||||
int opApply(T)(int delegate(ref T) dg) @trusted
|
int opApply(T)(int delegate(ref T) dg) @trusted
|
||||||
{
|
{
|
||||||
enforce(isSequence,
|
enforce(isSequence,
|
||||||
|
@ -1085,15 +1054,13 @@ struct Node
|
||||||
assert(array2 == [11, 12, 13, 14]);
|
assert(array2 == [11, 12, 13, 14]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Foreach over a mapping, getting each key/value as K/V.
|
||||||
* Foreach over a mapping, getting each key/value as K/V.
|
///
|
||||||
*
|
/// If the K and/or V is Node, simply iterate over the nodes in the mapping.
|
||||||
* If the K and/or V is Node, simply iterate over the nodes in the mapping.
|
/// Otherwise, convert each key/value to T during iteration.
|
||||||
* Otherwise, convert each key/value to T during iteration.
|
///
|
||||||
*
|
/// Throws: NodeException if the node is not a mapping or an
|
||||||
* Throws: NodeException if the node is not a mapping or an
|
/// element could not be converted to specified type.
|
||||||
* element could not be converted to specified type.
|
|
||||||
*/
|
|
||||||
int opApply(K, V)(int delegate(ref K, ref V) dg) @trusted
|
int opApply(K, V)(int delegate(ref K, ref V) dg) @trusted
|
||||||
{
|
{
|
||||||
enforce(isMapping,
|
enforce(isMapping,
|
||||||
|
@ -1179,21 +1146,19 @@ struct Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Add an element to a sequence.
|
||||||
* Add an element to a sequence.
|
///
|
||||||
*
|
/// This method can only be called on sequence nodes.
|
||||||
* This method can only be called on sequence nodes.
|
///
|
||||||
*
|
/// If value is a node, it is copied to the sequence directly. Otherwise
|
||||||
* If value is a node, it is copied to the sequence directly. Otherwise
|
/// value is converted to a node and then stored in the sequence.
|
||||||
* value is converted to a node and then stored in the sequence.
|
///
|
||||||
*
|
/// $(P When emitting, all values in the sequence will be emitted. When
|
||||||
* $(P When emitting, all values in the sequence will be emitted. When
|
/// using the !!set tag, the user needs to ensure that all elements in
|
||||||
* using the !!set tag, the user needs to ensure that all elements in
|
/// the sequence are unique, otherwise $(B invalid) YAML code will be
|
||||||
* the sequence are unique, otherwise $(B invalid) YAML code will be
|
/// emitted.)
|
||||||
* emitted.)
|
///
|
||||||
*
|
/// Params: value = Value to _add to the sequence.
|
||||||
* Params: value = Value to _add to the sequence.
|
|
||||||
*/
|
|
||||||
void add(T)(T value) @safe
|
void add(T)(T value) @safe
|
||||||
{
|
{
|
||||||
enforce(isSequence(),
|
enforce(isSequence(),
|
||||||
|
@ -1215,22 +1180,20 @@ struct Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Add a key-value pair to a mapping.
|
||||||
* Add a key-value pair to a mapping.
|
///
|
||||||
*
|
/// This method can only be called on mapping nodes.
|
||||||
* This method can only be called on mapping nodes.
|
///
|
||||||
*
|
/// If key and/or value is a node, it is copied to the mapping directly.
|
||||||
* If key and/or value is a node, it is copied to the mapping directly.
|
/// Otherwise it is converted to a node and then stored in the mapping.
|
||||||
* Otherwise it is converted to a node and then stored in the mapping.
|
///
|
||||||
*
|
/// $(P It is possible for the same key to be present more than once in a
|
||||||
* $(P It is possible for the same key to be present more than once in a
|
/// mapping. When emitting, all key-value pairs will be emitted.
|
||||||
* mapping. When emitting, all key-value pairs will be emitted.
|
/// This is useful with the "!!pairs" tag, but will result in
|
||||||
* This is useful with the "!!pairs" tag, but will result in
|
/// $(B invalid) YAML with "!!map" and "!!omap" tags.)
|
||||||
* $(B invalid) YAML with "!!map" and "!!omap" tags.)
|
///
|
||||||
*
|
/// Params: key = Key to _add.
|
||||||
* Params: key = Key to _add.
|
/// value = Value to _add.
|
||||||
* value = Value to _add.
|
|
||||||
*/
|
|
||||||
void add(K, V)(K key, V value) @safe
|
void add(K, V)(K key, V value) @safe
|
||||||
{
|
{
|
||||||
enforce(isMapping(),
|
enforce(isMapping(),
|
||||||
|
@ -1252,21 +1215,19 @@ struct Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Determine whether a key is in a mapping, and access its value.
|
||||||
* Determine whether a key is in a mapping, and access its value.
|
///
|
||||||
*
|
/// This method can only be called on mapping nodes.
|
||||||
* This method can only be called on mapping nodes.
|
///
|
||||||
*
|
/// Params: key = Key to search for.
|
||||||
* Params: key = Key to search for.
|
///
|
||||||
*
|
/// Returns: A pointer to the value (as a Node) corresponding to key,
|
||||||
* Returns: A pointer to the value (as a Node) corresponding to key,
|
/// or null if not found.
|
||||||
* or null if not found.
|
///
|
||||||
*
|
/// Note: Any modification to the node can invalidate the returned
|
||||||
* Note: Any modification to the node can invalidate the returned
|
/// pointer.
|
||||||
* pointer.
|
///
|
||||||
*
|
/// See_Also: contains
|
||||||
* See_Also: contains
|
|
||||||
*/
|
|
||||||
Node* opBinaryRight(string op, K)(K key) @trusted if (op == "in")
|
Node* opBinaryRight(string op, K)(K key) @trusted if (op == "in")
|
||||||
{
|
{
|
||||||
enforce(isMapping, new Error("Trying to use 'in' on a " ~
|
enforce(isMapping, new Error("Trying to use 'in' on a " ~
|
||||||
|
@ -1295,19 +1256,17 @@ struct Node
|
||||||
assert(mapping["foo"] == Node("newfoo"));
|
assert(mapping["foo"] == Node("newfoo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Remove first (if any) occurence of a value in a collection.
|
||||||
* Remove first (if any) occurence of a value in a collection.
|
///
|
||||||
*
|
/// This method can only be called on collection nodes.
|
||||||
* This method can only be called on collection nodes.
|
///
|
||||||
*
|
/// If the node is a sequence, the first node matching value is removed.
|
||||||
* If the node is a sequence, the first node matching value is removed.
|
/// If the node is a mapping, the first key-value pair where _value
|
||||||
* If the node is a mapping, the first key-value pair where _value
|
/// matches specified value is removed.
|
||||||
* matches specified value is removed.
|
///
|
||||||
*
|
/// Params: rhs = Value to _remove.
|
||||||
* Params: rhs = Value to _remove.
|
///
|
||||||
*
|
/// Throws: NodeException if the node is not a collection.
|
||||||
* Throws: NodeException if the node is not a collection.
|
|
||||||
*/
|
|
||||||
void remove(T)(T rhs) @trusted
|
void remove(T)(T rhs) @trusted
|
||||||
{
|
{
|
||||||
remove_!(T, No.key, "remove")(rhs);
|
remove_!(T, No.key, "remove")(rhs);
|
||||||
|
@ -1338,25 +1297,23 @@ struct Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Remove element at the specified index of a collection.
|
||||||
* Remove element at the specified index of a collection.
|
///
|
||||||
*
|
/// This method can only be called on collection nodes.
|
||||||
* This method can only be called on collection nodes.
|
///
|
||||||
*
|
/// If the node is a sequence, index must be integral.
|
||||||
* If the node is a sequence, index must be integral.
|
///
|
||||||
*
|
/// If the node is a mapping, remove the first key-value pair where
|
||||||
* If the node is a mapping, remove the first key-value pair where
|
/// key matches index.
|
||||||
* key matches index.
|
///
|
||||||
*
|
/// If the node is a mapping and no key matches index, nothing is removed
|
||||||
* If the node is a mapping and no key matches index, nothing is removed
|
/// and no exception is thrown. This ensures behavior siilar to D arrays
|
||||||
* and no exception is thrown. This ensures behavior siilar to D arrays
|
/// and associative arrays.
|
||||||
* and associative arrays.
|
///
|
||||||
*
|
/// Params: index = Index to remove at.
|
||||||
* Params: index = Index to remove at.
|
///
|
||||||
*
|
/// Throws: NodeException if the node is not a collection, index is out
|
||||||
* Throws: NodeException if the node is not a collection, index is out
|
/// of range or if a non-integral index is used on a sequence node.
|
||||||
* of range or if a non-integral index is used on a sequence node.
|
|
||||||
*/
|
|
||||||
void removeAt(T)(T index) @trusted
|
void removeAt(T)(T index) @trusted
|
||||||
{
|
{
|
||||||
remove_!(T, Yes.key, "removeAt")(index);
|
remove_!(T, Yes.key, "removeAt")(index);
|
||||||
|
@ -1415,17 +1372,15 @@ struct Node
|
||||||
}
|
}
|
||||||
|
|
||||||
package:
|
package:
|
||||||
/*
|
// Construct a node from raw data.
|
||||||
* Construct a node from raw data.
|
//
|
||||||
*
|
// Params: value = Value of the node.
|
||||||
* Params: value = Value of the node.
|
// startMark = Start position of the node in file.
|
||||||
* startMark = Start position of the node in file.
|
// tag = Tag of the node.
|
||||||
* tag = Tag of the node.
|
// scalarStyle = Scalar style of the node.
|
||||||
* scalarStyle = Scalar style of the node.
|
// collectionStyle = Collection style of the node.
|
||||||
* collectionStyle = Collection style of the node.
|
//
|
||||||
*
|
// Returns: Constructed node.
|
||||||
* Returns: Constructed node.
|
|
||||||
*/
|
|
||||||
static Node rawNode(Value value, const Mark startMark, const Tag tag,
|
static Node rawNode(Value value, const Mark startMark, const Tag tag,
|
||||||
const ScalarStyle scalarStyle,
|
const ScalarStyle scalarStyle,
|
||||||
const CollectionStyle collectionStyle) @safe
|
const CollectionStyle collectionStyle) @safe
|
||||||
|
@ -1468,11 +1423,9 @@ struct Node
|
||||||
else static assert(false, "Unknown value type. Is value() in sync with allowed()?");
|
else static assert(false, "Unknown value type. Is value() in sync with allowed()?");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Equality test with any value.
|
||||||
* Equality test with any value.
|
//
|
||||||
*
|
// useTag determines whether or not to consider tags in node-node comparisons.
|
||||||
* useTag determines whether or not to consider tags in node-node comparisons.
|
|
||||||
*/
|
|
||||||
bool equals(Flag!"useTag" useTag, T)(ref T rhs) const @safe
|
bool equals(Flag!"useTag" useTag, T)(ref T rhs) const @safe
|
||||||
{
|
{
|
||||||
static if(is(Unqual!T == Node))
|
static if(is(Unqual!T == Node))
|
||||||
|
@ -1498,13 +1451,11 @@ struct Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Comparison with another node.
|
||||||
* Comparison with another node.
|
//
|
||||||
*
|
// Used for ordering in mappings and for opEquals.
|
||||||
* Used for ordering in mappings and for opEquals.
|
//
|
||||||
*
|
// useTag determines whether or not to consider tags in the comparison.
|
||||||
* useTag determines whether or not to consider tags in the comparison.
|
|
||||||
*/
|
|
||||||
int cmp(Flag!"useTag" useTag)(const ref Node rhs) const @trusted
|
int cmp(Flag!"useTag" useTag)(const ref Node rhs) const @trusted
|
||||||
{
|
{
|
||||||
// Compare tags - if equal or both null, we need to compare further.
|
// Compare tags - if equal or both null, we need to compare further.
|
||||||
|
@ -1611,13 +1562,11 @@ struct Node
|
||||||
assert(false, "Unknown type of node for comparison : " ~ type.toString());
|
assert(false, "Unknown type of node for comparison : " ~ type.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get a string representation of the node tree. Used for debugging.
|
||||||
* Get a string representation of the node tree. Used for debugging.
|
//
|
||||||
*
|
// Params: level = Level of the node in the tree.
|
||||||
* Params: level = Level of the node in the tree.
|
//
|
||||||
*
|
// Returns: String representing the node tree.
|
||||||
* Returns: String representing the node tree.
|
|
||||||
*/
|
|
||||||
@property string debugString(uint level = 0) @trusted
|
@property string debugString(uint level = 0) @trusted
|
||||||
{
|
{
|
||||||
string indent;
|
string indent;
|
||||||
|
@ -1660,11 +1609,9 @@ struct Node
|
||||||
return (cast(nothrowType)&value_.type)();
|
return (cast(nothrowType)&value_.type)();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Determine if the value stored by the node is of specified type.
|
||||||
* Determine if the value stored by the node is of specified type.
|
//
|
||||||
*
|
// This only works for default YAML types, not for user defined types.
|
||||||
* This only works for default YAML types, not for user defined types.
|
|
||||||
*/
|
|
||||||
@property bool isType(T)() const @safe nothrow
|
@property bool isType(T)() const @safe nothrow
|
||||||
{
|
{
|
||||||
return this.type is typeid(Unqual!T);
|
return this.type is typeid(Unqual!T);
|
||||||
|
@ -1850,15 +1797,13 @@ struct Node
|
||||||
}
|
}
|
||||||
|
|
||||||
package:
|
package:
|
||||||
/*
|
// Merge a pair into an array of pairs based on merge rules in the YAML spec.
|
||||||
* Merge a pair into an array of pairs based on merge rules in the YAML spec.
|
//
|
||||||
*
|
// The new pair will only be added if there is not already a pair
|
||||||
* The new pair will only be added if there is not already a pair
|
// with the same key.
|
||||||
* with the same key.
|
//
|
||||||
*
|
// Params: pairs = Appender managing the array of pairs to merge into.
|
||||||
* Params: pairs = Appender managing the array of pairs to merge into.
|
// toMerge = Pair to merge.
|
||||||
* toMerge = Pair to merge.
|
|
||||||
*/
|
|
||||||
void merge(ref Appender!(Node.Pair[], Node.Pair) pairs, ref Node.Pair toMerge) @trusted
|
void merge(ref Appender!(Node.Pair[], Node.Pair) pairs, ref Node.Pair toMerge) @trusted
|
||||||
{
|
{
|
||||||
foreach(ref pair; pairs.data)
|
foreach(ref pair; pairs.data)
|
||||||
|
@ -1868,15 +1813,13 @@ void merge(ref Appender!(Node.Pair[], Node.Pair) pairs, ref Node.Pair toMerge) @
|
||||||
pairs.put(toMerge);
|
pairs.put(toMerge);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Merge pairs into an array of pairs based on merge rules in the YAML spec.
|
||||||
* Merge pairs into an array of pairs based on merge rules in the YAML spec.
|
//
|
||||||
*
|
// Any new pair will only be added if there is not already a pair
|
||||||
* Any new pair will only be added if there is not already a pair
|
// with the same key.
|
||||||
* with the same key.
|
//
|
||||||
*
|
// Params: pairs = Appender managing the array of pairs to merge into.
|
||||||
* Params: pairs = Appender managing the array of pairs to merge into.
|
// toMerge = Pairs to merge.
|
||||||
* toMerge = Pairs to merge.
|
|
||||||
*/
|
|
||||||
void merge(ref Appender!(Node.Pair[], Node.Pair) pairs, Node.Pair[] toMerge) @trusted
|
void merge(ref Appender!(Node.Pair[], Node.Pair) pairs, Node.Pair[] toMerge) @trusted
|
||||||
{
|
{
|
||||||
bool eq(ref Node.Pair a, ref Node.Pair b){return a.key == b.key;}
|
bool eq(ref Node.Pair a, ref Node.Pair b){return a.key == b.key;}
|
||||||
|
|
Loading…
Reference in a new issue