// GNU Lesser General Public License v3.0 // Copyright (c) 2025 Bart Beumer // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License v3.0 as published by // the Free Software Foundation. // #pragma once #include "server.hpp" #include #include #include namespace bmrshared::web { class request_response final { public: using response_sender = std::function; using request_type = bmrshared::web::server::request_type; using callback_on_finalize = std::function; private: class response_writer_interface { public: virtual ~response_writer_interface(); virtual void write_response(boost::beast::tcp_stream&) = 0; }; template class response_writer final : public response_writer_interface { public: template response_writer(TArgs&&... args) : m_response(std::forward(args)...) {} ~response_writer() override = default; void write_response(boost::beast::tcp_stream& stream) override { boost::beast::http::write(stream, m_response); } response_type& response() { return m_response; } private: response_type m_response; }; class internal_request_response final { public: // Disabling copying and moving. internal_request_response() = delete; internal_request_response(const internal_request_response&) = delete; internal_request_response(internal_request_response&&) = delete; internal_request_response& operator=(const internal_request_response&) = delete; internal_request_response& operator=(internal_request_response&&) = delete; internal_request_response(request_type request, callback_on_finalize cb_finalize); ~internal_request_response(); const request_type& get_request() const; void set_response_sender(std::unique_ptr response_writer); private: request_type m_request; callback_on_finalize m_cb_finalize; std::unique_ptr m_response_writer; }; public: request_response() = delete; request_response(const request_response&) = default; request_response(request_response&&) = default; request_response& operator=(const request_response&) = default; request_response& operator=(request_response&&) = default; request_response(request_type request, callback_on_finalize cb_finalize); ~request_response(); template response_type& create_response(arg_types&&... args) { auto created = std::make_unique>(std::forward(args)...); auto& resp = created->response(); m_internal->set_response_sender(std::move(created)); return resp; } const request_type& get_request() const; private: std::shared_ptr m_internal; }; }