Vaguely one half of #186. Fixes #827. Change-Id: Ie6a296465beb089bf812ea27091648ca6a6a6964
205 lines
5.1 KiB
C++
205 lines
5.1 KiB
C++
#pragma once
|
|
///@file
|
|
|
|
#include "lix/libutil/config.hh"
|
|
#include "lix/libutil/fmt.hh"
|
|
#include "lix/libutil/json-fwd.hh"
|
|
|
|
#include <cassert>
|
|
#include <format>
|
|
#include <optional>
|
|
#include <string_view>
|
|
|
|
namespace nix
|
|
{
|
|
|
|
/**
|
|
* This was previously defined in libcmd, because libutil doesn't know what the hell a progress bar is.
|
|
* But we want this to be a setting, and all the other logging stuff is here in libutil.
|
|
*/
|
|
struct LogFormat
|
|
{
|
|
enum class LogFormatValue : uint8_t
|
|
{
|
|
Auto,
|
|
Raw,
|
|
RawWithLogs,
|
|
InternalJson,
|
|
Bar,
|
|
BarWithLogs,
|
|
Multiline,
|
|
MultilineWithLogs,
|
|
};
|
|
|
|
using enum LogFormatValue;
|
|
|
|
public:
|
|
LogFormatValue value;
|
|
|
|
// Boilerplate.
|
|
public:
|
|
constexpr LogFormat() noexcept : value(Auto) { }
|
|
// Intentionally implicit constructor. For once.
|
|
constexpr LogFormat(LogFormatValue const & value) noexcept : value(value) { }
|
|
|
|
// Intentionally implicit operator. For once.
|
|
constexpr operator LogFormatValue() const noexcept
|
|
{
|
|
return value;
|
|
}
|
|
|
|
static constexpr std::optional<LogFormatValue> parse(std::string_view str)
|
|
{
|
|
if (str == "auto") {
|
|
return Auto;
|
|
} else if (str == "raw") {
|
|
return Raw;
|
|
} else if (str == "raw-with-logs") {
|
|
return RawWithLogs;
|
|
} else if (str == "internal-json") {
|
|
return InternalJson;
|
|
} else if (str == "bar") {
|
|
return Bar;
|
|
} else if (str == "bar-with-logs") {
|
|
return BarWithLogs;
|
|
} else if (str == "multiline") {
|
|
return Multiline;
|
|
} else if (str == "multiline-with-logs") {
|
|
return MultilineWithLogs;
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
constexpr std::string_view toStr() const noexcept
|
|
{
|
|
switch (value) {
|
|
case Auto:
|
|
return "auto";
|
|
case Raw:
|
|
return "raw";
|
|
case RawWithLogs:
|
|
return "raw-with-logs";
|
|
case InternalJson:
|
|
return "internal-json";
|
|
case Bar:
|
|
return "bar";
|
|
case BarWithLogs:
|
|
return "bar-with-logs";
|
|
case Multiline:
|
|
return "multiline";
|
|
case MultilineWithLogs:
|
|
return "multiline-with-logs";
|
|
}
|
|
}
|
|
|
|
// Actual API.
|
|
public:
|
|
/** Does nothing if not applicable.
|
|
*
|
|
*/
|
|
constexpr LogFormatValue withoutLogs() const noexcept
|
|
{
|
|
switch (value) {
|
|
case Auto:
|
|
[[fallthrough]];
|
|
case Raw:
|
|
[[fallthrough]];
|
|
case Bar:
|
|
[[fallthrough]];
|
|
case Multiline:
|
|
[[fallthrough]];
|
|
case InternalJson:
|
|
return *this;
|
|
|
|
case RawWithLogs:
|
|
return Raw;
|
|
case BarWithLogs:
|
|
return Bar;
|
|
case MultilineWithLogs:
|
|
return Multiline;
|
|
}
|
|
}
|
|
|
|
constexpr LogFormatValue withLogs() const noexcept
|
|
{
|
|
switch (value) {
|
|
case Auto:
|
|
[[fallthrough]];
|
|
case RawWithLogs:
|
|
[[fallthrough]];
|
|
case BarWithLogs:
|
|
[[fallthrough]];
|
|
case MultilineWithLogs:
|
|
[[fallthrough]];
|
|
case InternalJson:
|
|
return *this;
|
|
|
|
case Raw:
|
|
return RawWithLogs;
|
|
case Bar:
|
|
return BarWithLogs;
|
|
case Multiline:
|
|
return MultilineWithLogs;
|
|
}
|
|
}
|
|
};
|
|
|
|
using LogFormatValue = LogFormat::LogFormatValue;
|
|
|
|
template<>
|
|
struct LegacyFormat<LogFormat> : std::true_type { };
|
|
template<>
|
|
struct LegacyFormat<LogFormatValue> : std::true_type { };
|
|
|
|
template<>
|
|
struct json::is_integral_enum<nix::LogFormat> : std::true_type {};
|
|
template<>
|
|
struct json::is_integral_enum<nix::LogFormatValue> : std::true_type {};
|
|
|
|
/** Note: you'll have to include `config-impl.hh` when you want to use methods from this type. */
|
|
struct LogFormatSetting : public BaseSetting<LogFormat>
|
|
{
|
|
// I hate global state, man.
|
|
LogFormat autoValue = LogFormat::RawWithLogs;
|
|
|
|
LogFormatSetting(
|
|
Config * options,
|
|
const LogFormat & def,
|
|
const std::string & name,
|
|
const std::string & description,
|
|
const std::set<std::string> & aliases = {},
|
|
bool documentDefault = true,
|
|
std::optional<ExperimentalFeature> experimentalFeature = std::nullopt,
|
|
bool deprecated = false
|
|
) : BaseSetting<LogFormat>(def, true, name, description, aliases, experimentalFeature, deprecated)
|
|
{
|
|
options->addSetting(this);
|
|
}
|
|
};
|
|
|
|
void to_json(JSON & j, const LogFormat & self);
|
|
void from_json(const JSON & j, LogFormat & self);
|
|
|
|
}
|
|
|
|
template<>
|
|
struct std::formatter<nix::LogFormat> : std::formatter<std::string_view>
|
|
{
|
|
template<typename Ctx>
|
|
constexpr Ctx::iterator format(nix::LogFormat self, Ctx & ctx) const
|
|
{
|
|
return std::formatter<std::string_view>::format(self.toStr(), ctx);
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct std::formatter<nix::LogFormatValue> : std::formatter<nix::LogFormat>
|
|
{
|
|
template<typename Ctx>
|
|
constexpr Ctx::iterator format(nix::LogFormatValue self, Ctx & ctx) const
|
|
{
|
|
return std::formatter<nix::LogFormatValue>::format(self, ctx);
|
|
}
|
|
};
|