mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Make ValFromJSON return zeek::expected instead of a variant
This commit is contained in:
parent
e545fe8256
commit
201d4508e6
6 changed files with 64 additions and 60 deletions
90
src/Val.cc
90
src/Val.cc
|
@ -891,8 +891,8 @@ unsigned int StringVal::ComputeFootprint(std::unordered_set<const Val*>* analyze
|
||||||
return 1 /* this object */ + static_cast<unsigned int>(Len()) / sizeof(Val);
|
return 1 /* this object */ + static_cast<unsigned int>(Len()) / sizeof(Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, const TypePtr& t,
|
static zeek::expected<ValPtr, std::string> BuildVal(const rapidjson::Value& j, const TypePtr& t,
|
||||||
const FuncPtr& key_func) {
|
const FuncPtr& key_func) {
|
||||||
auto mismatch_err = [t, &j]() {
|
auto mismatch_err = [t, &j]() {
|
||||||
std::string json_type;
|
std::string json_type;
|
||||||
switch ( j.GetType() ) {
|
switch ( j.GetType() ) {
|
||||||
|
@ -906,7 +906,8 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
default: json_type = "unknown";
|
default: json_type = "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
return util::fmt("cannot convert JSON type '%s' to Zeek type '%s'", json_type.c_str(), type_name(t->Tag()));
|
return zeek::unexpected<std::string>(
|
||||||
|
util::fmt("cannot convert JSON type '%s' to Zeek type '%s'", json_type.c_str(), type_name(t->Tag())));
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( j.IsNull() )
|
if ( j.IsNull() )
|
||||||
|
@ -960,7 +961,7 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
parts.erase(std::remove_if(parts.begin(), parts.end(), [](auto x) { return x.empty(); }), parts.end());
|
parts.erase(std::remove_if(parts.begin(), parts.end(), [](auto x) { return x.empty(); }), parts.end());
|
||||||
|
|
||||||
if ( (parts.size() % 2) != 0 )
|
if ( (parts.size() % 2) != 0 )
|
||||||
return "wrong interval format, must be pairs of values with units";
|
return zeek::unexpected<std::string>("wrong interval format, must be pairs of values with units");
|
||||||
|
|
||||||
double interval_secs = 0.0;
|
double interval_secs = 0.0;
|
||||||
for ( size_t i = 0; i < parts.size(); i += 2 ) {
|
for ( size_t i = 0; i < parts.size(); i += 2 ) {
|
||||||
|
@ -980,7 +981,8 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
else if ( unit == "usec" || unit == "usecs" )
|
else if ( unit == "usec" || unit == "usecs" )
|
||||||
interval_secs += (value * Microseconds);
|
interval_secs += (value * Microseconds);
|
||||||
else
|
else
|
||||||
return util::fmt("wrong interval format, invalid unit type %s", unit.data());
|
return zeek::unexpected<std::string>(
|
||||||
|
util::fmt("wrong interval format, invalid unit type %s", unit.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return make_intrusive<IntervalVal>(interval_secs, Seconds);
|
return make_intrusive<IntervalVal>(interval_secs, Seconds);
|
||||||
|
@ -991,11 +993,10 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
|
|
||||||
case TYPE_PORT: {
|
case TYPE_PORT: {
|
||||||
if ( j.IsString() ) {
|
if ( j.IsString() ) {
|
||||||
int port = 0;
|
|
||||||
if ( j.GetStringLength() > 0 && j.GetStringLength() < 10 ) {
|
if ( j.GetStringLength() > 0 && j.GetStringLength() < 10 ) {
|
||||||
char* slash;
|
char* slash;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
port = strtol(j.GetString(), &slash, 10);
|
auto port = strtol(j.GetString(), &slash, 10);
|
||||||
if ( ! errno ) {
|
if ( ! errno ) {
|
||||||
++slash;
|
++slash;
|
||||||
if ( util::streq(slash, "tcp") )
|
if ( util::streq(slash, "tcp") )
|
||||||
|
@ -1009,15 +1010,17 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "wrong port format, string must be /[0-9]{1,5}\\/(tcp|udp|icmp|unknown)/";
|
return zeek::unexpected<std::string>(
|
||||||
|
"wrong port format, string must be /[0-9]{1,5}\\/(tcp|udp|icmp|unknown)/");
|
||||||
}
|
}
|
||||||
else if ( j.IsObject() ) {
|
else if ( j.IsObject() ) {
|
||||||
if ( ! j.HasMember("port") || ! j.HasMember("proto") )
|
if ( ! j.HasMember("port") || ! j.HasMember("proto") )
|
||||||
return "wrong port format, object must have 'port' and 'proto' members";
|
return zeek::unexpected<std::string>(
|
||||||
|
"wrong port format, object must have 'port' and 'proto' members");
|
||||||
if ( ! j["port"].IsNumber() )
|
if ( ! j["port"].IsNumber() )
|
||||||
return "wrong port format, port must be a number";
|
return zeek::unexpected<std::string>("wrong port format, port must be a number");
|
||||||
if ( ! j["proto"].IsString() )
|
if ( ! j["proto"].IsString() )
|
||||||
return "wrong port format, protocol must be a string";
|
return zeek::unexpected<std::string>("wrong port format, protocol must be a string");
|
||||||
|
|
||||||
std::string proto{j["proto"].GetString()};
|
std::string proto{j["proto"].GetString()};
|
||||||
|
|
||||||
|
@ -1030,10 +1033,10 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
if ( proto == "unknown" )
|
if ( proto == "unknown" )
|
||||||
return val_mgr->Port(j["port"].GetInt(), TRANSPORT_UNKNOWN);
|
return val_mgr->Port(j["port"].GetInt(), TRANSPORT_UNKNOWN);
|
||||||
|
|
||||||
return "wrong port format, invalid protocol string";
|
return zeek::unexpected<std::string>("wrong port format, invalid protocol string");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return "wrong port format, must be string or object";
|
return zeek::unexpected<std::string>("wrong port format, must be string or object");
|
||||||
}
|
}
|
||||||
|
|
||||||
case TYPE_PATTERN: {
|
case TYPE_PATTERN: {
|
||||||
|
@ -1055,7 +1058,7 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
|
|
||||||
auto re = std::make_unique<RE_Matcher>(candidate.c_str());
|
auto re = std::make_unique<RE_Matcher>(candidate.c_str());
|
||||||
if ( ! re->Compile() )
|
if ( ! re->Compile() )
|
||||||
return "error compiling pattern";
|
return zeek::unexpected<std::string>("error compiling pattern");
|
||||||
|
|
||||||
return make_intrusive<PatternVal>(re.release());
|
return make_intrusive<PatternVal>(re.release());
|
||||||
}
|
}
|
||||||
|
@ -1074,7 +1077,7 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
std::string_view subnet_sv(j.GetString(), j.GetStringLength());
|
std::string_view subnet_sv(j.GetString(), j.GetStringLength());
|
||||||
auto pos = subnet_sv.find('/');
|
auto pos = subnet_sv.find('/');
|
||||||
if ( pos == subnet_sv.npos )
|
if ( pos == subnet_sv.npos )
|
||||||
return util::fmt("invalid value for subnet: '%s'", j.GetString());
|
return zeek::unexpected<std::string>(util::fmt("invalid value for subnet: '%s'", j.GetString()));
|
||||||
|
|
||||||
candidate = std::string(j.GetString(), pos);
|
candidate = std::string(j.GetString(), pos);
|
||||||
|
|
||||||
|
@ -1082,7 +1085,7 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
char* end;
|
char* end;
|
||||||
width = strtol(subnet_sv.data() + pos + 1, &end, 10);
|
width = strtol(subnet_sv.data() + pos + 1, &end, 10);
|
||||||
if ( subnet_sv.data() + pos + 1 == end || errno )
|
if ( subnet_sv.data() + pos + 1 == end || errno )
|
||||||
return util::fmt("invalid value for subnet: '%s'", j.GetString());
|
return zeek::unexpected<std::string>(util::fmt("invalid value for subnet: '%s'", j.GetString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( candidate.front() == '[' )
|
if ( candidate.front() == '[' )
|
||||||
|
@ -1104,7 +1107,8 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
auto intval = et->Lookup({j.GetString(), j.GetStringLength()});
|
auto intval = et->Lookup({j.GetString(), j.GetStringLength()});
|
||||||
|
|
||||||
if ( intval < 0 )
|
if ( intval < 0 )
|
||||||
return util::fmt("'%s' is not a valid enum for '%s'.", j.GetString(), et->GetName().c_str());
|
return zeek::unexpected<std::string>(
|
||||||
|
util::fmt("'%s' is not a valid enum for '%s'.", j.GetString(), et->GetName().c_str()));
|
||||||
|
|
||||||
return et->GetEnumVal(intval);
|
return et->GetEnumVal(intval);
|
||||||
}
|
}
|
||||||
|
@ -1126,19 +1130,19 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
return mismatch_err();
|
return mismatch_err();
|
||||||
|
|
||||||
for ( const auto& item : j.GetArray() ) {
|
for ( const auto& item : j.GetArray() ) {
|
||||||
std::variant<ValPtr, std::string> v;
|
zeek::expected<ValPtr, std::string> v;
|
||||||
|
|
||||||
if ( tl->GetTypes().size() == 1 )
|
if ( tl->GetTypes().size() == 1 )
|
||||||
v = BuildVal(item, tl->GetPureType(), key_func);
|
v = BuildVal(item, tl->GetPureType(), key_func);
|
||||||
else
|
else
|
||||||
v = BuildVal(item, tl, key_func);
|
v = BuildVal(item, tl, key_func);
|
||||||
|
|
||||||
if ( ! get_if<ValPtr>(&v) )
|
if ( ! v )
|
||||||
return v;
|
return v;
|
||||||
if ( ! std::get<ValPtr>(v) )
|
if ( v.value() == nullptr )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tv->Assign(std::move(std::get<ValPtr>(v)), nullptr);
|
tv->Assign(v.value(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tv;
|
return tv;
|
||||||
|
@ -1151,7 +1155,7 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
rapidjson::Document idxstr;
|
rapidjson::Document idxstr;
|
||||||
idxstr.Parse(it->name.GetString(), it->name.GetStringLength());
|
idxstr.Parse(it->name.GetString(), it->name.GetStringLength());
|
||||||
|
|
||||||
std::variant<ValPtr, std::string> idx;
|
zeek::expected<ValPtr, std::string> idx;
|
||||||
|
|
||||||
if ( tl->GetTypes().size() > 1 )
|
if ( tl->GetTypes().size() > 1 )
|
||||||
idx = BuildVal(idxstr, tl, key_func);
|
idx = BuildVal(idxstr, tl, key_func);
|
||||||
|
@ -1163,19 +1167,19 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
// Parse the string's content, not the full JSON string.
|
// Parse the string's content, not the full JSON string.
|
||||||
idx = BuildVal(idxstr, tl->GetPureType(), key_func);
|
idx = BuildVal(idxstr, tl->GetPureType(), key_func);
|
||||||
|
|
||||||
if ( ! get_if<ValPtr>(&idx) )
|
if ( ! idx )
|
||||||
return idx;
|
return idx;
|
||||||
if ( ! std::get<ValPtr>(idx) )
|
if ( idx.value() == nullptr )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto v = BuildVal(it->value, tt->Yield(), key_func);
|
auto v = BuildVal(it->value, tt->Yield(), key_func);
|
||||||
|
|
||||||
if ( ! get_if<ValPtr>(&v) )
|
if ( ! v )
|
||||||
return v;
|
return v;
|
||||||
if ( ! std::get<ValPtr>(v) )
|
if ( v.value() == nullptr )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tv->Assign(std::move(std::get<ValPtr>(idx)), std::move(std::get<ValPtr>(v)));
|
tv->Assign(idx.value(), v.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
return tv;
|
return tv;
|
||||||
|
@ -1202,7 +1206,7 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! result )
|
if ( ! result )
|
||||||
return "key function error";
|
return zeek::unexpected<std::string>("key function error");
|
||||||
|
|
||||||
normalized_keys[result->AsStringVal()->CheckString()] = &it->value;
|
normalized_keys[result->AsStringVal()->CheckString()] = &it->value;
|
||||||
}
|
}
|
||||||
|
@ -1226,17 +1230,18 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
if ( ! td_i->GetAttr(detail::ATTR_OPTIONAL) && ! td_i->GetAttr(detail::ATTR_DEFAULT) )
|
if ( ! td_i->GetAttr(detail::ATTR_OPTIONAL) && ! td_i->GetAttr(detail::ATTR_DEFAULT) )
|
||||||
// jval being set means it is a null JSON value else
|
// jval being set means it is a null JSON value else
|
||||||
// it wasn't even there.
|
// it wasn't even there.
|
||||||
return util::fmt("required field %s$%s is %s in JSON", t->GetName().c_str(), td_i->id,
|
return zeek::unexpected<std::string>(util::fmt("required field %s$%s is %s in JSON",
|
||||||
jval ? "null" : "missing");
|
t->GetName().c_str(), td_i->id,
|
||||||
|
jval ? "null" : "missing"));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto v = BuildVal(*jval, td_i->type, key_func);
|
auto v = BuildVal(*jval, td_i->type, key_func);
|
||||||
if ( ! get_if<ValPtr>(&v) )
|
if ( ! v )
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
rv->Assign(i, std::move(std::get<ValPtr>(v)));
|
rv->Assign(i, v.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -1249,16 +1254,16 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
auto lt = t->AsTypeList();
|
auto lt = t->AsTypeList();
|
||||||
|
|
||||||
if ( j.GetArray().Size() < lt->GetTypes().size() )
|
if ( j.GetArray().Size() < lt->GetTypes().size() )
|
||||||
return "index type doesn't match";
|
return zeek::unexpected<std::string>("index type doesn't match");
|
||||||
|
|
||||||
auto lv = make_intrusive<ListVal>(TYPE_ANY);
|
auto lv = make_intrusive<ListVal>(TYPE_ANY);
|
||||||
|
|
||||||
for ( size_t i = 0; i < lt->GetTypes().size(); i++ ) {
|
for ( size_t i = 0; i < lt->GetTypes().size(); i++ ) {
|
||||||
auto v = BuildVal(j.GetArray()[i], lt->GetTypes()[i], key_func);
|
auto v = BuildVal(j.GetArray()[i], lt->GetTypes()[i], key_func);
|
||||||
if ( ! get_if<ValPtr>(&v) )
|
if ( ! v )
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
lv->Append(std::move(std::get<ValPtr>(v)));
|
lv->Append(v.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
return lv;
|
return lv;
|
||||||
|
@ -1272,29 +1277,30 @@ static std::variant<ValPtr, std::string> BuildVal(const rapidjson::Value& j, con
|
||||||
auto vv = make_intrusive<VectorVal>(IntrusivePtr{NewRef{}, vt});
|
auto vv = make_intrusive<VectorVal>(IntrusivePtr{NewRef{}, vt});
|
||||||
for ( const auto& item : j.GetArray() ) {
|
for ( const auto& item : j.GetArray() ) {
|
||||||
auto v = BuildVal(item, vt->Yield(), key_func);
|
auto v = BuildVal(item, vt->Yield(), key_func);
|
||||||
if ( ! get_if<ValPtr>(&v) )
|
if ( ! v )
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
if ( ! std::get<ValPtr>(v) )
|
if ( v.value() == nullptr )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vv->Assign(vv->Size(), std::move(std::get<ValPtr>(v)));
|
vv->Assign(vv->Size(), v.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
return vv;
|
return vv;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: return util::fmt("type '%s' unsupported", type_name(t->Tag()));
|
default: return zeek::unexpected<std::string>(util::fmt("type '%s' unsupported", type_name(t->Tag())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::variant<ValPtr, std::string> detail::ValFromJSON(std::string_view json_str, const TypePtr& t,
|
zeek::expected<ValPtr, std::string> detail::ValFromJSON(std::string_view json_str, const TypePtr& t,
|
||||||
const FuncPtr& key_func) {
|
const FuncPtr& key_func) {
|
||||||
rapidjson::Document doc;
|
rapidjson::Document doc;
|
||||||
rapidjson::ParseResult ok = doc.Parse(json_str.data(), json_str.length());
|
rapidjson::ParseResult ok = doc.Parse(json_str.data(), json_str.length());
|
||||||
|
|
||||||
if ( ! ok )
|
if ( ! ok )
|
||||||
return util::fmt("JSON parse error: %s Offset: %lu", rapidjson::GetParseError_En(ok.Code()), ok.Offset());
|
return zeek::unexpected<std::string>(
|
||||||
|
util::fmt("JSON parse error: %s Offset: %lu", rapidjson::GetParseError_En(ok.Code()), ok.Offset()));
|
||||||
|
|
||||||
return BuildVal(doc, t, key_func);
|
return BuildVal(doc, t, key_func);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1774,8 +1774,8 @@ namespace detail {
|
||||||
//
|
//
|
||||||
// The *key_func* parameter is a Zeek script function called for every JSON key
|
// The *key_func* parameter is a Zeek script function called for every JSON key
|
||||||
// for normalization. If Func::nil is passed, no normalization happens.
|
// for normalization. If Func::nil is passed, no normalization happens.
|
||||||
extern std::variant<ValPtr, std::string> ValFromJSON(std::string_view json_str, const TypePtr& t,
|
extern zeek::expected<ValPtr, std::string> ValFromJSON(std::string_view json_str, const TypePtr& t,
|
||||||
const FuncPtr& key_func);
|
const FuncPtr& key_func);
|
||||||
|
|
||||||
// If the given vector is an empty vector-of-any ("unspecified"),
|
// If the given vector is an empty vector-of-any ("unspecified"),
|
||||||
// concretizes it to the given type. *v* gives the vector and *t* the
|
// concretizes it to the given type. *v* gives the vector and *t* the
|
||||||
|
|
|
@ -440,10 +440,10 @@ void Redis::HandleGetResult(redisReply* reply, ResultCallback* callback) {
|
||||||
res = ParseReplyError("get", reply->str);
|
res = ParseReplyError("get", reply->str);
|
||||||
else {
|
else {
|
||||||
auto val = zeek::detail::ValFromJSON(reply->str, val_type, Func::nil);
|
auto val = zeek::detail::ValFromJSON(reply->str, val_type, Func::nil);
|
||||||
if ( std::holds_alternative<ValPtr>(val) )
|
if ( val )
|
||||||
res = {ReturnCode::SUCCESS, "", std::get<ValPtr>(val)};
|
res = {ReturnCode::SUCCESS, "", val.value()};
|
||||||
else
|
else
|
||||||
res = {ReturnCode::OPERATION_FAILED, std::get<std::string>(val)};
|
res = {ReturnCode::OPERATION_FAILED, val.error()};
|
||||||
}
|
}
|
||||||
|
|
||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
|
|
|
@ -270,13 +270,11 @@ OperationResult SQLite::Step(sqlite3_stmt* stmt, bool parse_value) {
|
||||||
const char* text = (const char*)sqlite3_column_text(stmt, 0);
|
const char* text = (const char*)sqlite3_column_text(stmt, 0);
|
||||||
auto val = zeek::detail::ValFromJSON(text, val_type, Func::nil);
|
auto val = zeek::detail::ValFromJSON(text, val_type, Func::nil);
|
||||||
sqlite3_reset(stmt);
|
sqlite3_reset(stmt);
|
||||||
if ( std::holds_alternative<ValPtr>(val) ) {
|
|
||||||
ValPtr val_v = std::get<ValPtr>(val);
|
if ( val )
|
||||||
ret = {ReturnCode::SUCCESS, "", val_v};
|
ret = {ReturnCode::SUCCESS, "", val.value()};
|
||||||
}
|
else
|
||||||
else {
|
ret = {ReturnCode::OPERATION_FAILED, val.error()};
|
||||||
ret = {ReturnCode::OPERATION_FAILED, std::get<std::string>(val)};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = {ReturnCode::OPERATION_FAILED, "sqlite3_step should not have returned a value"};
|
ret = {ReturnCode::OPERATION_FAILED, "sqlite3_step should not have returned a value"};
|
||||||
|
|
|
@ -1363,8 +1363,8 @@ RecordValPtr Supervisor::NodeConfig::ToRecord() const {
|
||||||
|
|
||||||
auto tt = rt->GetFieldType<TableType>("cluster");
|
auto tt = rt->GetFieldType<TableType>("cluster");
|
||||||
auto json_res = detail::ValFromJSON(cluster, tt, Func::nil);
|
auto json_res = detail::ValFromJSON(cluster, tt, Func::nil);
|
||||||
if ( auto val = std::get_if<ValPtr>(&json_res) ) {
|
if ( json_res ) {
|
||||||
rval->AssignField("cluster", *val);
|
rval->AssignField("cluster", json_res.value());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// This should never happen: the JSON data comes from a table[string] of
|
// This should never happen: the JSON data comes from a table[string] of
|
||||||
|
@ -1372,7 +1372,7 @@ RecordValPtr Supervisor::NodeConfig::ToRecord() const {
|
||||||
// here can be hard to debug. Other JSON code (see FromJSON()) fails
|
// here can be hard to debug. Other JSON code (see FromJSON()) fails
|
||||||
// silently when the JSON is misformatted. We just warn:
|
// silently when the JSON is misformatted. We just warn:
|
||||||
fprintf(stderr, "Could not parse %s's cluster table from '%s': %s\n", name.c_str(), cluster.c_str(),
|
fprintf(stderr, "Could not parse %s's cluster table from '%s': %s\n", name.c_str(), cluster.c_str(),
|
||||||
std::get<std::string>(json_res).c_str());
|
json_res.error().c_str());
|
||||||
rval->AssignField("cluster", make_intrusive<TableVal>(std::move(tt)));
|
rval->AssignField("cluster", make_intrusive<TableVal>(std::move(tt)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5268,15 +5268,15 @@ function from_json%(s: string, t: any, key_func: string_mapper &default=from_jso
|
||||||
auto res = zeek::detail::ValFromJSON(s->ToStdStringView(), t->AsType()->AsTypeType()->GetType(),
|
auto res = zeek::detail::ValFromJSON(s->ToStdStringView(), t->AsType()->AsTypeType()->GetType(),
|
||||||
key_func_ptr);
|
key_func_ptr);
|
||||||
|
|
||||||
if ( auto val = std::get_if<zeek::ValPtr>(&res) )
|
if ( res )
|
||||||
{
|
{
|
||||||
rval->Assign(v_idx, *val);
|
rval->Assign(v_idx, res.value());
|
||||||
rval->Assign(valid_idx, true);
|
rval->Assign(valid_idx, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rval->Assign(valid_idx, false);
|
rval->Assign(valid_idx, false);
|
||||||
zeek::emit_builtin_error(std::get<std::string>(res).c_str());
|
zeek::emit_builtin_error(res.error().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::move(rval);
|
return std::move(rval);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue