diff --git a/src/python/pybind11_key.cpp b/src/python/pybind11_key.cpp index c8db562..1437c7b 100644 --- a/src/python/pybind11_key.cpp +++ b/src/python/pybind11_key.cpp @@ -72,6 +72,63 @@ py::list python_card_parse_whole(dro::Card &self, py::list value_widths) { return rv; } +#ifdef __APPLE__ +#define RDRT(val) read_return(std::move(val)) +template inline py::object read_return(T arr) noexcept { + return py::cast(std::move(arr)); +} + +py::object +#else +#define RDRT(val) (val) + +std::variant +#endif +python_card_parse(dro::Card &self, bool trim_string, py::object value_width) { + if (value_width.is_none()) { + if (self.is_empty()) { + return py::none(); + } + + const auto ty = self.parse_get_type(); + + switch (ty) { + case CARD_PARSE_INT: + return RDRT(self.parse()); + case CARD_PARSE_FLOAT: + return RDRT(self.parse()); + case CARD_PARSE_STRING: + if (trim_string) { + return RDRT(self.parse()); + } else { + return RDRT(self.parse_string_no_trim()); + } + } + } else { + const auto vw = value_width.cast(); + if (self.is_empty(vw)) { + return py::none(); + } + + const auto ty = self.parse_get_type(vw); + + switch (ty) { + case CARD_PARSE_INT: + return RDRT(self.parse(vw)); + case CARD_PARSE_FLOAT: + return RDRT(self.parse(vw)); + case CARD_PARSE_STRING: + if (trim_string) { + return RDRT(self.parse(vw)); + } else { + return RDRT(self.parse_string_no_trim(vw)); + } + } + } + + return py::none(); +} + void add_key_library_to_module(py::module_ &m) { py::class_(m, "Keywords") .def("__len__", [](dro::Keywords &self) { return self.size(); }) @@ -98,12 +155,21 @@ void add_key_library_to_module(py::module_ &m) { .def("begin", &dro::Card::begin, "Initialises the parsing of the card", py::arg("value_width") = DEFAULT_VALUE_WIDTH) .def( - "next", [](dro::Card &self) { self.next(); }, - "Advance to the next value. Uses the value width from begin") + "next", + [](dro::Card &self, py::object value_width) { + if (value_width.is_none()) { + self.next(); + } else { + self.next(value_width.cast()); + } + }, + "Advance to the next value. Uses the value width from begin", + py::arg("value_width") = py::none()) .def( "next_width", [](dro::Card &self, uint8_t value_width) { self.next(value_width); }, - "Advance to the next value. Uses the value width provided here", + "DEPRECATED(use Card.next) Advance to the next value. Uses the value " + "width provided here", py::arg("value_width")) .def("done", &dro::Card::done, "Returns wether the card has been completely parsed. Breaks if " @@ -123,39 +189,64 @@ void add_key_library_to_module(py::module_ &m) { py::arg("value_width") = py::none()) .def( "parse_i64", - [](const dro::Card &self) { return self.parse(); }, - "Parses the current value as an integer. Uses the value " - "width from begin") + [](const dro::Card &self, py::object value_width) { + if (value_width.is_none()) { + return self.parse(); + } else { + return self.parse(value_width.cast()); + } + }, + "Parses the current value as an integer", + py::arg("value_width") = py::none()) .def( "parse_f64", - [](const dro::Card &self) { return self.parse(); }, - "Parses the current value as a float. Uses the value " - "width from begin") + [](const dro::Card &self, py::object value_width) { + if (value_width.is_none()) { + return self.parse(); + } else { + return self.parse(value_width.cast()); + } + }, + "Parses the current value as a float", + py::arg("value_width") = py::none()) .def( "parse_str", - [](const dro::Card &self, bool trim) { - if (trim) - return self.parse(); - else - return self.parse_string_no_trim(); + [](const dro::Card &self, bool trim, py::object value_width) { + if (value_width.is_none()) { + if (trim) { + return self.parse(); + } else { + return self.parse_string_no_trim(); + } + } else { + if (trim) { + return self.parse(value_width.cast()); + } else { + return self.parse_string_no_trim( + value_width.cast()); + } + } }, - "Parses the current value as a string. Uses the value " - "width from begin. If trim is set to True then it trims leading and " + "Parses the current value as a string. If trim is set to True then " + "it trims leading and " "trailing whitespace", - py::arg("trim") = true, py::return_value_policy::take_ownership) + py::arg("trim") = true, py::arg("value_width") = py::none(), + py::return_value_policy::take_ownership) .def( "parse_width_i64", [](const dro::Card &self, uint8_t value_width) { return self.parse(value_width); }, - "Parses the current value as an integer. Uses the value " + "DEPRECATED(use Card.parse_i64) Parses the current value as an " + "integer. Uses the value " "width provided here") .def( "parse_width_f64", [](const dro::Card &self, uint8_t value_width) { return self.parse(value_width); }, - "Parses the current value as a float. Uses the value " + "DEPRECATED(use Card.parse_f64) Parses the current value as a float. " + "Uses the value " "width provided here") .def( "parse_width_str", @@ -165,12 +256,18 @@ void add_key_library_to_module(py::module_ &m) { else return self.parse_string_no_trim(value_width); }, - "Parses the current value as a string. Uses the value " + "DEPRECATED(use Card.parse_str) Parses the current value as a " + "string. Uses the value " "width provided here. If trim is set to True then it trims leading " "and " "trailing whitespace", py::arg("value_width"), py::arg("trim") = true, py::return_value_policy::take_ownership) + .def("parse", &python_card_parse, + "Parses the current value as the recognized type (if it looks like " + "an int its an int and so on). If the value is empty then None is " + "returned", + py::arg("trim_string") = true, py::arg("value_width") = py::none()) .def("parse_whole", &python_card_parse_whole, "Parses all values of the card as the correct types. The width of " "each value needs to be provided as a list through value_widths",