forked from lix-project/lix
Parse TOML timestamps (#8120)
Currently `fromTOML` throws an exception when encountering a timestamp since the Nix language lacks a way to represent them. This patch changes this beaviour and makes `fromTOML` parse timestamps as attrsets of the format { _type = "timestamp"; value = "1979-05-27T07:32:00Z"; } This is guarded by an experimental feature flag to leave room for iterating on the representation.
This commit is contained in:
parent
bf7dc3c7dc
commit
3c78920f73
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "../../toml11/toml.hpp"
|
#include "../../toml11/toml.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
static void prim_fromTOML(EvalState & state, const PosIdx pos, Value * * args, Value & val)
|
static void prim_fromTOML(EvalState & state, const PosIdx pos, Value * * args, Value & val)
|
||||||
|
@ -58,8 +60,18 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value * * args, V
|
||||||
case toml::value_t::offset_datetime:
|
case toml::value_t::offset_datetime:
|
||||||
case toml::value_t::local_date:
|
case toml::value_t::local_date:
|
||||||
case toml::value_t::local_time:
|
case toml::value_t::local_time:
|
||||||
// We fail since Nix doesn't have date and time types
|
{
|
||||||
throw std::runtime_error("Dates and times are not supported");
|
if (experimentalFeatureSettings.isEnabled(Xp::ParseTomlTimestamps)) {
|
||||||
|
auto attrs = state.buildBindings(2);
|
||||||
|
attrs.alloc("_type").mkString("timestamp");
|
||||||
|
std::ostringstream s;
|
||||||
|
s << t;
|
||||||
|
attrs.alloc("value").mkString(s.str());
|
||||||
|
v.mkAttrs(attrs);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Dates and times are not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
break;;
|
break;;
|
||||||
case toml::value_t::empty:
|
case toml::value_t::empty:
|
||||||
v.mkNull();
|
v.mkNull();
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct ExperimentalFeatureDetails
|
||||||
std::string_view description;
|
std::string_view description;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr std::array<ExperimentalFeatureDetails, 13> xpFeatureDetails = {{
|
constexpr std::array<ExperimentalFeatureDetails, 14> xpFeatureDetails = {{
|
||||||
{
|
{
|
||||||
.tag = Xp::CaDerivations,
|
.tag = Xp::CaDerivations,
|
||||||
.name = "ca-derivations",
|
.name = "ca-derivations",
|
||||||
|
@ -214,6 +214,13 @@ constexpr std::array<ExperimentalFeatureDetails, 13> xpFeatureDetails = {{
|
||||||
derivations that are themselves derivations outputs.
|
derivations that are themselves derivations outputs.
|
||||||
)",
|
)",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.tag = Xp::ParseTomlTimestamps,
|
||||||
|
.name = "parse-toml-timestamps",
|
||||||
|
.description = R"(
|
||||||
|
Allow parsing of timestamps in builtins.fromTOML.
|
||||||
|
)",
|
||||||
|
},
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
|
@ -248,7 +255,7 @@ std::string_view showExperimentalFeature(const ExperimentalFeature tag)
|
||||||
return xpFeatureDetails[(size_t)tag].name;
|
return xpFeatureDetails[(size_t)tag].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json documentExperimentalFeatures()
|
nlohmann::json documentExperimentalFeatures()
|
||||||
{
|
{
|
||||||
StringMap res;
|
StringMap res;
|
||||||
for (auto & xpFeature : xpFeatureDetails)
|
for (auto & xpFeature : xpFeatureDetails)
|
||||||
|
|
|
@ -30,6 +30,7 @@ enum struct ExperimentalFeature
|
||||||
DiscardReferences,
|
DiscardReferences,
|
||||||
DaemonTrustOverride,
|
DaemonTrustOverride,
|
||||||
DynamicDerivations,
|
DynamicDerivations,
|
||||||
|
ParseTomlTimestamps,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
130
tests/lang/eval-fail-fromTOML-timestamps.nix
Normal file
130
tests/lang/eval-fail-fromTOML-timestamps.nix
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
builtins.fromTOML ''
|
||||||
|
key = "value"
|
||||||
|
bare_key = "value"
|
||||||
|
bare-key = "value"
|
||||||
|
1234 = "value"
|
||||||
|
|
||||||
|
"127.0.0.1" = "value"
|
||||||
|
"character encoding" = "value"
|
||||||
|
"ʎǝʞ" = "value"
|
||||||
|
'key2' = "value"
|
||||||
|
'quoted "value"' = "value"
|
||||||
|
|
||||||
|
name = "Orange"
|
||||||
|
|
||||||
|
physical.color = "orange"
|
||||||
|
physical.shape = "round"
|
||||||
|
site."google.com" = true
|
||||||
|
|
||||||
|
# This is legal according to the spec, but cpptoml doesn't handle it.
|
||||||
|
#a.b.c = 1
|
||||||
|
#a.d = 2
|
||||||
|
|
||||||
|
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
|
||||||
|
|
||||||
|
int1 = +99
|
||||||
|
int2 = 42
|
||||||
|
int3 = 0
|
||||||
|
int4 = -17
|
||||||
|
int5 = 1_000
|
||||||
|
int6 = 5_349_221
|
||||||
|
int7 = 1_2_3_4_5
|
||||||
|
|
||||||
|
hex1 = 0xDEADBEEF
|
||||||
|
hex2 = 0xdeadbeef
|
||||||
|
hex3 = 0xdead_beef
|
||||||
|
|
||||||
|
oct1 = 0o01234567
|
||||||
|
oct2 = 0o755
|
||||||
|
|
||||||
|
bin1 = 0b11010110
|
||||||
|
|
||||||
|
flt1 = +1.0
|
||||||
|
flt2 = 3.1415
|
||||||
|
flt3 = -0.01
|
||||||
|
flt4 = 5e+22
|
||||||
|
flt5 = 1e6
|
||||||
|
flt6 = -2E-2
|
||||||
|
flt7 = 6.626e-34
|
||||||
|
flt8 = 9_224_617.445_991_228_313
|
||||||
|
|
||||||
|
bool1 = true
|
||||||
|
bool2 = false
|
||||||
|
|
||||||
|
odt1 = 1979-05-27T07:32:00Z
|
||||||
|
odt2 = 1979-05-27T00:32:00-07:00
|
||||||
|
odt3 = 1979-05-27T00:32:00.999999-07:00
|
||||||
|
odt4 = 1979-05-27 07:32:00Z
|
||||||
|
ldt1 = 1979-05-27T07:32:00
|
||||||
|
ldt2 = 1979-05-27T00:32:00.999999
|
||||||
|
ld1 = 1979-05-27
|
||||||
|
lt1 = 07:32:00
|
||||||
|
lt2 = 00:32:00.999999
|
||||||
|
|
||||||
|
arr1 = [ 1, 2, 3 ]
|
||||||
|
arr2 = [ "red", "yellow", "green" ]
|
||||||
|
arr3 = [ [ 1, 2 ], [3, 4, 5] ]
|
||||||
|
arr4 = [ "all", 'strings', """are the same""", ''''type'''']
|
||||||
|
arr5 = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||||
|
|
||||||
|
arr7 = [
|
||||||
|
1, 2, 3
|
||||||
|
]
|
||||||
|
|
||||||
|
arr8 = [
|
||||||
|
1,
|
||||||
|
2, # this is ok
|
||||||
|
]
|
||||||
|
|
||||||
|
[table-1]
|
||||||
|
key1 = "some string"
|
||||||
|
key2 = 123
|
||||||
|
|
||||||
|
|
||||||
|
[table-2]
|
||||||
|
key1 = "another string"
|
||||||
|
key2 = 456
|
||||||
|
|
||||||
|
[dog."tater.man"]
|
||||||
|
type.name = "pug"
|
||||||
|
|
||||||
|
[a.b.c]
|
||||||
|
[ d.e.f ]
|
||||||
|
[ g . h . i ]
|
||||||
|
[ j . "ʞ" . 'l' ]
|
||||||
|
[x.y.z.w]
|
||||||
|
|
||||||
|
name = { first = "Tom", last = "Preston-Werner" }
|
||||||
|
point = { x = 1, y = 2 }
|
||||||
|
animal = { type.name = "pug" }
|
||||||
|
|
||||||
|
[[products]]
|
||||||
|
name = "Hammer"
|
||||||
|
sku = 738594937
|
||||||
|
|
||||||
|
[[products]]
|
||||||
|
|
||||||
|
[[products]]
|
||||||
|
name = "Nail"
|
||||||
|
sku = 284758393
|
||||||
|
color = "gray"
|
||||||
|
|
||||||
|
[[fruit]]
|
||||||
|
name = "apple"
|
||||||
|
|
||||||
|
[fruit.physical]
|
||||||
|
color = "red"
|
||||||
|
shape = "round"
|
||||||
|
|
||||||
|
[[fruit.variety]]
|
||||||
|
name = "red delicious"
|
||||||
|
|
||||||
|
[[fruit.variety]]
|
||||||
|
name = "granny smith"
|
||||||
|
|
||||||
|
[[fruit]]
|
||||||
|
name = "banana"
|
||||||
|
|
||||||
|
[[fruit.variety]]
|
||||||
|
name = "plantain"
|
||||||
|
''
|
1
tests/lang/eval-okay-fromTOML-timestamps.exp
Normal file
1
tests/lang/eval-okay-fromTOML-timestamps.exp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ "1234" = "value"; "127.0.0.1" = "value"; a = { b = { c = { }; }; }; arr1 = [ 1 2 3 ]; arr2 = [ "red" "yellow" "green" ]; arr3 = [ [ 1 2 ] [ 3 4 5 ] ]; arr4 = [ "all" "strings" "are the same" "type" ]; arr5 = [ [ 1 2 ] [ "a" "b" "c" ] ]; arr7 = [ 1 2 3 ]; arr8 = [ 1 2 ]; bare-key = "value"; bare_key = "value"; bin1 = 214; bool1 = true; bool2 = false; "character encoding" = "value"; d = { e = { f = { }; }; }; dog = { "tater.man" = { type = { name = "pug"; }; }; }; flt1 = 1; flt2 = 3.1415; flt3 = -0.01; flt4 = 5e+22; flt5 = 1e+06; flt6 = -0.02; flt7 = 6.626e-34; flt8 = 9.22462e+06; fruit = [ { name = "apple"; physical = { color = "red"; shape = "round"; }; variety = [ { name = "red delicious"; } { name = "granny smith"; } ]; } { name = "banana"; variety = [ { name = "plantain"; } ]; } ]; g = { h = { i = { }; }; }; hex1 = 3735928559; hex2 = 3735928559; hex3 = 3735928559; int1 = 99; int2 = 42; int3 = 0; int4 = -17; int5 = 1000; int6 = 5349221; int7 = 12345; j = { "ʞ" = { l = { }; }; }; key = "value"; key2 = "value"; ld1 = { _type = "timestamp"; value = "1979-05-27"; }; ldt1 = { _type = "timestamp"; value = "1979-05-27T07:32:00"; }; ldt2 = { _type = "timestamp"; value = "1979-05-27T00:32:00.999999"; }; lt1 = { _type = "timestamp"; value = "07:32:00"; }; lt2 = { _type = "timestamp"; value = "00:32:00.999999"; }; name = "Orange"; oct1 = 342391; oct2 = 493; odt1 = { _type = "timestamp"; value = "1979-05-27T07:32:00Z"; }; odt2 = { _type = "timestamp"; value = "1979-05-27T00:32:00-07:00"; }; odt3 = { _type = "timestamp"; value = "1979-05-27T00:32:00.999999-07:00"; }; odt4 = { _type = "timestamp"; value = "1979-05-27T07:32:00Z"; }; physical = { color = "orange"; shape = "round"; }; products = [ { name = "Hammer"; sku = 738594937; } { } { color = "gray"; name = "Nail"; sku = 284758393; } ]; "quoted \"value\"" = "value"; site = { "google.com" = true; }; str = "I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF."; table-1 = { key1 = "some string"; key2 = 123; }; table-2 = { key1 = "another string"; key2 = 456; }; x = { y = { z = { w = { animal = { type = { name = "pug"; }; }; name = { first = "Tom"; last = "Preston-Werner"; }; point = { x = 1; y = 2; }; }; }; }; }; "ʎǝʞ" = "value"; }
|
1
tests/lang/eval-okay-fromTOML-timestamps.flags
Normal file
1
tests/lang/eval-okay-fromTOML-timestamps.flags
Normal file
|
@ -0,0 +1 @@
|
||||||
|
--extra-experimental-features parse-toml-timestamps
|
130
tests/lang/eval-okay-fromTOML-timestamps.nix
Normal file
130
tests/lang/eval-okay-fromTOML-timestamps.nix
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
builtins.fromTOML ''
|
||||||
|
key = "value"
|
||||||
|
bare_key = "value"
|
||||||
|
bare-key = "value"
|
||||||
|
1234 = "value"
|
||||||
|
|
||||||
|
"127.0.0.1" = "value"
|
||||||
|
"character encoding" = "value"
|
||||||
|
"ʎǝʞ" = "value"
|
||||||
|
'key2' = "value"
|
||||||
|
'quoted "value"' = "value"
|
||||||
|
|
||||||
|
name = "Orange"
|
||||||
|
|
||||||
|
physical.color = "orange"
|
||||||
|
physical.shape = "round"
|
||||||
|
site."google.com" = true
|
||||||
|
|
||||||
|
# This is legal according to the spec, but cpptoml doesn't handle it.
|
||||||
|
#a.b.c = 1
|
||||||
|
#a.d = 2
|
||||||
|
|
||||||
|
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
|
||||||
|
|
||||||
|
int1 = +99
|
||||||
|
int2 = 42
|
||||||
|
int3 = 0
|
||||||
|
int4 = -17
|
||||||
|
int5 = 1_000
|
||||||
|
int6 = 5_349_221
|
||||||
|
int7 = 1_2_3_4_5
|
||||||
|
|
||||||
|
hex1 = 0xDEADBEEF
|
||||||
|
hex2 = 0xdeadbeef
|
||||||
|
hex3 = 0xdead_beef
|
||||||
|
|
||||||
|
oct1 = 0o01234567
|
||||||
|
oct2 = 0o755
|
||||||
|
|
||||||
|
bin1 = 0b11010110
|
||||||
|
|
||||||
|
flt1 = +1.0
|
||||||
|
flt2 = 3.1415
|
||||||
|
flt3 = -0.01
|
||||||
|
flt4 = 5e+22
|
||||||
|
flt5 = 1e6
|
||||||
|
flt6 = -2E-2
|
||||||
|
flt7 = 6.626e-34
|
||||||
|
flt8 = 9_224_617.445_991_228_313
|
||||||
|
|
||||||
|
bool1 = true
|
||||||
|
bool2 = false
|
||||||
|
|
||||||
|
odt1 = 1979-05-27T07:32:00Z
|
||||||
|
odt2 = 1979-05-27T00:32:00-07:00
|
||||||
|
odt3 = 1979-05-27T00:32:00.999999-07:00
|
||||||
|
odt4 = 1979-05-27 07:32:00Z
|
||||||
|
ldt1 = 1979-05-27T07:32:00
|
||||||
|
ldt2 = 1979-05-27T00:32:00.999999
|
||||||
|
ld1 = 1979-05-27
|
||||||
|
lt1 = 07:32:00
|
||||||
|
lt2 = 00:32:00.999999
|
||||||
|
|
||||||
|
arr1 = [ 1, 2, 3 ]
|
||||||
|
arr2 = [ "red", "yellow", "green" ]
|
||||||
|
arr3 = [ [ 1, 2 ], [3, 4, 5] ]
|
||||||
|
arr4 = [ "all", 'strings', """are the same""", ''''type'''']
|
||||||
|
arr5 = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||||
|
|
||||||
|
arr7 = [
|
||||||
|
1, 2, 3
|
||||||
|
]
|
||||||
|
|
||||||
|
arr8 = [
|
||||||
|
1,
|
||||||
|
2, # this is ok
|
||||||
|
]
|
||||||
|
|
||||||
|
[table-1]
|
||||||
|
key1 = "some string"
|
||||||
|
key2 = 123
|
||||||
|
|
||||||
|
|
||||||
|
[table-2]
|
||||||
|
key1 = "another string"
|
||||||
|
key2 = 456
|
||||||
|
|
||||||
|
[dog."tater.man"]
|
||||||
|
type.name = "pug"
|
||||||
|
|
||||||
|
[a.b.c]
|
||||||
|
[ d.e.f ]
|
||||||
|
[ g . h . i ]
|
||||||
|
[ j . "ʞ" . 'l' ]
|
||||||
|
[x.y.z.w]
|
||||||
|
|
||||||
|
name = { first = "Tom", last = "Preston-Werner" }
|
||||||
|
point = { x = 1, y = 2 }
|
||||||
|
animal = { type.name = "pug" }
|
||||||
|
|
||||||
|
[[products]]
|
||||||
|
name = "Hammer"
|
||||||
|
sku = 738594937
|
||||||
|
|
||||||
|
[[products]]
|
||||||
|
|
||||||
|
[[products]]
|
||||||
|
name = "Nail"
|
||||||
|
sku = 284758393
|
||||||
|
color = "gray"
|
||||||
|
|
||||||
|
[[fruit]]
|
||||||
|
name = "apple"
|
||||||
|
|
||||||
|
[fruit.physical]
|
||||||
|
color = "red"
|
||||||
|
shape = "round"
|
||||||
|
|
||||||
|
[[fruit.variety]]
|
||||||
|
name = "red delicious"
|
||||||
|
|
||||||
|
[[fruit.variety]]
|
||||||
|
name = "granny smith"
|
||||||
|
|
||||||
|
[[fruit]]
|
||||||
|
name = "banana"
|
||||||
|
|
||||||
|
[[fruit.variety]]
|
||||||
|
name = "plantain"
|
||||||
|
''
|
Loading…
Reference in a new issue