diff --git a/demo/rust/src/interface.rs b/demo/rust/src/interface.rs index ac0c9c2..72776c5 100644 --- a/demo/rust/src/interface.rs +++ b/demo/rust/src/interface.rs @@ -1,1410 +1,1410 @@ /* generated by rust_qt_binding_generator */ use libc::{c_char, c_ushort, c_int}; use std::slice; use std::char::decode_utf16; use std::sync::Arc; use std::sync::atomic::{AtomicPtr, Ordering}; use std::ptr::null; use implementation::*; #[repr(C)] pub struct COption { data: T, some: bool, } impl COption { #![allow(dead_code)] fn into(self) -> Option { if self.some { Some(self.data) } else { None } } } impl From> for COption where T: Default, { fn from(t: Option) -> COption { if let Some(v) = t { COption { data: v, some: true, } } else { COption { data: T::default(), some: false, } } } } pub enum QString {} fn set_string_from_utf16(s: &mut String, str: *const c_ushort, len: c_int) { let utf16 = unsafe { slice::from_raw_parts(str, to_usize(len)) }; let characters = decode_utf16(utf16.iter().cloned()) .map(|r| r.unwrap()); s.clear(); s.extend(characters); } pub enum QByteArray {} #[repr(C)] #[derive(PartialEq, Eq, Debug)] pub enum SortOrder { Ascending = 0, Descending = 1, } #[repr(C)] pub struct QModelIndex { row: c_int, internal_id: usize, } fn to_usize(n: c_int) -> usize { if n < 0 { panic!("Cannot cast {} to usize", n); } n as usize } fn to_c_int(n: usize) -> c_int { if n > c_int::max_value() as usize { panic!("Cannot cast {} to c_int", n); } n as c_int } pub struct DemoQObject {} pub struct DemoEmitter { qobject: Arc>, } unsafe impl Send for DemoEmitter {} impl DemoEmitter { /// Clone the emitter /// /// The emitter can only be cloned when it is mutable. The emitter calls /// into C++ code which may call into Rust again. If emmitting is possible /// from immutable structures, that might lead to access to a mutable /// reference. That is undefined behaviour and forbidden. pub fn clone(&mut self) -> DemoEmitter { DemoEmitter { qobject: self.qobject.clone(), } } fn clear(&self) { let n: *const DemoQObject = null(); self.qobject.store(n as *mut DemoQObject, Ordering::SeqCst); } } pub trait DemoTrait { fn new(emit: DemoEmitter, fibonacci: Fibonacci, fibonacci_list: FibonacciList, file_system_tree: FileSystemTree, processes: Processes, time_series: TimeSeries) -> Self; fn emit(&mut self) -> &mut DemoEmitter; fn fibonacci(&self) -> &Fibonacci; fn fibonacci_mut(&mut self) -> &mut Fibonacci; fn fibonacci_list(&self) -> &FibonacciList; fn fibonacci_list_mut(&mut self) -> &mut FibonacciList; fn file_system_tree(&self) -> &FileSystemTree; fn file_system_tree_mut(&mut self) -> &mut FileSystemTree; fn processes(&self) -> &Processes; fn processes_mut(&mut self) -> &mut Processes; fn time_series(&self) -> &TimeSeries; fn time_series_mut(&mut self) -> &mut TimeSeries; } #[no_mangle] pub extern "C" fn demo_new( demo: *mut DemoQObject, fibonacci: *mut FibonacciQObject, fibonacci_input_changed: fn(*mut FibonacciQObject), fibonacci_result_changed: fn(*mut FibonacciQObject), fibonacci_list: *mut FibonacciListQObject, fibonacci_list_new_data_ready: fn(*mut FibonacciListQObject), fibonacci_list_layout_about_to_be_changed: fn(*mut FibonacciListQObject), fibonacci_list_layout_changed: fn(*mut FibonacciListQObject), fibonacci_list_data_changed: fn(*mut FibonacciListQObject, usize, usize), fibonacci_list_begin_reset_model: fn(*mut FibonacciListQObject), fibonacci_list_end_reset_model: fn(*mut FibonacciListQObject), fibonacci_list_begin_insert_rows: fn(*mut FibonacciListQObject, usize, usize), fibonacci_list_end_insert_rows: fn(*mut FibonacciListQObject), fibonacci_list_begin_move_rows: fn(*mut FibonacciListQObject, usize, usize, usize), fibonacci_list_end_move_rows: fn(*mut FibonacciListQObject), fibonacci_list_begin_remove_rows: fn(*mut FibonacciListQObject, usize, usize), fibonacci_list_end_remove_rows: fn(*mut FibonacciListQObject), file_system_tree: *mut FileSystemTreeQObject, file_system_tree_path_changed: fn(*mut FileSystemTreeQObject), file_system_tree_new_data_ready: fn(*mut FileSystemTreeQObject, index: COption), file_system_tree_layout_about_to_be_changed: fn(*mut FileSystemTreeQObject), file_system_tree_layout_changed: fn(*mut FileSystemTreeQObject), file_system_tree_data_changed: fn(*mut FileSystemTreeQObject, usize, usize), file_system_tree_begin_reset_model: fn(*mut FileSystemTreeQObject), file_system_tree_end_reset_model: fn(*mut FileSystemTreeQObject), file_system_tree_begin_insert_rows: fn(*mut FileSystemTreeQObject, index: COption, usize, usize), file_system_tree_end_insert_rows: fn(*mut FileSystemTreeQObject), file_system_tree_begin_move_rows: fn(*mut FileSystemTreeQObject, index: COption, usize, usize, index: COption, usize), file_system_tree_end_move_rows: fn(*mut FileSystemTreeQObject), file_system_tree_begin_remove_rows: fn(*mut FileSystemTreeQObject, index: COption, usize, usize), file_system_tree_end_remove_rows: fn(*mut FileSystemTreeQObject), processes: *mut ProcessesQObject, processes_active_changed: fn(*mut ProcessesQObject), processes_new_data_ready: fn(*mut ProcessesQObject, index: COption), processes_layout_about_to_be_changed: fn(*mut ProcessesQObject), processes_layout_changed: fn(*mut ProcessesQObject), processes_data_changed: fn(*mut ProcessesQObject, usize, usize), processes_begin_reset_model: fn(*mut ProcessesQObject), processes_end_reset_model: fn(*mut ProcessesQObject), processes_begin_insert_rows: fn(*mut ProcessesQObject, index: COption, usize, usize), processes_end_insert_rows: fn(*mut ProcessesQObject), processes_begin_move_rows: fn(*mut ProcessesQObject, index: COption, usize, usize, index: COption, usize), processes_end_move_rows: fn(*mut ProcessesQObject), processes_begin_remove_rows: fn(*mut ProcessesQObject, index: COption, usize, usize), processes_end_remove_rows: fn(*mut ProcessesQObject), time_series: *mut TimeSeriesQObject, time_series_new_data_ready: fn(*mut TimeSeriesQObject), time_series_layout_about_to_be_changed: fn(*mut TimeSeriesQObject), time_series_layout_changed: fn(*mut TimeSeriesQObject), time_series_data_changed: fn(*mut TimeSeriesQObject, usize, usize), time_series_begin_reset_model: fn(*mut TimeSeriesQObject), time_series_end_reset_model: fn(*mut TimeSeriesQObject), time_series_begin_insert_rows: fn(*mut TimeSeriesQObject, usize, usize), time_series_end_insert_rows: fn(*mut TimeSeriesQObject), time_series_begin_move_rows: fn(*mut TimeSeriesQObject, usize, usize, usize), time_series_end_move_rows: fn(*mut TimeSeriesQObject), time_series_begin_remove_rows: fn(*mut TimeSeriesQObject, usize, usize), time_series_end_remove_rows: fn(*mut TimeSeriesQObject), ) -> *mut Demo { let fibonacci_emit = FibonacciEmitter { qobject: Arc::new(AtomicPtr::new(fibonacci)), input_changed: fibonacci_input_changed, result_changed: fibonacci_result_changed, }; let d_fibonacci = Fibonacci::new(fibonacci_emit); let fibonacci_list_emit = FibonacciListEmitter { qobject: Arc::new(AtomicPtr::new(fibonacci_list)), new_data_ready: fibonacci_list_new_data_ready, }; let model = FibonacciListList { qobject: fibonacci_list, layout_about_to_be_changed: fibonacci_list_layout_about_to_be_changed, layout_changed: fibonacci_list_layout_changed, data_changed: fibonacci_list_data_changed, begin_reset_model: fibonacci_list_begin_reset_model, end_reset_model: fibonacci_list_end_reset_model, begin_insert_rows: fibonacci_list_begin_insert_rows, end_insert_rows: fibonacci_list_end_insert_rows, begin_move_rows: fibonacci_list_begin_move_rows, end_move_rows: fibonacci_list_end_move_rows, begin_remove_rows: fibonacci_list_begin_remove_rows, end_remove_rows: fibonacci_list_end_remove_rows, }; let d_fibonacci_list = FibonacciList::new(fibonacci_list_emit, model); let file_system_tree_emit = FileSystemTreeEmitter { qobject: Arc::new(AtomicPtr::new(file_system_tree)), path_changed: file_system_tree_path_changed, new_data_ready: file_system_tree_new_data_ready, }; let model = FileSystemTreeTree { qobject: file_system_tree, layout_about_to_be_changed: file_system_tree_layout_about_to_be_changed, layout_changed: file_system_tree_layout_changed, data_changed: file_system_tree_data_changed, begin_reset_model: file_system_tree_begin_reset_model, end_reset_model: file_system_tree_end_reset_model, begin_insert_rows: file_system_tree_begin_insert_rows, end_insert_rows: file_system_tree_end_insert_rows, begin_move_rows: file_system_tree_begin_move_rows, end_move_rows: file_system_tree_end_move_rows, begin_remove_rows: file_system_tree_begin_remove_rows, end_remove_rows: file_system_tree_end_remove_rows, }; let d_file_system_tree = FileSystemTree::new(file_system_tree_emit, model); let processes_emit = ProcessesEmitter { qobject: Arc::new(AtomicPtr::new(processes)), active_changed: processes_active_changed, new_data_ready: processes_new_data_ready, }; let model = ProcessesTree { qobject: processes, layout_about_to_be_changed: processes_layout_about_to_be_changed, layout_changed: processes_layout_changed, data_changed: processes_data_changed, begin_reset_model: processes_begin_reset_model, end_reset_model: processes_end_reset_model, begin_insert_rows: processes_begin_insert_rows, end_insert_rows: processes_end_insert_rows, begin_move_rows: processes_begin_move_rows, end_move_rows: processes_end_move_rows, begin_remove_rows: processes_begin_remove_rows, end_remove_rows: processes_end_remove_rows, }; let d_processes = Processes::new(processes_emit, model); let time_series_emit = TimeSeriesEmitter { qobject: Arc::new(AtomicPtr::new(time_series)), new_data_ready: time_series_new_data_ready, }; let model = TimeSeriesList { qobject: time_series, layout_about_to_be_changed: time_series_layout_about_to_be_changed, layout_changed: time_series_layout_changed, data_changed: time_series_data_changed, begin_reset_model: time_series_begin_reset_model, end_reset_model: time_series_end_reset_model, begin_insert_rows: time_series_begin_insert_rows, end_insert_rows: time_series_end_insert_rows, begin_move_rows: time_series_begin_move_rows, end_move_rows: time_series_end_move_rows, begin_remove_rows: time_series_begin_remove_rows, end_remove_rows: time_series_end_remove_rows, }; let d_time_series = TimeSeries::new(time_series_emit, model); let demo_emit = DemoEmitter { qobject: Arc::new(AtomicPtr::new(demo)), }; let d_demo = Demo::new(demo_emit, d_fibonacci, d_fibonacci_list, d_file_system_tree, d_processes, d_time_series); Box::into_raw(Box::new(d_demo)) } #[no_mangle] pub unsafe extern "C" fn demo_free(ptr: *mut Demo) { Box::from_raw(ptr).emit().clear(); } #[no_mangle] pub unsafe extern "C" fn demo_fibonacci_get(ptr: *mut Demo) -> *mut Fibonacci { (&mut *ptr).fibonacci_mut() } #[no_mangle] pub unsafe extern "C" fn demo_fibonacci_list_get(ptr: *mut Demo) -> *mut FibonacciList { (&mut *ptr).fibonacci_list_mut() } #[no_mangle] pub unsafe extern "C" fn demo_file_system_tree_get(ptr: *mut Demo) -> *mut FileSystemTree { (&mut *ptr).file_system_tree_mut() } #[no_mangle] pub unsafe extern "C" fn demo_processes_get(ptr: *mut Demo) -> *mut Processes { (&mut *ptr).processes_mut() } #[no_mangle] pub unsafe extern "C" fn demo_time_series_get(ptr: *mut Demo) -> *mut TimeSeries { (&mut *ptr).time_series_mut() } pub struct FibonacciQObject {} pub struct FibonacciEmitter { qobject: Arc>, input_changed: fn(*mut FibonacciQObject), result_changed: fn(*mut FibonacciQObject), } unsafe impl Send for FibonacciEmitter {} impl FibonacciEmitter { /// Clone the emitter /// /// The emitter can only be cloned when it is mutable. The emitter calls /// into C++ code which may call into Rust again. If emmitting is possible /// from immutable structures, that might lead to access to a mutable /// reference. That is undefined behaviour and forbidden. pub fn clone(&mut self) -> FibonacciEmitter { FibonacciEmitter { qobject: self.qobject.clone(), input_changed: self.input_changed, result_changed: self.result_changed, } } fn clear(&self) { let n: *const FibonacciQObject = null(); self.qobject.store(n as *mut FibonacciQObject, Ordering::SeqCst); } pub fn input_changed(&mut self) { let ptr = self.qobject.load(Ordering::SeqCst); if !ptr.is_null() { (self.input_changed)(ptr); } } pub fn result_changed(&mut self) { let ptr = self.qobject.load(Ordering::SeqCst); if !ptr.is_null() { (self.result_changed)(ptr); } } } pub trait FibonacciTrait { fn new(emit: FibonacciEmitter) -> Self; fn emit(&mut self) -> &mut FibonacciEmitter; fn input(&self) -> u32; fn set_input(&mut self, value: u32); fn result(&self) -> u64; } #[no_mangle] pub extern "C" fn fibonacci_new( fibonacci: *mut FibonacciQObject, fibonacci_input_changed: fn(*mut FibonacciQObject), fibonacci_result_changed: fn(*mut FibonacciQObject), ) -> *mut Fibonacci { let fibonacci_emit = FibonacciEmitter { qobject: Arc::new(AtomicPtr::new(fibonacci)), input_changed: fibonacci_input_changed, result_changed: fibonacci_result_changed, }; let d_fibonacci = Fibonacci::new(fibonacci_emit); Box::into_raw(Box::new(d_fibonacci)) } #[no_mangle] pub unsafe extern "C" fn fibonacci_free(ptr: *mut Fibonacci) { Box::from_raw(ptr).emit().clear(); } #[no_mangle] pub unsafe extern "C" fn fibonacci_input_get(ptr: *const Fibonacci) -> u32 { (&*ptr).input() } #[no_mangle] pub unsafe extern "C" fn fibonacci_input_set(ptr: *mut Fibonacci, v: u32) { (&mut *ptr).set_input(v); } #[no_mangle] pub unsafe extern "C" fn fibonacci_result_get(ptr: *const Fibonacci) -> u64 { (&*ptr).result() } pub struct FibonacciListQObject {} pub struct FibonacciListEmitter { qobject: Arc>, new_data_ready: fn(*mut FibonacciListQObject), } unsafe impl Send for FibonacciListEmitter {} impl FibonacciListEmitter { /// Clone the emitter /// /// The emitter can only be cloned when it is mutable. The emitter calls /// into C++ code which may call into Rust again. If emmitting is possible /// from immutable structures, that might lead to access to a mutable /// reference. That is undefined behaviour and forbidden. pub fn clone(&mut self) -> FibonacciListEmitter { FibonacciListEmitter { qobject: self.qobject.clone(), new_data_ready: self.new_data_ready, } } fn clear(&self) { let n: *const FibonacciListQObject = null(); self.qobject.store(n as *mut FibonacciListQObject, Ordering::SeqCst); } pub fn new_data_ready(&mut self) { let ptr = self.qobject.load(Ordering::SeqCst); if !ptr.is_null() { (self.new_data_ready)(ptr); } } } #[derive(Clone)] pub struct FibonacciListList { qobject: *mut FibonacciListQObject, layout_about_to_be_changed: fn(*mut FibonacciListQObject), layout_changed: fn(*mut FibonacciListQObject), data_changed: fn(*mut FibonacciListQObject, usize, usize), begin_reset_model: fn(*mut FibonacciListQObject), end_reset_model: fn(*mut FibonacciListQObject), begin_insert_rows: fn(*mut FibonacciListQObject, usize, usize), end_insert_rows: fn(*mut FibonacciListQObject), begin_move_rows: fn(*mut FibonacciListQObject, usize, usize, usize), end_move_rows: fn(*mut FibonacciListQObject), begin_remove_rows: fn(*mut FibonacciListQObject, usize, usize), end_remove_rows: fn(*mut FibonacciListQObject), } impl FibonacciListList { pub fn layout_about_to_be_changed(&mut self) { (self.layout_about_to_be_changed)(self.qobject); } pub fn layout_changed(&mut self) { (self.layout_changed)(self.qobject); } pub fn data_changed(&mut self, first: usize, last: usize) { (self.data_changed)(self.qobject, first, last); } pub fn begin_reset_model(&mut self) { (self.begin_reset_model)(self.qobject); } pub fn end_reset_model(&mut self) { (self.end_reset_model)(self.qobject); } pub fn begin_insert_rows(&mut self, first: usize, last: usize) { (self.begin_insert_rows)(self.qobject, first, last); } pub fn end_insert_rows(&mut self) { (self.end_insert_rows)(self.qobject); } pub fn begin_move_rows(&mut self, first: usize, last: usize, destination: usize) { (self.begin_move_rows)(self.qobject, first, last, destination); } pub fn end_move_rows(&mut self) { (self.end_move_rows)(self.qobject); } pub fn begin_remove_rows(&mut self, first: usize, last: usize) { (self.begin_remove_rows)(self.qobject, first, last); } pub fn end_remove_rows(&mut self) { (self.end_remove_rows)(self.qobject); } } pub trait FibonacciListTrait { fn new(emit: FibonacciListEmitter, model: FibonacciListList) -> Self; fn emit(&mut self) -> &mut FibonacciListEmitter; fn row_count(&self) -> usize; fn insert_rows(&mut self, _row: usize, _count: usize) -> bool { false } fn remove_rows(&mut self, _row: usize, _count: usize) -> bool { false } fn can_fetch_more(&self) -> bool { false } fn fetch_more(&mut self) {} fn sort(&mut self, _: u8, _: SortOrder) {} fn fibonacci_number(&self, index: usize) -> u64; fn row(&self, index: usize) -> u64; } #[no_mangle] pub extern "C" fn fibonacci_list_new( fibonacci_list: *mut FibonacciListQObject, fibonacci_list_new_data_ready: fn(*mut FibonacciListQObject), fibonacci_list_layout_about_to_be_changed: fn(*mut FibonacciListQObject), fibonacci_list_layout_changed: fn(*mut FibonacciListQObject), fibonacci_list_data_changed: fn(*mut FibonacciListQObject, usize, usize), fibonacci_list_begin_reset_model: fn(*mut FibonacciListQObject), fibonacci_list_end_reset_model: fn(*mut FibonacciListQObject), fibonacci_list_begin_insert_rows: fn(*mut FibonacciListQObject, usize, usize), fibonacci_list_end_insert_rows: fn(*mut FibonacciListQObject), fibonacci_list_begin_move_rows: fn(*mut FibonacciListQObject, usize, usize, usize), fibonacci_list_end_move_rows: fn(*mut FibonacciListQObject), fibonacci_list_begin_remove_rows: fn(*mut FibonacciListQObject, usize, usize), fibonacci_list_end_remove_rows: fn(*mut FibonacciListQObject), ) -> *mut FibonacciList { let fibonacci_list_emit = FibonacciListEmitter { qobject: Arc::new(AtomicPtr::new(fibonacci_list)), new_data_ready: fibonacci_list_new_data_ready, }; let model = FibonacciListList { qobject: fibonacci_list, layout_about_to_be_changed: fibonacci_list_layout_about_to_be_changed, layout_changed: fibonacci_list_layout_changed, data_changed: fibonacci_list_data_changed, begin_reset_model: fibonacci_list_begin_reset_model, end_reset_model: fibonacci_list_end_reset_model, begin_insert_rows: fibonacci_list_begin_insert_rows, end_insert_rows: fibonacci_list_end_insert_rows, begin_move_rows: fibonacci_list_begin_move_rows, end_move_rows: fibonacci_list_end_move_rows, begin_remove_rows: fibonacci_list_begin_remove_rows, end_remove_rows: fibonacci_list_end_remove_rows, }; let d_fibonacci_list = FibonacciList::new(fibonacci_list_emit, model); Box::into_raw(Box::new(d_fibonacci_list)) } #[no_mangle] pub unsafe extern "C" fn fibonacci_list_free(ptr: *mut FibonacciList) { Box::from_raw(ptr).emit().clear(); } #[no_mangle] pub unsafe extern "C" fn fibonacci_list_row_count(ptr: *const FibonacciList) -> c_int { to_c_int((&*ptr).row_count()) } #[no_mangle] pub unsafe extern "C" fn fibonacci_list_insert_rows(ptr: *mut FibonacciList, row: c_int, count: c_int) -> bool { (&mut *ptr).insert_rows(to_usize(row), to_usize(count)) } #[no_mangle] pub unsafe extern "C" fn fibonacci_list_remove_rows(ptr: *mut FibonacciList, row: c_int, count: c_int) -> bool { (&mut *ptr).remove_rows(to_usize(row), to_usize(count)) } #[no_mangle] pub unsafe extern "C" fn fibonacci_list_can_fetch_more(ptr: *const FibonacciList) -> bool { (&*ptr).can_fetch_more() } #[no_mangle] pub unsafe extern "C" fn fibonacci_list_fetch_more(ptr: *mut FibonacciList) { (&mut *ptr).fetch_more() } #[no_mangle] pub unsafe extern "C" fn fibonacci_list_sort( ptr: *mut FibonacciList, column: u8, order: SortOrder, ) { (&mut *ptr).sort(column, order) } #[no_mangle] pub unsafe extern "C" fn fibonacci_list_data_fibonacci_number(ptr: *const FibonacciList, row: c_int) -> u64 { let o = &*ptr; o.fibonacci_number(to_usize(row)).into() } #[no_mangle] pub unsafe extern "C" fn fibonacci_list_data_row(ptr: *const FibonacciList, row: c_int) -> u64 { let o = &*ptr; o.row(to_usize(row)).into() } pub struct FileSystemTreeQObject {} pub struct FileSystemTreeEmitter { qobject: Arc>, path_changed: fn(*mut FileSystemTreeQObject), new_data_ready: fn(*mut FileSystemTreeQObject, index: COption), } unsafe impl Send for FileSystemTreeEmitter {} impl FileSystemTreeEmitter { /// Clone the emitter /// /// The emitter can only be cloned when it is mutable. The emitter calls /// into C++ code which may call into Rust again. If emmitting is possible /// from immutable structures, that might lead to access to a mutable /// reference. That is undefined behaviour and forbidden. pub fn clone(&mut self) -> FileSystemTreeEmitter { FileSystemTreeEmitter { qobject: self.qobject.clone(), path_changed: self.path_changed, new_data_ready: self.new_data_ready, } } fn clear(&self) { let n: *const FileSystemTreeQObject = null(); self.qobject.store(n as *mut FileSystemTreeQObject, Ordering::SeqCst); } pub fn path_changed(&mut self) { let ptr = self.qobject.load(Ordering::SeqCst); if !ptr.is_null() { (self.path_changed)(ptr); } } pub fn new_data_ready(&mut self, item: Option) { let ptr = self.qobject.load(Ordering::SeqCst); if !ptr.is_null() { (self.new_data_ready)(ptr, item.into()); } } } #[derive(Clone)] pub struct FileSystemTreeTree { qobject: *mut FileSystemTreeQObject, layout_about_to_be_changed: fn(*mut FileSystemTreeQObject), layout_changed: fn(*mut FileSystemTreeQObject), data_changed: fn(*mut FileSystemTreeQObject, usize, usize), begin_reset_model: fn(*mut FileSystemTreeQObject), end_reset_model: fn(*mut FileSystemTreeQObject), begin_insert_rows: fn(*mut FileSystemTreeQObject, index: COption, usize, usize), end_insert_rows: fn(*mut FileSystemTreeQObject), begin_move_rows: fn(*mut FileSystemTreeQObject, index: COption, usize, usize, dest: COption, usize), end_move_rows: fn(*mut FileSystemTreeQObject), begin_remove_rows: fn(*mut FileSystemTreeQObject, index: COption, usize, usize), end_remove_rows: fn(*mut FileSystemTreeQObject), } impl FileSystemTreeTree { pub fn layout_about_to_be_changed(&mut self) { (self.layout_about_to_be_changed)(self.qobject); } pub fn layout_changed(&mut self) { (self.layout_changed)(self.qobject); } pub fn data_changed(&mut self, first: usize, last: usize) { (self.data_changed)(self.qobject, first, last); } pub fn begin_reset_model(&mut self) { (self.begin_reset_model)(self.qobject); } pub fn end_reset_model(&mut self) { (self.end_reset_model)(self.qobject); } pub fn begin_insert_rows(&mut self, index: Option, first: usize, last: usize) { (self.begin_insert_rows)(self.qobject, index.into(), first, last); } pub fn end_insert_rows(&mut self) { (self.end_insert_rows)(self.qobject); } pub fn begin_move_rows(&mut self, index: Option, first: usize, last: usize, dest: Option, destination: usize) { (self.begin_move_rows)(self.qobject, index.into(), first, last, dest.into(), destination); } pub fn end_move_rows(&mut self) { (self.end_move_rows)(self.qobject); } pub fn begin_remove_rows(&mut self, index: Option, first: usize, last: usize) { (self.begin_remove_rows)(self.qobject, index.into(), first, last); } pub fn end_remove_rows(&mut self) { (self.end_remove_rows)(self.qobject); } } pub trait FileSystemTreeTrait { fn new(emit: FileSystemTreeEmitter, model: FileSystemTreeTree) -> Self; fn emit(&mut self) -> &mut FileSystemTreeEmitter; fn path(&self) -> Option<&str>; fn set_path(&mut self, value: Option); fn row_count(&self, _: Option) -> usize; fn can_fetch_more(&self, _: Option) -> bool { false } fn fetch_more(&mut self, _: Option) {} fn sort(&mut self, _: u8, _: SortOrder) {} fn check_row(&self, index: usize, row: usize) -> Option; fn index(&self, item: Option, row: usize) -> usize; fn parent(&self, index: usize) -> Option; fn row(&self, index: usize) -> usize; fn file_icon(&self, index: usize) -> &[u8]; fn file_name(&self, index: usize) -> String; fn file_path(&self, index: usize) -> Option; fn file_permissions(&self, index: usize) -> i32; fn file_size(&self, index: usize) -> Option; fn file_type(&self, index: usize) -> i32; } #[no_mangle] pub extern "C" fn file_system_tree_new( file_system_tree: *mut FileSystemTreeQObject, file_system_tree_path_changed: fn(*mut FileSystemTreeQObject), file_system_tree_new_data_ready: fn(*mut FileSystemTreeQObject, index: COption), file_system_tree_layout_about_to_be_changed: fn(*mut FileSystemTreeQObject), file_system_tree_layout_changed: fn(*mut FileSystemTreeQObject), file_system_tree_data_changed: fn(*mut FileSystemTreeQObject, usize, usize), file_system_tree_begin_reset_model: fn(*mut FileSystemTreeQObject), file_system_tree_end_reset_model: fn(*mut FileSystemTreeQObject), file_system_tree_begin_insert_rows: fn(*mut FileSystemTreeQObject, index: COption, usize, usize), file_system_tree_end_insert_rows: fn(*mut FileSystemTreeQObject), file_system_tree_begin_move_rows: fn(*mut FileSystemTreeQObject, index: COption, usize, usize, index: COption, usize), file_system_tree_end_move_rows: fn(*mut FileSystemTreeQObject), file_system_tree_begin_remove_rows: fn(*mut FileSystemTreeQObject, index: COption, usize, usize), file_system_tree_end_remove_rows: fn(*mut FileSystemTreeQObject), ) -> *mut FileSystemTree { let file_system_tree_emit = FileSystemTreeEmitter { qobject: Arc::new(AtomicPtr::new(file_system_tree)), path_changed: file_system_tree_path_changed, new_data_ready: file_system_tree_new_data_ready, }; let model = FileSystemTreeTree { qobject: file_system_tree, layout_about_to_be_changed: file_system_tree_layout_about_to_be_changed, layout_changed: file_system_tree_layout_changed, data_changed: file_system_tree_data_changed, begin_reset_model: file_system_tree_begin_reset_model, end_reset_model: file_system_tree_end_reset_model, begin_insert_rows: file_system_tree_begin_insert_rows, end_insert_rows: file_system_tree_end_insert_rows, begin_move_rows: file_system_tree_begin_move_rows, end_move_rows: file_system_tree_end_move_rows, begin_remove_rows: file_system_tree_begin_remove_rows, end_remove_rows: file_system_tree_end_remove_rows, }; let d_file_system_tree = FileSystemTree::new(file_system_tree_emit, model); Box::into_raw(Box::new(d_file_system_tree)) } #[no_mangle] pub unsafe extern "C" fn file_system_tree_free(ptr: *mut FileSystemTree) { Box::from_raw(ptr).emit().clear(); } #[no_mangle] pub unsafe extern "C" fn file_system_tree_path_get( ptr: *const FileSystemTree, p: *mut QString, set: fn(*mut QString, *const c_char, c_int), ) { let o = &*ptr; let v = o.path(); if let Some(v) = v { let s: *const c_char = v.as_ptr() as (*const c_char); set(p, s, to_c_int(v.len())); } } #[no_mangle] pub unsafe extern "C" fn file_system_tree_path_set(ptr: *mut FileSystemTree, v: *const c_ushort, len: c_int) { let o = &mut *ptr; let mut s = String::new(); set_string_from_utf16(&mut s, v, len); o.set_path(Some(s)); } #[no_mangle] pub unsafe extern "C" fn file_system_tree_path_set_none(ptr: *mut FileSystemTree) { let o = &mut *ptr; o.set_path(None); } #[no_mangle] pub unsafe extern "C" fn file_system_tree_row_count( ptr: *const FileSystemTree, index: COption, ) -> c_int { to_c_int((&*ptr).row_count(index.into())) } #[no_mangle] pub unsafe extern "C" fn file_system_tree_can_fetch_more( ptr: *const FileSystemTree, index: COption, ) -> bool { (&*ptr).can_fetch_more(index.into()) } #[no_mangle] pub unsafe extern "C" fn file_system_tree_fetch_more(ptr: *mut FileSystemTree, index: COption) { (&mut *ptr).fetch_more(index.into()) } #[no_mangle] pub unsafe extern "C" fn file_system_tree_sort( ptr: *mut FileSystemTree, column: u8, order: SortOrder ) { (&mut *ptr).sort(column, order) } #[no_mangle] pub unsafe extern "C" fn file_system_tree_check_row( ptr: *const FileSystemTree, index: usize, row: c_int, ) -> COption { (&*ptr).check_row(index.into(), to_usize(row)).into() } #[no_mangle] pub unsafe extern "C" fn file_system_tree_index( ptr: *const FileSystemTree, index: COption, row: c_int, ) -> usize { (&*ptr).index(index.into(), to_usize(row)) } #[no_mangle] pub unsafe extern "C" fn file_system_tree_parent(ptr: *const FileSystemTree, index: usize) -> QModelIndex { if let Some(parent) = (&*ptr).parent(index) { QModelIndex { row: to_c_int((&*ptr).row(parent)), internal_id: parent, } } else { QModelIndex { row: -1, internal_id: 0, } } } #[no_mangle] pub unsafe extern "C" fn file_system_tree_row(ptr: *const FileSystemTree, index: usize) -> c_int { to_c_int((&*ptr).row(index)) } #[no_mangle] pub unsafe extern "C" fn file_system_tree_data_file_icon( ptr: *const FileSystemTree, index: usize, d: *mut QByteArray, set: fn(*mut QByteArray, *const c_char, len: c_int), ) { let o = &*ptr; let data = o.file_icon(index); let s: *const c_char = data.as_ptr() as (*const c_char); set(d, s, to_c_int(data.len())); } #[no_mangle] pub unsafe extern "C" fn file_system_tree_data_file_name( ptr: *const FileSystemTree, index: usize, d: *mut QString, set: fn(*mut QString, *const c_char, len: c_int), ) { let o = &*ptr; let data = o.file_name(index); let s: *const c_char = data.as_ptr() as (*const c_char); set(d, s, to_c_int(data.len())); } #[no_mangle] pub unsafe extern "C" fn file_system_tree_data_file_path( ptr: *const FileSystemTree, index: usize, d: *mut QString, set: fn(*mut QString, *const c_char, len: c_int), ) { let o = &*ptr; let data = o.file_path(index); if let Some(data) = data { let s: *const c_char = data.as_ptr() as (*const c_char); set(d, s, to_c_int(data.len())); } } #[no_mangle] pub unsafe extern "C" fn file_system_tree_data_file_permissions(ptr: *const FileSystemTree, index: usize) -> i32 { let o = &*ptr; o.file_permissions(index).into() } #[no_mangle] pub unsafe extern "C" fn file_system_tree_data_file_size(ptr: *const FileSystemTree, index: usize) -> COption { let o = &*ptr; o.file_size(index).into() } #[no_mangle] pub unsafe extern "C" fn file_system_tree_data_file_type(ptr: *const FileSystemTree, index: usize) -> i32 { let o = &*ptr; o.file_type(index).into() } pub struct ProcessesQObject {} pub struct ProcessesEmitter { qobject: Arc>, active_changed: fn(*mut ProcessesQObject), new_data_ready: fn(*mut ProcessesQObject, index: COption), } unsafe impl Send for ProcessesEmitter {} impl ProcessesEmitter { /// Clone the emitter /// /// The emitter can only be cloned when it is mutable. The emitter calls /// into C++ code which may call into Rust again. If emmitting is possible /// from immutable structures, that might lead to access to a mutable /// reference. That is undefined behaviour and forbidden. pub fn clone(&mut self) -> ProcessesEmitter { ProcessesEmitter { qobject: self.qobject.clone(), active_changed: self.active_changed, new_data_ready: self.new_data_ready, } } fn clear(&self) { let n: *const ProcessesQObject = null(); self.qobject.store(n as *mut ProcessesQObject, Ordering::SeqCst); } pub fn active_changed(&mut self) { let ptr = self.qobject.load(Ordering::SeqCst); if !ptr.is_null() { (self.active_changed)(ptr); } } pub fn new_data_ready(&mut self, item: Option) { let ptr = self.qobject.load(Ordering::SeqCst); if !ptr.is_null() { (self.new_data_ready)(ptr, item.into()); } } } #[derive(Clone)] pub struct ProcessesTree { qobject: *mut ProcessesQObject, layout_about_to_be_changed: fn(*mut ProcessesQObject), layout_changed: fn(*mut ProcessesQObject), data_changed: fn(*mut ProcessesQObject, usize, usize), begin_reset_model: fn(*mut ProcessesQObject), end_reset_model: fn(*mut ProcessesQObject), begin_insert_rows: fn(*mut ProcessesQObject, index: COption, usize, usize), end_insert_rows: fn(*mut ProcessesQObject), begin_move_rows: fn(*mut ProcessesQObject, index: COption, usize, usize, dest: COption, usize), end_move_rows: fn(*mut ProcessesQObject), begin_remove_rows: fn(*mut ProcessesQObject, index: COption, usize, usize), end_remove_rows: fn(*mut ProcessesQObject), } impl ProcessesTree { pub fn layout_about_to_be_changed(&mut self) { (self.layout_about_to_be_changed)(self.qobject); } pub fn layout_changed(&mut self) { (self.layout_changed)(self.qobject); } pub fn data_changed(&mut self, first: usize, last: usize) { (self.data_changed)(self.qobject, first, last); } pub fn begin_reset_model(&mut self) { (self.begin_reset_model)(self.qobject); } pub fn end_reset_model(&mut self) { (self.end_reset_model)(self.qobject); } pub fn begin_insert_rows(&mut self, index: Option, first: usize, last: usize) { (self.begin_insert_rows)(self.qobject, index.into(), first, last); } pub fn end_insert_rows(&mut self) { (self.end_insert_rows)(self.qobject); } pub fn begin_move_rows(&mut self, index: Option, first: usize, last: usize, dest: Option, destination: usize) { (self.begin_move_rows)(self.qobject, index.into(), first, last, dest.into(), destination); } pub fn end_move_rows(&mut self) { (self.end_move_rows)(self.qobject); } pub fn begin_remove_rows(&mut self, index: Option, first: usize, last: usize) { (self.begin_remove_rows)(self.qobject, index.into(), first, last); } pub fn end_remove_rows(&mut self) { (self.end_remove_rows)(self.qobject); } } pub trait ProcessesTrait { fn new(emit: ProcessesEmitter, model: ProcessesTree) -> Self; fn emit(&mut self) -> &mut ProcessesEmitter; fn active(&self) -> bool; fn set_active(&mut self, value: bool); fn row_count(&self, _: Option) -> usize; fn can_fetch_more(&self, _: Option) -> bool { false } fn fetch_more(&mut self, _: Option) {} fn sort(&mut self, _: u8, _: SortOrder) {} fn check_row(&self, index: usize, row: usize) -> Option; fn index(&self, item: Option, row: usize) -> usize; fn parent(&self, index: usize) -> Option; fn row(&self, index: usize) -> usize; fn cmd(&self, index: usize) -> String; fn cpu_percentage(&self, index: usize) -> u8; fn cpu_usage(&self, index: usize) -> f32; fn memory(&self, index: usize) -> u64; fn name(&self, index: usize) -> &str; fn pid(&self, index: usize) -> u32; fn uid(&self, index: usize) -> u32; } #[no_mangle] pub extern "C" fn processes_new( processes: *mut ProcessesQObject, processes_active_changed: fn(*mut ProcessesQObject), processes_new_data_ready: fn(*mut ProcessesQObject, index: COption), processes_layout_about_to_be_changed: fn(*mut ProcessesQObject), processes_layout_changed: fn(*mut ProcessesQObject), processes_data_changed: fn(*mut ProcessesQObject, usize, usize), processes_begin_reset_model: fn(*mut ProcessesQObject), processes_end_reset_model: fn(*mut ProcessesQObject), processes_begin_insert_rows: fn(*mut ProcessesQObject, index: COption, usize, usize), processes_end_insert_rows: fn(*mut ProcessesQObject), processes_begin_move_rows: fn(*mut ProcessesQObject, index: COption, usize, usize, index: COption, usize), processes_end_move_rows: fn(*mut ProcessesQObject), processes_begin_remove_rows: fn(*mut ProcessesQObject, index: COption, usize, usize), processes_end_remove_rows: fn(*mut ProcessesQObject), ) -> *mut Processes { let processes_emit = ProcessesEmitter { qobject: Arc::new(AtomicPtr::new(processes)), active_changed: processes_active_changed, new_data_ready: processes_new_data_ready, }; let model = ProcessesTree { qobject: processes, layout_about_to_be_changed: processes_layout_about_to_be_changed, layout_changed: processes_layout_changed, data_changed: processes_data_changed, begin_reset_model: processes_begin_reset_model, end_reset_model: processes_end_reset_model, begin_insert_rows: processes_begin_insert_rows, end_insert_rows: processes_end_insert_rows, begin_move_rows: processes_begin_move_rows, end_move_rows: processes_end_move_rows, begin_remove_rows: processes_begin_remove_rows, end_remove_rows: processes_end_remove_rows, }; let d_processes = Processes::new(processes_emit, model); Box::into_raw(Box::new(d_processes)) } #[no_mangle] pub unsafe extern "C" fn processes_free(ptr: *mut Processes) { Box::from_raw(ptr).emit().clear(); } #[no_mangle] pub unsafe extern "C" fn processes_active_get(ptr: *const Processes) -> bool { (&*ptr).active() } #[no_mangle] pub unsafe extern "C" fn processes_active_set(ptr: *mut Processes, v: bool) { (&mut *ptr).set_active(v); } #[no_mangle] pub unsafe extern "C" fn processes_row_count( ptr: *const Processes, index: COption, ) -> c_int { to_c_int((&*ptr).row_count(index.into())) } #[no_mangle] pub unsafe extern "C" fn processes_can_fetch_more( ptr: *const Processes, index: COption, ) -> bool { (&*ptr).can_fetch_more(index.into()) } #[no_mangle] pub unsafe extern "C" fn processes_fetch_more(ptr: *mut Processes, index: COption) { (&mut *ptr).fetch_more(index.into()) } #[no_mangle] pub unsafe extern "C" fn processes_sort( ptr: *mut Processes, column: u8, order: SortOrder ) { (&mut *ptr).sort(column, order) } #[no_mangle] pub unsafe extern "C" fn processes_check_row( ptr: *const Processes, index: usize, row: c_int, ) -> COption { (&*ptr).check_row(index.into(), to_usize(row)).into() } #[no_mangle] pub unsafe extern "C" fn processes_index( ptr: *const Processes, index: COption, row: c_int, ) -> usize { (&*ptr).index(index.into(), to_usize(row)) } #[no_mangle] pub unsafe extern "C" fn processes_parent(ptr: *const Processes, index: usize) -> QModelIndex { if let Some(parent) = (&*ptr).parent(index) { QModelIndex { row: to_c_int((&*ptr).row(parent)), internal_id: parent, } } else { QModelIndex { row: -1, internal_id: 0, } } } #[no_mangle] pub unsafe extern "C" fn processes_row(ptr: *const Processes, index: usize) -> c_int { to_c_int((&*ptr).row(index)) } #[no_mangle] pub unsafe extern "C" fn processes_data_cmd( ptr: *const Processes, index: usize, d: *mut QString, set: fn(*mut QString, *const c_char, len: c_int), ) { let o = &*ptr; let data = o.cmd(index); let s: *const c_char = data.as_ptr() as (*const c_char); set(d, s, to_c_int(data.len())); } #[no_mangle] pub unsafe extern "C" fn processes_data_cpu_percentage(ptr: *const Processes, index: usize) -> u8 { let o = &*ptr; o.cpu_percentage(index).into() } #[no_mangle] pub unsafe extern "C" fn processes_data_cpu_usage(ptr: *const Processes, index: usize) -> f32 { let o = &*ptr; o.cpu_usage(index).into() } #[no_mangle] pub unsafe extern "C" fn processes_data_memory(ptr: *const Processes, index: usize) -> u64 { let o = &*ptr; o.memory(index).into() } #[no_mangle] pub unsafe extern "C" fn processes_data_name( ptr: *const Processes, index: usize, d: *mut QString, set: fn(*mut QString, *const c_char, len: c_int), ) { let o = &*ptr; let data = o.name(index); let s: *const c_char = data.as_ptr() as (*const c_char); set(d, s, to_c_int(data.len())); } #[no_mangle] pub unsafe extern "C" fn processes_data_pid(ptr: *const Processes, index: usize) -> u32 { let o = &*ptr; o.pid(index).into() } #[no_mangle] pub unsafe extern "C" fn processes_data_uid(ptr: *const Processes, index: usize) -> u32 { let o = &*ptr; o.uid(index).into() } pub struct TimeSeriesQObject {} pub struct TimeSeriesEmitter { qobject: Arc>, new_data_ready: fn(*mut TimeSeriesQObject), } unsafe impl Send for TimeSeriesEmitter {} impl TimeSeriesEmitter { /// Clone the emitter /// /// The emitter can only be cloned when it is mutable. The emitter calls /// into C++ code which may call into Rust again. If emmitting is possible /// from immutable structures, that might lead to access to a mutable /// reference. That is undefined behaviour and forbidden. pub fn clone(&mut self) -> TimeSeriesEmitter { TimeSeriesEmitter { qobject: self.qobject.clone(), new_data_ready: self.new_data_ready, } } fn clear(&self) { let n: *const TimeSeriesQObject = null(); self.qobject.store(n as *mut TimeSeriesQObject, Ordering::SeqCst); } pub fn new_data_ready(&mut self) { let ptr = self.qobject.load(Ordering::SeqCst); if !ptr.is_null() { (self.new_data_ready)(ptr); } } } #[derive(Clone)] pub struct TimeSeriesList { qobject: *mut TimeSeriesQObject, layout_about_to_be_changed: fn(*mut TimeSeriesQObject), layout_changed: fn(*mut TimeSeriesQObject), data_changed: fn(*mut TimeSeriesQObject, usize, usize), begin_reset_model: fn(*mut TimeSeriesQObject), end_reset_model: fn(*mut TimeSeriesQObject), begin_insert_rows: fn(*mut TimeSeriesQObject, usize, usize), end_insert_rows: fn(*mut TimeSeriesQObject), begin_move_rows: fn(*mut TimeSeriesQObject, usize, usize, usize), end_move_rows: fn(*mut TimeSeriesQObject), begin_remove_rows: fn(*mut TimeSeriesQObject, usize, usize), end_remove_rows: fn(*mut TimeSeriesQObject), } impl TimeSeriesList { pub fn layout_about_to_be_changed(&mut self) { (self.layout_about_to_be_changed)(self.qobject); } pub fn layout_changed(&mut self) { (self.layout_changed)(self.qobject); } pub fn data_changed(&mut self, first: usize, last: usize) { (self.data_changed)(self.qobject, first, last); } pub fn begin_reset_model(&mut self) { (self.begin_reset_model)(self.qobject); } pub fn end_reset_model(&mut self) { (self.end_reset_model)(self.qobject); } pub fn begin_insert_rows(&mut self, first: usize, last: usize) { (self.begin_insert_rows)(self.qobject, first, last); } pub fn end_insert_rows(&mut self) { (self.end_insert_rows)(self.qobject); } pub fn begin_move_rows(&mut self, first: usize, last: usize, destination: usize) { (self.begin_move_rows)(self.qobject, first, last, destination); } pub fn end_move_rows(&mut self) { (self.end_move_rows)(self.qobject); } pub fn begin_remove_rows(&mut self, first: usize, last: usize) { (self.begin_remove_rows)(self.qobject, first, last); } pub fn end_remove_rows(&mut self) { (self.end_remove_rows)(self.qobject); } } pub trait TimeSeriesTrait { fn new(emit: TimeSeriesEmitter, model: TimeSeriesList) -> Self; fn emit(&mut self) -> &mut TimeSeriesEmitter; fn row_count(&self) -> usize; fn insert_rows(&mut self, _row: usize, _count: usize) -> bool { false } fn remove_rows(&mut self, _row: usize, _count: usize) -> bool { false } fn can_fetch_more(&self) -> bool { false } fn fetch_more(&mut self) {} fn sort(&mut self, _: u8, _: SortOrder) {} fn cos(&self, index: usize) -> f32; - fn set_cos(&mut self, index: usize, f32) -> bool; + fn set_cos(&mut self, index: usize, _: f32) -> bool; fn sin(&self, index: usize) -> f32; - fn set_sin(&mut self, index: usize, f32) -> bool; + fn set_sin(&mut self, index: usize, _: f32) -> bool; fn time(&self, index: usize) -> f32; - fn set_time(&mut self, index: usize, f32) -> bool; + fn set_time(&mut self, index: usize, _: f32) -> bool; } #[no_mangle] pub extern "C" fn time_series_new( time_series: *mut TimeSeriesQObject, time_series_new_data_ready: fn(*mut TimeSeriesQObject), time_series_layout_about_to_be_changed: fn(*mut TimeSeriesQObject), time_series_layout_changed: fn(*mut TimeSeriesQObject), time_series_data_changed: fn(*mut TimeSeriesQObject, usize, usize), time_series_begin_reset_model: fn(*mut TimeSeriesQObject), time_series_end_reset_model: fn(*mut TimeSeriesQObject), time_series_begin_insert_rows: fn(*mut TimeSeriesQObject, usize, usize), time_series_end_insert_rows: fn(*mut TimeSeriesQObject), time_series_begin_move_rows: fn(*mut TimeSeriesQObject, usize, usize, usize), time_series_end_move_rows: fn(*mut TimeSeriesQObject), time_series_begin_remove_rows: fn(*mut TimeSeriesQObject, usize, usize), time_series_end_remove_rows: fn(*mut TimeSeriesQObject), ) -> *mut TimeSeries { let time_series_emit = TimeSeriesEmitter { qobject: Arc::new(AtomicPtr::new(time_series)), new_data_ready: time_series_new_data_ready, }; let model = TimeSeriesList { qobject: time_series, layout_about_to_be_changed: time_series_layout_about_to_be_changed, layout_changed: time_series_layout_changed, data_changed: time_series_data_changed, begin_reset_model: time_series_begin_reset_model, end_reset_model: time_series_end_reset_model, begin_insert_rows: time_series_begin_insert_rows, end_insert_rows: time_series_end_insert_rows, begin_move_rows: time_series_begin_move_rows, end_move_rows: time_series_end_move_rows, begin_remove_rows: time_series_begin_remove_rows, end_remove_rows: time_series_end_remove_rows, }; let d_time_series = TimeSeries::new(time_series_emit, model); Box::into_raw(Box::new(d_time_series)) } #[no_mangle] pub unsafe extern "C" fn time_series_free(ptr: *mut TimeSeries) { Box::from_raw(ptr).emit().clear(); } #[no_mangle] pub unsafe extern "C" fn time_series_row_count(ptr: *const TimeSeries) -> c_int { to_c_int((&*ptr).row_count()) } #[no_mangle] pub unsafe extern "C" fn time_series_insert_rows(ptr: *mut TimeSeries, row: c_int, count: c_int) -> bool { (&mut *ptr).insert_rows(to_usize(row), to_usize(count)) } #[no_mangle] pub unsafe extern "C" fn time_series_remove_rows(ptr: *mut TimeSeries, row: c_int, count: c_int) -> bool { (&mut *ptr).remove_rows(to_usize(row), to_usize(count)) } #[no_mangle] pub unsafe extern "C" fn time_series_can_fetch_more(ptr: *const TimeSeries) -> bool { (&*ptr).can_fetch_more() } #[no_mangle] pub unsafe extern "C" fn time_series_fetch_more(ptr: *mut TimeSeries) { (&mut *ptr).fetch_more() } #[no_mangle] pub unsafe extern "C" fn time_series_sort( ptr: *mut TimeSeries, column: u8, order: SortOrder, ) { (&mut *ptr).sort(column, order) } #[no_mangle] pub unsafe extern "C" fn time_series_data_cos(ptr: *const TimeSeries, row: c_int) -> f32 { let o = &*ptr; o.cos(to_usize(row)).into() } #[no_mangle] pub unsafe extern "C" fn time_series_set_data_cos( ptr: *mut TimeSeries, row: c_int, v: f32, ) -> bool { (&mut *ptr).set_cos(to_usize(row), v) } #[no_mangle] pub unsafe extern "C" fn time_series_data_sin(ptr: *const TimeSeries, row: c_int) -> f32 { let o = &*ptr; o.sin(to_usize(row)).into() } #[no_mangle] pub unsafe extern "C" fn time_series_set_data_sin( ptr: *mut TimeSeries, row: c_int, v: f32, ) -> bool { (&mut *ptr).set_sin(to_usize(row), v) } #[no_mangle] pub unsafe extern "C" fn time_series_data_time(ptr: *const TimeSeries, row: c_int) -> f32 { let o = &*ptr; o.time(to_usize(row)).into() } #[no_mangle] pub unsafe extern "C" fn time_series_set_data_time( ptr: *mut TimeSeries, row: c_int, v: f32, ) -> bool { (&mut *ptr).set_time(to_usize(row), v) } diff --git a/src/configuration.rs b/src/configuration.rs index b63b5a9..4cf2c30 100644 --- a/src/configuration.rs +++ b/src/configuration.rs @@ -1,498 +1,498 @@ use configuration_private::*; use serde_json; use std::collections::{BTreeMap, BTreeSet}; use std::error::Error; use std::fs; use std::path::{Path, PathBuf}; use std::rc::Rc; use toml; mod json { use super::Rust; use std::collections::BTreeMap; use std::path::PathBuf; pub fn false_bool() -> bool { false } fn object() -> super::ObjectType { super::ObjectType::Object } #[derive(Deserialize)] #[serde(deny_unknown_fields)] pub struct Config { #[serde(rename = "cppFile")] pub cpp_file: PathBuf, pub objects: BTreeMap, pub rust: Rust, #[serde(default = "false_bool")] pub overwrite_implementation: bool, } #[derive(Deserialize)] #[serde(deny_unknown_fields)] pub struct Object { #[serde(default)] pub functions: BTreeMap, #[serde(rename = "itemProperties", default)] pub item_properties: BTreeMap, #[serde(rename = "type", default = "object")] pub object_type: super::ObjectType, #[serde(default)] pub properties: BTreeMap, } #[derive(Deserialize)] #[serde(deny_unknown_fields)] pub struct Property { #[serde(default = "false_bool")] pub optional: bool, #[serde(rename = "type")] pub property_type: String, #[serde(rename = "rustByFunction", default = "false_bool")] pub rust_by_function: bool, #[serde(default = "false_bool")] pub write: bool, } } pub enum RustEdition { Rust2015, Rust2018, Unknown, } impl<'a> ::std::convert::From> for RustEdition { fn from(str: Option<&'a str>) -> RustEdition { match str { None | Some("2015") => RustEdition::Rust2015, Some("2018") => RustEdition::Rust2018, _ => RustEdition::Unknown, } } } pub struct Config { pub config_file: PathBuf, pub cpp_file: PathBuf, pub objects: BTreeMap>, pub rust: Rust, pub rust_edition: RustEdition, pub overwrite_implementation: bool, } impl ConfigPrivate for Config { fn types(&self) -> BTreeSet { let mut ops = BTreeSet::new(); for o in self.objects.values() { for p in o.properties.values() { ops.insert(p.type_name().into()); } for p in o.item_properties.values() { ops.insert(p.type_name().into()); } for f in o.functions.values() { ops.insert(f.return_type.name().into()); for a in &f.arguments { ops.insert(a.type_name().into()); } } } ops } fn optional_types(&self) -> BTreeSet { let mut ops = BTreeSet::new(); for o in self.objects.values() { for p in o.properties.values() { if p.optional { ops.insert(p.type_name().into()); } } for p in o.item_properties.values() { if p.optional { ops.insert(p.type_name().into()); } } if o.object_type != ObjectType::Object { ops.insert("quintptr".into()); } } ops } fn has_list_or_tree(&self) -> bool { self.objects .values() .any(|o| o.object_type == ObjectType::List || o.object_type == ObjectType::Tree) } } #[derive(PartialEq)] pub struct Object { pub name: String, pub functions: BTreeMap, pub item_properties: BTreeMap, pub object_type: ObjectType, pub properties: BTreeMap, } impl ObjectPrivate for Object { fn contains_object(&self) -> bool { self.properties.values().any(|p| p.is_object()) } fn column_count(&self) -> usize { let mut column_count = 1; for ip in self.item_properties.values() { column_count = column_count.max(ip.roles.len()); } column_count } } #[derive(PartialEq)] pub struct Property { pub optional: bool, pub property_type: Type, pub rust_by_function: bool, pub write: bool, } impl PropertyPrivate for Property { fn is_object(&self) -> bool { self.property_type.is_object() } fn is_complex(&self) -> bool { self.property_type.is_complex() } fn c_get_type(&self) -> String { let name = self.property_type.name(); name.to_string() + "*, " + &name.to_lowercase() + "_set" } } impl TypeName for Property { fn type_name(&self) -> &str { self.property_type.name() } } #[derive(Deserialize)] #[serde(deny_unknown_fields)] pub struct Rust { pub dir: PathBuf, #[serde(rename = "implementationModule")] pub implementation_module: String, #[serde(rename = "interfaceModule")] pub interface_module: String, } #[derive(Deserialize, Clone, Copy, PartialEq)] pub enum ObjectType { Object, List, Tree, } #[derive(Deserialize, Clone, Copy, PartialEq)] pub enum SimpleType { QString, QByteArray, #[serde(rename = "bool")] Bool, #[serde(rename = "float")] Float, #[serde(rename = "double")] Double, #[serde(rename = "void")] Void, #[serde(rename = "qint8")] Qint8, #[serde(rename = "qint16")] Qint16, #[serde(rename = "qint32")] Qint32, #[serde(rename = "qint64")] Qint64, #[serde(rename = "quint8")] QUint8, #[serde(rename = "quint16")] QUint16, #[serde(rename = "quint32")] QUint32, #[serde(rename = "quint64")] QUint64, } impl SimpleTypePrivate for SimpleType { fn name(&self) -> &str { match self { SimpleType::QString => "QString", SimpleType::QByteArray => "QByteArray", SimpleType::Bool => "bool", SimpleType::Float => "float", SimpleType::Double => "double", SimpleType::Void => "void", SimpleType::Qint8 => "qint8", SimpleType::Qint16 => "qint16", SimpleType::Qint32 => "qint32", SimpleType::Qint64 => "qint64", SimpleType::QUint8 => "quint8", SimpleType::QUint16 => "quint16", SimpleType::QUint32 => "quint32", SimpleType::QUint64 => "quint64", } } fn cpp_set_type(&self) -> &str { match self { SimpleType::QString => "const QString&", SimpleType::QByteArray => "const QByteArray&", _ => self.name(), } } fn c_set_type(&self) -> &str { match self { SimpleType::QString => "qstring_t", SimpleType::QByteArray => "qbytearray_t", _ => self.name(), } } fn rust_type(&self) -> &str { match self { SimpleType::QString => "String", SimpleType::QByteArray => "Vec", SimpleType::Bool => "bool", SimpleType::Float => "f32", SimpleType::Double => "f64", SimpleType::Void => "()", SimpleType::Qint8 => "i8", SimpleType::Qint16 => "i16", SimpleType::Qint32 => "i32", SimpleType::Qint64 => "i64", SimpleType::QUint8 => "u8", SimpleType::QUint16 => "u16", SimpleType::QUint32 => "u32", SimpleType::QUint64 => "u64", } } fn rust_type_init(&self) -> &str { match self { SimpleType::QString => "String::new()", SimpleType::QByteArray => "Vec::new()", SimpleType::Bool => "false", SimpleType::Float | SimpleType::Double => "0.0", SimpleType::Void => "()", _ => "0", } } fn is_complex(&self) -> bool { self == &SimpleType::QString || self == &SimpleType::QByteArray } } #[derive(PartialEq)] pub enum Type { Simple(SimpleType), Object(Rc), } impl TypePrivate for Type { fn is_object(&self) -> bool { match self { Type::Object(_) => true, _ => false, } } fn is_complex(&self) -> bool { match self { Type::Simple(simple) => simple.is_complex(), _ => false, } } fn name(&self) -> &str { match self { Type::Simple(s) => s.name(), Type::Object(o) => &o.name, } } fn cpp_set_type(&self) -> &str { match self { Type::Simple(s) => s.cpp_set_type(), Type::Object(o) => &o.name, } } fn c_set_type(&self) -> &str { match self { Type::Simple(s) => s.c_set_type(), Type::Object(o) => &o.name, } } fn rust_type(&self) -> &str { match self { Type::Simple(s) => s.rust_type(), Type::Object(o) => &o.name, } } fn rust_type_init(&self) -> &str { match self { Type::Simple(s) => s.rust_type_init(), Type::Object(_) => unimplemented!(), } } } #[derive(Deserialize, Clone, PartialEq)] #[serde(deny_unknown_fields)] pub struct ItemProperty { #[serde(rename = "type")] pub item_property_type: SimpleType, #[serde(default = "json::false_bool")] pub optional: bool, #[serde(default)] pub roles: Vec>, #[serde(rename = "rustByValue", default = "json::false_bool")] pub rust_by_value: bool, #[serde(default = "json::false_bool")] pub write: bool, } impl TypeName for ItemProperty { fn type_name(&self) -> &str { self.item_property_type.name() } } impl ItemPropertyPrivate for ItemProperty { fn is_complex(&self) -> bool { self.item_property_type.is_complex() } fn cpp_set_type(&self) -> String { let t = self.item_property_type.cpp_set_type().to_string(); if self.optional { return "option_".to_string() + &t; } t } fn c_get_type(&self) -> String { let name = self.item_property_type.name(); name.to_string() + "*, " + &name.to_lowercase() + "_set" } fn c_set_type(&self) -> &str { self.item_property_type.c_set_type() } } #[derive(Deserialize, Clone, PartialEq)] #[serde(deny_unknown_fields)] pub struct Function { #[serde(rename = "return")] pub return_type: SimpleType, #[serde(rename = "mut", default = "json::false_bool")] pub mutable: bool, #[serde(default)] pub arguments: Vec, } impl TypeName for Function { fn type_name(&self) -> &str { self.return_type.name() } } #[derive(Deserialize, Clone, PartialEq)] #[serde(deny_unknown_fields)] pub struct Argument { pub name: String, #[serde(rename = "type")] pub argument_type: SimpleType, } impl TypeName for Argument { fn type_name(&self) -> &str { self.argument_type.name() } } fn post_process_property( a: (&String, &json::Property), b: &mut BTreeMap>, c: &BTreeMap, -) -> Result> { +) -> Result> { let name = &a.1.property_type; let t = match serde_json::from_str::(&format!("\"{}\"", name)) { Err(_) => { if b.get(name).is_none() { if let Some(object) = c.get(name) { post_process_object((name, object), b, c)?; } else { return Err(format!("Type {} cannot be found.", name).into()); } } Type::Object(Rc::clone(b.get(name).unwrap())) } Ok(simple) => Type::Simple(simple), }; Ok(Property { property_type: t, optional: a.1.optional, rust_by_function: a.1.rust_by_function, write: a.1.write, }) } fn post_process_object( a: (&String, &json::Object), b: &mut BTreeMap>, c: &BTreeMap, -) -> Result<(), Box> { +) -> Result<(), Box> { let mut properties = BTreeMap::default(); for p in &a.1.properties { properties.insert(p.0.clone(), post_process_property(p, b, c)?); } let object = Rc::new(Object { name: a.0.clone(), object_type: a.1.object_type, functions: a.1.functions.clone(), item_properties: a.1.item_properties.clone(), properties, }); b.insert(a.0.clone(), object); Ok(()) } -fn post_process(config_file: &Path, json: json::Config) -> Result> { +fn post_process(config_file: &Path, json: json::Config) -> Result> { let mut objects = BTreeMap::default(); for object in &json.objects { post_process_object(object, &mut objects, &json.objects)?; } let rust_edition: RustEdition = { let mut buf = config_file.to_path_buf(); buf.pop(); buf.push(&json.rust.dir); buf.push("Cargo.toml"); if !buf.exists() { return Err(format!("{} does not exist.", buf.display()).into()); } let manifest: toml::Value = fs::read_to_string(&buf)?.parse()?; manifest["package"] .get("edition") .and_then(|val| val.as_str()) .into() }; Ok(Config { config_file: config_file.into(), cpp_file: json.cpp_file, objects, rust: json.rust, rust_edition, overwrite_implementation: json.overwrite_implementation, }) } -pub fn parse>(config_file: P) -> Result> { +pub fn parse>(config_file: P) -> Result> { let contents = fs::read_to_string(config_file.as_ref())?; let config: json::Config = serde_json::from_str(&contents)?; post_process(config_file.as_ref(), config) } diff --git a/src/lib.rs b/src/lib.rs index acca2b8..7d2f440 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,43 +1,43 @@ extern crate regex; #[macro_use] extern crate serde_derive; extern crate serde_json; extern crate serde_xml_rs; extern crate toml; pub mod build; pub mod configuration; mod configuration_private; mod cpp; mod rust; mod util; use configuration::Config; use std::error::Error; use std::path::Path; /// Read a file with bindings. -pub fn read_bindings_file>(config_file: P) -> Result> { +pub fn read_bindings_file>(config_file: P) -> Result> { configuration::parse(config_file) } /// Generate bindings from a bindings configuration. -pub fn generate_bindings(config: &Config) -> Result<(), Box> { +pub fn generate_bindings(config: &Config) -> Result<(), Box> { cpp::write_header(config)?; cpp::write_cpp(config)?; rust::write_interface(config)?; rust::write_implementation(config)?; Ok(()) } /// Generate bindings from a bindings configuration file. pub fn generate_bindings_from_config_file>( config_file: P, overwrite_implementation: bool, -) -> Result<(), Box> { +) -> Result<(), Box> { let mut config = read_bindings_file(config_file)?; if overwrite_implementation { config.overwrite_implementation = true; } generate_bindings(&config) }