Skip to content

Conforming an enum to ReflectionDecodable makes Fluent create it as type jsonb instead of int8 #79

@MrMage

Description

@MrMage

(I am using all relevant packages on the master branch.)

I have an enum like this:

public enum EntityType: SwiftProtobuf.Enum {
  public typealias RawValue = Int
  case unknown // = 0
  case appActivity // = 1
  // more cases
  case UNRECOGNIZED(Int)

  public init() {
    self = .unknown
  }

  public init?(rawValue: Int) {
    switch rawValue {
    case 0: self = .unknown
    case 1: self = .appActivity
    // more cases
    default: self = .UNRECOGNIZED(rawValue)
    }
  }

  public var rawValue: Int {
    switch self {
    case .unknown: return 0
    case .appActivity: return 1
    // more cases
    case .UNRECOGNIZED(let i): return i
    }
  }

}

If I try to make this codable and encoded as an int8 as follows, using EntityType fields in a model creates table columns of type int8 as expected:


extension EntityType: Codable, PostgreSQLDataConvertible, ReflectionDecodable {
	public static var postgreSQLDataType: PostgreSQLDataType { return .int8 }
	public static var postgreSQLDataArrayType: PostgreSQLDataType { return .array(.int8) }
	
	public init(from decoder: Swift.Decoder) throws {
		let container = try decoder.singleValueContainer()
		self.init(rawValue: try container.decode(Int.self))!
	}
	
	public func encode(to encoder: Encoder) throws {
		var container = encoder.singleValueContainer()
		try container.encode(self.rawValue)
	}

	public static func convertFromPostgreSQLData(_ data: PostgreSQLData) throws -> EntityType {
		return EntityType(rawValue: try Int.convertFromPostgreSQLData(data))!
	}

	public func convertToPostgreSQLData() throws -> PostgreSQLData {
		return try self.rawValue.convertToPostgreSQLData()
	}
}

However, then I get runtime errors because the enum is not ReflectionDecodable. If I add ReflectionDecodable conformance like this:

extension EntityType: ReflectionDecodable {
	public static func reflectDecoded() throws -> (EntityType, EntityType) {
		return (.unknown, .appActivity)
	}
}

Then my migrations create the column as type jsonb instead and I get PostgreSQL errors like cannot compare jsonb = bigint for query filters like .filter(\MyModelType.entityType == .appActivity).

How can I ensure that Fluent creates my column of type .int8 even if conforming to ReflectionDecodable?

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions