rippled
Loading...
Searching...
No Matches
json_get_or_throw.h
1#pragma once
2
3#include <xrpl/basics/Buffer.h>
4#include <xrpl/basics/StringUtilities.h>
5#include <xrpl/basics/contract.h>
6#include <xrpl/json/json_value.h>
7#include <xrpl/protocol/SField.h>
8
9#include <charconv>
10#include <exception>
11#include <optional>
12
13namespace Json {
15{
16 char const* const key;
19 {
20 }
21 char const*
22 what() const noexcept override
23 {
24 if (msg.empty())
25 {
26 msg = std::string("Missing json key: ") + key;
27 }
28 return msg.c_str();
29 }
30};
31
33{
34 char const* const key;
38 {
39 }
40 char const*
41 what() const noexcept override
42 {
43 if (msg.empty())
44 {
45 msg = std::string("Type mismatch on json key: ") + key + "; expected type: " + expectedType;
46 }
47 return msg.c_str();
48 }
49};
50
51template <class T>
52T
53getOrThrow(Json::Value const& v, xrpl::SField const& field)
54{
55 static_assert(sizeof(T) == -1, "This function must be specialized");
56}
57
58template <>
59inline std::string
60getOrThrow(Json::Value const& v, xrpl::SField const& field)
61{
62 using namespace xrpl;
63 Json::StaticString const& key = field.getJsonName();
64 if (!v.isMember(key))
65 Throw<JsonMissingKeyError>(key);
66
67 Json::Value const& inner = v[key];
68 if (!inner.isString())
69 Throw<JsonTypeMismatchError>(key, "string");
70 return inner.asString();
71}
72
73// Note, this allows integer numeric fields to act as bools
74template <>
75inline bool
76getOrThrow(Json::Value const& v, xrpl::SField const& field)
77{
78 using namespace xrpl;
79 Json::StaticString const& key = field.getJsonName();
80 if (!v.isMember(key))
81 Throw<JsonMissingKeyError>(key);
82 Json::Value const& inner = v[key];
83 if (inner.isBool())
84 return inner.asBool();
85 if (!inner.isIntegral())
86 Throw<JsonTypeMismatchError>(key, "bool");
87
88 return inner.asInt() != 0;
89}
90
91template <>
92inline std::uint64_t
93getOrThrow(Json::Value const& v, xrpl::SField const& field)
94{
95 using namespace xrpl;
96 Json::StaticString const& key = field.getJsonName();
97 if (!v.isMember(key))
98 Throw<JsonMissingKeyError>(key);
99 Json::Value const& inner = v[key];
100 if (inner.isUInt())
101 return inner.asUInt();
102 if (inner.isInt())
103 {
104 auto const r = inner.asInt();
105 if (r < 0)
106 Throw<JsonTypeMismatchError>(key, "uint64");
107 return r;
108 }
109 if (inner.isString())
110 {
111 auto const s = inner.asString();
112 // parse as hex
113 std::uint64_t val;
114
115 auto [p, ec] = std::from_chars(s.data(), s.data() + s.size(), val, 16);
116
117 if (ec != std::errc() || (p != s.data() + s.size()))
118 Throw<JsonTypeMismatchError>(key, "uint64");
119 return val;
120 }
121 Throw<JsonTypeMismatchError>(key, "uint64");
122}
123
124template <>
125inline xrpl::Buffer
126getOrThrow(Json::Value const& v, xrpl::SField const& field)
127{
128 using namespace xrpl;
129 std::string const hex = getOrThrow<std::string>(v, field);
130 if (auto const r = strUnHex(hex))
131 {
132 // TODO: mismatch between a buffer and a blob
133 return Buffer{r->data(), r->size()};
134 }
135 Throw<JsonTypeMismatchError>(field.getJsonName(), "Buffer");
136}
137
138// This function may be used by external projects (like the witness server).
139template <class T>
141getOptional(Json::Value const& v, xrpl::SField const& field)
142{
143 try
144 {
145 return getOrThrow<T>(v, field);
146 }
147 catch (...)
148 {
149 }
150 return {};
151}
152
153} // namespace Json
T c_str(T... args)
Lightweight wrapper to tag static string.
Definition json_value.h:44
Represents a JSON value.
Definition json_value.h:130
Int asInt() const
bool isString() const
UInt asUInt() const
std::string asString() const
Returns the unquoted string value.
bool isBool() const
bool isIntegral() const
bool asBool() const
bool isUInt() const
bool isMember(char const *key) const
Return true if the object has a member named key.
bool isInt() const
Like std::vector<char> but better.
Definition Buffer.h:16
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Buffer.h:128
Identifies fields.
Definition SField.h:126
T empty(T... args)
T from_chars(T... args)
JSON (JavaScript Object Notation).
Definition json_errors.h:5
std::optional< T > getOptional(Json::Value const &v, xrpl::SField const &field)
xrpl::AccountID getOrThrow(Json::Value const &v, xrpl::SField const &field)
Definition AccountID.h:111
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
char const * what() const noexcept override
JsonMissingKeyError(Json::StaticString const &k)
char const * what() const noexcept override
JsonTypeMismatchError(Json::StaticString const &k, std::string et)