Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
IBackend.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 fuddlesworth
2// SPDX-License-Identifier: LGPL-2.1-or-later
3
4#pragma once
5
6#include <phosphorconfig_export.h>
7
8#include <QColor>
9#include <QJsonArray>
10#include <QJsonDocument>
11#include <QJsonObject>
12#include <QJsonParseError>
13#include <QJsonValue>
14#include <QString>
15#include <QStringList>
16
17#include <memory>
18
19namespace PhosphorConfig {
20
22struct Schema;
23
37class PHOSPHORCONFIG_EXPORT IGroup
38{
39public:
40 virtual ~IGroup() = default;
41
42 // Typed reads — return defaultValue when the key is absent, present-but-wrong-type,
43 // or otherwise unparseable. Concrete backends document the exact coercion rules.
44 virtual QString readString(const QString& key, const QString& defaultValue = {}) const = 0;
45 virtual int readInt(const QString& key, int defaultValue = 0) const = 0;
46 virtual bool readBool(const QString& key, bool defaultValue = false) const = 0;
47 virtual double readDouble(const QString& key, double defaultValue = 0.0) const = 0;
48 virtual QColor readColor(const QString& key, const QColor& defaultValue = {}) const = 0;
49
56 virtual void writeString(const QString& key, const QString& value) = 0;
57 virtual void writeInt(const QString& key, int value) = 0;
58 virtual void writeBool(const QString& key, bool value) = 0;
59 virtual void writeDouble(const QString& key, double value) = 0;
60 virtual void writeColor(const QString& key, const QColor& value) = 0;
61
72 virtual void writeJson(const QString& key, const QJsonValue& value)
73 {
74 // QJsonDocument only accepts arrays/objects at the root. For scalar
75 // values (including strings, so writeJson/readJson round-trip
76 // correctly via a single uniform encoding) wrap in a one-element
77 // array and strip the brackets; for arrays/objects emit the compact
78 // form directly.
79 if (value.isArray()) {
80 writeString(key, QString::fromUtf8(QJsonDocument(value.toArray()).toJson(QJsonDocument::Compact)));
81 return;
82 }
83 if (value.isObject()) {
84 writeString(key, QString::fromUtf8(QJsonDocument(value.toObject()).toJson(QJsonDocument::Compact)));
85 return;
86 }
87 QJsonArray wrapped;
88 wrapped.append(value);
89 const QByteArray raw = QJsonDocument(wrapped).toJson(QJsonDocument::Compact);
90 writeString(key, QString::fromUtf8(raw.mid(1, raw.size() - 2)));
91 }
92
101 virtual QJsonValue readJson(const QString& key, const QJsonValue& defaultValue = {}) const
102 {
103 if (!hasKey(key)) {
104 return defaultValue;
105 }
106 const QString raw = readString(key);
107 // Wrap so QJsonDocument::fromJson accepts bare scalars.
108 const QByteArray wrapped = QByteArray("[") + raw.toUtf8() + QByteArray("]");
109 QJsonParseError err;
110 const QJsonDocument doc = QJsonDocument::fromJson(wrapped, &err);
111 if (err.error != QJsonParseError::NoError) {
112 return defaultValue;
113 }
114 const QJsonArray arr = doc.array();
115 if (arr.size() != 1) {
116 return defaultValue;
117 }
118 return arr.at(0);
119 }
120
121 // Key management.
122 virtual bool hasKey(const QString& key) const = 0;
123 virtual void deleteKey(const QString& key) = 0;
124
129 virtual QStringList keyList() const = 0;
130
131 IGroup(const IGroup&) = delete;
132 IGroup& operator=(const IGroup&) = delete;
133
134protected:
135 IGroup() = default;
136};
137
149class PHOSPHORCONFIG_EXPORT IBackend
150{
151public:
152 virtual ~IBackend() = default;
153
156 virtual std::unique_ptr<IGroup> group(const QString& name) = 0;
157
160 virtual void reparseConfiguration() = 0;
161
165 virtual bool sync() = 0;
166
169 virtual void deleteGroup(const QString& name) = 0;
170
172 virtual QString readRootString(const QString& key, const QString& defaultValue = {}) const = 0;
173 virtual void writeRootString(const QString& key, const QString& value) = 0;
174 virtual void removeRootKey(const QString& key) = 0;
175
180 virtual QStringList groupList() const = 0;
181
182 // ── Schema-aware hooks (default no-op) ────────────────────────────────
183 // Store consults these to wire a schema's resolver, version stamp, and
184 // migration chain into the backend. Backends without a JSON-root concept
185 // (QSettingsBackend) inherit the default no-ops; JsonBackend overrides.
186 // Keeping the hooks on IBackend lets Store work against the polymorphic
187 // interface instead of a dynamic_cast, and lets a future backend opt in
188 // to schema participation by providing its own overrides.
189
194 virtual void setPathResolver(std::shared_ptr<IGroupPathResolver>)
195 {
196 }
199 virtual std::shared_ptr<IGroupPathResolver> pathResolver() const
200 {
201 return nullptr;
202 }
203
208 virtual void setVersionStamp(const QString&, int)
209 {
210 }
214 virtual std::pair<QString, int> versionStamp() const
215 {
216 return {};
217 }
218
226 virtual bool applyMigration(const Schema&)
227 {
228 return false;
229 }
230
231 IBackend(const IBackend&) = delete;
232 IBackend& operator=(const IBackend&) = delete;
233
234protected:
235 IBackend() = default;
236};
237
238} // namespace PhosphorConfig
Pluggable configuration backend.
Definition IBackend.h:150
virtual void setVersionStamp(const QString &, int)
Install a "stamp on first sync" version annotation: if key is absent from the backend's root on the n...
Definition IBackend.h:208
virtual ~IBackend()=default
virtual bool sync()=0
Flush pending writes to disk.
virtual void removeRootKey(const QString &key)=0
virtual bool applyMigration(const Schema &)
Apply schema's migration chain against the backend's in-memory state and commit any resulting version...
Definition IBackend.h:226
virtual std::pair< QString, int > versionStamp() const
Currently-installed version stamp as {key, version}.
Definition IBackend.h:214
virtual void deleteGroup(const QString &name)=0
Delete an entire group and everything inside it.
virtual std::unique_ptr< IGroup > group(const QString &name)=0
Return a scoped view into the named group.
IBackend(const IBackend &)=delete
virtual void writeRootString(const QString &key, const QString &value)=0
IBackend & operator=(const IBackend &)=delete
virtual QString readRootString(const QString &key, const QString &defaultValue={}) const =0
Read/write ungrouped (root-level) keys.
virtual void reparseConfiguration()=0
Re-read configuration from disk, discarding any pending in-memory changes.
virtual void setPathResolver(std::shared_ptr< IGroupPathResolver >)
Install a group-path resolver.
Definition IBackend.h:194
virtual QStringList groupList() const =0
Enumerate every top-level group name.
virtual std::shared_ptr< IGroupPathResolver > pathResolver() const
Currently-installed resolver, or nullptr when none is set (also the default for backends that ignore ...
Definition IBackend.h:199
Optional plug-in for custom group name semantics.
Definition IGroupPathResolver.h:30
Scoped view into a single configuration group.
Definition IBackend.h:38
virtual ~IGroup()=default
virtual QStringList keyList() const =0
Enumerate scalar leaf keys directly under this group.
virtual bool readBool(const QString &key, bool defaultValue=false) const =0
IGroup(const IGroup &)=delete
virtual QJsonValue readJson(const QString &key, const QJsonValue &defaultValue={}) const
Read a structured JSON value.
Definition IBackend.h:101
virtual void writeColor(const QString &key, const QColor &value)=0
virtual QString readString(const QString &key, const QString &defaultValue={}) const =0
virtual int readInt(const QString &key, int defaultValue=0) const =0
virtual void writeJson(const QString &key, const QJsonValue &value)
Write a structured JSON value (array/object/scalar) natively where supported, or as a compact-JSON st...
Definition IBackend.h:72
virtual QColor readColor(const QString &key, const QColor &defaultValue={}) const =0
virtual void deleteKey(const QString &key)=0
virtual void writeBool(const QString &key, bool value)=0
virtual void writeString(const QString &key, const QString &value)=0
Write a string.
virtual double readDouble(const QString &key, double defaultValue=0.0) const =0
virtual void writeDouble(const QString &key, double value)=0
IGroup & operator=(const IGroup &)=delete
virtual bool hasKey(const QString &key) const =0
virtual void writeInt(const QString &key, int value)=0
Definition IBackend.h:19
Declarative description of a configuration store.
Definition Schema.h:89