blob: 53ca07963fe65947f1aa4e7d9159d268ccac20e8 [file] [log] [blame]
// 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