Skip to content

Commit 6122eb8

Browse files
committed
JsonUtils: remove Optional specializations, use constexpr if, add IReference
1 parent f5d1a6b commit 6122eb8

File tree

1 file changed

+45
-34
lines changed

1 file changed

+45
-34
lines changed

src/cascadia/TerminalApp/JsonUtilsNew.h

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ Author(s):
2020

2121
namespace winrt
2222
{
23-
// If we don't use winrt, nobody will include the ConversionTrait for winrt::guid.
24-
// If nobody includes it, this forward declaration will suffice.
23+
// If we don't use winrt, nobody will include the ConversionTraits for winrt stuff.
24+
// If nobody includes it, these forward declarations will suffice.
2525
struct guid;
26+
struct hstring;
27+
namespace Windows::Foundation
28+
{
29+
template<typename T>
30+
struct IReference;
31+
}
2632
}
2733

2834
namespace TerminalApp::JsonUtils
@@ -45,12 +51,21 @@ namespace TerminalApp::JsonUtils
4551
struct DeduceOptional
4652
{
4753
using Type = typename std::decay<T>::type;
54+
static constexpr bool IsOptional = false;
4855
};
4956

5057
template<typename TOpt>
5158
struct DeduceOptional<std::optional<TOpt>>
5259
{
5360
using Type = typename std::decay<TOpt>::type;
61+
static constexpr bool IsOptional = true;
62+
};
63+
64+
template<typename TOpt>
65+
struct DeduceOptional<::winrt::Windows::Foundation::IReference<TOpt>>
66+
{
67+
using Type = typename std::decay<TOpt>::type;
68+
static constexpr bool IsOptional = true;
5469
};
5570
}
5671

@@ -105,7 +120,9 @@ namespace TerminalApp::JsonUtils
105120
template<typename T>
106121
struct ConversionTrait
107122
{
108-
// FromJson, CanConvert are not defined so as to cause a compile error (which forces a specialization)
123+
// Forward-declare these so the linker can pick up specializations from elsewhere!
124+
T FromJson(const Json::Value&);
125+
bool CanConvert(const Json::Value& json);
109126
};
110127

111128
template<>
@@ -136,6 +153,18 @@ namespace TerminalApp::JsonUtils
136153
}
137154
};
138155

156+
#ifdef WINRT_BASE_H
157+
template<>
158+
struct ConversionTrait<winrt::hstring> : public ConversionTrait<std::wstring>
159+
{
160+
// Leverage the wstring converter's validation
161+
winrt::hstring FromJson(const Json::Value& json)
162+
{
163+
return winrt::hstring{ til::u8u16(Detail::GetStringView(json)) };
164+
}
165+
};
166+
#endif
167+
139168
template<>
140169
struct ConversionTrait<bool>
141170
{
@@ -248,7 +277,7 @@ namespace TerminalApp::JsonUtils
248277
}
249278

250279
const auto string{ Detail::GetStringView(json) };
251-
return (string.length() == 7 || string.length() == 3) && string.front() == '#';
280+
return (string.length() == 7 || string.length() == 4) && string.front() == '#';
252281
}
253282
};
254283

@@ -334,6 +363,18 @@ namespace TerminalApp::JsonUtils
334363
template<typename T, typename Converter>
335364
bool GetValue(const Json::Value& json, T& target, Converter&& conv)
336365
{
366+
if constexpr (Detail::DeduceOptional<T>::IsOptional)
367+
{
368+
// FOR OPTION TYPES
369+
// - If the json object is set to `null`, then
370+
// we'll instead set the target back to the empty optional.
371+
if (json.isNull())
372+
{
373+
target = T{}; // zero-construct an empty optional
374+
return true;
375+
}
376+
}
377+
337378
if (json)
338379
{
339380
if (!conv.CanConvert(json))
@@ -347,36 +388,6 @@ namespace TerminalApp::JsonUtils
347388
return false;
348389
}
349390

350-
// Method Description:
351-
// - Overload on GetValue that will populate a std::optional with a value converted from json
352-
// - If the json value doesn't exist we'll leave the target object unmodified.
353-
// - If the json object is set to `null`, then
354-
// we'll instead set the target back to nullopt.
355-
// Arguments:
356-
// - json: the json object to convert
357-
// - target: the value to populate with the converted result
358-
// Return Value:
359-
// - a boolean indicating whether the optional was changed
360-
//
361-
// GetValue, type-deduced for optional, manual converter
362-
template<typename TOpt, typename Converter>
363-
bool GetValue(const Json::Value& json, std::optional<TOpt>& target, Converter&& conv)
364-
{
365-
if (json.isNull())
366-
{
367-
target = std::nullopt;
368-
return true; // null is valid for optionals
369-
}
370-
371-
std::decay_t<TOpt> local{};
372-
if (GetValue(json, local, std::forward<Converter>(conv)))
373-
{
374-
target = std::move(local);
375-
return true;
376-
}
377-
return false;
378-
}
379-
380391
// GetValue, forced return type, manual converter
381392
template<typename T, typename Converter>
382393
std::decay_t<T> GetValue(const Json::Value& json, Converter&& conv)

0 commit comments

Comments
 (0)