Put the ffi in it's own module (for namespace control)

This commit is contained in:
Dane Johnson 2022-01-11 15:53:50 -06:00
parent 6430123d2f
commit 8d23af431e
2 changed files with 74 additions and 71 deletions

View File

@ -2,7 +2,7 @@ language = "C"
[export.rename]
"FooterType" = "footer"
"Footer" = "footer"
[enum]
rename_variants = "QualifiedScreamingSnakeCase"

View File

@ -38,7 +38,6 @@ pub struct StatChange {
addend: i32,
}
peg::parser! {
grammar storybook_parser() for str {
pub rule story() -> Vec<Page>
@ -168,84 +167,88 @@ impl From<Vec<Page>> for Book {
// C API
use std::ffi::CStr;
use std::ffi::CString;
use std::os::raw::c_char;
pub mod ffi {
use std::ffi::CStr;
use std::ffi::CString;
use std::os::raw::c_char;
#[no_mangle]
pub extern fn storybook_make_book(string: *const c_char) -> *mut Book {
use super::Book;
#[repr(C)]
pub enum Footer {
Ending,
Goto,
Choices,
}
#[no_mangle]
pub extern fn storybook_make_book(string: *const c_char) -> *mut Book {
let string = unsafe {
CStr::from_ptr(string)
};
let string = string.to_str().expect("Error, input string not valid UTF-8");
let pages = storybook_parser::story(string).expect("Error, input string could not be parsed");
let pages = super::storybook_parser::story(string).expect("Error, input string could not be parsed");
let book = Book::from(pages);
let book = Box::from(book);
Box::into_raw(book)
}
}
#[no_mangle]
pub extern fn storybook_free_book(book: *mut Book) {
#[no_mangle]
pub extern fn storybook_free_book(book: *mut Book) {
unsafe {
Box::from_raw(book);
}
}
}
#[no_mangle]
pub extern fn storybook_free_string(s: *mut c_char) {
#[no_mangle]
pub extern fn storybook_free_string(s: *mut c_char) {
unsafe {
drop(CString::from_raw(s));
}
}
}
fn get_book_from_ref<'a> (book: *mut Book) -> &'a mut Book {
fn get_book_from_ref<'a> (book: *mut Book) -> &'a mut Book {
let book = unsafe {
book.as_mut().expect("Invalid Book pointer")
};
book
}
}
#[no_mangle]
pub extern fn storybook_get_body(book: *mut Book) -> *mut c_char {
#[no_mangle]
pub extern fn storybook_get_body(book: *mut Book) -> *mut c_char {
let book = get_book_from_ref(book);
let body = book.get_current().body.clone();
let body = CString::new(body).expect("Body cannot be converted to CString");
body.into_raw()
}
}
#[repr(C)]
pub enum FooterType {
Ending,
Goto,
Choices,
}
#[no_mangle]
pub extern fn storybook_get_footer(book: *mut Book) -> FooterType {
#[no_mangle]
pub extern fn storybook_get_footer(book: *mut Book) -> Footer {
let book = get_book_from_ref(book);
match book.get_current().footer {
Footer::Ending => FooterType::Ending,
Footer::Goto(_) => FooterType::Goto,
Footer::Choices(_) => FooterType::Choices,
super::Footer::Ending => Footer::Ending,
super::Footer::Goto(_) => Footer::Goto,
super::Footer::Choices(_) => Footer::Choices,
}
}
}
#[no_mangle]
pub extern fn storybook_is_ended(book: *mut Book) -> bool {
#[no_mangle]
pub extern fn storybook_is_ended(book: *mut Book) -> bool {
let book = get_book_from_ref(book);
book.is_ended()
}
}
#[no_mangle]
pub extern fn storybook_advance_nooption(book: *mut Book) {
#[no_mangle]
pub extern fn storybook_advance_nooption(book: *mut Book) {
let book = get_book_from_ref(book);
book.advance_nooption();
}
#[no_mangle]
pub extern fn storybook_advance_option(book: *mut Book, option: u32) {
}
#[no_mangle]
pub extern fn storybook_advance_option(book: *mut Book, option: u32) {
let book = get_book_from_ref(book);
book.advance_option(option);
}
}
#[cfg(test)]