From fbc962623d56d2cad7e8fa7671507fea40308176 Mon Sep 17 00:00:00 2001
From: Ferdinand Majerech
Date: Thu, 17 Nov 2011 23:53:24 +0100
Subject: [PATCH] Simplified the Constructor API.
---
doc/doctrees/environment.pickle | Bin 12705 -> 12705 bytes
doc/doctrees/tutorials/custom_types.doctree | Bin 47085 -> 46989 bytes
doc/html/_sources/tutorials/custom_types.txt | 51 +++--
doc/html/api/dyaml.constructor.html | 81 +++-----
doc/html/articles/spec_differences.html | 2 +-
doc/html/index.html | 2 +-
doc/html/search.html | 2 +-
doc/html/searchindex.js | 2 +-
doc/html/tutorials/custom_types.html | 52 +++--
doc/html/tutorials/getting_started.html | 2 +-
doc/html/tutorials/yaml_syntax.html | 2 +-
docsrc/tutorials/custom_types.rst | 51 +++--
dyaml/constructor.d | 207 ++++++++-----------
examples/constructor/main.d | 23 +--
examples/resolver/main.d | 23 +--
test/src/constructor.d | 14 +-
16 files changed, 217 insertions(+), 297 deletions(-)
diff --git a/doc/doctrees/environment.pickle b/doc/doctrees/environment.pickle
index 9894b7d00b6ff975046591a9b15a1635930d29a6..5abd626d2511e19827e35b507d2010d071007127 100644
GIT binary patch
delta 62
zcmZ3OyfAq~o4#T4t2+C68OrXCmp3NAD&tt4p#x!7$IQzxg)l2EGc)X<3ZA!Z-md?O
F5dfW99xVU>
delta 62
zcmZ3OyfAq~o4z57?1ygs3}tu6%Nto_pZo60(19@D@)=~9LYS|1ZOX8NFkd*gZr-l{
GiV*-KeHtSG
diff --git a/doc/doctrees/tutorials/custom_types.doctree b/doc/doctrees/tutorials/custom_types.doctree
index 3fe2c1cf915cec62babd894da06437bd29315317..7518da8275eec601c0a29c08fc8cebd63af49377 100644
GIT binary patch
delta 6153
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
diff --git a/doc/html/_sources/tutorials/custom_types.txt b/doc/html/_sources/tutorials/custom_types.txt
index 9b3eaf5..65853ee 100644
--- a/doc/html/_sources/tutorials/custom_types.txt
+++ b/doc/html/_sources/tutorials/custom_types.txt
@@ -3,13 +3,13 @@ Custom YAML data types
======================
Sometimes you need to serialize complex data types such as classes. To do this
-you could use plain nodes such as mappings with class data members. However,
-YAML supports custom types with identifiers called *tags*. That is the topic of
-this tutorial.
+you could use plain nodes such as mappings with class data members. YAML also
+supports custom types with identifiers called *tags*. That is the topic of this
+tutorial.
Each YAML node has a tag specifying its type. For instance: strings use the tag
``tag:yaml.org,2002:str``. Tags of most default types are *implicitly resolved*
-during parsing, so you don't need to specify tag for each float, integer, etc.
+during parsing - you don't need to specify tag for each float, integer, etc.
D:YAML can also implicitly resolve custom tags, as we will show later.
@@ -24,7 +24,7 @@ the *addConstructorXXX()* methods, where *XXX* is *Scalar*, *Sequence* or
*Mapping*. *Constructor* is then passed to *Loader*, which parses YAML input.
Struct types have no specific requirements for YAML support. Class types should
-define the *opEquals()* operator, as this is used in equality comparisons of
+define the *opEquals()* operator - this is used in equality comparisons of
nodes. Default class *opEquals()* compares references, which means two identical
objects might be considered unequal. (Default struct *opEquals()* compares
byte-by-byte, sometimes you might want to override that as well.)
@@ -41,24 +41,26 @@ following struct:
ubyte blue;
}
-First, we need a function to construct our data type. It must take two *Mark*
-structs, which store position of the node in the file, and a reference to *Node*
-to construct from. The node is guaranteed to contain either a *string*, an array
-of *Node* or of *Node.Pair*, depending on whether we're constructing our value
-from a scalar, sequence, or mapping, respectively. In this tutorial, we have
-functions to construct a color from a scalar, using CSS-like format, RRGGBB, or
-from a mapping, where we use the following format: {r:RRR, g:GGG, b:BBB} . Code
-of these functions:
+First, we need a function to construct our data type. The function will take a
+reference to *Node* to construct from. The node is guaranteed to contain either
+a *string*, an array of *Node* or of *Node.Pair*, depending on whether we're
+constructing our value from a scalar, sequence, or mapping, respectively.
+If this function throws any exception, D:YAML handles it and adds its message
+to a *YAMLException* that will be thrown when loading the file.
+
+In this tutorial, we have functions to construct a color from a scalar, using
+CSS-like format, RRGGBB, or from a mapping, where we use the following format:
+{r:RRR, g:GGG, b:BBB} . Code of these functions:
.. code-block:: d
- Color constructColorScalar(Mark start, Mark end, ref Node node)
+ Color constructColorScalar(ref Node node)
{
string value = node.as!string;
if(value.length != 6)
{
- throw new ConstructorException("Invalid color: " ~ value, start, end);
+ throw new Exception("Invalid color: " ~ value);
}
//We don't need to check for uppercase chars this way.
value = value.toLower();
@@ -68,7 +70,7 @@ of these functions:
{
if(!std.ascii.isHexDigit(c))
{
- throw new ConstructorException("Invalid color: " ~ value, start, end);
+ throw new Exception("Invalid color: " ~ value);
}
if(std.ascii.isDigit(c))
@@ -86,21 +88,16 @@ of these functions:
return result;
}
- Color constructColorMapping(Mark start, Mark end, ref Node node)
+ Color constructColorMapping(ref Node node)
{
ubyte r,g,b;
//Might throw if a value is missing is not an integer, or is out of range.
- try
- {
- r = node["r"].as!ubyte;
- g = node["g"].as!ubyte;
- b = node["b"].as!ubyte;
- }
- catch(NodeException e)
- {
- throw new ConstructorException("Invalid color: " ~ e.msg, start, end);
- }
+ //If this happens, D:YAML will handle the exception and use its message
+ //in a YAMLException thrown when loading.
+ r = node["r"].as!ubyte;
+ g = node["g"].as!ubyte;
+ b = node["b"].as!ubyte;
return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b);
}
diff --git a/doc/html/api/dyaml.constructor.html b/doc/html/api/dyaml.constructor.html
index b81d239..f05fd59 100644
--- a/doc/html/api/dyaml.constructor.html
+++ b/doc/html/api/dyaml.constructor.html
@@ -95,14 +95,20 @@
-void addConstructorScalar(T)(in string tag, T function(Mark, Mark, ref Node) ctor);
+void addConstructorScalar(T)(in string tag, T function(ref Node) ctor);
Add a constructor function from scalar.
-The function must take two Marks (start and end positions of
- the node in file) and a reference to Node to construct from.
+
The function must take a reference to Node to construct from.
The node contains a string for scalars, Node[] for sequences and
Node.Pair[] for mappings.
+
+
+ Any exception thrown by this function will be caught by D:YAML and
+ its message will be added to a YAMLException that will also tell the
+ user which type failed to construct, and position in the file.
+
+
The value returned by this function will be stored in the resulting node.
@@ -124,20 +130,13 @@
int x, y, z;
}
- MyStruct constructMyStructScalar(Mark start, Mark end, ref Node node)
+ MyStruct constructMyStructScalar(ref Node node)
{
auto parts = node.as!string().split(":");
- try
- {
- return MyStruct(to!int(parts[0]), to!int(parts[1]), to!int(parts[2]));
- }
- catch(Exception e)
- {
- throw new ConstructorException("Could not construct MyStruct: " ~ e.msg,
- start, end);
- }
+ return MyStruct(to!int(parts[0]), to!int(parts[1]), to!int(parts[2]));
}
void main()
@@ -152,7 +151,7 @@
-void addConstructorSequence(T)(in string tag, T function(Mark, Mark, ref Node) ctor);
+void addConstructorSequence(T)(in string tag, T function(ref Node) ctor);
Add a constructor function from sequence.
@@ -169,19 +168,11 @@
int x, y, z;
}
- MyStruct constructMyStructSequence(Mark start, Mark end, ref Node node)
+ MyStruct constructMyStructSequence(ref Node node)
{
try
- {
- return MyStruct(node[0].as!int, node[1].as!int, node[2].as!int);
- }
- catch(NodeException e)
- {
- throw new ConstructorException("Could not construct MyStruct: " ~ e.msg,
- start, end);
- }
+ return MyStruct(node[0].as!int, node[1].as!int, node[2].as!int);
}
void main()
@@ -196,7 +187,7 @@
-void addConstructorMapping(T)(in string tag, T function(Mark, Mark, ref Node) ctor);
+void addConstructorMapping(T)(in string tag, T function(ref Node) ctor);
Add a constructor function from a mapping.
@@ -213,19 +204,11 @@
int x, y, z;
}
- MyStruct constructMyStructMapping(Mark start, Mark end, ref Node node)
+ MyStruct constructMyStructMapping(ref Node node)
{
try
- {
- return MyStruct(node["x"].as!int, node["y"].as!int, node["z"].as!int);
- }
- catch(NodeException e)
- {
- throw new ConstructorException("Could not construct MyStruct: " ~ e.msg,
- start, end);
- }
+ return MyStruct(node["x"].as!int, node["y"].as!int, node["z"].as!int);
}
void main()
@@ -242,72 +225,72 @@
-YAMLNull constructNull(Mark start, Mark end, ref Node node);
+YAMLNull constructNull(ref Node node);
Construct a null node.
-YAMLMerge constructMerge(Mark start, Mark end, ref Node node);
+YAMLMerge constructMerge(ref Node node);
Construct a merge node - a node that merges another node into a mapping.
-bool constructBool(Mark start, Mark end, ref Node node);
+bool constructBool(ref Node node);
Construct a boolean node.
-long constructLong(Mark start, Mark end, ref Node node);
+long constructLong(ref Node node);
Construct an integer (long) node.
-real constructReal(Mark start, Mark end, ref Node node);
+real constructReal(ref Node node);
Construct a floating point (real) node.
-ubyte[] constructBinary(Mark start, Mark end, ref Node node);
+ubyte[] constructBinary(ref Node node);
Construct a binary (base64) node.
-SysTime constructTimestamp(Mark start, Mark end, ref Node node);
+SysTime constructTimestamp(ref Node node);
Construct a timestamp (SysTime) node.
-string constructString(Mark start, Mark end, ref Node node);
+string constructString(ref Node node);
Construct a string node.
-Pair[] getPairs(string type, Mark start, Mark end, Node[] nodes);
+Pair[] getPairs(string type, Node[] nodes);
Convert a sequence of single-element mappings into a sequence of pairs.
-Pair[] constructOrderedMap(Mark start, Mark end, ref Node node);
+Pair[] constructOrderedMap(ref Node node);
Construct an ordered map (ordered sequence of key:value pairs without duplicates) node.
-Pair[] constructPairs(Mark start, Mark end, ref Node node);
+Pair[] constructPairs(ref Node node);
Construct a pairs (ordered sequence of key: value pairs allowing duplicates) node.
-Node[] constructSet(Mark start, Mark end, ref Node node);
+Node[] constructSet(ref Node node);
Construct a set node.
-Node[] constructSequence(Mark start, Mark end, ref Node node);
+Node[] constructSequence(ref Node node);
Construct a sequence (array) node.
-Pair[] constructMap(Mark start, Mark end, ref Node node);
+Pair[] constructMap(ref Node node);
Construct an unordered map (unordered set of key: value pairs without duplicates) node.
diff --git a/doc/html/articles/spec_differences.html b/doc/html/articles/spec_differences.html
index c859c39..eaff95f 100644
--- a/doc/html/articles/spec_differences.html
+++ b/doc/html/articles/spec_differences.html
@@ -138,7 +138,7 @@ struct appears in Phobos.