@@ -76,6 +76,38 @@ func BuildImplementationRust(component ComponentDefinition, outputFolder string,
7676 return err
7777 }
7878
79+ IntfWrapperFileName := BaseName + "_interface_wrapper.rs"
80+ IntfWrapperFilePath := path .Join (outputFolder , IntfWrapperFileName )
81+ modfiles = append (modfiles , IntfWrapperFilePath )
82+ log .Printf ("Creating \" %s\" " , IntfWrapperFilePath )
83+ IntfWrapperRSFile , err := CreateLanguageFile (IntfWrapperFilePath , indentString )
84+ if err != nil {
85+ return err
86+ }
87+ IntfWrapperRSFile .WriteCLicenseHeader (component ,
88+ fmt .Sprintf ("This is an autogenerated Rust implementation file in order to allow easy\n development of %s. The functions in this file need to be implemented. It needs to be generated only once." , LibraryName ),
89+ true )
90+ err = buildRustWrapper (component , IntfWrapperRSFile , InterfaceMod )
91+ if err != nil {
92+ return err
93+ }
94+
95+ IntfHandleFileName := BaseName + "_interface_handle.rs"
96+ IntfHandleFilePath := path .Join (outputFolder , IntfHandleFileName )
97+ modfiles = append (modfiles , IntfHandleFilePath )
98+ log .Printf ("Creating \" %s\" " , IntfHandleFilePath )
99+ IntfHandleRSFile , err := CreateLanguageFile (IntfHandleFilePath , indentString )
100+ if err != nil {
101+ return err
102+ }
103+ IntfHandleRSFile .WriteCLicenseHeader (component ,
104+ fmt .Sprintf ("This is an autogenerated Rust implementation file in order to allow easy\n development of %s. The functions in this file need to be implemented. It needs to be generated only once." , LibraryName ),
105+ true )
106+ err = buildRustHandle (component , IntfHandleRSFile , InterfaceMod )
107+ if err != nil {
108+ return err
109+ }
110+
79111 IntfWrapperStubName := path .Join (stubOutputFolder , BaseName + stubIdentifier + ".rs" )
80112 modfiles = append (modfiles , IntfWrapperStubName )
81113 if forceRebuild || ! FileExists (IntfWrapperStubName ) {
@@ -344,7 +376,7 @@ func buildRustGlobalStubFile(component ComponentDefinition, w LanguageWriter, In
344376 w .Writeln ("use %s::*;" , InterfaceMod )
345377 w .Writeln ("" )
346378 w .Writeln ("// Wrapper struct to implement the wrapper trait for global methods" )
347- w .Writeln ("struct CWrapper;" )
379+ w .Writeln ("pub struct CWrapper;" )
348380 w .Writeln ("" )
349381 w .Writeln ("impl Wrapper for CWrapper {" )
350382 w .Writeln ("" )
@@ -474,3 +506,162 @@ func buildRustStubFile(component ComponentDefinition, class ComponentDefinitionC
474506 w .Writeln ("" )
475507 return nil
476508}
509+
510+ func buildRustWrapper (component ComponentDefinition , w LanguageWriter , InterfaceMod string ) error {
511+ // Imports
512+ ModName := strings .ToLower (component .NameSpace )
513+ w .Writeln ("" )
514+ w .Writeln ("// Calls from the C-Interface to the Rust traits via the CWrapper" )
515+ w .Writeln ("// These are the symbols exposed in the shared object interface" )
516+ w .Writeln ("" )
517+ w .Writeln ("use %s::*;" , InterfaceMod )
518+ w .Writeln ("use %s::CWrapper;" , ModName )
519+ w .Writeln ("use std::ffi::{c_char, CStr};" )
520+ w .Writeln ("" )
521+ cprefix := ModName + "_"
522+ // Build the global methods
523+ err := writeGlobalRustWrapper (component , w , cprefix )
524+ if err != nil {
525+ return err
526+ }
527+ return nil
528+ }
529+
530+ func buildRustHandle (component ComponentDefinition , w LanguageWriter , InterfaceMod string ) error {
531+ w .Writeln ("" )
532+ w .Writeln ("// Handle passed through interface define the casting maps needed to extract" )
533+ w .Writeln ("" )
534+ w .Writeln ("use %s::*;" , InterfaceMod )
535+ w .Writeln ("" )
536+ w .Writeln ("impl HandleImpl {" )
537+ w .AddIndentationLevel (1 )
538+ for i := 0 ; i < len (component .Classes ); i ++ {
539+ class := component .Classes [i ]
540+ writeRustHandleAs (component , w , class , false )
541+ writeRustHandleAs (component , w , class , true )
542+ w .Writeln ("" )
543+ }
544+ w .AddIndentationLevel (- 1 )
545+ w .Writeln ("}" )
546+ return nil
547+ }
548+
549+ func writeRustHandleAs (component ComponentDefinition , w LanguageWriter , class ComponentDefinitionClass , mut bool ) error {
550+ //parents, err := getParentList(component, class)
551+ //if err != nil {
552+ // return err
553+ //}
554+ Name := class .ClassName
555+ if ! mut {
556+ w .Writeln ("pub fn as_%s(&self) -> Option<&dyn %s> {" , toSnakeCase (Name ), Name )
557+ } else {
558+ w .Writeln ("pub fn as_mut_%s(&mut self) -> Option<&mut dyn %s> {" , toSnakeCase (Name ), Name )
559+ }
560+ w .AddIndentationLevel (1 )
561+ w .Writeln ("None" )
562+ w .AddIndentationLevel (- 1 )
563+ w .Writeln ("}" )
564+ return nil
565+ }
566+
567+ func writeGlobalRustWrapper (component ComponentDefinition , w LanguageWriter , cprefix string ) error {
568+ methods := component .Global .Methods
569+ for i := 0 ; i < len (methods ); i ++ {
570+ method := methods [i ]
571+ err := writeRustMethodWrapper (method , w , cprefix )
572+ if err != nil {
573+ return err
574+ }
575+ w .Writeln ("" )
576+ }
577+ return nil
578+ }
579+
580+ func writeRustMethodWrapper (method ComponentDefinitionMethod , w LanguageWriter , cprefix string ) error {
581+ // Build up the parameter strings
582+ parameterString := ""
583+ returnName := ""
584+ for k := 0 ; k < len (method .Params ); k ++ {
585+ param := method .Params [k ]
586+ RustParams , err := generateRustParameters (param , true )
587+ if err != nil {
588+ return err
589+ }
590+ for i := 0 ; i < len (RustParams ); i ++ {
591+ RustParam := RustParams [i ]
592+ if parameterString == "" {
593+ parameterString += fmt .Sprintf ("%s : %s" , RustParam .ParamName , RustParam .ParamType )
594+ } else {
595+ parameterString += fmt .Sprintf (", %s : %s" , RustParam .ParamName , RustParam .ParamType )
596+ }
597+ }
598+ }
599+ w .Writeln ("pub fn %s%s(%s) -> i32 {" , cprefix , strings .ToLower (method .MethodName ), parameterString )
600+ w .AddIndentationLevel (1 )
601+ argsString := ""
602+ for k := 0 ; k < len (method .Params ); k ++ {
603+ param := method .Params [k ]
604+ OName , err := writeRustParameterConversionArg (param , w )
605+ if err != nil {
606+ return err
607+ }
608+ if OName != "" {
609+ if argsString == "" {
610+ argsString = OName
611+ } else {
612+ argsString += fmt .Sprintf (", %s" , OName )
613+ }
614+ }
615+ }
616+ if returnName != "" {
617+ w .Writeln ("let %s = CWrapper::%s(%s);" , returnName , toSnakeCase (method .MethodName ), argsString )
618+ } else {
619+ w .Writeln ("CWrapper::%s(%s);" , toSnakeCase (method .MethodName ), argsString )
620+ }
621+ w .Writeln ("// All ok" )
622+ w .Writeln ("0" )
623+ w .AddIndentationLevel (- 1 )
624+ w .Writeln ("}" )
625+ return nil
626+ }
627+
628+ func writeRustParameterConversionArg (param ComponentDefinitionParam , w LanguageWriter ) (string , error ) {
629+ if param .ParamPass == "return" {
630+ return "" , nil
631+ }
632+ IName := toSnakeCase (param .ParamName )
633+ OName := "_" + IName
634+ switch param .ParamType {
635+ case "uint8" , "uint16" , "uint32" , "uint64" , "int8" , "int16" , "int32" , "int64" , "single" , "double" :
636+ if param .ParamPass == "in" {
637+ w .Writeln ("let %s = %s;" , OName , IName )
638+ } else {
639+ w .Writeln ("let %s = unsafe {&mut *%s};" , OName , IName )
640+ }
641+ case "class" , "optionalclass" :
642+ if param .ParamPass == "in" {
643+ HName := "_Handle_" + IName
644+ w .Writeln ("let %s = unsafe {&*%s};" , HName , IName )
645+ w .Writeln ("let %s = %s.as_%s().unwrap();" , OName , HName , toSnakeCase (param .ParamClass ))
646+ } else {
647+ HName := "_Handle_" + IName
648+ w .Writeln ("let %s = unsafe {&mut *%s};" , HName , IName )
649+ w .Writeln ("let %s = %s.as_mut_%s().unwrap();" , OName , HName , toSnakeCase (param .ParamClass ))
650+ }
651+ case "string" :
652+ if param .ParamPass == "in" {
653+ SName := "_Str_" + IName
654+ w .Writeln ("let %s = unsafe{ CStr::from_ptr(%s) };" , SName , IName )
655+ w .Writeln ("let %s = %s.to_str().unwrap();" , OName , SName )
656+ } else {
657+ SName := "_String_" + IName
658+ w .Writeln ("let mut %s = String::new();" , SName )
659+ w .Writeln ("let %s = &mut %s;" , OName , SName )
660+ }
661+ case "bool" , "pointer" , "struct" , "basicarray" , "structarray" :
662+ //return fmt.Errorf("Conversion of type %s for parameter %s not supported", param.ParamType, IName)
663+ default :
664+ return "" , fmt .Errorf ("Conversion of type %s for parameter %s not supported as is unknown" , param .ParamType , IName )
665+ }
666+ return OName , nil
667+ }
0 commit comments