Doc style changes in constructor.d

This commit is contained in:
Ferdinand Majerech 2014-07-19 03:49:21 +02:00
parent d8f19ffc33
commit 424035601c

View file

@ -31,20 +31,16 @@ import dyaml.tag;
import dyaml.style; import dyaml.style;
/** /// Exception thrown at constructor errors.
* Exception thrown at constructor errors. ///
* /// Can be thrown by custom constructor functions.
* Can be thrown by custom constructor functions.
*/
package class ConstructorException : YAMLException package class ConstructorException : YAMLException
{ {
/** /// Construct a ConstructorException.
* Construct a ConstructorException. ///
* /// Params: msg = Error message.
* Params: msg = Error message. /// start = Start position of the error context.
* start = Start position of the error context. /// end = End position of the error context.
* end = End position of the error context.
*/
this(string msg, Mark start, Mark end, string file = __FILE__, int line = __LINE__) this(string msg, Mark start, Mark end, string file = __FILE__, int line = __LINE__)
@safe @safe
{ {
@ -55,40 +51,36 @@ package class ConstructorException : YAMLException
private alias ConstructorException Error; private alias ConstructorException Error;
/** /// Constructs YAML values.
* Constructs YAML values. ///
* /// Each YAML scalar, sequence or mapping has a tag specifying its data type.
* Each YAML scalar, sequence or mapping has a tag specifying its data type. /// Constructor uses user-specifyable functions to create a node of desired
* Constructor uses user-specifyable functions to create a node of desired /// data type from a scalar, sequence or mapping.
* data type from a scalar, sequence or mapping. ///
* ///
* /// Each of these functions is associated with a tag, and can process either
* Each of these functions is associated with a tag, and can process either /// a scalar, a sequence, or a mapping. The constructor passes each value to
* a scalar, a sequence, or a mapping. The constructor passes each value to /// the function with corresponding tag, which then returns the resulting value
* the function with corresponding tag, which then returns the resulting value /// that can be stored in a node.
* that can be stored in a node. ///
* /// If a tag is detected with no known constructor function, it is considered an error.
* If a tag is detected with no known constructor function, it is considered an error.
*/
final class Constructor final class Constructor
{ {
private: private:
///Constructor functions from scalars. /// Constructor functions from scalars.
Node.Value delegate(ref Node)[Tag] fromScalar_; Node.Value delegate(ref Node)[Tag] fromScalar_;
///Constructor functions from sequences. /// Constructor functions from sequences.
Node.Value delegate(ref Node)[Tag] fromSequence_; Node.Value delegate(ref Node)[Tag] fromSequence_;
///Constructor functions from mappings. /// Constructor functions from mappings.
Node.Value delegate(ref Node)[Tag] fromMapping_; Node.Value delegate(ref Node)[Tag] fromMapping_;
public: public:
/** /// Construct a Constructor.
* Construct a Constructor. ///
* /// If you don't want to support default YAML tags/data types, you can use
* If you don't want to support default YAML tags/data types, you can use /// defaultConstructors to disable constructor functions for these.
* defaultConstructors to disable constructor functions for these. ///
* /// Params: defaultConstructors = Use constructors for default YAML tags?
* Params: defaultConstructors = Use constructors for default YAML tags?
*/
this(const Flag!"useDefaultConstructors" defaultConstructors = Yes.useDefaultConstructors) this(const Flag!"useDefaultConstructors" defaultConstructors = Yes.useDefaultConstructors)
@safe nothrow @safe nothrow
{ {
@ -113,7 +105,7 @@ final class Constructor
addConstructorScalar("tag:yaml.org,2002:merge", &constructMerge); addConstructorScalar("tag:yaml.org,2002:merge", &constructMerge);
} }
///Destroy the constructor. /// Destroy the constructor.
pure @safe nothrow ~this() pure @safe nothrow ~this()
{ {
clear(fromScalar_); clear(fromScalar_);
@ -124,74 +116,72 @@ final class Constructor
fromMapping_ = null; fromMapping_ = null;
} }
/** /// Add a constructor function from scalar.
* Add a constructor function from scalar. ///
* /// The function must take a reference to $(D Node) to construct from.
* The function must take a reference to $(D Node) to construct from. /// The node contains a string for scalars, $(Node[]) for sequences and
* The node contains a string for scalars, $(Node[]) for sequences and /// $(Node.Pair[]) for mappings.
* $(Node.Pair[]) for mappings. ///
* /// Any exception thrown by this function will be caught by D:YAML and
* 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
* 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 user which type failed to construct, and position in the file. ///
* ///
* /// The value returned by this function will be stored in the resulting node.
* The value returned by this function will be stored in the resulting node. ///
* /// Only one constructor function can be set for one tag.
* Only one constructor function can be set for one tag. ///
* ///
* /// Structs and classes must implement the $(D opCmp()) operator for D:YAML
* Structs and classes must implement the $(D opCmp()) operator for D:YAML /// support. The signature of the operator that must be implemented
* support. The signature of the operator that must be implemented /// is $(D const int opCmp(ref const MyStruct s)) for structs where
* is $(D const int opCmp(ref const MyStruct s)) for structs where /// $(I MyStruct) is the struct type, and $(D int opCmp(Object o)) for
* $(I MyStruct) is the struct type, and $(D int opCmp(Object o)) for /// classes. Note that the class $(D opCmp()) should not alter the compared
* classes. Note that the class $(D opCmp()) should not alter the compared /// values - it is not const for compatibility reasons.
* values - it is not const for compatibility reasons. ///
* /// Params: tag = Tag for the function to handle.
* Params: tag = Tag for the function to handle. /// ctor = Constructor function.
* ctor = Constructor function. ///
* /// Example:
* Example: ///
* /// --------------------
* -------------------- /// import std.string;
* import std.string; ///
* /// import dyaml.all;
* import dyaml.all; ///
* /// struct MyStruct
* struct MyStruct /// {
* { /// int x, y, z;
* int x, y, z; ///
* /// //Any D:YAML type must have a custom opCmp operator.
* //Any D:YAML type must have a custom opCmp operator. /// //This is used for ordering in mappings.
* //This is used for ordering in mappings. /// const int opCmp(ref const MyStruct s)
* const int opCmp(ref const MyStruct s) /// {
* { /// if(x != s.x){return x - s.x;}
* if(x != s.x){return x - s.x;} /// if(y != s.y){return y - s.y;}
* if(y != s.y){return y - s.y;} /// if(z != s.z){return z - s.z;}
* if(z != s.z){return z - s.z;} /// return 0;
* return 0; /// }
* } /// }
* } ///
* /// MyStruct constructMyStructScalar(ref Node node)
* MyStruct constructMyStructScalar(ref Node node) /// {
* { /// //Guaranteed to be string as we construct from scalar.
* //Guaranteed to be string as we construct from scalar. /// //!mystruct x:y:z
* //!mystruct x:y:z /// auto parts = node.as!string().split(":");
* auto parts = node.as!string().split(":"); /// // If this throws, the D:YAML will handle it and throw a YAMLException.
* //If this throws, the D:YAML will handle it and throw a YAMLException. /// return MyStruct(to!int(parts[0]), to!int(parts[1]), to!int(parts[2]));
* return MyStruct(to!int(parts[0]), to!int(parts[1]), to!int(parts[2])); /// }
* } ///
* /// void main()
* void main() /// {
* { /// auto loader = Loader("file.yaml");
* auto loader = Loader("file.yaml"); /// auto constructor = new Constructor;
* auto constructor = new Constructor; /// constructor.addConstructorScalar("!mystruct", &constructMyStructScalar);
* constructor.addConstructorScalar("!mystruct", &constructMyStructScalar); /// loader.constructor = constructor;
* loader.constructor = constructor; /// Node node = loader.load();
* Node node = loader.load(); /// }
* } /// --------------------
* --------------------
*/
void addConstructorScalar(T)(const string tag, T function(ref Node) ctor) void addConstructorScalar(T)(const string tag, T function(ref Node) ctor)
@safe nothrow @safe nothrow
{ {
@ -200,50 +190,48 @@ final class Constructor
(*delegates!string)[t] = deleg; (*delegates!string)[t] = deleg;
} }
/** /// Add a constructor function from sequence.
* Add a constructor function from sequence. ///
* /// See_Also: addConstructorScalar
* See_Also: addConstructorScalar ///
* /// Example:
* Example: ///
* /// --------------------
* -------------------- /// import std.string;
* import std.string; ///
* /// import dyaml.all;
* import dyaml.all; ///
* /// struct MyStruct
* struct MyStruct /// {
* { /// int x, y, z;
* int x, y, z; ///
* /// //Any D:YAML type must have a custom opCmp operator.
* //Any D:YAML type must have a custom opCmp operator. /// //This is used for ordering in mappings.
* //This is used for ordering in mappings. /// const int opCmp(ref const MyStruct s)
* const int opCmp(ref const MyStruct s) /// {
* { /// if(x != s.x){return x - s.x;}
* if(x != s.x){return x - s.x;} /// if(y != s.y){return y - s.y;}
* if(y != s.y){return y - s.y;} /// if(z != s.z){return z - s.z;}
* if(z != s.z){return z - s.z;} /// return 0;
* return 0; /// }
* } /// }
* } ///
* /// MyStruct constructMyStructSequence(ref Node node)
* MyStruct constructMyStructSequence(ref Node node) /// {
* { /// //node is guaranteed to be sequence.
* //node is guaranteed to be sequence. /// //!mystruct [x, y, z]
* //!mystruct [x, y, z] /// return MyStruct(node[0].as!int, node[1].as!int, node[2].as!int);
* return MyStruct(node[0].as!int, node[1].as!int, node[2].as!int); /// }
* } ///
* /// void main()
* void main() /// {
* { /// auto loader = Loader("file.yaml");
* auto loader = Loader("file.yaml"); /// auto constructor = new Constructor;
* auto constructor = new Constructor; /// constructor.addConstructorSequence("!mystruct", &constructMyStructSequence);
* constructor.addConstructorSequence("!mystruct", &constructMyStructSequence); /// loader.constructor = constructor;
* loader.constructor = constructor; /// Node node = loader.load();
* Node node = loader.load(); /// }
* } /// --------------------
* --------------------
*/
void addConstructorSequence(T)(const string tag, T function(ref Node) ctor) void addConstructorSequence(T)(const string tag, T function(ref Node) ctor)
@safe nothrow @safe nothrow
{ {
@ -252,50 +240,48 @@ final class Constructor
(*delegates!(Node[]))[t] = deleg; (*delegates!(Node[]))[t] = deleg;
} }
/** /// Add a constructor function from a mapping.
* Add a constructor function from a mapping. ///
* /// See_Also: addConstructorScalar
* See_Also: addConstructorScalar ///
* /// Example:
* Example: ///
* /// --------------------
* -------------------- /// import std.string;
* import std.string; ///
* /// import dyaml.all;
* import dyaml.all; ///
* /// struct MyStruct
* struct MyStruct /// {
* { /// int x, y, z;
* int x, y, z; ///
* /// //Any D:YAML type must have a custom opCmp operator.
* //Any D:YAML type must have a custom opCmp operator. /// //This is used for ordering in mappings.
* //This is used for ordering in mappings. /// const int opCmp(ref const MyStruct s)
* const int opCmp(ref const MyStruct s) /// {
* { /// if(x != s.x){return x - s.x;}
* if(x != s.x){return x - s.x;} /// if(y != s.y){return y - s.y;}
* if(y != s.y){return y - s.y;} /// if(z != s.z){return z - s.z;}
* if(z != s.z){return z - s.z;} /// return 0;
* return 0; /// }
* } /// }
* } ///
* /// MyStruct constructMyStructMapping(ref Node node)
* MyStruct constructMyStructMapping(ref Node node) /// {
* { /// //node is guaranteed to be mapping.
* //node is guaranteed to be mapping. /// //!mystruct {"x": x, "y": y, "z": z}
* //!mystruct {"x": x, "y": y, "z": z} /// return MyStruct(node["x"].as!int, node["y"].as!int, node["z"].as!int);
* return MyStruct(node["x"].as!int, node["y"].as!int, node["z"].as!int); /// }
* } ///
* /// void main()
* void main() /// {
* { /// auto loader = Loader("file.yaml");
* auto loader = Loader("file.yaml"); /// auto constructor = new Constructor;
* auto constructor = new Constructor; /// constructor.addConstructorMapping("!mystruct", &constructMyStructMapping);
* constructor.addConstructorMapping("!mystruct", &constructMyStructMapping); /// loader.constructor = constructor;
* loader.constructor = constructor; /// Node node = loader.load();
* Node node = loader.load(); /// }
* } /// --------------------
* --------------------
*/
void addConstructorMapping(T)(const string tag, T function(ref Node) ctor) void addConstructorMapping(T)(const string tag, T function(ref Node) ctor)
@safe nothrow @safe nothrow
{ {
@ -386,19 +372,19 @@ final class Constructor
} }
///Construct a _null _node. /// Construct a _null _node.
YAMLNull constructNull(ref Node node) YAMLNull constructNull(ref Node node)
{ {
return YAMLNull(); return YAMLNull();
} }
///Construct a merge _node - a _node that merges another _node into a mapping. /// Construct a merge _node - a _node that merges another _node into a mapping.
YAMLMerge constructMerge(ref Node node) YAMLMerge constructMerge(ref Node node)
{ {
return YAMLMerge(); return YAMLMerge();
} }
///Construct a boolean _node. /// Construct a boolean _node.
bool constructBool(ref Node node) bool constructBool(ref Node node)
{ {
static yes = ["yes", "true", "on"]; static yes = ["yes", "true", "on"];
@ -409,7 +395,7 @@ bool constructBool(ref Node node)
throw new Exception("Unable to parse boolean value: " ~ value); throw new Exception("Unable to parse boolean value: " ~ value);
} }
///Construct an integer (long) _node. /// Construct an integer (long) _node.
long constructLong(ref Node node) long constructLong(ref Node node)
{ {
string value = node.as!string().replace("_", ""); string value = node.as!string().replace("_", "");
@ -478,7 +464,7 @@ unittest
assert(685230 == getLong(sexagesimal)); assert(685230 == getLong(sexagesimal));
} }
///Construct a floating point (real) _node. /// Construct a floating point (real) _node.
real constructReal(ref Node node) real constructReal(ref Node node)
{ {
string value = node.as!string().replace("_", "").toLower(); string value = node.as!string().replace("_", "").toLower();
@ -549,11 +535,11 @@ unittest
assert(to!string(getReal(NaN)) == "nan"); assert(to!string(getReal(NaN)) == "nan");
} }
///Construct a binary (base64) _node. /// Construct a binary (base64) _node.
ubyte[] constructBinary(ref Node node) ubyte[] constructBinary(ref Node node)
{ {
string value = node.as!string; string value = node.as!string;
//For an unknown reason, this must be nested to work (compiler bug?). // For an unknown reason, this must be nested to work (compiler bug?).
try try
{ {
try{return Base64.decode(value.removechars("\n"));} try{return Base64.decode(value.removechars("\n"));}
@ -578,7 +564,7 @@ unittest
assert(value == test); assert(value == test);
} }
///Construct a timestamp (SysTime) _node. /// Construct a timestamp (SysTime) _node.
SysTime constructTimestamp(ref Node node) SysTime constructTimestamp(ref Node node)
{ {
string value = node.as!string; string value = node.as!string;
@ -589,7 +575,7 @@ SysTime constructTimestamp(ref Node node)
try try
{ {
//First, get year, month and day. // First, get year, month and day.
auto matches = match(value, YMDRegexp); auto matches = match(value, YMDRegexp);
enforce(!matches.empty, enforce(!matches.empty,
@ -600,7 +586,7 @@ SysTime constructTimestamp(ref Node node)
const month = to!int(captures[2]); const month = to!int(captures[2]);
const day = to!int(captures[3]); const day = to!int(captures[3]);
//If available, get hour, minute, second and fraction, if present. // If available, get hour, minute, second and fraction, if present.
value = matches.front.post; value = matches.front.post;
matches = match(value, HMSRegexp); matches = match(value, HMSRegexp);
if(matches.empty) if(matches.empty)
@ -614,7 +600,7 @@ SysTime constructTimestamp(ref Node node)
const second = to!int(captures[3]); const second = to!int(captures[3]);
const hectonanosecond = cast(int)(to!real("0" ~ captures[4]) * 10000000); const hectonanosecond = cast(int)(to!real("0" ~ captures[4]) * 10000000);
//If available, get timezone. // If available, get timezone.
value = matches.front.post; value = matches.front.post;
matches = match(value, TZRegexp); matches = match(value, TZRegexp);
if(matches.empty || matches.front.captures[0] == "Z") if(matches.empty || matches.front.captures[0] == "Z")
@ -678,14 +664,14 @@ unittest
assert(timestamp(ymd) == "20021214T000000Z"); assert(timestamp(ymd) == "20021214T000000Z");
} }
///Construct a string _node. /// Construct a string _node.
string constructString(ref Node node) string constructString(ref Node node)
{ {
return node.as!string; return node.as!string;
} }
///Convert a sequence of single-element mappings into a sequence of pairs. /// Convert a sequence of single-element mappings into a sequence of pairs.
Node.Pair[] getPairs(string type, Node[] nodes) Node.Pair[] getPairs(string type, Node[] nodes)
{ {
Node.Pair[] pairs; Node.Pair[] pairs;
@ -702,7 +688,7 @@ Node.Pair[] getPairs(string type, Node[] nodes)
return pairs; return pairs;
} }
///Construct an ordered map (ordered sequence of key:value pairs without duplicates) _node. /// Construct an ordered map (ordered sequence of key:value pairs without duplicates) _node.
Node.Pair[] constructOrderedMap(ref Node node) Node.Pair[] constructOrderedMap(ref Node node)
{ {
auto pairs = getPairs("ordered map", node.as!(Node[])); auto pairs = getPairs("ordered map", node.as!(Node[]));
@ -764,13 +750,13 @@ unittest
assert(!hasDuplicates(alternateTypes(64))); assert(!hasDuplicates(alternateTypes(64)));
} }
///Construct a pairs (ordered sequence of key: value pairs allowing duplicates) _node. /// Construct a pairs (ordered sequence of key: value pairs allowing duplicates) _node.
Node.Pair[] constructPairs(ref Node node) Node.Pair[] constructPairs(ref Node node)
{ {
return getPairs("pairs", node.as!(Node[])); return getPairs("pairs", node.as!(Node[]));
} }
///Construct a set _node. /// Construct a set _node.
Node[] constructSet(ref Node node) Node[] constructSet(ref Node node)
{ {
auto pairs = node.as!(Node.Pair[]); auto pairs = node.as!(Node.Pair[]);
@ -836,13 +822,13 @@ unittest
assert(null is collectException(constructSet(nodeNoDuplicatesLong))); assert(null is collectException(constructSet(nodeNoDuplicatesLong)));
} }
///Construct a sequence (array) _node. /// Construct a sequence (array) _node.
Node[] constructSequence(ref Node node) Node[] constructSequence(ref Node node)
{ {
return node.as!(Node[]); return node.as!(Node[]);
} }
///Construct an unordered map (unordered set of key:value _pairs without duplicates) _node. /// Construct an unordered map (unordered set of key:value _pairs without duplicates) _node.
Node.Pair[] constructMap(ref Node node) Node.Pair[] constructMap(ref Node node)
{ {
auto pairs = node.as!(Node.Pair[]); auto pairs = node.as!(Node.Pair[]);