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 {
25 	final switch (toml.type) with (TOML_TYPE)
26 	{
27 	case STRING:
28 		return JSONValue(toml.str);
29 	case INTEGER:
30 		return JSONValue(toml.integer);
31 	case FLOAT:
32 		return JSONValue(toml.floating);
33 	case OFFSET_DATETIME:
34 		return JSONValue(toml.offsetDatetime.toISOExtString());
35 	case LOCAL_DATETIME:
36 		return JSONValue(toml.localDatetime.toISOExtString());
37 	case LOCAL_DATE:
38 		return JSONValue(toml.localDate.toISOExtString());
39 	case LOCAL_TIME:
40 		return JSONValue(toml.localTime.toISOExtString());
41 	case ARRAY:
42 		JSONValue[] ret;
43 		foreach (value; toml.array)
44 		{
45 			ret ~= toJSON(value);
46 		}
47 		return JSONValue(ret);
48 	case TABLE:
49 		JSONValue[string] ret;
50 		foreach (key, value; toml.table)
51 		{
52 			ret[key] = toJSON(value);
53 		}
54 		return JSONValue(ret);
55 	case TRUE:
56 		return JSONValue(true);
57 	case FALSE:
58 		return JSONValue(false);
59 	}
60 }
61 
62 /// ditto
63 JSONValue toJSON(TOMLDocument doc)
64 {
65 	return toJSON(TOMLValue(doc.table));
66 }
67 
68 ///
69 unittest
70 {
71 
72 	import std.datetime : SysTime, Date;
73 	import toml.datetime : DateTime, TimeOfDay;
74 
75 	assert(toJSON(TOMLValue("string")).str == "string");
76 	assert(toJSON(TOMLValue(42)) == JSONValue(42));
77 	assert(toJSON(TOMLValue(.1)) == JSONValue(.1));
78 	assert(toJSON(TOMLValue(SysTime.fromISOExtString("1979-05-27T07:32:00Z")))
79 			.str == "1979-05-27T07:32:00Z");
80 	assert(toJSON(TOMLValue(DateTime.fromISOExtString("1979-05-27T07:32:00")))
81 			.str == "1979-05-27T07:32:00");
82 	assert(toJSON(TOMLValue(Date.fromISOExtString("1979-05-27"))).str == "1979-05-27");
83 	assert(toJSON(TOMLValue(TimeOfDay.fromISOExtString("07:32:00"))).str == "07:32:00");
84 	assert(toJSON(TOMLValue([1, 2, 3])) == JSONValue([1, 2, 3]));
85 	assert(toJSON(TOMLDocument(["a" : TOMLValue(0), "b" : TOMLValue(1)])) == JSONValue(["a"
86 			: 0, "b" : 1]));
87 	assert(toJSON(TOMLValue(true)).type == JSON_TYPE.TRUE);
88 	assert(toJSON(TOMLValue(false)).type == JSON_TYPE.FALSE);
89 
90 }
91 
92 /**
93  * Convert a JSONValue to a TOMLValue.
94  * Throws:
95  * 		TOMLException if the array values have different types
96  * 		TOMLExcpetion if a floating point value is not finite
97  * 		TOMLException if the json value is null
98  */
99 TOMLValue toTOML(JSONValue json)
100 {
101 	final switch (json.type) with (JSON_TYPE)
102 	{
103 	case NULL:
104 		throw new TOMLException("JSONValue is null");
105 	case TRUE:
106 		return TOMLValue(true);
107 	case FALSE:
108 		return TOMLValue(false);
109 	case STRING:
110 		return TOMLValue(json.str);
111 	case INTEGER:
112 		return TOMLValue(json.integer);
113 	case UINTEGER:
114 		return TOMLValue(cast(long) json.uinteger);
115 	case FLOAT:
116 		return TOMLValue(json.floating);
117 	case ARRAY:
118 		TOMLValue[] ret;
119 		foreach (value; json.array)
120 		{
121 			ret ~= toTOML(value);
122 		}
123 		return TOMLValue(ret);
124 	case OBJECT:
125 		TOMLValue[string] ret;
126 		foreach (key, value; json.object)
127 		{
128 			ret[key] = toTOML(value);
129 		}
130 		return TOMLValue(ret);
131 	}
132 }
133 
134 ///
135 unittest
136 {
137 
138 	try
139 	{
140 		// null
141 		toTOML(JSONValue.init);
142 		assert(0);
143 	}
144 	catch (TOMLException)
145 	{
146 	}
147 
148 	assert(toTOML(JSONValue(true)).type == TOML_TYPE.TRUE);
149 	assert(toTOML(JSONValue(false)) == false);
150 	assert(toTOML(JSONValue("test")) == "test");
151 	assert(toTOML(JSONValue(42)) == 42);
152 	assert(toTOML(JSONValue(ulong.max)) == -1);
153 	assert(toTOML(JSONValue(.1)) == .1);
154 	assert(toTOML(JSONValue([1, 2, 3])) == [1, 2, 3]);
155 	assert(toTOML(JSONValue(["a" : 1, "b" : 2])) == ["a" : 1, "b" : 2]);
156 
157 }