Closed ghost closed 2 months ago
Sounds like you are getting nom
through cexpr
.
The version of cexpr you are using is over 4 years old. The fix for this was in #1657 which was released in v5.1.3 and v6.2.2 .
If you upgrade to cexpr 0.4.0, 0.5.0, or 0.6.0, then this should be resolved.
Thanks for your soon response.
I think something else makes this invocation, because these are statements where is used command use, in a program.
use std::os::raw::c_char; use std::ffi::CStr; use calamine::{open_workbook, Reader, Range, DataType, Xlsx, XlsxError}; use std::error::Error; use csv::Writer; use std::fs::File; use std::io::BufWriter; use xlsxwriter::*;
This is Cargo.toml content: [package] name = "excel-merger" version = "0.1.0" edition = "2021"
[dependencies] calamine = "0.23.1" xlsxwriter = "0.1.0" csv = "1.1"
[lib] name = "excel_merger" path = "src/lib.rs" crate-type = ["cdylib"]
How can I know where explicitly is invoked cexpr?
Run the command:
$ cargo tree --invert --package cexpr
And it will show you the dependency tree that leads to cexpr being a dependency.
This is the result:
cexpr v0.3.6 └── bindgen v0.51.1 [build-dependencies] └── libxlsxwriter-sys v0.8.7 └── xlsxwriter v0.1.0 └── excel-merger v0.1.0 (D:\Rust\excel-merger)
And I looked for the last xlsxwriter version. This is v0.6.0, but program is not compiling now. I am going to deal with this:
error[E0599]: no method named add_worksheet found for enum Result in the current scope
--> src/lib.rs:85:56 |
85 | let mut worksheet_xlsxwriter = workbook_xlsxwriter.add_worksheet(None).unwrap(); | ^^^^^^^^^^^^^ method not found in Result<Workbook, XlsxError> |
---|
note: the method add_worksheet exists on the type xlsxwriter::Workbook
--> C:\Users\huertaga.cargo\registry\src\index.crates.io-6f17d22bba15001f\xlsxwriter-0.6.0\src\workbook.rs:157:5 |
157 | / pub fn add_worksheet<'a>( 158 | &'a self, 159 | sheet_name: Option<&str>, 160 | ) -> Result<Worksheet<'a>, XlsxError> { | _____^
help: use the ? operator to extract the xlsxwriter::Workbook value, propagating a Result::Err value to the caller |
||||
---|---|---|---|---|---|---|---|---|---|---|
85 | let mut worksheet_xlsxwriter = workbook_xlsxwriter?.add_worksheet(None).unwrap(); | |||||||||
+ |
error[E0599]: no method named close found for enum Result in the current scope
--> src/lib.rs:116:25 |
116 | workbook_xlsxwriter.close().unwrap(); | ^^^^^ method not found in Result<Workbook, XlsxError> |
---|
note: the method close exists on the type xlsxwriter::Workbook
--> C:\Users\huertaga.cargo\registry\src\index.crates.io-6f17d22bba15001f\xlsxwriter-0.6.0\src\workbook.rs:277:5 |
277 | pub fn close(mut self) -> Result<(), XlsxError> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: use the ? operator to extract the xlsxwriter::Workbook value, propagating a Result::Err value to the caller |
---|---|---|---|
116 | workbook_xlsxwriter?.close().unwrap(); | ||
+ |
I believe this can be closed, right?
I ask for apologies. I could not enter into GitHub link, because I am going to be at work in the office during two weeks. I hope as soon as I can be at HomeOffice, I can do it.
Regards.
De: stefnotch @.> Enviado el: martes, 27 de febrero de 2024 03:56 a. m. Para: rust-bakery/nom @.> CC: Gabriel Huerta Araujo @.>; Author @.> Asunto: Re: [rust-bakery/nom] A fix has to be implemented by those dependencies (Issue #1727)
No suele recibir correos electrónicos de @.**@.>. Por qué esto es importantehttps://aka.ms/LearnAboutSenderIdentification
I believe this can be closed, right?
— Reply to this email directly, view it on GitHubhttps://github.com/rust-bakery/nom/issues/1727#issuecomment-1966180553, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AFL3AT3VJZSRHBDX2EMXZOTYVWUUJAVCNFSM6AAAAABC2XKAK6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNRWGE4DANJVGM. You are receiving this because you authored the thread.Message ID: @.**@.>>
This is the final code I could make it to work.
use std::os::raw::c_char; use std::ffi::CStr; use calamine::{open_workbook, Reader, Range, DataType, Xls, Xlsx}; use calamine::Error as CalamineError; use std::error::Error; use std::convert::From; use std::fmt; use csv::Writer; use std::fs::File; use std::fs; use std::io::BufWriter; use xlsxwriter::*; use libc::c_int; use std::path::Path;
pub struct ConcreteXlsxError { message: String, code: i32, }
impl ConcreteXlsxError { pub fn new(message: String, code: i32) -> Self { ConcreteXlsxError { message, code } }
pub fn get_message(&self) -> &str {
&self.message
}
pub fn get_code(&self) -> i32 {
self.code
}
}
pub extern "C" fn mergeExcelFiles(file1_path: const c_char, file2_path: const c_char, output_path: *const c_char) -> c_int
{
merge_excel_files_wrapper::
fn merge_excel_files_wrapper
unsafe {
let file1 = CStr::from_ptr(file1_path).to_string_lossy().into_owned();
let file2 = CStr::from_ptr(file2_path).to_string_lossy().into_owned();
let output = CStr::from_ptr(output_path).to_string_lossy().into_owned();
// Convert the XLS file to XLSX
let xlsx_file1 = convert_xls_to_xlsx(&file1).expect("Failed to convert XLS to XLSX");
let xlsx_file2 = convert_xls_to_xlsx(&file2).expect("Failed to convert XLS to XLSX");
let mut row_values: Vec<String> = Vec::new();
let mut index = 0;
// Process the first workbook
let range1 = take_range(&xlsx_file1);
match range1 {
Ok(range) => process_range(&mut index, &range, &mut row_values),
Err(err) => eprintln!("Error: {}", err),
}
// Process the second workbook
let range2 = take_range(&xlsx_file2);
match range2 {
Ok(range) => process_range(&mut index, &range, &mut row_values),
Err(err) => eprintln!("Error: {}", err),
}
// Write the combined data to a new Excel or CSV file
if output.ends_with(".csv") {
let _ = write_data_to_csv(&mut row_values, &output);
}
if let Err(err) = fs::remove_file(xlsx_file2) {
eprintln!("Error removing file: {}", err);
}
}
0
}
enum MyError { CalamineError(calamine::XlsxError), CalamineErrorXls(calamine::XlsError), XlsxWriterError(xlsxwriter::XlsxError), }
impl fmt::Display for MyError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { MyError::CalamineError(err) => write!(f, "Calamine error: {}", err), MyError::CalamineErrorXls(err) => write!(f, "Calamine error: {}", err), MyError::XlsxWriterError(err) => write!(f, "XlsxWriter error: {}", err), } } }
impl Error for MyError { fn source(&self) -> Option<&(dyn Error + 'static)> { match self { MyError::CalamineError(err) => Some(err), MyError::CalamineErrorXls(err) => Some(err), MyError::XlsxWriterError(err) => Some(err), } } }
impl From
impl From
impl From
fn take_range(xlsfile: &str) -> Result<Range
if let Some(first_sheet_name) = sheet_names.first() {
let range = workbook.worksheet_range(first_sheet_name)?;
Ok(range)
} else {
Err(CalamineError::Msg("No sheets found in the Excel file"))
}
}
fn convert_xls_to_xlsx(xls_file: &str) -> Result<String, MyError> { let mut xlsx_file = xls_file.to_string(); let extension = Path::new(xls_file) .extension() .and_then(|ext| ext.to_str()) .unwrap_or("");
if extension == "xls" {
// Handle .xls file
xlsx_file = xlsx_file.replace(extension, "xlsx");
let mut workbook: Xls<_> = open_workbook(xls_file)?;
let sheet = workbook.sheet_names().first().cloned();
let range = workbook
.worksheet_range(&sheet.as_ref().unwrap())
.expect("Failed to get worksheet range");
let workbook_xlsxwriter = match Workbook::new(&xlsx_file) {
Ok(workbook) => workbook,
Err(error) => return Err(error.into()),
};
let mut worksheet_xlsxwriter = workbook_xlsxwriter.add_worksheet(None)?;
for (row_index, row_result) in range.rows().enumerate() {
let row: Result<_, Box<dyn std::error::Error>> = Ok(row_result);
let row = row.expect("Failed to read row");
for (col_index, cell) in row.iter().enumerate() {
match cell {
calamine::DataType::Empty => {
worksheet_xlsxwriter.write_blank((row_index as i32).try_into().unwrap(), (col_index as i32).try_into().unwrap(), None).unwrap();
}
calamine::DataType::String(value) => {
worksheet_xlsxwriter
.write_string((row_index as i32).try_into().unwrap(), (col_index as i32).try_into().unwrap(), value, None)
.unwrap();
}
calamine::DataType::Float(value) => {
worksheet_xlsxwriter
.write_number((row_index as i32).try_into().unwrap(), (col_index as i32).try_into().unwrap(), *value, None)
.unwrap();
}
calamine::DataType::Int(value) => {
worksheet_xlsxwriter
.write_number((row_index as i32).try_into().unwrap(), (col_index as i32).try_into().unwrap(), *value as f64, None)
.unwrap();
}
// Handle other data types as needed
_ => {}
}
}
}
// Close the xlsxwriter workbook
workbook_xlsxwriter.close().map_err::<MyError, _>(Into::into)?;
}
Ok(xlsx_file.to_string())
}
fn process_range(index: &mut i32, range: &Range
for (i, row) in range.rows().enumerate() {
let mut row_value = String::new();
for (j, cell) in row.iter().enumerate() {
if j == 0 && i > 0 {
row_value.push_str(&({ *index += 1; index }).to_string());
} else if let Some(cell_value) = cell.get_string() {
if j > 0 {
row_value.push(',');
}
row_value.push_str(&format!("\"{}\"", cell_value));
}
}
if i > 0 {
row_values.push(row_value);
}
}
}
fn write_data_to_csv(data: &mut Vec
for row in data {
writer.write_record(&[row.to_owned()])?;
}
writer.flush()?;
Ok(())
}
With this Cargo.toml: [package] name = "excel-merger" version = "0.1.0" edition = "2021"
[dependencies] calamine = "0.23.1"
xlsxwriter = "0.6.0" csv = "1.1" libc = "0.2"
[lib] name = "excel_merger" path = "src/lib.rs" crate-type = ["cdylib"]
Hello, and thank you for submitting an issue to nom!
First, please note that, for family reasons, I have limited time to work on nom, so following the advice here will make sure I will quickly understand your problem and answer as soon as possible. Second, if I don't get to work on your issue quickly, that does not mean I don't consider it important or useful. Major version releases happen once a year, and a lot of fixes are done for the occasion, once I have had time to think of the right solution. So I will get back to you :)
Prerequisites
Here are a few things you should provide to help me understand the issue:
rustc -V
Test case
Please provide a short, complete (with crate import, etc) test case for the issue, showing clearly the expected and obtained results.
Example test case: