62 lines
1.5 KiB
Rust
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 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())
|
|
}
|
|
}
|