Skip to content
This repository has been archived by the owner on Nov 16, 2020. It is now read-only.

Added support for passing userInfo to Encoder #61

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

foscomputerservices
Copy link
Contributor

This change allows the userInfo passed to render to be passed down the TemplateDateEncoder chain. This provides for the ability for Request-level information to be passed all the way into the view model during the Encoder process.

The only minor quirk is that the type on userInfo passed to render is very broad [AnyHashable: Any] where the type on Encoder.userInfo is [CodingUserInfoKey: Any]. I opted to filter for the subset and document the filter. I'm happy to consider alternatives.

Any feedback on alternatives to making such information available are happily accepted.

…ataEncoder to Encoder

These changes allow for data to be passed through the TemplateRenderer all the way through to the Encoder that is passed to the view model objects during encoding. This allows for passing request-level information such as locale to the view model objects for selecting formatting, language, etc. during view model encoding.

Existing public APIs (TemplateDataEncoder.encode) were augmented with default values for the new argument to maintain backwards API compatibility, while providing for the new functionality.
Copy link
Member

@tanner0101 tanner0101 left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

Maybe instead of mapping the user info, we could store the entire dictionary in a single key? That way we don't lose any keys that can't convert to CodingUserInfoKey.

For example:

var encodingInfo: [CodingUserInfoKey: Any]
encodingInfo["renderUserInfo"] = userInfo

@@ -4,13 +4,13 @@ public final class TemplateDataEncoder {
public init() {}

/// Encode an `Encodable` item to `TemplateData`.
public func encode<E>(_ encodable: E, on worker: Worker) throws -> Future<TemplateData> where E: Encodable {
public func encode<E>(_ encodable: E, on worker: Worker, userInfo: [CodingUserInfoKey: Any] = [:]) throws -> Future<TemplateData> where E: Encodable {
Copy link
Member

Choose a reason for hiding this comment

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

could we pass this to the init method instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I too thought about mapping the entire dictionary to a single key. I chose against it because it makes the semantics of the Encoder.userInfo call a bit odd:

    let myUserInfo: [AnyHashable: Any] = [
        "myKey" : "myData"
    ]
    
    renderer.render(path, context, userInfo: myUserInfo)
    
    public func encode(to encoder: Encoder) throws {
        let myData = (encoder.userInfo[CodingUserInfoKey(rawValue: "renderUserInfo")] as? [AnyHashable: Any])["myKey"]

However, whatever you think is best. Just let me know and I'll align with your suggestion.

As for the init(), no problem I'll change it.

This change was made as requested by code review.
@foscomputerservices
Copy link
Contributor Author

I'm not sure why this performance test would fail. No code changes affect the performance-tested code, I've double-checked...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants