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] [export.rename]
"FooterType" = "footer" "Footer" = "footer"
[enum] [enum]
rename_variants = "QualifiedScreamingSnakeCase" rename_variants = "QualifiedScreamingSnakeCase"

View File

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