changeset 634:005794d9cf77

json_util: cleanups - Make overloads that takes a string as a key, - make header only code, - Remove contains function, use std::count or std::find instead.
author David Demelier <markand@malikania.fr>
date Fri, 23 Mar 2018 12:56:47 +0100
parents b3db5933c08b
children 002c13ee0021
files cpp/json_util/CMakeLists.txt cpp/json_util/json_util.cpp cpp/json_util/json_util.hpp
diffstat 3 files changed, 153 insertions(+), 244 deletions(-) [+]
line wrap: on
line diff
--- a/cpp/json_util/CMakeLists.txt	Fri Mar 23 12:55:52 2018 +0100
+++ b/cpp/json_util/CMakeLists.txt	Fri Mar 23 12:56:47 2018 +0100
@@ -16,13 +16,12 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-project(options)
+project(json-util)
 
 code_define_module(
     NAME json-util
     LIBRARIES json
     SOURCES
-        ${options_SOURCE_DIR}/json_util.cpp
-        ${options_SOURCE_DIR}/json_util.hpp
+        ${json-util_SOURCE_DIR}/json_util.hpp
 )
 
--- a/cpp/json_util/json_util.cpp	Fri Mar 23 12:55:52 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * json_util.cpp -- utilities for JSON
- *
- * Copyright (c) 2018 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "json_util.hpp"
-
-namespace json_util {
-
-boost::optional<nlohmann::json> get(const nlohmann::json& json,
-                                    const nlohmann::json::json_pointer& key) noexcept
-{
-    // Unfortunately, there is no find using pointer yet.
-    try {
-        return json.at(key);
-    } catch (...) {
-        return boost::none;
-    }
-}
-
-boost::optional<bool> get_bool(const nlohmann::json& json,
-                               const nlohmann::json::json_pointer& key) noexcept
-{
-    const auto v = get(json, key);
-
-    if (!v || !v->is_boolean())
-        return boost::none;
-
-    return v->get<bool>();
-}
-
-boost::optional<std::uint64_t> get_int(const nlohmann::json& json,
-                                       const nlohmann::json::json_pointer& key) noexcept
-{
-    const auto v = get(json, key);
-
-    if (!v || !v->is_number_integer())
-        return boost::none;
-
-    return v->get<std::uint64_t>();
-}
-
-boost::optional<std::uint64_t> get_uint(const nlohmann::json& json,
-                                        const nlohmann::json::json_pointer& key) noexcept
-{
-    const auto v = get(json, key);
-
-    if (!v || !v->is_number_unsigned())
-        return boost::none;
-
-    return v->get<std::uint64_t>();
-}
-
-boost::optional<std::string> get_string(const nlohmann::json& json,
-                                        const nlohmann::json::json_pointer& key) noexcept
-{
-    const auto v = get(json, key);
-
-    if (!v || !v->is_string())
-        return boost::none;
-
-    return v->get<std::string>();
-}
-
-boost::optional<bool> optional_bool(const nlohmann::json& json,
-                                    const nlohmann::json::json_pointer& key,
-                                    bool def) noexcept
-{
-    const auto v = get(json, key);
-
-    if (!v)
-        return def;
-    if (!v->is_boolean())
-        return boost::none;
-
-    return v->get<bool>();
-}
-
-boost::optional<std::int64_t> optional_int(const nlohmann::json& json,
-                                           const nlohmann::json::json_pointer& key,
-                                           std::int64_t def) noexcept
-{
-    const auto v = get(json, key);
-
-    if (!v)
-        return def;
-    if (!v->is_number_integer())
-        return boost::none;
-
-    return v->get<std::int64_t>();
-}
-
-boost::optional<std::uint64_t> optional_uint(const nlohmann::json& json,
-                                             const nlohmann::json::json_pointer& key,
-                                             std::uint64_t def) noexcept
-{
-    const auto v = get(json, key);
-
-    if (!v)
-        return def;
-    if (!v->is_number_unsigned())
-        return boost::none;
-
-    return v->get<std::uint64_t>();
-}
-
-boost::optional<std::string> optional_string(const nlohmann::json& json,
-                                             const nlohmann::json::json_pointer& key,
-                                             const std::string& def) noexcept
-{
-    const auto v = get(json, key);
-
-    if (!v)
-        return def;
-    if (!v->is_string())
-        return boost::none;
-
-    return v->get<std::string>();
-}
-
-std::string pretty(const nlohmann::json& value)
-{
-    switch (value.type()) {
-    case nlohmann::json::value_t::boolean:
-        return value.get<bool>() ? "true" : "false";
-    case nlohmann::json::value_t::string:
-        return value.get<std::string>();
-    default:
-        return value.dump();
-    }
-}
-
-bool contains(const nlohmann::json& array, const nlohmann::json& value) noexcept
-{
-    for (const auto &v : array)
-        if (v == value)
-            return true;
-
-    return false;
-}
-
-} // !json_util
--- a/cpp/json_util/json_util.hpp	Fri Mar 23 12:55:52 2018 +0100
+++ b/cpp/json_util/json_util.hpp	Fri Mar 23 12:56:47 2018 +0100
@@ -24,17 +24,6 @@
  * \brief Utilities for JSON.
  */
 
