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

RawRepresentable not supported in SQLite #45

Open
jeremyquinn opened this issue Jun 4, 2018 · 5 comments
Open

RawRepresentable not supported in SQLite #45

jeremyquinn opened this issue Jun 4, 2018 · 5 comments
Labels
enhancement New feature or request

Comments

@jeremyquinn
Copy link
Contributor

Context and Description

As I mentioned in Issue #42, I get errors encoding and decoding Enums which are RawRepresentable & Codable.

I have a tentative solution but at the moment is is per RawType, so would likely be user-specific.

Maybe this could be added to your codebase as an example or to your documentation.
Here is the solution for Int based enum, String etc. is equally trivial.

extension KeyedEncodingContainer {
	public mutating func encodeIfPresent<T>(_ value: T?, forKey key: K) throws where T : Encodable & RawRepresentable, T.RawValue == Int {
		try encodeIfPresent(value?.rawValue, forKey: key)
	}
}

extension KeyedDecodingContainer {
	public func decodeIfPresent<T>(_ type: T.Type, forKey key: K) throws -> T? where T : Decodable & RawRepresentable, T.RawValue == Int {
		if let value = try decodeIfPresent(Int.self, forKey: key) {
			return T.init(rawValue: value)
		}
		return nil
	}
}

Environment Details

Information about your OS, Swift version and Xcode version if on macOS.
MacOS 10.13.4
Xcode 9.4
Kitura 2.4.1
SwiftKuery 1.3.1
SwiftKueryORM 0.1.1
SwiftKuerySQLite 1.0.0

Steps to Reproduce

Model struct contains enum :

public struct Bookmark:Codable, Equatable {
    ...
    public var created: Status? // the read status
    ...
}

public enum Status:Int, Codable {
case nought = 0 	// no special status
case unread		// the user would like to see this highlighted as being in their reading list
case read		// this was in the user's reading list but now they are finished
}
@EnriqueL8
Copy link
Contributor

Hey @jeremyquinn, this is something we should definitely support! Maybe we could have a protocol that the enum has to implement so it can be used in the ORM? Could you open a PR with your prototype?

@jeremyquinn
Copy link
Contributor Author

Hi @EnriqueL8, glad to know you are interested.

The only way I have managed to make this work so far, is to be specific about the type of the RawValue and use a global extension.

My guess is that an implementation for Int and String RawValue will cover 90% of use cases.

Enums can already be made Codable and were already supported by the JSONDecoder. They just were not supported by your DatabaseDecoder/Encoder.

I want to test this extension has no effect on normal Codable usage.
I want to see if it can be added as an extension private to this module only.
I plan to add the support for String

@jeremyquinn
Copy link
Contributor Author

jeremyquinn commented Jun 5, 2018

Added PR #46

Sorry, it looks like my last PR got mixed in ...

@kilnerm kilnerm added the enhancement New feature or request label Nov 19, 2018
@xeokeri
Copy link

xeokeri commented Nov 21, 2019

Is there still a plan to include this in the near future? I'm running into the same issues.

@lmihalkovic
Copy link

Seems it is still broken... I realized that somehow DatabaseEncoder only supports types that do not need any mapping/encoding:

    public mutating func encode<T: Encodable>(_ value: T, forKey key: Key) throws {
        if let dataValue = value as? Data {
        } else {
            encoder.values[key.stringValue] = value
        }

when value is an enum type, then values only contains the naked enum value, rather than storing the mapped value (I use a property wrapper that encodes the enums into their rawValue. the wrapper's encoder is invoked when using JSONEncoder, but never invoked when using DatabaseEncoder.

fileprivate class _DatabaseEncoder: Encoder {
    public var values: [String: Any] = [:]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants