diff --git a/src/cascadia/TerminalControl/pch.h b/src/cascadia/TerminalControl/pch.h index bac6c29ca..7c32b2dec 100644 --- a/src/cascadia/TerminalControl/pch.h +++ b/src/cascadia/TerminalControl/pch.h @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. // // pch.h @@ -58,6 +58,7 @@ TRACELOGGING_DECLARE_PROVIDER(g_hTerminalControlProvider); #include #include +#include #include "til.h" diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.h b/src/cascadia/TerminalSettingsModel/ActionAndArgs.h index abf9a4823..62faaa0fc 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.h +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.h @@ -5,7 +5,6 @@ #include "ActionAndArgs.g.h" #include "ActionArgs.h" -#include "TerminalWarnings.h" #include "../inc/cppwinrt_utils.h" namespace winrt::Microsoft::Terminal::Settings::Model::implementation @@ -36,6 +35,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation BASIC_FACTORY(ActionAndArgs); } +#ifdef JSON_UTILS_H +#error foo +#endif + namespace Microsoft::Terminal::Settings::Model::JsonUtils { using namespace winrt::Microsoft::Terminal::Settings::Model; diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp index d713825cd..cb349c6b5 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp @@ -40,6 +40,9 @@ #include #include +#include "TerminalSettingsSerializationHelpers.h" +#include "JsonUtils.h" + using namespace winrt::Microsoft::Terminal::Control; namespace winrt::Microsoft::Terminal::Settings::Model::implementation diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.h b/src/cascadia/TerminalSettingsModel/ActionArgs.h index 1c95209e4..4a753d7d2 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.h +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.h @@ -40,12 +40,10 @@ #include "MultipleActionsArgs.g.h" #include "../../cascadia/inc/cppwinrt_utils.h" -#include "JsonUtils.h" -#include "HashUtils.h" #include "TerminalWarnings.h" #include "../inc/WindowingBehavior.h" -#include "TerminalSettingsSerializationHelpers.h" +#include "HashUtils.h" #define ACTION_ARG(type, name, ...) \ public: \ diff --git a/src/cascadia/TerminalSettingsModel/AppearanceConfig.h b/src/cascadia/TerminalSettingsModel/AppearanceConfig.h index bbc30927e..eb53160f7 100644 --- a/src/cascadia/TerminalSettingsModel/AppearanceConfig.h +++ b/src/cascadia/TerminalSettingsModel/AppearanceConfig.h @@ -17,7 +17,6 @@ Author(s): #pragma once #include "AppearanceConfig.g.h" -#include "JsonUtils.h" #include "IInheritable.h" #include "MTSMSettings.h" #include diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.h b/src/cascadia/TerminalSettingsModel/FontConfig.h index db69fd08f..9d649fb48 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.h +++ b/src/cascadia/TerminalSettingsModel/FontConfig.h @@ -18,7 +18,6 @@ Author(s): #include "pch.h" #include "FontConfig.g.h" -#include "JsonUtils.h" #include "MTSMSettings.h" #include "../inc/cppwinrt_utils.h" #include "IInheritable.h" diff --git a/src/cascadia/TerminalSettingsModel/IconPathConverter.cpp b/src/cascadia/TerminalSettingsModel/IconPathConverter.cpp index d649fb885..c87c35957 100644 --- a/src/cascadia/TerminalSettingsModel/IconPathConverter.cpp +++ b/src/cascadia/TerminalSettingsModel/IconPathConverter.cpp @@ -67,7 +67,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation try { winrt::Windows::Foundation::Uri iconUri{ path }; - BitmapIconSource::type iconSource; + typename BitmapIconSource::type iconSource; // Make sure to set this to false, so we keep the RGB data of the // image. Otherwise, the icon will be white for all the // non-transparent pixels in the image. @@ -81,6 +81,16 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation return nullptr; } + static winrt::hstring _expandIconPath(hstring iconPath) + { + if (iconPath.empty()) + { + return iconPath; + } + winrt::hstring envExpandedPath{ wil::ExpandEnvironmentStringsW(iconPath.c_str()) }; + return envExpandedPath; + } + // Method Description: // - Creates an IconSource for the given path. // * If the icon is a path to an image, we'll use that. @@ -115,7 +125,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { try { - FontIconSource::type icon; + typename FontIconSource::type icon; const wchar_t ch = iconPath[0]; // The range of MDL2 Icons isn't explicitly defined, but @@ -146,7 +156,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // Swapping between nullptr IconSources and non-null IconSources causes a crash // to occur, but swapping between IconSources with a null source and non-null IconSources // work perfectly fine :shrug:. - BitmapIconSource::type icon; + typename BitmapIconSource::type icon; icon.UriSource(nullptr); iconSource = icon; } @@ -154,16 +164,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation return iconSource; } - static winrt::hstring _expandIconPath(hstring iconPath) - { - if (iconPath.empty()) - { - return iconPath; - } - winrt::hstring envExpandedPath{ wil::ExpandEnvironmentStringsW(iconPath.c_str()) }; - return envExpandedPath; - } - // Method Description: // - Attempt to convert something into another type. For the // IconPathConverter, we support a variety of icons: diff --git a/src/cascadia/TerminalSettingsModel/JsonUtils.h b/src/cascadia/TerminalSettingsModel/JsonUtils.h index be29f15de..43ca35fa7 100644 --- a/src/cascadia/TerminalSettingsModel/JsonUtils.h +++ b/src/cascadia/TerminalSettingsModel/JsonUtils.h @@ -14,6 +14,8 @@ Author(s): #pragma once +#define JSON_UTILS_H + #include #include "../types/inc/utils.hpp" @@ -117,137 +119,9 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils std::string expectedType; }; - // Method Description: - // - Helper that will populate a reference with a value converted from a json object. - // Arguments: - // - json: the json object to convert - // - target: the value to populate with the converted result - // Return Value: - // - a boolean indicating whether the value existed (in this case, was non-null) - // - // GetValue, type-deduced, manual converter - template - bool GetValue(const Json::Value& json, T& target, Converter&& conv) - { - if (!conv.CanConvert(json)) - { - DeserializationError e{ json }; - e.expectedType = conv.TypeDescription(); - throw e; - } - - target = conv.FromJson(json); - return true; - } - - // GetValue, forced return type, manual converter - template - std::decay_t GetValue(const Json::Value& json, Converter&& conv) - { - std::decay_t local{}; - GetValue(json, local, std::forward(conv)); - return local; // returns zero-initialized or value - } - - // GetValueForKey, type-deduced, manual converter - template - bool GetValueForKey(const Json::Value& json, std::string_view key, T& target, Converter&& conv) - { - if (auto found{ json.find(&*key.cbegin(), (&*key.cbegin()) + key.size()) }) - { - try - { - return GetValue(*found, target, std::forward(conv)); - } - catch (DeserializationError& e) - { - e.SetKey(key); - throw; // rethrow now that it has a key - } - } - return false; - } - - // GetValueForKey, forced return type, manual converter - template - std::decay_t GetValueForKey(const Json::Value& json, std::string_view key, Converter&& conv) - { - std::decay_t local{}; - GetValueForKey(json, key, local, std::forward(conv)); - return local; // returns zero-initialized? - } - - // GetValue, type-deduced, with automatic converter - template - bool GetValue(const Json::Value& json, T& target) - { - return GetValue(json, target, ConversionTrait::type>{}); - } - - // GetValue, forced return type, with automatic converter - template - std::decay_t GetValue(const Json::Value& json) - { - std::decay_t local{}; - GetValue(json, local, ConversionTrait::type>{}); - return local; // returns zero-initialized or value - } - - // GetValueForKey, type-deduced, with automatic converter - template - bool GetValueForKey(const Json::Value& json, std::string_view key, T& target) - { - return GetValueForKey(json, key, target, ConversionTrait::type>{}); - } - - // GetValueForKey, forced return type, with automatic converter - template - std::decay_t GetValueForKey(const Json::Value& json, std::string_view key) - { - return GetValueForKey(json, key, ConversionTrait::type>{}); - } - - // Get multiple values for keys (json, k, &v, k, &v, k, &v, ...). - // Uses the default converter for each v. - // Careful: this can cause a template explosion. - constexpr void GetValuesForKeys(const Json::Value& /*json*/) {} - - template - void GetValuesForKeys(const Json::Value& json, std::string_view key1, T&& val1, Args&&... args) - { - GetValueForKey(json, key1, val1); - GetValuesForKeys(json, std::forward(args)...); - } - - // SetValueForKey, type-deduced, manual converter - template - void SetValueForKey(Json::Value& json, std::string_view key, const T& target, Converter&& conv) - { - // We don't want to write any empty optionals into JSON (right now). - if (OptionOracle::HasValue(target)) - { - // demand guarantees that it will return a value or throw an exception - *json.demand(&*key.cbegin(), (&*key.cbegin()) + key.size()) = conv.ToJson(target); - } - } - - // SetValueForKey, type-deduced, with automatic converter - template - void SetValueForKey(Json::Value& json, std::string_view key, const T& target) - { - SetValueForKey(json, key, target, ConversionTrait::type>{}); - } - template struct ConversionTrait { - // Forward-declare these so the linker can pick up specializations from elsewhere! - T FromJson(const Json::Value&); - bool CanConvert(const Json::Value& json); - - Json::Value ToJson(const T& val); - - std::string TypeDescription() const { return ""; } }; template<> @@ -377,7 +251,8 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils std::string TypeDescription() const { - return fmt::format("{}[]", ConversionTrait{}.TypeDescription()); + ConversionTrait trait; + return fmt::format("{}[]", trait.TypeDescription()); } }; @@ -421,7 +296,8 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils for (const auto& [k, v] : val) { - SetValueForKey(json, k, v); + ConversionTrait trait; + *json.demand(&*k.cbegin(), (&*k.cbegin()) + k.size()) = trait.ToJson(v); } return json; @@ -435,7 +311,7 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils #ifdef WINRT_BASE_H template<> - struct ConversionTrait : public ConversionTrait + struct ConversionTrait { // Leverage the wstring converter's validation winrt::hstring FromJson(const Json::Value& json) @@ -459,7 +335,12 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils bool CanConvert(const Json::Value& json) const { // hstring has a specific behavior for null, so it can convert it - return ConversionTrait::CanConvert(json) || json.isNull(); + return ConversionTrait{}.CanConvert(json) || json.isNull(); + } + + std::string TypeDescription() const + { + return "string"; } }; @@ -539,7 +420,7 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils for (const auto& [k, v] : val) { - SetValueForKey(json, til::u16u8(k), v); + //SetValueForKey(json, til::u16u8(k), v); } return json; @@ -709,22 +590,26 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils { winrt::guid FromJson(const Json::Value& json) const { - return static_cast(ConversionTrait{}.FromJson(json)); + ConversionTrait trait; + return static_cast(trait.FromJson(json)); } bool CanConvert(const Json::Value& json) const { - return ConversionTrait{}.CanConvert(json); + ConversionTrait trait; + return trait.CanConvert(json); } Json::Value ToJson(const winrt::guid& val) { - return ConversionTrait{}.ToJson(val); + ConversionTrait trait; + return trait.ToJson(val); } std::string TypeDescription() const { - return ConversionTrait{}.TypeDescription(); + ConversionTrait trait; + return trait.TypeDescription(); } }; @@ -762,11 +647,11 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils template<> struct ConversionTrait { - winrt::Windows::Foundation::Size FromJson(const Json::Value& json) + winrt::Windows::Foundation::Size FromJson(const Json::Value&) { winrt::Windows::Foundation::Size size{}; - GetValueForKey(json, std::string_view("width"), size.Width); - GetValueForKey(json, std::string_view("height"), size.Height); + //GetValueForKey(json, std::string_view("width"), size.Width); + //GetValueForKey(json, std::string_view("height"), size.Height); return size; } @@ -781,12 +666,12 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils return json.isMember("width") && json.isMember("height"); } - Json::Value ToJson(const winrt::Windows::Foundation::Size& val) + Json::Value ToJson(const winrt::Windows::Foundation::Size&) { Json::Value json{ Json::objectValue }; - SetValueForKey(json, std::string_view("width"), val.Width); - SetValueForKey(json, std::string_view("height"), val.Height); + //SetValueForKey(json, std::string_view("width"), val.Width); + //SetValueForKey(json, std::string_view("height"), val.Height); return json; } @@ -804,22 +689,26 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils { winrt::Windows::UI::Color FromJson(const Json::Value& json) const { - return static_cast(ConversionTrait{}.FromJson(json)); + ConversionTrait trait; + return static_cast(trait.FromJson(json)); } bool CanConvert(const Json::Value& json) const { - return ConversionTrait{}.CanConvert(json); + ConversionTrait trait; + return trait.CanConvert(json); } Json::Value ToJson(const winrt::Windows::UI::Color& val) { - return ConversionTrait{}.ToJson(val); + ConversionTrait trait; + return trait.ToJson(val); } std::string TypeDescription() const { - return ConversionTrait{}.TypeDescription(); + ConversionTrait trait; + return trait.TypeDescription(); } }; #endif @@ -1055,6 +944,131 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils return "any"; } }; + + // Method Description: + // - Helper that will populate a reference with a value converted from a json object. + // Arguments: + // - json: the json object to convert + // - target: the value to populate with the converted result + // Return Value: + // - a boolean indicating whether the value existed (in this case, was non-null) + // + // GetValue, type-deduced, manual converter + template + bool GetValue(const Json::Value& json, T& target, Converter&& conv) + { + if (!conv.CanConvert(json)) + { + DeserializationError e{ json }; + e.expectedType = conv.TypeDescription(); + throw e; + } + + target = conv.FromJson(json); + return true; + } + + // GetValue, forced return type, manual converter + template + std::decay_t GetValue(const Json::Value& json, Converter&& conv) + { + std::decay_t local{}; + GetValue(json, local, std::forward(conv)); + return local; // returns zero-initialized or value + } + + // GetValueForKey, type-deduced, manual converter + template + bool GetValueForKey(const Json::Value& json, std::string_view key, T& target, Converter&& conv) + { + if (auto found{ json.find(&*key.cbegin(), (&*key.cbegin()) + key.size()) }) + { + try + { + return GetValue(*found, target, std::forward(conv)); + } + catch (DeserializationError& e) + { + e.SetKey(key); + throw; // rethrow now that it has a key + } + } + return false; + } + + // GetValueForKey, forced return type, manual converter + template + std::decay_t GetValueForKey(const Json::Value& json, std::string_view key, Converter&& conv) + { + std::decay_t local{}; + GetValueForKey(json, key, local, std::forward(conv)); + return local; // returns zero-initialized? + } + + // GetValue, type-deduced, with automatic converter + template + bool GetValue(const Json::Value& json, T& target) + { + ConversionTrait> trait; + return GetValue(json, target, trait); + } + + // GetValue, forced return type, with automatic converter + template + std::decay_t GetValue(const Json::Value& json) + { + std::decay_t local{}; + ConversionTrait> trait; + GetValue(json, local, trait); + return local; // returns zero-initialized or value + } + + // GetValueForKey, type-deduced, with automatic converter + template + bool GetValueForKey(const Json::Value& json, std::string_view key, T& target) + { + ConversionTrait> trait; + return GetValueForKey(json, key, target, trait); + } + + // GetValueForKey, forced return type, with automatic converter + template + std::decay_t GetValueForKey(const Json::Value& json, std::string_view key) + { + ConversionTrait> trait; + return GetValueForKey(json, key, trait); + } + + // Get multiple values for keys (json, k, &v, k, &v, k, &v, ...). + // Uses the default converter for each v. + // Careful: this can cause a template explosion. + constexpr void GetValuesForKeys(const Json::Value& /*json*/) {} + + template + void GetValuesForKeys(const Json::Value& json, std::string_view key1, T&& val1, Args&&... args) + { + GetValueForKey(json, key1, val1); + GetValuesForKeys(json, std::forward(args)...); + } + + // SetValueForKey, type-deduced, manual converter + template + void SetValueForKey(Json::Value& json, std::string_view key, const T& target, Converter&& conv) + { + // We don't want to write any empty optionals into JSON (right now). + if (OptionOracle::HasValue(target)) + { + // demand guarantees that it will return a value or throw an exception + *json.demand(&*key.cbegin(), (&*key.cbegin()) + key.size()) = conv.ToJson(target); + } + } + + // SetValueForKey, type-deduced, with automatic converter + template + void SetValueForKey(Json::Value& json, std::string_view key, const T& target) + { + SetValueForKey(json, key, target, ConversionTrait::type>{}); + } }; #define JSON_ENUM_MAPPER(...) \ diff --git a/src/cascadia/TerminalSettingsModel/KeyChordSerialization.h b/src/cascadia/TerminalSettingsModel/KeyChordSerialization.h index 3f80c9204..d18007c65 100644 --- a/src/cascadia/TerminalSettingsModel/KeyChordSerialization.h +++ b/src/cascadia/TerminalSettingsModel/KeyChordSerialization.h @@ -4,7 +4,6 @@ #pragma once #include "KeyChordSerialization.g.h" -#include "JsonUtils.h" #include "../inc/cppwinrt_utils.h" namespace winrt::Microsoft::Terminal::Settings::Model::implementation diff --git a/src/cascadia/TerminalSettingsModel/Profile.h b/src/cascadia/TerminalSettingsModel/Profile.h index db715f07a..0a2152158 100644 --- a/src/cascadia/TerminalSettingsModel/Profile.h +++ b/src/cascadia/TerminalSettingsModel/Profile.h @@ -49,7 +49,6 @@ Author(s): #include "MTSMSettings.h" #include "../inc/cppwinrt_utils.h" -#include "JsonUtils.h" #include #include "AppearanceConfig.h" #include "FontConfig.h" diff --git a/src/cascadia/TerminalSettingsModel/pch.h b/src/cascadia/TerminalSettingsModel/pch.h index 25773a45d..f0ced10ce 100644 --- a/src/cascadia/TerminalSettingsModel/pch.h +++ b/src/cascadia/TerminalSettingsModel/pch.h @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. // // pch.h @@ -43,11 +43,13 @@ // Including TraceLogging essentials for the binary #include -#include TRACELOGGING_DECLARE_PROVIDER(g_hSettingsModelProvider); #include #include +#include +#include + // JsonCpp #include