mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 03:56:01 +01:00
Merge ccdd97e60a into 147e183c68
This commit is contained in:
commit
74219794ce
5 changed files with 107 additions and 6 deletions
|
|
@ -12,6 +12,13 @@ struct Value;
|
||||||
|
|
||||||
MakeError(JSONParseError, Error);
|
MakeError(JSONParseError, Error);
|
||||||
|
|
||||||
void parseJSON(EvalState & state, const std::string_view & s, Value & v);
|
/**
|
||||||
|
* Parse the string into the Value
|
||||||
|
* @param state
|
||||||
|
* @param s
|
||||||
|
* @param v
|
||||||
|
* @param allowComments Whether to allow comments in the JSON
|
||||||
|
*/
|
||||||
|
void parseJSON(EvalState & state, const std::string_view & s, Value & v, bool allowComments = false);
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|
|
||||||
|
|
@ -201,10 +201,11 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void parseJSON(EvalState & state, const std::string_view & s_, Value & v)
|
void parseJSON(EvalState & state, const std::string_view & s_, Value & v, bool allowComments)
|
||||||
{
|
{
|
||||||
JSONSax parser(state, v);
|
JSONSax parser(state, v);
|
||||||
bool res = json::sax_parse(s_, &parser);
|
bool res = json::sax_parse(
|
||||||
|
s_, &parser, nlohmann::detail::input_format_t::json, /* strict= */ true, /* ignore_comments= */ allowComments);
|
||||||
if (!res)
|
if (!res)
|
||||||
throw JSONParseError("Invalid JSON Value");
|
throw JSONParseError("Invalid JSON Value");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2539,11 +2539,11 @@ static RegisterPrimOp primop_toJSON({
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Parse a JSON string to a value. */
|
/* Parse a JSON string to a value. */
|
||||||
static void prim_fromJSON(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
static void prim_fromJSON(EvalState & state, const PosIdx pos, Value ** args, Value & v, bool allow_comments)
|
||||||
{
|
{
|
||||||
auto s = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.fromJSON");
|
auto s = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.fromJSON");
|
||||||
try {
|
try {
|
||||||
parseJSON(state, s, v);
|
parseJSON(state, s, v, allow_comments);
|
||||||
} catch (JSONParseError & e) {
|
} catch (JSONParseError & e) {
|
||||||
e.addTrace(state.positions[pos], "while decoding a JSON string");
|
e.addTrace(state.positions[pos], "while decoding a JSON string");
|
||||||
throw;
|
throw;
|
||||||
|
|
@ -2562,7 +2562,38 @@ static RegisterPrimOp primop_fromJSON({
|
||||||
|
|
||||||
returns the value `{ x = [ 1 2 3 ]; y = null; }`.
|
returns the value `{ x = [ 1 2 3 ]; y = null; }`.
|
||||||
)",
|
)",
|
||||||
.fun = prim_fromJSON,
|
.fun =
|
||||||
|
[](EvalState & state, const PosIdx pos, Value ** args, Value & v) {
|
||||||
|
return prim_fromJSON(state, pos, args, v, false);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
static RegisterPrimOp primop_fromJSONC({
|
||||||
|
.name = "__fromJSONC",
|
||||||
|
.args = {"e"},
|
||||||
|
.doc = R"(
|
||||||
|
Convert a JSON string, potentially with comments, to a Nix value.
|
||||||
|
For example,
|
||||||
|
|
||||||
|
```nix
|
||||||
|
builtins.fromJSONC ''
|
||||||
|
{
|
||||||
|
// This is a comment
|
||||||
|
"x": [1, 2, 3],
|
||||||
|
/* This is another comment */
|
||||||
|
"y": null
|
||||||
|
}
|
||||||
|
''
|
||||||
|
```
|
||||||
|
|
||||||
|
returns the value `{ x = [ 1 2 3 ]; y = null; }`.
|
||||||
|
|
||||||
|
This function supports JSON with comments.
|
||||||
|
)",
|
||||||
|
.fun =
|
||||||
|
[](EvalState & state, const PosIdx pos, Value ** args, Value & v) {
|
||||||
|
return prim_fromJSON(state, pos, args, v, true);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Store a string in the Nix store as a source file that can be used
|
/* Store a string in the Nix store as a source file that can be used
|
||||||
|
|
|
||||||
1
tests/functional/lang/eval-okay-fromjson-comments.exp
Normal file
1
tests/functional/lang/eval-okay-fromjson-comments.exp
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
true
|
||||||
61
tests/functional/lang/eval-okay-fromjson-comments.nix
Normal file
61
tests/functional/lang/eval-okay-fromjson-comments.nix
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
builtins.fromJSONC ''
|
||||||
|
{
|
||||||
|
// This is a comment
|
||||||
|
"Video": {
|
||||||
|
/* Multi line comment single line */
|
||||||
|
"Title": "The Penguin Chronicles",
|
||||||
|
"Width": 1920,
|
||||||
|
"Height": 1080,
|
||||||
|
/**
|
||||||
|
* Multi line comment
|
||||||
|
* with multiple lines
|
||||||
|
*/
|
||||||
|
"EmbeddedData": [3.14159, 23493,null, true ,false, -10],
|
||||||
|
"Thumb": {
|
||||||
|
"Url": "http://www.example.com/video/5678931",
|
||||||
|
"Width": 200,
|
||||||
|
"Height": 250
|
||||||
|
},
|
||||||
|
"Animated" : false,
|
||||||
|
"IDs": [116, 943, 234, 38793, true ,false,null, -100],
|
||||||
|
"Escapes": "\"\\\/\t\n\r\t",
|
||||||
|
"Subtitle" : false,
|
||||||
|
"Latitude": 37.7668,
|
||||||
|
"Longitude": -122.3959
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'' == {
|
||||||
|
Video = {
|
||||||
|
Title = "The Penguin Chronicles";
|
||||||
|
Width = 1920;
|
||||||
|
Height = 1080;
|
||||||
|
EmbeddedData = [
|
||||||
|
3.14159
|
||||||
|
23493
|
||||||
|
null
|
||||||
|
true
|
||||||
|
false
|
||||||
|
(0 - 10)
|
||||||
|
];
|
||||||
|
Thumb = {
|
||||||
|
Url = "http://www.example.com/video/5678931";
|
||||||
|
Width = 200;
|
||||||
|
Height = 250;
|
||||||
|
};
|
||||||
|
Animated = false;
|
||||||
|
IDs = [
|
||||||
|
116
|
||||||
|
943
|
||||||
|
234
|
||||||
|
38793
|
||||||
|
true
|
||||||
|
false
|
||||||
|
null
|
||||||
|
(0 - 100)
|
||||||
|
];
|
||||||
|
Escapes = "\"\\\/\t\n\r\t"; # supported in JSON but not Nix: \b\f
|
||||||
|
Subtitle = false;
|
||||||
|
Latitude = 37.7668;
|
||||||
|
Longitude = -122.3959;
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue