Skip to content

Commit

Permalink
Add indentation to json dump method
Browse files Browse the repository at this point in the history
Closes #747
  • Loading branch information
sina-rostami authored and gittiver committed Mar 10, 2024
1 parent 049490c commit 106aeb0
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 5 deletions.
63 changes: 58 additions & 5 deletions include/crow/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -1840,7 +1840,14 @@ namespace crow
out.push_back('"');
}

inline void dump_internal(const wvalue& v, std::string& out) const
inline void dump_indentation_part(std::string& out, const int indent, const char separator, const int indent_level) const
{
out.push_back('\n');
out.append(indent_level * indent, separator);
}


inline void dump_internal(const wvalue& v, std::string& out, const int indent, const char separator, const int indent_level = 0) const
{
switch (v.t_)
{
Expand Down Expand Up @@ -1934,6 +1941,12 @@ namespace crow
case type::List:
{
out.push_back('[');

if (indent >= 0)
{
dump_indentation_part(out, indent, separator, indent_level + 1);
}

if (v.l)
{
bool first = true;
Expand All @@ -1942,17 +1955,34 @@ namespace crow
if (!first)
{
out.push_back(',');

if (indent >= 0)
{
dump_indentation_part(out, indent, separator, indent_level + 1);
}
}
first = false;
dump_internal(x, out);
dump_internal(x, out, indent, separator, indent_level + 1);
}
}

if (indent >= 0)
{
dump_indentation_part(out, indent, separator, indent_level);
}

out.push_back(']');
}
break;
case type::Object:
{
out.push_back('{');

if (indent >= 0)
{
dump_indentation_part(out, indent, separator, indent_level + 1);
}

if (v.o)
{
bool first = true;
Expand All @@ -1961,13 +1991,29 @@ namespace crow
if (!first)
{
out.push_back(',');
if (indent >= 0)
{
dump_indentation_part(out, indent, separator, indent_level + 1);
}
}
first = false;
dump_string(kv.first, out);
out.push_back(':');
dump_internal(kv.second, out);

if (indent >= 0)
{
out.push_back(' ');
}

dump_internal(kv.second, out, indent, separator, indent_level + 1);
}
}

if (indent >= 0)
{
dump_indentation_part(out, indent, separator, indent_level);
}

out.push_back('}');
}
break;
Expand All @@ -1979,13 +2025,20 @@ namespace crow
}

public:
std::string dump() const
std::string dump(const int indent, const char separator = ' ') const
{
std::string ret;
ret.reserve(estimate_length());
dump_internal(*this, ret);
dump_internal(*this, ret, indent, separator);
return ret;
}

std::string dump() const
{
static constexpr int DontIndent = -1;

return dump(DontIndent);
}
};

// Used for accessing the internals of a wvalue
Expand Down
66 changes: 66 additions & 0 deletions tests/unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,72 @@ TEST_CASE("json_write")
CHECK(R"({"scores":[1,2,3]})" == y.dump());
} // json_write

TEST_CASE("json_write_with_indent")
{
static constexpr int IndentationLevelOne = 1;
static constexpr int IndentationLevelTwo = 2;
static constexpr int IndentationLevelFour = 4;

json::wvalue y;

y["scores"][0] = 1;
y["scores"][1] = "king";
y["scores"][2][0] = "real";
y["scores"][2][1] = false;
y["scores"][2][2] = true;

CHECK(R"({
"scores": [
1,
"king",
[
"real",
false,
true
]
]
})" == y.dump(IndentationLevelOne));

CHECK(R"({
"scores": [
1,
"king",
[
"real",
false,
true
]
]
})" == y.dump(IndentationLevelTwo));

CHECK(R"({
"scores": [
1,
"king",
[
"real",
false,
true
]
]
})" == y.dump(IndentationLevelFour));

static constexpr char TabSeparator = '\t';

CHECK(R"({
"scores": [
1,
"king",
[
"real",
false,
true
]
]
})" == y.dump(IndentationLevelOne, TabSeparator));
} // json_write_with_indent


TEST_CASE("json_copy_r_to_w_to_w_to_r")
{
json::rvalue r = json::load(
Expand Down

0 comments on commit 106aeb0

Please sign in to comment.