aboutsummaryrefslogtreecommitdiff
path: root/include/jsoncons_ext/jsonpath/json_query.hpp
blob: 8facfa982f057788eab3f70521b175ad4ec9f4cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright 2021 Daniel Parker
// Distributed under the Boost license, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

// See https://github.com/danielaparker/jsoncons for latest version

#ifndef JSONCONS_JSONPATH_JSON_QUERY_HPP
#define JSONCONS_JSONPATH_JSON_QUERY_HPP

#include <jsoncons/json.hpp>
#include <jsoncons_ext/jsonpath/jsonpath_expression.hpp>

namespace jsoncons { 
namespace jsonpath {
     
    template<class Json>
    Json json_query(const Json& instance,
                    const typename Json::string_view_type& path, 
                    result_options options = result_options(),
                    const custom_functions<Json>& functions = custom_functions<Json>())
    {
        auto expr = make_expression<Json>(path, functions);
        return expr.evaluate(instance, options);
    }

    template<class Json,class Callback>
    typename std::enable_if<type_traits::is_binary_function_object<Callback,const std::basic_string<typename Json::char_type>&,const Json&>::value,void>::type
    json_query(const Json& instance, 
               const typename Json::string_view_type& path, 
               Callback callback,
               result_options options = result_options(),
               const custom_functions<Json>& functions = custom_functions<Json>())
    {
        auto expr = make_expression<Json>(path, functions);
        expr.evaluate(instance, callback, options);
    }

    template<class Json, class T>
    typename std::enable_if<is_json_type_traits_specialized<Json,T>::value,void>::type
        json_replace(Json& instance, const typename Json::string_view_type& path, T&& new_value,
                     result_options options = result_options::nodups,
                     const custom_functions<Json>& funcs = custom_functions<Json>())
    {
        using evaluator_t = typename jsoncons::jsonpath::detail::jsonpath_evaluator<Json, Json&>;
        //using string_type = typename evaluator_t::string_type;
        using value_type = typename evaluator_t::value_type;
        using reference = typename evaluator_t::reference;
        using json_selector_t = typename evaluator_t::path_expression_type;
        using json_location_type = typename evaluator_t::json_location_type;

        jsoncons::jsonpath::detail::static_resources<value_type,reference> static_resources(funcs);
        evaluator_t e;
        json_selector_t expr = e.compile(static_resources, path);

        jsoncons::jsonpath::detail::dynamic_resources<Json,reference> resources;
        auto callback = [&new_value](const json_location_type&, reference v)
        {
            v = std::forward<T>(new_value);
        };
        expr.evaluate(resources, instance, resources.root_path_node(), instance, callback, options);
    }

    template<class Json, class UnaryCallback>
    typename std::enable_if<type_traits::is_unary_function_object<UnaryCallback,Json>::value,void>::type
    json_replace(Json& instance, const typename Json::string_view_type& path , UnaryCallback callback)
    {
        using evaluator_t = typename jsoncons::jsonpath::detail::jsonpath_evaluator<Json, Json&>;
        //using string_type = typename evaluator_t::string_type;
        using value_type = typename evaluator_t::value_type;
        using reference = typename evaluator_t::reference;
        using json_selector_t = typename evaluator_t::path_expression_type;
        using json_location_type = typename evaluator_t::json_location_type;

        jsoncons::jsonpath::detail::static_resources<value_type,reference> static_resources;
        evaluator_t e;
        json_selector_t expr = e.compile(static_resources, path);

        jsoncons::jsonpath::detail::dynamic_resources<Json,reference> resources;
        auto f = [callback](const json_location_type&, reference v)
        {
            v = callback(v);
        };
        expr.evaluate(resources, instance, resources.root_path_node(), instance, f, result_options::nodups);
    }

    template<class Json, class BinaryCallback>
    typename std::enable_if<type_traits::is_binary_function_object<BinaryCallback,const std::basic_string<typename Json::char_type>&,Json&>::value,void>::type
    json_replace(Json& instance, const typename Json::string_view_type& path , BinaryCallback callback, 
                 result_options options = result_options::nodups,
                 const custom_functions<Json>& funcs = custom_functions<Json>())
    {
        using evaluator_t = typename jsoncons::jsonpath::detail::jsonpath_evaluator<Json, Json&>;
        //using string_type = typename evaluator_t::string_type;
        using value_type = typename evaluator_t::value_type;
        using reference = typename evaluator_t::reference;
        using json_selector_t = typename evaluator_t::path_expression_type;
        using json_location_type = typename evaluator_t::json_location_type;

        jsoncons::jsonpath::detail::static_resources<value_type,reference> static_resources(funcs);
        evaluator_t e;
        json_selector_t expr = e.compile(static_resources, path);

        jsoncons::jsonpath::detail::dynamic_resources<Json,reference> resources;

        auto f = [&callback](const json_location_type& path, reference val)
        {
            callback(path.to_string(), val);
        };
        expr.evaluate(resources, instance, resources.root_path_node(), instance, f, options);
    }

} // namespace jsonpath
} // namespace jsoncons

#endif