Skip to content

Commit 01f60ae

Browse files
authoredMar 22, 2025
Update traits.h
1 parent e71e0c2 commit 01f60ae

File tree

1 file changed

+149
-41
lines changed
  • include/jwt-cpp/traits/danielaparker-jsoncons

1 file changed

+149
-41
lines changed
 

‎include/jwt-cpp/traits/danielaparker-jsoncons/traits.h

Lines changed: 149 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
#ifndef JWT_CPP_DANIELAPARKER_JSONCONS_TRAITS_H
2+
#define JWT_CPP_DANIELAPARKER_JSONCONS_TRAITS_H
3+
14
#define JWT_DISABLE_PICOJSON
25
#define JSONCONS_NO_DEPRECATED
36

47
#include "jwt-cpp/jwt.h"
5-
68
#include "jsoncons/json.hpp"
79

810
#include <sstream>
@@ -15,59 +17,103 @@ namespace jwt {
1517
/// basic_claim's JSON trait implementation for jsoncons.
1618
struct danielaparker_jsoncons {
1719
// Needs at least https://github.com/danielaparker/jsoncons/commit/28c56b90ec7337f98a5b8942574590111a5e5831
18-
static_assert(jsoncons::version().minor >= 167, "A higher version of jsoncons is required!");
20+
static_assert(jsoncons::version().minor >= 167 || (jsoncons::version().major > 0), "A higher version of jsoncons is required!");
1921

2022
using json = jsoncons::json;
2123
using value_type = json;
22-
struct object_type : json::object {
23-
// Add missing C++11 member types
24-
// https://github.com/danielaparker/jsoncons/commit/1b1ceeb572f9a2db6d37cff47ac78a4f14e072e2#commitcomment-45391411
25-
using value_type = key_value_type; // Enable optional jwt-cpp methods
26-
using mapped_type = key_value_type::value_type;
27-
using size_type = size_t; // for implementing count
24+
25+
struct object_type {
26+
using key_type = json::key_type;
27+
using mapped_type = json;
28+
using value_type = std::pair<const key_type, mapped_type>;
29+
using size_type = size_t;
30+
using iterator = json::object_iterator;
31+
using const_iterator = json::const_object_iterator;
2832

2933
object_type() = default;
30-
object_type(const object_type&) = default;
31-
explicit object_type(const json::object& o) : json::object(o) {}
32-
object_type(object_type&&) = default;
33-
explicit object_type(json::object&& o) : json::object(o) {}
34+
object_type(const object_type& o) : json_(o) {}
35+
explicit object_type(const json& j) : json_(j) {}
36+
explicit object_type(object_type&& o) noexcept : json_(std::move(o)) {}
3437
~object_type() = default;
35-
object_type& operator=(const object_type& o) = default;
36-
object_type& operator=(object_type&& o) noexcept = default;
3738

38-
// Add missing C++11 subscription operator
39-
mapped_type& operator[](const key_type& key) {
40-
// https://github.com/microsoft/STL/blob/2914b4301c59dc7ffc09d16ac6f7979fde2b7f2c/stl/inc/map#L325
41-
return try_emplace(key).first->value();
39+
object_type& operator=(const object_type& o) {
40+
json_ = o.json_;
41+
return *this;
42+
}
43+
44+
object_type& operator=(object_type&& o) noexcept {
45+
json_ = std::move(o.json_);
46+
return *this;
4247
}
4348

49+
// Add missing C++11 subscription operator
50+
mapped_type& operator[](const key_type& key) { return const_cast<mapped_type&>(json_[key]); }
51+
4452
// Add missing C++11 element access
45-
const mapped_type& at(const key_type& key) const {
46-
auto target = find(key);
47-
if (target != end()) return target->value();
53+
const mapped_type& at(const key_type& key) const { return json_.at(key); }
54+
55+
// Add missing C++11 lookup method
56+
size_type count(const key_type& key) const { return json_.count(key); }
57+
58+
iterator begin() { return json_.object_range().begin(); }
59+
iterator end() { return json_.object_range().end(); }
60+
const_iterator begin() const { return json_.object_range().cbegin(); }
61+
const_iterator end() const { return json_.object_range().cend(); }
62+
const_iterator cbegin() const { return json_.object_range().cbegin(); }
63+
const_iterator cend() const { return json_.object_range().cend(); }
4864

49-
throw std::out_of_range("invalid key");
65+
private:
66+
json json_;
67+
};
68+
69+
struct array_type {
70+
using value_type = json;
71+
using size_type = size_t;
72+
using iterator = json::array_iterator;
73+
using const_iterator = json::const_array_iterator;
74+
75+
array_type() = default;
76+
array_type(const array_type& a) : json_(a) {}
77+
explicit array_type(const json& j) : json_(j) {}
78+
explicit array_type(array_type&& a) noexcept : json_(std::move(a)) {}
79+
template<typename Iterator>
80+
array_type(Iterator first, Iterator last) {
81+
json_ = json::array();
82+
for (auto it = first; it != last; ++it) {
83+
json_.push_back(*it);
84+
}
5085
}
86+
~array_type() = default;
5187

52-
// Add missing C++11 lookup method
53-
size_type count(const key_type& key) const {
54-
struct compare {
55-
bool operator()(const value_type& val, const key_type& key) const { return val.key() < key; }
56-
bool operator()(const key_type& key, const value_type& val) const { return key < val.key(); }
57-
};
58-
59-
// https://en.cppreference.com/w/cpp/algorithm/binary_search#Complexity
60-
if (std::binary_search(this->begin(), this->end(), key, compare{})) return 1;
61-
return 0;
88+
array_type& operator=(const array_type& o) {
89+
json_ = o.json_;
90+
return *this;
6291
}
92+
93+
array_type& operator=(array_type&& o) noexcept {
94+
json_ = std::move(o.json_);
95+
return *this;
96+
}
97+
98+
value_type& operator[](size_type index) { return const_cast<value_type&>(json_[index]); }
99+
100+
const value_type& at(size_type index) const { return json_.at(index); }
101+
102+
value_type const& front() const { return json_.at(0); }
103+
104+
void push_back(const value_type& val) { json_.push_back(val); }
105+
106+
iterator begin() { return json_.array_range().begin(); }
107+
iterator end() { return json_.array_range().end(); }
108+
const_iterator begin() const { return json_.array_range().cbegin(); }
109+
const_iterator end() const { return json_.array_range().cend(); }
110+
const_iterator cbegin() const { return json_.array_range().cbegin(); }
111+
const_iterator cend() const { return json_.array_range().cend(); }
112+
113+
private:
114+
json json_;
63115
};
64-
class array_type : public json::array {
65-
public:
66-
using json::array::array;
67-
explicit array_type(const json::array& a) : json::array(a) {}
68-
explicit array_type(json::array&& a) : json::array(a) {}
69-
value_type const& front() const { return this->operator[](0U); }
70-
};
116+
71117
using string_type = std::string; // current limitation of traits implementation
72118
using number_type = double;
73119
using integer_type = int64_t;
@@ -90,12 +136,12 @@ namespace jwt {
90136

91137
static object_type as_object(const json& val) {
92138
if (val.type() != jsoncons::json_type::object_value) throw std::bad_cast();
93-
return object_type(val.object_value());
139+
return object_type(val);
94140
}
95141

96142
static array_type as_array(const json& val) {
97143
if (val.type() != jsoncons::json_type::array_value) throw std::bad_cast();
98-
return array_type(val.array_value());
144+
return array_type(val);
99145
}
100146

101147
static string_type as_string(const json& val) {
@@ -131,3 +177,65 @@ namespace jwt {
131177
};
132178
} // namespace traits
133179
} // namespace jwt
180+
181+
namespace jsoncons {
182+
template <typename Json>
183+
struct json_type_traits<Json, jwt::traits::danielaparker_jsoncons::object_type> {
184+
185+
using allocator_type = typename Json::allocator_type;
186+
187+
static bool is(const Json&) noexcept {
188+
return true;
189+
}
190+
191+
static jwt::traits::danielaparker_jsoncons::object_type as(const Json& j) {
192+
jwt::traits::danielaparker_jsoncons::object_type o;
193+
for (const auto& item : j.object_range()) {
194+
o[item.key()] = item.value();
195+
}
196+
}
197+
198+
static Json to_json(const jwt::traits::danielaparker_jsoncons::object_type& val) {
199+
jsoncons::json j = jsoncons::json::object();
200+
for (const auto& item : val) {
201+
j[item.key()] = item.value();
202+
}
203+
return j;
204+
}
205+
206+
static Json to_json(const jwt::traits::danielaparker_jsoncons::object_type& val, const allocator_type&) {
207+
return to_json(val);
208+
}
209+
};
210+
211+
template <typename Json>
212+
struct json_type_traits<Json, jwt::traits::danielaparker_jsoncons::array_type> {
213+
214+
using allocator_type = typename Json::allocator_type;
215+
216+
static bool is(const Json&) noexcept {
217+
return true;
218+
}
219+
220+
static jwt::traits::danielaparker_jsoncons::array_type as(const Json& j) {
221+
jwt::traits::danielaparker_jsoncons::array_type a;
222+
for (const auto& item : j.array_range()) {
223+
a.push_back(item);
224+
}
225+
}
226+
227+
static Json to_json(const jwt::traits::danielaparker_jsoncons::array_type& val) {
228+
jsoncons::json a = jsoncons::json::array();
229+
for (const auto& item : val) {
230+
a.push_back(item);
231+
}
232+
return a;
233+
}
234+
235+
static Json to_json(const jwt::traits::danielaparker_jsoncons::array_type& val, const allocator_type&) {
236+
return to_json(val);
237+
}
238+
};
239+
} // namespace jsoncons
240+
241+
#endif // JWT_CPP_DANIELAPARKER_JSONCONS_TRAITS_H

0 commit comments

Comments
 (0)
Failed to load comments.