winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ManifestLocalization.h (4480B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #pragma once
      4 #include <winget/ManifestCommon.h>
      5 #include <AppInstallerStrings.h>
      6 
      7 #include <variant>
      8 
      9 namespace AppInstaller::Manifest
     10 {
     11     using string_t = Utility::NormalizedString;
     12 
     13     enum class Localization : size_t
     14     {
     15         Publisher,
     16         PublisherUrl,
     17         PublisherSupportUrl,
     18         PrivacyUrl,
     19         Author,
     20         PackageName,
     21         PackageUrl,
     22         License,
     23         LicenseUrl,
     24         Copyright,
     25         CopyrightUrl,
     26         ShortDescription,
     27         Description,
     28         Tags,
     29         Agreements,
     30         Documentations,
     31         ReleaseNotes,
     32         ReleaseNotesUrl,
     33         PurchaseUrl,
     34         InstallationNotes,
     35         Icons,
     36         Max
     37     };
     38 
     39     struct Agreement
     40     {
     41         string_t Label;
     42         string_t AgreementText;
     43         string_t AgreementUrl;
     44     };
     45 
     46     struct Documentation
     47     {
     48         string_t DocumentLabel;
     49         string_t DocumentUrl;
     50     };
     51 
     52     struct Icon
     53     {
     54         string_t Url;
     55         IconFileTypeEnum FileType = IconFileTypeEnum::Unknown;
     56         IconResolutionEnum Resolution = IconResolutionEnum::Unknown;
     57         IconThemeEnum Theme = IconThemeEnum::Unknown;
     58         std::vector<BYTE> Sha256;
     59     };
     60 
     61     namespace details
     62     {
     63         template <Localization L>
     64         struct LocalizationMapping
     65         {
     66             using value_t = string_t;
     67         };
     68 
     69         template <>
     70         struct LocalizationMapping<Localization::Tags>
     71         {
     72             using value_t = std::vector<string_t>;
     73         };
     74 
     75         template <>
     76         struct LocalizationMapping<Localization::Agreements>
     77         {
     78             using value_t = std::vector<Agreement>;
     79         };
     80 
     81         template <>
     82         struct LocalizationMapping<Localization::Documentations>
     83         {
     84             using value_t = std::vector<Documentation>;
     85         };
     86 
     87         template <>
     88         struct LocalizationMapping<Localization::Icons>
     89         {
     90             using value_t = std::vector<Icon>;
     91         };
     92 
     93         // Used to deduce the LocalizationVariant type; making a variant that includes std::monostate and all LocalizationMapping types.
     94         template <size_t... I>
     95         inline auto Deduce(std::index_sequence<I...>) { return std::variant<std::monostate, typename LocalizationMapping<static_cast<Localization>(I)>::value_t...>{}; }
     96 
     97         // Holds data of any type listed in a LocalizationMapping.
     98         using LocalizationVariant = decltype(Deduce(std::make_index_sequence<static_cast<size_t>(Localization::Max)>()));
     99 
    100         // Gets the index into the variant for the given Localization.
    101         constexpr inline size_t LocalizationIndex(Localization l) { return static_cast<size_t>(l) + 1; }
    102     }
    103 
    104     struct ManifestLocalization
    105     {
    106         string_t Locale;
    107 
    108         // Adds a value to the Localization data, or overwrites an existing entry.
    109         template <Localization L>
    110         void Add(typename details::LocalizationMapping<L>::value_t&& v)
    111         {
    112             m_data[L].emplace<details::LocalizationIndex(L)>(std::forward<typename details::LocalizationMapping<L>::value_t>(v));
    113         }
    114         template <Localization L>
    115         void Add(const typename details::LocalizationMapping<L>::value_t& v)
    116         {
    117             m_data[L].emplace<details::LocalizationIndex(L)>(v);
    118         }
    119 
    120         // Return a value indicating whether the given localization type exists.
    121         bool Contains(Localization l) const { return (m_data.find(l) != m_data.end()); }
    122 
    123         // Gets the localization value if exists, otherwise empty for easier access
    124         template <Localization L>
    125         typename details::LocalizationMapping<L>::value_t Get() const
    126         {
    127             auto itr = m_data.find(L);
    128             if (itr == m_data.end())
    129             {
    130                 return {};
    131             }
    132             else
    133             {
    134                 return std::get<details::LocalizationIndex(L)>(itr->second);
    135             }
    136         }
    137 
    138         void ReplaceOrMergeWith(const ManifestLocalization& other)
    139         {
    140             for (auto const& entry : other.m_data)
    141             {
    142                 this->m_data[entry.first] = entry.second;
    143             }
    144 
    145             this->Locale = other.Locale;
    146         }
    147 
    148     private:
    149         std::map<Localization, details::LocalizationVariant> m_data;
    150     };
    151 }