| // Copyright 2019 Google Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| #include <pybind11/pybind11.h> |
| |
| #include "absl/memory/memory.h" |
| #include "tink/util/status.h" |
| #include "tink/cc/pybind/status_casters.h" |
| #include "pybind11/detail/common.h" |
| |
| namespace pybind11 { |
| namespace test { |
| |
| namespace util = crypto::tink::util; |
| |
| struct IntValue { |
| IntValue() = default; |
| IntValue(int value_in) : value(value_in) {} |
| int value; |
| }; |
| |
| class TestClass { |
| public: |
| util::Status MakeStatus(util::error::Code code, |
| const std::string& text = "") { |
| return util::Status(code, text); |
| } |
| |
| util::Status MakeStatusConst(util::error::Code code, |
| const std::string& text = "") const { |
| return util::Status(code, text); |
| } |
| |
| util::StatusOr<int> MakeFailureStatusOr(util::error::Code code, |
| const std::string& text = "") { |
| return util::Status(code, text); |
| } |
| }; |
| |
| bool CheckStatus(const util::Status& status, util::error::Code code) { |
| return status.error_code() == code; |
| } |
| |
| util::Status ReturnStatus(util::error::Code code, |
| const std::string& text = "") { |
| return util::Status(code, text); |
| } |
| |
| pybind11::object ReturnStatusManualCast(util::error::Code code, |
| const std::string& text = "") { |
| return pybind11::cast(google::DoNotThrowStatus(util::Status(code, text))); |
| } |
| |
| const util::Status& ReturnStatusRef(util::error::Code code, |
| const std::string& text = "") { |
| static util::Status static_status; |
| static_status = util::Status(code, text); |
| return static_status; |
| } |
| |
| const util::Status* ReturnStatusPtr(util::error::Code code, |
| const std::string& text = "") { |
| static util::Status static_status; |
| static_status = util::Status(code, text); |
| return &static_status; |
| } |
| |
| util::StatusOr<int> ReturnFailureStatusOr(util::error::Code code, |
| const std::string& text = "") { |
| return util::Status(code, text); |
| } |
| |
| pybind11::object ReturnFailureStatusOrManualCast(util::error::Code code, |
| const std::string& text = "") { |
| return pybind11::cast(google::DoNotThrowStatus(util::Status(code, text))); |
| } |
| |
| util::StatusOr<int> ReturnValueStatusOr(int value) { return value; } |
| |
| util::StatusOr<const IntValue*> ReturnPtrStatusOr(int value) { |
| static IntValue static_object; |
| static_object.value = value; |
| return &static_object; |
| } |
| |
| util::StatusOr<std::unique_ptr<IntValue>> ReturnUniquePtrStatusOr(int value) { |
| return absl::make_unique<IntValue>(value); |
| } |
| |
| util::StatusOr<std::string> ReturnAlphaBetaGammaEncoded() { |
| return std::string("EDD4f89 alpha=\xce\xb1 beta=\xce\xb2 gamma=\xce\xb3"); |
| } |
| |
| void PybindRegisterStatusInjector(pybind11::module* module) { |
| namespace py = pybind11; |
| py::module& m = *module; |
| |
| class_<IntValue>(m, "IntValue").def_readonly("value", &IntValue::value); |
| |
| class_<TestClass>(m, "TestClass") |
| .def(init()) |
| .def("make_status", google::DoNotThrowStatus(&TestClass::MakeStatus), |
| arg("code"), arg("text") = "") |
| .def("make_status_const", |
| google::DoNotThrowStatus(&TestClass::MakeStatusConst), arg("code"), |
| arg("text") = "") |
| .def("make_failure_status_or", |
| google::DoNotThrowStatus(&TestClass::MakeFailureStatusOr), |
| arg("code"), arg("text") = ""); |
| |
| // util::Status bindings |
| m.def("check_status", &CheckStatus, arg("status"), arg("code")); |
| m.def("return_status", &ReturnStatus, "Raise an error if code is not OK.", |
| arg("code"), arg("text") = ""); |
| m.def("make_status", google::DoNotThrowStatus(&ReturnStatus), |
| "Return a status without raising an error, regardless of what it is.", |
| arg("code"), arg("text") = ""); |
| m.def("make_status_manual_cast", ReturnStatusManualCast, |
| "Return a status without raising an error, regardless of what it is.", |
| arg("code"), arg("text") = ""); |
| m.def("make_status_ref", google::DoNotThrowStatus(&ReturnStatusRef), |
| "Return a reference to a static status value without raising an error.", |
| arg("code"), arg("text") = "", return_value_policy::reference); |
| m.def("make_status_ptr", google::DoNotThrowStatus(&ReturnStatusPtr), |
| "Return a reference to a static status value without raising an error.", |
| arg("code"), arg("text") = "", return_value_policy::reference); |
| |
| // util::StatusOr bindings |
| m.def("return_value_status_or", &ReturnValueStatusOr, arg("value")); |
| m.def("return_failure_status_or", &ReturnFailureStatusOr, |
| "Raise an error with the given code.", arg("code"), arg("text") = ""); |
| m.def("make_failure_status_or", |
| google::DoNotThrowStatus(&ReturnFailureStatusOr), arg("code"), |
| arg("text") = "", "Return a status without raising an error."); |
| m.def("make_failure_status_or_manual_cast", &ReturnFailureStatusOrManualCast, |
| arg("code"), arg("text") = "", "Return a status."); |
| m.def("return_ptr_status_or", &ReturnPtrStatusOr, arg("value"), |
| "Return a reference in a status or to a static value.", |
| return_value_policy::reference); |
| m.def("return_unique_ptr_status_or", &ReturnUniquePtrStatusOr, arg("value")); |
| m.def("return_alpha_beta_gamma_decoded", &ReturnAlphaBetaGammaEncoded); |
| m.def("return_alpha_beta_gamma_encoded", |
| []() -> util::StatusOr<bytes> { |
| return ReturnAlphaBetaGammaEncoded(); |
| }); |
| } |
| |
| } // namespace test |
| } // namespace pybind11 |