-
Notifications
You must be signed in to change notification settings - Fork 7
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
Decoding fails for keyed structs in a singleValueContainer
#9
Decoding fails for keyed structs in a singleValueContainer
#9
Conversation
Thanks for the notification of the issue, and the thorough investigation and test case.
I'll report back once I had time to look at it more closely. |
Thanks for the feedback and confirming some of my assumptions. I actually had another go at my attempted fix and managed to do in such way that it does resolve the new test without introducing any regressions. I pushed it up to this branch, so it's part of this PR. Please have a look if you see any potential issues with this solution.
Yeah, I did see this as well, but as it was consistently used in all |
Thanks for the update! It seems to be working (although the pipeline fails due to an unrelated error), and I'll check the code later to see before merging this. |
`Date.now` is only available from iOS 15, tvOS 15, watchOS 8 and hence not available on all valid platforms of the package. (iOS 11+, tvOS 11+, watchOS 4+)
Just addressed the CI failure as well to get this out of the way. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor issues with the test, but I'll merge this and clean up when I'll do some refactoring.
let wrapped = Wrapped(val: "Some") | ||
let encodedWrapped = try BinaryEncoder.encode(wrapped) | ||
|
||
try compare(encodedWrapped, to: expected) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be changed to compare(wrapped, to: expected)
.
The function encodes wrapped
and compares it to expected
. That it works for encodedWrapped
as well is just due to the fact that [UInt8]
encodes to itself.
let wrapper = Wrapper(wrapped: wrapped) | ||
let encodedWrapper = try BinaryEncoder.encode(wrapper) | ||
|
||
try compare(encodedWrapper, to: expected) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would change this to XCTAssertEqual(encodedWrapper, Data(expected))
Thanks for swiftly merging and releasing this! 🙏 Legit feedback on code review. I think there are a few more places in |
This is for now mostly a bug report, adding a failing test reproducing the issue at hand, as I don't have a solution to this without better understanding the expected behavior.
🐛 Problem
Assume I have the following structs:
I presume the values of both structs are expected to encode and decode the same binary format, as the type
Wrapper
acts a transparent wrapper from an encoding/decoding perspective. That at least is the current behavior, encoding-wise. So while they encode indeed to the same data, the decoding ofWrapper
however does always (!) fail.In a more complex situation, I also saw this failing with:
🔍 Solution Explored
To me, the problem seemed to be that
DecodingNode.singleValueContainer()
turns itsstorage
into an indexedBinaryStreamProvider
, which will be eventually turned back intoData
. While converting back and forth here seemed innocuous at first glance, I presumed they inadvertently consume the count byte(s) in this case. However when I attempted to fix this myself (by makingValueDecoder
operate directly on theStorage
instead), I found out that while this does indeed fix the new test, it does break several other tests which seem to rely on exactly this behavior ofsingleValueContainer
. (testDecodingAsDifferentType
,testStringEnumEncoding
,testStringEncoding
,UUIDEncodingTests
)🛟 Help Required
I'm not quite sure on the design of the binary format and whether this is supposed to work as is or the wrapped struct should be rather prepended by a count byte.