xler/native/xler_native/src/lib.rs

62 lines
1.5 KiB
Rust

extern crate calamine;
extern crate lazy_static;
extern crate rustler;
use calamine::Error as CaError;
use calamine::{open_workbook_auto, Reader};
rustler::init!("Elixir.Xler.Native");
mod atoms {
rustler::atoms! {
ok,
error,
// Posix
enoent, // File does not exist
eacces, // Permission denied
epipe, // Broken pipe
eexist, // File exists
}
}
type Sheet = Vec<Vec<String>>;
type SheetName = String;
type Worksheets = Vec<SheetName>;
fn io_error_to_term(err: &CaError) -> String {
let error = match err {
_ => format!("{}", err),
};
error
}
#[rustler::nif(schedule = "DirtyCpu")]
fn worksheets(filename: String) -> Result<Worksheets, String> {
match open_workbook_auto(&filename) {
Err(ref error) => Err(io_error_to_term(error)),
Ok(ref inner) => Ok(inner.sheet_names().to_owned()),
}
}
#[rustler::nif(schedule = "DirtyCpu")]
fn parse(filename: String, sheetname: SheetName) -> Result<Sheet, String> {
let mut excel = match open_workbook_auto(&filename) {
Err(ref error) => return Err(io_error_to_term(error)),
Ok(inner) => inner,
};
if let Some(Ok(range)) = excel.worksheet_range(&sheetname) {
let row: Sheet = range
.rows()
.into_iter()
.enumerate()
.map(|(_i, col)| col.iter().map(|c| c.to_string()).collect::<Vec<_>>())
.collect::<Vec<_>>();
Ok(row)
} else {
Err("Couldnt find the worksheet".to_string())
}
}