Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert most of our JSON deserializers to use type-based conversion #6590

Merged
27 commits merged into from
Jul 17, 2020

Conversation

DHowett
Copy link
Member

@DHowett DHowett commented Jun 19, 2020

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.

@DHowett
Copy link
Member Author

DHowett commented Jun 19, 2020

image
image

src/cascadia/TerminalApp/GlobalAppSettings.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/GlobalAppSettings.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/Profile.cpp Show resolved Hide resolved
src/cascadia/TerminalApp/Profile.cpp Show resolved Hide resolved
src/cascadia/TerminalApp/Profile.h Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/ProfileConversionTraits.cpp Outdated Show resolved Hide resolved
@DHowett DHowett marked this pull request as draft June 19, 2020 16:33
Copy link
Member

@carlos-zamora carlos-zamora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh. Most of my review was mostly admiring this:
+456, -1145 PR diff

Submitting a review so that I can just see the new changes next time I come around.

src/cascadia/TerminalApp/JsonUtilsNew.h Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/ActionArgs.h Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/GlobalAppSettings.cpp Outdated Show resolved Hide resolved
Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm certainly not about to block this while I'm gone, though, there are still TODOs and I've got questions, so I'm just gonna "comment"

src/cascadia/TerminalApp/ActionArgs.h Outdated Show resolved Hide resolved
{ "keys": ["ctrl+g"], "command": { "action": "splitPane" } },
{ "keys": ["ctrl+h"], "command": { "action": "splitPane", "split": "auto" } },
{ "keys": ["ctrl+i"], "command": { "action": "splitPane", "split": "foo" } }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add back a test case that ensures a warning was returned for this case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, this causes a whole settings parsing failure... but the specific case of deserializing an unknown enum member is actually handled in the JsonUtilsTests. Should we have one specifically for a "known type of flag"?

src/cascadia/TerminalApp/JsonUtilsNew.h Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/ProfileConversionTraits.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/ProfileConversionTraits.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/Profile.cpp Show resolved Hide resolved
@@ -334,6 +363,18 @@ namespace TerminalApp::JsonUtils
template<typename T, typename Converter>
bool GetValue(const Json::Value& json, T& target, Converter&& conv)
{
if constexpr (Detail::DeduceOptional<T>::IsOptional)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wat the heck is this witchcraft

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if constexpr is SO GOOD. It's like, "only compile this block of code if this thing is true"

it's like std::enable_if but for an actual individual block of code instead of how enable_if uses the failure of a type to be well-formed to "hide" it from existence

@DHowett DHowett force-pushed the dev/duhowett/json-2-new branch from 6122eb8 to f20b623 Compare July 12, 2020 23:36
ghost pushed a commit that referenced this pull request Jul 13, 2020
…6890)

This commit updates JsonUtilsNew to support winrt
`Windows::Foundation::IReference<T>` as an option type, and cleans up the
optional support code by removing the optional overload on
`GetValue(...)`. Instead of using an overload with a partial
specialization, we're using a constexpr if with a type trait to
determine option-type-ness.

In addition, Carlos reported an issue with deriving from `FlagMapper`
(itself templated) and referring to the base type's members without
fully qualifying them. To make derivation easier, `EnumMapper` and
`FlagMapper` now provide `BaseEnumMapper` and `BaseFlagMapper` type
aliases.

I've taken the opportunity to add a `winrt::hstring` conversion
trait.

Lastly, in casual use, I found out that I'd written the til::color
converter wrong: it supports color strings of length 7 (`#rrggbb`) and
length 4 (`#rgb`). I mistyped (and failed to test) support for 4-length
color strings by pretending they were only 3 characters long.

## References

Merged JsonUtils changes from #6004 and #6590.

## PR Checklist
* [x] Unblocks aforementioned PRs
* [x] cla
* [x] Tests added/passed
* [x] Documentation N/A
* [x] Schema N/A
* [x] Kid tested, mother approved.
@DHowett DHowett force-pushed the dev/duhowett/json-2-new branch from f20b623 to 16ab0ae Compare July 14, 2020 07:04
Move all settings types out of globalapp/profile into SettingsTypes.

**EVENTUALLY** they will become exported types from the Terminal
Settings Model library. This is a temporary stopgap.

I added a ValueType convenience helper to EnumMapper so you don't have
to repeat a really obscenely long fully-qualified namespace name for
every mapped value.
Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's ship this, this is great. It'll break all the in-flight PRs, but hey, lets just do it.

@zadjii-msft zadjii-msft added Area-CodeHealth Issues related to code cleanliness, linting, rules, warnings, errors, static analysis, etc. Area-Settings Issues related to settings and customizability, for console or terminal Product-Terminal The new Windows Terminal. labels Jul 14, 2020
src/cascadia/TerminalApp/ActionArgs.h Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/JsonUtilsNew.h Outdated Show resolved Hide resolved
@DHowett
Copy link
Member Author

DHowett commented Jul 14, 2020

So we're still keeping the strings separate? I'm ok with it, but is there a benefit/cost to putting the strings directly into the pair_types? You don't do that in one of the other files.

forgot the ones in binding serialization, thanks

@ghost ghost added the Issue-Task It's a feature request, but it doesn't really need a major design. label Jul 15, 2020
@DHowett DHowett marked this pull request as ready for review July 15, 2020 00:57
@DHowett
Copy link
Member Author

DHowett commented Jul 15, 2020

Net code removed: 773 lines.

@DHowett DHowett changed the title Convert most of our JSON deserializers to JsonUtilsNew Convert most of our JSON deserializers to to use type-based conversion Jul 15, 2020
@DHowett DHowett changed the title Convert most of our JSON deserializers to to use type-based conversion Convert most of our JSON deserializers to use type-based conversion Jul 15, 2020
@DHowett
Copy link
Member Author

DHowett commented Jul 15, 2020

I am blocking this until 1.3.

@DHowett DHowett added the AutoMerge Marked for automatic merge by the bot when requirements are met label Jul 17, 2020
@ghost
Copy link

ghost commented Jul 17, 2020

Hello @DHowett!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit efb1fdd into master Jul 17, 2020
@ghost ghost deleted the dev/duhowett/json-2-new branch July 17, 2020 01:31
@ghost
Copy link

ghost commented Aug 26, 2020

🎉Windows Terminal Preview v1.3.2382.0 has been released which incorporates this pull request.:tada:

Handy links:

@ghost ghost mentioned this pull request Aug 26, 2020
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-CodeHealth Issues related to code cleanliness, linting, rules, warnings, errors, static analysis, etc. Area-Settings Issues related to settings and customizability, for console or terminal AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Task It's a feature request, but it doesn't really need a major design. Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add more _templated_ JsonUtils
3 participants