15#ifndef ACTIONENGINE_REDIS_REPLY_H_ 
   16#define ACTIONENGINE_REDIS_REPLY_H_ 
   24#include <absl/container/flat_hash_map.h> 
   25#include <absl/log/check.h> 
   26#include <absl/status/statusor.h> 
   27#include <hiredis/hiredis.h> 
   29#include "actionengine/util/status_macros.h" 
   34  Status = REDIS_REPLY_STATUS,
 
   35  Error = REDIS_REPLY_ERROR,
 
   36  Integer = REDIS_REPLY_INTEGER,
 
   37  Nil = REDIS_REPLY_NIL,
 
   38  String = REDIS_REPLY_STRING,
 
   39  Array = REDIS_REPLY_ARRAY,
 
   40  Bool = REDIS_REPLY_BOOL,
 
   41  Double = REDIS_REPLY_DOUBLE,
 
   42  Map = REDIS_REPLY_MAP,
 
   43  Set = REDIS_REPLY_SET,
 
   44  Push = REDIS_REPLY_PUSH,
 
   45  Attr = REDIS_REPLY_ATTR,
 
   46  BigNum = REDIS_REPLY_BIGNUM,
 
   47  Verbatim = REDIS_REPLY_VERB,
 
   51struct StatusReplyData;
 
   53struct IntegerReplyData;
 
   55struct StringReplyData;
 
   57struct DoubleReplyData;
 
   60struct BigNumReplyData;
 
   61struct VerbatimReplyData;
 
   67    std::variant<StatusReplyData, ErrorReplyData, IntegerReplyData,
 
   68                 NilReplyData, StringReplyData, BoolReplyData, DoubleReplyData,
 
   69                 PushReplyData, AttrReplyData, BigNumReplyData,
 
   70                 VerbatimReplyData, ArrayReplyData, MapReplyData, SetReplyData>;
 
   72struct NilReplyData {};
 
   74struct StatusReplyData {
 
   75  [[nodiscard]] std::string Consume() { 
return std::move(value); }
 
   77  absl::Status AsAbslStatus()
 const { 
return {absl::StatusCode::kOk, value}; }
 
   82struct ErrorReplyData {
 
   83  [[nodiscard]] std::string Consume() { 
return std::move(value); }
 
   85  absl::Status AsAbslStatus()
 const {
 
   86    return {absl::StatusCode::kInternal, value};
 
   92struct IntegerReplyData {
 
   93  [[nodiscard]] int64_t Consume()
 const { 
return value; }
 
   98struct StringReplyData {
 
   99  [[nodiscard]] std::string Consume() { 
return std::move(value); }
 
  104struct BoolReplyData {
 
  105  [[nodiscard]] 
bool Consume()
 const { 
return value; }
 
  110struct DoubleReplyData {
 
  111  [[nodiscard]] 
double Consume()
 const { 
return value; }
 
  116struct BigNumReplyData {
 
  117  [[nodiscard]] std::string Consume() { 
return std::move(value); }
 
  122struct VerbatimReplyData {
 
  123  [[nodiscard]] std::string Consume() { 
return std::move(value); }
 
  125  std::array<char, 3> type{};
 
  129struct AttrReplyData {
 
  130  AttrReplyData() { CHECK(
false) << 
"AttrReplyData is not implemented yet."; }
 
  135struct ArrayReplyData {
 
  136  [[nodiscard]] std::vector<Reply> Consume();
 
  137  [[nodiscard]] absl::flat_hash_map<std::string, Reply> ConsumeAsMapOrDie();
 
  139  std::vector<Reply> values;
 
  143  [[nodiscard]] absl::flat_hash_map<std::string, Reply> Consume();
 
  144  absl::flat_hash_map<std::string, Reply> values;
 
  148  [[nodiscard]] std::vector<Reply> Consume();
 
  150  std::vector<Reply> values;
 
  153struct PushReplyData {
 
  154  [[nodiscard]] std::vector<Reply> ConsumeValueArray();
 
  157  ArrayReplyData value_array;
 
  164  std::string ConsumeStringContentOrDie();
 
  165  std::vector<Reply> ConsumeAsArrayOrDie();
 
  166  absl::flat_hash_map<std::string, Reply> ConsumeAsMapOrDie();
 
  168  absl::StatusOr<bool> ToBool() 
const;
 
  169  absl::StatusOr<double> ToDouble() 
const;
 
  170  absl::StatusOr<int64_t> ToInt() 
const;
 
  172  [[nodiscard]] 
bool ToBoolOrDie()
 const {
 
  173    auto status_or_value = ToBool();
 
  174    CHECK_OK(status_or_value);
 
  175    return *status_or_value;
 
  178  [[nodiscard]] 
double ToDoubleOrDie()
 const {
 
  179    auto status_or_value = ToDouble();
 
  180    CHECK_OK(status_or_value);
 
  181    return *status_or_value;
 
  184  int64_t ToIntOrDie()
 const {
 
  185    auto status_or_value = ToInt();
 
  186    CHECK_OK(status_or_value);
 
  187    return *status_or_value;
 
  190  [[nodiscard]] 
bool IsString()
 const {
 
  191    return type == ReplyType::String &&
 
  192           std::holds_alternative<StringReplyData>(data);
 
  195  [[nodiscard]] 
bool IsStatus()
 const {
 
  196    return type == ReplyType::Status &&
 
  197           std::holds_alternative<StatusReplyData>(data);
 
  200  [[nodiscard]] 
bool IsError()
 const {
 
  201    return type == ReplyType::Error &&
 
  202           std::holds_alternative<ErrorReplyData>(data);
 
  205  [[nodiscard]] 
bool IsNil()
 const {
 
  206    return type == ReplyType::Nil && std::holds_alternative<NilReplyData>(data);
 
  209  ReplyType type{ReplyType::Uninitialized};
 
  210  ReplyData data{NilReplyData{}};
 
  213absl::Status GetStatusOrErrorFrom(
const Reply& reply);