tadzik / JSON-Unmarshal

MIT License
5 stars 9 forks source link

Null data structures containers (type objects) should be unmarshalled as type objects #30

Open lefth opened 6 years ago

lefth commented 6 years ago

An undefined but typed data structure (Array as opposed to Array.new) is serialized as "null". Accordingly, "null" is unmarshalled as a type structure. This works for the most classes, but fails for Positional, Array, Hash, Hash[Int], etc.

> class MyClass { has Array $.array; }
(MyClass)
> unmarshal('{"array": null}', MyClass); # expecting MyClass.new(array => Array)
Cannot look up attributes in a Array type object
  in sub _unmarshal at D:\rakudo-2017.12\share\perl6\site\sources\BD58585C8BB103CC821AB89EFD8D30DA4FB8FDF9 (JSON::Unmarshal) line 118
  in block  at D:\rakudo-2017.12\share\perl6\site\sources\BD58585C8BB103CC821AB89EFD8D30DA4FB8FDF9 (JSON::Unmarshal) line 108
  in sub _unmarshal at D:\rakudo-2017.12\share\perl6\site\sources\BD58585C8BB103CC821AB89EFD8D30DA4FB8FDF9 (JSON::Unmarshal) line 92
  in sub unmarshal at D:\rakudo-2017.12\share\perl6\site\sources\BD58585C8BB103CC821AB89EFD8D30DA4FB8FDF9 (JSON::Unmarshal) line 157

Also note that Positional and Associative types are a more complex case, because depending on the sigil of the variable, it may be impossible for them to be undefined. I believe the following should be an error, since the JSON definitely does not specify an array with one element:

> class HasSigil { has @.array; }
(HasSigil)
> unmarshal('{"array": null}', HasSigil); # bad input, since this class cannot have a null array
HasSigil.new(array => [Mu]) # garbage in, garbage out

See also: issue #29 and https://github.com/jonathanstowe/JSON-Marshal/issues/8