From ab44e97d90167c11cd7cca3a115f566926f9ed52 Mon Sep 17 00:00:00 2001 From: NotWearingPants Date: Sat, 2 Oct 2021 17:55:33 +0300 Subject: [PATCH] Add whitespaceOptions: colonBraceSameLine to settings --- include/json/value.h | 16 ++++++++++++++++ include/json/writer.h | 27 +++++++++++++++------------ src/lib_json/json_writer.cpp | 34 +++++++++++++++++++++++++++------- 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 9a302c1..cf8f2f4 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -124,6 +124,22 @@ enum CommentPlacement { numberOfCommentPlacement }; +enum WhitespaceOptions { + colonBraceSameLine = 1 << 0, ///< braces just after colons on the same line +}; +inline WhitespaceOptions operator|( + WhitespaceOptions left, WhitespaceOptions right) { + return static_cast(static_cast(left) | static_cast(right)); +} +inline void operator|=( + WhitespaceOptions& left, WhitespaceOptions right) { + left = left | right; +} +inline WhitespaceOptions operator&( + WhitespaceOptions left, WhitespaceOptions right) { + return static_cast(static_cast(left) & static_cast(right)); +} + /** \brief Type of precision for formatting of real values. */ enum PrecisionType { diff --git a/include/json/writer.h b/include/json/writer.h index 7d8cf4d..ba075fc 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -94,25 +94,28 @@ public: /** Configuration of this builder. * Available settings (case-sensitive): * - "commentStyle": "None" or "All" - * - "indentation": "". - * - Setting this to an empty string also omits newline characters. + * - "indentation": "". + * Setting this to an empty string also omits newline characters. * - "enableYAMLCompatibility": false or true * - slightly change the whitespace around colons + * - "whitespaceOptions": array of any combination of the following: + * "colonBraceSameLine" - when an object or an array appears as a value + * inside an object, keep the opening brace on the same line * - "dropNullPlaceholders": false or true - * - Drop the "null" string from the writer's output for nullValues. - * Strictly speaking, this is not valid JSON. But when the output is being - * fed to a browser's JavaScript, it makes for smaller output and the - * browser can handle the output just fine. + * Drop the "null" string from the writer's output for nullValues. + * Strictly speaking, this is not valid JSON. But when the output is being + * fed to a browser's JavaScript, it makes for smaller output and the + * browser can handle the output just fine. * - "useSpecialFloats": false or true - * - If true, outputs non-finite floating point values in the following way: - * NaN values as "NaN", positive infinity as "Infinity", and negative - * infinity as "-Infinity". + * If true, outputs non-finite floating point values in the following way: + * NaN values as "NaN", positive infinity as "Infinity", and negative + * infinity as "-Infinity". * - "precision": int - * - Number of precision digits for formatting of real values. + * Number of precision digits for formatting of real values. * - "precisionType": "significant"(default) or "decimal" - * - Type of precision for formatting of real values. + * Type of precision for formatting of real values. * - "emitUTF8": false or true - * - If true, outputs raw UTF8 strings instead of escaping them. + * If true, outputs raw UTF8 strings instead of escaping them. * You can examine 'settings_` yourself * to see the defaults. You can also write and read them just like any diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 0dd160e..9a493d2 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -878,9 +878,10 @@ struct CommentStyle { struct BuiltStyledStreamWriter : public StreamWriter { BuiltStyledStreamWriter(String indentation, CommentStyle::Enum cs, String colonSymbol, String nullSymbol, - String endingLineFeedSymbol, bool useSpecialFloats, - bool emitUTF8, unsigned int precision, - PrecisionType precisionType); + String endingLineFeedSymbol, + WhitespaceOptions whitespaceOptions, + bool useSpecialFloats, bool emitUTF8, + unsigned int precision, PrecisionType precisionType); int write(Value const& root, OStream* sout) override; private: @@ -906,6 +907,7 @@ private: String colonSymbol_; String nullSymbol_; String endingLineFeedSymbol_; + WhitespaceOptions whitespaceOptions_; bool addChildValues_ : 1; bool indented_ : 1; bool useSpecialFloats_ : 1; @@ -915,11 +917,13 @@ private: }; BuiltStyledStreamWriter::BuiltStyledStreamWriter( String indentation, CommentStyle::Enum cs, String colonSymbol, - String nullSymbol, String endingLineFeedSymbol, bool useSpecialFloats, - bool emitUTF8, unsigned int precision, PrecisionType precisionType) + String nullSymbol, String endingLineFeedSymbol, + WhitespaceOptions whitespaceOptions, bool useSpecialFloats, bool emitUTF8, + unsigned int precision, PrecisionType precisionType) : rightMargin_(74), indentation_(std::move(indentation)), cs_(cs), colonSymbol_(std::move(colonSymbol)), nullSymbol_(std::move(nullSymbol)), endingLineFeedSymbol_(std::move(endingLineFeedSymbol)), + whitespaceOptions_(whitespaceOptions), addChildValues_(false), indented_(false), useSpecialFloats_(useSpecialFloats), emitUTF8_(emitUTF8), precision_(precision), precisionType_(precisionType) {} @@ -986,7 +990,11 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { writeWithIndent( valueToQuotedStringN(name.data(), name.length(), emitUTF8_)); *sout_ << colonSymbol_; + if (whitespaceOptions_ & WhitespaceOptions::colonBraceSameLine) + indented_ = true; writeValue(childValue); + if (whitespaceOptions_ & WhitespaceOptions::colonBraceSameLine) + indented_ = false; if (++it == members.end()) { writeCommentAfterValueOnSameLine(childValue); break; @@ -1164,6 +1172,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const { const String cs_str = settings_["commentStyle"].asString(); const String pt_str = settings_["precisionType"].asString(); const bool eyc = settings_["enableYAMLCompatibility"].asBool(); + const Value& wo_array = settings_["whitespaceOptions"]; const bool dnp = settings_["dropNullPlaceholders"].asBool(); const bool usf = settings_["useSpecialFloats"].asBool(); const bool emitUTF8 = settings_["emitUTF8"].asBool(); @@ -1190,6 +1199,15 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const { } else if (indentation.empty()) { colonSymbol = ":"; } + WhitespaceOptions whitespaceOptions = static_cast(0); + for (auto wi = wo_array.begin(); wi != wo_array.end(); ++wi) { + const String& option = wi->asString(); + if (option == "colonBraceSameLine") { + whitespaceOptions |= WhitespaceOptions::colonBraceSameLine; + } else { + throwRuntimeError("unknown option passed to whitespaceOptions"); + } + } String nullSymbol = "null"; if (dnp) { nullSymbol.clear(); @@ -1198,8 +1216,8 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const { pre = 17; String endingLineFeedSymbol; return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol, - endingLineFeedSymbol, usf, emitUTF8, pre, - precisionType); + endingLineFeedSymbol, whitespaceOptions, + usf, emitUTF8, pre, precisionType); } bool StreamWriterBuilder::validate(Json::Value* invalid) const { @@ -1207,6 +1225,7 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const { "indentation", "commentStyle", "enableYAMLCompatibility", + "whitespaceOptions", "dropNullPlaceholders", "useSpecialFloats", "emitUTF8", @@ -1234,6 +1253,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings) { (*settings)["commentStyle"] = "All"; (*settings)["indentation"] = "\t"; (*settings)["enableYAMLCompatibility"] = false; + (*settings)["whitespaceOptions"] = Value(arrayValue); (*settings)["dropNullPlaceholders"] = false; (*settings)["useSpecialFloats"] = false; (*settings)["emitUTF8"] = false;