From 9594cbe20db6bb54a21df949656b7ca89dbf8b9b Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Mon, 15 Jan 2024 05:15:40 +0100 Subject: [PATCH] Finished writing the reader --- include/rfl/bson/Reader.hpp | 57 ++++++++++++++++++++++++++++++------- include/rfl/bson/read.hpp | 15 ++++++++++ 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/include/rfl/bson/Reader.hpp b/include/rfl/bson/Reader.hpp index 74ba5935..a646d37e 100644 --- a/include/rfl/bson/Reader.hpp +++ b/include/rfl/bson/Reader.hpp @@ -20,6 +20,7 @@ namespace rfl { namespace bson { +/// Please refer to https://mongoc.org/libbson/current/api.html struct Reader { struct BSONInputArray { bson_iter_t iter_; @@ -43,10 +44,19 @@ struct Reader { }); rfl::Result get_field( - const std::string& _name, const InputObjectType& _obj) const noexcept {} + const std::string& _name, const InputObjectType& _obj) const noexcept { + auto iter = _obj.iter_; + while (bson_iter_next(&iter)) { + auto key = std::string(bson_iter_key(&iter)); + if (key == _name) { + return InputVarType{iter}; + } + } + return Error("No field named '" + _name + "' was found."); + } - bool is_empty(const InputVarType _var) const noexcept { - return bson_iter_type(_var.iter_) == BSON_TYPE_NULL; + bool is_empty(const InputVarType& _var) const noexcept { + return bson_iter_type(&_var.iter_) == BSON_TYPE_NULL; } template @@ -68,7 +78,7 @@ struct Reader { if (bson_iter_type(&_var.iter_) != BSON_TYPE_DOUBLE) { return rfl::Error("Could not cast to double."); } - return static_cast(bson_iter_double(_var.val_)); + return static_cast(bson_iter_double(&_var.iter_)); } else if constexpr (std::is_integral>()) { const auto btype = bson_iter_type(&_var.iter_); if (btype != BSON_TYPE_DOUBLE && btype != BSON_TYPE_BOOL && @@ -83,20 +93,40 @@ struct Reader { rfl::Result to_array( const InputVarType& _var) const noexcept { - if (bson_iter_type(&_var.iter_) != BSON_TYPE_ARRAY) { + auto iter = _obj.iter_; + if (bson_iter_type(iter) != BSON_TYPE_ARRAY) { return Error("Could not cast to an array."); } InputArrayType arr; - bson_iter_recurse(&_var.iter_, &arr.iter_); + bson_iter_recurse(&iter, &arr.iter_); return arr; } template std::array, size> to_fields_array( - const FunctionType _fct, const InputObjectType _obj) const noexcept {} + const FunctionType& _fct, const InputObjectType& _obj) const noexcept { + auto iter = _obj.iter_; + std::array, size> f_arr; + while (bson_iter_next(&iter)) { + const char* k = bson_iter_key(&iter); + const auto ix = _fct(std::string_view(k)); + if (ix != -1) { + f_arr[ix] = InputVarType{iter}; + } + } + return f_arr; + } std::vector> to_map( - const InputObjectType _obj) const noexcept {} + const InputObjectType& _obj) const noexcept { + auto iter = _obj.iter_; + std::vector> map; + while (bson_iter_next(&iter)) { + auto key = std::string(bson_iter_key(&iter)); + map.emplace_back(std::make_pair(std::move(key), iter)); + } + return map; + } rfl::Result to_object( const InputVarType& _var) const noexcept { @@ -108,11 +138,18 @@ struct Reader { return obj; } - std::vector to_vec(const InputArrayType _arr) const noexcept {} + std::vector to_vec(const InputArrayType& _arr) const noexcept { + auto iter = _obj.iter_; + std::vector vec; + while (bson_iter_next(&iter)) { + vec.push_back(iter); + } + return vec; + } template rfl::Result use_custom_constructor( - const InputVarType _var) const noexcept { + const InputVarType& _var) const noexcept { try { return T::from_bson_obj(_var); } catch (std::exception& e) { diff --git a/include/rfl/bson/read.hpp b/include/rfl/bson/read.hpp index db77fa87..f2e9cb64 100644 --- a/include/rfl/bson/read.hpp +++ b/include/rfl/bson/read.hpp @@ -21,6 +21,21 @@ auto read(const InputVarType& _obj) { return Parser::read(r, _obj); } +/// Parses an object from flexbuf using reflection. +template +auto read(const char* _bytes, const size_t _size) { + InputVarType doc; + const bool success = bson_init_static( + &doc.iter_, reinterpret_cast(_bytes.data()), + bytes.size()); + if (!success) { + return Error("Bytestring was not a valid BSON string."); + } + const auto result = read(doc); + bson_destroy(&doc.iter_); + return result; +} + /// Parses an object from BSON using reflection. template Result> read(const std::vector& _bytes) {