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"));
+}