1#![allow( 2 clippy::boxed_local, 3 clippy::derive_partial_eq_without_eq, 4 clippy::just_underscores_and_digits, 5 clippy::missing_safety_doc, 6 clippy::must_use_candidate, 7 clippy::needless_lifetimes, 8 clippy::needless_pass_by_value, 9 clippy::ptr_arg, 10 clippy::trivially_copy_pass_by_ref, 11 clippy::unnecessary_wraps, 12 clippy::unused_self 13)] 14 15pub mod cast; 16pub mod module; 17 18use cxx::{type_id, CxxString, CxxVector, ExternType, SharedPtr, UniquePtr}; 19use std::fmt::{self, Display}; 20use std::mem::MaybeUninit; 21use std::os::raw::c_char; 22 23#[cxx::bridge(namespace = "tests")] 24pub mod ffi { 25 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] 26 struct Shared { 27 z: usize, 28 } 29 30 #[derive(PartialEq, PartialOrd)] 31 struct SharedString { 32 msg: String, 33 } 34 35 #[derive(Debug, Hash, PartialOrd, Ord)] 36 enum Enum { 37 AVal, 38 BVal = 2020, 39 #[cxx_name = "CVal"] 40 LastVal, 41 } 42 43 #[namespace = "A"] 44 #[derive(Copy, Clone, Default)] 45 struct AShared { 46 #[cxx_name = "type"] 47 z: usize, 48 } 49 50 #[namespace = "A"] 51 enum AEnum { 52 AAVal, 53 ABVal = 2020, 54 ACVal, 55 } 56 57 #[namespace = "A::B"] 58 enum ABEnum { 59 ABAVal, 60 ABBVal = 2020, 61 ABCVal, 62 } 63 64 #[namespace = "A::B"] 65 #[derive(Clone)] 66 struct ABShared { 67 z: usize, 68 } 69 70 #[namespace = "first"] 71 struct First { 72 second: Box<Second>, 73 } 74 75 #[namespace = "second"] 76 #[derive(Hash)] 77 struct Second { 78 i: i32, 79 e: COwnedEnum, 80 } 81 82 pub struct Array { 83 a: [i32; 4], 84 b: Buffer, 85 } 86 87 #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] 88 pub struct StructWithLifetime<'a> { 89 s: &'a str, 90 } 91 92 unsafe extern "C++" { 93 include!("tests/ffi/tests.h"); 94 95 type C; 96 97 fn c_return_primitive() -> usize; 98 fn c_return_shared() -> Shared; 99 fn c_return_box() -> Box<R>; 100 fn c_return_unique_ptr() -> UniquePtr<C>; 101 fn c_return_shared_ptr() -> SharedPtr<C>; 102 fn c_return_ref(shared: &Shared) -> &usize; 103 fn c_return_mut(shared: &mut Shared) -> &mut usize; 104 fn c_return_str(shared: &Shared) -> &str; 105 fn c_return_slice_char(shared: &Shared) -> &[c_char]; 106 fn c_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8]; 107 fn c_return_rust_string() -> String; 108 fn c_return_rust_string_lossy() -> String; 109 fn c_return_unique_ptr_string() -> UniquePtr<CxxString>; 110 fn c_return_unique_ptr_vector_u8() -> UniquePtr<CxxVector<u8>>; 111 fn c_return_unique_ptr_vector_f64() -> UniquePtr<CxxVector<f64>>; 112 fn c_return_unique_ptr_vector_string() -> UniquePtr<CxxVector<CxxString>>; 113 fn c_return_unique_ptr_vector_shared() -> UniquePtr<CxxVector<Shared>>; 114 fn c_return_unique_ptr_vector_opaque() -> UniquePtr<CxxVector<C>>; 115 fn c_return_ref_vector(c: &C) -> &CxxVector<u8>; 116 fn c_return_mut_vector(c: Pin<&mut C>) -> Pin<&mut CxxVector<u8>>; 117 fn c_return_rust_vec_u8() -> Vec<u8>; 118 fn c_return_ref_rust_vec(c: &C) -> &Vec<u8>; 119 fn c_return_mut_rust_vec(c: Pin<&mut C>) -> &mut Vec<u8>; 120 fn c_return_rust_vec_string() -> Vec<String>; 121 fn c_return_rust_vec_bool() -> Vec<bool>; 122 fn c_return_identity(_: usize) -> usize; 123 fn c_return_sum(_: usize, _: usize) -> usize; 124 fn c_return_enum(n: u16) -> Enum; 125 fn c_return_ns_ref(shared: &AShared) -> &usize; 126 fn c_return_nested_ns_ref(shared: &ABShared) -> &usize; 127 fn c_return_ns_enum(n: u16) -> AEnum; 128 fn c_return_nested_ns_enum(n: u16) -> ABEnum; 129 fn c_return_const_ptr(n: usize) -> *const C; 130 fn c_return_mut_ptr(n: usize) -> *mut C; 131 132 fn c_take_primitive(n: usize); 133 fn c_take_shared(shared: Shared); 134 fn c_take_box(r: Box<R>); 135 fn c_take_ref_r(r: &R); 136 fn c_take_ref_c(c: &C); 137 fn c_take_str(s: &str); 138 fn c_take_slice_char(s: &[c_char]); 139 fn c_take_slice_shared(s: &[Shared]); 140 fn c_take_slice_shared_sort(s: &mut [Shared]); 141 fn c_take_slice_r(s: &[R]); 142 fn c_take_slice_r_sort(s: &mut [R]); 143 fn c_take_rust_string(s: String); 144 fn c_take_unique_ptr_string(s: UniquePtr<CxxString>); 145 fn c_take_unique_ptr_vector_u8(v: UniquePtr<CxxVector<u8>>); 146 fn c_take_unique_ptr_vector_f64(v: UniquePtr<CxxVector<f64>>); 147 fn c_take_unique_ptr_vector_string(v: UniquePtr<CxxVector<CxxString>>); 148 fn c_take_unique_ptr_vector_shared(v: UniquePtr<CxxVector<Shared>>); 149 fn c_take_ref_vector(v: &CxxVector<u8>); 150 fn c_take_rust_vec(v: Vec<u8>); 151 fn c_take_rust_vec_shared(v: Vec<Shared>); 152 fn c_take_rust_vec_string(v: Vec<String>); 153 fn c_take_rust_vec_index(v: Vec<u8>); 154 fn c_take_rust_vec_shared_index(v: Vec<Shared>); 155 fn c_take_rust_vec_shared_push(v: Vec<Shared>); 156 fn c_take_rust_vec_shared_truncate(v: Vec<Shared>); 157 fn c_take_rust_vec_shared_clear(v: Vec<Shared>); 158 fn c_take_rust_vec_shared_forward_iterator(v: Vec<Shared>); 159 fn c_take_rust_vec_shared_sort(v: Vec<Shared>); 160 fn c_take_ref_rust_vec(v: &Vec<u8>); 161 fn c_take_ref_rust_vec_string(v: &Vec<String>); 162 fn c_take_ref_rust_vec_index(v: &Vec<u8>); 163 fn c_take_ref_rust_vec_copy(v: &Vec<u8>); 164 fn c_take_ref_shared_string(s: &SharedString) -> &SharedString; 165 fn c_take_callback(callback: fn(String) -> usize); 166 fn c_take_callback_ref(callback: fn(&String)); 167 #[cxx_name = "c_take_callback_ref"] 168 fn c_take_callback_ref_lifetime<'a>(callback: fn(&'a String)); 169 fn c_take_callback_mut(callback: fn(&mut String)); 170 fn c_take_enum(e: Enum); 171 fn c_take_ns_enum(e: AEnum); 172 fn c_take_nested_ns_enum(e: ABEnum); 173 fn c_take_ns_shared(shared: AShared); 174 fn c_take_nested_ns_shared(shared: ABShared); 175 fn c_take_rust_vec_ns_shared(v: Vec<AShared>); 176 fn c_take_rust_vec_nested_ns_shared(v: Vec<ABShared>); 177 unsafe fn c_take_const_ptr(c: *const C) -> usize; 178 unsafe fn c_take_mut_ptr(c: *mut C) -> usize; 179 180 fn c_try_return_void() -> Result<()>; 181 fn c_try_return_primitive() -> Result<usize>; 182 fn c_fail_return_primitive() -> Result<usize>; 183 fn c_try_return_box() -> Result<Box<R>>; 184 fn c_try_return_ref(s: &String) -> Result<&String>; 185 fn c_try_return_str(s: &str) -> Result<&str>; 186 fn c_try_return_sliceu8(s: &[u8]) -> Result<&[u8]>; 187 fn c_try_return_mutsliceu8(s: &mut [u8]) -> Result<&mut [u8]>; 188 fn c_try_return_rust_string() -> Result<String>; 189 fn c_try_return_unique_ptr_string() -> Result<UniquePtr<CxxString>>; 190 fn c_try_return_rust_vec() -> Result<Vec<u8>>; 191 fn c_try_return_rust_vec_string() -> Result<Vec<String>>; 192 fn c_try_return_ref_rust_vec(c: &C) -> Result<&Vec<u8>>; 193 194 fn get(self: &C) -> usize; 195 fn set(self: Pin<&mut C>, n: usize) -> usize; 196 fn get2(&self) -> usize; 197 fn getRef(self: &C) -> &usize; 198 fn getMut(self: Pin<&mut C>) -> &mut usize; 199 fn set_succeed(self: Pin<&mut C>, n: usize) -> Result<usize>; 200 fn get_fail(self: Pin<&mut C>) -> Result<usize>; 201 fn c_method_on_shared(self: &Shared) -> usize; 202 fn c_method_ref_on_shared(self: &Shared) -> &usize; 203 fn c_method_mut_on_shared(self: &mut Shared) -> &mut usize; 204 fn c_set_array(self: &mut Array, value: i32); 205 206 fn c_get_use_count(weak: &WeakPtr<C>) -> usize; 207 208 #[rust_name = "i32_overloaded_method"] 209 fn cOverloadedMethod(&self, x: i32) -> String; 210 #[rust_name = "str_overloaded_method"] 211 fn cOverloadedMethod(&self, x: &str) -> String; 212 #[rust_name = "i32_overloaded_function"] 213 fn cOverloadedFunction(x: i32) -> String; 214 #[rust_name = "str_overloaded_function"] 215 fn cOverloadedFunction(x: &str) -> String; 216 217 #[namespace = "other"] 218 fn ns_c_take_ns_shared(shared: AShared); 219 } 220 221 extern "C++" { 222 include!("tests/ffi/module.rs.h"); 223 224 type COwnedEnum; 225 type Job = crate::module::ffi::Job; 226 } 227 228 extern "Rust" { 229 #[derive(ExternType)] 230 type Reference<'a>; 231 } 232 233 unsafe extern "C++" { 234 type Borrow<'a>; 235 236 fn c_return_borrow<'a>(s: &'a CxxString) -> UniquePtr<Borrow<'a>>; 237 238 #[rust_name = "c_return_borrow_elided"] 239 fn c_return_borrow(s: &CxxString) -> UniquePtr<Borrow>; 240 241 fn const_member(self: &Borrow); 242 fn nonconst_member(self: Pin<&mut Borrow>); 243 } 244 245 #[repr(u32)] 246 #[derive(Hash)] 247 enum COwnedEnum { 248 #[cxx_name = "CVAL1"] 249 CVal1, 250 #[cxx_name = "CVAL2"] 251 CVal2, 252 } 253 254 extern "C++" { 255 type Buffer = crate::Buffer; 256 } 257 258 extern "Rust" { 259 type R; 260 261 fn r_return_primitive() -> usize; 262 fn r_return_shared() -> Shared; 263 fn r_return_box() -> Box<R>; 264 fn r_return_unique_ptr() -> UniquePtr<C>; 265 fn r_return_shared_ptr() -> SharedPtr<C>; 266 fn r_return_ref(shared: &Shared) -> &usize; 267 fn r_return_mut(shared: &mut Shared) -> &mut usize; 268 fn r_return_str(shared: &Shared) -> &str; 269 fn r_return_sliceu8(shared: &Shared) -> &[u8]; 270 fn r_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8]; 271 fn r_return_rust_string() -> String; 272 fn r_return_unique_ptr_string() -> UniquePtr<CxxString>; 273 fn r_return_rust_vec() -> Vec<u8>; 274 fn r_return_rust_vec_string() -> Vec<String>; 275 fn r_return_rust_vec_extern_struct() -> Vec<Job>; 276 fn r_return_ref_rust_vec(shared: &Shared) -> &Vec<u8>; 277 fn r_return_mut_rust_vec(shared: &mut Shared) -> &mut Vec<u8>; 278 fn r_return_identity(_: usize) -> usize; 279 fn r_return_sum(_: usize, _: usize) -> usize; 280 fn r_return_enum(n: u32) -> Enum; 281 282 fn r_take_primitive(n: usize); 283 fn r_take_shared(shared: Shared); 284 fn r_take_box(r: Box<R>); 285 fn r_take_unique_ptr(c: UniquePtr<C>); 286 fn r_take_shared_ptr(c: SharedPtr<C>); 287 fn r_take_ref_r(r: &R); 288 fn r_take_ref_c(c: &C); 289 fn r_take_str(s: &str); 290 fn r_take_slice_char(s: &[c_char]); 291 fn r_take_rust_string(s: String); 292 fn r_take_unique_ptr_string(s: UniquePtr<CxxString>); 293 fn r_take_ref_vector(v: &CxxVector<u8>); 294 fn r_take_ref_empty_vector(v: &CxxVector<u64>); 295 fn r_take_rust_vec(v: Vec<u8>); 296 fn r_take_rust_vec_string(v: Vec<String>); 297 fn r_take_ref_rust_vec(v: &Vec<u8>); 298 fn r_take_ref_rust_vec_string(v: &Vec<String>); 299 fn r_take_enum(e: Enum); 300 301 fn r_try_return_void() -> Result<()>; 302 fn r_try_return_primitive() -> Result<usize>; 303 fn r_try_return_box() -> Result<Box<R>>; 304 fn r_fail_return_primitive() -> Result<usize>; 305 fn r_try_return_sliceu8(s: &[u8]) -> Result<&[u8]>; 306 fn r_try_return_mutsliceu8(s: &mut [u8]) -> Result<&mut [u8]>; 307 308 fn get(self: &R) -> usize; 309 fn set(self: &mut R, n: usize) -> usize; 310 fn r_method_on_shared(self: &Shared) -> String; 311 fn r_get_array_sum(self: &Array) -> i32; 312 313 #[cxx_name = "rAliasedFunction"] 314 fn r_aliased_function(x: i32) -> String; 315 } 316 317 struct Dag0 { 318 i: i32, 319 } 320 321 struct Dag1 { 322 dag2: Dag2, 323 vec: Vec<Dag3>, 324 } 325 326 struct Dag2 { 327 dag4: Dag4, 328 } 329 330 struct Dag3 { 331 dag1: Dag1, 332 } 333 334 struct Dag4 { 335 dag0: Dag0, 336 } 337 338 impl Box<Shared> {} 339 impl CxxVector<SharedString> {} 340} 341 342mod other { 343 use cxx::kind::{Opaque, Trivial}; 344 use cxx::{type_id, CxxString, ExternType}; 345 346 #[repr(C)] 347 pub struct D { 348 pub d: u64, 349 } 350 351 #[repr(C)] 352 pub struct E { 353 e: u64, 354 e_str: CxxString, 355 } 356 357 pub mod f { 358 use cxx::kind::Opaque; 359 use cxx::{type_id, CxxString, ExternType}; 360 361 #[repr(C)] 362 pub struct F { 363 e: u64, 364 e_str: CxxString, 365 } 366 367 unsafe impl ExternType for F { 368 type Id = type_id!("F::F"); 369 type Kind = Opaque; 370 } 371 } 372 373 #[repr(C)] 374 pub struct G { 375 pub g: u64, 376 } 377 378 unsafe impl ExternType for G { 379 type Id = type_id!("G::G"); 380 type Kind = Trivial; 381 } 382 383 unsafe impl ExternType for D { 384 type Id = type_id!("tests::D"); 385 type Kind = Trivial; 386 } 387 388 unsafe impl ExternType for E { 389 type Id = type_id!("tests::E"); 390 type Kind = Opaque; 391 } 392} 393 394#[derive(PartialEq, Debug)] 395pub struct R(pub usize); 396 397impl R { 398 fn get(&self) -> usize { 399 self.0 400 } 401 402 fn set(&mut self, n: usize) -> usize { 403 self.0 = n; 404 n 405 } 406} 407 408pub struct Reference<'a>(&'a String); 409 410impl ffi::Shared { 411 fn r_method_on_shared(&self) -> String { 412 "2020".to_owned() 413 } 414} 415 416impl ffi::Array { 417 pub fn r_get_array_sum(&self) -> i32 { 418 self.a.iter().sum() 419 } 420} 421 422#[derive(Default)] 423#[repr(C)] 424pub struct Buffer([c_char; 12]); 425 426unsafe impl ExternType for Buffer { 427 type Id = type_id!("tests::Buffer"); 428 type Kind = cxx::kind::Trivial; 429} 430 431#[derive(Debug)] 432struct Error; 433 434impl std::error::Error for Error {} 435 436impl Display for Error { 437 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 438 f.write_str("rust error") 439 } 440} 441 442fn r_return_primitive() -> usize { 443 2020 444} 445 446fn r_return_shared() -> ffi::Shared { 447 ffi::Shared { z: 2020 } 448} 449 450fn r_return_box() -> Box<R> { 451 Box::new(R(2020)) 452} 453 454fn r_return_unique_ptr() -> UniquePtr<ffi::C> { 455 extern "C" { 456 fn cxx_test_suite_get_unique_ptr() -> *mut ffi::C; 457 } 458 unsafe { UniquePtr::from_raw(cxx_test_suite_get_unique_ptr()) } 459} 460 461fn r_return_shared_ptr() -> SharedPtr<ffi::C> { 462 extern "C" { 463 fn cxx_test_suite_get_shared_ptr(repr: *mut SharedPtr<ffi::C>); 464 } 465 let mut shared_ptr = MaybeUninit::<SharedPtr<ffi::C>>::uninit(); 466 let repr = shared_ptr.as_mut_ptr(); 467 unsafe { 468 cxx_test_suite_get_shared_ptr(repr); 469 shared_ptr.assume_init() 470 } 471} 472 473fn r_return_ref(shared: &ffi::Shared) -> &usize { 474 &shared.z 475} 476 477fn r_return_mut(shared: &mut ffi::Shared) -> &mut usize { 478 &mut shared.z 479} 480 481fn r_return_str(shared: &ffi::Shared) -> &str { 482 let _ = shared; 483 "2020" 484} 485 486fn r_return_sliceu8(shared: &ffi::Shared) -> &[u8] { 487 let _ = shared; 488 b"2020" 489} 490 491fn r_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8] { 492 slice 493} 494 495fn r_return_rust_string() -> String { 496 "2020".to_owned() 497} 498 499fn r_return_unique_ptr_string() -> UniquePtr<CxxString> { 500 extern "C" { 501 fn cxx_test_suite_get_unique_ptr_string() -> *mut CxxString; 502 } 503 unsafe { UniquePtr::from_raw(cxx_test_suite_get_unique_ptr_string()) } 504} 505 506fn r_return_rust_vec() -> Vec<u8> { 507 Vec::new() 508} 509 510fn r_return_rust_vec_string() -> Vec<String> { 511 Vec::new() 512} 513 514fn r_return_rust_vec_extern_struct() -> Vec<ffi::Job> { 515 Vec::new() 516} 517 518fn r_return_ref_rust_vec(shared: &ffi::Shared) -> &Vec<u8> { 519 let _ = shared; 520 unimplemented!() 521} 522 523fn r_return_mut_rust_vec(shared: &mut ffi::Shared) -> &mut Vec<u8> { 524 let _ = shared; 525 unimplemented!() 526} 527 528fn r_return_identity(n: usize) -> usize { 529 n 530} 531 532fn r_return_sum(n1: usize, n2: usize) -> usize { 533 n1 + n2 534} 535 536fn r_return_enum(n: u32) -> ffi::Enum { 537 if n == 0 { 538 ffi::Enum::AVal 539 } else if n <= 2020 { 540 ffi::Enum::BVal 541 } else { 542 ffi::Enum::LastVal 543 } 544} 545 546fn r_take_primitive(n: usize) { 547 assert_eq!(n, 2020); 548} 549 550fn r_take_shared(shared: ffi::Shared) { 551 assert_eq!(shared.z, 2020); 552} 553 554fn r_take_box(r: Box<R>) { 555 let _ = r; 556} 557 558fn r_take_unique_ptr(c: UniquePtr<ffi::C>) { 559 let _ = c; 560} 561 562fn r_take_shared_ptr(c: SharedPtr<ffi::C>) { 563 let _ = c; 564} 565 566fn r_take_ref_r(r: &R) { 567 let _ = r; 568} 569 570fn r_take_ref_c(c: &ffi::C) { 571 let _ = c; 572} 573 574fn r_take_str(s: &str) { 575 assert_eq!(s, "2020"); 576} 577 578fn r_take_rust_string(s: String) { 579 assert_eq!(s, "2020"); 580} 581 582fn r_take_slice_char(s: &[c_char]) { 583 assert_eq!(s.len(), 5); 584 let s = cast::c_char_to_unsigned(s); 585 assert_eq!(std::str::from_utf8(s).unwrap(), "2020\0"); 586} 587 588fn r_take_unique_ptr_string(s: UniquePtr<CxxString>) { 589 assert_eq!(s.as_ref().unwrap().to_str().unwrap(), "2020"); 590} 591 592fn r_take_ref_vector(v: &CxxVector<u8>) { 593 let slice = v.as_slice(); 594 assert_eq!(slice, [20, 2, 0]); 595} 596 597fn r_take_ref_empty_vector(v: &CxxVector<u64>) { 598 assert!(v.as_slice().is_empty()); 599 assert!(v.is_empty()); 600} 601 602fn r_take_rust_vec(v: Vec<u8>) { 603 let _ = v; 604} 605 606fn r_take_rust_vec_string(v: Vec<String>) { 607 let _ = v; 608} 609 610fn r_take_ref_rust_vec(v: &Vec<u8>) { 611 let _ = v; 612} 613 614fn r_take_ref_rust_vec_string(v: &Vec<String>) { 615 let _ = v; 616} 617 618fn r_take_enum(e: ffi::Enum) { 619 let _ = e; 620} 621 622fn r_try_return_void() -> Result<(), Error> { 623 Ok(()) 624} 625 626fn r_try_return_primitive() -> Result<usize, Error> { 627 Ok(2020) 628} 629 630fn r_try_return_box() -> Result<Box<R>, Error> { 631 Ok(Box::new(R(2020))) 632} 633 634fn r_fail_return_primitive() -> Result<usize, Error> { 635 Err(Error) 636} 637 638fn r_try_return_sliceu8(slice: &[u8]) -> Result<&[u8], Error> { 639 Ok(slice) 640} 641 642fn r_try_return_mutsliceu8(slice: &mut [u8]) -> Result<&mut [u8], Error> { 643 Ok(slice) 644} 645 646fn r_aliased_function(x: i32) -> String { 647 x.to_string() 648} 649