With a little help, we now have VerseKey
Went with a basic wrapper that cxx is able to handle for the bridge between the languages, along with simple wrapper methods
This commit is contained in:
@@ -1,23 +1,21 @@
|
||||
use system_deps;
|
||||
|
||||
fn main() {
|
||||
let sources = vec!["key", "mgr", "module", "versekey", "versification"];
|
||||
let deps = system_deps::Config::new().probe().unwrap();
|
||||
|
||||
cxx_build::bridge("src/cxx/mod.rs")
|
||||
.file("src/cxx/mgr.cc")
|
||||
.file("src/cxx/module.cc")
|
||||
.file("src/cxx/versification.cc")
|
||||
let mut build = cxx_build::bridge("src/cxx/mod.rs");
|
||||
for src in sources {
|
||||
build.file(&format!("src/cxx/{}.cc", src));
|
||||
println!("cargo:rerun-if-changed=src/cxx/{}.cc", src);
|
||||
println!("cargo:rerun-if-changed=src/cxx/{}.h", src);
|
||||
}
|
||||
build
|
||||
.includes(deps.all_include_paths())
|
||||
.cpp_link_stdlib("stdc++")
|
||||
.flag("-Os")
|
||||
.compile("sword_rs");
|
||||
|
||||
println!("cargo:rerun-if-changed=src/cxx/mod.rs");
|
||||
println!("cargo:rerun-if-changed=src/cxx/mgr.cc");
|
||||
println!("cargo:rerun-if-changed=src/cxx/mgr.h");
|
||||
println!("cargo:rerun-if-changed=src/cxx/module.cc");
|
||||
println!("cargo:rerun-if-changed=src/cxx/module.h");
|
||||
println!("cargo:rerun-if-changed=src/cxx/versification.h");
|
||||
println!("cargo:rerun-if-changed=src/cxx/versification.cc");
|
||||
println!("cargo:rustc-link-lib=sword");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "key.h"
|
||||
|
||||
namespace sword_rs {
|
||||
uint8_t Key::get_error() const {
|
||||
return this->getError();
|
||||
}
|
||||
|
||||
rust::String Key::get_locale() const {
|
||||
return rust::String(this->getLocale());
|
||||
}
|
||||
|
||||
rust::String Key::get_range_text() const {
|
||||
return rust::String(this->getRangeText());
|
||||
}
|
||||
|
||||
rust::String Key::get_short_text() const {
|
||||
return rust::String(this->getShortText());
|
||||
}
|
||||
|
||||
rust::String Key::get_text() const {
|
||||
return rust::String(this->getText());
|
||||
}
|
||||
|
||||
uint8_t Key::pop_error() {
|
||||
return this->popError();
|
||||
}
|
||||
|
||||
void Key::set_locale(const rust::String &locale) {
|
||||
this->setLocale(std::string(locale).c_str());
|
||||
}
|
||||
|
||||
void Key::set_text(const rust::String &text) {
|
||||
this->setText(std::string(text).c_str());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <sword/swkey.h>
|
||||
|
||||
#include "rust/cxx.h"
|
||||
|
||||
namespace sword_rs {
|
||||
class Key : public sword::SWKey {
|
||||
public:
|
||||
uint8_t get_error() const;
|
||||
rust::String get_locale() const;
|
||||
rust::String get_range_text() const;
|
||||
rust::String get_short_text() const;
|
||||
rust::String get_text() const;
|
||||
|
||||
uint8_t pop_error();
|
||||
|
||||
void set_locale(const rust::String &locale);
|
||||
void set_text(const rust::String &text);
|
||||
};
|
||||
}
|
||||
+160
@@ -4,6 +4,7 @@ pub mod ffi {
|
||||
include!("sword_rs/src/cxx/mgr.h");
|
||||
include!("sword_rs/src/cxx/module.h");
|
||||
include!("sword_rs/src/cxx/versification.h");
|
||||
include!("sword_rs/src/cxx/versekey.h");
|
||||
|
||||
type Mgr;
|
||||
|
||||
@@ -18,6 +19,7 @@ pub mod ffi {
|
||||
fn decrement(self: Pin<&mut Module>);
|
||||
fn get_name(self: &Module) -> String;
|
||||
fn get_type(self: &Module) -> String;
|
||||
fn get_verse_key(self: &Module) -> *mut VerseKey;
|
||||
fn increment(self: Pin<&mut Module>);
|
||||
fn is_skip_consecutive_links(self: &Module) -> bool;
|
||||
fn render_text(self: Pin<&mut Module>) -> String;
|
||||
@@ -31,6 +33,56 @@ pub mod ffi {
|
||||
fn getVersifications(self: &Versification) -> Vec<String>;
|
||||
fn getVersification(self: &Versification, name: &mut String) -> *const VersificationSystem;
|
||||
fn new_versification() -> UniquePtr<Versification>;
|
||||
|
||||
type VerseKey;
|
||||
// Factory functions for VerseKey
|
||||
fn new_verse_key() -> UniquePtr<VerseKey>;
|
||||
fn new_verse_key_from_text(text: &String) -> UniquePtr<VerseKey>;
|
||||
unsafe fn delete_verse_key(key: *mut VerseKey);
|
||||
|
||||
// From Key
|
||||
fn get_error(self: &VerseKey) -> u8;
|
||||
fn get_locale(self: &VerseKey) -> String;
|
||||
fn get_range_text(self: &VerseKey) -> String;
|
||||
fn get_short_text(self: &VerseKey) -> String;
|
||||
fn get_text(self: &VerseKey) -> String;
|
||||
fn normalize(self: Pin<&mut VerseKey>, autocheck: bool);
|
||||
// From VerseKey
|
||||
fn get_book_name(self: &VerseKey) -> String;
|
||||
fn get_book_abbrev(self: &VerseKey) -> String;
|
||||
fn get_osis_book_name(self: &VerseKey) -> String;
|
||||
fn get_osis_ref(self: &VerseKey) -> String;
|
||||
fn get_osis_ref_range_text(self: &VerseKey) -> String;
|
||||
fn get_short_range_text(self: &VerseKey) -> String;
|
||||
fn get_testament(self: &VerseKey) -> u8;
|
||||
fn get_testament_max(self: &VerseKey) -> u8;
|
||||
fn get_book(self: &VerseKey) -> u8;
|
||||
fn get_book_max(self: &VerseKey) -> u8;
|
||||
fn get_chapter(self: &VerseKey) -> u8;
|
||||
fn get_chapter_max(self: &VerseKey) -> u8;
|
||||
fn get_verse(self: &VerseKey) -> u8;
|
||||
fn get_verse_max(self: &VerseKey) -> u8;
|
||||
|
||||
// From VerseKey
|
||||
fn is_autonormalize(self: &VerseKey) -> bool;
|
||||
fn is_intros(self: &VerseKey) -> bool;
|
||||
// From Key
|
||||
fn pop_error(self: Pin<&mut VerseKey>) -> u8;
|
||||
|
||||
// From Key
|
||||
fn set_locale(self: Pin<&mut VerseKey>, locale: &String);
|
||||
fn set_text(self: Pin<&mut VerseKey>, text: &String);
|
||||
// From VerseKey
|
||||
fn set_autonormalize(self: Pin<&mut VerseKey>, autoNormalize: bool);
|
||||
fn set_book_name(self: Pin<&mut VerseKey>, bookName: &String);
|
||||
fn set_intros(self: Pin<&mut VerseKey>, intros: bool);
|
||||
fn set_testament(self: Pin<&mut VerseKey>, testament: u8);
|
||||
fn set_book(self: Pin<&mut VerseKey>, book: u8);
|
||||
fn set_chapter(self: Pin<&mut VerseKey>, chapter: u8);
|
||||
fn set_verse(self: Pin<&mut VerseKey>, verse: u8);
|
||||
|
||||
// Explicit cleanup
|
||||
fn cleanup(self: Pin<&mut VerseKey>);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,4 +144,112 @@ mod tests {
|
||||
);
|
||||
assert!(mgr.get_modules().len() == 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_create_verse_key() {
|
||||
let verse_key = ffi::new_verse_key();
|
||||
assert!(!verse_key.is_null());
|
||||
|
||||
// Test that we can call methods without errors
|
||||
let _testament = verse_key.get_testament();
|
||||
let _book = verse_key.get_book();
|
||||
let _chapter = verse_key.get_chapter();
|
||||
let _verse = verse_key.get_verse();
|
||||
let _book_name = verse_key.get_book_name();
|
||||
let _text = verse_key.get_text();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_create_verse_key_from_text() {
|
||||
let verse_key = ffi::new_verse_key_from_text(&"Genesis 1:1".to_string());
|
||||
assert!(!verse_key.is_null());
|
||||
|
||||
// Test that we can get values without errors
|
||||
let _chapter = verse_key.get_chapter();
|
||||
let _verse = verse_key.get_verse();
|
||||
let _text = verse_key.get_text();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verse_key_can_be_modified() {
|
||||
let mut verse_key = ffi::new_verse_key();
|
||||
|
||||
// Test that we can call setter methods without panicking
|
||||
verse_key.pin_mut().set_chapter(5);
|
||||
verse_key.pin_mut().set_verse(10);
|
||||
verse_key.pin_mut().set_text(&"Genesis 1:1".to_string());
|
||||
|
||||
// Test that we can call getter methods after setting
|
||||
let _chapter = verse_key.get_chapter();
|
||||
let _verse = verse_key.get_verse();
|
||||
let _text = verse_key.get_text();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn high_level_verse_key_api() {
|
||||
use crate::versekey::VerseKey;
|
||||
|
||||
// Test owned VerseKey creation and usage
|
||||
let mut verse_key = VerseKey::new();
|
||||
|
||||
// Test that we can call methods without panicking
|
||||
verse_key.set_chapter(3);
|
||||
verse_key.set_verse(16);
|
||||
verse_key.set_text("John 3:16");
|
||||
|
||||
// Test getters
|
||||
let _book_name = verse_key.get_book_name();
|
||||
let _text = verse_key.get_text();
|
||||
let _chapter = verse_key.get_chapter();
|
||||
let _verse = verse_key.get_verse();
|
||||
|
||||
// Test creation from text
|
||||
let verse_key2 = VerseKey::from_text("Romans 8:28");
|
||||
let _text2 = verse_key2.get_text();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn borrowed_verse_key_from_module() {
|
||||
use std::fs::{create_dir, File};
|
||||
use std::io::Write;
|
||||
use tempfile;
|
||||
|
||||
// Create a temporary directory with a module
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
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();
|
||||
}
|
||||
|
||||
// Create manager and get module
|
||||
let mut mgr = ffi::new_mgr_with_path(&dir.path().to_str().unwrap().to_string());
|
||||
let mut module = mgr.pin_mut().get_module(&String::from("KJVdummy"));
|
||||
|
||||
// Test that we can get a VerseKey from the module
|
||||
let verse_key_ptr = module.pin_mut().get_verse_key();
|
||||
if !verse_key_ptr.is_null() {
|
||||
// Test that we can create a BorrowedVerseKey and use it
|
||||
let borrowed_verse_key =
|
||||
unsafe { crate::versekey::BorrowedVerseKey::from_ptr(verse_key_ptr) };
|
||||
|
||||
if let Some(mut borrowed_vk) = borrowed_verse_key {
|
||||
// Test that we can call methods without panicking
|
||||
let _book_name = borrowed_vk.get_book_name();
|
||||
let _text = borrowed_vk.get_text();
|
||||
borrowed_vk.set_chapter(1);
|
||||
borrowed_vk.set_verse(1);
|
||||
let _chapter = borrowed_vk.get_chapter();
|
||||
let _verse = borrowed_vk.get_verse();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,16 @@ namespace sword_rs {
|
||||
return rust::String(this->module->getType());
|
||||
}
|
||||
|
||||
VerseKey* Module::get_verse_key() const {
|
||||
sword::VerseKey* key = dynamic_cast<sword::VerseKey*>(this->module->getKey());
|
||||
if (key) {
|
||||
// Create a borrowed VerseKey on the heap - caller must delete but not the inner ptr
|
||||
VerseKey* result = new VerseKey{key, false};
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Module::increment() {
|
||||
this->module->increment();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <sword/swmodule.h>
|
||||
#include <string>
|
||||
|
||||
#include "rust/cxx.h"
|
||||
#include "versekey.h"
|
||||
|
||||
namespace sword_rs {
|
||||
class Module {
|
||||
@@ -19,6 +21,8 @@ namespace sword_rs {
|
||||
|
||||
rust::String get_type() const;
|
||||
|
||||
VerseKey* get_verse_key() const;
|
||||
|
||||
void increment();
|
||||
|
||||
bool is_skip_consecutive_links() const;
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
#include "versekey.h"
|
||||
#include <memory>
|
||||
#include <sword/versekey.h>
|
||||
|
||||
namespace sword_rs {
|
||||
// Key methods
|
||||
uint8_t VerseKey::get_error() const {
|
||||
return ptr ? ptr->getError() : 0;
|
||||
}
|
||||
|
||||
rust::String VerseKey::get_locale() const {
|
||||
return ptr ? rust::String(ptr->getLocale()) : rust::String("");
|
||||
}
|
||||
|
||||
rust::String VerseKey::get_range_text() const {
|
||||
return ptr ? rust::String(ptr->getRangeText()) : rust::String("");
|
||||
}
|
||||
|
||||
rust::String VerseKey::get_short_text() const {
|
||||
return ptr ? rust::String(ptr->getShortText()) : rust::String("");
|
||||
}
|
||||
|
||||
rust::String VerseKey::get_text() const {
|
||||
return ptr ? rust::String(ptr->getText()) : rust::String("");
|
||||
}
|
||||
|
||||
void VerseKey::normalize(bool autocheck) {
|
||||
if (ptr) {
|
||||
ptr->normalize(autocheck);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t VerseKey::pop_error() {
|
||||
return ptr ? ptr->popError() : 0;
|
||||
}
|
||||
|
||||
void VerseKey::set_locale(const rust::String &locale) {
|
||||
if (ptr) {
|
||||
ptr->setLocale(std::string(locale).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void VerseKey::set_text(const rust::String &text) {
|
||||
if (ptr) {
|
||||
ptr->setText(std::string(text).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// VerseKey specific methods
|
||||
rust::String VerseKey::get_book_name() const {
|
||||
return ptr ? rust::String(ptr->getBookName()) : rust::String("");
|
||||
}
|
||||
|
||||
rust::String VerseKey::get_book_abbrev() const {
|
||||
return ptr ? rust::String(ptr->getBookAbbrev()) : rust::String("");
|
||||
}
|
||||
|
||||
rust::String VerseKey::get_osis_book_name() const {
|
||||
return ptr ? rust::String(ptr->getOSISBookName()) : rust::String("");
|
||||
}
|
||||
|
||||
rust::String VerseKey::get_osis_ref() const {
|
||||
return ptr ? rust::String(ptr->getOSISRef()) : rust::String("");
|
||||
}
|
||||
|
||||
rust::String VerseKey::get_osis_ref_range_text() const {
|
||||
return ptr ? rust::String(ptr->getOSISRefRangeText()) : rust::String("");
|
||||
}
|
||||
|
||||
rust::String VerseKey::get_short_range_text() const {
|
||||
return ptr ? rust::String(ptr->getShortRangeText()) : rust::String("");
|
||||
}
|
||||
|
||||
uint8_t VerseKey::get_testament() const {
|
||||
return ptr ? ptr->getTestament() : 0;
|
||||
}
|
||||
|
||||
uint8_t VerseKey::get_testament_max() const {
|
||||
return ptr ? ptr->getTestamentMax() : 0;
|
||||
}
|
||||
|
||||
uint8_t VerseKey::get_book() const {
|
||||
return ptr ? ptr->getBook() : 0;
|
||||
}
|
||||
|
||||
uint8_t VerseKey::get_book_max() const {
|
||||
return ptr ? ptr->getBookMax() : 0;
|
||||
}
|
||||
|
||||
uint8_t VerseKey::get_chapter() const {
|
||||
return ptr ? ptr->getChapter() : 0;
|
||||
}
|
||||
|
||||
uint8_t VerseKey::get_chapter_max() const {
|
||||
return ptr ? ptr->getChapterMax() : 0;
|
||||
}
|
||||
|
||||
uint8_t VerseKey::get_verse() const {
|
||||
return ptr ? ptr->getVerse() : 0;
|
||||
}
|
||||
|
||||
uint8_t VerseKey::get_verse_max() const {
|
||||
return ptr ? ptr->getVerseMax() : 0;
|
||||
}
|
||||
|
||||
bool VerseKey::is_autonormalize() const {
|
||||
return ptr ? ptr->isAutoNormalize() : false;
|
||||
}
|
||||
|
||||
bool VerseKey::is_intros() const {
|
||||
return ptr ? ptr->isIntros() : false;
|
||||
}
|
||||
|
||||
void VerseKey::set_autonormalize(bool autoNormalize) {
|
||||
if (ptr) {
|
||||
ptr->setAutoNormalize(autoNormalize);
|
||||
}
|
||||
}
|
||||
|
||||
void VerseKey::set_book_name(const rust::String &bookName) {
|
||||
if (ptr) {
|
||||
ptr->setBookName(std::string(bookName).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void VerseKey::set_intros(bool intros) {
|
||||
if (ptr) {
|
||||
ptr->setIntros(intros);
|
||||
}
|
||||
}
|
||||
|
||||
void VerseKey::set_testament(uint8_t testament) {
|
||||
if (ptr) {
|
||||
ptr->setTestament(testament);
|
||||
}
|
||||
}
|
||||
|
||||
void VerseKey::set_book(uint8_t book) {
|
||||
if (ptr) {
|
||||
ptr->setBook(book);
|
||||
}
|
||||
}
|
||||
|
||||
void VerseKey::set_chapter(uint8_t chapter) {
|
||||
if (ptr) {
|
||||
ptr->setChapter(chapter);
|
||||
}
|
||||
}
|
||||
|
||||
void VerseKey::set_verse(uint8_t verse) {
|
||||
if (ptr) {
|
||||
ptr->setVerse(verse);
|
||||
}
|
||||
}
|
||||
|
||||
// Explicit cleanup method
|
||||
void VerseKey::cleanup() {
|
||||
if (owned && ptr) {
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
owned = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Factory functions
|
||||
std::unique_ptr<VerseKey> new_verse_key() {
|
||||
auto verse_key = std::unique_ptr<VerseKey>(new VerseKey{new sword::VerseKey(), true});
|
||||
return verse_key;
|
||||
}
|
||||
|
||||
std::unique_ptr<VerseKey> new_verse_key_from_text(const rust::String& text) {
|
||||
auto verse_key = std::unique_ptr<VerseKey>(new VerseKey{new sword::VerseKey(std::string(text).c_str()), true});
|
||||
return verse_key;
|
||||
}
|
||||
|
||||
VerseKey verse_key_from_borrowed(sword::VerseKey* key) {
|
||||
VerseKey verse_key{key, false};
|
||||
return verse_key;
|
||||
}
|
||||
|
||||
void delete_verse_key(VerseKey* key) {
|
||||
if (key) {
|
||||
key->cleanup();
|
||||
delete key;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <sword/swkey.h>
|
||||
#include <sword/versekey.h>
|
||||
#include "rust/cxx.h"
|
||||
|
||||
namespace sword_rs {
|
||||
// Trivial wrapper that just holds a pointer and ownership flag
|
||||
// No destructor - cleanup is handled explicitly
|
||||
struct VerseKey {
|
||||
sword::VerseKey* ptr;
|
||||
bool owned;
|
||||
|
||||
// Key methods
|
||||
uint8_t get_error() const;
|
||||
rust::String get_locale() const;
|
||||
rust::String get_range_text() const;
|
||||
rust::String get_short_text() const;
|
||||
rust::String get_text() const;
|
||||
void normalize(bool autocheck);
|
||||
uint8_t pop_error();
|
||||
void set_locale(const rust::String &locale);
|
||||
void set_text(const rust::String &text);
|
||||
|
||||
// VerseKey methods
|
||||
rust::String get_book_name() const;
|
||||
rust::String get_book_abbrev() const;
|
||||
rust::String get_osis_book_name() const;
|
||||
rust::String get_osis_ref() const;
|
||||
rust::String get_osis_ref_range_text() const;
|
||||
rust::String get_short_range_text() const;
|
||||
uint8_t get_testament() const;
|
||||
uint8_t get_testament_max() const;
|
||||
uint8_t get_book() const;
|
||||
uint8_t get_book_max() const;
|
||||
uint8_t get_chapter() const;
|
||||
uint8_t get_chapter_max() const;
|
||||
uint8_t get_verse() const;
|
||||
uint8_t get_verse_max() const;
|
||||
|
||||
bool is_autonormalize() const;
|
||||
bool is_intros() const;
|
||||
|
||||
void set_autonormalize(bool autoNormalize);
|
||||
void set_book_name(const rust::String &bookName);
|
||||
void set_intros(bool intros);
|
||||
void set_testament(uint8_t testament);
|
||||
void set_book(uint8_t book);
|
||||
void set_chapter(uint8_t chapter);
|
||||
void set_verse(uint8_t verse);
|
||||
|
||||
// Explicit cleanup method
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
// Factory functions for creating VerseKeys
|
||||
std::unique_ptr<VerseKey> new_verse_key();
|
||||
std::unique_ptr<VerseKey> new_verse_key_from_text(const rust::String& text);
|
||||
VerseKey verse_key_from_borrowed(sword::VerseKey* key);
|
||||
|
||||
// Memory management for raw VerseKey pointers
|
||||
void delete_verse_key(VerseKey* key);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
mod cxx;
|
||||
pub mod mgr;
|
||||
pub mod module;
|
||||
pub mod versekey;
|
||||
|
||||
+19
@@ -2,6 +2,25 @@ use rand::Rng;
|
||||
use sword_rs::mgr::{Format, Mgr};
|
||||
|
||||
fn main() {
|
||||
one_chapter();
|
||||
// iterate();
|
||||
}
|
||||
|
||||
fn one_chapter() {
|
||||
let mut mgr = Mgr::new_with_format(Format::HTMLHref);
|
||||
let mut module = mgr.get_module(&String::from("KJV"));
|
||||
let mut key = module
|
||||
.get_verse_key()
|
||||
.expect("This was not a verse based module?!");
|
||||
key.set_book_name(&String::from("John"));
|
||||
key.set_chapter(3);
|
||||
for verse in 1..=key.get_verse_max() {
|
||||
key.set_verse(verse);
|
||||
println!("{}: {}", key.get_short_text(), module.render_text());
|
||||
}
|
||||
}
|
||||
|
||||
fn iterate() {
|
||||
let mut mgr = Mgr::new_with_format(Format::HTMLHref);
|
||||
for mod_name in mgr.get_modules() {
|
||||
let mut module = mgr.get_module(&mod_name);
|
||||
|
||||
@@ -83,4 +83,16 @@ impl Module {
|
||||
pub fn strip_text(&mut self) -> String {
|
||||
self.module.pin_mut().strip_text()
|
||||
}
|
||||
|
||||
pub fn get_verse_key(&mut self) -> Option<crate::versekey::BorrowedVerseKey> {
|
||||
match self.get_type() {
|
||||
Type::BiblicalTexts => unsafe {
|
||||
crate::versekey::BorrowedVerseKey::from_ptr(self.module.pin_mut().get_verse_key())
|
||||
},
|
||||
Type::Commentaries => unsafe {
|
||||
crate::versekey::BorrowedVerseKey::from_ptr(self.module.pin_mut().get_verse_key())
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+398
@@ -0,0 +1,398 @@
|
||||
use crate::cxx::ffi;
|
||||
|
||||
/// Safe wrapper for owned VerseKey instances
|
||||
pub struct VerseKey {
|
||||
inner: cxx::UniquePtr<ffi::VerseKey>,
|
||||
}
|
||||
|
||||
impl VerseKey {
|
||||
/// Create a new VerseKey
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
inner: ffi::new_verse_key(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new VerseKey from text
|
||||
pub fn from_text(text: &str) -> Self {
|
||||
Self {
|
||||
inner: ffi::new_verse_key_from_text(&text.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the book name
|
||||
pub fn get_book_name(&self) -> String {
|
||||
self.inner.get_book_name()
|
||||
}
|
||||
|
||||
/// Get the book abbreviation
|
||||
pub fn get_book_abbrev(&self) -> String {
|
||||
self.inner.get_book_abbrev()
|
||||
}
|
||||
|
||||
/// Get the OSIS book name
|
||||
pub fn get_osis_book_name(&self) -> String {
|
||||
self.inner.get_osis_book_name()
|
||||
}
|
||||
|
||||
/// Get the OSIS reference
|
||||
pub fn get_osis_ref(&self) -> String {
|
||||
self.inner.get_osis_ref()
|
||||
}
|
||||
|
||||
/// Get the OSIS reference range text
|
||||
pub fn get_osis_ref_range_text(&self) -> String {
|
||||
self.inner.get_osis_ref_range_text()
|
||||
}
|
||||
|
||||
/// Get the short range text
|
||||
pub fn get_short_range_text(&self) -> String {
|
||||
self.inner.get_short_range_text()
|
||||
}
|
||||
|
||||
/// Get the testament number
|
||||
pub fn get_testament(&self) -> u8 {
|
||||
self.inner.get_testament()
|
||||
}
|
||||
|
||||
/// Get the maximum testament number
|
||||
pub fn get_testament_max(&self) -> u8 {
|
||||
self.inner.get_testament_max()
|
||||
}
|
||||
|
||||
/// Get the book number
|
||||
pub fn get_book(&self) -> u8 {
|
||||
self.inner.get_book()
|
||||
}
|
||||
|
||||
/// Get the maximum book number
|
||||
pub fn get_book_max(&self) -> u8 {
|
||||
self.inner.get_book_max()
|
||||
}
|
||||
|
||||
/// Get the chapter number
|
||||
pub fn get_chapter(&self) -> u8 {
|
||||
self.inner.get_chapter()
|
||||
}
|
||||
|
||||
/// Get the maximum chapter number
|
||||
pub fn get_chapter_max(&self) -> u8 {
|
||||
self.inner.get_chapter_max()
|
||||
}
|
||||
|
||||
/// Get the verse number
|
||||
pub fn get_verse(&self) -> u8 {
|
||||
self.inner.get_verse()
|
||||
}
|
||||
|
||||
/// Get the maximum verse number
|
||||
pub fn get_verse_max(&self) -> u8 {
|
||||
self.inner.get_verse_max()
|
||||
}
|
||||
|
||||
/// Check if auto-normalize is enabled
|
||||
pub fn is_autonormalize(&self) -> bool {
|
||||
self.inner.is_autonormalize()
|
||||
}
|
||||
|
||||
/// Check if intros are enabled
|
||||
pub fn is_intros(&self) -> bool {
|
||||
self.inner.is_intros()
|
||||
}
|
||||
|
||||
/// Get the error code
|
||||
pub fn get_error(&self) -> u8 {
|
||||
self.inner.get_error()
|
||||
}
|
||||
|
||||
/// Get the locale
|
||||
pub fn get_locale(&self) -> String {
|
||||
self.inner.get_locale()
|
||||
}
|
||||
|
||||
/// Get the range text
|
||||
pub fn get_range_text(&self) -> String {
|
||||
self.inner.get_range_text()
|
||||
}
|
||||
|
||||
/// Get the short text
|
||||
pub fn get_short_text(&self) -> String {
|
||||
self.inner.get_short_text()
|
||||
}
|
||||
|
||||
/// Get the text
|
||||
pub fn get_text(&self) -> String {
|
||||
self.inner.get_text()
|
||||
}
|
||||
|
||||
/// Normalize the key
|
||||
pub fn normalize(&mut self, autocheck: bool) {
|
||||
self.inner.pin_mut().normalize(autocheck)
|
||||
}
|
||||
|
||||
/// Pop an error
|
||||
pub fn pop_error(&mut self) -> u8 {
|
||||
self.inner.pin_mut().pop_error()
|
||||
}
|
||||
|
||||
/// Set auto-normalize
|
||||
pub fn set_autonormalize(&mut self, auto_normalize: bool) {
|
||||
self.inner.pin_mut().set_autonormalize(auto_normalize)
|
||||
}
|
||||
|
||||
/// Set the book name
|
||||
pub fn set_book_name(&mut self, book_name: &str) {
|
||||
self.inner.pin_mut().set_book_name(&book_name.to_string())
|
||||
}
|
||||
|
||||
/// Set intros
|
||||
pub fn set_intros(&mut self, intros: bool) {
|
||||
self.inner.pin_mut().set_intros(intros)
|
||||
}
|
||||
|
||||
/// Set the locale
|
||||
pub fn set_locale(&mut self, locale: &str) {
|
||||
self.inner.pin_mut().set_locale(&locale.to_string())
|
||||
}
|
||||
|
||||
/// Set the text
|
||||
pub fn set_text(&mut self, text: &str) {
|
||||
self.inner.pin_mut().set_text(&text.to_string())
|
||||
}
|
||||
|
||||
/// Set the testament
|
||||
pub fn set_testament(&mut self, testament: u8) {
|
||||
self.inner.pin_mut().set_testament(testament)
|
||||
}
|
||||
|
||||
/// Set the book
|
||||
pub fn set_book(&mut self, book: u8) {
|
||||
self.inner.pin_mut().set_book(book)
|
||||
}
|
||||
|
||||
/// Set the chapter
|
||||
pub fn set_chapter(&mut self, chapter: u8) {
|
||||
self.inner.pin_mut().set_chapter(chapter)
|
||||
}
|
||||
|
||||
/// Set the verse
|
||||
pub fn set_verse(&mut self, verse: u8) {
|
||||
self.inner.pin_mut().set_verse(verse)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for VerseKey {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper for borrowed VerseKey instances (from modules)
|
||||
pub struct BorrowedVerseKey {
|
||||
ptr: *mut ffi::VerseKey,
|
||||
}
|
||||
|
||||
impl BorrowedVerseKey {
|
||||
/// Create from a raw pointer (unsafe)
|
||||
pub unsafe fn from_ptr(ptr: *mut ffi::VerseKey) -> Option<Self> {
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(Self { ptr })
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the book name
|
||||
pub fn get_book_name(&self) -> String {
|
||||
unsafe { (&*self.ptr).get_book_name() }
|
||||
}
|
||||
|
||||
/// Get the book abbreviation
|
||||
pub fn get_book_abbrev(&self) -> String {
|
||||
unsafe { (&*self.ptr).get_book_abbrev() }
|
||||
}
|
||||
|
||||
/// Get the OSIS book name
|
||||
pub fn get_osis_book_name(&self) -> String {
|
||||
unsafe { (&*self.ptr).get_osis_book_name() }
|
||||
}
|
||||
|
||||
/// Get the OSIS reference
|
||||
pub fn get_osis_ref(&self) -> String {
|
||||
unsafe { (&*self.ptr).get_osis_ref() }
|
||||
}
|
||||
|
||||
/// Get the OSIS reference range text
|
||||
pub fn get_osis_ref_range_text(&self) -> String {
|
||||
unsafe { (&*self.ptr).get_osis_ref_range_text() }
|
||||
}
|
||||
|
||||
/// Get the short range text
|
||||
pub fn get_short_range_text(&self) -> String {
|
||||
unsafe { (&*self.ptr).get_short_range_text() }
|
||||
}
|
||||
|
||||
/// Get the testament number
|
||||
pub fn get_testament(&self) -> u8 {
|
||||
unsafe { (&*self.ptr).get_testament() }
|
||||
}
|
||||
|
||||
/// Get the maximum testament number
|
||||
pub fn get_testament_max(&self) -> u8 {
|
||||
unsafe { (&*self.ptr).get_testament_max() }
|
||||
}
|
||||
|
||||
/// Get the book number
|
||||
pub fn get_book(&self) -> u8 {
|
||||
unsafe { (&*self.ptr).get_book() }
|
||||
}
|
||||
|
||||
/// Get the maximum book number
|
||||
pub fn get_book_max(&self) -> u8 {
|
||||
unsafe { (&*self.ptr).get_book_max() }
|
||||
}
|
||||
|
||||
/// Get the chapter number
|
||||
pub fn get_chapter(&self) -> u8 {
|
||||
unsafe { (&*self.ptr).get_chapter() }
|
||||
}
|
||||
|
||||
/// Get the maximum chapter number
|
||||
pub fn get_chapter_max(&self) -> u8 {
|
||||
unsafe { (&*self.ptr).get_chapter_max() }
|
||||
}
|
||||
|
||||
/// Get the verse number
|
||||
pub fn get_verse(&self) -> u8 {
|
||||
unsafe { (&*self.ptr).get_verse() }
|
||||
}
|
||||
|
||||
/// Get the maximum verse number
|
||||
pub fn get_verse_max(&self) -> u8 {
|
||||
unsafe { (&*self.ptr).get_verse_max() }
|
||||
}
|
||||
|
||||
/// Check if auto-normalize is enabled
|
||||
pub fn is_autonormalize(&self) -> bool {
|
||||
unsafe { (&*self.ptr).is_autonormalize() }
|
||||
}
|
||||
|
||||
/// Check if intros are enabled
|
||||
pub fn is_intros(&self) -> bool {
|
||||
unsafe { (&*self.ptr).is_intros() }
|
||||
}
|
||||
|
||||
/// Get the error code
|
||||
pub fn get_error(&self) -> u8 {
|
||||
unsafe { (&*self.ptr).get_error() }
|
||||
}
|
||||
|
||||
/// Get the locale
|
||||
pub fn get_locale(&self) -> String {
|
||||
unsafe { (&*self.ptr).get_locale() }
|
||||
}
|
||||
|
||||
/// Get the range text
|
||||
pub fn get_range_text(&self) -> String {
|
||||
unsafe { (&*self.ptr).get_range_text() }
|
||||
}
|
||||
|
||||
/// Get the short text
|
||||
pub fn get_short_text(&self) -> String {
|
||||
unsafe { (&*self.ptr).get_short_text() }
|
||||
}
|
||||
|
||||
/// Get the text
|
||||
pub fn get_text(&self) -> String {
|
||||
unsafe { (&*self.ptr).get_text() }
|
||||
}
|
||||
|
||||
/// Normalize the key
|
||||
pub fn normalize(&mut self, autocheck: bool) {
|
||||
unsafe {
|
||||
std::pin::Pin::new_unchecked(&mut *self.ptr).normalize(autocheck);
|
||||
}
|
||||
}
|
||||
|
||||
/// Pop an error
|
||||
pub fn pop_error(&mut self) -> u8 {
|
||||
unsafe { std::pin::Pin::new_unchecked(&mut *self.ptr).pop_error() }
|
||||
}
|
||||
|
||||
/// Set auto-normalize
|
||||
pub fn set_autonormalize(&mut self, auto_normalize: bool) {
|
||||
unsafe {
|
||||
std::pin::Pin::new_unchecked(&mut *self.ptr).set_autonormalize(auto_normalize);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the book name
|
||||
pub fn set_book_name(&mut self, book_name: &str) {
|
||||
unsafe {
|
||||
std::pin::Pin::new_unchecked(&mut *self.ptr).set_book_name(&book_name.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
/// Set intros
|
||||
pub fn set_intros(&mut self, intros: bool) {
|
||||
unsafe {
|
||||
std::pin::Pin::new_unchecked(&mut *self.ptr).set_intros(intros);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the locale
|
||||
pub fn set_locale(&mut self, locale: &str) {
|
||||
unsafe {
|
||||
std::pin::Pin::new_unchecked(&mut *self.ptr).set_locale(&locale.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the text
|
||||
pub fn set_text(&mut self, text: &str) {
|
||||
unsafe {
|
||||
std::pin::Pin::new_unchecked(&mut *self.ptr).set_text(&text.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the testament
|
||||
pub fn set_testament(&mut self, testament: u8) {
|
||||
unsafe {
|
||||
std::pin::Pin::new_unchecked(&mut *self.ptr).set_testament(testament);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the book
|
||||
pub fn set_book(&mut self, book: u8) {
|
||||
unsafe {
|
||||
std::pin::Pin::new_unchecked(&mut *self.ptr).set_book(book);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the chapter
|
||||
pub fn set_chapter(&mut self, chapter: u8) {
|
||||
unsafe {
|
||||
std::pin::Pin::new_unchecked(&mut *self.ptr).set_chapter(chapter);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the verse
|
||||
pub fn set_verse(&mut self, verse: u8) {
|
||||
unsafe {
|
||||
std::pin::Pin::new_unchecked(&mut *self.ptr).set_verse(verse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for BorrowedVerseKey {
|
||||
fn drop(&mut self) {
|
||||
if !self.ptr.is_null() {
|
||||
unsafe {
|
||||
ffi::delete_verse_key(self.ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Safety: BorrowedVerseKey can be sent between threads safely as long as
|
||||
// the underlying SWORD library is thread-safe for reading
|
||||
unsafe impl Send for BorrowedVerseKey {}
|
||||
Reference in New Issue
Block a user