winget-cli

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

ManifestComparator.h (5202B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #pragma once
      4 #include <winget/Manifest.h>
      5 #include <memory>
      6 #include <optional>
      7 #include <string>
      8 #include <string_view>
      9 #include <utility>
     10 #include <vector>
     11 
     12 
     13 namespace AppInstaller::Manifest
     14 {
     15     // Flags to indicate why an installer was not applicable
     16     enum class InapplicabilityFlags : int
     17     {
     18         None = 0x0,
     19         OSVersion = 0x1,
     20         InstalledScope = 0x2,
     21         InstalledType = 0x4,
     22         InstalledLocale = 0x8,
     23         Locale = 0x10,
     24         Scope = 0x20,
     25         MachineArchitecture = 0x40,
     26         Market = 0x80,
     27         InstallerType = 0x100,
     28     };
     29 
     30     DEFINE_ENUM_FLAG_OPERATORS(InapplicabilityFlags);
     31 
     32     namespace details
     33     {
     34         // An interface for defining new filters based on user inputs.
     35         struct FilterField
     36         {
     37             FilterField(std::string_view name) : m_name(name) {}
     38 
     39             virtual ~FilterField() = default;
     40 
     41             std::string_view Name() const { return m_name; }
     42 
     43             // Determines if the installer is applicable based on this field alone.
     44             virtual InapplicabilityFlags IsApplicable(const AppInstaller::Manifest::ManifestInstaller& installer) = 0;
     45 
     46             // Explains why the filter regarded this installer as inapplicable.
     47             // Will only be called when IsApplicable returns false.
     48             virtual std::string ExplainInapplicable(const AppInstaller::Manifest::ManifestInstaller& installer) = 0;
     49 
     50         private:
     51             std::string_view m_name;
     52         };
     53 
     54         // The result of ComparisonField::IsFirstBetter
     55         enum class ComparisonResult
     56         {
     57             // The first input is not better than the second input.
     58             Negative,
     59             // The first input is somewhat better than the second input.
     60             // If another comparison has a strong positive result, it will override a weak result.
     61             WeakPositive,
     62             // The first input is definitely better than the second input.
     63             StrongPositive,
     64         };
     65 
     66         // An interface for defining new comparisons based on user inputs.
     67         struct ComparisonField : public FilterField
     68         {
     69             using FilterField::FilterField;
     70 
     71             virtual ~ComparisonField() = default;
     72 
     73             // Determines if the first installer is a better choice based on this field alone.
     74             virtual ComparisonResult IsFirstBetter(const AppInstaller::Manifest::ManifestInstaller& first, const AppInstaller::Manifest::ManifestInstaller& second) = 0;
     75         };
     76     }
     77 
     78     struct InstallerAndInapplicabilities
     79     {
     80         std::optional<AppInstaller::Manifest::ManifestInstaller> installer;
     81         std::vector<InapplicabilityFlags> inapplicabilitiesInstaller;
     82     };
     83 
     84     // Class in charge of comparing manifest entries
     85     struct ManifestComparator
     86     {
     87         // Options that affect the comparisons.
     88         struct Options
     89         {
     90             // The allowed architectures and a value indicating whether to perform applicability checks.
     91             std::vector<Utility::Architecture> AllowedArchitectures;
     92             bool SkipApplicabilityCheck = false;
     93 
     94             // The requested installer type.
     95             std::optional<InstallerTypeEnum> RequestedInstallerType;
     96 
     97             // The currently installed type.
     98             std::optional<InstallerTypeEnum> CurrentlyInstalledType;
     99 
    100             // The requested installer scope and a value indicating whether and unknown scope is acceptable.
    101             std::optional<ScopeEnum> RequestedInstallerScope;
    102             std::optional<bool> AllowUnknownScope;
    103 
    104             // The currently installed scope.
    105             std::optional<ScopeEnum> CurrentlyInstalledScope;
    106 
    107             // The requested installer locale.
    108             std::optional<std::string> RequestedInstallerLocale;
    109 
    110             // Get the currently installed locale intent and value.
    111             std::optional<std::string> PreviousUserIntentLocale;
    112             std::optional<std::string> CurrentlyInstalledLocale;
    113         };
    114 
    115         ManifestComparator(const Options& options);
    116 
    117         // Gets the best installer from the manifest, if at least one is applicable.
    118         InstallerAndInapplicabilities GetPreferredInstaller(const AppInstaller::Manifest::Manifest& manifest);
    119 
    120         // Determines if an installer is applicable.
    121         InapplicabilityFlags IsApplicable(const AppInstaller::Manifest::ManifestInstaller& installer);
    122 
    123         // Determines if the first installer is a better choice.
    124         bool IsFirstBetter(
    125             const AppInstaller::Manifest::ManifestInstaller& first,
    126             const AppInstaller::Manifest::ManifestInstaller& second);
    127 
    128     private:
    129         void AddFilter(std::unique_ptr<details::FilterField>&& filter);
    130         void AddComparator(std::unique_ptr<details::ComparisonField>&& comparator);
    131 
    132         std::vector<std::unique_ptr<details::FilterField>> m_filters;
    133         // Non-owning pointers to values in m_filters.
    134         std::vector<details::ComparisonField*> m_comparators;
    135     };
    136 
    137 }