diff options
Diffstat (limited to 'protocols/Telegram/tdlib/td/td/tl/tl_json.h')
-rw-r--r-- | protocols/Telegram/tdlib/td/td/tl/tl_json.h | 139 |
1 files changed, 58 insertions, 81 deletions
diff --git a/protocols/Telegram/tdlib/td/td/tl/tl_json.h b/protocols/Telegram/tdlib/td/td/tl/tl_json.h index f8f21203da..fb7a4a1e63 100644 --- a/protocols/Telegram/tdlib/td/td/tl/tl_json.h +++ b/protocols/Telegram/tdlib/td/td/tl/tl_json.h @@ -1,47 +1,26 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once +#include "td/tl/TlObject.h" + #include "td/utils/base64.h" +#include "td/utils/common.h" #include "td/utils/format.h" #include "td/utils/JsonBuilder.h" #include "td/utils/misc.h" #include "td/utils/Slice.h" +#include "td/utils/SliceBuilder.h" #include "td/utils/Status.h" -#include "td/utils/tl_storers.h" - -#include "td/telegram/td_api.h" -#include "td/telegram/td_api.hpp" +#include "td/utils/TlDowncastHelper.h" #include <type_traits> namespace td { -template <class T> -class ToJsonImpl : public Jsonable { - public: - explicit ToJsonImpl(const T &value) : value_(value) { - } - void store(JsonValueScope *scope) const { - to_json(*scope, value_); - } - - private: - const T &value_; -}; - -template <class T> -auto ToJson(const T &value) { - return ToJsonImpl<T>(value); -} - -template <class T> -void to_json(JsonValueScope &jv, const T &value) { - jv << value; -} struct JsonInt64 { int64 value; @@ -50,6 +29,7 @@ struct JsonInt64 { inline void to_json(JsonValueScope &jv, const JsonInt64 json_int64) { jv << JsonString(PSLICE() << json_int64.value); } + struct JsonVectorInt64 { const std::vector<int64> &value; }; @@ -61,13 +41,6 @@ inline void to_json(JsonValueScope &jv, const JsonVectorInt64 &vec) { } } -inline void to_json(JsonValueScope &jv, const td_api::Object &object) { - td_api::downcast_call(const_cast<td_api::Object &>(object), [&jv](const auto &object) { to_json(jv, object); }); -} -inline void to_json(JsonValueScope &jv, const td_api::Function &object) { - td_api::downcast_call(const_cast<td_api::Function &>(object), [&jv](const auto &object) { to_json(jv, object); }); -} - template <class T> void to_json(JsonValueScope &jv, const tl_object_ptr<T> &value) { if (value) { @@ -85,101 +58,106 @@ void to_json(JsonValueScope &jv, const std::vector<T> &v) { } } -inline Status from_json(int32 &to, JsonValue &from) { +inline Status from_json(int32 &to, JsonValue from) { if (from.type() != JsonValue::Type::Number && from.type() != JsonValue::Type::String) { - return Status::Error(PSLICE() << "Expected number, got " << from.type()); + if (from.type() == JsonValue::Type::Null) { + return Status::OK(); + } + return Status::Error(PSLICE() << "Expected Number, got " << from.type()); } Slice number = from.type() == JsonValue::Type::String ? from.get_string() : from.get_number(); - TRY_RESULT(res, to_integer_safe<int32>(number)); - to = res; + TRY_RESULT_ASSIGN(to, to_integer_safe<int32>(number)); return Status::OK(); } -inline Status from_json(bool &to, JsonValue &from) { - if (from.type() != JsonValue::Type::Boolean) { - int32 x; - auto status = from_json(x, from); +inline Status from_json(bool &to, JsonValue from) { + auto from_type = from.type(); + if (from_type != JsonValue::Type::Boolean) { + if (from_type == JsonValue::Type::Null) { + return Status::OK(); + } + int32 x = 0; + auto status = from_json(x, std::move(from)); if (status.is_ok()) { to = x != 0; return Status::OK(); } - return Status::Error(PSLICE() << "Expected bool, got " << from.type()); + return Status::Error(PSLICE() << "Expected Boolean, got " << from_type); } to = from.get_boolean(); return Status::OK(); } -inline Status from_json(int64 &to, JsonValue &from) { +inline Status from_json(int64 &to, JsonValue from) { if (from.type() != JsonValue::Type::Number && from.type() != JsonValue::Type::String) { - return Status::Error(PSLICE() << "Expected number, got " << from.type()); + if (from.type() == JsonValue::Type::Null) { + return Status::OK(); + } + return Status::Error(PSLICE() << "Expected String or Number, got " << from.type()); } Slice number = from.type() == JsonValue::Type::String ? from.get_string() : from.get_number(); - TRY_RESULT(res, to_integer_safe<int64>(number)); - to = res; + TRY_RESULT_ASSIGN(to, to_integer_safe<int64>(number)); return Status::OK(); } -inline Status from_json(double &to, JsonValue &from) { + +inline Status from_json(double &to, JsonValue from) { if (from.type() != JsonValue::Type::Number) { - return Status::Error(PSLICE() << "Expected number, got " << from.type()); + if (from.type() == JsonValue::Type::Null) { + return Status::OK(); + } + return Status::Error(PSLICE() << "Expected Number, got " << from.type()); } to = to_double(from.get_number()); return Status::OK(); } -inline Status from_json(string &to, JsonValue &from) { +inline Status from_json(string &to, JsonValue from) { if (from.type() != JsonValue::Type::String) { - return Status::Error(PSLICE() << "Expected string, got " << from.type()); + if (from.type() == JsonValue::Type::Null) { + return Status::OK(); + } + return Status::Error(PSLICE() << "Expected String, got " << from.type()); } to = from.get_string().str(); return Status::OK(); } -inline Status from_json_bytes(string &to, JsonValue &from) { +inline Status from_json_bytes(string &to, JsonValue from) { if (from.type() != JsonValue::Type::String) { - return Status::Error(PSLICE() << "Expected string, got " << from.type()); + if (from.type() == JsonValue::Type::Null) { + return Status::OK(); + } + return Status::Error(PSLICE() << "Expected String, got " << from.type()); } - TRY_RESULT(decoded, base64_decode(from.get_string())); - to = std::move(decoded); + TRY_RESULT_ASSIGN(to, base64_decode(from.get_string())); return Status::OK(); } template <class T> -Status from_json(std::vector<T> &to, JsonValue &from) { +Status from_json(std::vector<T> &to, JsonValue from) { if (from.type() != JsonValue::Type::Array) { - return Status::Error(PSLICE() << "Expected array, got " << from.type()); + if (from.type() == JsonValue::Type::Null) { + return Status::OK(); + } + return Status::Error(PSLICE() << "Expected Array, got " << from.type()); } to = std::vector<T>(from.get_array().size()); size_t i = 0; for (auto &value : from.get_array()) { - TRY_STATUS(from_json(to[i], value)); + TRY_STATUS(from_json(to[i], std::move(value))); i++; } return Status::OK(); } template <class T> -class DowncastHelper : public T { - public: - explicit DowncastHelper(int32 constructor) : constructor_(constructor) { - } - int32 get_id() const override { - return constructor_; - } - void store(TlStorerToString &s, const char *field_name) const override { - } - - private: - int32 constructor_{0}; -}; - -template <class T> -std::enable_if_t<!std::is_constructible<T>::value, Status> from_json(tl_object_ptr<T> &to, JsonValue &from) { +std::enable_if_t<!std::is_constructible<T>::value, Status> from_json(tl_object_ptr<T> &to, JsonValue from) { if (from.type() != JsonValue::Type::Object) { if (from.type() == JsonValue::Type::Null) { to = nullptr; return Status::OK(); } - return Status::Error(PSLICE() << "Expected object, got " << from.type()); + return Status::Error(PSLICE() << "Expected Object, got " << from.type()); } auto &object = from.get_object(); @@ -188,13 +166,12 @@ std::enable_if_t<!std::is_constructible<T>::value, Status> from_json(tl_object_p if (constructor_value.type() == JsonValue::Type::Number) { constructor = to_integer<int32>(constructor_value.get_number()); } else if (constructor_value.type() == JsonValue::Type::String) { - TRY_RESULT(t_constructor, tl_constructor_from_string(to.get(), constructor_value.get_string().str())); - constructor = t_constructor; + TRY_RESULT_ASSIGN(constructor, tl_constructor_from_string(to.get(), constructor_value.get_string().str())); } else { - return Status::Error(PSLICE() << "Expected string or int, got " << constructor_value.type()); + return Status::Error(PSLICE() << "Expected String or Integer, got " << constructor_value.type()); } - DowncastHelper<T> helper(constructor); + TlDowncastHelper<T> helper(constructor); Status status; bool ok = downcast_call(static_cast<T &>(helper), [&](auto &dummy) { auto result = make_tl_object<std::decay_t<decltype(dummy)>>(); @@ -210,13 +187,13 @@ std::enable_if_t<!std::is_constructible<T>::value, Status> from_json(tl_object_p } template <class T> -std::enable_if_t<std::is_constructible<T>::value, Status> from_json(tl_object_ptr<T> &to, JsonValue &from) { +std::enable_if_t<std::is_constructible<T>::value, Status> from_json(tl_object_ptr<T> &to, JsonValue from) { if (from.type() != JsonValue::Type::Object) { if (from.type() == JsonValue::Type::Null) { to = nullptr; return Status::OK(); } - return Status::Error(PSLICE() << "Expected object, got " << from.type()); + return Status::Error(PSLICE() << "Expected Object, got " << from.type()); } to = make_tl_object<T>(); return from_json(*to, from.get_object()); |