File indexing completed on 2024-11-24 03:56:29

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #pragma once
0008 
0009 #include <QtGlobal>
0010 #include <QString>
0011 #include <QStringList>
0012 
0013 #ifdef Q_OS_WIN
0014 #   define ENV_SEPARATOR ";"
0015 #else
0016 #   define ENV_SEPARATOR ":"
0017 #endif
0018 
0019 namespace app {
0020 
0021 class Environment
0022 {
0023 public:
0024     class Variable
0025     {
0026     public:
0027         explicit Variable(const char* name) : name(name) {}
0028 
0029         operator const QString&() const
0030         {
0031             ensure_loaded();
0032             return value;
0033         }
0034 
0035         const QString& get(const QString& default_value = {}) const
0036         {
0037             ensure_loaded(default_value);
0038             return value;
0039         }
0040 
0041         bool is_set() const
0042         {
0043             return qEnvironmentVariableIsSet(name.constData());
0044         }
0045 
0046         void operator=(const QString& value) const
0047         {
0048             set(value);
0049         }
0050 
0051         void set(const QString& value) const
0052         {
0053             this->value = value;
0054             loaded = true;
0055             qputenv(name.constData(), value.toUtf8());
0056         }
0057 
0058         void erase() const
0059         {
0060             value.clear();
0061             loaded = true;
0062             qunsetenv(name.constData());
0063         }
0064 
0065         const QString& load(const QString& default_value = {}) const
0066         {
0067             value = qEnvironmentVariable(name.constData(), default_value);
0068             loaded = true;
0069             return value;
0070         }
0071 
0072         bool operator==(const QString& val) const
0073         {
0074             return get() == val;
0075         }
0076 
0077         bool operator!=(const QString& val) const
0078         {
0079             return get() != val;
0080         }
0081 
0082         void push_back(const QString& item, const QString& separator=ENV_SEPARATOR)
0083         {
0084             ensure_loaded();
0085             if ( !value.isEmpty() )
0086                 value += separator;
0087             value += item;
0088             qputenv(name.constData(), value.toUtf8().constData());
0089         }
0090 
0091         void push_back(const QStringList& items, const QString& separator=ENV_SEPARATOR)
0092         {
0093             if ( items.empty() )
0094                 return;
0095             push_back(items.join(separator), separator);
0096         }
0097 
0098         void push_front(const QString& item, const QString& separator=ENV_SEPARATOR)
0099         {
0100             ensure_loaded();
0101             QString new_value = item;
0102             if ( !value.isEmpty() )
0103                 value += separator;
0104             new_value += value;
0105             set(new_value);
0106         }
0107 
0108         void push_front(const QStringList& items, const QString& separator=ENV_SEPARATOR)
0109         {
0110             if ( items.empty() )
0111                 return;
0112             push_front(items.join(separator), separator);
0113         }
0114 
0115         QStringList to_list(const QString& separator=ENV_SEPARATOR) const
0116         {
0117             ensure_loaded();
0118             return value.split(separator);
0119         }
0120 
0121         bool empty() const
0122         {
0123             ensure_loaded({});
0124             return value.isEmpty();
0125         }
0126 
0127     private:
0128         void ensure_loaded(const QString& default_value = {}) const
0129         {
0130             if ( !loaded )
0131                 load(default_value);
0132         }
0133 
0134         QByteArray name;
0135         mutable QString value;
0136         mutable bool loaded = false;
0137     };
0138 
0139     Variable operator[](const char* name) { return Variable(name); }
0140     bool contains(const char* name) { return qEnvironmentVariableIsSet(name); }
0141     void erase(const char* name) { qunsetenv(name); }
0142 };
0143 
0144 } // namespace app