Changed the Constructor API (for loading of custom types) to
make it easier to load custom classes/structs. Updated API docs, tutorials and examples accordingly.
This commit is contained in:
parent
5547f62176
commit
548480b06b
19 changed files with 371 additions and 396 deletions
|
@ -10,70 +10,63 @@ struct Color
|
|||
ubyte blue;
|
||||
}
|
||||
|
||||
Color constructColorScalar(Mark start, Mark end, string value)
|
||||
Color constructColorScalar(Mark start, Mark end, ref Node node)
|
||||
{
|
||||
if(value.length != 6)
|
||||
{
|
||||
throw new ConstructorException("Invalid color: " ~ value, start, end);
|
||||
}
|
||||
//We don't need to check for uppercase chars this way.
|
||||
value = value.toLower();
|
||||
string value = node.get!string;
|
||||
|
||||
//Get value of a hex digit.
|
||||
uint hex(char c)
|
||||
{
|
||||
if(!std.ascii.isHexDigit(c))
|
||||
{
|
||||
throw new ConstructorException("Invalid color: " ~ value, start, end);
|
||||
}
|
||||
if(value.length != 6)
|
||||
{
|
||||
throw new ConstructorException("Invalid color: " ~ value, start, end);
|
||||
}
|
||||
//We don't need to check for uppercase chars this way.
|
||||
value = value.toLower();
|
||||
|
||||
if(std.ascii.isDigit(c))
|
||||
{
|
||||
return c - '0';
|
||||
}
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
//Get value of a hex digit.
|
||||
uint hex(char c)
|
||||
{
|
||||
if(!std.ascii.isHexDigit(c))
|
||||
{
|
||||
throw new ConstructorException("Invalid color: " ~ value, start, end);
|
||||
}
|
||||
|
||||
Color result;
|
||||
result.red = cast(ubyte)(16 * hex(value[0]) + hex(value[1]));
|
||||
result.green = cast(ubyte)(16 * hex(value[2]) + hex(value[3]));
|
||||
result.blue = cast(ubyte)(16 * hex(value[4]) + hex(value[5]));
|
||||
if(std.ascii.isDigit(c))
|
||||
{
|
||||
return c - '0';
|
||||
}
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
|
||||
return result;
|
||||
Color result;
|
||||
result.red = cast(ubyte)(16 * hex(value[0]) + hex(value[1]));
|
||||
result.green = cast(ubyte)(16 * hex(value[2]) + hex(value[3]));
|
||||
result.blue = cast(ubyte)(16 * hex(value[4]) + hex(value[5]));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Color constructColorMapping(Mark start, Mark end, Node.Pair[] pairs)
|
||||
Color constructColorMapping(Mark start, Mark end, ref Node node)
|
||||
{
|
||||
int r, g, b;
|
||||
r = g = b = -1;
|
||||
bool error = pairs.length != 3;
|
||||
int r,g,b;
|
||||
bool error = false;
|
||||
|
||||
foreach(ref pair; pairs)
|
||||
{
|
||||
//Key might not be a string, and value might not be an int,
|
||||
//so we need to check for that
|
||||
try
|
||||
{
|
||||
switch(pair.key.get!string)
|
||||
{
|
||||
case "r": r = pair.value.get!int; break;
|
||||
case "g": g = pair.value.get!int; break;
|
||||
case "b": b = pair.value.get!int; break;
|
||||
default: error = true;
|
||||
}
|
||||
}
|
||||
catch(NodeException e)
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
//Might throw if a value is missing or is not an integer.
|
||||
try
|
||||
{
|
||||
r = node["r"].get!int;
|
||||
g = node["g"].get!int;
|
||||
b = node["b"].get!int;
|
||||
}
|
||||
catch(NodeException e)
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
|
||||
if(error || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
|
||||
{
|
||||
throw new ConstructorException("Invalid color", start, end);
|
||||
}
|
||||
if(error || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
|
||||
{
|
||||
throw new ConstructorException("Invalid color", start, end);
|
||||
}
|
||||
|
||||
return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b);
|
||||
return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b);
|
||||
}
|
||||
|
||||
void main()
|
||||
|
@ -85,8 +78,8 @@ void main()
|
|||
{
|
||||
auto constructor = new Constructor;
|
||||
//both functions handle the same tag, but one handles scalar, one mapping.
|
||||
constructor.addConstructor("!color", &constructColorScalar);
|
||||
constructor.addConstructor("!color-mapping", &constructColorMapping);
|
||||
constructor.addConstructorScalar("!color", &constructColorScalar);
|
||||
constructor.addConstructorMapping("!color-mapping", &constructColorMapping);
|
||||
|
||||
auto loader = Loader("input.yaml");
|
||||
loader.constructor = constructor;
|
||||
|
|
|
@ -10,70 +10,63 @@ struct Color
|
|||
ubyte blue;
|
||||
}
|
||||
|
||||
Color constructColorScalar(Mark start, Mark end, string value)
|
||||
Color constructColorScalar(Mark start, Mark end, ref Node node)
|
||||
{
|
||||
if(value.length != 6)
|
||||
{
|
||||
throw new ConstructorException("Invalid color: " ~ value, start, end);
|
||||
}
|
||||
//We don't need to check for uppercase chars this way.
|
||||
value = value.toLower();
|
||||
string value = node.get!string;
|
||||
|
||||
//Get value of a hex digit.
|
||||
uint hex(char c)
|
||||
{
|
||||
if(!std.ascii.isHexDigit(c))
|
||||
{
|
||||
throw new ConstructorException("Invalid color: " ~ value, start, end);
|
||||
}
|
||||
if(value.length != 6)
|
||||
{
|
||||
throw new ConstructorException("Invalid color: " ~ value, start, end);
|
||||
}
|
||||
//We don't need to check for uppercase chars this way.
|
||||
value = value.toLower();
|
||||
|
||||
if(std.ascii.isDigit(c))
|
||||
{
|
||||
return c - '0';
|
||||
}
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
//Get value of a hex digit.
|
||||
uint hex(char c)
|
||||
{
|
||||
if(!std.ascii.isHexDigit(c))
|
||||
{
|
||||
throw new ConstructorException("Invalid color: " ~ value, start, end);
|
||||
}
|
||||
|
||||
Color result;
|
||||
result.red = cast(ubyte)(16 * hex(value[0]) + hex(value[1]));
|
||||
result.green = cast(ubyte)(16 * hex(value[2]) + hex(value[3]));
|
||||
result.blue = cast(ubyte)(16 * hex(value[4]) + hex(value[5]));
|
||||
if(std.ascii.isDigit(c))
|
||||
{
|
||||
return c - '0';
|
||||
}
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
|
||||
return result;
|
||||
Color result;
|
||||
result.red = cast(ubyte)(16 * hex(value[0]) + hex(value[1]));
|
||||
result.green = cast(ubyte)(16 * hex(value[2]) + hex(value[3]));
|
||||
result.blue = cast(ubyte)(16 * hex(value[4]) + hex(value[5]));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Color constructColorMapping(Mark start, Mark end, Node.Pair[] pairs)
|
||||
Color constructColorMapping(Mark start, Mark end, ref Node node)
|
||||
{
|
||||
int r, g, b;
|
||||
r = g = b = -1;
|
||||
bool error = pairs.length != 3;
|
||||
int r,g,b;
|
||||
bool error = false;
|
||||
|
||||
foreach(ref pair; pairs)
|
||||
{
|
||||
//Key might not be a string, and value might not be an int,
|
||||
//so we need to check for that
|
||||
try
|
||||
{
|
||||
switch(pair.key.get!string)
|
||||
{
|
||||
case "r": r = pair.value.get!int; break;
|
||||
case "g": g = pair.value.get!int; break;
|
||||
case "b": b = pair.value.get!int; break;
|
||||
default: error = true;
|
||||
}
|
||||
}
|
||||
catch(NodeException e)
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
//Might throw if a value is missing or is not an integer.
|
||||
try
|
||||
{
|
||||
r = node["r"].get!int;
|
||||
g = node["g"].get!int;
|
||||
b = node["b"].get!int;
|
||||
}
|
||||
catch(NodeException e)
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
|
||||
if(error || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
|
||||
{
|
||||
throw new ConstructorException("Invalid color", start, end);
|
||||
}
|
||||
if(error || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
|
||||
{
|
||||
throw new ConstructorException("Invalid color", start, end);
|
||||
}
|
||||
|
||||
return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b);
|
||||
return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b);
|
||||
}
|
||||
|
||||
void main()
|
||||
|
@ -85,8 +78,8 @@ void main()
|
|||
{
|
||||
auto constructor = new Constructor;
|
||||
//both functions handle the same tag, but one handles scalar, one mapping.
|
||||
constructor.addConstructor("!color", &constructColorScalar);
|
||||
constructor.addConstructor("!color-mapping", &constructColorMapping);
|
||||
constructor.addConstructorScalar("!color", &constructColorScalar);
|
||||
constructor.addConstructorMapping("!color-mapping", &constructColorMapping);
|
||||
|
||||
auto resolver = new Resolver;
|
||||
resolver.addImplicitResolver("!color", std.regex.regex("[0-9a-fA-F]{6}"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue