Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use std::expected instead of std::error_code reference #11

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions client/include/client_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,16 @@ namespace pine

/// @brief Start listening for messages from the server.
/// @return An asynchronous task completed when the connection has been closed.
async_task listen();
async_operation<void, std::error_code> listen() const;

/// @brief Receive an HTTP response from the server.
/// @param ec The error code set if the response could not be received.
/// @return An asynchronous task completed when the response has been received.
async_operation<http_response> receive_response(std::error_code& ec);
async_operation<http_response, std::error_code> receive_response() const;

/// @brief Send an HTTP request to the server.
/// @param request The request to send.
/// @param ec The error code set if the request could not be sent.
/// @return An asynchronous task completed when the request has been sent.
async_task send_request(http_request const& request, std::error_code& ec);
async_operation<void, std::error_code> send_request(http_request const& request) const;

private:
std::jthread client_thread;
Expand Down
36 changes: 24 additions & 12 deletions client/src/client_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ namespace pine

bool client_connection::connect(std::string const& host, uint16_t const& port)
{
if (!this->connect(host, port))
// TODO: ???
if (!connect(host, port))
return false;

this->listen();
Expand All @@ -29,28 +30,39 @@ namespace pine
this->close();
}

async_task client_connection::listen()
async_operation<void, std::error_code>
client_connection::listen() const
{
while (true)
{
std::error_code ec;
co_await receive_raw_message(ec);
const auto& received_message_result = co_await receive_raw_message();
if (!received_message_result)
co_return received_message_result.error();
}
}

async_operation<http_response> client_connection::receive_response(std::error_code& ec)
async_operation<http_response, std::error_code>
client_connection::receive_response() const
{
std::string response_string = co_await this->receive_raw_message(ec);
if (ec)
co_return http_response{};
const auto& received_message_result = co_await this->receive_raw_message();
if (!received_message_result)
co_return received_message_result.error();

auto response = http_response::parse(response_string, ec);
const auto& response_string = received_message_result.value();

auto response = http_response::parse(response_string);
co_return response;
}

