xref: /aosp_15_r20/external/grpc-grpc/include/grpc/support/json.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 // Copyright 2015 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef GRPC_SUPPORT_JSON_H
18 #define GRPC_SUPPORT_JSON_H
19 
20 #include <stdint.h>
21 
22 #include <map>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 
27 #include "absl/strings/str_cat.h"
28 #include "absl/types/variant.h"
29 
30 #include <grpc/support/port_platform.h>
31 
32 namespace grpc_core {
33 namespace experimental {
34 
35 // A JSON value, which can be any one of null, boolean, number, string,
36 // object, or array.
37 class Json {
38  public:
39   // The JSON type.
40   enum class Type {
41     kNull,     // No payload.  Default type when using the zero-arg ctor.
42     kBoolean,  // Use boolean() for payload.
43     kNumber,   // Numbers are stored in string form to avoid precision
44                // and integer capacity issues.  Use string() for payload.
45     kString,   // Use string() for payload.
46     kObject,   // Use object() for payload.
47     kArray,    // Use array() for payload.
48   };
49 
50   using Object = std::map<std::string, Json>;
51   using Array = std::vector<Json>;
52 
53   // Factory method for kBoolean.
FromBool(bool b)54   static Json FromBool(bool b) {
55     Json json;
56     json.value_ = b;
57     return json;
58   }
59 
60   // Factory methods for kNumber.
FromNumber(const std::string & str)61   static Json FromNumber(const std::string& str) {
62     Json json;
63     json.value_ = NumberValue{str};
64     return json;
65   }
FromNumber(const char * str)66   static Json FromNumber(const char* str) {
67     Json json;
68     json.value_ = NumberValue{std::string(str)};
69     return json;
70   }
FromNumber(std::string && str)71   static Json FromNumber(std::string&& str) {
72     Json json;
73     json.value_ = NumberValue{std::move(str)};
74     return json;
75   }
FromNumber(int32_t value)76   static Json FromNumber(int32_t value) {
77     Json json;
78     json.value_ = NumberValue{absl::StrCat(value)};
79     return json;
80   }
FromNumber(uint32_t value)81   static Json FromNumber(uint32_t value) {
82     Json json;
83     json.value_ = NumberValue{absl::StrCat(value)};
84     return json;
85   }
FromNumber(int64_t value)86   static Json FromNumber(int64_t value) {
87     Json json;
88     json.value_ = NumberValue{absl::StrCat(value)};
89     return json;
90   }
FromNumber(uint64_t value)91   static Json FromNumber(uint64_t value) {
92     Json json;
93     json.value_ = NumberValue{absl::StrCat(value)};
94     return json;
95   }
FromNumber(double value)96   static Json FromNumber(double value) {
97     Json json;
98     json.value_ = NumberValue{absl::StrCat(value)};
99     return json;
100   }
101 
102   // Factory methods for kString.
FromString(const std::string & str)103   static Json FromString(const std::string& str) {
104     Json json;
105     json.value_ = str;
106     return json;
107   }
FromString(const char * str)108   static Json FromString(const char* str) {
109     Json json;
110     json.value_ = std::string(str);
111     return json;
112   }
FromString(std::string && str)113   static Json FromString(std::string&& str) {
114     Json json;
115     json.value_ = std::move(str);
116     return json;
117   }
118 
119   // Factory methods for kObject.
FromObject(const Object & object)120   static Json FromObject(const Object& object) {
121     Json json;
122     json.value_ = object;
123     return json;
124   }
FromObject(Object && object)125   static Json FromObject(Object&& object) {
126     Json json;
127     json.value_ = std::move(object);
128     return json;
129   }
130 
131   // Factory methods for kArray.
FromArray(const Array & array)132   static Json FromArray(const Array& array) {
133     Json json;
134     json.value_ = array;
135     return json;
136   }
FromArray(Array && array)137   static Json FromArray(Array&& array) {
138     Json json;
139     json.value_ = std::move(array);
140     return json;
141   }
142 
143   Json() = default;
144 
145   // Copyable.
146   Json(const Json& other) = default;
147   Json& operator=(const Json& other) = default;
148 
149   // Moveable.
Json(Json && other)150   Json(Json&& other) noexcept : value_(std::move(other.value_)) {
151     other.value_ = absl::monostate();
152   }
153   Json& operator=(Json&& other) noexcept {
154     value_ = std::move(other.value_);
155     other.value_ = absl::monostate();
156     return *this;
157   }
158 
159   // Returns the JSON type.
type()160   Type type() const {
161     struct ValueFunctor {
162       Json::Type operator()(const absl::monostate&) { return Type::kNull; }
163       Json::Type operator()(bool) { return Type::kBoolean; }
164       Json::Type operator()(const NumberValue&) { return Type::kNumber; }
165       Json::Type operator()(const std::string&) { return Type::kString; }
166       Json::Type operator()(const Object&) { return Type::kObject; }
167       Json::Type operator()(const Array&) { return Type::kArray; }
168     };
169     return absl::visit(ValueFunctor(), value_);
170   }
171 
172   // Payload accessor for kBoolean.
173   // Must not be called for other types.
boolean()174   bool boolean() const { return absl::get<bool>(value_); }
175 
176   // Payload accessor for kNumber or kString.
177   // Must not be called for other types.
string()178   const std::string& string() const {
179     const NumberValue* num = absl::get_if<NumberValue>(&value_);
180     if (num != nullptr) return num->value;
181     return absl::get<std::string>(value_);
182   }
183 
184   // Payload accessor for kObject.
185   // Must not be called for other types.
object()186   const Object& object() const { return absl::get<Object>(value_); }
187 
188   // Payload accessor for kArray.
189   // Must not be called for other types.
array()190   const Array& array() const { return absl::get<Array>(value_); }
191 
192   bool operator==(const Json& other) const { return value_ == other.value_; }
193   bool operator!=(const Json& other) const { return !(*this == other); }
194 
195  private:
196   struct NumberValue {
197     std::string value;
198 
199     bool operator==(const NumberValue& other) const {
200       return value == other.value;
201     }
202   };
203   using Value = absl::variant<absl::monostate,  // kNull
204                               bool,             // kBoolean
205                               NumberValue,      // kNumber
206                               std::string,      // kString
207                               Object,           // kObject
208                               Array>;           // kArray
209 
Json(Value value)210   explicit Json(Value value) : value_(std::move(value)) {}
211 
212   Value value_;
213 };
214 
215 }  // namespace experimental
216 }  // namespace grpc_core
217 
218 #endif  // GRPC_SUPPORT_JSON_H
219