#include "attrs.hh" #include "fetchers.hh" #include namespace nix::fetchers { Attrs jsonToAttrs(const nlohmann::json & json) { Attrs attrs; for (auto & i : json.items()) { if (i.value().is_number()) attrs.emplace(i.key(), i.value().get()); else if (i.value().is_string()) attrs.emplace(i.key(), i.value().get()); else if (i.value().is_boolean()) attrs.emplace(i.key(), Explicit { i.value().get() }); else throw Error("unsupported input attribute type in lock file"); } return attrs; } nlohmann::json attrsToJSON(const Attrs & attrs) { nlohmann::json json; for (auto & attr : attrs) { if (auto v = std::get_if(&attr.second)) { json[attr.first] = *v; } else if (auto v = std::get_if(&attr.second)) { json[attr.first] = *v; } else if (auto v = std::get_if>(&attr.second)) { json[attr.first] = v->t; } else abort(); } return json; } std::optional maybeGetStrAttr(const Attrs & attrs, const std::string & name) { auto i = attrs.find(name); if (i == attrs.end()) return {}; if (auto v = std::get_if(&i->second)) return *v; throw Error("input attribute '%s' is not a string %s", name, attrsToJSON(attrs).dump()); } std::string getStrAttr(const Attrs & attrs, const std::string & name) { auto s = maybeGetStrAttr(attrs, name); if (!s) throw Error("input attribute '%s' is missing", name); return *s; } std::optional maybeGetIntAttr(const Attrs & attrs, const std::string & name) { auto i = attrs.find(name); if (i == attrs.end()) return {}; if (auto v = std::get_if(&i->second)) return *v; throw Error("input attribute '%s' is not an integer", name); } uint64_t getIntAttr(const Attrs & attrs, const std::string & name) { auto s = maybeGetIntAttr(attrs, name); if (!s) throw Error("input attribute '%s' is missing", name); return *s; } std::optional maybeGetBoolAttr(const Attrs & attrs, const std::string & name) { auto i = attrs.find(name); if (i == attrs.end()) return {}; if (auto v = std::get_if>(&i->second)) return v->t; throw Error("input attribute '%s' is not a Boolean", name); } bool getBoolAttr(const Attrs & attrs, const std::string & name) { auto s = maybeGetBoolAttr(attrs, name); if (!s) throw Error("input attribute '%s' is missing", name); return *s; } std::map attrsToQuery(const Attrs & attrs) { std::map query; for (auto & attr : attrs) { if (auto v = std::get_if(&attr.second)) { query.insert_or_assign(attr.first, fmt("%d", *v)); } else if (auto v = std::get_if(&attr.second)) { query.insert_or_assign(attr.first, *v); } else if (auto v = std::get_if>(&attr.second)) { query.insert_or_assign(attr.first, v->t ? "1" : "0"); } else abort(); } return query; } }