terminal/src/cascadia/TerminalSettingsModel
Dustin L. Howett 3a5c33b005
Rework JsonUtils' optional handling to let Converters see null (#8175)
The JsonUtils changes in #8018 revealed that we need more robust,
configurable optional handling. We learned that there's a class of
values that was previously underrepresented in our API: _strings that
have an explicit empty value_.

The Settings model supports starting directory, icon, background image
et al values that are empty. That emptiness _overrides_ a value set in a
lower layer, so it is not sufficient to represent the empty value for
any one of those fields as an unset optional.

There are a couple other settings for which we've implemented a
hand-rolled option type (for roughly the same reason): foreground,
background, any color fields that override values from the color scheme
_or_ the lower layer profile.

These requirements are best fulfilled by better optional support in
JsonUtils. Where the library would originally detect known types of
optional and pre-filter them out during `GetValue` and `SetValue`, it
will now defer to another conversion trait.

This commit introduces a helper conversion trait and an "option oracle".
The conversion trait will use the option oracle to detect emptiness,
generate empty option values, and read values out of option types. In so
doing, the trait is insulated from the implementation details of any
specific option type.

Any special logic for handling JSON null and option types has been
stripped from GetValue. Due to this, there is an express change in
behavior for some converters:

* `GetValue<T>(jsonNull)` where `T` is **not** an option type[1] has
  been upgraded from a silent no-op to an exception.

Further, I took the opportunity to replace NullableSetting with
std::optional<std::optional<T>>, which accurately represents "setting
that the user might explicitly clear". I've added a test to
JsonUtilsTests to make sure it can serialize/deserialize double
optionals the way we expect it to.

Tests (Local, Unit for TerminalApp/SettingsModel):
Summary: Total=140, Passed=140, Failed=0, Blocked=0, Not Run=0, Skipped=0

[1]: Explicitly, if `T` is not an option type _and the converter does
not support null_.
2020-11-09 15:13:02 -08:00
..
dll Remove all our path antics; force native projects to bin/, obj/ (#8062) 2020-10-27 15:00:41 -07:00
Resources/en-US Add openTabRenamer action (#7462) 2020-10-28 19:36:30 +00:00
ActionAndArgs.cpp Add openTabRenamer action (#7462) 2020-10-28 19:36:30 +00:00
ActionAndArgs.h Implement CascadiaSettings::Copy() (#7877) 2020-10-16 15:14:11 -07:00
ActionArgs.cpp add rowsToScroll to scrollUp/Down w/ fallback to system default (#7924) 2020-10-26 18:19:52 -07:00
ActionArgs.h add rowsToScroll to scrollUp/Down w/ fallback to system default (#7924) 2020-10-26 18:19:52 -07:00
ActionArgs.idl add rowsToScroll to scrollUp/Down w/ fallback to system default (#7924) 2020-10-26 18:19:52 -07:00
AzureCloudShellGenerator.cpp Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
AzureCloudShellGenerator.h Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
CascadiaSettings.cpp Store and expose hidden profiles (#8070) 2020-10-28 16:22:26 +00:00
CascadiaSettings.h Store and expose hidden profiles (#8070) 2020-10-28 16:22:26 +00:00
CascadiaSettings.idl Store and expose hidden profiles (#8070) 2020-10-28 16:22:26 +00:00
CascadiaSettingsSerialization.cpp Update active profiles when loading defaults (#8156) 2020-11-04 23:57:15 +00:00
ColorScheme.cpp Implement CascadiaSettings::Copy() (#7877) 2020-10-16 15:14:11 -07:00
ColorScheme.h Implement CascadiaSettings::Copy() (#7877) 2020-10-16 15:14:11 -07:00
ColorScheme.idl Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
Command.cpp Implement CascadiaSettings::Copy() (#7877) 2020-10-16 15:14:11 -07:00
Command.h Implement CascadiaSettings::Copy() (#7877) 2020-10-16 15:14:11 -07:00
Command.idl Introduce IconConverter (#7830) 2020-10-08 11:29:04 -07:00
DefaultProfileUtils.cpp Make Global and Profile settings inheritable (#7923) 2020-10-27 17:35:09 +00:00
DefaultProfileUtils.h Make Global and Profile settings inheritable (#7923) 2020-10-27 17:35:09 +00:00
defaults-universal.json From orbit, nuke the Telnet connection and all supporting infra. (#7840) 2020-10-09 18:59:58 +00:00
defaults.json Allow the user to use the tab switcher with in-order tab switching (#8076) 2020-11-05 14:28:16 +00:00
GlobalAppSettings.cpp Allow the user to use the tab switcher with in-order tab switching (#8076) 2020-11-05 14:28:16 +00:00
GlobalAppSettings.h Allow the user to use the tab switcher with in-order tab switching (#8076) 2020-11-05 14:28:16 +00:00
GlobalAppSettings.idl Allow the user to use the tab switcher with in-order tab switching (#8076) 2020-11-05 14:28:16 +00:00
IDynamicProfileGenerator.h Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
IInheritable.h Rework JsonUtils' optional handling to let Converters see null (#8175) 2020-11-09 15:13:02 -08:00
init.cpp Hook up the WIL fallback error tracer in Terminal (#7864) 2020-10-09 22:20:12 +00:00
JsonUtils.h Rework JsonUtils' optional handling to let Converters see null (#8175) 2020-11-09 15:13:02 -08:00
KeyChordSerialization.cpp Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
KeyChordSerialization.h Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
KeyChordSerialization.idl Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
KeyMapping.cpp Implement CascadiaSettings::Copy() (#7877) 2020-10-16 15:14:11 -07:00
KeyMapping.h Implement CascadiaSettings::Copy() (#7877) 2020-10-16 15:14:11 -07:00
KeyMapping.idl Add openTabRenamer action (#7462) 2020-10-28 19:36:30 +00:00
KeyMappingSerialization.cpp Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
LegacyProfileGeneratorNamespaces.h From orbit, nuke the Telnet connection and all supporting infra. (#7840) 2020-10-09 18:59:58 +00:00
Microsoft.Terminal.Settings.ModelLib.vcxproj Remove all our path antics; force native projects to bin/, obj/ (#8062) 2020-10-27 15:00:41 -07:00
Microsoft.Terminal.Settings.ModelLib.vcxproj.filters Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
packages.config Update C++/WinRT to 2.0.201017.1 (#8061) 2020-10-27 20:15:30 +00:00
pch.cpp Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
pch.h Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
PowershellCoreProfileGenerator.cpp Introduce IconConverter (#7830) 2020-10-08 11:29:04 -07:00
PowershellCoreProfileGenerator.h Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
Profile.cpp Rework JsonUtils' optional handling to let Converters see null (#8175) 2020-11-09 15:13:02 -08:00
Profile.h Make Global and Profile settings inheritable (#7923) 2020-10-27 17:35:09 +00:00
Profile.idl Make Global and Profile settings inheritable (#7923) 2020-10-27 17:35:09 +00:00
SettingsTypes.h Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
TerminalSettingsSerializationHelpers.h Allow the user to use the tab switcher with in-order tab switching (#8076) 2020-11-05 14:28:16 +00:00
TerminalWarnings.h Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
TerminalWarnings.idl Display a warning for when we fail to write to the settings file (#7950) 2020-10-23 00:21:07 +00:00
userDefaults.json Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00
WslDistroGenerator.cpp Introduce IconConverter (#7830) 2020-10-08 11:29:04 -07:00
WslDistroGenerator.h Introduce TerminalSettingsModel project (#7667) 2020-10-06 09:56:59 -07:00