mirror of
https://github.com/getml/sqlgen.git
synced 2026-01-07 01:50:09 -06:00
Beautified from_str_vec
This commit is contained in:
@@ -1,21 +0,0 @@
|
||||
#ifndef SQLGEN_INTERNAL_FROM_STR_HPP_
|
||||
#define SQLGEN_INTERNAL_FROM_STR_HPP_
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "../Result.hpp"
|
||||
#include "../parsing/Parser.hpp"
|
||||
|
||||
namespace sqlgen::internal {
|
||||
|
||||
template <class T>
|
||||
Result<T> from_str(const std::optional<std::string>& _str) {
|
||||
using Type = std::remove_cvref_t<T>;
|
||||
return Parser<Type>::read(_str);
|
||||
}
|
||||
|
||||
} // namespace sqlgen::internal
|
||||
|
||||
#endif
|
||||
@@ -1,25 +1,79 @@
|
||||
#ifndef SQLGEN_INTERNAL_FROM_STR_VEC_HPP_
|
||||
#define SQLGEN_INTERNAL_FROM_STR_VEC_HPP_
|
||||
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <rfl.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "../Result.hpp"
|
||||
#include "../parsing/ViewReader.hpp"
|
||||
#include "../parsing/Parser.hpp"
|
||||
|
||||
namespace sqlgen::internal {
|
||||
|
||||
template <class ViewType, size_t i>
|
||||
void assign_if_field_is_field_i(
|
||||
const std::vector<std::optional<std::string>>& _row, const size_t _i,
|
||||
ViewType* _view, std::optional<Error>* _err) noexcept {
|
||||
using FieldType = rfl::tuple_element_t<i, typename ViewType::Fields>;
|
||||
using OriginalType = typename FieldType::Type;
|
||||
using T =
|
||||
std::remove_cvref_t<std::remove_pointer_t<typename FieldType::Type>>;
|
||||
constexpr auto name = FieldType::name();
|
||||
if (_i == i) {
|
||||
auto res = parsing::Parser<T>::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<i>(*_view) = std::move(*res);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ViewType, size_t... is>
|
||||
std::optional<Error> assign_to_field_i(
|
||||
const std::vector<std::optional<std::string>>& _row, const size_t _i,
|
||||
ViewType* _view, std::integer_sequence<size_t, is...>) noexcept {
|
||||
std::optional<Error> err;
|
||||
(assign_if_field_is_field_i<is>(_row, _i, _view, &err), ...);
|
||||
return err;
|
||||
}
|
||||
|
||||
template <class ViewType>
|
||||
std::pair<std::optional<Error>, size_t> read_into_view(
|
||||
const std::vector<std::optional<std::string>>& _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<size_t, size>());
|
||||
if (err) {
|
||||
return std::make_pair(err, i);
|
||||
}
|
||||
}
|
||||
return std::make_pair(std::nullopt, size);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Result<T> from_str_vec(
|
||||
const std::vector<std::optional<std::string>>& _str_vec) {
|
||||
T t;
|
||||
auto view = rfl::to_view(t);
|
||||
auto view_reader =
|
||||
parsing::ViewReader<std::remove_cvref_t<decltype(view)>>(&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());
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
#ifndef SQLGEN_PARSING_VIEWREADER_HPP_
|
||||
#define SQLGEN_PARSING_VIEWREADER_HPP_
|
||||
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <rfl.hpp>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "../Result.hpp"
|
||||
#include "Parser.hpp"
|
||||
|
||||
namespace sqlgen::parsing {
|
||||
|
||||
template <class ViewType>
|
||||
class ViewReader {
|
||||
private:
|
||||
static constexpr size_t size_ = ViewType::size();
|
||||
|
||||
public:
|
||||
ViewReader(ViewType* _view) : view_(_view) {}
|
||||
|
||||
~ViewReader() = default;
|
||||
|
||||
std::pair<std::optional<Error>, size_t> read(
|
||||
const std::vector<std::optional<std::string>>& _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<size_t, size_>());
|
||||
if (err) {
|
||||
return std::make_pair(err, i);
|
||||
}
|
||||
}
|
||||
return std::make_pair(std::nullopt, size_);
|
||||
}
|
||||
|
||||
private:
|
||||
template <size_t i>
|
||||
static void assign_if_field_is_field_i(
|
||||
const std::vector<std::optional<std::string>>& _row, const size_t _i,
|
||||
ViewType* _view, std::optional<Error>* _err) noexcept {
|
||||
using FieldType = rfl::tuple_element_t<i, typename ViewType::Fields>;
|
||||
using OriginalType = typename FieldType::Type;
|
||||
using T =
|
||||
std::remove_cvref_t<std::remove_pointer_t<typename FieldType::Type>>;
|
||||
constexpr auto name = FieldType::name();
|
||||
if (_i == i) {
|
||||
auto res = Parser<T>::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<i>(*_view) = std::move(*res);
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t... is>
|
||||
static std::optional<Error> assign_to_field_i(
|
||||
const std::vector<std::optional<std::string>>& _row, const size_t _i,
|
||||
ViewType* _view, std::integer_sequence<size_t, is...>) noexcept {
|
||||
std::optional<Error> err;
|
||||
(assign_if_field_is_field_i<is>(_row, _i, _view, &err), ...);
|
||||
return err;
|
||||
}
|
||||
|
||||
private:
|
||||
ViewType* view_;
|
||||
};
|
||||
|
||||
} // namespace sqlgen::parsing
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user