summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorLucas CHOLLET <lucas.chollet@free.fr>2023-01-14 12:11:29 -0500
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2023-01-16 17:28:32 +0330
commit4952cdfe2ba2de4831a64f8b0a920870e9d1bc39 (patch)
tree7468d4bcbc4db333e77a151fdc47f4c30990f4d7 /Userland
parentfc413711eeb17558dff5138a67360f24ef87e34e (diff)
downloadserenity-4952cdfe2ba2de4831a64f8b0a920870e9d1bc39.zip
Spreadsheet: Move to a non-owning model for `Stream` in `Writer::XSV`
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Applications/Spreadsheet/ExportDialog.cpp22
-rw-r--r--Userland/Applications/Spreadsheet/ExportDialog.h10
-rw-r--r--Userland/Applications/Spreadsheet/Writers/CSV.h14
-rw-r--r--Userland/Applications/Spreadsheet/Writers/Test/TestXSVWriter.cpp10
-rw-r--r--Userland/Applications/Spreadsheet/Writers/XSV.h78
5 files changed, 75 insertions, 59 deletions
diff --git a/Userland/Applications/Spreadsheet/ExportDialog.cpp b/Userland/Applications/Spreadsheet/ExportDialog.cpp
index d706c80e3c..d185b1259a 100644
--- a/Userland/Applications/Spreadsheet/ExportDialog.cpp
+++ b/Userland/Applications/Spreadsheet/ExportDialog.cpp
@@ -88,7 +88,7 @@ CSVExportDialogPage::CSVExportDialogPage(Sheet const& sheet)
update_preview();
}
-auto CSVExportDialogPage::make_writer(Core::Stream::Handle<Core::Stream::Stream> stream) -> ErrorOr<NonnullOwnPtr<XSV>>
+auto CSVExportDialogPage::generate(Core::Stream::Stream& stream, GenerationType type) -> ErrorOr<void>
{
auto delimiter = TRY([this]() -> ErrorOr<DeprecatedString> {
if (m_delimiter_other_radio->is_checked()) {
@@ -150,15 +150,25 @@ auto CSVExportDialogPage::make_writer(Core::Stream::Handle<Core::Stream::Stream>
if (should_quote_all_fields)
behaviors = behaviors | Writer::WriterBehavior::QuoteAll;
- return try_make<XSV>(move(stream), m_data, move(traits), *headers, behaviors);
+ switch (type) {
+ case GenerationType::Normal:
+ TRY((Writer::XSV<decltype(m_data), Vector<DeprecatedString>>::generate(stream, m_data, move(traits), *headers, behaviors)));
+ break;
+ case GenerationType::Preview:
+ TRY((Writer::XSV<decltype(m_data), decltype(*headers)>::generate_preview(stream, m_data, move(traits), *headers, behaviors)));
+ break;
+ default:
+ VERIFY_NOT_REACHED();
+ }
+
+ return {};
}
void CSVExportDialogPage::update_preview()
{
auto maybe_error = [this]() -> ErrorOr<void> {
Core::Stream::AllocatingMemoryStream memory_stream;
- auto writer = TRY(make_writer(Core::Stream::Handle<Core::Stream::Stream>(memory_stream)));
- TRY(writer->generate_preview());
+ TRY(generate(memory_stream, GenerationType::Preview));
auto buffer = TRY(memory_stream.read_until_eof());
m_data_preview_text_editor->set_text(StringView(buffer));
m_data_preview_text_editor->update();
@@ -185,8 +195,8 @@ ErrorOr<void> ExportDialog::make_and_run_for(StringView mime, NonnullOwnPtr<Core
if (wizard->exec() != GUI::Dialog::ExecResult::OK)
return Error::from_string_literal("CSV Export was cancelled");
- auto writer = TRY(page.make_writer(move(file)));
- return writer->generate();
+ TRY(page.generate(*file, CSVExportDialogPage::GenerationType::Normal));
+ return {};
};
auto export_worksheet = [&]() -> ErrorOr<void> {
diff --git a/Userland/Applications/Spreadsheet/ExportDialog.h b/Userland/Applications/Spreadsheet/ExportDialog.h
index da73500443..2f07f87653 100644
--- a/Userland/Applications/Spreadsheet/ExportDialog.h
+++ b/Userland/Applications/Spreadsheet/ExportDialog.h
@@ -18,12 +18,16 @@ class Sheet;
class Workbook;
struct CSVExportDialogPage {
- using XSV = Writer::XSV<Vector<Vector<DeprecatedString>>, Vector<DeprecatedString>>;
-
explicit CSVExportDialogPage(Sheet const&);
NonnullRefPtr<GUI::WizardPage> page() { return *m_page; }
- ErrorOr<NonnullOwnPtr<XSV>> make_writer(Core::Stream::Handle<Core::Stream::Stream>);
+
+ enum class GenerationType {
+ Normal,
+ Preview
+ };
+
+ ErrorOr<void> generate(Core::Stream::Stream&, GenerationType);
protected:
void update_preview();
diff --git a/Userland/Applications/Spreadsheet/Writers/CSV.h b/Userland/Applications/Spreadsheet/Writers/CSV.h
index 6a6e2fe801..fb0cbd4ca7 100644
--- a/Userland/Applications/Spreadsheet/Writers/CSV.h
+++ b/Userland/Applications/Spreadsheet/Writers/CSV.h
@@ -12,12 +12,18 @@
namespace Writer {
-template<typename ContainerType>
-class CSV : public XSV<ContainerType> {
+class CSV {
public:
- CSV(Core::Stream::Handle<Core::Stream::Stream> output, ContainerType const& data, Vector<StringView> headers = {}, WriterBehavior behaviors = default_behaviors())
- : XSV<ContainerType>(move(output), data, { ",", "\"", WriterTraits::Repeat }, move(headers), behaviors)
+ template<typename ContainerType>
+ static ErrorOr<void> generate(Core::Stream::Stream& output, ContainerType const& data, Vector<StringView> headers = {}, WriterBehavior behaviors = default_behaviors())
{
+ return XSV<ContainerType>::generate(output, data, { ",", "\"", WriterTraits::Repeat }, move(headers), behaviors);
+ }
+
+ template<typename ContainerType>
+ static ErrorOr<void> generate_preview(Core::Stream::Stream& output, ContainerType const& data, Vector<StringView> headers = {}, WriterBehavior behaviors = default_behaviors())
+ {
+ return XSV<ContainerType>::generate_preview(output, data, { ",", "\"", WriterTraits::Repeat }, move(headers), behaviors);
}
};
diff --git a/Userland/Applications/Spreadsheet/Writers/Test/TestXSVWriter.cpp b/Userland/Applications/Spreadsheet/Writers/Test/TestXSVWriter.cpp
index 978eb20801..f47c98ee8a 100644
--- a/Userland/Applications/Spreadsheet/Writers/Test/TestXSVWriter.cpp
+++ b/Userland/Applications/Spreadsheet/Writers/Test/TestXSVWriter.cpp
@@ -7,7 +7,6 @@
#include <LibTest/TestCase.h>
#include "../CSV.h"
-#include "../XSV.h"
#include <LibCore/MemoryStream.h>
TEST_CASE(can_write)
@@ -19,8 +18,7 @@ TEST_CASE(can_write)
};
Core::Stream::AllocatingMemoryStream stream;
- auto csv = Writer::CSV(Core::Stream::Handle<Core::Stream::Stream>(stream), data);
- MUST(csv.generate());
+ MUST(Writer::CSV::generate(stream, data));
auto expected_output = R"~(1,2,3
4,5,6
@@ -40,8 +38,7 @@ TEST_CASE(can_write_with_header)
};
Core::Stream::AllocatingMemoryStream stream;
- auto csv = Writer::CSV(Core::Stream::Handle<Core::Stream::Stream>(stream), data, { "A"sv, "B\""sv, "C"sv });
- MUST(csv.generate());
+ MUST(Writer::CSV::generate(stream, data, { "A"sv, "B\""sv, "C"sv }));
auto expected_output = R"~(A,"B""",C
1,2,3
@@ -61,8 +58,7 @@ TEST_CASE(can_write_with_different_behaviors)
};
Core::Stream::AllocatingMemoryStream stream;
- auto csv = Writer::CSV(Core::Stream::Handle<Core::Stream::Stream>(stream), data, { "A"sv, "B\""sv, "C"sv }, Writer::WriterBehavior::QuoteOnlyInFieldStart | Writer::WriterBehavior::WriteHeaders);
- MUST(csv.generate());
+ MUST(Writer::CSV::generate(stream, data, { "A"sv, "B\""sv, "C"sv }, Writer::WriterBehavior::QuoteOnlyInFieldStart | Writer::WriterBehavior::WriteHeaders));
auto expected_output = R"~(A,B",C
Well,Hello",Friends
diff --git a/Userland/Applications/Spreadsheet/Writers/XSV.h b/Userland/Applications/Spreadsheet/Writers/XSV.h
index 4fac47920b..f81a17d4ed 100644
--- a/Userland/Applications/Spreadsheet/Writers/XSV.h
+++ b/Userland/Applications/Spreadsheet/Writers/XSV.h
@@ -42,59 +42,48 @@ constexpr WriterBehavior default_behaviors()
template<typename ContainerType, typename HeaderType = Vector<StringView>>
class XSV {
public:
- XSV(Core::Stream::Handle<Core::Stream::Stream> output, ContainerType const& data, WriterTraits traits, HeaderType headers = {}, WriterBehavior behaviors = default_behaviors())
- : m_data(data)
- , m_traits(move(traits))
- , m_behaviors(behaviors)
- , m_names(headers)
- , m_output(move(output))
- {
- if (!headers.is_empty())
- m_behaviors = m_behaviors | WriterBehavior::WriteHeaders;
- }
-
- virtual ~XSV() = default;
-
- ErrorOr<void> generate()
+ static ErrorOr<void> generate(Core::Stream::Stream& output, ContainerType const& data, WriterTraits traits, HeaderType headers = {}, WriterBehavior behaviors = default_behaviors())
{
- auto with_headers = has_flag(m_behaviors, WriterBehavior::WriteHeaders);
+ auto writer = XSV(output, data, traits, headers, behaviors);
+ auto with_headers = has_flag(writer.m_behaviors, WriterBehavior::WriteHeaders);
if (with_headers) {
- TRY(write_row(m_names));
- TRY(m_output->write_entire_buffer({ "\n", 1 }));
+ TRY(writer.write_row(writer.m_names));
+ TRY(writer.m_output.write_entire_buffer({ "\n", 1 }));
}
- for (auto&& row : m_data) {
+ for (auto&& row : writer.m_data) {
if (with_headers) {
- if (row.size() != m_names.size())
+ if (row.size() != writer.m_names.size())
return Error::from_string_literal("Header count does not match given column count");
}
- TRY(write_row(row));
- TRY(m_output->write_entire_buffer({ "\n", 1 }));
+ TRY(writer.write_row(row));
+ TRY(writer.m_output.write_entire_buffer({ "\n", 1 }));
}
return {};
}
- ErrorOr<void> generate_preview()
+ static ErrorOr<void> generate_preview(Core::Stream::Stream& output, ContainerType const& data, WriterTraits traits, HeaderType headers = {}, WriterBehavior behaviors = default_behaviors())
{
+ auto writer = XSV(output, data, traits, headers, behaviors);
auto lines_written = 0;
constexpr auto max_preview_lines = 8;
- auto with_headers = has_flag(m_behaviors, WriterBehavior::WriteHeaders);
+ auto with_headers = has_flag(writer.m_behaviors, WriterBehavior::WriteHeaders);
if (with_headers) {
- TRY(write_row(m_names));
- TRY(m_output->write_entire_buffer({ "\n", 1 }));
+ TRY(writer.write_row(writer.m_names));
+ TRY(writer.m_output.write_entire_buffer({ "\n", 1 }));
++lines_written;
}
- for (auto&& row : m_data) {
+ for (auto&& row : writer.m_data) {
if (with_headers) {
- if (row.size() != m_names.size())
+ if (row.size() != writer.m_names.size())
return Error::from_string_literal("Header count does not match given column count");
}
- TRY(write_row(row));
- TRY(m_output->write_entire_buffer({ "\n", 1 }));
+ TRY(writer.write_row(row));
+ TRY(writer.m_output.write_entire_buffer({ "\n", 1 }));
++lines_written;
if (lines_written >= max_preview_lines)
@@ -104,13 +93,24 @@ public:
}
private:
+ XSV(Core::Stream::Stream& output, ContainerType const& data, WriterTraits traits, HeaderType headers = {}, WriterBehavior behaviors = default_behaviors())
+ : m_data(data)
+ , m_traits(move(traits))
+ , m_behaviors(behaviors)
+ , m_names(headers)
+ , m_output(output)
+ {
+ if (!headers.is_empty())
+ m_behaviors = m_behaviors | WriterBehavior::WriteHeaders;
+ }
+
template<typename T>
ErrorOr<void> write_row(T&& row)
{
bool first = true;
for (auto&& entry : row) {
if (!first) {
- TRY(m_output->write_entire_buffer(m_traits.separator.bytes()));
+ TRY(m_output.write_entire_buffer(m_traits.separator.bytes()));
}
first = false;
TRY(write_entry(entry));
@@ -136,33 +136,33 @@ private:
if (safe_to_write_normally) {
if (!string.is_empty())
- TRY(m_output->write_entire_buffer(string.bytes()));
+ TRY(m_output.write_entire_buffer(string.bytes()));
return {};
}
- TRY(m_output->write_entire_buffer(m_traits.quote.bytes()));
+ TRY(m_output.write_entire_buffer(m_traits.quote.bytes()));
GenericLexer lexer(string);
while (!lexer.is_eof()) {
if (lexer.consume_specific(m_traits.quote)) {
switch (m_traits.quote_escape) {
case WriterTraits::Repeat:
- TRY(m_output->write_entire_buffer(m_traits.quote.bytes()));
- TRY(m_output->write_entire_buffer(m_traits.quote.bytes()));
+ TRY(m_output.write_entire_buffer(m_traits.quote.bytes()));
+ TRY(m_output.write_entire_buffer(m_traits.quote.bytes()));
break;
case WriterTraits::Backslash:
- TRY(m_output->write_entire_buffer({ "\\", 1 }));
- TRY(m_output->write_entire_buffer(m_traits.quote.bytes()));
+ TRY(m_output.write_entire_buffer({ "\\", 1 }));
+ TRY(m_output.write_entire_buffer(m_traits.quote.bytes()));
break;
}
continue;
}
auto ch = lexer.consume();
- TRY(m_output->write_entire_buffer({ &ch, 1 }));
+ TRY(m_output.write_entire_buffer({ &ch, 1 }));
}
- TRY(m_output->write_entire_buffer(m_traits.quote.bytes()));
+ TRY(m_output.write_entire_buffer(m_traits.quote.bytes()));
return {};
}
@@ -170,7 +170,7 @@ private:
WriterTraits m_traits;
WriterBehavior m_behaviors;
HeaderType m_names;
- Core::Stream::Handle<Core::Stream::Stream> m_output;
+ Core::Stream::Stream& m_output;
};
}