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.
 | /// \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); | 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_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() | BOOST_AUTO_TEST_SUITE_END() | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user