Skip to content

Commit 4e61dce

Browse files
committed
Date support, compatible up to TOML 0.4
1 parent aa00dba commit 4e61dce

3 files changed

Lines changed: 29 additions & 4 deletions

File tree

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ auto config = parseFile("/path/to/toml.conf");
3636
TODO
3737
--------------
3838

39-
1) Date support
40-
2) Tables in tables
39+
1) Tables in tables
4140

4241

source/toml/grammar.d

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ TOML:
4747
# DateTime
4848
# -------------------------------------------
4949
50-
DatetimeValue <~ ([1-9] digit digit digit) "-" (digit digit) "-" (digit digit) "T" (digit digit) ":" (digit digit) ":" (digit digit) "Z"
50+
DatetimeValue <~ ([1-9] digit digit digit) "-" (digit digit) "-" (digit digit)
51+
"T" (digit digit) ":" (digit digit) ":" (digit digit)
52+
("." digit digit digit digit digit digit)?
53+
(("-" / "+") (digit digit) ":" (digit digit) / "Z")?
5154
5255
#
5356
# Boolean
@@ -186,6 +189,8 @@ unittest {
186189
key_string_array = ["abc","cde"]
187190
arrayOfArrays = [[1,2], ["a","b"], [1.2, 1.2]]
188191
date = 1979-05-27T07:32:00Z
192+
date_two = 1979-05-27T00:32:00-07:00
193+
anotherdate = 1979-05-27T00:32:00.999999-07:00
189194
multistring = "
190195
hello \tworld
191196
this is a big

source/toml/parser.d

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module toml.parser;
33
import toml.grammar;
44
import pegged.grammar;
55
import std.array: split;
6+
import std.datetime : SysTime;
67
import std.exception;
78
import std.file : readText;
89

@@ -58,7 +59,13 @@ struct TOMLValue {
5859
_store.floatv = val;
5960
_type = TOMLType.Float;
6061
}
61-
else
62+
else static if ( is(T: SysTime) ) {
63+
// Hack: store the datetime in string representation, SysTime
64+
// cannot be part of Store as it has no default initializer
65+
_store.stringv = val.toISOExtString();
66+
_type = TOMLType.Datetime;
67+
}
68+
else
6269
static assert(0, "Unknown type");
6370

6471
}
@@ -143,6 +150,11 @@ struct TOMLValue {
143150
return _store.boolv;
144151
}
145152

153+
SysTime datetime() {
154+
enforceTOML(_type==TOMLType.Datetime);
155+
return SysTime.fromISOExtString(_store.stringv);
156+
}
157+
146158
TOMLValue[] array() {
147159
enforceTOML(_type==TOMLType.Array);
148160
return _store.arrayv;
@@ -173,6 +185,9 @@ void _toTOMLDictionary(ParseTree p, ref TOMLValue root, string current_header=nu
173185
return TOMLValue(v.to!float);
174186
case "TOML.BooleanValue":
175187
return TOMLValue(v.to!bool);
188+
case "TOML.DatetimeValue":
189+
// We need to add a time for date-only values for fromISOExtString
190+
return TOMLValue(SysTime.fromISOExtString(v.to!string));
176191
case "TOML.Array":
177192
TOMLValue[] vals;
178193
//first children is the typed array match
@@ -232,16 +247,19 @@ TOMLValue parseFile(string filename) {
232247
}
233248

234249
unittest {
250+
import std.datetime: DateTime, UTC;
235251
import std.stdio;
236252

237253
enum TEST1 = `
238254
key_string = "string_value"
239255
key_array = ["string_1", "string_2"]
240256
float_value = 17.23
241257
258+
242259
[servers]
243260
a = 12
244261
managed = true
262+
last_reboot = 2011-02-23T22:11:43Z
245263
246264
[servers.test]
247265
a = 12
@@ -257,6 +275,9 @@ unittest {
257275
writefln("All: %s", d.keys);
258276
assert(d["servers"]["a"].integer == 12);
259277
assert(d["servers"]["managed"].boolean == true);
278+
writefln("last_reboot: %s", d["servers"]["last_reboot"].datetime.toISOExtString);
279+
assert(d["servers"]["last_reboot"].datetime ==
280+
SysTime(DateTime(2011, 2, 23, 22, 11, 43), UTC()));
260281
assert(d["servers"]["test"]["a"].integer == 12);
261282
assert(d["servers"]["test"]["ports"].array[0].integer == 1);
262283
assert(d["servers"]["test"]["ports"].array[2].integer == 3);

0 commit comments

Comments
 (0)