-/**
- * \page Json Json
- * \brief Utilities for JSON.
- *
- * ## Export macros
- *
- * You must define `JSON_UTIL_DLL` globally and `JSON_UTIL_BUILDING_DLL` when
- * compiling the library if you want a DLL, alternatively you can provide your
- * own `JSON_UTIL_EXPORT` macro instead.
- */
-
 #include <cstdint>
 #include <string>
 
@@ -43,30 +32,6 @@
 #include <json.hpp>
 
 /**
- * \cond JSON_UTIL_HIDDEN_SYMBOLS
- */
-
-#if !defined(JSON_UTIL_EXPORT)
-#   if defined(JSON_UTIL_DLL)
-#       if defined(_WIN32)
-#           if defined(JSON_UTIL_BUILDING_DLL)
-#               define JSON_UTIL_EXPORT __declspec(dllexport)
-#           else
-#               define JSON_UTIL_EXPORT __declspec(dllimport)
-#           endif
-#       else
-#           define JSON_UTIL_EXPORT
-#       endif
-#   else
-#       define JSON_UTIL_EXPORT
-#   endif
-#endif
-
-/**
- * \endcond
- */
-
-/**
  * \brief Utilities for JSON.
  */
 namespace json_util {
@@ -78,53 +43,106 @@
  * \param key the pointer to the object
  * \return the value or boost::none if not found
  */
-JSON_UTIL_EXPORT
-boost::optional<nlohmann::json> get(const nlohmann::json& json,
-                                    const nlohmann::json::json_pointer& key) noexcept;
+inline boost::optional<nlohmann::json> get(const nlohmann::json& json,
+                                           const nlohmann::json::json_pointer& key) noexcept
+{
+    // Unfortunately, there is no find using pointer yet.
+    try {
+        return json.at(key);
+    } catch (...) {
+        return boost::none;
+    }
+}
+
+/**
+ * Convenient overload with simple key.
+ *
+ * \param json the JSON object/array
+ * \param key the pointer to the object
+ * \return the value or boost::none if not found
+ */
+inline boost::optional<nlohmann::json> get(const nlohmann::json& json,
+                                           const std::string& key) noexcept
+{
+    const auto it = json.find(key);
+
+    if (it == json.end())
+        return boost::none;
+
+    return *it;
+}
 
 /**
  * Get a bool or null if not found or invalid.
  *
  * \param json the JSON object/array
- * \param key the pointer to the object
+ * \param key the pointer or property key
  * \return the value or boost::none if not found or invalid
  */
-JSON_UTIL_EXPORT
-boost::optional<bool> get_bool(const nlohmann::json& json,
-                               const nlohmann::json::json_pointer& key) noexcept;
+template <typename Key>
+inline boost::optional<bool> get_bool(const nlohmann::json& json, const Key& key) noexcept
+{
+    const auto v = get(json, key);
+
+    if (!v || !v->is_boolean())
+        return boost::none;
+
+    return v->template get<bool>();
+}
 
 /**
  * Get a 64 bit signed integer or null if not found or invalid.
  *
  * \param json the JSON object/array
- * \param key the pointer to the object
+ * \param key the pointer or property key
  * \return the value or boost::none if not found or invalid
  */
-JSON_UTIL_EXPORT
-boost::optional<std::uint64_t> get_int(const nlohmann::json& json,
-                                       const nlohmann::json::json_pointer& key) noexcept;
+template <typename Key>
+inline boost::optional<std::int64_t> get_int(const nlohmann::json& json, const Key& key) noexcept
+{
+    const auto v = get(json, key);
+
+    if (!v || !v->is_number_integer())
+        return boost::none;
+
+    return v->template get<std::int64_t>();
+}
 
 /**
  * Get a 64 bit unsigned integer or null if not found or invalid.
  *
  * \param json the JSON object/array
- * \param key the pointer to the object
+ * \param key the pointer or property key
  * \return the value or boost::none if not found or invalid
  */
-JSON_UTIL_EXPORT
-boost::optional<std::uint64_t> get_uint(const nlohmann::json& json,
-                                        const nlohmann::json::json_pointer& key) noexcept;
+template <typename Key>
+inline boost::optional<std::uint64_t> get_uint(const nlohmann::json& json, const Key& key) noexcept
+{
+    const auto v = get(json, key);
+
+    if (!v || !v->is_number_unsigned())
+        return boost::none;
+
+    return v->template get<std::uint64_t>();
+}
 
 /**
  * Get a string or null if not found or invalid.
  *
  * \param json the JSON object/array
- * \param key the pointer to the object
+ * \param key the pointer or property key
  * \return the value or boost::none if not found or invalid
  */
-JSON_UTIL_EXPORT
-boost::optional<std::string> get_string(const nlohmann::json& json,
-                                        const nlohmann::json::json_pointer& key) noexcept;
+template <typename Key>
+inline boost::optional<std::string> get_string(const nlohmann::json& json, const Key& key) noexcept
+{
+    const auto v = get(json, key);
+
+    if (!v || !v->is_string())
+        return boost::none;
+
+    return v->template get<std::string>();
+}
 
 /**
  * Get an optional bool.
@@ -133,14 +151,22 @@
  * a bool, return boost::none, otherwise return the value.
  *
  * \param json the JSON object/array
- * \param key the pointer to the object
+ * \param key the pointer or property key
  * \param def the default value
  * \return the value, boost::none or def
  */
-JSON_UTIL_EXPORT
-boost::optional<bool> optional_bool(const nlohmann::json& json,
-                                    const nlohmann::json::json_pointer& key,
-                                    bool def = false) noexcept;
+template <typename Key>
+inline boost::optional<bool> optional_bool(const nlohmann::json& json, const Key& key, bool def = false) noexcept
+{
+    const auto v = get(json, key);
+
+    if (!v)
+        return def;
+    if (!v->is_boolean())
+        return boost::none;
+
+    return v->template get<bool>();
+}
 
 /**
  * Get an optional integer.
@@ -149,14 +175,24 @@
  * an integer, return boost::none, otherwise return the value.
  *
  * \param json the JSON object/array
- * \param key the pointer to the object
+ * \param key the pointer or property key
  * \param def the default value
  * \return the value, boost::none or def
  */
-JSON_UTIL_EXPORT
-boost::optional<std::int64_t> optional_int(const nlohmann::json& json,
-                                           const nlohmann::json::json_pointer& key,
-                                           std::int64_t def = 0) noexcept;
+template <typename Key>
+inline boost::optional<std::int64_t> optional_int(const nlohmann::json& json,
+                                                  const Key& key,
+                                                  std::int64_t def = 0) noexcept
+{
+    const auto v = get(json, key);
+
+    if (!v)
+        return def;
+    if (!v->is_number_integer())
+        return boost::none;
+
+    return v->template get<std::int64_t>();
+}
 
 /**
  * Get an optional unsigned integer.
@@ -165,14 +201,24 @@
  * an unsigned integer, return boost::none, otherwise return the value.
  *
  * \param json the JSON object/array
- * \param key the pointer to the object
+ * \param key the pointer or property key
  * \param def the default value
  * \return the value, boost::none or def
  */
-JSON_UTIL_EXPORT
-boost::optional<std::uint64_t> optional_uint(const nlohmann::json& json,
-                                             const nlohmann::json::json_pointer& key,
-                                             std::uint64_t def = 0) noexcept;
+template <typename Key>
+inline boost::optional<std::uint64_t> optional_uint(const nlohmann::json& json,
+                                                    const Key& key,
+                                                    std::uint64_t def = 0) noexcept
+{
+    const auto v = get(json, key);
+
+    if (!v)
+        return def;
+    if (!v->is_number_unsigned())
+        return boost::none;
+
+    return v->template get<std::uint64_t>();
+}
 
 /**
  * Get an optional string.
@@ -181,33 +227,52 @@
  * a string, return boost::none, otherwise return the value.
  *
  * \param json the JSON object/array
- * \param key the pointer to the object
+ * \param key the pointer or property key
  * \param def the default value
  * \return the value, boost::none or def
  */
-JSON_UTIL_EXPORT
-boost::optional<std::string> optional_string(const nlohmann::json& json,
-                                             const nlohmann::json::json_pointer& key,
-                                             const std::string& def = "") noexcept;
+template <typename Key>
+inline boost::optional<std::string> optional_string(const nlohmann::json& json,
+                                                    const Key& key,
+                                                    const std::string& def = "") noexcept
+{
+    const auto v = get(json, key);
+
+    if (!v)
+        return def;
+    if (!v->is_string())
+        return boost::none;
+
+    return v->template get<std::string>();
+}
 
 /**
  * Print the value as human readable.
  *
+ * \note This only works on flat objects.
  * \param value the value
+ * \param indent the optional indent for objects/arrays
  * \return the string
  */
-JSON_UTIL_EXPORT
-std::string pretty(const nlohmann::json& value);
-
-/**
- * Check if the array contains the given value.
- *
- * \param array the array
- * \param value the JSON value to check
- * \return true if present
- */
-JSON_UTIL_EXPORT
-bool contains(const nlohmann::json& array, const nlohmann::json& value) noexcept;
+inline std::string pretty(const nlohmann::json& value, int indent = 4)
+{
+    switch (value.type()) {
+    case nlohmann::json::value_t::null:
+        return "null";
+    case nlohmann::json::value_t::string:
+        return value.get<std::string>();
+    case nlohmann::json::value_t::boolean:
+        return value.get<bool>() ? "true" : "false";
+    case nlohmann::json::value_t::number_integer:
+        return std::to_string(value.get<std::int64_t>());
+    case nlohmann::json::value_t::number_unsigned:
+        return std::to_string(value.get<std::uint64_t>());
+    case nlohmann::json::value_t::number_float:
+        return std::to_string(value.get<double>());
+    default:
+        return value.dump(indent);
+    }
+}
 
 } // !json_util