diff --git a/doc/doctrees/environment.pickle b/doc/doctrees/environment.pickle index a65f29a..aab709c 100644 Binary files a/doc/doctrees/environment.pickle and b/doc/doctrees/environment.pickle differ diff --git a/doc/doctrees/tutorials/custom_types.doctree b/doc/doctrees/tutorials/custom_types.doctree index 46a4fd0..056c1d8 100644 Binary files a/doc/doctrees/tutorials/custom_types.doctree and b/doc/doctrees/tutorials/custom_types.doctree differ diff --git a/doc/html/_sources/tutorials/custom_types.txt b/doc/html/_sources/tutorials/custom_types.txt index da62c91..389abdc 100644 --- a/doc/html/_sources/tutorials/custom_types.txt +++ b/doc/html/_sources/tutorials/custom_types.txt @@ -88,29 +88,23 @@ of these functions: Color constructColorMapping(Mark start, Mark end, ref Node node) { - int r,g,b; - bool error = false; - - //Might throw if a value is missing or is not an integer. + ubyte r,g,b; + + //Might throw if a value is missing is not an integer, or is out of range. try { - r = node["r"].get!int; - g = node["g"].get!int; - b = node["b"].get!int; + r = node["r"].get!ubyte; + g = node["g"].get!ubyte; + b = node["b"].get!ubyte; } catch(NodeException e) { - error = true; + throw new ConstructorException("Invalid color: " ~ e.msg, 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); } - + Next, we need some YAML data using our new tag. Create a file called ``input.yaml`` with the following contents: diff --git a/doc/html/api/dyaml.node.html b/doc/html/api/dyaml.node.html index d0f90a3..4788c3e 100644 --- a/doc/html/api/dyaml.node.html +++ b/doc/html/api/dyaml.node.html @@ -280,6 +280,10 @@ conversion is attempted.
+ Numeric values are range checked, throwing if out of range of + requested type. +
+ Timestamps are stored as std.datetime.SysTime. Binary values are decoded and stored as ubyte[].
@@ -308,7 +312,8 @@ Returns:
Value of the node as specified type.
-Throws:
NodeException if unable to convert to specified type.
+Throws:
NodeException if unable to convert to specified type, or if + the value is out of range of requested type.
void getToVar(T)(out T target); diff --git a/doc/html/searchindex.js b/doc/html/searchindex.js index c856169..f016544 100644 --- a/doc/html/searchindex.js +++ b/doc/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({objects:{},terms:{represent:[2,3],all:[1,3,4],code:[0,1,3,4],representmap:3,scalar:[0,1,2,3,4],follow:[3,4],decid:3,depend:[0,3],show:[0,3],readabl:0,specif:[0,1,3,2],representsequ:3,program:4,digit:[3,4],sourc:[3,4],everi:3,string:[0,3,4],powervr:0,"void":[3,4],phobo:1,ident:3,failur:3,yamlexcept:[3,4],implicitli:[0,3],implement:[1,3],tri:1,gender:0,list:[0,1,2],iter:4,"try":[3,4],item:0,refer:[0,3],slower:0,past:4,fold:0,second:[0,4],design:0,pass:3,download:4,rrr:3,even:[1,4],index:[3,4],what:3,appear:1,compar:3,cast:3,preserv:[0,4],section:3,current:4,version:4,"new":3,method:[3,4],dyaml:[1,4],never:1,here:4,ggg:3,ldyaml:4,path:4,modifi:4,sinc:3,valu:[0,1,3,4],convert:[0,3,4],male:0,loos:1,datetim:0,omap:0,chang:[0,1,3],commonli:4,modul:4,unix:4,subnod:4,instal:4,articl:[0,2],regex:3,from:3,would:[3,4],doubl:0,two:[0,1,3],next:[3,4],few:1,call:[3,4],msg:3,type:[0,1,2,3,4],tell:4,more:[0,4],phone:0,known:[1,2,4],hold:3,must:[3,4],addrepresent:3,word:4,alia:[0,1],work:1,itself:3,can:[0,1,3,4],learn:4,purpos:3,root:[3,4],overrid:3,want:3,stream:[0,1],give:4,process:3,templat:3,topic:3,tag:[0,1,3,2],tab:1,serial:[0,3],addconstructorxxx:3,cours:3,multipl:[0,1],newlin:0,quot:[0,1],getting_start:4,how:[3,4],foreach:[3,4],answer:[0,4],instead:0,simpl:[0,3,4],css:3,map:[0,1,2,3,4],mar:4,clone:0,variant:1,befor:3,ff0000:3,uint:3,mai:1,end:[0,1,3],data:[0,1,2,3,4],welcom:[2,4],ani:[0,3,4],stdio:4,explicit:[0,3],correspond:3,ambigu:1,caus:1,inform:[0,4],green:[0,3],allow:[0,1,4],first:[0,2,3,4],order:[1,4],over:4,move:4,orang:3,becaus:1,veri:1,hierarchi:0,still:[0,1],paramet:3,write:4,style:[0,4],precondit:3,yaml:[0,1,2,3,4],window:4,complex:[0,3],main:[3,4],might:[0,1,3,4],easier:0,them:[0,1,3,4],"float":[0,3],"return":[3,4],thei:[0,1,3,4],python:0,auto:3,now:[1,3,4],introduct:[0,4],name:[0,3],separ:0,each:[0,3],found:[3,4],went:3,complet:3,mean:[1,3],compil:[3,4],unequ:[1,3],idea:4,"static":3,expect:[3,4],our:[3,4],extract:4,out:0,space:0,content:[1,3,4],rel:4,"0123456789abcdefabcdef":3,ref:3,red:[0,3],difficulti:1,advanc:0,"0123456789abcdef":3,base:[0,3],dictionari:0,put:[3,4],org:[1,3],"byte":1,thrown:4,pyyaml:[0,1],indent:[0,1],could:[3,4],keep:4,length:3,yamlcoloninflowcontext:1,confus:1,assign:0,radeon:0,oper:[0,3,4],onc:[0,1],arrai:[0,1,3,4],restrict:1,unlik:0,alreadi:[3,4],done:3,stabl:4,miss:3,addconstructormap:3,size:0,differ:[1,2,3,4],dump:[3,4],script:4,associ:[0,1,4],addimplicitresolv:3,system:[0,4],construct:[0,3],gpu:0,white:3,conveni:0,"final":[3,4],store:[0,3],adher:1,consol:4,option:[0,4],especi:0,ishexdigit:3,specifi:[0,3,4],pars:[0,3,4],somewhat:0,exactli:4,than:1,serv:4,remov:0,structur:[0,1],charact:[0,1,3],project:[2,4],str:[0,3],were:3,posit:3,argument:3,packag:[3,4],have:[0,3,4],tabl:0,need:[0,1,3,4],"null":0,lib:4,alias:[0,1,2],constructcolormap:3,note:[3,4],also:[0,3,4],read:[0,3,4],take:3,which:[0,1,3],brace:0,channel:3,uppercas:3,blue:[0,3],begin:[0,1],normal:4,previou:3,most:[0,3,4],regular:3,pair:[0,3],"class":[1,3],opequ:3,don:[1,3,4],later:3,flow:[0,1],doe:[0,1,4],bracket:0,cortex:0,fact:0,ldc:4,cdc:4,alphanumer:1,syntax:[0,2],identifi:[0,3],find:[3,4],onli:[3,4],explicitli:[0,3],just:[3,4],explain:4,should:[1,3,4],meant:4,std:[3,4],get:[2,3,4],express:3,cannot:[1,4],report:3,requir:3,whether:3,common:0,contain:[0,1,3,4],where:[0,3,4],wiki:1,set:[0,2,3,4],seq:0,see:[0,1,3],rgb:3,result:3,fail:1,close:1,athlon:0,representscalar:3,wikipedia:0,written:4,between:[0,1,2],"import":4,altern:3,accord:1,kei:[0,1,4],both:3,last:0,howev:[0,3],equal:3,comment:[0,4],etc:3,tutori:[2,3,4],context:[0,1],load:[1,3,4],bool:[0,3],color:[0,3],hyphen:0,loader:[3,4],colon:0,suppli:3,respect:3,addconstructorscalar:3,bbb:3,empti:0,implicit:[0,3],json:0,basic:4,xxx:[3,4],anywher:0,assert:3,togeth:3,input:[3,4],"catch":3,multi:0,therefor:[1,3],look:4,plain:[0,1,3],ffff00:3,defin:[0,3],ain:0,error:[3,4],anchor:[0,1,2],readi:3,non:[0,3],archiv:4,tediou:3,ascii:[1,3],dumper:[3,4],disabl:3,clearli:1,same:[0,1,3,4],check:[3,4],member:3,binari:0,instanc:[1,3,4],timestamp:0,android:0,document:[0,1,2,3,4],difficult:0,http:1,nest:0,user:[0,3],nodeexcept:3,markup:0,well:3,constructorexcept:3,person:0,exampl:[3,4],command:4,thi:[0,1,3,4],everyth:3,left:0,explan:4,systim:0,newest:4,execut:4,less:1,paragraph:0,gdc:4,human:0,yet:4,languag:[0,4],struct:[1,3,4],libdyaml:4,interptet:1,except:4,constructcolorscalar:3,add:[3,4],other:[1,4],els:0,match:3,build:4,real:0,format:[0,3,4],handl:[1,3],know:3,world:4,recurs:[0,1],tolow:3,like:3,success:3,arbitrari:3,resolv:[0,2,3],integ:[0,3,4],arthur:0,api:[2,3,4],singl:[0,1],output:[3,4],unnecessari:1,right:1,often:3,linux:[0,4],some:[0,1,3,4],guarante:3,ubyt:[0,3],librari:4,representcolor:3,lead:1,though:4,unord:1,condit:3,either:[0,3,4],object:3,run:4,acronym:0,usag:4,immut:3,unicod:1,chapter:0,comparison:3,about:[1,4],rare:1,usedefaultrepresent:3,page:0,constructor:[2,3],fals:3,produc:4,block:0,subset:0,within:1,encod:1,automat:4,bsd:0,mark:[0,1,3],your:[2,3,4],wai:[1,3],support:[0,1,3],question:0,"long":0,custom:[0,2,3],writeln:[3,4],start:[0,2,3,4],"function":3,form:3,continu:0,link:4,line:0,"true":3,conclus:4,"throw":[3,4],dmd:4,consist:0,possibl:[0,1,3,4],"default":[0,3],displai:4,until:0,directori:[3,4],problem:1,similar:[0,4],featur:[0,1],creat:[0,3,4],"int":[0,3,4],cover:4,dure:3,parser:[0,4],doesn:4,repres:[0,3,4],"char":3,exist:4,file:[1,3,4],yamlnul:0,isdigit:3,dent:0,simplest:4,probabl:0,hex:3,when:[3,4],detail:[0,1],invalid:3,valid:1,rrggbb:3,futur:[0,1],test:3,you:[0,3,4],node:[0,3,4],resolut:[0,3],sequenc:[0,2,3,4],consid:[1,3],debian:0,reduc:0,longer:3,home:4,rule:1,hello:4,ignor:1,far:3,escap:0,cpu:0},objtypes:{},titles:["YAML syntax","Differences between D:YAML and the YAML specification","Welcome to D:YAML documentation!","Custom YAML data types","Getting started"],objnames:{},filenames:["tutorials/yaml_syntax","articles/spec_differences","index","tutorials/custom_types","tutorials/getting_started"]}) \ No newline at end of file +Search.setIndex({objects:{},terms:{represent:[2,3],all:[1,3,4],code:[0,1,3,4],representmap:3,scalar:[0,1,2,3,4],follow:[3,4],decid:3,depend:[0,3],show:[0,3],readabl:0,specif:[0,1,3,2],representsequ:3,program:4,digit:[3,4],sourc:[3,4],everi:3,string:[0,3,4],powervr:0,"void":[3,4],phobo:1,ident:3,failur:3,yamlexcept:[3,4],implicitli:[0,3],implement:[1,3],tri:1,gender:0,list:[0,1,2],iter:4,"try":[3,4],item:0,refer:[0,3],slower:0,past:4,fold:0,second:[0,4],design:0,pass:3,download:4,rrr:3,even:[1,4],index:[3,4],what:3,appear:1,compar:3,cast:3,preserv:[0,4],section:3,current:4,version:4,"new":3,method:[3,4],dyaml:[1,4],never:1,here:4,ggg:3,ldyaml:4,path:4,modifi:4,implicit:[0,3],valu:[0,1,3,4],convert:[0,3,4],male:0,loos:1,datetim:0,omap:0,chang:[0,1,3],commonli:4,modul:4,unix:4,subnod:4,instal:4,articl:[0,2],regex:3,from:3,would:[3,4],doubl:0,two:[0,1,3],next:[3,4],few:1,call:[3,4],msg:3,type:[0,1,2,3,4],tell:4,more:[0,4],phone:0,known:[1,2,4],hold:3,must:[3,4],addrepresent:3,word:4,alia:[0,1],work:1,itself:3,can:[0,1,3,4],learn:4,purpos:3,root:[3,4],overrid:3,want:3,stream:[0,1],give:4,process:3,templat:3,topic:3,tag:[0,1,3,2],tab:1,serial:[0,3],addconstructorxxx:3,cours:3,multipl:[0,1],newlin:0,quot:[0,1],getting_start:4,how:[3,4],foreach:[3,4],answer:[0,4],instead:0,simpl:[0,3,4],css:3,map:[0,1,2,3,4],mar:4,clone:0,variant:1,befor:3,ff0000:3,uint:3,mai:1,end:[0,1,3],data:[0,1,2,3,4],welcom:[2,4],ani:[0,3,4],stdio:4,explicit:[0,3],correspond:3,ambigu:1,caus:1,inform:[0,4],green:[0,3],allow:[0,1,4],first:[0,2,3,4],order:[1,4],over:4,move:4,orang:3,becaus:1,veri:1,hierarchi:0,still:[0,1],paramet:3,write:4,style:[0,4],precondit:3,yaml:[0,1,2,3,4],window:4,complex:[0,3],main:[3,4],might:[0,1,3,4],easier:0,them:[0,1,3,4],"float":[0,3],"return":[3,4],thei:[0,1,3,4],python:0,auto:3,now:[1,3,4],introduct:[0,4],name:[0,3],separ:0,each:[0,3],found:[3,4],went:3,complet:3,mean:[1,3],compil:[3,4],unequ:[1,3],idea:4,"static":3,expect:[3,4],our:[3,4],extract:4,out:[0,3],space:0,content:[1,3,4],rel:4,"0123456789abcdefabcdef":3,ref:3,red:[0,3],difficulti:1,advanc:0,"0123456789abcdef":3,base:[0,3],dictionari:0,put:[3,4],org:[1,3],"byte":1,thrown:4,pyyaml:[0,1],indent:[0,1],could:[3,4],keep:4,length:3,yamlcoloninflowcontext:1,confus:1,assign:0,radeon:0,oper:[0,3,4],rang:3,onc:[0,1],arrai:[0,1,3,4],restrict:1,unlik:0,alreadi:[3,4],done:3,stabl:4,miss:3,addconstructormap:3,size:0,differ:[1,2,3,4],dump:[3,4],script:4,associ:[0,1,4],addimplicitresolv:3,system:[0,4],construct:[0,3],gpu:0,white:3,conveni:0,"final":[3,4],store:[0,3],adher:1,consol:4,option:[0,4],especi:0,ishexdigit:3,specifi:[0,3,4],pars:[0,3,4],somewhat:0,exactli:4,than:1,serv:4,remov:0,structur:[0,1],charact:[0,1,3],project:[2,4],str:[0,3],were:3,posit:3,argument:3,packag:[3,4],have:[0,3,4],tabl:0,need:[0,1,3,4],"null":0,lib:4,alias:[0,1,2],constructcolormap:3,note:[3,4],also:[0,3,4],read:[0,3,4],take:3,which:[0,1,3],brace:0,channel:3,uppercas:3,blue:[0,3],begin:[0,1],normal:4,previou:3,most:[0,3,4],regular:3,pair:[0,3],"class":[1,3],opequ:3,don:[1,3,4],later:3,flow:[0,1],doe:[0,1,4],bracket:0,cortex:0,fact:0,ldc:4,cdc:4,alphanumer:1,syntax:[0,2],identifi:[0,3],find:[3,4],onli:[3,4],explicitli:[0,3],just:[3,4],explain:4,should:[1,3,4],meant:4,std:[3,4],get:[2,3,4],express:3,cannot:[1,4],report:3,requir:3,whether:3,common:0,contain:[0,1,3,4],where:[0,3,4],wiki:1,set:[0,2,3,4],seq:0,see:[0,1,3],rgb:3,result:3,fail:1,close:1,athlon:0,representscalar:3,wikipedia:0,written:4,between:[0,1,2],"import":4,altern:3,accord:1,kei:[0,1,4],both:3,last:0,howev:[0,3],equal:3,comment:[0,4],etc:3,tutori:[2,3,4],context:[0,1],load:[1,3,4],color:[0,3],hyphen:0,loader:[3,4],colon:0,suppli:3,respect:3,addconstructorscalar:3,bbb:3,empti:0,sinc:3,json:0,basic:4,xxx:[3,4],anywher:0,assert:3,togeth:3,input:[3,4],"catch":3,multi:0,therefor:[1,3],look:4,plain:[0,1,3],ffff00:3,defin:[0,3],ain:0,error:4,anchor:[0,1,2],readi:3,non:[0,3],archiv:4,tediou:3,ascii:[1,3],dumper:[3,4],disabl:3,clearli:1,same:[0,1,3,4],check:[3,4],member:3,binari:0,instanc:[1,3,4],timestamp:0,android:0,document:[0,1,2,3,4],difficult:0,http:1,nest:0,user:[0,3],nodeexcept:3,markup:0,well:3,constructorexcept:3,person:0,exampl:[3,4],command:4,thi:[0,1,3,4],everyth:3,left:0,explan:4,systim:0,newest:4,execut:4,less:1,paragraph:0,gdc:4,human:0,yet:4,languag:[0,4],struct:[1,3,4],libdyaml:4,interptet:1,except:4,constructcolorscalar:3,add:[3,4],other:[1,4],els:0,match:3,build:4,real:0,format:[0,3,4],handl:[1,3],know:3,world:4,recurs:[0,1],tolow:3,like:3,success:3,arbitrari:3,resolv:[0,2,3],integ:[0,3,4],arthur:0,api:[2,3,4],singl:[0,1],output:[3,4],unnecessari:1,right:1,often:3,linux:[0,4],some:[0,1,3,4],guarante:3,ubyt:[0,3],librari:4,representcolor:3,lead:1,though:4,unord:1,condit:3,either:[0,3,4],object:3,run:4,acronym:0,usag:4,immut:3,rrggbb:3,unicod:1,chapter:0,comparison:3,about:[1,4],rare:1,usedefaultrepresent:3,page:0,constructor:[2,3],fals:3,produc:4,block:0,subset:0,within:1,encod:1,automat:4,bsd:0,mark:[0,1,3],your:[2,3,4],wai:[1,3],support:[0,1,3],question:0,"long":0,custom:[0,2,3],writeln:[3,4],start:[0,2,3,4],"function":3,form:3,continu:0,link:4,line:0,conclus:4,"throw":[3,4],dmd:4,consist:0,possibl:[0,1,3,4],"default":[0,3],displai:4,until:0,directori:[3,4],problem:1,similar:[0,4],featur:[0,1],creat:[0,3,4],"int":[0,3,4],cover:4,dure:3,parser:[0,4],doesn:4,repres:[0,3,4],"char":3,exist:4,file:[1,3,4],yamlnul:0,isdigit:3,dent:0,simplest:4,probabl:0,hex:3,when:[3,4],detail:[0,1],invalid:3,valid:1,bool:0,futur:[0,1],test:3,you:[0,3,4],node:[0,3,4],resolut:[0,3],sequenc:[0,2,3,4],consid:[1,3],debian:0,reduc:0,longer:3,home:4,rule:1,hello:4,ignor:1,far:3,escap:0,cpu:0},objtypes:{},titles:["YAML syntax","Differences between D:YAML and the YAML specification","Welcome to D:YAML documentation!","Custom YAML data types","Getting started"],objnames:{},filenames:["tutorials/yaml_syntax","articles/spec_differences","index","tutorials/custom_types","tutorials/getting_started"]}) \ No newline at end of file diff --git a/doc/html/tutorials/custom_types.html b/doc/html/tutorials/custom_types.html index f83e737..c7a0c4c 100644 --- a/doc/html/tutorials/custom_types.html +++ b/doc/html/tutorials/custom_types.html @@ -121,24 +121,18 @@ of these functions:

Color constructColorMapping(Mark start, Mark end, ref Node node) { - int r,g,b; - bool error = false; + ubyte r,g,b; - //Might throw if a value is missing or is not an integer. + //Might throw if a value is missing is not an integer, or is out of range. try { - r = node["r"].get!int; - g = node["g"].get!int; - b = node["b"].get!int; + r = node["r"].get!ubyte; + g = node["g"].get!ubyte; + b = node["b"].get!ubyte; } 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); + throw new ConstructorException("Invalid color: " ~ e.msg, start, end); } return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b); diff --git a/docsrc/tutorials/custom_types.rst b/docsrc/tutorials/custom_types.rst index da62c91..389abdc 100644 --- a/docsrc/tutorials/custom_types.rst +++ b/docsrc/tutorials/custom_types.rst @@ -88,29 +88,23 @@ of these functions: Color constructColorMapping(Mark start, Mark end, ref Node node) { - int r,g,b; - bool error = false; - - //Might throw if a value is missing or is not an integer. + ubyte r,g,b; + + //Might throw if a value is missing is not an integer, or is out of range. try { - r = node["r"].get!int; - g = node["g"].get!int; - b = node["b"].get!int; + r = node["r"].get!ubyte; + g = node["g"].get!ubyte; + b = node["b"].get!ubyte; } catch(NodeException e) { - error = true; + throw new ConstructorException("Invalid color: " ~ e.msg, 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); } - + Next, we need some YAML data using our new tag. Create a file called ``input.yaml`` with the following contents: diff --git a/dyaml/node.d b/dyaml/node.d index f11b058..9e52261 100644 --- a/dyaml/node.d +++ b/dyaml/node.d @@ -456,6 +456,9 @@ struct Node * If the specifed type does not match type in the node, * conversion is attempted. * + * Numeric values are range checked, throwing if out of range of + * requested type. + * * Timestamps are stored as std.datetime.SysTime. * Binary values are decoded and stored as ubyte[]. * @@ -483,7 +486,8 @@ struct Node * * Returns: Value of the node as specified type. * - * Throws: NodeException if unable to convert to specified type. + * Throws: NodeException if unable to convert to specified type, or if + * the value is out of range of requested type. */ @property T get(T)() { diff --git a/examples/constructor/main.d b/examples/constructor/main.d index a80c0d7..c8fe62e 100644 --- a/examples/constructor/main.d +++ b/examples/constructor/main.d @@ -46,24 +46,18 @@ Color constructColorScalar(Mark start, Mark end, ref Node node) Color constructColorMapping(Mark start, Mark end, ref Node node) { - int r,g,b; - bool error = false; + ubyte r,g,b; - //Might throw if a value is missing or is not an integer. + //Might throw if a value is missing is not an integer, or is out of range. try { - r = node["r"].get!int; - g = node["g"].get!int; - b = node["b"].get!int; + r = node["r"].get!ubyte; + g = node["g"].get!ubyte; + b = node["b"].get!ubyte; } 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); + throw new ConstructorException("Invalid color: " ~ e.msg, start, end); } return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b); diff --git a/examples/resolver/main.d b/examples/resolver/main.d index b80b1e4..5cac6ab 100644 --- a/examples/resolver/main.d +++ b/examples/resolver/main.d @@ -46,24 +46,18 @@ Color constructColorScalar(Mark start, Mark end, ref Node node) Color constructColorMapping(Mark start, Mark end, ref Node node) { - int r,g,b; - bool error = false; + ubyte r,g,b; - //Might throw if a value is missing or is not an integer. + //Might throw if a value is missing is not an integer, or is out of range. try { - r = node["r"].get!int; - g = node["g"].get!int; - b = node["b"].get!int; + r = node["r"].get!ubyte; + g = node["g"].get!ubyte; + b = node["b"].get!ubyte; } 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); + throw new ConstructorException("Invalid color: " ~ e.msg, start, end); } return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b);