8 #include "configuration.h" 16 #include <unordered_map> 19 #include "fcitx-utils/macros.h" 22 #include "rawconfig.h" 27 std::list<std::string> optionsOrder_;
28 std::unordered_map<std::string, OptionBase *> options_;
31 Configuration::Configuration()
32 : d_ptr(std::make_unique<ConfigurationPrivate>()) {}
34 Configuration::~Configuration() =
default;
36 void Configuration::dumpDescription(
RawConfig &config)
const {
37 dumpDescriptionImpl(config, {});
40 void Configuration::dumpDescriptionImpl(
41 RawConfig &config,
const std::vector<std::string> &parentPaths)
const {
43 auto fullpaths = parentPaths;
44 fullpaths.push_back(typeName());
46 std::shared_ptr<RawConfig> subRoot = config.
get(pathString,
true);
48 std::tuple<std::vector<std::string>, std::unique_ptr<Configuration>>>
50 for (
const auto &path : d->optionsOrder_) {
51 auto optionIter = d->options_.find(path);
52 assert(optionIter != d->options_.end());
53 auto *option = optionIter->second;
54 if (option->skipDescription()) {
57 auto descConfigPtr = subRoot->get(option->path(),
true);
58 option->dumpDescription(*descConfigPtr);
60 auto subConfig = option->subConfigSkeleton();
62 auto subConfigPath = parentPaths;
63 subConfigPath.push_back(option->path());
64 std::string subTypeName = subConfig->typeName();
65 const auto *oldTypeName = descConfigPtr->valueByPath(
"Type");
68 if (oldTypeName && oldTypeName->ends_with(subTypeName)) {
69 auto newTypeName = oldTypeName->substr(
70 0, oldTypeName->size() - subTypeName.size());
72 newTypeName.append(
"$");
73 newTypeName.append(subTypeName);
74 descConfigPtr->setValueByPath(
"Type", std::move(newTypeName));
76 subConfigs.emplace_back(subConfigPath, std::move(subConfig));
81 for (
const auto &[subConfigPath, subConfigPtr] : subConfigs) {
82 subConfigPtr->dumpDescriptionImpl(config, subConfigPath);
86 bool Configuration::compareHelper(
const Configuration &other)
const {
88 return std::ranges::all_of(d->optionsOrder_, [d, &other](
const auto &path) {
89 auto optionIter = d->options_.find(path);
90 assert(optionIter != d->options_.end());
91 auto otherOptionIter = other.d_func()->options_.find(path);
92 assert(otherOptionIter != other.d_func()->options_.end());
93 return *optionIter->second == *otherOptionIter->second;
100 for (
const auto &path : d->optionsOrder_) {
101 auto optionIter = d->options_.find(path);
102 assert(optionIter != d->options_.end());
103 auto otherOptionIter = other.d_func()->options_.find(path);
104 assert(otherOptionIter != other.d_func()->options_.end());
105 optionIter->second->copyFrom(*otherOptionIter->second);
111 for (
const auto &path : d->optionsOrder_) {
112 auto subConfigPtr = config.
get(path);
113 auto *option = d->options_[path];
120 if (!option->unmarshall(*subConfigPtr, partial)) {
126 void Configuration::save(
RawConfig &config)
const {
128 for (
const auto &path : d->optionsOrder_) {
129 auto iter = d->options_.find(path);
130 assert(iter != d->options_.end());
131 if (iter->second->skipSave()) {
134 auto subConfigPtr = config.
get(path,
true);
135 iter->second->marshall(*subConfigPtr);
136 subConfigPtr->setComment(iter->second->description());
137 subConfigPtr->setImplicit(iter->second->isDefault());
141 void Configuration::addOption(
OptionBase *option) {
143 if (d->options_.contains(option->path())) {
144 throw std::logic_error(
"Duplicate option path");
147 d->optionsOrder_.push_back(option->path());
148 d->options_[option->path()] = option;
153 for (
const auto &path : d->optionsOrder_) {
154 auto iter = d->options_.find(path);
155 assert(iter != d->options_.end());
159 if (
auto *optionV3 = dynamic_cast<OptionBaseV3 *>(iter->second)) {
160 optionV3->syncDefaultValueToCurrent();
161 }
else if (
auto *optionV2 =
162 dynamic_cast<OptionBaseV2 *>(iter->second)) {
163 optionV2->syncDefaultValueToCurrent();
A raw configuration tree that stores key-value pairs in a hierarchical structure. ...
std::shared_ptr< RawConfig > get(const std::string &path, bool create=false)
Get a sub-item by path.
void load(const RawConfig &config, bool partial=false)
Load configuration from RawConfig.
void syncDefaultValueToCurrent()
Set default value to current value.
std::string join(Iter start, Iter end, T &&delim)
Join a range of string with delim.