oj icon indicating copy to clipboard operation
oj copied to clipboard

Oj::StringWriter: Formatting options only partially applied

Open mttkay opened this issue 3 years ago • 2 comments

According to https://github.com/ohler55/oj/blob/v3.10.6/pages/Modes.md, the :rails mode should support the space formatting option. However, this does not seem to work when using a StringWriter; only some of the options given below are applied:

[26] pry(main)> Oj::StringWriter.new(indent: 2, space: ' ', mode: :rails).tap { |w| w.push_object; w.push_value(42, 'k'); w.pop }.to_s
=> "{\n  \"k\":42\n}\n"

indent is applied, but space is not. I found this to be true for other options such as array_nl, which appears to be ignored. I also tried using :custom mode, which equally ignores these options.

mttkay avatar Feb 25 '22 10:02 mttkay

Just skimming over string_writer.c, I noticed this:

void oj_str_writer_init(StrWriter sw, int buf_size) {
    sw->opts       = oj_default_options;
    // ...
    sw->out.opts       = &sw->opts;
    sw->out.indent     = sw->opts.indent;
    // ...
    sw->out.ropts      = NULL;
    sw->out.omit_nil   = oj_default_options.dump_opts.omit_nil;
}

https://github.com/ohler55/oj/blob/develop/ext/oj/string_writer.c#L43-L72

This looks like indent is assigned explicitly, but all other options are using the oj defaults.

Going back to the class docs: http://www.ohler.com/oj/doc/Oj/StringWriter.html#new-class_method

Options are supported according the the specified mode or the mode in the default options. Note that if mimic_JSON or Oj.optimize_rails has not been called then the behavior of the modes may not be the same as if they were.

I'm not sure what the second sentence suggests; could that be the reason? I am not calling into either of those.

mttkay avatar Feb 25 '22 10:02 mttkay

StringWriter and StreamWriter are meant as a convenient way to write JSON without creating a bunch of Ruby objects. Currently it does not support the special dump options. I had no plans to expand the capabilities as the idea was to keep the writer fast and adding the various options would add additional overhead. Maybe I should update the docs to make that clear. My apologies.

ohler55 avatar Feb 25 '22 22:02 ohler55