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 b2e86574b52004a532c5d96468ac36252b36f954 Author: Pepijn Noltes <[email protected]> AuthorDate: Fri Aug 25 15:33:50 2023 +0200 #599: Remove BundleContext trait so that generic method are possible --- .../rust/celix/src/bundle_activator.rs | 2 +- misc/experimental/rust/celix/src/bundle_context.rs | 96 +++++++--------------- misc/experimental/rust/celix/src/log_helper.rs | 2 +- .../rust/hello_world_activator/src/lib.rs | 4 +- .../rust/shell_command_bundle/src/lib.rs | 14 ++-- 5 files changed, 42 insertions(+), 76 deletions(-) diff --git a/misc/experimental/rust/celix/src/bundle_activator.rs b/misc/experimental/rust/celix/src/bundle_activator.rs index a54ad5ea..d3050bce 100644 --- a/misc/experimental/rust/celix/src/bundle_activator.rs +++ b/misc/experimental/rust/celix/src/bundle_activator.rs @@ -23,7 +23,7 @@ use super::BundleContext; use super::Error; pub trait BundleActivator { - fn new(ctx: Arc<dyn BundleContext>) -> Self; + fn new(ctx: Arc<BundleContext>) -> Self; fn start(&mut self) -> Result<(), Error> { /* Default implementation */ Ok(()) diff --git a/misc/experimental/rust/celix/src/bundle_context.rs b/misc/experimental/rust/celix/src/bundle_context.rs index 01022fa6..56ddc69a 100644 --- a/misc/experimental/rust/celix/src/bundle_context.rs +++ b/misc/experimental/rust/celix/src/bundle_context.rs @@ -43,7 +43,7 @@ use super::LogLevel; pub struct ServiceRegistration { service_id: i64, - weak_ctx: Weak<BundleContextImpl>, + weak_ctx: Weak<BundleContext>, _boxed_svc: Option<Box<dyn Any>>, } @@ -58,20 +58,18 @@ impl Drop for ServiceRegistration { } pub struct ServiceRegistrationBuilder<'a> { - ctx: &'a BundleContextImpl, + ctx: &'a BundleContext, boxed_svc: Option<Box<dyn Any>>, - unmanaged_svc: *mut c_void, service_name: String, service_version: String, service_properties: HashMap<String, String>, } impl ServiceRegistrationBuilder<'_> { - fn new(ctx: &BundleContextImpl) -> ServiceRegistrationBuilder { + fn new(ctx: &BundleContext) -> ServiceRegistrationBuilder { ServiceRegistrationBuilder { ctx, boxed_svc: None, - unmanaged_svc: null_mut(), service_name: "".to_string(), service_version: "".to_string(), service_properties: HashMap::new(), @@ -92,22 +90,14 @@ impl ServiceRegistrationBuilder<'_> { pub fn with_service<I: 'static>(&mut self, svc: I) -> &mut Self { self.boxed_svc = Some(Box::new(svc)); - self.unmanaged_svc = null_mut(); self.with_service_name_if_not_set(type_name::<I>()) } pub fn with_boxed_service<T: ?Sized + 'static>(&mut self, svc: Box<T>) -> &mut Self { self.boxed_svc = Some(Box::new(svc)); - self.unmanaged_svc = null_mut(); self.with_service_name_if_not_set(type_name::<T>()) } - pub fn with_unmanaged_service<I>(&mut self, svc: *mut I) -> &mut Self { - self.boxed_svc = None; - self.unmanaged_svc = svc as *mut c_void; - self.with_service_name_if_not_set(type_name::<I>()) - } - pub fn with_version(&mut self, version: &str) -> &mut Self { self.service_version = version.to_string(); self @@ -131,7 +121,7 @@ impl ServiceRegistrationBuilder<'_> { .log_error("Cannot register service. Service name is empty"); valid = false; } - if self.boxed_svc.is_none() && /*self.arc_svc.is_none() &&*/ self.unmanaged_svc.is_null() { + if self.boxed_svc.is_none() /*&& self.arc_svc.is_none() */ { self.ctx .log_error("Cannot register service. No instance provided"); valid = false; @@ -147,10 +137,8 @@ impl ServiceRegistrationBuilder<'_> { let any_svc: &mut dyn Any = boxed_svc.as_mut(); let boxed_svc_ptr = any_svc as *mut dyn Any; //note box still owns the instance boxed_svc_ptr as *mut c_void - } else if self.unmanaged_svc.is_null() { - panic!("Cannot get c_svc. No instance provided"); } else { - self.unmanaged_svc + null_mut() } } @@ -184,8 +172,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 - // arc_svc: self.arc_svc.take(), //to ensure that a possible arc instance is not dropped + _boxed_svc: self.boxed_svc.take(), }) } else { Err(Error::BundleException) @@ -202,7 +189,7 @@ impl ServiceRegistrationBuilder<'_> { } pub struct ServiceUseBuilder<'a> { - ctx: &'a BundleContextImpl, + ctx: &'a BundleContext, many: bool, service_name: String, filter: String, @@ -210,7 +197,7 @@ pub struct ServiceUseBuilder<'a> { } impl ServiceUseBuilder<'_> { - fn new(ctx: &BundleContextImpl, many: bool) -> ServiceUseBuilder { + fn new(ctx: &BundleContext, many: bool) -> ServiceUseBuilder { ServiceUseBuilder { ctx, many, @@ -317,38 +304,14 @@ impl ServiceUseBuilder<'_> { } } -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); - - fn register_service(&self) -> ServiceRegistrationBuilder; - - fn use_service(&self) -> ServiceUseBuilder; - - fn use_services(&self) -> ServiceUseBuilder; -} - -struct BundleContextImpl { +pub struct BundleContext { c_bundle_context: *mut celix_bundle_context_t, - weak_self: Mutex<Option<Weak<BundleContextImpl>>>, + weak_self: Mutex<Option<Weak<BundleContext>>>, } -impl BundleContextImpl { +impl BundleContext { fn new(c_bundle_context: *mut celix_bundle_context_t) -> Arc<Self> { - let ctx = Arc::new(BundleContextImpl { + let ctx = Arc::new(BundleContext { c_bundle_context, weak_self: Mutex::new(None), }); @@ -357,12 +320,12 @@ impl BundleContextImpl { ctx } - fn set_self(&self, weak_self: Weak<BundleContextImpl>) { + fn set_self(&self, weak_self: Weak<BundleContext>) { let mut guard = self.weak_self.lock().unwrap(); *guard = Some(weak_self); } - fn get_self(&self) -> Weak<BundleContextImpl> { + fn get_self(&self) -> Weak<BundleContext> { self.weak_self.lock().unwrap().clone().unwrap() } @@ -389,54 +352,55 @@ impl BundleContextImpl { } } } -} -impl BundleContext for BundleContextImpl { - fn get_c_bundle_context(&self) -> *mut celix_bundle_context_t { + pub fn get_c_bundle_context(&self) -> *mut celix_bundle_context_t { self.c_bundle_context } - fn log(&self, level: LogLevel, message: &str) { + pub fn log(&self, level: LogLevel, message: &str) { self.log_to_c(level, message); } - fn log_trace(&self, message: &str) { + pub fn log_trace(&self, message: &str) { self.log(LogLevel::Trace, message); } - fn log_debug(&self, message: &str) { + pub fn log_debug(&self, message: &str) { self.log(LogLevel::Debug, message); } - fn log_info(&self, message: &str) { + pub fn log_info(&self, message: &str) { self.log(LogLevel::Info, message); } - fn log_warning(&self, message: &str) { + pub fn log_warning(&self, message: &str) { self.log(LogLevel::Warning, message); } - fn log_error(&self, message: &str) { + pub fn log_error(&self, message: &str) { self.log(LogLevel::Error, message); } - fn log_fatal(&self, message: &str) { + pub fn log_fatal(&self, message: &str) { self.log(LogLevel::Fatal, message); } - fn register_service(&self) -> ServiceRegistrationBuilder { + //TODO make generic + pub fn register_service(&self) -> ServiceRegistrationBuilder { ServiceRegistrationBuilder::new(self) } - fn use_service(&self) -> ServiceUseBuilder { + //TODO make generic + pub fn use_service(&self) -> ServiceUseBuilder { ServiceUseBuilder::new(self, false) } - fn use_services(&self) -> ServiceUseBuilder { + //TODO make generic + pub fn use_services(&self) -> ServiceUseBuilder { ServiceUseBuilder::new(self, true) } } -pub fn bundle_context_new(c_bundle_context: *mut celix_bundle_context_t) -> Arc<dyn BundleContext> { - BundleContextImpl::new(c_bundle_context) +pub fn bundle_context_new(c_bundle_context: *mut celix_bundle_context_t) -> Arc<BundleContext> { + BundleContext::new(c_bundle_context) } diff --git a/misc/experimental/rust/celix/src/log_helper.rs b/misc/experimental/rust/celix/src/log_helper.rs index 5c681024..64099ba5 100644 --- a/misc/experimental/rust/celix/src/log_helper.rs +++ b/misc/experimental/rust/celix/src/log_helper.rs @@ -31,7 +31,7 @@ pub struct LogHelper { } impl LogHelper { - pub fn new(ctx: Arc<dyn BundleContext>, name: &str) -> Self { + pub fn new(ctx: Arc<BundleContext>, name: &str) -> Self { unsafe { let result = std::ffi::CString::new(name); match result { diff --git a/misc/experimental/rust/hello_world_activator/src/lib.rs b/misc/experimental/rust/hello_world_activator/src/lib.rs index c9e6e861..80d7b720 100644 --- a/misc/experimental/rust/hello_world_activator/src/lib.rs +++ b/misc/experimental/rust/hello_world_activator/src/lib.rs @@ -26,11 +26,11 @@ use celix::BundleContext; use celix::Error; struct HelloWorldBundle { - ctx: Arc<dyn BundleContext>, + ctx: Arc<BundleContext>, } impl BundleActivator for HelloWorldBundle { - fn new(ctx: Arc<dyn celix::BundleContext>) -> Self { + fn new(ctx: Arc<BundleContext>) -> Self { ctx.log_info("Hello World Bundle Activator created"); HelloWorldBundle { ctx } } diff --git a/misc/experimental/rust/shell_command_bundle/src/lib.rs b/misc/experimental/rust/shell_command_bundle/src/lib.rs index 50d2905f..3856734e 100644 --- a/misc/experimental/rust/shell_command_bundle/src/lib.rs +++ b/misc/experimental/rust/shell_command_bundle/src/lib.rs @@ -35,11 +35,11 @@ use celix_bindings::celix_shell_command_t; use celix_bindings::FILE; struct CShellCommandImpl { - ctx: Arc<dyn BundleContext>, + ctx: Arc<BundleContext>, } impl CShellCommandImpl { - fn new(ctx: Arc<dyn BundleContext>) -> Self { + fn new(ctx: Arc<BundleContext>) -> Self { ctx.log_info("Shell Command created"); CShellCommandImpl { ctx } } @@ -72,11 +72,11 @@ impl CShellCommandImpl { //temporary, should be moved in a separate API crate struct RustShellCommandImpl { - ctx: Arc<dyn BundleContext>, + ctx: Arc<BundleContext>, } impl RustShellCommandImpl { - fn new(ctx: Arc<dyn BundleContext>) -> Self { + fn new(ctx: Arc<BundleContext>) -> Self { ctx.log_info("Rust Shell Command created"); RustShellCommandImpl { ctx } } @@ -91,7 +91,7 @@ impl RustShellCommandTrait for RustShellCommandImpl { } struct ShellCommandActivator { - ctx: Arc<dyn BundleContext>, + ctx: Arc<BundleContext>, //log_helper: Box<dyn LogHelper>, shell_command_provider: CShellCommandImpl, registrations: Vec<celix::ServiceRegistration>, @@ -167,6 +167,8 @@ impl ShellCommandActivator { let count = self.ctx.use_services() .with_service::<dyn RustShellCommandTrait>() .with_any_callback(Box::new( |svc: &dyn Any| { + //Mote below downcast, this is a hack. Cannot downcast to trait. + //Fixme trait service users should not need impl type (impl details) let typed_svc = svc.downcast_ref::<RustShellCommandImpl>(); if let Some(svc) = typed_svc { let _ = svc.execute_command("test"); @@ -190,7 +192,7 @@ impl ShellCommandActivator { } impl BundleActivator for ShellCommandActivator { - fn new(ctx: Arc<dyn celix::BundleContext>) -> Self { + fn new(ctx: Arc<BundleContext>) -> Self { let result = ShellCommandActivator { ctx: ctx.clone(), shell_command_provider: CShellCommandImpl::new(ctx.clone()),
