koxudaxi / datamodel-code-generator

Pydantic model and dataclasses.dataclass generator for easy conversion of JSON, OpenAPI, JSON Schema, and YAML data sources.
https://koxudaxi.github.io/datamodel-code-generator/
MIT License
2.8k stars 307 forks source link

Add Swift codable structs support #2022

Open natikgadzhi opened 5 months ago

natikgadzhi commented 5 months ago

Problem

We're using datamodel-code-generator for our Python code at @airbytehq, and I was about to make a little experimental app with Swift on our protocol, and realized there is not great way to generate models in Swift for JSON Schemas.

Let's add Swift support!

Solution

A good solution should:

Additionally, generated code should be validated:

Great, who wants to build that?

I would be interested in tinkering with this. Before starting, wanted to run this by @koxudaxi to see if it makes sense to add Swift generation to koxudaxi.

koxudaxi commented 5 months ago

@natikgadzhi Thank you for suggesting Swift support for datamodel-code-generator Indeed, our tool aims to be language-agnostic, and adding Swift would be beneficial. However, I don't have experience with Swift, so I can't implement this feature directly. I would greatly appreciate it if anyone familiar with Swift and willing to contribute would create a pull request.

This repository has a merge rule of approximately 100% test coverage. (Edge cases may be ignored.)

In other words, if you add a test case, the specific output is guaranteed. (I should not need to know Swift.)

natikgadzhi commented 5 months ago

Thank you for replying! <3

The testing piece gives me pause. Of course we can test that the flow works and generates some *.swift files. What I'd want to test is verify end to end that those are valid structs and perhaps that they emit records compatible with the source schema.

We could do an end to end test harness with a Python flask app on one end that runs with newly generated models and accepts new records, and Swift app that takes generated models, instantiates objects, sends them to Python API to make sure that those records will map perfectly.

That's probably overkill?

If you want code coverage and semantic correctness, we could just validate that the code is formatted (swift-format) and that it builds without errors?

koxudaxi commented 5 months ago

That's probably overkill?

Yes, I agree. It does seem like overkill.

If you want code coverage and semantic correctness, we could just validate that the code is formatted (swift-format) and that it builds without errors?

This approach sounds more practical and can be easily verified using CI, which is great.

Is it possible that the build passes, yet we encounter issues despite the output files matching the expected results?

natikgadzhi commented 5 months ago

Yeah, just successful exit 0 compilation only gives us "oh, there are no syntax errors" level of confidence.

But! We could actually generate Swift test cases that validate that it not only builds, but can also successfully encode / decode models. That would still be runnable as swift test dummy-package, hence runnable in CI rather easily without having the whole Swift stack in this repo, just a GH action.

Can you point me at Python tests that make sure that jsonschema models can be encoded / decoded from resulting models?

koxudaxi commented 5 months ago

hence runnable in CI rather easily without having the whole Swift stack in this repo, just a GH action.

Looks good.

Can you point me at Python tests that make sure that jsonschema models can be encoded / decoded from resulting models?

This should be provided for in the future, but unfortunately this is not the case. (Perhaps it would be better to create mock data from jsonschema and parse it.)

At least Pydantic should be able to encode and decode if the type definition is correct. It is also assumed that this code generator does not generate code containing its own logic, so it is largely OK if it outputs the expected model.

natikgadzhi commented 5 months ago

I've also asked on Twitter if any of Swift on Server folks will help me review this IF I actually get this done.

I'm mostly interested in JSON Schemas, but I take it is that one level deep, the generation infrastructure takes the parsed models in and presents them in unified format, whether they're json models or openapi models, right?

koxudaxi commented 5 months ago

Yes. The system parses the input schema and maps it to intermediate classes, so that the output can be in any data model you like. However, some parts are currently implemented with Python in mind, so this may need some thought. For example, checking for reserved keywords and rules for import statements.

The app is not fully abstracted, starting from my personal project, just refactored every time it is needed, to make the output flexible. Even if some refactoring was necessary, Swift support should be possible. At least the parser part contains a lot of logic, which should be far more beneficial than building it from scratch.