blob: 8893ee84a482719f2013c581a018e85291d26bd9 [file] [log] [blame]
David Tolnay97c72102020-01-25 16:49:00 -08001#include "tests/ffi/tests.h"
David Tolnay1a2683a2020-03-17 19:09:29 -07002#include "tests/ffi/lib.rs.h"
David Tolnayb6c5ea72020-03-16 13:36:28 -07003#include <cstring>
David Tolnayebef4a22020-03-17 15:33:47 -07004#include <stdexcept>
David Tolnay97c72102020-01-25 16:49:00 -08005
David Tolnay2fe58c62020-03-06 16:23:09 -08006extern "C" void cxx_test_suite_set_correct() noexcept;
7extern "C" tests::R *cxx_test_suite_get_box() noexcept;
8extern "C" bool cxx_test_suite_r_is_correct(const tests::R *) noexcept;
David Tolnay3fd7f562020-01-26 17:47:11 -08009
David Tolnay97c72102020-01-25 16:49:00 -080010namespace tests {
11
David Tolnayeb952ba2020-04-14 15:02:24 -070012const char *SLICE_DATA = "2020";
Adrian Taylorf5dd5522020-04-13 16:50:14 -070013
David Tolnayad5b8af2020-01-26 16:59:13 -080014C::C(size_t n) : n(n) {}
15
David Tolnay3fd7f562020-01-26 17:47:11 -080016size_t C::get() const { return this->n; }
17
Joel Galenson3d4f6122020-04-07 15:54:05 -070018size_t C::set(size_t n) {
19 this->n = n;
20 return this->n;
21}
22
David Tolnayb8715772020-01-28 00:54:05 -080023size_t c_return_primitive() { return 2020; }
David Tolnayad5b8af2020-01-26 16:59:13 -080024
David Tolnayb8715772020-01-28 00:54:05 -080025Shared c_return_shared() { return Shared{2020}; }
David Tolnayad5b8af2020-01-26 16:59:13 -080026
David Tolnaybe13d8a2020-03-06 15:45:39 -080027rust::Box<R> c_return_box() {
28 return rust::Box<R>::from_raw(cxx_test_suite_get_box());
29}
30
David Tolnayad5b8af2020-01-26 16:59:13 -080031std::unique_ptr<C> c_return_unique_ptr() {
32 return std::unique_ptr<C>(new C{2020});
33}
34
David Tolnayb8715772020-01-28 00:54:05 -080035const size_t &c_return_ref(const Shared &shared) { return shared.z; }
David Tolnayad5b8af2020-01-26 16:59:13 -080036
David Tolnay750755e2020-03-01 13:04:08 -080037rust::Str c_return_str(const Shared &shared) {
David Tolnayad5b8af2020-01-26 16:59:13 -080038 (void)shared;
39 return "2020";
40}
41
David Tolnayeb952ba2020-04-14 15:02:24 -070042rust::Slice<uint8_t> c_return_sliceu8(const Shared &shared) {
Adrian Taylorf5dd5522020-04-13 16:50:14 -070043 (void)shared;
David Tolnay633b1f52020-04-14 16:33:14 -070044 return rust::Slice<uint8_t>(reinterpret_cast<const uint8_t *>(SLICE_DATA), 5);
Adrian Taylorf5dd5522020-04-13 16:50:14 -070045}
46
David Tolnay750755e2020-03-01 13:04:08 -080047rust::String c_return_rust_string() { return "2020"; }
David Tolnayad5b8af2020-01-26 16:59:13 -080048
49std::unique_ptr<std::string> c_return_unique_ptr_string() {
50 return std::unique_ptr<std::string>(new std::string("2020"));
51}
52
David Tolnay3fd7f562020-01-26 17:47:11 -080053void c_take_primitive(size_t n) {
54 if (n == 2020) {
55 cxx_test_suite_set_correct();
56 }
57}
David Tolnayad5b8af2020-01-26 16:59:13 -080058
David Tolnay3fd7f562020-01-26 17:47:11 -080059void c_take_shared(Shared shared) {
60 if (shared.z == 2020) {
61 cxx_test_suite_set_correct();
62 }
63}
David Tolnayad5b8af2020-01-26 16:59:13 -080064
David Tolnay750755e2020-03-01 13:04:08 -080065void c_take_box(rust::Box<R> r) {
David Tolnaya7d00e82020-03-06 15:50:14 -080066 if (cxx_test_suite_r_is_correct(&*r)) {
67 cxx_test_suite_set_correct();
68 }
David Tolnay3fd7f562020-01-26 17:47:11 -080069}
David Tolnayad5b8af2020-01-26 16:59:13 -080070
David Tolnay3fd7f562020-01-26 17:47:11 -080071void c_take_unique_ptr(std::unique_ptr<C> c) {
72 if (c->get() == 2020) {
73 cxx_test_suite_set_correct();
74 }
75}
David Tolnayad5b8af2020-01-26 16:59:13 -080076
David Tolnaya7d00e82020-03-06 15:50:14 -080077void c_take_ref_r(const R &r) {
78 if (cxx_test_suite_r_is_correct(&r)) {
79 cxx_test_suite_set_correct();
80 }
81}
David Tolnayad5b8af2020-01-26 16:59:13 -080082
David Tolnay3fd7f562020-01-26 17:47:11 -080083void c_take_ref_c(const C &c) {
84 if (c.get() == 2020) {
85 cxx_test_suite_set_correct();
86 }
87}
David Tolnayad5b8af2020-01-26 16:59:13 -080088
David Tolnay750755e2020-03-01 13:04:08 -080089void c_take_str(rust::Str s) {
David Tolnay3fd7f562020-01-26 17:47:11 -080090 if (std::string(s) == "2020") {
91 cxx_test_suite_set_correct();
92 }
93}
David Tolnayad5b8af2020-01-26 16:59:13 -080094
Adrian Taylorf5dd5522020-04-13 16:50:14 -070095void c_take_sliceu8(rust::Slice<uint8_t> s) {
David Tolnay633b1f52020-04-14 16:33:14 -070096 if (std::string(reinterpret_cast<const char *>(s.data()), s.size()) ==
97 "2020") {
Adrian Taylorf5dd5522020-04-13 16:50:14 -070098 cxx_test_suite_set_correct();
99 }
100}
101
David Tolnay750755e2020-03-01 13:04:08 -0800102void c_take_rust_string(rust::String s) {
David Tolnay3fd7f562020-01-26 17:47:11 -0800103 if (std::string(s) == "2020") {
104 cxx_test_suite_set_correct();
105 }
106}
David Tolnayad5b8af2020-01-26 16:59:13 -0800107
David Tolnay3fd7f562020-01-26 17:47:11 -0800108void c_take_unique_ptr_string(std::unique_ptr<std::string> s) {
109 if (*s == "2020") {
110 cxx_test_suite_set_correct();
111 }
112}
David Tolnayad5b8af2020-01-26 16:59:13 -0800113
David Tolnay75dca2e2020-03-25 20:17:52 -0700114void c_take_callback(rust::Fn<size_t(rust::String)> callback) {
115 callback("2020");
116}
117
David Tolnayebef4a22020-03-17 15:33:47 -0700118void c_try_return_void() {}
119
120size_t c_try_return_primitive() { return 2020; }
121
122size_t c_fail_return_primitive() { throw std::logic_error("logic error"); }
123
David Tolnay99642622020-03-25 13:07:35 -0700124rust::Box<R> c_try_return_box() { return c_return_box(); }
Myron Ahn84849302020-03-25 22:00:58 +0700125
David Tolnay99642622020-03-25 13:07:35 -0700126const rust::String &c_try_return_ref(const rust::String &s) { return s; }
127
128rust::Str c_try_return_str(rust::Str s) { return s; }
129
Adrian Taylorec9430e2020-04-14 16:09:58 -0700130rust::Slice<uint8_t> c_try_return_sliceu8(rust::Slice<uint8_t> s) { return s; }
Adrian Taylorf5dd5522020-04-13 16:50:14 -0700131
David Tolnay99642622020-03-25 13:07:35 -0700132rust::String c_try_return_rust_string() { return c_return_rust_string(); }
133
134std::unique_ptr<std::string> c_try_return_unique_ptr_string() {
135 return c_return_unique_ptr_string();
Myron Ahn84849302020-03-25 22:00:58 +0700136}
137
David Tolnay2fe58c62020-03-06 16:23:09 -0800138extern "C" C *cxx_test_suite_get_unique_ptr() noexcept {
David Tolnay4b3a66e2020-03-06 16:14:00 -0800139 return std::unique_ptr<C>(new C{2020}).release();
140}
141
David Tolnay85db24862020-03-06 16:24:41 -0800142extern "C" std::string *cxx_test_suite_get_unique_ptr_string() noexcept {
143 return std::unique_ptr<std::string>(new std::string("2020")).release();
144}
145
David Tolnayf306da42020-02-22 19:55:43 -0800146extern "C" const char *cxx_run_test() noexcept {
147#define STRINGIFY(x) #x
148#define TOSTRING(x) STRINGIFY(x)
149#define ASSERT(x) \
150 do { \
151 if (!(x)) { \
152 return "Assertion failed: `" #x "`, " __FILE__ ":" TOSTRING(__LINE__); \
153 } \
154 } while (false)
155
156 ASSERT(r_return_primitive() == 2020);
157 ASSERT(r_return_shared().z == 2020);
David Tolnay5cd8d612020-03-06 15:56:30 -0800158 ASSERT(cxx_test_suite_r_is_correct(&*r_return_box()));
David Tolnay4b3a66e2020-03-06 16:14:00 -0800159 ASSERT(r_return_unique_ptr()->get() == 2020);
David Tolnayf306da42020-02-22 19:55:43 -0800160 ASSERT(r_return_ref(Shared{2020}) == 2020);
161 ASSERT(std::string(r_return_str(Shared{2020})) == "2020");
162 ASSERT(std::string(r_return_rust_string()) == "2020");
David Tolnay85db24862020-03-06 16:24:41 -0800163 ASSERT(*r_return_unique_ptr_string() == "2020");
David Tolnayf306da42020-02-22 19:55:43 -0800164
165 r_take_primitive(2020);
166 r_take_shared(Shared{2020});
167 r_take_unique_ptr(std::unique_ptr<C>(new C{2020}));
168 r_take_ref_c(C{2020});
David Tolnay750755e2020-03-01 13:04:08 -0800169 r_take_str(rust::Str("2020"));
David Tolnay633b1f52020-04-14 16:33:14 -0700170 r_take_sliceu8(
171 rust::Slice<uint8_t>(reinterpret_cast<const uint8_t *>(SLICE_DATA), 5));
David Tolnay40226ab2020-03-03 00:05:35 -0800172 r_take_rust_string(rust::String("2020"));
David Tolnayf306da42020-02-22 19:55:43 -0800173 r_take_unique_ptr_string(
174 std::unique_ptr<std::string>(new std::string("2020")));
175
David Tolnayb6c5ea72020-03-16 13:36:28 -0700176 ASSERT(r_try_return_primitive() == 2020);
177 try {
178 r_fail_return_primitive();
179 ASSERT(false);
180 } catch (const rust::Error &e) {
181 ASSERT(std::strcmp(e.what(), "rust error") == 0);
182 }
183
Joel Galensonc1c4e7a2020-04-15 10:21:00 -0700184 auto r2 = r_return_r2(2020);
185 ASSERT(r2->get() == 2020);
186 ASSERT(r2->set(2021) == 2021);
187 ASSERT(r2->get() == 2021);
188 ASSERT(r2->set(2020) == 2020);
189 ASSERT(r2->get() == 2020);
190
David Tolnayf306da42020-02-22 19:55:43 -0800191 cxx_test_suite_set_correct();
192 return nullptr;
193}
194
David Tolnay97c72102020-01-25 16:49:00 -0800195} // namespace tests