summaryrefslogtreecommitdiff
path: root/src/csv.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/csv.cc')
-rw-r--r--src/csv.cc63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/csv.cc b/src/csv.cc
new file mode 100644
index 0000000..4135555
--- /dev/null
+++ b/src/csv.cc
@@ -0,0 +1,63 @@
+#include "csv.hh"
+
+#include "line.hh"
+#include "str.hh"
+
+#include <cstdint>
+#include <expected>
+#include <memory>
+#include <span>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace csv {
+
+namespace {
+
+class ReaderImpl : public Reader {
+ public:
+ ReaderImpl(std::unique_ptr<line::Reader> reader, char separator)
+ : reader_(std::move(reader)), separator_(separator) {
+ }
+
+ [[nodiscard]]
+ std::expected<std::span<std::string_view>, io::ReadError> read() override {
+ while (true) {
+ auto line = reader_->read();
+ if (line.has_value()) {
+ str::split(line.value(), line_, separator_, /* keep_empty */ true);
+ if (line_.size() == 1 && line_[0].empty())
+ continue;
+ return line_;
+ }
+ if (line.error().eof) {
+ return {};
+ }
+ return std::unexpected(line.error().io_error.value());
+ }
+ }
+
+ [[nodiscard]] uint64_t number() const override {
+ return reader_->number();
+ }
+
+ private:
+ std::unique_ptr<line::Reader> reader_;
+ char const separator_;
+ std::vector<std::string_view> line_;
+};
+
+} // namespace
+
+std::unique_ptr<Reader> open(std::unique_ptr<line::Reader> reader,
+ char separator) {
+ return std::make_unique<ReaderImpl>(std::move(reader), separator);
+}
+
+std::unique_ptr<Reader> open(std::unique_ptr<io::Reader> reader,
+ char separator) {
+ return open(line::open(std::move(reader)), separator);
+}
+
+} // namespace csv