1 // Written in the D programming language.
2 
3 /**
4  * 
5  * Conversion between JSON and TOML.
6  *
7  * License: $(HTTP https://github.com/Kripth/toml/blob/master/LICENSE, MIT)
8  * Authors: Kripth
9  * References: $(LINK https://github.com/toml-lang/toml/blob/master/conv-json/README.md)
10  * Source: $(HTTP https://github.com/Kripth/toml/blob/master/src/conv-json/src/toml/json.d, toml/conv/_json.d)
11  * 
12  */
13 module toml.json;
14 
15 import std.json : JSONValue, JSON_TYPE;
16 
17 import toml.toml : TOMLDocument, TOMLValue, TOML_TYPE, TOMLException;
18 
19 /**
20  * Converts a TOMLValue to a JSONValue.
21  * Note: datetimes are converted to strings.
22  */
23 JSONValue toJSON(TOMLValue toml) {
24 	final switch(toml.type) with(TOML_TYPE) {
25 		case STRING: return JSONValue(toml.str);
26 		case INTEGER: return JSONValue(toml.integer);
27 		case FLOAT: return JSONValue(toml.floating);
28 		case OFFSET_DATETIME: return JSONValue(toml.offsetDatetime.toISOExtString());
29 		case LOCAL_DATETIME: return JSONValue(toml.localDatetime.toISOExtString());
30 		case LOCAL_DATE: return JSONValue(toml.localDate.toISOExtString());
31 		case LOCAL_TIME: return JSONValue(toml.localTime.toISOExtString());
32 		case ARRAY:
33 			JSONValue[] ret;
34 			foreach(value ; toml.array) {
35 				ret ~= toJSON(value);
36 			}
37 			return JSONValue(ret);
38 		case TABLE:
39 			JSONValue[string] ret;
40 			foreach(key, value; toml.table) {
41 				ret[key] = toJSON(value);
42 			}
43 			return JSONValue(ret);
44 		case TRUE: return JSONValue(true);
45 		case FALSE: return JSONValue(false);
46 	}
47 }
48 
49 /// ditto
50 JSONValue toJSON(TOMLDocument doc) {
51 	return toJSON(TOMLValue(doc.table));
52 }
53 
54 ///
55 unittest {
56 
57 	import std.datetime : SysTime, Date;
58 	import toml.datetime : DateTime, TimeOfDay;
59 
60 	assert(toJSON(TOMLValue("string")).str == "string");
61 	assert(toJSON(TOMLValue(42)) == JSONValue(42));
62 	assert(toJSON(TOMLValue(.1)) == JSONValue(.1));
63 	assert(toJSON(TOMLValue(SysTime.fromISOExtString("1979-05-27T07:32:00Z"))).str == "1979-05-27T07:32:00Z");
64 	assert(toJSON(TOMLValue(DateTime.fromISOExtString("1979-05-27T07:32:00"))).str == "1979-05-27T07:32:00");
65 	assert(toJSON(TOMLValue(Date.fromISOExtString("1979-05-27"))).str == "1979-05-27");
66 	assert(toJSON(TOMLValue(TimeOfDay.fromISOExtString("07:32:00"))).str == "07:32:00");
67 	assert(toJSON(TOMLValue([1, 2, 3])) == JSONValue([1, 2, 3]));
68 	assert(toJSON(TOMLDocument(["a": TOMLValue(0), "b": TOMLValue(1)])) == JSONValue(["a": 0, "b": 1]));
69 	assert(toJSON(TOMLValue(true)).type == JSON_TYPE.TRUE);
70 	assert(toJSON(TOMLValue(false)).type == JSON_TYPE.FALSE);
71 	
72 }
73 
74 /**
75  * Convert a JSONValue to a TOMLValue.
76  * Throws:
77  * 		TOMLException if the array values have different types
78  * 		TOMLExcpetion if a floating point value is not finite
79  * 		TOMLException if the json value is null
80  */
81 TOMLValue toTOML(JSONValue json) {
82 	final switch(json.type) with(JSON_TYPE) {
83 		case NULL: throw new TOMLException("JSONValue is null");
84 		case TRUE: return TOMLValue(true);
85 		case FALSE: return TOMLValue(false);
86 		case STRING: return TOMLValue(json.str);
87 		case INTEGER: return TOMLValue(json.integer);
88 		case UINTEGER: return TOMLValue(cast(long)json.uinteger);
89 		case FLOAT: return TOMLValue(json.floating);
90 		case ARRAY:
91 			TOMLValue[] ret;
92 			foreach(value ; json.array) {
93 				ret ~= toTOML(value);
94 			}
95 			return TOMLValue(ret);
96 		case OBJECT:
97 			TOMLValue[string] ret;
98 			foreach(key, value; json.object) {
99 				ret[key] = toTOML(value);
100 			}
101 			return TOMLValue(ret);
102 	}
103 }
104 
105 ///
106 unittest {
107 
108 	try {
109 		// null
110 		toTOML(JSONValue.init); assert(0);
111 	} catch(TOMLException) {}
112 
113 	assert(toTOML(JSONValue(true)).type == TOML_TYPE.TRUE);
114 	assert(toTOML(JSONValue(false)) == false);
115 	assert(toTOML(JSONValue("test")) == "test");
116 	assert(toTOML(JSONValue(42)) == 42);
117 	assert(toTOML(JSONValue(ulong.max)) == -1);
118 	assert(toTOML(JSONValue(.1)) == .1);
119 	assert(toTOML(JSONValue([1, 2, 3])) == [1, 2, 3]);
120 	assert(toTOML(JSONValue(["a": 1, "b": 2])) == ["a": 1, "b": 2]);
121 
122 }