Settings.h (4110B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #pragma once 4 #include <filesystem> 5 #include <memory> 6 #include <string> 7 #include <string_view> 8 9 namespace AppInstaller::Settings 10 { 11 using namespace std::string_view_literals; 12 13 namespace details 14 { 15 // A settings container. 16 struct ISettingsContainer 17 { 18 virtual ~ISettingsContainer() = default; 19 20 // Gets a stream containing the setting's value, if present. 21 // If the setting does not exist, returns an empty value. 22 virtual std::unique_ptr<std::istream> Get() = 0; 23 24 // Sets the setting to the given value. 25 virtual bool Set(std::string_view value) = 0; 26 27 // Deletes the setting. 28 virtual void Remove() = 0; 29 30 // Gets the path to the setting, if reasonable. 31 virtual std::filesystem::path PathTo() = 0; 32 }; 33 } 34 35 // Allows settings to be classified and treated differently base on any number of factors. 36 // Names should still be unique, as there is no guarantee made about types mapping to unique roots. 37 enum class Type 38 { 39 // A Standard setting stream has no special requirements. 40 Standard, 41 // A UserFile setting stream should be located in a file that is easily editable by the user. 42 UserFile, 43 // A settings stream that should not be modified except by admin privileges. 44 Secure, 45 }; 46 47 // Converts the Type enum to a string. 48 std::string_view ToString(Type type); 49 50 // A stream definition, combining both type and path. 51 // The well known values in Streams should be used by product code, while tests may directly create them. 52 struct StreamDefinition 53 { 54 constexpr StreamDefinition(Type type, std::string_view name) : Type(type), Name(name) {} 55 56 // The type of stream. 57 Type Type; 58 59 // The name is used as a file name in some situations. 60 std::string_view Name; 61 }; 62 63 // A setting stream; provides access to functionality on the stream. 64 struct Stream 65 { 66 // The set of well known settings streams. 67 // Changing these values can result in data loss. 68 69 // The set of sources as defined by the user. 70 constexpr static StreamDefinition UserSources{ Type::Secure, "user_sources"sv }; 71 // The metadata about all sources. 72 constexpr static StreamDefinition SourcesMetadata{ Type::Standard, "sources_metadata"sv }; 73 // The primary user settings file. 74 constexpr static StreamDefinition PrimaryUserSettings{ Type::UserFile, "settings.json"sv }; 75 // The backup user settings file. 76 constexpr static StreamDefinition BackupUserSettings{ Type::UserFile, "settings.json.backup"sv }; 77 // The admin settings. 78 constexpr static StreamDefinition AdminSettings{ Type::Secure, "admin_settings"sv }; 79 80 // Gets a Stream for the StreamDefinition. 81 // If the stream is synchronized, attempts to Set the value can fail due to another writer 82 // having changed the underlying stream. 83 Stream(const StreamDefinition& streamDefinition); 84 85 const StreamDefinition& Definition() const { return m_streamDefinition; } 86 87 // Gets the stream if present. 88 // If the setting stream does not exist, returns an empty value (see operator bool). 89 std::unique_ptr<std::istream> Get(); 90 91 // Sets the stream to the given value. 92 // Returns true if successful; false if the underlying stream has changed. 93 [[nodiscard]] bool Set(std::string_view value); 94 95 // Deletes the setting stream. 96 void Remove(); 97 98 // Gets the name of the stream. 99 std::string_view GetName() const; 100 101 // Gets the path to the stream. 102 std::filesystem::path GetPath() const; 103 104 private: 105 const StreamDefinition m_streamDefinition; 106 std::unique_ptr<details::ISettingsContainer> m_container; 107 }; 108 }