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 21b00277b2fb052eac308a6c002df7512c969ab4
Author: Pepijn Noltes <pepijnnol...@gmail.com>
AuthorDate: Sun Aug 20 19:33:32 2023 +0200

    #599: Refactor rust celix lib and add LogHelper to rust celix lib
---
 misc/experimental/rust/celix/Cargo.toml            |   7 +-
 .../rust/celix/src/bundle_activator.rs             |  70 +++++++--------
 misc/experimental/rust/celix/src/bundle_context.rs |  58 +++++++++---
 misc/experimental/rust/celix/src/errno.rs          |  11 ++-
 .../experimental/rust/celix/src/{mod.rs => lib.rs} |  34 ++++---
 misc/experimental/rust/celix/src/log_helper.rs     | 100 +++++++++++++--------
 misc/experimental/rust/celix/src/log_level.rs      |  64 +++++++++++++
 .../rust/hello_world_activator/Cargo.toml          |   2 +-
 .../rust/hello_world_activator/src/lib.rs          |  27 +++---
 9 files changed, 252 insertions(+), 121 deletions(-)

diff --git a/misc/experimental/rust/celix/Cargo.toml 
b/misc/experimental/rust/celix/Cargo.toml
index d81416c8..4ae42766 100644
--- a/misc/experimental/rust/celix/Cargo.toml
+++ b/misc/experimental/rust/celix/Cargo.toml
@@ -16,14 +16,13 @@
 # under the License.
 
 [package]
-name = "celixs"
+name = "celix"
 version = "0.0.1"
 
-[build-dependencies]
+[dependencies]
 celix_bindings = { path = "../celix_bindings" }
 
-
 [lib]
-name = "bindings"
+name = "celix"
 path = "src/lib.rs"
 crate-type = ["rlib"]
diff --git a/misc/experimental/rust/celix/src/bundle_activator.rs 
b/misc/experimental/rust/celix/src/bundle_activator.rs
index 01dece71..11fa22a3 100644
--- a/misc/experimental/rust/celix/src/bundle_activator.rs
+++ b/misc/experimental/rust/celix/src/bundle_activator.rs
@@ -17,52 +17,41 @@
  * under the License.
  */
 
-use ::celix::BundleContext;
-use ::celix::Error;
+use std::sync::Arc;
+
+use super::BundleContext;
+use super::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(())}
+    fn new(ctx: Arc<dyn BundleContext>) -> Self;
+    fn start(&mut self) -> Result<(), Error> { /* Default implementation */ 
Ok(())}
+    fn stop(&mut self) -> 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,
+            ctx: *mut $crate::details::CBundleContext,
             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
+        ) -> $crate::details::CStatus {
+            let boxed_context = $crate::bundle_context_new(ctx);
+            let mut arc_context = Arc::from(boxed_context);
+            let activator = <$activator>::new(arc_context);
+            *out = Box::into_raw(Box::new(activator)) as *mut 
::std::ffi::c_void;
+            $crate::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);
+            ctx: *mut $crate::details::CBundleContext,
+        ) -> $crate::details::CStatus {
+            let activator = &mut *(handle as *mut $activator);
+            let result = activator.start();
             match result {
-                Ok(_) => $crate::celix::CELIX_SUCCESS,
+                Ok(_) => $crate::CELIX_SUCCESS,
                 Err(e) => e.into(),
             }
         }
@@ -70,23 +59,24 @@ macro_rules! generate_bundle_activator {
         #[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);
+            ctx: *mut $crate::details::CBundleContext,
+        ) -> $crate::details::CStatus {
+            let activator = &mut *(handle as *mut $activator);
+            let result = activator.stop();
             match result {
-                Ok(_) => $crate::celix::CELIX_SUCCESS,
+                Ok(_) => $crate::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
+            handle: *mut ::std::ffi::c_void,
+            _ctx: *mut $crate::details::CBundleContext,
+        ) -> $crate::details::CStatus {
+            let reclaimed_activator = Box::from_raw(handle as *mut $activator);
+            drop(reclaimed_activator);
+            $crate::CELIX_SUCCESS
         }
     };
 }
