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 dd13817198a35c91ce6f3604fa98d0c5892d5b8c Author: Pepijn Noltes <pepijnnol...@gmail.com> AuthorDate: Tue Aug 22 20:53:49 2023 +0200 #599: Refactor rust log helper --- misc/experimental/rust/celix/src/bundle_context.rs | 4 +- misc/experimental/rust/celix/src/lib.rs | 1 - misc/experimental/rust/celix/src/log_helper.rs | 84 ++++++++++------------ .../rust/shell_command_bundle/src/lib.rs | 68 +++++++++++++----- 4 files changed, 91 insertions(+), 66 deletions(-) diff --git a/misc/experimental/rust/celix/src/bundle_context.rs b/misc/experimental/rust/celix/src/bundle_context.rs index 5ff380a4..5d2841d8 100644 --- a/misc/experimental/rust/celix/src/bundle_context.rs +++ b/misc/experimental/rust/celix/src/bundle_context.rs @@ -40,7 +40,7 @@ use super::LogLevel; pub struct ServiceRegistration { service_id: i64, weak_ctx: Weak<BundleContextImpl>, - boxed_svc: Option<Box<dyn Any>>, + _boxed_svc: Option<Box<dyn Any>>, // arc_svc: Option<Arc<dyn Any>>, } @@ -194,7 +194,7 @@ impl ServiceRegistrationBuilder<'_> { Ok(ServiceRegistration { service_id, weak_ctx: self.ctx.get_self().clone(), - boxed_svc: self.boxed_svc.take(), //to ensure that a possible box instance is not dropped + _boxed_svc: self.boxed_svc.take(), //to ensure that a possible box instance is not dropped // arc_svc: self.arc_svc.take(), //to ensure that a possible arc instance is not dropped }) } else { diff --git a/misc/experimental/rust/celix/src/lib.rs b/misc/experimental/rust/celix/src/lib.rs index 9befdeb8..b5d5dc57 100644 --- a/misc/experimental/rust/celix/src/lib.rs +++ b/misc/experimental/rust/celix/src/lib.rs @@ -51,4 +51,3 @@ pub use self::bundle_activator::BundleActivator as BundleActivator; 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 488c6277..2af5656c 100644 --- a/misc/experimental/rust/celix/src/log_helper.rs +++ b/misc/experimental/rust/celix/src/log_helper.rs @@ -17,6 +17,8 @@ * under the License. */ +use std::sync::Arc; + use super::LogLevel; use super::BundleContext; @@ -24,71 +26,32 @@ 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 trait LogHelper { - fn log(&self, level: LogLevel, message: &str); - - fn trace(&self, message: &str) { - self.log(LogLevel::Trace, message); - } - - fn debug(&self, message: &str) { - self.log(LogLevel::Debug, message); - } - - fn info(&self, message: &str) { - self.log(LogLevel::Info, message); - } - - fn warning(&self, message: &str) { - self.log(LogLevel::Warning, message); - } - - fn error(&self, message: &str) { - self.log(LogLevel::Error, message); - } - - fn fatal(&self, message: &str) { - self.log(LogLevel::Fatal, message); - } -} - -struct LogHelperImpl { +pub struct LogHelper { celix_log_helper: *mut celix_log_helper_t, } -impl LogHelperImpl { - pub fn new(ctx: &dyn BundleContext, name: &str) -> Self { +impl LogHelper { + pub fn new(ctx: Arc<dyn BundleContext>, name: &str) -> Self { unsafe { let result = std::ffi::CString::new(name); match result { Ok(c_str) => { - LogHelperImpl { + LogHelper { 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 { + LogHelper { 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) { + pub fn log(&self, level: LogLevel, message: &str) { unsafe { let result = std::ffi::CString::new(message); match result { @@ -101,8 +64,35 @@ impl LogHelper for LogHelperImpl { } } } + pub fn trace(&self, message: &str) { + self.log(LogLevel::Trace, message); + } + + pub fn debug(&self, message: &str) { + self.log(LogLevel::Debug, message); + } + + pub fn info(&self, message: &str) { + self.log(LogLevel::Info, message); + } + + pub fn warning(&self, message: &str) { + self.log(LogLevel::Warning, message); + } + + pub fn error(&self, message: &str) { + self.log(LogLevel::Error, message); + } + + pub fn fatal(&self, message: &str) { + self.log(LogLevel::Fatal, message); + } } -pub fn log_helper_new(ctx: &dyn BundleContext, name: &str) -> Box<dyn LogHelper> { - Box::new(LogHelperImpl::new(ctx, name)) +impl Drop for LogHelper { + fn drop(&mut self) { + unsafe { + celix_logHelper_destroy(self.celix_log_helper); + } + } } diff --git a/misc/experimental/rust/shell_command_bundle/src/lib.rs b/misc/experimental/rust/shell_command_bundle/src/lib.rs index cc9b83f9..1ed3b04d 100644 --- a/misc/experimental/rust/shell_command_bundle/src/lib.rs +++ b/misc/experimental/rust/shell_command_bundle/src/lib.rs @@ -31,18 +31,15 @@ use celix::Error; use celix_bindings::celix_shell_command_t; use celix_bindings::FILE; -//temporary, should be moved in a separate API crate -// trait RustShellCommand { -// fn execute_command(&mut self, command_line: &str, command_args: Vec<&str>) -> Result<(), Error>; -// } -struct ShellCommandProvider { +struct CShellCommandImpl { ctx: Arc<dyn BundleContext>, } -impl ShellCommandProvider { + +impl CShellCommandImpl { fn new(ctx: Arc<dyn BundleContext>) -> Self { ctx.log_info("Shell Command created"); - ShellCommandProvider{ + CShellCommandImpl { ctx, } } @@ -53,7 +50,7 @@ impl ShellCommandProvider { } unsafe { println!("call_execute_command"); - let obj = &mut *(handle as *mut ShellCommandProvider); + let obj = &mut *(handle as *mut CShellCommandImpl); let str_command_line = std::ffi::CStr::from_ptr(command_line).to_str().unwrap(); obj.execute_command(str_command_line); } @@ -65,40 +62,79 @@ impl ShellCommandProvider { } } +//temporary, should be moved in a separate API crate +trait RustShellCommand { + fn execute_command(&mut self, command_line: &str) -> Result<(), Error>; +} + +struct RustShellCommandImpl { + ctx: Arc<dyn BundleContext>, +} + +impl RustShellCommandImpl { + fn new(ctx: Arc<dyn BundleContext>) -> Self { + ctx.log_info("Rust Shell Command created"); + RustShellCommandImpl { + ctx, + } + } +} + +impl RustShellCommand for RustShellCommandImpl { + fn execute_command(&mut self, command_line: &str) -> Result<(), Error> { + self.ctx.log_info(format!("Execute command: {}.", command_line).as_str()); + Ok(()) + } +} + struct ShellCommandActivator { ctx: Arc<dyn BundleContext>, //log_helper: Box<dyn LogHelper>, - shell_command_provider: ShellCommandProvider, - registration: Option<celix::ServiceRegistration>, + shell_command_provider: CShellCommandImpl, + c_registration: Option<celix::ServiceRegistration>, + rust_registration: Option<celix::ServiceRegistration>, } impl BundleActivator for ShellCommandActivator { fn new(ctx: Arc<dyn celix::BundleContext>) -> Self { let result = ShellCommandActivator { ctx: ctx.clone(), - shell_command_provider: ShellCommandProvider::new(ctx.clone()), + shell_command_provider: CShellCommandImpl::new(ctx.clone()), //log_helper: log_helper_new(&*ctx, "ShellCommandBundle"), - registration: None, + c_registration: None, + rust_registration: None, }; result } fn start(&mut self) -> Result<(), Error> { let registration = self.ctx.register_service() .with_service( celix_shell_command_t{ - handle: &mut self.shell_command_provider as *mut ShellCommandProvider as *mut c_void, - executeCommand: Some(ShellCommandProvider::call_execute_command), + handle: &mut self.shell_command_provider as *mut CShellCommandImpl as *mut c_void, + executeCommand: Some(CShellCommandImpl::call_execute_command), }) .with_service_name("celix_shell_command") .with_property("command.name", "exe_in_rust") .with_property("command.description", "Simple command written in Rust") .build()?; - self.registration = Some(registration); + self.c_registration = Some(registration); + self.ctx.log_info("C Shell Command registered"); + + let rust_shell_command = Box::new(RustShellCommandImpl::new(self.ctx.clone())); + let registration = self.ctx.register_service() + //maybe make svc types more explicit, e.g.with type parameters + .with_service(rust_shell_command as Box<dyn RustShellCommand>) + .with_property("command.name", "exe_in_rust") + .with_property("command.description", "Simple command written in Rust") + .build()?; + self.rust_registration = Some(registration); + self.ctx.log_info("Rust Shell Command started"); Ok(()) } fn stop(&mut self) -> Result<(), Error> { - self.registration = None; + self.rust_registration = None; + self.c_registration = None; self.ctx.log_info("Rust Shell Command stopped"); Ok(()) }