#pragma once #include #include #include #include #include #include #include "detail/BufferError.hpp" namespace ovdl::detail { template struct ParseHandler { std::string make_error_from(buffer_error error) { switch (error) { using enum ovdl::detail::buffer_error; case buffer_is_null: return "Buffer could not be loaded."; case os_error: return "OS file error."; case file_not_found: return "File not found."; case permission_denied: return "Read Permission denied."; default: return ""; } } template constexpr void _run_load_func(detail::LoadCallback auto func, Args... args); }; template struct BasicFileParseHandler : ParseHandler> { using parse_state_type = ParseState; using encoding_type = typename parse_state_type::file_type::encoding_type; constexpr bool is_valid() const { if (!_parse_state) return false; return buffer().data() != nullptr; } constexpr buffer_error load_buffer_size(const char* data, std::size_t size) { lexy::buffer buffer(data, size); if (buffer.data() == nullptr) return buffer_error::buffer_is_null; _parse_state.reset(new parse_state_type { std::move(buffer) }); return is_valid() ? buffer_error::success : buffer_error::buffer_is_null; } constexpr buffer_error load_buffer(const char* start, const char* end) { lexy::buffer buffer(start, end); if (buffer.data() == nullptr) return buffer_error::buffer_is_null; _parse_state.reset(new parse_state_type { std::move(buffer) }); return is_valid() ? buffer_error::success : buffer_error::buffer_is_null; } buffer_error load_file(const char* path) { lexy::read_file_result file = lexy::read_file(path); if (!file) { _parse_state.reset(new parse_state_type { path, lexy::buffer() }); return ovdl::detail::from_underlying(ovdl::detail::to_underlying(file.error())); } _parse_state.reset(new parse_state_type { path, std::move(file).buffer() }); return is_valid() ? buffer_error::success : buffer_error::buffer_is_null; } const char* path() const { if (!_parse_state) return ""; return _parse_state->file().path(); } parse_state_type& parse_state() { return *_parse_state; } const parse_state_type& parse_state() const { return *_parse_state; } constexpr const auto& buffer() const { return _parse_state->file().buffer(); } protected: std::unique_ptr _parse_state; }; template struct BasicStateParseHandler : ParseHandler> { using parse_state_type = ParseState; using encoding_type = typename parse_state_type::ast_type::file_type::encoding_type; constexpr bool is_valid() const { if (!_parse_state) return false; return buffer().data() != nullptr; } constexpr buffer_error load_buffer_size(const char* data, std::size_t size) { lexy::buffer buffer(data, size); _parse_state.reset(new parse_state_type { std::move(buffer) }); return is_valid() ? buffer_error::success : buffer_error::buffer_is_null; } constexpr buffer_error load_buffer(const char* start, const char* end) { lexy::buffer buffer(start, end); _parse_state.reset(new parse_state_type { std::move(buffer) }); return is_valid() ? buffer_error::success : buffer_error::buffer_is_null; } buffer_error load_file(const char* path) { lexy::read_file_result file = lexy::read_file(path); if (!file) { _parse_state.reset(new parse_state_type { path, lexy::buffer() }); return ovdl::detail::from_underlying(ovdl::detail::to_underlying(file.error())); } _parse_state.reset(new parse_state_type { path, std::move(file).buffer() }); return is_valid() ? buffer_error::success : buffer_error::buffer_is_null; } const char* path() const { if (!_parse_state) return ""; return _parse_state->ast().file().path(); } parse_state_type& parse_state() { return *_parse_state; } const parse_state_type& parse_state() const { return *_parse_state; } constexpr const auto& buffer() const { return _parse_state->ast().file().buffer(); } protected: std::unique_ptr _parse_state; }; }