stephenberry / glaze

Extremely fast, in memory, JSON and interface library for modern C++
MIT License
1.22k stars 121 forks source link

Non-Vector CSV support #1436

Open pawcam opened 1 week ago

pawcam commented 1 week ago

I was digging through how you handle non vector members for CSV and was curious about the reasoning behind the API requiring rowwise csv writes to be vector or array

template <class T>
      concept writable_array_t =
         (range<T> && !custom_write<T> && !meta_value_t<T> && !str_t<T> && !writable_map_t<T> && !filesystem_path<T>);

csv/write.hpp

glz {
 detail {
struct to <CSV, T>
     ... 
     if constexpr (writable_array_t<value_type>) {
   // write cols
    }
       else {
                     dump<key>(b, ix);
                     dump<','>(b, ix);
                     write<CSV>::op<Opts>(get_member(value, mem), ctx, b, ix);
                     dump<'\n'>(b, ix);
                  }
 }
}

I have:

 struct struct_with_optional
  {
    std::optional<int> number{std::nullopt};
     std::optional<std::string> string{""};
// other various types with detail specializations
  };

Is there a way I can write my non vector members without the keys, or the end line appended?

std::string csv;
struct_with_optional s{}
s. number = 123
glz::write_csv(s, csv)

std::string csv2
s.number = std::nullopt
s.string = "456"
glz::write_csv(s, csv2)

csv output:

123,

csv2 output:

,"456"

Edit: I suppose this issue https://github.com/stephenberry/glaze/issues/1305 already covers this ask, but it's slightly different (vector of structs vs just one struct to a csv line). Mabe if there were an additional opt field like transpose_members to treat all the members as a single csv row?

stephenberry commented 2 days ago

Thanks for bringing this up. This would be helpful to add and you can feel free to submit a pull request. Otherwise, I'll keep this issue alive and try to address it sooner than later, but right now I'm limited on development time.