///|
/// Conversion from a parsed `Table` to the tagged JSON format used by the
/// official `toml-test` conformance suite. Primitive values are tagged with
/// their TOML type; tables and arrays map to plain JSON objects and arrays.
///|
/// Converts a table to the toml-test tagged JSON representation.
pub fn to_json(table : Table) -> Json {
table_to_json(table)
}
///|
fn table_to_json(table : Table) -> Json {
let object : Map[String, Json] = Map([])
for key, value in table {
object.set(key, value_to_json(value))
}
Json::object(object)
}
///|
fn value_to_json(value : Value) -> Json {
match value {
String(s) => tagged("string", s)
Integer(i) => tagged("integer", i.to_string())
Float(f) => tagged("float", format_float(f))
Boolean(b) => tagged("bool", if b { "true" } else { "false" })
OffsetDateTime(dt) => tagged("datetime", format_offset_datetime(dt))
LocalDateTime(dt) => tagged("datetime-local", format_local_datetime(dt))
LocalDate(d) => tagged("date-local", format_date(d))
LocalTime(t) => tagged("time-local", format_time(t))
Array(arr) => {
let items : Array[Json] = []
for v in arr {
items.push(value_to_json(v))
}
Json::array(items)
}
Table(t) => table_to_json(t)
}
}
///|
fn tagged(kind : String, value : String) -> Json {
let object : Map[String, Json] = Map([])
object.set("type", Json::string(kind))
object.set("value", Json::string(value))
Json::object(object)
}
///|
fn format_offset_datetime(dt : OffsetDateTime) -> String {
format_date(dt.date) +
"T" +
format_time(dt.time) +
format_offset(dt.offset_minutes)
}
///|
fn format_local_datetime(dt : LocalDateTime) -> String {
format_date(dt.date) + "T" + format_time(dt.time)
}