1use super::LibraryError;
5use crate::std_types::{RBoxError, Tuple2, Tuple3};
6
7mod types;
9
10mod functions;
11
12#[macro_use]
13mod c_abi_testing_macros;
14
15use self::types::MyUnit;
16
17pub use self::functions::{CAbiTestingFns, C_ABI_TESTING_FNS};
18
19pub fn run_tests(funcs: &CAbiTestingFns) -> Result<(), LibraryError> {
22 pair_tests(funcs)?;
23 triple_tests(funcs)?;
24 two_pair_tests(funcs)?;
25 mixed_units_test(funcs)?;
26 Ok(())
27}
28
29fn make_invalid_cabi_err<T>(expected: T, found: T) -> LibraryError
30where
31 T: std::fmt::Debug,
32{
33 LibraryError::InvalidCAbi {
34 expected: RBoxError::from_debug(&expected),
35 found: RBoxError::from_debug(&found),
36 }
37}
38
39fn pair_tests(funcs: &CAbiTestingFns) -> Result<(), LibraryError> {
40 check_roundtrip!(funcs, 0x1, (a = Tuple2(1, ())), ret_pair_a, take_pair_a);
41 check_roundtrip!(funcs, 0x5, (a = Tuple2(5, ())), ret_pair_a, take_pair_a);
42
43 check_roundtrip!(
44 funcs,
45 0x1_0000,
46 (a = Tuple2((), 1)),
47 ret_pair_b,
48 take_pair_b
49 );
50 check_roundtrip!(
51 funcs,
52 0x5_0000,
53 (a = Tuple2((), 5)),
54 ret_pair_b,
55 take_pair_b
56 );
57 Ok(())
58}
59
60fn triple_tests(funcs: &CAbiTestingFns) -> Result<(), LibraryError> {
61 check_roundtrip!(
62 funcs,
63 0x1_0001_0000,
64 (a = Tuple3((), 1, 1)),
65 ret_triple_a,
66 take_triple_a
67 );
68 check_roundtrip!(
69 funcs,
70 0x1_0005_0000,
71 (a = Tuple3((), 5, 1)),
72 ret_triple_a,
73 take_triple_a
74 );
75 check_roundtrip!(
76 funcs,
77 0x7_0001_0000,
78 (a = Tuple3((), 1, 7)),
79 ret_triple_a,
80 take_triple_a
81 );
82 check_roundtrip!(
83 funcs,
84 0x7_0003_0000,
85 (a = Tuple3((), 3, 7)),
86 ret_triple_a,
87 take_triple_a
88 );
89
90 check_roundtrip!(
91 funcs,
92 0x1_0000_0001,
93 (a = Tuple3(1, (), 1)),
94 ret_triple_b,
95 take_triple_b
96 );
97 check_roundtrip!(
98 funcs,
99 0x1_0000_0005,
100 (a = Tuple3(5, (), 1)),
101 ret_triple_b,
102 take_triple_b
103 );
104 check_roundtrip!(
105 funcs,
106 0x7_0000_0001,
107 (a = Tuple3(1, (), 7)),
108 ret_triple_b,
109 take_triple_b
110 );
111 check_roundtrip!(
112 funcs,
113 0x7_0000_0003,
114 (a = Tuple3(3, (), 7)),
115 ret_triple_b,
116 take_triple_b
117 );
118
119 check_roundtrip!(
120 funcs,
121 0x1_0001,
122 (a = Tuple3(1, 1, ())),
123 ret_triple_c,
124 take_triple_c
125 );
126 check_roundtrip!(
127 funcs,
128 0x1_0005,
129 (a = Tuple3(5, 1, ())),
130 ret_triple_c,
131 take_triple_c
132 );
133 check_roundtrip!(
134 funcs,
135 0x7_0001,
136 (a = Tuple3(1, 7, ())),
137 ret_triple_c,
138 take_triple_c
139 );
140 check_roundtrip!(
141 funcs,
142 0x7_0003,
143 (a = Tuple3(3, 7, ())),
144 ret_triple_c,
145 take_triple_c
146 );
147 Ok(())
148}
149
150fn two_pair_tests(funcs: &CAbiTestingFns) -> Result<(), LibraryError> {
151 let funcs = anon_struct! {
152 ret_2_pairs_a:|n|(funcs.ret_2_pairs_a)(n).into_tuple(),
153 ret_2_pairs_b:|n|(funcs.ret_2_pairs_b)(n).into_tuple(),
154 take_2_pairs_a:funcs.take_2_pairs_a,
155 take_2_pairs_b:funcs.take_2_pairs_b,
156 };
157
158 check_roundtrip!(
159 funcs,
160 0x1_0000_0005_0000,
161 (a = Tuple2((), 5), b = Tuple2((), 1)),
162 ret_2_pairs_a,
163 take_2_pairs_a,
164 );
165 check_roundtrip!(
166 funcs,
167 0xF_0000_000A_0000,
168 (a = Tuple2((), 10), b = Tuple2((), 15)),
169 ret_2_pairs_a,
170 take_2_pairs_a,
171 );
172
173 check_roundtrip!(
174 funcs,
175 0x0_0007_0000_0003,
176 (a = Tuple2(3, ()), b = Tuple2(7, ())),
177 ret_2_pairs_b,
178 take_2_pairs_b,
179 );
180 check_roundtrip!(
181 funcs,
182 0x0_0002_0000_000B,
183 (a = Tuple2(11, ()), b = Tuple2(2, ())),
184 ret_2_pairs_b,
185 take_2_pairs_b,
186 );
187 Ok(())
188}
189
190fn mixed_units_test(funcs: &CAbiTestingFns) -> Result<(), LibraryError> {
191 let single_test = |n: u64| {
192 let a = n as u16;
193 let b = (n >> 16) as u16;
194 let c = (n >> 32) as u16;
195 let d = (n >> 48) as u16;
196
197 let res = (funcs.mixed_units)(a, MyUnit, b, MyUnit, c, MyUnit, d);
198 if res != n {
199 Err(make_invalid_cabi_err(n, res))
200 } else {
201 Ok(())
202 }
203 };
204
205 single_test(0x0)?;
206 single_test(0x1)?;
207 single_test(0x2_0003)?;
208 single_test(0x4_0005_0006)?;
209 single_test(0x7_0008_0009_000A)?;
210 Ok(())
211}