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 committed Jan 21, 2024
1 parent f4166ac commit 8f3b5b5
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 5 deletions.
51 changes: 46 additions & 5 deletions include/crow/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -1826,7 +1826,16 @@ 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');
for (int i = 0; i < indent_level; i++)
for (int j = 0; j < indent; j++)
out.push_back(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 @@ -1909,6 +1918,10 @@ 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 @@ -1917,17 +1930,28 @@ 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 @@ -1936,13 +1960,23 @@ 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 @@ -1954,13 +1988,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 @@ -921,6 +921,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 8f3b5b5

Please sign in to comment.