diff --git a/misc/experimental/rust/celix/src/bundle_context.rs 
b/misc/experimental/rust/celix/src/bundle_context.rs
index b63ae497..4bfacce2 100644
--- a/misc/experimental/rust/celix/src/bundle_context.rs
+++ b/misc/experimental/rust/celix/src/bundle_context.rs
@@ -17,18 +17,31 @@
  * under the License.
  */
 
-use celix_bundle_context_t;
-use celix_bundleContext_log;
-use celix_log_level_CELIX_LOG_LEVEL_INFO;
+use super::LogLevel;
+
+use celix_bindings::celix_bundle_context_t;
+use celix_bindings::celix_bundleContext_log;
+use celix_bindings::celix_log_level_e;
 
 pub trait BundleContext {
     fn get_c_bundle_context(&self) -> *mut celix_bundle_context_t;
 
+    fn log(&self, level: LogLevel, message: &str);
+
+    fn log_trace(&self, message: &str);
+
+    fn log_debug(&self, message: &str);
+
     fn log_info(&self, message: &str);
+
+    fn log_warning(&self, message: &str);
+
+    fn log_error(&self, message: &str);
+
+    fn log_fatal(&self, message: &str);
 }
 
-//note BundleContextImpl is pub for usage in bundle activator macro. TODO 
check if this can be avoided
-pub struct BundleContextImpl {
+struct BundleContextImpl {
     c_bundle_context: *mut celix_bundle_context_t,
 }
 
@@ -38,6 +51,19 @@ impl BundleContextImpl {
             c_bundle_context,
         }
     }
+    fn log_to_c(&self, level: LogLevel, message: &str) {
+        unsafe {
+            let result = std::ffi::CString::new(message);
+            match result {
+                Ok(c_str) => {
+                    celix_bundleContext_log(self.c_bundle_context, 
level.into(), c_str.as_ptr() as *const i8);
+                }
+                Err(e) => {
+                    println!("Error creating CString: {}", e);
+                }
+            }
+        }
+    }
 }
 
 impl BundleContext for BundleContextImpl {
@@ -45,15 +71,21 @@ impl BundleContext for BundleContextImpl {
         self.c_bundle_context
     }
 
-    fn log_info(&self, message: &str) {
-        unsafe {
-            //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);
-        }
-    }
+    fn log(&self, level: LogLevel, message: &str) { self.log_to_c(level, 
message); }
+
+    fn log_trace(&self, message: &str) { self.log(LogLevel::Trace, message); }
+
+    fn log_debug(&self, message: &str) { self.log(LogLevel::Debug, message); }
+
+    fn log_info(&self, message: &str) { self.log(LogLevel::Info, message); }
+
+    fn log_warning(&self, message: &str) { self.log(LogLevel::Warning, 
message); }
+
+    fn log_error(&self, message: &str){ self.log(LogLevel::Error, message); }
+
+    fn log_fatal(&self, message: &str){ self.log(LogLevel::Fatal, message); }
 }
 
