Rapidjson::Type 的开关盒
Switch case for Rapidjson::Type
我正在尝试解析的 JSON 看起来像这样:
{
"testBool": true,
"testString": "eu"
}
而且我现在的解析器看起来真的很难看,感觉真的有更优雅的方法来解决这个问题。我尝试使用 document.GetObject().GetType()
研究 rapidjson::Type
的 switch case,但它不提供使用 Get%TypeName%()
函数可以实现的相同类型精度。 hashmap
只不过是 std::unordered_map<std::string, std::any>
.
的包装器
rapidjson::Document document;
document.Parse(tmp_string.c_str());
for (auto& member : document.GetObject())
{
if (member.value.IsBool())
{
hashmap->addEntry<bool>(member.name.GetString(), member.value.GetBool());
}
else if (member.value.IsString())
{
hashmap->addEntry<std::string>(member.name.GetString(), member.value.GetString());
}
else if (member.value.IsInt())
{
hashmap->addEntry<int>(member.name.GetString(), member.value.GetInt());
}
.....
//And so on
.....
}
my current parser looks really ugly
美丽在持有人的眼中……这是我的代码:
static void
printField(const Value& e, const string& fld, bool print_newline = true) {
const Value &v = fld.empty() ? e : e[fld];
if (print_newline)
cout << endl << "\t";
if (not fld.empty())
cout << fld << ": ";
if ( /* custom stuff required? */ ) {
// Do custom stuff
else {
switch (v.GetType()) {
case kNullType:
cout << "Null";
break;
case kFalseType:
case kTrueType:
cout << v.GetBool();
break;
case kObjectType: {
bool first = true;
cout << "{ ";
for (const auto &subfield: v.GetObject()) {
if (first)
first = false;
else
cout << ", ";
printField(v, subfield.name.GetString(), false);
}
cout << " }";
break;
}
case kArrayType: {
bool first = true;
cout << "[ ";
for (const auto &arrEntry: v.GetArray()) {
if (first)
first = false;
else
cout << ", ";
printField(arrEntry, "", false);
}
cout << " ]";
break;
}
case kStringType:
cout << v.GetString();
break;
case kNumberType:
if (v.IsInt64())
cout << v.GetInt64();
else if (v.IsUint64())
cout << v.GetUint64();
else
cout << v.GetDouble();
break;
default:
stringstream msg;
msg << "Unexpected RapidJSON Value type: " << v.GetType();
throw logic_error(msg.str());
}
}
}
这使用了 stringize 的东西来解决一些问题,但是,如果你不喜欢那样,你可以手动获得相同的效果。它使用级联 if
细分 IsNumber
案例;如果你需要更多的分辨率,你可以添加其他案例。
JSON 看起来像这样:
{
"testBool": true,
"testString": "eu"
}
而且我现在的解析器看起来真的很难看,感觉真的有更优雅的方法来解决这个问题。我尝试使用 document.GetObject().GetType()
研究 rapidjson::Type
的 switch case,但它不提供使用 Get%TypeName%()
函数可以实现的相同类型精度。 hashmap
只不过是 std::unordered_map<std::string, std::any>
.
rapidjson::Document document;
document.Parse(tmp_string.c_str());
for (auto& member : document.GetObject())
{
if (member.value.IsBool())
{
hashmap->addEntry<bool>(member.name.GetString(), member.value.GetBool());
}
else if (member.value.IsString())
{
hashmap->addEntry<std::string>(member.name.GetString(), member.value.GetString());
}
else if (member.value.IsInt())
{
hashmap->addEntry<int>(member.name.GetString(), member.value.GetInt());
}
.....
//And so on
.....
}
my current parser looks really ugly
美丽在持有人的眼中……这是我的代码:
static void
printField(const Value& e, const string& fld, bool print_newline = true) {
const Value &v = fld.empty() ? e : e[fld];
if (print_newline)
cout << endl << "\t";
if (not fld.empty())
cout << fld << ": ";
if ( /* custom stuff required? */ ) {
// Do custom stuff
else {
switch (v.GetType()) {
case kNullType:
cout << "Null";
break;
case kFalseType:
case kTrueType:
cout << v.GetBool();
break;
case kObjectType: {
bool first = true;
cout << "{ ";
for (const auto &subfield: v.GetObject()) {
if (first)
first = false;
else
cout << ", ";
printField(v, subfield.name.GetString(), false);
}
cout << " }";
break;
}
case kArrayType: {
bool first = true;
cout << "[ ";
for (const auto &arrEntry: v.GetArray()) {
if (first)
first = false;
else
cout << ", ";
printField(arrEntry, "", false);
}
cout << " ]";
break;
}
case kStringType:
cout << v.GetString();
break;
case kNumberType:
if (v.IsInt64())
cout << v.GetInt64();
else if (v.IsUint64())
cout << v.GetUint64();
else
cout << v.GetDouble();
break;
default:
stringstream msg;
msg << "Unexpected RapidJSON Value type: " << v.GetType();
throw logic_error(msg.str());
}
}
}
这使用了 stringize 的东西来解决一些问题,但是,如果你不喜欢那样,你可以手动获得相同的效果。它使用级联 if
细分 IsNumber
案例;如果你需要更多的分辨率,你可以添加其他案例。