This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/599-provide-and-use-c-service-in-rust
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 3b4ccb9effd87c42e3ddb973ab7075f1e4ac03fd
Author: Pepijn Noltes <pepijnnol...@gmail.com>
AuthorDate: Sun Aug 20 16:43:31 2023 +0200

    #599: Refactor rust api into modules
---
 misc/experimental/rust/CMakeLists.txt              | 22 +++---
 misc/experimental/rust/Cargo.toml                  |  2 +-
 .../rust/celix_bindings/src/BundleActivator.rs     | 78 ------------------
 .../celix_bindings/src/celix/bundle_activator.rs   | 92 ++++++++++++++++++++++
 .../{BundleContext.rs => celix/bundle_context.rs}  | 11 ++-
 .../celix_bindings/src/{lib.rs => celix/errno.rs}  | 43 +++++-----
 .../src/{LogHelper.rs => celix/log_helper.rs}      |  8 +-
 .../celix_bindings/src/{lib.rs => celix/mod.rs}    | 37 ++++-----
 misc/experimental/rust/celix_bindings/src/lib.rs   | 22 +-----
 .../rust/hello_world_activator/src/lib.rs          | 16 ++--
 10 files changed, 165 insertions(+), 166 deletions(-)

diff --git a/misc/experimental/rust/CMakeLists.txt 
b/misc/experimental/rust/CMakeLists.txt
index 3a710803..a98150f2 100644
--- a/misc/experimental/rust/CMakeLists.txt
+++ b/misc/experimental/rust/CMakeLists.txt
@@ -41,11 +41,11 @@ if (CELIX_RUST_EXPERIMENTAL)
     add_celix_bundle(rust_bundle ACTIVATOR ${ACTUAL_LIB_TARGET})
     add_dependencies(rust_bundle rust_bundle_activator)
 
-    corrosion_add_target_local_rustflags(rust_shell_tui_activator 
"-Cprefer-dynamic")
-    corrosion_link_libraries(rust_shell_tui_activator Celix::framework)
-    get_target_property(ACTUAL_LIB_TARGET rust_shell_tui_activator 
INTERFACE_LINK_LIBRARIES)
-    add_celix_bundle(rust_shell_tui ACTIVATOR ${ACTUAL_LIB_TARGET})
-    add_dependencies(rust_shell_tui rust_shell_tui_activator)
+#    corrosion_add_target_local_rustflags(rust_shell_tui_activator 
"-Cprefer-dynamic")
+#    corrosion_link_libraries(rust_shell_tui_activator Celix::framework)
+#    get_target_property(ACTUAL_LIB_TARGET rust_shell_tui_activator 
INTERFACE_LINK_LIBRARIES)
+#    add_celix_bundle(rust_shell_tui ACTIVATOR ${ACTUAL_LIB_TARGET})
+#    add_dependencies(rust_shell_tui rust_shell_tui_activator)
 
     add_celix_container(rust_container NO_COPY
         BUNDLES
@@ -54,11 +54,11 @@ if (CELIX_RUST_EXPERIMENTAL)
             rust_bundle
     )
 
-    add_celix_container(rust_shell_tui_cnt NO_COPY
-        BUNDLES
-            Celix::shell
-            Celix::shell_tui
-            rust_shell_tui
-    )
+#    add_celix_container(rust_shell_tui_cnt NO_COPY
+#        BUNDLES
+#            Celix::shell
+#            Celix::shell_tui
+#            rust_shell_tui
+#    )
 
 endif()
diff --git a/misc/experimental/rust/Cargo.toml 
b/misc/experimental/rust/Cargo.toml
index ef69f6c6..891c8dd6 100644
--- a/misc/experimental/rust/Cargo.toml
+++ b/misc/experimental/rust/Cargo.toml
@@ -19,5 +19,5 @@
 members = [
     "celix_bindings",
     "hello_world_activator",
-    "rust_shell_tui",
+    #"rust_shell_tui",
 ]
