This commit is contained in:
@@ -24,13 +24,12 @@ pub fn parse_csv(bytes: &[u8]) -> Result<ParsedFile, ImportError> {
|
||||
let rows: Vec<Vec<String>> = rdr
|
||||
.records()
|
||||
.map(|r| {
|
||||
r.map_err(|e| ImportError::Csv(e.to_string()))
|
||||
.map(|rec| {
|
||||
let mut cells: Vec<String> = rec.iter().map(|f| f.trim().to_string()).collect();
|
||||
cells.resize(columns.len(), String::new());
|
||||
cells.truncate(columns.len());
|
||||
cells
|
||||
})
|
||||
r.map_err(|e| ImportError::Csv(e.to_string())).map(|rec| {
|
||||
let mut cells: Vec<String> = rec.iter().map(|f| f.trim().to_string()).collect();
|
||||
cells.resize(columns.len(), String::new());
|
||||
cells.truncate(columns.len());
|
||||
cells
|
||||
})
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
|
||||
@@ -2,17 +2,19 @@ use domain::models::{ImportError, ParsedFile};
|
||||
use serde_json::Value;
|
||||
|
||||
pub fn parse_json(bytes: &[u8]) -> Result<ParsedFile, ImportError> {
|
||||
let value: Value = serde_json::from_slice(bytes)
|
||||
.map_err(|e| ImportError::Json(e.to_string()))?;
|
||||
let value: Value =
|
||||
serde_json::from_slice(bytes).map_err(|e| ImportError::Json(e.to_string()))?;
|
||||
|
||||
let arr = value.as_array()
|
||||
let arr = value
|
||||
.as_array()
|
||||
.ok_or_else(|| ImportError::Json("expected a JSON array".into()))?;
|
||||
|
||||
if arr.is_empty() {
|
||||
return Err(ImportError::Empty);
|
||||
}
|
||||
|
||||
let first = arr[0].as_object()
|
||||
let first = arr[0]
|
||||
.as_object()
|
||||
.ok_or_else(|| ImportError::Json("array elements must be objects".into()))?;
|
||||
let columns: Vec<String> = first.keys().cloned().collect();
|
||||
|
||||
@@ -20,12 +22,15 @@ pub fn parse_json(bytes: &[u8]) -> Result<ParsedFile, ImportError> {
|
||||
return Err(ImportError::NoHeader);
|
||||
}
|
||||
|
||||
let rows: Vec<Vec<String>> = arr.iter()
|
||||
let rows: Vec<Vec<String>> = arr
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, item)| {
|
||||
let obj = item.as_object()
|
||||
.ok_or_else(|| ImportError::Json(format!("element at index {} is not an object", idx)))?;
|
||||
Ok(columns.iter()
|
||||
let obj = item.as_object().ok_or_else(|| {
|
||||
ImportError::Json(format!("element at index {} is not an object", idx))
|
||||
})?;
|
||||
Ok(columns
|
||||
.iter()
|
||||
.map(|col| obj.get(col).map(value_to_string).unwrap_or_default())
|
||||
.collect())
|
||||
})
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
use calamine::{Reader, open_workbook_from_rs, Xlsx, Data};
|
||||
use std::io::Cursor;
|
||||
use calamine::{Data, Reader, Xlsx, open_workbook_from_rs};
|
||||
use domain::models::{ImportError, ParsedFile};
|
||||
use std::io::Cursor;
|
||||
|
||||
pub fn parse_xlsx(bytes: &[u8]) -> Result<ParsedFile, ImportError> {
|
||||
let cursor = Cursor::new(bytes);
|
||||
let mut workbook: Xlsx<_> = open_workbook_from_rs(cursor)
|
||||
.map_err(|e: calamine::XlsxError| ImportError::Xlsx(e.to_string()))?;
|
||||
|
||||
let sheet_name = workbook.sheet_names()
|
||||
let sheet_name = workbook
|
||||
.sheet_names()
|
||||
.first()
|
||||
.cloned()
|
||||
.ok_or(ImportError::Empty)?;
|
||||
|
||||
let range = workbook.worksheet_range(&sheet_name)
|
||||
let range = workbook
|
||||
.worksheet_range(&sheet_name)
|
||||
.map_err(|e| ImportError::Xlsx(e.to_string()))?;
|
||||
|
||||
let mut iter = range.rows();
|
||||
|
||||
let header = iter.next().ok_or(ImportError::NoHeader)?;
|
||||
let columns: Vec<String> = header.iter()
|
||||
let columns: Vec<String> = header
|
||||
.iter()
|
||||
.map(|c| cell_to_string(c).trim().to_string())
|
||||
.collect();
|
||||
|
||||
@@ -46,7 +49,11 @@ fn cell_to_string(cell: &Data) -> String {
|
||||
match cell {
|
||||
Data::String(s) => s.clone(),
|
||||
Data::Float(f) => {
|
||||
if f.fract() == 0.0 { format!("{}", *f as i64) } else { format!("{}", f) }
|
||||
if f.fract() == 0.0 {
|
||||
format!("{}", *f as i64)
|
||||
} else {
|
||||
format!("{}", f)
|
||||
}
|
||||
}
|
||||
Data::Int(i) => i.to_string(),
|
||||
Data::Bool(b) => b.to_string(),
|
||||
|
||||
Reference in New Issue
Block a user