Files
ingey/src/lib.rs

138 lines
4.0 KiB
Rust

mod move_money;
use std::ffi::c_char;
use std::ffi::CStr;
use std::ffi::CString;
pub use self::move_money::*;
mod overhead_allocation;
pub use self::overhead_allocation::*;
mod create_products;
pub use self::create_products::*;
mod shared_models;
pub use self::shared_models::*;
#[no_mangle]
pub extern "C" fn move_money_from_text(
rules: *const c_char,
lines: *const c_char,
accounts: *const c_char,
cost_centres: *const c_char,
use_numeric_accounts: bool,
) -> *mut c_char {
let mut output_writer = csv::Writer::from_writer(vec![]);
let safe_rules = unsafe {
assert!(!rules.is_null());
CStr::from_ptr(rules)
};
let safe_lines = unsafe {
assert!(!lines.is_null());
CStr::from_ptr(lines)
};
let safe_accounts = unsafe {
assert!(!accounts.is_null());
CStr::from_ptr(accounts)
};
let safe_cost_centres = unsafe {
assert!(!cost_centres.is_null());
CStr::from_ptr(cost_centres)
};
move_money(
&mut csv::Reader::from_reader(safe_rules.to_bytes()),
&mut csv::Reader::from_reader(safe_lines.to_bytes()),
&mut csv::Reader::from_reader(safe_accounts.to_bytes()),
&mut csv::Reader::from_reader(safe_cost_centres.to_bytes()),
&mut output_writer,
use_numeric_accounts,
true,
)
.expect("Failed to move money");
// TODO: Replace all these unwraps with something more elegant
let inner = output_writer.into_inner().unwrap();
CString::new(String::from_utf8(inner).unwrap())
.unwrap()
.into_raw()
// Also some resources I looked at, in case things aren't going right:
// https://notes.huy.rocks/en/string-ffi-rust.html
// http://jakegoulding.com/rust-ffi-omnibus/string_return/
// https://rust-unofficial.github.io/patterns/idioms/ffi/passing-strings.html
// This looks like exactly what I'm doing too: https://mozilla.github.io/firefox-browser-architecture/experiments/2017-09-06-rust-on-ios.htmlcar
}
#[no_mangle]
pub extern "C" fn move_money_from_text_free(s: *mut c_char) {
unsafe {
if s.is_null() {
return;
}
CString::from_raw(s)
};
}
#[no_mangle]
pub extern "C" fn allocate_overheads_from_text(
lines: *const c_char,
accounts: *const c_char,
allocation_statistics: *const c_char,
areas: *const c_char,
cost_centres: *const c_char,
account_type: *const c_char,
use_numeric_accounts: bool,
) -> *mut c_char {
let lines = unsafe {
assert!(!lines.is_null());
CStr::from_ptr(lines)
};
let accounts = unsafe {
assert!(!accounts.is_null());
CStr::from_ptr(accounts)
};
let allocation_statistics = unsafe {
assert!(!allocation_statistics.is_null());
CStr::from_ptr(allocation_statistics)
};
let areas = unsafe {
assert!(!areas.is_null());
CStr::from_ptr(areas)
};
let cost_centres = unsafe {
assert!(!cost_centres.is_null());
CStr::from_ptr(cost_centres)
};
let account_type = unsafe {
assert!(!account_type.is_null());
CStr::from_ptr(account_type)
};
let mut output_writer = csv::Writer::from_writer(vec![]);
reciprocal_allocation(
csv::Reader::from_reader(lines.to_bytes()),
csv::Reader::from_reader(accounts.to_bytes()),
csv::Reader::from_reader(allocation_statistics.to_bytes()),
csv::Reader::from_reader(areas.to_bytes()),
csv::Reader::from_reader(cost_centres.to_bytes()),
&mut output_writer,
use_numeric_accounts,
false,
true,
account_type.to_str().unwrap().to_owned(),
)
.expect("Failed to allocate overheads");
let inner = output_writer.into_inner().unwrap();
CString::new(String::from_utf8(inner).unwrap())
.unwrap()
.into_raw()
}
#[no_mangle]
pub extern "C" fn allocate_overheads_from_text_free(s: *mut c_char) {
unsafe {
if s.is_null() {
return;
}
CString::from_raw(s)
};
}