Explicit / Non-lexicographical sorting when serializing?
Raildex opened this issue · 5 comments
Is your feature request related to a problem? Please describe.
I am using TOML++ for serializing settings. The output file however has fields in alphabetical order and not in the order I add them to the toml::table
initializer_list
constructor.
Describe the solution you'd like
Either Serializing in the order the key-value pairs arrive in the table or explicit numbering
Additional context
Table serialization (snippet)
{"graphics", toml::table{
{"windowed",s.graphics.windowed},
{"refresh_rate",int(s.graphics.refresh_rate)},
{"width",int(s.graphics.resolution_width)},
{"height",int(s.graphics.resolution_height)},
{"animation",int(s.graphics.animation)},
{"fog",int(s.graphics.fog)},
{"lighting",int(s.graphics.lighting)},
{"particle",int(s.graphics.particle)},
{"post-processing",int(s.graphics.post_processing)},
{"reflection",int(s.graphics.reflection)},
{"texture",int(s.graphics.texture)},
{"shadow",int(s.graphics.shadow)},
}}
Resulting TOML, notice how width
, height
, refresh_rate
and windowed
are scattered, despite being next to each other in the serialization:
[graphics]
animation = 2
fog = 2
height = 576
lighting = 2
particle = 2
post-processing = 2
reflection = 2
refresh_rate = 30
shadow = 2
texture = 2
width = 1024
windowed = true
This happens because TOML++ uses std::map under the hood to make use of C++17's heterogeneous lookup. In order to change this, the underlying map type would need to change, which is obviously a big ask (any drop-in replacement needs to satisfy the full interface).
Considering the TOML spec doesn't specify that key ordering needs to be maintained during serialisation round-trips, you're likely to have this (or similar) problems with different implementations too; if you want similar keys to be grouped together, could you not simply use tighter grouping in your schema? For example, put width
and height
as subkeys of a size
key, e.g:
size.width = 1024
size.height = 768
When I use the following:
{"graphics", toml::table{
{"display.windowed",s.graphics.windowed},
{"display.refresh_rate",int(s.graphics.refresh_rate)},
{"display.resolution.width",int(s.graphics.resolution_width)},
{"display.resolution.height",int(s.graphics.resolution_height)},
{"quality.animation",int(s.graphics.animation)},
{"quality.fog",int(s.graphics.fog)},
{"quality.lighting",int(s.graphics.lighting)},
{"quality.particle",int(s.graphics.particle)},
{"quality.post-processing",int(s.graphics.post_processing)},
{"quality.reflection",int(s.graphics.reflection)},
{"quality.texture",int(s.graphics.texture)},
{"quality.shadow",int(s.graphics.shadow)},
}},
The resulting TOML contains single-quotes around keys:
[graphics]
'display.refresh_rate' = 30
'display.resolution.height' = 450
'display.resolution.width' = 800
'display.windowed' = true
'quality.animation' = 2
'quality.fog' = 2
'quality.lighting' = 2
'quality.particle' = 2
'quality.post-processing' = 2
'quality.reflection' = 2
'quality.shadow' = 2
'quality.texture' = 2
Which is correct; by putting the dots in the keys, you're telling TOML++ you literally want dots in the keys, not that you want dotted keys (i.e. no parsing and key subdivision takes place here). To achieve what you want, you need to nest subtables inside the C++ initializer list. From the 'Serializing' example on the toml++ homepage:
auto tbl = toml::table{
{ "lib", "toml++" },
{ "cpp", toml::array{ 17, 20, "and beyond" } },
{ "toml", toml::array{ "1.0.0", "and beyond" } },
{ "repo", "https://github.com/marzer/tomlplusplus/" },
{ "author", toml::table{
{ "name", "Mark Gillard" },
{ "github", "https://github.com/marzer" },
{ "twitter", "https://twitter.com/marzer8789" }
}
},
};
Note the author
key nests an additional toml::table inside of it. The above example would serialize as a nested table:
cpp = [ 17, 20, 'and beyond' ]
lib = 'toml++'
repo = 'https://github.com/marzer/tomlplusplus/'
toml = [ '1.0.0', 'and beyond' ]
[author]
github = 'https://github.com/marzer'
name = 'Mark Gillard'
twitter = 'https://twitter.com/marzer8789'
There's no way to say "emit the author
subkeys as dotted keys please", though I wouldn't be averse to adding something like that.
I'll close it :)