diff --git a/misc/experimental/rust/celix_bindings/src/BundleActivator.rs 
b/misc/experimental/rust/celix_bindings/src/BundleActivator.rs
deleted file mode 100644
index e46ea8d3..00000000
--- a/misc/experimental/rust/celix_bindings/src/BundleActivator.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-pub trait BundleActivator {
-    fn new(ctx: &mut dyn BundleContext) -> Self;
-    fn start(&mut self, ctx: &mut dyn BundleContext) -> celix_status_t { /* 
Default implementation */ CELIX_SUCCESS}
-    fn stop(&mut self, ctx: &mut dyn BundleContext) -> celix_status_t { /* 
Default implementation */ CELIX_SUCCESS}
-}
-
-#[macro_export]
-macro_rules! generate_bundle_activator {
-    ($activator:ident) => {
-        use celix::BundleContextImpl;
-        use CELIX_SUCCESS;
-        use celix_bindings::celix_bundle_context_t;
-
-        struct ActivatorWrapper {
-            ctx: BundleContextImpl,
-            activator: $activator,
-        }
-
-        #[no_mangle]
-        pub unsafe extern "C" fn celix_bundleActivator_create(
-            ctx: *mut celix_bundle_context_t,
-            out: *mut *mut c_void,
-        ) -> celix_status_t {
-            let mut context = BundleContextImpl::new(ctx);
-            let activator = $activator::new(&mut context);
-            let wrapper = ActivatorWrapper {
-                ctx: context,
-                activator
-            };
-            *out = Box::into_raw(Box::new(wrapper)) as *mut c_void;
-            CELIX_SUCCESS
-        }
-
-        #[no_mangle]
-        pub unsafe extern "C" fn celix_bundleActivator_start(
-            handle: *mut c_void,
-            ctx: *mut celix_bundle_context_t,
-        ) -> celix_status_t {
-            let wrapper = &mut *(handle as *mut ActivatorWrapper);
-            wrapper.activator.start(&mut wrapper.ctx)
-        }
-
-        #[no_mangle]
-        pub unsafe extern "C" fn celix_bundleActivator_stop(
-            handle: *mut c_void,
-            ctx: *mut celix_bundle_context_t,
-        ) -> celix_status_t {
-            let wrapper = &mut *(handle as *mut ActivatorWrapper);
-            wrapper.activator.stop(&mut wrapper.ctx)
-        }
-
-        #[no_mangle]
-        pub unsafe extern "C" fn celix_bundleActivator_destroy(handle: *mut 
c_void) -> celix_status_t {
-            let wrapper = Box::from_raw(handle as *mut ActivatorWrapper);
-            drop(wrapper);
-            CELIX_SUCCESS
-        }
-    };
-}
diff --git 
a/misc/experimental/rust/celix_bindings/src/celix/bundle_activator.rs 
b/misc/experimental/rust/celix_bindings/src/celix/bundle_activator.rs
new file mode 100644
index 00000000..01dece71
--- /dev/null
+++ b/misc/experimental/rust/celix_bindings/src/celix/bundle_activator.rs
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use ::celix::BundleContext;
+use ::celix::Error;
+
+pub trait BundleActivator {
+    fn new(ctx: &mut dyn BundleContext) -> Self;
+    fn start(&mut self, _ctx: &mut dyn BundleContext) -> Result<(), Error> { 
/* Default implementation */ Ok(())}
+    fn stop(&mut self, _ctx: &mut dyn BundleContext)  -> Result<(), Error> { 
/* Default implementation */ Ok(())}
+}
+
+#[macro_export]
+macro_rules! generate_bundle_activator {
+    ($activator:ty) => {
+        // fn assert_implements_trait(_: &$activator) {
+        //     fn must_implement<T: celix::BundleActivator>(_t: &T) {}
+        //     must_implement(&*(None::<$activator>).unwrap_or_default());
+        // }
+
+        struct ActivatorWrapper {
+            ctx: Box<dyn $crate::celix::BundleContext>,
+            activator: $activator,
+        }
+
+        #[no_mangle]
+        pub unsafe extern "C" fn celix_bundleActivator_create(
+            ctx: *mut $crate::celix_bundle_context_t,
+            out: *mut *mut ::std::ffi::c_void,
+        ) -> $crate::celix_status_t {
+            let mut context = 
$crate::celix::create_bundle_context_instance(ctx);
+            let activator = <$activator>::new(&mut *context);
+            let wrapper = ActivatorWrapper {
+                ctx: context,
+                activator
+            };
+            *out = Box::into_raw(Box::new(wrapper)) as *mut ::std::ffi::c_void;
+            $crate::celix::CELIX_SUCCESS
+        }
+
+        #[no_mangle]
+        pub unsafe extern "C" fn celix_bundleActivator_start(
+            handle: *mut ::std::ffi::c_void,
+            ctx: *mut $crate::celix_bundle_context_t,
+        ) -> $crate::celix_status_t {
+            let wrapper = &mut *(handle as *mut ActivatorWrapper);
+            let result = wrapper.activator.start(&mut *wrapper.ctx);
+            match result {
+                Ok(_) => $crate::celix::CELIX_SUCCESS,
+                Err(e) => e.into(),
+            }
+        }
+
+        #[no_mangle]
+        pub unsafe extern "C" fn celix_bundleActivator_stop(
+            handle: *mut ::std::ffi::c_void,
+            ctx: *mut $crate::celix_bundle_context_t,
+        ) -> $crate::celix_status_t {
+            let wrapper = &mut *(handle as *mut ActivatorWrapper);
+            let result = wrapper.activator.stop(&mut *wrapper.ctx);
+            match result {
+                Ok(_) => $crate::celix::CELIX_SUCCESS,
+                Err(e) => e.into(),
+            }
+        }
+
+        #[no_mangle]
+        pub unsafe extern "C" fn celix_bundleActivator_destroy(
+            handle: *mut ::std::ffi::c_void
+        ) -> $crate::celix_status_t {
+            let reclaimed_wrapper = Box::from_raw(handle as *mut 
ActivatorWrapper);
+            drop(reclaimed_wrapper);
+            $crate::celix::CELIX_SUCCESS
+        }
+    };
+}
diff --git a/misc/experimental/rust/celix_bindings/src/BundleContext.rs 
b/misc/experimental/rust/celix_bindings/src/celix/bundle_context.rs
similarity index 79%
rename from misc/experimental/rust/celix_bindings/src/BundleContext.rs
rename to misc/experimental/rust/celix_bindings/src/celix/bundle_context.rs
index 9dc340b7..b63ae497 100644
--- a/misc/experimental/rust/celix_bindings/src/BundleContext.rs
+++ b/misc/experimental/rust/celix_bindings/src/celix/bundle_context.rs
@@ -16,6 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
+use celix_bundle_context_t;
+use celix_bundleContext_log;
 use celix_log_level_CELIX_LOG_LEVEL_INFO;
 
 pub trait BundleContext {
@@ -44,7 +47,13 @@ impl BundleContext for BundleContextImpl {
 
     fn log_info(&self, message: &str) {
         unsafe {
-            celix_bundleContext_log(self.c_bundle_context, 
celix_log_level_CELIX_LOG_LEVEL_INFO as u32, message.as_ptr() as *const i8);
+            //wrap str into CString to ensure null-terminated string
+            let c_str = std::ffi::CString::new(message).unwrap();
+            celix_bundleContext_log(self.c_bundle_context, 
celix_log_level_CELIX_LOG_LEVEL_INFO as u32, c_str.as_ptr() as *const i8);
         }
     }
 }
+
+pub fn create_bundle_context_instance(c_bundle_context: *mut 
celix_bundle_context_t) -> Box<dyn BundleContext> {
+    Box::new(BundleContextImpl::new(c_bundle_context))
+}
diff --git a/misc/experimental/rust/celix_bindings/src/lib.rs 
b/misc/experimental/rust/celix_bindings/src/celix/errno.rs
similarity index 52%
copy from misc/experimental/rust/celix_bindings/src/lib.rs
copy to misc/experimental/rust/celix_bindings/src/celix/errno.rs
index 2e6588d3..ea164b5b 100644
--- a/misc/experimental/rust/celix_bindings/src/lib.rs
+++ b/misc/experimental/rust/celix_bindings/src/celix/errno.rs
@@ -17,30 +17,29 @@
  * under the License.
  */
 
-#[allow(non_camel_case_types, non_snake_case, non_upper_case_globals, 
dead_code)]
-mod bindings {
-     include!(concat!(env!("OUT_DIR"), "/celix_bindings.rs"));
-}
-pub use bindings::*;
-
-//Note C #defines (compile-time constants) are not all generated in the 
bindings.
-pub const CELIX_SUCCESS: celix_status_t = 0;
-pub const CELIX_BUNDLE_EXCEPTION: celix_status_t = 70001;
+use celix_status_t;
 
