You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2014/08/12 00:51:33 UTC
git commit: Added a JSON::Object::find.
Repository: mesos
Updated Branches:
refs/heads/master cfa168f51 -> 7933de5ca
Added a JSON::Object::find.
Review: https://reviews.apache.org/r/24541
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/7933de5c
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/7933de5c
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/7933de5c
Branch: refs/heads/master
Commit: 7933de5ca19974af8b908f643ff2891bd7d8bd80
Parents: cfa168f
Author: Benjamin Hindman <be...@gmail.com>
Authored: Sun Aug 10 23:49:02 2014 -0700
Committer: Benjamin Hindman <be...@gmail.com>
Committed: Mon Aug 11 15:51:05 2014 -0700
----------------------------------------------------------------------
.../3rdparty/stout/include/stout/json.hpp | 93 ++++++++++++++++++--
.../3rdparty/stout/tests/json_tests.cpp | 56 ++++++++++++
2 files changed, 140 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/7933de5c/3rdparty/libprocess/3rdparty/stout/include/stout/json.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/json.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/json.hpp
index 0ce002c..d98d953 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/json.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/json.hpp
@@ -22,6 +22,7 @@
#include <list>
#include <map>
#include <string>
+#include <vector>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/utility/enable_if.hpp>
@@ -29,6 +30,8 @@
#include <stout/check.hpp>
#include <stout/foreach.hpp>
+#include <stout/result.hpp>
+#include <stout/strings.hpp>
#include <stout/try.hpp>
#include <stout/unreachable.hpp>
@@ -79,6 +82,23 @@ struct Number
struct Object
{
+ // Returns the JSON value (specified by the type) given a "path"
+ // into the structure, for example:
+ //
+ // Result<JSON::Array> array = object.find<JSON::Array>("nested.array");
+ //
+ // Will return 'None' if no field could be found called 'array'
+ // within a field called 'nested' of 'object' (where 'nested' must
+ // also be a JSON object).
+ //
+ // Returns an error if a JSON value of the wrong type is found, or
+ // an intermediate JSON value is not an object that we can do a
+ // recursive find on.
+ //
+ // TODO(benh): Support paths that index, e.g., 'nested.array[4].field'.
+ template <typename T>
+ Result<T> find(const std::string& path) const;
+
std::map<std::string, Value> values;
};
@@ -159,20 +179,75 @@ struct Value : internal::Variant
: internal::Variant(value) {}
template <typename T>
- bool is() const
- {
- const T* t = boost::get<T>(this);
- return t != NULL;
- }
+ bool is() const;
template <typename T>
- const T& as() const
- {
- return *CHECK_NOTNULL(boost::get<T>(this));
- }
+ const T& as() const;
};
+template <typename T>
+bool Value::is() const
+{
+ const T* t = boost::get<T>(this);
+ return t != NULL;
+}
+
+
+template <>
+inline bool Value::is<Value>() const
+{
+ return true;
+}
+
+
+template <typename T>
+const T& Value::as() const
+{
+ return *CHECK_NOTNULL(boost::get<T>(this));
+}
+
+
+template <>
+inline const Value& Value::as<Value>() const
+{
+ return *this;
+}
+
+
+
+template <typename T>
+Result<T> Object::find(const std::string& path) const
+{
+ const std::vector<std::string>& names = strings::split(path, ".", 2);
+
+ if (names.empty()) {
+ return None();
+ }
+
+ std::map<std::string, Value>::const_iterator entry = values.find(names[0]);
+
+ if (entry == values.end()) {
+ return None();
+ }
+
+ const Value& value = entry->second;
+
+ if (names.size() == 1) {
+ if (!value.is<T>()) {
+ // TODO(benh): Use a visitor to print out the type found.
+ return Error("Found JSON value of wrong type");
+ }
+ return value.as<T>();
+ } else if (!value.is<Object>()) {
+ // TODO(benh): Use a visitor to print out the intermediate type.
+ return Error("Intermediate JSON value not an object");
+ }
+
+ return value.as<Object>().find<T>(names[1]);
+}
+
+
struct Comparator : boost::static_visitor<bool>
{
Comparator(const Value& _value)
http://git-wip-us.apache.org/repos/asf/mesos/blob/7933de5c/3rdparty/libprocess/3rdparty/stout/tests/json_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/json_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/json_tests.cpp
index ee82d15..3bfc8e6 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/json_tests.cpp
+++ b/3rdparty/libprocess/3rdparty/stout/tests/json_tests.cpp
@@ -175,3 +175,59 @@ TEST(JsonTest, parse)
EXPECT_SOME_EQ(object, JSON::parse(stringify(object)));
}
+
+
+TEST(JsonTest, Find)
+{
+ JSON::Object object;
+
+ JSON::Object nested1;
+
+ JSON::Object nested2;
+ nested2.values["string"] = "string";
+ nested2.values["integer"] = -1;
+ nested2.values["double"] = -1.42;
+ nested2.values["null"] = JSON::Null();
+
+ JSON::Array array;
+ array.values.push_back("hello");
+
+ nested2.values["array"] = array;
+
+ nested1.values["nested2"] = nested2;
+
+ object.values["nested1"] = nested1;
+
+ ASSERT_NONE(object.find<JSON::String>("nested.nested.string"));
+ ASSERT_NONE(object.find<JSON::String>("nested1.nested2.none"));
+
+ ASSERT_ERROR(object.find<JSON::String>("nested1.nested2.array"));
+ ASSERT_ERROR(object.find<JSON::String>("nested1.nested2.array.foo"));
+
+ ASSERT_SOME_EQ(
+ JSON::String("string"),
+ object.find<JSON::String>("nested1.nested2.string"));
+
+ ASSERT_SOME_EQ(
+ JSON::Number(-1),
+ object.find<JSON::Number>("nested1.nested2.integer"));
+
+ ASSERT_SOME_EQ(
+ JSON::Number(-1.42),
+ object.find<JSON::Number>("nested1.nested2.double"));
+
+ ASSERT_SOME_EQ(
+ JSON::Null(),
+ object.find<JSON::Null>("nested1.nested2.null"));
+
+ Result<JSON::Array> result =
+ object.find<JSON::Array>("nested1.nested2.array");
+
+ ASSERT_SOME(result);
+ ASSERT_FALSE(result.get().values.empty());
+ ASSERT_TRUE(result.get().values.front().is<JSON::String>());
+ ASSERT_EQ("hello", result.get().values.front().as<JSON::String>());
+
+ // Also test getting JSON::Value when you don't know the type.
+ ASSERT_SOME(object.find<JSON::Value>("nested1.nested2.null"));
+}