@@ -3,7 +3,7 @@ use crate::gen::nested::NamespaceEntries;
33use crate :: gen:: out:: OutFile ;
44use crate :: gen:: { builtin, include, Opt } ;
55use crate :: syntax:: atom:: Atom :: { self , * } ;
6- use crate :: syntax:: instantiate:: { ImplKey , NamedImplKey } ;
6+ use crate :: syntax:: instantiate:: { ImplKey , NamedImplKey , OptionInner } ;
77use crate :: syntax:: map:: UnorderedMap as Map ;
88use crate :: syntax:: set:: UnorderedSet ;
99use crate :: syntax:: symbol:: { self , Symbol } ;
@@ -214,6 +214,7 @@ fn pick_includes_and_builtins(out: &mut OutFile, apis: &[Api]) {
214214 } ,
215215 Type :: RustBox ( _) => out. builtin . rust_box = true ,
216216 Type :: RustVec ( _) => out. builtin . rust_vec = true ,
217+ Type :: RustOption ( _) => out. builtin . rust_option = true ,
217218 Type :: UniquePtr ( _) => out. include . memory = true ,
218219 Type :: SharedPtr ( _) | Type :: WeakPtr ( _) => out. include . memory = true ,
219220 Type :: Str ( _) => out. builtin . rust_str = true ,
@@ -836,6 +837,8 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
836837 out. builtin . unsafe_bitcopy = true ;
837838 write_type ( out, & arg. ty ) ;
838839 write ! ( out, "(::rust::unsafe_bitcopy, *{})" , arg. name. cxx) ;
840+ } else if let Type :: RustOption ( _) = arg. ty {
841+ write ! ( out, "std::move(* {})" , arg. name. cxx) ;
839842 } else if out. types . needs_indirect_abi ( & arg. ty ) {
840843 out. include . utility = true ;
841844 write ! ( out, "::std::move(*{})" , arg. name. cxx) ;
@@ -1235,6 +1238,21 @@ fn write_type(out: &mut OutFile, ty: &Type) {
12351238 write_type ( out, & ty. inner ) ;
12361239 write ! ( out, ">" ) ;
12371240 }
1241+ Type :: RustOption ( ty) => {
1242+ write ! ( out, "::rust::Option<" ) ;
1243+ match & ty. inner {
1244+ Type :: RustBox ( _) => write_type ( out, & ty. inner ) ,
1245+ Type :: Ref ( r) => {
1246+ write_type_space ( out, & r. inner ) ;
1247+ if !r. mutable {
1248+ write ! ( out, "const " ) ;
1249+ }
1250+ write ! ( out, "*" ) ;
1251+ }
1252+ _ => unreachable ! ( ) ,
1253+ }
1254+ write ! ( out, ">" ) ;
1255+ }
12381256 Type :: UniquePtr ( ptr) => {
12391257 write ! ( out, "::std::unique_ptr<" ) ;
12401258 write_type ( out, & ptr. inner ) ;
@@ -1340,6 +1358,7 @@ fn write_space_after_type(out: &mut OutFile, ty: &Type) {
13401358 | Type :: Str ( _)
13411359 | Type :: CxxVector ( _)
13421360 | Type :: RustVec ( _)
1361+ | Type :: RustOption ( _)
13431362 | Type :: SliceRef ( _)
13441363 | Type :: Fn ( _)
13451364 | Type :: Array ( _) => write ! ( out, " " ) ,
@@ -1354,6 +1373,12 @@ enum UniquePtr<'a> {
13541373 CxxVector ( & ' a Ident ) ,
13551374}
13561375
1376+ enum RustOption < ' a > {
1377+ RustBox ( & ' a Ident ) ,
1378+ Ref ( & ' a Ident ) ,
1379+ MutRef ( & ' a Ident ) ,
1380+ }
1381+
13571382trait ToTypename {
13581383 fn to_typename ( & self , types : & Types ) -> String ;
13591384}
@@ -1375,6 +1400,18 @@ impl<'a> ToTypename for UniquePtr<'a> {
13751400 }
13761401}
13771402
1403+ impl < ' a > ToTypename for RustOption < ' a > {
1404+ fn to_typename ( & self , types : & Types ) -> String {
1405+ match self {
1406+ RustOption :: RustBox ( inner) => {
1407+ format ! ( "::rust::cxxbridge1::Box<{}>" , inner. to_typename( types) )
1408+ }
1409+ RustOption :: Ref ( inner) => format ! ( "const {}*" , inner. to_typename( types) ) ,
1410+ RustOption :: MutRef ( inner) => format ! ( "{}*" , inner. to_typename( types) ) ,
1411+ }
1412+ }
1413+ }
1414+
13781415trait ToMangled {
13791416 fn to_mangled ( & self , types : & Types ) -> Symbol ;
13801417}
@@ -1396,6 +1433,22 @@ impl<'a> ToMangled for UniquePtr<'a> {
13961433 }
13971434}
13981435
1436+ impl < ' a > ToMangled for RustOption < ' a > {
1437+ fn to_mangled ( & self , types : & Types ) -> Symbol {
1438+ match self {
1439+ RustOption :: RustBox ( inner) => symbol:: join ( & [ & "Box" , & inner. to_mangled ( types) ] ) ,
1440+ RustOption :: Ref ( inner) => {
1441+ let symbol = symbol:: join ( & [ & "const" , & inner. to_mangled ( types) ] ) ;
1442+ symbol
1443+ }
1444+ RustOption :: MutRef ( inner) => {
1445+ let symbol = symbol:: join ( & [ & inner. to_mangled ( types) ] ) ;
1446+ symbol
1447+ }
1448+ }
1449+ }
1450+ }
1451+
13991452fn write_generic_instantiations ( out : & mut OutFile ) {
14001453 if out. header {
14011454 return ;
@@ -1409,6 +1462,7 @@ fn write_generic_instantiations(out: &mut OutFile) {
14091462 match * impl_key {
14101463 ImplKey :: RustBox ( ident) => write_rust_box_extern ( out, ident) ,
14111464 ImplKey :: RustVec ( ident) => write_rust_vec_extern ( out, ident) ,
1465+ ImplKey :: RustOption ( ident) => write_rust_option_extern ( out, ident) ,
14121466 ImplKey :: UniquePtr ( ident) => write_unique_ptr ( out, ident) ,
14131467 ImplKey :: SharedPtr ( ident) => write_shared_ptr ( out, ident) ,
14141468 ImplKey :: WeakPtr ( ident) => write_weak_ptr ( out, ident) ,
@@ -1423,6 +1477,7 @@ fn write_generic_instantiations(out: &mut OutFile) {
14231477 match * impl_key {
14241478 ImplKey :: RustBox ( ident) => write_rust_box_impl ( out, ident) ,
14251479 ImplKey :: RustVec ( ident) => write_rust_vec_impl ( out, ident) ,
1480+ ImplKey :: RustOption ( ident) => write_rust_option_impl ( out, ident) ,
14261481 _ => { }
14271482 }
14281483 }
@@ -1501,6 +1556,53 @@ fn write_rust_vec_extern(out: &mut OutFile, key: NamedImplKey) {
15011556 ) ;
15021557}
15031558
1559+ fn write_rust_option_extern ( out : & mut OutFile , inner : OptionInner ) {
1560+ out. include . cstddef = true ;
1561+ let element = match inner {
1562+ OptionInner :: RustBox ( key) => RustOption :: RustBox ( key. rust ) ,
1563+ OptionInner :: Ref ( key) => {
1564+ if out. types . try_resolve ( key. rust ) . is_none ( ) {
1565+ return ;
1566+ }
1567+ RustOption :: Ref ( key. rust )
1568+ }
1569+ OptionInner :: MutRef ( key) => {
1570+ if out. types . try_resolve ( key. rust ) . is_none ( ) {
1571+ return ;
1572+ }
1573+ RustOption :: MutRef ( key. rust )
1574+ }
1575+ } ;
1576+ let inner = element. to_typename ( out. types ) ;
1577+ let instance = element. to_mangled ( out. types ) ;
1578+
1579+ writeln ! (
1580+ out,
1581+ "void cxxbridge1$rust_option${}$new(const ::rust::Option<{}> *ptr) noexcept;" ,
1582+ instance, inner,
1583+ ) ;
1584+ writeln ! (
1585+ out,
1586+ "void cxxbridge1$rust_option${}$drop(::rust::Option<{}> *ptr) noexcept;" ,
1587+ instance, inner,
1588+ ) ;
1589+ writeln ! (
1590+ out,
1591+ "bool cxxbridge1$rust_option${}$has_value(::rust::Option<{}> const *ptr) noexcept;" ,
1592+ instance, inner
1593+ ) ;
1594+ writeln ! (
1595+ out,
1596+ "{}* cxxbridge1$rust_option${}$value_ptr(::rust::Option<{0}> *ptr) noexcept;" ,
1597+ inner, instance
1598+ ) ;
1599+ writeln ! (
1600+ out,
1601+ "void cxxbridge1$rust_option${}$set(::rust::Option<{1}> *ptr, {1}&& value) noexcept;" ,
1602+ instance, inner
1603+ ) ;
1604+ }
1605+
15041606fn write_rust_box_impl ( out : & mut OutFile , key : NamedImplKey ) {
15051607 let resolve = out. types . resolve ( & key) ;
15061608 let inner = resolve. name . to_fully_qualified ( ) ;
@@ -1621,6 +1723,72 @@ fn write_rust_vec_impl(out: &mut OutFile, key: NamedImplKey) {
16211723 writeln ! ( out, "}}" ) ;
16221724}
16231725
1726+ fn write_rust_option_impl ( out : & mut OutFile , inner : OptionInner ) {
1727+ let element = match inner {
1728+ OptionInner :: RustBox ( key) => RustOption :: RustBox ( key. rust ) ,
1729+ OptionInner :: Ref ( key) => {
1730+ if out. types . try_resolve ( key. rust ) . is_none ( ) {
1731+ return ;
1732+ }
1733+ RustOption :: Ref ( key. rust )
1734+ }
1735+ OptionInner :: MutRef ( key) => {
1736+ if out. types . try_resolve ( key. rust ) . is_none ( ) {
1737+ return ;
1738+ }
1739+ RustOption :: MutRef ( key. rust )
1740+ }
1741+ } ;
1742+ let inner = element. to_typename ( out. types ) ;
1743+ let instance = element. to_mangled ( out. types ) ;
1744+
1745+ writeln ! ( out, "template <>" ) ;
1746+ begin_function_definition ( out) ;
1747+ writeln ! ( out, "Option<{}>::Option() noexcept {{" , inner) ;
1748+ writeln ! ( out, " cxxbridge1$rust_option${}$new(this);" , instance) ;
1749+ writeln ! ( out, "}}" ) ;
1750+
1751+ writeln ! ( out, "template <>" ) ;
1752+ begin_function_definition ( out) ;
1753+ writeln ! ( out, "void Option<{}>::drop() noexcept {{" , inner) ;
1754+ writeln ! (
1755+ out,
1756+ " return cxxbridge1$rust_option${}$drop(this);" ,
1757+ instance
1758+ ) ;
1759+ writeln ! ( out, "}}" ) ;
1760+
1761+ writeln ! ( out, "template <>" ) ;
1762+ begin_function_definition ( out) ;
1763+ writeln ! ( out, "bool Option<{}>::has_value() const noexcept {{" , inner) ;
1764+ writeln ! (
1765+ out,
1766+ " return cxxbridge1$rust_option${}$has_value(this);" ,
1767+ instance
1768+ ) ;
1769+ writeln ! ( out, "}}" ) ;
1770+
1771+ writeln ! ( out, "template <>" ) ;
1772+ begin_function_definition ( out) ;
1773+ writeln ! ( out, "{0}* Option<{0}>::value_ptr() noexcept {{" , inner) ;
1774+ writeln ! (
1775+ out,
1776+ " return cxxbridge1$rust_option${}$value_ptr(this);" ,
1777+ instance
1778+ ) ;
1779+ writeln ! ( out, "}}" ) ;
1780+
1781+ writeln ! ( out, "template <>" ) ;
1782+ begin_function_definition ( out) ;
1783+ writeln ! ( out, "void Option<{0}>::set({0}&& value) noexcept {{" , inner) ;
1784+ writeln ! (
1785+ out,
1786+ " return cxxbridge1$rust_option${}$set(this, ::std::move(value));" ,
1787+ instance
1788+ ) ;
1789+ writeln ! ( out, "}}" ) ;
1790+ }
1791+
16241792fn write_unique_ptr ( out : & mut OutFile , key : NamedImplKey ) {
16251793 let ty = UniquePtr :: Ident ( key. rust ) ;
16261794 write_unique_ptr_common ( out, ty) ;
0 commit comments