-pub mod celix {
-    use celix_status_t;
-    use CELIX_SUCCESS;
-    use CELIX_BUNDLE_EXCEPTION;
+pub const BUNDLE_EXCEPTION: celix_status_t = 70001; //TODO move to 
celix_status_t_CELIX_BUNDLE_EXCEPTION
 
-    use celix_bundle_context_t;
-    use celix_bundleContext_log;
+pub enum Error {
+    BundleException,
+    CelixStatusError(celix_status_t), // Represent unexpected C API errors
+}
 
-    use celix_log_helper_t;
-    use celix_logHelper_create;
-    use celix_logHelper_log;
-    use celix_logHelper_destroy;
+impl From<celix_status_t> for Error {
+    fn from(status: celix_status_t) -> Self {
+        match status {
+            BUNDLE_EXCEPTION => Error::BundleException,
+            _ => Error::CelixStatusError(status),
+        }
+    }
+}
 
-    include!("BundleContext.rs");
-    include!("BundleActivator.rs");
-    include!("LogHelper.rs");
+impl Into<celix_status_t> for Error {
+    fn into(self) -> celix_status_t {
+        match self {
+            Error::BundleException => BUNDLE_EXCEPTION,
+            Error::CelixStatusError(status) => status,
+        }
+    }
 }
diff --git a/misc/experimental/rust/celix_bindings/src/LogHelper.rs 
b/misc/experimental/rust/celix_bindings/src/celix/log_helper.rs
similarity index 93%
rename from misc/experimental/rust/celix_bindings/src/LogHelper.rs
rename to misc/experimental/rust/celix_bindings/src/celix/log_helper.rs
index b168b80c..9f0a43b2 100644
--- a/misc/experimental/rust/celix_bindings/src/LogHelper.rs
+++ b/misc/experimental/rust/celix_bindings/src/celix/log_helper.rs
@@ -17,6 +17,12 @@
  * under the License.
  */
 
+use ::celix::BundleContext;
+use celix_log_helper_t;
+use celix_logHelper_create;
+use celix_logHelper_destroy;
+use celix_logHelper_log;
+
 #[warn(unused_imports)]
 pub enum LogLevel {
     Trace = ::bindings::celix_log_level_CELIX_LOG_LEVEL_TRACE as isize,
@@ -27,7 +33,7 @@ pub enum LogLevel {
     Fatal = ::bindings::celix_log_level_CELIX_LOG_LEVEL_FATAL as isize,
 }
 
-struct LogHelper {
+pub struct LogHelper {
     celix_log_helper: *mut celix_log_helper_t,
 }
 
diff --git a/misc/experimental/rust/celix_bindings/src/lib.rs 
b/misc/experimental/rust/celix_bindings/src/celix/mod.rs
similarity index 58%
copy from misc/experimental/rust/celix_bindings/src/lib.rs
copy to misc/experimental/rust/celix_bindings/src/celix/mod.rs
index 2e6588d3..e0c30e20 100644
--- a/misc/experimental/rust/celix_bindings/src/lib.rs
+++ b/misc/experimental/rust/celix_bindings/src/celix/mod.rs
@@ -17,30 +17,25 @@
  * under the License.
  */
 
-#[allow(non_camel_case_types, non_snake_case, non_upper_case_globals, 
dead_code)]
-mod bindings {
-     include!(concat!(env!("OUT_DIR"), "/celix_bindings.rs"));
-}
-pub use bindings::*;
+use celix_status_t;
 
-//Note C #defines (compile-time constants) are not all generated in the 
bindings.
+//Note C #defines (compile-time constants) are not all generated in the 
bindings file.
+//So introduce them here as constants.
 pub const CELIX_SUCCESS: celix_status_t = 0;
-pub const CELIX_BUNDLE_EXCEPTION: celix_status_t = 70001;
 
-pub mod celix {
-    use celix_status_t;
-    use CELIX_SUCCESS;
-    use CELIX_BUNDLE_EXCEPTION;
+mod errno;
+// Export errno types in the public API.
+pub use self::errno::Error as Error;
 
-    use celix_bundle_context_t;
-    use celix_bundleContext_log;
+mod bundle_context;
+// Export bundle context types in the public API.
+pub use self::bundle_context::BundleContext as BundleContext;
+pub use self::bundle_context::create_bundle_context_instance as 
create_bundle_context_instance;
 
-    use celix_log_helper_t;
-    use celix_logHelper_create;
-    use celix_logHelper_log;
-    use celix_logHelper_destroy;
+mod bundle_activator;
+// Export bundle activator types in the public API.
+pub use self::bundle_activator::BundleActivator as BundleActivator;
 
-    include!("BundleContext.rs");
-    include!("BundleActivator.rs");
-    include!("LogHelper.rs");
-}
+// mod log_helper;
+// // Export log helper types in the public API.
+// pub use self::log_helper::LogHelper as LogHelper;
diff --git a/misc/experimental/rust/celix_bindings/src/lib.rs 
b/misc/experimental/rust/celix_bindings/src/lib.rs
index 2e6588d3..a07ac3ea 100644
--- a/misc/experimental/rust/celix_bindings/src/lib.rs
+++ b/misc/experimental/rust/celix_bindings/src/lib.rs
@@ -23,24 +23,4 @@ mod bindings {
 }
 pub use bindings::*;
 
-//Note C #defines (compile-time constants) are not all generated in the 
bindings.
-pub const CELIX_SUCCESS: celix_status_t = 0;
-pub const CELIX_BUNDLE_EXCEPTION: celix_status_t = 70001;
-
-pub mod celix {
-    use celix_status_t;
-    use CELIX_SUCCESS;
-    use CELIX_BUNDLE_EXCEPTION;
-
-    use celix_bundle_context_t;
-    use celix_bundleContext_log;
-
-    use celix_log_helper_t;
-    use celix_logHelper_create;
-    use celix_logHelper_log;
-    use celix_logHelper_destroy;
-
-    include!("BundleContext.rs");
-    include!("BundleActivator.rs");
-    include!("LogHelper.rs");
-}
+pub mod celix;
diff --git a/misc/experimental/rust/hello_world_activator/src/lib.rs 
b/misc/experimental/rust/hello_world_activator/src/lib.rs
index 89b6d78c..25390ddf 100644
--- a/misc/experimental/rust/hello_world_activator/src/lib.rs
+++ b/misc/experimental/rust/hello_world_activator/src/lib.rs
@@ -19,31 +19,27 @@
 
 extern crate celix_bindings;
 
-use std::os::raw::c_void;
-use std::ffi::CString;
-use std::ffi::NulError;
-
-//TODO try to remove celix_bindings use statement
 use celix_bindings::*; //Add all Apache Celix C bindings to the namespace 
(i.e. celix_bundleContext_log, etc.)
 use celix::BundleActivator;
 use celix::BundleContext;
+use celix::Error;
 
 struct HelloWorldBundle {}
 
 impl BundleActivator for HelloWorldBundle {
     fn new(ctx: &mut dyn celix::BundleContext) -> Self {
         ctx.log_info("Hello World Bundle Activator created");
-        HelloWorldBundle {}
+        HelloWorldBundle{}
     }
 
-    fn start(&mut self, ctx: &mut dyn BundleContext) -> celix_status_t {
+    fn start(&mut self, ctx: &mut dyn BundleContext) -> Result<(), Error> {
         ctx.log_info("Hello World Bundle Activator started");
-        CELIX_SUCCESS
+        Ok(())
     }
 
-    fn stop(&mut self, ctx: &mut dyn BundleContext) -> celix_status_t {
+    fn stop(&mut self, ctx: &mut dyn BundleContext) -> Result<(), Error> {
         ctx.log_info("Hello World Bundle Activator stopped");
-        CELIX_SUCCESS
+        Ok(())
     }
 }
 

Reply via email to