Repository: microsoft/terminal
File: src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp (C++)

Code before:
    // as DefaultTerminal::Available creates the exact same issue.
    std::pair<std::vector<Model::DefaultTerminal>, Model::DefaultTerminal> result{ {}, nullptr };
    til::latch latch{ 1 };

    std::ignore = [&]() -> winrt::fire_and_forget {
        const auto cleanup = wil::scope_exit([&]() {
            latch.count_down();
        });
        co_await winrt::resume_background();
        result = DefaultTerminal::Available();
    }();

    latch.wait();
    _defaultTerminals = winrt::single_threaded_observable_vector(std::move(result.first));
    _currentDefaultTerminal = std::move(result.second);
}

void CascadiaSettings::ExportFile(winrt::hstring path, winrt::hstring content)
{
    try
    {
        WriteUTF8FileAtomic({ path.c_str() }, til::u16u8(content));
    }
    CATCH_LOG();
}
winrt::hstring CascadiaSettings::ReadFile(winrt::hstring path)
{
    try
    {
        auto maybeContents = ReadUTF8FileIfExists({ path.c_str() });
        if (maybeContents.has_value())
        {
            return winrt::hstring{ til::u8u16(*maybeContents) };
        }
    }
    CATCH_LOG();

    return L"";
}

void CascadiaSettings::_validateThemeExists()
{
    const auto& themes{ _globals->Themes() };
    if (themes.Size() == 0)
    {
        // We didn't even load the default themes. This should only be possible
        // if the defaults.json didn't include any themes, or if no
        // defaults.json was loaded at all. The second case is especially common
        // in tests (that don't bother with a defaults.json). No matter. Create
        // a default theme under `system` and just stick it in there.


Review comment (suggestion):
You're only using this in one spot and this function is basically a WinRT wrapper for `ReadUTF8FileIfExists()`. You can probably remove it and just call `ReadUTF8FileIfExists()` over there.

Code after:
    // as DefaultTerminal::Available creates the exact same issue.
    std::pair<std::vector<Model::DefaultTerminal>, Model::DefaultTerminal> result{ {}, nullptr };
    til::latch latch{ 1 };

    std::ignore = [&]() -> winrt::fire_and_forget {
        const auto cleanup = wil::scope_exit([&]() {
            latch.count_down();
        });
        co_await winrt::resume_background();
        result = DefaultTerminal::Available();
    }();

    latch.wait();
    _defaultTerminals = winrt::single_threaded_observable_vector(std::move(result.first));
    _currentDefaultTerminal = std::move(result.second);
}

void CascadiaSettings::_validateThemeExists()
{
    const auto& themes{ _globals->Themes() };
    if (themes.Size() == 0)
    {
        // We didn't even load the default themes. This should only be possible
        // if the defaults.json didn't include any themes, or if no
        // defaults.json was loaded at all. The second case is especially common
        // in tests (that don't bother with a defaults.json). No matter. Create
        // a default theme under `system` and just stick it in there.

        auto newTheme = winrt::make_self<Theme>();
        newTheme->Name(L"system");
        _globals->AddTheme(*newTheme);
        _globals->Theme(Model::ThemePair{ L"system" });
    }

    const auto& theme{ _globals->Theme() };
    if (theme.DarkName() == theme.LightName())
    {
        // Only one theme. We'll treat it as such.
        if (!themes.HasKey(theme.DarkName()))
        {
            _warnings.Append(SettingsLoadWarnings::UnknownTheme);
            // safely fall back to system as the theme.
            _globals->Theme(*winrt::make_self<ThemePair>(L"system"));
        }
    }
    else
    {
        // Two different themes. Check each separately, and fall back to a
        // reasonable default contextually
        if (!themes.HasKey(theme.LightName()))
        {