From 5ff507db2f6667a0305e2382037710f6082d75da Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Sat, 10 Aug 2024 19:25:25 +0200 Subject: imlement native csv loader --- Cargo.lock | 22 ++++++++++++++++ Cargo.toml | 1 + src/sheet/cell.rs | 5 +++- src/sheet/loader.rs | 48 ---------------------------------- src/sheet/loader/mod.rs | 58 ++++++++++++++++++++++++++++++++++++++++++ src/sheet/loader/native/csv.rs | 19 ++++++++++++++ src/sheet/loader/native/mod.rs | 2 ++ 7 files changed, 106 insertions(+), 49 deletions(-) delete mode 100644 src/sheet/loader.rs create mode 100644 src/sheet/loader/mod.rs create mode 100644 src/sheet/loader/native/csv.rs create mode 100644 src/sheet/loader/native/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 584660b..5a7ea4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,6 +116,27 @@ dependencies = [ "winapi", ] +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + [[package]] name = "dirs" version = "5.0.1" @@ -278,6 +299,7 @@ dependencies = [ name = "neosheet" version = "0.1.0" dependencies = [ + "csv", "dirs", "mlua", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index c046f4e..3fd65ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] +csv = "1.3.0" dirs = "5.0.1" mlua = { version = "0.9.9", features = ["luajit"] } once_cell = "1.19.0" diff --git a/src/sheet/cell.rs b/src/sheet/cell.rs index d723732..6973b96 100644 --- a/src/sheet/cell.rs +++ b/src/sheet/cell.rs @@ -57,7 +57,10 @@ impl From for Cell { impl From<&str> for Cell { fn from(value: &str) -> Self { - Cell::String(value.to_string()) + match value.parse::() { + Ok(n) => Cell::Number(n), + Err(_) => Cell::String(value.to_string()), + } } } diff --git a/src/sheet/loader.rs b/src/sheet/loader.rs deleted file mode 100644 index 35b6da2..0000000 --- a/src/sheet/loader.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::{collections::HashMap, path::Path, ptr::addr_of_mut}; - -use mlua::{Lua, UserData}; -use once_cell::sync::Lazy; - -use crate::lua::{ownedfunction::OwnedFunction, runnable::Runnable}; - -use super::{register::SheetId, tablized::Tablized}; - -#[derive(Default)] -pub struct Loader { - loaders: HashMap>>, -} - -impl Loader { - pub fn new() -> Self { - Self { - loaders: HashMap::new(), - } - } - - pub fn load_sheet(&self, path: String, lua: &Lua) -> Option { - let p = Path::new(&path); - let loader = self.loaders.get(p.extension()?.to_str()?)?; - match loader.run(path, lua) { - Ok(table) => table.to_sheet(lua).ok(), - Err(_) => None, - } - } - - pub fn add(&mut self, extension: String, func: Box>) { - self.loaders.insert(extension, func); - } - - pub fn get() -> &'static mut Self { - static mut GLOBAL_LOADER: Lazy = Lazy::new(|| Loader::new()); - unsafe { &mut *addr_of_mut!(GLOBAL_LOADER) } - } -} - -impl UserData for Loader { - fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { - methods.add_function("add", |_, (extension, func): (String, OwnedFunction)| { - Loader::get().add(extension, Box::new(func)); - Ok(()) - }); - } -} diff --git a/src/sheet/loader/mod.rs b/src/sheet/loader/mod.rs new file mode 100644 index 0000000..0e083fe --- /dev/null +++ b/src/sheet/loader/mod.rs @@ -0,0 +1,58 @@ +use std::{collections::HashMap, path::Path, ptr::addr_of_mut}; + +use mlua::{Lua, UserData}; +use once_cell::sync::Lazy; + +use crate::lua::{ownedfunction::OwnedFunction, runnable::Runnable}; + +use self::native::csv::load_csv; + +use super::{register::SheetId, tablized::Tablized}; + +pub mod native; + +#[derive(Default)] +pub struct Loader { + loaders: HashMap>>, +} + +impl Loader { + pub fn new() -> Self { + let mut loaders: HashMap>> = HashMap::new(); + + loaders.insert("csv".to_string(), Box::new(load_csv)); + + Self { loaders } + } + + pub fn load_sheet(&self, path: String, lua: &Lua) -> Option { + let p = Path::new(&path); + if p.is_file() { + let loader = self.loaders.get(p.extension()?.to_str()?)?; + return match loader.run(path, lua) { + Ok(table) => table.to_sheet(lua).ok(), + Err(_) => None, + }; + } + + return None; + } + + pub fn add(&mut self, extension: String, func: Box>) { + self.loaders.insert(extension, func); + } + + pub fn get() -> &'static mut Self { + static mut GLOBAL_LOADER: Lazy = Lazy::new(|| Loader::new()); + unsafe { &mut *addr_of_mut!(GLOBAL_LOADER) } + } +} + +impl UserData for Loader { + fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_function("add", |_, (extension, func): (String, OwnedFunction)| { + Loader::get().add(extension, Box::new(func)); + Ok(()) + }); + } +} diff --git a/src/sheet/loader/native/csv.rs b/src/sheet/loader/native/csv.rs new file mode 100644 index 0000000..4a8f05d --- /dev/null +++ b/src/sheet/loader/native/csv.rs @@ -0,0 +1,19 @@ +use std::{fs::File, io::BufReader}; + +use crate::sheet::{cell::Cell, tablized::Tablized}; + +pub fn load_csv(path: String) -> Tablized { + let file = File::open(path).unwrap(); + let reader = BufReader::new(file); + let mut csv_reader = csv::Reader::from_reader(reader); + + let mut table = Vec::new(); + + for result in csv_reader.records() { + if let Ok(record) = result { + table.push(record.iter().map(|s| Cell::from(s)).collect::>()) + } + } + + Tablized::Vector(table) +} diff --git a/src/sheet/loader/native/mod.rs b/src/sheet/loader/native/mod.rs new file mode 100644 index 0000000..41ec797 --- /dev/null +++ b/src/sheet/loader/native/mod.rs @@ -0,0 +1,2 @@ + +pub mod csv; -- cgit v1.2.3-70-g09d2