diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 3f7d4b760d..36f1e0cd50 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -81,7 +81,6 @@ add_library(${TARGET} imatrix-loader.cpp imatrix-loader.h json-schema-to-grammar.cpp - json-shim.h json.cpp json.h llguidance.cpp diff --git a/common/json-shim.h b/common/json-shim.h deleted file mode 100644 index 1a1d201d37..0000000000 --- a/common/json-shim.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -// converts between common_json and the backing JSON library -// -// include this only in a cpp file that touches an internal component, never in a header -// every use here is a place to fix if the library changes - -#include "json.h" - -template T & common_json_raw(common_json & json); -template const T & common_json_raw(const common_json & json); - -template common_json common_json_from_raw(const T & json); - -// view over a value of the backing library, it does not copy -template common_json & common_json_ref_from_raw(T & json); diff --git a/common/json.cpp b/common/json.cpp index 6c2be95d66..547542bb7d 100644 --- a/common/json.cpp +++ b/common/json.cpp @@ -1,6 +1,4 @@ #include "json.h" -// defines the shim -#include "json-shim.h" #include "ggml.h" @@ -10,6 +8,7 @@ #include #include #include +#include #include using nlohmann::ordered_json; @@ -64,28 +63,6 @@ static ordered_json to_json(const common_json_value & val) { return nullptr; } -template T & common_json_raw(common_json & json) { - return as_json(&json); -} - -template const T & common_json_raw(const common_json & json) { - return as_json(&json); -} - -template common_json common_json_from_raw(const T & json) { - return common_json(as_common(json)); -} - -template common_json & common_json_ref_from_raw(T & json) { - return as_common(json); -} - -// the bridge is usable only for the type below -template ordered_json & common_json_raw(common_json &); -template const ordered_json & common_json_raw(const common_json &); -template common_json common_json_from_raw(const ordered_json &); -template common_json & common_json_ref_from_raw(ordered_json &); - common_json_value::common_json_value(const char * val) { if (val) { type = VAL_STRING; @@ -139,6 +116,24 @@ COMMON_JSON_MAP(std::string) #undef COMMON_JSON_MAP +template +common_json_value::common_json_value(const std::unordered_map & vals) : type(VAL_JSON) { + common_json out = common_json::object(); + + for (const auto & val : vals) { + out.set({ val.first, val.second }); + } + + val_json = std::make_shared(std::move(out)); +} + +// an unordered map value is usable only for the types below +#define COMMON_JSON_UMAP(...) template common_json_value::common_json_value(const std::unordered_map &); + +COMMON_JSON_UMAP(size_t) + +#undef COMMON_JSON_UMAP + template common_json_value::common_json_value(const std::vector & vals) : type(VAL_JSON) { common_json out = common_json::array(); @@ -436,5 +431,7 @@ COMMON_JSON_GET(std::vector) COMMON_JSON_GET(std::vector) COMMON_JSON_GET(std::set) COMMON_JSON_GET(std::vector) +COMMON_JSON_GET(std::vector) +COMMON_JSON_GET(std::unordered_map) #undef COMMON_JSON_GET diff --git a/common/json.h b/common/json.h index a16bbad1ee..8bef391d43 100644 --- a/common/json.h +++ b/common/json.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -68,6 +69,7 @@ struct common_json_value { template common_json_value(const std::set & vals); // a map becomes an object, keyed in the map's own order template common_json_value(const std::map & vals); + template common_json_value(const std::unordered_map & vals); // nested object, e.g. {"fn", {{"name", "x"}}} // note: a nested pair {"a", "b"} becomes the object {"a": "b"}, not an array @@ -120,6 +122,9 @@ struct common_json_is_value> : std::true_type {}; template struct common_json_is_value> : std::true_type {}; +template +struct common_json_is_value> : std::true_type {}; + class common_json { public: common_json(); diff --git a/common/peg-parser.cpp b/common/peg-parser.cpp index 8194ddb1d8..46fc29bf2f 100644 --- a/common/peg-parser.cpp +++ b/common/peg-parser.cpp @@ -1,6 +1,4 @@ #include "peg-parser.h" -// the interface takes common_json, the parser internals stay on the library -#include "json-shim.h" #include "common.h" #include "json-schema-to-grammar.h" @@ -12,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -1807,8 +1804,8 @@ void common_peg_arena::build_grammar(const common_grammar_builder & builder, boo } } -static nlohmann::ordered_json serialize_parser_variant(const common_peg_parser_variant & variant) { - using json = nlohmann::ordered_json; +static common_json serialize_parser_variant(const common_peg_parser_variant & variant) { + using json = common_json; return std::visit([](const auto & p) -> json { using T = std::decay_t; @@ -1862,7 +1859,7 @@ static nlohmann::ordered_json serialize_parser_variant(const common_peg_parser_v {"type", "schema"}, {"child", p.child}, {"name", p.name}, - {"schema", p.schema ? common_json_raw(*p.schema) : nlohmann::ordered_json(nullptr)}, + {"schema", p.schema ? *p.schema : json(nullptr)}, {"raw", p.raw} }; } else if constexpr (std::is_same_v) { @@ -1891,21 +1888,18 @@ static nlohmann::ordered_json serialize_parser_variant(const common_peg_parser_v } common_json common_peg_arena::to_json() const { - auto parsers = nlohmann::ordered_json::array(); + auto parsers = common_json::array(); for (const auto & parser : parsers_) { parsers.push_back(serialize_parser_variant(parser)); } - // the assignment moves the tree in, it does not copy - common_json out; - common_json_raw(out) = nlohmann::ordered_json{ + return common_json{ {"parsers", parsers}, {"rules", rules_}, {"root", root_} }; - return out; } -static common_peg_parser_variant deserialize_parser_variant(const nlohmann::ordered_json & j) { +static common_peg_parser_variant deserialize_parser_variant(const common_json & j) { if (!j.contains("type") || !j["type"].is_string()) { throw std::runtime_error("Parser variant JSON missing or invalid 'type' field"); } @@ -1974,9 +1968,9 @@ static common_peg_parser_variant deserialize_parser_variant(const nlohmann::orde } common_peg_chars_parser parser; parser.pattern = j["pattern"]; - parser.negated = j["negated"]; - parser.min_count = j["min_count"]; - parser.max_count = j["max_count"]; + parser.negated = j["negated"].get(); + parser.min_count = j["min_count"].get(); + parser.max_count = j["max_count"].get(); for (const auto & range_json : j["ranges"]) { if (!range_json.contains("start") || !range_json.contains("end")) { throw std::runtime_error("char_range missing 'start' or 'end' field"); @@ -2012,7 +2006,7 @@ static common_peg_parser_variant deserialize_parser_variant(const nlohmann::orde parser.child = j["child"].get(); parser.name = j["name"]; if (!j["schema"].is_null()) { - parser.schema = std::make_shared(common_json_from_raw(j["schema"])); + parser.schema = std::make_shared(j["schema"]); } parser.raw = j["raw"].get(); return parser; @@ -2074,8 +2068,7 @@ static common_peg_parser_variant deserialize_parser_variant(const nlohmann::orde throw std::runtime_error("Unknown parser type: " + type); } -common_peg_arena common_peg_arena::from_json(const common_json & j_in) { - const nlohmann::ordered_json & j = common_json_raw(j_in); +common_peg_arena common_peg_arena::from_json(const common_json & j) { if (!j.contains("parsers") || !j["parsers"].is_array()) { throw std::runtime_error("JSON missing or invalid 'parsers' array"); }