ipfs-chromium
Loading...
Searching...
No Matches
json_cbor_adapter.h
1#ifndef IPFS_JSON_CBOR_ADAPTER_H_
2#define IPFS_JSON_CBOR_ADAPTER_H_
3
4#include <ipfs_client/dag_cbor_value.h>
5#include <ipfs_client/dag_json_value.h>
6
7#include <iomanip>
8#include <sstream>
9
10#if __has_include(<nlohmann/json.hpp>)
11
12#include <nlohmann/json.hpp>
13#define HAS_JSON_CBOR_ADAPTER 1
14
15namespace ipfs {
16// LCOV_EXCL_START
17class JsonCborAdapter final : public DagCborValue, public DagJsonValue {
18 nlohmann::json data_;
19
20 public:
21 using Cid = ipfs::Cid;
22 JsonCborAdapter(nlohmann::json const& data) : data_(data) {}
23 std::unique_ptr<DagCborValue> at(std::string_view k) const override {
24 if (data_.is_object() && data_.contains(k)) {
25 return std::make_unique<JsonCborAdapter>(data_.at(k));
26 }
27 return {};
28 }
29 std::unique_ptr<DagJsonValue> operator[](std::string_view k) const override {
30 if (data_.is_object() && data_.contains(k)) {
31 return std::make_unique<JsonCborAdapter>(data_[k]);
32 }
33 return {};
34 }
35 std::optional<std::uint64_t> as_unsigned() const override {
36 if (data_.is_number_unsigned()) {
37 return data_.get<std::uint64_t>();
38 }
39 return std::nullopt;
40 }
41 std::optional<std::int64_t> as_signed() const override {
42 if (data_.is_number_integer()) {
43 return data_.get<std::int64_t>();
44 } else if (auto ui = as_unsigned()) {
45 if (*ui <= std::numeric_limits<std::int64_t>::max()) {
46 return static_cast<std::int64_t>(*ui);
47 }
48 }
49 return std::nullopt;
50 }
51 std::optional<double> as_float() const override {
52 if (data_.is_number_float()) {
53 return data_.get<double>();
54 }
55 return std::nullopt;
56 }
57 std::optional<std::string> as_string() const override {
58 if (data_.is_string()) {
59 return data_.get<std::string>();
60 }
61 return std::nullopt;
62 }
63 std::optional<std::string> get_if_string() const override {
64 return as_string();
65 }
66 std::optional<bool> as_bool() const override {
67 if (data_.is_boolean()) {
68 return data_.get<bool>();
69 }
70 return std::nullopt;
71 }
72 std::optional<std::vector<std::uint8_t>> as_bytes() const override {
73 if (data_.is_binary()) {
74 return data_.get_binary();
75 }
76 return std::nullopt;
77 }
78 std::optional<Cid> as_link() const override {
79 if (!data_.is_binary()) {
80 return std::nullopt;
81 }
82 auto& bin = data_.get_binary();
83 if (!bin.has_subtype() || bin.subtype() != 42) {
84 return std::nullopt;
85 }
86 if (bin.size() < 6) {
87 return std::nullopt;
88 }
89 if (bin[0]) {
90 return std::nullopt;
91 }
92 auto p = reinterpret_cast<std::byte const*>(bin.data()) + 1UL;
93 Cid from_binary(ByteView{p, bin.size() - 1UL});
94 if (from_binary.valid()) {
95 return from_binary;
96 } else {
97 return std::nullopt;
98 }
99 }
100 bool is_map() const override {return data_.is_object();}
101 bool is_array() const override {return data_.is_array();}
102 void iterate_map(MapElementCallback cb) const override {
103 if (!is_map()) {
104 return;
105 }
106 for (auto& [k,v] : data_.items()) {
107 JsonCborAdapter el(v);
108 cb(k, el);
109 }
110 }
111 void iterate_array(ArrayElementCallback cb) const override {
112 if (!is_array()) {
113 return;
114 }
115 for (auto& v : data_) {
116 JsonCborAdapter el(v);
117 cb(el);
118 }
119 }
120 std::string pretty_print() const override {
121 std::ostringstream result;
122 result << std::setw(2) << data_;
123 return result.str();
124 }
125 std::optional<std::vector<std::string>> object_keys() const override {
126 if (!data_.is_object()) {
127 return std::nullopt;
128 }
129 std::vector<std::string> rv;
130 for (auto& [k, v] : data_.items()) {
131 rv.push_back(k);
132 }
133 return rv;
134 }
135 bool iterate_list(
136 std::function<void(DagJsonValue const&)> cb) const override {
137 if (!data_.is_array()) {
138 return false;
139 }
140 for (auto& v : data_) {
141 JsonCborAdapter wrap(v);
142 cb(wrap);
143 }
144 return true;
145 }
146};
147} // namespace ipfs
148#endif
149
150#endif // IPFS_JSON_CBOR_ADAPTER_H_
Definition cid.h:16