Cloning Vs Taking Ownership in a Read Only Function with &Option

⚓ Rust    📅 2025-08-30    👤 surdeus    👁️ 3      

surdeus

I'm using the rust_xlsxwriter library to write some data to an Excel spreadsheet, and I have some data that looks like Vec<Vec<Option<f32>>>. This represents rows of data (the inner vec contains the data within a single row, the outer vec contains the collection of rows). It's possible the data has nulls, so a row has Option<f32> rather than just standard floats.

Since I just plan on reading the data, my function that writes it to the spreadsheet takes a reference to the data (or &Vec<Vec<Option<f32>>>)

The problem I'm running into is that the function write_row_matrix that I'm trying to use to write the data wants something with the IntoExcelData trait.

The trait is defined for Option<T> where T is something else implementing IntoExcelData, and the trait is implemented for f32. However, it's not implemented for &f32 or &Option:

error[E0277]: the trait bound `&std::option::Option<f32>: IntoExcelData` is not satisfied
    --> src\worksheet_functions.rs:64:19
     |
64   |             sheet.write_row_matrix(LIMIT_LOCATION.0 + 2, LIMIT_LOCATION.1, lower_limit)?;
     |                   ^^^^^^^^^^^^^^^^ the trait `IntoExcelData` is not implemented for `&std::option::Option<f32>`
     |
     = help: the trait `IntoExcelData` is implemented for `std::option::Option<T>`

If I had a standard Vec<Vec<Option<f32>>>, I'd be fine. So it seems like I have two workarounds:

  1. Have my function take ownership of the dataset before it writes it to Excel
  2. Use a clone function on the elements of the vector.

This does seem to compile:

let lower_limit: &Vec<Vec<Option<f32>>> = data_source;

// clone the inner elements of the item, so the elements are all Option<f32> vs &Option<f32>.
let data = lower_limit.iter().map(|x| x.iter().map(|y| y.clone()));

// this now works
sheet.write_row_matrix(LIMIT_LOCATION.0 + 2, LIMIT_LOCATION.1, lower_limit)?;

What I wanted to understand is there a "rust preferred" solution to this sort of problem. More generally:

  1. When writing my function, if I'm going to need to clone the underlying data anyway, does it make sense to just take the Vec<Vec<Option<f32>>> in my function signature?
  2. Does cloning the set of f32 cost me anything? For example, if the data is going to be copied when it's consumed by the function that writes to Excel, will clone impact performance, or will it get optimized out?
  3. As I understand, I can't write an implementation for the trait IntoExcelData for &Option<f32> since both are defined elsewhere, but is there something else I could do (such as defining a new container type with Option) that would make this cleaner?

2 posts - 2 participants

Read full topic

🏷️ Rust_feed