diff --git a/include/sqlgen/internal/from_str.hpp b/include/sqlgen/internal/from_str.hpp deleted file mode 100644 index 601fe48..0000000 --- a/include/sqlgen/internal/from_str.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef SQLGEN_INTERNAL_FROM_STR_HPP_ -#define SQLGEN_INTERNAL_FROM_STR_HPP_ - -#include -#include -#include - -#include "../Result.hpp" -#include "../parsing/Parser.hpp" - -namespace sqlgen::internal { - -template -Result from_str(const std::optional& _str) { - using Type = std::remove_cvref_t; - return Parser::read(_str); -} - -} // namespace sqlgen::internal - -#endif diff --git a/include/sqlgen/internal/from_str_vec.hpp b/include/sqlgen/internal/from_str_vec.hpp index c9b3b4c..7a7d94b 100644 --- a/include/sqlgen/internal/from_str_vec.hpp +++ b/include/sqlgen/internal/from_str_vec.hpp @@ -1,25 +1,79 @@ #ifndef SQLGEN_INTERNAL_FROM_STR_VEC_HPP_ #define SQLGEN_INTERNAL_FROM_STR_VEC_HPP_ +#include #include #include +#include #include +#include #include +#include #include #include "../Result.hpp" -#include "../parsing/ViewReader.hpp" +#include "../parsing/Parser.hpp" namespace sqlgen::internal { +template +void assign_if_field_is_field_i( + const std::vector>& _row, const size_t _i, + ViewType* _view, std::optional* _err) noexcept { + using FieldType = rfl::tuple_element_t; + using OriginalType = typename FieldType::Type; + using T = + std::remove_cvref_t>; + constexpr auto name = FieldType::name(); + if (_i == i) { + auto res = parsing::Parser::read(_row[i]); + if (!res) { + std::stringstream stream; + stream << "Failed to parse field '" << std::string(name) + << "': " << res.error().what(); + *_err = Error(stream.str()); + return; + } + rfl::get(*_view) = std::move(*res); + } +} + +template +std::optional assign_to_field_i( + const std::vector>& _row, const size_t _i, + ViewType* _view, std::integer_sequence) noexcept { + std::optional err; + (assign_if_field_is_field_i(_row, _i, _view, &err), ...); + return err; +} + +template +std::pair, size_t> read_into_view( + const std::vector>& _row, + ViewType* _view) noexcept { + constexpr size_t size = ViewType::size(); + if (_row.size() != size) { + std::stringstream stream; + stream << "Expected exactly " << std::to_string(size) << " fields, but got " + << _row.size() << "."; + return std::make_pair(Error(stream.str()), 0); + } + for (size_t i = 0; i < size; ++i) { + const auto err = assign_to_field_i( + _row, i, _view, std::make_integer_sequence()); + if (err) { + return std::make_pair(err, i); + } + } + return std::make_pair(std::nullopt, size); +} + template Result from_str_vec( const std::vector>& _str_vec) { T t; auto view = rfl::to_view(t); - auto view_reader = - parsing::ViewReader>(&view); - const auto [err, num_fields_assigned] = view_reader.read(_str_vec); + const auto [err, num_fields_assigned] = read_into_view(_str_vec, &view); if (err) { return error(err->what()); } diff --git a/include/sqlgen/parsing/ViewReader.hpp b/include/sqlgen/parsing/ViewReader.hpp deleted file mode 100644 index d4eb039..0000000 --- a/include/sqlgen/parsing/ViewReader.hpp +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef SQLGEN_PARSING_VIEWREADER_HPP_ -#define SQLGEN_PARSING_VIEWREADER_HPP_ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../Result.hpp" -#include "Parser.hpp" - -namespace sqlgen::parsing { - -template -class ViewReader { - private: - static constexpr size_t size_ = ViewType::size(); - - public: - ViewReader(ViewType* _view) : view_(_view) {} - - ~ViewReader() = default; - - std::pair, size_t> read( - const std::vector>& _row) noexcept { - if (_row.size() != size_) { - std::stringstream stream; - stream << "Expected exactly " << std::to_string(size_) - << " fields, but got " << _row.size() << "."; - return std::make_pair(Error(stream.str()), 0); - } - for (size_t i = 0; i < size_; ++i) { - const auto err = assign_to_field_i( - _row, i, &view_, std::make_integer_sequence()); - if (err) { - return std::make_pair(err, i); - } - } - return std::make_pair(std::nullopt, size_); - } - - private: - template - static void assign_if_field_is_field_i( - const std::vector>& _row, const size_t _i, - ViewType* _view, std::optional* _err) noexcept { - using FieldType = rfl::tuple_element_t; - using OriginalType = typename FieldType::Type; - using T = - std::remove_cvref_t>; - constexpr auto name = FieldType::name(); - if (_i == i) { - auto res = Parser::read(_row[i]); - if (!res) { - std::stringstream stream; - stream << "Failed to parse field '" << std::string(name) - << "': " << res.error().what(); - *_err = Error(stream.str()); - return; - } - rfl::get(*_view) = std::move(*res); - } - } - - template - static std::optional assign_to_field_i( - const std::vector>& _row, const size_t _i, - ViewType* _view, std::integer_sequence) noexcept { - std::optional err; - (assign_if_field_is_field_i(_row, _i, _view, &err), ...); - return err; - } - - private: - ViewType* view_; -}; - -} // namespace sqlgen::parsing - -#endif