mirror of
https://github.com/red0124/ssp.git
synced 2025-12-14 21:59:55 +01:00
add ignore_header setup option, add unit tests for parsing by header, add string_view to possible conversion values
This commit is contained in:
@@ -273,7 +273,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void set_error_number_of_colums(size_t expected_pos, size_t pos) {
|
||||
void set_error_number_of_columns(size_t expected_pos, size_t pos) {
|
||||
if constexpr (string_error) {
|
||||
error_.clear();
|
||||
error_.append("invalid number of columns, expected: ")
|
||||
@@ -339,7 +339,7 @@ private:
|
||||
|
||||
if (!columns_mapped()) {
|
||||
if (sizeof...(Ts) != elems.size()) {
|
||||
set_error_number_of_colums(sizeof...(Ts), elems.size());
|
||||
set_error_number_of_columns(sizeof...(Ts), elems.size());
|
||||
return return_type{};
|
||||
}
|
||||
} else {
|
||||
@@ -349,9 +349,8 @@ private:
|
||||
return return_type{};
|
||||
}
|
||||
|
||||
if (elems.size() != number_of_columnts_) {
|
||||
set_error_number_of_colums(sizeof...(Ts),
|
||||
column_mappings_.size());
|
||||
if (elems.size() != number_of_columns_) {
|
||||
set_error_number_of_columns(number_of_columns_, elems.size());
|
||||
return return_type{};
|
||||
}
|
||||
}
|
||||
@@ -382,25 +381,25 @@ private:
|
||||
}
|
||||
|
||||
void set_column_mapping(std::vector<size_t> positions,
|
||||
size_t number_of_columnts) {
|
||||
size_t number_of_columns) {
|
||||
if (positions.empty()) {
|
||||
set_error_invalid_mapping();
|
||||
return;
|
||||
}
|
||||
|
||||
auto max_index = *std::max_element(positions.begin(), positions.end());
|
||||
if (max_index >= number_of_columnts) {
|
||||
set_error_mapping_out_of_range(max_index, number_of_columnts);
|
||||
if (max_index >= number_of_columns) {
|
||||
set_error_mapping_out_of_range(max_index, number_of_columns);
|
||||
return;
|
||||
}
|
||||
|
||||
column_mappings_ = positions;
|
||||
number_of_columnts_ = number_of_columnts;
|
||||
number_of_columns_ = number_of_columns;
|
||||
}
|
||||
|
||||
void clear_column_positions() {
|
||||
column_mappings_.clear();
|
||||
number_of_columnts_ = 0;
|
||||
number_of_columns_ = 0;
|
||||
}
|
||||
|
||||
////////////////
|
||||
@@ -479,7 +478,7 @@ private:
|
||||
friend class parser;
|
||||
|
||||
std::vector<size_t> column_mappings_;
|
||||
size_t number_of_columnts_;
|
||||
size_t number_of_columns_;
|
||||
};
|
||||
|
||||
} /* ss */
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
|
||||
namespace ss {
|
||||
@@ -318,7 +319,14 @@ inline bool extract(const char* begin, const char* end, char& value) {
|
||||
|
||||
template <>
|
||||
inline bool extract(const char* begin, const char* end, std::string& value) {
|
||||
value = std::string(begin, end);
|
||||
value = std::string{begin, end};
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool extract(const char* begin, const char* end,
|
||||
std::string_view& value) {
|
||||
value = std::string_view{begin, static_cast<size_t>(end - begin)};
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,15 +25,19 @@ class parser {
|
||||
constexpr static bool quoted_multiline_enabled =
|
||||
multiline::enabled && setup<Matchers...>::quote::enabled;
|
||||
|
||||
constexpr static bool ignore_header = setup<Matchers...>::ignore_header;
|
||||
|
||||
public:
|
||||
parser(const std::string& file_name,
|
||||
const std::string& delim = ss::default_delimiter)
|
||||
: file_name_{file_name}, reader_{file_name_, delim} {
|
||||
if (reader_.file_) {
|
||||
read_line();
|
||||
// TODO if header reading enabled
|
||||
header_ = reader_.get_next_row();
|
||||
// TODO if ignore_header defined ignore first line
|
||||
if constexpr (ignore_header) {
|
||||
ignore_next();
|
||||
} else {
|
||||
header_ = reader_.get_next_row();
|
||||
}
|
||||
} else {
|
||||
set_error_file_not_open();
|
||||
eof_ = true;
|
||||
@@ -102,6 +106,11 @@ public:
|
||||
|
||||
template <typename... Ts>
|
||||
void use_fields(const Ts&... fields_args) {
|
||||
if constexpr (ignore_header) {
|
||||
set_error_header_ignored();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!valid()) {
|
||||
return;
|
||||
}
|
||||
@@ -449,6 +458,18 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void set_error_header_ignored() {
|
||||
if constexpr (string_error) {
|
||||
error_.append(file_name_)
|
||||
.append(": \"")
|
||||
.append("the header row is ignored within the setup, it cannot "
|
||||
"be used")
|
||||
.append("\"");
|
||||
} else {
|
||||
error_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void set_error_invalid_field(const std::string& field) {
|
||||
if constexpr (string_error) {
|
||||
error_.append(file_name_)
|
||||
|
||||
@@ -167,6 +167,12 @@ using get_multiline_t = typename get_multiline<Ts...>::type;
|
||||
|
||||
class string_error;
|
||||
|
||||
////////////////
|
||||
// ignore_header
|
||||
////////////////
|
||||
|
||||
class ignore_header;
|
||||
|
||||
////////////////
|
||||
// setup implementation
|
||||
////////////////
|
||||
@@ -185,13 +191,19 @@ private:
|
||||
template <typename T>
|
||||
struct is_string_error : std::is_same<T, string_error> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_ignore_header : std::is_same<T, ignore_header> {};
|
||||
|
||||
constexpr static auto count_matcher = count_v<is_matcher, Ts...>;
|
||||
constexpr static auto count_multiline =
|
||||
count_v<is_instance_of_multiline, Ts...>;
|
||||
constexpr static auto count_string_error = count_v<is_string_error, Ts...>;
|
||||
constexpr static auto count_ignore_header =
|
||||
count_v<is_ignore_header, Ts...>;
|
||||
|
||||
constexpr static auto number_of_valid_setup_types =
|
||||
count_matcher + count_multiline + count_string_error;
|
||||
count_matcher + count_multiline + count_string_error +
|
||||
count_ignore_header;
|
||||
|
||||
using trim_left_only = get_matcher_t<trim_left, Ts...>;
|
||||
using trim_right_only = get_matcher_t<trim_right, Ts...>;
|
||||
@@ -206,6 +218,7 @@ public:
|
||||
|
||||
using multiline = get_multiline_t<Ts...>;
|
||||
constexpr static bool string_error = (count_string_error == 1);
|
||||
constexpr static bool ignore_header = (count_ignore_header == 1);
|
||||
|
||||
private:
|
||||
#define ASSERT_MSG "cannot have the same match character in multiple matchers"
|
||||
|
||||
Reference in New Issue
Block a user