mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #13579 from ethereum/refactor-json
[libsolutil] Add new JSON helper functions.
This commit is contained in:
		
						commit
						0c168b154c
					
				| @ -67,4 +67,66 @@ std::string jsonPrint(Json::Value const& _input, JsonFormat const& _format); | ||||
| /// \return \c true if the document was successfully parsed, \c false if an error occurred.
 | ||||
| bool jsonParseStrict(std::string const& _input, Json::Value& _json, std::string* _errs = nullptr); | ||||
| 
 | ||||
| namespace detail | ||||
| { | ||||
| 
 | ||||
| template<typename T> | ||||
| struct helper; | ||||
| 
 | ||||
| template<typename T, bool(Json::Value::*checkMember)() const, T(Json::Value::*convertMember)() const> | ||||
| struct helper_impl | ||||
| { | ||||
| 	static bool isOfType(Json::Value const& _input) | ||||
| 	{ | ||||
| 		return (_input.*checkMember)(); | ||||
| 	} | ||||
| 	static T get(Json::Value const& _input) | ||||
| 	{ | ||||
| 		return (_input.*convertMember)(); | ||||
| 	} | ||||
| 	static T getOrDefault(Json::Value const& _input, T _default = {}) | ||||
| 	{ | ||||
| 		T result = _default; | ||||
| 		if (isOfType(_input)) | ||||
| 			result = (_input.*convertMember)(); | ||||
| 		return result; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| template<> struct helper<float>: helper_impl<float, &Json::Value::isDouble, &Json::Value::asFloat> {}; | ||||
| template<> struct helper<double>: helper_impl<double, &Json::Value::isDouble, &Json::Value::asDouble> {}; | ||||
| template<> struct helper<std::string>: helper_impl<std::string, &Json::Value::isString, &Json::Value::asString> {}; | ||||
| template<> struct helper<Json::Int>: helper_impl<Json::Int, &Json::Value::isInt, &Json::Value::asInt> {}; | ||||
| template<> struct helper<Json::Int64>: helper_impl<Json::Int64, &Json::Value::isInt64, &Json::Value::asInt64> {}; | ||||
| template<> struct helper<Json::UInt>: helper_impl<Json::UInt, &Json::Value::isUInt, &Json::Value::asUInt> {}; | ||||
| template<> struct helper<Json::UInt64>: helper_impl<Json::UInt64, &Json::Value::isUInt64, &Json::Value::asUInt64> {}; | ||||
| 
 | ||||
| } // namespace detail
 | ||||
| 
 | ||||
| template<typename T> | ||||
| bool isOfType(Json::Value const& _input) | ||||
| { | ||||
| 	return detail::helper<T>::isOfType(_input); | ||||
| } | ||||
| 
 | ||||
| template<typename T> | ||||
| bool isOfTypeIfExists(Json::Value const& _input, std::string const& _name) | ||||
| { | ||||
| 	if (_input.isMember(_name)) | ||||
| 		return isOfType<T>(_input[_name]); | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| template<typename T> | ||||
| T get(Json::Value const& _input) | ||||
| { | ||||
| 	return detail::helper<T>::get(_input); | ||||
| } | ||||
| 
 | ||||
| template<typename T> | ||||
| T getOrDefault(Json::Value const& _input, T _default = {}) | ||||
| { | ||||
| 	return detail::helper<T>::getOrDefault(_input, _default); | ||||
| } | ||||
| 
 | ||||
| } // namespace solidity::util
 | ||||
|  | ||||
| @ -184,6 +184,131 @@ BOOST_AUTO_TEST_CASE(parse_json_strict) | ||||
| 	BOOST_CHECK(json[0] == "😊"); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(json_isOfType) | ||||
| { | ||||
| 	Json::Value json; | ||||
| 
 | ||||
| 	json["float"] = 3.1f; | ||||
| 	json["double"] = 3.1; | ||||
| 	json["int"] = 2; | ||||
| 	json["int64"] = Json::Int64{0x4000000000000000}; | ||||
| 	json["string"] = "Hello World!"; | ||||
| 
 | ||||
| 	BOOST_CHECK(isOfType<float>(json["float"])); | ||||
| 	BOOST_CHECK(isOfType<double>(json["double"])); | ||||
| 	BOOST_CHECK(isOfType<int>(json["int"])); | ||||
| 	BOOST_CHECK(isOfType<Json::Int>(json["int"])); | ||||
| 	BOOST_CHECK(isOfType<Json::UInt>(json["int"])); | ||||
| 	BOOST_CHECK(isOfType<Json::Int64>(json["int"])); | ||||
| 	BOOST_CHECK(isOfType<Json::Int64>(json["int64"])); | ||||
| 	BOOST_CHECK(isOfType<Json::UInt64>(json["int64"])); | ||||
| 	BOOST_CHECK(isOfType<std::string>(json["string"])); | ||||
| 	BOOST_CHECK(!isOfType<Json::Int>(json["int64"])); | ||||
| 	BOOST_CHECK(!isOfType<int>(json["double"])); | ||||
| 	BOOST_CHECK(!isOfType<float>(json["string"])); | ||||
| 	BOOST_CHECK(!isOfType<double>(json["string"])); | ||||
| 	BOOST_CHECK(!isOfType<Json::Int>(json["string"])); | ||||
| 	BOOST_CHECK(!isOfType<Json::Int64>(json["string"])); | ||||
| 	BOOST_CHECK(!isOfType<Json::UInt>(json["string"])); | ||||
| 	BOOST_CHECK(!isOfType<Json::UInt64>(json["string"])); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(json_isisOfTypeIfExists) | ||||
| { | ||||
| 	Json::Value json; | ||||
| 
 | ||||
| 	json["float"] = 3.1f; | ||||
| 	json["double"] = 3.1; | ||||
| 	json["int"] = 2; | ||||
| 	json["int64"] = Json::Int64{0x4000000000000000}; | ||||
| 	json["string"] = "Hello World!"; | ||||
| 
 | ||||
| 	BOOST_CHECK(isOfTypeIfExists<float>(json, "float")); | ||||
| 	BOOST_CHECK(isOfTypeIfExists<double>(json, "double")); | ||||
| 	BOOST_CHECK(isOfTypeIfExists<int>(json, "int")); | ||||
| 	BOOST_CHECK(isOfTypeIfExists<Json::Int>(json, "int")); | ||||
| 	BOOST_CHECK(isOfTypeIfExists<Json::UInt>(json, "int")); | ||||
| 	BOOST_CHECK(isOfTypeIfExists<Json::Int64>(json, "int")); | ||||
| 	BOOST_CHECK(isOfTypeIfExists<Json::Int64>(json, "int64")); | ||||
| 	BOOST_CHECK(isOfTypeIfExists<Json::UInt64>(json, "int64")); | ||||
| 	BOOST_CHECK(isOfTypeIfExists<std::string>(json, "string")); | ||||
| 	BOOST_CHECK(!isOfTypeIfExists<Json::Int>(json, "int64")); | ||||
| 	BOOST_CHECK(!isOfTypeIfExists<int>(json, "double")); | ||||
| 	BOOST_CHECK(!isOfTypeIfExists<float>(json, "string")); | ||||
| 	BOOST_CHECK(!isOfTypeIfExists<double>(json, "string")); | ||||
| 	BOOST_CHECK(!isOfTypeIfExists<Json::Int>(json, "string")); | ||||
| 	BOOST_CHECK(!isOfTypeIfExists<Json::Int64>(json, "string")); | ||||
| 	BOOST_CHECK(!isOfTypeIfExists<Json::UInt>(json, "string")); | ||||
| 	BOOST_CHECK(!isOfTypeIfExists<Json::UInt64>(json, "string")); | ||||
| 	BOOST_CHECK(isOfTypeIfExists<Json::UInt64>(json, "NOT_EXISTING")); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(json_getOrDefault) | ||||
| { | ||||
| 	Json::Value json; | ||||
| 
 | ||||
| 	json["float"] = 3.1f; | ||||
| 	json["double"] = 3.1; | ||||
| 	json["int"] = 2; | ||||
| 	json["int64"] = Json::Int64{0x4000000000000000}; | ||||
| 	json["uint64"] = Json::UInt64{0x5000000000000000}; | ||||
| 	json["string"] = "Hello World!"; | ||||
| 
 | ||||
| 	BOOST_CHECK(getOrDefault<float>(json["float"]) == 3.1f); | ||||
| 	BOOST_CHECK(getOrDefault<float>(json["float"], -1.1f) == 3.1f); | ||||
| 	BOOST_CHECK(getOrDefault<float>(json["no_float"], -1.1f) == -1.1f); | ||||
| 	BOOST_CHECK(getOrDefault<double>(json["double"]) == 3.1); | ||||
| 	BOOST_CHECK(getOrDefault<double>(json["double"], -1) == 3.1); | ||||
| 	BOOST_CHECK(getOrDefault<double>(json["no_double"], -1.1) == -1.1); | ||||
| 	BOOST_CHECK(getOrDefault<int>(json["int"]) == 2); | ||||
| 	BOOST_CHECK(getOrDefault<int>(json["int"], -1) == 2); | ||||
| 	BOOST_CHECK(getOrDefault<int>(json["no_int"], -1) == -1); | ||||
| 	BOOST_CHECK(getOrDefault<Json::Int>(json["int"]) == 2); | ||||
| 	BOOST_CHECK(getOrDefault<Json::Int>(json["int"], -1) == 2); | ||||
| 	BOOST_CHECK(getOrDefault<Json::Int>(json["no_int"], -1) == -1); | ||||
| 	BOOST_CHECK(getOrDefault<Json::UInt>(json["int"]) == 2); | ||||
| 	BOOST_CHECK(getOrDefault<Json::UInt>(json["int"], 1) == 2); | ||||
| 	BOOST_CHECK(getOrDefault<Json::UInt>(json["no_int"], 1) == 1); | ||||
| 	BOOST_CHECK(getOrDefault<Json::Int64>(json["int"]) == 2); | ||||
| 	BOOST_CHECK(getOrDefault<Json::Int64>(json["int"], -1) == 2); | ||||
| 	BOOST_CHECK(getOrDefault<Json::Int64>(json["no_int"], -1) == -1); | ||||
| 	BOOST_CHECK(getOrDefault<Json::Int64>(json["int64"]) == 0x4000000000000000); | ||||
| 	BOOST_CHECK(getOrDefault<Json::Int64>(json["int64"], -1) == 0x4000000000000000); | ||||
| 	BOOST_CHECK(getOrDefault<Json::Int64>(json["no_int64"], -1) == -1); | ||||
| 	BOOST_CHECK(getOrDefault<Json::UInt64>(json["int64"]) == 0x4000000000000000); | ||||
| 	BOOST_CHECK(getOrDefault<Json::UInt64>(json["int64"], 1) == 0x4000000000000000); | ||||
| 	BOOST_CHECK(getOrDefault<Json::UInt64>(json["no_int64"], 1) == 1); | ||||
| 	BOOST_CHECK(getOrDefault<Json::UInt64>(json["uint64"]) == 0x5000000000000000); | ||||
| 	BOOST_CHECK(getOrDefault<Json::UInt64>(json["uint64"], 1) == 0x5000000000000000); | ||||
| 	BOOST_CHECK(getOrDefault<Json::UInt64>(json["no_uint64"], 1) == 1); | ||||
| 	BOOST_CHECK(getOrDefault<std::string>(json["string"], "ERROR") == "Hello World!"); | ||||
| 	BOOST_CHECK(getOrDefault<std::string>(json["no_string"]).empty()); | ||||
| 	BOOST_CHECK(getOrDefault<std::string>(json["no_string"], "ERROR") == "ERROR"); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(json_get) | ||||
| { | ||||
| 	Json::Value json; | ||||
| 
 | ||||
| 	json["float"] = 3.1f; | ||||
| 	json["double"] = 3.1; | ||||
| 	json["int"] = 2; | ||||
| 	json["int64"] = Json::Int64{0x4000000000000000}; | ||||
| 	json["uint64"] = Json::UInt64{0x5000000000000000}; | ||||
| 	json["string"] = "Hello World!"; | ||||
| 
 | ||||
| 	BOOST_CHECK(get<float>(json["float"]) == 3.1f); | ||||
| 	BOOST_CHECK(get<double>(json["double"]) == 3.1); | ||||
| 	BOOST_CHECK(get<int>(json["int"]) == 2); | ||||
| 	BOOST_CHECK(get<Json::Int>(json["int"]) == 2); | ||||
| 	BOOST_CHECK(get<Json::UInt>(json["int"]) == 2); | ||||
| 	BOOST_CHECK(get<Json::Int64>(json["int"]) == 2); | ||||
| 	BOOST_CHECK(get<Json::Int64>(json["int64"]) == 0x4000000000000000); | ||||
| 	BOOST_CHECK(get<Json::UInt64>(json["int64"]) == 0x4000000000000000); | ||||
| 	BOOST_CHECK(get<Json::UInt64>(json["uint64"]) == 0x5000000000000000); | ||||
| 	BOOST_CHECK(get<std::string>(json["string"]) == "Hello World!"); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_SUITE_END() | ||||
| 
 | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user