Skip to content

Commit 3b01b67

Browse files
committed
Move more parser logic into Rust.
1 parent ac6ad54 commit 3b01b67

File tree

9 files changed

+43
-70
lines changed

9 files changed

+43
-70
lines changed

app/app.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,13 @@ void app::restore_previous_documents() {
155155
if (existing_tab >= 0) {
156156
continue;
157157
}
158-
const auto* parser = find_parser_by_extension(wxFileName(path).GetExt());
159-
if (parser == nullptr) {
160-
parser = get_parser_for_unknown_file(path, config_mgr);
161-
if (parser == nullptr) {
158+
const wxString extension = wxFileName(path).GetExt();
159+
if (!is_parser_supported(extension)) {
160+
if (!ensure_parser_for_unknown_file(path, config_mgr)) {
162161
continue;
163162
}
164163
}
165-
if (!doc_manager->create_document_tab(path, parser, false, false)) {
164+
if (!doc_manager->create_document_tab(path, false, false)) {
166165
continue;
167166
}
168167
}

app/document_manager.cpp

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,11 @@ bool document_manager::open_file(const wxString& path, bool add_to_recent) {
131131
if (text_ctrl != nullptr) text_ctrl->SetFocus();
132132
return true;
133133
}
134-
const parser_info* parser = find_parser_by_extension(wxFileName(path).GetExt());
135-
if (parser == nullptr) {
136-
parser = get_parser_for_unknown_file(path, config);
137-
if (parser == nullptr) return false;
134+
const wxString extension = wxFileName(path).GetExt();
135+
if (!is_parser_supported(extension)) {
136+
if (!ensure_parser_for_unknown_file(path, config)) return false;
138137
}
139-
if (!create_document_tab(path, parser, true, add_to_recent)) return false;
138+
if (!create_document_tab(path, true, add_to_recent)) return false;
140139
auto* const text_ctrl = get_active_text_ctrl();
141140
if (text_ctrl != nullptr) {
142141
text_ctrl->Bind(wxEVT_KEY_UP, &main_window::on_text_cursor_changed, &main_win);
@@ -146,8 +145,7 @@ bool document_manager::open_file(const wxString& path, bool add_to_recent) {
146145
return true;
147146
}
148147

149-
bool document_manager::create_document_tab(const wxString& path, const parser_info* parser, bool set_focus, bool add_to_recent) {
150-
if (parser == nullptr) return false;
148+
bool document_manager::create_document_tab(const wxString& path, bool set_focus, bool add_to_recent) {
151149
try {
152150
config.import_document_settings(path);
153151
const wxString forced_extension = config.get_document_format(path);
@@ -196,7 +194,6 @@ bool document_manager::create_document_tab(const wxString& path, const parser_in
196194
auto* tab_data = new document_tab;
197195
tab_data->session_doc = std::move(session_doc);
198196
tab_data->file_path = path;
199-
tab_data->parser = parser;
200197
wxPanel* panel = create_tab_panel(tab_data->session_doc->content, tab_data);
201198
tab_data->panel = panel;
202199
notebook->AddPage(panel, tab_data->session_doc->get_title(), true);
@@ -274,11 +271,6 @@ wxTextCtrl* document_manager::get_active_text_ctrl() const {
274271
return tab != nullptr ? tab->text_ctrl : nullptr;
275272
}
276273

277-
const parser_info* document_manager::get_active_parser() const {
278-
const document_tab* tab = get_active_tab();
279-
return tab != nullptr ? tab->parser : nullptr;
280-
}
281-
282274
int document_manager::get_tab_count() const {
283275
return static_cast<int>(notebook->GetPageCount());
284276
}

app/document_manager.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <wx/clntdata.h>
88
#include <wx/string.h>
99

10-
struct parser_info;
1110
class wxNotebook;
1211
class wxTextCtrl;
1312
class wxPanel;
@@ -20,7 +19,6 @@ struct document_tab : public wxClientData {
2019
std::unique_ptr<session_document> session_doc;
2120
wxString file_path;
2221
wxPanel* panel{nullptr};
23-
const parser_info* parser{nullptr};
2422

2523
document_tab() = default;
2624
~document_tab() = default;
@@ -55,15 +53,14 @@ class document_manager {
5553
document_manager(document_manager&&) = delete;
5654
document_manager& operator=(document_manager&&) = delete;
5755
[[nodiscard]] bool open_file(const wxString& path, bool add_to_recent = true);
58-
[[nodiscard]] bool create_document_tab(const wxString& path, const parser_info* parser, bool set_focus = true, bool add_to_recent = true);
56+
[[nodiscard]] bool create_document_tab(const wxString& path, bool set_focus = true, bool add_to_recent = true);
5957
void update_ui();
6058
void close_document(int index);
6159
void close_all_documents();
6260
[[nodiscard]] bool export_document(int index, const wxString& export_path) const;
6361
[[nodiscard]] document_tab* get_tab(int index) const;
6462
[[nodiscard]] document_tab* get_active_tab() const;
6563
[[nodiscard]] wxTextCtrl* get_active_text_ctrl() const;
66-
[[nodiscard]] const parser_info* get_active_parser() const;
6764
[[nodiscard]] int get_tab_count() const;
6865
[[nodiscard]] int get_active_tab_index() const;
6966
[[nodiscard]] int page_index(size_t position) const;

app/parser.cpp

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,7 @@
1515
#include <wx/string.h>
1616
#include <wx/translation.h>
1717

18-
namespace {
19-
using parser_list = std::vector<parser_info>;
20-
2118
constexpr std::string_view PASSWORD_REQUIRED_PREFIX = "[password_required]";
22-
23-
parser_list& get_parser_infos() {
24-
static parser_list parsers;
25-
return parsers;
26-
}
27-
2819
parser_exception make_parser_exception(const std::exception& e, const wxString& path) {
2920
const std::string message = e.what();
3021
if (message.rfind(PASSWORD_REQUIRED_PREFIX, 0) == 0) {
@@ -35,43 +26,25 @@ parser_exception make_parser_exception(const std::exception& e, const wxString&
3526
}
3627
return parser_exception(wxString::FromUTF8(message.c_str()), path);
3728
}
38-
} // namespace
3929

4030
bool initialize_parser_registry() {
4131
try {
42-
const auto parser_infos = get_available_parsers();
43-
auto& parsers = get_parser_infos();
44-
parsers.clear();
45-
parsers.reserve(parser_infos.size());
46-
for (const auto& info : parser_infos) {
47-
parser_info record;
48-
record.name = to_wxstring(info.name);
49-
record.flags = static_cast<parser_flags>(info.flags);
50-
record.extensions.reserve(info.extensions.size());
51-
for (const auto& ext : info.extensions) {
52-
record.extensions.push_back(to_wxstring(ext));
53-
}
54-
parsers.push_back(std::move(record));
55-
}
32+
// Touch the backend to surface any parser initialization errors early.
33+
[[maybe_unused]] const auto parser_infos = get_available_parsers();
5634
return true;
5735
} catch (const std::exception& e) {
5836
wxMessageBox(e.what(), _("Error"), wxICON_ERROR);
5937
return false;
6038
}
6139
}
6240

63-
const parser_info* find_parser_by_extension(const wxString& extension) {
41+
bool is_parser_supported(const wxString& extension) {
6442
if (extension.IsEmpty()) {
65-
return nullptr;
43+
return false;
6644
}
6745
const wxString normalized = extension.Lower();
68-
const auto& parsers = get_parser_infos();
69-
const auto parser_it = std::find_if(parsers.begin(), parsers.end(), [&](const parser_info& parser) {
70-
return std::any_of(parser.extensions.begin(), parser.extensions.end(), [&](const wxString& ext) {
71-
return ext.Lower() == normalized;
72-
});
73-
});
74-
return parser_it != parsers.end() ? &(*parser_it) : nullptr;
46+
const std::string ext_utf8 = std::string(normalized.ToUTF8());
47+
return parser_supports_extension(ext_utf8);
7548
}
7649

7750
wxString get_supported_wildcards() {

app/parser.hpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,8 @@ inline constexpr bool parser_supports(parser_flags flags, parser_flags flag) noe
7878
return (flags & flag) == flag;
7979
}
8080

81-
struct parser_info {
82-
wxString name;
83-
std::vector<wxString> extensions;
84-
parser_flags flags{parser_flags::none};
85-
};
86-
8781
bool initialize_parser_registry();
88-
[[nodiscard]] const parser_info* find_parser_by_extension(const wxString& extension);
82+
[[nodiscard]] bool is_parser_supported(const wxString& extension);
8983
[[nodiscard]] wxString get_supported_wildcards();
9084
// Legacy function - commented out, use session_new() instead
9185
// [[nodiscard]] std::unique_ptr<document> load_document_from_rust(const wxString& path, const std::optional<std::string>& password = std::nullopt, const wxString& forced_extension = wxEmptyString);

app/utils.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,18 @@ long find_text(const wxString& haystack, const wxString& needle, long start, fin
3232
return result < 0 ? wxNOT_FOUND : static_cast<long>(result);
3333
}
3434

35-
const parser_info* get_parser_for_unknown_file(const wxString& path, config_manager& config) {
35+
bool ensure_parser_for_unknown_file(const wxString& path, config_manager& config) {
3636
const wxString saved_format = config.get_document_format(path);
37-
if (!saved_format.IsEmpty()) {
38-
const auto* par = find_parser_by_extension(saved_format);
39-
if (par != nullptr) return par;
40-
}
37+
if (!saved_format.IsEmpty() && is_parser_supported(saved_format)) return true;
4138
open_as_dialog dlg(nullptr, path);
42-
if (dlg.ShowModal() != wxID_OK) return nullptr;
39+
if (dlg.ShowModal() != wxID_OK) return false;
4340
const wxString format = dlg.get_selected_format();
41+
if (!is_parser_supported(format)) {
42+
wxMessageBox(_("Unsupported format selected."), _("Error"), wxICON_ERROR);
43+
return false;
44+
}
4445
config.set_document_format(path, format);
45-
return find_parser_by_extension(format);
46+
return true;
4647
}
4748

4849
void speak(const wxString& message) {

app/utils.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ inline constexpr bool has_option(find_options options, find_options flag) noexce
4040
}
4141

4242
[[nodiscard]] long find_text(const wxString& haystack, const wxString& needle, long start, find_options options = find_options::forward);
43-
[[nodiscard]] const parser_info* get_parser_for_unknown_file(const wxString& path, config_manager& config);
43+
[[nodiscard]] bool ensure_parser_for_unknown_file(const wxString& path, config_manager& config);
4444
void speak(const wxString& message);
4545

4646
// FFI helper functions

lib/src/bridge.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ pub mod ffi {
357357
fn find_zip_entry(zip_path: &str, entry_name: &str) -> Result<usize>;
358358
fn get_available_parsers() -> Vec<ParserInfo>;
359359
fn parser_supported_wildcards() -> String;
360+
fn parser_supports_extension(extension: &str) -> bool;
360361
fn parse_document(file_path: &str, password: &str) -> Result<FfiDocument>;
361362
fn get_parser_for_extension(extension: &str) -> Result<String>;
362363
fn convert_xml_to_text(content: &str) -> Result<FfiXmlConversion>;
@@ -743,6 +744,10 @@ fn parser_supported_wildcards() -> String {
743744
parser::build_file_filter_string()
744745
}
745746

747+
fn parser_supports_extension(extension: &str) -> bool {
748+
parser::parser_supports_extension(extension)
749+
}
750+
746751
fn parse_document(file_path: &str, password: &str) -> Result<ffi::FfiDocument, String> {
747752
let mut context = ParserContext::new(file_path.to_string());
748753
if !password.is_empty() {

lib/src/parser.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,18 @@ pub fn get_parser_flags_for_context(context: &ParserContext) -> ParserFlags {
148148
ParserRegistry::global().get_parser_for_extension(extension).map_or(ParserFlags::NONE, Parser::supported_flags)
149149
}
150150

151+
#[must_use]
152+
pub fn parser_supports_extension(extension: &str) -> bool {
153+
if extension.is_empty() {
154+
return false;
155+
}
156+
let normalized = extension.trim_start_matches('.').to_ascii_lowercase();
157+
if normalized.is_empty() {
158+
return false;
159+
}
160+
ParserRegistry::global().get_parser_for_extension(&normalized).is_some()
161+
}
162+
151163
fn join_extensions<'a, I>(exts: I) -> String
152164
where
153165
I: IntoIterator<Item = &'a str>,

0 commit comments

Comments
 (0)