Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.dub
__*
*.a
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
=======
toml.d. A TOML Parser for D
============================

Expand Down Expand Up @@ -36,7 +35,6 @@ auto config = parseFile("/path/to/toml.conf");
TODO
--------------

1) Date support
2) Tables in tables
1) Tables in tables


2 changes: 1 addition & 1 deletion dub.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
"license": "BSL-1.0",
"targetType" : "library",
"dependencies": {
"pegged": "0.2.1"
"pegged": "~>0.3.3"
}
}
7 changes: 6 additions & 1 deletion source/toml/grammar.d
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ TOML:
# DateTime
# -------------------------------------------
DatetimeValue <~ ([1-9] digit digit digit) "-" (digit digit) "-" (digit digit) "T" (digit digit) ":" (digit digit) ":" (digit digit) "Z"
DatetimeValue <~ ([1-9] digit digit digit) "-" (digit digit) "-" (digit digit)
"T" (digit digit) ":" (digit digit) ":" (digit digit)
("." digit digit digit digit digit digit)?
(("-" / "+") (digit digit) ":" (digit digit) / "Z")?
#
# Boolean
Expand Down Expand Up @@ -186,6 +189,8 @@ unittest {
key_string_array = ["abc","cde"]
arrayOfArrays = [[1,2], ["a","b"], [1.2, 1.2]]
date = 1979-05-27T07:32:00Z
date_two = 1979-05-27T00:32:00-07:00
anotherdate = 1979-05-27T00:32:00.999999-07:00
multistring = "
hello \tworld
this is a big
Expand Down
54 changes: 46 additions & 8 deletions source/toml/parser.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ module toml.parser;
import toml.grammar;
import pegged.grammar;
import std.array: split;
import std.datetime : SysTime;
import std.exception;
import std.file : readText;
import std.conv : to;

enum TOMLType {
String,
Expand All @@ -29,7 +31,7 @@ struct TOMLValue {
union Store {
string stringv;
long intv;
float floatv;
double floatv;
bool boolv;
TOMLValue[] arrayv;
TOMLValue[string] keygroups;
Expand All @@ -44,20 +46,27 @@ struct TOMLValue {
static if( is(T: string) ) {
_store.stringv = val;
_type = TOMLType.String;
}
else static if ( is(T: long) ) {
_store.intv = val;
_type = TOMLType.Integer;
}
// bool needs to to be assigned before long, because long eats bool!
else static if ( is(T: bool) ) {
_store.boolv = val;
_type = TOMLType.Boolean;
}
else static if ( is(T: float) ) {
else static if ( is(T: long) ) {
_store.intv = val;
_type = TOMLType.Integer;
}
else static if ( is(T: double) ) {
_store.floatv = val;
_type = TOMLType.Float;
}
else
else static if ( is(T: SysTime) ) {
// Hack: store the datetime in string representation, SysTime
// cannot be part of Store as it has no default initializer
_store.stringv = val.toISOExtString();
_type = TOMLType.Datetime;
}
else
static assert(0, "Unknown type");

}
Expand Down Expand Up @@ -132,6 +141,21 @@ struct TOMLValue {
return _store.intv;
}

double floating() {
enforceTOML(_type==TOMLType.Float);
return _store.floatv;
}

bool boolean() {
enforceTOML(_type==TOMLType.Boolean);
return _store.boolv;
}

SysTime datetime() {
enforceTOML(_type==TOMLType.Datetime);
return SysTime.fromISOExtString(_store.stringv);
}

TOMLValue[] array() {
enforceTOML(_type==TOMLType.Array);
return _store.arrayv;
Expand Down Expand Up @@ -159,9 +183,11 @@ void _toTOMLDictionary(ParseTree p, ref TOMLValue root, string current_header=nu
case "TOML.StringValue":
return TOMLValue(v.to!string);
case "TOML.FloatValue":
return TOMLValue(v.to!float);
return TOMLValue(v.to!double);
case "TOML.BooleanValue":
return TOMLValue(v.to!bool);
case "TOML.DatetimeValue":
return TOMLValue(SysTime.fromISOExtString(v.to!string));
case "TOML.Array":
TOMLValue[] vals;
//first children is the typed array match
Expand Down Expand Up @@ -221,27 +247,39 @@ TOMLValue parseFile(string filename) {
}

unittest {
import std.datetime: DateTime, UTC;
import std.stdio;

enum TEST1 = `
key_string = "string_value"
key_array = ["string_1", "string_2"]
float_value = 17.23

[servers]
a = 12
managed = true
last_reboot = 2011-02-23T22:11:43Z

[servers.test]
a = 12
ports = [1,2,3]
operational = false
`;

auto d = parse(TEST1);

assert(d["key_string"].str == "string_value");
assert(d["float_value"].floating == 17.23f);
writefln("Servers: %s", d["servers"].keys);
writefln("All: %s", d.keys);
assert(d["servers"]["a"].integer == 12);
assert(d["servers"]["managed"].boolean == true);
writefln("last_reboot: %s", d["servers"]["last_reboot"].datetime.toISOExtString);
assert(d["servers"]["last_reboot"].datetime ==
SysTime(DateTime(2011, 2, 23, 22, 11, 43), UTC()));
assert(d["servers"]["test"]["a"].integer == 12);
assert(d["servers"]["test"]["ports"].array[0].integer == 1);
assert(d["servers"]["test"]["ports"].array[2].integer == 3);
assert(d["servers"]["test"]["operational"].boolean == false);

}