use crate::std_types::{RBoxError,Tuple2,Tuple3};
use super::LibraryError;
mod types;
mod functions;
#[macro_use]
mod c_abi_testing_macros;
use self::types::{MyUnit};
pub use self::functions::{C_ABI_TESTING_FNS,CAbiTestingFns};
pub fn run_tests(funcs:&CAbiTestingFns)->Result<(),LibraryError>{
pair_tests(&funcs)?;
triple_tests(&funcs)?;
two_pair_tests(&funcs)?;
mixed_units_test(&funcs)?;
Ok(())
}
fn make_invalid_cabi_err<T>(expected:T,found:T)->LibraryError
where
T:std::fmt::Debug
{
LibraryError::InvalidCAbi{
expected:RBoxError::from_debug(&expected),
found :RBoxError::from_debug(&found ),
}
}
fn pair_tests(funcs:&CAbiTestingFns)->Result<(),LibraryError>{
check_roundtrip!(funcs,0x1,( a=Tuple2(1,()) ),ret_pair_a,take_pair_a);
check_roundtrip!(funcs,0x5,( a=Tuple2(5,()) ),ret_pair_a,take_pair_a);
check_roundtrip!(funcs,0x1_0000,( a=Tuple2((),1) ),ret_pair_b,take_pair_b);
check_roundtrip!(funcs,0x5_0000,( a=Tuple2((),5) ),ret_pair_b,take_pair_b);
Ok(())
}
fn triple_tests(funcs:&CAbiTestingFns)->Result<(),LibraryError>{
check_roundtrip!(funcs,0x1_0001_0000,( a=Tuple3((),1,1) ),ret_triple_a,take_triple_a);
check_roundtrip!(funcs,0x1_0005_0000,( a=Tuple3((),5,1) ),ret_triple_a,take_triple_a);
check_roundtrip!(funcs,0x7_0001_0000,( a=Tuple3((),1,7) ),ret_triple_a,take_triple_a);
check_roundtrip!(funcs,0x7_0003_0000,( a=Tuple3((),3,7) ),ret_triple_a,take_triple_a);
check_roundtrip!(funcs,0x1_0000_0001,( a=Tuple3(1,(),1) ),ret_triple_b,take_triple_b);
check_roundtrip!(funcs,0x1_0000_0005,( a=Tuple3(5,(),1) ),ret_triple_b,take_triple_b);
check_roundtrip!(funcs,0x7_0000_0001,( a=Tuple3(1,(),7) ),ret_triple_b,take_triple_b);
check_roundtrip!(funcs,0x7_0000_0003,( a=Tuple3(3,(),7) ),ret_triple_b,take_triple_b);
check_roundtrip!(funcs,0x1_0001,( a=Tuple3(1,1,()) ),ret_triple_c,take_triple_c);
check_roundtrip!(funcs,0x1_0005,( a=Tuple3(5,1,()) ),ret_triple_c,take_triple_c);
check_roundtrip!(funcs,0x7_0001,( a=Tuple3(1,7,()) ),ret_triple_c,take_triple_c);
check_roundtrip!(funcs,0x7_0003,( a=Tuple3(3,7,()) ),ret_triple_c,take_triple_c);
Ok(())
}
fn two_pair_tests(funcs:&CAbiTestingFns)->Result<(),LibraryError>{
let funcs=anon_struct!{
ret_2_pairs_a:|n|(funcs.ret_2_pairs_a)(n).into_tuple(),
ret_2_pairs_b:|n|(funcs.ret_2_pairs_b)(n).into_tuple(),
take_2_pairs_a:funcs.take_2_pairs_a,
take_2_pairs_b:funcs.take_2_pairs_b,
};
check_roundtrip!(
funcs,
0x1_0000_0005_0000,
( a=Tuple2((),5),b=Tuple2((),1) ),
ret_2_pairs_a,
take_2_pairs_a,
);
check_roundtrip!(
funcs,
0xF_0000_000A_0000,
( a=Tuple2((),10),b=Tuple2((),15) ),
ret_2_pairs_a,
take_2_pairs_a,
);
check_roundtrip!(
funcs,
0x0_0007_0000_0003,
( a=Tuple2(3,()),b=Tuple2(7,()) ),
ret_2_pairs_b,
take_2_pairs_b,
);
check_roundtrip!(
funcs,
0x0_0002_0000_000B,
( a=Tuple2(11,()),b=Tuple2(2,()) ),
ret_2_pairs_b,
take_2_pairs_b,
);
Ok(())
}
fn mixed_units_test(funcs:&CAbiTestingFns)->Result<(),LibraryError>{
let single_test=|n:u64|{
let a=n as u16;
let b=(n>>16) as u16;
let c=(n>>32) as u16;
let d=(n>>48) as u16;
let res=(funcs.mixed_units)(a,MyUnit,b,MyUnit,c,MyUnit,d);
if res!=n {
Err(make_invalid_cabi_err(n,res))
}else{
Ok(())
}
};
single_test(0x0)?;
single_test(0x1)?;
single_test(0x2_0003)?;
single_test(0x4_0005_0006)?;
single_test(0x7_0008_0009_000A)?;
Ok(())
}