Skip to content

Commit

Permalink
ffi: Add IrUnitHandlerInterface to perform user-defined handling fo…
Browse files Browse the repository at this point in the history
…r deserialized IR units. (y-scope#540)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: davidlion <[email protected]>
  • Loading branch information
3 people authored Sep 28, 2024
1 parent 695a1f8 commit 7b921f1
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 0 deletions.
2 changes: 2 additions & 0 deletions components/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ set(SOURCE_FILES_unitTest
src/clp/ffi/ir_stream/decoding_methods.inc
src/clp/ffi/ir_stream/encoding_methods.cpp
src/clp/ffi/ir_stream/encoding_methods.hpp
src/clp/ffi/ir_stream/IrUnitHandlerInterface.hpp
src/clp/ffi/ir_stream/protocol_constants.hpp
src/clp/ffi/ir_stream/Serializer.cpp
src/clp/ffi/ir_stream/Serializer.hpp
Expand Down Expand Up @@ -498,6 +499,7 @@ set(SOURCE_FILES_unitTest
tests/test-BufferedFileReader.cpp
tests/test-EncodedVariableInterpreter.cpp
tests/test-encoding_methods.cpp
tests/test-ffi_IrUnitHandlerInterface.cpp
tests/test-ffi_KeyValuePairLogEvent.cpp
tests/test-ffi_SchemaTree.cpp
tests/test-FileDescriptorReader.cpp
Expand Down
62 changes: 62 additions & 0 deletions components/core/src/clp/ffi/ir_stream/IrUnitHandlerInterface.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef CLP_FFI_IR_STREAM_IRUNITHANDLERINTERFACE_HPP
#define CLP_FFI_IR_STREAM_IRUNITHANDLERINTERFACE_HPP

#include <concepts>
#include <utility>

#include "../../time_types.hpp"
#include "../KeyValuePairLogEvent.hpp"
#include "../SchemaTree.hpp"
#include "decoding_methods.hpp"

namespace clp::ffi::ir_stream {
/**
* Concept that defines the IR unit handler interface.
*/
template <typename Handler>
concept IrUnitHandlerInterface = requires(
Handler handler,
KeyValuePairLogEvent&& log_event,
UtcOffset utc_offset_old,
UtcOffset utc_offset_new,
SchemaTree::NodeLocator schema_tree_node_locator
) {
/**
* Handles a log event IR unit.
* @param log_event The deserialized result from IR deserializer.
* @return IRErrorCode::Success on success, user-defined error code on failures.
*/
{
handler.handle_log_event(std::forward<KeyValuePairLogEvent&&>(log_event))
} -> std::same_as<IRErrorCode>;

/**
* Handles a UTC offset change IR unit.
* @param utc_offset_old The offset before the change.
* @param utc_offset_new The deserialized new offset.
* @return IRErrorCode::Success on success, user-defined error code on failures.
*/
{
handler.handle_utc_offset_change(utc_offset_old, utc_offset_new)
} -> std::same_as<IRErrorCode>;

/**
* Handles a schema tree node insertion IR unit.
* @param schema_tree_node_locator The locator of the node to insert.
* @return IRErrorCode::Success on success, user-defined error code on failures.
*/
{
handler.handle_schema_tree_node_insertion(schema_tree_node_locator)
} -> std::same_as<IRErrorCode>;

/**
* Handles an end-of-stream indicator IR unit.
* @return IRErrorCode::Success on success, user-defined error code on failures.
*/
{
handler.handle_end_of_stream()
} -> std::same_as<IRErrorCode>;
};
} // namespace clp::ffi::ir_stream

#endif // CLP_FFI_IR_STREAM_IRUNITHANDLERINTERFACE_HPP
140 changes: 140 additions & 0 deletions components/core/tests/test-ffi_IrUnitHandlerInterface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include <memory>
#include <optional>
#include <string_view>
#include <utility>

#include <Catch2/single_include/catch2/catch.hpp>

#include "../src/clp/ffi/ir_stream/decoding_methods.hpp"
#include "../src/clp/ffi/ir_stream/IrUnitHandlerInterface.hpp"
#include "../src/clp/ffi/KeyValuePairLogEvent.hpp"
#include "../src/clp/ffi/SchemaTree.hpp"
#include "../src/clp/ffi/SchemaTreeNode.hpp"
#include "../src/clp/time_types.hpp"

namespace {
using clp::ffi::ir_stream::IRErrorCode;
using clp::ffi::KeyValuePairLogEvent;
using clp::ffi::SchemaTree;
using clp::ffi::SchemaTreeNode;
using clp::UtcOffset;

constexpr UtcOffset cTestUtcOffset{100};
constexpr UtcOffset cTestUtcOffsetDelta{1000};
constexpr std::string_view cTestSchemaTreeNodeKeyName{"test_key"};

/**
* Class that implements `clp::ffi::ir_stream::IrUnitHandlerInterface` for testing purposes.
*/
class TrivialIrUnitHandler {
public:
// Implements `clp::ffi::ir_stream::IrUnitHandlerInterface` interface
[[nodiscard]] auto handle_log_event(KeyValuePairLogEvent&& log_event) -> IRErrorCode {
m_log_event.emplace(std::move(log_event));
return IRErrorCode::IRErrorCode_Success;
}

[[nodiscard]] auto
handle_utc_offset_change(UtcOffset utc_offset_old, UtcOffset utc_offset_new) -> IRErrorCode {
m_utc_offset_delta = utc_offset_new - utc_offset_old;
return IRErrorCode::IRErrorCode_Success;
}

[[nodiscard]] auto handle_schema_tree_node_insertion(
SchemaTree::NodeLocator schema_tree_node_locator
) -> IRErrorCode {
m_schema_tree_node_locator.emplace(schema_tree_node_locator);
return IRErrorCode::IRErrorCode_Success;
}

[[nodiscard]] auto handle_end_of_stream() -> IRErrorCode {
m_is_complete = true;
return IRErrorCode::IRErrorCode_Success;
}

// Methods
[[nodiscard]] auto get_utc_offset_delta() const -> UtcOffset { return m_utc_offset_delta; }

[[nodiscard]] auto is_complete() const -> bool { return m_is_complete; }

[[nodiscard]] auto get_schema_tree_node_locator(
) const -> std::optional<SchemaTree::NodeLocator> const& {
return m_schema_tree_node_locator;
}

[[nodiscard]] auto get_log_event() const -> std::optional<KeyValuePairLogEvent> const& {
return m_log_event;
}

private:
UtcOffset m_utc_offset_delta{0};
bool m_is_complete{false};
std::optional<SchemaTree::NodeLocator> m_schema_tree_node_locator;
std::optional<KeyValuePairLogEvent> m_log_event;
};

/**
* Class that inherits `TrivialIrUnitHandler` which also implements
* `clp::ffi::ir_stream::IrUnitHandlerInterface`.
*/
class TriviallyInheritedIrUnitHandler : public TrivialIrUnitHandler {};

/**
* Simulates the use of an IR unit handler. It calls every method required by
* `clp::ffi::ir_stream::IrUnitHandlerInterface` and ensure they don't return errors.
* @param handler
*/
auto test_ir_unit_handler_interface(clp::ffi::ir_stream::IrUnitHandlerInterface auto& handler
) -> void;

auto test_ir_unit_handler_interface(clp::ffi::ir_stream::IrUnitHandlerInterface auto& handler
) -> void {
auto test_log_event_result{
KeyValuePairLogEvent::create(std::make_shared<SchemaTree>(), {}, cTestUtcOffset)
};
REQUIRE(
(false == test_log_event_result.has_error()
&& IRErrorCode::IRErrorCode_Success
== handler.handle_log_event(std::move(test_log_event_result.value())))
);
REQUIRE(
(IRErrorCode::IRErrorCode_Success
== handler.handle_utc_offset_change(
cTestUtcOffset,
cTestUtcOffset + cTestUtcOffsetDelta
))
);
REQUIRE(
(IRErrorCode::IRErrorCode_Success
== handler.handle_schema_tree_node_insertion(
{SchemaTree::cRootId, cTestSchemaTreeNodeKeyName, SchemaTreeNode::Type::Obj}
))
);
REQUIRE((IRErrorCode::IRErrorCode_Success == handler.handle_end_of_stream()));
}
} // namespace

TEMPLATE_TEST_CASE(
"test_ir_unit_handler_interface_basic",
"[ffi][ir_stream]",
TrivialIrUnitHandler,
TriviallyInheritedIrUnitHandler
) {
TestType handler;
REQUIRE_FALSE(handler.is_complete());
test_ir_unit_handler_interface(handler);

REQUIRE((handler.get_utc_offset_delta() == cTestUtcOffsetDelta));
auto const& optional_log_event{handler.get_log_event()};
REQUIRE(
(optional_log_event.has_value()
&& optional_log_event.value().get_utc_offset() == cTestUtcOffset
&& optional_log_event.value().get_node_id_value_pairs().empty())
);
auto const& optional_schema_tree_locator{handler.get_schema_tree_node_locator()};
REQUIRE(
(optional_schema_tree_locator.has_value()
&& optional_schema_tree_locator.value().get_key_name() == cTestSchemaTreeNodeKeyName)
);
REQUIRE(handler.is_complete());
}

0 comments on commit 7b921f1

Please sign in to comment.