snix/third_party/nix/src/libutil/json.hh
Vincent Ambo 1cf11317ca refactor(tvix/libutil): Mark single-argument constructors explicit
This is the clang-tidy lint 'google-explicit-constructor'.

There's a whole bunch of breakage that was introduced by this, and we
had to opt out a few types of this (esp. the string formatting crap).

In some cases minor other changes have been done to keep the code
working, instead of converting between types (e.g. an explicit
comparison operator implementation for nix::Pid).

Change-Id: I12e1ca51a6bc2c882dba81a2526b9729d26988e7
Reviewed-on: https://cl.tvl.fyi/c/depot/+/1832
Tested-by: BuildkiteCI
Reviewed-by: kanepyork <rikingcoding@gmail.com>
Reviewed-by: glittershark <grfn@gws.fyi>
2020-08-23 11:58:44 +00:00

144 lines
2.7 KiB
C++

#pragma once
#include <cassert>
#include <iostream>
#include <vector>
namespace nix {
void toJSON(std::ostream& str, const char* start, const char* end);
void toJSON(std::ostream& str, const char* s);
template <typename T>
void toJSON(std::ostream& str, const T& n);
class JSONWriter {
protected:
struct JSONState {
std::ostream& str;
bool indent;
size_t depth = 0;
size_t stack = 0;
JSONState(std::ostream& str, bool indent) : str(str), indent(indent) {}
~JSONState() { assert(stack == 0); }
};
JSONState* state;
bool first = true;
JSONWriter(std::ostream& str, bool indent);
explicit JSONWriter(JSONState* state);
~JSONWriter();
void assertActive() { assert(state->stack != 0); }
void comma();
void indent();
};
class JSONObject;
class JSONPlaceholder;
class JSONList : JSONWriter {
private:
friend class JSONObject;
friend class JSONPlaceholder;
void open();
explicit JSONList(JSONState* state) : JSONWriter(state) { open(); }
public:
explicit JSONList(std::ostream& str, bool indent = false)
: JSONWriter(str, indent) {
open();
}
~JSONList();
template <typename T>
JSONList& elem(const T& v) {
comma();
toJSON(state->str, v);
return *this;
}
JSONList list();
JSONObject object();
JSONPlaceholder placeholder();
};
class JSONObject : JSONWriter {
private:
friend class JSONList;
friend class JSONPlaceholder;
void open();
explicit JSONObject(JSONState* state) : JSONWriter(state) { open(); }
void attr(const std::string& s);
public:
explicit JSONObject(std::ostream& str, bool indent = false)
: JSONWriter(str, indent) {
open();
}
JSONObject(const JSONObject& obj) = delete;
JSONObject(JSONObject&& obj) : JSONWriter(obj.state) { obj.state = 0; }
~JSONObject();
template <typename T>
JSONObject& attr(const std::string& name, const T& v) {
attr(name);
toJSON(state->str, v);
return *this;
}
JSONList list(const std::string& name);
JSONObject object(const std::string& name);
JSONPlaceholder placeholder(const std::string& name);
};
class JSONPlaceholder : JSONWriter {
private:
friend class JSONList;
friend class JSONObject;
explicit JSONPlaceholder(JSONState* state) : JSONWriter(state) {}
void assertValid() {
assertActive();
assert(first);
}
public:
explicit JSONPlaceholder(std::ostream& str, bool indent = false)
: JSONWriter(str, indent) {}
~JSONPlaceholder() { assert(!first || std::uncaught_exception()); }
template <typename T>
void write(const T& v) {
assertValid();
first = false;
toJSON(state->str, v);
}
JSONList list();
JSONObject object();
};
} // namespace nix