Skip to content

Commit

Permalink
📝 add documentation for JSON Lines
Browse files Browse the repository at this point in the history
  • Loading branch information
nlohmann committed Jan 4, 2022
1 parent 4fc7b3d commit b6c753c
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 0 deletions.
22 changes: 22 additions & 0 deletions doc/examples/json_lines.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <sstream>
#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main()
{
// JSON Lines (see https://jsonlines.org)
std::stringstream input;
input << R"({"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
{"name": "May", "wins": []}
{"name": "Deloise", "wins": [["three of a kind", "5♣"]]}
)";

std::string line;
while (std::getline(input, line))
{
std::cout << json::parse(line) << std::endl;
}
}
4 changes: 4 additions & 0 deletions doc/examples/json_lines.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{"name":"Gilbert","wins":[["straight","7♣"],["one pair","10♥"]]}
{"name":"Alexa","wins":[["two pair","4♠"],["two pair","9♠"]]}
{"name":"May","wins":[]}
{"name":"Deloise","wins":[["three of a kind","5♣"]]}
49 changes: 49 additions & 0 deletions doc/mkdocs/docs/features/parsing/json_lines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# JSON Lines

The [JSON Lines](https://jsonlines.org) format is a text format of newline-delimited JSON. In particular:

1. The input must be UTF-8 encoded.
2. Every line must be a valid JSON value.
3. The line separator must be `\n`. As `\r` is silently ignored, `\r\n` is also supported.
4. The final character may be `\n`, but is not required to be one.

!!! example "JSON Text example"

```json
{"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
{"name": "May", "wins": []}
{"name": "Deloise", "wins": [["three of a kind", "5♣"]]}
```

JSON Lines input with more than one value is treated as invalid JSON by the [`parse`](../../api/basic_json/parse.md) or
[`accept`](../../api/basic_json/accept.md) functions. The process it line by line, functions like
[`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) can be used:

!!! example "Example: Parse JSON Text input line by line"

The example below demonstrates how JSON Lines can be processed.

```cpp
--8<-- "examples/json_lines.cpp"
```

Output:

```json
--8<-- "examples/json_lines.output"
```

!!! warning "Note"

Using [`operator>>`](../../api/basic_json/operator_gtgt.md) like

```cpp
json j;
while (input >> j)
{
std::cout << j << std::endl;
}
```

with a JSON Lines input does not work, because the parser will try to parse one value after the last one.
1 change: 1 addition & 0 deletions doc/mkdocs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ nav:
- features/object_order.md
- Parsing:
- features/parsing/index.md
- features/parsing/json_lines.md
- features/parsing/parse_exceptions.md
- features/parsing/parser_callbacks.md
- features/parsing/sax_interface.md
Expand Down
42 changes: 42 additions & 0 deletions test/src/unit-deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,48 @@ TEST_CASE("deserialization")
"start_array()"
}));
}

SECTION("JSON Lines")
{
SECTION("Example file")
{
std::stringstream ss;
ss << R"({"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
{"name": "May", "wins": []}
{"name": "Deloise", "wins": [["three of a kind", "5♣"]]}
)";

std::string line;
int object_count = 0;
while (std::getline(ss, line))
{
++object_count;
CHECK(json::accept(line));
}

CHECK(object_count == 4);
}

SECTION("Example file without trailing newline")
{
std::stringstream ss;
ss << R"({"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
{"name": "May", "wins": []}
{"name": "Deloise", "wins": [["three of a kind", "5♣"]]})";

std::string line;
int object_count = 0;
while (std::getline(ss, line))
{
++object_count;
CHECK(json::accept(line));
}

CHECK(object_count == 4);
}
}
}

TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T,
Expand Down

0 comments on commit b6c753c

Please sign in to comment.