async_task client_connection::send_request(http_request const& request, std::error_code& ec)
async_operation<void, std::error_code>
client_connection::send_request(http_request const& request) const
{
auto request_string = request.to_string();
co_await this->send_raw_message(request_string, ec);
const auto& request_string = request.to_string();

const auto& send_result = co_await this->send_raw_message(request_string);
if (!send_result)
co_return send_result.error();

co_return {};
}
}
2 changes: 1 addition & 1 deletion examples/client_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ int main()
std::cout << "Failed to connect to server" << std::endl;
return 1;
}
}
}
7 changes: 3 additions & 4 deletions examples/server_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
int main()
{
pine::server server;
std::error_code ec;
server.start(ec);
if (ec)

if (auto server_result = server.start(); !server_result)
{
std::cerr << "Error: " << ec.message() << std::endl;
std::cerr << "Error: " << server_result.error().message() << std::endl;
return 1;
}

Expand Down
43 changes: 24 additions & 19 deletions server/include/server.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#pragma once

#include <coroutine.h>
#include <cstdint>
#include <expected.h>
#include <functional>
#include <memory>
#include <mutex>
#include <string_view>
#include <system_error>
#include <thread>
#include <unordered_map>
#include <vector>
#include "coroutine.h"
#include "server_connection.h"
#include <WinSock2.h>

namespace pine
{
Expand All @@ -24,7 +24,7 @@ namespace pine
explicit server(const char* port = "80");

/// @brief Start listening for connections.
void start(std::error_code& ec);
std::expected<void, std::error_code> start();

/// @brief Stop listening for connections.
void stop();
Expand All @@ -33,16 +33,16 @@ namespace pine
/// @param client_id Id of the client to disconnect.
/// @return An asynchronous task completed when the client has been
/// disconnected.
async_task disconnect_client(uint64_t const& client_id);
async_operation<void, std::error_code> disconnect_client(
uint64_t const& client_id);

private:
/// @brief Accept clients.
/// This function waits for clients to connect and creates a server
/// connection for each client.
/// @param ec An error code to be set if an error occurs.
/// @return An asynchronous task completed when the server has stopped
/// listening.
void accept_clients(std::error_code& ec);
std::expected<void, std::error_code> accept_clients();

std::mutex delete_clients_mutex;
std::mutex mutate_clients_mutex;
Expand All @@ -65,54 +65,59 @@ namespace pine
/// @brief Call this function to add a callback that will be executed when
/// a new client attempts to connect to the server.
/// @return A reference to this server.
server& on_connection_attempt(std::function < async_task(
server&,
server&
on_connection_attempt(
std::function<async_operation<void, std::error_code>(server&,
std::shared_ptr<server_connection> const&)> const& callback
);
);

/// @brief Call this function to add a callback that will be executed when
/// a client fails
/// to connect to the server.
/// @return A reference to this server.
server& on_connection_failed(std::function < async_task(
server&
on_connection_failed(
std::function < async_operation<void, std::error_code>(
server&,
std::shared_ptr<server_connection> const&)> const& callback
);
);

/// @brief Call this function to add a callback that will be executed when
/// a client successfully
/// connects to the server.
/// @return A reference to this server.
server& on_connection(std::function < async_task(
server&
on_connection(std::function < async_operation<void, std::error_code>(
server&,
std::shared_ptr<server_connection> const&)> const& callback
);
);

/// @brief Call this function to add a callback that will be executed when
/// the server is ready
/// to accept connections.
/// @return A reference to this server.
server& on_ready(std::function < async_task(
server&
on_ready(std::function < async_operation<void, std::error_code>(
server&)> const& callback
);

private:
std::vector<std::function<async_task(
std::vector<std::function<async_operation<void, std::error_code>(
server&,
std::shared_ptr<server_connection> const&)>
> on_connection_attemps_callbacks;

std::vector<std::function<async_task(
std::vector<std::function<async_operation<void, std::error_code>(
server&,
std::shared_ptr<server_connection> const&)>
> on_connection_failed_callbacks;

std::vector<std::function<async_task(
std::vector<std::function<async_operation<void, std::error_code>(
server&,
std::shared_ptr<server_connection> const&)>
> on_connection_callbacks;

std::vector < std::function < async_task(
std::vector < std::function < async_operation<void, std::error_code>(
server&)>
> on_ready_callbacks;
};
Expand Down
23 changes: 9 additions & 14 deletions server/include/server_connection.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
#pragma once

#include <connection.h>
#include <coroutine.h>
#include <http_request.h>
#include <http_response.h>
#include <memory>
#include <mutex>
#include <string_view>
#include <thread>
#include "connection.h"
#include "coroutine.h"
#include "http_request.h"
#include "http_response.h"
#include "snowflake.h"
#include <system_error>
#include <WinSock2.h>

namespace pine
{
Expand All @@ -22,20 +20,17 @@ namespace pine
explicit server_connection(SOCKET socket);

/// @brief Receive an HTTP request.
/// @param ec An error code to be set if an error occurs.
/// @return An asynchronous task completed when the request has been received.
async_operation<http_request> receive_request(std::error_code& ec);
async_operation<http_request, std::error_code> receive_request() const;

/// @brief Send an HTTP response.
/// @param response The response to send.
/// @param ec An error code to be set if an error occurs.
/// @return An asynchronous task completed when the response has been sent.
async_task send_response(http_response const& response, std::error_code& ec);
async_operation<void, std::error_code> send_response(http_response const& response) const;

/// @brief Start listening for messages from the client.
/// @param ec An error code to be set if an error occurs.
/// @return An asynchronous task completed when the connection has been closed.
async_task start(std::error_code& ec);
async_operation<void, std::error_code> start();

private:
/// @brief Whether the connection is connected.
Expand Down
Loading
Loading