Cppinecone
A C++ client for the Pinecone vector database
result.hpp
Go to the documentation of this file.
1 #pragma once
7 #include <sstream>
8 #include <string>
9 #include <variant>
10 
11 #include <curl/curl.h>
12 #include <nlohmann/json.hpp>
13 
14 #include "pinecone/types/error.hpp"
16 
17 using json = nlohmann::json;
18 
19 namespace pinecone::util
20 {
31 enum class failure {
35  none,
54 };
55 
61 template <failure F>
63 };
64 
68 template <>
70  explicit constexpr failure_reason(curl_result::error_type err) noexcept : _curl_err(err) {}
71 
75  [[nodiscard]] constexpr auto curl_error() const noexcept -> curl_result::error_type
76  {
77  return _curl_err;
78  }
79 
80  private:
81  curl_result::error_type _curl_err;
82 };
83 using request_rejected = failure_reason<failure::request_rejected>;
84 
88 template <>
90  failure_reason(int64_t code, std::string body) noexcept
91  : _response_code(code), _body(std::move(body))
92  {
93  }
94 
98  [[nodiscard]] constexpr auto response_code() const noexcept -> int64_t { return _response_code; }
99 
103  [[nodiscard]] constexpr auto body() const noexcept -> std::string const& { return _body; }
104 
110  [[nodiscard]] auto api_error() const noexcept -> std::variant<types::api_error, json::exception>
111  {
112  try {
113  types::api_error err = json::parse(_body);
114  return err;
115  } catch (json::exception const& ex) {
116  return ex;
117  }
118  }
119 
120  private:
121  int64_t _response_code;
122  std::string _body;
123 };
124 using request_failed = failure_reason<failure::request_failed>;
125 
132 template <>
134  explicit failure_reason(json::exception const& ex) noexcept : _message(ex.what()) {}
135  explicit failure_reason(char const* message) noexcept : _message(message) {}
136 
140  [[nodiscard]] constexpr auto message() const noexcept -> char const* { return _message; }
141 
142  private:
143  const char* _message;
144 };
145 using parsing_failed = failure_reason<failure::parsing_failed>;
146 
156 template <typename T>
157 struct [[nodiscard]] result {
158  using error_type = std::variant<request_rejected, request_failed, parsing_failed>;
159  using value_type = std::variant<T, error_type>;
160 
161  result() noexcept = default;
162  // NOLINTNEXTLINE
163  result(T value) noexcept : _value(std::move(value)) {}
164  // NOLINTNEXTLINE
165  result(curl_result::error_type err) noexcept : _value(request_rejected(err)) {}
166  // NOLINTNEXTLINE
167  result(int64_t code, std::string body) noexcept : _value(request_failed(code, std::move(body))) {}
168  // NOLINTNEXTLINE
169  result(json::exception const& ex) noexcept : _value(parsing_failed(ex)) {}
170  // NOLINTNEXTLINE
171  result(char const* message) noexcept : _value(parsing_failed(message)) {}
172  // NOLINTNEXTLINE
173  result(error_type err) noexcept : _value(std::move(err)) {}
174 
178  [[nodiscard]] constexpr auto failure_reason() const noexcept -> failure
179  {
180  if (_value.index() == 0) {
181  return failure::none;
182  }
183 
184  auto const& err = std::get<error_type>(_value);
185  switch (err.index()) {
186  case 0:
187  return failure::request_rejected;
188  case 1:
189  return failure::request_failed;
190  case 2:
191  return failure::parsing_failed;
192  }
193  }
194 
203  [[nodiscard]] auto to_string() const noexcept -> std::string
204  {
205  if (_value.index() == 0) {
206  return "success";
207  }
208 
209  std::ostringstream oss;
210  auto const& err = std::get<error_type>(_value);
211  switch (err.index()) {
212  case 0:
213  oss << "Request rejected. CURL error code: "
214  << curl_result::to_string(std::get<request_rejected>(err).curl_error());
215  break;
216  case 1:
217  oss << "Request failed. HTTP response code: "
218  << std::get<request_failed>(err).response_code() << " "
219  << std::get<request_failed>(err).body();
220  break;
221  case 2:
222  oss << "Parsing failed. Exception message: " << std::get<parsing_failed>(err).message();
223  break;
224  default:
225  return "Unknown. This is a bug, please report it!";
226  }
227 
228  return oss.str();
229  }
230 
234  [[nodiscard]] constexpr auto is_successful() const noexcept -> bool
235  {
236  return _value.index() == 0;
237  }
238 
242  [[nodiscard]] constexpr auto is_failed() const noexcept -> bool { return !is_successful(); }
243 
251  template <typename U>
252  constexpr auto and_then(std::function<result<U>(T&)> const& func) noexcept -> result<U>
253  {
254  if (is_failed()) {
255  return propagate<U>();
256  }
257 
258  return func(std::get<T>(_value));
259  }
260 
264  [[nodiscard]] constexpr auto operator->() noexcept -> T* { return &std::get<T>(_value); }
265 
269  [[nodiscard]] constexpr auto operator*() noexcept -> T& { return std::get<T>(_value); }
270 
274  [[nodiscard]] constexpr auto value() noexcept -> value_type& { return _value; }
275 
276  private:
277  template <typename U>
278  [[nodiscard]] constexpr auto propagate() noexcept -> result<U>
279  {
280  return {std::move(std::get<error_type>(_value))};
281  }
282 
283  value_type _value;
284 };
285 } // namespace pinecone::util
Wraps CURL results for type and exception safety.
Pinecone's custom error format.
T move(T... args)
STL namespace.
failure
The possible ways in which a Pinecone API call can fail.
Definition: result.hpp:31
T str(T... args)
An error response returned by the Pinecone API.
Definition: error.hpp:41
Models the possibly of failure for remote HTTP operations.
Definition: curl_result.hpp:20
auto to_string() const noexcept -> std::string
Retrieves the string representation of the current instance.
A request that succeeded on the remote server, but whose response could not be parsed.
Definition: result.hpp:133
constexpr auto message() const noexcept -> char const *
Definition: result.hpp:140
A request that was processed by the remote API, but failed during processing.
Definition: result.hpp:89
auto api_error() const noexcept -> std::variant< types::api_error, json::exception >
Attempts to parse the body as a structured API error.
Definition: result.hpp:110
constexpr auto body() const noexcept -> std::string const &
Definition: result.hpp:103
constexpr auto response_code() const noexcept -> int64_t
Definition: result.hpp:98
A request that was rejected by the remote API.
Definition: result.hpp:69
constexpr auto curl_error() const noexcept -> curl_result::error_type
Definition: result.hpp:75
Data associated with the possible failure modes for Cppinecone operations.
Definition: result.hpp:62
Models the possibility of failure for all Cppinecone public API operations.
Definition: result.hpp:157
constexpr auto is_successful() const noexcept -> bool
Definition: result.hpp:234
constexpr auto operator->() noexcept -> T *
Can be used only on successful results.
Definition: result.hpp:264
constexpr auto operator*() noexcept -> T &
Can be used only on successful results.
Definition: result.hpp:269
constexpr auto and_then(std::function< result< U >(T &)> const &func) noexcept -> result< U >
Runs a transformation function on a successful result; does nothing on a failed result.
Definition: result.hpp:252
constexpr auto value() noexcept -> value_type &
Definition: result.hpp:274
constexpr auto is_failed() const noexcept -> bool
Definition: result.hpp:242
constexpr auto failure_reason() const noexcept -> failure
Definition: result.hpp:178
auto to_string() const noexcept -> std::string
Retrieves a string representation of the operation result.
Definition: result.hpp:203