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 }