Giving code some initial structure
This commit is contained in:
parent
e0611ec6ff
commit
96e35a5814
7 changed files with 194 additions and 57 deletions
67
src/main.cpp
67
src/main.cpp
|
@ -1,63 +1,16 @@
|
|||
#define HAS_UNCAUGHT_EXCEPTIONS 1
|
||||
|
||||
#include <restc-cpp/restc-cpp.h>
|
||||
#include <restc-cpp/RequestBuilder.h>
|
||||
#include <string>
|
||||
#include <boost/fusion/adapted.hpp>
|
||||
#include "oro/api.hpp"
|
||||
#include <iostream>
|
||||
#include "date/date.h"
|
||||
|
||||
namespace rc = restc_cpp;
|
||||
|
||||
namespace oro {
|
||||
typedef date::sys_time<std::chrono::microseconds> timestamp_t;
|
||||
|
||||
struct Timestamp {
|
||||
Timestamp& operator= (const std::string& str) {
|
||||
std::istringstream iss(str);
|
||||
date::from_stream(iss, "%FT%T%Ez", ts);
|
||||
return *this;
|
||||
}
|
||||
|
||||
timestamp_t ts;
|
||||
};
|
||||
|
||||
struct Ping {
|
||||
Timestamp generation_timestamp;
|
||||
std::string message;
|
||||
int version;
|
||||
};
|
||||
} //namespace oro
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
oro::Ping,
|
||||
(oro::Timestamp, generation_timestamp)
|
||||
(std::string, message)
|
||||
(int, version)
|
||||
)
|
||||
|
||||
int main() {
|
||||
using date::operator<<;
|
||||
oro::Api oro_api("https://api.originsro.org", "RESTC_CPP", "Testing");
|
||||
auto ping = oro_api.ping();
|
||||
|
||||
auto rest_client = rc::RestClient::Create();
|
||||
oro::Ping ping = rest_client->ProcessWithPromiseT<oro::Ping>([&](rc::Context& ctx) {
|
||||
oro::Ping ping;
|
||||
std::unique_ptr<rc::Reply> reply = rc::RequestBuilder(ctx)
|
||||
.Get("https://api.originsro.org/api/v1/ping")
|
||||
.Header("X-Client", "RESTC_CPP")
|
||||
.Header("X-Client-Purpose", "Testing")
|
||||
.Execute();
|
||||
|
||||
std::cout << "I got X-RateLimit-Limit: " << *reply->GetHeader("X-RateLimit-Limit") << '\n';
|
||||
|
||||
rc::SerializeFromJson(ping, std::move(reply));
|
||||
return ping;
|
||||
}).get();
|
||||
|
||||
std::cout << "Response received:\n\ttimestamp: " << ping.generation_timestamp.ts;
|
||||
std::cout << "\n\tmessage: " << ping.message;
|
||||
std::cout << "\n\tversion: " << ping.version;
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "rate limit: " << ping.first.rate_limit << '\n';
|
||||
std::cout << "remaining: " << ping.first.rate_limit_remaining << '\n';
|
||||
std::cout << "reset: " << ping.first.rate_limit_reset << '\n';
|
||||
std::cout << "retry after: " << ping.first.retry_after << '\n';
|
||||
std::cout << "server: " << ping.first.server << '\n';
|
||||
std::cout << "answer: " << ping.second.message << '\n';
|
||||
std::cout << "version: " << ping.second.version << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ restc_cpp_dep = dependency('restc-cpp', version: '>=0.1.1',
|
|||
|
||||
executable(meson.project_name(),
|
||||
'main.cpp',
|
||||
'oro/datatypes.cpp',
|
||||
'oro/api.cpp',
|
||||
install: true,
|
||||
dependencies: [restc_cpp_dep],
|
||||
include_directories: date_incdir,
|
||||
|
|
75
src/oro/api.cpp
Normal file
75
src/oro/api.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include "api.hpp"
|
||||
#include "datatypes.hpp"
|
||||
#include <restc-cpp/restc-cpp.h>
|
||||
#include <restc-cpp/RequestBuilder.h>
|
||||
#include <boost/fusion/adapted.hpp>
|
||||
|
||||
namespace rc = restc_cpp;
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
oro::Ping,
|
||||
(oro::Timestamp, generation_timestamp)
|
||||
(std::string, message)
|
||||
(int, version)
|
||||
)
|
||||
|
||||
namespace oro {
|
||||
namespace {
|
||||
constexpr const char g_endpoint_ping[] = "api/v1/ping";
|
||||
|
||||
template <typename T>
|
||||
std::pair<Header, T> call_rest_api (
|
||||
rc::RestClient& rest_client,
|
||||
const std::string& url,
|
||||
const std::string& client_name,
|
||||
const std::string& client_purpose
|
||||
) {
|
||||
return rest_client.template ProcessWithPromiseT< std::pair<Header, T> >([&](rc::Context& ctx) {
|
||||
std::unique_ptr<rc::Reply> reply = rc::RequestBuilder(ctx)
|
||||
.Get(url)
|
||||
.Header("X-Client", client_name)
|
||||
.Header("X-Client-Purpose", client_purpose)
|
||||
.Execute();
|
||||
|
||||
Header h;
|
||||
if (auto val = reply->GetHeader("X-RateLimit-Limit")) {
|
||||
h.rate_limit = std::stoi(*val);
|
||||
}
|
||||
if (auto val = reply->GetHeader("X-RateLimit-Remaining")) {
|
||||
h.rate_limit_remaining = std::stoi(*val);
|
||||
}
|
||||
if (auto val = reply->GetHeader("X-RateLimit-Reset")) {
|
||||
h.rate_limit_reset = std::stoul(*val);
|
||||
}
|
||||
if (auto val = reply->GetHeader("Retry-After")) {
|
||||
h.retry_after = std::stoul(*val);
|
||||
}
|
||||
if (auto val = reply->GetHeader("Server")) {
|
||||
h.server = std::move(*val);
|
||||
}
|
||||
|
||||
T retval;
|
||||
rc::SerializeFromJson(retval, std::move(reply));
|
||||
|
||||
return std::make_pair(std::move(h), std::move(retval));
|
||||
}).get();
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
Api::Api (std::string&& root_address, std::string&& client_name, std::string&& client_purpose) :
|
||||
m_prefix(std::move(root_address)),
|
||||
m_client_name(std::move(client_name)),
|
||||
m_client_purpose(std::move(client_purpose)),
|
||||
m_client(rc::RestClient::Create())
|
||||
{
|
||||
if (not m_prefix.empty() and m_prefix[m_prefix.size() - 1] != '/')
|
||||
m_prefix.push_back('/');
|
||||
}
|
||||
|
||||
Api::~Api() noexcept = default;
|
||||
|
||||
std::pair<Header, Ping> Api::ping() {
|
||||
return call_rest_api<oro::Ping>(*m_client, m_prefix + g_endpoint_ping, m_client_name, m_client_purpose);
|
||||
}
|
||||
|
||||
} //namespace oro
|
65
src/oro/api.hpp
Normal file
65
src/oro/api.hpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
#pragma once
|
||||
|
||||
#include "ping.hpp"
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
|
||||
namespace restc_cpp {
|
||||
class RestClient;
|
||||
} //namespace restc_cpp
|
||||
|
||||
namespace oro {
|
||||
|
||||
struct Header {
|
||||
//Date: Fri, 19 Jun 2020 22:33:43 GMT
|
||||
Timestamp date;
|
||||
|
||||
//Content-Type: application/json
|
||||
//Content-Length: 89
|
||||
//Connection: keep-alive
|
||||
//Set-Cookie: __cfduid=dccdd965b47650be8b0107bb1292154981592606023; expires=Sun, 19-Jul-20 22:33:43 GMT; path=/; domain=.originsro.org; HttpOnly; SameSite=Lax
|
||||
|
||||
//X-RateLimit-Limit: 2
|
||||
int rate_limit;
|
||||
|
||||
//X-RateLimit-Remaining: 0
|
||||
int rate_limit_remaining;
|
||||
|
||||
//X-RateLimit-Reset: 1592606027
|
||||
unsigned long rate_limit_reset;
|
||||
|
||||
//Retry-After: 3
|
||||
unsigned long retry_after;
|
||||
|
||||
//CF-Cache-Status: DYNAMIC
|
||||
//cf-request-id: 03705077e200000091668c6200000001
|
||||
//Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
|
||||
//Server: cloudflare
|
||||
std::string server;
|
||||
|
||||
//CF-RAY: 5a60b69fdc270091-LHR
|
||||
|
||||
|
||||
};
|
||||
|
||||
class Api {
|
||||
public:
|
||||
Api (
|
||||
std::string&& root_address,
|
||||
std::string&& client_name,
|
||||
std::string&& client_purpose
|
||||
);
|
||||
~Api() noexcept;
|
||||
|
||||
std::pair<Header, Ping> ping();
|
||||
|
||||
private:
|
||||
std::string m_prefix;
|
||||
std::string m_client_name;
|
||||
std::string m_client_purpose;
|
||||
|
||||
std::unique_ptr<restc_cpp::RestClient> m_client;
|
||||
};
|
||||
|
||||
} //namespace oro
|
15
src/oro/datatypes.cpp
Normal file
15
src/oro/datatypes.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include "datatypes.hpp"
|
||||
|
||||
#define HAS_UNCAUGHT_EXCEPTIONS 1
|
||||
#include "date/date.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace oro {
|
||||
Timestamp& Timestamp::operator= (const std::string& str) {
|
||||
std::istringstream iss(str);
|
||||
|
||||
//date has this format: 2020-06-19T22:33:36.855672+00:00
|
||||
date::from_stream(iss, "%FT%T%Ez", ts);
|
||||
return *this;
|
||||
}
|
||||
} //namespace oro
|
15
src/oro/datatypes.hpp
Normal file
15
src/oro/datatypes.hpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
namespace oro {
|
||||
typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds> timestamp_t;
|
||||
|
||||
struct Timestamp {
|
||||
Timestamp& operator= (const std::string& str);
|
||||
operator timestamp_t() const { return ts; }
|
||||
|
||||
timestamp_t ts;
|
||||
};
|
||||
} //namespace oro
|
12
src/oro/ping.hpp
Normal file
12
src/oro/ping.hpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "datatypes.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace oro {
|
||||
struct Ping {
|
||||
Timestamp generation_timestamp;
|
||||
std::string message;
|
||||
int version;
|
||||
};
|
||||
} //namespace oro
|
Loading…
Add table
Reference in a new issue