-pub fn create_bundle_context_instance(c_bundle_context: *mut 
celix_bundle_context_t) -> Box<dyn BundleContext> {
+pub fn bundle_context_new(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/src/errno.rs 
b/misc/experimental/rust/celix/src/errno.rs
index ea164b5b..a8037866 100644
--- a/misc/experimental/rust/celix/src/errno.rs
+++ b/misc/experimental/rust/celix/src/errno.rs
@@ -17,13 +17,18 @@
  * under the License.
  */
 
-use celix_status_t;
+use celix_bindings::celix_status_t;
+
+pub const CELIX_SUCCESS: celix_status_t = celix_bindings::CELIX_SUCCESS as 
celix_status_t;
+
+//Note compile-time defined constants are not available in rust generated 
bindings, so
+//these are defined with literal values.
+pub const BUNDLE_EXCEPTION: celix_status_t = 70001;
 
-pub const BUNDLE_EXCEPTION: celix_status_t = 70001; //TODO move to 
celix_status_t_CELIX_BUNDLE_EXCEPTION
 
 pub enum Error {
     BundleException,
-    CelixStatusError(celix_status_t), // Represent unexpected C API errors
+    CelixStatusError(celix_status_t), // Represent not explicitly mapped 
celix_status_t values
 }
 
 impl From<celix_status_t> for Error {
diff --git a/misc/experimental/rust/celix/src/mod.rs 
b/misc/experimental/rust/celix/src/lib.rs
similarity index 50%
rename from misc/experimental/rust/celix/src/mod.rs
rename to misc/experimental/rust/celix/src/lib.rs
index e0c30e20..791a3cda 100644
--- a/misc/experimental/rust/celix/src/mod.rs
+++ b/misc/experimental/rust/celix/src/lib.rs
@@ -17,25 +17,37 @@
  * under the License.
  */
 
-use celix_status_t;
+extern crate celix_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;
+// Re-export the celix_status_t and celix_bundle_context_t C API in this crate 
public API so that
+// it can be used in the generate_bundle_activator macro.
+// Note that as result the celix rust lib is leaking the celix_status_t and 
celix_bundle_context_t
+// C API in its public API.
+#[doc(hidden)]
+pub mod details {
+    pub use celix_bindings::celix_status_t as CStatus;
+    pub use celix_bindings::celix_bundle_context_t as CBundleContext;
+}
 
 mod errno;
-// Export errno types in the public API.
+// Re-export errno types in the public API.
+pub use self::errno::CELIX_SUCCESS as CELIX_SUCCESS;
 pub use self::errno::Error as Error;
 
+mod log_level;
+// Re-export log level types in the public API.
+pub use self::log_level::LogLevel as LogLevel;
+
 mod bundle_context;
-// Export bundle context types in the public API.
+// Re-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;
+pub use self::bundle_context::bundle_context_new as bundle_context_new;
 
 mod bundle_activator;
-// Export bundle activator types in the public API.
+// Re-export bundle activator types in the public API.
 pub use self::bundle_activator::BundleActivator as BundleActivator;
 
-// mod log_helper;
-// // Export log helper types in the public API.
-// pub use self::log_helper::LogHelper as LogHelper;
+mod log_helper;
+// Re-export log helper types in the public API.
+pub use self::log_helper::LogHelper as LogHelper;
+pub use self::log_helper::log_helper_new as log_helper_new;
diff --git a/misc/experimental/rust/celix/src/log_helper.rs 
b/misc/experimental/rust/celix/src/log_helper.rs
index 9f0a43b2..488c6277 100644
--- a/misc/experimental/rust/celix/src/log_helper.rs
+++ b/misc/experimental/rust/celix/src/log_helper.rs
@@ -17,68 +17,92 @@
  * under the License.
  */
 
-use ::celix::BundleContext;
-use celix_log_helper_t;
-use celix_logHelper_create;
-use celix_logHelper_destroy;
-use celix_logHelper_log;
+use super::LogLevel;
+use super::BundleContext;
 
-#[warn(unused_imports)]
-pub enum LogLevel {
-    Trace = ::bindings::celix_log_level_CELIX_LOG_LEVEL_TRACE as isize,
-    Debug = ::bindings::celix_log_level_CELIX_LOG_LEVEL_DEBUG as isize,
-    Info = ::bindings::celix_log_level_CELIX_LOG_LEVEL_INFO as isize,
-    Warn = ::bindings::celix_log_level_CELIX_LOG_LEVEL_WARNING as isize,
-    Error = ::bindings::celix_log_level_CELIX_LOG_LEVEL_ERROR as isize,
-    Fatal = ::bindings::celix_log_level_CELIX_LOG_LEVEL_FATAL as isize,
-}
-
-pub struct LogHelper {
-    celix_log_helper: *mut celix_log_helper_t,
-}
-
-impl LogHelper {
-    pub fn new(ctx: &dyn BundleContext, name: &str) -> Self {
-        LogHelper {
-            celix_log_helper: unsafe { 
celix_logHelper_create(ctx.get_c_bundle_context(), name.as_ptr() as *const i8) 
},
-        }
-    }
+use celix_bindings::celix_log_helper_t;
+use celix_bindings::celix_logHelper_create;
+use celix_bindings::celix_logHelper_destroy;
+use celix_bindings::celix_logHelper_log;
 
-    pub fn log(&self, level: LogLevel, message: &str) {
-        unsafe {
-            celix_logHelper_log(self.celix_log_helper, level as u32, 
message.as_ptr() as *const i8);
-        }
-    }
+pub trait LogHelper {
+    fn log(&self, level: LogLevel, message: &str);
 
-    pub fn trace(&self, message: &str) {
+    fn trace(&self, message: &str) {
         self.log(LogLevel::Trace, message);
     }
 
-    pub fn debug(&self, message: &str) {
+    fn debug(&self, message: &str) {
         self.log(LogLevel::Debug, message);
     }
 
-    pub fn info(&self, message: &str) {
+    fn info(&self, message: &str) {
         self.log(LogLevel::Info, message);
     }
 
-    pub fn warn(&self, message: &str) {
-        self.log(LogLevel::Warn, message);
+    fn warning(&self, message: &str) {
+        self.log(LogLevel::Warning, message);
     }
 
-    pub fn error(&self, message: &str) {
+    fn error(&self, message: &str) {
         self.log(LogLevel::Error, message);
     }
 
-    pub fn fatal(&self, message: &str) {
+    fn fatal(&self, message: &str) {
         self.log(LogLevel::Fatal, message);
     }
 }
 
-impl Drop for LogHelper {
+struct LogHelperImpl {
+    celix_log_helper: *mut celix_log_helper_t,
+}
+
+impl  LogHelperImpl {
+    pub fn new(ctx: &dyn BundleContext, name: &str) -> Self {
+        unsafe {
+            let result = std::ffi::CString::new(name);
+            match result {
+                Ok(c_str) => {
+                    LogHelperImpl {
+                        celix_log_helper: 
celix_logHelper_create(ctx.get_c_bundle_context(), c_str.as_ptr() as *const i8),
+                    }
+                }
+                Err(e) => {
+                    ctx.log_error(&format!("Error creating CString: {}. Using 
\"error\" as log name", e));
+                    let c_str = std::ffi::CString::new("error").unwrap();
+                    LogHelperImpl {
+                        celix_log_helper: 
celix_logHelper_create(ctx.get_c_bundle_context(), c_str.as_ptr() as *const i8),
+                    }
+                }
+            }
+        }
+    }
+}
+
+impl Drop for LogHelperImpl {
     fn drop(&mut self) {
         unsafe {
             celix_logHelper_destroy(self.celix_log_helper);
         }
     }
 }
+
+impl LogHelper for LogHelperImpl {
+    fn log(&self, level: LogLevel, message: &str) {
+        unsafe {
+            let result = std::ffi::CString::new(message);
+            match result {
+                Ok(c_str) => {
+                    celix_logHelper_log(self.celix_log_helper, level.into(), 
c_str.as_ptr() as *const i8);
+                }
+                Err(e) => {
+                    println!("Error creating CString: {}", e);
+                }
+            }
+        }
+    }
+}
+
+pub fn log_helper_new(ctx: &dyn BundleContext, name: &str) -> Box<dyn 
LogHelper> {
+    Box::new(LogHelperImpl::new(ctx, name))
+}
diff --git a/misc/experimental/rust/celix/src/log_level.rs 
b/misc/experimental/rust/celix/src/log_level.rs
new file mode 100644
index 00000000..d2b22470
--- /dev/null
+++ b/misc/experimental/rust/celix/src/log_level.rs
@@ -0,0 +1,64 @@
+/*
+ * 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_bindings::celix_log_level_e;
+use celix_bindings::celix_log_level_CELIX_LOG_LEVEL_TRACE;
+use celix_bindings::celix_log_level_CELIX_LOG_LEVEL_DEBUG;
+use celix_bindings::celix_log_level_CELIX_LOG_LEVEL_INFO;
+use celix_bindings::celix_log_level_CELIX_LOG_LEVEL_WARNING;
+use celix_bindings::celix_log_level_CELIX_LOG_LEVEL_ERROR;
+use celix_bindings::celix_log_level_CELIX_LOG_LEVEL_FATAL;
+use celix_bindings::celix_log_level_CELIX_LOG_LEVEL_DISABLED;
+
+pub enum LogLevel {
+    Trace,
+    Debug,
+    Info,
+    Warning,
+    Error,
+    Fatal,
+    Disabled
+}
+impl From<celix_log_level_e> for LogLevel {
+    fn from(level: celix_log_level_e) -> Self {
+        match level {
+            celix_log_level_CELIX_LOG_LEVEL_TRACE => LogLevel::Trace,
+            celix_log_level_CELIX_LOG_LEVEL_DEBUG => LogLevel::Debug,
+            celix_log_level_CELIX_LOG_LEVEL_INFO => LogLevel::Info,
+            celix_log_level_CELIX_LOG_LEVEL_WARNING => LogLevel::Warning,
+            celix_log_level_CELIX_LOG_LEVEL_ERROR => LogLevel::Error,
+            celix_log_level_CELIX_LOG_LEVEL_FATAL => LogLevel::Fatal,
+            _ => LogLevel::Disabled,
+        }
+    }
+}
+
+impl Into<celix_log_level_e> for LogLevel {
+    fn into(self) -> celix_log_level_e {
+        match self {
+            LogLevel::Trace => celix_log_level_CELIX_LOG_LEVEL_TRACE,
+            LogLevel::Debug => celix_log_level_CELIX_LOG_LEVEL_DEBUG,
+            LogLevel::Info => celix_log_level_CELIX_LOG_LEVEL_INFO,
+            LogLevel::Warning => celix_log_level_CELIX_LOG_LEVEL_WARNING,
+            LogLevel::Error => celix_log_level_CELIX_LOG_LEVEL_ERROR,
+            LogLevel::Fatal => celix_log_level_CELIX_LOG_LEVEL_FATAL,
+            _ => celix_log_level_CELIX_LOG_LEVEL_DISABLED,
+        }
+    }
+}
diff --git a/misc/experimental/rust/hello_world_activator/Cargo.toml 
b/misc/experimental/rust/hello_world_activator/Cargo.toml
index 6202ece9..191c5e96 100644
--- a/misc/experimental/rust/hello_world_activator/Cargo.toml
+++ b/misc/experimental/rust/hello_world_activator/Cargo.toml
@@ -20,7 +20,7 @@ name = "rust_bundle"
 version = "0.0.1"
 
 [dependencies]
-celix_bindings = { path = "../celix_bindings" }
+celix = { path = "../celix" }
 
 [lib]
 name = "rust_bundle_activator"
diff --git a/misc/experimental/rust/hello_world_activator/src/lib.rs 
b/misc/experimental/rust/hello_world_activator/src/lib.rs
index 25390ddf..93c676ef 100644
--- a/misc/experimental/rust/hello_world_activator/src/lib.rs
+++ b/misc/experimental/rust/hello_world_activator/src/lib.rs
@@ -17,36 +17,41 @@
  * under the License.
  */
 
-extern crate celix_bindings;
+extern crate celix;
+
+use std::sync::Arc;
 
-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 {}
+struct HelloWorldBundle {
+    ctx: Arc<dyn BundleContext>,
+}
 
 impl BundleActivator for HelloWorldBundle {
-    fn new(ctx: &mut dyn celix::BundleContext) -> Self {
+    fn new(ctx: Arc<dyn celix::BundleContext>) -> Self {
         ctx.log_info("Hello World Bundle Activator created");
-        HelloWorldBundle{}
+        HelloWorldBundle{
+            ctx,
+        }
     }
 
-    fn start(&mut self, ctx: &mut dyn BundleContext) -> Result<(), Error> {
-        ctx.log_info("Hello World Bundle Activator started");
+    fn start(&mut self) -> Result<(), Error> {
+        self.ctx.log_info("Hello World Bundle Activator started");
         Ok(())
     }
 
-    fn stop(&mut self, ctx: &mut dyn BundleContext) -> Result<(), Error> {
-        ctx.log_info("Hello World Bundle Activator stopped");
+    fn stop(&mut self) -> Result<(), Error> {
+        self.ctx.log_info("Hello World Bundle Activator stopped");
         Ok(())
     }
 }
 
 impl Drop for HelloWorldBundle {
     fn drop(&mut self) {
-        //TODO self.ctx.log_info("Hello World Bundle Activator dropped");
+        self.ctx.log_info("Hello World Bundle Activator destroyed");
     }
 }
 
-generate_bundle_activator!(HelloWorldBundle);
\ No newline at end of file
+celix::generate_bundle_activator!(HelloWorldBundle);

Reply via email to