grpc_response.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #pragma once
  2. #include <grpc++/impl/codegen/byte_buffer.h>
  3. #include <grpc++/impl/codegen/proto_utils.h>
  4. #include <variant>
  5. namespace NGrpc {
  6. /**
  7. * Universal response that owns underlying message or buffer.
  8. */
  9. template <typename TMsg>
  10. class TUniversalResponse: public TAtomicRefCount<TUniversalResponse<TMsg>>, public TMoveOnly {
  11. friend class grpc::SerializationTraits<TUniversalResponse<TMsg>>;
  12. public:
  13. explicit TUniversalResponse(NProtoBuf::Message* msg) noexcept
  14. : Data_{TMsg{}}
  15. {
  16. std::get<TMsg>(Data_).Swap(static_cast<TMsg*>(msg));
  17. }
  18. explicit TUniversalResponse(grpc::ByteBuffer* buffer) noexcept
  19. : Data_{grpc::ByteBuffer{}}
  20. {
  21. std::get<grpc::ByteBuffer>(Data_).Swap(buffer);
  22. }
  23. private:
  24. std::variant<TMsg, grpc::ByteBuffer> Data_;
  25. };
  26. /**
  27. * Universal response that only keeps reference to underlying message or buffer.
  28. */
  29. template <typename TMsg>
  30. class TUniversalResponseRef: private TMoveOnly {
  31. friend class grpc::SerializationTraits<TUniversalResponseRef<TMsg>>;
  32. public:
  33. explicit TUniversalResponseRef(const NProtoBuf::Message* msg)
  34. : Data_{msg}
  35. {
  36. }
  37. explicit TUniversalResponseRef(const grpc::ByteBuffer* buffer)
  38. : Data_{buffer}
  39. {
  40. }
  41. private:
  42. std::variant<const NProtoBuf::Message*, const grpc::ByteBuffer*> Data_;
  43. };
  44. } // namespace NGrpc
  45. namespace grpc {
  46. template <typename TMsg>
  47. class SerializationTraits<NGrpc::TUniversalResponse<TMsg>> {
  48. public:
  49. static Status Serialize(
  50. const NGrpc::TUniversalResponse<TMsg>& resp,
  51. ByteBuffer* buffer,
  52. bool* ownBuffer)
  53. {
  54. return std::visit([&](const auto& data) {
  55. using T = std::decay_t<decltype(data)>;
  56. return SerializationTraits<T>::Serialize(data, buffer, ownBuffer);
  57. }, resp.Data_);
  58. }
  59. };
  60. template <typename TMsg>
  61. class SerializationTraits<NGrpc::TUniversalResponseRef<TMsg>> {
  62. public:
  63. static Status Serialize(
  64. const NGrpc::TUniversalResponseRef<TMsg>& resp,
  65. ByteBuffer* buffer,
  66. bool* ownBuffer)
  67. {
  68. return std::visit([&](const auto* data) {
  69. using T = std::decay_t<std::remove_pointer_t<decltype(data)>>;
  70. return SerializationTraits<T>::Serialize(*data, buffer, ownBuffer);
  71. }, resp.Data_);
  72. }
  73. };
  74. } // namespace grpc