elnabo / json2object

Type safe Haxe/JSON (de)serializer
MIT License
66 stars 17 forks source link

Writer for class containing @:optional field throws "null can't be used as basic type" #90

Closed EliteMasterEric closed 1 year ago

EliteMasterEric commented 1 year ago

Something like:

class SampleData {
  @:optional
  @:default(false)
  public var optionalValue:Bool;

  public var mandatoryValue:Int;
}

class SampleDataParser {
  function parse() {
    var parser = new json2object.JsonParser<SampleData>();
    parser.fromJson(contents);
  }
  function write() {
    var writer = new json2object.JsonWriter<SampleData>();
    return writer.write(value, pretty ? '  ');
  }
}

causes a compilation error:

json2object/git/src/json2object/writer/DataBuilder.hx:215: characters 32-36 : On static platforms, null can't be used as basic type Bool

The issue appears to be with the writer interpreting the @:optional and assuming that means the underlying field is nullable, when actually @:optional is for the parser.

Note this issue would only happen on basic fields unless null safety was enabled.

This could be solved by ignoring @:optional on the writer if the field is a basic type that isn't nullable.

Let me know if you need a more thorough reproduction.

EliteMasterEric commented 1 year ago

I rewrote it to this and it seems to work:

                    if (field.meta.has(':optional')) {
                        switch (field.type) {
                            case TAbstract(t, params):
                                if (t.toString() == "Null") {
                                    // Null<Bool>
                                    skips.push(macro $f_a == null);
                                } else {
                                    // Bool
                                    skips.push(macro false);
                                }
                            default:
                                skips.push(macro $f_a == null);
                        }
                    } else {
                        skips.push(macro false);
                    }
elnabo commented 1 year ago

Thanks.

I think at some point the compiler treated @:optional as Null<> fields but it must have changed.