@@ -8,7 +8,8 @@ use petgraph::Direction;
8
8
use my_ast:: { code_to_item, if_option_return_some_type, if_result_return_ok_err_types,
9
9
if_vec_return_elem_type, normalized_ty_string, parse_ty, RustType } ;
10
10
use errors:: fatal_error;
11
- use types_conv_map:: { ForeignTypeInfo , FROM_VAR_TEMPLATE } ;
11
+ use types_conv_map:: { make_unique_rust_typename, ForeignTypeInfo , FROM_VAR_TEMPLATE ,
12
+ TO_VAR_TEMPLATE } ;
12
13
use { CppConfig , CppOptional , CppVariant , ForeignEnumInfo , ForeignerClassInfo , TypesConvMap } ;
13
14
use cpp:: { CppConverter , CppForeignTypeInfo } ;
14
15
use cpp:: cpp_code:: c_class_type;
@@ -571,6 +572,86 @@ fn handle_option_type_in_result<'a>(
571
572
} ) ,
572
573
} ) ) ;
573
574
}
575
+
576
+ //handle Option<&ForeignClass> case
577
+ if let ast:: TyKind :: Rptr (
578
+ _,
579
+ ast:: MutTy {
580
+ ty : ref under_ref_ty,
581
+ mutbl : ast:: Mutability :: Immutable ,
582
+ } ,
583
+ ) = opt_ty. node
584
+ {
585
+ if let Some ( fclass) = conv_map
586
+ . find_foreigner_class_with_such_self_type ( under_ref_ty, false )
587
+ . map ( |v| v. clone ( ) )
588
+ {
589
+ let foreign_info =
590
+ foreign_class_foreign_name ( sess, conv_map, & fclass, under_ref_ty. span , false ) ?;
591
+ let this_type_for_method = fclass. this_type_for_method . as_ref ( ) . ok_or_else ( || {
592
+ fatal_error (
593
+ sess,
594
+ fclass. span ,
595
+ & format ! (
596
+ "Class {} (namespace {}) return as reference, but there is no constructor" ,
597
+ fclass. name, cpp_cfg. namespace_name,
598
+ ) ,
599
+ )
600
+ } ) ?;
601
+ let this_type: RustType = this_type_for_method. clone ( ) . into ( ) ;
602
+ let void_ptr_typename = Symbol :: intern ( "*mut ::std::os::raw::c_void" ) ;
603
+ let my_void_ptr_ti = RustType :: new (
604
+ parse_ty ( sess, DUMMY_SP , void_ptr_typename) ?,
605
+ make_unique_rust_typename ( void_ptr_typename, this_type. normalized_name ) ,
606
+ ) ;
607
+ let arg_rust_ty: RustType = arg_ty. clone ( ) . into ( ) ;
608
+ conv_map. add_type ( arg_rust_ty. clone ( ) ) ;
609
+ conv_map. add_conversation_rule (
610
+ arg_rust_ty,
611
+ my_void_ptr_ti,
612
+ Symbol :: intern ( & format ! (
613
+ r#"
614
+ let {to_var}: *mut ::std::os::raw::c_void = match {from_var} {{
615
+ Some(x) => x as *const {self_type} as *mut ::std::os::raw::c_void,
616
+ None => ::std::ptr::null_mut(),
617
+ }};
618
+ "# ,
619
+ to_var = TO_VAR_TEMPLATE ,
620
+ from_var = FROM_VAR_TEMPLATE ,
621
+ self_type = this_type. normalized_name,
622
+ ) ) . into ( ) ,
623
+ ) ;
624
+
625
+ let ( typename, output_converter) = match cpp_cfg. cpp_optional {
626
+ CppOptional :: Std17 => (
627
+ Symbol :: intern ( & format ! ( "std::optional<{}Ref>" , fclass. name) ) ,
628
+ format ! (
629
+ "{var} != nullptr ? {Type}Ref({var}) : std::optional<{Type}Ref>()" ,
630
+ Type = fclass. name,
631
+ var = FROM_VAR_TEMPLATE ,
632
+ ) ,
633
+ ) ,
634
+ CppOptional :: Boost => (
635
+ Symbol :: intern ( & format ! ( "boost::optional<{}Ref>" , fclass. name) ) ,
636
+ format ! (
637
+ "{var} != nullptr ? {Type}Ref({var}) : boost::optional<{Type}Ref>()" ,
638
+ Type = fclass. name,
639
+ var = FROM_VAR_TEMPLATE ,
640
+ ) ,
641
+ ) ,
642
+ } ;
643
+ return Ok ( Some ( CppForeignTypeInfo {
644
+ base : foreign_info,
645
+ c_converter : String :: new ( ) ,
646
+ cpp_converter : Some ( CppConverter {
647
+ typename,
648
+ output_converter,
649
+ input_converter : "#error" . to_string ( ) ,
650
+ } ) ,
651
+ } ) ) ;
652
+ }
653
+ }
654
+
574
655
let mut cpp_info_opt = map_ordinal_result_type ( sess, conv_map, arg_ty) ?;
575
656
let cpp_info_ty = map_ordinal_result_type ( sess, conv_map, opt_ty) ?;
576
657
let f_opt_ty = cpp_info_ty. base . name ;
0 commit comments