Skip to content

Commit 26dd941

Browse files
committed
Add COLNAMES option to give names to the columns
The COLNAMES option should contain the row number giving the name to the columns. This name will be used in place of the lettered column name used by excel in the SQL Table.
1 parent ec6b81d commit 26dd941

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

src/options.rs

+12
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ pub enum UsingOption {
99
File(String),
1010
Worksheet(String),
1111
Range(String),
12+
ColNames(String),
1213
}
1314

1415
pub fn parse_option(input: &str) -> IResult<&str, UsingOption> {
1516
parse_with_spaces(alt((
1617
parse_filename_option,
1718
parse_worksheet_option,
1819
parse_range_option,
20+
parse_colnames_option,
1921
))).parse(input)
2022
}
2123

@@ -49,6 +51,16 @@ fn parse_range_option(input: &str) -> IResult<&str, UsingOption> {
4951
|t: (&str, &str)| UsingOption::Range(t.1.to_string()))(input)
5052
}
5153

54+
fn parse_colnames_option(input: &str) -> IResult<&str, UsingOption> {
55+
let option = tag_no_case("COLNAMES");
56+
57+
let value = preceded(
58+
tag("'"), terminated(digit0, tag("'")));
59+
60+
map(separated_pair(option, multispace1, value),
61+
|t: (&str, &str)| UsingOption::ColNames(t.1.to_string()))(input)
62+
}
63+
5264
fn parse_with_spaces<'a, T>(parser: impl Parser<&'a str, T, nom::error::Error<&'a str>>)
5365
-> impl Parser<&'a str, T, nom::error::Error<&'a str>> {
5466
preceded(multispace0, terminated(parser, multispace0))

src/spreadsheet/manager.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ use crate::spreadsheet::{
55
};
66
use calamine::{open_workbook_auto, DataType, Range, Reader, Sheets};
77
use std::path::Path;
8+
use std::str::FromStr;
89

910
pub struct DataManager {
1011
sheets: Sheets,
1112
worksheet: String,
1213
range: Option<CellRange>,
14+
colnames_row: Option<u32>,
1315
}
1416

1517
pub enum DataManagerError {
@@ -47,9 +49,17 @@ impl DataManager {
4749
pub fn get_columns(&mut self) -> Vec<String> {
4850
let range = self.get_effective_range();
4951
if range.get_size().1 > 0 {
52+
let row_workspace_sheet = self.colnames_row
53+
.and_then(|v| Some((v, self.sheets.worksheet_range(self.worksheet.as_str()))))
54+
.and_then(|(row, sheet)| Some((row, sheet?.ok()?)));
5055
(range.start().unwrap().1..=range.end().unwrap().1)
5156
.into_iter()
52-
.map(|n| CellIndex::new(n + 1, 1).get_x_as_string())
57+
.map(|n| {
58+
row_workspace_sheet
59+
.as_ref()
60+
.and_then(|(row, sheet)| sheet.get_value((*row, n)).map(|v| v.to_string()))
61+
.unwrap_or_else(|| CellIndex::new(n + 1, 1).get_x_as_string())
62+
})
5363
.collect()
5464
} else {
5565
Vec::new()
@@ -68,6 +78,7 @@ pub struct DataManagerBuilder {
6878
file: Option<String>,
6979
worksheet: Option<String>,
7080
range: Option<CellRange>,
81+
colnames_row: Option<u32>,
7182
}
7283

7384
impl DataManagerBuilder {
@@ -89,6 +100,9 @@ impl DataManagerBuilder {
89100
UsingOption::Range(range) => {
90101
builder = builder.range(CellRange::try_parse(range.as_str()).unwrap());
91102
}
103+
UsingOption::ColNames(colnames) => {
104+
builder = builder.colnames_row(u32::from_str(colnames.as_str()).unwrap());
105+
},
92106
}
93107
}
94108

@@ -110,6 +124,11 @@ impl DataManagerBuilder {
110124
self
111125
}
112126

127+
pub fn colnames_row(mut self, row: u32) -> Self {
128+
self.colnames_row = Some(row);
129+
self
130+
}
131+
113132
pub fn open(self) -> Result<DataManager, DataManagerError> {
114133
if let Some(file) = self.file {
115134
if let Some(worksheet) = self.worksheet {
@@ -118,6 +137,7 @@ impl DataManagerBuilder {
118137
sheets,
119138
worksheet,
120139
range: self.range,
140+
colnames_row: self.colnames_row,
121141
}),
122142
Err(err) => Err(DataManagerError::Calamine(err)),
123143
}

0 commit comments

Comments
 (0)