-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathWSLCUserSettings.h
More file actions
179 lines (146 loc) · 6.03 KB
/
WSLCUserSettings.h
File metadata and controls
179 lines (146 loc) · 6.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*++
Copyright (c) Microsoft. All rights reserved.
Module Name:
WSLCUserSettings.h
Abstract:
Declaration of UserSettings — the singleton that loads, validates, and
provides access to the wslc user settings file.
--*/
#pragma once
#include "defs.h"
#include "EnumVariantMap.h"
#include "wslc.h"
#include <cstdint>
#include <filesystem>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
// How to add a setting:
// 1 - Add an entry to the Setting enum.
// 2 - Add a DEFINE_SETTING_MAPPING specialization with yaml_t, value_t, default, and YAML path.
// 3 - Implement the Validate function in UserSettings.cpp if needed, otherwise use pass through.
namespace wsl::windows::wslc::settings {
// Enum of all user settings.
// Must start at 0 to enable direct variant indexing.
// Max must be last and unused.
enum class Setting : size_t
{
SessionCpuCount = 0,
SessionMemoryMb,
SessionStorageSizeMb,
SessionStoragePath,
SessionNetworkingMode,
SessionHostFileShareMode,
SessionDnsTunneling,
Max
};
enum class HostFileShareMode
{
Plan9,
VirtioFs
};
namespace details {
template <Setting S>
struct SettingMapping
{
// yaml_t - the C++ type read from the YAML node via node.as<yaml_t>()
// value_t - the native type stored in SettingsMap
// DefaultValue - used when the key is absent or fails validation
// YamlPath - dot-separated path into the YAML document (e.g. "session.cpuCount")
// Validate - semantic validation; returns nullopt to reject and fall back to default
};
// clang-format off
#define DEFINE_SETTING_MAPPING(_setting_, _yaml_t_, _value_t_, _default_, _path_) \
template <> \
struct SettingMapping<Setting::_setting_> \
{ \
using yaml_t = _yaml_t_; \
using value_t = _value_t_; \
inline static const value_t DefaultValue = _default_; \
static constexpr std::string_view YamlPath = _path_; \
static std::optional<value_t> Validate(const yaml_t& value); \
};
DEFINE_SETTING_MAPPING(SessionCpuCount, uint32_t, uint32_t, 4, "session.cpuCount")
DEFINE_SETTING_MAPPING(SessionMemoryMb, std::string, uint32_t, 2048, "session.memorySize")
DEFINE_SETTING_MAPPING(SessionStorageSizeMb, std::string, uint32_t, 102400, "session.maxStorageSize")
DEFINE_SETTING_MAPPING(SessionStoragePath, std::string, std::wstring, {}, "session.defaultStoragePath")
DEFINE_SETTING_MAPPING(SessionNetworkingMode, std::string, WSLCNetworkingMode, WSLCNetworkingModeVirtioProxy, "session.networkingMode")
DEFINE_SETTING_MAPPING(SessionHostFileShareMode, std::string, HostFileShareMode, HostFileShareMode::VirtioFs, "session.hostFileShareMode")
DEFINE_SETTING_MAPPING(SessionDnsTunneling, bool, bool, true, "session.dnsTunneling")
#undef DEFINE_SETTING_MAPPING
// clang-format on
} // namespace details
// Type-safe enum-indexed map of all settings values, backed by EnumBasedVariantMap.
struct SettingsMap : wsl::windows::wslc::EnumBasedVariantMap<Setting, details::SettingMapping>
{
// Returns the stored value if present, otherwise the compile-time default.
template <Setting S>
typename details::SettingMapping<S>::value_t GetOrDefault() const
{
if (Contains(S))
{
return Get<S>();
}
return details::SettingMapping<S>::DefaultValue;
}
};
// Indicates which source the settings were loaded from.
enum class UserSettingsType
{
Default, // Settings file did not exist or failed to parse; built-in defaults are used.
Standard, // Settings file (settings.yaml) loaded successfully.
};
struct Warning
{
std::wstring Message;
std::wstring SettingPath; // Empty for file-level warnings; key path for per-field warnings.
};
// Singleton that owns the parsed settings for the current process lifetime.
// Load order:
// 1. settings.yaml (Standard)
// 2. Built-in defaults (Default, if the file is absent or fails to parse)
class UserSettings
{
public:
// Returns the singleton instance. Loaded on first call; subsequent calls are no-ops.
static UserSettings const& Instance();
NON_COPYABLE(UserSettings);
NON_MOVABLE(UserSettings);
// Returns the value for setting S, or its built-in default if not present in the file.
template <Setting S>
typename details::SettingMapping<S>::value_t Get() const
{
return m_settings.GetOrDefault<S>();
}
std::vector<Warning> const& GetWarnings() const
{
return m_warnings;
}
UserSettingsType GetType() const
{
return m_type;
}
// Called before opening the settings file in an editor.
// If type is Default, creates the file from the commented-out defaults template.
void PrepareToShellExecuteFile() const;
std::filesystem::path SettingsFilePath() const;
// Overwrites the settings file with the commented-out defaults template.
void Reset() const;
// Loads settings from an explicit directory.
explicit UserSettings(const std::filesystem::path& settingsDir);
~UserSettings() = default;
private:
UserSettings();
SettingsMap m_settings;
std::vector<Warning> m_warnings;
UserSettingsType m_type = UserSettingsType::Default;
std::filesystem::path m_settingsPath;
};
// Convenience free function — returns the singleton instance.
// Usage: settings::User().Get<Setting::Foo>()
inline UserSettings const& User()
{
return UserSettings::Instance();
}
} // namespace wsl::windows::wslc::settings