Skip to content
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

Fix the bug of not decoding nested Array of Object #69

Closed
wants to merge 10 commits into from

Conversation

chocoford
Copy link

Fix the problem that Multipart-kit could not decode nested Array of Object mentioned in #67.

fixed the bug that could not decode nested Array of Objects.
remove console code
@chocoford
Copy link
Author

The situation is more complicated than I thought before.

@chocoford chocoford closed this Jun 19, 2021
@chocoford chocoford reopened this Jun 19, 2021
@chocoford
Copy link
Author

chocoford commented Jun 20, 2021

With this PR, multipart-kit can decode form-data like below.

struct Formdata: Decodable, Equatable {
    struct NestedFormdata: Decodable, Equatable {
        struct AnotherNestedFormdata: Decodable, Equatable {
            let int: Int
            let string: String
            let strings: [String]
        }
        let int: String
        let string: Int
        let strings: [String]
        let anotherNestedFormdata: AnotherNestedFormdata
        let anotherNestedFormdataList: [AnotherNestedFormdata]
    }
    let nestedFormdata: [NestedFormdata]
}

Fixed the bug that when it comes to form-data containing arrays of objects of more than one properties, Multipart-kit then decodes it with same object's properties split into different objects(or keyed in code).

But form-data still lacks the ability to express complex nested structures. For example, when it comes to structure like below:

struct Formdata: Content {
    struct NestedFormdata: Content {
        let strings: [String]
    }
    let nestedFormdata: [NestedFormdata]
}

it cannot distinguish

Formdata(nestedFormdata: [
            .init(strings: ["1", "2"]),
            .init(strings: ["3", "4"])
        ])

from

Formdata(nestedFormdata: [
            .init(strings: ["1", "2", "3", "4"]),
        ])

(let me know if I am wrong)

@siemensikkema
Copy link
Member

@chocoford I'll need to get into the details at a later point when I have more time but with regards to form-data not being able to distinguish between the 2 scenarios you mention it seems we'd need to introduce numbered keys. Do you know off-hand if that conflicts with any part of the spec?

@chocoford
Copy link
Author

@chocoford I'll need to get into the details at a later point when I have more time but with regards to form-data not being able to distinguish between the 2 scenarios you mention it seems we'd need to introduce numbered keys. Do you know off-hand if that conflicts with any part of the spec?

I found Specifying array keys is optional in HTML. If you do not specify the keys, the array gets filled in the order the elements appear in the form. in PHP Documentation

So far, I haven't found any information about that from the rfc specifications.

Copy link
Member

@siemensikkema siemensikkema left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me like we shouldn't try to guess which element of an array a part belongs to but rather require an index except for maybe the last part of the name. So nestedFormdata[0][strings][] for example. And we should change the encoder to match that (but there just output indexes for all).

}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

@@ -423,38 +423,107 @@ class MultipartTests: XCTestCase {

XCTAssertEqual(data, expected)
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

@chocoford
Copy link
Author

chocoford commented Jun 26, 2021

It seems to me like we shouldn't try to guess which element of an array a part belongs to but rather require an index except for maybe the last part of the name.

That is a great idea.
Actually when form-data brings any array of objects(in-array-objects) which contains just one property, the distinguish problem exists.
If all in-array-objects containing multiple properties, the problem mentioned will no longer exist.

So, we have two options: allow or disallow optional indices for non-last keys.
If allowed, we must be able to detect if there is an in-array-object only has one property and give warnings.

@chocoford
Copy link
Author

So far, I've allowed optional index in non-last part.

@siemensikkema
Copy link
Member

@chocoford hi! Apologies for the long hiatus. As you can see in #70 I have been busy rethinking the Codable implementation as the existing one isn't as correct as I'd like. I'm pretty happy with how that turned out. However, it would make this PR hard to adapt.
So I've taken the liberty of drafting another PR (#71) that believe adds what we've discussed here, including your thorough unit tests! Would you be ok that we use that one in favor of your PR? (Of course you'll get your well-deserved credits!)
Do you see any issues with my implementation?

@chocoford
Copy link
Author

chocoford commented Sep 3, 2021

@siemensikkema It doesn't matter, as long as the problem can be solved. So far, I hadn't seen any issues. The redesign is great by the way.

@chocoford chocoford closed this Sep 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants