Skip to content

Integer keys#29

Open
michelf wants to merge 1 commit into
hirotakan:masterfrom
michelf:integer-keys
Open

Integer keys#29
michelf wants to merge 1 commit into
hirotakan:masterfrom
michelf:integer-keys

Conversation

@michelf
Copy link
Copy Markdown

@michelf michelf commented Feb 20, 2020

This code adds an encoding and decoding mode where keys in the message pack data are allowed to be integer. If the provided key returns a non-nil intValue and allowIntKeys is set to true in the encoder/decoder, the integer key will be used instead of its string form.

…aries when the CodingKey implementation provides an intValue.
Comment on lines 163 to 171
func contains(_ key: Key) -> Bool {
return container[key.stringValue] != nil
return container[decoder.convertToPackKey(from: key)] != nil
}

func findEntry(by key: CodingKey) throws -> Data {
guard let entry = self.container[key.stringValue] else {
guard let entry = self.container[decoder.convertToPackKey(from: key)] else {
let context = DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")
throw DecodingError.keyNotFound(key, context)
}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

If you change as follows, I think that Decoder does not need allowIntKeys.

        func contains(_ key: Key) -> Bool {
            if let intValue = key.intValue, let _ = container[.int(intValue)] {
                return true
            }
            return container[.string(key.stringValue)] != nil
        }

        func findEntry(by key: CodingKey) throws -> Data {
            if let intValue = key.intValue, let entry = container[.int(intValue)] {
                return entry
            }

            if let entry = self.container[.string(key.stringValue)] {
                return entry
            }

            let context = DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")
            throw DecodingError.keyNotFound(key, context)
        }

fileprivate var storage = MessagePackStorage()

public init() {}
public init(allowIntKeys: Bool = false) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for a good idea!
But I want to change to:

  1. Add KeyEncodingType.
public enum KeyEncodingType {
    case string
    case int
}
  1. Change the initializer.
    private let keyEncodingType: KeyEncodingType

    public init(keyEncodingType: KeyEncodingType = .string) {
        self.keyEncodingType = keyEncodingType
    }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Sounds like a good idea.

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