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

Add DSL-like initializers for document and element #186

Merged
merged 1 commit into from
Jan 16, 2024
Merged

Add DSL-like initializers for document and element #186

merged 1 commit into from
Jan 16, 2024

Conversation

sgade
Copy link
Contributor

@sgade sgade commented Jan 15, 2024

I recently looked at a bit of XML-handling code of mine and thought that the API could be improved to be more ergonomic using @resultBuilders.

This introduces two @resultBuilder-based builders: AEXMLDocumentBuilder and AEXMLElementBuilder. The main difference is that the first produces an AEXMLDocument and only accepts a singular AEXMLElement as its root. The latter produces an array of AEXMLElements.

Both can be used in conjunction to create new hierarchies of elements easily and quickly. Instead of creating child elements before adding them to their parents, they can be created in code in a way that more closely resembles the actual XML structure in the resulting document.

An example use from code that I plan to ship into production is the following. Note how the structure of the document is easily defined and resembles the XML string that would be generated from it.
I added the document builder to the function but I could as well have just wrapped the root element in a AEXMLDocument {} without it.

    @AEXMLDocumentBuilder
    private func buildSoapEnvelope(
        for action: String,
        in serviceType: String,
        with parameters: [String: String] = [:]
    ) -> AEXMLDocument {
        AEXMLElement("s:Envelope", attributes: [
            "xmlns:s": "http://schemas.xmlsoap.org/soap/envelope/",
            "s:encodingStyle": "http://schemas.xmlsoap.org/soap/encoding/"
        ]) {
            AEXMLElement("s:Body") {
                AEXMLElement("s:\(action)", attributes: [
                    "xmlns:u": serviceType
                ]) {

                    for parameter in parameters {
                        AEXMLElement(
                            name: parameter.key,
                            value: parameter.value
                        )
                    }

                }
            }
        }
    }

I think this API is very flexible and adds to the library's readability. It doesn't take away any existing APIs so they remain the same. Would love your feedback. Just let me know what you think about this addition and if I should adjust anything.

(Btw, I have been using your library for years and I am super happy with it! Thank you for providing this to the community!)

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
This introduces two @resultBuilder-based builders: AEXMLDocumentBuilder and
AEXMLElementBuilder. The main difference is that the first produces an
AEXMLDocument an only accepts a singular AEXMLElement as its root. The latter
produces an array of AEXMLElements.

Both can be used in conjunction to create new hierarchies of elements easily
and quickly. Instead of creating child elements before adding them to their
parents, they can be created in code in a way that more closely resembles the
actual XML structure in the resulting document.
@tadija tadija merged commit cbe3b55 into tadija:develop Jan 16, 2024
@tadija
Copy link
Owner

tadija commented Jan 16, 2024

Hi @sgade, thank you for this nice contribution and kind words! This change is now merged on develop and will roll out with the next release soon.

tadija added a commit that referenced this pull request Jan 16, 2024
+ same for the example project
+ remove generated files for testing on linux (deprecated)
+ reorder targets / build phases for all targets
+ add "Builders.swift" from PR #186
+ update Package.swift
tadija pushed a commit that referenced this pull request Jan 16, 2024
This introduces two @resultBuilder-based builders: AEXMLDocumentBuilder and
AEXMLElementBuilder. The main difference is that the first produces an
AEXMLDocument an only accepts a singular AEXMLElement as its root. The latter
produces an array of AEXMLElements.

Both can be used in conjunction to create new hierarchies of elements easily
and quickly. Instead of creating child elements before adding them to their
parents, they can be created in code in a way that more closely resembles the
actual XML structure in the resulting document.
tadija added a commit that referenced this pull request Jan 16, 2024
+ same for the example project
+ remove generated files for testing on linux (deprecated)
+ reorder targets / build phases for all targets
+ add "Builders.swift" from PR #186
+ update Package.swift
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.

None yet

2 participants