Skip to content

Commit 1bf6bbf

Browse files
committed
JSON parsing changes from new product query
Eliminates need for default constructor
1 parent 8fe4a39 commit 1bf6bbf

File tree

4 files changed

+74
-8
lines changed

4 files changed

+74
-8
lines changed

phlex/configuration.cpp

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,57 @@
11
#include "phlex/configuration.hpp"
22
#include "phlex/core/product_query.hpp"
3+
#include "phlex/model/product_specification.hpp"
34

4-
#include <ranges>
5+
#include <algorithm>
6+
#include <array>
57
#include <string>
8+
#include <string_view>
9+
10+
namespace {
11+
[[maybe_unused]] std::optional<std::string> value_if_exists(boost::json::object const& obj, // will be used later for new product_query
12+
std::string_view parameter)
13+
{
14+
if (!obj.contains(parameter)) {
15+
return std::nullopt;
16+
}
17+
auto const& val = obj.at(parameter);
18+
if (!val.is_string()) {
19+
std::string_view kind;
20+
switch (val.kind()) {
21+
case boost::json::kind::null:
22+
// seems reasonable to interpret this as if the value were not provided
23+
return std::nullopt;
24+
break;
25+
case boost::json::kind::bool_:
26+
kind = "bool";
27+
break;
28+
case boost::json::kind::int64:
29+
kind = "std::int64_t";
30+
break;
31+
case boost::json::kind::uint64:
32+
kind = "std::uint64_t";
33+
break;
34+
case boost::json::kind::double_:
35+
kind = "double";
36+
break;
37+
case boost::json::kind::array:
38+
kind = "array";
39+
break;
40+
case boost::json::kind::object:
41+
kind = "object";
42+
break;
43+
default:
44+
// std::unreachable();
45+
break;
46+
}
47+
throw std::runtime_error(
48+
fmt::format("Error retrieving parameter '{}'. Should be a string but is instead a {}",
49+
parameter,
50+
kind));
51+
}
52+
return boost::json::value_to<std::string>(val);
53+
}
54+
}
655

756
namespace phlex {
857
std::vector<std::string> configuration::keys() const
@@ -25,7 +74,8 @@ namespace phlex {
2574
{
2675
using detail::value_decorate_exception;
2776
auto query_object = jv.as_object();
28-
return product_query{{value_decorate_exception<std::string>(query_object, "product")},
29-
value_decorate_exception<std::string>(query_object, "layer")};
77+
auto product = value_decorate_exception<std::string>(query_object, "product");
78+
auto layer = value_decorate_exception<std::string>(query_object, "layer");
79+
return product_query{experimental::product_specification::create(product), layer};
3080
}
3181
}

phlex/configuration.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ namespace phlex {
1919
} catch (std::exception const& e) {
2020
throw std::runtime_error("Error retrieving parameter '" + key + "':\n" + e.what());
2121
}
22+
23+
// helper for unpacking json array
24+
template <typename T, std::size_t... I>
25+
std::array<T, sizeof...(I)> unpack_json_array(boost::json::array const& array,
26+
std::index_sequence<I...>)
27+
{
28+
return std::array<T, sizeof...(I)>{boost::json::value_to<T>(array.at(I))...};
29+
}
2230
}
2331

2432
class configuration {
@@ -81,6 +89,19 @@ namespace phlex {
8189

8290
product_query tag_invoke(boost::json::value_to_tag<product_query> const&,
8391
boost::json::value const& jv);
92+
93+
template <std::size_t N>
94+
std::array<product_query, N> tag_invoke(
95+
boost::json::value_to_tag<std::array<product_query, N>> const&, boost::json::value const& jv)
96+
{
97+
auto const& array = jv.as_array();
98+
return detail::unpack_json_array<product_query>(array, std::make_index_sequence<N>());
99+
}
84100
}
85101

102+
// The below is a better long term fix but it requires a Boost JSON bug (#1140) to be fixed
103+
// namespace boost::json {
104+
// template <std::size_t N>
105+
// struct is_sequence_like<std::array<phlex::product_query, N>> : std::false_type {};
106+
// }
86107
#endif // PHLEX_CONFIGURATION_HPP

phlex/core/product_query.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
#include <stdexcept>
66

77
namespace phlex {
8-
product_query::product_query() = default;
9-
108
product_query::product_query(experimental::product_specification spec, std::string layer) :
119
spec_{std::move(spec)}, layer_{std::move(layer)}
1210
{

phlex/core/product_query.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
namespace phlex {
1111
class product_query {
1212
public:
13-
// FIXME: Boost JSON's parameter retrieval facilities require a default constructor
14-
// whenever the type is (e.g.) std::array<product_query, N>.
15-
product_query();
1613
product_query(experimental::product_specification spec, std::string layer);
1714

1815
auto const& spec() const noexcept { return spec_; }

0 commit comments

Comments
 (0)