1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
//
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
#include <grpc/support/port_platform.h>
#include "src/core/lib/json/json_util.h"
#include "src/core/lib/gprpp/no_destruct.h"
#include "src/core/lib/gprpp/validation_errors.h"
#include "src/core/lib/json/json_args.h"
#include "src/core/lib/json/json_object_loader.h"
namespace grpc_core {
bool ParseDurationFromJson(const Json& field, Duration* duration) {
ValidationErrors errors;
static_cast<json_detail::LoaderInterface*>(
NoDestructSingleton<json_detail::AutoLoader<Duration>>::Get())
->LoadInto(field, JsonArgs(), duration, &errors);
return errors.ok();
}
bool ExtractJsonBool(const Json& json, y_absl::string_view field_name,
bool* output, std::vector<grpc_error_handle>* error_list) {
switch (json.type()) {
case Json::Type::JSON_TRUE:
*output = true;
return true;
case Json::Type::JSON_FALSE:
*output = false;
return true;
default:
error_list->push_back(GRPC_ERROR_CREATE(
y_absl::StrCat("field:", field_name, " error:type should be BOOLEAN")));
return false;
}
}
bool ExtractJsonArray(const Json& json, y_absl::string_view field_name,
const Json::Array** output,
std::vector<grpc_error_handle>* error_list) {
if (json.type() != Json::Type::ARRAY) {
*output = nullptr;
error_list->push_back(GRPC_ERROR_CREATE(
y_absl::StrCat("field:", field_name, " error:type should be ARRAY")));
return false;
}
*output = &json.array_value();
return true;
}
bool ExtractJsonObject(const Json& json, y_absl::string_view field_name,
const Json::Object** output,
std::vector<grpc_error_handle>* error_list) {
if (json.type() != Json::Type::OBJECT) {
*output = nullptr;
error_list->push_back(GRPC_ERROR_CREATE(
y_absl::StrCat("field:", field_name, " error:type should be OBJECT")));
return false;
}
*output = &json.object_value();
return true;
}
bool ParseJsonObjectFieldAsDuration(const Json::Object& object,
y_absl::string_view field_name,
Duration* output,
std::vector<grpc_error_handle>* error_list,
bool required) {
// TODO(roth): Once we can use C++14 heterogenous lookups, stop
// creating a TString here.
auto it = object.find(TString(field_name));
if (it == object.end()) {
if (required) {
error_list->push_back(GRPC_ERROR_CREATE(
y_absl::StrCat("field:", field_name, " error:does not exist.")));
}
return false;
}
if (!ParseDurationFromJson(it->second, output)) {
*output = Duration::NegativeInfinity();
error_list->push_back(GRPC_ERROR_CREATE(
y_absl::StrCat("field:", field_name,
" error:type should be STRING of the form given by "
"google.proto.Duration.")));
return false;
}
return true;
}
} // namespace grpc_core
|