terminal/src/cascadia/TerminalApp/Utils.h
Dustin L. Howett efb1fddb99
Convert most of our JSON deserializers to use type-based conversion (#6590)
This pull request converts the following JSON deserializers to use the
new JSON deserializer pattern:

* Profile
* Command
* ColorScheme
* Action/Args
* GlobalSettings
* CascadiaSettingsSerialization

This is the completion of a long-term JSON refactoring that makes our
parser and deserializer more type-safe and robust. We're finally able to
get rid of all our manual enum conversion code and unify JSON conversion
around _types_ instead of around _keys_.

I've introduced another file filled with template specializations,
TerminalSettingsSerializationHelpers.h, which comprises a single unit
that holds all of the JSON deserializers (and eventually serializers)
for every type that comes from TerminalApp or TerminalSettings.

I've also moved some types out of Profile and GlobalAppSettings into a
new SettingsTypes.h to improve settings locality.

This does to some extent constitute a breaking change for already-broken
settings. Instead of parsing "successfully" (where invalid values are
null or 0 or unknown or unset), deserialization will now fail when
there's a type mismatch. Because of that, some tests had to be removed.

While I was on a refactoring spree, I removed a number of helpless
helpers, like GetWstringFromJson (which converted a u8 string to an
hstring to make a wstring out of its data pointer :|) and
_ConvertJsonToBool.

In the future, we can make the error types more robust and give them
position and type information such that a conformant application can
display rich error information ("line 3 column 3, I expected a string,
you gave me an integer").

Closes #2550.
2020-07-17 01:31:09 +00:00

118 lines
3.3 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- Utils.h
Abstract:
- Helpers for the TerminalApp project
Author(s):
- Mike Griese - May 2019
--*/
#pragma once
// Method Description:
// - Create a std::string from a string_view. We do this because we can't look
// up a key in a Json::Value with a string_view directly, so instead we'll use
// this helper. Should a string_view lookup ever be added to jsoncpp, we can
// remove this entirely.
// Arguments:
// - key: the string_view to build a string from
// Return Value:
// - a std::string to use for looking up a value from a Json::Value
inline std::string JsonKey(const std::string_view key)
{
return static_cast<std::string>(key);
}
// This is a pair of helpers for determining if a pair of guids are equal, and
// establishing an ordering on GUIDs (via std::less).
namespace std
{
template<>
struct less<GUID>
{
bool operator()(const GUID& lhs, const GUID& rhs) const
{
return memcmp(&lhs, &rhs, sizeof(rhs)) < 0;
}
};
template<>
struct equal_to<GUID>
{
bool operator()(const GUID& lhs, const GUID& rhs) const
{
return memcmp(&lhs, &rhs, sizeof(rhs)) == 0;
}
};
}
namespace winrt::Microsoft::UI::Xaml::Controls
{
struct IconSource;
struct BitmapIconSource;
}
namespace winrt::Windows::UI::Xaml::Controls
{
struct IconSource;
struct BitmapIconSource;
}
namespace Microsoft::TerminalApp::details
{
// This is a template that helps us figure out which BitmapIconSource to use for a given IconSource.
// We have to do this because some of our code still wants to use WUX IconSources.
template<typename TIconSource>
struct BitmapIconSource
{
};
template<>
struct BitmapIconSource<winrt::Microsoft::UI::Xaml::Controls::IconSource>
{
using type = winrt::Microsoft::UI::Xaml::Controls::BitmapIconSource;
};
template<>
struct BitmapIconSource<winrt::Windows::UI::Xaml::Controls::IconSource>
{
using type = winrt::Windows::UI::Xaml::Controls::BitmapIconSource;
};
}
// Method Description:
// - Creates an IconElement for the given path. The icon returned is a colored
// icon. If we couldn't create the icon for any reason, we return an empty
// IconElement.
// Template Types:
// - <TIconSource>: The type of IconSource (MUX, WUX) to generate.
// Arguments:
// - path: the full, expanded path to the icon.
// Return Value:
// - An IconElement with its IconSource set, if possible.
template<typename TIconSource>
TIconSource GetColoredIcon(const winrt::hstring& path)
{
if (!path.empty())
{
try
{
winrt::Windows::Foundation::Uri iconUri{ path };
::Microsoft::TerminalApp::details::BitmapIconSource<TIconSource>::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.
iconSource.ShowAsMonochrome(false);
iconSource.UriSource(iconUri);
return iconSource;
}
CATCH_LOG();
}
return nullptr;
}