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 2f37f723797bf7e10a9e96ee71bc394742d558a7 Author: Pepijn Noltes <[email protected]> AuthorDate: Sat Aug 19 20:03:25 2023 +0200 #599: Add initial setup for rust shell tui --- misc/experimental/rust/rust_shell_tui/Cargo.toml | 28 ++++ misc/experimental/rust/rust_shell_tui/src/lib.rs | 161 +++++++++++++++++++++++ 2 files changed, 189 insertions(+) diff --git a/misc/experimental/rust/rust_shell_tui/Cargo.toml b/misc/experimental/rust/rust_shell_tui/Cargo.toml new file mode 100644 index 00000000..fb4dced0 --- /dev/null +++ b/misc/experimental/rust/rust_shell_tui/Cargo.toml @@ -0,0 +1,28 @@ +# 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. + +[package] +name = "rust_shell_tui" +version = "0.0.1" + +[dependencies] +celix_bindings = { path = "../celix_bindings" } + +[lib] +name = "rust_shell_tui_activator" +path = "src/lib.rs" +crate-type = ["cdylib"] diff --git a/misc/experimental/rust/rust_shell_tui/src/lib.rs b/misc/experimental/rust/rust_shell_tui/src/lib.rs new file mode 100644 index 00000000..08727add --- /dev/null +++ b/misc/experimental/rust/rust_shell_tui/src/lib.rs @@ -0,0 +1,161 @@ +/* + * 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. + */ + +extern crate celix_bindings; + +use std::os::raw::c_char; +use std::os::raw::c_void; +use std::ffi::CString; +use std::ffi::NulError; +use std::ptr::null_mut; +use celix_bindings::*; //Add all Apache Celix C bindings to the namespace (i.e. celix_bundleContext_log, etc.) + +// pub struct celix_shell_command { +// pub handle +// : *mut ::std ::os ::raw ::c_void, +// #[doc = +// " Calls the shell command.\n @param handle The shell command handle.\n @param commandLine The " +// "complete provided cmd line (e.g. for a 'stop' command -> 'stop 42')\n @param outStream The output " +// "stream, to use for printing normal flow info.\n @param errorStream The error stream, to use for " +// "printing error flow info.\n @return Whether a command is successfully executed."] pub +// executeCommand +// pub executeCommand : :: std :: option :: Option < unsafe extern "C" fn (handle : * mut :: std :: os :: raw :: c_void , commandLine : * const :: std :: os :: raw :: c_char , outStream : * mut FILE , errorStream : * mut FILE) -> bool > , } +// } + + +struct RustShellTui { + ctx: *mut celix_bundle_context_t, + svc_id: i64, + svc: celix_shell_command, +} + +unsafe extern "C" fn rust_shell_tui_execute_command(_handle: *mut c_void, command_line: *const c_char, out_stream: *mut FILE, error_stream: *mut FILE) -> bool { + let obj = Box::from_raw(_handle as *mut RustShellTui); + obj.execute_command(command_line, out_stream, error_stream) +} + +impl RustShellTui { + + unsafe fn new(ctx: *mut celix_bundle_context_t) -> Result<RustShellTui, NulError> { + let result = RustShellTui { + ctx, + svc_id: -1, + svc: celix_shell_command { + handle: null_mut(), + executeCommand: Some(rust_shell_tui_execute_command), + }, + }; + Ok(result) + } + + unsafe fn start(&mut self) -> Result<(), NulError> { + + // let mut input = String::new(); + // print!("-> "); + // loop { + // std::io::stdin().read_line(&mut input).unwrap(); + // println!("You typed: {}", input.trim()); + // input.clear(); + // print!("-> "); + // } + + // self.svc.executeCommand = Some(|handle: *mut c_void, commandLine: *const c_char, outStream: *mut FILE, errorStream: *mut FILE| -> bool { + // println!("RustShellTui::executeCommand called"); + // true + // }); + + //TODO let svc_name = CString::new(CELIX_SHELL_COMMAND_SERVICE_NAME as * const c_char).unwrap(); + let svc_name = CString::new("celix_shell_command").unwrap(); + + let command_name = CString::new("command.name").unwrap(); + let props = celix_properties_create(); + celix_properties_set(props, command_name.as_ptr(), CString::new("rust").unwrap().as_ptr()); + + self.svc.handle = Box::into_raw(Box::new(self.svc)) as *mut c_void; + + + self.svc_id = celix_bundleContext_registerServiceAsync( + self.ctx, + Box::into_raw(Box::new(self.svc)) as *mut c_void, + svc_name.as_ptr(), + props); + + Ok(()) + } + + unsafe fn stop(&mut self) -> Result<(), NulError> { + celix_bundleContext_unregisterService(self.ctx, self.svc_id); + self.svc_id = -1; + + // let to_drop = Box::from_raw(self.svc.handle); + // drop(to_drop); + + // TODO drop + // let to_drop = Box::from_raw(&self.svc); + // drop(to_drop); + Ok(()) + } + + fn execute_command(&self, _command_line: *const c_char, _out_stream: *mut FILE, _error_stream: *mut FILE) -> bool { + println!("RustShellTui::executeCommand called"); + true + } +} + +impl Drop for RustShellTui { + fn drop(&mut self) { () } +} + +#[no_mangle] +pub unsafe extern "C" fn celix_bundleActivator_create(ctx: *mut celix_bundle_context_t, data: *mut *mut c_void) -> celix_status_t { + let obj = RustShellTui::new(ctx); + if obj.is_err() { + return CELIX_BUNDLE_EXCEPTION; + } + *data = Box::into_raw(Box::new(obj.unwrap())) as *mut c_void; + CELIX_SUCCESS +} + +#[no_mangle] +pub unsafe extern "C" fn celix_bundleActivator_start(data: *mut c_void, _ctx: *mut celix_bundle_context_t) -> celix_status_t { + let obj = &mut *(data as *mut RustShellTui); + let result = obj.start(); + match result { + Ok(()) => CELIX_SUCCESS, + Err(_) => CELIX_BUNDLE_EXCEPTION, + } +} + +#[no_mangle] +pub unsafe extern "C" fn celix_bundleActivator_stop(data: *mut c_void, _ctx: *mut celix_bundle_context_t) -> celix_status_t { + let obj = &mut *(data as *mut RustShellTui); + let result = obj.stop(); + match result { + Ok(()) => CELIX_SUCCESS, + Err(_) => CELIX_BUNDLE_EXCEPTION, + } +} + +#[no_mangle] +pub unsafe extern "C" fn celix_bundleActivator_destroy(data: *mut c_void, _ctx: *mut celix_bundle_context_t) -> celix_status_t { + let obj = Box::from_raw(data as *mut RustShellTui); + drop(obj); + CELIX_SUCCESS +} +
