From 0c3e46497c1538be63fba931514c26170e72e682 Mon Sep 17 00:00:00 2001 From: Greg Hellings Date: Mon, 24 Feb 2025 23:18:38 -0600 Subject: [PATCH] Better wrapping with Rust Trying to hide most of the CXX nastiness behind the actual module Move the CXX ffi stuff to its own module Separate mgr and module mods Modify main.rs to use the basic code we have done so far --- build.rs | 2 +- src/cxx/mod.rs | 70 +++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 ++ src/main.rs | 10 ++++-- src/mgr.rs | 85 +++++++++++++------------------------------------- src/module.rs | 20 ++++++++++++ 6 files changed, 121 insertions(+), 68 deletions(-) create mode 100644 src/cxx/mod.rs create mode 100644 src/module.rs diff --git a/build.rs b/build.rs index d1b3d4c..4bb8a93 100644 --- a/build.rs +++ b/build.rs @@ -3,7 +3,7 @@ use system_deps; fn main() { let deps = system_deps::Config::new().probe().unwrap(); - cxx_build::bridge("src/mgr.rs") + cxx_build::bridge("src/cxx/mod.rs") .file("src/cxx/mgr.cc") .includes(deps.all_include_paths()) .cpp_link_stdlib("stdc++") diff --git a/src/cxx/mod.rs b/src/cxx/mod.rs new file mode 100644 index 0000000..26e18da --- /dev/null +++ b/src/cxx/mod.rs @@ -0,0 +1,70 @@ +#[cxx::bridge] +pub mod ffi { + unsafe extern "C++" { + include!("sword_rs/src/cxx/mgr.h"); + include!("sword_rs/src/cxx/module.h"); + + type Mgr; + type Module; + + fn new_mgr() -> UniquePtr; + fn new_mgr_with_path(path: &String) -> UniquePtr; + fn get_modules(self: &Mgr) -> Vec; + fn get_module(self: Pin<&mut Mgr>, name: &String) -> UniquePtr; + + fn get_name(self: &Module) -> String; + fn strip_text(self: Pin<&mut Module>) -> String; + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fs::{create_dir, File}; + use std::io::Write; + use tempfile; + + #[test] + fn can_create_mgr() { + let mgr = ffi::new_mgr(); + assert!(!mgr.is_null()); + } + + #[test] + fn reads_module_list() { + // Create a temporary directory to isolate tests + let dir = tempfile::tempdir().unwrap(); + // Create a basic SWORD directory + let mods_d = dir.path().join("mods.d"); + create_dir(&mods_d).unwrap(); + // Write a dummy conf file + let kjv_conf = mods_d.join("kjv.conf"); + { + let mut file = File::create(&kjv_conf).unwrap(); + writeln!(file, "[KJVdummy]").unwrap(); + writeln!(file, "DataPath=./modules/texts/ztext/kjv").unwrap(); + writeln!(file, "ModDrv=RawText").unwrap(); + writeln!(file, "Description=Test description").unwrap(); + writeln!(file, "About=A test conf file").unwrap(); + } + let mut mgr = ffi::new_mgr_with_path(&dir.path().to_str().unwrap().to_string()); + assert!(mgr.get_modules().len() == 1); + assert!(mgr.get_modules().contains(&String::from("KJVdummy"))); + + let mut module = mgr.pin_mut().get_module(&String::from("KJVdummy")); + assert!(module.pin_mut().get_name() == "KJVdummy"); + } + + #[test] + fn has_no_modules() { + let mgr = ffi::new_mgr_with_path( + &tempfile::tempdir() + .unwrap() + .path() + .to_str() + .unwrap() + .to_string(), + ); + assert!(mgr.get_modules().len() == 0); + } +} diff --git a/src/lib.rs b/src/lib.rs index 7983903..e39426e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,3 @@ +mod cxx; pub mod mgr; +mod module; diff --git a/src/main.rs b/src/main.rs index a2077b8..e02de51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,10 @@ -use sword_rs::mgr::{new_mgr, Mgr}; +use sword_rs::mgr::Mgr; fn main() { - let mgr = new_mgr(); - println!("{:?}", mgr.get_modules()); + let mut mgr = Mgr::new(); + for mod_name in mgr.get_modules() { + let mut module = mgr.get_module(&mod_name); + println!("Module: {}", module.get_name()); + println!("Text: {}", module.strip_text()); + } } diff --git a/src/mgr.rs b/src/mgr.rs index 4a21028..e83ec7f 100644 --- a/src/mgr.rs +++ b/src/mgr.rs @@ -1,72 +1,29 @@ -pub use ffi::*; +use crate::cxx::ffi; +use crate::module::Module; +use cxx::UniquePtr; -#[cxx::bridge] -mod ffi { - unsafe extern "C++" { - include!("sword_rs/src/cxx/mgr.h"); - include!("sword_rs/src/cxx/module.h"); - - type Mgr; - type Module; - - fn new_mgr() -> UniquePtr; - fn new_mgr_with_path(path: &String) -> UniquePtr; - fn get_modules(self: &Mgr) -> Vec; - fn get_module(self: Pin<&mut Mgr>, name: &String) -> UniquePtr; - - fn get_name(self: &Module) -> String; - fn strip_text(self: Pin<&mut Module>) -> String; - } +pub struct Mgr { + mgr: UniquePtr, } -#[cfg(test)] -mod tests { - use super::*; - use std::fs::{create_dir, File}; - use std::io::Write; - use tempfile; - - #[test] - fn can_create_mgr() { - let mgr = ffi::new_mgr(); - assert!(!mgr.is_null()); - } - - #[test] - fn reads_module_list() { - // Create a temporary directory to isolate tests - let dir = tempfile::tempdir().unwrap(); - // Create a basic SWORD directory - let mods_d = dir.path().join("mods.d"); - create_dir(&mods_d).unwrap(); - // Write a dummy conf file - let kjv_conf = mods_d.join("kjv.conf"); - { - let mut file = File::create(&kjv_conf).unwrap(); - writeln!(file, "[KJVdummy]").unwrap(); - writeln!(file, "DataPath=./modules/texts/ztext/kjv").unwrap(); - writeln!(file, "ModDrv=RawText").unwrap(); - writeln!(file, "Description=Test description").unwrap(); - writeln!(file, "About=A test conf file").unwrap(); +impl Mgr { + pub fn new() -> Self { + Self { + mgr: ffi::new_mgr(), } - let mut mgr = ffi::new_mgr_with_path(&dir.path().to_str().unwrap().to_string()); - assert!(mgr.get_modules().len() == 1); - assert!(mgr.get_modules().contains(&String::from("KJVdummy"))); - - let mut module = mgr.pin_mut().get_module(&String::from("KJVdummy")); - assert!(module.pin_mut().get_name() == "KJVdummy"); } - #[test] - fn has_no_modules() { - let mgr = ffi::new_mgr_with_path( - &tempfile::tempdir() - .unwrap() - .path() - .to_str() - .unwrap() - .to_string(), - ); - assert!(mgr.get_modules().len() == 0); + pub fn new_with_path(path: &String) -> Self { + Self { + mgr: ffi::new_mgr_with_path(path), + } + } + + pub fn get_modules(&self) -> Vec { + self.mgr.get_modules() + } + + pub fn get_module(&mut self, mod_name: &String) -> Module { + Module::new(self.mgr.pin_mut().get_module(mod_name)) } } diff --git a/src/module.rs b/src/module.rs new file mode 100644 index 0000000..1f46705 --- /dev/null +++ b/src/module.rs @@ -0,0 +1,20 @@ +use crate::cxx::ffi; +use cxx::UniquePtr; + +pub struct Module { + module: UniquePtr, +} + +impl Module { + pub fn new(module: UniquePtr) -> Self { + Self { module: module } + } + + pub fn get_name(&self) -> String { + self.module.get_name() + } + + pub fn strip_text(&mut self) -> String { + self.module.pin_mut().strip_text() + } +}