New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow maps to convert into objects when missing optional attributes are not compatible #139
Allow maps to convert into objects when missing optional attributes are not compatible #139
Conversation
This test case does seem reasonable to me. I would expect it to behave as if the map were first trivially converted to the closest analogous object type ( It doesn't actually need to be implemented exactly like that, of course... but the main point is that we must treat it like an object which has |
@apparentlymart - this is ready for review and contains a fix for the original test case. |
e7a700c
to
03e3d6d
Compare
… type Optional object attributes give us a new situation to consider here: the source element type might not be compatible with all of the optional attributes of a target object type, but that doesn't matter if the given map doesn't include an element corresponding with the mismatching attributes. This is a bit awkward because we need to first allow the type conversion logic to produce a valid conversion but then catch the attribute mismatch only when applying the conversion function to the value. This is effectively the same sequence of events that happens when converting from string to number or string to bool: we optimistally assume that a conversion will succeed when looking only at types, and then catch the error dynamically once we have a final value to check.
03e3d6d
to
ac3f431
Compare
Thanks for working on this, @liamcervante! The logic you implemented here looks correct to me. While I was reviewing this I noticed that the tests here only check for whether the conversion succeeded or failed and don't actually test the error messages, so I made a change elsewhere to improve that so we can make sure all of the failing conversions are failing in the way they ought to be failing. I then rebased what you did here onto that commit so that your new test cases would match the new structure. Aside from rebasing to the new test structure, I've also made a couple other minor changes:
I'm going to merge this now. Thanks again! |
Before this PR
When converting a map into an object, if any attributes/values were not compatible the whole conversion would fail.
After this PR
If an attribute is not convertible then we check if it's optional. If it is optional, then we don't error right away. We record a nil converter for that attribute leaving us with three cases for each attribute:
Case 1 and Case 2 are covered already, and case 3 is introduced by this PR. Case 3 is only possible when we have found an optional attribute that is not convertible (we fail early if an attribute is required but not convertible). If we encounter case 3 during the conversion, it means an optional attribute that is not convertible is actually present in the map, so we fail at this point. If case 3 is never encountered then it means the map didn't actually contain any of these optional attributes so we can just set null values for them and still have a successful conversion.